Джонсон Харт - Системное программирование в среде Windows
- Название:Системное программирование в среде Windows
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2005
- Город:Москва • Санкт-Петербург • Киев
- ISBN:5-8459-0879-5
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Джонсон Харт - Системное программирование в среде Windows краткое содержание
Эта книга посвящена вопросам разработки приложений с использованием интерфейса прикладного программирования операционных систем компании Microsoft (Windows 9х, Windows XP, Windows 2000 и Windows Server 2003). Основное внимание уделяется базовым системным службам, включая управление файловой системой, процессами и потоками, взаимодействие между процессами, сетевое программирование и синхронизацию. Рассматривается методика переноса приложений, написанных в среде Win32, в среду Win64. Подробно описываются все аспекты системы безопасности Windows и ее практического применения. Изобилие реальных примеров, доступных также и на Web-сайте книги, существенно упрощает усвоение материала.
Книга ориентирована на разработчиков и программистов, как высокой квалификации, так и начинающих, а также будет полезна для студентов соответствующих специальностей.
Системное программирование в среде Windows - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
В случае дескрипторов, которые не являются дескрипторами файлов или не используются для перенаправления ввода/вывода, применим другой способ, в соответствии с которым дескриптор преобразуется в текстовый формат и помещается в командную строку или переменную окружения. Такой подход можно использовать лишь в том случае, если дескриптор является наследуемым, поскольку и родительский, и дочерний процессы используют для идентификации дескриптора одно и то же значение. Один из способов реализации этого подхода предлагается в упражнении 6.2, а соответствующее решение приводится на Web-сайте книги.
Унаследованные дескрипторы представляют собой отдельные экземпляры. Поэтому родительский и дочерний процессы могут получить доступ к одному и тому же файлу, используя различные указатели файлов. Более того, каждый из обоих процессов может и должен самостоятельно закрывать принадлежащий ему дескриптор.
На рис. 6.2 показан пример двух процессов с двумя различными таблицами дескрипторов, в которых с одним и тем же файлом или иным объектом связаны два различных дескриптора. Процесс 1 является родительским, процесс 2 — дочерним. Если принадлежащий дочернему процессу дескриптор был унаследован им, как это имеет место в случае дескрипторов 1 и 3, то значения дескрипторов в обоих процессах будут одинаковыми.
Однако подобные дескрипторы могут иметь и различные значения. Так, на файл D указывают два дескриптора, причем процесс 2 получил дескриптор за счет вызова функции CreateFile, а не путем наследования. Наконец, возможны ситуации, когда один из процессов имеет дескриптор объекта, а второй — не имеет, что наблюдается для файлов В и Е. Так происходит в тех случаях, когда дескриптор создается дочерним процессом или дублируется из одного процесса в другой, о чем говорится в разделе "Дублирование дескрипторов".
Рис. 6.2.Таблицы дескрипторов объектов для двух процессов
Счетчики дескрипторов процессов
Распространенной ошибкой программистов является пренебрежение закрытием дескрипторов после того, как необходимость в них отпала; это может стать причиной утечки ресурсов, что, в свою очередь, может приводить к снижению производительности или сбоям в программе и даже влиять на другие процессы. В версии NT 5.1 добавлена новая функция, позволяющая определить количество открытых дескрипторов, принадлежащих указанному процессу. Таким способом вы можете контролировать как собственный, так и другие процессы.
Приведенное ниже определение упомянутой функции не нуждается в отдельных пояснениях:
BOOL GetProcessHandleCount( HANDLE hProcess, PDWORD pdwHandleCount)
Идентификаторы процессов
Процесс может получить идентификатор и дескриптор нового дочернего процесса из структуры PROCESS_INFORMATION. Разумеется, закрытие дескриптора дочернего процесса не приводит к уничтожению самого процесса; становится невозможным лишь доступ к нему со стороны родительского процесса. Для получения идентификационной информации о текущем процессе служат две функции.
HANDLE GetCurrentProcess(VOID)
DWORD GetCurrentProcessId(VOID)
В действительности функция GetCurrentProcess возвращает псевдодескриптор (pseudohandle), который не является наследуемым. Это значение может использоваться вызывающим процессом всякий раз, когда ему требуется его собственный дескриптор. Реальный дескриптор процесса создается на основе идентификатора (ID) процесса, включая и тот, который возвращается функцией GetCurrentProcessID, путем использования функции OpenProcess. Как и в случае любого разделяемого объекта, при отсутствии надлежащих разрешений доступа попытка открытия объекта процесса окажется неуспешной.
HANDLE OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
Возвращаемое значение:в случае успешного завершения — дескриптор процесса, иначе — NULL.
dwDesiredAccess — определяет права доступа к процессу. Некоторые из возможных значений этого параметра перечислены ниже.
• SYNCHRONIZE — разрешается использование дескриптора процесса в функциях ожидания завершения процесса, которые описываются далее в этой главе.
• PROCESS_ALL_ACCESS — устанавливаются все флаги доступа к процессу.
• PROCESS_TERMINATE — делает возможным завершение процесса с использованием функции TerminateProcess.
• PROCESS_QUERY_INFORMATION — разрешает использование дескриптора процесса в функциях GetExitCodeProcess и GetPriorityClass для получения информации о процессе.
bInheritHandle — позволяет указать, является ли новый дескриптор наследуемым. Параметр dwProcessID является идентификатором процесса, запрашивающего дескриптор.
Наконец, выполняющийся процесс может определить полный путь доступа к файлу исполняемого модуля, который использовался для его запуска, с помощью функций GetModuleFileName или GetModuleFileNameEx, при вызове которых значение параметра hModule должно устанавливаться равным NULL. При вызове этой функции из DLL будет возвращено имя файла DLL, а не .ЕХЕ-файла, который использует эту библиотеку DLL.
Дублирование дескрипторов
Родительскому и дочернему процессам может требоваться различный доступ к объекту, идентифицируемому дескриптором, который наследует дочерний процесс. Кроме того, процессу вместо псевдодескриптора, получаемого с помощью функции GetModuleFileName или GetModuleFileNameEx, может потребоваться реальный, наследуемый дескриптор, который мог бы использоваться дочерним процессом. Родительский процесс может обеспечить это, создав копию дескриптора с желаемыми разрешениями доступа и свойствами наследования. Функция, позволяющая создавать копии дескрипторов, имеет следующий вид:
BOOL DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, LPHANDLE lphTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions)
По завершении выполнения функции указатель lphTargetHandle будет указывать на копию исходного дескриптора, hSourceHandle. hSourceHandle является дескриптором дублируемого объекта в процессе, указанном дескриптором hSourceProcessHandle, и должен иметь права доступа PROCESS_DUP_HANDLE; если указанного дескриптора в исходном процессе не существует, функция DuplicateHandle завершается ошибкой. Новый дескриптор, на который указывает указатель lphTargetHandle, является действительным в целевом процессе, hTargetProcessHandle. Обратите внимание на то, что в нашем рассмотрении фигурировали три процесса, включая вызывающий. Часто в роли вызывающего процесса выступает целевой или исходный процесс, и тогда соответствующий дескриптор получают с помощью функции GetCurrentProcess. Заметьте также, что процесс может создать дескриптор в другом процессе; если вы это делаете, то вам потребуется механизм, с помощью которого можно было бы передать в другой процесс идентификационные данные нового дескриптора.
Функция DuplicateHandle может применяться к дескрипторам любого типа.
Читать дальшеИнтервал:
Закладка: