ReactOS  0.4.15-dev-2528-g5506091
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 2226 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 2227 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:3398
#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:47
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:164
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:2015
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:40
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define DPRINT
Definition: sndvol32.h:71

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:3838
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:3398
#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
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#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
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:496
#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
__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:4405
#define NtCurrentPeb()
Definition: FLS.c:22
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
#define DPRINT
Definition: sndvol32.h:71
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:2843
#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:47
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 4743 of file proc.c.

4753 {
4754  /* Call the internal (but exported) version */
4756  lpApplicationName,
4757  lpCommandLine,
4758  lpProcessAttributes,
4759  lpThreadAttributes,
4760  bInheritHandles,
4761  dwCreationFlags,
4762  lpEnvironment,
4763  lpCurrentDirectory,
4764  lpStartupInfo,
4765  lpProcessInformation,
4766  NULL);
4767 }
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:4625
#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 4625 of file proc.c.

4637 {
4638  UNICODE_STRING CommandLine;
4641  BOOL bRetVal;
4642  STARTUPINFOW StartupInfo;
4643 
4644  DPRINT("dwCreationFlags %x, lpEnvironment %p, lpCurrentDirectory %p, "
4645  "lpStartupInfo %p, lpProcessInformation %p\n",
4646  dwCreationFlags, lpEnvironment, lpCurrentDirectory,
4647  lpStartupInfo, lpProcessInformation);
4648 
4649  /* Copy Startup Info */
4650  RtlMoveMemory(&StartupInfo, lpStartupInfo, sizeof(*lpStartupInfo));
4651 
4652  /* Initialize all strings to nothing */
4653  CommandLine.Buffer = NULL;
4654  ApplicationName.Buffer = NULL;
4655  CurrentDirectory.Buffer = NULL;
4656  StartupInfo.lpDesktop = NULL;
4657  StartupInfo.lpReserved = NULL;
4658  StartupInfo.lpTitle = NULL;
4659 
4660  /* Convert the Command line */
4661  if (lpCommandLine)
4662  {
4664  lpCommandLine);
4665  }
4666 
4667  /* Convert the Name and Directory */
4668  if (lpApplicationName)
4669  {
4671  lpApplicationName);
4672  }
4673  if (lpCurrentDirectory)
4674  {
4676  lpCurrentDirectory);
4677  }
4678 
4679  /* Now convert Startup Strings */
4680  if (lpStartupInfo->lpReserved)
4681  {
4683  &StartupInfo.lpReserved);
4684  }
4685  if (lpStartupInfo->lpDesktop)
4686  {
4688  &StartupInfo.lpDesktop);
4689  }
4690  if (lpStartupInfo->lpTitle)
4691  {
4693  &StartupInfo.lpTitle);
4694  }
4695 
4696  /* Call the Unicode function */
4697  bRetVal = CreateProcessInternalW(hToken,
4698  ApplicationName.Buffer,
4699  CommandLine.Buffer,
4700  lpProcessAttributes,
4701  lpThreadAttributes,
4702  bInheritHandles,
4703  dwCreationFlags,
4704  lpEnvironment,
4705  CurrentDirectory.Buffer,
4706  &StartupInfo,
4707  lpProcessInformation,
4708  hNewToken);
4709 
4710  /* Clean up */
4712  RtlFreeUnicodeString(&CommandLine);
4714  RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpDesktop);
4715  RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpReserved);
4716  RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpTitle);
4717 
4718  /* Return what Unicode did */
4719  return bRetVal;
4720 }
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:2235
LPSTR lpTitle
Definition: winbase.h:828
LPWSTR lpReserved
Definition: winbase.h:847
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:848
LPWSTR lpTitle
Definition: winbase.h:849
LPSTR lpReserved
Definition: winbase.h:826
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
PVOID PVOID PWCHAR ApplicationName
Definition: env.c:47
LPSTR lpDesktop
Definition: winbase.h:827
#define NULL
Definition: types.h:112
#define DPRINT
Definition: sndvol32.h:71

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 2235 of file proc.c.

2247 {
2248  //
2249  // Core variables used for creating the initial process and thread
2250  //
2251  SECURITY_ATTRIBUTES LocalThreadAttributes, LocalProcessAttributes;
2252  OBJECT_ATTRIBUTES LocalObjectAttributes;
2254  SECTION_IMAGE_INFORMATION ImageInformation;
2257  ULONG NoWindow, StackSize, ErrorCode, Flags;
2259  USHORT ImageMachine;
2260  ULONG ParameterFlags, PrivilegeValue, HardErrorMode, ErrorResponse;
2261  ULONG_PTR ErrorParameters[2];
2262  BOOLEAN InJob, SaferNeeded, UseLargePages, HavePrivilege;
2263  BOOLEAN QuerySection, SkipSaferAndAppCompat;
2264  CONTEXT Context;
2265  BASE_API_MESSAGE CsrMsg[2];
2266  PBASE_CREATE_PROCESS CreateProcessMsg;
2267  PCSR_CAPTURE_BUFFER CaptureBuffer;
2268  PVOID BaseAddress, PrivilegeState, RealTimePrivilegeState;
2269  HANDLE DebugHandle, TokenHandle, JobHandle, KeyHandle, ThreadHandle;
2270  HANDLE FileHandle, SectionHandle, ProcessHandle;
2272  PROCESS_PRIORITY_CLASS PriorityClass;
2273  NTSTATUS Status, AppCompatStatus, SaferStatus, IFEOStatus, ImageDbgStatus;
2274  PPEB Peb, RemotePeb;
2275  PTEB Teb;
2276  INITIAL_TEB InitialTeb;
2277  PVOID TibValue;
2278  PIMAGE_NT_HEADERS NtHeaders;
2279  STARTUPINFOW StartupInfo;
2280  PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
2281  UNICODE_STRING DebuggerString;
2282  BOOL Result;
2283  //
2284  // Variables used for command-line and argument parsing
2285  //
2286  PCHAR pcScan;
2287  SIZE_T n;
2288  WCHAR SaveChar;
2289  ULONG Length, FileAttribs, CmdQuoteLength;
2290  ULONG ResultSize;
2291  SIZE_T EnvironmentLength, CmdLineLength;
2292  PWCHAR QuotedCmdLine, AnsiCmdCommand, ExtBuffer, CurrentDirectory;
2293  PWCHAR NullBuffer, ScanString, NameBuffer, SearchPath, DebuggerCmdLine;
2294  ANSI_STRING AnsiEnv;
2295  UNICODE_STRING UnicodeEnv, PathName;
2296  BOOLEAN SearchRetry, QuotesNeeded, CmdLineIsAppName, HasQuotes;
2297 
2298  //
2299  // Variables used for Fusion/SxS (Side-by-Side Assemblies)
2300  //
2301  RTL_PATH_TYPE SxsPathType, PathType;
2302 #if _SXS_SUPPORT_ENABLED_
2303  PRTL_BUFFER ByteBuffer;
2304  PRTL_UNICODE_STRING_BUFFER ThisBuffer, Buffer, SxsStaticBuffers[5];
2305  PRTL_UNICODE_STRING_BUFFER* BufferHead, SxsStringBuffer;
2306  RTL_UNICODE_STRING_BUFFER SxsWin32ManifestPath, SxsNtManifestPath;
2307  RTL_UNICODE_STRING_BUFFER SxsWin32PolicyPath, SxsNtPolicyPath;
2308  RTL_UNICODE_STRING_BUFFER SxsWin32AssemblyDirectory;
2309  BASE_MSG_SXS_HANDLES MappedHandles, Handles, FileHandles;
2310  PVOID CapturedStrings[3];
2311  SXS_WIN32_NT_PATH_PAIR ExePathPair, ManifestPathPair, PolicyPathPair;
2312  SXS_OVERRIDE_MANIFEST OverrideManifest;
2313  UNICODE_STRING FreeString, SxsNtExePath;
2314  PWCHAR SxsConglomeratedBuffer, StaticBuffer;
2315  ULONG ConglomeratedBufferSizeBytes, StaticBufferSize, i;
2316 #endif
2318 
2319  //
2320  // Variables used for path conversion (and partially Fusion/SxS)
2321  //
2322  PWCHAR FilePart, PathBuffer, FreeBuffer;
2323  BOOLEAN TranslationStatus;
2324  RTL_RELATIVE_NAME_U SxsWin32RelativePath;
2325  UNICODE_STRING PathBufferString, SxsWin32ExePath;
2326 
2327  //
2328  // Variables used by Application Compatibility (and partially Fusion/SxS)
2329  //
2330  PVOID AppCompatSxsData, AppCompatData;
2331  ULONG AppCompatSxsDataSize, AppCompatDataSize;
2332  //
2333  // Variables used by VDM (Virtual Dos Machine) and WOW32 (16-bit Support)
2334  //
2335  ULONG BinarySubType, VdmBinaryType, VdmTask, VdmReserve;
2336  ULONG VdmUndoLevel;
2337  BOOLEAN UseVdmReserve;
2338  HANDLE VdmWaitObject;
2339  ANSI_STRING VdmAnsiEnv;
2340  UNICODE_STRING VdmString, VdmUnicodeEnv;
2341  BOOLEAN IsWowApp;
2342  PBASE_CHECK_VDM CheckVdmMsg;
2343 
2344  /* Zero out the initial core variables and handles */
2345  QuerySection = FALSE;
2346  InJob = FALSE;
2347  SkipSaferAndAppCompat = FALSE;
2348  ParameterFlags = 0;
2349  Flags = 0;
2350  DebugHandle = NULL;
2351  JobHandle = NULL;
2352  TokenHandle = NULL;
2353  FileHandle = NULL;
2354  SectionHandle = NULL;
2355  ProcessHandle = NULL;
2356  ThreadHandle = NULL;
2357  BaseAddress = (PVOID)1;
2358 
2359  /* Zero out initial SxS and Application Compatibility state */
2360  AppCompatData = NULL;
2361  AppCompatDataSize = 0;
2362  AppCompatSxsData = NULL;
2363  AppCompatSxsDataSize = 0;
2364  CaptureBuffer = NULL;
2365 #if _SXS_SUPPORT_ENABLED_
2366  SxsConglomeratedBuffer = NULL;
2367 #endif
2368  FusionFlags = 0;
2369 
2370  /* Zero out initial parsing variables -- others are initialized later */
2371  DebuggerCmdLine = NULL;
2372  PathBuffer = NULL;
2373  SearchPath = NULL;
2374  NullBuffer = NULL;
2375  FreeBuffer = NULL;
2376  NameBuffer = NULL;
2378  FilePart = NULL;
2379  DebuggerString.Buffer = NULL;
2380  HasQuotes = FALSE;
2381  QuotedCmdLine = NULL;
2382 
2383  /* Zero out initial VDM state */
2384  VdmAnsiEnv.Buffer = NULL;
2385  VdmUnicodeEnv.Buffer = NULL;
2386  VdmString.Buffer = NULL;
2387  VdmTask = 0;
2388  VdmUndoLevel = 0;
2389  VdmBinaryType = 0;
2390  VdmReserve = 0;
2391  VdmWaitObject = NULL;
2392  UseVdmReserve = FALSE;
2393  IsWowApp = FALSE;
2394 
2395  /* Set message structures */
2396  CreateProcessMsg = &CsrMsg[0].Data.CreateProcessRequest;
2397  CheckVdmMsg = &CsrMsg[1].Data.CheckVDMRequest;
2398 
2399  /* Clear the more complex structures by zeroing out their entire memory */
2400  RtlZeroMemory(&Context, sizeof(Context));
2401 #if _SXS_SUPPORT_ENABLED_
2402  RtlZeroMemory(&FileHandles, sizeof(FileHandles));
2403  RtlZeroMemory(&MappedHandles, sizeof(MappedHandles));
2404  RtlZeroMemory(&Handles, sizeof(Handles));
2405 #endif
2406  RtlZeroMemory(&CreateProcessMsg->Sxs, sizeof(CreateProcessMsg->Sxs));
2407  RtlZeroMemory(&LocalProcessAttributes, sizeof(LocalProcessAttributes));
2408  RtlZeroMemory(&LocalThreadAttributes, sizeof(LocalThreadAttributes));
2409 
2410  /* Zero out output arguments as well */
2411  RtlZeroMemory(lpProcessInformation, sizeof(*lpProcessInformation));
2412  if (hNewToken) *hNewToken = NULL;
2413 
2414  /* Capture the special window flag */
2415  NoWindow = dwCreationFlags & CREATE_NO_WINDOW;
2416  dwCreationFlags &= ~CREATE_NO_WINDOW;
2417 
2418 #if _SXS_SUPPORT_ENABLED_
2419  /* Setup the SxS static string arrays and buffers */
2420  SxsStaticBuffers[0] = &SxsWin32ManifestPath;
2421  SxsStaticBuffers[1] = &SxsWin32PolicyPath;
2422  SxsStaticBuffers[2] = &SxsWin32AssemblyDirectory;
2423  SxsStaticBuffers[3] = &SxsNtManifestPath;
2424  SxsStaticBuffers[4] = &SxsNtPolicyPath;
2425  ExePathPair.Win32 = &SxsWin32ExePath;
2426  ExePathPair.Nt = &SxsNtExePath;
2427  ManifestPathPair.Win32 = &SxsWin32ManifestPath.String;
2428  ManifestPathPair.Nt = &SxsNtManifestPath.String;
2429  PolicyPathPair.Win32 = &SxsWin32PolicyPath.String;
2430  PolicyPathPair.Nt = &SxsNtPolicyPath.String;
2431 #endif
2432 
2433  DPRINT("CreateProcessInternalW: '%S' '%S' %lx\n", lpApplicationName, lpCommandLine, dwCreationFlags);
2434 
2435  /* Finally, set our TEB and PEB */
2436  Teb = NtCurrentTeb();
2437  Peb = NtCurrentPeb();
2438 
2439  /* This combination is illegal (see MSDN) */
2440  if ((dwCreationFlags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE)) ==
2442  {
2443  DPRINT1("Invalid flag combo used\n");
2445  return FALSE;
2446  }
2447 
2448  /* Convert the priority class */
2449  if (dwCreationFlags & IDLE_PRIORITY_CLASS)
2450  {
2452  }
2453  else if (dwCreationFlags & BELOW_NORMAL_PRIORITY_CLASS)
2454  {
2456  }
2457  else if (dwCreationFlags & NORMAL_PRIORITY_CLASS)
2458  {
2460  }
2461  else if (dwCreationFlags & ABOVE_NORMAL_PRIORITY_CLASS)
2462  {
2464  }
2465  else if (dwCreationFlags & HIGH_PRIORITY_CLASS)
2466  {
2468  }
2469  else if (dwCreationFlags & REALTIME_PRIORITY_CLASS)
2470  {
2472  PriorityClass.PriorityClass += (BasepIsRealtimeAllowed(FALSE) != NULL);
2473  }
2474  else
2475  {
2477  }
2478 
2479  /* Done with the priority masks, so get rid of them */
2480  PriorityClass.Foreground = FALSE;
2481  dwCreationFlags &= ~(NORMAL_PRIORITY_CLASS |
2487 
2488  /* You cannot request both a shared and a separate WoW VDM */
2489  if ((dwCreationFlags & CREATE_SEPARATE_WOW_VDM) &&
2490  (dwCreationFlags & CREATE_SHARED_WOW_VDM))
2491  {
2492  /* Fail such nonsensical attempts */
2493  DPRINT1("Invalid WOW flags\n");
2495  return FALSE;
2496  }
2497  else if (!(dwCreationFlags & CREATE_SHARED_WOW_VDM) &&
2499  {
2500  /* A shared WoW VDM was not requested but system enforces separation */
2501  dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
2502  }
2503 
2504  /* If a shared WoW VDM is used, make sure the process isn't in a job */
2505  if (!(dwCreationFlags & CREATE_SEPARATE_WOW_VDM) &&
2507  {
2508  /* Remove the shared flag and add the separate flag */
2509  dwCreationFlags = (dwCreationFlags &~ CREATE_SHARED_WOW_VDM) |
2511  }
2512 
2513  /* Convert the environment */
2514  if ((lpEnvironment) && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
2515  {
2516  /* Scan the environment to calculate its Unicode size */
2517  AnsiEnv.Buffer = pcScan = (PCHAR)lpEnvironment;
2518  while ((*pcScan) || (*(pcScan + 1))) ++pcScan;
2519 
2520  /* Make sure the environment is not too large */
2521  EnvironmentLength = (pcScan + sizeof(ANSI_NULL) - (PCHAR)lpEnvironment);
2522  if (EnvironmentLength > MAXUSHORT)
2523  {
2524  /* Fail */
2526  return FALSE;
2527  }
2528 
2529  /* Create our ANSI String */
2530  AnsiEnv.Length = (USHORT)EnvironmentLength;
2531  AnsiEnv.MaximumLength = AnsiEnv.Length + sizeof(ANSI_NULL);
2532 
2533  /* Allocate memory for the Unicode Environment */
2534  UnicodeEnv.Buffer = NULL;
2535  RegionSize = AnsiEnv.MaximumLength * sizeof(WCHAR);
2537  (PVOID)&UnicodeEnv.Buffer,
2538  0,
2539  &RegionSize,
2540  MEM_COMMIT,
2541  PAGE_READWRITE);
2542  if (!NT_SUCCESS(Status))
2543  {
2544  /* Fail */
2546  return FALSE;
2547  }
2548 
2549  /* Use the allocated size and convert */
2550  UnicodeEnv.MaximumLength = (USHORT)RegionSize;
2551  Status = RtlAnsiStringToUnicodeString(&UnicodeEnv, &AnsiEnv, FALSE);
2552  if (!NT_SUCCESS(Status))
2553  {
2554  /* Fail */
2556  (PVOID)&UnicodeEnv.Buffer,
2557  &RegionSize,
2558  MEM_RELEASE);
2560  return FALSE;
2561  }
2562 
2563  /* Now set the Unicode environment as the environment string pointer */
2564  lpEnvironment = UnicodeEnv.Buffer;
2565  }
2566 
2567  /* Make a copy of the caller's startup info since we'll modify it */
2568  StartupInfo = *lpStartupInfo;
2569 
2570  /* Check if private data is being sent on the same channel as std handles */
2571  if ((StartupInfo.dwFlags & STARTF_USESTDHANDLES) &&
2572  (StartupInfo.dwFlags & (STARTF_USEHOTKEY | STARTF_SHELLPRIVATE)))
2573  {
2574  /* Cannot use the std handles since we have monitor/hotkey values */
2575  StartupInfo.dwFlags &= ~STARTF_USESTDHANDLES;
2576  }
2577 
2578  /* If there's a debugger, or we have to launch cmd.exe, we go back here */
2579 AppNameRetry:
2580  /* New iteration -- free any existing name buffer */
2581  if (NameBuffer)
2582  {
2583  RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
2584  NameBuffer = NULL;
2585  }
2586 
2587  /* New iteration -- free any existing free buffer */
2588  if (FreeBuffer)
2589  {
2590  RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer);
2591  FreeBuffer = NULL;
2592  }
2593 
2594  /* New iteration -- close any existing file handle */
2595  if (FileHandle)
2596  {
2598  FileHandle = NULL;
2599  }
2600 
2601  /* Set the initial parsing state. This code can loop -- don't move this! */
2602  ErrorCode = 0;
2603  SearchRetry = TRUE;
2604  QuotesNeeded = FALSE;
2605  CmdLineIsAppName = FALSE;
2606 
2607  /* First check if we don't have an application name */
2608  if (!lpApplicationName)
2609  {
2610  /* This should be the first time we attempt creating one */
2611  ASSERT(NameBuffer == NULL);
2612 
2613  /* Allocate a buffer to hold it */
2614  NameBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
2615  0,
2616  MAX_PATH * sizeof(WCHAR));
2617  if (!NameBuffer)
2618  {
2620  Result = FALSE;
2621  goto Quickie;
2622  }
2623 
2624  /* Initialize the application name and our parsing parameters */
2625  lpApplicationName = NullBuffer = ScanString = lpCommandLine;
2626 
2627  /* Check for an initial quote*/
2628  if (*lpCommandLine == L'\"')
2629  {
2630  /* We found a quote, keep searching for another one */
2631  SearchRetry = FALSE;
2632  ScanString++;
2633  lpApplicationName = ScanString;
2634  while (*ScanString)
2635  {
2636  /* Have we found the terminating quote? */
2637  if (*ScanString == L'\"')
2638  {
2639  /* We're done, get out of here */
2640  NullBuffer = ScanString;
2641  HasQuotes = TRUE;
2642  break;
2643  }
2644 
2645  /* Keep searching for the quote */
2646  ScanString++;
2647  NullBuffer = ScanString;
2648  }
2649  }
2650  else
2651  {
2652 StartScan:
2653  /* We simply make the application name be the command line*/
2654  lpApplicationName = lpCommandLine;
2655  while (*ScanString)
2656  {
2657  /* Check if it starts with a space or tab */
2658  if ((*ScanString == L' ') || (*ScanString == L'\t'))
2659  {
2660  /* Break out of the search loop */
2661  NullBuffer = ScanString;
2662  break;
2663  }
2664 
2665  /* Keep searching for a space or tab */
2666  ScanString++;
2667  NullBuffer = ScanString;
2668  }
2669  }
2670 
2671  /* We have found the end of the application name, terminate it */
2672  SaveChar = *NullBuffer;
2673  *NullBuffer = UNICODE_NULL;
2674 
2675  /* New iteration -- free any existing saved path */
2676  if (SearchPath)
2677  {
2678  RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath);
2679  SearchPath = NULL;
2680  }
2681 
2682  /* Now compute the final EXE path based on the name */
2683  SearchPath = BaseComputeProcessExePath((LPWSTR)lpApplicationName);
2684  DPRINT("Search Path: %S\n", SearchPath);
2685  if (!SearchPath)
2686  {
2688  Result = FALSE;
2689  goto Quickie;
2690  }
2691 
2692  /* And search for the executable in the search path */
2694  lpApplicationName,
2695  L".exe",
2696  MAX_PATH,
2697  NameBuffer,
2698  NULL);
2699 
2700  /* Did we find it? */
2701  if ((Length) && (Length < MAX_PATH))
2702  {
2703  /* Get file attributes */
2704  FileAttribs = GetFileAttributesW(NameBuffer);
2705  if ((FileAttribs != INVALID_FILE_ATTRIBUTES) &&
2706  (FileAttribs & FILE_ATTRIBUTE_DIRECTORY))
2707  {
2708  /* This was a directory, fail later on */
2709  Length = 0;
2710  }
2711  else
2712  {
2713  /* It's a file! */
2714  Length++;
2715  }
2716  }
2717 
2718  DPRINT("Length: %lu Buffer: %S\n", Length, NameBuffer);
2719 
2720  /* Check if there was a failure in SearchPathW */
2721  if ((Length) && (Length < MAX_PATH))
2722  {
2723  /* Everything looks good, restore the name */
2724  *NullBuffer = SaveChar;
2725  lpApplicationName = NameBuffer;
2726  }
2727  else
2728  {
2729  /* Check if this was a relative path, which would explain it */
2730  PathType = RtlDetermineDosPathNameType_U(lpApplicationName);
2732  {
2733  /* This should fail, and give us a detailed LastError */
2734  FileHandle = CreateFileW(lpApplicationName,
2735  GENERIC_READ,
2736  FILE_SHARE_READ |
2738  NULL,
2739  OPEN_EXISTING,
2741  NULL);
2743  {
2744  /* It worked? Return a generic error */
2746  FileHandle = NULL;
2748  }
2749  }
2750  else
2751  {
2752  /* Path was absolute, which means it doesn't exist */
2754  }
2755 
2756  /* Did we already fail once? */
2757  if (ErrorCode)
2758  {
2759  /* Set the error code */
2761  }
2762  else
2763  {
2764  /* Not yet, cache it */
2765  ErrorCode = GetLastError();
2766  }
2767 
2768  /* Put back the command line */
2769  *NullBuffer = SaveChar;
2770  lpApplicationName = NameBuffer;
2771 
2772  /* It's possible there's whitespace in the directory name */
2773  if (!(*ScanString) || !(SearchRetry))
2774  {
2775  /* Not the case, give up completely */
2776  Result = FALSE;
2777  goto Quickie;
2778  }
2779 
2780  /* There are spaces, so keep trying the next possibility */
2781  ScanString++;
2782  NullBuffer = ScanString;
2783 
2784  /* We will have to add a quote, since there is a space */
2785  QuotesNeeded = TRUE;
2786  HasQuotes = TRUE;
2787  goto StartScan;
2788  }
2789  }
2790  else if (!(lpCommandLine) || !(*lpCommandLine))
2791  {
2792  /* We don't have a command line, so just use the application name */
2793  CmdLineIsAppName = TRUE;
2794  lpCommandLine = (LPWSTR)lpApplicationName;
2795  }
2796 
2797  /* Convert the application name to its NT path */
2798  TranslationStatus = RtlDosPathNameToRelativeNtPathName_U(lpApplicationName,
2799  &PathName,
2800  NULL,
2801  &SxsWin32RelativePath);
2802  if (!TranslationStatus)
2803  {
2804  /* Path must be invalid somehow, bail out */
2805  DPRINT1("Path translation for SxS failed\n");
2807  Result = FALSE;
2808  goto Quickie;
2809  }
2810 
2811  /* Setup the buffer that needs to be freed at the end */
2812  ASSERT(FreeBuffer == NULL);
2813  FreeBuffer = PathName.Buffer;
2814 
2815  /* Check what kind of path the application is, for SxS (Fusion) purposes */
2816  RtlInitUnicodeString(&SxsWin32ExePath, lpApplicationName);
2817  SxsPathType = RtlDetermineDosPathNameType_U(lpApplicationName);
2818  if ((SxsPathType != RtlPathTypeDriveAbsolute) &&
2819  (SxsPathType != RtlPathTypeLocalDevice) &&
2820  (SxsPathType != RtlPathTypeRootLocalDevice) &&
2821  (SxsPathType != RtlPathTypeUncAbsolute))
2822  {
2823  /* Relative-type path, get the full path */
2824  RtlInitEmptyUnicodeString(&PathBufferString, NULL, 0);
2825  Status = RtlGetFullPathName_UstrEx(&SxsWin32ExePath,
2826  NULL,
2827  &PathBufferString,
2828  NULL,
2829  NULL,
2830  NULL,
2831  &SxsPathType,
2832  NULL);
2833  if (!NT_SUCCESS(Status))
2834  {
2835  /* Fail the rest of the create */
2836  RtlReleaseRelativeName(&SxsWin32RelativePath);
2838  Result = FALSE;
2839  goto Quickie;
2840  }
2841 
2842  /* Use this full path as the SxS path */
2843  SxsWin32ExePath = PathBufferString;
2844  PathBuffer = PathBufferString.Buffer;
2845  PathBufferString.Buffer = NULL;
2846  DPRINT("SxS Path: %S\n", PathBuffer);
2847  }
2848 
2849  /* Also set the .EXE path based on the path name */
2850 #if _SXS_SUPPORT_ENABLED_
2851  SxsNtExePath = PathName;
2852 #endif
2853  if (SxsWin32RelativePath.RelativeName.Length)
2854  {
2855  /* If it's relative, capture the relative name */
2856  PathName = SxsWin32RelativePath.RelativeName;
2857  }
2858  else
2859  {
2860  /* Otherwise, it's absolute, make sure no relative dir is used */
2861  SxsWin32RelativePath.ContainingDirectory = NULL;
2862  }
2863 
2864  /* Now use the path name, and the root path, to try opening the app */
2865  DPRINT("Path: %wZ. Dir: %p\n", &PathName, SxsWin32RelativePath.ContainingDirectory);
2866  InitializeObjectAttributes(&LocalObjectAttributes,
2867  &PathName,
2869  SxsWin32RelativePath.ContainingDirectory,
2870  NULL);
2872  SYNCHRONIZE |
2874  FILE_READ_DATA |
2875  FILE_EXECUTE,
2876  &LocalObjectAttributes,
2877  &IoStatusBlock,
2881  if (!NT_SUCCESS(Status))
2882  {
2883  /* Try to open the app just for execute purposes instead */
2886  &LocalObjectAttributes,
2887  &IoStatusBlock,
2891  }
2892 
2893  /* Failure path, display which file failed to open */
2894  if (!NT_SUCCESS(Status))
2895  DPRINT1("Open file failed: %lx (%wZ)\n", Status, &PathName);
2896 
2897  /* Cleanup in preparation for failure or success */
2898  RtlReleaseRelativeName(&SxsWin32RelativePath);
2899 
2900  if (!NT_SUCCESS(Status))
2901  {
2902  /* Failure path, try to understand why */
2903  if (RtlIsDosDeviceName_U(lpApplicationName))
2904  {
2905  /* If a device is being executed, return this special error code */
2907  Result = FALSE;
2908  goto Quickie;
2909  }
2910  else
2911  {
2912  /* Otherwise return the converted NT error code */
2914  Result = FALSE;
2915  goto Quickie;
2916  }
2917  }
2918 
2919  /* Did the caller specify a desktop? */
2920  if (!StartupInfo.lpDesktop)
2921  {
2922  /* Use the one from the current process */
2924  }
2925 
2926  /* Create a section for this file */
2927  Status = NtCreateSection(&SectionHandle,
2929  NULL,
2930  NULL,
2931  PAGE_EXECUTE,
2932  SEC_IMAGE,
2933  FileHandle);
2934  DPRINT("Section status: %lx\n", Status);
2935  if (NT_SUCCESS(Status))
2936  {
2937  /* Are we running on Windows Embedded, Datacenter, Blade or Starter? */
2938  if (SharedUserData->SuiteMask & (VER_SUITE_EMBEDDEDNT |
2941  VER_SUITE_BLADE))
2942  {
2943  /* These SKUs do not allow running certain applications */
2946  {
2947  /* And this is one of them! */
2948  DPRINT1("Invalid Blade hashes!\n");
2950  Result = FALSE;
2951  goto Quickie;
2952  }
2953 
2954  /* Did we get some other failure? */
2955  if (!NT_SUCCESS(Status))
2956  {
2957  /* If we couldn't check the hashes, assume nefariousness */
2958  DPRINT1("Tampered Blade hashes!\n");
2960  Result = FALSE;
2961  goto Quickie;
2962  }
2963  }
2964 
2965  /* Now do Winsafer, etc, checks */
2966  Status = BasepIsProcessAllowed((LPWSTR)lpApplicationName);
2967  if (!NT_SUCCESS(Status))
2968  {
2969  /* Fail if we're not allowed to launch the process */
2970  DPRINT1("Process not allowed to launch: %lx\n", Status);
2972  if (SectionHandle)
2973  {
2974  NtClose(SectionHandle);
2975  SectionHandle = NULL;
2976  }
2977  Result = FALSE;
2978  goto Quickie;
2979  }
2980 
2981  /* Is a DOS VDM being forced, but we already have a WOW32 instance ready? */
2982  if ((dwCreationFlags & CREATE_FORCEDOS) &&
2984  {
2985  /* This request can't be satisfied, instead, a separate VDM is needed */
2986  dwCreationFlags &= ~(CREATE_FORCEDOS | CREATE_SHARED_WOW_VDM);
2987  dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
2988 
2989  /* Set a failure code, ask for VDM reservation */
2991  UseVdmReserve = TRUE;
2992 
2993  /* Close the current handle */
2994  NtClose(SectionHandle);
2995  SectionHandle = NULL;
2996 
2997  /* Don't query the section later */
2998  QuerySection = FALSE;
2999  }
3000  }
3001 
3002  /* Did we already do these checks? */
3003  if (!SkipSaferAndAppCompat)
3004  {
3005  /* Is everything OK so far, OR do we have an non-MZ, non-DOS app? */
3006  if ((NT_SUCCESS(Status)) ||
3008  !(BaseIsDosApplication(&PathName, Status))))
3009  {
3010  /* Clear the machine type in case of failure */
3011  ImageMachine = 0;
3012 
3013  /* Clean any app compat data that may have accumulated */
3014  BasepFreeAppCompatData(AppCompatData, AppCompatSxsData);
3015  AppCompatData = NULL;
3016  AppCompatSxsData = NULL;
3017 
3018  /* Do we have a section? */
3019  if (SectionHandle)
3020  {
3021  /* Have we already queried it? */
3022  if (QuerySection)
3023  {
3024  /* Nothing to do */
3025  AppCompatStatus = STATUS_SUCCESS;
3026  }
3027  else
3028  {
3029  /* Get some information about the executable */
3030  AppCompatStatus = NtQuerySection(SectionHandle,
3032  &ImageInformation,
3033  sizeof(ImageInformation),
3034  NULL);
3035  }
3036 
3037  /* Do we have section information now? */
3038  if (NT_SUCCESS(AppCompatStatus))
3039  {
3040  /* Don't ask for it again, save the machine type */
3041  QuerySection = TRUE;
3042  ImageMachine = ImageInformation.Machine;
3043  }
3044  }
3045 
3046  /* Is there a reason/Shim we shouldn't run this application? */
3047  AppCompatStatus = BasepCheckBadapp(FileHandle,
3048  FreeBuffer,
3049  lpEnvironment,
3050  ImageMachine,
3051  &AppCompatData,
3052  &AppCompatDataSize,
3053  &AppCompatSxsData,
3054  &AppCompatSxsDataSize,
3055  &FusionFlags);
3056  if (!NT_SUCCESS(AppCompatStatus))
3057  {
3058  /* This is usually the status we get back */
3059  DPRINT1("App compat launch failure: %lx\n", AppCompatStatus);
3060  if (AppCompatStatus == STATUS_ACCESS_DENIED)
3061  {
3062  /* Convert it to something more Win32-specific */
3064  }
3065  else
3066  {
3067  /* Some other error */
3068  BaseSetLastNTError(AppCompatStatus);
3069  }
3070 
3071  /* Did we have a section? */
3072  if (SectionHandle)
3073  {
3074  /* Clean it up */
3075  NtClose(SectionHandle);
3076  SectionHandle = NULL;
3077  }
3078 
3079  /* Fail the call */
3080  Result = FALSE;
3081  goto Quickie;
3082  }
3083  }
3084  }
3085 
3086  //ASSERT((dwFusionFlags & ~SXS_APPCOMPACT_FLAG_APP_RUNNING_SAFEMODE) == 0);
3087 
3088  /* Have we already done, and do we need to do, SRP (WinSafer) checks? */
3089  if (!(SkipSaferAndAppCompat) &&
3090  ~(dwCreationFlags & CREATE_PRESERVE_CODE_AUTHZ_LEVEL))
3091  {
3092  /* Assume yes */
3093  SaferNeeded = TRUE;
3094  switch (Status)
3095  {
3100  /* For all DOS, 16-bit, OS/2 images, we do*/
3101  break;
3102 
3104  /* For invalid files, we don't, unless it's a .BAT file */
3105  if (BaseIsDosApplication(&PathName, Status)) break;
3106 
3107  default:
3108  /* Any other error codes we also don't */
3109  if (!NT_SUCCESS(Status))
3110  {
3111  SaferNeeded = FALSE;
3112  }
3113 
3114  /* But for success, we do */
3115  break;
3116  }
3117 
3118  /* Okay, so what did the checks above result in? */
3119  if (SaferNeeded)
3120  {
3121  /* We have to call into the WinSafer library and actually check */
3123  (LPWSTR)lpApplicationName,
3124  FileHandle,
3125  &InJob,
3126  &TokenHandle,
3127  &JobHandle);
3128  if (SaferStatus == 0xFFFFFFFF)
3129  {
3130  /* Back in 2003, they didn't have an NTSTATUS for this... */
3131  DPRINT1("WinSafer blocking process launch\n");
3133  Result = FALSE;
3134  goto Quickie;
3135  }
3136 
3137  /* Other status codes are not-Safer related, just convert them */
3138  if (!NT_SUCCESS(SaferStatus))
3139  {
3140  DPRINT1("Error checking WinSafer: %lx\n", SaferStatus);
3141  BaseSetLastNTError(SaferStatus);
3142  Result = FALSE;
3143  goto Quickie;
3144  }
3145  }
3146  }
3147 
3148  /* The last step is to figure out why the section object was not created */
3149  switch (Status)
3150  {
3152  {
3153  /* 16-bit binary. Should we use WOW or does the caller force VDM? */
3154  if (!(dwCreationFlags & CREATE_FORCEDOS))
3155  {
3156  /* Remember that we're launching WOW */
3157  IsWowApp = TRUE;
3158 
3159  /* Create the VDM environment, it's valid for WOW too */
3160  Result = BaseCreateVDMEnvironment(lpEnvironment,
3161  &VdmAnsiEnv,
3162  &VdmUnicodeEnv);
3163  if (!Result)
3164  {
3165  DPRINT1("VDM environment for WOW app failed\n");
3166  goto Quickie;
3167  }
3168 
3169  /* We're going to try this twice, so do a loop */
3170  while (TRUE)
3171  {
3172  /* Pick which kind of WOW mode we want to run in */
3173  VdmBinaryType = (dwCreationFlags &
3176 
3177  /* Get all the VDM settings and current status */
3178  Status = BaseCheckVDM(VdmBinaryType,
3179  lpApplicationName,
3180  lpCommandLine,
3181  lpCurrentDirectory,
3182  &VdmAnsiEnv,
3183  &CsrMsg[1],
3184  &VdmTask,
3185  dwCreationFlags,
3186  &StartupInfo,
3187  hUserToken);
3188 
3189  /* If it worked, no need to try again */
3190  if (NT_SUCCESS(Status)) break;
3191 
3192  /* Check if it's disallowed or if it's our second time */
3194  if ((Status == STATUS_VDM_DISALLOWED) ||
3195  (VdmBinaryType == BINARY_TYPE_SEPARATE_WOW) ||
3197  {
3198  /* Fail the call -- we won't try again */
3199  DPRINT1("VDM message failure for WOW: %lx\n", Status);
3200  Result = FALSE;
3201  goto Quickie;
3202  }
3203 
3204  /* Try one more time, but with a separate WOW instance */
3205  dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
3206  }
3207 
3208  /* Check which VDM state we're currently in */
3209  switch (CheckVdmMsg->VDMState & (VDM_NOT_LOADED |
3210  VDM_NOT_READY |
3211  VDM_READY))
3212  {
3213  case VDM_NOT_LOADED:
3214  /* VDM is not fully loaded, so not that much to undo */
3215  VdmUndoLevel = VDM_UNDO_PARTIAL;
3216 
3217  /* Reset VDM reserve if needed */
3218  if (UseVdmReserve) VdmReserve = 1;
3219 
3220  /* Get the required parameters and names for launch */
3221  Result = BaseGetVdmConfigInfo(lpCommandLine,
3222  VdmTask,
3223  VdmBinaryType,
3224  &VdmString,
3225  &VdmReserve);
3226  if (!Result)
3227  {
3228  DPRINT1("VDM Configuration failed for WOW\n");
3230  goto Quickie;
3231  }
3232 
3233  /* Update the command-line with the VDM one instead */
3234  lpCommandLine = VdmString.Buffer;
3235  lpApplicationName = NULL;
3236 
3237  /* We don't want a console, detachment, nor a window */
3238  dwCreationFlags |= CREATE_NO_WINDOW;
3239  dwCreationFlags &= ~(CREATE_NEW_CONSOLE | DETACHED_PROCESS);
3240 
3241  /* Force feedback on */
3242  StartupInfo.dwFlags |= STARTF_FORCEONFEEDBACK;
3243  break;
3244 
3245 
3246  case VDM_READY:
3247  /* VDM is ready, so we have to undo everything */
3248  VdmUndoLevel = VDM_UNDO_REUSE;
3249 
3250  /* Check if CSRSS wants us to wait on VDM */
3251  VdmWaitObject = CheckVdmMsg->WaitObjectForParent;
3252  break;
3253 
3254  case VDM_NOT_READY:
3255  /* Something is wrong with VDM, we'll fail the call */
3256  DPRINT1("VDM is not ready for WOW\n");
3258  Result = FALSE;
3259  goto Quickie;
3260 
3261  default:
3262  break;
3263  }
3264 
3265  /* Since to get NULL, we allocate from 0x1, account for this */
3266  VdmReserve--;
3267 
3268  /* This implies VDM is ready, so skip everything else */
3269  if (VdmWaitObject) goto VdmShortCircuit;
3270 
3271  /* Don't inherit handles since we're doing VDM now */
3272  bInheritHandles = FALSE;
3273 
3274  /* Had the user passed in environment? If so, destroy it */
3275  if ((lpEnvironment) &&
3276  !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
3277  {
3278  RtlDestroyEnvironment(lpEnvironment);
3279  }
3280 
3281  /* We've already done all these checks, don't do them again */
3282  SkipSaferAndAppCompat = TRUE;
3283  goto AppNameRetry;
3284  }
3285 
3286  // There is no break here on purpose, so FORCEDOS drops down!
3287  }
3288 
3292  {
3293  /* We're launching an executable application */
3294  BinarySubType = BINARY_TYPE_EXE;
3295 
3296  /* We can drop here from other "cases" above too, so check */
3299  (BinarySubType = BaseIsDosApplication(&PathName, Status)))
3300  {
3301  /* We're launching a DOS application */
3302  VdmBinaryType = BINARY_TYPE_DOS;
3303 
3304  /* Based on the caller environment, create a VDM one */
3305  Result = BaseCreateVDMEnvironment(lpEnvironment,
3306  &VdmAnsiEnv,
3307  &VdmUnicodeEnv);
3308  if (!Result)
3309  {
3310  DPRINT1("VDM environment for DOS failed\n");
3311  goto Quickie;
3312  }
3313 
3314  /* Check the current state of the VDM subsystem */
3315  Status = BaseCheckVDM(VdmBinaryType | BinarySubType,
3316  lpApplicationName,
3317  lpCommandLine,
3318  lpCurrentDirectory,
3319  &VdmAnsiEnv,
3320  &CsrMsg[1],
3321  &VdmTask,
3322  dwCreationFlags,
3323  &StartupInfo,
3324  NULL);
3325  if (!NT_SUCCESS(Status))
3326  {
3327  /* Failed to inquire about VDM, fail the call */
3328  DPRINT1("VDM message failure for DOS: %lx\n", Status);
3330  Result = FALSE;
3331  goto Quickie;
3332  };
3333 
3334  /* Handle possible VDM states */
3335  switch (CheckVdmMsg->VDMState & (VDM_NOT_LOADED |
3336  VDM_NOT_READY |
3337  VDM_READY))
3338  {
3339  case VDM_NOT_LOADED:
3340  /* If VDM is not loaded, we'll do a partial undo */
3341  VdmUndoLevel = VDM_UNDO_PARTIAL;
3342 
3343  /* A VDM process can't also be detached, so fail */
3344  if (dwCreationFlags & DETACHED_PROCESS)
3345  {
3346  DPRINT1("Detached process but no VDM, not allowed\n");
3348  return FALSE;
3349  }
3350 
3351  /* Get the required parameters and names for launch */
3352  Result = BaseGetVdmConfigInfo(lpCommandLine,
3353  VdmTask,
3354  VdmBinaryType,
3355  &VdmString,
3356  &VdmReserve);
3357  if (!Result)
3358  {
3359  DPRINT1("VDM Configuration failed for DOS\n");
3361  goto Quickie;
3362  }
3363 
3364  /* Update the command-line to launch VDM instead */
3365  lpCommandLine = VdmString.Buffer;
3366  lpApplicationName = NULL;
3367  break;
3368 
3369  case VDM_READY:
3370  /* VDM is ready, so we have to undo everything */
3371  VdmUndoLevel = VDM_UNDO_REUSE;
3372 
3373  /* Check if CSRSS wants us to wait on VDM */
3374  VdmWaitObject = CheckVdmMsg->WaitObjectForParent;
3375  break;
3376 
3377  case VDM_NOT_READY:
3378  /* Something is wrong with VDM, we'll fail the call */
3379  DPRINT1("VDM is not ready for DOS\n");
3381  Result = FALSE;
3382  goto Quickie;
3383 
3384  default:
3385  break;
3386  }
3387 
3388  /* Since to get NULL, we allocate from 0x1, account for this */
3389  VdmReserve--;
3390 
3391  /* This implies VDM is ready, so skip everything else */
3392  if (VdmWaitObject) goto VdmShortCircuit;
3393 
3394  /* Don't inherit handles since we're doing VDM now */
3395  bInheritHandles = FALSE;
3396 
3397  /* Had the user passed in environment? If so, destroy it */
3398  if ((lpEnvironment) &&
3399  !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
3400  {
3401  RtlDestroyEnvironment(lpEnvironment);
3402  }
3403 
3404  /* Use our VDM Unicode environment instead */
3405  lpEnvironment = VdmUnicodeEnv.Buffer;
3406  }
3407  else
3408  {
3409  /* It's a batch file, get the extension */
3410  ExtBuffer = &PathName.Buffer[PathName.Length / sizeof(WCHAR) - 4];
3411 
3412  /* Make sure the extensions are correct */
3413  if ((PathName.Length < (4 * sizeof(WCHAR))) ||
3414  ((_wcsnicmp(ExtBuffer, L".bat", 4)) &&
3415  (_wcsnicmp(ExtBuffer, L".cmd", 4))))
3416  {
3417  DPRINT1("'%wZ': Invalid EXE, and not a batch or script file\n", &PathName);
3419  Result = FALSE;
3420  goto Quickie;
3421  }
3422 
3423  /* Check if we need to account for quotes around the path */
3424  CmdQuoteLength = CmdLineIsAppName || HasQuotes;
3425  if (!CmdLineIsAppName)
3426  {
3427  if (HasQuotes) CmdQuoteLength++;
3428  }
3429  else
3430  {
3431  CmdQuoteLength++;
3432  }
3433 
3434  /* Calculate the length of the command line */
3435  CmdLineLength = wcslen(lpCommandLine);
3436  CmdLineLength += wcslen(CMD_STRING);
3437  CmdLineLength += CmdQuoteLength + sizeof(ANSI_NULL);
3438  CmdLineLength *= sizeof(WCHAR);
3439 
3440  /* Allocate space for the new command line */
3441  AnsiCmdCommand = RtlAllocateHeap(RtlGetProcessHeap(),
3442  0,
3443  CmdLineLength);
3444  if (!AnsiCmdCommand)
3445  {
3447  Result = FALSE;
3448  goto Quickie;
3449  }
3450 
3451  /* Build it */
3452  wcscpy(AnsiCmdCommand, CMD_STRING);
3453  if ((CmdLineIsAppName) || (HasQuotes))
3454  {
3455  wcscat(AnsiCmdCommand, L"\"");
3456  }
3457  wcscat(AnsiCmdCommand, lpCommandLine);
3458  if ((CmdLineIsAppName) || (HasQuotes))
3459  {
3460  wcscat(AnsiCmdCommand, L"\"");
3461  }
3462 
3463  /* Create it as a Unicode String */
3464  RtlInitUnicodeString(&DebuggerString, AnsiCmdCommand);
3465 
3466  /* Set the command line to this */
3467  lpCommandLine = DebuggerString.Buffer;
3468  lpApplicationName = NULL;
3469  DPRINT1("Retrying with: %S\n", lpCommandLine);
3470  }
3471 
3472  /* We've already done all these checks, don't do them again */
3473  SkipSaferAndAppCompat = TRUE;
3474  goto AppNameRetry;
3475  }
3476 
3478  {
3479  /* 64-bit binaries are not allowed to run on 32-bit ReactOS */
3480  DPRINT1("64-bit binary, failing\n");
3482  Result = FALSE;
3483  goto Quickie;
3484  }
3485 
3487  {
3488  /* Set the correct last error for this */
3489  DPRINT1("File is offline, failing\n");
3491  break;
3492  }
3493 
3494  default:
3495  {
3496  /* Any other error, convert it to a generic Win32 error */
3497  if (!NT_SUCCESS(Status))
3498  {
3499  DPRINT1("Failed to create section: %lx\n", Status);
3501  Result = FALSE;
3502  goto Quickie;
3503  }
3504 
3505  /* Otherwise, this must be success */
3507  break;
3508  }
3509  }
3510 
3511  /* Is this not a WOW application, but a WOW32 VDM was requested for it? */
3512  if (!(IsWowApp) && (dwCreationFlags & CREATE_SEPARATE_WOW_VDM))
3513  {
3514  /* Ignore the nonsensical request */
3515  dwCreationFlags &= ~CREATE_SEPARATE_WOW_VDM;
3516  }
3517 
3518  /* Did we already check information for the section? */
3519  if (!QuerySection)
3520  {
3521  /* Get some information about the executable */
3522  Status = NtQuerySection(SectionHandle,
3524  &ImageInformation,
3525  sizeof(ImageInformation),
3526  NULL);
3527  if (!NT_SUCCESS(Status))
3528  {
3529  /* We failed, bail out */
3530  DPRINT1("Section query failed\n");
3532  Result = FALSE;
3533  goto Quickie;
3534  }
3535 
3536  /* Don't check this later */
3537  QuerySection = TRUE;
3538  }
3539 
3540  /* Check if this was linked as a DLL */
3541  if (ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL)
3542  {
3543  /* These aren't valid images to try to execute! */
3544  DPRINT1("Trying to launch a DLL, failing\n");
3546  Result = FALSE;
3547  goto Quickie;
3548  }
3549 
3550  /* Don't let callers pass in this flag -- we'll only get it from IFEO */
3552 
3553  /* Clear the IFEO-missing flag, before we know for sure... */
3554  ParameterFlags &= ~2;
3555 
3556  /* If the process is being debugged, only read IFEO if the PEB says so */
3557  if (!(dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)) ||
3558  (NtCurrentPeb()->ReadImageFileExecOptions))
3559  {
3560  /* Let's do this! Attempt to open IFEO */
3561  IFEOStatus = LdrOpenImageFileOptionsKey(&PathName, 0, &KeyHandle);
3562  if (!NT_SUCCESS(IFEOStatus))
3563  {
3564  /* We failed, set the flag so we store this in the parameters */
3565  if (IFEOStatus == STATUS_OBJECT_NAME_NOT_FOUND) ParameterFlags |= 2;
3566  }
3567  else
3568  {
3569  /* Was this our first time going through this path? */
3570  if (!DebuggerCmdLine)
3571  {
3572  /* Allocate a buffer for the debugger path */
3573  DebuggerCmdLine = RtlAllocateHeap(RtlGetProcessHeap(),
3574  0,
3575  MAX_PATH * sizeof(WCHAR));
3576  if (!DebuggerCmdLine)
3577  {
3578  /* Close IFEO on failure */
3579  IFEOStatus = NtClose(KeyHandle);
3580  ASSERT(NT_SUCCESS(IFEOStatus));
3581 
3582  /* Fail the call */
3584  Result = FALSE;
3585  goto Quickie;
3586  }
3587  }
3588 
3589  /* Now query for the debugger */
3591  L"Debugger",
3592  REG_SZ,
3593  DebuggerCmdLine,
3594  MAX_PATH * sizeof(WCHAR),
3595  &ResultSize);
3596  if (!(NT_SUCCESS(IFEOStatus)) ||
3597  (ResultSize < sizeof(WCHAR)) ||
3598  (DebuggerCmdLine[0] == UNICODE_NULL))
3599  {
3600  /* If it's not there, or too small, or invalid, ignore it */
3601  RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine);
3602  DebuggerCmdLine = NULL;
3603  }
3604 
3605  /* Also query if we should map with large pages */
3607  L"UseLargePages",
3608  REG_DWORD,
3609  &UseLargePages,
3610  sizeof(UseLargePages),
3611  NULL);
3612  if ((NT_SUCCESS(IFEOStatus)) && (UseLargePages))
3613  {
3614  /* Do it! This is the only way this flag can be set */
3616  }
3617 
3618  /* We're done with IFEO, can close it now */
3619  IFEOStatus = NtClose(KeyHandle);
3620  ASSERT(NT_SUCCESS(IFEOStatus));
3621  }
3622  }
3623 
3624  /* Make sure the image was compiled for this processor */
3625  if ((ImageInformation.Machine < SharedUserData->ImageNumberLow) ||
3626  (ImageInformation.Machine > SharedUserData->ImageNumberHigh))
3627  {
3628  /* It was not -- raise a hard error */
3629  ErrorResponse = ResponseOk;
3630  ErrorParameters[0] = (ULONG_PTR)&PathName;
3632  1,
3633  1,
3634  ErrorParameters,
3635  OptionOk,
3636  &ErrorResponse);
3637  if (Peb->ImageSubsystemMajorVersion <= 3)
3638  {
3639  /* If it's really old, return this error */
3641  }
3642  else
3643  {
3644  /* Otherwise, return a more modern error */
3646  }
3647 
3648  /* Go to the failure path */
3649  DPRINT1("Invalid image architecture: %lx\n", ImageInformation.Machine);
3650  Result = FALSE;
3651  goto Quickie;
3652  }
3653 
3654  /* Check if this isn't a Windows image */
3655  if ((ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_GUI) &&
3656  (ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_CUI))
3657  {
3658  /* Get rid of section-related information since we'll retry */
3659  NtClose(SectionHandle);
3660  SectionHandle = NULL;
3661  QuerySection = FALSE;
3662 
3663  /* The only other non-Windows image type we support here is POSIX */
3664  if (ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_POSIX_CUI)
3665  {
3666  /* Bail out if it's something else */
3668  Result = FALSE;
3669  goto Quickie;
3670  }
3671 
3672  /* Now build the command-line to have posix launch this image */
3673  Result = BuildSubSysCommandLine(L"POSIX /P ",
3674  lpApplicationName,
3675  lpCommandLine,
3676  &DebuggerString);
3677  if (!Result)
3678  {
3679  /* Bail out if that failed */
3680  DPRINT1("Subsystem command line failed\n");
3681  goto Quickie;
3682  }
3683 
3684  /* And re-try launching the process, with the new command-line now */
3685  lpCommandLine = DebuggerString.Buffer;
3686  lpApplicationName = NULL;
3687 
3688  /* We've already done all these checks, don't do them again */
3689  SkipSaferAndAppCompat = TRUE;
3690  DPRINT1("Retrying with: %S\n", lpCommandLine);
3691  goto AppNameRetry;
3692  }
3693 
3694  /* Was this image built for a version of Windows whose images we can run? */
3696  ImageInformation.SubSystemMinorVersion);
3697  if (!Result)
3698  {
3699  /* It was not, bail out */
3700  DPRINT1("Invalid subsystem version: %hu.%hu\n",
3701  ImageInformation.SubSystemMajorVersion,
3702  ImageInformation.SubSystemMinorVersion);
3704  goto Quickie;
3705  }
3706 
3707  /* Check if there is a debugger associated with the application */
3708  if (DebuggerCmdLine)
3709  {
3710  /* Get the length of the command line */
3711  n = wcslen(lpCommandLine);
3712  if (!n)
3713  {
3714  /* There's no command line, use the application name instead */
3715  lpCommandLine = (LPWSTR)lpApplicationName;
3716  n = wcslen(lpCommandLine);
3717  }
3718 
3719  /* Protect against overflow */
3721  {
3723  Result = FALSE;
3724  goto Quickie;
3725  }
3726 
3727  /* Now add the length of the debugger command-line */
3728  n += wcslen(DebuggerCmdLine);
3729 
3730  /* Again make sure we don't overflow */
3732  {
3734  Result = FALSE;
3735  goto Quickie;
3736  }
3737 
3738  /* Account for the quotes and space between the two */
3739  n += sizeof("\" \"") - sizeof(ANSI_NULL);
3740 
3741  /* Convert to bytes, and make sure we don't overflow */
3742  n *= sizeof(WCHAR);
3744  {
3746  Result = FALSE;
3747  goto Quickie;
3748  }
3749 
3750  /* Allocate space for the string */
3751  DebuggerString.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, n);
3752  if (!DebuggerString.Buffer)
3753  {
3755  Result = FALSE;
3756  goto Quickie;
3757  }
3758 
3759  /* Set the length */
3760  RtlInitEmptyUnicodeString(&DebuggerString,
3761  DebuggerString.Buffer,
3762  (USHORT)n);
3763 
3764  /* Now perform the command line creation */
3765  ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString,
3766  DebuggerCmdLine);
3767  ASSERT(NT_SUCCESS(ImageDbgStatus));
3768  ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString, L" ");
3769  ASSERT(NT_SUCCESS(ImageDbgStatus));
3770  ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString, lpCommandLine);
3771  ASSERT(NT_SUCCESS(ImageDbgStatus));
3772 
3773  /* Make sure it all looks nice */
3774  DbgPrint("BASE: Calling debugger with '%wZ'\n", &DebuggerString);
3775 
3776  /* Update the command line and application name */
3777  lpCommandLine = DebuggerString.Buffer;
3778  lpApplicationName = NULL;
3779 
3780  /* Close all temporary state */
3781  NtClose(SectionHandle);
3782  SectionHandle = NULL;
3783  QuerySection = FALSE;
3784 
3785  /* Free all temporary memory */
3786  RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
3787  NameBuffer = NULL;
3788  RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer);
3789  FreeBuffer = NULL;
3790  RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine);
3791  DebuggerCmdLine = NULL;
3792  DPRINT1("Retrying with: %S\n", lpCommandLine);
3793  goto AppNameRetry;
3794  }
3795 
3796  /* Initialize the process object attributes */
3797  ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
3798  lpProcessAttributes,
3799  NULL);
3800  if ((hUserToken) && (lpProcessAttributes))
3801  {
3802  /* Augment them with information from the user */
3803 
3804  LocalProcessAttributes = *lpProcessAttributes;
3805  LocalProcessAttributes.lpSecurityDescriptor = NULL;
3806  ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
3807  &LocalProcessAttributes,
3808  NULL);
3809  }
3810 
3811  /* Check if we're going to be debugged */
3812  if (dwCreationFlags & DEBUG_PROCESS)
3813  {
3814  /* Set process flag */
3816  }
3817 
3818  /* Check if we're going to be debugged */
3819  if (dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
3820  {
3821  /* Connect to DbgUi */
3823  if (!NT_SUCCESS(Status))
3824  {
3825  DPRINT1("Failed to connect to DbgUI!\n");
3827  Result = FALSE;
3828  goto Quickie;
3829  }
3830 
3831  /* Get the debug object */
3832  DebugHandle = DbgUiGetThreadDebugObject();
3833 
3834  /* Check if only this process will be debugged */
3835  if (dwCreationFlags & DEBUG_ONLY_THIS_PROCESS)
3836  {
3837  /* Set process flag */
3839  }
3840  }
3841 
3842  /* Set inherit flag */
3843  if (bInheritHandles) Flags |= PROCESS_CREATE_FLAGS_INHERIT_HANDLES;
3844 
3845  /* Check if the process should be created with large pages */
3846  HavePrivilege = FALSE;
3847  PrivilegeState = NULL;
3849  {
3850  /* Acquire the required privilege so that the kernel won't fail the call */
3851  PrivilegeValue = SE_LOCK_MEMORY_PRIVILEGE;
3852  Status = RtlAcquirePrivilege(&PrivilegeValue, 1, 0, &PrivilegeState);
3853  if (NT_SUCCESS(Status))
3854  {
3855  /* Remember to release it later */
3856  HavePrivilege = TRUE;
3857  }
3858  }
3859 
3860  /* Save the current TIB value since kernel overwrites it to store PEB */
3861  TibValue = Teb->NtTib.ArbitraryUserPointer;
3862 
3863  /* Tell the kernel to create the process */
3867  NtCurrentProcess(),
3868  Flags,
3869  SectionHandle,
3870  DebugHandle,
3871  NULL,
3872  InJob);
3873 
3874  /* Load the PEB address from the hacky location where the kernel stores it */
3875  RemotePeb = Teb->NtTib.ArbitraryUserPointer;
3876 
3877  /* And restore the old TIB value */
3878  Teb->NtTib.ArbitraryUserPointer = TibValue;
3879 
3880  /* Release the large page privilege if we had acquired it */
3881  if (HavePrivilege) RtlReleasePrivilege(PrivilegeState);
3882 
3883  /* And now check if the kernel failed to create the process */
3884  if (!NT_SUCCESS(Status))
3885  {
3886  /* Go to failure path */
3887  DPRINT1("Failed to create process: %lx\n", Status);
3889  Result = FALSE;
3890  goto Quickie;
3891  }
3892 
3893  /* Check if there is a priority class to set */
3894  if (PriorityClass.PriorityClass)
3895  {
3896  /* Reset current privilege state */
3897  RealTimePrivilegeState = NULL;
3898 
3899  /* Is realtime priority being requested? */
3900  if (PriorityClass.PriorityClass == PROCESS_PRIORITY_CLASS_REALTIME)
3901  {
3902  /* Check if the caller has real-time access, and enable it if so */
3903  RealTimePrivilegeState = BasepIsRealtimeAllowed(TRUE);
3904  }
3905 
3906  /* Set the new priority class and release the privilege */
3909  &PriorityClass,
3910  sizeof(PROCESS_PRIORITY_CLASS));
3911  if (RealTimePrivilegeState) RtlReleasePrivilege(RealTimePrivilegeState);
3912 
3913  /* Check if we failed to set the priority class */
3914  if (!NT_SUCCESS(Status))
3915  {
3916  /* Bail out on failure */
3917  DPRINT1("Failed to set priority class: %lx\n", Status);
3919  Result = FALSE;
3920  goto Quickie;
3921  }
3922  }
3923 
3924  /* Check if the caller wants the default error mode */
3925  if (dwCreationFlags & CREATE_DEFAULT_ERROR_MODE)
3926  {
3927  /* Set Error Mode to only fail on critical errors */
3928  HardErrorMode = SEM_FAILCRITICALERRORS;
3931  &HardErrorMode,
3932  sizeof(ULONG));
3933  }
3934 
3935  /* Check if this was a VDM binary */
3936  if (VdmBinaryType)
3937  {
3938  /* Update VDM by telling it the process has now been created */
3939  VdmWaitObject = ProcessHandle;
3941  &VdmWaitObject,
3942  VdmTask,
3943  VdmBinaryType);
3944 
3945  if (!Result)
3946  {
3947  /* Bail out on failure */
3948  DPRINT1("Failed to update VDM with wait object\n");
3949  VdmWaitObject = NULL;
3950  goto Quickie;
3951  }
3952 
3953  /* At this point, a failure means VDM has to undo all the state */
3954  VdmUndoLevel |= VDM_UNDO_FULL;
3955  }
3956 
3957  /* Check if VDM needed reserved low-memory */
3958  if (VdmReserve)
3959  {
3960  /* Reserve the requested allocation */
3961  RegionSize = VdmReserve;
3963  &BaseAddress,
3964  0,
3965  &RegionSize,
3966  MEM_RESERVE,
3968  if (!NT_SUCCESS(Status))
3969  {
3970  /* Bail out on failure */
3971  DPRINT1("Failed to reserve memory for VDM: %lx\n", Status);
3973  Result = FALSE;
3974  goto Quickie;
3975  }
3976 
3977  VdmReserve = (ULONG)RegionSize;
3978  }
3979 
3980  /* Check if we've already queried information on the section */
3981  if (!QuerySection)
3982  {
3983  /* We haven't, so get some information about the executable */
3984  Status = NtQuerySection(SectionHandle,
3986  &ImageInformation,
3987  sizeof(ImageInformation),
3988  NULL);
3989  if (!NT_SUCCESS(Status))
3990  {
3991  /* Bail out on failure */
3992  DPRINT1("Failed to query section: %lx\n", Status);
3994  Result = FALSE;
3995  goto Quickie;
3996  }
3997 
3998  /* If we encounter a restart, don't re-query this information again */
3999  QuerySection = TRUE;
4000  }
4001 
4002  /* Do we need to apply SxS to this image? */
4004  {
4005  /* Too bad, we don't support this yet */
4006  DPRINT1("Image should receive SxS Fusion Isolation\n");
4007  }
4008 
4009  /* There's some SxS flag that we need to set if fusion flags have 1 set */
4010  if (FusionFlags & 1) CreateProcessMsg->Sxs.Flags |= 0x10;
4011 
4012  /* Check if we have a current directory */
4013  if (lpCurrentDirectory)
4014  {
4015  /* Allocate a buffer so we can keep a Unicode copy */
4016  DPRINT("Current directory: %S\n", lpCurrentDirectory);
4017  CurrentDirectory = RtlAllocateHeap(RtlGetProcessHeap(),
4018  0,
4019  (MAX_PATH * sizeof(WCHAR)) +
4020  sizeof(UNICODE_NULL));
4021  if (!CurrentDirectory)
4022  {
4023  /* Bail out if this failed */
4025  Result = FALSE;
4026  goto Quickie;
4027  }
4028 
4029  /* Get the length in Unicode */
4030  Length = GetFullPathNameW(lpCurrentDirectory,
4031  MAX_PATH,
4033  &FilePart);
4034  if (Length > MAX_PATH)
4035  {
4036  /* The directory is too long, so bail out */
4038  Result = FALSE;
4039  goto Quickie;
4040  }
4041 
4042  /* Make sure the directory is actually valid */
4043  FileAttribs = GetFileAttributesW(CurrentDirectory);
4044  if ((FileAttribs == INVALID_FILE_ATTRIBUTES) ||
4045  !(FileAttribs & FILE_ATTRIBUTE_DIRECTORY))
4046  {
4047  /* It isn't, so bail out */
4048  DPRINT1("Current directory is invalid\n");
4050  Result = FALSE;
4051  goto Quickie;
4052  }
4053  }
4054 
4055  /* Insert quotes if needed */
4056  if ((QuotesNeeded) || (CmdLineIsAppName))
4057  {
4058  /* Allocate our buffer, plus enough space for quotes and a NULL */
4059  QuotedCmdLine = RtlAllocateHeap(RtlGetProcessHeap(),
4060  0,
4061  (wcslen(lpCommandLine) * sizeof(WCHAR)) +
4062  (2 * sizeof(L'\"') + sizeof(UNICODE_NULL)));
4063  if (QuotedCmdLine)
4064  {
4065  /* Copy the first quote */
4066  wcscpy(QuotedCmdLine, L"\"");
4067 
4068  /* Save the current null-character */
4069  if (QuotesNeeded)
4070  {
4071  SaveChar = *NullBuffer;
4072  *NullBuffer = UNICODE_NULL;
4073  }
4074 
4075  /* Copy the command line and the final quote */
4076  wcscat(QuotedCmdLine, lpCommandLine);
4077  wcscat(QuotedCmdLine, L"\"");
4078 
4079  /* Copy the null-char back */
4080  if (QuotesNeeded)
4081  {
4082  *NullBuffer = SaveChar;
4083  wcscat(QuotedCmdLine, NullBuffer);
4084  }
4085  }
4086  else
4087  {
4088  /* We can't put quotes around the thing, so try it anyway */
4089  if (QuotesNeeded) QuotesNeeded = FALSE;
4090  if (CmdLineIsAppName) CmdLineIsAppName = FALSE;
4091  }
4092  }
4093 
4094  /* Use isolation if needed */
4095  if (CreateProcessMsg->Sxs.Flags & 1) ParameterFlags |= 1;
4096 
4097  /* Set the new command-line if needed */
4098  if ((QuotesNeeded) || (CmdLineIsAppName)) lpCommandLine = QuotedCmdLine;
4099 
4100  /* Call the helper function in charge of RTL_USER_PROCESS_PARAMETERS */
4101  Result = BasePushProcessParameters(ParameterFlags,
4102  ProcessHandle,
4103  RemotePeb,
4104  lpApplicationName,
4106  lpCommandLine,
4107  lpEnvironment,
4108  &StartupInfo,
4109  dwCreationFlags | NoWindow,
4110  bInheritHandles,
4111  IsWowApp ? IMAGE_SUBSYSTEM_WINDOWS_GUI: 0,
4112  AppCompatData,
4113  AppCompatDataSize);
4114  if (!Result)
4115  {
4116  /* The remote process would have an undefined state, so fail the call */
4117  DPRINT1("BasePushProcessParameters failed\n");
4118  goto Quickie;
4119  }
4120 
4121  /* Free the VDM command line string as it's no longer needed */
4122  RtlFreeUnicodeString(&VdmString);
4123  VdmString.Buffer = NULL;
4124 
4125  /* Non-VDM console applications usually inherit handles unless specified */
4126  if (!(VdmBinaryType) &&
4127  !(bInheritHandles) &&
4128  !(StartupInfo.dwFlags & STARTF_USESTDHANDLES) &&
4129  !(dwCreationFlags & (CREATE_NO_WINDOW |
4131  DETACHED_PROCESS)) &&
4132  (ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_CUI))
4133  {
4134  /* Get the remote parameters */
4136  &RemotePeb->ProcessParameters,
4137  &ProcessParameters,
4139  NULL);
4140  if (NT_SUCCESS(Status))
4141  {
4142  /* Duplicate standard input unless it's a console handle */
4144  {
4147  &ProcessParameters->StandardInput);
4148  }
4149 
4150  /* Duplicate standard output unless it's a console handle */
4152  {
4155  &ProcessParameters->StandardOutput);
4156  }
4157 
4158  /* Duplicate standard error unless it's a console handle */
4160  {
4163  &ProcessParameters->StandardError);
4164  }
4165  }
4166  }
4167 
4168  /* Create the Thread's Stack */
4169  StackSize = max(256 * 1024, ImageInformation.MaximumStackSize);
4171  ImageInformation.CommittedStackSize,
4172  StackSize,
4173  &InitialTeb);
4174  if (!NT_SUCCESS(Status))
4175  {
4176  DPRINT1("Creating the thread stack failed: %lx\n", Status);
4178  Result = FALSE;
4179  goto Quickie;
4180  }
4181 
4182  /* Create the Thread's Context */
4184  Peb,
4185  ImageInformation.TransferAddress,
4186  InitialTeb.StackBase,
4187  0);
4188 
4189  /* Convert the thread attributes */
4190  ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
4191  lpThreadAttributes,
4192  NULL);
4193  if ((hUserToken) && (lpThreadAttributes))
4194  {
4195  /* If the caller specified a user token, zero the security descriptor */
4196  LocalThreadAttributes = *lpThreadAttributes;
4197  LocalThreadAttributes.lpSecurityDescriptor = NULL;
4198  ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
4199  &LocalThreadAttributes,
4200  NULL);
4201  }
4202 
4203  /* Create the Kernel Thread Object */
4204  Status = NtCreateThread(&ThreadHandle,
4207  ProcessHandle,
4208  &ClientId,
4209  &Context,
4210  &InitialTeb,
4211  TRUE);
4212  if (!NT_SUCCESS(Status))
4213  {
4214  /* A process is not allowed to exist without a main thread, so fail */
4215  DPRINT1("Creating the main thread failed: %lx\n", Status);
4217  Result = FALSE;
4218  goto Quickie;
4219  }
4220 
4221  /* Begin filling out the CSRSS message, first with our IDs and handles */
4222  CreateProcessMsg->ProcessHandle = ProcessHandle;
4223  CreateProcessMsg->ThreadHandle = ThreadHandle;
4224  CreateProcessMsg->ClientId = ClientId;
4225 
4226  /* Write the remote PEB address and clear it locally, we no longer use it */
4227  CreateProcessMsg->PebAddressNative = RemotePeb;
4228 #ifdef _WIN64
4229  DPRINT1("TODO: WOW64 is not supported yet\n");
4230  CreateProcessMsg->PebAddressWow64 = 0;
4231 #else
4232  CreateProcessMsg->PebAddressWow64 = (ULONG)RemotePeb;
4233 #endif
4234  RemotePeb = NULL;
4235 
4236  /* Now check what kind of architecture this image was made for */
4237  switch (ImageInformation.Machine)
4238  {
4239  /* IA32, IA64 and AMD64 are supported in Server 2003 */
4242  break;
4245  break;
4248  break;
4249 
4250  /* Anything else results in image unknown -- but no failure */
4251  default:
4252  DbgPrint("kernel32: No mapping for ImageInformation.Machine == %04x\n",
4253  ImageInformation.Machine);
4255  break;
4256  }
4257 
4258  /* Write the input creation flags except any debugger-related flags */
4259  CreateProcessMsg->CreationFlags = dwCreationFlags &
4261 
4262  /* CSRSS needs to know if this is a GUI app or not */
4263  if ((ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_GUI) ||
4264  (IsWowApp))
4265  {
4266  /*
4267  * For GUI apps we turn on the 2nd bit. This allow CSRSS server dlls
4268  * (basesrv in particular) to know whether or not this is a GUI or a
4269  * TUI application.
4270  */
4271  AddToHandle(CreateProcessMsg->ProcessHandle, 2);
4272 
4273  /* Also check if the parent is also a GUI process */
4274  NtHeaders = RtlImageNtHeader(GetModuleHandle(NULL));
4275  if ((NtHeaders) &&
4277  {
4278  /* Let it know that it should display the hourglass mouse cursor */
4279  AddToHandle(CreateProcessMsg->ProcessHandle, 1);
4280  }
4281  }
4282 
4283  /* For all apps, if this flag is on, the hourglass mouse cursor is shown */
4284  if (StartupInfo.dwFlags & STARTF_FORCEONFEEDBACK)
4285  {
4286  AddToHandle(CreateProcessMsg->ProcessHandle, 1);
4287  }
4288 
4289  /* Likewise, the opposite holds as well */
4290  if (StartupInfo.dwFlags & STARTF_FORCEOFFFEEDBACK)
4291  {
4292  RemoveFromHandle(CreateProcessMsg->ProcessHandle, 1);
4293  }
4294 
4295  /* Also store which kind of VDM app (if any) this is */
4296  CreateProcessMsg->VdmBinaryType = VdmBinaryType;
4297 
4298  /* And if it really is a VDM app... */
4299  if (VdmBinaryType)
4300  {
4301  /* Store the task ID and VDM console handle */
4302  CreateProcessMsg->hVDM = VdmTask ? 0 : Peb->ProcessParameters->ConsoleHandle;
4303  CreateProcessMsg->VdmTask = VdmTask;
4304  }
4305  else if (VdmReserve)
4306  {
4307  /* Extended VDM, set a flag */
4308  CreateProcessMsg->VdmBinaryType |= BINARY_TYPE_WOW_EX;
4309  }
4310 
4311  /* Check if there's side-by-side assembly data associated with the process */
4312  if (CreateProcessMsg->Sxs.Flags)
4313  {
4314  /* This should not happen in ReactOS yet */
4315  DPRINT1("This is an SxS Message -- should not happen yet\n");
4318  Result = FALSE;
4319  goto Quickie;
4320  }
4321 
4322  /* We are finally ready to call CSRSS to tell it about our new process! */
4324  CaptureBuffer,
4327  sizeof(*CreateProcessMsg));
4328 
4329  /* CSRSS has returned, free the capture buffer now if we had one */
4330  if (CaptureBuffer)
4331  {
4332  CsrFreeCaptureBuffer(CaptureBuffer);
4333  CaptureBuffer = NULL;
4334  }
4335 
4336  /* Check if CSRSS failed to accept ownership of the new Windows process */
4337  if (!NT_SUCCESS(CsrMsg[0].Status))
4338  {
4339  /* Terminate the process and enter failure path with the CSRSS status */
4340  DPRINT1("Failed to tell csrss about new process\n");
4341  BaseSetLastNTError(CsrMsg[0].Status);
4343  Result = FALSE;
4344  goto Quickie;
4345  }
4346 
4347  /* Check if we have a token due to Authz/Safer, not passed by the user */
4348  if ((TokenHandle) && !(hUserToken))
4349  {
4350  /* Replace the process and/or thread token with the one from Safer */
4352  ProcessHandle,
4353  ThreadHandle);
4354  if (!NT_SUCCESS(Status))
4355  {
4356  /* If this failed, kill the process and enter the failure path */
4357  DPRINT1("Failed to update process token: %lx\n", Status);
4360  Result = FALSE;
4361  goto Quickie;
4362  }
4363  }
4364 
4365  /* Check if a job was associated with this process */
4366  if (JobHandle)
4367  {
4368  /* Bind the process and job together now */
4370  if (!NT_SUCCESS(Status))
4371  {
4372  /* Kill the process and enter the failure path if binding failed */
4373  DPRINT1("Failed to assign process to job: %lx\n", Status);
4376  Result = FALSE;
4377  goto Quickie;
4378  }
4379  }
4380 
4381  /* Finally, resume the thread to actually get the process started */
4382  if (!(dwCreationFlags & CREATE_SUSPENDED))
4383  {
4384  NtResumeThread(ThreadHandle, &ResumeCount);
4385  }
4386 
4387 VdmShortCircuit:
4388  /* We made it this far, meaning we have a fully created process and thread */
4389  Result = TRUE;
4390 
4391  /* Anyone doing a VDM undo should now undo everything, since we are done */
4392  if (VdmUndoLevel) VdmUndoLevel |= VDM_UNDO_COMPLETED;
4393 
4394  /* Having a VDM wait object implies this must be a VDM process */
4395  if (VdmWaitObject)
4396  {
4397  /* Check if it's a 16-bit separate WOW process */
4398  if (VdmBinaryType == BINARY_TYPE_SEPARATE_WOW)
4399  {
4400  /* OR-in the special flag to indicate this, and return to caller */
4401  AddToHandle(VdmWaitObject, 2);
4402  lpProcessInformation->hProcess = VdmWaitObject;
4403 
4404  /* Check if this was a re-used VDM */
4405  if (VdmUndoLevel & VDM_UNDO_REUSE)
4406  {
4407  /* No Client ID should be returned in this case */
4408  ClientId.UniqueProcess = 0;
4409  ClientId.UniqueThread = 0;
4410  }
4411  }
4412  else
4413  {
4414  /* OR-in the special flag to indicate this is not a separate VDM */
4415  AddToHandle(VdmWaitObject, 1);
4416 
4417  /* Return handle to the caller */
4418  lpProcessInformation->hProcess = VdmWaitObject;
4419  }
4420 
4421  /* Close the original process handle, since it's not needed for VDM */
4423  }
4424  else
4425  {
4426  /* This is a regular process, so return the real process handle */
4427  lpProcessInformation->hProcess = ProcessHandle;
4428  }
4429 
4430  /* Return the rest of the process information based on what we have so far */
4431  lpProcessInformation->hThread = ThreadHandle;
4432  lpProcessInformation->dwProcessId = HandleToUlong(ClientId.UniqueProcess);
4433  lpProcessInformation->dwThreadId = HandleToUlong(ClientId.UniqueThread);
4434 
4435  /* NULL these out here so we know to treat this as a success scenario */
4436  ProcessHandle = NULL;
4437  ThreadHandle = NULL;
4438 
4439 Quickie:
4440  /* Free the debugger command line if one was allocated */
4441  if (DebuggerCmdLine) RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine);
4442 
4443  /* Check if an SxS full path as queried */
4444  if (PathBuffer)
4445  {
4446  /* Reinitialize the executable path */
4447  RtlInitEmptyUnicodeString(&SxsWin32ExePath, NULL, 0);
4448  SxsWin32ExePath.Length = 0;
4449 
4450  /* Free the path buffer */
4451  RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
4452  }
4453 
4454 #if _SXS_SUPPORT_ENABLED_
4455  /* Check if this was a non-VDM process */
4456  if (!VdmBinaryType)
4457  {
4458  /* Then it must've had SxS data, so close the handles used for it */
4459  BasepSxsCloseHandles(&Handles);
4460  BasepSxsCloseHandles(&FileHandles);
4461 
4462  /* Check if we built SxS byte buffers for this create process request */
4463  if (SxsConglomeratedBuffer)
4464  {
4465  /* Loop all of them */
4466  for (i = 0; i < 5; i++)
4467  {
4468  /* Check if this one was allocated */
4469  ThisBuffer = SxsStaticBuffers[i];
4470  if (ThisBuffer)
4471  {
4472  /* Get the underlying RTL_BUFFER structure */
4473  ByteBuffer = &ThisBuffer->ByteBuffer;
4474  if ((ThisBuffer != (PVOID)-8) && (ByteBuffer->Buffer))
4475  {
4476  /* Check if it was dynamic */
4477  if (ByteBuffer->Buffer != ByteBuffer->StaticBuffer)
4478  {
4479  /* Free it from the heap */
4480  FreeString.Buffer = (PWCHAR)ByteBuffer->Buffer;
4481  RtlFreeUnicodeString(&FreeString);
4482  }
4483 
4484  /* Reset the buffer to its static data */
4485  ByteBuffer->Buffer = ByteBuffer->StaticBuffer;
4486  ByteBuffer->Size = ByteBuffer->StaticSize;
4487  }
4488 
4489  /* Reset the string to the static buffer */
4490  RtlInitEmptyUnicodeString(&ThisBuffer->String,
4491  (PWCHAR)ByteBuffer->StaticBuffer,
4492  ByteBuffer->StaticSize);
4493  if (ThisBuffer->String.Buffer)
4494  {
4495  /* Also NULL-terminate it */
4496  *ThisBuffer->String.Buffer = UNICODE_NULL;
4497  }
4498  }
4499  }
4500  }
4501  }
4502 #endif
4503  /* Check if an environment was passed in */
4504  if ((lpEnvironment) && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
4505  {
4506  /* Destroy it */
4507  RtlDestroyEnvironment(lpEnvironment);
4508 
4509  /* If this was the VDM environment too, clear that as well */
4510  if (VdmUnicodeEnv.Buffer == lpEnvironment) VdmUnicodeEnv.Buffer = NULL;
4511  lpEnvironment = NULL;
4512  }
4513 
4514  /* Unconditionally free all the name parsing buffers we always allocate */
4515  RtlFreeHeap(RtlGetProcessHeap(), 0, QuotedCmdLine);
4516  RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
4517  RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDirectory);
4518  RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer);
4519 
4520  /* Close open file/section handles */
4522  if (SectionHandle) NtClose(SectionHandle);
4523 
4524  /* If we have a thread handle, this was a failure path */
4525  if (ThreadHandle)
4526  {
4527  /* So kill the process and close the thread handle */
4529  NtClose(ThreadHandle);
4530  }
4531 
4532  /* If we have a process handle, this was a failure path, so close it */
4534 
4535  /* Thread/process handles, if any, are now processed. Now close this one. */
4536  if (JobHandle) NtClose(JobHandle);
4537 
4538  /* Check if we had created a token */
4539  if (TokenHandle)
4540  {
4541  /* And if the user asked for one */
4542  if (hUserToken)
4543  {
4544  /* Then return it */
4545  *hNewToken = TokenHandle;
4546  }
4547  else
4548  {
4549  /* User didn't want it, so we used it temporarily -- close it */
4551  }
4552  }
4553 
4554  /* Free any temporary app compatibility data, it's no longer needed */
4555  BasepFreeAppCompatData(AppCompatData, AppCompatSxsData);
4556 
4557  /* Free a few strings. The API takes care of these possibly being NULL */
4558  RtlFreeUnicodeString(&VdmString);
4559  RtlFreeUnicodeString(&DebuggerString);
4560 
4561  /* Check if we had built any sort of VDM environment */
4562  if ((VdmAnsiEnv.Buffer) || (VdmUnicodeEnv.Buffer))
4563  {
4564  /* Free it */
4565  BaseDestroyVDMEnvironment(&VdmAnsiEnv, &VdmUnicodeEnv);
4566  }
4567 
4568  /* Check if this was any kind of VDM application that we ended up creating */
4569  if ((VdmUndoLevel) && (!(VdmUndoLevel & VDM_UNDO_COMPLETED)))
4570  {
4571  /* Send an undo */
4573  (PHANDLE)&VdmTask,
4574  VdmUndoLevel,
4575  VdmBinaryType);
4576 
4577  /* And close whatever VDM handle we were using for notifications */
4578  if (VdmWaitObject) NtClose(VdmWaitObject);
4579  }
4580 
4581  /* Check if we ended up here with an allocated search path, and free it */
4582  if (SearchPath) RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath);
4583 
4584  /* Finally, return the API's result */
4585  return Result;
4586 }
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
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:2227
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:47
#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:3431
#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:2226
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:494
#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:495
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:3756
#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:848
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:694
_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:3623
#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:496
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:2729
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3398
#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
union _BASE_API_MESSAGE::@3486 Data
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:4405
#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:1104
LPVOID lpSecurityDescriptor
Definition: compat.h:193
#define GetModuleHandle
Definition: winbase.h:3683
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:22
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
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
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:857
#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
#define DPRINT
Definition: sndvol32.h:71
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
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:5128

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 4594 of file proc.c.

4604 {
4605  /* Call the internal (but exported) version */
4607  lpApplicationName,
4608  lpCommandLine,
4609  lpProcessAttributes,
4610  lpThreadAttributes,
4611  bInheritHandles,
4612  dwCreationFlags,
4613  lpEnvironment,
4614  lpCurrentDirectory,
4615  lpStartupInfo,
4616  lpProcessInformation,
4617  NULL);
4618 }
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:2235
#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