Here is my latest attempt. It throws an exception when making the API call:
An unhandled exception of type 'System.TypeLoadException' occurred in
TestApp.exe
Additional information: Can not marshal field Groups of type TOKEN_GROUPS:
This type can not be marshaled as a structure field.
Any ideas?
________________________________________
Option Strict On
Imports System.Runtime.InteropServices
Imports System.Runtime.InteropServices.Marshal
Public Class Class2
Public Const ANYSIZE_ARRAY As Integer = 100
Private Enum TOKEN_INFORMATION_CLASS
TokenUser = 1
TokenGroups
TokenPrivileges
TokenOwner
TokenPrimaryGroup
TokenDefaultDacl
TokenSource
TokenType
TokenImpersonationLevel
TokenStatistics
TokenRestrictedSids
TokenSessionId
TokenGroupsAndPrivileges
TokenSessionReference
TokenSandBoxInert
End Enum
Private Declare Auto Function GetTokenInfo Lib "Advapi32.dll" Alias
"GetTokenInformation" ( _
ByVal TokenHandle As IntPtr, _
ByVal eTokenInformationClass As TOKEN_INFORMATION_CLASS, _
ByRef TokenInformation As TOKEN_GROUPS, _
<MarshalAsAttribute(UnmanagedType.U4)> ByVal TokenInformationLength As
Integer, _
<MarshalAsAttribute(UnmanagedType.U4)> ByRef iReturnLength As Integer) As
Boolean
<StructLayoutAttribute(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Friend Structure TOKEN_GROUPS
<MarshalAsAttribute(UnmanagedType.U4)> _
Public GroupCount As Integer
<MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst:=ANYSIZE_ARRAY)> _
Friend Groups As SID_AND_ATTRIBUTES()
End Structure
<StructLayoutAttribute(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Friend Structure SID_AND_ATTRIBUTES
Public Sid As IntPtr
<MarshalAsAttribute(UnmanagedType.U4)> _
Public Attributes As Integer
End Structure
Public Sub GetTokenGroups()
Dim hToken As IntPtr = Security.Principal.WindowsIdentity.GetCurrent.Token
Dim oTokenInfo As TOKEN_GROUPS
Dim iSizeOfTokenInfo As Integer
Dim iSizeOfGroup As Integer
Dim iSizeOfReturnedTokenInfo As Integer
Const cSizeOfGroupCountField As Integer = 4
oTokenInfo = CreateTokenGroups(ANYSIZE_ARRAY)
iSizeOfGroup = SizeOf(New SID_AND_ATTRIBUTES())
iSizeOfTokenInfo = cSizeOfGroupCountField + (ANYSIZE_ARRAY * iSizeOfGroup)
GetTokenInfo(hToken, TOKEN_INFORMATION_CLASS.TokenGroups, oTokenInfo,
iSizeOfTokenInfo, iSizeOfReturnedTokenInfo)
Debug.WriteLine("oToken filled with data = " & (oTokenInfo.GroupCount <>
0).ToString)
End Sub
Private Function CreateTokenGroups(ByVal iArraySize As Integer) As
TOKEN_GROUPS
Dim oGroups As SID_AND_ATTRIBUTES()
Dim oToken_Groups As New TOKEN_GROUPS()
oGroups = New SID_AND_ATTRIBUTES(iArraySize - 1) {}
oToken_Groups.Groups = oGroups
Return oToken_Groups
End Function
End Class
>Any ideas?
In this case, it's probably easier to skip the structure and work
directly against a dynamicly allocated chunk of unmanaged memory
(since you don't know how many SID_AND_ATTRIBUTES will be returned).
Use one of the Marshal.Alloc* methods for allocation, pass the pointer
to the function, use Marshal.ReadInt32() to read
TOKEN_GROUPS.GroupCount, then use Marshal.PtrToStructure() GroupCount
times to read each SID_AND_ATTRIBUTES, incrementing the pointer each
time as needed.
Mattias
===
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.
"Mattias Sjögren" <mattias.don...@mvps.org> wrote in message
news:uTJjHnqWCHA.2720@tkmsftngp10...
>That's exactly what I did. It seemed to work beautifully, but I'm a little
>concerned because I got 33 SID_AND_ATTRIBUTES structures back (in the Groups
>field), while the GroupCount field was only 10.
What makes you think that the Groups field had 33 members? GroupCount
is the only indicator of how long the array is.
Here's a breakdown of what I did. Maybe it's something different than what
you were thinking.
I created a Byte array with a length of 800 (enough room for a TOKEN_GROUP
structure with 100 groups). I pinned a pointer (so .NET won't move the data
it pointed to) for the Byte array. I passed this pointer to the
GetTokenInfo function. GetTokenInfo filled 268 of the members in the array
with values. Using Marshal.ReadInt32 I read the integers one by one starting
at the memory address indicated by the pointer to the byte array. The first
integer went to fill the GroupCount field. The following two went to fill
the first SID_AND_ATTRIBUTES structure (contained by the TOKEN_GROUP
structure), and so on until the array of SID_AND_ATTRIBUTE structures was
filed. When done, the Groups field contained an array of 7 structures even
thought the GroupCount field read 10.
"Mattias Sjögren" <mattias.don...@mvps.org> wrote in message
news:u0UIzd$WCHA.1752@tkmsftngp10...
I went back and reread your post more carefully and did exactly what you
said. It worked! Thanks so much for your help. I wonder why the Byte
array didn't (not that I'd prefer it).
"Mattias Sjögren" <mattias.don...@mvps.org> wrote in message
news:u0UIzd$WCHA.1752@tkmsftngp10...