Форум: "WinAPI";
Текущий архив: 2015.09.10;
Скачать: [xml.tar.bz2];
Внизвладелец процесса, ошибка при определении Найти похожие ветки
← →
Danger © (2010-04-25 15:53) [0]Здравствуйте,
Мне нужно определить владельцев всех процессов, имеющихся в системе. Получаю список процессов системы при помощи 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.
← →
Игорь © (2010-04-25 19:05) [1]Не помню есть ли 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;
← →
Danger © (2010-04-25 21:42) [2]> Не помню есть ли WinStationGetProcessSid в Windows 2003
Вроде, в ХР есть, значит, и в 2003 должно быть. Кстати, там рядом есть еще одна функция, наводящая на раздумье - WinStationGetAllProcesses().
Попробую Ваше решение; завтра отпишусь.
Жаль только, что приходится использовать низкоуровневые функции (рискованное это дело в продакшене, да документации по ним мало).
← →
Игорь © (2010-04-25 22:25) [3]
> Danger © (25.04.10 21:42) [2]
>
> Жаль только, что приходится использовать низкоуровневые
> функции (рискованное это дело в продакшене, да документации
> по ним мало).
Низкоуровневая функция?
Ниже какого она уровня? че за бред?
Обычная функция импортируемая из winsta.dll
← →
Danger © (2010-04-25 23:47) [4]Имел в виду, недокументированная в MSDN и, соответственно, отсутствующая в заголовочных файлах. Ниже API, предоставленного пользователю, ведь экспорт нигде официально не описан.
Спасибо за подсказку, будем смотреть. Надеюсь, что получится.
← →
Eraser © (2010-04-26 00:21) [5]до кучи WTSEnumerateProcesses.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2015.09.10;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.05 c