[BASESRV][KERNEL32][NTVDM]
[reactos.git] / subsystems / ntvdm / ntvdm.c
index a079e2d..c6cc701 100644 (file)
@@ -25,7 +25,7 @@
  * Activate this line if you want to run NTVDM in standalone mode with:
  * ntvdm.exe <program>
  */
-#define STANDALONE
+// #define STANDALONE
 
 /* VARIABLES ******************************************************************/
 
@@ -34,6 +34,7 @@ static HANDLE ConsoleOutput = INVALID_HANDLE_VALUE;
 static DWORD  OrgConsoleInputMode, OrgConsoleOutputMode;
 static CONSOLE_CURSOR_INFO         OrgConsoleCursorInfo;
 static CONSOLE_SCREEN_BUFFER_INFO  OrgConsoleBufferInfo;
+static BOOLEAN AcceptCommands = TRUE;
 static HANDLE CommandThread = NULL;
 
 static HMENU hConsoleMenu  = NULL;
@@ -199,7 +200,17 @@ BOOL WINAPI ConsoleCtrlHandler(DWORD ControlType)
         }
         case CTRL_LAST_CLOSE_EVENT:
         {
-            if (CommandThread) TerminateThread(CommandThread, 0);
+            if (!VdmRunning)
+            {
+                /* Exit immediately */
+                if (CommandThread) TerminateThread(CommandThread, 0);
+            }
+            else
+            {
+                /* Stop accepting new commands */
+                AcceptCommands = FALSE;
+            }
+
             break;
         }
         default:
@@ -379,22 +390,25 @@ VOID ConsoleCleanup(VOID)
 
 DWORD WINAPI CommandThreadProc(LPVOID Parameter)
 {
+    BOOLEAN First = TRUE;
+    DWORD Result;
     VDM_COMMAND_INFO CommandInfo;
     CHAR CmdLine[MAX_PATH];
     CHAR AppName[MAX_PATH];
     CHAR PifFile[MAX_PATH];
     CHAR Desktop[MAX_PATH];
     CHAR Title[MAX_PATH];
+    CHAR Env[MAX_PATH];
 
     UNREFERENCED_PARAMETER(Parameter);
 
-    while (TRUE)
+    while (AcceptCommands)
     {
         /* Clear the structure */
         ZeroMemory(&CommandInfo, sizeof(CommandInfo));
 
         /* Initialize the structure members */
-        CommandInfo.VDMState = VDM_NOT_LOADED;
+        CommandInfo.VDMState = VDM_FLAG_DOS;
         CommandInfo.CmdLine = CmdLine;
         CommandInfo.CmdLen = sizeof(CmdLine);
         CommandInfo.AppName = AppName;
@@ -405,15 +419,25 @@ DWORD WINAPI CommandThreadProc(LPVOID Parameter)
         CommandInfo.DesktopLen = sizeof(Desktop);
         CommandInfo.Title = Title;
         CommandInfo.TitleLen = sizeof(Title);
+        CommandInfo.Env = Env;
+        CommandInfo.EnvLen = sizeof(Env);
+
+        if (First)
+        {
+            CommandInfo.VDMState |= VDM_FLAG_FIRST_TASK;
+            First = FALSE;
+        }
 
         /* Wait for the next available VDM */
         if (!GetNextVDMCommand(&CommandInfo)) break;
 
         /* Start the process from the command line */
         DPRINT1("Starting '%s'...\n", AppName);
-        if (!DosCreateProcess(AppName, 0))
+
+        Result = DosLoadExecutable(DOS_LOAD_AND_EXECUTE, AppName, CmdLine, Env, NULL, NULL);
+        if (Result != ERROR_SUCCESS)
         {
-            DisplayMessage(L"Could not start '%S'", AppName);
+            DisplayMessage(L"Could not start '%S'. Error: %u", AppName, Result);
             break;
         }
 
@@ -431,16 +455,21 @@ INT wmain(INT argc, WCHAR *argv[])
 {
 #ifdef STANDALONE
 
+    DWORD Result;
+    CHAR ApplicationName[MAX_PATH];
     CHAR CommandLine[DOS_CMDLINE_LENGTH];
 
-    if (argc == 2 && argv[1] != NULL)
+    if (argc >= 2)
     {
-        WideCharToMultiByte(CP_ACP, 0, argv[1], -1, CommandLine, sizeof(CommandLine), NULL, NULL);
+        WideCharToMultiByte(CP_ACP, 0, argv[1], -1, ApplicationName, sizeof(ApplicationName), NULL, NULL);
+
+        if (argc >= 3) WideCharToMultiByte(CP_ACP, 0, argv[2], -1, CommandLine, sizeof(CommandLine), NULL, NULL);
+        else strcpy(CommandLine, "");
     }
     else
     {
         wprintf(L"\nReactOS Virtual DOS Machine\n\n"
-                L"Usage: NTVDM <executable>\n");
+                L"Usage: NTVDM <executable> [<parameters>]\n");
         return 0;
     }
 
@@ -495,10 +524,17 @@ INT wmain(INT argc, WCHAR *argv[])
 #else
 
     /* Start the process from the command line */
-    DPRINT1("Starting '%s'...\n", CommandLine);
-    if (!DosCreateProcess(CommandLine, 0))
+    DPRINT1("Starting '%s'...\n", ApplicationName);
+
+    Result = DosLoadExecutable(DOS_LOAD_AND_EXECUTE,
+                               ApplicationName,
+                               CommandLine,
+                               GetEnvironmentStrings(),
+                               NULL,
+                               NULL);
+    if (Result != ERROR_SUCCESS)
     {
-        DisplayMessage(L"Could not start '%S'", CommandLine);
+        DisplayMessage(L"Could not start '%S'. Error: %u", ApplicationName, Result);
         goto Cleanup;
     }