[KERNEL32] Do not use TEB->StaticUnicodeString in CreateProcessInternalA. CORE-10368
[reactos.git] / reactos / dll / win32 / kernel32 / client / proc.c
index a91cef7..2047cca 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
- * FILE:            lib/kernel32/proc/proc.c
+ * FILE:            dll/win32/kernel32/client/proc.c
  * PURPOSE:         Process functions
  * PROGRAMMERS:     Ariadne (ariadne@xs4all.nl)
  * UPDATE HISTORY:
@@ -102,7 +102,7 @@ BuildSubSysCommandLine(IN LPCWSTR SubsystemName,
     /* Allocate buffer for the output string */
     Length = CommandLineString.MaximumLength + ApplicationNameString.MaximumLength + 32;
     Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
-    RtlInitEmptyUnicodeString(SubsysCommandLine, Buffer, Length);
+    RtlInitEmptyUnicodeString(SubsysCommandLine, Buffer, (USHORT)Length);
     if (!Buffer)
     {
         /* Fail, no memory */
@@ -499,7 +499,6 @@ WINAPI
 BasepNotifyCsrOfThread(IN HANDLE ThreadHandle,
                        IN PCLIENT_ID ClientId)
 {
-    NTSTATUS Status;
     BASE_API_MESSAGE ApiMessage;
     PBASE_CREATE_THREAD CreateThreadRequest = &ApiMessage.Data.CreateThreadRequest;
 
@@ -511,14 +510,14 @@ BasepNotifyCsrOfThread(IN HANDLE ThreadHandle,
     CreateThreadRequest->ThreadHandle = ThreadHandle;
 
     /* Call CSR */
-    Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
-                                 NULL,
-                                 CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepCreateThread),
-                                 sizeof(BASE_CREATE_THREAD));
-    if (!NT_SUCCESS(Status))
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        NULL,
+                        CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepCreateThread),
+                        sizeof(*CreateThreadRequest));
+    if (!NT_SUCCESS(ApiMessage.Status))
     {
-        DPRINT1("Failed to tell CSRSS about new thread: %lx\n", Status);
-        return Status;
+        DPRINT1("Failed to tell CSRSS about new thread: %lx\n", ApiMessage.Status);
+        return ApiMessage.Status;
     }
 
     /* Return Success */
@@ -629,14 +628,14 @@ BasePushProcessParameters(IN ULONG ParameterFlags,
 
     /* Create the Parameter Block */
     ProcessParameters = NULL;
-    DPRINT1("ImageName: '%wZ'\n", &ImageName);
-    DPRINT1("DllPath  : '%wZ'\n", &DllPath);
-    DPRINT1("CurDir   : '%wZ'\n", &CurrentDirectory);
-    DPRINT1("CmdLine  : '%wZ'\n", &CommandLine);
-    DPRINT1("Title    : '%wZ'\n", &Title);
-    DPRINT1("Desktop  : '%wZ'\n", &Desktop);
-    DPRINT1("Shell    : '%wZ'\n", &Shell);
-    DPRINT1("Runtime  : '%wZ'\n", &Runtime);
+    DPRINT("ImageName: '%wZ'\n", &ImageName);
+    DPRINT("DllPath  : '%wZ'\n", &DllPath);
+    DPRINT("CurDir   : '%wZ'\n", &CurrentDirectory);
+    DPRINT("CmdLine  : '%wZ'\n", &CommandLine);
+    DPRINT("Title    : '%wZ'\n", &Title);
+    DPRINT("Desktop  : '%wZ'\n", &Desktop);
+    DPRINT("Shell    : '%wZ'\n", &Shell);
+    DPRINT("Runtime  : '%wZ'\n", &Runtime);
     Status = RtlCreateProcessParameters(&ProcessParameters,
                                         &ImageName,
                                         &DllPath,
@@ -673,9 +672,8 @@ BasePushProcessParameters(IN ULONG ParameterFlags,
     if (lpEnvironment)
     {
         /* Find the environment size */
-        while ((ScanChar[0]) || (ScanChar[1])) ++ScanChar;
-        ScanChar += (2 * sizeof(UNICODE_NULL));
-        EnviroSize = (ULONG_PTR)ScanChar - (ULONG_PTR)lpEnvironment;
+        while (*ScanChar++) while (*ScanChar++);
+        EnviroSize = (ULONG)((ULONG_PTR)ScanChar - (ULONG_PTR)lpEnvironment);
 
         /* Allocate and Initialize new Environment Block */
         Size = EnviroSize;
@@ -727,7 +725,7 @@ BasePushProcessParameters(IN ULONG ParameterFlags,
         ProcessParameters->StandardError = StartupInfo->hStdError;
     }
 
-    /* Use Special Flags for BasepInitConsole in Kernel32 */
+    /* Use Special Flags for ConDllInitialize in Kernel32 */
     if (CreationFlags & DETACHED_PROCESS)
     {
         ProcessParameters->ConsoleHandle = HANDLE_DETACHED_PROCESS;
@@ -917,8 +915,8 @@ GetProcessAffinityMask(IN HANDLE hProcess,
     /* Query information on the process from the kernel */
     Status = NtQueryInformationProcess(hProcess,
                                        ProcessBasicInformation,
-                                       (PVOID)&ProcessInfo,
-                                       sizeof(PROCESS_BASIC_INFORMATION),
+                                       &ProcessInfo,
+                                       sizeof(ProcessInfo),
                                        NULL);
     if (!NT_SUCCESS(Status))
     {
@@ -967,19 +965,18 @@ WINAPI
 GetProcessShutdownParameters(OUT LPDWORD lpdwLevel,
                              OUT LPDWORD lpdwFlags)
 {
-    NTSTATUS Status;
     BASE_API_MESSAGE ApiMessage;
     PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest = &ApiMessage.Data.ShutdownParametersRequest;
 
     /* Ask CSRSS for shutdown information */
-    Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
-                                 NULL,
-                                 CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepGetProcessShutdownParam),
-                                 sizeof(BASE_GETSET_PROCESS_SHUTDOWN_PARAMS));
-    if (!NT_SUCCESS(Status))
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        NULL,
+                        CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepGetProcessShutdownParam),
+                        sizeof(*ShutdownParametersRequest));
+    if (!NT_SUCCESS(ApiMessage.Status))
     {
         /* Return the failure from CSRSS */
-        BaseSetLastNTError(Status);
+        BaseSetLastNTError(ApiMessage.Status);
         return FALSE;
     }
 
@@ -997,21 +994,20 @@ WINAPI
 SetProcessShutdownParameters(IN DWORD dwLevel,
                              IN DWORD dwFlags)
 {
-    NTSTATUS Status;
     BASE_API_MESSAGE ApiMessage;
     PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest = &ApiMessage.Data.ShutdownParametersRequest;
 
     /* Write the data into the CSRSS request and send it */
     ShutdownParametersRequest->ShutdownLevel = dwLevel;
     ShutdownParametersRequest->ShutdownFlags = dwFlags;
-    Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
-                                 NULL,
-                                 CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepSetProcessShutdownParam),
-                                 sizeof(BASE_GETSET_PROCESS_SHUTDOWN_PARAMS));
-    if (!NT_SUCCESS(Status))
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        NULL,
+                        CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepSetProcessShutdownParam),
+                        sizeof(*ShutdownParametersRequest));
+    if (!NT_SUCCESS(ApiMessage.Status))
     {
         /* Return the failure from CSRSS */
-        BaseSetLastNTError(Status);
+        BaseSetLastNTError(ApiMessage.Status);
         return FALSE;
     }
 
@@ -1036,7 +1032,7 @@ GetProcessWorkingSetSizeEx(IN HANDLE hProcess,
     Status = NtQueryInformationProcess(hProcess,
                                        ProcessQuotaLimits,
                                        &QuotaLimits,
-                                       sizeof(QUOTA_LIMITS_EX),
+                                       sizeof(QuotaLimits),
                                        NULL);
     if (!NT_SUCCESS(Status))
     {
@@ -1224,7 +1220,7 @@ GetExitCodeProcess(IN HANDLE hProcess,
     Status = NtQueryInformationProcess(hProcess,
                                        ProcessBasicInformation,
                                        &ProcessBasic,
-                                       sizeof(PROCESS_BASIC_INFORMATION),
+                                       sizeof(ProcessBasic),
                                        NULL);
     if (!NT_SUCCESS(Status))
     {
@@ -1255,7 +1251,7 @@ GetProcessId(IN HANDLE Process)
     Status = NtQueryInformationProcess(Process,
                                        ProcessBasicInformation,
                                        &ProcessBasic,
-                                       sizeof(PROCESS_BASIC_INFORMATION),
+                                       sizeof(ProcessBasic),
                                        NULL);
     if (!NT_SUCCESS(Status))
     {
@@ -1438,7 +1434,7 @@ GetStartupInfoA(IN LPSTARTUPINFOA lpStartupInfo)
                         StartupInfo->lpTitle = TitleString.Buffer;
 
                         /* We finished with the ANSI version, try to cache it */
-                        if (!InterlockedCompareExchangePointer(&BaseAnsiStartupInfo,
+                        if (!InterlockedCompareExchangePointer((PVOID*)&BaseAnsiStartupInfo,
                                                                StartupInfo,
                                                                NULL))
                         {
@@ -1511,12 +1507,12 @@ BOOL
 WINAPI
 FlushInstructionCache(IN HANDLE hProcess,
                       IN LPCVOID lpBaseAddress,
-                      IN SIZE_T dwSize)
+                      IN SIZE_T nSize)
 {
     NTSTATUS Status;
 
     /* Call the native function */
-    Status = NtFlushInstructionCache(hProcess, (PVOID)lpBaseAddress, dwSize);
+    Status = NtFlushInstructionCache(hProcess, (PVOID)lpBaseAddress, nSize);
     if (!NT_SUCCESS(Status))
     {
         /* Handle failure case */
@@ -1546,7 +1542,7 @@ ExitProcess(IN UINT uExitCode)
         RtlAcquirePebLock();
 
         /* Kill all the threads */
-        NtTerminateProcess(NULL, 0);
+        NtTerminateProcess(NULL, uExitCode);
 
         /* Unload all DLLs */
         LdrShutdownProcess();
@@ -1556,7 +1552,7 @@ ExitProcess(IN UINT uExitCode)
         CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
                             NULL,
                             CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepExitProcess),
-                            sizeof(BASE_EXIT_PROCESS));
+                            sizeof(*ExitProcessRequest));
 
         /* Now do it again */
         NtTerminateProcess(NtCurrentProcess(), uExitCode);
@@ -1619,7 +1615,7 @@ FatalAppExitA(UINT uAction,
     MessageTextU = &NtCurrentTeb()->StaticUnicodeString;
     RtlInitAnsiString(&MessageText, (LPSTR)lpMessageText);
 
-    /* Convert to unicode and just exit normally if this failed */
+    /* Convert to unicode, or just exit normally if this failed */
     Status = RtlAnsiStringToUnicodeString(MessageTextU, &MessageText, FALSE);
     if (!NT_SUCCESS(Status)) ExitProcess(0);
 
@@ -1647,11 +1643,18 @@ FatalAppExitW(IN UINT uAction,
                               1,
                               1,
                               (PULONG_PTR)&UnicodeString,
+#if DBG
+    /* On Checked builds, Windows allows the user to cancel the operation */
                               OptionOkCancel,
+#else
+                              OptionOk,
+#endif
                               &Response);
 
+#if DBG
     /* Give the user a chance to abort */
     if ((NT_SUCCESS(Status)) && (Response == ResponseCancel)) return;
+#endif
 
     /* Otherwise kill the process */
     ExitProcess(0);
@@ -1665,7 +1668,7 @@ WINAPI
 FatalExit(IN int ExitCode)
 {
 #if DBG
-    /* On Checked builds, Windows gives you a nice little debugger UI */
+    /* On Checked builds, Windows gives the user a nice little debugger UI */
     CHAR ch[2];
     DbgPrint("FatalExit...\n");
     DbgPrint("\n");
@@ -1705,7 +1708,7 @@ GetPriorityClass(IN HANDLE hProcess)
     Status = NtQueryInformationProcess(hProcess,
                                        ProcessPriorityClass,
                                        &PriorityClass,
-                                       sizeof(PROCESS_PRIORITY_CLASS),
+                                       sizeof(PriorityClass),
                                        NULL);
     if (NT_SUCCESS(Status))
     {
@@ -1838,7 +1841,7 @@ GetProcessVersion(IN DWORD ProcessId)
             ProcessHandle = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
                                         FALSE,
                                         ProcessId);
-            if (!ProcessHandle) return 0;
+            if (!ProcessHandle) _SEH2_YIELD(return 0);
 
             /* Try to find out where its PEB lives */
             Status = NtQueryInformationProcess(ProcessHandle,
@@ -1937,7 +1940,7 @@ GetProcessPriorityBoost(IN HANDLE hProcess,
     Status = NtQueryInformationProcess(hProcess,
                                        ProcessPriorityBoost,
                                        &PriorityBoost,
-                                       sizeof(ULONG),
+                                       sizeof(PriorityBoost),
                                        NULL);
     if (NT_SUCCESS(Status))
     {
@@ -1994,11 +1997,11 @@ GetProcessHandleCount(IN HANDLE hProcess,
     Status = NtQueryInformationProcess(hProcess,
                                        ProcessHandleCount,
                                        &phc,
-                                       sizeof(ULONG),
+                                       sizeof(phc),
                                        NULL);
     if (NT_SUCCESS(Status))
     {
-        /* Copy the count and return sucecss */
+        /* Copy the count and return success */
         *pdwHandleCount = phc;
         return TRUE;
     }
@@ -2248,7 +2251,7 @@ ProcessIdToSessionId(IN DWORD dwProcessId,
                                            sizeof(SessionInformation),
                                            NULL);
 
-        /* Close the handle and check if we suceeded */
+        /* Close the handle and check if we succeeded */
         NtClose(ProcessHandle);
         if (NT_SUCCESS(Status))
         {
@@ -2295,13 +2298,14 @@ CreateProcessInternalW(IN HANDLE hUserToken,
     SECTION_IMAGE_INFORMATION ImageInformation;
     IO_STATUS_BLOCK IoStatusBlock;
     CLIENT_ID ClientId;
-    ULONG NoWindow, RegionSize, StackSize, ImageMachine, ErrorCode, Flags;
+    ULONG NoWindow, RegionSize, StackSize, ErrorCode, Flags;
+    USHORT ImageMachine;
     ULONG ParameterFlags, PrivilegeValue, HardErrorMode, ErrorResponse;
     ULONG_PTR ErrorParameters[2];
     BOOLEAN InJob, SaferNeeded, UseLargePages, HavePrivilege;
     BOOLEAN QuerySection, SkipSaferAndAppCompat;
     CONTEXT Context;
-    BASE_API_MESSAGE CsrMsg;
+    BASE_API_MESSAGE CsrMsg[2];
     PBASE_CREATE_PROCESS CreateProcessMsg;
     PCSR_CAPTURE_BUFFER CaptureBuffer;
     PVOID BaseAddress, PrivilegeState, RealTimePrivilegeState;
@@ -2309,7 +2313,7 @@ CreateProcessInternalW(IN HANDLE hUserToken,
     HANDLE FileHandle, SectionHandle, ProcessHandle;
     ULONG ResumeCount;
     PROCESS_PRIORITY_CLASS PriorityClass;
-    NTSTATUS Status, Status1, ImageDbgStatus;
+    NTSTATUS Status, AppCompatStatus, SaferStatus, IFEOStatus, ImageDbgStatus;
     PPEB Peb, RemotePeb;
     PTEB Teb;
     INITIAL_TEB InitialTeb;
@@ -2325,7 +2329,7 @@ CreateProcessInternalW(IN HANDLE hUserToken,
     PCHAR pcScan;
     SIZE_T n;
     WCHAR SaveChar;
-    ULONG Length, CurdirLength, CmdQuoteLength;
+    ULONG Length, FileAttribs, CmdQuoteLength;
     ULONG CmdLineLength, ResultSize;
     PWCHAR QuotedCmdLine, AnsiCmdCommand, ExtBuffer, CurrentDirectory;
     PWCHAR NullBuffer, ScanString, NameBuffer, SearchPath, DebuggerCmdLine;
@@ -2347,7 +2351,7 @@ CreateProcessInternalW(IN HANDLE hUserToken,
     BASE_MSG_SXS_HANDLES MappedHandles, Handles, FileHandles;
     PVOID CapturedStrings[3];
     SXS_WIN32_NT_PATH_PAIR ExePathPair, ManifestPathPair, PolicyPathPair;
-    SXS_OVERRIDE_MANIFEST OverrideMannifest;
+    SXS_OVERRIDE_MANIFEST OverrideManifest;
     UNICODE_STRING FreeString, SxsNtExePath;
     PWCHAR SxsConglomeratedBuffer, StaticBuffer;
     ULONG ConglomeratedBufferSizeBytes, StaticBufferSize, i;
@@ -2377,12 +2381,12 @@ CreateProcessInternalW(IN HANDLE hUserToken,
     ANSI_STRING VdmAnsiEnv;
     UNICODE_STRING VdmString, VdmUnicodeEnv;
     BOOLEAN IsWowApp;
-    PBASE_CHECK_VDM VdmMsg;
+    PBASE_CHECK_VDM CheckVdmMsg;
 
     /* Zero out the initial core variables and handles */
     QuerySection = FALSE;
     InJob = FALSE;
-    SkipSaferAndAppCompat = TRUE; // HACK for making .bat/.cmd launch working again.
+    SkipSaferAndAppCompat = FALSE;
     ParameterFlags = 0;
     Flags = 0;
     DebugHandle = NULL;
@@ -2431,8 +2435,8 @@ CreateProcessInternalW(IN HANDLE hUserToken,
     IsWowApp = FALSE;
 
     /* Set message structures */
-    CreateProcessMsg = &CsrMsg.Data.CreateProcessRequest;
-    VdmMsg = &CsrMsg.Data.CheckVDMRequest;
+    CreateProcessMsg = &CsrMsg[0].Data.CreateProcessRequest;
+    CheckVdmMsg = &CsrMsg[1].Data.CheckVDMRequest;
 
     /* Clear the more complex structures by zeroing out their entire memory */
     RtlZeroMemory(&Context, sizeof(Context));
@@ -2468,7 +2472,7 @@ CreateProcessInternalW(IN HANDLE hUserToken,
     PolicyPathPair.Nt = &SxsNtPolicyPath.String;
 #endif
 
-    DPRINT1("CreateProcessInternalW: %S %S %lx\n", lpApplicationName, lpCommandLine, dwCreationFlags);
+    DPRINT("CreateProcessInternalW: '%S' '%S' %lx\n", lpApplicationName, lpCommandLine, dwCreationFlags);
 
     /* Finally, set our TEB and PEB */
     Teb = NtCurrentTeb();
@@ -2576,7 +2580,7 @@ CreateProcessInternalW(IN HANDLE hUserToken,
         }
 
         /* Use the allocated size and convert */
-        UnicodeEnv.MaximumLength = RegionSize;
+        UnicodeEnv.MaximumLength = (USHORT)RegionSize;
         Status = RtlAnsiStringToUnicodeString(&UnicodeEnv, &AnsiEnv, FALSE);
         if (!NT_SUCCESS(Status))
         {
@@ -2710,7 +2714,7 @@ StartScan:
 
         /* Now compute the final EXE path based on the name */
         SearchPath = BaseComputeProcessExePath((LPWSTR)lpApplicationName);
-        DPRINT1("Search Path: %S\n", SearchPath);
+        DPRINT("Search Path: %S\n", SearchPath);
         if (!SearchPath)
         {
             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
@@ -2730,9 +2734,9 @@ StartScan:
         if ((Length) && (Length < MAX_PATH))
         {
             /* Get file attributes */
-            CurdirLength = GetFileAttributesW(NameBuffer);
-            if ((CurdirLength != 0xFFFFFFFF) &&
-                (CurdirLength & FILE_ATTRIBUTE_DIRECTORY))
+            FileAttribs = GetFileAttributesW(NameBuffer);
+            if ((FileAttribs != INVALID_FILE_ATTRIBUTES) &&
+                (FileAttribs & FILE_ATTRIBUTE_DIRECTORY))
             {
                 /* This was a directory, fail later on */
                 Length = 0;
@@ -2744,7 +2748,7 @@ StartScan:
             }
         }
 
-        DPRINT1("Length: %lx Buffer: %S\n", Length, NameBuffer);
+        DPRINT("Length: %lu Buffer: %S\n", Length, NameBuffer);
 
         /* Check if there was a failure in SearchPathW */
         if ((Length) && (Length < MAX_PATH))
@@ -2830,7 +2834,7 @@ StartScan:
                                                              &SxsWin32RelativePath);
     if (!TranslationStatus)
     {
-        /* Path must be invaild somehow, bail out */
+        /* Path must be invalid somehow, bail out */
         DPRINT1("Path translation for SxS failed\n");
         SetLastError(ERROR_PATH_NOT_FOUND);
         Result = FALSE;
@@ -2872,7 +2876,7 @@ StartScan:
         SxsWin32ExePath = PathBufferString;
         PathBuffer = PathBufferString.Buffer;
         PathBufferString.Buffer = NULL;
-        DPRINT1("SxS Path: %S\n", PathBuffer);
+        DPRINT("SxS Path: %S\n", PathBuffer);
     }
 
     /* Also set the .EXE path based on the path name */
@@ -2891,7 +2895,7 @@ StartScan:
     }
 
     /* Now use the path name, and the root path, to try opening the app */
-    DPRINT1("Path: %wZ. Dir: %p\n", &PathName, SxsWin32RelativePath.ContainingDirectory);
+    DPRINT("Path: %wZ. Dir: %p\n", &PathName, SxsWin32RelativePath.ContainingDirectory);
     InitializeObjectAttributes(&LocalObjectAttributes,
                                &PathName,
                                OBJ_CASE_INSENSITIVE,
@@ -2919,12 +2923,16 @@ StartScan:
                             FILE_NON_DIRECTORY_FILE);
     }
 
+    /* Failure path, display which file failed to open */
+    if (!NT_SUCCESS(Status))
+        DPRINT1("Open file failed: %lx (%wZ)\n", Status, &PathName);
+
     /* Cleanup in preparation for failure or success */
     RtlReleaseRelativeName(&SxsWin32RelativePath);
+
     if (!NT_SUCCESS(Status))
     {
         /* Failure path, try to understand why */
-        DPRINT1("Open file failed: %lx\n", Status);
         if (RtlIsDosDeviceName_U(lpApplicationName))
         {
             /* If a device is being executed, return this special error code */
@@ -2956,7 +2964,7 @@ StartScan:
                              PAGE_EXECUTE,
                              SEC_IMAGE,
                              FileHandle);
-    DPRINT1("Section status: %lx\n", Status);
+    DPRINT("Section status: %lx\n", Status);
     if (NT_SUCCESS(Status))
     {
         /* Are we running on Windows Embedded, Datacenter, Blade or Starter? */
@@ -3047,12 +3055,12 @@ StartScan:
                 if (QuerySection)
                 {
                     /* Nothing to do */
-                    Status = STATUS_SUCCESS;
+                    AppCompatStatus = STATUS_SUCCESS;
                 }
                 else
                 {
                     /* Get some information about the executable */
-                    Status = NtQuerySection(SectionHandle,
+                    AppCompatStatus = NtQuerySection(SectionHandle,
                                             SectionImageInformation,
                                             &ImageInformation,
                                             sizeof(ImageInformation),
@@ -3060,7 +3068,7 @@ StartScan:
                 }
 
                 /* Do we have section information now? */
-                if (NT_SUCCESS(Status))
+                if (NT_SUCCESS(AppCompatStatus))
                 {
                     /* Don't ask for it again, save the machine type */
                     QuerySection = TRUE;
@@ -3069,7 +3077,7 @@ StartScan:
             }
 
             /* Is there a reason/Shim we shouldn't run this application? */
-            Status = BasepCheckBadapp(FileHandle,
+            AppCompatStatus = BasepCheckBadapp(FileHandle,
                                       FreeBuffer,
                                       lpEnvironment,
                                       ImageMachine,
@@ -3078,11 +3086,11 @@ StartScan:
                                       &AppCompatSxsData,
                                       &AppCompatSxsDataSize,
                                       &FusionFlags);
-            if (!NT_SUCCESS(Status))
+            if (!NT_SUCCESS(AppCompatStatus))
             {
                 /* This is usually the status we get back */
-                DPRINT1("App compat launch failure: %lx\n", Status);
-                if (Status == STATUS_ACCESS_DENIED)
+                DPRINT1("App compat launch failure: %lx\n", AppCompatStatus);
+                if (AppCompatStatus == STATUS_ACCESS_DENIED)
                 {
                     /* Convert it to something more Win32-specific */
                     SetLastError(ERROR_CANCELLED);
@@ -3090,7 +3098,7 @@ StartScan:
                 else
                 {
                     /* Some other error */
-                    BaseSetLastNTError(Status);
+                    BaseSetLastNTError(AppCompatStatus);
                 }
 
                 /* Did we have a section? */
@@ -3144,13 +3152,13 @@ StartScan:
         if (SaferNeeded)
         {
             /* We have to call into the WinSafer library and actually check */
-            Status = BasepCheckWinSaferRestrictions(hUserToken,
+            SaferStatus = BasepCheckWinSaferRestrictions(hUserToken,
                                                     (LPWSTR)lpApplicationName,
                                                     FileHandle,
                                                     &InJob,
                                                     &TokenHandle,
                                                     &JobHandle);
-            if (Status == 0xFFFFFFFF)
+            if (SaferStatus == 0xFFFFFFFF)
             {
                 /* Back in 2003, they didn't have an NTSTATUS for this... */
                 DPRINT1("WinSafer blocking process launch\n");
@@ -3160,10 +3168,10 @@ StartScan:
             }
 
             /* Other status codes are not-Safer related, just convert them */
-            if (!NT_SUCCESS(Status))
+            if (!NT_SUCCESS(SaferStatus))
             {
-                DPRINT1("Error checking WinSafer: %lx\n", Status);
-                BaseSetLastNTError(Status);
+                DPRINT1("Error checking WinSafer: %lx\n", SaferStatus);
+                BaseSetLastNTError(SaferStatus);
                 Result = FALSE;
                 goto Quickie;
             }
@@ -3197,7 +3205,7 @@ StartScan:
                     /* Pick which kind of WOW mode we want to run in */
                     VdmBinaryType = (dwCreationFlags &
                                      CREATE_SEPARATE_WOW_VDM) ?
-                                     BINARY_TYPE_WOW : BINARY_TYPE_SEPARATE_WOW;
+                                     BINARY_TYPE_SEPARATE_WOW : BINARY_TYPE_WOW;
 
                     /* Get all the VDM settings and current status */
                     Status = BaseCheckVDM(VdmBinaryType,
@@ -3205,7 +3213,7 @@ StartScan:
                                           lpCommandLine,
                                           lpCurrentDirectory,
                                           &VdmAnsiEnv,
-                                          (PCSR_API_MESSAGE)VdmMsg,
+                                          &CsrMsg[1],
                                           &VdmTask,
                                           dwCreationFlags,
                                           &StartupInfo,
@@ -3231,9 +3239,9 @@ StartScan:
                 }
 
                 /* Check which VDM state we're currently in */
-                switch (VdmMsg->VDMState & (VDM_NOT_LOADED |
-                                            VDM_NOT_READY |
-                                            VDM_READY))
+                switch (CheckVdmMsg->VDMState & (VDM_NOT_LOADED |
+                                                 VDM_NOT_READY |
+                                                 VDM_READY))
                 {
                     case VDM_NOT_LOADED:
                         /* VDM is not fully loaded, so not that much to undo */
@@ -3273,7 +3281,7 @@ StartScan:
                         VdmUndoLevel = VDM_UNDO_REUSE;
 
                         /* Check if CSRSS wants us to wait on VDM */
-                        VdmWaitObject = VdmMsg->WaitObjectForParent;
+                        VdmWaitObject = CheckVdmMsg->WaitObjectForParent;
                         break;
 
                     case VDM_NOT_READY:
@@ -3342,7 +3350,7 @@ StartScan:
                                       lpCommandLine,
                                       lpCurrentDirectory,
                                       &VdmAnsiEnv,
-                                      (PCSR_API_MESSAGE)VdmMsg,
+                                      &CsrMsg[1],
                                       &VdmTask,
                                       dwCreationFlags,
                                       &StartupInfo,
@@ -3357,9 +3365,9 @@ StartScan:
                 };
 
                 /* Handle possible VDM states */
-                switch (VdmMsg->VDMState & (VDM_NOT_LOADED |
-                                            VDM_NOT_READY |
-                                            VDM_READY))
+                switch (CheckVdmMsg->VDMState & (VDM_NOT_LOADED |
+                                                 VDM_NOT_READY |
+                                                 VDM_READY))
                 {
                     case VDM_NOT_LOADED:
                         /* If VDM is not loaded, we'll do a partial undo */
@@ -3396,7 +3404,7 @@ StartScan:
                         VdmUndoLevel = VDM_UNDO_REUSE;
 
                         /* Check if CSRSS wants us to wait on VDM */
-                        VdmWaitObject = VdmMsg->WaitObjectForParent;
+                        VdmWaitObject = CheckVdmMsg->WaitObjectForParent;
                         break;
 
                     case VDM_NOT_READY:
@@ -3439,7 +3447,7 @@ StartScan:
                     ((_wcsnicmp(ExtBuffer, L".bat", 4)) &&
                      (_wcsnicmp(ExtBuffer, L".cmd", 4))))
                 {
-                    DPRINT1("Invalid EXE, and not a batch or script file\n");
+                    DPRINT1("'%wZ': Invalid EXE, and not a batch or script file\n", &PathName);
                     SetLastError(ERROR_BAD_EXE_FORMAT);
                     Result = FALSE;
                     goto Quickie;
@@ -3572,7 +3580,7 @@ StartScan:
         goto Quickie;
     }
 
-    /* Don't let callers pass in this flag -- we'll only get it from IFRO */
+    /* Don't let callers pass in this flag -- we'll only get it from IFEO */
     Flags &= ~PROCESS_CREATE_FLAGS_LARGE_PAGES;
 
     /* Clear the IFEO-missing flag, before we know for sure... */
@@ -3583,11 +3591,11 @@ StartScan:
         (NtCurrentPeb()->ReadImageFileExecOptions))
     {
         /* Let's do this! Attempt to open IFEO */
-        Status1 = LdrOpenImageFileOptionsKey(&PathName, 0, &KeyHandle);
-        if (!NT_SUCCESS(Status1))
+        IFEOStatus = LdrOpenImageFileOptionsKey(&PathName, 0, &KeyHandle);
+        if (!NT_SUCCESS(IFEOStatus))
         {
             /* We failed, set the flag so we store this in the parameters */
-            if (Status1 == STATUS_OBJECT_NAME_NOT_FOUND) ParameterFlags |= 2;
+            if (IFEOStatus == STATUS_OBJECT_NAME_NOT_FOUND) ParameterFlags |= 2;
         }
         else
         {
@@ -3601,8 +3609,8 @@ StartScan:
                 if (!DebuggerCmdLine)
                 {
                     /* Close IFEO on failure */
-                    Status1 = NtClose(KeyHandle);
-                    ASSERT(NT_SUCCESS(Status1));
+                    IFEOStatus = NtClose(KeyHandle);
+                    ASSERT(NT_SUCCESS(IFEOStatus));
 
                     /* Fail the call */
                     SetLastError(ERROR_NOT_ENOUGH_MEMORY);
@@ -3612,13 +3620,13 @@ StartScan:
             }
 
             /* Now query for the debugger */
-            Status1 = LdrQueryImageFileKeyOption(KeyHandle,
+            IFEOStatus = LdrQueryImageFileKeyOption(KeyHandle,
                                                  L"Debugger",
                                                  REG_SZ,
                                                  DebuggerCmdLine,
                                                  MAX_PATH * sizeof(WCHAR),
                                                  &ResultSize);
-            if (!(NT_SUCCESS(Status1)) ||
+            if (!(NT_SUCCESS(IFEOStatus)) ||
                 (ResultSize < sizeof(WCHAR)) ||
                 (DebuggerCmdLine[0] == UNICODE_NULL))
             {
@@ -3628,21 +3636,21 @@ StartScan:
             }
 
             /* Also query if we should map with large pages */
-            Status1 = LdrQueryImageFileKeyOption(KeyHandle,
+            IFEOStatus = LdrQueryImageFileKeyOption(KeyHandle,
                                                  L"UseLargePages",
                                                  REG_DWORD,
                                                  &UseLargePages,
                                                  sizeof(UseLargePages),
                                                  NULL);
-            if ((NT_SUCCESS(Status1)) && (UseLargePages))
+            if ((NT_SUCCESS(IFEOStatus)) && (UseLargePages))
             {
                 /* Do it! This is the only way this flag can be set */
                 Flags |= PROCESS_CREATE_FLAGS_LARGE_PAGES;
             }
 
             /* We're done with IFEO, can close it now */
-            Status1 = NtClose(KeyHandle);
-            ASSERT(NT_SUCCESS(Status1));
+            IFEOStatus = NtClose(KeyHandle);
+            ASSERT(NT_SUCCESS(IFEOStatus));
         }
     }
 
@@ -3761,7 +3769,7 @@ StartScan:
         }
 
         /* Account for the quotes and space between the two */
-        n += ((sizeof('""') * 2) + sizeof(' '));
+        n += sizeof("\" \"") - sizeof(ANSI_NULL);
 
         /* Convert to bytes, and make sure we don't overflow */
         n *= sizeof(WCHAR);
@@ -3784,7 +3792,7 @@ StartScan:
         /* Set the length */
         RtlInitEmptyUnicodeString(&DebuggerString,
                                   DebuggerString.Buffer,
-                                  n);
+                                  (USHORT)n);
 
         /* Now perform the command line creation */
         ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString,
@@ -3824,7 +3832,7 @@ StartScan:
                                                   NULL);
     if ((hUserToken) && (lpProcessAttributes))
     {
-        /* Auggment them with information from the user */
+        /* Augment them with information from the user */
 
         LocalProcessAttributes = *lpProcessAttributes;
         LocalProcessAttributes.lpSecurityDescriptor = NULL;
@@ -3874,7 +3882,7 @@ StartScan:
     {
         /* Acquire the required privilege so that the kernel won't fail the call */
         PrivilegeValue = SE_LOCK_MEMORY_PRIVILEGE;
-        Status = RtlAcquirePrivilege(&PrivilegeValue, TRUE, FALSE, &PrivilegeState);
+        Status = RtlAcquirePrivilege(&PrivilegeValue, 1, 0, &PrivilegeState);
         if (NT_SUCCESS(Status))
         {
             /* Remember to release it later */
@@ -3922,7 +3930,7 @@ StartScan:
         RealTimePrivilegeState = NULL;
 
         /* Is realtime priority being requested? */
-        if (PriorityClass.PriorityClass == REALTIME_PRIORITY_CLASS)
+        if (PriorityClass.PriorityClass == PROCESS_PRIORITY_CLASS_REALTIME)
         {
             /* Check if the caller has real-time access, and enable it if so */
             RealTimePrivilegeState = BasepIsRealtimeAllowed(TRUE);
@@ -3966,6 +3974,8 @@ StartScan:
                                     &VdmWaitObject,
                                     VdmTask,
                                     VdmBinaryType);
+
+        if (!Result)
         {
             /* Bail out on failure */
             DPRINT1("Failed to update VDM with wait object\n");
@@ -3990,7 +4000,7 @@ StartScan:
         if (!NT_SUCCESS(Status))
         {
             /* Bail out on failure */
-            DPRINT1("Failed to reserved memory for VDM: %lx\n", Status);
+            DPRINT1("Failed to reserve memory for VDM: %lx\n", Status);
             BaseSetLastNTError(Status);
             Result = FALSE;
             goto Quickie;
@@ -4033,7 +4043,7 @@ StartScan:
     if (lpCurrentDirectory)
     {
         /* Allocate a buffer so we can keep a Unicode copy */
-        DPRINT1("Current directory: %S\n", lpCurrentDirectory);
+        DPRINT("Current directory: %S\n", lpCurrentDirectory);
         CurrentDirectory = RtlAllocateHeap(RtlGetProcessHeap(),
                                            0,
                                            (MAX_PATH * sizeof(WCHAR)) +
@@ -4060,9 +4070,9 @@ StartScan:
         }
 
         /* Make sure the directory is actually valid */
-        CurdirLength = GetFileAttributesW(CurrentDirectory);
-        if ((CurdirLength == 0xffffffff) ||
-           !(CurdirLength & FILE_ATTRIBUTE_DIRECTORY))
+        FileAttribs = GetFileAttributesW(CurrentDirectory);
+        if ((FileAttribs == INVALID_FILE_ATTRIBUTES) ||
+           !(FileAttribs & FILE_ATTRIBUTE_DIRECTORY))
         {
             /* It isn't, so bail out */
             DPRINT1("Current directory is invalid\n");
@@ -4253,7 +4263,7 @@ StartScan:
     {
         /* IA32, IA64 and AMD64 are supported in Server 2003 */
         case IMAGE_FILE_MACHINE_I386:
-         CreateProcessMsg->ProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
+            CreateProcessMsg->ProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
             break;
         case IMAGE_FILE_MACHINE_IA64:
             CreateProcessMsg->ProcessorArchitecture = PROCESSOR_ARCHITECTURE_IA64;
@@ -4335,7 +4345,7 @@ StartScan:
     }
 
     /* We are finally ready to call CSRSS to tell it about our new process! */
-    CsrClientCallServer((PCSR_API_MESSAGE)&CsrMsg,
+    CsrClientCallServer((PCSR_API_MESSAGE)&CsrMsg[0],
                         CaptureBuffer,
                         CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX,
                                               BasepCreateProcess),
@@ -4349,12 +4359,12 @@ StartScan:
     }
 
     /* Check if CSRSS failed to accept ownership of the new Windows process */
-    if (!NT_SUCCESS(CsrMsg.Status))
+    if (!NT_SUCCESS(CsrMsg[0].Status))
     {
         /* Terminate the process and enter failure path with the CSRSS status */
         DPRINT1("Failed to tell csrss about new process\n");
-        BaseSetLastNTError(CsrMsg.Status);
-        NtTerminateProcess(ProcessHandle, CsrMsg.Status);
+        BaseSetLastNTError(CsrMsg[0].Status);
+        NtTerminateProcess(ProcessHandle, CsrMsg[0].Status);
         Result = FALSE;
         goto Quickie;
     }
@@ -4605,6 +4615,7 @@ Quickie:
  */
 BOOL
 WINAPI
+DECLSPEC_HOTPATCH
 CreateProcessW(LPCWSTR lpApplicationName,
                LPWSTR lpCommandLine,
                LPSECURITY_ATTRIBUTES lpProcessAttributes,
@@ -4649,9 +4660,7 @@ CreateProcessInternalA(HANDLE hToken,
                        LPPROCESS_INFORMATION lpProcessInformation,
                        PHANDLE hNewToken)
 {
-    PUNICODE_STRING CommandLine = NULL;
-    UNICODE_STRING DummyString;
-    UNICODE_STRING LiveCommandLine;
+    UNICODE_STRING CommandLine;
     UNICODE_STRING ApplicationName;
     UNICODE_STRING CurrentDirectory;
     BOOL bRetVal;
@@ -4666,8 +4675,7 @@ CreateProcessInternalA(HANDLE hToken,
     RtlMoveMemory(&StartupInfo, lpStartupInfo, sizeof(*lpStartupInfo));
 
     /* Initialize all strings to nothing */
-    LiveCommandLine.Buffer = NULL;
-    DummyString.Buffer = NULL;
+    CommandLine.Buffer = NULL;
     ApplicationName.Buffer = NULL;
     CurrentDirectory.Buffer = NULL;
     StartupInfo.lpDesktop = NULL;
@@ -4677,24 +4685,8 @@ CreateProcessInternalA(HANDLE hToken,
     /* Convert the Command line */
     if (lpCommandLine)
     {
-        /* If it's too long, then we'll have a problem */
-        if ((strlen(lpCommandLine) + 1) * sizeof(WCHAR) <
-            NtCurrentTeb()->StaticUnicodeString.MaximumLength)
-        {
-            /* Cache it in the TEB */
-            CommandLine = Basep8BitStringToStaticUnicodeString(lpCommandLine);
-        }
-        else
-        {
-            /* Use a dynamic version */
-            Basep8BitStringToDynamicUnicodeString(&LiveCommandLine,
-                                                  lpCommandLine);
-        }
-    }
-    else
-    {
-        /* The logic below will use CommandLine, so we must make it valid */
-        CommandLine = &DummyString;
+        Basep8BitStringToDynamicUnicodeString(&CommandLine,
+                                              lpCommandLine);
     }
 
     /* Convert the Name and Directory */
@@ -4729,8 +4721,7 @@ CreateProcessInternalA(HANDLE hToken,
     /* Call the Unicode function */
     bRetVal = CreateProcessInternalW(hToken,
                                      ApplicationName.Buffer,
-                                     LiveCommandLine.Buffer ?
-                                     LiveCommandLine.Buffer : CommandLine->Buffer,
+                                     CommandLine.Buffer,
                                      lpProcessAttributes,
                                      lpThreadAttributes,
                                      bInheritHandles,
@@ -4743,7 +4734,7 @@ CreateProcessInternalA(HANDLE hToken,
 
     /* Clean up */
     RtlFreeUnicodeString(&ApplicationName);
-    RtlFreeUnicodeString(&LiveCommandLine);
+    RtlFreeUnicodeString(&CommandLine);
     RtlFreeUnicodeString(&CurrentDirectory);
     RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpDesktop);
     RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpReserved);
@@ -4773,6 +4764,7 @@ CreateProcessInternalA(HANDLE hToken,
  */
 BOOL
 WINAPI
+DECLSPEC_HOTPATCH
 CreateProcessA(LPCSTR lpApplicationName,
                LPSTR lpCommandLine,
                LPSECURITY_ATTRIBUTES lpProcessAttributes,
@@ -4804,6 +4796,7 @@ CreateProcessA(LPCSTR lpApplicationName,
  */
 UINT
 WINAPI
+DECLSPEC_HOTPATCH
 WinExec(LPCSTR lpCmdLine,
         UINT uCmdShow)
 {