FreeOdbcConnectParams

Release an ODBC_CONNECT_PARAMS instance and its internal parameter list

Overview

FreeOdbcConnectParams releases a PODBC_CONNECT_PARAMS instance previously returned by InitializeOdbcConnectParams(). It clears the public bPromptIfIncomplete, AddParam, and ClearParams fields, then frees the underlying allocation (recovered by up-casting the public view back to its internal superset struct, which is valid because the public struct is always the first member).

Purpose

ODBC_CONNECT_PARAMS is the end-user-facing parameter bag used to build a connection string before connecting. Because the public structure is only the first member of a larger private structure, it cannot be released with free(); this function is the only supported way to tear it down, including its internal SLIST-backed parameter storage.

Key Features

Function Signature


HRESULT _Success_(SUCCEEDED(return)) FreeOdbcConnectParams(
    _In_ _Post_invalid_ PODBC_CONNECT_PARAMS pParams
);

Parameters

pParams

[In, Post-invalid] PODBC_CONNECT_PARAMS

The instance to free, obtained from InitializeOdbcConnectParams().

  • Type: the pointer itself (PODBC_CONNECT_PARAMS), not the address of a pointer.
  • NULL: not allowed; the function returns HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER).
  • Valid values: only pointers returned by InitializeOdbcConnectParams(). Do not pass a stack-declared or malloced ODBC_CONNECT_PARAMS.
  • Ownership/lifetime: ownership returns to the library. The pointer is invalid after the call (_Post_invalid_) and must not be used or freed again; set your variable to NULL afterwards.

Return Values

Check the result with FAILED/SUCCEEDED.

Return valueMeaning
S_OKInstance released successfully.
HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER)pParams is NULL.

Behavior and Operations

Validate pParams
→
Clear public fields
→
Up-cast to internal struct
→
Free allocation

The function clears bPromptIfIncomplete, AddParam, and ClearParams, then frees the allocation obtained from InitializeOdbcConnectParams() after recovering the internal superset structure from the public view.

Remarks

This function only tears down the standalone ODBC_CONNECT_PARAMS object itself (the end-user-facing parameter bag used to build a connection string before connecting). It is distinct from the connection's own internal parameter list, which is released as part of FreeOdbcConnectionContext().
Always pair every successful call to InitializeOdbcConnectParams() with exactly one call to FreeOdbcConnectParams() to avoid leaking the internal SLIST-backed parameter storage.
Documentation inconsistencies: this function takes the pointer itself, but the ODBC_CONNECT_PARAMS page's examples pass &pParams. The overview above mentions a public bPromptIfIncomplete field, which the structure page does not list among the public members.

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;
    PODBC_CONNECT_PARAMS pParams = NULL;

    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 date log needs a reserved connection slot before it can be connected. */
    hr = InitializeDateLogHandleOdbc(hDateLog, DATE_LOG_ODBC_1);
    if (FAILED(hr)) {
        printf("InitializeDateLogHandleOdbc failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    hr = InitializeOdbcConnectParams(&pParams);
    if (FAILED(hr)) {
        printf("InitializeOdbcConnectParams failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    /* Parameters are added through the AddParam function pointer on the instance. */
    hr = pParams->AddParam(pParams, "Driver", "{ODBC Driver 17 for SQL Server}");
    if (FAILED(hr)) {
        printf("AddParam [Driver] failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }
    hr = pParams->AddParam(pParams, "Server", "localhost\\SQLEXPRESS");
    if (FAILED(hr)) {
        printf("AddParam [Server] failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }
    hr = pParams->AddParam(pParams, "Database", "DateDatabase");
    if (FAILED(hr)) {
        printf("AddParam [Database] failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }
    hr = pParams->AddParam(pParams, "Trusted_Connection", "yes");
    if (FAILED(hr)) {
        printf("AddParam [Trusted_Connection] failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    printf("Connection string holds %lu parameter(s).\n", (unsigned long)pParams->ParamCount);

    /* The handle consumes the parameters without retaining pParams itself. */
    hr = ConnectDateLogHandleToOdbcDatabase(hDateLog, pParams, DATE_LOG_ODBC_1);
    if (FAILED(hr)) {
        printf("ConnectDateLogHandleToOdbcDatabase failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    /* Exactly one FreeOdbcConnectParams per successful InitializeOdbcConnectParams. */
    hr = FreeOdbcConnectParams(pParams);
    pParams = NULL;
    if (FAILED(hr)) {
        printf("FreeOdbcConnectParams failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    printf("Connected; the parameter object has been released.\n");
    exitCode = 0;

cleanup:
    if (pParams != NULL) {
        /* Failure paths that never reached the free above release the object here. */
        hr = FreeOdbcConnectParams(pParams);
        if (FAILED(hr)) {
            printf("FreeOdbcConnectParams failed: 0x%08lX\n", (unsigned long)hr);
        }
        pParams = NULL;
    }
    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;
}