tags:

views:

149

answers:

2

Both LogonUserExEx() and LsaLogonUser() accept a PTOKEN_GROUPS pTokenGroups parameter. I am having trouble marshalling my structure correctly for this parameter.

I have the following structures defined:

[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_GROUPS
{
    public UInt32 GroupCount;
    // Followed by this:
    public SID_AND_ATTRIBUTES[] Groups;
}

[StructLayout(LayoutKind.Sequential)]
public struct SID_AND_ATTRIBUTES
{
    public IntPtr Sid;
    public UInt32 Attributes;
}

Then, in my code I am setting up the structure like this:

win32.TOKEN_GROUPS tg = new win32.TOKEN_GROUPS();
tg.GroupCount = 2;
tg.Groups = new win32.SID_AND_ATTRIBUTES[2];
tg.Groups[0].Attributes = win32.SE_GROUP_ENABLED;
win32.ConvertStringSidToSid("S-1-5-32-546", out (tg.Groups[0].Sid)); // guests TEST
tg.Groups[1].Attributes = win32.SE_GROUP_ENABLED;
win32.ConvertStringSidToSid("S-1-5-32-547", out (tg.Groups[1].Sid)); // power users TEST

This all seems to work (the ConvertStringSidToSid returns TRUE both times). Then I want to turn this into an IntPtr which I can pass to the actual API function. To do this I try:

IntPtr pGroups = Marshal.AllocHGlobal(Marshal.SizeOf(tg))

Followed by:

Marshal.StructureToPtr(tg, pGroups, false);

Something goes awry here however since an exception is thrown with "The Parameter Is Incorrect". Does anyone have an idea why this is happening? Many thanks in advance for your help.

A: 

If you have not done so already, have a look on http://pinvoke.net/

The page for LsaLogonUser may help.

Ian Ringrose
Thanks for your answer. I did look there originally, but the sample provided does not do any marshalling of the token groups. :(
mrbouffant
+1  A: 

have you tried defining TOKEN_GROUPS like this:

[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_GROUPS
{
    public UInt32 GroupCount;
    // Followed by this:
    [MarshalAs(UnmanagedType.ByValArray)] // <--
    public SID_AND_ATTRIBUTES[] Groups;
}

see: TOKEN_GROUPS

najmeddine