-
Здравствуйте, Мне нужно определить владельцев всех процессов, имеющихся в системе. Получаю список процессов системы при помощи 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
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; finally
FreeMem( ptiUser );
end;
end; CloseHandle( hToken );
end else Writeln('OpenProcessToken() failed - ', GetLastError); if ( not GetProcessTimes( hProcess, timeCreate^, timeExit, timeKernel, timeUser ) ) then
begin
Result:= false;
Writeln('GetProcessTimes() failed');
end; CloseHandle( hProcess );
end else Writeln('OpenProcess() failed'); if not ( Result ) then Writeln('FAILED'); end;
Проблема в том, что при вызове OpenProcessToken() выдает ошибку "0x05 (Access Denied)" для процессов, владельцем которых не является запускающий программу пользователь. Подскажите, как побороть? Хотя программу запускаю из-под администратора. Привилегии SE_DEBUG_NAME даны (без них отваливается на OpenProcess() ). Системы Windows 2003 и WIndows 7 Home.
-
Не помню есть ли 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;
-
> Не помню есть ли WinStationGetProcessSid в Windows 2003
Вроде, в ХР есть, значит, и в 2003 должно быть. Кстати, там рядом есть еще одна функция, наводящая на раздумье - WinStationGetAllProcesses(). Попробую Ваше решение; завтра отпишусь.
Жаль только, что приходится использовать низкоуровневые функции (рискованное это дело в продакшене, да документации по ним мало).
-
> Danger © (25.04.10 21:42) [2] > > Жаль только, что приходится использовать низкоуровневые > функции (рискованное это дело в продакшене, да документации > по ним мало).
Низкоуровневая функция?
Ниже какого она уровня? че за бред?
Обычная функция импортируемая из winsta.dll
-
Имел в виду, недокументированная в MSDN и, соответственно, отсутствующая в заголовочных файлах. Ниже API, предоставленного пользователю, ведь экспорт нигде официально не описан.
Спасибо за подсказку, будем смотреть. Надеюсь, что получится.
-
до кучи WTSEnumerateProcesses.
|