Author: aandrejevic
Date: Mon Jun 24 01:59:09 2013
New Revision: 59328

URL: http://svn.reactos.org/svn/reactos?rev=59328&view=rev
Log:
[NTOSKRNL]
Check for old-style MZ executable in PeFmtCreateSection.
[NTVDM]
Fix bugs.
Implement MZ executable loading.


Modified:
    branches/ntvdm/ntoskrnl/mm/section.c
    branches/ntvdm/subsystems/ntvdm/dos.c
    branches/ntvdm/subsystems/ntvdm/emulator.c
    branches/ntvdm/subsystems/ntvdm/ntvdm.c
    branches/ntvdm/subsystems/ntvdm/ntvdm.h

Modified: branches/ntvdm/ntoskrnl/mm/section.c
URL: 
http://svn.reactos.org/svn/reactos/branches/ntvdm/ntoskrnl/mm/section.c?rev=59328&r1=59327&r2=59328&view=diff
==============================================================================
--- branches/ntvdm/ntoskrnl/mm/section.c        [iso-8859-1] (original)
+++ branches/ntvdm/ntoskrnl/mm/section.c        [iso-8859-1] Mon Jun 24 
01:59:09 2013
@@ -236,6 +236,10 @@
     /* no MZ signature */
     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)

Modified: branches/ntvdm/subsystems/ntvdm/dos.c
URL: 
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos.c?rev=59328&r1=59327&r2=59328&view=diff
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/dos.c       [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/dos.c       [iso-8859-1] Mon Jun 24 
01:59:09 2013
@@ -320,7 +320,10 @@
     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 @@
     {
         /* 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
     {

Modified: branches/ntvdm/subsystems/ntvdm/emulator.c
URL: 
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/emulator.c?rev=59328&r1=59327&r2=59328&view=diff
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/emulator.c  [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/emulator.c  [iso-8859-1] Mon Jun 24 
01:59:09 2013
@@ -254,25 +254,25 @@
 
 ULONG EmulatorGetRegister(ULONG Register)
 {
+    if (Register < EMULATOR_REG_ES)
+    {
+        return EmulatorContext.state->general_reg[Register].val;
+    }
+    else
+    {
+        return EmulatorContext.state->segment_reg[Register - 
EMULATOR_REG_ES].val;
+    }
+}
+
+VOID EmulatorSetRegister(ULONG Register, ULONG Value)
+{
     if (Register < EMULATOR_REG_CS)
     {
-        return EmulatorContext.state->general_reg[Register].val;
+        EmulatorContext.state->general_reg[Register].val = Value;
     }
     else
     {
-        return EmulatorContext.state->segment_reg[(Register >> 3) - 1].val;
-    }
-}
-
-VOID EmulatorSetRegister(ULONG Register, ULONG Value)
-{
-    if (Register < EMULATOR_REG_CS)
-    {
-        EmulatorContext.state->general_reg[Register].val = Value;
-    }
-    else
-    {
-        EmulatorContext.state->segment_reg[(Register >> 3) - 1].val = Value;
+        EmulatorContext.state->segment_reg[Register - EMULATOR_REG_ES].val = 
Value;
     }
 }
 

Modified: branches/ntvdm/subsystems/ntvdm/ntvdm.c
URL: 
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ntvdm.c?rev=59328&r1=59327&r2=59328&view=diff
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/ntvdm.c     [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/ntvdm.c     [iso-8859-1] Mon Jun 24 
01:59:09 2013
@@ -42,6 +42,7 @@
         {
             /* Perform interrupt 0x23 */
             EmulatorInterrupt(0x23);
+            break;
         }
         default:
         {
@@ -124,9 +125,12 @@
         }
         
         /* 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);

Modified: branches/ntvdm/subsystems/ntvdm/ntvdm.h
URL: 
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ntvdm.h?rev=59328&r1=59327&r2=59328&view=diff
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/ntvdm.h     [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/ntvdm.h     [iso-8859-1] Mon Jun 24 
01:59:09 2013
@@ -102,12 +102,10 @@
     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)


Reply via email to