Форум программистов, компьютерный форум CyberForum.ru

Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему? - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.89
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
16.07.2011, 20:56     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему? #1
Друзья! Вот код A.exe, суть которого просто стать родительским для B.exe и висеть в системе.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <windows.h>
 
int main() {
 STARTUPINFO si;
 PROCESS_INFORMATION pi;
 ZeroMemory(&si,sizeof(STARTUPINFO) );
 
 if (CreateProcess ("B.exe", 0, 0, 0, 0, 0, 0, 0, &si, &pi)) { 
  CloseHandle( pi.hProcess );
  CloseHandle( pi.hThread );
 }
 
 
 else {
  printf ("protsess ne sozdan\n");
 }
 
 while (1);
 
// system ("pause");
 return 0;
}

Так, а вот код B.exe,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h> 
#include <Windows.h> 
#include <Winnt.h> 
#include <tlhelp32.h>
 
int main () {
  SetConsoleCP(1251);
  SetConsoleOutputCP(1251);
  
  //Это будет ID текущего процеса
  DWORD handle_B= (DWORD)GetCurrentProcessId();  
  
  //Это находим дескриптор снимка процессов
  HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
  if (hProcessSnap == INVALID_HANDLE_VALUE)
   return false;
  PROCESSENTRY32 pe32;
  pe32.dwSize = sizeof(PROCESSENTRY32);
 
  //и пошли циклом пробегаться по этим процессам, остановимся на двух, на текущем и родительском
  //Выводимые данные, напомню, берутся из структуры pe32
  while (Process32Next(hProcessSnap, &pe32)) {
   
   //Ага, здесь мы споткнулись о текущий процесс 
   if (handle_B== pe32.th32ProcessID) {
    printf ("тут должно быть имя B.exe  %s  \n", pe32.szExeFile);
    printf ("Так, а тут ID родительского процесса, то есть ID процесса A.exe=   %x  \n", pe32.th32ParentProcessID);
    getchar ();
    HANDLE handle= OpenProcess (PROCESS_TERMINATE, true, pe32.th32ParentProcessID);
   
    //И вывели хэндл его родительского процесса, который A.exe
    printf ("А тут собственно хэндл процесса A.exe!   %x\n", handle);
    getchar ();   
   }
 
   //Так, а здесь мы споткнулись о родительский процесс
   if (!strcmp ("A.exe", pe32.szExeFile)) {
    printf ("ЗДесь должно быть имя процесса A.exe   %s  \n", pe32.szExeFile);
    printf ("Зесь его ID  %x  \n", pe32.th32ProcessID);
    getchar ();
    HANDLE handle= OpenProcess (PROCESS_TERMINATE, true, pe32.th32ProcessID);
    
    //И опять выводим его хэендл. Так вот, в выводе хэндлы A.exe разнятся!
    printf ("А тут его хэндл, комментарии излишни!   %x\n", handle);
    getchar ();   
   }
  }  
 
 
  CloseHandle(hProcessSnap);
  getchar ();
  return 0;
 }


его роль: перебрать все процессы оси.

Найти себя-> найти хэндл родительского процесса и вывести его
и
Найти хэндл процесса A.exe-> вывести его

Эти два пунта могут меняться местами в зависимости от того, какой процесс будет найден первым.
Но я надеюсь никто не сомневается в том, что выводимые хэндлы должны быть одинаковы в обоих случаях? А зря.
Смотрим вывод.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.07.2011, 20:56     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему?
Посмотрите здесь:

C++ как программно создать процесс, который создаёт окно консоли?
Почему процесс прерывается? C++
Загрузить процесс из другого процесса C++
C++ Процесс А инициализирует массив случайными значениями и записывает их в файл, а затем запускает процесс Б
C++ Inject процесса в процесс win7
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
16.07.2011, 21:03  [ТС]     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему? #2
Вот вывод
Миниатюры
Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему?  
soft.creator
 Аватар для soft.creator
103 / 103 / 4
Регистрация: 17.10.2010
Сообщений: 283
16.07.2011, 22:20     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему? #3
Так хэндл и не обязан быть одинаковым.
Каждый процесс имеет свою собственную таблицу хэндлов, и какой хэндл будет ссылаться на тот или иной объект, решает уже система.
А вот ID какого-либо процесса является величиной постоянной, какой бы другой процесс его не запрашивал, именно поэтому для получения хэндла чужого процесса используют ID

P.S. Грубо говоря, хэндл - это указатель на некий объект в глубине системы. А указатель работает в адресном пространстве только своего процесса. Для другого процесса указатель на ту же область памяти может иметь совсем другое значение, благодаря механизму трансляции адресов. Так что все штатно.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
17.07.2011, 01:21  [ТС]     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему? #4
Нет, нештатно. Я говорю:
вот процесс B получает хэндл процесса A, этот хэндл равен x
И
опять вот процесс B получает хэндл процесса A, этот хэндл равен y

Он получает одну и ту же величину, только по-разному. Один и тот же указатель ё. И этот указатель непостоянен.
Bers
Заблокирован
17.07.2011, 02:54     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему? #5
Цитата Сообщение от kravam Посмотреть сообщение
Нет, нештатно. Я говорю:
вот процесс B получает хэндл процесса A, этот хэндл равен x
И
опять вот процесс B получает хэндл процесса A, этот хэндл равен y

Он получает одну и ту же величину, только по-разному. Один и тот же указатель ё. И этот указатель непостоянен.
Понимаешь в чем тонкость.... ваш хэндл на самом деле ни что иное, как:

typedef void *HANDLE; //всего лишь всевдоним обычного указателя на войд

Почему два разных процесса указывают казалось бы на одно и тоже место в памяти, но при этом адреса разные?

Начните читать с 22# сообщения по этой ссылке.
Указатели
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
17.07.2011, 10:10  [ТС]     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему? #6
Я прочту, конечно, но... Мне кажется, я представляю себе, что такое хэндл.
В процессе есть таблица хэндлов, а у Рихтера она называется таблица описаталей.
И там есть разные всякие хэндлы. И очередной хэндл это
"индекс в таблице описателей, принадлежащей процессу"
И это индексы разны. Вот что странно.
soft.creator
 Аватар для soft.creator
103 / 103 / 4
Регистрация: 17.10.2010
Сообщений: 283
17.07.2011, 10:55     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему? #7
Сорри, не очень внимательно глянул исходник. Но все равно все штатно.

Один и тот же объект может быть открыт под разными хэндлами даже в одном процессе.
Насколько я понимаю внутреннее устройство Windows, обращение к объекту идет следующим образом:

хэндл -> объект-описатель -> собственно объект в памяти ядра

Так вот, объект в памяти ядра у нас один-единственный, и ему соответствует уникальный ID. А вот объектов-описателей может быть много. Причин для этого вижу две, и обе связаны с обязанностями объекта-описателя:
- у разных описателей могут быть разные права доступа к объекту ядра, хотя бы поэтому их может быть несколько
- при разрушении описателя, система подсчитывает количество оставшихся описателей, и грохает объект ядра (к процессу, правда, это не относится, т.к. на него, скорее всего, есть еще как минимум одна ссылка внутри самого ядра до окончания работы)

P.S. Насколько я помню, DuplicateHandle выдает другой хэндл даже при полном совпадении прав доступа. Скорее всего, OpenProcess реализует похожую стратегию.
P.P.S. В своих знаниях по глубинному устройству Windows я не совсем уверен, так что если есть спецы, поправьте меня
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
17.07.2011, 11:25  [ТС]     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему? #8
soft.creator, мне это как-то поможет?
Я вызываю хэндл двумя способами (хотя язык не поворачивается называть 2 вызова одной и той же функции с одними и теми же параметрами как 2 способа). Но по крайне ймере в исходнике они разделены.

Так вот, второй способ- истиный. Я это определил так:
C++
1
2
3
4
5
6
7
8
9
   if (!strcmp ("A.exe", pe32.szExeFile)) {
    printf ("Çåñü ГҐГЈГ® ID  %x  \n", pe32.th32ProcessID);
    getchar ();
    HANDLE handle= OpenProcess (PROCESS_TERMINATE, true, pe32.th32ProcessID);
    
    //ЕСли этот способ истиный, то хэндл правильный и родительский процесс закроется.
    TerminateProcess (handle, 0);
    getchar ();   
   }
И родительский процесс закрывается. Так, а если я использую другой хэндл, то не закрывается.
А у меня стоит задача, чтобы закрыть родительский процесс не исходя из его имени, которое дочерний просто не знает- то есть дочерний процесс должен закрыть родительский, а исходя из его ID (первый способ)
А он не работает
.............................................................
В ссыли добил пост номер 45

Добавлено через 9 минут
Цитата Сообщение от soft.creator Посмотреть сообщение
Скорее всего, OpenProcess реализует похожую стратегию.
Так-то мне всё равно. Если можешь выдать нормальный хэндл, выдай, пусть он хоть от вызова к вызову меняется. Не можешь выдать- выдай ноль. Но выдывать ненулевой неправильный хэндл, при чём какой какой красивый:28 не (12345678 и не 877654321) это у меня слов нет.
soft.creator
 Аватар для soft.creator
103 / 103 / 4
Регистрация: 17.10.2010
Сообщений: 283
17.07.2011, 11:53     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему? #9
Очень странно, что TerminateProcess на первом хэндле не сработал.
А что GetLastError говорит?
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
17.07.2011, 12:23  [ТС]     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему? #10
Я не умею ей пользоваться, в MSND примеров нет. Вот так на свой страх и риск написал:
C++
1
2
3
4
    HANDLE handle= OpenProcess (PROCESS_TERMINATE, true, pe32.th32ParentProcessID);
    //HANDLE handle= OpenProcess (PROCESS_TERMINATE, true, pe32.szExeFile);
    DWORD mistake= GetLastError ();
    printf ("mistake= %d\n", mistake);
Выводит 2

Добавлено через 8 минут
А в MSND прочёл
The system cannot find the file specified.


Это что система не может найти, какой-то файл? Что-то не то.
soft.creator
 Аватар для soft.creator
103 / 103 / 4
Регистрация: 17.10.2010
Сообщений: 283
17.07.2011, 12:31     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему? #11
Ошибка 2 - объект не найден. Странная ошибка в этом контексте.
Попробуйте вот что:
C
1
2
3
4
5
6
7
8
9
10
11
    HANDLE handle;
    while (Process32Next(...)) {
        if (...) {
            handle = OpenProcess(..., pe32.th32ParentProcessID);
            break;
        }
    }
    printf("Handle = %x, error before = %d\n", handle, GetLastError());
    SetLastError(0);
    TerminateProcess(handle, 0);
    printf("Error after = %d\n", GetLastError());
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
17.07.2011, 13:24  [ТС]     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему? #12
Всё получилось, а вот Ваш код я подогнал под свой, то есть просто не прерываю цикл принудительно. И тоже родительский процесс благополучно уничтожается.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  while (Process32Next(hProcessSnap, &pe32)) {
   //Ага, здесь мы споткнулись о текущий процесс 
   printf ("\nЗдесь ID найденного процесса  %x  \n", pe32.th32ProcessID);
   printf ("ID Текущего процесса  %x  \n", handle_B);
   getchar ();
   if (handle_B== pe32.th32ProcessID) {
    handle= OpenProcess (PROCESS_TERMINATE, true, pe32.th32ParentProcessID);
 
    printf("Handle = %x, error before = %d\n", handle, GetLastError());
    SetLastError(0);
    TerminateProcess(handle, 0);
    printf("Error after = %d\n", GetLastError());    
    
    //Тут  можно поставить break;    
 
   }
  }
...Так это что мы делаем? Просто напросто принудительно скидываем ошибку (мы ведь не смогли найти ей по факту вот и решили скинуть в ноль, так?) И дальше код нормально работает.

Вопрос остался: почему всё-таки возвращалась ошибка 2?
soft.creator
 Аватар для soft.creator
103 / 103 / 4
Регистрация: 17.10.2010
Сообщений: 283
17.07.2011, 14:37     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему? #13
Я скидывал принудительно ошибку, которую повесит Process32Next, когда больше не осталось процессов, чтобы получить именно ошибку от TerminateProcess. Странно, что у Вас эта ошибка появилась раньше.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.07.2011, 17:43     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему?
Еще ссылки по теме:

C++ Передать параметр в дочерний процесс через execl()
Передача аргументов из родительского в дочерний процесс C++
C++ Родительский и дочерний процесс

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
17.07.2011, 17:43  [ТС]     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему? #14
Будем считать вопрос условно-решённым, спасибо большое.
Yandex
Объявления
17.07.2011, 17:43     Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему?
Ответ Создать тему
Опции темы

Текущее время: 13:25. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru