Free an allocated, unbound date item
FreeDateItem releases a standalone DATE_ITEM_HANDLE previously returned by
functions such as NewDateItem(), GetDateItemCopy(), or
InitializeDateItem(). Items that are still bound/linked to a date log core (recognizable by
their sentinel indicator fields) are silently ignored and not freed, to prevent accidental corruption of the
core's internal array.
Date items come from two very different places: they are either standalone allocations owned by the
caller, or they are entries that live directly inside a date log core's array and are owned by that core.
FreeDateItem is the single release call for standalone items, and it is deliberately defensive
so that a handle which points into a core cannot be freed by mistake.
NULL as a harmless no-op, so unconditional cleanup paths are safevoid; there is no error to inspect
void FreeDateItem(
_In_ _Post_invalid_ DATE_ITEM_HANDLE hDateItem
);
[In, Post-invalid] DATE_ITEM_HANDLE
The standalone (unlinked) date item to release.
DATE_ITEM_HANDLE (opaque void*, see datelog.h).InitializeDateItem(), GetDateItemCopy() (or NewDateItem()), or a handle that is already linked into a core (which is ignored)._Post_invalid_) and must not be used again, unless the call skipped it because it was bound to a core (see Remarks). Do not free the same standalone item twice.This function returns no value, so there is nothing to test with FAILED/SUCCEEDED.
| Return value | Meaning |
|---|---|
void | No return value. The handle is invalid after this call unless it was skipped because it is bound to a date log core. |
The function frees the item only when bookmarkLenOrInd, iNumberLenOrInd, and dateLenOrInd are all equal to DATE_LOG_SENTINEL. This is the signature of a standalone item, as opposed to one stored directly inside a DATE_LOG_CORE array, which must never be individually freed. Any other item is ignored without an error.
InitializeDateItem() or GetDateItemCopy() must be released with exactly one call to FreeDateItem().FindDateItemHandle() returns a pointer into the
collection's internal array. That is not a standalone item and must not be freed; passing it to
FreeDateItem() is silently ignored. To keep an item beyond the collection's lifetime, take a standalone
copy with GetDateItemCopy() and free that copy.
CloseDateLogHandle(), DuplicateDateLogHandle()) are, but freeing an item does not affect any handle's reference count.LoadDateLogHandle()) are still owned by the caller afterwards and should be freed with this function once no longer needed.InitializeDateItem() guarantees *hDateItem is NULL on failure, so unconditional FreeDateItem() calls in cleanup code are safe.
#include <Windows.h>
#include <stdio.h>
#include "datelog.h"
static BOOL MakeFiletime(WORD wYear, WORD wMonth, WORD wDay, PFILETIME pFiletime)
{
SYSTEMTIME st = { 0 };
st.wYear = wYear;
st.wMonth = wMonth;
st.wDay = wDay;
return SystemTimeToFileTime(&st, pFiletime);
}
int main(void)
{
HOLIDAYS_HANDLE hHolidays = NULL;
DATE_LOG_HANDLE hDateLog = NULL;
DATE_ITEM_HANDLE hItem = NULL;
DATE_ITEM_HANDLE hCopy = NULL;
FILETIME ft = { 0 };
HRESULT hr = E_FAIL;
int exitCode = 1;
hr = InitializeDateLogHandle(NULL, DATE_LOG_MAX, NULL, &hHolidays, HandleIsForHolidays);
if (FAILED(hr)) {
printf("InitializeDateLogHandle [holidays] failed: 0x%08lX\n", (unsigned long)hr);
goto cleanup;
}
hr = InitializeDateLogHandle(NULL, DATE_LOG_MAX, hHolidays, &hDateLog, HandleIsForDatelog);
if (FAILED(hr)) {
printf("InitializeDateLogHandle [date log] failed: 0x%08lX\n", (unsigned long)hr);
goto cleanup;
}
if (!MakeFiletime(2026, 10, 13, &ft)) {
printf("SystemTimeToFileTime failed: %lu\n", GetLastError());
goto cleanup;
}
/* InitializeDateItem returns a standalone item that the caller must free. */
hr = InitializeDateItem(hDateLog, &ft, NULL, &hItem);
if (hr == ERR_DATE_IS_HOLIDAY) {
printf("2026-10-13 is a weekend or market holiday.\n");
goto cleanup;
}
if (FAILED(hr)) {
printf("InitializeDateItem failed: 0x%08lX\n", (unsigned long)hr);
goto cleanup;
}
/* GetDateItemCopy also returns a standalone item (NULL on failure). */
hCopy = GetDateItemCopy(hItem);
if (hCopy == NULL) {
printf("GetDateItemCopy failed.\n");
goto cleanup;
}
/* Each standalone item is released exactly once. */
FreeDateItem(hCopy);
hCopy = NULL;
FreeDateItem(hItem);
hItem = NULL;
/* FreeDateItem(NULL) is a documented no-op, so unconditional cleanup is safe. */
FreeDateItem(hItem);
exitCode = 0;
cleanup:
FreeDateItem(hCopy);
FreeDateItem(hItem);
if (hDateLog != NULL) {
hr = CloseDateLogHandle(hDateLog);
if (FAILED(hr)) {
printf("CloseDateLogHandle [date log] failed: 0x%08lX\n", (unsigned long)hr);
}
}
if (hHolidays != NULL) {
hr = CloseDateLogHandle(hHolidays);
if (FAILED(hr)) {
printf("CloseDateLogHandle [holidays] failed: 0x%08lX\n", (unsigned long)hr);
}
}
return exitCode;
}