[KERNEL32]
[reactos.git] / dll / win32 / kernel32 / client / proc.c
index 7fd9ce6..fee3215 100644 (file)
@@ -49,6 +49,7 @@ VOID WINAPI
 RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
 
 #define CMD_STRING L"cmd /c "
+#define NTVDM_STRING L"\\ntvdm.exe"
 
 /* FUNCTIONS ****************************************************************/
 
@@ -182,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)
@@ -509,10 +526,10 @@ BasepNotifyCsrOfThread(IN HANDLE ThreadHandle,
                                  NULL,
                                  CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepCreateThread),
                                  sizeof(BASE_CREATE_THREAD));
-    if (!NT_SUCCESS(Status) || !NT_SUCCESS(ApiMessage.Status))
+    if (!NT_SUCCESS(Status))
     {
-        DPRINT1("Failed to tell CSRSS about new thread: %lx %lx\n", Status, ApiMessage.Status);
-        return ApiMessage.Status;
+        DPRINT1("Failed to tell CSRSS about new thread: %lx\n", Status);
+        return Status;
     }
 
     /* Return Success */
@@ -581,7 +598,7 @@ BasepCreateFirstThread(HANDLE ProcessHandle,
 
     /*
      * For GUI applications we turn on the 2nd bit. This also allows
-     * us to know whether or not the application is a GUI or CUI app.
+     * us to know whether or not this is a GUI or a TUI application.
      */
     if (IMAGE_SUBSYSTEM_WINDOWS_GUI == SectionImageInfo->SubSystemType)
     {
@@ -594,9 +611,9 @@ BasepCreateFirstThread(HANDLE ProcessHandle,
                                  NULL,
                                  CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepCreateProcess),
                                  sizeof(BASE_CREATE_PROCESS));
-    if (!NT_SUCCESS(Status) || !NT_SUCCESS(ApiMessage.Status))
+    if (!NT_SUCCESS(Status))
     {
-        DPRINT1("Failed to tell CSRSS about new process: %lx %lx\n", Status, ApiMessage.Status);
+        DPRINT1("Failed to tell CSRSS about new process: %lx\n", Status);
         return NULL;
     }
 
@@ -1193,10 +1210,10 @@ GetProcessShutdownParameters(OUT LPDWORD lpdwLevel,
                                  NULL,
                                  CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepGetProcessShutdownParam),
                                  sizeof(BASE_GET_PROCESS_SHUTDOWN_PARAMS));
-    if (!(NT_SUCCESS(Status)) || !(NT_SUCCESS(ApiMessage.Status)))
+    if (!NT_SUCCESS(Status))
     {
         /* Return the failure from CSRSS */
-        BaseSetLastNTError(ApiMessage.Status);
+        BaseSetLastNTError(Status);
         return FALSE;
     }
 
@@ -1225,10 +1242,10 @@ SetProcessShutdownParameters(IN DWORD dwLevel,
                                  NULL,
                                  CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepSetProcessShutdownParam),
                                  sizeof(BASE_SET_PROCESS_SHUTDOWN_PARAMS));
-    if (!NT_SUCCESS(Status) || !NT_SUCCESS(ApiMessage.Status))
+    if (!NT_SUCCESS(Status))
     {
         /* Return the failure from CSRSS */
-        BaseSetLastNTError(ApiMessage.Status);
+        BaseSetLastNTError(Status);
         return FALSE;
     }
 
@@ -1856,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 */
@@ -2524,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;
@@ -2531,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
@@ -2611,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:
@@ -2847,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,
@@ -2865,7 +2893,6 @@ GetAppName:
                                       &StartupInfo,
                                       lpProcessInformation);
             }
-#endif
             /* It's a batch file */
             Extension = &ApplicationName.Buffer[ApplicationName.Length /
                                                 sizeof(WCHAR) - 4];
@@ -2925,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,