Управление ресурсами в ОС Windows

advertisement
Управление ресурсами в ОС Windows
Содержание
Создание Windows – приложения
Объекты ядра
Процессы
Память и Windows
Виртуальная память
Проецируемые в память файлы
Динамически распределяемая память
Динамически подключаемые библиотеки
Литература
Создание Windows – приложения
Оконные приложения. Обработка сообщения в ОС Windows
В отличие от традиционного процедурного, программирование для
Windows является объектно-ориентированным. Система
Windows
представляет собой
набор объектов, с которыми приходится
сталкиваться и при работе и при программировании. Самым важным
объектом является окно. Общение с объектом-окном возможно при
помощи сообщений. Механизм сообщений в Windows реализуется при
помощи очереди сообщений, поддерживаемой системой. Каждое
сообщение попадает в такую очередь, где и ожидает последующей
обработки. Механизм сообщений является единственным способом
связи приложений со своими окнами. Таким образом, сообщения - это
вход в приложение. Они представляют собой события, на которые,
при необходимости должно реагировать приложение.
Очереди сообщений
Каждое сообщение связано с конкретным окном, с каждым из которых,
связана собственная оконная процедура (процедура обработки
сообщений). Все сообщения, источником которых служат аппаратные
средства, система помещает в первичную входную очередь. В 32разрядных операционных системах Windows 95 и Windows NT реализован
метод поддержки отдельных очередей сообщений. При этом сообщение
попадает в первичную входную очередь, после чего перенаправляются
в частную очередь конкретного потока 32-разрядного приложения. В
самом начале работы приложения имеет единственную очередь
сообщений, которая относится к первичному потоку, если процесс
заводит новый поток, которому очередь сообщений не нужна, то система
не создает новую очередь сообщений. Сообщения, находящиеся в
очереди, обрабатываются процедурой обработки сообщений, которая
связана с каждым окном.
Типы сообщений
В настоящее время в системе Windows имеется более 900 стандартных
сообщений. По причине большого количества сообщений их можно
разделить на 8 категорий:
 Аппаратные сообщения,
 Сообщения об организации окна,
 Сообщение об организации интерфейса пользователя,
 Сообщения о завершении работы,
 Частные сообщения,
 Уведомления о системных ресурсах,
 Обмен данными,
 Внутрисистемные сообщения.
Аппаратные сообщения
Оконная процедура получает сообщения, инициируемые тремя частями
аппаратного обеспечения: клавиатурой, мышью и системным таймером.
Каждое сообщение обрабатывается в порядке их поступления, что
достигается буферизацией сообщений, которое берет на себя
операционная система.
При быстром перемещении мыши может произойти большое
количество прерываний. Чтобы избежать переполнения очереди, система
Windows хранит только одно сообщение о перемещении мыши в каждый
момент времени. Когда приходит новое сообщение, система проверяет,
есть ли уже подобное, если оно есть, то в нем обновляется информация
о положении. Новое сообщение помещается в очередь сообщений только
в случае отсутствия подобного сообщения.
Сообщения от таймера
Сообщения от таймера помещаются в очередь сообщений аналогично
всем другим аппаратным сообщениям, поэтому таймеры не являются
точными в системе Windows. Также стоит отметить, что таймер в
Windows имеет разрешающую способность 54.925 миллисекунды, что и
встроенный таймер PC, что приводит к двум ограничениям при
работе с таймером:
 сообщения от таймера не могут посылаться чаще, чем 18.2 раза в
секунду
 временной интервал округляется до ближайшего меньшего целого
числа, кратного частоте срабатывания таймера. Например, интервал
в 1000 миллисекунд, разделенный на 54.925 миллисекунды,
равен 18.207 срабатываний, которые округляются до 18, что
приводит к интервалу 989 миллисекунд
Сообщения об обслуживании окна
Данные сообщения уведомляют оконную процедуру об изменении
состояния окна, причем данные сообщения не обязывают совершать
какие- либо действия, а говорят лишь о них, как о свершившемся факте
(сообщение о перемещении окна). Из данной категории сообщений
следует выделить сообщение перерисовки окна (WM_PAINT),
являющимся одним из самых важных сообщений для организации
графического вывода.
Windows посылает сообщение WM_PAINT окну только тогда, когда
очередь сообщения пуста и есть что перерисовывать, то есть в окне
портятся какие-либо данные другими окнами. Это достаточно
правильно, так как изменения отображаются блоками, сокращая время на
вывод.
Сообщения об организации интерфейса пользователи
Эта группа содержит сообщения для объектов пользовательского
интерфейса (кнопки, меню, …). А также сообщения, используемые для
поддержки многодокументного интерфейса.
Сообщения о завершении работы
Сообщения используются для управления завершением приложений.
Например, при закрытии приложения можно спросить о сохранении
данных.
Частные сообщения
Помимо стандартных сообщений можно определять и собственные.
Существует сообщение WMUSER, начиная с которого можно
определять собственные сообщения, например:
#define PM_CALL_CLIENT WM_USER+1
// создание частного сообщения
Информационные сообщения системных ресурсов
Посылаются окну верхнего уровня каждой программы при
изменении некоторых системных ресурсов, типичной реакцией на
такие изменения является сохранение проведенных вычислений.
Сообщение с уведомлением об изменениях системных ресурсов
В Windows есть сообщения, которые посылаются при совместном
использовании данных при поддержки механизмов работы с буфером
обмена и динамического обмена данными.
Внутрисистемные сообщения
Данные сообщения используются только для собственных целей
операционной системы.
Создание окна приложения
Создание окна приложения состоит из следующих этапов:
 Регистрация класса окна приложения,
 Создание главного окна приложения,
 Цикл обработки сообщений.
Регистрация класса окна
Любое окно Windows принадлежит одному из существующих в
данный момент в системе классов, который должен быть определен
до отображения окна на экране. Класс окна – это шаблон, в котором
определяются выбранные стили, шрифты, заголовки, пиктограммы,
размер. При этом следует учитывать, что имя класса окна доступно
всем в системе и как следствие имя должно быть уникальным, для не
возникновения конфликтов с классами окон других приложений.
Простейшая программа для Windows
#include<windows.h>
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
return TRUE;
}
// дескриптор текущего приложения
// дескриптор предыдущего приложения
// указатель на командную строку
// режим отображения окна
Раньше параметр hPrevInstance позволял определить наличие уже
запущенных копий программы. Сейчас каждое 32-разрядное
приложение запускается в собственном адресном пространстве, где
других приложений просто нет. Поэтому параметр hPrevInstance всегда
равен NULL и оставлен для совместимости.
Пример регистрации класса окна
WNDCLASS wc;
...
// окно перерисовывается после изменения размеров окна стиль
wc.style
= CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc
= (WNDPROC) WndProc; // адрес функции обработчика сообщений
wc.cbClsExtra = 0; // количество байт присоединенных к классу для данной структуры
wc.cbWndExtra = 0; // количество байт присоединенных к классу для всех структуры
wc.hInstance = hInstance; // дескриптор приложения, создающего окно
wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION); // пиктограмма окна
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // загрузка формы курсора для данного
класса окна
wc.hbrBackground = (HBRUSH)(COLOR_WHITE); // фон окна
wc.lpszMenuName = NULL; // меню у нас нет
wc.lpszClassName = ClassName; // имя класса
RegisterClass(&wc); // регистрируем класс окна
Создание главного окна приложения
HWND hWnd;
hWnd = CreateWindow(
ClassName, // имя класса окна
Title, // заголовок окна
WS_OVERLAPPEDWINDOW, // стиль окна
CW_USEDEFAULT, // горизонтальная координата окна
CW_USEDEFAULT, // вертикальная координата окна
CW_USEDEFAULT, // ширина окна
CW_USEDEFAULT, // высота окна
NULL, // дескриптор родительского окна
NULL, // дескриптор меню окна
hInstance, // дескриптор экземпляра приложения
NULL); // указатель на дополнительные окна
// отображаем окно с видом отображения, указанном во втором параметре
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// посылаем окну сообщение WM_PAINT для перерисовки
Цикл обработки сообщений
Стандартный
цикл
обработки
сообщений
представляет
собой
следующий порядок действий:
 получение сообщения,
 преобразование виртуальных кодов клавиш в ASCII-значения,
 посылка сообщения в нужную оконную процедуру.
// принимаем все сообщения, за что отвечает второй параметр
while(GetMessage(&msg, NULL, 0, 0))
{
// перевод кодов клавиш
TranslateMessage(&msg);
// посылает сообщение в конкретное оконную процедуру
DispatchMessage(&msg);
}
Обработка сообщений
Прототип функции обработки сообщений:
LRESULT CALLBACK WindowProc(
HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
// дескриптор окна, получившего сообщения
// сообщение
// дополнительный параметр
// второй дополнительный параметр
Базовый вид оконной процедуры с обязательными параметрами:
LRESUT CALLBACK WindowProc(
HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch(message)
{
// разрушаем очередь сообщений
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
// доверяем остальные сообщения системе
return DefWindowProc(hWnd,message,wParam,lParam);
}
return 0;
}
Графический вывод
Система Windows предоставляет приложению следующий набор
графических устройств, которые используются для организации
вывода:
1. Битовые
образы
–
прямоугольные
массивы
точек,
формирующие растровые изображения
2. Карандаши – используется для параметров рисования линий
3. Кисти – используется для параметров заливки замкнутых
контуров
4. Шрифты – используются для задания параметров вывода текста
5. Регионы – область окна, которая может иметь в общем случае
любую форму
6. Логические палитры – обеспечивает связь между приложением
и устройством вывода, содержат список цветов необходимых
приложению
7. Контуры – используются для заполнения или выделения
контура фигур
Одна из главных особенностей Windows – независимость устройств.
То есть для вывода на конкретное устройство приложение использует
драйвер устройства, причем на логическом уровне приложение
работает с контекстом устройства, в котором хранятся все параметры
вывода.
Контекст устройства – структура, определяющая набор
графических объектов и связанных с ними атрибутов и графических
режимов, которые воздействуют на вывод.
В Windows определены четыре типа контекстов устройств:
1. Экран,
2. Принтер,
3. Объект в памяти,
4. Информационный.
Обработка сообщения WM_PAINT
При получении сообщения WM_PAINT нам необходимо сообщить
системе о начале рисования, это достигается использованием
функции BeginPaint(), после чего делаются необходимые операции
рисования, а затем сообщается системе об окончании рисования,
путем использования функции EndPaint().
Проблема синхронного вывода
При немедленном рисовании (синхронный вывод, например чтение
файла с последующим выводом на экран) используются функции
GetDC() – для начала рисования, ReleaseDC() – для окончания
рисования.
Доступ к графическим объектам
Для рисования какого-либо графического объекта сначала
необходимо настроить соответствующим образом параметры
контекста устройства, которые он получает по умолчанию, а затем
восстановить исходные. На примере использования кисти (или
любого другого объекта) следует выполнить следующие действия:
1. Создание кисти как объекта,
2. Сохранение предыдущей кисти,
3. Установка новой кисти,
4. Операции рисования с использованием кисти,
5. Восстановление кисти.
Пример рисования карандашом при обработке сообщения
WM_PAINT
HDC hDC;
PAINTSTRUCT ps;
HPEN newPen, oldPen;
hDC=BeginPaint(hWnd, &ps);
newPen = CreatePen(
PS_SOLID,
5,
RGB(255,0,0));
oldPen=(HPEN)SelectObject(hDC, newPen);
// сплошная линия
// толщина карандаша
// красный цвет карандаша
// сохранение предыдущего карандаша
// рисуем прямоугольник с координатами верхнего левого угла (0,0) и нижнего
// правого угла (100,100)
Rectangle(hDC,0,0,100,100);
SelectObject(hDC, oldPen); // восстанавливаем карандаш
EndPaint(hWnd, &ps);
Работа с битовыми массивами в памяти
Назначение битовых карт – формирование графического изображения
в памяти и дальнейшее его отображение на экране. Работа с
подготовкой битовых карт состоит из следующих этапов:
1. Создание контекста устройства, совместимого с устройством
вывода,
2. Создание битового отображения устройства вывода,
3. Рисование, отображаемое в битовое представление,
4. Освобождение совместимого устройства.
Работа с битовым представлением осуществляется следующим
образом:
1. Создание контекста устройства, совместимого с устройством
вывода,
2. Выбор в качестве графического устройства битового образа,
3. Копирование с определённой маской битового образа в контекст
основного устройства.
Пример рисования осей координат
...
// сообщение «изменение размера» формируется при создании окна
case WM_SIZE:
// получаем контекст устройства
hDC = GetDC (hWndMain);
// создание совместимого контекста
hdcMem = CreateCompatibleDC (hDC);
// создали образ осей
hBitmapAxis = CreateCompatibleBitmap (hDC, iClientWidth, iClientHeight);
// освободили контекст устройства
ReleaseDC (hWndMain, hDC);
// выбрали объект образа
SelectObject (hdcMem, hBitmapAxis);
// нарисовали оси координат
DrawAxis(hdcMem);
// удалили контекст образа
DeleteDC(hdcMem);
break;
…
…
case WM_PAINT:
// начинаем рисовать
hDC = BeginPaint(hWnd, &ps);
// создание совместимого контекста
hdcMem = CreateCompatibleDC (hDC);
// выбираем объект образа
SelectObject (hdcMem, hBitmapAxis);
// копирование битового образа на контекст
BitBlt (hDC, 0, 0, iClientWidth, iClientHeight, hdcMem, 0, 0, SRCCOPY);
// заканчиваем рисование
EndPaint(hWnd, &ps);
// удаляем память контекста
DeleteDC(hdcMem);
break;
...
Отображение пользовательских элементов управления
...
HWND hwndButtonOpen;
hwndButtonOpen = CreateWindow(
"BUTTON",
// имя класса кнопки (уже определённый класс!)
"Open",
// заголовок
WS_VISIBLE|
// стили:
видимого окна
WS_CHILD|
//
дочернее окно
BS_DEFPUSHBUTTON, //
стиль кнопки
iWidth-120,
// положение
30,
100,
// размеры
50,
hWndMain,
// родительское окно
NULL,
// меню окна
// приложение владельца
(HINSTANCE)GetWindowLong(hWndMain, GWL_HINSTANCE),
NULL);
// дополнительные окна
...
case WM_COMMAND:
// поступление команды от кнопок
// нажатие кнопки
if((HWND)lParam==hwndButtonOpen && HIWORD(wParam)==BN_CLICKED )
{ /* Обработка сообщения */ }
Управление окнами
Функции управления окнами при известном дескрипторе окна
приложения:
1. CloseWindow() – закрытие окна приложения,
2. EnableWindow() – управление доступом окном,
3. MoveWindow() – перемещение окна,
4. SetWindowPos() – установка окна в нужную позицию,
5. SetWindowText() – установка нового, связанного с окном текста,
…
Функции управления окнами при неизвестном дескрипторе окна
приложения:
1. FindWindow() – дескриптор окна при известном имени класса окна
приложения и его заголовка,
2. GetNextWindow()
–
дескриптор
следующего
в
zпоследовательности окна приложения,
3. GetWindowText() – определение заголовка окна,
…
Посылка сообщений
Синхронная передача сообщения
Функция SendMessage() – посылает сообщение окну или множеству
окон и не возвращает управление, пока это сообщение
обрабатывается.
Асинхронная передача сообщения
Функция PostMessage() – посылает сообщение окну или множеству
окон и возвращает управление сразу, не ожидая обработки
сообщения.
Работа с таймером
#define
ID_HEAD_TIMER 1
#define TICK_TIME 500
// номер таймера
// период срабатывания таймера миллисекунды
...
case WM_CREATE:
// создание таймера
SetTimer(hWndMain, ID_HEAD_TIMER, TICK_TIME, (TIMEPROC) NULL);
break;
...
case WM_TIMER:
...
// обработка срабатывания таймера
case WM_CLOSE:
// удаление таймера
KillTimer(hWndMain, ID_HEAD_TIMER);
break;
...
Работа со стандартными блоками диалога
...
OPENFILENAME ofn;
// структура открытия файла
char szFile[260];
// имя файла
FILE *Fout;
// поток файла
// Инициализация структуры
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize
= sizeof(OPENFILENAME);
ofn.hwndOwner
= hWndMain;
// владелец диалога
ofn.lpstrFile
= szFile;
// имя файла
ofn.nMaxFile
= sizeof(szFile);
// максимальное число букв
ofn.lpstrFilter
= "Файлы решения\0*.dat\0";
// фильтры
ofn.nFilterIndex
= 1;
// индекс фильтра
ofn.lpstrFileTitle
= NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir
= NULL;
ofn.Flags
= OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
strcpy(ofn.lpstrFile,"");
if (GetOpenFileName(&ofn) == TRUE) // Отображение диалогового окна
FOut = fopen(ofn.lpstrFile,"r");
else
FOut = NULL;
...
Объекты ядра.
Что такое объект ядра?
 Объект ядра – блок памяти, выделенный ядром и доступный
только ему. Этот блок представляет собой структуру данных, в
элементах которой содержится информация об объекте.
Некоторые элементы (дескриптор защиты, счётчик числа
пользователей) присутствуют во всех объектах, но большая
часть их специфична для объектов конкретного типа. Структуры
объектов ядра доступны только ядру и ни одно приложение не
может самостоятельно найти эти структуры в памяти и
напрямую модифицировать их содержимое. В Windows
предусмотрен набор функций, обрабатывающих структуры
объектов ядра по определённым правилам.
 Объекты ядра принадлежат ядру, а не процессу. Пример: если
Ваш процесс вызывает функцию, создающую объект ядра, а
затем завершается, объект ядра может быть и не разрушен,
например, если он используется ещё и другим процессом.
 Ядру известно, сколько процессов используют конкретный
объект ядра, поскольку в каждом объекте есть счётчик его
пользователей. Счётчик один из элементов ядра, присущий всем
процессам. В момент создания ему присваивается 1. Когда к
объекту обращается другой процесс, его счётчик увеличивается.
А когда какой-то процесс завершается, счётчики всех
используемых им объектов уменьшаются. Как только счётчик
стал равен 0, объект уничтожается.





Примеры объектов ядра
Мьютексы
–
объекты
синхронизации,
позволяющие
координировать взаимное исключение доступа к разделяемому
ресурсу,
Семафоры
–
объекты
синхронизации,
позволяющие
ограничивать количество потоков, которые одновременно
обращаются за набором разделяемых ресурсов,
Процессы,
Потоки,
Каналы.
Таблица описателей ядра
При инициализации процесса система создаёт в нём таблицу
описателей, используемую только для объектов ядра. Сведенья о
структуре таблицы и управлению ею не документированы.
Создание объекта ядра
Когда процесс инициализируется в первый раз, таблица описателей ещё
пуста. Но стоит одному из его потоков вызвать функцию, создающую
объект ядра (например, создание нового потока), как ядро выделяет для
этого объекта блок памяти и инициализирует его; далее ядро
просматривает для этого объекта таблицу описателей этого процесса и
отыскивает свободную запись. Все функции, создающие объекты ядра,
возвращают описатели, которые привязаны к конкретному процессу и
могут быть использованы в любом потоке данного процесса.
HANDLE CreateThread(
PSECURITY_ATTRIBUTES psa,
DWORD dwStackSize,
PTHREAD_START_ROUTINE pfnStartAddr,
PVOID pvParam,
DWORD dwCreationFlags,
PDWORD pdwThreadId);
// указатель на атрибуты защиты
// размер стека
// указатель на функцию потока
// указатель на параметры
// флаг
// номер потока
Закрытие объекта ядра
Независимо от того, как именно Вы создали объект ядра, по окончании
работы с ним его нужно закрыть вызовом CloseHandle:
BOOL CloseHandle(HANDLE hobj);
Эта функция проверяет таблицу описателей соответствующего процесса,
идентифицируя этот объект, получает адрес структуры данных объекта и
уменьшает счётчик на 1. Перед возвратом управления функция удаляет
соответствующую запись из таблицы описателей: описатель становится
не действительным и его использовать нельзя.
Совместное использование объектов ядра
между несколькими процессами
Время от времени возникает необходимость в разделении объектов
ядра между потоками, исполняемыми в разных процессах. Причин
тому может быть несколько:
 объекты "проекции файлов" позволяют двум процессам,
исполняемым на одной машине, совместно использовать одни и
те же блоки данных,
 почтовые ящики и именованные каналы дают возможность
программам обмениваться данными с процессами, исполняемыми
на других машинах в сети,
 мьютексы, семафоры и события позволяют синхронизировать
потоки, исполняемые в разных процессах, чтобы одно
приложение могло уведомить другое об окончании той или иной
операции.
Описатели объектов ядра имеют смысл только в конкретном процессе.
Главная причина сделать описатели процессно-зависимыми –
устойчивость операционной системы к сбоям. Если бы описатели
объектов ядра были общесистемными, то один процесс мог бы
запросто получить описатель объекта, используемого другим
процессом, и устроить в нем настоящий хаос. Другая причина —
защита. Объекты ядра защищены, и процесс, прежде чем оперировать с
ними, должен запрашивать разрешение на доступ к ним. В MS
Windows существует три механизма совместного использования
одного объекта ядра:
1. Наследование описателя объекта,
2. Именованные объекты,
3. Дублирование описателей объектов.
Наследование описателя объекта
Наследование применимо, когда процессы связаны родственными
связями. Если процессу в момент порождения потомка доступен один
или несколько описателей, то он решает, передать по наследству
дочернему процессу доступ к своим описателям или нет. Чтобы
механизм наследования действовал, нужно создать объект ядра с
наследуемым описателем.
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
// защита по умолчанию
sa.bInheritHandle = TRUE;
// описатель будет наследуемым
HANDLE hMutex = CreateMutex(&sa, FALSE, NULL);
// создали мьютекс
Следующий этап – порождение родительским процессом дочернего.
BOOL CreateProcess(
PCTSTR pszApplicationName,
// имя исполняемого файла
PTSTR pszCommandLine,
// командная строка
PSECURITY_ATTRIBUTES psaProcess,
// атрибуты защиты для объектов
PSECURITY_ATTRIBUTES psaThread,
// ядра «процесс» и «поток»
BOOL bInheritHandles,
// наследование описателей объекта
DWORD fdwCreate,
// способ создания процесса
PVOID pvEnvironment,
// переменные окружения
PCTSTR pszCurDir,
// текущая директория процесса
PSTARTUPINFO psiStartInfo,
// структура информации о запуске
PPROCESS_INFORMATION ppiProcInfo); // структура информации о приложении
Для того чтобы дочерний процесс унаследовал наследуемые описатели,
зафиксированные в таблице родительского процесса, в параметре
bInheritHandles Вы должны передать TRUE, если наследование не
предполагается, то FASLE.
После формирование нового процесса, система скопирует из таблицы
описателей все действительные описатели из родительского процесса в
таблицу дочернего, причём в те же позиции. Помимо копирования
системы увеличит значение счётчиков объектов ядра.
Закрытие описателя в одном из процессов не отразиться на способности
другого процесса манипулировать с этим объектом. Чтобы уничтожить
объект вы должны закрыть его в обоих процессах или уничтожить
процессы.
Именованные объекты
Именование допускают многие (не все) объекты ядра.
HANDLE CreateMutex(
PSECURITY_ATTRIBUTES psa,
BOOL bInitialOwner,
PCTSTR pszName);
HANDLE CreateWaitableTimer(
PSECURITY_ATTRIBUTES psa,
BOOL bManualReset,
PCTSTR pszName);
HANDLE CreateEvent(
PSECURITY_ATTRIBUTES psa,
BOOL bManualReset,
BOOL bInitialState,
PCTSTR pszName);
HANDLE CreateFileMapping(
HANDLE hFile,
PSECURITY_ATTRIBUTES psa,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
PCTSTR pszName);
HANDLE CreateSemaphore(
PSECURITY_ATTRIBUTES psa,
LONG lInitialCount,
LONG lMaximumCount,
PCTSTR pszName);
HANDLE CreateJobObject(
PSECURITY_ATTRIBUTES psa,
PCTSTR pszName);
Последний параметр этих функций pszName служит для именования
объекта ядра.
Есть и другой способ разделения объектов по именам. Вместо вызова
Create-функции процесс может обратиться к одной из следующих
Open-функций:
 OpenMutex()
 OpenEvent()
 OpenSemaphore()
 OpenWaitableTimer()
 OpenFileMapping()
 OpenJobObject()
В последнем параметре определяется имя объекта ядра. В этом
параметре нельзя передавать NULL. Функция Open просматривает
пространство имён объектов ядра, пытаясь найти в нём совпадение.
Если объекта ядра с указанным именем не существует, функция
возвратит NULL. Но если объект найден, то будет проведена проверка
разрешения доступа к этому объекту, Если доступ разрешён, то
таблица описателей вызвавшего функцию Open обновляется, а счётчик
числа пользователей обновляется.
Дублирование описателей объектов
Последний механизм совместного использования объектов ядра
несколькими процессами требует функции DuplicateHandle:
BOOL DuplicateHandle(
HANDLE hSourceProcessHandle,
HANDLE hSourceHandle,
HANDLE hTargetProcessHandle,
PHANDLE phTargetHandle,
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwOptions);
Эта функция берет запись в таблице описателей одного процесса и
создает ее копию в таблице другого.
Первый и третий параметры функции DuplicateHandle представляют
собой описатели объектов ядра, специфичные для вызывающего
процесса.
Второй параметр, hSourceHandle – описатель объекта ядра любого
типа. Его значение специфично не для процесса, вызывающего
DuplicateHandle, а для того, на который указывает описатель
hSourceProcessHandle.
Параметр phTargetHandle – это адрес переменной типа HANDLE, в
которой возвращается индекс записи с копией описателя из процессаисточника.
Предпоследние два параметра DuplicateHandle позволяют задать маску
доступа и флаг наследования, устанавливаемые для данного описателя
в процессе-приемнике.
Download