В прошлый раз мне было сказано, что в описании я допустил одну неточность, вернее, не совсем верно объяснил ситуацию с уничтожением объекта ядра. Вот тут
в форуме можно увидеть полное описание проблемы и ответы на нее.
Продолжая тему защиты объектов ядра, приведу описание 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 при уничтожении процесса уничтожаются и все привязанные к нему ресурсы. Опасность в многократной потере таких ресурсов, например, при многократном создании и удалении виртуальной памяти. Создание и неуничтожение потоков и т.д. В этом случае потери памяти будут накапливаться в процессе.
В следующем выпуске - совместное использование объектов ядра несколькими процессами.