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


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

Защита объектов ядра.


Продолжая тему защиты объектов ядра, приведу описание SECURITY_ATTRIBUTES.
Код:
typedef  struct _SECURITY_ATTRIBUTES {
DWORD nLength;
LPVOID lpSecurityDescriptor;
BOOL bInheritTable;
} SECURITY_ATTRIBUTES;

Конкретно в этой структуре за защиту отвечает lpSecurityDescriptor. bInheritTable не относится к защите самого объекта, а nLength содержит длину sizeof(SECURITY_ATTRIBUTES), которую необходимо записать в элемент при инициализации.

Я сам редко использовал дополнительные свойства защиты объекта ядра. Обычно всегда хватает защиты по умолчанию, выставляемой системой при передаче NULL в этот параметр.

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

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

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

Все это справедливо в WinNT/2000/XP. Говоря о линейке 9х, это все получается ерундой, так как есть вполне легальный доступ к любым ресурсам в обход запретов ОС.

Упомяну о том, что для отличия объекта ядра от других объектов, создаваемых функциями Create(), обратите внимание на наличие параметра защиты в вызове функции. В создании объектов ядра этот параметр всегда присутствует.

Таблица описателей ядра.


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

Создание и уничтожение объектов ядра.


Для создания объекта ядра разных типов используются функции типа Create();

Возвращаемое значение имеет тип HANDLE.

Типовая процедура создания выглядит так:
Код:
HANDLE hObj = Create()

If (hObj == INVALID_HANDLE_VALUE)
{
  //ошибка
}

// действия

Уничтожение объекта
Код:
CloseHandle(hObj);

// Либо

HANDLE hObj = Create()

If (hObj ==NULL)
{
  //ошибка
}

Подробности смотрите в описании самой функции создания объекта конкретного типа.

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

Закрытие объекта ядра достаточно условно. Такая функция, как я уже говорил, уменьшает счетчик пользователей у такого объекта, после чего уничтожает сам объект уже система, в случае, если пользователей объекта больше не осталось. Сама функция удаляет из таблицы описателей, принадлежащей вашему процессу, соответствующую запись, описатель становится недействительным для текущего процесса.

Если вы забыли вызвать функцию CloseHandle или в результате ее вызова произошла ошибка, тогда происходит потеря объекта и потеря памяти (memory leak). Однако в Windows при уничтожении процесса уничтожаются и все привязанные к нему ресурсы. Опасность в многократной потере таких ресурсов, например, при многократном создании и удалении виртуальной памяти. Создание и неуничтожение потоков и т.д. В этом случае потери памяти будут накапливаться в процессе.

В следующем выпуске - совместное использование объектов ядра несколькими процессами.
Версия для печати
Обсудить на форуме