RetVal is in bytes, so check against MAX_PATH in bytes
[reactos.git] / reactos / lib / kernel32 / process / create.c
index f745774..23fd7d1 100644 (file)
@@ -36,10 +36,14 @@ _SEH_FILTER(BaseExceptionFilter)
         }
         _SEH_HANDLE
         {
-            ExceptionDisposition = UnhandledExceptionFilter(ExceptionInfo);
         }
         _SEH_END;
     }
+    if ((ExceptionDisposition == EXCEPTION_CONTINUE_SEARCH || ExceptionDisposition == EXCEPTION_EXECUTE_HANDLER) &&
+        GlobalTopLevelExceptionFilter != UnhandledExceptionFilter)
+    {
+       ExceptionDisposition = UnhandledExceptionFilter(ExceptionInfo);
+    }
 
     return ExceptionDisposition;
 }
@@ -80,18 +84,20 @@ BaseProcessStartup(PPROCESS_START_ROUTINE lpStartAddress)
 NTSTATUS
 STDCALL
 BasepNotifyCsrOfCreation(ULONG dwCreationFlags,
-                         IN HANDLE ProcessId)
+                         IN HANDLE ProcessId,
+                         IN BOOL InheritHandles)
 {
     ULONG Request = CREATE_PROCESS;
     CSR_API_MESSAGE CsrRequest;
     NTSTATUS Status;
     
-    DPRINT1("BasepNotifyCsrOfCreation: Process: %lx, Flags %lx\n", 
+    DPRINT("BasepNotifyCsrOfCreation: Process: %lx, Flags %lx\n", 
             ProcessId, dwCreationFlags);
          
     /* Fill out the request */
     CsrRequest.Data.CreateProcessRequest.NewProcessId = ProcessId;
     CsrRequest.Data.CreateProcessRequest.Flags = dwCreationFlags;
+    CsrRequest.Data.CreateProcessRequest.bInheritHandles = InheritHandles;
     
     /* Call CSR */
     Status = CsrClientCallServer(&CsrRequest,
@@ -164,10 +170,10 @@ BasepCreateFirstThread(HANDLE ProcessHandle,
  */
 PVOID
 STDCALL
-BasepConvertUnicodeEnvironment(IN PVOID lpEnvironment)
+BasepConvertUnicodeEnvironment(OUT SIZE_T* EnvSize,
+                               IN PVOID lpEnvironment)
 {
     PCHAR pcScan;
-    SIZE_T EnvSize = 0;
     ANSI_STRING AnsiEnv;
     UNICODE_STRING UnicodeEnv;
     NTSTATUS Status;
@@ -175,31 +181,43 @@ BasepConvertUnicodeEnvironment(IN PVOID lpEnvironment)
     DPRINT("BasepConvertUnicodeEnvironment\n");
 
     /* Scan the environment to calculate its Unicode size */
-    AnsiEnv.Buffer = pcScan = lpEnvironment;
-    while (*pcScan) while (*pcScan++);
+    AnsiEnv.Buffer = pcScan = (PCHAR)lpEnvironment;
+    while (*pcScan) 
+    {
+        pcScan += strlen(pcScan) + 1;
+    }
 
     /* Create our ANSI String */
-    AnsiEnv.Length = (ULONG_PTR)pcScan - (ULONG_PTR)lpEnvironment + 1;
+    if (pcScan == (PCHAR)lpEnvironment)
+    {
+        AnsiEnv.Length = 2 * sizeof(CHAR);
+    }
+    else
+    {
+
+        AnsiEnv.Length = (ULONG_PTR)pcScan - (ULONG_PTR)lpEnvironment + sizeof(CHAR);
+    }
     AnsiEnv.MaximumLength = AnsiEnv.Length + 1;
     
     /* Allocate memory for the Unicode Environment */
     UnicodeEnv.Buffer = NULL;
-    EnvSize = AnsiEnv.MaximumLength * sizeof(WCHAR);
+    *EnvSize = AnsiEnv.MaximumLength * sizeof(WCHAR);
     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                      (PVOID)&UnicodeEnv.Buffer,
                                      0,
-                                     &EnvSize,
+                                     EnvSize,
                                      MEM_COMMIT,
                                      PAGE_READWRITE);
     /* Failure */
     if (!NT_SUCCESS(Status))
     {
         SetLastError(Status);
+        *EnvSize = 0;
         return NULL;
     }
         
     /* Use the allocated size */
-    UnicodeEnv.MaximumLength = EnvSize;
+    UnicodeEnv.MaximumLength = *EnvSize;
     
     /* Convert */
     RtlAnsiStringToUnicodeString(&UnicodeEnv, &AnsiEnv, FALSE);
@@ -249,7 +267,7 @@ BasepConvertPriorityClass(IN ULONG dwCreationFlags)
     }
     else
     {
-        ReturnClass = 0 /* FIXME */;
+        ReturnClass = PROCESS_PRIORITY_CLASS_INVALID;
     }
     
     return ReturnClass;
@@ -308,6 +326,8 @@ BasepCopyHandles(IN PRTL_USER_PROCESS_PARAMETERS Params,
                  IN PRTL_USER_PROCESS_PARAMETERS PebParams,
                  IN BOOL InheritHandles)
 {
+    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))
     {
@@ -330,7 +350,8 @@ BasepInitializeEnvironment(HANDLE ProcessHandle,
                            LPWSTR ApplicationPathName,
                            LPWSTR lpCurrentDirectory,
                            LPWSTR lpCommandLine,
-                           LPVOID Environment,
+                           LPVOID lpEnvironment,
+                           SIZE_T EnvSize,
                            LPSTARTUPINFOW StartupInfo,
                            DWORD CreationFlags,
                            BOOL InheritHandles)
@@ -348,6 +369,7 @@ BasepInitializeEnvironment(HANDLE ProcessHandle,
     ULONG Size;
     UNICODE_STRING Desktop, Shell, Runtime, Title;
     PPEB OurPeb = NtCurrentPeb();
+    LPVOID Environment = lpEnvironment;
     
     DPRINT("BasepInitializeEnvironment\n");
     
@@ -435,10 +457,28 @@ BasepInitializeEnvironment(HANDLE ProcessHandle,
     /* Find the environment size */
     if (ScanChar)
     {
-        while (*ScanChar) while (*ScanChar++);
-        
-        /* Calculate the size of the block */
-        EnviroSize = (ULONG)((ULONG_PTR)ScanChar - (ULONG_PTR)Environment);
+        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));
+            }
+        }
         DPRINT("EnvironmentSize %ld\n", EnviroSize);
 
         /* Allocate and Initialize new Environment Block */
@@ -478,6 +518,7 @@ BasepInitializeEnvironment(HANDLE ProcessHandle,
     /* Write the handles only if we have to */
     if (StartupInfo->dwFlags & STARTF_USESTDHANDLES)
     {
+        DPRINT("Using Standard Handles\n");
         ProcessParameters->StandardInput = StartupInfo->hStdInput;
         ProcessParameters->StandardOutput = StartupInfo->hStdOutput;
         ProcessParameters->StandardError = StartupInfo->hStdError;
@@ -506,10 +547,11 @@ BasepInitializeEnvironment(HANDLE ProcessHandle,
               (STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE)))
         {
             /* Use handles from PEB, if inheriting or they are console */ 
+            DPRINT("Copying handles from parent\n");
             BasepCopyHandles(ProcessParameters,
                              OurPeb->ProcessParameters,
                              InheritHandles);
-       }
+        }
     }
     
     /* Also set the Console Flag */
@@ -639,7 +681,7 @@ CreateProcessA(LPCSTR lpApplicationName,
         else
         {
             /* Use a dynamic version */
-            Basep8BitStringToLiveUnicodeString(&LiveCommandLine, 
+            Basep8BitStringToHeapUnicodeString(&LiveCommandLine, 
                                                lpCommandLine);
         }
     }
@@ -652,12 +694,12 @@ CreateProcessA(LPCSTR lpApplicationName,
     /* Convert the Name and Directory */
     if (lpApplicationName)
     {
-        Basep8BitStringToLiveUnicodeString(&ApplicationName, 
+        Basep8BitStringToHeapUnicodeString(&ApplicationName, 
                                            lpApplicationName);
     }
     if (lpCurrentDirectory)
     {
-        Basep8BitStringToLiveUnicodeString(&CurrentDirectory, 
+        Basep8BitStringToHeapUnicodeString(&CurrentDirectory, 
                                            lpCurrentDirectory);
     }
     
@@ -737,19 +779,19 @@ CreateProcessW(LPCWSTR lpApplicationName,
     LPWSTR BatchCommandLine;
     ULONG CmdLineLength;
     UNICODE_STRING CommandLineString;
-    LPWSTR TempBuffer;
     PWCHAR Extension;
     LPWSTR QuotedCmdLine = NULL;
     LPWSTR ScanString;
-    LPWSTR NullBuffer;
+    LPWSTR NullBuffer = NULL;
     LPWSTR NameBuffer = NULL;
-    WCHAR SaveChar;
+    WCHAR SaveChar = 0;
     ULONG RetVal;
-    UINT Error;
+    UINT Error = 0;
     BOOLEAN SearchDone = FALSE;
     CLIENT_ID ClientId;
     PPEB OurPeb = NtCurrentPeb();
     PPEB RemotePeb;
+    SIZE_T EnvSize = 0;
     
     DPRINT("CreateProcessW: lpApplicationName: %S lpCommandLine: %S"
            " lpEnvironment: %p lpCurrentDirectory: %S dwCreationFlags: %lx\n",
@@ -834,13 +876,6 @@ CreateProcessW(LPCWSTR lpApplicationName,
     PriorityClass.Foreground = FALSE;
     PriorityClass.PriorityClass = BasepConvertPriorityClass(dwCreationFlags);
 
-    /* Convert the environment */
-    if(lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
-    {
-        lpEnvironment = BasepConvertUnicodeEnvironment(lpEnvironment);
-        if (!lpEnvironment) return FALSE;
-    }
-
     /* Get the application name and do all the proper formating necessary */
 GetAppName:
     /* See if we have an application name (oh please let us have one!) */
@@ -938,7 +973,7 @@ GetAppName:
         }
                 
         /* Now check if we have a file, and if the path size is OK */
-        if (!RetVal || RetVal >= (MAX_PATH / sizeof(WCHAR)))
+        if (!RetVal || RetVal >= (MAX_PATH * sizeof(WCHAR)))
         {
             ULONG PathType;
             HANDLE hFile;
@@ -1038,8 +1073,9 @@ GetAppName:
             case STATUS_INVALID_IMAGE_PROTECT:
             case STATUS_INVALID_IMAGE_NOT_MZ:
             
-            /* If it's a DOS app, use VDM
-            if ((BasepCheckDosApp(&ApplicationName))) */
+#if 0
+            /* If it's a DOS app, use VDM */
+            if ((BasepCheckDosApp(&ApplicationName))) 
             {
                 DPRINT1("Launching VDM...\n");
                 RtlFreeHeap(GetProcessHeap(), 0, NameBuffer);
@@ -1054,8 +1090,8 @@ GetAppName:
                                       lpCurrentDirectory,
                                       lpStartupInfo,
                                       lpProcessInformation);    
-            }
-            
+            } 
+#endif            
             /* It's a batch file */
             Extension = &ApplicationName.Buffer[ApplicationName.Length / 
                                                 sizeof(WCHAR) - 4];
@@ -1099,10 +1135,8 @@ GetAppName:
             lpApplicationName = NULL;
             
             /* Free memory */
-            RtlFreeHeap(GetProcessHeap(), 0, TempBuffer);
             RtlFreeHeap(GetProcessHeap(), 0, ApplicationName.Buffer);
             ApplicationName.Buffer = NULL;
-            TempBuffer = NULL;
             goto GetAppName;
             break;
             
@@ -1283,6 +1317,13 @@ GetAppName:
                                        sizeof(ProcessBasicInfo),
                                        NULL);
     
+    /* Convert the environment */
+    if(lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
+    {
+        lpEnvironment = BasepConvertUnicodeEnvironment(&EnvSize, lpEnvironment);
+        if (!lpEnvironment) return FALSE;
+    }
+
     /* Create Process Environment */
     RemotePeb = ProcessBasicInfo.PebBaseAddress;
     Status = BasepInitializeEnvironment(hProcess,
@@ -1292,9 +1333,17 @@ GetAppName:
                                         (QuotesNeeded || CmdLineIsAppName) ?
                                         QuotedCmdLine : lpCommandLine,
                                         lpEnvironment,
+                                        EnvSize,
                                         lpStartupInfo,
                                         dwCreationFlags,
                                         bInheritHandles);
+
+    /* Cleanup Environment */    
+    if (lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
+    {
+        RtlDestroyEnvironment(lpEnvironment);
+    }
+
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Could not initialize Process Environment\n");
@@ -1353,7 +1402,8 @@ GetAppName:
     
     /* Notify CSRSS */
     Status = BasepNotifyCsrOfCreation(dwCreationFlags,
-                                      (HANDLE)ProcessBasicInfo.UniqueProcessId);
+                                      (HANDLE)ProcessBasicInfo.UniqueProcessId,
+                                      bInheritHandles);
 
     if (!NT_SUCCESS(Status))
     {
@@ -1367,12 +1417,6 @@ GetAppName:
         NtResumeThread(hThread, &Dummy);
     }
     
-    /* Cleanup Environment */    
-    if (lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
-    {
-        RtlDestroyEnvironment(lpEnvironment);
-    }
-
     /* Return Data */        
     lpProcessInformation->dwProcessId = (DWORD)ClientId.UniqueProcess;
     lpProcessInformation->dwThreadId = (DWORD)ClientId.UniqueThread;