Статья
Версия для печати
Обсудить на форуме
Объекты ядра. (часть 3) совместное использование.


В продолжение разговора об объектах ядра, последней будет тема передачи и использования HANDLE (описателя) объекта в нескольких процессах. Не перепутайте с потоками, ибо внутренние потоки автоматически имеют доступ ко всем описателям внутри текущего процесса.

Передача прав пользования описателями может происходить несколькими путями.
  • Наследованием
  • Именованием
  • Дублированием

Наследование:


В этом случае при создании объекта ядра необходимо создать структуру SECURITY_ATTRIBUTES и задать параметр bInheritHandle=TRUE; После чего передать в параметр SECURITY_ATTRIBUTES функции создающей объект вышеупомянутую структуру защиты.

Однако это еще не все. Наследовать описатель может только дочерний процесс, созданный внутри текущего. При создании такового функцией CreateProcess() в параметр BOOL bInheritHandles присваивается значение TRUE, что говорит системе, скопировать описатели из таблицы родительского в таблицу дочернего процесса. Причем переписывание происходит на те же места, т.е. значение HANDLE остается неизменным.

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

Именование:


Именование поддерживается не всеми типами объектов ядра. Список поддерживающих: Mutex, Event, Semaphore, WaitableTimer, FileMapping, JobObject.

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

При создании объекта в функции, поддерживающей именование объекта, присутствует параметр PCSTR pszName, который обычно равен NULL, поэтому все объекты получаются безымянными.

Когда мы хотим использовать метод именования, мы должны дать объекту имя. Никакой гарантии нет, что объект с таким именем уже не существует и такая попытка не вызовет ошибку в системе, поэтому старайтесь давать именам префиксы чего-нибудь личного, например, GromObjMutex.

При желании обратиться к такому объекту из другого процесса, зная имя, можно создать CreateMutex() с тем же именем. В случае, если объект уже существует, система проверит права доступа и при разрешении вернет вам HANDLE, указывающий на готовый объект, либо NULL, если объект процессу недоступен. Можно вместо Create функции с таким же успехом использовать Open.

Учтите, что успешное завершение Create функции может произойти и в случае, если объект существует и доступен, и в случае, если объект не существует. В этом случае создастся новый объект ядра с указанным именем. Поэтому, если нужен гарантированный результат присоединения к существующему объекту, используйте функции Open.

Дублирование:


Я только скажу, что, просмотрев прототип требуемой функции DuplicateHandle, вы быстро поймете, как работает эта простая и вместе с тем гибкая функция.

Если будет необходимо, я отвечу на вопросы на форуме.

Уничтожение общих описателей:


Обязательно стоит обратить внимание на то, что объект будет удален из системы только тогда, когда все процессы, использующие его, вызовут функцию CloseHandle() с параметром описателем этого объекта.

Как я говорил ранее, при всех трех методах совместного использования в процессах объектов ядра счетчик пользователей в самом объекте должен быть сведен к 0.
Версия для печати
Обсудить на форуме