Всем привет! Мучаюсь уже не первый день. Никак не могу найти в сети пример использования функции QueryServiceLockStatus на Delphi. Вроде как есть примеры на C++, в этом языке я вообще 0, но как мне кажется параметры этой функции там объявлены иначе. Причем прецедент уже был со стороны Delphi - в этом же модуле функция EnumServicesStatus так же была объявлена с ошибкой и в новых версиях Delphi ее исправили, видимо и с этой тоже самое. Я попытался написать обёртку для этой функции:
Код:
function IsLockServiceDatabase(
out ErrCode: Integer;
out LockOwner: string;
out LockDuration: Cardinal
): Boolean;
var
hSCManager: SC_HANDLE;
BufSize, BytesNeeded: DWORD;
//Buffer: PByte;
LockStatus: QUERY_SERVICE_LOCK_STATUS;
begin
Result := False;
ErrCode := ERROR_SUCCESS;
LockOwner := '';
LockDuration := 0;
hSCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if hSCManager > 0 then
try
BufSize := 0;
BytesNeeded := 0;
if not QueryServiceLockStatus(
hSCManager,
LockStatus,
BufSize,
BytesNeeded
) and (GetLastError() = ERROR_INSUFFICIENT_BUFFER) then
begin
BufSize := BytesNeeded;
//GetMem(Buffer, BytesNeeded);
try
if QueryServiceLockStatus(
hSCManager,
LockStatus,
BufSize,
BytesNeeded
) then
begin
Result := not (LockStatus.fIsLocked = 0);
if Result then
begin
LockOwner := LockStatus.lpLockOwner;
LockDuration := LockStatus.dwLockDuration;
end;
end else
ErrCode := GetLastError();
finally
//FreeMem(Buffer);
end;
end;
finally
CloseServiceHandle(hSCManager);
end else
ErrCode := GetLastError();
end;
но когда я вызываю QueryServiceLockStatus второй раз то меняется значение в переменной BufSize, видимо где-то затирается память. Кроме того теряется весь смысл получения размера для буфера данных, ведь в Delphi 2-ой параметр в этой функции не объявлен как указатель, в С++ это как раз указатель на буффер в памяти. Я попытался переопределить описание функции:
Код:
function QueryServiceLockStatus(hSCManager: SC_HANDLE;
var lpLockStatus: PByte; cbBufSize: DWORD;
pcbBytesNeeded: PDWORD): BOOL; stdcall;
function QueryServiceLockStatus; external advapi32 name 'QueryServiceLockStatusW';
function IsLockServiceDatabase(
out ErrCode: Integer;
out LockOwner: string;
out LockDuration: Cardinal
): Boolean;
var
hSCManager: SC_HANDLE;
BufSize, BytesNeeded: DWORD;
Buffer: PByte;
lpLockStatus: LPQUERY_SERVICE_LOCK_STATUSW; //QUERY_SERVICE_LOCK_STATUS;
begin
Result := False;
ErrCode := ERROR_SUCCESS;
LockOwner := '';
LockDuration := 0;
hSCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if hSCManager > 0 then
try
BufSize := 0;
BytesNeeded := 0;
if not QueryServiceLockStatus(
hSCManager,
Buffer, //lpLockStatus,
BufSize,
@BytesNeeded
) and (GetLastError() = ERROR_INSUFFICIENT_BUFFER) then
begin
BufSize := BytesNeeded;
GetMem(Buffer, BytesNeeded);
try
if QueryServiceLockStatus(
hSCManager,
Buffer, //lpLockStatus,
BufSize,
@BytesNeeded
) then
begin
Result := not (LPQUERY_SERVICE_LOCK_STATUSW(Buffer)^.fIsLocked = 0);
if Result then
begin
LockOwner := LPQUERY_SERVICE_LOCK_STATUSW(Buffer)^.lpLockOwner;
LockDuration := LPQUERY_SERVICE_LOCK_STATUSW(Buffer)^.dwLockDuration;
end;
end else
ErrCode := GetLastError();
finally
FreeMem(Buffer);
end;
end;
finally
CloseServiceHandle(hSCManager);
end else
ErrCode := GetLastError();
end;
Все компилится, по при выполнении падает в виолейшин.
Может кто нибудь привести объяснить и привести пример кода, как правильно работать с этим зверем? Код пишу в Delphi 10.4, одна из последних версий. Ооооочень нужна помощь. Заранее спасибо!