CreateProcessWithTokenW-Funktion (winbase.h)

Erstellt einen neuen Prozess und seinen primären Thread. Der neue Prozess wird im Sicherheitskontext des angegebenen Tokens ausgeführt. Optional kann das Benutzerprofil für den angegebenen Benutzer geladen werden.

Der Prozess, der CreateProcessWithTokenW aufruft, muss über die SE_IMPERSONATE_NAME-Berechtigung verfügen. Wenn diese Funktion mit ERROR_PRIVILEGE_NOT_HELD (1314) fehlschlägt, verwenden Sie stattdessen die Funktion CreateProcessAsUser oder CreateProcessWithLogonW . In der Regel der Prozess, der aufruft
CreateProcessAsUser muss über das SE_INCREASE_QUOTA_NAME-Recht verfügen und erfordert möglicherweise die SE_ASSIGNPRIMARYTOKEN_NAME-Berechtigung, wenn das Token nicht zugewiesen werden kann. CreateProcessWithLogonW erfordert keine besonderen Berechtigungen, aber das angegebene Benutzerkonto muss für die interaktive Anmeldung zugelassen werden. Im Allgemeinen empfiehlt es sich, CreateProcessWithLogonW zu verwenden, um einen Prozess mit alternativen Anmeldeinformationen zu erstellen.

Syntax

BOOL CreateProcessWithTokenW(
  [in]                HANDLE                hToken,
  [in]                DWORD                 dwLogonFlags,
  [in, optional]      LPCWSTR               lpApplicationName,
  [in, out, optional] LPWSTR                lpCommandLine,
  [in]                DWORD                 dwCreationFlags,
  [in, optional]      LPVOID                lpEnvironment,
  [in, optional]      LPCWSTR               lpCurrentDirectory,
  [in]                LPSTARTUPINFOW        lpStartupInfo,
  [out]               LPPROCESS_INFORMATION lpProcessInformation
);

Parameter

[in] hToken

Ein Handle für das primäre Token, das einen Benutzer darstellt. Das Handle muss über die Zugriffsberechtigungen TOKEN_QUERY, TOKEN_DUPLICATE und TOKEN_ASSIGN_PRIMARY verfügen. Weitere Informationen finden Sie unter Zugriffsrechte für Access-Token-Objekte. Der durch das Token dargestellte Benutzer muss Lese- und Ausführungszugriff auf die Anwendung haben, die durch den lpApplicationName-Parameter oder den lpCommandLine-Parameter angegeben wird.

Um ein primäres Token abzurufen, das den angegebenen Benutzer darstellt, rufen Sie die LogonUser-Funktion auf. Alternativ können Sie die DuplicateTokenEx-Funktion aufrufen, um ein Identitätswechseltoken in ein primäres Token zu konvertieren. Dadurch kann eine Serveranwendung, die die Identität eines Clients angibt, einen Prozess mit dem Sicherheitskontext des Clients erstellen.

Terminaldienste: Der Prozess des Aufrufers wird immer in der Sitzung des Aufrufers ausgeführt, nicht in der im Token angegebenen Sitzung. Um einen Prozess in der im Token angegebenen Sitzung auszuführen, verwenden Sie die Funktion CreateProcessAsUser.

[in] dwLogonFlags

Die Anmeldeoption. Dieser Parameter kann null oder einer der folgenden Werte sein.

Wert Bedeutung
LOGON_WITH_PROFILE
0x00000001
Melden Sie sich an, und laden Sie dann das Profil des Benutzers in den HKEY_USERS Registrierungsschlüssel. Die Funktion wird zurückgegeben, nachdem das Profil geladen wurde. Das Laden des Profils kann zeitaufwändig sein. Daher empfiehlt es sich, diesen Wert nur zu verwenden, wenn Sie auf die Informationen im HKEY_CURRENT_USER Registrierungsschlüssel zugreifen müssen.

Windows Server 2003: Das Profil wird entladen, nachdem der neue Prozess beendet wurde, unabhängig davon, ob es untergeordnete Prozesse erstellt hat.

LOGON_NETCREDENTIALS_ONLY
0x00000002
Melden Sie sich an, aber verwenden Sie nur die angegebenen Anmeldeinformationen im Netzwerk. Der neue Prozess verwendet das gleiche Token wie der Aufrufer, aber das System erstellt eine neue Anmeldesitzung innerhalb von LSA, und der Prozess verwendet die angegebenen Anmeldeinformationen als Standardanmeldeinformationen.

Dieser Wert kann verwendet werden, um einen Prozess zu erstellen, der einen anderen Satz von Anmeldeinformationen lokal als remote verwendet. Dies ist in domänenübergreifenden Szenarien nützlich, in denen keine Vertrauensstellung besteht.

Das System überprüft die angegebenen Anmeldeinformationen nicht. Daher kann der Prozess gestartet werden, hat aber möglicherweise keinen Zugriff auf Netzwerkressourcen.

[in, optional] lpApplicationName

Der Name des auszuführenden Moduls. Dieses Modul kann eine Windows-basierte Anwendung sein. Es kann sich um einen anderen Modultyp (z. B. MS-DOS oder OS/2) handeln, wenn das entsprechende Subsystem auf dem lokalen Computer verfügbar ist.

Die Zeichenfolge kann den vollständigen Pfad und Dateinamen des auszuführenden Moduls angeben oder einen teilweisen Namen angeben. Im Fall eines teilweisen Namens verwendet die Funktion das aktuelle Laufwerk und das aktuelle Verzeichnis, um die Spezifikation zu vervollständigen. Die Funktion verwendet nicht den Suchpfad. Dieser Parameter muss die Dateinamenerweiterung enthalten. es wird keine Standarderweiterung angenommen.

Der lpApplicationName-Parameter kann NULL sein. In diesem Fall muss der Modulname das erste durch Leerzeichen getrennte Token in der lpCommandLine-Zeichenfolge sein. Wenn Sie einen langen Dateinamen verwenden, der ein Leerzeichen enthält, verwenden Sie Anführungszeichen, um anzugeben, wo der Dateiname endet und die Argumente beginnen. Andernfalls ist der Dateiname mehrdeutig. Betrachten Sie beispielsweise die Zeichenfolge "c:\program files\sub dir\program name". Diese Zeichenfolge kann auf verschiedene Arten interpretiert werden. Das System versucht, die Möglichkeiten in folgender Reihenfolge zu interpretieren:

c:\program.exec:\program files\sub.exec:\programme\sub dir\program.exec:\programme\sub dir\program name.exe Wenn es sich bei dem ausführbaren Modul um eine 16-Bit-Anwendung handelt, sollte lpApplicationName NULL sein, und die Zeichenfolge, auf die von lpCommandLine verwiesen wird, sollte das ausführbare Modul sowie seine Argumente angeben.

[in, out, optional] lpCommandLine

Die auszuführende Befehlszeile.

Die maximale Länge dieser Zeichenfolge beträgt 1024 Zeichen. Wenn lpApplicationName NULL ist, ist der Modulnameteil von lpCommandLine auf MAX_PATH Zeichen beschränkt.

Die Funktion kann den Inhalt dieser Zeichenfolge ändern. Daher kann dieser Parameter kein Zeiger auf schreibgeschützten Arbeitsspeicher (z. B. eine const-Variable oder eine Literalzeichenfolge) sein. Wenn es sich bei diesem Parameter um eine konstante Zeichenfolge handelt, kann die Funktion eine Zugriffsverletzung verursachen.

Der lpCommandLine-Parameter kann NULL sein. In diesem Fall verwendet die Funktion die Zeichenfolge, auf die von lpApplicationName als Befehlszeile verwiesen wird.

Wenn sowohl lpApplicationName als auch lpCommandLine nicht NULL sind, gibt *lpApplicationName das auszuführende Modul an, und *lpCommandLine gibt die Befehlszeile an. Der neue Prozess kann GetCommandLine verwenden, um die gesamte Befehlszeile abzurufen. Konsolenprozesse, die in C geschrieben wurden, können die Argumente argc und argv verwenden, um die Befehlszeile zu analysieren. Da argv[0] der Modulname ist, wiederholen C-Programmierer in der Regel den Modulnamen als erstes Token in der Befehlszeile.

Wenn lpApplicationName NULL ist, gibt das erste leerzeichentrennte Token der Befehlszeile den Modulnamen an. Wenn Sie einen langen Dateinamen verwenden, der ein Leerzeichen enthält, verwenden Sie Anführungszeichen, um anzugeben, wo der Dateiname endet und die Argumente beginnen (siehe erklärung für den lpApplicationName-Parameter ). Wenn der Dateiname keine Erweiterung enthält, wird .exe angefügt. Wenn die Dateinamenerweiterung .com ist, muss dieser Parameter daher die .com-Erweiterung enthalten. Wenn der Dateiname mit einem Punkt (.) ohne Erweiterung endet oder der Dateiname einen Pfad enthält, wird .exe nicht angefügt. Wenn der Dateiname keinen Verzeichnispfad enthält, sucht das System nach der ausführbaren Datei in der folgenden Sequenz:

  1. Das Verzeichnis, aus dem die Anwendung geladen wurde.
  2. Das aktuelle Verzeichnis für den übergeordneten Prozess.
  3. Das 32-Bit-Windows-Systemverzeichnis. Verwenden Sie die GetSystemDirectory-Funktion , um den Pfad dieses Verzeichnisses abzurufen.
  4. Das 16-Bit-Windows-Systemverzeichnis. Es gibt keine Funktion, die den Pfad dieses Verzeichnisses abruft, aber es wird durchsucht.
  5. Das Windows-Verzeichnis. Verwenden Sie die GetWindowsDirectory-Funktion , um den Pfad dieses Verzeichnisses abzurufen.
  6. Die Verzeichnisse, die in der PATH-Umgebungsvariablen aufgeführt sind. Beachten Sie, dass diese Funktion nicht den anwendungsspezifischen Pfad durchsucht, der durch den Registrierungsschlüssel "App Paths" angegeben ist. Verwenden Sie die Funktion ShellExecute , um diesen Pfad pro Anwendung in die Suchsequenz aufzunehmen.
Das System fügt der Befehlszeilenzeichenfolge ein NULL-Zeichen hinzu, um den Dateinamen von den Argumenten zu trennen. Dadurch wird die ursprüngliche Zeichenfolge für die interne Verarbeitung in zwei Zeichenfolgen unterteilt.

[in] dwCreationFlags

Die Flags, die steuern, wie der Prozess erstellt wird. Die Flags CREATE_DEFAULT_ERROR_MODE, CREATE_NEW_CONSOLE und CREATE_NEW_PROCESS_GROUP sind standardmäßig aktiviert. Eine Liste der Werte finden Sie unter Flags zur Prozesserstellung.

Dieser Parameter steuert auch die Prioritätsklasse des neuen Prozesses, die verwendet wird, um die Planungsprioritäten der Threads des Prozesses zu bestimmen. Eine Liste der Werte finden Sie unter GetPriorityClass. Wenn keines der Prioritätsklassenflags angegeben wird, wird die Prioritätsklasse standardmäßig auf NORMAL_PRIORITY_CLASS festgelegt, es sei denn, die Prioritätsklasse des Erstellungsprozesses ist IDLE_PRIORITY_CLASS oder BELOW_NORMAL_PRIORITY_CLASS. In diesem Fall erhält der untergeordnete Prozess die Standardprioritätsklasse des aufrufenden Prozesses.

Wenn der dwCreationFlags-Parameter den Wert 0 aufweist:

  • Der Prozess ruft den Standardfehlermodus ab, erstellt eine neue Konsole und eine neue Prozessgruppe.
  • Es wird davon ausgegangen, dass der Umgebungsblock für den neuen Prozess ANSI-Zeichen enthält (weitere Informationen finden Sie unter lpEnvironment-Parameter ).
  • Eine 16-Bit-Windows-basierte Anwendung wird auf einem freigegebenen virtuellen DOS-Computer (VDM) ausgeführt.

[in, optional] lpEnvironment

Ein Zeiger auf einen Umgebungsblock für den neuen Prozess. Wenn dieser Parameter NULL ist, verwendet der neue Prozess eine Umgebung, die aus dem Profil des Benutzers erstellt wurde, das durch lpUsername angegeben wurde.

Ein Umgebungsblock besteht aus einem NULL-beendeten Block von Zeichenfolgen, die null beendet wurden. Jede Zeichenfolge hat die folgende Form:

Namen=Wert

Da das Gleichheitszeichen (=) als Trennzeichen verwendet wird, darf es nicht im Namen einer Umgebungsvariablen verwendet werden.

Ein Umgebungsblock kann Unicode- oder ANSI-Zeichen enthalten. Wenn der Umgebungsblock, auf den lpEnvironment verweist, Unicode-Zeichen enthält, stellen Sie sicher, dass dwCreationFlags CREATE_UNICODE_ENVIRONMENT enthält.

Ein ANSI-Umgebungsblock wird durch zwei Nullbytes beendet: eins für die letzte Zeichenfolge und ein weiteres zum Beenden des Blocks. Ein Unicode-Umgebungsblock wird durch vier Nullbytes beendet: zwei für die letzte Zeichenfolge und zwei weitere, um den Block zu beenden.

Verwenden Sie die Funktion CreateEnvironmentBlock , um eine Kopie des Umgebungsblocks für einen bestimmten Benutzer abzurufen.

[in, optional] lpCurrentDirectory

Der vollständige Pfad zum aktuellen Verzeichnis für den Prozess. Die Zeichenfolge kann auch einen UNC-Pfad angeben.

Wenn dieser Parameter NULL ist, verwendet der neue Prozess dasselbe aktuelle Laufwerk und Verzeichnis wie der aufrufende Prozess. (Dieses Feature wird in erster Linie für Shells bereitgestellt, die eine Anwendung starten und deren Anfangslaufwerk und Arbeitsverzeichnis angeben müssen.)

[in] lpStartupInfo

Ein Zeiger auf eine STARTUPINFO - oder STARTUPINFOEX-Struktur .

Wenn das lpDesktop-Element NULL oder eine leere Zeichenfolge ist, erbt der neue Prozess die Desktop- und Fensterstation des übergeordneten Prozesses. Die Funktion fügt der geerbten Fensterstation und dem desktop die Berechtigung für das angegebene Benutzerkonto hinzu. Wenn dieses Mitglied einen Desktop angibt, liegt es in der Verantwortung der Anwendung, der angegebenen Fensterstation und dem angegebenen Desktop die Berechtigung für das angegebene Benutzerkonto hinzuzufügen, auch für WinSta0\Default.

Handles in STARTUPINFO oder STARTUPINFOEX müssen mit CloseHandle geschlossen werden, wenn sie nicht mehr benötigt werden.

Wichtig Wenn der dwFlags-Member der STARTUPINFO-StrukturSTARTF_USESTDHANDLES angibt, werden die Standardhandlefelder unverändert ohne Validierung in den untergeordneten Prozess kopiert. Der Aufrufer ist dafür verantwortlich, sicherzustellen, dass diese Felder gültige Handlewerte enthalten. Falsche Werte können dazu führen, dass sich der untergeordnete Prozess falsch benimmt oder abstürzt. Verwenden Sie das Application Verifier-Laufzeitüberprüfungstool , um ungültige Handles zu erkennen.
 

[out] lpProcessInformation

Ein Zeiger auf eine PROCESS_INFORMATION Struktur, die Identifikationsinformationen für den neuen Prozess empfängt, einschließlich eines Handles für den Prozess.

Handles in PROCESS_INFORMATION müssen mit der CloseHandle-Funktion geschlossen werden, wenn sie nicht mehr benötigt werden.

Rückgabewert

Wenn die Funktion erfolgreich ist, ist der Rückgabewert ungleich Null.

Wenn die Funktion fehlerhaft ist, ist der Rückgabewert null. Um erweiterte Fehlerinformationen zu erhalten, rufen Sie GetLastError auf.

Beachten Sie, dass die Funktion zurückgibt, bevor die Initialisierung des Prozesses abgeschlossen ist. Wenn eine erforderliche DLL nicht gefunden werden kann oder nicht initialisiert werden kann, wird der Prozess beendet. Rufen Sie GetExitCodeProcess auf, um die beendigung status eines Prozesses zu erhalten.

Hinweise

Standardmäßig lädt CreateProcessWithTokenW das Profil des angegebenen Benutzers nicht in den HKEY_USERS Registrierungsschlüssel. Dies bedeutet, dass der Zugriff auf Informationen im HKEY_CURRENT_USER Registrierungsschlüssel möglicherweise keine Ergebnisse erzeugt, die mit einer normalen interaktiven Anmeldung konsistent sind. Es liegt in Ihrer Verantwortung, die Registrierungsstruktur des Benutzers in HKEY_USERS zu laden, indem Sie entweder LOGON_WITH_PROFILE verwenden oder die LoadUserProfile-Funktion aufrufen, bevor Sie diese Funktion aufrufen.

Wenn der lpEnvironment-Parameter NULL ist, verwendet der neue Prozess einen Umgebungsblock, der aus dem Profil des Benutzers erstellt wurde, das durch lpUserName angegeben wurde. Wenn die Variablen HOMEDRIVE und HOMEPATH nicht festgelegt sind, ändert CreateProcessWithTokenW den Umgebungsblock so, dass er das Laufwerk und den Pfad des Arbeitsverzeichnisses des Benutzers verwendet.

Bei der Erstellung erhalten die neuen Prozess- und Threadhandles Vollzugriffsrechte (PROCESS_ALL_ACCESS und THREAD_ALL_ACCESS). Wenn bei beiden Handles kein Sicherheitsdeskriptor bereitgestellt wird, kann das Handle in jeder Funktion verwendet werden, die ein Objekthandle dieses Typs erfordert. Wenn ein Sicherheitsdeskriptor bereitgestellt wird, wird eine Zugriffsüberprüfung für alle nachfolgenden Verwendungen des Handles durchgeführt, bevor der Zugriff gewährt wird. Wenn der Zugriff verweigert wird, kann der anfordernde Prozess das Handle nicht verwenden, um Zugriff auf den Prozess oder Thread zu erhalten.

Um ein Sicherheitstoken abzurufen, übergeben Sie das Prozesshandle in der PROCESS_INFORMATION-Struktur an die OpenProcessToken-Funktion .

Dem Prozess wird ein Prozessbezeichner zugewiesen. Der Bezeichner ist gültig, bis der Prozess beendet wird. Es kann verwendet werden, um den Prozess zu identifizieren, oder in der OpenProcess-Funktion angegeben werden, um ein Handle für den Prozess zu öffnen. Dem anfänglichen Thread im Prozess wird auch ein Threadbezeichner zugewiesen. Es kann in der OpenThread-Funktion angegeben werden, um ein Handle für den Thread zu öffnen. Der Bezeichner ist gültig, bis der Thread beendet wird, und kann verwendet werden, um den Thread innerhalb des Systems eindeutig zu identifizieren. Diese Bezeichner werden in PROCESS_INFORMATION zurückgegeben.

Der aufrufende Thread kann die WaitForInputIdle-Funktion verwenden, um zu warten, bis der neue Prozess seine Initialisierung abgeschlossen hat und auf Benutzereingaben wartet, ohne dass eine Eingabe aussteht. Dies kann für die Synchronisierung zwischen übergeordneten und untergeordneten Prozessen nützlich sein, da CreateProcessWithTokenW zurückgibt, ohne darauf zu warten, dass der neue Prozess seine Initialisierung abgeschlossen hat. Beispielsweise verwendet der Erstellungsprozess WaitForInputIdle , bevor versucht wird, ein Fenster zu finden, das dem neuen Prozess zugeordnet ist.

Die bevorzugte Möglichkeit zum Herunterfahren eines Prozesses ist die Verwendung der ExitProcess-Funktion , da diese Funktion eine Benachrichtigung über die bevorstehende Beendigung an alle dlLs sendet, die an den Prozess angefügt sind. Andere Mittel zum Herunterfahren eines Prozesses benachrichtigen die angefügten DLLs nicht. Beachten Sie, dass, wenn ein Thread ExitProcess aufruft, andere Threads des Prozesses beendet werden, ohne dass zusätzlichen Code ausgeführt werden kann (einschließlich des Threadabschlusscodes der angefügten DLLs). Weitere Informationen finden Sie unter Beenden eines Prozesses.

Um eine Anwendung zu kompilieren, die diese Funktion verwendet, definieren Sie _WIN32_WINNT als 0x0500 oder höher. Weitere Informationen finden Sie unter Verwenden der Windows-Header.

Sicherheitsbemerkungen

Der lpApplicationName-Parameter kann NULL sein. In diesem Fall muss der name der ausführbaren Datei die erste leerzeichentrennte Zeichenfolge in lpCommandLine sein. Wenn die ausführbare Datei oder der Pfadname ein Leerzeichen enthält, besteht aufgrund der Art und Weise, wie die Funktion Leerzeichen analysiert, das Risiko, dass eine andere ausführbare Datei ausgeführt werden kann. Das folgende Beispiel ist gefährlich, da die Funktion versucht, "Program.exe" anstelle von "MyApp.exe" auszuführen, sofern vorhanden.
	LPTSTR szCmdline = L"C:\\Program Files\\MyApp";
	CreateProcessWithTokenW(/*...*/, szCmdline, /*...*/);

Wenn ein böswilliger Benutzer eine Anwendung namens "Program.exe" auf einem System erstellen würde, führt jedes Programm, das CreateProcessWithTokenW fälschlicherweise über das Verzeichnis Programme aufruft, diese Anwendung anstelle der beabsichtigten Anwendung aus.

Um dieses Problem zu vermeiden, übergeben Sie null nicht für lpApplicationName. Wenn Sie NULL für lpApplicationName übergeben, verwenden Sie anführungszeichen um den ausführbaren Pfad in lpCommandLine, wie im folgenden Beispiel gezeigt.

	LPTSTR szCmdline = L"\"C:\\Program Files\\MyApp\"";
	CreateProcessWithTokenW(/*...*/, szCmdline, /*...*/);

Anforderungen

Anforderung Wert
Unterstützte Mindestversion (Client) Windows Vista [nur Desktop-Apps]
Unterstützte Mindestversion (Server) Windows Server 2003 [nur Desktop-Apps]
Zielplattform Windows
Kopfzeile winbase.h (Windows.h einschließen)
Bibliothek Advapi32.lib
DLL Advapi32.dll

Weitere Informationen

CloseHandle

CreateEnvironmentBlock

ExitProcess

GetEnvironmentStrings

GetExitCodeProcess

OpenProcess

PROCESS_INFORMATION

Prozess- und Threadfunktionen

Prozesse

STARTUPINFO

SetErrorMode

Waitforinputidle