I have a project ported to Delphi 11.2 from 10.2 which appears to be going very well. So far.
I now have an issue with a tried and tested function that checks to see if a file share exists. I have put this into its own test form to make it stand-alone.
The issue with this is the NetApiBufferFree(retBuf). This causes a 0x0000374 (Heap corruption) and the program bombs (no error), sometimes. The pattern of failures is very frustrating.
The same files with Delphi 10.2 work fine, so I’m not sure if it is the code or the 11.2 compiler, or maybe a definition somewhere outside the unit.
Here is the test form used:
unit Unit47;
interface
uses
Vcl.Forms, WinAPI.Windows;
type
TForm47 = class(TForm)
procedure FormShow(Sender: TObject);
end;
TNetShareGetInfo = Function(servername : LPWSTR; netname : LPWSTR;
level : DWORD; var bufptr : LPBYTE) : DWORD stdcall;
TNetApiBufferFree = function(var bufptr: LPBYTE): DWORD stdcall;
var
Form47: TForm47;
implementation
{$R *.dfm}
uses System.SysUtils;
function GetPCName: string;
var
u: array [0 .. 255] of Char;
sz: DWord;
begin
sz := 256 + 1;
GetComputerName(u, sz);
Result := u;
end;
procedure shareExists(srvName, shareName: String; var shrExists, err: boolean);
var
reqdSrv, reqdShare: array[0..255] of WideChar;
retBuf: LPBYTE;
retVal: Integer;
NetShareGetInfo: TNetShareGetInfo;
NetApiBufferFree: TNetApiBufferFree;
Handle: THandle;
lastErrVal: LongInt;
lastError: String;
begin
Handle := LoadLibrary('netapi32.dll');
if Handle <> 0 then
begin
try
shrExists := false;
err := False;
StringToWideChar(srvName, reqdSrv, Length(srvName) + 1);
StringToWideChar(shareName, reqdShare, Length(shareName) + 1);
@NetShareGetInfo := GetProcAddress(Handle, 'NetShareGetInfo');
if @NetShareGetInfo <> nil then
begin
retVal := NetShareGetInfo(reqdSrv, reqdShare, 2, retBuf);
if (retVal = 0) then
begin
@NetApiBufferFree := GetProcAddress(Handle, 'NetApiBufferFree');
NetApiBufferFree(retBuf);
shrExists := true
end;
end;
finally
FreeLibrary(Handle);
end;
end;
end;
procedure TForm47.FormShow(Sender: TObject);
var
ShareExist: Boolean;
Err: Boolean;
begin
shareExists('\\' + GetPCName, 'LGCLIENT$', ShareExist, Err);
end;
end.
The program bombs when the share already exists. Only in D11, and inconsistently, I can run it multiple times without a problem, then suddenly it starts crashing.
Any ideas, or any other known way to do this that doesn’t involve a third party?