Skip to content

Generate SafeHandle owners for cleanup functions that return BOOLEAN - #1859

Merged
Jevan Saks (jevansaks) merged 1 commit into
mainfrom
jevansaks-hidp-preparsed-data-safehandle
Oct 19, 2026
Merged

Jevan Saks (jevansaks) merged 1 commit into
mainfrom
jevansaks-hidp-preparsed-data-safehandle

Conversation

@jevansaks

@jevansaks Jevan Saks (jevansaks) commented Oct 18, 2026 •

Copy link
Copy Markdown
Member

Summary

IsSupportedCleanupReturn now accepts BOOLEAN. The generated ReleaseHandle returns a BOOLEAN result directly, the same way it already handles BOOL: non-zero is success, through BOOLEAN's implicit bool conversion.

Before this change, a RAIIFree or FreeWith annotation that names a BOOLEAN cleanup function produced an abstract owner, and the producer kept its raw output. HidD_FreePreparsedData is the motivating case (discussion #1675, microsoft/win32metadata#2375). With this change and microsoft/win32metadata#2376, this works:

BOOLEAN ok = PInvoke.HidD_GetPreparsedData(device, out HidD_FreePreparsedDataSafeHandle preparsed);
using (preparsed)
{
    if (ok)
    {
        PInvoke.HidP_GetCaps(preparsed.DangerousValue, out HIDP_CAPS caps);
    }
}

Effect on current metadata

None. In Windows.Win32.winmd 71.0.30-preview, the only BOOLEAN function named by a cleanup annotation is ClosePrivateNamespace. It takes two arguments, so its owner stays abstract. Generated output for the stock winmd is unchanged.

Validation

  • New BooleanCleanupProducesOwner theory (RAIIFree and FreeWith, with and without runtime marshaling). It uses the SafeHandleOwnership fixture, which now includes a BOOLEAN typedef, a FreeBoolean cleanup function, and returned and out-parameter producers. The test fails without the fix. All 75 SafeHandleLeaseTests pass with it.
  • End to end, using the winmd built from Add RAIIFree annotations for HidD_GetPreparsedData and related producers win32metadata#2376:
    • All 15 handle types annotated by that PR get a concrete owner. Each owner's ReleaseHandle calls the cleanup function, its IsInvalid treats 0 as invalid, and every producer has an overload with an out owner parameter. With the stock 71.0.30-preview winmd, all 15 fail this check.
    • The generated code compiles, and a console app ran on a real machine with 33 HID interfaces present. HidD_GetPreparsedData with out HidD_FreePreparsedDataSafeHandle, followed by HidP_GetCaps through DangerousValue and through Lease(), succeeded on 32 of them.
    • Disposing the owner while a lease is active defers the free until the lease ends.
    • ReleaseHandle returns true.
    • Over 20,000 iterations, getting and disposing the owner grew private bytes by under 1 MB. A loop that never frees grew them by 9.3 MB.

IsSupportedCleanupReturn rejected cleanup functions that return BOOLEAN,
such as HidD_FreePreparsedData, so their owners were generated as abstract
and producers kept raw outputs. BOOLEAN is now handled like BOOL: the
generated ReleaseHandle returns the result through BOOLEAN's implicit bool
conversion, where non-zero is success.

Related: microsoft/win32metadata#2375

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 0aa7080c-77a0-44e7-8869-029671991a9a
@jevansaks
Jevan Saks (jevansaks) merged commit aabdfc6 into main Oct 19, 2026
20 checks passed
@jevansaks
Jevan Saks (jevansaks) deleted the jevansaks-hidp-preparsed-data-safehandle branch October 19, 2026 01:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants