B приведенном ниже списке перечислены основные этапы создания процесса Windows-функцией CreateProcess. Детальное описание действий на каждом этапе дается в следующих разделах.
ПРИМЕЧАНИЕ Многие этапы работы CreateProcess связаны с подготовкой виртуального адресного пространства процесса и поэтому требуют понимания массы структур и терминов, связанных с управлением памятью и описываемых в главе 7.
1. Открывается файл образа (EXE), который будет выполняться в процессе.
2. Создается объект «процесс» исполнительной системы.
3. Создается первичный поток (стек, контекст и объект «поток» исполнительной системы).
4. Подсистема Windows уведомляется о создании нового процесса и потока.
5. Начинается выполнение первичного потока (если не указан флаг CREATE_SUSPENDED).
6. B контексте нового процесса и потока инициализируется адресное пространство (например, загружаются требуемые DLL) и начинается выполнение программы.
Общая схема создания процесса в Windows показана на рис. 6–5. Прежде чем открыть исполняемый образ для выполнения, CreateProcess делает следующее.
• При вызове CreateProcess класс приоритета указывается в параметре CreationFlags, и, вызывая CreateProcess, вы можете задать сразу несколько классов приоритета. Windows выбирает самый низкий из них.
• Когда для нового процесса не указывается класс приоритета, по умолчанию принимается Normal, если только класс приоритета процесса-создателя не равен IdIe или Below Normal. B последнем случае новый процесс получает тот же класс приоритета, что и у родительского процесса.
• Если для нового процесса указан класс приоритета Real-time, а создатель не имеет привилегии Increase Scheduling Priority, устанавливается класс приоритета High. Иначе говоря, функция CreateProcess завершается успешно, даже если у того, кто ее вызвал, недостаточно привилегий для создания процессов с классом приоритета Real-time, — просто класс приоритета нового процесса будет ниже Real-time.
• Все окна сопоставляются с объектами «рабочий стол», которые являются графическим представлением рабочего пространства. Если при вызове CreateProcess не указан конкретный объект «рабочий стол», новый процесс сопоставляется с текущим объектом «рабочий стол» процесса-создателя.
Как показано на рис. 6–6 и в таблице 6–5, на первом этапе CreateProcess должна найти нужный Windows-образ, который будет выполнять файл, указанный вызвавшим процессом, и создать объект «раздел» для его последующего проецирования на адресное пространство нового процесса. Если имя образа не указано, используется первая лексема командной строки (первая часть командной строки, которая заканчивается пробелом или знаком табуляции и является допустимой в качестве имени образа).
B Windows XP и Windows Server 2003 CreateProcess проверяет, не запрещает ли политика безопасности на данной машине запуск этого образа (см. главу 8).
Если в качестве исполняемого файла указана Windows-программа, ее имя используется напрямую. A если исполняемый файл является не Windows-приложением, а программой MS-DOS, Winl6 или POSIX, то CreateProcess ищет образ поддержки (support image) для запуска этой программы. Данный процесс необходим потому, что приложения, не являющиеся Windows-программами, нельзя запускать напрямую. Вместо этого Windows использует один из нескольких специальных образов поддержки, которые и отвечают за запуск приложений, отличных от Windows-программ. Так, если вы пытаетесь запустить POSIX-приложение, CreateProcess идентифицирует его как таковое и вызывает исполняемый Windows-файл поддержки POSIX, Posix.exe. A если вы запускаете программу MS-DOS или Winl6, стартует исполняемый Windows-файл поддержки Ntvdm.exe. Короче говоря, вы не можете напрямую создать процесс, не являющийся Windows-процессом. Если Windows не найдет соответствующий файл поддержки, вызов CreateProcess закончится неудачей.
Конкретное решение о запуске того или иного файла поддержки CreateProcess принимает так.
• Если исполняемый файл — программа MS-DOS с расширением EXE, COM или PIF, подсистеме Windows посылается сообщение, чтобы она проверила, не создан ли уже процесс поддержки MS-DOS (Ntvdm.exe, указанный в параметре реестра HKLM\SYSTEM\CurrentControlSet\Control\WOW\Cmdline). Если да, этот процесс используется для запуска программы MS-DOS — подсистема Windows посылает виртуальной DOS-машине (Virtual DOS Machine, VDM) сообщение для запуска новой программы, — после чего управление возвращается к CreateProcess. Если нет, запускается Ntvdm.exe и повторно выполняется первый этап CreateProcess.
• Если исполняемый файл — командный файл с расширением BAT или CMD, запускается Cmd.exe, обрабатывающий командную строку Windows, и повторно выполняется первый этап CreateProcess. (Имя командного файла передается Cmd.exe как первый параметр.)
• Если исполняемый файл — приложение Winl6 (Windows 3.1), CreateProcess решает, надо ли для его запуска создавать новый процесс VDM или оно должно использовать глобальный для всех сеансов процесс VDM (который, возможно, еще не создан). Решение определяется флагами CREATE_SEPARATE_WOW_VDM и CREATE_SHARED_WOW_VDM. Если эти флаги не заданы, то по умолчанию решение принимается, исходя из значения параметра реестра HKLM\SYSTEM\CurrentControlSet\Control\WOW\DefaultSeparateVDM. Если программа будет работать в отдельной VDM, запускается приложение, указанное в HKLM\SYSTEM\CurrentControlSet\Control\WOW\WowCmdline, и повторно выполняется первый этап CreateProcess. B ином случае подсистема Windows посылает сообщение для проверки возможности использования общего процесса VDM. (Это исключено, если процесс VDM сопоставлен с другим объектом «рабочий стол» или если его параметры защиты отличны от таковых для вызывающего процесса. Тогда нужно создавать новый процесс VDM.) Если задействовать общий процесс VDM нельзя, подсистема Windows посылает ему сообщение о необходимости запуска нового образа, и управление возвращается к CreateProcess. Если процесс VDM еще не создан (или если он существует, но использовать его нельзя), запускается образ поддержки VDM и повторно выполняется первый этап CreateProcess. K этому моменту CreateProcess успешно открывает допустимый исполняемый файл Windows и создает для него объект «раздел». Этот объект еще не спроецирован на память, но уже открыт. Однако сам факт успешного создания объекта «раздел» не означает того, что запускаемый файл является допустимым Windows-образом, — он может быть DLL или исполняемым файлом POSIX. Если это исполняемый файл POSIX, запускается Posix.exe, и CreateProcess заново выполняет действия первого этапа. A если это DLL, вызов CreateProcess заканчивается неудачей.
CreateProcess, найдя допустимый исполняемый Windows-образ, ищет в разделе реестра HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options подраздел с именем и расширением запускаемого образа (но без указания пути к нему, например Image.exe). Если такой подраздел есть, CreateProcess ищет в нем параметр Debugger. Если он присутствует, его значение становится именем запускаемого образа, после чего следует повторение первого этапа CreateProcess.
СОВЕТ Вы можете извлечь выгоду из такого поведения CreateProcess. Оно позволяет отлаживать стартовый код процессов сервисов Windows перед их запуском. Если бы вы подключили отладчик лишь после запуска сервиса, это исключило бы возможность отладки стартового кода.