![]()  | 
	
 
  | 
		
			
  | 	
	
	
		
		|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны | 
![]()  | 
	
	
| 
		 | 
	Опции темы | Поиск в этой теме | Опции просмотра | 
| 
		 
			 
			#1  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Всем привет! Мучаюсь уже не первый день. Никак не могу найти в сети пример использования функции 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; Если все сработает для одного статуса, то тогда можно будет дальше эксперементировать с тем, что бы получать несколько статусов.  |