mirror of
https://github.com/reactos/reactos.git
synced 2024-07-11 15:15:27 +00:00
[NTOSKRNL]
Check for old-style MZ executable in PeFmtCreateSection. [NTVDM] Fix bugs. Implement MZ executable loading. svn path=/branches/ntvdm/; revision=59328
This commit is contained in:
parent
13a004a57d
commit
ca06374c9f
|
@ -237,6 +237,10 @@ NTSTATUS NTAPI PeFmtCreateSection(IN CONST VOID * FileHeader,
|
|||
if(pidhDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
DIE(("No MZ signature found, e_magic is %hX\n", pidhDosHeader->e_magic));
|
||||
|
||||
/* check if this is an old MZ executable */
|
||||
if(pidhDosHeader->e_lfarlc < 0x40)
|
||||
DIE(("Old-style MZ executable found, e_lfarlc is %d\n", pidhDosHeader->e_lfarlc));
|
||||
|
||||
/* not a Windows executable */
|
||||
if(pidhDosHeader->e_lfanew <= 0)
|
||||
DIE(("Not a Windows executable, e_lfanew is %d\n", pidhDosHeader->e_lfanew));
|
||||
|
|
|
@ -320,7 +320,10 @@ BOOLEAN DosCreateProcess(LPCSTR CommandLine, WORD EnvBlock)
|
|||
LPSTR ProgramFilePath, Parameters[128];
|
||||
CHAR CommandLineCopy[128];
|
||||
INT ParamCount = 0;
|
||||
WORD Segment, FileSize;
|
||||
WORD i, Segment, FileSize, ExeSize;
|
||||
PIMAGE_DOS_HEADER Header;
|
||||
PDWORD RelocationTable;
|
||||
PWORD RelocWord;
|
||||
|
||||
/* Save a copy of the command line */
|
||||
strcpy(CommandLineCopy, CommandLine);
|
||||
|
@ -366,8 +369,64 @@ BOOLEAN DosCreateProcess(LPCSTR CommandLine, WORD EnvBlock)
|
|||
{
|
||||
/* EXE file */
|
||||
|
||||
// TODO: NOT IMPLEMENTED
|
||||
DisplayMessage(L"EXE files are not yet supported!");
|
||||
/* Get the MZ header */
|
||||
Header = (PIMAGE_DOS_HEADER)Address;
|
||||
|
||||
// TODO: Verify checksum and executable!
|
||||
|
||||
/* Get the base size of the file, in paragraphs (rounded up) */
|
||||
ExeSize = (((Header->e_cp - 1) << 8) + Header->e_cblp + 0x0F) >> 4;
|
||||
|
||||
/* Loop from the maximum to the minimum number of extra paragraphs */
|
||||
for (i = Header->e_maxalloc; i >= Header->e_minalloc; i--)
|
||||
{
|
||||
/* Try to allocate that much memory */
|
||||
Segment = DosAllocateMemory(ExeSize + (sizeof(DOS_PSP) >> 4) + i);
|
||||
if (Segment != 0) break;
|
||||
}
|
||||
|
||||
/* Check if at least the lowest allocation was successful */
|
||||
if (Segment == 0) goto Cleanup;
|
||||
|
||||
/* Initialize the PSP */
|
||||
DosInitializePsp(Segment,
|
||||
CommandLine, ExeSize + (sizeof(DOS_PSP) >> 4) + i,
|
||||
EnvBlock);
|
||||
|
||||
/* Copy the program to Segment:0100 */
|
||||
RtlCopyMemory((PVOID)((ULONG_PTR)BaseAddress
|
||||
+ TO_LINEAR(Segment, 0x100)),
|
||||
Address + (Header->e_cparhdr << 4),
|
||||
FileSize - (Header->e_cparhdr << 4));
|
||||
|
||||
/* Get the relocation table */
|
||||
RelocationTable = (PDWORD)(Address + Header->e_lfarlc);
|
||||
|
||||
/* Perform relocations */
|
||||
for (i = 0; i < Header->e_crlc; i++)
|
||||
{
|
||||
/* Get a pointer to the word that needs to be patched */
|
||||
RelocWord = (PWORD)((ULONG_PTR)BaseAddress
|
||||
+ TO_LINEAR(Segment + HIWORD(RelocationTable[i]),
|
||||
0x100 + LOWORD(RelocationTable[i])));
|
||||
|
||||
/* Add the number of the EXE segment to it */
|
||||
*RelocWord += Segment + (sizeof(DOS_PSP) >> 4);
|
||||
}
|
||||
|
||||
/* Set the initial segment registers */
|
||||
EmulatorSetRegister(EMULATOR_REG_DS, Segment);
|
||||
EmulatorSetRegister(EMULATOR_REG_ES, Segment);
|
||||
|
||||
/* Set the stack to the location from the header */
|
||||
EmulatorSetStack(Segment + (sizeof(DOS_PSP) >> 4) + Header->e_ss,
|
||||
Header->e_sp);
|
||||
|
||||
/* Execute */
|
||||
CurrentPsp = Segment;
|
||||
EmulatorExecute(Segment + Header->e_cs, sizeof(DOS_PSP) + Header->e_ip);
|
||||
|
||||
Success = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -254,13 +254,13 @@ VOID EmulatorInterrupt(BYTE Number)
|
|||
|
||||
ULONG EmulatorGetRegister(ULONG Register)
|
||||
{
|
||||
if (Register < EMULATOR_REG_CS)
|
||||
if (Register < EMULATOR_REG_ES)
|
||||
{
|
||||
return EmulatorContext.state->general_reg[Register].val;
|
||||
}
|
||||
else
|
||||
{
|
||||
return EmulatorContext.state->segment_reg[(Register >> 3) - 1].val;
|
||||
return EmulatorContext.state->segment_reg[Register - EMULATOR_REG_ES].val;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,7 +272,7 @@ VOID EmulatorSetRegister(ULONG Register, ULONG Value)
|
|||
}
|
||||
else
|
||||
{
|
||||
EmulatorContext.state->segment_reg[(Register >> 3) - 1].val = Value;
|
||||
EmulatorContext.state->segment_reg[Register - EMULATOR_REG_ES].val = Value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ BOOL WINAPI ConsoleCtrlHandler(DWORD ControlType)
|
|||
{
|
||||
/* Perform interrupt 0x23 */
|
||||
EmulatorInterrupt(0x23);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
|
@ -124,9 +125,12 @@ INT wmain(INT argc, WCHAR *argv[])
|
|||
}
|
||||
|
||||
/* Continue CPU emulation */
|
||||
for (i = 0; i < STEPS_PER_CYCLE; i++) EmulatorStep();
|
||||
for (i = 0; (i < STEPS_PER_CYCLE) && VdmRunning; i++)
|
||||
{
|
||||
EmulatorStep();
|
||||
Cycles++;
|
||||
}
|
||||
|
||||
Cycles += STEPS_PER_CYCLE;
|
||||
if ((CurrentTickCount - LastCyclePrintout) >= 1000)
|
||||
{
|
||||
DPRINT1("NTVDM: %d Instructions Per Second\n", Cycles);
|
||||
|
|
|
@ -102,12 +102,10 @@ typedef enum
|
|||
EMULATOR_REG_DI,
|
||||
EMULATOR_REG_SP,
|
||||
EMULATOR_REG_BP,
|
||||
EMULATOR_REG_ES,
|
||||
EMULATOR_REG_CS,
|
||||
EMULATOR_REG_SS,
|
||||
EMULATOR_REG_DS,
|
||||
EMULATOR_REG_ES,
|
||||
EMULATOR_REG_FS,
|
||||
EMULATOR_REG_GS
|
||||
} EMULATOR_REGISTER;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
|
Loading…
Reference in a new issue