Функция CreateProcessWithLogonW


Функция CreateProcessWithLogonW создает новый процесс и его первичный (главный) поток. Новый процесс затем запускает заданный исполняемый файл в контексте системы безопасности определяемых полномочиями (пользователь, домен и пароль). Она может необязательно загружать профиль пользователя заданный им.

Функция CreateProcessWithLogonW походит на функцию CreateProcessAsUser, за исключением того, что вызывающей программе не нужно вызывать функцию LogonUser, чтобы подтвердить подлинность пользователя и получить маркер доступа.

Синтаксис

BOOL CreateProcessWithLogonW(
  LPCWSTR lpUsername,                 // имя пользователя
  LPCWSTR lpDomain,                   // домен пользователя
  LPCWSTR lpPassword,                 // пароль пользователя
  DWORD dwLogonFlags,                 // опция входа в сеть
  LPCWSTR lpApplicationName,          // имя исполняемого модуля
  LPWSTR lpCommandLine ,              // командная строка
  DWORD dwCreationFlags,              // флажки создания
  LPVOID lpEnvironment,               // блок новой конфигурации
  LPCWSTR lpCurrentDirectory,         // имя текущей папки
  LPSTARTUPINFOW lpStartupInfo,       // информация предустановки
  LPPROCESS_INFORMATION lpProcessInfo // информация о процессе
); 

Параметры

lpUsername

[in] Указатель на строку с нулем в конце, которая определяет имя пользователя. Это - имя учетной записи пользователя для входа в систему. Если Вы используете формат UPN, user@DNS_domain_name, параметр lpDomain должен иметь значение ПУСТО (NULL).

Учетная запись пользователя должна иметь разрешение начать работу в определенном месте на локальном компьютере. Это разрешение предоставляется всем пользователям на рабочих станциях и серверах, но управляется только администраторами на доменах.

lpDomain

[in] Указатель на строку с символом нуля в конце, которая устанавливает имя домена или сервера, учетная запись которого содержит базу данных с учетной записью lpUsername. Если этот параметр имеет значение ПУСТО (NULL), имя пользователя должно быть задано в формате UPN.

Windows XP: Если этот параметр ".", функция считает учетную запись полноценной, используя только локальную базу данных с учетной записью.

lpPassword

[in] Указатель на строку с символом нуля в конце, задающую открытый пароль учетной записи lpUsername.

dwLogonFlags

[in] Параметр входа в систему. Этот параметр может быть одним из следующих значений.

 

Значение

Предназначение

LOGON_WITH_PROFILE

Входит в систему, затем загружает профиль пользователя в ключе HKEY_USERS системного реестра. Функция возвращает значение после того, как была загружена конфигурация. Загрузка конфигурации может быть операцией со значительной затратой времени, так что самое лучшее использовать это значение, только в том случае, если Вы должны обратиться к информации в ключе HKEY_CURRENT_USER системного реестра.

Windows 2000, Windows .NET Server: конфигурация разгружается после того, как новый процесс завершил работу, независимо от того, создал ли он дочерние процессы.

Windows XP: конфигурация разгружается после того, как новый процесс и все дочерние процессы, которые он создал, завершил работу. 

LOGON_NETCREDENTIALS_ONLY

Входит в систему, но использует только заданные полномочия на сети. Новый процесс использует тот же самый маркер безопасности, как и вызывающая программа, но система создает новый сеанс входа в систему в пределах LSA, а процесс использует определяемые полномочия как заданные по умолчанию полномочия

Это значение может быть использовано для создания процесса, который использует другой набор полномочий в заданном месте, чем это делается дистанционно. Это полезно в междоменных сценариях, где не имеется меду ними доверительного отношения.

Система не проверяет правильность заданных полномочий. Поэтому процесс может начать работу, но он не сможет иметь доступ к сетевым ресурсам. 

 

lpApplicationName

[in] Указатель на строку с нулем в конце, которая определяет модуль исполняемого кода. Заданный модуль может быть базирующейся на Windows прикладной программой. Это может быть какой-то другой тип модуля (например, MS-DOS или OS/2), если соответствующая подсистема доступна на локальном компьютере.

Строка может указывать полный путь и имя файла исполняемого модуля или она может определять часть имени. В случае если это часть имени, функция использует текущий диск и текущий каталог, чтобы завершить определение. Функция не будет использовать найденный путь. Если имя файла не содержит расширение, подразумевается расширение .exe. Поэтому, если расширение имени файла - .com, этот параметр должен включить в себя расширение .com.

Параметр lpApplicationName может быть значением ПУСТО (NULL). В этом случае, имя модуля должно быть в строке lpCommandLine как первое незаполненное пространство, разграниченное маркером.

Если Вы используете длинное имя файла, которое содержит пробел, применяйте строки в кавычках, чтобы обозначить, где имя файла заканчивается, и начинаются параметры; иначе, имя файла становится неоднозначным. Например, рассмотрим строку " c:\program files\sub dir\program name ". Эта строка может интерпретироваться несколькими способами. Попытки системы интерпретировать ее, возможны в нижеследующем порядке:

c:\program.exe files\sub dir\program name
c:\program files\sub.exe dir\program name
c:\program files\sub dir\program.exe name
c:\program files\sub dir\program name.exe

Если исполняемый модуль - 16-разрядное приложение, параметр lpApplicationName должен быть значением ПУСТО (NULL), а строка, указанная в параметре lpCommandLine должна задать выполняемый модуль, также как его параметры.

lpCommandLine

[in] Указатель на строку с символом нуля в конце, определяющую командную строку для выполнения.

Эта функция завершится ошибкой, если этот параметр является строкой типа const.

Параметр lpCommandLine может быть значением ПУСТО (NULL). В этом случае, функция использует строку, указанную параметром lpApplicationName как командную строку.

Если и lpApplicationName и lpCommandLine не пустые (non-NULL), *lpApplicationName задает модуль выполнения, а *lpCommandLine определяет командную строку. Новый процесс может использовать функцию GetCommandLine, чтобы извлечь взятую в целом командную строку. Консольные процессы, написанные на языке C, могут использовать параметры argc и argv, чтобы подробно анализировать командную строку. Поскольку argv [0] - имя модуля, C - программисты обычно повторяют имя модуля как первый маркер в командной строке.

Если lpApplicationName имеет значение ПУСТО (NULL), первое незаполненное пространство, ограниченное маркером командной строки, определяет имя модуля. Если Вы используете длинное имя файла, которое содержит пробел, используйте строки в кавычках, чтобы обозначить, где заканчивается имя файла, и начинаются параметры (см. объяснение параметра lpApplicationName).Если имя файла не содержит расширения, предполагается расширение .exe. Поэтому, если расширение имени файла - .com, этот параметр должен включать в себя расширение .com. Если имя файла заканчивается точкой (.) без расширения, или имя файла содержит путь, расширение .exe не присоединяется. Если имя файла не содержит путь к каталогу, система ищет исполняемый файл в нижеследующей последовательности:

  1. Каталог, из которого загружена прикладная программа.
  2. Текущий каталог родительского процесса.
  3. Windows 95/98/Me: системный каталог Windows. Используйте функцию GetSystemDirectory, чтобы получить путь к этому каталогу.

    32-разрядный системный каталог Windows. Используйте функцию GetSystemDirectory, чтобы получить путь к этому каталогу. Имя этого каталога - System32.

  4. Windows NT/2000/XP: 16-разрядный системный каталог Windows. Нет функции, которая получает путь к этому каталогу, но он находится. Имя этого каталога - SYSTEM.
  5. Каталог Windows. Используйте функцию GetWindowsDirectory, чтобы получить путь к этому каталогу.
  6. Каталоги, которые внесены в список в переменной окружения PATH.

Система добавляет нулевой символ к командной строке, чтобы отделить имя файла от параметров. Он делит исходную строку на две строки для внутренней обработки.

dwCreationFlags

[in] Флажки, которые управляют, когда создается процесс. Флажки CREATE_DEFAULT_ERROR_MODE, CREATE_NEW_CONSOLE, и CREATE_NEW_PROCESS_GROUP включаются по умолчанию. Вы можете определить дополнительные флажки, как отмечено ниже.

 

Значение

Предназначение

CREATE_DEFAULT_ERROR_MODE

Новый процесс не наследует режим ошибки вызывающего процесса. Вместо этого, функция CreateProcessWithLogonW дает новому процессу текущий заданный по умолчанию режим ошибки. Приложение устанавливает текущий заданный по умолчанию режим ошибки путем вызова SetErrorMode.

Этот флажок включается по умолчанию.

CREATE_NEW_CONSOLE

Новый процесс получает новую консоль, вместо наследования консоли родителя. Этот флажок не может быть использован с флажком DETACHED_PROCESS.

Этот флажок включается по умолчанию. 

CREATE_NEW_PROCESS_GROUP

Новый процесс становиться корневым процессом группы нового процесса. Группа процесса включает в себя все процессы, которые являются потомками этого корневого процесса. Идентификатор процесса группы нового процесса то же самое, что и идентификатор процесса, который возвращается в параметре lpProcessInfo. Группы процессов используются функцией GenerateConsoleCtrlEvent, чтобы дать возможность отправлять сигнал CTRL+C или CTRL+BREAK группе консольных процессов.

Этот флажок включается по умолчанию. 

CREATE_SEPARATE_WOW_VDM

Этот флажок является правильным только тогда, когда стартует 16-разрядное базирующееся на Windows приложение. Если он установлен, новый процесс выполняется в отдельной Виртуальной Машине DOS (VDM). По умолчанию, все 16-разрядные приложения, базирующиеся на Windows, работают на отдельной, совместно используемой VDM. Преимущество отдельного запуска в том, что аварийный отказ завершает работу только отдельной VDM; любые другие программы, выполняющиеся в различных VDM продолжают функционировать как обычно. К тому же, 16-разрядные приложения базирующиеся на Windows, которые работают в отдельных VDM, имеют отдельные очереди введенных данных. Это означает то, что если одно приложение останавливает ответ в данный момент, приложения в отдельных VDM продолжают получать ввод данных. 

CREATE_SUSPENDED

Первичный поток нового процесса создается в состоянии ожидания, и не запускается до тех пор, пока не будет вызвана функция ResumeThread. 

CREATE_UNICODE_ENVIRONMENT

Обозначает формат параметра lpEnvironment. Если этот флажок установлен, блок конфигурации, указанный lpEnvironment использует символы Unicode. Иначе, блок конфигурации использует символы ANSI. 

Этот параметр также управляет и классом приоритета нового процесса, который используется в определении приоритетов диспетчеризации потоков процесса. За перечнем значений обратитесь к статье о функции GetPriorityClass. Если ни один из флажков класса приоритета не установлен, значения по умолчанию класса приоритета NORMAL_PRIORITY_CLASS, если класс приоритета процесса созданного процесса не является IDLE_PRIORITY_CLASS или BELOW_NORMAL_PRIORITY_CLASS. В данном случае дочерние процессы получают заданный по умолчанию класс приоритета вызывающего процесса.

lpEnvironment

[in] Указатель на блок конфигурации нового процесса. Если этот параметр имеет значение ПУСТО (NULL), новый процесс использует конфигурацию вызывающего процесса.

Блок конфигурации состоит из блока строк с символом нуля в конце, который завершается также нулем. Каждая строка представляется в форме:

name=value

Поскольку знак "=" используется как разделитель, он не должен быть использован в имени переменной окружения.

Блок конфигурации может содержать или символы Unicode или ANSI. Если блок конфигурации, указанный параметром lpEnvironment, содержит символы Unicode, убедитесь, что в параметре dwCreationFlags установлен флажок CREATE_UNICODE_ENVIRONMENT. Если блок содержит символы ANSI, этот флажок будет сброшен.

Обратите внимание! на то, что блок конфигурации в ANSI заканчивается двумя нулевыми байтами: один для последней строки, еще один, чтобы завершить блок. Блок конфигурации Уникода заканчивается четырьмя нулевыми байтами: два - для последней строки, еще два, чтобы завершить блок.

Чтобы получить копию блока конфигурации для данного пользователя, используйте функцию CreateEnvironmentBlock.

lpCurrentDirectory

[in] Указатель на строку с символом нуля в конце, определяющую текущий диск и каталог для нового процесса. Строка должна быть полным путем, который включает в себя букву (имя) диска. Если этот параметр является значением ПУСТО (NULL), новый процесс будет иметь тот же самый текущий диск и каталог, что и вызывающий процесс. (Этот параметр дается, прежде всего, для оболочек, которым нужно запустить прикладную программу и установить ее исходный диск и рабочий каталог).

lpStartupInfo

[in] Указатель на структуру STARTUPINFO, которая устанавливает оконный режим терминала, рабочий стол, стандартные дескрипторы и внешний вид главного окна для нового процесса.

Если ее член lpDesktop имеет значение ПУСТО (NULL) или он - пустая строка, новый процесс наследует рабочий стол и оконный режим терминала своего родительского процесса. Функция CreateProcessWithLogonW добавляет разрешение для заданной учетной записи пользователя наследовать оконный режим терминала и рабочего стола. Иначе, если этот член устанавливает рабочий стол, то возникает ответственность приложения, чтобы добавить разрешение для заданной учетной записи пользователя для заданного оконного терминала и рабочего стола.

lpProcessInfo

[out] Указатель на структуру PROCESS_INFORMATION, которая принимает идентифицирующую информацию о новом процессе, включая дескриптор процесса.

Дескрипторы в структуре PROCESS_INFORMATION, когда они больше не нужны, должны быть закрыты функцией CloseHandle.

Возвращаемые значения

Если функция завершается успешно, величина возвращаемого значения - не ноль.

Если функция завершается с ошибкой, величина возвращаемого значения - ноль. Чтобы получить дополнительные данные об ошибках, вызовите GetLastError.

Замечания

По умолчанию, функция CreateProcessWithLogonW не загружает заданный профиль пользователя в ключ системного реестра HKEY_USERS. Это означает, что доступ к информации в ключе системного реестра HKEY_CURRENT_USER, не может достичь результатов совместимых с нормальным интерактивным входом в систему. Это является вашей ответственностью загрузить улей системного реестра пользователя в HKEY_USERS перед вызовом CreateProcessWithLogonW, используя, или LOGON_WITH_PROFILE, или вызывая функцию LoadUserProfile.

Если параметр lpEnvironment имеет значение ПУСТО (NULL), новый процесс наследует конфигурацию вызывающего процесса. Функция CreateProcessWithLogonW автоматически не изменяет блок конфигурации, чтобы включить переменные окружения, конкретные для пользователя. Например, переменные USERNAME и USERDOMAIN наследуются от вызывающего процесса, если lpEnvironment - значение ПУСТО (NULL). Это - вы отвечаете за подготовку блока конфигурации нового процесса и устанавливаете его в lpEnvironment.

Когда идет действие создания, дескрипторы нового процесса и потока получают полные права доступа (PROCESS_ALL_ACCESS и THREAD_ALL_ACCESS). Любой из дескрипторов, если дескриптор безопасности не предусмотрен, может быть использован в любой функции, которая требует дескриптора объекта этого типа. Когда предоставлен дескриптор безопасности, проверка прав доступа выполняется для всех последующих используемых дескрипторов прежде, чем доступ предоставляется. Если доступ не дан, запрашивающий процесс не может использовать дескриптор, чтобы получить доступ к процессу или потоку.

Чтобы извлечь маркер системы безопасности, передайте дескриптор процесса в структуру PROCESS_INFORMATION для функции OpenProcessToken.

Процессу присваивается идентификатор. Идентификатор является правильным до тех пор, пока процесс не завершит работу. Он может быть использован, чтобы идентифицировать процесс, или открыть определяемый функцией OpenProcess дескриптор процесса. Начальный поток в процессе также получает свой идентификатор. Он может быть задан функцией OpenThread, чтобы открыть дескриптор потока. Идентификатор правильный до тех пор, пока поток закончит свою работу и может быть использован, чтобы уникально идентифицировать поток в пределах системы. Эти идентификаторы возвращаются в структуре PROCESS_INFORMATION.

Вызывающий поток может использовать функцию WaitForInputIdle, чтобы ждать до тех пор, пока новый процесс не завершит свою инициализацию и станет ждать от пользователя ввода данных без задержки ввода. Этот прием может быть полезным для синхронизации родительского и дочернего процессов, поскольку функция CreateProcessWithLogonW возвращает значение не ожидая, когда новый процесс закончит свою инициализацию. Например, создающий процесс должен использовать функцию WaitForInputIdle перед попыткой найти окно, связанное с новым процессом.

Предпочтительным способом выключить процесс является использование функции ExitProcess, потому что эта функция отправляет уведомление всем динамически подключаемым библиотекам (DLL), связанным с процессом о приближающемся завершении работы. Другой способ завершения процесса не уведомляет связанные DLL.

Обратите внимание! на то, что когда поток вызывает ExitProcess, другие потоки процесса, завершают работу без возможности выполнить какой-либо дополнительный код (включая код завершения потока связанных DLL). За дополнительной информацией обратитесь к статье Завершение работы процесса.

Чтобы компилировать приложение, которое использует эту функцию, определите макрокоманду _WIN32_WINNT как 0x0500 или позже. Для получения дополнительной информации, см. статью Использование заголовков SDK.

Замечания по безопасности

Параметр lpApplicationName, может иметь значение ПУСТО (NULL), в этом случае имя исполняемой программы должно быть первое незаполненное пространство разграничивающее строку в параметре lpCommandLine. Если имя пути или исполняемой программы имеют пробел, имеется риск того, что может быть запущена другая исполняемая программа из-за способа, которым функция подробно анализирует пробелы. Нижеследующий пример демонстрирует эту опасность, потому что функция вместо "MyApp.exe" будет пытаться запустить "Program.exe", если таковая существует.

CreateProcessWithLogonW(..., "C:\\Program Files\\MyApp", ...) 

Если неграмотный пользователь создаст в системе прикладную программу, называемую "Program.exe", любая программа, которая неправильно вызывает функцию CreateProcessWithLogonW, используя каталог Program Files, будет запускать это приложение вместо заданной программы.

Чтобы избежать этой проблемы, не передавайте значение ПУСТО (NULL) для параметра lpApplicationName. Если Вы передаете это значение ПУСТО (NULL) для lpApplicationName, используйте кавычки вокруг пути к исполняемой программе в параметре lpCommandLine, как показано в примере ниже.

CreateProcessWithLogonW(..., "\"C:\\Program Files\\MyApp.exe\" -L -S", ...)

Смотри также

Краткий обзор Процессы и потоки, Функции, используемые процессами и потоками, CloseHandle, CreateEnvironmentBlock, CreateProcessAsUser, ExitProcess, GetEnvironmentStrings, GetExitCodeProcess, OpenProcess, PROCESS_INFORMATION, SetErrorMode, STARTUPINFO, WaitForInputIdle

Размещение и совместимость CreateProcessWithLogonW

Windows. NET Server

Да

Windows XP

Да

Windows 2000

Да

Windows NT

Нет

Windows Me

Нет

Windows 98

Нет

Windows 95

Нет

Используемая библиотека

Advapi32.lib

Заголовочный файл

 

- объявлено в

Winbase.h

- включено в

Windows.h

Unicode

Реализуется только как Unicode.

Замечания по платформе

Не имеется

Назад в оглавление
На главную страницу
На оглавление справки

Hosted by uCoz