microsoft / CsWin32

A source generator to add a user-defined set of Win32 P/Invoke methods and supporting types to a C# project.
MIT License
1.99k stars 84 forks source link

PROCESS_MITIGATION_REDIRECTION_TRUST_POLICY (I assume most PROCESS_MITIGATION_*) structs not fully generated #1160

Closed mitchcapper closed 3 months ago

mitchcapper commented 3 months ago

Actual behavior

A struct declared as:

internal partial struct PROCESS_MITIGATION_REDIRECTION_TRUST_POLICY {
    internal _Anonymous_e__Union Anonymous;

    [StructLayout(LayoutKind.Explicit)]
    [global::System.CodeDom.Compiler.GeneratedCode("Microsoft.Windows.CsWin32", "0.3.49-beta+91f5c15987")]
    internal partial struct _Anonymous_e__Union {
        [FieldOffset(0)]
        internal uint Flags;
        [FieldOffset(0)]
        internal _Anonymous_e__Struct Anonymous;
        [global::System.CodeDom.Compiler.GeneratedCode("Microsoft.Windows.CsWin32", "0.3.49-beta+91f5c15987")]
        internal partial struct _Anonymous_e__Struct {
            internal uint _bitfield;
        }
    }
}

Expected behavior

Officially it is

typedef struct _PROCESS_MITIGATION_REDIRECTION_TRUST_POLICY {
  union {
    DWORD Flags;
    struct {
      DWORD EnforceRedirectionTrust : 1;
      DWORD AuditRedirectionTrust : 1;
      DWORD ReservedFlags : 30;
    } DUMMYSTRUCTNAME;
  } DUMMYUNIONNAME;
} PROCESS_MITIGATION_REDIRECTION_TRUST_POLICY, *PPROCESS_MITIGATION_REDIRECTION_TRUST_POLICY;

We can declare 1 bit fields for structs so it should be doable to have the flags declared.

On a side note, CsWin32 could create a SafeStructHandle class to assist on void* passes where the type of struct is not known (assuming not going the overload route). Just wrapping the marshal calls below.

Repro steps

  1. NativeMethods.txt content:

    SetProcessMitigationPolicy
    PROCESS_MITIGATION_REDIRECTION_TRUST_POLICY
  2. NativeMethods.json content (if present):


3. Any of your own code that should be shared?
```csharp
private unsafe void SetRedirectionPolicy() {
    var polStruct = new PROCESS_MITIGATION_REDIRECTION_TRUST_POLICY();
    polStruct.Anonymous.Flags = 1 << 1;
    var sSize = Marshal.SizeOf(polStruct);
    IntPtr ptr = Marshal.AllocHGlobal(sSize);
    Marshal.StructureToPtr(polStruct, ptr, false);
    if (!PInvoke.SetProcessMitigationPolicy(Windows.Win32.System.Threading.PROCESS_MITIGATION_POLICY.ProcessRedirectionTrustPolicy, ptr.ToPointer(), (nuint)sSize))
        throw new Win32Exception();
    Marshal.DestroyStructure(ptr,polStruct.GetType());
    Marshal.FreeHGlobal(ptr);
}

Granted for my use case I still got access denied but I think the code is sound.

Context

net472 <PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.49-beta">

AArnott commented 3 months ago

Support for bitfields was added recently (#987). Try 0.3.85-beta from our CI feed (per the README) and let me know how it goes.

mitchcapper commented 3 months ago

like magic :)