Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

владелец процесса, ошибка при определении [D7]


Danger ©   (2010-04-25 15:53:00) 

Здравствуйте,
Мне нужно определить владельцев всех процессов, имеющихся в системе. Получаю список процессов системы при помощи EnumProcesses()(из PsAPI), затем пробую получить информацию о каждом конкретном процессе  при помощи такой функции:


function GetProcessParams( dwProcessID: DWord; var strOwner: string; var timeCreate: PFileTime ): Boolean;
var
 hProcess, hToken: THandle;
 ptiUser: PTOKEN_USER; peUse: SID_NAME_USE;
 dwLength: DWord; dwLen1, dwLen2: DWord;
 timeExit, timeKernel, timeUser: FILETIME;
begin
 Result:= false;
 hProcess:= OpenProcess( PROCESS_QUERY_INFORMATION + PROCESS_VM_READ, false, dwProcessId );
 if ( hProcess > 0 ) then
 begin
   // retrieving process owner
   if ( OpenProcessToken( hProcess, TOKEN_QUERY, hToken ) ) then
   begin
     GetTokenInformation( hToken, TokenUser, nil, 0, dwLength );
     if ( ( GetLastError = ERROR_INSUFFICIENT_BUFFER ) and ( dwLength > 0 ) ) then
     begin
       GetMem( ptiUser, dwLength );
       try
        if ( GetTokenInformation( hToken, TokenUser, ptiUser, dwLength, dwLength ) ) then
         if IsValidSid( ptiUser^.User.Sid ) then
         begin
           ZeroMemory( @strUsername, MAX_PATH );
           ZeroMemory( @strDomain, MAX_PATH );
           dwLen1:= MAX_PATH - 1;
           dwLen2:= MAX_PATH - 1;
           if ( LookupAccountSid( nil, ptiUser^.User.Sid, strUsername, dwLen1, strDomain, dwLen2, peUse ) ) then
           begin;
             strOwner:= Copy( strDomain, 0, lstrlen( strDomain ) ) + '\' + Copy( strUsername, 0, lstrlen( strUsername ) );
             Result:= true;
           end;
         end; // 'if IsValidSid( ptiUser^.User.Sid ) then'
       finally
         FreeMem( ptiUser );
       end;
     end; // 'if ( ( GetLastError = ERROR_INSUFFICIENT_BUFFER ) and ( dwLength > 0 ) ) then'
     CloseHandle( hToken );
   end // 'if ( OpenProcessToken( hProcess, TOKEN_READ, hToken ) ) then'
   else Writeln('OpenProcessToken() failed - ', GetLastError); // TODO
  // retrieving process times
   if ( not GetProcessTimes( hProcess, timeCreate^, timeExit, timeKernel, timeUser ) ) then
    // if fails, always set result to false
   begin
   Result:= false;
   Writeln('GetProcessTimes() failed');
   end; // TODO
   CloseHandle( hProcess );
 end // 'if ( hProcess > 0 ) then'
 else Writeln('OpenProcess() failed'); // TODO
  if not ( Result ) then Writeln('FAILED'); // TODO
end;  


Проблема в том, что при вызове OpenProcessToken()выдает ошибку "0x05 (Access Denied)"для процессов, владельцем которых не является запускающий программу пользователь. Подскажите, как побороть?

Хотя программу запускаю из-под администратора. Привилегии SE_DEBUG_NAMEданы (без них отваливается на OpenProcess()).
Системы Windows 2003 и WIndows 7 Home.


Eraser   (2010-04-26 00:21:00) [1]

до кучи WTSEnumerateProcesses.


Danger   (2010-04-25 23:47:00) [2]

Имел в виду, недокументированная в MSDN и, соответственно, отсутствующая в заголовочных файлах. Ниже API, предоставленного пользователю, ведь экспорт нигде официально не описан.

Спасибо за подсказку, будем смотреть. Надеюсь, что получится.


Игорь   (2010-04-25 22:25:00) [3]


> Danger ©   (25.04.10 21:42) [2]
>
> Жаль только, что приходится использовать низкоуровневые
> функции (рискованное это дело в продакшене, да документации
> по ним мало).


Низкоуровневая функция?

Ниже какого она уровня? че за бред?

Обычная функция импортируемая из winsta.dll


Danger   (2010-04-25 21:42:00) [4]

> Не помню есть ли WinStationGetProcessSid в Windows 2003

Вроде, в ХР есть, значит, и в 2003 должно быть. Кстати, там рядом есть еще одна функция, наводящая на раздумье - WinStationGetAllProcesses().
Попробую Ваше решение; завтра отпишусь.

Жаль только, что приходится использовать низкоуровневые функции (рискованное это дело в продакшене, да документации по ним мало).


Игорь   (2010-04-25 19:05:00) [5]

Не помню есть ли WinStationGetProcessSid в Windows 2003

function WinStationGetProcessSid(hServer: Cardinal; ProcessId: Cardinal; ProcessStartTime: _FILETIME; pProcessUserSid: PByte; var dwSidSize: Cardinal): Boolean; stdcall; external 'winsta.dll';

function GetProcessUserAndDomainName(PID: DWORD; var UserName: string; var DomainName: string): Boolean;
var
 hProcess: THandle;
 CreationTime, ExitTime, KernelTime, UserTime: _FILETIME;
 UserSid: Pointer;
 _UserName, _DomainName: PAnsiChar;
 cbUser, cbDomain: Cardinal;
 ReturnLength: Cardinal;
 CreateTime: TSystemTime;
begin
 UserName:= '';
 DomainName:= '';
 Result:= False;
 hProcess:= 0;
   hProcess:= OpenProcess(MAXIMUM_ALLOWED($1000 Vista, 7), False, PID);
 if hProcess > 0 then
 begin
   try
     GetProcessTimes(hProcess, CreationTime, ExitTime, KernelTime, UserTime);
     FileTimeToSystemTime(CreationTime, CreateTime);
     ReturnLength:= 1024;
     GetMem(UserSid, ReturnLength);
     try
       if WinStationGetProcessSid(0, PID, CreationTime, UserSid, ReturnLength) then
       begin
         cbUser:= 1024;
         cbDomain:= 1024;
         GetMem(_UserName, cbUser);
         GetMem(_DomainName, cbDomain);
         try
           if LookupAccountSid(nil, UserSid, _UserName, cbUser, _DomainName, cbDomain, ReturnLength) then
           begin
             SetLength(UserName, cbUser);
             SetLength(DomainName, cbDomain);
             lstrcpy(PAnsiChar(UserName), _UserName);
             lstrcpy(PAnsiChar(DomainName), _DomainName);
             Result:= True;
           end;
         finally
           FreeMem(_UserName);
           FreeMem(_DomainName);
         end;
       end;
     finally
       FreeMem(UserSid);
     end;
   finally
     CloseHandle(hProcess);
   end;
 end;
end;


Наверх

Титульная страница Поиск, карта сайта Написать письмо