Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как получить ppid на WinNT*?

30K
19 сентября 2007 года
red f0x
5 / / 14.09.2007
Проблема в следующем, некий процесс (не оконный), запущенный другим (оконным) перечисляет Top-level окна с помощью EnumWindows(), а результат потом скармливает родителю. Callback выглядит приблизительно так:
Код:
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;
}


Т.е., 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;
}


Но он не вполне устраивает, т.к. использует не очень надёжную в плане совместимости Zw-рутину. А с другой стороны, он просто не работает. Вообще-то, как выяснилось, он возвращает наш pid, а не родителя.

PS: до недавнего времени я имел дело исключительно с Unix, поэтому звиняйте, если вопрос не очень умный. Хотя с WinAPI я давно знаком, но так вплотную начал пользоваться сравнительно недавно и для меня здесь оказалось много необычного :-(
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог