Author: hbelusca
Date: Sat Jul 18 19:45:37 2015
New Revision: 68418
URL:
http://svn.reactos.org/svn/reactos?rev=68418&view=rev
Log:
[NTVDM]
- Move some #defines into their correct headers.
- Fix some DPRINTs.
- Add missing DOS SYSVars values (memory-related), confirmed by DOS undocumented &
FreeDOS.
- Implement INT 21h, AX=5700h and 5701h "Get/Set File last-written date &
time".
- Implement INT 2Fh, AH=13h "Set Disk Interrupt Handler" chain support, which is
an obscure functionality (to make story short: allows inserting disk filter drivers): see
the comments inside the code (dos.c/dos.h) for more information.
Modified:
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.h
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] Sat Jul 18
19:45:37 2015
@@ -785,10 +785,10 @@
break;
}
- default:
- {
- DPRINT1("INT 21h, AH = 33h, subfunction AL = %Xh NOT
IMPLEMENTED\n",
- getAL());
+ default: // goto Default;
+ {
+ DPRINT1("INT 21h, AH = %02Xh, subfunction AL = %02Xh NOT
IMPLEMENTED\n",
+ getAH(), getAL());
}
}
@@ -1512,6 +1512,110 @@
break;
}
+ /* File Attributes */
+ case 0x57:
+ {
+ switch (getAL())
+ {
+ /* Get File's last-written Date and Time */
+ case 0x00:
+ {
+ PDOS_FILE_DESCRIPTOR Descriptor =
DosGetHandleFileDescriptor(getBX());
+ FILETIME LastWriteTime;
+ WORD FileDate, FileTime;
+
+ if (Descriptor == NULL)
+ {
+ /* Invalid handle */
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ // Sda->LastErrorCode = ERROR_INVALID_HANDLE;
+ setAX(ERROR_INVALID_HANDLE);
+ break;
+ }
+
+ if (Descriptor->DeviceInfo & FILE_INFO_DEVICE)
+ {
+ /* Invalid for devices */
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ // setAX(ERROR_INVALID_FUNCTION);
+ setAX(ERROR_INVALID_HANDLE);
+ break;
+ }
+
+ /*
+ * Retrieve the last-written Win32 date and time,
+ * and convert it to DOS format.
+ */
+ if (!GetFileTime(Descriptor->Win32Handle,
+ NULL, NULL, &LastWriteTime) ||
+ !FileTimeToDosDateTime(&LastWriteTime,
+ &FileDate, &FileTime))
+ {
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ setAX(GetLastError());
+ break;
+ }
+
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
+ setCX(FileTime);
+ setDX(FileDate);
+ break;
+ }
+
+ /* Set File's last-written Date and Time */
+ case 0x01:
+ {
+ PDOS_FILE_DESCRIPTOR Descriptor =
DosGetHandleFileDescriptor(getBX());
+ FILETIME LastWriteTime;
+ WORD FileDate = getDX();
+ WORD FileTime = getCX();
+
+ if (Descriptor == NULL)
+ {
+ /* Invalid handle */
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ // Sda->LastErrorCode = ERROR_INVALID_HANDLE;
+ setAX(ERROR_INVALID_HANDLE);
+ break;
+ }
+
+ if (Descriptor->DeviceInfo & FILE_INFO_DEVICE)
+ {
+ /* Invalid for devices */
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ // setAX(ERROR_INVALID_FUNCTION);
+ setAX(ERROR_INVALID_HANDLE);
+ break;
+ }
+
+ /*
+ * Convert the new last-written DOS date and time
+ * to Win32 format and set it.
+ */
+ if (!DosDateTimeToFileTime(FileDate, FileTime,
+ &LastWriteTime) ||
+ !SetFileTime(Descriptor->Win32Handle,
+ NULL, NULL, &LastWriteTime))
+ {
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ setAX(GetLastError());
+ break;
+ }
+
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
+ break;
+ }
+
+ default: // goto Default;
+ {
+ DPRINT1("INT 21h, AH = %02Xh, subfunction AL = %02Xh NOT
IMPLEMENTED\n",
+ getAH(), getAL());
+ }
+ }
+
+ break;
+ }
+
/* Get/Set Memory Management Options */
case 0x58:
{
@@ -1748,10 +1852,10 @@
break;
}
- default:
- {
- DPRINT1("INT 21h, AH = 5Dh, subfunction AL = %Xh NOT
IMPLEMENTED\n",
- getAL());
+ default: // goto Default;
+ {
+ DPRINT1("INT 21h, AH = %02Xh, subfunction AL = %02Xh NOT
IMPLEMENTED\n",
+ getAH(), getAL());
}
}
@@ -1833,10 +1937,10 @@
break;
}
- default:
- {
- DPRINT1("INT 21h, AH = 65h, subfunction AL = %Xh NOT
IMPLEMENTED\n",
- getAL());
+ default: // goto Default;
+ {
+ DPRINT1("INT 21h, AH = %02Xh, subfunction AL = %02Xh NOT
IMPLEMENTED\n",
+ getAH(), getAL());
}
}
@@ -1926,9 +2030,9 @@
}
/* Unsupported */
- default:
- {
- DPRINT1("DOS Function INT 0x21, AH = %xh, AL = %xh NOT
IMPLEMENTED!\n",
+ default: // Default:
+ {
+ DPRINT1("DOS Function INT 21h, AH = %02Xh, AL = %02Xh NOT
IMPLEMENTED!\n",
getAH(), getAL());
setAL(0); // Some functions expect AL to be 0 when it's not supported.
@@ -2091,6 +2195,28 @@
break;
}
+ /* Set Disk Interrupt Handler */
+ case 0x13:
+ {
+ /* Save the old values of PrevInt13 and RomBiosInt13 */
+ ULONG OldInt13 = DosData->PrevInt13;
+ ULONG OldBiosInt13 = DosData->RomBiosInt13;
+
+ /* Set PrevInt13 and RomBiosInt13 to their new values */
+ DosData->PrevInt13 = MAKELONG(getDX(), getDS());
+ DosData->RomBiosInt13 = MAKELONG(getBX(), getES());
+
+ /* Return in DS:DX the old value of PrevInt13 */
+ setDS(HIWORD(OldInt13));
+ setDX(LOWORD(OldInt13));
+
+ /* Return in DS:DX the old value of RomBiosInt13 */
+ setES(HIWORD(OldBiosInt13));
+ setBX(LOWORD(OldBiosInt13));
+
+ break;
+ }
+
/* Mostly Windows 2.x/3.x/9x support */
case 0x16:
{
@@ -2127,7 +2253,7 @@
}
default:
- DPRINT1("Unknown DOS XMS Function: INT 0x2F, AH = 43h, AL =
%xh\n", getAL());
+ DPRINT1("Unknown DOS XMS Function: INT 2Fh, AH = 43h, AL =
%02Xh\n", getAL());
break;
}
@@ -2136,7 +2262,7 @@
default: Default:
{
- DPRINT1("DOS Internal System Function INT 0x2F, AH = %xh, AL = %xh NOT
IMPLEMENTED!\n",
+ DPRINT1("DOS Internal System Function INT 2Fh, AH = %02Xh, AL = %02Xh
NOT IMPLEMENTED!\n",
getAH(), getAL());
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
}
@@ -2315,11 +2441,36 @@
/* Unimplemented DOS interrupts */
RegisterDosInt32(0x2A, DosInt2Ah); // DOS Critical Sections / Network
// RegisterDosInt32(0x2E, NULL); //
COMMAND.COM "Reload Transient"
+//
COMMAND.COM adds support for INT 2Fh, AX=AE00h and AE01h "Installable Command -
Installation Check & Execute"
+//
COMMAND.COM adds support for INT 2Fh, AX=5500h "COMMAND.COM Interface"
/* Reserved DOS interrupts */
RegisterDosInt32(0x2B, NULL);
RegisterDosInt32(0x2C, NULL);
RegisterDosInt32(0x2D, NULL);
+
+ /*
+ * Initialize the INT 13h (BIOS Disk Services) handler chain support.
+ *
+ * The INT 13h handler chain is some functionality that allows DOS
+ * to insert disk filter drivers in between the (hooked) INT 13h handler
+ * and its original handler.
+ * Typically, those are:
+ * - filter for detecting disk changes (for floppy disks),
+ * - filter for tracking formatting calls and correcting DMA boundary errors,
+ * - a possible filter to work around a bug in a particular version of PC-AT's
+ * IBM's ROM BIOS (on systems with model byte FCh and BIOS date
"01/10/84" only)
+ * (see
http://www.ctyme.com/intr/rb-4453.htm for more details).
+ *
+ * This functionality is known to be used by some legitimate programs,
+ * by Windows 3.x, as well as some illegitimate ones (aka. virii).
+ *
+ * See extra information about this support in dos.h
+ */
+ // FIXME: Should be done by the DOS BIOS
+ DosData->RomBiosInt13 = ((PULONG)BaseAddress)[0x13];
+ DosData->PrevInt13 = DosData->RomBiosInt13;
+// RegisterDosInt32(0x13, DosInt13h); // Unused at the moment!
/* Initialize country data */
DosCountryInitialize();
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h [iso-8859-1] Sat Jul 18
19:45:37 2015
@@ -26,8 +26,7 @@
#define DOS_CONFIG_PATH L"%SystemRoot%\\system32\\CONFIG.NT"
#define DOS_COMMAND_INTERPRETER
L"%SystemRoot%\\system32\\COMMAND.COM /k
%SystemRoot%\\system32\\AUTOEXEC.NT"
-#define FIRST_MCB_SEGMENT 0x1000
-#define USER_MEMORY_SIZE (0x9FFE - FIRST_MCB_SEGMENT)
+
#define SYSTEM_PSP 0x08
#define SYSTEM_ENV_BLOCK 0x800
#define DOS_CODE_SEGMENT 0x70
@@ -41,16 +40,9 @@
#define DOS_ERROR_HANDLE 2
#define DOS_SFT_SIZE 255
-#define UMB_START_SEGMENT 0xC000
-#define UMB_END_SEGMENT 0xDFFF
-#define DOS_ALLOC_HIGH 0x40
-#define DOS_ALLOC_HIGH_LOW 0x80
#define DOS_DIR_LENGTH 64
#define NUM_DRIVES ('Z' - 'A' + 1)
#define DOS_CHAR_ATTRIBUTE 0x07
-
-/* 16 MB of EMS memory */
-#define EMS_TOTAL_PAGES 1024
#pragma pack(push, 1)
@@ -99,6 +91,11 @@
BYTE BootDrive; // 0x43
BYTE UseDwordMoves; // 0x44
WORD ExtMemSize; // 0x45
+ BYTE Reserved4[0x1C]; // 0x47
+ BYTE ChainUMB; // 0x63 - 0/1: UMB chain (un)linked to
MCB chain
+ WORD Reserved5; // 0x64
+ WORD UMBChainStart; // 0x66 - Segment of the first UMB MCB
+ WORD MemAllocScanStart; // 0x68 - Segment where allocation scan
starts
} DOS_SYSVARS, *PDOS_SYSVARS;
typedef struct _DOS_CLOCK_TRANSFER_RECORD
@@ -235,6 +232,33 @@
typedef struct _DOS_DATA
{
+/*
+ * INT 13h (BIOS Disk Services) handler chain support.
+ *
+ * RomBiosInt13: The original INT 13h vector (normally from ROM BIOS).
+ * PrevInt13 : The previous INT 13h vector in the handler chain (initially
+ * initialized with the RomBiosInt13 value; each time some
+ * program calls INT 2Fh, AH=13h, PrevInt13 is updated).
+ *
+ * DOS hooks INT 13h with its own code, then (in normal circumstances) calls
+ * PrevInt13, so that when a program calls INT 13h, the DOS hook is first called,
+ * followed by the previous INT 13h (be it the original or some other hooked one).
+ * DOS may call PrevInt13 directly in some internal operations too.
+ * RomBiosInt13 is intended to be the original INT 13h vector that existed
+ * before DOS was loaded. A particular version of PC-AT's IBM's ROM BIOS
+ * (on systems with model byte FCh and BIOS date "01/10/84" only, see
+ *
http://www.ctyme.com/intr/rb-4453.htm for more details) had a bug on disk
+ * reads so that it was patched by DOS, and therefore PrevInt13 was the fixed
+ * INT 13 interrupt (for the other cases, a direct call to RomBiosInt13 is done).
+ *
+ * NOTE: For compatibility with some programs (including virii), PrevInt13 should
+ * be at 0070:00B4, see for more details:
+ *
http://repo.hackerzvoice.net/depot_madchat/vxdevl/vdat/tuvd0001.htm
+ *
http://vxheaven.org/lib/vsm01.html
+ */
+ DWORD RomBiosInt13;
+ DWORD PrevInt13; // FIXME: Put it at 0070:00B4
+
DOS_SYSVARS SysVars;
BYTE NullDriverRoutine[7];
WORD DosVersion; // DOS version to report to programs (can be different from the true
one)
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h [iso-8859-1] Sat Jul 18
19:45:37 2015
@@ -18,6 +18,9 @@
#define EMS_PAGE_BITS 14
#define EMS_PAGE_SIZE (1 << EMS_PAGE_BITS)
#define EMS_PHYSICAL_PAGES 4
+
+/* 16 MB of EMS memory */
+#define EMS_TOTAL_PAGES 1024
#define EMS_STATUS_OK 0x00
#define EMS_STATUS_INTERNAL_ERROR 0x80
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.h [iso-8859-1] Sat Jul 18
19:45:37 2015
@@ -12,6 +12,15 @@
/* TYPEDEFS *******************************************************************/
#define SEGMENT_TO_MCB(seg) ((PDOS_MCB)SEG_OFF_TO_PTR((seg), 0))
+
+#define FIRST_MCB_SEGMENT 0x1000
+#define USER_MEMORY_SIZE (0x9FFE - FIRST_MCB_SEGMENT)
+
+#define UMB_START_SEGMENT 0xC000
+#define UMB_END_SEGMENT 0xDFFF
+
+#define DOS_ALLOC_HIGH 0x40
+#define DOS_ALLOC_HIGH_LOW 0x80
enum DOS_ALLOC_STRATEGY
{