Author: ion
Date: Sun Dec  4 16:34:58 2011
New Revision: 54587

URL: http://svn.reactos.org/svn/reactos?rev=54587&view=rev
Log:
[KERNEL32]: Fix many bugs in BasepInitailizeEnvironment (and rename to 
BasePushProcessParameters):
    - Depending on how big the full path is, either the application path or the 
full path should be used. Size the buffers correctly, too.
    - If the caller did not specify a window title, should use the app path as 
title.
    - Clear the current directory handle if InheritHandles is false.
    - Correctly handle CREATE_NEW_PROCESS_GROUP and CREATE_NEW_CONSOLE.
    - Check the failure codes of many APIs that we just assumed returned 
success.
    - STARTF_USEHOTKEY | STARTF_SHELLPRIVATE should be checked when inheriting 
console handles.
    - Handle 1MB and 16MB reservation requests.
    - Bugs remain: ImageSubsystem not written, and failure will leak. To be 
fixed later.

Modified:
    trunk/reactos/dll/win32/kernel32/client/proc.c

Modified: trunk/reactos/dll/win32/kernel32/client/proc.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/proc.c?rev=54587&r1=54586&r2=54587&view=diff
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/proc.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/proc.c [iso-8859-1] Sun Dec  4 
16:34:58 2011
@@ -16,13 +16,13 @@
 #define NDEBUG
 #include <debug.h>
 
-
 typedef INT (WINAPI *MessageBoxW_Proc) (HWND, LPCWSTR, LPCWSTR, UINT);
 
 /* GLOBALS *******************************************************************/
 
 static UNICODE_STRING CommandLineStringW;
 static ANSI_STRING CommandLineStringA;
+UNICODE_STRING BasePathVariableName = RTL_CONSTANT_STRING(L"PATH");
 
 static BOOL bCommandLineInitialized = FALSE;
 
@@ -33,7 +33,6 @@
 VOID WINAPI
 RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
 
-UNICODE_STRING BasePathVariableName = RTL_CONSTANT_STRING(L"PATH");
 PLDR_DATA_TABLE_ENTRY BasepExeLdrEntry;
 
 #define CMD_STRING L"cmd /c "
@@ -219,13 +218,13 @@
     {
         return NULL;
     }
-    
+
     Status = BasepNotifyCsrOfThread(hThread, ClientId);
     if (!NT_SUCCESS(Status))
     {
         ASSERT(FALSE);
     }
-    
+
     /* Success */
     return hThread;
 }
@@ -580,15 +579,17 @@
     DPRINT("BasepCopyHandles %p %p, %d\n", Params, PebParams, InheritHandles);
 
     /* Copy the handle if we are inheriting or if it's a console handle */
-    if (InheritHandles || IsConsoleHandle(PebParams->StandardInput))
+    if ((InheritHandles) || (IsConsoleHandle(PebParams->StandardInput)))
     {
         Params->StandardInput = PebParams->StandardInput;
     }
-    if (InheritHandles || IsConsoleHandle(PebParams->StandardOutput))
+
+    if ((InheritHandles) || (IsConsoleHandle(PebParams->StandardOutput)))
     {
         Params->StandardOutput = PebParams->StandardOutput;
     }
-    if (InheritHandles || IsConsoleHandle(PebParams->StandardError))
+
+    if ((InheritHandles) || (IsConsoleHandle(PebParams->StandardError)))
     {
         Params->StandardError = PebParams->StandardError;
     }
@@ -596,18 +597,18 @@
 
 NTSTATUS
 WINAPI
-BasepInitializeEnvironment(HANDLE ProcessHandle,
-                           PPEB Peb,
-                           LPWSTR ApplicationPathName,
-                           LPWSTR lpCurrentDirectory,
-                           LPWSTR lpCommandLine,
-                           LPVOID lpEnvironment,
-                           SIZE_T EnvSize,
-                           LPSTARTUPINFOW StartupInfo,
-                           DWORD CreationFlags,
-                           BOOL InheritHandles)
-{
-    WCHAR FullPath[MAX_PATH];
+BasePushProcessParameters(IN HANDLE ProcessHandle,
+                          IN PPEB Peb,
+                          IN LPWSTR ApplicationPathName,
+                          IN LPWSTR lpCurrentDirectory,
+                          IN LPWSTR lpCommandLine,
+                          IN LPVOID lpEnvironment,
+                          IN SIZE_T EnvSize,
+                          IN LPSTARTUPINFOW StartupInfo,
+                          IN DWORD CreationFlags,
+                          IN BOOL InheritHandles)
+{
+    WCHAR FullPath[MAX_PATH + 5];
     LPWSTR Remaining;
     LPWSTR DllPathString;
     PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
@@ -620,23 +621,34 @@
     UNICODE_STRING Desktop, Shell, Runtime, Title;
     PPEB OurPeb = NtCurrentPeb();
     LPVOID Environment = lpEnvironment;
-
-    DPRINT("BasepInitializeEnvironment\n");
+    DPRINT("BasePushProcessParameters\n");
 
     /* Get the full path name */
-    GetFullPathNameW(ApplicationPathName,
-                     MAX_PATH,
-                     FullPath,
-                     &Remaining);
-    DPRINT("ApplicationPathName: %S, FullPath: %S\n", ApplicationPathName,
-            FullPath);
-
-    /* Get the DLL Path */
-    DllPathString = BasepGetDllPath(FullPath, Environment);
+    Size = GetFullPathNameW(ApplicationPathName,
+                            MAX_PATH + 4,
+                            FullPath,
+                            &Remaining);
+    if ((Size) && (Size <= (MAX_PATH + 4)))
+    {
+        /* Get the DLL Path */
+        DllPathString = BasepGetDllPath(ApplicationPathName, Environment);
+
+        /* Initialize Strings */
+        RtlInitUnicodeString(&DllPath, DllPathString);
+        RtlInitUnicodeString(&ImageName, ApplicationPathName);
+    }
+    else
+    {
+        /* Get the DLL Path */
+        DllPathString = BasepGetDllPath(FullPath, Environment);
+
+        /* Initialize Strings */
+        RtlInitUnicodeString(&DllPath, DllPathString);
+        RtlInitUnicodeString(&ImageName, FullPath);
+    }
+    DPRINT("DllPath: %wZ, ImageName: %wZ\n", DllPath, ImageName);
 
     /* Initialize Strings */
-    RtlInitUnicodeString(&DllPath, DllPathString);
-    RtlInitUnicodeString(&ImageName, FullPath);
     RtlInitUnicodeString(&CommandLine, lpCommandLine);
     RtlInitUnicodeString(&CurrentDirectory, lpCurrentDirectory);
 
@@ -663,7 +675,7 @@
     }
     else
     {
-        RtlInitUnicodeString(&Title, L"");
+        RtlInitUnicodeString(&Title, ApplicationPathName);
     }
 
     /* This one is special because the length can differ */
@@ -685,50 +697,22 @@
                                         &Desktop,
                                         &Shell,
                                         &Runtime);
-
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Failed to create process parameters!\n");
         return Status;
     }
 
-    /* Check if we got an environment. If not, use ours */
+    /* Clear the current directory handle if not inheriting */
+    if (!InheritHandles) ProcessParameters->CurrentDirectory.Handle = NULL;
+
+    /* Save pointer and start lookup */
+    Environment = ScanChar = ProcessParameters->Environment;
     if (Environment)
     {
-        /* Save pointer and start lookup */
-        Environment = ScanChar = ProcessParameters->Environment;
-    }
-    else
-    {
-        /* Save pointer and start lookup */
-        Environment = ScanChar = OurPeb->ProcessParameters->Environment;
-    }
-
-    /* Find the environment size */
-    if (ScanChar)
-    {
-        if (EnvSize && Environment == lpEnvironment)
-        {
-            /* its a converted ansi environment, bypass the length calculation 
*/
-            EnviroSize = EnvSize;
-        }
-        else
-        {
-            while (*ScanChar)
-            {
-                ScanChar += wcslen(ScanChar) + 1;
-            }
-
-            /* Calculate the size of the block */
-            if (ScanChar == Environment)
-            {
-                EnviroSize = 2 * sizeof(WCHAR);
-            }
-            else
-            {
-                EnviroSize = (ULONG)((ULONG_PTR)ScanChar - 
(ULONG_PTR)Environment + sizeof(WCHAR));
-            }
-        }
+        /* Find the environment size */
+        while (*ScanChar) ScanChar += wcslen(ScanChar) + 1;
+        EnviroSize = (ULONG_PTR)ScanChar - (ULONG_PTR)Environment;
         DPRINT("EnvironmentSize %ld\n", EnviroSize);
 
         /* Allocate and Initialize new Environment Block */
@@ -743,15 +727,20 @@
         if (!NT_SUCCESS(Status))
         {
             DPRINT1("Failed to allocate Environment Block\n");
-            return(Status);
+            return Status;
         }
 
         /* Write the Environment Block */
-        ZwWriteVirtualMemory(ProcessHandle,
-                             ProcessParameters->Environment,
-                             Environment,
-                             EnviroSize,
-                             NULL);
+        Status = ZwWriteVirtualMemory(ProcessHandle,
+                                      ProcessParameters->Environment,
+                                      Environment,
+                                      EnviroSize,
+                                      NULL);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed to write Environment Block\n");
+            return Status;
+        }
     }
 
     /* Write new parameters */
@@ -766,7 +755,8 @@
     ProcessParameters->ShowWindowFlags = StartupInfo->wShowWindow;
 
     /* Write the handles only if we have to */
-    if (StartupInfo->dwFlags & STARTF_USESTDHANDLES)
+    if (StartupInfo->dwFlags &
+        (STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE))
     {
         DPRINT("Using Standard Handles\n");
         ProcessParameters->StandardInput = StartupInfo->hStdInput;
@@ -794,7 +784,7 @@
 
         /* Is the shell trampling on our Handles? */
         if (!(StartupInfo->dwFlags &
-              (STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE)))
+             (STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE)))
         {
             /* Use handles from PEB, if inheriting or they are console */
             DPRINT("Copying handles from parent\n");
@@ -805,9 +795,22 @@
     }
 
     /* Also set the Console Flag */
-    if (CreationFlags & CREATE_NEW_PROCESS_GROUP)
+    if ((CreationFlags & CREATE_NEW_PROCESS_GROUP) &&
+        (!(CreationFlags & CREATE_NEW_CONSOLE)))
     {
         ProcessParameters->ConsoleFlags = 1;
+    }
+    
+    /* See if the first 1MB should be reserved */
+    if ((ULONG_PTR)ApplicationPathName & 1)
+    {
+        ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB;
+    }
+
+    /* See if the first 16MB should be reserved */
+    if ((ULONG_PTR)ApplicationPathName & 2)
+    {
+        ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_RESERVE_16MB;
     }
 
     /* Allocate memory for the parameter block */
@@ -821,14 +824,13 @@
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Failed to allocate Parameters Block\n");
-        return(Status);
+        return Status;
     }
 
     /* Set the allocated size */
     ProcessParameters->MaximumLength = Size;
 
     /* Handle some Parameter Flags */
-    ProcessParameters->ConsoleFlags = (CreationFlags & 
CREATE_NEW_PROCESS_GROUP);
     ProcessParameters->Flags |= (CreationFlags & PROFILE_USER) ?
                                  RTL_USER_PROCESS_PARAMETERS_PROFILE_USER : 0;
     ProcessParameters->Flags |= (CreationFlags & PROFILE_KERNEL) ?
@@ -844,6 +846,11 @@
                                   ProcessParameters,
                                   ProcessParameters->Length,
                                   NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to write Parameters Block\n");
+        return Status;
+    }
 
     /* Write the PEB Pointer */
     Status = NtWriteVirtualMemory(ProcessHandle,
@@ -851,6 +858,14 @@
                                   &RemoteParameters,
                                   sizeof(PVOID),
                                   NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to write Parameters Block\n");
+        return Status;
+    }
+
+    /* FIXME: Write Peb->ImageSubSystem */
+
 
     /* Cleanup */
     RtlFreeHeap(RtlGetProcessHeap(), 0, DllPath.Buffer);
@@ -2836,17 +2851,17 @@
 
     /* Create Process Environment */
     RemotePeb = ProcessBasicInfo.PebBaseAddress;
-    Status = BasepInitializeEnvironment(hProcess,
-                                        RemotePeb,
-                                        (LPWSTR)lpApplicationName,
-                                        CurrentDirectory,
-                                        (QuotesNeeded || CmdLineIsAppName || 
Escape) ?
-                                        QuotedCmdLine : lpCommandLine,
-                                        lpEnvironment,
-                                        EnvSize,
-                                        &StartupInfo,
-                                        dwCreationFlags,
-                                        bInheritHandles);
+    Status = BasePushProcessParameters(hProcess,
+                                       RemotePeb,
+                                       (LPWSTR)lpApplicationName,
+                                       CurrentDirectory,
+                                       (QuotesNeeded || CmdLineIsAppName || 
Escape) ?
+                                       QuotedCmdLine : lpCommandLine,
+                                       lpEnvironment,
+                                       EnvSize,
+                                       &StartupInfo,
+                                       dwCreationFlags,
+                                       bInheritHandles);
 
     /* Cleanup Environment */
     if (lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
@@ -2906,7 +2921,7 @@
         BaseSetLastNTError(Status);
         goto Cleanup;
     }
-    
+
     /* Create the first thread */
     DPRINT("Creating thread for process (EntryPoint = 0x%p)\n",
             SectionImageInfo.TransferAddress);


Reply via email to