Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Passing structures to Windows API

250 views
Skip to first unread message

Christopher Grace

unread,
Sep 11, 2002, 7:03:54 PM9/11/02
to
I'm trying to call Windows' GetTokenInformation function from VB.NET. It
seems part of the problem is that the function requires a structure
containing an array of another type of structure.

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

Mattias Sjögren

unread,
Sep 12, 2002, 6:17:01 PM9/12/02
to
Christopher,

>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.

Christopher Grace

unread,
Sep 12, 2002, 7:16:55 PM9/12/02
to
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.

"Mattias Sjögren" <mattias.don...@mvps.org> wrote in message
news:uTJjHnqWCHA.2720@tkmsftngp10...

Mattias Sjögren

unread,
Sep 14, 2002, 10:05:41 AM9/14/02
to
Christopher,

>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.

Christopher Grace

unread,
Sep 14, 2002, 1:31:06 PM9/14/02
to
I checked it again and this time I see GroupCount=10 and Groups has 7
members. I can tell this by looking in VS.NET's locals window right after
building the structure.

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...

Christopher Grace

unread,
Sep 14, 2002, 11:01:45 PM9/14/02
to
Mattias,

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...

0 new messages