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/d... ============================================================================== --- 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/d... ============================================================================== --- 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/d... ============================================================================== --- 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/d... ============================================================================== --- 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 {