Форум: "WinAPI";
Текущий архив: 2004.11.14;
Скачать: [xml.tar.bz2];
ВнизЗависание при выполнении ZwQueryObject Найти похожие ветки
← →
Nalexey © (2004-10-06 10:21) [0]Доброго всем дня.
Столкнулся с проблемой: пытаюсь по хэндлу файла получить его имя, при обращаении к некоторым пайпам открытым в синхронном режиме вдимо мой процесс встает в очередь, и его невозможно прибить. Есть ли возможность решения этой проблемы? Сталкивался ли кто с такой проблемой? Или может есть другие пути получния имя файла по хендлу?
← →
Digitman © (2004-10-06 10:37) [1]Zw-функции допустимы к вызову только в режиме ядра
← →
Nalexey © (2004-10-06 10:54) [2]>Digitman © (06.10.04 10:37) [1]
Хорошо, тогда перефразирую свой вопрос, как из пользовательского режима можно получить имя файла по его хендлу?
← →
Digitman © (2004-10-06 11:16) [3]NtQueryObject
← →
Игорь Шевченко © (2004-10-06 11:43) [4]Digitman © (06.10.04 10:37) [1]
Без разницы
Nalexey © (06.10.04 10:21)
Эта проблема описана у Неббета. Ее решение - не опрашивать те объекты, которые относятся к процессам сервисов и процессу SERVICES.EXE. Или использовать Process Explorer Руссиновича, где эта проблема решается собственным драйвером режима ядра.
← →
Nalexey © (2004-10-06 13:11) [5]>Игорь Шевченко © (06.10.04 11:43) [4]
Тогда осмелюсь задать еще один вопрос: насколько мне известно, сервисы запускаются под Local System Account, я пытаюсь определить, PID ли это сервиса следующим образом:
function GetSidStr(Sid : PSid) : string;
var
h: LongWord;
Buf: array [0..MAX_PATH - 1] of char;
p: PAnsiChar;
begin
FillChar (Buf, SizeOf(Buf), 0);
if ConvertSidToStringSid(Sid, p) then
Result := string(p);
LocalFree (LongWord(p));
end;
function GoThru(PID: DWORD): boolean;
type
PTOKEN_OWNER = ^TOKEN_OWNER;
_TOKEN_OWNER = record
Owner: PSID;
end;
TOKEN_OWNER = _TOKEN_OWNER;
var
hToken: THandle;
Res: boolean;
pOut: PTOKEN_OWNER;
dwLen: DWORD;
dwRet: DWORD;
hModule: THandle;
ResStr: string;
begin
OpenProcessToken(PID, TOKEN_ALL_ACCESS,hToken);
dwLen := 127;
pOut := AllocMem(dwLen);
GetTokenInformation(hToken, TokenOwner{TokenUser}, pOut, dwLen, dwRet);
ResStr := WinGetSidStr(PSID(pOut.Owner));
Result := ResStr = "S-1-5-18";
end;
Перебираю все процессы ч.з CreateToolHelp32SnapShot. Можно ли сказать что это правильный подход? Если нет, то как можно определить что это PID сервиса?
← →
Игорь Шевченко © (2004-10-06 14:00) [6]Nalexey © (06.10.04 13:11) [5]
Я делал так, определяя системный ли процесс (этот код показывает имя учетной записи для каждого процесса):unit main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
NtProcessInfo, ComCtrls;
type
TfMain = class(TForm)
ListView: TListView;
procedure FormCreate(Sender: TObject);
private
FProcessList: THSNtProcessInfoList;
procedure RefreshProcessList;
procedure LookupProcessOwner(AProcess: THSNtProcessInfo);
procedure DisplayProcess(AProcess: THSNtProcessInfo;
const UserName: string);
end;
var
fMain: TfMain;
implementation
uses
NtDll, HsNtDef, HsWinUtils;
{$R *.DFM}
type
ZString = array[0..1024] of char;
function SIDToName (const SID: PSID): string;
var
Use : SID_NAME_USE;
DomainName : ZString;
DomainNameLength : DWORD;
Name : ZString;
NameLength : DWORD;
begin
if not LookupAccountSid(nil, SID, Name, NameLength, DomainName,
DomainNameLength, Use) then
Result := "***"
else
Result := Name;
end;
procedure TfMain.RefreshProcessList;
var
Processes : Pointer;
rc : NTSTATUS;
Dummy: ULONG;
I: Integer;
begin
FProcessList.Free;
Processes := QueryListInformation(SystemProcessesAndThreadsInformation, rc,
Dummy);
if NT_SUCCESS(rc) then begin
FProcessList := THSNtProcessInfoList.Create(Processes);
for I:=0 to Pred(FProcessList.Count) do
if FProcessList[I].Info.ProcessId <> 0 then
LookupProcessOwner(FProcessList[I]);
end;
end;
procedure TfMain.FormCreate(Sender: TObject);
begin
if not HSEnablePrivilege(SE_DEBUG_NAME) then
raise Exception.CreateFmt("Can""t set debug privilege due to %s",
[SysErrorMessage(GetLastError)]);
RefreshProcessList;
end;
procedure TfMain.LookupProcessOwner(AProcess: THSNtProcessInfo);
var
UserName: string;
AccessToken : THandle;
Info : PSIDANDATTRIBUTES;
ReturnLength : DWORD;
ProcessHandle: THandle;
begin
ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION, false,
AProcess.Info.ProcessId);
if ProcessHandle = 0 then
Exit;
try
if not OpenProcessToken(ProcessHandle, TOKEN_QUERY, AccessToken) then
Exit;
GetMem (Info, 4096);
try
Win32Check(GetTokenInformation(AccessToken, TokenUser, Info, 4096,
ReturnLength));
UserName := SidToName(Info^.Sid);
finally
FreeMem(Info);
CloseHandle(AccessToken);
end;
finally
CloseHandle(ProcessHandle);
end;
DisplayProcess(AProcess, UserName);
end;
procedure TfMain.DisplayProcess(AProcess: THSNtProcessInfo;
const UserName: string);
begin
with ListView.Items.Add do begin
Caption := AProcess.ProcessName;
SubItems.Add(UserName);
end;
end;
end.
После этого, объекты процессов, запущенных от SYSTEM я не опрашивал во избежание.
← →
Nalexey © (2004-10-06 14:56) [7]>Игорь Шевченко © (06.10.04 14:00) [6]
Спасибо, мне это очень помогло.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.11.14;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.041 c