DosTerminateProcess shouldn't blindly attempt to restore the old state,
(for example if the process was started manually by a debugger).


svn path=/trunk/; revision=67603
This commit is contained in:
Aleksandar Andrejevic
2015-05-08 23:26:15 +00:00
parent 410c54e5f9
commit cd1046dd75
4 changed files with 45 additions and 34 deletions
@@ -1342,7 +1342,6 @@ VOID WINAPI DosInt21h(LPWORD Stack)
BYTE OrgAL = getAL();
LPSTR ProgramName = SEG_OFF_TO_PTR(getDS(), getDX());
PDOS_EXEC_PARAM_BLOCK ParamBlock = SEG_OFF_TO_PTR(getES(), getBX());
DWORD ReturnAddress = MAKELONG(Stack[STACK_IP], Stack[STACK_CS]);
WORD ErrorCode;
if (OrgAL <= DOS_LOAD_OVERLAY)
@@ -1353,9 +1352,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
if (LoadType == DOS_LOAD_AND_EXECUTE)
{
/* Create a new process */
ErrorCode = DosCreateProcess(ProgramName,
ParamBlock,
ReturnAddress);
ErrorCode = DosCreateProcess(ProgramName, ParamBlock);
}
else
#endif
@@ -1365,8 +1362,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
ProgramName,
ParamBlock,
NULL,
NULL,
ReturnAddress);
NULL);
}
}
else if (OrgAL == 0x05)
@@ -2003,7 +1999,7 @@ BOOLEAN DosKRNLInitialize(VOID)
#endif
/* Initialize the callback context */
InitializeContext(&DosContext, 0x0070, 0x0000);
InitializeContext(&DosContext, DOS_CODE_SEGMENT, 0x0000);
/* Register the DOS 32-bit Interrupts */
RegisterDosInt32(0x20, DosInt20h );
@@ -30,6 +30,7 @@
#define USER_MEMORY_SIZE (0x9FFE - FIRST_MCB_SEGMENT)
#define SYSTEM_PSP 0x08
#define SYSTEM_ENV_BLOCK 0x800
#define DOS_CODE_SEGMENT 0x70
#define DOS_DATA_SEGMENT 0xA0
#define MASTER_SFT_OFFSET 0x100
@@ -54,6 +54,7 @@ static inline VOID DosSaveState(VOID)
/* Allocate stack space for the registers */
StackPointer -= sizeof(DOS_REGISTER_STATE);
State = SEG_OFF_TO_PTR(getSS(), StackPointer);
setSP(StackPointer);
/* Save */
State->EAX = getEAX();
@@ -74,12 +75,10 @@ static inline VOID DosSaveState(VOID)
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);
/* Pop the state structure from the stack */
State = SEG_OFF_TO_PTR(getSS(), getSP());
setSP(getSP() + sizeof(DOS_REGISTER_STATE));
/* Restore */
setEAX(State->EAX);
@@ -244,8 +243,7 @@ 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 DWORD ReturnAddress OPTIONAL)
IN LPCSTR Environment OPTIONAL)
{
DWORD Result = ERROR_SUCCESS;
HANDLE FileHandle = INVALID_HANDLE_VALUE, FileMapping = NULL;
@@ -264,8 +262,7 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
DPRINT1("DosLoadExecutable(%d, %s, 0x%08X, 0x%08X)\n",
LoadType,
ExecutablePath,
Parameters,
ReturnAddress);
Parameters);
/* Try to get the full path to the executable */
if (GetFullPathNameA(ExecutablePath, sizeof(FullPath), FullPath, NULL))
@@ -454,8 +451,8 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
DosChangeMemoryOwner(Segment, Segment);
DosChangeMemoryOwner(EnvBlock, Segment);
/* Set INT 22h to the return address */
((PULONG)BaseAddress)[0x22] = ReturnAddress;
/* Set INT 22h to the current CS:IP */
((PULONG)BaseAddress)[0x22] = MAKELONG(getIP(), getCS());
/* Create the PSP */
DosCreatePsp(Segment, (WORD)TotalSize);
@@ -497,7 +494,14 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
if (LoadType == DOS_LOAD_AND_EXECUTE)
{
/* Save the program state */
if (CurrentPsp != SYSTEM_PSP) DosSaveState();
if (CurrentPsp != SYSTEM_PSP)
{
/* Push the task state */
DosSaveState();
/* Update the last stack in the PSP */
SEGMENT_TO_PSP(CurrentPsp)->LastStack = MAKELONG(getSP(), getSS());
}
/* Set the initial segment registers */
setDS(Segment);
@@ -546,8 +550,8 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
DosChangeMemoryOwner(Segment, Segment);
DosChangeMemoryOwner(EnvBlock, Segment);
/* Set INT 22h to the return address */
((PULONG)BaseAddress)[0x22] = ReturnAddress;
/* Set INT 22h to the current CS:IP */
((PULONG)BaseAddress)[0x22] = MAKELONG(getIP(), getCS());
/* Create the PSP */
DosCreatePsp(Segment, MaxAllocSize);
@@ -570,6 +574,16 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
if (LoadType == DOS_LOAD_AND_EXECUTE)
{
/* Save the program state */
if (CurrentPsp != SYSTEM_PSP)
{
/* Push the task state */
DosSaveState();
/* Update the last stack in the PSP */
SEGMENT_TO_PSP(CurrentPsp)->LastStack = MAKELONG(getSP(), getSS());
}
/* Set the initial segment registers */
setDS(Segment);
setES(Segment);
@@ -621,7 +635,6 @@ DWORD DosStartProcess(IN LPCSTR ExecutablePath,
IN LPCSTR Environment OPTIONAL)
{
DWORD Result;
LPDWORD IntVecTable = (LPDWORD)((ULONG_PTR)BaseAddress);
SIZE_T CmdLen = strlen(CommandLine);
DPRINT1("Starting '%s' ('%.*s')...\n",
@@ -636,8 +649,7 @@ DWORD DosStartProcess(IN LPCSTR ExecutablePath,
ExecutablePath,
NULL,
CommandLine,
Environment,
IntVecTable[0x20]);
Environment);
if (Result != ERROR_SUCCESS) goto Quit;
@@ -665,8 +677,7 @@ Quit:
#ifndef STANDALONE
WORD DosCreateProcess(LPCSTR ProgramName,
PDOS_EXEC_PARAM_BLOCK Parameters,
DWORD ReturnAddress)
PDOS_EXEC_PARAM_BLOCK Parameters)
{
DWORD Result;
DWORD BinaryType;
@@ -784,8 +795,7 @@ Command:
AppName,
Parameters,
CmdLine,
Env,
ReturnAddress);
Env);
if (Result == ERROR_SUCCESS)
{
/* Increment the re-entry count */
@@ -924,8 +934,14 @@ Done:
setSS(HIWORD(SEGMENT_TO_PSP(CurrentPsp)->LastStack));
setSP(LOWORD(SEGMENT_TO_PSP(CurrentPsp)->LastStack));
/* Restore the program state */
DosRestoreState();
DPRINT1("Terminate returning to %08X\n", PspBlock->TerminateAddress);
/* Are we returning to DOS code? */
if (HIWORD(PspBlock->TerminateAddress) == DOS_CODE_SEGMENT)
{
/* Pop the task state */
DosRestoreState();
}
/* Return control to the parent process */
CpuExecute(HIWORD(PspBlock->TerminateAddress),
@@ -97,8 +97,7 @@ DWORD DosLoadExecutable
IN LPCSTR ExecutablePath,
IN PDOS_EXEC_PARAM_BLOCK Parameters,
IN LPCSTR CommandLine OPTIONAL,
IN LPCSTR Environment OPTIONAL,
IN DWORD ReturnAddress OPTIONAL
IN LPCSTR Environment OPTIONAL
);
DWORD DosStartProcess(
@@ -110,8 +109,7 @@ DWORD DosStartProcess(
WORD DosCreateProcess
(
LPCSTR ProgramName,
PDOS_EXEC_PARAM_BLOCK Parameters,
DWORD ReturnAddress
PDOS_EXEC_PARAM_BLOCK Parameters
);
VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode, WORD KeepResident);