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
2.06k stars 87 forks source link

Helper generated for SetEntriesInAcl is failing with ERROR_INVALID_PARAMETER #929

Open tydunkel opened 1 year ago

tydunkel commented 1 year ago

Actual behavior

Calling PInvoke.SetEntriesInAcl(Span, ACL, out ACL) with an existing ACL (second param) fails with ERROR_INVALID_PARAMETER.

Expected behavior

The entries are set in the out param.

Repro steps

  1. NativeMethods.txt content:

    SetEntriesInAcl
    GetNamedSecurityInfo
    BuildTrusteeWithSid
  2. NativeMethods.json content (if present): N/A

  3. Any of your own code that should be shared?

ACL* existingAcl;

 // Get the existing ACL.
var error = PInvoke.GetNamedSecurityInfo(
                serviceName,
                SE_OBJECT_TYPE.SE_SERVICE,
                OBJECT_SECURITY_INFORMATION.DACL_SECURITY_INFORMATION,
                null,
                null,
                &existingAcl,
                null,
                out var securityDescriptor);

...

// Set the SID to be the trustee of the access we are adding.
PInvoke.BuildTrusteeWithSid(ref access.Trustee, sid);

// Grant service permissions for the SID.
access.grfAccessMode = ACCESS_MODE.SET_ACCESS;
access.grfInheritance = ACE_FLAGS.NO_INHERITANCE;
access.grfAccessPermissions = SetupPInvoke.SERVICE_START
            | SetupPInvoke.SERVICE_STOP
            | SetupPInvoke.SERVICE_QUERY_CONFIG
            | SetupPInvoke.SERVICE_QUERY_STATUS
            | SetupPInvoke.SERVICE_ENUMERATE_DEPENDENTS
            | SetupPInvoke.SERVICE_INTERROGATE;

// Copy the existing ACL to our new ACL + the new access we are adding
error = PInvoke.SetEntriesInAcl(new[] { access }, *existingAcl, out var newAcl);

Context

AArnott commented 1 year ago

I don't see any obvious errors in the C# code CsWin32 generates compared to the win32metadata. Can you try a few things to help with the investigation?

  1. Does it fail when you call the other SetEntriesInAcl overload (the one that takes cCountOfExplicitEntries as a first parameter)?
  2. Did you have this working in C# before with a custom p/invoke? If so, can you share the one that works?
  3. Can you try this from native C code to see if you get a better result?

A subset of the above may be adequate.