[NTVDM]
authorAleksandar Andrejevic <aandrejevic@reactos.org>
Fri, 2 May 2014 18:24:40 +0000 (18:24 +0000)
committerAleksandar Andrejevic <aandrejevic@reactos.org>
Fri, 2 May 2014 18:24:40 +0000 (18:24 +0000)
Use VdmRunning to keep the state of the whole VDM, not a VDM task.
Add an event whose signaled state determines the state of the VDM task.
Use FILE_SHARE_READ when opening executables.

svn path=/branches/ntvdm/; revision=63116

subsystems/ntvdm/dos/dos32krnl/dos.c
subsystems/ntvdm/emulator.c
subsystems/ntvdm/ntvdm.c
subsystems/ntvdm/ntvdm.h

index d0bf064..59bf9e2 100644 (file)
@@ -1075,7 +1075,7 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
     /* Open a handle to the executable */
     FileHandle = CreateFileA(ExecutablePath,
                              GENERIC_READ,
-                             0,
+                             FILE_SHARE_READ,
                              NULL,
                              OPEN_EXISTING,
                              FILE_ATTRIBUTE_NORMAL,
@@ -1443,12 +1443,16 @@ Done:
     if (Psp == CurrentPsp)
     {
         CurrentPsp = PspBlock->ParentPsp;
-        if (CurrentPsp == SYSTEM_PSP) VdmRunning = FALSE;
+        if (CurrentPsp == SYSTEM_PSP)
+        {
+            ResetEvent(VdmTaskEvent);
+            EmulatorUnsimulate();
+        }
     }
 
     // FIXME: This is probably not the best way to do it
     /* Check if this was a nested DOS task */
-    if (VdmRunning)
+    if (CurrentPsp != SYSTEM_PSP)
     {
         /* Decrement the re-entry count */
         CommandInfo.VDMState = VDM_DEC_REENTER_COUNT;
@@ -2646,8 +2650,9 @@ VOID WINAPI DosBreakInterrupt(LPWORD Stack)
 {
     UNREFERENCED_PARAMETER(Stack);
 
-    /* Stop the VDM */
-    VdmRunning = FALSE;
+    /* Stop the VDM task */
+    ResetEvent(VdmTaskEvent);
+    EmulatorUnsimulate();
 }
 
 VOID WINAPI DosFastConOut(LPWORD Stack)
index 6128d5d..fe4bdfd 100644 (file)
@@ -203,7 +203,7 @@ VOID EmulatorSimulate(VOID)
     }
     CpuCallLevel++;
 
-    VdmRunning = CpuSimulate = TRUE;
+    CpuSimulate = TRUE;
     while (VdmRunning && CpuSimulate) ClockUpdate();
 
     CpuCallLevel--;
index c6cc701..f0c7cc1 100644 (file)
@@ -41,6 +41,8 @@ static HMENU hConsoleMenu  = NULL;
 static INT   VdmMenuPos    = -1;
 static BOOLEAN ShowPointer = FALSE;
 
+HANDLE VdmTaskEvent = NULL;
+
 /*
  * Those menu helpers were taken from the GUI frontend in winsrv.dll
  */
@@ -200,10 +202,11 @@ BOOL WINAPI ConsoleCtrlHandler(DWORD ControlType)
         }
         case CTRL_LAST_CLOSE_EVENT:
         {
-            if (!VdmRunning)
+            if (WaitForSingleObject(VdmTaskEvent, 0) == WAIT_TIMEOUT)
             {
                 /* Exit immediately */
                 if (CommandThread) TerminateThread(CommandThread, 0);
+                EmulatorTerminate();
             }
             else
             {
@@ -243,6 +246,9 @@ DWORD WINAPI PumpConsoleInput(LPVOID Parameter)
 
     while (VdmRunning)
     {
+        /* Make sure the task event is signaled */
+        WaitForSingleObject(VdmTaskEvent, INFINITE);
+
         /* Wait for an input record */
         if (!ReadConsoleInput(ConsoleInput, &InputRecord, 1, &Count))
         {
@@ -442,6 +448,7 @@ DWORD WINAPI CommandThreadProc(LPVOID Parameter)
         }
 
         /* Start simulation */
+        SetEvent(VdmTaskEvent);
         EmulatorSimulate();
 
         /* Perform another screen refresh */
@@ -477,6 +484,10 @@ INT wmain(INT argc, WCHAR *argv[])
 
     DPRINT1("\n\n\nNTVDM - Starting...\n\n\n");
 
+    /* Create the task event */
+    VdmTaskEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+    ASSERT(VdmTaskEvent != NULL);
+
     /* Initialize the console */
     if (!ConsoleInit())
     {
@@ -539,6 +550,7 @@ INT wmain(INT argc, WCHAR *argv[])
     }
 
     /* Start simulation */
+    SetEvent(VdmTaskEvent);
     EmulatorSimulate();
 
     /* Perform another screen refresh */
index 4aed0ed..2404dd4 100644 (file)
@@ -33,6 +33,8 @@ DWORD WINAPI SetLastConsoleEventActive(VOID);
 
 /* FUNCTIONS ******************************************************************/
 
+extern HANDLE VdmTaskEvent;
+
 VOID DisplayMessage(LPCWSTR Format, ...);
 
 #endif // _NTVDM_H_