Skip to content

SafeHandle generation for NTSTATUS-returning release method doesn't find constants across multiple ProjectionMetadataWinmd inputs #1677

@MasonBergstrom

Description

@MasonBergstrom

Actual behavior

When generating a SafeHandle for a handle type whose release method returns NTSTATUS, CsWin32 fails during source generation:

PInvoke000: An internal error occurred: Failed while generating extern method: MySubscribeFunction.
Failed while generating SafeHandle for MyReleaseFunction.
Unable to find expected constant: STATUS_SUCCESS.

This occurs when the release method is defined in a custom ProjectionMetadataWinmd, while STATUS_SUCCESS is defined in the standard Win32Metadata winmd. Both winmds are loaded as ProjectionMetadataWinmd items.

In Generator.Handle.cs, the case "NTSTATUS" block calls this.TryGenerateConstantOrThrow("STATUS_SUCCESS") on the individual Generator instance, which only searches its own MetadataIndex. SuperGenerator provides cross-metadata search for types, methods, and enums,
but not for constants — so STATUS_SUCCESS from Win32Metadata is invisible during SafeHandle generation.

Expected behavior

CsWin32 should find STATUS_SUCCESS in Win32Metadata when generating a SafeHandle, since it's loaded as a ProjectionMetadataWinmd input alongside the custom winmd.

Repro steps

  1. NativeMethods.txt content:

    MyReleaseFunction

  2. NativeMethods.json content (if present):

     {
       "$schema": "https://aka.ms/CsWin32.schema.json",
       "emitSingleFile": true
     }
  3. Any of your own code that should be shared?

    Create a custom winmd (via WinmdGenerator) containing:

    • A handle typedef mapped via autoTypes.json with a release method that returns NTSTATUS
    • Do NOT define STATUS_SUCCESS in the custom winmd

    Reference both the custom winmd and Win32Metadata as ProjectionMetadataWinmd items in the consuming project:

    Workaround: Define STATUS_SUCCESS in the custom winmd's source header so it gets scraped into the custom winmd:

    #ifndef STATUS_SUCCESS
    #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
    #endif

Context

  • CsWin32 version: 0.3.213 and 0.3.269 (both reproduce)
  • Win32Metadata version: default (via CsWin32 dependency)
  • Target Framework: netstandard2.0
  • LangVersion: not explicitly set

This issue was drafted with the assistance of GitHub Copilot.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions