I have a problem converting a 32-bit to 64-bit code using the lsaapi.pas unit
with a small Unicode PChar to PAnsiChar correction.
The following code will work in 32-bit mode but not in 64-bit.
Running the procedure (not in 64-bit Debug mode!), getting the error message
invalid parameter by calling LsaQueryInformationPolicy()
Any ideas, what's wrong ?
Why is there a different behavior running this code in the 64-bit debug and non-debug mode ?
Maybe a record alignment problem in 64-bit ?
Here is the code:
uses
lsaapi;
function GetDomainName: string;
var
Buffer: Pointer;
Status: NTStatus;
PolicyHandle: LSA_HANDLE;
ComputerName: TLsaUnicodeStr;
Attributes: TLsaObjectAttributes;
PolicyAccountDomainInfo: PPolicyAccountDomainInfo;
begin
ComputerName := TLsaUnicodeStr.CreateFromStr('');
try
FillChar(Attributes, SizeOf(Attributes), 0);
Status := LsaOpenPolicy(ComputerName.Value, Attributes,
POLICY_VIEW_LOCAL_INFORMATION, PolicyHandle);
if Status <> STATUS_SUCCESS then
raise Exception.Create('LsaOpenPolicy Failed: ' +
SysErrorMessage(LsaNtStatusToWinError(Status)));
try
Status := LsaQueryInformationPolicy(PolicyHandle,
PolicyPrimaryDomainInformation, Buffer);
if Status <> STATUS_SUCCESS then
raise Exception.Create('LsaQueryInformationPolicy Failed: ' +
SysErrorMessage(LsaNtStatusToWinError(Status)));
try
PolicyAccountDomainInfo := Buffer;
Result := PolicyAccountDomainInfo.DomainName.Buffer;
finally
LsaFreeMemory(Buffer)
end;
finally
LsaClose(PolicyHandle)
end;
finally
ComputerName.Free;
end;
end;
All the records in that lsaapi unit are declared to be packed. The Windows API header files do not use packed structs. Fix it by removing all the packed modifiers. If you make that change your function succeeds in both 32 and 64 bit targets.
For what it is worth, your code is actually failing on the call to LsaOpenPolicy. With packed records SizeOf(Attributes) returns 40. The correct size, is 48, and that's the value you get when you remove the packed modifier.
The easiest way to debug this kind of thing is to have a copy of Visual Studio installed so that you can compare equivalent C++ code.
I presume that the incorrect record declarations is the primary problem with that unit. There may very be others, but that's the one that sticks out like a sore thumb.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With