From f37afd481ab788d22029c7d4048bc2e808a7ab3d Mon Sep 17 00:00:00 2001 From: Aleksandar Andrejevic Date: Sun, 7 Jun 2015 20:29:56 +0000 Subject: [PATCH] [NTVDM] Revert r67603, apparently DosTerminateProcess should just always pop the registers. Make our DOS_REGISTERS_STATE structure more compatible. svn path=/trunk/; revision=68065 --- reactos/subsystems/mvdm/ntvdm/dos/dem.c | 2 +- .../subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c | 7 +- .../mvdm/ntvdm/dos/dos32krnl/process.c | 81 +++++++++---------- .../mvdm/ntvdm/dos/dos32krnl/process.h | 14 ++-- 4 files changed, 54 insertions(+), 50 deletions(-) diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dem.c b/reactos/subsystems/mvdm/ntvdm/dos/dem.c index f4608ea1eea..281dc79744a 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dem.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dem.c @@ -266,7 +266,7 @@ Command: } /* Start the process from the command line */ - Result = DosStartProcess(AppName, CmdLine, Env); + Result = DosStartProcess(AppName, CmdLine, Env, 0); if (Result != ERROR_SUCCESS) { DisplayMessage(L"Could not start '%S'. Error: %u", AppName, Result); diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c index 94c94e1b6c0..37422410d9a 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c @@ -1376,7 +1376,9 @@ VOID WINAPI DosInt21h(LPWORD Stack) if (LoadType == DOS_LOAD_AND_EXECUTE) { /* Create a new process */ - ErrorCode = DosCreateProcess(ProgramName, ParamBlock); + ErrorCode = DosCreateProcess(ProgramName, + ParamBlock, + MAKELONG(Stack[STACK_IP], Stack[STACK_CS])); } else #endif @@ -1386,7 +1388,8 @@ VOID WINAPI DosInt21h(LPWORD Stack) ProgramName, ParamBlock, NULL, - NULL); + NULL, + MAKELONG(Stack[STACK_IP], Stack[STACK_CS])); } } else if (OrgAL == 0x05) diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.c b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.c index d1e22b1891e..1a257420086 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.c @@ -49,25 +49,24 @@ static inline VOID DosSaveState(VOID) PDOS_REGISTER_STATE State; WORD StackPointer = getSP(); - /* Allocate stack space for the registers */ - StackPointer -= sizeof(DOS_REGISTER_STATE); + /* + * Allocate stack space for the registers. Note that we + * already have one word allocated (the interrupt number). + */ + StackPointer -= sizeof(DOS_REGISTER_STATE) - sizeof(WORD); State = SEG_OFF_TO_PTR(getSS(), StackPointer); setSP(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(); + State->AX = getAX(); + State->CX = getCX(); + State->DX = getDX(); + State->BX = getBX(); + State->BP = getBP(); + State->SI = getSI(); + State->DI = getDI(); } static inline VOID DosRestoreState(VOID) @@ -76,21 +75,18 @@ static inline VOID DosRestoreState(VOID) /* Pop the state structure from the stack */ State = SEG_OFF_TO_PTR(getSS(), getSP()); - setSP(getSP() + sizeof(DOS_REGISTER_STATE)); + setSP(getSP() + sizeof(DOS_REGISTER_STATE) - sizeof(WORD)); /* 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); + setAX(State->AX); + setCX(State->CX); + setDX(State->DX); + setBX(State->BX); + setBP(State->BP); + setSI(State->SI); + setDI(State->DI); } static WORD DosCopyEnvironmentBlock(LPCSTR Environment OPTIONAL, @@ -244,7 +240,8 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType, IN LPCSTR ExecutablePath, IN PDOS_EXEC_PARAM_BLOCK Parameters, IN LPCSTR CommandLine OPTIONAL, - IN LPCSTR Environment OPTIONAL) + IN LPCSTR Environment OPTIONAL, + IN DWORD ReturnAddress OPTIONAL) { DWORD Result = ERROR_SUCCESS; HANDLE FileHandle = INVALID_HANDLE_VALUE, FileMapping = NULL; @@ -454,8 +451,8 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType, DosChangeMemoryOwner(Segment, Segment); DosChangeMemoryOwner(EnvBlock, Segment); - /* Set INT 22h to the current CS:IP */ - ((PULONG)BaseAddress)[0x22] = MAKELONG(getIP(), getCS()); + /* Set INT 22h to the return address */ + ((PULONG)BaseAddress)[0x22] = ReturnAddress; /* Create the PSP */ DosCreatePsp(Segment, (WORD)TotalSize); @@ -556,8 +553,8 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType, DosChangeMemoryOwner(Segment, Segment); DosChangeMemoryOwner(EnvBlock, Segment); - /* Set INT 22h to the current CS:IP */ - ((PULONG)BaseAddress)[0x22] = MAKELONG(getIP(), getCS()); + /* Set INT 22h to the return address */ + ((PULONG)BaseAddress)[0x22] = ReturnAddress; /* Create the PSP */ DosCreatePsp(Segment, MaxAllocSize); @@ -641,7 +638,8 @@ Cleanup: DWORD DosStartProcess(IN LPCSTR ExecutablePath, IN LPCSTR CommandLine, - IN LPCSTR Environment OPTIONAL) + IN LPCSTR Environment OPTIONAL, + IN DWORD ReturnAddress OPTIONAL) { DWORD Result; @@ -658,7 +656,8 @@ DWORD DosStartProcess(IN LPCSTR ExecutablePath, ExecutablePath, NULL, CommandLine, - Environment); + Environment, + ReturnAddress); if (Result != ERROR_SUCCESS) goto Quit; @@ -686,7 +685,8 @@ Quit: #ifndef STANDALONE WORD DosCreateProcess(LPCSTR ProgramName, - PDOS_EXEC_PARAM_BLOCK Parameters) + PDOS_EXEC_PARAM_BLOCK Parameters, + DWORD ReturnAddress OPTIONAL) { DWORD Result; DWORD BinaryType; @@ -809,7 +809,8 @@ Command: AppName, Parameters, CmdLine, - Env); + Env, + ReturnAddress); if (Result == ERROR_SUCCESS) { /* Increment the re-entry count */ @@ -849,6 +850,7 @@ VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode, WORD KeepResident) PDOS_MCB CurrentMcb; LPDWORD IntVecTable = (LPDWORD)((ULONG_PTR)BaseAddress); PDOS_PSP PspBlock = SEGMENT_TO_PSP(Psp); + LPWORD Stack; #ifndef STANDALONE VDM_COMMAND_INFO CommandInfo; #endif @@ -951,15 +953,12 @@ Done: setSS(HIWORD(SEGMENT_TO_PSP(Sda->CurrentPsp)->LastStack)); setSP(LOWORD(SEGMENT_TO_PSP(Sda->CurrentPsp)->LastStack)); - /* Are we returning to DOS code? */ - if (HIWORD(PspBlock->TerminateAddress) == DOS_CODE_SEGMENT) - { - /* Pop the task state */ - DosRestoreState(); - } + /* Pop the task state */ + DosRestoreState(); /* Return control to the parent process */ - CpuExecute(HIWORD(PspBlock->TerminateAddress), - LOWORD(PspBlock->TerminateAddress)); + Stack = (LPWORD)SEG_OFF_TO_PTR(getSS(), getSP()); + Stack[STACK_CS] = HIWORD(PspBlock->TerminateAddress); + Stack[STACK_IP] = LOWORD(PspBlock->TerminateAddress); } diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.h b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.h index b9c71e79b2b..3e8c3e771dd 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.h +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.h @@ -74,9 +74,8 @@ typedef struct _DOS_EXEC_PARAM_BLOCK typedef struct _DOS_REGISTER_STATE { - DWORD Flags; - WORD GS, FS, ES, DS; - DWORD EDI, ESI, EBP, ESP, EBX, EDX, ECX, EAX; + WORD DI, SI, BP, BX, DX, CX, AX; + WORD ES, DS; } DOS_REGISTER_STATE, *PDOS_REGISTER_STATE; #pragma pack(pop) @@ -97,19 +96,22 @@ DWORD DosLoadExecutable IN LPCSTR ExecutablePath, IN PDOS_EXEC_PARAM_BLOCK Parameters, IN LPCSTR CommandLine OPTIONAL, - IN LPCSTR Environment OPTIONAL + IN LPCSTR Environment OPTIONAL, + IN DWORD ReturnAddress OPTIONAL ); DWORD DosStartProcess( IN LPCSTR ExecutablePath, IN LPCSTR CommandLine, - IN LPCSTR Environment OPTIONAL + IN LPCSTR Environment OPTIONAL, + IN DWORD ReturnAddress OPTIONAL ); WORD DosCreateProcess ( LPCSTR ProgramName, - PDOS_EXEC_PARAM_BLOCK Parameters + PDOS_EXEC_PARAM_BLOCK Parameters, + IN DWORD ReturnAddress OPTIONAL ); VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode, WORD KeepResident);