ReactOS  0.4.15-dev-1377-ga59cecd
proc.c File Reference
#include <k32.h>
#include <debug.h>
Include dependency graph for proc.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define CMD_STRING   L"cmd /c "
 
#define AddToHandle(x, y)   (x) = (HANDLE)((ULONG_PTR)(x) | (y));
 
#define RemoveFromHandle(x, y)   (x) = (HANDLE)((ULONG_PTR)(x) & ~(y));
 

Functions

VOID WINAPI RegisterWaitForInputIdle (WaitForInputIdleType lpfnRegisterWaitForInputIdle)
 
VOID WINAPI StuffStdHandle (IN HANDLE ProcessHandle, IN HANDLE StandardHandle, IN PHANDLE Address)
 
BOOLEAN WINAPI BuildSubSysCommandLine (IN LPCWSTR SubsystemName, IN LPCWSTR ApplicationName, IN LPCWSTR CommandLine, OUT PUNICODE_STRING SubsysCommandLine)
 
BOOLEAN WINAPI BasepIsImageVersionOk (IN ULONG ImageMajorVersion, IN ULONG ImageMinorVersion)
 
NTSTATUS WINAPI BasepCheckWebBladeHashes (IN HANDLE FileHandle)
 
NTSTATUS NTAPI BasepSaveAppCertRegistryValue (IN PLIST_ENTRY List, IN PWCHAR ComponentName, IN PWCHAR DllName)
 
NTSTATUS NTAPI BasepConfigureAppCertDlls (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
NTSTATUS WINAPI BasepIsProcessAllowed (IN LPWSTR ApplicationName)
 
NTSTATUS WINAPI BasepReplaceProcessThreadTokens (IN HANDLE TokenHandle, IN HANDLE ProcessHandle, IN HANDLE ThreadHandle)
 
VOID WINAPI BasepSxsCloseHandles (IN PBASE_MSG_SXS_HANDLES Handles)
 
VOID WINAPI BaseProcessStartup (PPROCESS_START_ROUTINE lpStartAddress)
 
BOOLEAN WINAPI BasePushProcessParameters (IN ULONG ParameterFlags, IN HANDLE ProcessHandle, IN PPEB RemotePeb, IN LPCWSTR ApplicationPathName, IN LPWSTR lpCurrentDirectory, IN LPWSTR lpCommandLine, IN LPVOID lpEnvironment, IN LPSTARTUPINFOW StartupInfo, IN DWORD CreationFlags, IN BOOL InheritHandles, IN ULONG ImageSubsystem, IN PVOID AppCompatData, IN ULONG AppCompatDataSize)
 
VOID WINAPI InitCommandLines (VOID)
 
BOOL WINAPI GetProcessAffinityMask (IN HANDLE hProcess, OUT PDWORD_PTR lpProcessAffinityMask, OUT PDWORD_PTR lpSystemAffinityMask)
 
BOOL WINAPI SetProcessAffinityMask (IN HANDLE hProcess, IN DWORD_PTR dwProcessAffinityMask)
 
BOOL WINAPI GetProcessShutdownParameters (OUT LPDWORD lpdwLevel, OUT LPDWORD lpdwFlags)
 
BOOL WINAPI SetProcessShutdownParameters (IN DWORD dwLevel, IN DWORD dwFlags)
 
BOOL WINAPI GetProcessWorkingSetSizeEx (IN HANDLE hProcess, OUT PSIZE_T lpMinimumWorkingSetSize, OUT PSIZE_T lpMaximumWorkingSetSize, OUT PDWORD Flags)
 
BOOL WINAPI GetProcessWorkingSetSize (IN HANDLE hProcess, OUT PSIZE_T lpMinimumWorkingSetSize, OUT PSIZE_T lpMaximumWorkingSetSize)
 
BOOL WINAPI SetProcessWorkingSetSizeEx (IN HANDLE hProcess, IN SIZE_T dwMinimumWorkingSetSize, IN SIZE_T dwMaximumWorkingSetSize, IN DWORD Flags)
 
BOOL WINAPI SetProcessWorkingSetSize (IN HANDLE hProcess, IN SIZE_T dwMinimumWorkingSetSize, IN SIZE_T dwMaximumWorkingSetSize)
 
BOOL WINAPI GetProcessTimes (IN HANDLE hProcess, IN LPFILETIME lpCreationTime, IN LPFILETIME lpExitTime, IN LPFILETIME lpKernelTime, IN LPFILETIME lpUserTime)
 
HANDLE WINAPI GetCurrentProcess (VOID)
 
HANDLE WINAPI GetCurrentThread (VOID)
 
DWORD WINAPI GetCurrentProcessId (VOID)
 
BOOL WINAPI GetExitCodeProcess (IN HANDLE hProcess, IN LPDWORD lpExitCode)
 
DWORD WINAPI GetProcessId (IN HANDLE Process)
 
HANDLE WINAPI OpenProcess (IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
 
VOID WINAPI RegisterWaitForInputIdle (IN WaitForInputIdleType lpfnRegisterWaitForInputIdle)
 
VOID WINAPI GetStartupInfoW (IN LPSTARTUPINFOW lpStartupInfo)
 
VOID WINAPI GetStartupInfoA (IN LPSTARTUPINFOA lpStartupInfo)
 
BOOL WINAPI FlushInstructionCache (IN HANDLE hProcess, IN LPCVOID lpBaseAddress, IN SIZE_T nSize)
 
VOID WINAPI ExitProcess (IN UINT uExitCode)
 
BOOL WINAPI TerminateProcess (IN HANDLE hProcess, IN UINT uExitCode)
 
VOID WINAPI FatalAppExitA (UINT uAction, LPCSTR lpMessageText)
 
VOID WINAPI FatalAppExitW (IN UINT uAction, IN LPCWSTR lpMessageText)
 
VOID WINAPI FatalExit (IN int ExitCode)
 
DWORD WINAPI GetPriorityClass (IN HANDLE hProcess)
 
BOOL WINAPI SetPriorityClass (IN HANDLE hProcess, IN DWORD dwPriorityClass)
 
DWORD WINAPI GetProcessVersion (IN DWORD ProcessId)
 
BOOL WINAPI GetProcessIoCounters (IN HANDLE hProcess, OUT PIO_COUNTERS lpIoCounters)
 
BOOL WINAPI GetProcessPriorityBoost (IN HANDLE hProcess, OUT PBOOL pDisablePriorityBoost)
 
BOOL WINAPI SetProcessPriorityBoost (IN HANDLE hProcess, IN BOOL bDisablePriorityBoost)
 
BOOL WINAPI GetProcessHandleCount (IN HANDLE hProcess, OUT PDWORD pdwHandleCount)
 
BOOL WINAPI IsWow64Process (IN HANDLE hProcess, OUT PBOOL Wow64Process)
 
LPSTR WINAPI GetCommandLineA (VOID)
 
LPWSTR WINAPI GetCommandLineW (VOID)
 
BOOL NTAPI ReadProcessMemory (IN HANDLE hProcess, IN LPCVOID lpBaseAddress, IN LPVOID lpBuffer, IN SIZE_T nSize, OUT SIZE_T *lpNumberOfBytesRead)
 
BOOL NTAPI WriteProcessMemory (IN HANDLE hProcess, IN LPVOID lpBaseAddress, IN LPCVOID lpBuffer, IN SIZE_T nSize, OUT SIZE_T *lpNumberOfBytesWritten)
 
BOOL WINAPI ProcessIdToSessionId (IN DWORD dwProcessId, OUT PDWORD pSessionId)
 
 C_ASSERT (PROCESS_PRIORITY_CLASS_REALTIME==(PROCESS_PRIORITY_CLASS_HIGH+1))
 
BOOL WINAPI CreateProcessInternalW (IN HANDLE hUserToken, IN LPCWSTR lpApplicationName, IN LPWSTR lpCommandLine, IN LPSECURITY_ATTRIBUTES lpProcessAttributes, IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN BOOL bInheritHandles, IN DWORD dwCreationFlags, IN LPVOID lpEnvironment, IN LPCWSTR lpCurrentDirectory, IN LPSTARTUPINFOW lpStartupInfo, IN LPPROCESS_INFORMATION lpProcessInformation, OUT PHANDLE hNewToken)
 
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW (LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
 
BOOL WINAPI CreateProcessInternalA (HANDLE hToken, LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation, PHANDLE hNewToken)
 
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA (LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
 
UINT WINAPI DECLSPEC_HOTPATCH WinExec (LPCSTR lpCmdLine, UINT uCmdShow)
 

Variables

WaitForInputIdleType UserWaitForInputIdleRoutine
 
UNICODE_STRING BaseUnicodeCommandLine
 
ANSI_STRING BaseAnsiCommandLine
 
UNICODE_STRING BasePathVariableName = RTL_CONSTANT_STRING(L"PATH")
 
LPSTARTUPINFOA BaseAnsiStartupInfo = NULL
 
PLDR_DATA_TABLE_ENTRY BasepExeLdrEntry
 
BOOLEAN g_AppCertInitialized
 
BOOLEAN g_HaveAppCerts
 
LIST_ENTRY BasepAppCertDllsList
 
RTL_CRITICAL_SECTION gcsAppCert
 
PBASEP_APPCERT_EMBEDDED_FUNC fEmbeddedCertFunc
 
NTSTATUS g_AppCertStatus
 
RTL_QUERY_REGISTRY_TABLE BasepAppCertTable [2]
 
PSAFER_REPLACE_PROCESS_THREAD_TOKENS g_SaferReplaceProcessThreadTokens
 
HMODULE gSaferHandle = (HMODULE)-1
 

Macro Definition Documentation

◆ AddToHandle

#define AddToHandle (   x,
  y 
)    (x) = (HANDLE)((ULONG_PTR)(x) | (y));

Definition at line 2227 of file proc.c.

◆ CMD_STRING

#define CMD_STRING   L"cmd /c "

Definition at line 51 of file proc.c.

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file proc.c.

◆ RemoveFromHandle

#define RemoveFromHandle (   x,
  y 
)    (x) = (HANDLE)((ULONG_PTR)(x) & ~(y));

Definition at line 2228 of file proc.c.

Function Documentation

◆ BasepCheckWebBladeHashes()

NTSTATUS WINAPI BasepCheckWebBladeHashes ( IN HANDLE  FileHandle)

Definition at line 149 of file proc.c.

150 {
152  CHAR Hash[16];
153 
154  /* Get all the MD5 hashes */
156  if (!NT_SUCCESS(Status)) return Status;
157 
158  /* Depending on which suite this is, run a bsearch and block the appropriate ones */
159  if (SharedUserData->SuiteMask & VER_SUITE_COMPUTE_SERVER)
160  {
161  DPRINT1("Egad! This is a ReactOS Compute Server and we should prevent you from using certain APIs...but we won't.");
162  }
163  else if (SharedUserData->SuiteMask & VER_SUITE_STORAGE_SERVER)
164  {
165  DPRINT1("Gasp! This is a ReactOS Storage Server and we should prevent you from using certain APIs...but we won't.");
166  }
167  else if (SharedUserData->SuiteMask & VER_SUITE_BLADE)
168  {
169  DPRINT1("Golly! This is a ReactOS Web Blade Server and we should prevent you from using certain APIs...but we won't.");
170  }
171 
172  /* Actually, fuck it, don't block anything, we're open source */
173  return STATUS_SUCCESS;
174 }
static int Hash(const char *)
Definition: reader.c:2257
char CHAR
Definition: xmlstorage.h:175
#define VER_SUITE_BLADE
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI NTSTATUS NTAPI RtlComputeImportTableHash(IN HANDLE FileHandle, OUT PCHAR Hash, IN ULONG ImportTableHashSize)
Definition: libsupp.c:1027
HANDLE FileHandle
Definition: stats.c:38
#define VER_SUITE_STORAGE_SERVER
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SharedUserData
#define VER_SUITE_COMPUTE_SERVER
#define DPRINT1
Definition: precomp.h:8
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by CreateProcessInternalW().

◆ BasepConfigureAppCertDlls()

NTSTATUS NTAPI BasepConfigureAppCertDlls ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 189 of file proc.c.

195 {
196  /* Add this to the certification list */
198 }
NTSTATUS NTAPI BasepSaveAppCertRegistryValue(IN PLIST_ENTRY List, IN PWCHAR ComponentName, IN PWCHAR DllName)
Definition: proc.c:178
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240

◆ BasepIsImageVersionOk()

BOOLEAN WINAPI BasepIsImageVersionOk ( IN ULONG  ImageMajorVersion,
IN ULONG  ImageMinorVersion 
)

Definition at line 123 of file proc.c.

125 {
126  /* Accept images for NT 3.1 or higher */
127  if (ImageMajorVersion > 3 ||
128  (ImageMajorVersion == 3 && ImageMinorVersion >= 10))
129  {
130  /* ReactOS-specific: Accept images even if they are newer than our internal NT version. */
131  if (ImageMajorVersion > SharedUserData->NtMajorVersion ||
132  (ImageMajorVersion == SharedUserData->NtMajorVersion && ImageMinorVersion > SharedUserData->NtMinorVersion))
133  {
134  DPRINT1("Accepting image version %lu.%lu, although ReactOS is an NT %hu.%hu OS!\n",
135  ImageMajorVersion,
136  ImageMinorVersion,
137  SharedUserData->NtMajorVersion,
138  SharedUserData->NtMinorVersion);
139  }
140 
141  return TRUE;
142  }
143 
144  return FALSE;
145 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define SharedUserData
#define DPRINT1
Definition: precomp.h:8

Referenced by CreateProcessInternalW().

◆ BasepIsProcessAllowed()

NTSTATUS WINAPI BasepIsProcessAllowed ( IN LPWSTR  ApplicationName)

Definition at line 202 of file proc.c.

203 {
204  NTSTATUS Status, Status1;
205  PWCHAR Buffer;
206  UINT Length;
207  HMODULE TrustLibrary;
209  ULONG CertFlag;
210  PLIST_ENTRY NextEntry;
212  UNICODE_STRING CertKey = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\AppCertDlls");
214 
215  /* Try to initialize the certification subsystem */
216  while (!g_AppCertInitialized)
217  {
218  /* Defaults */
220  Buffer = NULL;
221 
222  /* Acquire the lock while initializing and see if we lost a race */
224  if (g_AppCertInitialized) break;
225 
226  /* On embedded, there is a special DLL */
227  if (SharedUserData->SuiteMask & VER_SUITE_EMBEDDEDNT)
228  {
229  /* Allocate a buffer for the name */
230  Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
231  0,
232  MAX_PATH * sizeof(WCHAR) +
233  sizeof(UNICODE_NULL));
234  if (!Buffer)
235  {
236  /* Fail if no memory */
238  }
239  else
240  {
241  /* Now get the system32 directory in our buffer, make sure it fits */
242  Length = GetSystemDirectoryW(Buffer, MAX_PATH - sizeof("EmbdTrst.DLL"));
243  if ((Length) && (Length <= MAX_PATH - sizeof("EmbdTrst.DLL")))
244  {
245  /* Add a slash if needed, and add the embedded cert DLL name */
246  if (Buffer[Length - 1] != '\\') Buffer[Length++] = '\\';
248  L"EmbdTrst.DLL",
249  sizeof(L"EmbdTrst.DLL"));
250 
251  /* Try to load it */
252  TrustLibrary = LoadLibraryW(Buffer);
253  if (TrustLibrary)
254  {
255  /* And extract the special function out of it */
256  fEmbeddedCertFunc = (PVOID)GetProcAddress(TrustLibrary,
257  "ImageOkToRunOnEmbeddedNT");
258  }
259  }
260 
261  /* If we didn't get this far, set a failure code */
263  }
264  }
265  else
266  {
267  /* Other systems have a registry entry for this */
268  Status1 = NtOpenKey(&KeyHandle, KEY_READ, &KeyAttributes);
269  if (NT_SUCCESS(Status1))
270  {
271  /* Close it, we'll query it through Rtl */
273 
274  /* Do the query, which will call a special callback */
276  L"Session Manager",
278  NULL,
279  NULL);
281  {
283  }
284  }
285  }
286 
287  /* Free any buffer if we had one */
288  if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
289 
290  /* Check for errors, or a missing embedded/custom certification DLL */
291  if (!NT_SUCCESS(Status) ||
293  {
294  /* The subsystem is not active on this machine, so give up */
297  }
298  else
299  {
300  /* We have certification DLLs active, remember this */
302  }
303 
304  /* We are done the initialization phase, release the lock */
307  }
308 
309  /* If there's no certification DLLs present, return the failure code */
310  if (!g_HaveAppCerts) return g_AppCertStatus;
311 
312  /* Otherwise, assume success and make sure we have *something* */
315 
316  /* If the something is an embedded certification DLL, call it and return */
318 
319  /* Otherwise we have custom certification DLLs, parse them */
320  NextEntry = BasepAppCertDllsList.Flink;
321  CertFlag = 2;
322  while (NextEntry != &BasepAppCertDllsList)
323  {
324  /* Make sure the entry has a callback */
326  ASSERT(Entry->fPluginCertFunc != NULL);
327 
328  /* Call it and check if it failed */
329  Status = Entry->fPluginCertFunc(ApplicationName, 1);
330  if (!NT_SUCCESS(Status)) CertFlag = 3;
331 
332  /* Move on */
333  NextEntry = NextEntry->Flink;
334  }
335 
336  /* Now loop them again */
337  NextEntry = BasepAppCertDllsList.Flink;
338  while (NextEntry != &BasepAppCertDllsList)
339  {
340  /* Make sure the entry has a callback */
342  ASSERT(Entry->fPluginCertFunc != NULL);
343 
344  /* Call it, this time with the flag from the loop above */
345  Status = Entry->fPluginCertFunc(ApplicationName, CertFlag);
346  }
347 
348  /* All done, return the status */
349  return Status;
350 }
NTSTATUS g_AppCertStatus
Definition: proc.c:31
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
RTL_CRITICAL_SECTION gcsAppCert
Definition: proc.c:29
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
struct _Entry Entry
Definition: kefuncs.h:627
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
BOOLEAN g_AppCertInitialized
Definition: proc.c:26
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
uint16_t * PWCHAR
Definition: typedefs.h:56
#define RTL_REGISTRY_CONTROL
Definition: nt_native.h:163
Definition: kernel32.h:385
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
BOOLEAN g_HaveAppCerts
Definition: proc.c:27
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define LoadLibraryW(x)
Definition: compat.h:606
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK _In_opt_ PWDF_OBJECT_ATTRIBUTES KeyAttributes
Definition: wdfdevice.h:2654
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:45
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:34
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define SharedUserData
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:119
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
#define VER_SUITE_EMBEDDEDNT
PVOID PVOID PWCHAR ApplicationName
Definition: env.c:45
RTL_QUERY_REGISTRY_TABLE BasepAppCertTable[2]
Definition: proc.c:32
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
PBASEP_APPCERT_EMBEDDED_FUNC fEmbeddedCertFunc
Definition: proc.c:30
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2312
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
LIST_ENTRY BasepAppCertDllsList
Definition: proc.c:28
unsigned int ULONG
Definition: retypes.h:1
#define GetProcAddress(x, y)
Definition: compat.h:612
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
base of all file and directory entries
Definition: entries.h:82
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by CreateProcessInternalW().

◆ BasepReplaceProcessThreadTokens()

NTSTATUS WINAPI BasepReplaceProcessThreadTokens ( IN HANDLE  TokenHandle,
IN HANDLE  ProcessHandle,
IN HANDLE  ThreadHandle 
)

Definition at line 354 of file proc.c.

357 {
359  ANSI_STRING SaferiReplaceProcessThreadTokens = RTL_CONSTANT_STRING("SaferiReplaceProcessThreadTokens");
360 
361  /* Enter the application certification lock */
363 
364  /* Check if we already know the function */
366  {
367  /* Call it */
370  ThreadHandle) ?
373  }
374  else
375  {
376  /* Check if the app certification DLL isn't loaded */
377  if (!(gSaferHandle) ||
378  (gSaferHandle == (HMODULE)-1) ||
379  (gSaferHandle == (HMODULE)-2))
380  {
381  /* Then we can't call the function */
383  }
384  else
385  {
386  /* We have the DLL, find the address of the Safer function */
388  &SaferiReplaceProcessThreadTokens,
389  0,
391  if (NT_SUCCESS(Status))
392  {
393  /* Found it, now call it */
396  ThreadHandle) ?
399  }
400  else
401  {
402  /* We couldn't find it, so this must be an unsupported DLL */
404  gSaferHandle = NULL;
406  }
407  }
408  }
409 
410  /* Release the lock and return the result */
412  return Status;
413 }
RTL_CRITICAL_SECTION gcsAppCert
Definition: proc.c:29
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
PSAFER_REPLACE_PROCESS_THREAD_TOKENS g_SaferReplaceProcessThreadTokens
Definition: proc.c:45
NTSTATUS NTAPI LdrGetProcedureAddress(IN PVOID BaseAddress, IN PANSI_STRING Name, IN ULONG Ordinal, OUT PVOID *ProcedureAddress)
Definition: ldrapi.c:823
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:715
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
NTSTATUS NTAPI LdrUnloadDll(IN PVOID BaseAddress)
Definition: ldrapi.c:1322
HMODULE gSaferHandle
Definition: proc.c:46
#define NULL
Definition: types.h:112
#define STATUS_ENTRYPOINT_NOT_FOUND
Definition: ntstatus.h:549
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by CreateProcessInternalW().

◆ BaseProcessStartup()

VOID WINAPI BaseProcessStartup ( PPROCESS_START_ROUTINE  lpStartAddress)

Definition at line 450 of file proc.c.

451 {
452  DPRINT("BaseProcessStartup(..) - setting up exception frame.\n");
453 
454  _SEH2_TRY
455  {
456  /* Set our Start Address */
459  &lpStartAddress,
460  sizeof(PPROCESS_START_ROUTINE));
461 
462  /* Call the Start Routine */
463  ExitThread(lpStartAddress());
464  }
466  {
467  /* Get the Exit code from the SEH Handler */
469  {
470  /* Kill the whole process, usually */
472  }
473  else
474  {
475  /* If running inside CSRSS, kill just this thread */
477  }
478  }
479  _SEH2_END;
480 }
#define NtCurrentThread()
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1487
_SEH2_TRY
Definition: create.c:4226
LONG WINAPI UnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
Definition: except.c:262
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
void DPRINT(...)
Definition: polytest.cpp:61
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:364
NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: query.c:2018
BOOLEAN BaseRunningInServerProcess
Definition: dllmain.c:20
_SEH2_END
Definition: create.c:4400
UINT(WINAPI * PPROCESS_START_ROUTINE)(VOID)
Definition: kernel32.h:248
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12

Referenced by BaseInitializeContext().

◆ BasepSaveAppCertRegistryValue()

NTSTATUS NTAPI BasepSaveAppCertRegistryValue ( IN PLIST_ENTRY  List,
IN PWCHAR  ComponentName,
IN PWCHAR  DllName 
)

Definition at line 178 of file proc.c.

181 {
182  /* Pretty much the only thing this key is used for, is malware */
184  return STATUS_NOT_IMPLEMENTED;
185 }
return STATUS_NOT_IMPLEMENTED
#define UNIMPLEMENTED
Definition: debug.h:115

Referenced by BasepConfigureAppCertDlls().

◆ BasepSxsCloseHandles()

VOID WINAPI BasepSxsCloseHandles ( IN PBASE_MSG_SXS_HANDLES  Handles)

Definition at line 417 of file proc.c.

418 {
420 
421  /* Sanity checks */
422  ASSERT(Handles != NULL);
423  ASSERT(Handles->Process == NULL || Handles->Process == NtCurrentProcess());
424 
425  /* Close the file handle */
426  if (Handles->File)
427  {
428  Status = NtClose(Handles->File);
430  }
431 
432  /* Close the section handle */
433  if (Handles->Section)
434  {
435  Status = NtClose(Handles->Section);
437  }
438 
439  /* Unmap the section view */
440  if (Handles->ViewBase.QuadPart)
441  {
443  (PVOID)(ULONG_PTR)Handles->ViewBase.QuadPart);
445  }
446 }
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3782
LONG NTSTATUS
Definition: precomp.h:26
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define NtCurrentProcess()
Definition: nt_native.h:1657
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define NULL
Definition: types.h:112

Referenced by CreateProcessInternalW().

◆ BasePushProcessParameters()

BOOLEAN WINAPI BasePushProcessParameters ( IN ULONG  ParameterFlags,
IN HANDLE  ProcessHandle,
IN PPEB  RemotePeb,
IN LPCWSTR  ApplicationPathName,
IN LPWSTR  lpCurrentDirectory,
IN LPWSTR  lpCommandLine,
IN LPVOID  lpEnvironment,
IN LPSTARTUPINFOW  StartupInfo,
IN DWORD  CreationFlags,
IN BOOL  InheritHandles,
IN ULONG  ImageSubsystem,
IN PVOID  AppCompatData,
IN ULONG  AppCompatDataSize 
)

Definition at line 484 of file proc.c.

497 {
498  WCHAR FullPath[MAX_PATH + 5];
499  PWCHAR Remaining, DllPathString, ScanChar;
500  PRTL_USER_PROCESS_PARAMETERS ProcessParameters, RemoteParameters;
501  PVOID RemoteAppCompatData;
503  UNICODE_STRING Desktop, Shell, Runtime, Title;
505  ULONG EnviroSize;
506  SIZE_T Size;
507  BOOLEAN HavePebLock = FALSE, Result;
508  PPEB Peb = NtCurrentPeb();
509 
510  /* Get the full path name */
511  Size = GetFullPathNameW(ApplicationPathName,
512  MAX_PATH + 4,
513  FullPath,
514  &Remaining);
515  if ((Size) && (Size <= (MAX_PATH + 4)))
516  {
517  /* Get the DLL Path */
518  DllPathString = BaseComputeProcessDllPath(FullPath, lpEnvironment);
519  if (!DllPathString)
520  {
521  /* Fail */
523  return FALSE;
524  }
525 
526  /* Initialize Strings */
527  RtlInitUnicodeString(&DllPath, DllPathString);
528  RtlInitUnicodeString(&ImageName, FullPath);
529  }
530  else
531  {
532  /* Couldn't get the path name. Just take the original path */
533  DllPathString = BaseComputeProcessDllPath((LPWSTR)ApplicationPathName,
534  lpEnvironment);
535  if (!DllPathString)
536  {
537  /* Fail */
539  return FALSE;
540  }
541 
542  /* Initialize Strings */
543  RtlInitUnicodeString(&DllPath, DllPathString);
544  RtlInitUnicodeString(&ImageName, ApplicationPathName);
545  }
546 
547  /* Initialize Strings */
548  RtlInitUnicodeString(&CommandLine, lpCommandLine);
549  RtlInitUnicodeString(&CurrentDirectory, lpCurrentDirectory);
550 
551  /* Initialize more Strings from the Startup Info */
552  if (StartupInfo->lpDesktop)
553  {
554  RtlInitUnicodeString(&Desktop, StartupInfo->lpDesktop);
555  }
556  else
557  {
559  }
560  if (StartupInfo->lpReserved)
561  {
562  RtlInitUnicodeString(&Shell, StartupInfo->lpReserved);
563  }
564  else
565  {
567  }
568  if (StartupInfo->lpTitle)
569  {
570  RtlInitUnicodeString(&Title, StartupInfo->lpTitle);
571  }
572  else
573  {
574  RtlInitUnicodeString(&Title, ApplicationPathName);
575  }
576 
577  /* This one is special because the length can differ */
578  Runtime.Buffer = (LPWSTR)StartupInfo->lpReserved2;
579  Runtime.MaximumLength = Runtime.Length = StartupInfo->cbReserved2;
580 
581  /* Enforce no app compat data if the pointer was NULL */
582  if (!AppCompatData) AppCompatDataSize = 0;
583 
584  /* Create the Parameter Block */
585  ProcessParameters = NULL;
586  DPRINT("ImageName: '%wZ'\n", &ImageName);
587  DPRINT("DllPath : '%wZ'\n", &DllPath);
588  DPRINT("CurDir : '%wZ'\n", &CurrentDirectory);
589  DPRINT("CmdLine : '%wZ'\n", &CommandLine);
590  DPRINT("Title : '%wZ'\n", &Title);
591  DPRINT("Desktop : '%wZ'\n", &Desktop);
592  DPRINT("Shell : '%wZ'\n", &Shell);
593  DPRINT("Runtime : '%wZ'\n", &Runtime);
594  Status = RtlCreateProcessParameters(&ProcessParameters,
595  &ImageName,
596  &DllPath,
597  lpCurrentDirectory ?
599  &CommandLine,
600  lpEnvironment,
601  &Title,
602  &Desktop,
603  &Shell,
604  &Runtime);
605  if (!NT_SUCCESS(Status)) goto FailPath;
606 
607  /* Clear the current directory handle if not inheriting */
608  if (!InheritHandles) ProcessParameters->CurrentDirectory.Handle = NULL;
609 
610  /* Check if the user passed in an environment */
611  if (lpEnvironment)
612  {
613  /* We should've made it part of the parameters block, enforce this */
614  ASSERT(ProcessParameters->Environment == lpEnvironment);
615  lpEnvironment = ProcessParameters->Environment;
616  }
617  else
618  {
619  /* The user did not, so use the one from the current PEB */
620  HavePebLock = TRUE;
622  lpEnvironment = Peb->ProcessParameters->Environment;
623  }
624 
625  /* Save pointer and start lookup */
626  ScanChar = lpEnvironment;
627  if (lpEnvironment)
628  {
629  /* Find the environment size */
630  while (*ScanChar++) while (*ScanChar++);
631  EnviroSize = (ULONG)((ULONG_PTR)ScanChar - (ULONG_PTR)lpEnvironment);
632 
633  /* Allocate and Initialize new Environment Block */
634  Size = EnviroSize;
635  ProcessParameters->Environment = NULL;
637  (PVOID*)&ProcessParameters->Environment,
638  0,
639  &Size,
640  MEM_COMMIT,
642  if (!NT_SUCCESS(Status)) goto FailPath;
643 
644  /* Write the Environment Block */
646  ProcessParameters->Environment,
647  lpEnvironment,
648  EnviroSize,
649  NULL);
650 
651  /* No longer need the PEB lock anymore */
652  if (HavePebLock)
653  {
654  /* Release it */
656  HavePebLock = FALSE;
657  }
658 
659  /* Check if the write failed */
660  if (!NT_SUCCESS(Status)) goto FailPath;
661  }
662 
663  /* Write new parameters */
664  ProcessParameters->StartingX = StartupInfo->dwX;
665  ProcessParameters->StartingY = StartupInfo->dwY;
666  ProcessParameters->CountX = StartupInfo->dwXSize;
667  ProcessParameters->CountY = StartupInfo->dwYSize;
668  ProcessParameters->CountCharsX = StartupInfo->dwXCountChars;
669  ProcessParameters->CountCharsY = StartupInfo->dwYCountChars;
670  ProcessParameters->FillAttribute = StartupInfo->dwFillAttribute;
671  ProcessParameters->WindowFlags = StartupInfo->dwFlags;
672  ProcessParameters->ShowWindowFlags = StartupInfo->wShowWindow;
673 
674  /* Write the handles only if we have to */
675  if (StartupInfo->dwFlags &
676  (STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE))
677  {
678  ProcessParameters->StandardInput = StartupInfo->hStdInput;
679  ProcessParameters->StandardOutput = StartupInfo->hStdOutput;
680  ProcessParameters->StandardError = StartupInfo->hStdError;
681  }
682 
683  /* Use Special Flags for ConDllInitialize in Kernel32 */
684  if (CreationFlags & DETACHED_PROCESS)
685  {
686  ProcessParameters->ConsoleHandle = HANDLE_DETACHED_PROCESS;
687  }
688  else if (CreationFlags & CREATE_NEW_CONSOLE)
689  {
690  ProcessParameters->ConsoleHandle = HANDLE_CREATE_NEW_CONSOLE;
691  }
692  else if (CreationFlags & CREATE_NO_WINDOW)
693  {
694  ProcessParameters->ConsoleHandle = HANDLE_CREATE_NO_WINDOW;
695  }
696  else
697  {
698  /* Inherit our Console Handle */
699  ProcessParameters->ConsoleHandle = Peb->ProcessParameters->ConsoleHandle;
700 
701  /* Make sure that the shell isn't trampling on our handles first */
702  if (!(StartupInfo->dwFlags &
703  (STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE)))
704  {
705  /* Copy the handle if we are inheriting or if it's a console handle */
706  if ((InheritHandles) ||
708  {
709  ProcessParameters->StandardInput = Peb->ProcessParameters->StandardInput;
710  }
711  if ((InheritHandles) ||
713  {
714  ProcessParameters->StandardOutput = Peb->ProcessParameters->StandardOutput;
715  }
716  if ((InheritHandles) ||
718  {
719  ProcessParameters->StandardError = Peb->ProcessParameters->StandardError;
720  }
721  }
722  }
723 
724  /* Also set the Console Flag */
725  if ((CreationFlags & CREATE_NEW_PROCESS_GROUP) &&
726  (!(CreationFlags & CREATE_NEW_CONSOLE)))
727  {
728  ProcessParameters->ConsoleFlags = 1;
729  }
730 
731  /* Check if there's a .local file present */
732  if (ParameterFlags & 1)
733  {
735  }
736 
737  /* Check if we failed to open the IFEO key */
738  if (ParameterFlags & 2)
739  {
741  }
742 
743  /* Allocate memory for the parameter block */
744  Size = ProcessParameters->Length;
745  RemoteParameters = NULL;
747  (PVOID*)&RemoteParameters,
748  0,
749  &Size,
750  MEM_COMMIT,
752  if (!NT_SUCCESS(Status)) goto FailPath;
753 
754  /* Set the allocated size */
755  ProcessParameters->MaximumLength = Size;
756 
757  /* Handle some Parameter Flags */
758  ProcessParameters->Flags |= (CreationFlags & PROFILE_USER) ?
760  ProcessParameters->Flags |= (CreationFlags & PROFILE_KERNEL) ?
762  ProcessParameters->Flags |= (CreationFlags & PROFILE_SERVER) ?
764  ProcessParameters->Flags |= (Peb->ProcessParameters->Flags &
766 
767  /* Write the Parameter Block */
769  RemoteParameters,
770  ProcessParameters,
771  ProcessParameters->Length,
772  NULL);
773  if (!NT_SUCCESS(Status)) goto FailPath;
774 
775  /* Write the PEB Pointer */
777  &RemotePeb->ProcessParameters,
778  &RemoteParameters,
779  sizeof(PVOID),
780  NULL);
781  if (!NT_SUCCESS(Status)) goto FailPath;
782 
783  /* Check if there's any app compat data to write */
784  RemoteAppCompatData = NULL;
785  if (AppCompatData)
786  {
787  /* Allocate some space for the application compatibility data */
788  Size = AppCompatDataSize;
790  &RemoteAppCompatData,
791  0,
792  &Size,
793  MEM_COMMIT,
795  if (!NT_SUCCESS(Status)) goto FailPath;
796 
797  /* Write the application compatibility data */
799  RemoteAppCompatData,
800  AppCompatData,
801  AppCompatDataSize,
802  NULL);
803  if (!NT_SUCCESS(Status)) goto FailPath;
804  }
805 
806  /* Write the PEB Pointer to the app compat data (might be NULL) */
808  &RemotePeb->pShimData,
809  &RemoteAppCompatData,
810  sizeof(PVOID),
811  NULL);
812  if (!NT_SUCCESS(Status)) goto FailPath;
813 
814  /* Now write Peb->ImageSubSystem */
815  if (ImageSubsystem)
816  {
818  &RemotePeb->ImageSubsystem,
819  &ImageSubsystem,
820  sizeof(ImageSubsystem),
821  NULL);
822  }
823 
824  /* Success path */
825  Result = TRUE;
826 
827 Quickie:
828  /* Cleanup */
829  if (HavePebLock) RtlReleasePebLock();
830  RtlFreeHeap(RtlGetProcessHeap(), 0, DllPath.Buffer);
831  if (ProcessParameters) RtlDestroyProcessParameters(ProcessParameters);
832  return Result;
833 FailPath:
834  DPRINT1("Failure to create process parameters: %lx\n", Status);
836  Result = FALSE;
837  goto Quickie;
838 }
NTSYSAPI NTSTATUS NTAPI RtlCreateProcessParameters(_Out_ PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, _In_ PUNICODE_STRING ImagePathName, _In_opt_ PUNICODE_STRING DllPath, _In_opt_ PUNICODE_STRING CurrentDirectory, _In_opt_ PUNICODE_STRING CommandLine, _In_opt_ PWSTR Environment, _In_opt_ PUNICODE_STRING WindowTitle, _In_opt_ PUNICODE_STRING DesktopInfo, _In_opt_ PUNICODE_STRING ShellInfo, _In_opt_ PUNICODE_STRING RuntimeInfo)
PPEB Peb
Definition: dllmain.c:27
#define RTL_USER_PROCESS_PARAMETERS_IMAGE_KEY_MISSING
Definition: rtltypes.h:54
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define HANDLE_DETACHED_PROCESS
Definition: console.h:13
#define HANDLE_CREATE_NO_WINDOW
Definition: console.h:15
WCHAR CurrentDirectory[1024]
Definition: chkdsk.c:74
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define PROFILE_KERNEL
Definition: winbase.h:197
NTSYSAPI NTSTATUS NTAPI RtlDestroyProcessParameters(_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1105
VOID NTAPI RtlReleasePebLock(VOID)
Definition: libsupp.c:82
uint16_t * PWCHAR
Definition: typedefs.h:56
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1959
#define CREATE_NEW_PROCESS_GROUP
Definition: winbase.h:185
#define MEM_COMMIT
Definition: nt_native.h:1313
#define PROFILE_USER
Definition: winbase.h:196
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CREATE_NO_WINDOW
Definition: winbase.h:195
#define FALSE
Definition: types.h:117
#define STARTF_SHELLPRIVATE
Definition: kernel32.h:60
#define RTL_USER_PROCESS_PARAMETERS_PROFILE_USER
Definition: rtltypes.h:42
unsigned char BOOLEAN
#define RTL_USER_PROCESS_PARAMETERS_PROFILE_KERNEL
Definition: rtltypes.h:43
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
void DPRINT(...)
Definition: polytest.cpp:61
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
static CHAR Desktop[MAX_PATH]
Definition: dem.c:256
Status
Definition: gdiplustypes.h:24
#define STARTF_USESTDHANDLES
Definition: winbase.h:480
#define HANDLE_CREATE_NEW_CONSOLE
Definition: console.h:14
#define CREATE_NEW_CONSOLE
Definition: winbase.h:180
static const WCHAR Title[]
Definition: oid.c:1259
#define ASSERT(a)
Definition: mode.c:45
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define RTL_USER_PROCESS_PARAMETERS_PROFILE_SERVER
Definition: rtltypes.h:44
#define MAX_PATH
Definition: compat.h:34
#define SetLastError(x)
Definition: compat.h:611
#define IsConsoleHandle(h)
Definition: console.h:14
static const char * ImageName
Definition: image.c:34
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_USER_PROCESS_PARAMETERS_DISABLE_HEAP_CHECKS
Definition: rtltypes.h:49
static int Shell(const char **args)
Definition: vfdcmd.c:1020
LPWSTR WINAPI BaseComputeProcessDllPath(IN LPWSTR FullPath, IN PVOID Environment)
Definition: path.c:420
ULONG_PTR SIZE_T
Definition: typedefs.h:80
NTSTATUS NTAPI NtAllocateVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *UBaseAddress, IN ULONG_PTR ZeroBits, IN OUT PSIZE_T URegionSize, IN ULONG AllocationType, IN ULONG Protect)
Definition: virtual.c:4407
#define NtCurrentPeb()
Definition: FLS.c:20
static const char const char * DllPath
Definition: image.c:34
#define DETACHED_PROCESS
Definition: winbase.h:179
#define NULL
Definition: types.h:112
VOID NTAPI RtlAcquirePebLock(VOID)
Definition: libsupp.c:72
#define DPRINT1
Definition: precomp.h:8
HANDLE Handle
Definition: rtltypes.h:1367
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define ULONG_PTR
Definition: config.h:101
#define PROFILE_SERVER
Definition: winbase.h:198
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH
Definition: rtltypes.h:53
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
NTSTATUS NTAPI NtWriteVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN SIZE_T NumberOfBytesToWrite, OUT PSIZE_T NumberOfBytesWritten OPTIONAL)
Definition: virtual.c:2845
#define PAGE_READWRITE
Definition: nt_native.h:1304

Referenced by CreateProcessInternalW().

◆ BuildSubSysCommandLine()

BOOLEAN WINAPI BuildSubSysCommandLine ( IN LPCWSTR  SubsystemName,
IN LPCWSTR  ApplicationName,
IN LPCWSTR  CommandLine,
OUT PUNICODE_STRING  SubsysCommandLine 
)

Definition at line 89 of file proc.c.

93 {
94  UNICODE_STRING CommandLineString, ApplicationNameString;
95  PWCHAR Buffer;
96  ULONG Length;
97 
98  /* Convert to unicode strings */
99  RtlInitUnicodeString(&CommandLineString, ApplicationName);
100  RtlInitUnicodeString(&ApplicationNameString, CommandLine);
101 
102  /* Allocate buffer for the output string */
103  Length = CommandLineString.MaximumLength + ApplicationNameString.MaximumLength + 32;
104  Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
105  RtlInitEmptyUnicodeString(SubsysCommandLine, Buffer, (USHORT)Length);
106  if (!Buffer)
107  {
108  /* Fail, no memory */
110  return FALSE;
111  }
112 
113  /* Build the final subsystem command line */
114  RtlAppendUnicodeToString(SubsysCommandLine, SubsystemName);
115  RtlAppendUnicodeStringToString(SubsysCommandLine, &CommandLineString);
116  RtlAppendUnicodeToString(SubsysCommandLine, L" /C ");
117  RtlAppendUnicodeStringToString(SubsysCommandLine, &ApplicationNameString);
118  return TRUE;
119 }
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
USHORT MaximumLength
Definition: env_spec_w32.h:370
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define TRUE
Definition: types.h:120
uint16_t * PWCHAR
Definition: typedefs.h:56
#define FALSE
Definition: types.h:117
Definition: bufpool.h:45
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
static const WCHAR L[]
Definition: oid.c:1250
PVOID PVOID PWCHAR ApplicationName
Definition: env.c:45
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)

Referenced by CreateProcessInternalW().

◆ C_ASSERT()

◆ CreateProcessA()

BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA ( LPCSTR  lpApplicationName,
LPSTR  lpCommandLine,
LPSECURITY_ATTRIBUTES  lpProcessAttributes,
LPSECURITY_ATTRIBUTES  lpThreadAttributes,
BOOL  bInheritHandles,
DWORD  dwCreationFlags,
LPVOID  lpEnvironment,
LPCSTR  lpCurrentDirectory,
LPSTARTUPINFOA  lpStartupInfo,
LPPROCESS_INFORMATION  lpProcessInformation 
)

Definition at line 4744 of file proc.c.

4754 {
4755  /* Call the internal (but exported) version */
4757  lpApplicationName,
4758  lpCommandLine,
4759  lpProcessAttributes,
4760  lpThreadAttributes,
4761  bInheritHandles,
4762  dwCreationFlags,
4763  lpEnvironment,
4764  lpCurrentDirectory,
4765  lpStartupInfo,
4766  lpProcessInformation,
4767  NULL);
4768 }
BOOL WINAPI CreateProcessInternalA(HANDLE hToken, LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation, PHANDLE hNewToken)
Definition: proc.c:4626
#define NULL
Definition: types.h:112

Referenced by _create_process(), cmd_available(), CommandThreadProc(), crash_and_debug(), crash_and_winedbg(), create_proc(), create_process(), create_server_process(), create_target_process(), create_writepipe_process(), CreateProcessAsUserA(), do_parent(), doChildren(), DoTestEntry(), fork_helper(), IDirectPlayLobby3AImpl_RunApplication(), LoadModule(), run_child_process(), run_client(), run_cmd(), run_ex(), run_process(), run_reg_exe_(), run_regedit_exe_(), run_script_file(), runcmd(), start_server(), START_TEST(), system(), test___getmainargs_parent(), test_alloc_shared(), test_apc_deadlock(), test_BreakawayOk(), test_comctl32_classes(), test_CommandLine(), test_Console(), test_CreateProcessWithDesktop(), test_debug_children(), test_debug_heap(), test_debug_loop(), test_DebuggingFlag(), test_DetachConsoleHandles(), test_DetachStdHandles(), test_Directory(), test_EnumProcessModules(), test_Environment(), test_ExitCode(), test_ExitProcess(), test_GetProcessVersion(), test_internet_features(), test_invalid_stdin(), test_IsWow64Process(), test_jobInheritance(), test_LresultFromObject(), test_NonExistentPath(), test_NtSuspendProcess(), test_process_access(), test_process_security(), test_query_process_debug_flags(), test_query_process_debug_object_handle(), test_query_process_debug_port(), test_section_access(), test_shared_memory(), test_shared_memory_ro(), test_Startup(), test_StartupNoConsole(), test_stdout_handle(), test_SuspendFlag(), test_TerminateProcess(), test_token_security_descriptor(), test_Toolhelp(), test_WaitForInputIdle(), test_window_from_point(), test_winproc_handles(), and WinExec().

◆ CreateProcessInternalA()

BOOL WINAPI CreateProcessInternalA ( HANDLE  hToken,
LPCSTR  lpApplicationName,
LPSTR  lpCommandLine,
LPSECURITY_ATTRIBUTES  lpProcessAttributes,
LPSECURITY_ATTRIBUTES  lpThreadAttributes,
BOOL  bInheritHandles,
DWORD  dwCreationFlags,
LPVOID  lpEnvironment,
LPCSTR  lpCurrentDirectory,
LPSTARTUPINFOA  lpStartupInfo,
LPPROCESS_INFORMATION  lpProcessInformation,
PHANDLE  hNewToken 
)

Definition at line 4626 of file proc.c.

4638 {
4639  UNICODE_STRING CommandLine;
4642  BOOL bRetVal;
4643  STARTUPINFOW StartupInfo;
4644 
4645  DPRINT("dwCreationFlags %x, lpEnvironment %p, lpCurrentDirectory %p, "
4646  "lpStartupInfo %p, lpProcessInformation %p\n",
4647  dwCreationFlags, lpEnvironment, lpCurrentDirectory,
4648  lpStartupInfo, lpProcessInformation);
4649 
4650  /* Copy Startup Info */
4651  RtlMoveMemory(&StartupInfo, lpStartupInfo, sizeof(*lpStartupInfo));
4652 
4653  /* Initialize all strings to nothing */
4654  CommandLine.Buffer = NULL;
4655  ApplicationName.Buffer = NULL;
4656  CurrentDirectory.Buffer = NULL;
4657  StartupInfo.lpDesktop = NULL;
4658  StartupInfo.lpReserved = NULL;
4659  StartupInfo.lpTitle = NULL;
4660 
4661  /* Convert the Command line */
4662  if (lpCommandLine)
4663  {
4665  lpCommandLine);
4666  }
4667 
4668  /* Convert the Name and Directory */
4669  if (lpApplicationName)
4670  {
4672  lpApplicationName);
4673  }
4674  if (lpCurrentDirectory)
4675  {
4677  lpCurrentDirectory);
4678  }
4679 
4680  /* Now convert Startup Strings */
4681  if (lpStartupInfo->lpReserved)
4682  {
4684  &StartupInfo.lpReserved);
4685  }
4686  if (lpStartupInfo->lpDesktop)
4687  {
4689  &StartupInfo.lpDesktop);
4690  }
4691  if (lpStartupInfo->lpTitle)
4692  {
4694  &StartupInfo.lpTitle);
4695  }
4696 
4697  /* Call the Unicode function */
4698  bRetVal = CreateProcessInternalW(hToken,
4699  ApplicationName.Buffer,
4700  CommandLine.Buffer,
4701  lpProcessAttributes,
4702  lpThreadAttributes,
4703  bInheritHandles,
4704  dwCreationFlags,
4705  lpEnvironment,
4706  CurrentDirectory.Buffer,
4707  &StartupInfo,
4708  lpProcessInformation,
4709  hNewToken);
4710 
4711  /* Clean up */
4713  RtlFreeUnicodeString(&CommandLine);
4715  RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpDesktop);
4716  RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpReserved);
4717  RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpTitle);
4718 
4719  /* Return what Unicode did */
4720  return bRetVal;
4721 }
BOOL WINAPI CreateProcessInternalW(IN HANDLE hUserToken, IN LPCWSTR lpApplicationName, IN LPWSTR lpCommandLine, IN LPSECURITY_ATTRIBUTES lpProcessAttributes, IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN BOOL bInheritHandles, IN DWORD dwCreationFlags, IN LPVOID lpEnvironment, IN LPCWSTR lpCurrentDirectory, IN LPSTARTUPINFOW lpStartupInfo, IN LPPROCESS_INFORMATION lpProcessInformation, OUT PHANDLE hNewToken)
Definition: proc.c:2236
LPSTR lpTitle
Definition: winbase.h:812
LPWSTR lpReserved
Definition: winbase.h:831
WCHAR CurrentDirectory[1024]
Definition: chkdsk.c:74
VOID WINAPI BasepAnsiStringToHeapUnicodeString(IN LPCSTR AnsiString, OUT LPWSTR *UnicodeString)
Definition: utils.c:263
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
BOOLEAN WINAPI Basep8BitStringToDynamicUnicodeString(OUT PUNICODE_STRING UnicodeString, IN LPCSTR String)
Definition: utils.c:225
unsigned int BOOL
Definition: ntddk_ex.h:94
LPWSTR lpDesktop
Definition: winbase.h:832
LPWSTR lpTitle
Definition: winbase.h:833
void DPRINT(...)
Definition: polytest.cpp:61
LPSTR lpReserved
Definition: winbase.h:810
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
PVOID PVOID PWCHAR ApplicationName
Definition: env.c:45
LPSTR lpDesktop
Definition: winbase.h:811
#define NULL
Definition: types.h:112

Referenced by CreateProcessA().

◆ CreateProcessInternalW()

BOOL WINAPI CreateProcessInternalW ( IN HANDLE  hUserToken,
IN LPCWSTR  lpApplicationName,
IN LPWSTR  lpCommandLine,
IN LPSECURITY_ATTRIBUTES  lpProcessAttributes,
IN LPSECURITY_ATTRIBUTES  lpThreadAttributes,
IN BOOL  bInheritHandles,
IN DWORD  dwCreationFlags,
IN LPVOID  lpEnvironment,
IN LPCWSTR  lpCurrentDirectory,
IN LPSTARTUPINFOW  lpStartupInfo,
IN LPPROCESS_INFORMATION  lpProcessInformation,
OUT PHANDLE  hNewToken 
)

Definition at line 2236 of file proc.c.

2248 {
2249  //
2250  // Core variables used for creating the initial process and thread
2251  //
2252  SECURITY_ATTRIBUTES LocalThreadAttributes, LocalProcessAttributes;
2253  OBJECT_ATTRIBUTES LocalObjectAttributes;
2255  SECTION_IMAGE_INFORMATION ImageInformation;
2258  ULONG NoWindow, StackSize, ErrorCode, Flags;
2260  USHORT ImageMachine;
2261  ULONG ParameterFlags, PrivilegeValue, HardErrorMode, ErrorResponse;
2262  ULONG_PTR ErrorParameters[2];
2263  BOOLEAN InJob, SaferNeeded, UseLargePages, HavePrivilege;
2264  BOOLEAN QuerySection, SkipSaferAndAppCompat;
2265  CONTEXT Context;
2266  BASE_API_MESSAGE CsrMsg[2];
2267  PBASE_CREATE_PROCESS CreateProcessMsg;
2268  PCSR_CAPTURE_BUFFER CaptureBuffer;
2269  PVOID BaseAddress, PrivilegeState, RealTimePrivilegeState;
2270  HANDLE DebugHandle, TokenHandle, JobHandle, KeyHandle, ThreadHandle;
2271  HANDLE FileHandle, SectionHandle, ProcessHandle;
2273  PROCESS_PRIORITY_CLASS PriorityClass;
2274  NTSTATUS Status, AppCompatStatus, SaferStatus, IFEOStatus, ImageDbgStatus;
2275  PPEB Peb, RemotePeb;
2276  PTEB Teb;
2277  INITIAL_TEB InitialTeb;
2278  PVOID TibValue;
2279  PIMAGE_NT_HEADERS NtHeaders;
2280  STARTUPINFOW StartupInfo;
2281  PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
2282  UNICODE_STRING DebuggerString;
2283  BOOL Result;
2284  //
2285  // Variables used for command-line and argument parsing
2286  //
2287  PCHAR pcScan;
2288  SIZE_T n;
2289  WCHAR SaveChar;
2290  ULONG Length, FileAttribs, CmdQuoteLength;
2291  ULONG ResultSize;
2292  SIZE_T EnvironmentLength, CmdLineLength;
2293  PWCHAR QuotedCmdLine, AnsiCmdCommand, ExtBuffer, CurrentDirectory;
2294  PWCHAR NullBuffer, ScanString, NameBuffer, SearchPath, DebuggerCmdLine;
2295  ANSI_STRING AnsiEnv;
2296  UNICODE_STRING UnicodeEnv, PathName;
2297  BOOLEAN SearchRetry, QuotesNeeded, CmdLineIsAppName, HasQuotes;
2298 
2299  //
2300  // Variables used for Fusion/SxS (Side-by-Side Assemblies)
2301  //
2302  RTL_PATH_TYPE SxsPathType, PathType;
2303 #if _SXS_SUPPORT_ENABLED_
2304  PRTL_BUFFER ByteBuffer;
2305  PRTL_UNICODE_STRING_BUFFER ThisBuffer, Buffer, SxsStaticBuffers[5];
2306  PRTL_UNICODE_STRING_BUFFER* BufferHead, SxsStringBuffer;
2307  RTL_UNICODE_STRING_BUFFER SxsWin32ManifestPath, SxsNtManifestPath;
2308  RTL_UNICODE_STRING_BUFFER SxsWin32PolicyPath, SxsNtPolicyPath;
2309  RTL_UNICODE_STRING_BUFFER SxsWin32AssemblyDirectory;
2310  BASE_MSG_SXS_HANDLES MappedHandles, Handles, FileHandles;
2311  PVOID CapturedStrings[3];
2312  SXS_WIN32_NT_PATH_PAIR ExePathPair, ManifestPathPair, PolicyPathPair;
2313  SXS_OVERRIDE_MANIFEST OverrideManifest;
2314  UNICODE_STRING FreeString, SxsNtExePath;
2315  PWCHAR SxsConglomeratedBuffer, StaticBuffer;
2316  ULONG ConglomeratedBufferSizeBytes, StaticBufferSize, i;
2317 #endif
2319 
2320  //
2321  // Variables used for path conversion (and partially Fusion/SxS)
2322  //
2323  PWCHAR FilePart, PathBuffer, FreeBuffer;
2324  BOOLEAN TranslationStatus;
2325  RTL_RELATIVE_NAME_U SxsWin32RelativePath;
2326  UNICODE_STRING PathBufferString, SxsWin32ExePath;
2327 
2328  //
2329  // Variables used by Application Compatibility (and partially Fusion/SxS)
2330  //
2331  PVOID AppCompatSxsData, AppCompatData;
2332  ULONG AppCompatSxsDataSize, AppCompatDataSize;
2333  //
2334  // Variables used by VDM (Virtual Dos Machine) and WOW32 (16-bit Support)
2335  //
2336  ULONG BinarySubType, VdmBinaryType, VdmTask, VdmReserve;
2337  ULONG VdmUndoLevel;
2338  BOOLEAN UseVdmReserve;
2339  HANDLE VdmWaitObject;
2340  ANSI_STRING VdmAnsiEnv;
2341  UNICODE_STRING VdmString, VdmUnicodeEnv;
2342  BOOLEAN IsWowApp;
2343  PBASE_CHECK_VDM CheckVdmMsg;
2344 
2345  /* Zero out the initial core variables and handles */
2346  QuerySection = FALSE;
2347  InJob = FALSE;
2348  SkipSaferAndAppCompat = FALSE;
2349  ParameterFlags = 0;
2350  Flags = 0;
2351  DebugHandle = NULL;
2352  JobHandle = NULL;
2353  TokenHandle = NULL;
2354  FileHandle = NULL;
2355  SectionHandle = NULL;
2356  ProcessHandle = NULL;
2357  ThreadHandle = NULL;
2358  BaseAddress = (PVOID)1;
2359 
2360  /* Zero out initial SxS and Application Compatibility state */
2361  AppCompatData = NULL;
2362  AppCompatDataSize = 0;
2363  AppCompatSxsData = NULL;
2364  AppCompatSxsDataSize = 0;
2365  CaptureBuffer = NULL;
2366 #if _SXS_SUPPORT_ENABLED_
2367  SxsConglomeratedBuffer = NULL;
2368 #endif
2369  FusionFlags = 0;
2370 
2371  /* Zero out initial parsing variables -- others are initialized later */
2372  DebuggerCmdLine = NULL;
2373  PathBuffer = NULL;
2374  SearchPath = NULL;
2375  NullBuffer = NULL;
2376  FreeBuffer = NULL;
2377  NameBuffer = NULL;
2379  FilePart = NULL;
2380  DebuggerString.Buffer = NULL;
2381  HasQuotes = FALSE;
2382  QuotedCmdLine = NULL;
2383 
2384  /* Zero out initial VDM state */
2385  VdmAnsiEnv.Buffer = NULL;
2386  VdmUnicodeEnv.Buffer = NULL;
2387  VdmString.Buffer = NULL;
2388  VdmTask = 0;
2389  VdmUndoLevel = 0;
2390  VdmBinaryType = 0;
2391  VdmReserve = 0;
2392  VdmWaitObject = NULL;
2393  UseVdmReserve = FALSE;
2394  IsWowApp = FALSE;
2395 
2396  /* Set message structures */
2397  CreateProcessMsg = &CsrMsg[0].Data.CreateProcessRequest;
2398  CheckVdmMsg = &CsrMsg[1].Data.CheckVDMRequest;
2399 
2400  /* Clear the more complex structures by zeroing out their entire memory */
2401  RtlZeroMemory(&Context, sizeof(Context));
2402 #if _SXS_SUPPORT_ENABLED_
2403  RtlZeroMemory(&FileHandles, sizeof(FileHandles));
2404  RtlZeroMemory(&MappedHandles, sizeof(MappedHandles));
2405  RtlZeroMemory(&Handles, sizeof(Handles));
2406 #endif
2407  RtlZeroMemory(&CreateProcessMsg->Sxs, sizeof(CreateProcessMsg->Sxs));
2408  RtlZeroMemory(&LocalProcessAttributes, sizeof(LocalProcessAttributes));
2409  RtlZeroMemory(&LocalThreadAttributes, sizeof(LocalThreadAttributes));
2410 
2411  /* Zero out output arguments as well */
2412  RtlZeroMemory(lpProcessInformation, sizeof(*lpProcessInformation));
2413  if (hNewToken) *hNewToken = NULL;
2414 
2415  /* Capture the special window flag */
2416  NoWindow = dwCreationFlags & CREATE_NO_WINDOW;
2417  dwCreationFlags &= ~CREATE_NO_WINDOW;
2418 
2419 #if _SXS_SUPPORT_ENABLED_
2420  /* Setup the SxS static string arrays and buffers */
2421  SxsStaticBuffers[0] = &SxsWin32ManifestPath;
2422  SxsStaticBuffers[1] = &SxsWin32PolicyPath;
2423  SxsStaticBuffers[2] = &SxsWin32AssemblyDirectory;
2424  SxsStaticBuffers[3] = &SxsNtManifestPath;
2425  SxsStaticBuffers[4] = &SxsNtPolicyPath;
2426  ExePathPair.Win32 = &SxsWin32ExePath;
2427  ExePathPair.Nt = &SxsNtExePath;
2428  ManifestPathPair.Win32 = &SxsWin32ManifestPath.String;
2429  ManifestPathPair.Nt = &SxsNtManifestPath.String;
2430  PolicyPathPair.Win32 = &SxsWin32PolicyPath.String;
2431  PolicyPathPair.Nt = &SxsNtPolicyPath.String;
2432 #endif
2433 
2434  DPRINT("CreateProcessInternalW: '%S' '%S' %lx\n", lpApplicationName, lpCommandLine, dwCreationFlags);
2435 
2436  /* Finally, set our TEB and PEB */
2437  Teb = NtCurrentTeb();
2438  Peb = NtCurrentPeb();
2439 
2440  /* This combination is illegal (see MSDN) */
2441  if ((dwCreationFlags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE)) ==
2443  {
2444  DPRINT1("Invalid flag combo used\n");
2446  return FALSE;
2447  }
2448 
2449  /* Convert the priority class */
2450  if (dwCreationFlags & IDLE_PRIORITY_CLASS)
2451  {
2453  }
2454  else if (dwCreationFlags & BELOW_NORMAL_PRIORITY_CLASS)
2455  {
2457  }
2458  else if (dwCreationFlags & NORMAL_PRIORITY_CLASS)
2459  {
2461  }
2462  else if (dwCreationFlags & ABOVE_NORMAL_PRIORITY_CLASS)
2463  {
2465  }
2466  else if (dwCreationFlags & HIGH_PRIORITY_CLASS)
2467  {
2469  }
2470  else if (dwCreationFlags & REALTIME_PRIORITY_CLASS)
2471  {
2473  PriorityClass.PriorityClass += (BasepIsRealtimeAllowed(FALSE) != NULL);
2474  }
2475  else
2476  {
2478  }
2479 
2480  /* Done with the priority masks, so get rid of them */
2481  PriorityClass.Foreground = FALSE;
2482  dwCreationFlags &= ~(NORMAL_PRIORITY_CLASS |
2488 
2489  /* You cannot request both a shared and a separate WoW VDM */
2490  if ((dwCreationFlags & CREATE_SEPARATE_WOW_VDM) &&
2491  (dwCreationFlags & CREATE_SHARED_WOW_VDM))
2492  {
2493  /* Fail such nonsensical attempts */
2494  DPRINT1("Invalid WOW flags\n");
2496  return FALSE;
2497  }
2498  else if (!(dwCreationFlags & CREATE_SHARED_WOW_VDM) &&
2500  {
2501  /* A shared WoW VDM was not requested but system enforces separation */
2502  dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
2503  }
2504 
2505  /* If a shared WoW VDM is used, make sure the process isn't in a job */
2506  if (!(dwCreationFlags & CREATE_SEPARATE_WOW_VDM) &&
2508  {
2509  /* Remove the shared flag and add the separate flag */
2510  dwCreationFlags = (dwCreationFlags &~ CREATE_SHARED_WOW_VDM) |
2512  }
2513 
2514  /* Convert the environment */
2515  if ((lpEnvironment) && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
2516  {
2517  /* Scan the environment to calculate its Unicode size */
2518  AnsiEnv.Buffer = pcScan = (PCHAR)lpEnvironment;
2519  while ((*pcScan) || (*(pcScan + 1))) ++pcScan;
2520 
2521  /* Make sure the environment is not too large */
2522  EnvironmentLength = (pcScan + sizeof(ANSI_NULL) - (PCHAR)lpEnvironment);
2523  if (EnvironmentLength > MAXUSHORT)
2524  {
2525  /* Fail */
2527  return FALSE;
2528  }
2529 
2530  /* Create our ANSI String */
2531  AnsiEnv.Length = (USHORT)EnvironmentLength;
2532  AnsiEnv.MaximumLength = AnsiEnv.Length + sizeof(ANSI_NULL);
2533 
2534  /* Allocate memory for the Unicode Environment */
2535  UnicodeEnv.Buffer = NULL;
2536  RegionSize = AnsiEnv.MaximumLength * sizeof(WCHAR);
2538  (PVOID)&UnicodeEnv.Buffer,
2539  0,
2540  &RegionSize,
2541  MEM_COMMIT,
2542  PAGE_READWRITE);
2543  if (!NT_SUCCESS(Status))
2544  {
2545  /* Fail */
2547  return FALSE;
2548  }
2549 
2550  /* Use the allocated size and convert */
2551  UnicodeEnv.MaximumLength = (USHORT)RegionSize;
2552  Status = RtlAnsiStringToUnicodeString(&UnicodeEnv, &AnsiEnv, FALSE);
2553  if (!NT_SUCCESS(Status))
2554  {
2555  /* Fail */
2557  (PVOID)&UnicodeEnv.Buffer,
2558  &RegionSize,
2559  MEM_RELEASE);
2561  return FALSE;
2562  }
2563 
2564  /* Now set the Unicode environment as the environment string pointer */
2565  lpEnvironment = UnicodeEnv.Buffer;
2566  }
2567 
2568  /* Make a copy of the caller's startup info since we'll modify it */
2569  StartupInfo = *lpStartupInfo;
2570 
2571  /* Check if private data is being sent on the same channel as std handles */
2572  if ((StartupInfo.dwFlags & STARTF_USESTDHANDLES) &&
2573  (StartupInfo.dwFlags & (STARTF_USEHOTKEY | STARTF_SHELLPRIVATE)))
2574  {
2575  /* Cannot use the std handles since we have monitor/hotkey values */
2576  StartupInfo.dwFlags &= ~STARTF_USESTDHANDLES;
2577  }
2578 
2579  /* If there's a debugger, or we have to launch cmd.exe, we go back here */
2580 AppNameRetry:
2581  /* New iteration -- free any existing name buffer */
2582  if (NameBuffer)
2583  {
2584  RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
2585  NameBuffer = NULL;
2586  }
2587 
2588  /* New iteration -- free any existing free buffer */
2589  if (FreeBuffer)
2590  {
2591  RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer);
2592  FreeBuffer = NULL;
2593  }
2594 
2595  /* New iteration -- close any existing file handle */
2596  if (FileHandle)
2597  {
2599  FileHandle = NULL;
2600  }
2601 
2602  /* Set the initial parsing state. This code can loop -- don't move this! */
2603  ErrorCode = 0;
2604  SearchRetry = TRUE;
2605  QuotesNeeded = FALSE;
2606  CmdLineIsAppName = FALSE;
2607 
2608  /* First check if we don't have an application name */
2609  if (!lpApplicationName)
2610  {
2611  /* This should be the first time we attempt creating one */
2612  ASSERT(NameBuffer == NULL);
2613 
2614  /* Allocate a buffer to hold it */
2615  NameBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
2616  0,
2617  MAX_PATH * sizeof(WCHAR));
2618  if (!NameBuffer)
2619  {
2621  Result = FALSE;
2622  goto Quickie;
2623  }
2624 
2625  /* Initialize the application name and our parsing parameters */
2626  lpApplicationName = NullBuffer = ScanString = lpCommandLine;
2627 
2628  /* Check for an initial quote*/
2629  if (*lpCommandLine == L'\"')
2630  {
2631  /* We found a quote, keep searching for another one */
2632  SearchRetry = FALSE;
2633  ScanString++;
2634  lpApplicationName = ScanString;
2635  while (*ScanString)
2636  {
2637  /* Have we found the terminating quote? */
2638  if (*ScanString == L'\"')
2639  {
2640  /* We're done, get out of here */
2641  NullBuffer = ScanString;
2642  HasQuotes = TRUE;
2643  break;
2644  }
2645 
2646  /* Keep searching for the quote */
2647  ScanString++;
2648  NullBuffer = ScanString;
2649  }
2650  }
2651  else
2652  {
2653 StartScan:
2654  /* We simply make the application name be the command line*/
2655  lpApplicationName = lpCommandLine;
2656  while (*ScanString)
2657  {
2658  /* Check if it starts with a space or tab */
2659  if ((*ScanString == L' ') || (*ScanString == L'\t'))
2660  {
2661  /* Break out of the search loop */
2662  NullBuffer = ScanString;
2663  break;
2664  }
2665 
2666  /* Keep searching for a space or tab */
2667  ScanString++;
2668  NullBuffer = ScanString;
2669  }
2670  }
2671 
2672  /* We have found the end of the application name, terminate it */
2673  SaveChar = *NullBuffer;
2674  *NullBuffer = UNICODE_NULL;
2675 
2676  /* New iteration -- free any existing saved path */
2677  if (SearchPath)
2678  {
2679  RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath);
2680  SearchPath = NULL;
2681  }
2682 
2683  /* Now compute the final EXE path based on the name */
2684  SearchPath = BaseComputeProcessExePath((LPWSTR)lpApplicationName);
2685  DPRINT("Search Path: %S\n", SearchPath);
2686  if (!SearchPath)
2687  {
2689  Result = FALSE;
2690  goto Quickie;
2691  }
2692 
2693  /* And search for the executable in the search path */
2695  lpApplicationName,
2696  L".exe",
2697  MAX_PATH,
2698  NameBuffer,
2699  NULL);
2700 
2701  /* Did we find it? */
2702  if ((Length) && (Length < MAX_PATH))
2703  {
2704  /* Get file attributes */
2705  FileAttribs = GetFileAttributesW(NameBuffer);
2706  if ((FileAttribs != INVALID_FILE_ATTRIBUTES) &&
2707  (FileAttribs & FILE_ATTRIBUTE_DIRECTORY))
2708  {
2709  /* This was a directory, fail later on */
2710  Length = 0;
2711  }
2712  else
2713  {
2714  /* It's a file! */
2715  Length++;
2716  }
2717  }
2718 
2719  DPRINT("Length: %lu Buffer: %S\n", Length, NameBuffer);
2720 
2721  /* Check if there was a failure in SearchPathW */
2722  if ((Length) && (Length < MAX_PATH))
2723  {
2724  /* Everything looks good, restore the name */
2725  *NullBuffer = SaveChar;
2726  lpApplicationName = NameBuffer;
2727  }
2728  else
2729  {
2730  /* Check if this was a relative path, which would explain it */
2731  PathType = RtlDetermineDosPathNameType_U(lpApplicationName);
2733  {
2734  /* This should fail, and give us a detailed LastError */
2735  FileHandle = CreateFileW(lpApplicationName,
2736  GENERIC_READ,
2737  FILE_SHARE_READ |
2739  NULL,
2740  OPEN_EXISTING,
2742  NULL);
2744  {
2745  /* It worked? Return a generic error */
2747  FileHandle = NULL;
2749  }
2750  }
2751  else
2752  {
2753  /* Path was absolute, which means it doesn't exist */
2755  }
2756 
2757  /* Did we already fail once? */
2758  if (ErrorCode)
2759  {
2760  /* Set the error code */
2762  }
2763  else
2764  {
2765  /* Not yet, cache it */
2766  ErrorCode = GetLastError();
2767  }
2768 
2769  /* Put back the command line */
2770  *NullBuffer = SaveChar;
2771  lpApplicationName = NameBuffer;
2772 
2773  /* It's possible there's whitespace in the directory name */
2774  if (!(*ScanString) || !(SearchRetry))
2775  {
2776  /* Not the case, give up completely */
2777  Result = FALSE;
2778  goto Quickie;
2779  }
2780 
2781  /* There are spaces, so keep trying the next possibility */
2782  ScanString++;
2783  NullBuffer = ScanString;
2784 
2785  /* We will have to add a quote, since there is a space */
2786  QuotesNeeded = TRUE;
2787  HasQuotes = TRUE;
2788  goto StartScan;
2789  }
2790  }
2791  else if (!(lpCommandLine) || !(*lpCommandLine))
2792  {
2793  /* We don't have a command line, so just use the application name */
2794  CmdLineIsAppName = TRUE;
2795  lpCommandLine = (LPWSTR)lpApplicationName;
2796  }
2797 
2798  /* Convert the application name to its NT path */
2799  TranslationStatus = RtlDosPathNameToRelativeNtPathName_U(lpApplicationName,
2800  &PathName,
2801  NULL,
2802  &SxsWin32RelativePath);
2803  if (!TranslationStatus)
2804  {
2805  /* Path must be invalid somehow, bail out */
2806  DPRINT1("Path translation for SxS failed\n");
2808  Result = FALSE;
2809  goto Quickie;
2810  }
2811 
2812  /* Setup the buffer that needs to be freed at the end */
2813  ASSERT(FreeBuffer == NULL);
2814  FreeBuffer = PathName.Buffer;
2815 
2816  /* Check what kind of path the application is, for SxS (Fusion) purposes */
2817  RtlInitUnicodeString(&SxsWin32ExePath, lpApplicationName);
2818  SxsPathType = RtlDetermineDosPathNameType_U(lpApplicationName);
2819  if ((SxsPathType != RtlPathTypeDriveAbsolute) &&
2820  (SxsPathType != RtlPathTypeLocalDevice) &&
2821  (SxsPathType != RtlPathTypeRootLocalDevice) &&
2822  (SxsPathType != RtlPathTypeUncAbsolute))
2823  {
2824  /* Relative-type path, get the full path */
2825  RtlInitEmptyUnicodeString(&PathBufferString, NULL, 0);
2826  Status = RtlGetFullPathName_UstrEx(&SxsWin32ExePath,
2827  NULL,
2828  &PathBufferString,
2829  NULL,
2830  NULL,
2831  NULL,
2832  &SxsPathType,
2833  NULL);
2834  if (!NT_SUCCESS(Status))
2835  {
2836  /* Fail the rest of the create */
2837  RtlReleaseRelativeName(&SxsWin32RelativePath);
2839  Result = FALSE;
2840  goto Quickie;
2841  }
2842 
2843  /* Use this full path as the SxS path */
2844  SxsWin32ExePath = PathBufferString;
2845  PathBuffer = PathBufferString.Buffer;
2846  PathBufferString.Buffer = NULL;
2847  DPRINT("SxS Path: %S\n", PathBuffer);
2848  }
2849 
2850  /* Also set the .EXE path based on the path name */
2851 #if _SXS_SUPPORT_ENABLED_
2852  SxsNtExePath = PathName;
2853 #endif
2854  if (SxsWin32RelativePath.RelativeName.Length)
2855  {
2856  /* If it's relative, capture the relative name */
2857  PathName = SxsWin32RelativePath.RelativeName;
2858  }
2859  else
2860  {
2861  /* Otherwise, it's absolute, make sure no relative dir is used */
2862  SxsWin32RelativePath.ContainingDirectory = NULL;
2863  }
2864 
2865  /* Now use the path name, and the root path, to try opening the app */
2866  DPRINT("Path: %wZ. Dir: %p\n", &PathName, SxsWin32RelativePath.ContainingDirectory);
2867  InitializeObjectAttributes(&LocalObjectAttributes,
2868  &PathName,
2870  SxsWin32RelativePath.ContainingDirectory,
2871  NULL);
2873  SYNCHRONIZE |
2875  FILE_READ_DATA |
2876  FILE_EXECUTE,
2877  &LocalObjectAttributes,
2878  &IoStatusBlock,
2882  if (!NT_SUCCESS(Status))
2883  {
2884  /* Try to open the app just for execute purposes instead */
2887  &LocalObjectAttributes,
2888  &IoStatusBlock,
2892  }
2893 
2894  /* Failure path, display which file failed to open */
2895  if (!NT_SUCCESS(Status))
2896  DPRINT1("Open file failed: %lx (%wZ)\n", Status, &PathName);
2897 
2898  /* Cleanup in preparation for failure or success */
2899  RtlReleaseRelativeName(&SxsWin32RelativePath);
2900 
2901  if (!NT_SUCCESS(Status))
2902  {
2903  /* Failure path, try to understand why */
2904  if (RtlIsDosDeviceName_U(lpApplicationName))
2905  {
2906  /* If a device is being executed, return this special error code */
2908  Result = FALSE;
2909  goto Quickie;
2910  }
2911  else
2912  {
2913  /* Otherwise return the converted NT error code */
2915  Result = FALSE;
2916  goto Quickie;
2917  }
2918  }
2919 
2920  /* Did the caller specify a desktop? */
2921  if (!StartupInfo.lpDesktop)
2922  {
2923  /* Use the one from the current process */
2925  }
2926 
2927  /* Create a section for this file */
2928  Status = NtCreateSection(&SectionHandle,
2930  NULL,
2931  NULL,
2932  PAGE_EXECUTE,
2933  SEC_IMAGE,
2934  FileHandle);
2935  DPRINT("Section status: %lx\n", Status);
2936  if (NT_SUCCESS(Status))
2937  {
2938  /* Are we running on Windows Embedded, Datacenter, Blade or Starter? */
2939  if (SharedUserData->SuiteMask & (VER_SUITE_EMBEDDEDNT |
2942  VER_SUITE_BLADE))
2943  {
2944  /* These SKUs do not allow running certain applications */
2947  {
2948  /* And this is one of them! */
2949  DPRINT1("Invalid Blade hashes!\n");
2951  Result = FALSE;
2952  goto Quickie;
2953  }
2954 
2955  /* Did we get some other failure? */
2956  if (!NT_SUCCESS(Status))
2957  {
2958  /* If we couldn't check the hashes, assume nefariousness */
2959  DPRINT1("Tampered Blade hashes!\n");
2961  Result = FALSE;
2962  goto Quickie;
2963  }
2964  }
2965 
2966  /* Now do Winsafer, etc, checks */
2967  Status = BasepIsProcessAllowed((LPWSTR)lpApplicationName);
2968  if (!NT_SUCCESS(Status))
2969  {
2970  /* Fail if we're not allowed to launch the process */
2971  DPRINT1("Process not allowed to launch: %lx\n", Status);
2973  if (SectionHandle)
2974  {
2975  NtClose(SectionHandle);
2976  SectionHandle = NULL;
2977  }
2978  Result = FALSE;
2979  goto Quickie;
2980  }
2981 
2982  /* Is a DOS VDM being forced, but we already have a WOW32 instance ready? */
2983  if ((dwCreationFlags & CREATE_FORCEDOS) &&
2985  {
2986  /* This request can't be satisfied, instead, a separate VDM is needed */
2987  dwCreationFlags &= ~(CREATE_FORCEDOS | CREATE_SHARED_WOW_VDM);
2988  dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
2989 
2990  /* Set a failure code, ask for VDM reservation */
2992  UseVdmReserve = TRUE;
2993 
2994  /* Close the current handle */
2995  NtClose(SectionHandle);
2996  SectionHandle = NULL;
2997 
2998  /* Don't query the section later */
2999  QuerySection = FALSE;
3000  }
3001  }
3002 
3003  /* Did we already do these checks? */
3004  if (!SkipSaferAndAppCompat)
3005  {
3006  /* Is everything OK so far, OR do we have an non-MZ, non-DOS app? */
3007  if ((NT_SUCCESS(Status)) ||
3009  !(BaseIsDosApplication(&PathName, Status))))
3010  {
3011  /* Clear the machine type in case of failure */
3012  ImageMachine = 0;
3013 
3014  /* Clean any app compat data that may have accumulated */
3015  BasepFreeAppCompatData(AppCompatData, AppCompatSxsData);
3016  AppCompatData = NULL;
3017  AppCompatSxsData = NULL;
3018 
3019  /* Do we have a section? */
3020  if (SectionHandle)
3021  {
3022  /* Have we already queried it? */
3023  if (QuerySection)
3024  {
3025  /* Nothing to do */
3026  AppCompatStatus = STATUS_SUCCESS;
3027  }
3028  else
3029  {
3030  /* Get some information about the executable */
3031  AppCompatStatus = NtQuerySection(SectionHandle,
3033  &ImageInformation,
3034  sizeof(ImageInformation),
3035  NULL);
3036  }
3037 
3038  /* Do we have section information now? */
3039  if (NT_SUCCESS(AppCompatStatus))
3040  {
3041  /* Don't ask for it again, save the machine type */
3042  QuerySection = TRUE;
3043  ImageMachine = ImageInformation.Machine;
3044  }
3045  }
3046 
3047  /* Is there a reason/Shim we shouldn't run this application? */
3048  AppCompatStatus = BasepCheckBadapp(FileHandle,
3049  FreeBuffer,
3050  lpEnvironment,
3051  ImageMachine,
3052  &AppCompatData,
3053  &AppCompatDataSize,
3054  &AppCompatSxsData,
3055  &AppCompatSxsDataSize,
3056  &FusionFlags);
3057  if (!NT_SUCCESS(AppCompatStatus))
3058  {
3059  /* This is usually the status we get back */
3060  DPRINT1("App compat launch failure: %lx\n", AppCompatStatus);
3061  if (AppCompatStatus == STATUS_ACCESS_DENIED)
3062  {
3063  /* Convert it to something more Win32-specific */
3065  }
3066  else
3067  {
3068  /* Some other error */
3069  BaseSetLastNTError(AppCompatStatus);
3070  }
3071 
3072  /* Did we have a section? */
3073  if (SectionHandle)
3074  {
3075  /* Clean it up */
3076  NtClose(SectionHandle);
3077  SectionHandle = NULL;
3078  }
3079 
3080  /* Fail the call */
3081  Result = FALSE;
3082  goto Quickie;
3083  }
3084  }
3085  }
3086 
3087  //ASSERT((dwFusionFlags & ~SXS_APPCOMPACT_FLAG_APP_RUNNING_SAFEMODE) == 0);
3088 
3089  /* Have we already done, and do we need to do, SRP (WinSafer) checks? */
3090  if (!(SkipSaferAndAppCompat) &&
3091  ~(dwCreationFlags & CREATE_PRESERVE_CODE_AUTHZ_LEVEL))
3092  {
3093  /* Assume yes */
3094  SaferNeeded = TRUE;
3095  switch (Status)
3096  {
3101  /* For all DOS, 16-bit, OS/2 images, we do*/
3102  break;
3103 
3105  /* For invalid files, we don't, unless it's a .BAT file */
3106  if (BaseIsDosApplication(&PathName, Status)) break;
3107 
3108  default:
3109  /* Any other error codes we also don't */
3110  if (!NT_SUCCESS(Status))
3111  {
3112  SaferNeeded = FALSE;
3113  }
3114 
3115  /* But for success, we do */
3116  break;
3117  }
3118 
3119  /* Okay, so what did the checks above result in? */
3120  if (SaferNeeded)
3121  {
3122  /* We have to call into the WinSafer library and actually check */
3124  (LPWSTR)lpApplicationName,
3125  FileHandle,
3126  &InJob,
3127  &TokenHandle,
3128  &JobHandle);
3129  if (SaferStatus == 0xFFFFFFFF)
3130  {
3131  /* Back in 2003, they didn't have an NTSTATUS for this... */
3132  DPRINT1("WinSafer blocking process launch\n");
3134  Result = FALSE;
3135  goto Quickie;
3136  }
3137 
3138  /* Other status codes are not-Safer related, just convert them */
3139  if (!NT_SUCCESS(SaferStatus))
3140  {
3141  DPRINT1("Error checking WinSafer: %lx\n", SaferStatus);
3142  BaseSetLastNTError(SaferStatus);
3143  Result = FALSE;
3144  goto Quickie;
3145  }
3146  }
3147  }
3148 
3149  /* The last step is to figure out why the section object was not created */
3150  switch (Status)
3151  {
3153  {
3154  /* 16-bit binary. Should we use WOW or does the caller force VDM? */
3155  if (!(dwCreationFlags & CREATE_FORCEDOS))
3156  {
3157  /* Remember that we're launching WOW */
3158  IsWowApp = TRUE;
3159 
3160  /* Create the VDM environment, it's valid for WOW too */
3161  Result = BaseCreateVDMEnvironment(lpEnvironment,
3162  &VdmAnsiEnv,
3163  &VdmUnicodeEnv);
3164  if (!Result)
3165  {
3166  DPRINT1("VDM environment for WOW app failed\n");
3167  goto Quickie;
3168  }
3169 
3170  /* We're going to try this twice, so do a loop */
3171  while (TRUE)
3172  {
3173  /* Pick which kind of WOW mode we want to run in */
3174  VdmBinaryType = (dwCreationFlags &
3177 
3178  /* Get all the VDM settings and current status */
3179  Status = BaseCheckVDM(VdmBinaryType,
3180  lpApplicationName,
3181  lpCommandLine,
3182  lpCurrentDirectory,
3183  &VdmAnsiEnv,
3184  &CsrMsg[1],
3185  &VdmTask,
3186  dwCreationFlags,
3187  &StartupInfo,
3188  hUserToken);
3189 
3190  /* If it worked, no need to try again */
3191  if (NT_SUCCESS(Status)) break;
3192 
3193  /* Check if it's disallowed or if it's our second time */
3195  if ((Status == STATUS_VDM_DISALLOWED) ||
3196  (VdmBinaryType == BINARY_TYPE_SEPARATE_WOW) ||
3198  {
3199  /* Fail the call -- we won't try again */
3200  DPRINT1("VDM message failure for WOW: %lx\n", Status);
3201  Result = FALSE;
3202  goto Quickie;
3203  }
3204 
3205  /* Try one more time, but with a separate WOW instance */
3206  dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
3207  }
3208 
3209  /* Check which VDM state we're currently in */
3210  switch (CheckVdmMsg->VDMState & (VDM_NOT_LOADED |
3211  VDM_NOT_READY |
3212  VDM_READY))
3213  {
3214  case VDM_NOT_LOADED:
3215  /* VDM is not fully loaded, so not that much to undo */
3216  VdmUndoLevel = VDM_UNDO_PARTIAL;
3217 
3218  /* Reset VDM reserve if needed */
3219  if (UseVdmReserve) VdmReserve = 1;
3220 
3221  /* Get the required parameters and names for launch */
3222  Result = BaseGetVdmConfigInfo(lpCommandLine,
3223  VdmTask,
3224  VdmBinaryType,
3225  &VdmString,
3226  &VdmReserve);
3227  if (!Result)
3228  {
3229  DPRINT1("VDM Configuration failed for WOW\n");
3231  goto Quickie;
3232  }
3233 
3234  /* Update the command-line with the VDM one instead */
3235  lpCommandLine = VdmString.Buffer;
3236  lpApplicationName = NULL;
3237 
3238  /* We don't want a console, detachment, nor a window */
3239  dwCreationFlags |= CREATE_NO_WINDOW;
3240  dwCreationFlags &= ~(CREATE_NEW_CONSOLE | DETACHED_PROCESS);
3241 
3242  /* Force feedback on */
3243  StartupInfo.dwFlags |= STARTF_FORCEONFEEDBACK;
3244  break;
3245 
3246 
3247  case VDM_READY:
3248  /* VDM is ready, so we have to undo everything */
3249  VdmUndoLevel = VDM_UNDO_REUSE;
3250 
3251  /* Check if CSRSS wants us to wait on VDM */
3252  VdmWaitObject = CheckVdmMsg->WaitObjectForParent;
3253  break;
3254 
3255  case VDM_NOT_READY:
3256  /* Something is wrong with VDM, we'll fail the call */
3257  DPRINT1("VDM is not ready for WOW\n");
3259  Result = FALSE;
3260  goto Quickie;
3261 
3262  default:
3263  break;
3264  }
3265 
3266  /* Since to get NULL, we allocate from 0x1, account for this */
3267  VdmReserve--;
3268 
3269  /* This implies VDM is ready, so skip everything else */
3270  if (VdmWaitObject) goto VdmShortCircuit;
3271 
3272  /* Don't inherit handles since we're doing VDM now */
3273  bInheritHandles = FALSE;
3274 
3275  /* Had the user passed in environment? If so, destroy it */
3276  if ((lpEnvironment) &&
3277  !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
3278  {
3279  RtlDestroyEnvironment(lpEnvironment);
3280  }
3281 
3282  /* We've already done all these checks, don't do them again */
3283  SkipSaferAndAppCompat = TRUE;
3284  goto AppNameRetry;
3285  }
3286 
3287  // There is no break here on purpose, so FORCEDOS drops down!
3288  }
3289 
3293  {
3294  /* We're launching an executable application */
3295  BinarySubType = BINARY_TYPE_EXE;
3296 
3297  /* We can drop here from other "cases" above too, so check */
3300  (BinarySubType = BaseIsDosApplication(&PathName, Status)))
3301  {
3302  /* We're launching a DOS application */
3303  VdmBinaryType = BINARY_TYPE_DOS;
3304 
3305  /* Based on the caller environment, create a VDM one */
3306  Result = BaseCreateVDMEnvironment(lpEnvironment,
3307  &VdmAnsiEnv,
3308  &VdmUnicodeEnv);
3309  if (!Result)
3310  {
3311  DPRINT1("VDM environment for DOS failed\n");
3312  goto Quickie;
3313  }
3314 
3315  /* Check the current state of the VDM subsystem */
3316  Status = BaseCheckVDM(VdmBinaryType | BinarySubType,
3317  lpApplicationName,
3318  lpCommandLine,
3319  lpCurrentDirectory,
3320  &VdmAnsiEnv,
3321  &CsrMsg[1],
3322  &VdmTask,
3323  dwCreationFlags,
3324  &StartupInfo,
3325  NULL);
3326  if (!NT_SUCCESS(Status))
3327  {
3328  /* Failed to inquire about VDM, fail the call */
3329  DPRINT1("VDM message failure for DOS: %lx\n", Status);
3331  Result = FALSE;
3332  goto Quickie;
3333  };
3334 
3335  /* Handle possible VDM states */
3336  switch (CheckVdmMsg->VDMState & (VDM_NOT_LOADED |
3337  VDM_NOT_READY |
3338  VDM_READY))
3339  {
3340  case VDM_NOT_LOADED:
3341  /* If VDM is not loaded, we'll do a partial undo */
3342  VdmUndoLevel = VDM_UNDO_PARTIAL;
3343 
3344  /* A VDM process can't also be detached, so fail */
3345  if (dwCreationFlags & DETACHED_PROCESS)
3346  {
3347  DPRINT1("Detached process but no VDM, not allowed\n");
3349  return FALSE;
3350  }
3351 
3352  /* Get the required parameters and names for launch */
3353  Result = BaseGetVdmConfigInfo(lpCommandLine,
3354  VdmTask,
3355  VdmBinaryType,
3356  &VdmString,
3357  &VdmReserve);
3358  if (!Result)
3359  {
3360  DPRINT1("VDM Configuration failed for DOS\n");
3362  goto Quickie;
3363  }
3364 
3365  /* Update the command-line to launch VDM instead */
3366  lpCommandLine = VdmString.Buffer;
3367  lpApplicationName = NULL;
3368  break;
3369 
3370  case VDM_READY:
3371  /* VDM is ready, so we have to undo everything */
3372  VdmUndoLevel = VDM_UNDO_REUSE;
3373 
3374  /* Check if CSRSS wants us to wait on VDM */
3375  VdmWaitObject = CheckVdmMsg->WaitObjectForParent;
3376  break;
3377 
3378  case VDM_NOT_READY:
3379  /* Something is wrong with VDM, we'll fail the call */
3380  DPRINT1("VDM is not ready for DOS\n");
3382  Result = FALSE;
3383  goto Quickie;
3384 
3385  default:
3386  break;
3387  }
3388 
3389  /* Since to get NULL, we allocate from 0x1, account for this */
3390  VdmReserve--;
3391 
3392  /* This implies VDM is ready, so skip everything else */
3393  if (VdmWaitObject) goto VdmShortCircuit;
3394 
3395  /* Don't inherit handles since we're doing VDM now */
3396  bInheritHandles = FALSE;
3397 
3398  /* Had the user passed in environment? If so, destroy it */
3399  if ((lpEnvironment) &&
3400  !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
3401  {
3402  RtlDestroyEnvironment(lpEnvironment);
3403  }
3404 
3405  /* Use our VDM Unicode environment instead */
3406  lpEnvironment = VdmUnicodeEnv.Buffer;
3407  }
3408  else
3409  {
3410  /* It's a batch file, get the extension */
3411  ExtBuffer = &PathName.Buffer[PathName.Length / sizeof(WCHAR) - 4];
3412 
3413  /* Make sure the extensions are correct */
3414  if ((PathName.Length < (4 * sizeof(WCHAR))) ||
3415  ((_wcsnicmp(ExtBuffer, L".bat", 4)) &&
3416  (_wcsnicmp(ExtBuffer, L".cmd", 4))))
3417  {
3418  DPRINT1("'%wZ': Invalid EXE, and not a batch or script file\n", &PathName);
3420  Result = FALSE;
3421  goto Quickie;
3422  }
3423 
3424  /* Check if we need to account for quotes around the path */
3425  CmdQuoteLength = CmdLineIsAppName || HasQuotes;
3426  if (!CmdLineIsAppName)
3427  {
3428  if (HasQuotes) CmdQuoteLength++;
3429  }
3430  else
3431  {
3432  CmdQuoteLength++;
3433  }
3434 
3435  /* Calculate the length of the command line */
3436  CmdLineLength = wcslen(lpCommandLine);
3437  CmdLineLength += wcslen(CMD_STRING);
3438  CmdLineLength += CmdQuoteLength + sizeof(ANSI_NULL);
3439  CmdLineLength *= sizeof(WCHAR);
3440 
3441  /* Allocate space for the new command line */
3442  AnsiCmdCommand = RtlAllocateHeap(RtlGetProcessHeap(),
3443  0,
3444  CmdLineLength);
3445  if (!AnsiCmdCommand)
3446  {
3448  Result = FALSE;
3449  goto Quickie;
3450  }
3451 
3452  /* Build it */
3453  wcscpy(AnsiCmdCommand, CMD_STRING);
3454  if ((CmdLineIsAppName) || (HasQuotes))
3455  {
3456  wcscat(AnsiCmdCommand, L"\"");
3457  }
3458  wcscat(AnsiCmdCommand, lpCommandLine);
3459  if ((CmdLineIsAppName) || (HasQuotes))
3460  {
3461  wcscat(AnsiCmdCommand, L"\"");
3462  }
3463 
3464  /* Create it as a Unicode String */
3465  RtlInitUnicodeString(&DebuggerString, AnsiCmdCommand);
3466 
3467  /* Set the command line to this */
3468  lpCommandLine = DebuggerString.Buffer;
3469  lpApplicationName = NULL;
3470  DPRINT1("Retrying with: %S\n", lpCommandLine);
3471  }
3472 
3473  /* We've already done all these checks, don't do them again */
3474  SkipSaferAndAppCompat = TRUE;
3475  goto AppNameRetry;
3476  }
3477 
3479  {
3480  /* 64-bit binaries are not allowed to run on 32-bit ReactOS */
3481  DPRINT1("64-bit binary, failing\n");
3483  Result = FALSE;
3484  goto Quickie;
3485  }
3486 
3488  {
3489  /* Set the correct last error for this */
3490  DPRINT1("File is offline, failing\n");
3492  break;
3493  }
3494 
3495  default:
3496  {
3497  /* Any other error, convert it to a generic Win32 error */
3498  if (!NT_SUCCESS(Status))
3499  {
3500  DPRINT1("Failed to create section: %lx\n", Status);
3502  Result = FALSE;
3503  goto Quickie;
3504  }
3505 
3506  /* Otherwise, this must be success */
3508  break;
3509  }
3510  }
3511 
3512  /* Is this not a WOW application, but a WOW32 VDM was requested for it? */
3513  if (!(IsWowApp) && (dwCreationFlags & CREATE_SEPARATE_WOW_VDM))
3514  {
3515  /* Ignore the nonsensical request */
3516  dwCreationFlags &= ~CREATE_SEPARATE_WOW_VDM;
3517  }
3518 
3519  /* Did we already check information for the section? */
3520  if (!QuerySection)
3521  {
3522  /* Get some information about the executable */
3523  Status = NtQuerySection(SectionHandle,
3525  &ImageInformation,
3526  sizeof(ImageInformation),
3527  NULL);
3528  if (!NT_SUCCESS(Status))
3529  {
3530  /* We failed, bail out */
3531  DPRINT1("Section query failed\n");
3533  Result = FALSE;
3534  goto Quickie;
3535  }
3536 
3537  /* Don't check this later */
3538  QuerySection = TRUE;
3539  }
3540 
3541  /* Check if this was linked as a DLL */
3542  if (ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL)
3543  {
3544  /* These aren't valid images to try to execute! */
3545  DPRINT1("Trying to launch a DLL, failing\n");
3547  Result = FALSE;
3548  goto Quickie;
3549  }
3550 
3551  /* Don't let callers pass in this flag -- we'll only get it from IFEO */
3553 
3554  /* Clear the IFEO-missing flag, before we know for sure... */
3555  ParameterFlags &= ~2;
3556 
3557  /* If the process is being debugged, only read IFEO if the PEB says so */
3558  if (!(dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)) ||
3559  (NtCurrentPeb()->ReadImageFileExecOptions))
3560  {
3561  /* Let's do this! Attempt to open IFEO */
3562  IFEOStatus = LdrOpenImageFileOptionsKey(&PathName, 0, &KeyHandle);
3563  if (!NT_SUCCESS(IFEOStatus))
3564  {
3565  /* We failed, set the flag so we store this in the parameters */
3566  if (IFEOStatus == STATUS_OBJECT_NAME_NOT_FOUND) ParameterFlags |= 2;
3567  }
3568  else
3569  {
3570  /* Was this our first time going through this path? */
3571  if (!DebuggerCmdLine)
3572  {
3573  /* Allocate a buffer for the debugger path */
3574  DebuggerCmdLine = RtlAllocateHeap(RtlGetProcessHeap(),
3575  0,
3576  MAX_PATH * sizeof(WCHAR));
3577  if (!DebuggerCmdLine)
3578  {
3579  /* Close IFEO on failure */
3580  IFEOStatus = NtClose(KeyHandle);
3581  ASSERT(NT_SUCCESS(IFEOStatus));
3582 
3583  /* Fail the call */
3585  Result = FALSE;
3586  goto Quickie;
3587  }
3588  }
3589 
3590  /* Now query for the debugger */
3592  L"Debugger",
3593  REG_SZ,
3594  DebuggerCmdLine,
3595  MAX_PATH * sizeof(WCHAR),
3596  &ResultSize);
3597  if (!(NT_SUCCESS(IFEOStatus)) ||
3598  (ResultSize < sizeof(WCHAR)) ||
3599  (DebuggerCmdLine[0] == UNICODE_NULL))
3600  {
3601  /* If it's not there, or too small, or invalid, ignore it */
3602  RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine);
3603  DebuggerCmdLine = NULL;
3604  }
3605 
3606  /* Also query if we should map with large pages */
3608  L"UseLargePages",
3609  REG_DWORD,
3610  &UseLargePages,
3611  sizeof(UseLargePages),
3612  NULL);
3613  if ((NT_SUCCESS(IFEOStatus)) && (UseLargePages))
3614  {
3615  /* Do it! This is the only way this flag can be set */
3617  }
3618 
3619  /* We're done with IFEO, can close it now */
3620  IFEOStatus = NtClose(KeyHandle);
3621  ASSERT(NT_SUCCESS(IFEOStatus));
3622  }
3623  }
3624 
3625  /* Make sure the image was compiled for this processor */
3626  if ((ImageInformation.Machine < SharedUserData->ImageNumberLow) ||
3627  (ImageInformation.Machine > SharedUserData->ImageNumberHigh))
3628  {
3629  /* It was not -- raise a hard error */
3630  ErrorResponse = ResponseOk;
3631  ErrorParameters[0] = (ULONG_PTR)&PathName;
3633  1,
3634  1,
3635  ErrorParameters,
3636  OptionOk,
3637  &ErrorResponse);
3638  if (Peb->ImageSubsystemMajorVersion <= 3)
3639  {
3640  /* If it's really old, return this error */
3642  }
3643  else
3644  {
3645  /* Otherwise, return a more modern error */
3647  }
3648 
3649  /* Go to the failure path */
3650  DPRINT1("Invalid image architecture: %lx\n", ImageInformation.Machine);
3651  Result = FALSE;
3652  goto Quickie;
3653  }
3654 
3655  /* Check if this isn't a Windows image */
3656  if ((ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_GUI) &&
3657  (ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_CUI))
3658  {
3659  /* Get rid of section-related information since we'll retry */
3660  NtClose(SectionHandle);
3661  SectionHandle = NULL;
3662  QuerySection = FALSE;
3663 
3664  /* The only other non-Windows image type we support here is POSIX */
3665  if (ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_POSIX_CUI)
3666  {
3667  /* Bail out if it's something else */
3669  Result = FALSE;
3670  goto Quickie;
3671  }
3672 
3673  /* Now build the command-line to have posix launch this image */
3674  Result = BuildSubSysCommandLine(L"POSIX /P ",
3675  lpApplicationName,
3676  lpCommandLine,
3677  &DebuggerString);
3678  if (!Result)
3679  {
3680  /* Bail out if that failed */
3681  DPRINT1("Subsystem command line failed\n");
3682  goto Quickie;
3683  }
3684 
3685  /* And re-try launching the process, with the new command-line now */
3686  lpCommandLine = DebuggerString.Buffer;
3687  lpApplicationName = NULL;
3688 
3689  /* We've already done all these checks, don't do them again */
3690  SkipSaferAndAppCompat = TRUE;
3691  DPRINT1("Retrying with: %S\n", lpCommandLine);
3692  goto AppNameRetry;
3693  }
3694 
3695  /* Was this image built for a version of Windows whose images we can run? */
3697  ImageInformation.SubSystemMinorVersion);
3698  if (!Result)
3699  {
3700  /* It was not, bail out */
3701  DPRINT1("Invalid subsystem version: %hu.%hu\n",
3702  ImageInformation.SubSystemMajorVersion,
3703  ImageInformation.SubSystemMinorVersion);
3705  goto Quickie;
3706  }
3707 
3708  /* Check if there is a debugger associated with the application */
3709  if (DebuggerCmdLine)
3710  {
3711  /* Get the length of the command line */
3712  n = wcslen(lpCommandLine);
3713  if (!n)
3714  {
3715  /* There's no command line, use the application name instead */
3716  lpCommandLine = (LPWSTR)lpApplicationName;
3717  n = wcslen(lpCommandLine);
3718  }
3719 
3720  /* Protect against overflow */
3722  {
3724  Result = FALSE;
3725  goto Quickie;
3726  }
3727 
3728  /* Now add the length of the debugger command-line */
3729  n += wcslen(DebuggerCmdLine);
3730 
3731  /* Again make sure we don't overflow */
3733  {
3735  Result = FALSE;
3736  goto Quickie;
3737  }
3738 
3739  /* Account for the quotes and space between the two */
3740  n += sizeof("\" \"") - sizeof(ANSI_NULL);
3741 
3742  /* Convert to bytes, and make sure we don't overflow */
3743  n *= sizeof(WCHAR);
3745  {
3747  Result = FALSE;
3748  goto Quickie;
3749  }
3750 
3751  /* Allocate space for the string */
3752  DebuggerString.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, n);
3753  if (!DebuggerString.Buffer)
3754  {
3756  Result = FALSE;
3757  goto Quickie;
3758  }
3759 
3760  /* Set the length */
3761  RtlInitEmptyUnicodeString(&DebuggerString,
3762  DebuggerString.Buffer,
3763  (USHORT)n);
3764 
3765  /* Now perform the command line creation */
3766  ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString,
3767  DebuggerCmdLine);
3768  ASSERT(NT_SUCCESS(ImageDbgStatus));
3769  ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString, L" ");
3770  ASSERT(NT_SUCCESS(ImageDbgStatus));
3771  ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString, lpCommandLine);
3772  ASSERT(NT_SUCCESS(ImageDbgStatus));
3773 
3774  /* Make sure it all looks nice */
3775  DbgPrint("BASE: Calling debugger with '%wZ'\n", &DebuggerString);
3776 
3777  /* Update the command line and application name */
3778  lpCommandLine = DebuggerString.Buffer;
3779  lpApplicationName = NULL;
3780 
3781  /* Close all temporary state */
3782  NtClose(SectionHandle);
3783  SectionHandle = NULL;
3784  QuerySection = FALSE;
3785 
3786  /* Free all temporary memory */
3787  RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
3788  NameBuffer = NULL;
3789  RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer);
3790  FreeBuffer = NULL;
3791  RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine);
3792  DebuggerCmdLine = NULL;
3793  DPRINT1("Retrying with: %S\n", lpCommandLine);
3794  goto AppNameRetry;
3795  }
3796 
3797  /* Initialize the process object attributes */
3798  ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
3799  lpProcessAttributes,
3800  NULL);
3801  if ((hUserToken) && (lpProcessAttributes))
3802  {
3803  /* Augment them with information from the user */
3804 
3805  LocalProcessAttributes = *lpProcessAttributes;
3806  LocalProcessAttributes.lpSecurityDescriptor = NULL;
3807  ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
3808  &LocalProcessAttributes,
3809  NULL);
3810  }
3811 
3812  /* Check if we're going to be debugged */
3813  if (dwCreationFlags & DEBUG_PROCESS)
3814  {
3815  /* Set process flag */
3817  }
3818 
3819  /* Check if we're going to be debugged */
3820  if (dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
3821  {
3822  /* Connect to DbgUi */
3824  if (!NT_SUCCESS(Status))
3825  {
3826  DPRINT1("Failed to connect to DbgUI!\n");
3828  Result = FALSE;
3829  goto Quickie;
3830  }
3831 
3832  /* Get the debug object */
3833  DebugHandle = DbgUiGetThreadDebugObject();
3834 
3835  /* Check if only this process will be debugged */
3836  if (dwCreationFlags & DEBUG_ONLY_THIS_PROCESS)
3837  {
3838  /* Set process flag */
3840  }
3841  }
3842 
3843  /* Set inherit flag */
3844  if (bInheritHandles) Flags |= PROCESS_CREATE_FLAGS_INHERIT_HANDLES;
3845 
3846  /* Check if the process should be created with large pages */
3847  HavePrivilege = FALSE;
3848  PrivilegeState = NULL;
3850  {
3851  /* Acquire the required privilege so that the kernel won't fail the call */
3852  PrivilegeValue = SE_LOCK_MEMORY_PRIVILEGE;
3853  Status = RtlAcquirePrivilege(&PrivilegeValue, 1, 0, &PrivilegeState);
3854  if (NT_SUCCESS(Status))
3855  {
3856  /* Remember to release it later */
3857  HavePrivilege = TRUE;
3858  }
3859  }
3860 
3861  /* Save the current TIB value since kernel overwrites it to store PEB */
3862  TibValue = Teb->NtTib.ArbitraryUserPointer;
3863 
3864  /* Tell the kernel to create the process */
3868  NtCurrentProcess(),
3869  Flags,
3870  SectionHandle,
3871  DebugHandle,
3872  NULL,
3873  InJob);
3874 
3875  /* Load the PEB address from the hacky location where the kernel stores it */
3876  RemotePeb = Teb->NtTib.ArbitraryUserPointer;
3877 
3878  /* And restore the old TIB value */
3879  Teb->NtTib.ArbitraryUserPointer = TibValue;
3880 
3881  /* Release the large page privilege if we had acquired it */
3882  if (HavePrivilege) RtlReleasePrivilege(PrivilegeState);
3883 
3884  /* And now check if the kernel failed to create the process */
3885  if (!NT_SUCCESS(Status))
3886  {
3887  /* Go to failure path */
3888  DPRINT1("Failed to create process: %lx\n", Status);
3890  Result = FALSE;
3891  goto Quickie;
3892  }
3893 
3894  /* Check if there is a priority class to set */
3895  if (PriorityClass.PriorityClass)
3896  {
3897  /* Reset current privilege state */
3898  RealTimePrivilegeState = NULL;
3899 
3900  /* Is realtime priority being requested? */
3901  if (PriorityClass.PriorityClass == PROCESS_PRIORITY_CLASS_REALTIME)
3902  {
3903  /* Check if the caller has real-time access, and enable it if so */
3904  RealTimePrivilegeState = BasepIsRealtimeAllowed(TRUE);
3905  }
3906 
3907  /* Set the new priority class and release the privilege */
3910  &PriorityClass,
3911  sizeof(PROCESS_PRIORITY_CLASS));
3912  if (RealTimePrivilegeState) RtlReleasePrivilege(RealTimePrivilegeState);
3913 
3914  /* Check if we failed to set the priority class */
3915  if (!NT_SUCCESS(Status))
3916  {
3917  /* Bail out on failure */
3918  DPRINT1("Failed to set priority class: %lx\n", Status);
3920  Result = FALSE;
3921  goto Quickie;
3922  }
3923  }
3924 
3925  /* Check if the caller wants the default error mode */
3926  if (dwCreationFlags & CREATE_DEFAULT_ERROR_MODE)
3927  {
3928  /* Set Error Mode to only fail on critical errors */
3929  HardErrorMode = SEM_FAILCRITICALERRORS;
3932  &HardErrorMode,
3933  sizeof(ULONG));
3934  }
3935 
3936  /* Check if this was a VDM binary */
3937  if (VdmBinaryType)
3938  {
3939  /* Update VDM by telling it the process has now been created */
3940  VdmWaitObject = ProcessHandle;
3942  &VdmWaitObject,
3943  VdmTask,
3944  VdmBinaryType);
3945 
3946  if (!Result)
3947  {
3948  /* Bail out on failure */
3949  DPRINT1("Failed to update VDM with wait object\n");
3950  VdmWaitObject = NULL;
3951  goto Quickie;
3952  }
3953 
3954  /* At this point, a failure means VDM has to undo all the state */
3955  VdmUndoLevel |= VDM_UNDO_FULL;
3956  }
3957 
3958  /* Check if VDM needed reserved low-memory */
3959  if (VdmReserve)
3960  {
3961  /* Reserve the requested allocation */
3962  RegionSize = VdmReserve;
3964  &BaseAddress,
3965  0,
3966  &RegionSize,
3967  MEM_RESERVE,
3969  if (!NT_SUCCESS(Status))
3970  {
3971  /* Bail out on failure */
3972  DPRINT1("Failed to reserve memory for VDM: %lx\n", Status);
3974  Result = FALSE;
3975  goto Quickie;
3976  }
3977 
3978  VdmReserve = (ULONG)RegionSize;
3979  }
3980 
3981  /* Check if we've already queried information on the section */
3982  if (!QuerySection)
3983  {
3984  /* We haven't, so get some information about the executable */
3985  Status = NtQuerySection(SectionHandle,
3987  &ImageInformation,
3988  sizeof(ImageInformation),
3989  NULL);
3990  if (!NT_SUCCESS(Status))
3991  {
3992  /* Bail out on failure */
3993  DPRINT1("Failed to query section: %lx\n", Status);
3995  Result = FALSE;
3996  goto Quickie;
3997  }
3998 
3999  /* If we encounter a restart, don't re-query this information again */
4000  QuerySection = TRUE;
4001  }
4002 
4003  /* Do we need to apply SxS to this image? */
4005  {
4006  /* Too bad, we don't support this yet */
4007  DPRINT1("Image should receive SxS Fusion Isolation\n");
4008  }
4009 
4010  /* There's some SxS flag that we need to set if fusion flags have 1 set */
4011  if (FusionFlags & 1) CreateProcessMsg->Sxs.Flags |= 0x10;
4012 
4013  /* Check if we have a current directory */
4014  if (lpCurrentDirectory)
4015  {
4016  /* Allocate a buffer so we can keep a Unicode copy */
4017  DPRINT("Current directory: %S\n", lpCurrentDirectory);
4018  CurrentDirectory = RtlAllocateHeap(RtlGetProcessHeap(),
4019  0,
4020  (MAX_PATH * sizeof(WCHAR)) +
4021  sizeof(UNICODE_NULL));
4022  if (!CurrentDirectory)
4023  {
4024  /* Bail out if this failed */
4026  Result = FALSE;
4027  goto Quickie;
4028  }
4029 
4030  /* Get the length in Unicode */
4031  Length = GetFullPathNameW(lpCurrentDirectory,
4032  MAX_PATH,
4034  &FilePart);
4035  if (Length > MAX_PATH)
4036  {
4037  /* The directory is too long, so bail out */
4039  Result = FALSE;
4040  goto Quickie;
4041  }
4042 
4043  /* Make sure the directory is actually valid */
4044  FileAttribs = GetFileAttributesW(CurrentDirectory);
4045  if ((FileAttribs == INVALID_FILE_ATTRIBUTES) ||
4046  !(FileAttribs & FILE_ATTRIBUTE_DIRECTORY))
4047  {
4048  /* It isn't, so bail out */
4049  DPRINT1("Current directory is invalid\n");
4051  Result = FALSE;
4052  goto Quickie;
4053  }
4054  }
4055 
4056  /* Insert quotes if needed */
4057  if ((QuotesNeeded) || (CmdLineIsAppName))
4058  {
4059  /* Allocate our buffer, plus enough space for quotes and a NULL */
4060  QuotedCmdLine = RtlAllocateHeap(RtlGetProcessHeap(),
4061  0,
4062  (wcslen(lpCommandLine) * sizeof(WCHAR)) +
4063  (2 * sizeof(L'\"') + sizeof(UNICODE_NULL)));
4064  if (QuotedCmdLine)
4065  {
4066  /* Copy the first quote */
4067  wcscpy(QuotedCmdLine, L"\"");
4068 
4069  /* Save the current null-character */
4070  if (QuotesNeeded)
4071  {
4072  SaveChar = *NullBuffer;
4073  *NullBuffer = UNICODE_NULL;
4074  }
4075 
4076  /* Copy the command line and the final quote */
4077  wcscat(QuotedCmdLine, lpCommandLine);
4078  wcscat(QuotedCmdLine, L"\"");
4079 
4080  /* Copy the null-char back */
4081  if (QuotesNeeded)
4082  {
4083  *NullBuffer = SaveChar;
4084  wcscat(QuotedCmdLine, NullBuffer);
4085  }
4086  }
4087  else
4088  {
4089  /* We can't put quotes around the thing, so try it anyway */
4090  if (QuotesNeeded) QuotesNeeded = FALSE;
4091  if (CmdLineIsAppName) CmdLineIsAppName = FALSE;
4092  }
4093  }
4094 
4095  /* Use isolation if needed */
4096  if (CreateProcessMsg->Sxs.Flags & 1) ParameterFlags |= 1;
4097 
4098  /* Set the new command-line if needed */
4099  if ((QuotesNeeded) || (CmdLineIsAppName)) lpCommandLine = QuotedCmdLine;
4100 
4101  /* Call the helper function in charge of RTL_USER_PROCESS_PARAMETERS */
4102  Result = BasePushProcessParameters(ParameterFlags,
4103  ProcessHandle,
4104  RemotePeb,
4105  lpApplicationName,
4107  lpCommandLine,
4108  lpEnvironment,
4109  &StartupInfo,
4110  dwCreationFlags | NoWindow,
4111  bInheritHandles,
4112  IsWowApp ? IMAGE_SUBSYSTEM_WINDOWS_GUI: 0,
4113  AppCompatData,
4114  AppCompatDataSize);
4115  if (!Result)
4116  {
4117  /* The remote process would have an undefined state, so fail the call */
4118  DPRINT1("BasePushProcessParameters failed\n");
4119  goto Quickie;
4120  }
4121 
4122  /* Free the VDM command line string as it's no longer needed */
4123  RtlFreeUnicodeString(&VdmString);
4124  VdmString.Buffer = NULL;
4125 
4126  /* Non-VDM console applications usually inherit handles unless specified */
4127  if (!(VdmBinaryType) &&
4128  !(bInheritHandles) &&
4129  !(StartupInfo.dwFlags & STARTF_USESTDHANDLES) &&
4130  !(dwCreationFlags & (CREATE_NO_WINDOW |
4132  DETACHED_PROCESS)) &&
4133  (ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_CUI))
4134  {
4135  /* Get the remote parameters */
4137  &RemotePeb->ProcessParameters,
4138  &ProcessParameters,
4140  NULL);
4141  if (NT_SUCCESS(Status))
4142  {
4143  /* Duplicate standard input unless it's a console handle */
4145  {
4148  &ProcessParameters->StandardInput);
4149  }
4150 
4151  /* Duplicate standard output unless it's a console handle */
4153  {
4156  &ProcessParameters->StandardOutput);
4157  }
4158 
4159  /* Duplicate standard error unless it's a console handle */
4161  {
4164  &ProcessParameters->StandardError);
4165  }
4166  }
4167  }
4168 
4169  /* Create the Thread's Stack */
4170  StackSize = max(256 * 1024, ImageInformation.MaximumStackSize);
4172  ImageInformation.CommittedStackSize,
4173  StackSize,
4174  &InitialTeb);
4175  if (!NT_SUCCESS(Status))
4176  {
4177  DPRINT1("Creating the thread stack failed: %lx\n", Status);
4179  Result = FALSE;
4180  goto Quickie;
4181  }
4182 
4183  /* Create the Thread's Context */
4185  Peb,
4186  ImageInformation.TransferAddress,
4187  InitialTeb.StackBase,
4188  0);
4189 
4190  /* Convert the thread attributes */
4191  ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
4192  lpThreadAttributes,
4193  NULL);
4194  if ((hUserToken) && (lpThreadAttributes))
4195  {
4196  /* If the caller specified a user token, zero the security descriptor */
4197  LocalThreadAttributes = *lpThreadAttributes;
4198  LocalThreadAttributes.lpSecurityDescriptor = NULL;
4199  ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
4200  &LocalThreadAttributes,
4201  NULL);
4202  }
4203 
4204  /* Create the Kernel Thread Object */
4205  Status = NtCreateThread(&ThreadHandle,
4208  ProcessHandle,
4209  &ClientId,
4210  &Context,
4211  &InitialTeb,
4212  TRUE);
4213  if (!NT_SUCCESS(Status))
4214  {
4215  /* A process is not allowed to exist without a main thread, so fail */
4216  DPRINT1("Creating the main thread failed: %lx\n", Status);
4218  Result = FALSE;
4219  goto Quickie;
4220  }
4221 
4222  /* Begin filling out the CSRSS message, first with our IDs and handles */
4223  CreateProcessMsg->ProcessHandle = ProcessHandle;
4224  CreateProcessMsg->ThreadHandle = ThreadHandle;
4225  CreateProcessMsg->ClientId = ClientId;
4226 
4227  /* Write the remote PEB address and clear it locally, we no longer use it */
4228  CreateProcessMsg->PebAddressNative = RemotePeb;
4229 #ifdef _WIN64
4230  DPRINT1("TODO: WOW64 is not supported yet\n");
4231  CreateProcessMsg->PebAddressWow64 = 0;
4232 #else
4233  CreateProcessMsg->PebAddressWow64 = (ULONG)RemotePeb;
4234 #endif
4235  RemotePeb = NULL;
4236 
4237  /* Now check what kind of architecture this image was made for */
4238  switch (ImageInformation.Machine)
4239  {
4240  /* IA32, IA64 and AMD64 are supported in Server 2003 */
4243  break;
4246  break;
4249  break;
4250 
4251  /* Anything else results in image unknown -- but no failure */
4252  default:
4253  DbgPrint("kernel32: No mapping for ImageInformation.Machine == %04x\n",
4254  ImageInformation.Machine);
4256  break;
4257  }
4258 
4259  /* Write the input creation flags except any debugger-related flags */
4260  CreateProcessMsg->CreationFlags = dwCreationFlags &
4262 
4263  /* CSRSS needs to know if this is a GUI app or not */
4264  if ((ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_GUI) ||
4265  (IsWowApp))
4266  {
4267  /*
4268  * For GUI apps we turn on the 2nd bit. This allow CSRSS server dlls
4269  * (basesrv in particular) to know whether or not this is a GUI or a
4270  * TUI application.
4271  */
4272  AddToHandle(CreateProcessMsg->ProcessHandle, 2);
4273 
4274  /* Also check if the parent is also a GUI process */
4275  NtHeaders = RtlImageNtHeader(GetModuleHandle(NULL));
4276  if ((NtHeaders) &&
4278  {
4279  /* Let it know that it should display the hourglass mouse cursor */
4280  AddToHandle(CreateProcessMsg->ProcessHandle, 1);
4281  }
4282  }
4283 
4284  /* For all apps, if this flag is on, the hourglass mouse cursor is shown */
4285  if (StartupInfo.dwFlags & STARTF_FORCEONFEEDBACK)
4286  {
4287  AddToHandle(CreateProcessMsg->ProcessHandle, 1);
4288  }
4289 
4290  /* Likewise, the opposite holds as well */
4291  if (StartupInfo.dwFlags & STARTF_FORCEOFFFEEDBACK)
4292  {
4293  RemoveFromHandle(CreateProcessMsg->ProcessHandle, 1);
4294  }
4295 
4296  /* Also store which kind of VDM app (if any) this is */
4297  CreateProcessMsg->VdmBinaryType = VdmBinaryType;
4298 
4299  /* And if it really is a VDM app... */
4300  if (VdmBinaryType)
4301  {
4302  /* Store the task ID and VDM console handle */
4303  CreateProcessMsg->hVDM = VdmTask ? 0 : Peb->ProcessParameters->ConsoleHandle;
4304  CreateProcessMsg->VdmTask = VdmTask;
4305  }
4306  else if (VdmReserve)
4307  {
4308  /* Extended VDM, set a flag */
4309  CreateProcessMsg->VdmBinaryType |= BINARY_TYPE_WOW_EX;
4310  }
4311 
4312  /* Check if there's side-by-side assembly data associated with the process */
4313  if (CreateProcessMsg->Sxs.Flags)
4314  {
4315  /* This should not happen in ReactOS yet */
4316  DPRINT1("This is an SxS Message -- should not happen yet\n");
4319  Result = FALSE;
4320  goto Quickie;
4321  }
4322 
4323  /* We are finally ready to call CSRSS to tell it about our new process! */
4325  CaptureBuffer,
4328  sizeof(*CreateProcessMsg));
4329 
4330  /* CSRSS has returned, free the capture buffer now if we had one */
4331  if (CaptureBuffer)
4332  {
4333  CsrFreeCaptureBuffer(CaptureBuffer);
4334  CaptureBuffer = NULL;
4335  }
4336 
4337  /* Check if CSRSS failed to accept ownership of the new Windows process */
4338  if (!NT_SUCCESS(CsrMsg[0].Status))
4339  {
4340  /* Terminate the process and enter failure path with the CSRSS status */
4341  DPRINT1("Failed to tell csrss about new process\n");
4342  BaseSetLastNTError(CsrMsg[0].Status);
4344  Result = FALSE;
4345  goto Quickie;
4346  }
4347 
4348  /* Check if we have a token due to Authz/Safer, not passed by the user */
4349  if ((TokenHandle) && !(hUserToken))
4350  {
4351  /* Replace the process and/or thread token with the one from Safer */
4353  ProcessHandle,
4354  ThreadHandle);
4355  if (!NT_SUCCESS(Status))
4356  {
4357  /* If this failed, kill the process and enter the failure path */
4358  DPRINT1("Failed to update process token: %lx\n", Status);
4361  Result = FALSE;
4362  goto Quickie;
4363  }
4364  }
4365 
4366  /* Check if a job was associated with this process */
4367  if (JobHandle)
4368  {
4369  /* Bind the process and job together now */
4371  if (!NT_SUCCESS(Status))
4372  {
4373  /* Kill the process and enter the failure path if binding failed */
4374  DPRINT1("Failed to assign process to job: %lx\n", Status);
4377  Result = FALSE;
4378  goto Quickie;
4379  }
4380  }
4381 
4382  /* Finally, resume the thread to actually get the process started */
4383  if (!(dwCreationFlags & CREATE_SUSPENDED))
4384  {
4385  NtResumeThread(ThreadHandle, &ResumeCount);
4386  }
4387 
4388 VdmShortCircuit:
4389  /* We made it this far, meaning we have a fully created process and thread */
4390  Result = TRUE;
4391 
4392  /* Anyone doing a VDM undo should now undo everything, since we are done */
4393  if (VdmUndoLevel) VdmUndoLevel |= VDM_UNDO_COMPLETED;
4394 
4395  /* Having a VDM wait object implies this must be a VDM process */
4396  if (VdmWaitObject)
4397  {
4398  /* Check if it's a 16-bit separate WOW process */
4399  if (VdmBinaryType == BINARY_TYPE_SEPARATE_WOW)
4400  {
4401  /* OR-in the special flag to indicate this, and return to caller */
4402  AddToHandle(VdmWaitObject, 2);
4403  lpProcessInformation->hProcess = VdmWaitObject;
4404 
4405  /* Check if this was a re-used VDM */
4406  if (VdmUndoLevel & VDM_UNDO_REUSE)
4407  {
4408  /* No Client ID should be returned in this case */
4409  ClientId.UniqueProcess = 0;
4410  ClientId.UniqueThread = 0;
4411  }
4412  }
4413  else
4414  {
4415  /* OR-in the special flag to indicate this is not a separate VDM */
4416  AddToHandle(VdmWaitObject, 1);
4417 
4418  /* Return handle to the caller */
4419  lpProcessInformation->hProcess = VdmWaitObject;
4420  }
4421 
4422  /* Close the original process handle, since it's not needed for VDM */
4424  }
4425  else
4426  {
4427  /* This is a regular process, so return the real process handle */
4428  lpProcessInformation->hProcess = ProcessHandle;
4429  }
4430 
4431  /* Return the rest of the process information based on what we have so far */
4432  lpProcessInformation->hThread = ThreadHandle;
4433  lpProcessInformation->dwProcessId = HandleToUlong(ClientId.UniqueProcess);
4434  lpProcessInformation->dwThreadId = HandleToUlong(ClientId.UniqueThread);
4435 
4436  /* NULL these out here so we know to treat this as a success scenario */
4437  ProcessHandle = NULL;
4438  ThreadHandle = NULL;
4439 
4440 Quickie:
4441  /* Free the debugger command line if one was allocated */
4442  if (DebuggerCmdLine) RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine);
4443 
4444  /* Check if an SxS full path as queried */
4445  if (PathBuffer)
4446  {
4447  /* Reinitialize the executable path */
4448  RtlInitEmptyUnicodeString(&SxsWin32ExePath, NULL, 0);
4449  SxsWin32ExePath.Length = 0;
4450 
4451  /* Free the path buffer */
4452  RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
4453  }
4454 
4455 #if _SXS_SUPPORT_ENABLED_
4456  /* Check if this was a non-VDM process */
4457  if (!VdmBinaryType)
4458  {
4459  /* Then it must've had SxS data, so close the handles used for it */
4460  BasepSxsCloseHandles(&Handles);
4461  BasepSxsCloseHandles(&FileHandles);
4462 
4463  /* Check if we built SxS byte buffers for this create process request */
4464  if (SxsConglomeratedBuffer)
4465  {
4466  /* Loop all of them */
4467  for (i = 0; i < 5; i++)
4468  {
4469  /* Check if this one was allocated */
4470  ThisBuffer = SxsStaticBuffers[i];
4471  if (ThisBuffer)
4472  {
4473  /* Get the underlying RTL_BUFFER structure */
4474  ByteBuffer = &ThisBuffer->ByteBuffer;
4475  if ((ThisBuffer != (PVOID)-8) && (ByteBuffer->Buffer))
4476  {
4477  /* Check if it was dynamic */
4478  if (ByteBuffer->Buffer != ByteBuffer->StaticBuffer)
4479  {
4480  /* Free it from the heap */
4481  FreeString.Buffer = (PWCHAR)ByteBuffer->Buffer;
4482  RtlFreeUnicodeString(&FreeString);
4483  }
4484 
4485  /* Reset the buffer to its static data */
4486  ByteBuffer->Buffer = ByteBuffer->StaticBuffer;
4487  ByteBuffer->Size = ByteBuffer->StaticSize;
4488  }
4489 
4490  /* Reset the string to the static buffer */
4491  RtlInitEmptyUnicodeString(&ThisBuffer->String,
4492  (PWCHAR)ByteBuffer->StaticBuffer,
4493  ByteBuffer->StaticSize);
4494  if (ThisBuffer->String.Buffer)
4495  {
4496  /* Also NULL-terminate it */
4497  *ThisBuffer->String.Buffer = UNICODE_NULL;
4498  }
4499  }
4500  }
4501  }
4502  }
4503 #endif
4504  /* Check if an environment was passed in */
4505  if ((lpEnvironment) && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
4506  {
4507  /* Destroy it */
4508  RtlDestroyEnvironment(lpEnvironment);
4509 
4510  /* If this was the VDM environment too, clear that as well */
4511  if (VdmUnicodeEnv.Buffer == lpEnvironment) VdmUnicodeEnv.Buffer = NULL;
4512  lpEnvironment = NULL;
4513  }
4514 
4515  /* Unconditionally free all the name parsing buffers we always allocate */
4516  RtlFreeHeap(RtlGetProcessHeap(), 0, QuotedCmdLine);
4517  RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
4518  RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDirectory);
4519  RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer);
4520 
4521  /* Close open file/section handles */
4523  if (SectionHandle) NtClose(SectionHandle);
4524 
4525  /* If we have a thread handle, this was a failure path */
4526  if (ThreadHandle)
4527  {
4528  /* So kill the process and close the thread handle */
4530  NtClose(ThreadHandle);
4531  }
4532 
4533  /* If we have a process handle, this was a failure path, so close it */
4535 
4536  /* Thread/process handles, if any, are now processed. Now close this one. */
4537  if (JobHandle) NtClose(JobHandle);
4538 
4539  /* Check if we had created a token */
4540  if (TokenHandle)
4541  {
4542  /* And if the user asked for one */
4543  if (hUserToken)
4544  {
4545  /* Then return it */
4546  *hNewToken = TokenHandle;
4547  }
4548  else
4549  {
4550  /* User didn't want it, so we used it temporarily -- close it */
4552  }
4553  }
4554 
4555  /* Free any temporary app compatibility data, it's no longer needed */
4556  BasepFreeAppCompatData(AppCompatData, AppCompatSxsData);
4557 
4558  /* Free a few strings. The API takes care of these possibly being NULL */
4559  RtlFreeUnicodeString(&VdmString);
4560  RtlFreeUnicodeString(&DebuggerString);
4561 
4562  /* Check if we had built any sort of VDM environment */
4563  if ((VdmAnsiEnv.Buffer) || (VdmUnicodeEnv.Buffer))
4564  {
4565  /* Free it */
4566  BaseDestroyVDMEnvironment(&VdmAnsiEnv, &VdmUnicodeEnv);
4567  }
4568 
4569  /* Check if this was any kind of VDM application that we ended up creating */
4570  if ((VdmUndoLevel) && (!(VdmUndoLevel & VDM_UNDO_COMPLETED)))
4571  {
4572  /* Send an undo */
4574  (PHANDLE)&VdmTask,
4575  VdmUndoLevel,
4576  VdmBinaryType);
4577 
4578  /* And close whatever VDM handle we were using for notifications */
4579  if (VdmWaitObject) NtClose(VdmWaitObject);
4580  }
4581 
4582  /* Check if we ended up here with an allocated search path, and free it */
4583  if (SearchPath) RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath);
4584 
4585  /* Finally, return the API's result */
4586  return Result;
4587 }
HANDLE NTAPI DbgUiGetThreadDebugObject(VOID)
Definition: dbgui.c:333
BASE_SXS_CREATEPROCESS_MSG Sxs
Definition: basemsg.h:96
signed char * PCHAR
Definition: retypes.h:7
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
VOID WINAPI BasepFreeAppCompatData(IN PVOID AppCompatData, IN PVOID AppCompatSxsData)
Definition: appcache.c:342
#define ERROR_CHILD_NOT_COMPLETE
Definition: winerror.h:201
PVOID WINAPI BasepIsRealtimeAllowed(IN BOOLEAN Keep)
Definition: utils.c:662
union _BASE_API_MESSAGE::@3519 Data
ULONG ImageSubsystemMajorVersion
Definition: ntddk_ex.h:305
VOID NTAPI CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer)
Definition: capture.c:210
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
enum _RTL_PATH_TYPE RTL_PATH_TYPE
#define STATUS_INVALID_IMAGE_WIN_64
Definition: ntstatus.h:901
#define RemoveFromHandle(x, y)
Definition: proc.c:2228
NTSTATUS WINAPI BaseCreateStack(_In_ HANDLE hProcess, _In_opt_ SIZE_T StackCommit, _In_opt_ SIZE_T StackReserve, _Out_ PINITIAL_TEB InitialTeb)
Definition: utils.c:354
NTSTATUS NTAPI DbgUiConnectToDbg(VOID)
Definition: dbgui.c:25
NTSTATUS NTAPI LdrQueryImageFileKeyOption(IN HANDLE KeyHandle, IN PCWSTR ValueName, IN ULONG Type, OUT PVOID Buffer, IN ULONG BufferSize, OUT PULONG ReturnedLength OPTIONAL)
Definition: ldrinit.c:184
VOID WINAPI BaseInitializeContext(IN PCONTEXT Context, IN PVOID Parameter, IN PVOID StartAddress, IN PVOID StackAddress, IN ULONG ContextType)
Definition: utils.c:513
#define max(a, b)
Definition: svc.c:63
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
PVOID PVOID PWCHAR PVOID USHORT PULONG PVOID PULONG PVOID PULONG PULONG FusionFlags
Definition: env.c:45
#define REALTIME_PRIORITY_CLASS
Definition: winbase.h:184
#define CloseHandle
Definition: compat.h:598
#define IMAGE_SUBSYSTEM_POSIX_CUI
Definition: ntimage.h:440
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
PPEB Peb
Definition: dllmain.c:27
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define CREATE_FORCEDOS
Definition: winbase.h:189
#define PROCESS_PRIORITY_CLASS_INVALID
Definition: pstypes.h:106
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1324
NTSTATUS NTAPI NtCreateSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection OPTIONAL, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL)
Definition: section.c:3373
#define SEM_FAILCRITICALERRORS
Definition: rtltypes.h:69
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS NTAPI NtCreateThread(OUT PHANDLE phThread, IN ACCESS_MASK AccessMask, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE hProcess, OUT PCLIENT_ID pClientId, IN PCONTEXT pContext, OUT PSTACKINFO pStackInfo, IN BOOLEAN bSuspended)
NTSTATUS NTAPI NtRaiseHardError(IN NTSTATUS ErrorStatus, IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask, IN PULONG_PTR Parameters, IN ULONG ValidResponseOptions, OUT PULONG Response)
Definition: harderr.c:553
#define BINARY_TYPE_WOW
Definition: vdm.h:40
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define DbgPrint
Definition: loader.c:25
BOOL WINAPI BaseUpdateVDMEntry(IN ULONG UpdateIndex, IN OUT PHANDLE WaitHandle, IN ULONG IndexInfo, IN ULONG BinaryType)
Definition: vdm.c:534
SIZE_T Size
Definition: rtltypes.h:1873
PBASE_STATIC_SERVER_DATA BaseStaticServerData
Definition: dllmain.c:19
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define CREATE_SEPARATE_WOW_VDM
Definition: winbase.h:187
#define CREATE_UNICODE_ENVIRONMENT
Definition: winbase.h:186
#define PROCESSOR_ARCHITECTURE_UNKNOWN
Definition: ketypes.h:115
WCHAR CurrentDirectory[1024]
Definition: chkdsk.c:74
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define SE_LOCK_MEMORY_PRIVILEGE
Definition: security.c:658
#define TRUE
Definition: types.h:120
#define AddToHandle(x, y)
Definition: proc.c:2227
NTSYSAPI VOID NTAPI RtlDestroyEnvironment(_In_ PWSTR Environment)
BOOL NTAPI BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment, OUT PANSI_STRING AnsiEnv, OUT PUNICODE_STRING UnicodeEnv)
Definition: vdm.c:736
NTSTATUS WINAPI BasepCheckWinSaferRestrictions(IN HANDLE UserToken, IN LPWSTR ApplicationName, IN HANDLE FileHandle, OUT PBOOLEAN InJob, OUT PHANDLE NewToken, OUT PHANDLE JobHandle)
Definition: utils.c:918
static DWORD ResumeCount
Definition: database.c:32
NTSTATUS NTAPI CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage, IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer OPTIONAL, IN CSR_API_NUMBER ApiNumber, IN ULONG DataLength)
Definition: connect.c:365
HANDLE ContainingDirectory
Definition: rtltypes.h:1379
#define VER_SUITE_BLADE
BOOL WINAPI BaseGetVdmConfigInfo(IN LPCWSTR CommandLineReserved, IN ULONG DosSeqId, IN ULONG BinaryType, IN PUNICODE_STRING CmdLineString, OUT PULONG VdmSize)
Definition: vdm.c:644
BASE_CREATE_PROCESS CreateProcessRequest
Definition: basemsg.h:283
BOOL NTAPI BaseDestroyVDMEnvironment(IN PANSI_STRING AnsiEnv, IN PUNICODE_STRING UnicodeEnv)
Definition: vdm.c:1026
VOID NTAPI RtlReleaseRelativeName(_In_ PRTL_RELATIVE_NAME_U RelativeName)
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN DefaultSeparateVDM
Definition: base.h:126
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define HandleToUlong(h)
Definition: basetsd.h:79
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
GLdouble n
Definition: glext.h:7729
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1105
#define ERROR_BAD_DEVICE
Definition: winerror.h:703
#define CREATE_DEFAULT_ERROR_MODE
Definition: winbase.h:194
NTSTATUS NTAPI RtlGetFullPathName_UstrEx(_In_ PUNICODE_STRING FileName, _In_opt_ PUNICODE_STRING StaticString, _In_opt_ PUNICODE_STRING DynamicString, _Out_opt_ PUNICODE_STRING *StringUsed, _Out_opt_ PSIZE_T FilePartSize, _Out_opt_ PBOOLEAN NameInvalid, _Out_ RTL_PATH_TYPE *PathType, _Out_opt_ PSIZE_T LengthNeeded)
#define VDM_UNDO_COMPLETED
Definition: vdm.h:30
uint16_t * PWCHAR
Definition: typedefs.h:56
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1959
#define STARTF_FORCEONFEEDBACK
Definition: winbase.h:478
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define NORMAL_PRIORITY_CLASS
Definition: winbase.h:181
#define PROCESS_CREATE_FLAGS_LARGE_PAGES
Definition: pstypes.h:95
HANDLE UniqueProcess
Definition: compat.h:684
UNICODE_STRING DesktopInfo
Definition: rtltypes.h:1553
#define UNICODE_STRING_MAX_BYTES
#define ERROR_DIRECTORY
Definition: winerror.h:295
#define ERROR_ACCESS_DISABLED_WEBBLADE
Definition: winerror.h:774
#define MEM_COMMIT
Definition: nt_native.h:1313
#define VER_SUITE_DATACENTER
#define IMAGE_FILE_MACHINE_AMD64
Definition: ntimage.h:17
#define STATUS_VDM_DISALLOWED
Definition: ntstatus.h:957
#define VER_SUITE_PERSONAL
PVOID ArbitraryUserPointer
Definition: compat.h:578
NTSTATUS NTAPI LdrOpenImageFileOptionsKey(IN PUNICODE_STRING SubKey, IN BOOLEAN Wow64, OUT PHANDLE NewKeyHandle)
Definition: ldrinit.c:112
#define IMAGE_FILE_DLL
Definition: pedump.c:169
#define FILE_SHARE_READ
Definition: compat.h:136
#define STARTF_FORCEOFFFEEDBACK
Definition: winbase.h:479
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToRelativeNtPathName_U(_In_ PCWSTR DosName, _Out_ PUNICODE_STRING NtName, _Out_ PCWSTR *PartName, _Out_ PRTL_RELATIVE_NAME_U RelativeName)
#define SearchPath
Definition: winbase.h:3740
#define ABOVE_NORMAL_PRIORITY_CLASS
Definition: winbase.h:191
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define PROCESSOR_ARCHITECTURE_IA64
Definition: ketypes.h:111
#define CREATE_NO_WINDOW
Definition: winbase.h:195
HANDLE ThreadHandle
Definition: basemsg.h:90
static IN ULONG IN PWSTR OUT PCWSTR OUT PBOOLEAN OUT PATH_TYPE_AND_UNKNOWN * PathType
#define VDM_READY
Definition: vdm.h:48
HANDLE FileHandle
Definition: stats.c:38
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
return STATUS_NOT_IMPLEMENTED
#define CREATE_SUSPENDED
Definition: winbase.h:178
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define ANSI_NULL
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
BOOLEAN WINAPI BasepIsImageVersionOk(IN ULONG ImageMajorVersion, IN ULONG ImageMinorVersion)
Definition: proc.c:123
unsigned int BOOL
Definition: ntddk_ex.h:94
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
#define STARTF_SHELLPRIVATE
Definition: kernel32.h:60
#define FILE_READ_DATA
Definition: nt_native.h:628
HANDLE WaitObjectForParent
Definition: basemsg.h:123
#define MEM_RESERVE
Definition: nt_native.h:1314
LPWSTR lpDesktop
Definition: winbase.h:832
BASE_CHECK_VDM CheckVDMRequest
Definition: basemsg.h:287
#define IMAGE_SUBSYSTEM_WINDOWS_CUI
Definition: ntimage.h:438
#define HIGH_PRIORITY_CLASS
Definition: winbase.h:183
unsigned char BOOLEAN
#define ERROR_BAD_EXE_FORMAT
Definition: winerror.h:251
#define ERROR_NOT_READY
Definition: winerror.h:124
NTSYSAPI VOID NTAPI RtlReleasePrivilege(_In_ PVOID ReturnedState)
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define PAGE_EXECUTE
Definition: nt_native.h:1306
PVOID StackBase
Definition: pstypes.h:686
void DPRINT(...)
Definition: polytest.cpp:61
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:715
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
#define PROCESS_PRIORITY_CLASS_NORMAL
Definition: pstypes.h:108
void * PVOID
Definition: retypes.h:9
NTSTATUS WINAPI BasepReplaceProcessThreadTokens(IN HANDLE TokenHandle, IN HANDLE ProcessHandle, IN HANDLE ThreadHandle)
Definition: proc.c:354
NTSTATUS NTAPI NtQuerySection(_In_ HANDLE SectionHandle, _In_ SECTION_INFORMATION_CLASS SectionInformationClass, _Out_ PVOID SectionInformation, _In_ SIZE_T SectionInformationLength, _Out_opt_ PSIZE_T ResultLength)
Definition: section.c:4257
#define OPEN_EXISTING
Definition: compat.h:634
#define VDM_UNDO_FULL
Definition: vdm.h:28
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define PCHAR
Definition: match.c:90
#define CSR_CREATE_API_NUMBER(ServerId, ApiId)
Definition: csrmsg.h:37
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
#define IMAGE_FILE_MACHINE_I386
Definition: pedump.c:174
#define PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
Definition: pstypes.h:112
#define CREATE_SHARED_WOW_VDM
Definition: winbase.h:188
Status
Definition: gdiplustypes.h:24
HANDLE hUserToken
Definition: install.c:39
#define STATUS_INVALID_IMAGE_PROTECT
Definition: ntstatus.h:540
#define STARTF_USESTDHANDLES
Definition: winbase.h:480
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
USHORT MaximumLength
Definition: env_spec_w32.h:377
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3951
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define STATUS_INVALID_IMAGE_NOT_MZ
Definition: ntstatus.h:539
#define CMD_STRING
Definition: proc.c:51
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
#define IDLE_PRIORITY_CLASS
Definition: winbase.h:182
#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES
Definition: pstypes.h:93
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define UNICODE_STRING_MAX_CHARS
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1163
#define CREATE_NEW_CONSOLE
Definition: winbase.h:180
#define PROCESS_PRIORITY_CLASS_REALTIME
Definition: pstypes.h:110
#define ASSERT(a)
Definition: mode.c:45
#define BASESRV_SERVERDLL_INDEX
Definition: basemsg.h:15
BOOLEAN IsWowTaskReady
Definition: base.h:127
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG WINAPI BaseIsDosApplication(IN PUNICODE_STRING PathName, IN NTSTATUS Status)
Definition: vdm.c:66
#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION
Definition: ntimage.h:458
#define MAX_PATH
Definition: compat.h:34
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define SetLastError(x)
Definition: compat.h:611
#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE
Definition: ntstatus.h:149
#define BINARY_TYPE_SEPARATE_WOW
Definition: vdm.h:39
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
#define PROCESS_PRIORITY_CLASS_HIGH
Definition: pstypes.h:109
#define DEBUG_PROCESS
Definition: winbase.h:176
HANDLE ProcessHandle
Definition: basemsg.h:89
#define IsConsoleHandle(h)
Definition: console.h:14
NTSTATUS NTAPI NtReadVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN SIZE_T NumberOfBytesToRead, OUT PSIZE_T NumberOfBytesRead OPTIONAL)
Definition: virtual.c:2731
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define PROCESSOR_ARCHITECTURE_AMD64
Definition: ketypes.h:114
HANDLE UniqueThread
Definition: compat.h:685
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define ERROR_EXE_MACHINE_TYPE_MISMATCH
Definition: winerror.h:271
#define SharedUserData
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static const WCHAR L[]
Definition: oid.c:1250
UNICODE_STRING String
Definition: rtltypes.h:1881
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:454
#define FILE_EXECUTE
Definition: nt_native.h:642
PUNICODE_STRING Nt
Definition: kernel32.h:403
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define GENERIC_READ
Definition: compat.h:135
#define VDM_UNDO_REUSE
Definition: vdm.h:29
_In_ USHORT _In_ CCHAR StackSize
Definition: iofuncs.h:1056
#define SYNCHRONIZE
Definition: nt_native.h:61
#define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT
Definition: pstypes.h:92
POBJECT_ATTRIBUTES WINAPI BaseFormatObjectAttributes(OUT POBJECT_ATTRIBUTES ObjectAttributes, IN PSECURITY_ATTRIBUTES SecurityAttributes OPTIONAL, IN PUNICODE_STRING ObjectName)
Definition: utils.c:304
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
NTSTATUS NTAPI NtAssignProcessToJobObject(HANDLE JobHandle, HANDLE ProcessHandle)
Definition: job.c:157
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1297
PUCHAR StaticBuffer
Definition: rtltypes.h:1872
#define PROCESSOR_ARCHITECTURE_INTEL
Definition: ketypes.h:105
#define STATUS_FILE_IS_OFFLINE
Definition: ntstatus.h:740
ULONG_PTR SIZE_T
Definition: typedefs.h:80
Definition: compat.h:694
#define ERROR_FILE_OFFLINE
Definition: winerror.h:1285
#define VER_SUITE_EMBEDDEDNT
NTSTATUS WINAPI BaseCheckVDM(IN ULONG BinaryType, IN PCWCH ApplicationName, IN PCWCH CommandLine, IN PCWCH CurrentDirectory, IN PANSI_STRING AnsiEnvironment, IN PBASE_API_MESSAGE ApiMessage, IN OUT PULONG iTask, IN DWORD CreationFlags, IN LPSTARTUPINFOW StartupInfo, IN HANDLE hUserToken OPTIONAL)
Definition: vdm.c:91
NTSTATUS NTAPI NtAllocateVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *UBaseAddress, IN ULONG_PTR ZeroBits, IN OUT PSIZE_T URegionSize, IN ULONG AllocationType, IN ULONG Protect)
Definition: virtual.c:4407
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
NTSTATUS NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength)
Definition: query.c:1107
LPVOID lpSecurityDescriptor
Definition: compat.h:193
#define GetModuleHandle
Definition: winbase.h:3667
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ERROR_CANCELLED
Definition: winerror.h:726
#define NtCurrentPeb()
Definition: FLS.c:20
unsigned short USHORT
Definition: pedump.c:61
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
VOID WINAPI StuffStdHandle(IN HANDLE ProcessHandle, IN HANDLE StandardHandle, IN PHANDLE Address)
Definition: proc.c:57
SIZE_T StaticSize
Definition: rtltypes.h:1874
NTSTATUS WINAPI BasepCheckWebBladeHashes(IN HANDLE FileHandle)
Definition: proc.c:149
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
#define VDM_NOT_LOADED
Definition: vdm.h:46
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define VDM_NOT_READY
Definition: vdm.h:47
#define DETACHED_PROCESS
Definition: winbase.h:179
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define VDM_UNDO_PARTIAL
Definition: vdm.h:27
#define NULL
Definition: types.h:112
#define PROCESS_CREATE_FLAGS_BREAKAWAY
Definition: pstypes.h:91
LPWSTR WINAPI BaseComputeProcessExePath(IN LPWSTR FullPath)
Definition: path.c:405
USHORT ProcessorArchitecture
Definition: basemsg.h:99
#define MAXUSHORT
Definition: typedefs.h:83
USHORT VDMState
Definition: basemsg.h:147
#define DPRINT1
Definition: precomp.h:8
#define RtlImageNtHeader
Definition: compat.h:665
#define CreateFileW
Definition: compat.h:600
PUNICODE_STRING Win32
Definition: kernel32.h:402
NTSYSAPI NTSTATUS NTAPI RtlAcquirePrivilege(_In_ PULONG Privilege, _In_ ULONG NumPriv, _In_ ULONG Flags, _Out_ PVOID *ReturnedState)
#define BINARY_TYPE_WOW_EX
Definition: vdm.h:41
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define MEM_RELEASE
Definition: nt_native.h:1316
struct tagContext Context
Definition: acpixf.h:1034
PUCHAR Buffer
Definition: rtltypes.h:1871
#define STATUS_INVALID_IMAGE_NE_FORMAT
Definition: ntstatus.h:519
PVOID PebAddressNative
Definition: basemsg.h:97
#define BELOW_NORMAL_PRIORITY_CLASS
Definition: winbase.h:190
ULONG PebAddressWow64
Definition: basemsg.h:98
CLIENT_ID ClientId
Definition: basemsg.h:91
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
#define ULONG_PTR
Definition: config.h:101
#define BINARY_TYPE_DOS
Definition: vdm.h:38
#define SEC_IMAGE
Definition: mmtypes.h:96
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
UNICODE_STRING RelativeName
Definition: rtltypes.h:1378
#define PROCESS_PRIORITY_CLASS_BELOW_NORMAL
Definition: pstypes.h:111
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
DWORD dwFlags
Definition: winbase.h:841
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER
Definition: winerror.h:775
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define ERROR_ACCESS_DISABLED_BY_POLICY
Definition: winerror.h:763
NTSTATUS NTAPI NtIsProcessInJob(IN HANDLE ProcessHandle, IN HANDLE JobHandle OPTIONAL)
Definition: job.c:361
#define PROCESS_PRIORITY_CLASS_IDLE
Definition: pstypes.h:107
#define CREATE_PRESERVE_CODE_AUTHZ_LEVEL
Definition: winbase.h:193
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
#define DEBUG_ONLY_THIS_PROCESS
Definition: winbase.h:177
BOOLEAN WINAPI BuildSubSysCommandLine(IN LPCWSTR SubsystemName, IN LPCWSTR ApplicationName, IN LPCWSTR CommandLine, OUT PUNICODE_STRING SubsysCommandLine)
Definition: proc.c:89
#define REG_DWORD
Definition: sdbapi.c:596
NTSTATUS NTAPI NtCreateProcessEx(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ParentProcess, IN ULONG Flags, IN HANDLE SectionHandle OPTIONAL, IN HANDLE DebugPort OPTIONAL, IN HANDLE ExceptionPort OPTIONAL, IN BOOLEAN InJob)
Definition: process.c:1344
VOID WINAPI BasepSxsCloseHandles(IN PBASE_MSG_SXS_HANDLES Handles)
Definition: proc.c:417
#define STATUS_INVALID_IMAGE_WIN_16
Definition: ntstatus.h:541
#define IMAGE_FILE_MACHINE_IA64
Definition: ntimage.h:22
NT_TIB NtTib
Definition: ntddk_ex.h:332
NTSYSAPI ULONG NTAPI RtlIsDosDeviceName_U(_In_ PCWSTR Name)
NTSTATUS WINAPI BasepIsProcessAllowed(IN LPWSTR ApplicationName)
Definition: proc.c:202
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
BOOLEAN WINAPI BasePushProcessParameters(IN ULONG ParameterFlags, IN HANDLE ProcessHandle, IN PPEB RemotePeb, IN LPCWSTR ApplicationPathName, IN LPWSTR lpCurrentDirectory, IN LPWSTR lpCommandLine, IN LPVOID lpEnvironment, IN LPSTARTUPINFOW StartupInfo, IN DWORD CreationFlags, IN BOOL InheritHandles, IN ULONG ImageSubsystem, IN PVOID AppCompatData, IN ULONG AppCompatDataSize)
Definition: proc.c:484
#define BINARY_TYPE_EXE
Definition: vdm.h:35
#define PAGE_READWRITE
Definition: nt_native.h:1304
NTSYSAPI RTL_PATH_TYPE NTAPI RtlDetermineDosPathNameType_U(_In_ PCWSTR Path)
#define IMAGE_SUBSYSTEM_WINDOWS_GUI
Definition: ntimage.h:437
NTSTATUS WINAPI BasepCheckBadapp(IN HANDLE FileHandle, IN PWCHAR ApplicationName, IN PWCHAR Environment, IN USHORT ExeType, IN PVOID *SdbQueryAppCompatData, IN PULONG SdbQueryAppCompatDataSize, IN PVOID *SxsData, IN PULONG SxsDataSize, OUT PULONG FusionFlags)
Definition: appcache.c:272
#define REG_SZ
Definition: layer.c:22
NTSTATUS NTAPI NtFreeVirtualMemory(IN HANDLE ProcessHandle, IN PVOID *UBaseAddress, IN PSIZE_T URegionSize, IN ULONG FreeType)
Definition: virtual.c:5130

Referenced by CreateProcessInternalA(), and CreateProcessW().

◆ CreateProcessW()

BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW ( LPCWSTR  lpApplicationName,
LPWSTR  lpCommandLine,
LPSECURITY_ATTRIBUTES  lpProcessAttributes,
LPSECURITY_ATTRIBUTES  lpThreadAttributes,
BOOL  bInheritHandles,
DWORD  dwCreationFlags,
LPVOID  lpEnvironment,
LPCWSTR  lpCurrentDirectory,
LPSTARTUPINFOW  lpStartupInfo,
LPPROCESS_INFORMATION  lpProcessInformation 
)

Definition at line 4595 of file proc.c.

4605 {
4606  /* Call the internal (but exported) version */
4608  lpApplicationName,
4609  lpCommandLine,
4610  lpProcessAttributes,
4611  lpThreadAttributes,
4612  bInheritHandles,
4613  dwCreationFlags,
4614  lpEnvironment,
4615  lpCurrentDirectory,
4616  lpStartupInfo,
4617  lpProcessInformation,
4618  NULL);
4619 }
BOOL WINAPI CreateProcessInternalW(IN HANDLE hUserToken, IN LPCWSTR lpApplicationName, IN LPWSTR lpCommandLine, IN LPSECURITY_ATTRIBUTES lpProcessAttributes, IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN BOOL bInheritHandles, IN DWORD dwCreationFlags, IN LPVOID lpEnvironment, IN LPCWSTR lpCurrentDirectory, IN LPSTARTUPINFOW lpStartupInfo, IN LPPROCESS_INFORMATION lpProcessInformation, OUT PHANDLE hNewToken)
Definition: proc.c:2236
#define NULL
Definition: types.h:112

Referenced by CorDebug_CreateProcess(), CProcess::CProcess(), create_server(), CreateClientProcess(), CreateProcessAsUserW(), CreateProcessWithTokenW(), do_register_dll(), execute_command(), HotkeyThread(), IDirectInputAImpl_RunControlPanel(), install_wine_gecko(), InstallDevice(), InstallLiveCD(), ITERATE_RemoveExistingProducts(), CNetConnectionPropertyUi::LANPropertiesUIDlg(), launch_exe(), CNewMenu::NewItemByCommand(), ProcessPage_OnDebug(), register_dll(), run_child(), run_rapps(), run_winemenubuilder(), runCmd(), RunControlPanelApplet(), RunNextJob(), RunSetupThreadProc(), ScmStartUserModeService(), SHELL_ExecuteW(), START_TEST(), StartChild(), StartLsass(), StartProcess(), StartScreenSaver(), StartServicesManager(), Test_CommandLine(), TestStaticDestruct(), UnhandledExceptionFilter(), WshExec_create(), and wWinMain().

◆ ExitProcess()

VOID WINAPI ExitProcess ( IN UINT  uExitCode)

Definition at line 1487 of file proc.c.

1488 {
1489  BASE_API_MESSAGE ApiMessage;
1490  PBASE_EXIT_PROCESS ExitProcessRequest = &ApiMessage.Data.ExitProcessRequest;
1491 
1493 
1494  _SEH2_TRY
1495  {
1496  /* Acquire the PEB lock */
1498 
1499  /* Kill all the threads */
1500  NtTerminateProcess(NULL, uExitCode);
1501 
1502  /* Unload all DLLs */
1504 
1505  /* Notify Base Server of process termination */
1506  ExitProcessRequest->uExitCode = uExitCode;
1508  NULL,
1510  sizeof(*ExitProcessRequest));
1511 
1512  /* Now do it again */
1513