Архитектура Windows
Цель работы: изучение архитектуры операционной системы Windows
Объекты и их дескрипторы
Архитектура Windows базируется на использовании множества различных объектов. Объект ядра - это структура данных, доступ к членам которой, имеет только ядро Windows. Далее приведены примеры объектов ядра:
- объект Process представляет процесс;
- объект Thread определяет поток;
- объект File представляет открытый файл;
- объект File-mapping представляет отображаемый в память файл (memory-mapped file), то есть файл, содержимое которого отображено непосредственно на виртуальное адресное пространство и используется как физическая память;
- объект Pipe используется для обмена данными между процессами;
- объект Event является объектом синхронизации потоков, сигнализирующим о завершении операции;
- объект Mutex представляет собой объект синхронизации потоков, который может использоваться несколькими процессами;
- объект Semaphore используется для того, чтобы учитывать ресурсы и сигнализировать потоку о доступности ресурса на данный момент.
Кроме объектов ядра, существуют также пользовательские объекты и объекты GDI, такие как меню, окна, шрифты, кисти и курсоры мыши.
Дескрипторы
Одной из характеристик любого объекта является дескриптор, который используется для идентификации этого объекта.
Хотя к объектам ядра нельзя получить непосредственный доступ из пользовательского режима, в Windows API есть функции, которые можно вызывать для управления этими объектами. Это своего рода инкапсуляция, защищающая объекты от непредусмотренных или неразрешенные действий. При создании объекта ядра посредством вызова соответствующей АРI функции (CreateProcess, GreateThread, CreateFile и GreateFileMapping), функция возвращает дескриптор вновь созданного объекта. Такой дескриптор может быть передан другой API-функции для того, чтобы она могла управлять данным объектом.
|
Дескриптор объекта является зависимым от процесса. Это означает, что он действует только в пределах данного процесса. Некоторые идентификаторы, такие как ID процесса, наоборот, являются идентификаторами системного уровня. Другими словами, область их действия - все процессы системы.
Подсчет используемости
Объект ядра принадлежит ядру Windows, а не процессу, создавшему этот объект (или любому другому процессу). Объекты могут использоваться совместно многими процессами и применяться разными способами. У каждого процесса, который работает с объектом, есть свой собственный, действующий в пределах данного процесса, дескриптор этого объекта.
С учетом этого ядро должно поддерживать подсчет используемости каждого объекта. Ядро уничтожает объект тогда, когда его используемость становится равной нулю, но не раньше. Таким образом, процесс, создавший данный объект, может закрыть его дескриптор (посредством вызова API-функции CloseHandle), но объект не будет уничтожен, если какой-то другой процесс продолжает его использовать (имеет его дескриптор).
У объектов ядра есть атрибуты защиты, которые можно использовать для ограничения доступа к данным объектам. Фактически это одно из основных свойств, отличающих объекты ядра от пользовательских объектов и объектов GDI..
Совместное использование объектов несколькими процессами
Существует несколько способов совместного использования объекта несколькими процессами.
|
Наследование
Когда процесс (а точнее, поток этого процесса) создает объект ядра, он может указать, что дескриптор этого объекта наследуется порожденными процессами, которые данный родительский процесс создаст впоследствии. В этой случае дескрипторы родительского и порожденного процессов одинаковы.
Дублирование дескриптора
Функция DuplicateHandle определяется следующим образом:
BOOL DuplicateHandlel (
HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, LPHANDLE IpTargetHandle, DWORD dwDesiredAccess, BOOL blnheriCHandle, DWORD dwOptions ); | // Дескриптор процесса-источника. // Копируемый дескриптор. // Дескриптор процесса-приемника. // Указатель на дескриптор - копию. // Доступ для дескриптора – копии. // Флаг наследуемости дескриптора. // Необязательные опции. |
Эта функция позволяет скопировать дескриптор объекта одного процесса в другой процесс. Новый дескриптор-копия, действующий в пределах своего процесса, может иметь значение, отличное от значения дескриптора-источника, но это не существенно, так как все дескрипторы действуют только в пределах своих процессов.
Именованные объекты
Многим объектам ядра при их создании может быть присвоено имя. Областью действия имени является вся система. Это означает, что любой другой процесс может получить доступ к объекту по его имени (если считать, конечно, что другому процессу это имя известно). Например, последний параметр функции
HAHDLE CreateFileMapping(
HANDLE hFile, // Дескриптор отображаемого файла.
LPSECUKITY_ATTRIBUTES IpFileMappingAttributes,
// Необязательные атрибуты защиты.
|
DWORD flProtect, // Защита отображаемого объекта.
DWORD dwMaxiniumSizeHigh, // Старшие 32 бита размера объекта.
DWORD dwMaximumSizeLow, // Младшие 32 бита размера объекта.
LPCTSTR IpHame // Имя объекта отображения файла.
);
может использоваться для задания имени отображения файла.
Предположим, создан объект File-mapping с именем MyFMO. Другой процесс может вызнать функцию OpenFileMapping с этим именем в качестве последнего аргумента. Функция вернет зависимый от процесса дескриптор объекта для использования во втором процессе. В виде альтернативы второй процесс может вызвать функцию GreateFileMapping, используя имя объекта в качестве ее последнего аргумента. Система определит, что объект File-mapping с таким именем уже существует и просто вернет его дескриптор. Здесь могут возникнуть проблемы, поскольку процесс считает, что он создает новый объект, тогда как в действительности он получает дескриптор существующего объекта. Программист должен сразу проверить возвращенное функцией CreateFileMapping значение, чтобы правильно сориентироваться в ситуации.