[KERNEL32]
[reactos.git] / dll / win32 / kernel32 / client / proc.c
index cbf5437..fee3215 100644 (file)
@@ -1,10 +1,9 @@
-/* $Id: proc.c 57086 2012-08-16 15:39:40Z akhaldi $
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
  * FILE:            lib/kernel32/proc/proc.c
  * PURPOSE:         Process functions
- * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
+ * PROGRAMMERS:     Ariadne (ariadne@xs4all.nl)
  * UPDATE HISTORY:
  *                  Created 01/11/98
  */
@@ -50,6 +49,7 @@ VOID WINAPI
 RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
 
 #define CMD_STRING L"cmd /c "
+#define NTVDM_STRING L"\\ntvdm.exe"
 
 /* FUNCTIONS ****************************************************************/
 
@@ -183,6 +183,22 @@ BasepConfigureAppCertDlls(IN PWSTR ValueName,
     return BasepSaveAppCertRegistryValue(Context, ValueName, ValueData);
 }
 
+
+BOOLEAN
+NTAPI
+BasepCheckDosApp(IN PUNICODE_STRING ApplicationName)
+{
+    PWCHAR Extension;
+    
+    /* Get the extension from the file name */
+    Extension = &ApplicationName->Buffer[ApplicationName->Length /
+                                         sizeof(WCHAR) - 4];
+
+    /* Check if the extension is .COM */
+    if (_wcsnicmp(Extension, L".com", 4) == 0) return TRUE;
+    else return FALSE;
+}
+
 NTSTATUS
 WINAPI
 BasepIsProcessAllowed(IN PCHAR ApplicationName)
@@ -494,26 +510,26 @@ WINAPI
 BasepNotifyCsrOfThread(IN HANDLE ThreadHandle,
                        IN PCLIENT_ID ClientId)
 {
-    ULONG Request = CREATE_THREAD;
-    CSR_API_MESSAGE CsrRequest;
     NTSTATUS Status;
+    BASE_API_MESSAGE ApiMessage;
+    PBASE_CREATE_THREAD CreateThreadRequest = &ApiMessage.Data.CreateThreadRequest;
 
     DPRINT("BasepNotifyCsrOfThread: Thread: %lx, Handle %lx\n",
             ClientId->UniqueThread, ThreadHandle);
 
     /* Fill out the request */
-    CsrRequest.Data.CreateThreadRequest.ClientId = *ClientId;
-    CsrRequest.Data.CreateThreadRequest.ThreadHandle = ThreadHandle;
+    CreateThreadRequest->ClientId = *ClientId;
+    CreateThreadRequest->ThreadHandle = ThreadHandle;
 
     /* Call CSR */
-    Status = CsrClientCallServer(&CsrRequest,
+    Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
                                  NULL,
-                                 MAKE_CSR_API(Request, CSR_NATIVE),
-                                 sizeof(CSR_API_MESSAGE));
-    if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status))
+                                 CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepCreateThread),
+                                 sizeof(BASE_CREATE_THREAD));
+    if (!NT_SUCCESS(Status))
     {
-        DPRINT1("Failed to tell csrss about new thread: %lx %lx\n", Status, CsrRequest.Status);
-        return CsrRequest.Status;
+        DPRINT1("Failed to tell CSRSS about new thread: %lx\n", Status);
+        return Status;
     }
 
     /* Return Success */
@@ -529,17 +545,17 @@ BasepCreateFirstThread(HANDLE ProcessHandle,
                        LPSECURITY_ATTRIBUTES lpThreadAttributes,
                        PSECTION_IMAGE_INFORMATION SectionImageInfo,
                        PCLIENT_ID ClientId,
-                       BOOLEAN InheritHandles,
                        DWORD dwCreationFlags)
 {
+    NTSTATUS Status;
     OBJECT_ATTRIBUTES LocalObjectAttributes;
     POBJECT_ATTRIBUTES ObjectAttributes;
     CONTEXT Context;
     INITIAL_TEB InitialTeb;
-    NTSTATUS Status;
     HANDLE hThread;
-    ULONG Request = CREATE_PROCESS;
-    CSR_API_MESSAGE CsrRequest;
+    BASE_API_MESSAGE ApiMessage;
+    PBASE_CREATE_PROCESS CreateProcessRequest = &ApiMessage.Data.CreateProcessRequest;
+
     DPRINT("BasepCreateFirstThread. hProcess: %lx\n", ProcessHandle);
 
     /* Create the Thread's Stack */
@@ -575,20 +591,29 @@ BasepCreateFirstThread(HANDLE ProcessHandle,
     }
 
     /* Fill out the request to notify CSRSS */
-    CsrRequest.Data.CreateProcessRequest.ClientId = *ClientId;
-    CsrRequest.Data.CreateProcessRequest.ProcessHandle = ProcessHandle;
-    CsrRequest.Data.CreateProcessRequest.ThreadHandle = hThread;
-    CsrRequest.Data.CreateProcessRequest.CreationFlags = dwCreationFlags;
-    CsrRequest.Data.CreateProcessRequest.bInheritHandles = InheritHandles;
+    CreateProcessRequest->ClientId = *ClientId;
+    CreateProcessRequest->ProcessHandle = ProcessHandle;
+    CreateProcessRequest->ThreadHandle = hThread;
+    CreateProcessRequest->CreationFlags = dwCreationFlags;
+
+    /*
+     * For GUI applications we turn on the 2nd bit. This also allows
+     * us to know whether or not this is a GUI or a TUI application.
+     */
+    if (IMAGE_SUBSYSTEM_WINDOWS_GUI == SectionImageInfo->SubSystemType)
+    {
+        CreateProcessRequest->ProcessHandle = (HANDLE)
+            ((ULONG_PTR)CreateProcessRequest->ProcessHandle | 2);
+    }
 
     /* Call CSR */
-    Status = CsrClientCallServer(&CsrRequest,
+    Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
                                  NULL,
-                                 MAKE_CSR_API(Request, CSR_NATIVE),
-                                 sizeof(CSR_API_MESSAGE));
-    if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status))
+                                 CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepCreateProcess),
+                                 sizeof(BASE_CREATE_PROCESS));
+    if (!NT_SUCCESS(Status))
     {
-        DPRINT1("Failed to tell csrss about new process: %lx %lx\n", Status, CsrRequest.Status);
+        DPRINT1("Failed to tell CSRSS about new process: %lx\n", Status);
         return NULL;
     }
 
@@ -936,19 +961,19 @@ BasePushProcessParameters(IN ULONG ParameterFlags,
         ProcessParameters->StandardError = StartupInfo->hStdError;
     }
 
-    /* Use Special Flags for ConDllInitialize in Kernel32 */
+    /* Use Special Flags for BasepInitConsole in Kernel32 */
     if (CreationFlags & DETACHED_PROCESS)
     {
         ProcessParameters->ConsoleHandle = HANDLE_DETACHED_PROCESS;
     }
-    else if (CreationFlags & CREATE_NO_WINDOW)
-    {
-        ProcessParameters->ConsoleHandle = HANDLE_CREATE_NO_WINDOW;
-    }
     else if (CreationFlags & CREATE_NEW_CONSOLE)
     {
         ProcessParameters->ConsoleHandle = HANDLE_CREATE_NEW_CONSOLE;
     }
+    else if (CreationFlags & CREATE_NO_WINDOW)
+    {
+        ProcessParameters->ConsoleHandle = HANDLE_CREATE_NO_WINDOW;
+    }
     else
     {
         /* Inherit our Console Handle */
@@ -1176,24 +1201,25 @@ WINAPI
 GetProcessShutdownParameters(OUT LPDWORD lpdwLevel,
                              OUT LPDWORD lpdwFlags)
 {
-    CSR_API_MESSAGE CsrRequest;
     NTSTATUS Status;
+    BASE_API_MESSAGE ApiMessage;
+    PBASE_GET_PROCESS_SHUTDOWN_PARAMS GetShutdownParametersRequest = &ApiMessage.Data.GetShutdownParametersRequest;
 
     /* Ask CSRSS for shutdown information */
-    Status = CsrClientCallServer(&CsrRequest,
+    Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
                                  NULL,
-                                 MAKE_CSR_API(GET_SHUTDOWN_PARAMETERS, CSR_NATIVE),
-                                 sizeof(CSR_API_MESSAGE));
-    if (!(NT_SUCCESS(Status)) || !(NT_SUCCESS(CsrRequest.Status)))
+                                 CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepGetProcessShutdownParam),
+                                 sizeof(BASE_GET_PROCESS_SHUTDOWN_PARAMS));
+    if (!NT_SUCCESS(Status))
     {
         /* Return the failure from CSRSS */
-        BaseSetLastNTError(CsrRequest.Status);
+        BaseSetLastNTError(Status);
         return FALSE;
     }
 
-    /* Get the data out of the LCP reply */
-    *lpdwLevel = CsrRequest.Data.GetShutdownParametersRequest.Level;
-    *lpdwFlags = CsrRequest.Data.GetShutdownParametersRequest.Flags;
+    /* Get the data back */
+    *lpdwLevel = GetShutdownParametersRequest->Level;
+    *lpdwFlags = GetShutdownParametersRequest->Flags;
     return TRUE;
 }
 
@@ -1205,20 +1231,21 @@ WINAPI
 SetProcessShutdownParameters(IN DWORD dwLevel,
                              IN DWORD dwFlags)
 {
-    CSR_API_MESSAGE CsrRequest;
     NTSTATUS Status;
+    BASE_API_MESSAGE ApiMessage;
+    PBASE_SET_PROCESS_SHUTDOWN_PARAMS SetShutdownParametersRequest = &ApiMessage.Data.SetShutdownParametersRequest;
 
     /* Write the data into the CSRSS request and send it */
-    CsrRequest.Data.SetShutdownParametersRequest.Level = dwLevel;
-    CsrRequest.Data.SetShutdownParametersRequest.Flags = dwFlags;
-    Status = CsrClientCallServer(&CsrRequest,
+    SetShutdownParametersRequest->Level = dwLevel;
+    SetShutdownParametersRequest->Flags = dwFlags;
+    Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
                                  NULL,
-                                 MAKE_CSR_API(SET_SHUTDOWN_PARAMETERS, CSR_NATIVE),
-                                 sizeof(CSR_API_MESSAGE));
-    if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status))
+                                 CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepSetProcessShutdownParam),
+                                 sizeof(BASE_SET_PROCESS_SHUTDOWN_PARAMS));
+    if (!NT_SUCCESS(Status))
     {
         /* Return the failure from CSRSS */
-        BaseSetLastNTError(CsrRequest.Status);
+        BaseSetLastNTError(Status);
         return FALSE;
     }
 
@@ -1742,7 +1769,9 @@ VOID
 WINAPI
 ExitProcess(IN UINT uExitCode)
 {
-    CSR_API_MESSAGE CsrRequest;
+    BASE_API_MESSAGE ApiMessage;
+    PBASE_EXIT_PROCESS ExitProcessRequest = &ApiMessage.Data.ExitProcessRequest;
+
     ASSERT(!BaseRunningInServerProcess);
 
     _SEH2_TRY
@@ -1757,11 +1786,11 @@ ExitProcess(IN UINT uExitCode)
         LdrShutdownProcess();
 
         /* Notify Base Server of process termination */
-        CsrRequest.Data.TerminateProcessRequest.uExitCode = uExitCode;
-        CsrClientCallServer(&CsrRequest,
+        ExitProcessRequest->uExitCode = uExitCode;
+        CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
                             NULL,
-                            MAKE_CSR_API(TERMINATE_PROCESS, CSR_NATIVE),
-                            sizeof(CSR_API_MESSAGE));
+                            CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepExitProcess),
+                            sizeof(BASE_EXIT_PROCESS));
 
         /* Now do it again */
         NtTerminateProcess(NtCurrentProcess(), uExitCode);
@@ -1844,7 +1873,7 @@ FatalAppExitW(IN UINT uAction,
     ULONG Response;
     NTSTATUS Status;
 
-    /* Setup the stirng to print out */
+    /* Setup the string to print out */
     RtlInitUnicodeString(&UnicodeString, lpMessageText);
 
     /* Display the hard error no matter what */
@@ -2512,6 +2541,7 @@ CreateProcessInternalW(HANDLE hToken,
     WCHAR SaveChar = 0;
     ULONG RetVal;
     UINT Error = 0;
+    UINT Length;
     BOOLEAN SearchDone = FALSE;
     BOOLEAN Escape = FALSE;
     CLIENT_ID ClientId;
@@ -2519,6 +2549,7 @@ CreateProcessInternalW(HANDLE hToken,
     PPEB RemotePeb;
     SIZE_T EnvSize = 0;
     BOOL Ret = FALSE;
+    WCHAR VdmPath[MAX_PATH];
 
     /* FIXME should process
      * HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
@@ -2599,6 +2630,16 @@ CreateProcessInternalW(HANDLE hToken,
         }
     }
 
+    /* Get the path to the VDM host */
+    Length = GetSystemDirectoryW(VdmPath, MAX_PATH - wcslen(NTVDM_STRING));
+    if ((Length == 0) || (Length >= MAX_PATH - wcslen(NTVDM_STRING)))
+    {
+        /* System path not found for some reason, fail */
+        SetLastError(ERROR_INVALID_NAME);
+        return FALSE;
+    }
+    wcscat(VdmPath, NTVDM_STRING);
+
     /*
      * According to some sites, ShellExecuteEx uses an undocumented flag to
      * send private handle data (such as HMONITOR or HICON). See:
@@ -2625,7 +2666,7 @@ CreateProcessInternalW(HANDLE hToken,
         while (NULL != (ScanString = wcschr(ScanString, L'^')))
         {
             ScanString++;
-            if (*ScanString == L'\"' || *ScanString == L'^' || *ScanString == L'\"')
+            if (*ScanString == L'\"' || *ScanString == L'^' || *ScanString == L'\\')
             {
                 Escape = TRUE;
                 break;
@@ -2835,14 +2876,13 @@ GetAppName:
             case STATUS_INVALID_IMAGE_PROTECT:
             case STATUS_INVALID_IMAGE_NOT_MZ:
 
-#if 0
             /* If it's a DOS app, use VDM */
             if ((BasepCheckDosApp(&ApplicationName)))
             {
                 DPRINT1("Launching VDM...\n");
                 RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
                 RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer);
-                return CreateProcessW(L"ntvdm.exe",
+                return CreateProcessW(VdmPath,
                                       (LPWSTR)((ULONG_PTR)lpApplicationName), /* FIXME: Buffer must be writable!!! */
                                       lpProcessAttributes,
                                       lpThreadAttributes,
@@ -2853,7 +2893,6 @@ GetAppName:
                                       &StartupInfo,
                                       lpProcessInformation);
             }
-#endif
             /* It's a batch file */
             Extension = &ApplicationName.Buffer[ApplicationName.Length /
                                                 sizeof(WCHAR) - 4];
@@ -2913,7 +2952,7 @@ GetAppName:
                 DPRINT1("Launching VDM...\n");
                 RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
                 RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer);
-                return CreateProcessW(L"ntvdm.exe",
+                return CreateProcessW(VdmPath,
                                       (LPWSTR)((ULONG_PTR)lpApplicationName), /* FIXME: Buffer must be writable!!! */
                                       lpProcessAttributes,
                                       lpThreadAttributes,
@@ -3236,7 +3275,6 @@ GetAppName:
                                      lpThreadAttributes,
                                      &SectionImageInfo,
                                      &ClientId,
-                                     bInheritHandles,
                                      dwCreationFlags);
 
     if (hThread == NULL)