Author: aandrejevic
Date: Sat May 2 18:51:03 2015
New Revision: 67513
URL:
http://svn.reactos.org/svn/reactos?rev=67513&view=rev
Log:
[NTVDM]
Save/restore the processor state when executing/terminating nested tasks.
Modified:
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.c
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.h
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.c [iso-8859-1] Sat May 2
18:51:03 2015
@@ -44,6 +44,56 @@
PspBlock->CommandLineSize = min(*(PBYTE)CommandLine, DOS_CMDLINE_LENGTH);
CommandLine++;
RtlCopyMemory(PspBlock->CommandLine, CommandLine, DOS_CMDLINE_LENGTH);
+}
+
+static inline VOID DosSaveState(VOID)
+{
+ PDOS_REGISTER_STATE State;
+ WORD StackPointer = getSP();
+
+ /* Allocate stack space for the registers */
+ StackPointer -= sizeof(DOS_REGISTER_STATE);
+ State = SEG_OFF_TO_PTR(getSS(), StackPointer);
+
+ /* Save */
+ State->EAX = getEAX();
+ State->ECX = getECX();
+ State->EDX = getEDX();
+ State->EBX = getEBX();
+ State->ESP = getESP();
+ State->EBP = getEBP();
+ State->ESI = getESI();
+ State->EDI = getEDI();
+ State->DS = getDS();
+ State->ES = getES();
+ State->FS = getFS();
+ State->GS = getGS();
+ State->Flags = getEFLAGS();
+}
+
+static inline VOID DosRestoreState(VOID)
+{
+ PDOS_REGISTER_STATE State;
+ WORD StackPointer = getSP();
+
+ /* SS:SP points to the stack on the last entry to INT 21h */
+ StackPointer -= (STACK_FLAGS + 1) * 2; /* Interrupt parameters */
+ StackPointer -= sizeof(DOS_REGISTER_STATE); /* Pushed state structure */
+ State = SEG_OFF_TO_PTR(getSS(), StackPointer);
+
+ /* Restore */
+ setEAX(State->EAX);
+ setECX(State->ECX);
+ setEDX(State->EDX);
+ setEBX(State->EBX);
+ setEBP(State->EBP);
+ setESI(State->ESI);
+ setEDI(State->EDI);
+ setDS(State->DS);
+ setES(State->ES);
+ setFS(State->FS);
+ setGS(State->GS);
+ setEFLAGS(State->Flags);
}
static WORD DosCopyEnvironmentBlock(LPCSTR Environment OPTIONAL,
@@ -432,6 +482,9 @@
if (LoadType == DOS_LOAD_AND_EXECUTE)
{
+ /* Save the program state */
+ if (CurrentPsp != SYSTEM_PSP) DosSaveState();
+
/* Set the initial segment registers */
setDS(Segment);
setES(Segment);
@@ -750,6 +803,9 @@
PDOS_MCB CurrentMcb;
LPDWORD IntVecTable = (LPDWORD)((ULONG_PTR)BaseAddress);
PDOS_PSP PspBlock = SEGMENT_TO_PSP(Psp);
+#ifndef STANDALONE
+ VDM_COMMAND_INFO CommandInfo;
+#endif
DPRINT("DosTerminateProcess: Psp 0x%04X, ReturnCode 0x%02X, KeepResident
0x%04X\n",
Psp,
@@ -818,29 +874,25 @@
{
ResetEvent(VdmTaskEvent);
CpuUnsimulate();
+ return;
}
}
#ifndef STANDALONE
- // FIXME: This is probably not the best way to do it
- /* Check if this was a nested DOS task */
- if (CurrentPsp != SYSTEM_PSP)
- {
- VDM_COMMAND_INFO CommandInfo;
-
- /* Decrement the re-entry count */
- CommandInfo.TaskId = SessionId;
- CommandInfo.VDMState = VDM_DEC_REENTER_COUNT;
- GetNextVDMCommand(&CommandInfo);
-
- /* Clear the structure */
- RtlZeroMemory(&CommandInfo, sizeof(CommandInfo));
-
- /* Update the VDM state of the task */
- CommandInfo.TaskId = SessionId;
- CommandInfo.VDMState = VDM_FLAG_DONT_WAIT;
- GetNextVDMCommand(&CommandInfo);
- }
+
+ /* Decrement the re-entry count */
+ CommandInfo.TaskId = SessionId;
+ CommandInfo.VDMState = VDM_DEC_REENTER_COUNT;
+ GetNextVDMCommand(&CommandInfo);
+
+ /* Clear the structure */
+ RtlZeroMemory(&CommandInfo, sizeof(CommandInfo));
+
+ /* Update the VDM state of the task */
+ CommandInfo.TaskId = SessionId;
+ CommandInfo.VDMState = VDM_FLAG_DONT_WAIT;
+ GetNextVDMCommand(&CommandInfo);
+
#endif
/* Save the return code - Normal termination */
@@ -850,6 +902,9 @@
setSS(HIWORD(SEGMENT_TO_PSP(CurrentPsp)->LastStack));
setSP(LOWORD(SEGMENT_TO_PSP(CurrentPsp)->LastStack));
+ /* Restore the program state */
+ DosRestoreState();
+
/* Return control to the parent process */
CpuExecute(HIWORD(PspBlock->TerminateAddress),
LOWORD(PspBlock->TerminateAddress));
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.h [iso-8859-1] Sat May 2
18:51:03 2015
@@ -72,6 +72,13 @@
};
} DOS_EXEC_PARAM_BLOCK, *PDOS_EXEC_PARAM_BLOCK;
+typedef struct _DOS_REGISTER_STATE
+{
+ DWORD Flags;
+ WORD GS, FS, ES, DS;
+ DWORD EDI, ESI, EBP, ESP, EBX, EDX, ECX, EAX;
+} DOS_REGISTER_STATE, *PDOS_REGISTER_STATE;
+
#pragma pack(pop)
/* VARIABLES ******************************************************************/