John, > > In > > particular, I'm having trouble trying to figure out how to > > marshal the following struct: > > > > public struct KERB_QUERY_TKT_CACHE_RESPONSE > > { > > public KERB_PROTOCOL_MESSAGE_TYPE MessageType; > > public ulong CountOfTickets; > > public KERB_TICKET_CACHE_INFO[] Tickets; > > } > > > > The marshaller bombs each and every time, stating that the > > Tickets array couldn't be marshalled as a struct.
The marhalling layer can't handle variable length arrays in a struct. The best workaround is usually to remove the array member, and then manually calculate the offset of the array and read it. > public struct LARGE_INTEGER > { > public uint LowPart; > public int HighPart; > public struct u > { > public uint LowPart; > public int HighPart; > } > public long QuadPart; > } This isn't right. LARGE_INTEGER is a union that you either can treat as a single 64 bit integer, or two 32 bit parts. Since .NET has a native 64 bit integer, it's easier to remove this type entirely, and replace it with a long everywhere. > [StructLayout(LayoutKind.Sequential)] > public struct KERB_QUERY_TKT_CACHE_RESPONSE > { > public KERB_PROTOCOL_MESSAGE_TYPE MessageType; > public uint CountOfTickets; > public KERB_TICKET_CACHE_INFO[] Tickets; > } I suggest you change it to public struct KERB_QUERY_TKT_CACHE_RESPONSE { public KERB_PROTOCOL_MESSAGE_TYPE MessageType; public uint CountOfTickets; // public KERB_TICKET_CACHE_INFO[] Tickets; } > public class AccessTktCacheExample > { > [DllImport("secur32.dll")] > static extern void LsaConnectUntrusted(out IntPtr LsaHandle); According to the docs, this function returns an NTSTATUS value you might want to check for success, not void. > [DllImport("secur32.dll")] > static extern int LsaCallAuthenticationPackage( > IntPtr LsaHandle, > ulong AuthenticationPackage, > ref KERB_QUERY_TKT_CACHE_REQUEST[] > ProtocolSubmitBuffer, > ref int SubmitBufferLength, > ref KERB_QUERY_TKT_CACHE_RESPONSE[] > ProtocolReturnBuffer, > ref ulong ReturnBufferLength, > ref int ProtocolStatus); AuthenticationPackage and ReturnBufferLength should have the type (u)int, not ulong. ProtocolSubmitBuffer shouldn't be an array, just ref KERB_QUERY_TKT_CACHE_REQUEST should work. ProtocolReturnBuffer should recieve a pointer to memory allocated by the function, you shouldn't supply your own buffer. Therefore, the type should be out IntPtr. Don't forget to free the buffer with LsaFreeReturnBuffer. You can use Marshal.PtrToStructure to retrieve a KERB_QUERY_TKT_CACHE_RESPONSE structure from the returned pointer. You then add an 8 byte offset (Marshal.Sizeof(typeof(KERB_QUERY_TKT_CACHE_RESPONSE))) to the pointer and start reading KERB_TICKET_CACHE_INFO array, item by item. This can be easier to do in an unsafe code block, where you can just increment a "real" pointer (not IntPtr). Mattias === Mattias Sjögren [EMAIL PROTECTED] You can read messages from the DOTNET archive, unsubscribe from DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.