
- •1.1 Основы программирования в операционной системе Windows
- •1.1.1 Вызов функций api
- •1.1.2 Структура программы
- •1.2 Вопросы системного программирования в Windows
- •1.2.1 Страничная и сегментная адресация.
- •1.2.2 Адресное пространство процесса.
- •2.1 Управление процессами
- •2.2 Процессы и потоки в Windows
- •2.3 Создание процессов
- •2.4 Определение исполняемого образа и командной строки
- •2.5 Идентификация процессов
- •3.1 Создание потока. Функция CreateThread
- •3.2. Завершение потока
- •3.3 Другие функции работы с потоками
- •3.4 Структура context
- •3.5 Приоритеты потоков
- •4.1 Объект critical_section
- •4.2 Мьютексы
- •4.3 Семафоры
- •5.1 События
- •7.1 Кучи
- •7.2 Управление памятью кучи
- •Другие функции для работы с кучей
- •Резюме по управлению кучей
- •Отображение адресного пространства процесса в объекты отображения
- •Что такое импорт
- •Явная загрузка dll
- •Явное подключение экспортируемого идентификатора
- •10.1 Управление файлами и каталогами Создание и открытие файлов
- •10.2 Управление каталогами
- •10.3 Другие методы получения атрибутов файлов и каталогов
- •11.1 Блокировка файлов
- •11.2 Реестр
- •12.1 Стандартные устройства и консольный ввод-вывод
- •12.2 Асинхронный ввод-вывод и порты завершения
- •Параметры
- •Цели системы безопасности
- •Параметры
- •Аварийное завершение
- •Использование именованных каналов
- •Параметры
- •Наблюдение за сообщениями в именованном канале
- •Параметры
2.4 Определение исполняемого образа и командной строки
Параметры lpszImageName и lpszCommandLine определяют имя исполняемого образа, руководствуясь приведенными ниже правилами.
• Если значение параметра lpszImageName не NULL, то это имя исполняемого файла. В случае если оно содержит пробелы, можно использовать кавычки.
• В противном случае имя исполняемого файла — первый элемент параметра lpszCortmandLine.
Обычно указывают только параметр lpszComanandLine, присваивая параметру lpszImageName значение NULL. Тем не менее существуют подробные правила для параметра lpszImageName.
• Если параметр lpszImageName имеет значение не NULL то он указывает имя загрузочного файла. Указывайте полный путь и имя файла. Можете указать только имя файла, тогда будут использованы текущие диск и каталог без дополнительного поиска. В имя файла включайте его расширение ( . ЕХЕ, . ВАТ и т.п.).
• Если параметр lpszImageName имеет значение NULL то за имя программы принимается первый элемент параметра lpszCommandLine, отделенный пробелом. Если это имя не содержит полного пути, происходит поиск в определенной последовательности.
1. Каталог образа текущего процесса.
2. Текущий каталог.
3. Системный каталог Windows, полученный посредством вызова функции
4. Каталог Windows, полученный посредством вызова функции
5. Каталоги, указанные в переменной окружения РАТН.
Новый процесс может получить командную строку, используя обычный механизм argv, или выполнить функцию GetCommandLine для получения всей командной строки в одной строковой переменной.
Отметим, что командная строка не является константой. Это следует из того факта, что параметры argv для главной программы тоже не константы. Программа может изменять свои параметры, поэтому желательно делать изменения в копии строки параметров.
Не требуется создавать новый процесс с таким же определением переменной препроцессора UNICODE, что и родительский. Возможны все комбинации. Для разработки переносимого кода полезно использовать макрос _tmain.
2.5 Идентификация процессов
Процесс может получить идентификатор и дескриптор нового дочернего процесса из структуры process_information. Закрытие дескриптора дочернего процесса, конечно, не уничтожает его, таким образом только уничтожается возможность доступа к нему родительского процесса. Для получения описания текущего процесса используется пара функций.
HANDLE GetCurrentProcess (VOID)
DWORD GetCurrentProcessId (VOID)
Функция GetCurrentProcess в действительности возвращает псевдодескриптор, который не может быть унаследован. Это значение используется в случаях, когда процессу требуется собственный дескриптор. Создавайте настоящий дескриптор процесса из его ID, используя в вызове функции OpenProcess значение, возвращенное функцией GetCurrentProcessId.
HANDLE OpenProcess ( DWORD fdwAccess, BOOL fInherit,
DWORD IDProcess)
Возвращаемое значение: дескриптор процесса или NULL в случае ошибки.
Параметры
fdwAccess определяет параметры доступа процесса к дескриптору. Приведем некоторые из его возможных значений.
• Флаг synchronize разрешает другим процессам ждать завершения этого процесса, используя функции ожидания, которые описаны в этой главе ниже.
• PROCESS_ALL_ACCESS — установлены все флаги доступа.
• Флаг PROCESS_TERMINATEделает возможным завершение процесса вызовом функции TerminateProcess.
• Флаг process_query_information разрешает использовать дескриптор функциями GetExitCodeProcess и GetPriorityClass для получения информации о процессе. .,
fInherit определяет, может ли новый дескриптор быть унаследован. IDProcess содержит идентификатор процесса, которому необходим дескриптор. И наконец, выполняющийся процесс может определить имя своего загрузочного файла с помощью функции GetModuleFileName, используя в качестве параметра hModule указатель NULL. Вызов этой функции из динамической библиотеки возвратит \ имя файла DLL, а не файла . ЕХЕ, используемого библиотекой.
Копирование дескрипторов
Родительскому и дочернему процессам может потребоваться различный доступ к объекту, который определяется дескриптором, унаследованным дочерним процессом. Также процессу может потребоваться его настоящий наследуемый дескриптор вместо псевдодескриптора, создаваемого функцией GetCurrentProcess для использования дочерним процессом. Чтобы решить эту проблему, родительский процесс может создать копию дескриптора с необходимыми правами доступа и видом наследования. Ниже представлена функция для копирования дескрипторов.
BOOL DuplicateHandle( HANDLE hSourceProcess, HANDLE hSource,
HANDLE hTargetProcess, LPHANDLE lphTarget,
DWORD fdwAccess, BOOL fInherit, DWORD fdwOptions);
После выполнения функции указатель lphTarget ссылается на копию исходного дескриптора hSource. Параметр hSource содержит дескриптор процесса, определяемого параметром hSourceProcess, и должен иметь права доступа process_dup_handle. Новый дескриптор, на который указывает переменная lphTarget, является действительным в целевом процессе hTargetProcess. Включая процесс, вызвавший функцию, здесь использованы три процесса. Вызывающий функцию процесс часто является также целевым и исходным, а дескриптор получают от функции GetCurrentProcess. Отметим, что возможно создание дескриптора в другом процессе; если вы это сделаете, то понадобится механизм для того, чтобы проинформировать его о новом экземпляре дескриптора.
Функция DuplicateHandle может быть использована для любого типа дескриптора.
Если параметр fdwAccess не подавлен флагом duplicate_same_access в переменной fdwOptions, то он может принимать множество значений (см. встроенную справку MSDN).
Значение параметра fdwOptions может быть любой комбинацией следующих флагов:
• DUPLICATE_CLOSE_SOURCE — исходный дескриптор будет закрыт;
• DUPLICATE_SAME_ACCSESS— параметр fdwAccess будет проигнорирован. Далее необходимо научиться определять, был ли процесс завершен.
Выход из процесса и его завершение
После того как процесс закончен, он вызывает функцию ExitProcess с кодом завершения.
Эта функция ничего не возвращает, вызвавший ее процесс и все его потоки завершаются.
Для определения кода завершения другой процесс может использовать функцию GetExitCodeProcess.
BOOL GetExitCodeProcess ( HANDLE hProcess,
LPDWORD lpdwExitCode);
Процесс, определенный переменной hProcess, должен иметь права доступа PROCESS_QUERY_INFORMATION (см. функцию OpenProcess). Параметр lpdwExitCode указывает на переменную типа dword, в которую будет помещено значение. Одно из возможных значений — STILL_ACTIVE; оно указывает, что процесс не был завершен.
Один процесс может завершить другой, если его дескриптор имеет флаг доступа PROCESS_TERMINATE. Функция, завершающая процесс, также определяет код выхода из процесса.
BOOL TerminateProcess ( HANDLE hProcess, UINT uExitCode)
Ожидание завершения процесса
Простейший и наиболее ограниченный способ синхронизации с другим процессом состоит в ожидании его полного завершения. Здесь представлены функции общего назначения Win 32 для ожидания, обладающие некоторыми интересными свойствами.
• Эти функции могут быть использованы для большого числа различных типов объектов; дескрипторы процессов — это лишь первое их применение.
• Функции могут ожидать завершения одного процесса, первого из нескольких указанных или всех процессов в группе.
• Для них может быть использована рекомендательная блокировка по времени.
Ниже показаны две функции ожидания общего назначения, которые наиболее часто будут использоваться далее.
Параметр lphObjects указывает на дескриптор одного процесса (типа hObject) или на массив различных объектов. Значение параметра cObjects (размер массива) не должно превышать константу maximum_wait_objects (в настоящее время ее значение 64 определено в заголовочном файле winnt.h).
Лекция 3. Тема: Потоки и планирование
Поток (thread) определяет последовательность исполнения кода в процессе. При инициализации процесса система всегда создает первичный поток. Большинство приложений обходится единственным, первичным потоком. Однако процессы могут создавать дополнительные потоки, что позволяет им эффективнее выполнять свою работу.
Каждый поток начинает выполнение с некоей входной функции. В первичном потоке таковой является WinMain. Если необходимо создать вторичный поток, в нем тоже должна быть входная функция.
Функция потока может выполнять любые задачи. Рано или поздно она закончит свою работу и вернет управление. В этот момент поток остановится, память, отведенная под его стек, будет освобождена, а счетчик пользователей его объекта ядра «поток» уменьшится на 1. Когда счетчик обнулится. этот объект ядра будет разрушен.
Функция потока должна возвращать значение, которое будет использоваться как код завершения потока. Функции потоков должны по мере возможности обходиться своими параметрами и локальными переменными.