|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
QueryServiceLockStatus
Всем привет! Мучаюсь уже не первый день. Никак не могу найти в сети пример использования функции 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, одна из последних версий. Ооооочень нужна помощь. Заранее спасибо! |
#2
|
|||
|
|||
1. lpLockStatus - это поинтер на структуру
3. cbBufSize - размер памяти переданный через lpLockStatus 2. pcbBytesNeeded - тоже поинтер, на DWORD Оба параметра, если правильно помню, передавать как var параметры Т.е. сигнатура будет примерно такой: Код:
function QueryServiceLockStatus(hSCManager: SC_HANDLE; var lpLockStatus: QUERY_SERVICE_LOCK_STATUS; cbBufSize: DWORD; var pcbBytesNeeded: DWORD): BOOL; Если все сработает для одного статуса, то тогда можно будет дальше эксперементировать с тем, что бы получать несколько статусов. |