int CALLBACK _enu_win (HWND hwnd, unsigned long lpara)
{
unsigned long pid = 0;
unsigned long i, l;
char buf [MAX_TITLE];
PTLS _tl = (PTLS) lpara;
if (!GetWindowThreadProcessId (hwnd, &pid)) {
return 1;
}
for (i = 0; i < task_n; i++) {
if (_tl .pid == pid && pid != __ppid) {
if ((l = GetWindowLong (hwnd, GWL_STYLE)) != 0) {
if ((l & WS_CAPTION) && (l & WS_VISIBLE)) {
if (SendMessage (hwnd, WM_GETTEXT, (WPARAM)MAX_TITLE -1, (LPARAM)&buf)) {
strcpy (_tl .wtitle, buf);
_tl .wh = hwnd;
}
}
}
break;
}
}
return 1;
}
Как получить ppid на WinNT*?
Код:
Т.е., callback определяет главное окно, принадлежащее данному процессу (если таковое у процесса есть) и запихивает его титл в соотв. структуру.
Но была замечена одна странность. Тулза нормально отрабатывает из командной строки, диалога "Run...", из-под отладчика, в общем, почти отовсюду. Кроме одного случая - когда она вызывается оконным фронт-эндом. В последнем случае, попрождённый процесс просто дедлочится где-то в ntdll, где-то на вызове GetWindowLong().
Я списал это явление на то, что попрождённый процесс пытается получить информацию и об окне родителя, но так как то ещё полностью не оформлено (ещё не произошёл возврат из InitInstance () и до цикла обработки сообщений дело не дошло), то выходит, что порождённый процесс не может получить сведения об окне родителя, а родитель ждёт, пока не отработает детёныш. Чтобы избежать этого явления, я сначала решил тупо отсеивать окно процесса-родителя по его pid в энумераторе и столкнулся с неожиданной фигнёй, что в винде нет такого API как getppid() в Unix.
На счёт взаимной блокировки есть, конечно, воркэраунд в лоб, но хотелось бы просто на будущее узнать, а как собственно, получить ppid? Было бы странно, если это невозможно без грязного хака. Или я чего-то недопонимаю? Процесс может не отфоркиваться, как в Unix, но его так или иначе должен кто-то порождать.
Нашёл такой кусочек кода:
Код:
ULONG GetParentPid (HANDLE hProcess)
{
PROCESS_BASIC_INFORMATION pbi = { 0 };
// Query the ProcessBasicInformation(0)
ZwQueryProcessInformation(hProcess, 0, &pbi, sizeof(pbi), 0);
return pbi.InheritedFromUniqueProcessId;
}
{
PROCESS_BASIC_INFORMATION pbi = { 0 };
// Query the ProcessBasicInformation(0)
ZwQueryProcessInformation(hProcess, 0, &pbi, sizeof(pbi), 0);
return pbi.InheritedFromUniqueProcessId;
}
Но он не вполне устраивает, т.к. использует не очень надёжную в плане совместимости Zw-рутину. А с другой стороны, он просто не работает. Вообще-то, как выяснилось, он возвращает наш pid, а не родителя.
PS: до недавнего времени я имел дело исключительно с Unix, поэтому звиняйте, если вопрос не очень умный. Хотя с WinAPI я давно знаком, но так вплотную начал пользоваться сравнительно недавно и для меня здесь оказалось много необычного :-(