FindDateItemHandle

Find a date item in a collection by handle, filetime, large integer, or GUID

Overview

FindDateItemHandle searches a DATE_COLLECTION_HANDLE (date log, date range, or holidays) for a date item matching exactly one of four possible search criteria: an existing date item handle, a FILETIME, a LARGE_INTEGER, or a GUID.

Purpose

Unifies four distinct lookup mechanisms (SearchDateItem, SearchDateItemByFileTime, SearchDateItemByLargeInteger, SearchDateItemByGuid) behind a single validated, thread-safe public entry point. The result is a handle that points at the matching item inside the collection's own storage, which can be passed to the GetDateItem* accessors, CompareDateItem(), or GetDateItemCopy().

Key Features

Function Signature


DATE_ITEM_HANDLE _Check_return_ _Maybenull_ FindDateItemHandle(
    _In_ _Pre_valid_ DATE_COLLECTION_HANDLE  hDateCollection,
    _In_opt_ DATE_ITEM_HANDLE hDateItem,
    _In_opt_ PFILETIME pFiletime,
    _In_opt_ PLARGE_INTEGER pLargeInt,
    _In_opt_ GUID * rfDateId
);

Parameters

hDateCollection

[In] DATE_COLLECTION_HANDLE

The date log, date range, or holidays handle whose core will be searched.

  • NULL: not allowed (_Pre_valid_); an invalid handle makes the function return NULL.
  • Valid values: a handle from InitializeDateLogHandle() or DuplicateDateLogHandle() whose core has been populated (for example by LoadDateLogHandle()). The handle is validated and locked for the duration of the search.
  • Ownership/lifetime: the caller keeps ownership and must close it later with CloseDateLogHandle().
hDateItem

[In, Optional] DATE_ITEM_HANDLE

Search by a matching date item handle.

  • NULL: allowed. Pass NULL unless this is the one criterion being used.
  • Ownership: not retained or freed.
pFiletime

[In, Optional] PFILETIME

Search by FILETIME value.

  • NULL: allowed. Pass NULL unless this is the one criterion being used.
  • Lifetime: read during the call only; keep it valid until the function returns.
pLargeInt

[In, Optional] PLARGE_INTEGER

Search by LARGE_INTEGER value (a FILETIME-compatible 64-bit integer).

  • NULL: allowed. Pass NULL unless this is the one criterion being used.
  • Lifetime: read during the call only; keep it valid until the function returns.
rfDateId

[In, Optional] GUID *

Search by the date item's GUID (see GetDateItemId in datelog.h).

  • NULL: allowed. Pass NULL unless this is the one criterion being used.
  • Lifetime: read during the call only; keep it valid until the function returns.
Exactly one of hDateItem/pFiletime/pLargeInt/rfDateId must be supplied (non-NULL); the others must be NULL. SAL _When_ annotations enforce this contract at compile time where possible. If all four are NULL the function returns NULL.

Return Values

The function returns a handle, not an HRESULT; test it against NULL. No error code is returned, so use CompareDateItem()/IsValidDateLogHandle() and the surrounding calls to tell "not found" apart from an invalid handle if that distinction matters.

Return valueMeaning
Non-NULL DATE_ITEM_HANDLEA pointer to the matching date item within the collection's internal core (not a copy; do not free).
NULLThe handle fails validation/locking, no search criterion was supplied, the core is missing, no match was found, or an internal mutex could not be acquired within its timeout.

Behavior and Operations

Validate & Lock Handle
→
Dispatch to Matching Search Helper
→
Unlock & Return

The function performs these validation steps before searching:

If more than one criterion is supplied (which violates the contract), the first non-NULL one is used in this order: hDateItem, pFiletime, pLargeInt, rfDateId.

Remarks

The returned handle points directly into the collection's internal array; it remains valid only as long as the collection itself is not freed or mutated.
Never pass the returned handle to FreeDateItem(); items bound to a core are silently ignored by it and are owned by the core. To retain an item, make a standalone copy with GetDateItemCopy() and free that copy.
Header note: datelog.h lists three separate lookups (FindDateItemByHandle, FindDateItemByGuid, FindDateItemByDate) instead of this combined function, and its FindDateItemByDate takes a DATE_STRUCT*. This page documents FindDateItemHandle as the page signature states.

See Also

Sample Code


#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 hStart = NULL;
    DATE_ITEM_HANDLE hEnd = NULL;
    FILETIME         ftStart = { 0 };
    FILETIME         ftEnd = { 0 };
    HRESULT          hr = E_FAIL;
    int              exitCode = 1;
    DATE_ITEM_HANDLE hFound = NULL;
    DATE_ITEM_HANDLE hOther = NULL;
    DATE_ITEM_HANDLE hCopy = NULL;
    FILETIME         ftProbe = { 0 };
    LARGE_INTEGER    liProbe = { 0 };
    GUID             itemId = { 0 };
    SYSTEMTIME       st = { 0 };

    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, 1, 5, &ftStart) || !MakeFiletime(2026, 3, 31, &ftEnd)) {
        printf("SystemTimeToFileTime failed: %lu\n", GetLastError());
        goto cleanup;
    }

    /* Standalone date items; the caller owns them and frees them with FreeDateItem. */
    hr = InitializeDateItem(hHolidays, &ftStart, NULL, &hStart);
    if (FAILED(hr)) {
        printf("InitializeDateItem [start] failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    hr = InitializeDateItem(hHolidays, &ftEnd, NULL, &hEnd);
    if (FAILED(hr)) {
        printf("InitializeDateItem [end] failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    /* The holidays collection is populated first, then the date log over the same range. */
    hr = LoadDateLogHandle(NULL, hStart, hEnd, hHolidays, NULL, 0);
    if (FAILED(hr)) {
        printf("LoadDateLogHandle [holidays] failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    hr = LoadDateLogHandle(NULL, hStart, hEnd, hDateLog, NULL, 0);
    if (FAILED(hr)) {
        printf("LoadDateLogHandle [date log] failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    /* 1. Search by FILETIME (Tuesday, 2026-02-10). */
    if (!MakeFiletime(2026, 2, 10, &ftProbe)) {
        printf("SystemTimeToFileTime failed: %lu\n", GetLastError());
        goto cleanup;
    }
    hFound = FindDateItemHandle(hDateLog, NULL, &ftProbe, NULL, NULL);
    if (hFound == NULL) {
        printf("2026-02-10 is not in the collection (or the handle could not be locked).\n");
        goto cleanup;
    }

    /* hFound points into the collection: read it, but never free it. */
    if (GetDateItemSystemTime(hFound, &st)) {
        printf("Found %04u-%02u-%02u as item number %lu\n",
               (unsigned)st.wYear, (unsigned)st.wMonth, (unsigned)st.wDay,
               (unsigned long)GetDateItemNumber(hFound));
    }

    /* 2. Search by LARGE_INTEGER taken from the found item. */
    if (!GetDateItemLargeInteger(hFound, &liProbe)) {
        printf("GetDateItemLargeInteger failed.\n");
        goto cleanup;
    }
    hOther = FindDateItemHandle(hDateLog, NULL, NULL, &liProbe, NULL);
    printf("Lookup by LARGE_INTEGER %s the same entry.\n", (hOther == hFound) ? "returned" : "did not return");

    /* 3. Search by GUID taken from the found item. */
    GetDateItemId(hFound, &itemId);
    hOther = FindDateItemHandle(hDateLog, NULL, NULL, NULL, &itemId);
    printf("Lookup by GUID %s the same entry.\n", (hOther == hFound) ? "returned" : "did not return");

    /* 4. Search by an item handle that already points into the collection. */
    hOther = FindDateItemHandle(hDateLog, hFound, NULL, NULL, NULL);
    printf("Lookup by handle %s the same entry.\n", (hOther == hFound) ? "returned" : "did not return");

    /* A search that cannot match returns NULL rather than an error code. */
    if (!MakeFiletime(2026, 2, 8, &ftProbe)) {   /* a Sunday */
        goto cleanup;
    }
    if (FindDateItemHandle(hDateLog, NULL, &ftProbe, NULL, NULL) == NULL) {
        printf("2026-02-08 is not in the collection.\n");
    }

    /* Keep an item beyond the lifetime of the collection by copying it. */
    hCopy = GetDateItemCopy(hFound);
    if (hCopy == NULL) {
        printf("GetDateItemCopy failed.\n");
        goto cleanup;
    }
    exitCode = 0;

cleanup:
    FreeDateItem(hCopy);   /* standalone copy: owned by the caller */
    /* hFound and hOther point into the core and are never freed. */
    FreeDateItem(hEnd);
    FreeDateItem(hStart);
    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;
}