Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between calling 64-bit API function in Debug and Release mode

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;
like image 369
user1627172 Avatar asked Jun 01 '26 12:06

user1627172


1 Answers

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.

like image 103
David Heffernan Avatar answered Jun 04 '26 08:06

David Heffernan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!