Winapi LsaLookupAuthenticationPackage always Returns Error 1364

I’ve tried every trick in the book that I can think of to try wrangle the LSA_STRING into submission but I just can’t seem to find a way to pass the PackageName for LsaLookupAuthenticationPackage in a way that returns anything other than Error: 1364.

declare function LsaConnectUntrusted lib "secur32.dll" ( _
byref lsaHandle as ptr) as Uint32 

dim ptrConnect as ptr 

call LsaConnectUntrusted(ptrConnect)

dim packageName as string = "Kerberos" // Doesn't have to be Kerberos just the easiest one to remember.
packageName = ConvertEncoding(packageName, Encodings.WindowsANSI)

dim strMb as new MemoryBlock(packageName.Length + 1)
strMB.CString(0) = packageName

dim LSA_STRING as new MemoryBlock(12)
LSA_STRING.UInt16Value(0) = packageName.Length
LSA_STRING.UInt16Value(2) = packageName.Length + 1
LSA_STRING.ptr(4) = strMb

Declare function LsaLookupAuthenticationPackage lib "secur32.dll" (_
byval LsaHandle as ptr,_ // [in]
byval PackageName as ptr,_
byref AuthenticationPackage as ptr)_ // [out]
as Uint32

declare function LsaNtStatusToWinError lib "advapi32.dll" (_
returnedError as Uint32) as Uint32

dim authpack As ptr

dim errorCode as uint32 = LsaNtStatusToWinError(LsaLookupAuthenticationPackage(ptrConnect,LSA_STRING,AuthPack))

if errorCode <> 1364 and errorCode <> 206 then break // Package Unkown

break

I’ve got a solution that avoids using the api entirely but I decided to still post this out of pure intrigue as to if there is a way to get Xojo and Winapi to play nice here.

Structure layouts are not necessarily contiguous, and are not necessarily consistent between 32-bit and 64-bit (or between different versions of the same library.) This is because the members are aligned to certain byte offsets for efficiency.

In this case LSA_STRING appears to use an 8-byte alignment on 64-bit Windows, which means the structure is actually 16 bytes long (not 12), and the Buffer member is at offset 8 (not 4):

dim LSA_STRING as new MemoryBlock(16)
LSA_STRING.UInt16Value(0) = packageName.Length
LSA_STRING.UInt16Value(2) = packageName.Length + 1
LSA_STRING.ptr(8) = strMb

Xojo can handle these details for you automatically. Insert a Structure into your app and recreate the LSA_STRING in it, and use that instead of a bare MemoryBlock. You can then alter the alignment using the StructureAlignment attribute:

3 Likes

Absolute genius! There’s not much else I can say… Thank you Andrew that had been bugging me for a while :grin:

1 Like