#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
+#define DOS_DATA_SEGMENT 0xA0
+
+#define DOS_DATA_OFFSET(x) FIELD_OFFSET(DOS_DATA, x)
#define INVALID_DOS_HANDLE 0xFFFF
#define DOS_INPUT_HANDLE 0
#define DOS_ERROR_HANDLE 2
#define DOS_SFT_SIZE 255
-#define SEGMENT_TO_MCB(seg) ((PDOS_MCB)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), 0)))
-#define SEGMENT_TO_PSP(seg) ((PDOS_PSP)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), 0)))
-#define UMB_START_SEGMENT 0xC000
-#define UMB_END_SEGMENT 0xDFFF
-#define DOS_ALLOC_HIGH 0x40
-#define DOS_ALLOC_HIGH_LOW 0x80
-#define DOS_CMDLINE_LENGTH 127
#define DOS_DIR_LENGTH 64
#define NUM_DRIVES ('Z' - 'A' + 1)
#define DOS_CHAR_ATTRIBUTE 0x07
-#define DOS_PROGRAM_NAME_TAG 0x0001
-#define DEFAULT_JFT_SIZE 20
-
-/* 16 MB of EMS memory */
-#define EMS_TOTAL_PAGES 1024
-
-typedef enum
-{
- DOS_LOAD_AND_EXECUTE = 0x00,
- DOS_LOAD_ONLY = 0x01,
- DOS_LOAD_OVERLAY = 0x03
-} DOS_EXEC_TYPE;
-
-typedef enum
-{
- DOS_SFT_ENTRY_NONE,
- DOS_SFT_ENTRY_WIN32,
- DOS_SFT_ENTRY_DEVICE
-} DOS_SFT_ENTRY_TYPE;
-
-typedef struct _DOS_SFT_ENTRY
-{
- DOS_SFT_ENTRY_TYPE Type;
- WORD RefCount;
-
- union
- {
- HANDLE Handle;
- PDOS_DEVICE_NODE DeviceNode;
- };
-} DOS_SFT_ENTRY, *PDOS_SFT_ENTRY;
#pragma pack(push, 1)
BYTE RecordNumber[3];
} DOS_FCB, *PDOS_FCB;
-typedef struct _DOS_PSP
+typedef struct _DOS_SYSVARS
{
- BYTE Exit[2];
- WORD LastParagraph;
- BYTE Reserved0[6];
- DWORD TerminateAddress;
- DWORD BreakAddress;
- DWORD CriticalAddress;
- WORD ParentPsp;
- BYTE HandleTable[20];
- WORD EnvBlock;
- DWORD LastStack;
- WORD HandleTableSize;
- DWORD HandleTablePtr;
- DWORD PreviousPsp;
- DWORD Reserved1;
- WORD DosVersion;
- BYTE Reserved2[14];
- BYTE FarCall[3];
- BYTE Reserved3[9];
- DOS_FCB Fcb;
- BYTE CommandLineSize;
- CHAR CommandLine[DOS_CMDLINE_LENGTH];
-} DOS_PSP, *PDOS_PSP;
+ DWORD OemHandler;
+ WORD Int21hReturn;
+ WORD ShareRetryCount;
+ WORD ShareRetryDelay;
+ DWORD DiskBuffer;
+ WORD UnreadConInput;
+ WORD FirstMcb;
+
+ /* This is where the SYSVARS really start */
+ DWORD FirstDpb; // 0x00
+ DWORD FirstSft; // 0x04
+ DWORD ActiveClock; // 0x08
+ DWORD ActiveCon; // 0x0c
+ BYTE Reserved0[6]; // 0x10
+ DWORD CurrentDirs; // 0x16
+ BYTE Reserved1[6]; // 0x1a
+ BYTE NumBlockDevices; // 0x20
+ BYTE NumLocalDrives; // 0x21 - Set by LASTDRIVE
+ DOS_DRIVER NullDevice; // 0x22
+ BYTE Reserved2; // 0x34
+ WORD ProgramVersionTable; // 0x35
+ DWORD SetVerTable; // 0x37
+ WORD Reserved3[2]; // 0x3b
+ WORD BuffersNumber; // 0x3f - 'x' parameter in "BUFFERS=x,y" command
+ WORD BuffersLookaheadNumber; // 0x41 - 'y' parameter in "BUFFERS=x,y" command
+ 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
+{
+ WORD NumberOfDays;
+ BYTE Minutes;
+ BYTE Hours;
+ BYTE Hundredths;
+ BYTE Seconds;
+} DOS_CLOCK_TRANSFER_RECORD, *PDOS_CLOCK_TRANSFER_RECORD;
typedef struct _DOS_INPUT_BUFFER
{
CHAR Buffer[ANYSIZE_ARRAY];
} DOS_INPUT_BUFFER, *PDOS_INPUT_BUFFER;
-typedef struct _DOS_DRIVER_HEADER
-{
- DWORD NextDriver;
- WORD Attributes;
- WORD StrategyEntry;
- WORD InterruptEntry;
- CHAR DeviceName[8];
-} DOS_DRIVER_HEADER, *PDOS_DRIVER_HEADER;
-
typedef struct _DOS_FIND_FILE_BLOCK
{
CHAR DriveLetter;
CHAR FileName[13];
} DOS_FIND_FILE_BLOCK, *PDOS_FIND_FILE_BLOCK;
-typedef struct _DOS_EXEC_PARAM_BLOCK
+typedef struct _DOS_SDA
{
- /* Input variables */
- WORD Environment;
- DWORD CommandLine;
- DWORD FirstFcb;
- DWORD SecondFcb;
-
- /* Output variables */
- DWORD StackLocation;
- DWORD EntryPoint;
-} DOS_EXEC_PARAM_BLOCK, *PDOS_EXEC_PARAM_BLOCK;
-
-typedef struct _DOS_COUNTRY_CODE_BUFFER
+ BYTE PrinterEchoFlag;
+ CHAR CurrentSwitchChar;
+ BYTE AllocStrategy;
+ BYTE Unused0[28];
+
+ /* This is where the SDA really starts */
+ BYTE ErrorMode;
+ BYTE InDos;
+ BYTE ErrorDrive;
+ BYTE LastErrorLocus;
+ WORD LastErrorCode;
+ BYTE LastErrorAction;
+ BYTE LastErrorClass;
+ DWORD LastErrorPointer;
+ DWORD DiskTransferArea;
+ WORD CurrentPsp;
+ WORD Int23StackPointer;
+ WORD ErrorLevel;
+ BYTE CurrentDrive;
+ BYTE ExtendedBreakFlag;
+
+ /* This part is only valid while in DOS */
+ WORD LastAX;
+ WORD NetworkPsp;
+ WORD NetworkMachineNumber;
+ WORD FirstFreeMcb;
+ WORD BestFreeMcb;
+ WORD LastFreeMcb;
+ WORD MemorySize;
+ WORD LastSearchDirEntry;
+ BYTE Int24FailFlag;
+ BYTE DirectoryFlag;
+ BYTE CtrlBreakFlag;
+ BYTE AllowFcbBlanks;
+ BYTE Unused1;
+ BYTE DayOfMonth;
+ BYTE Month;
+ WORD Year;
+ WORD NumDays;
+ BYTE DayOfWeek;
+ BYTE ConsoleSwappedFlag;
+ BYTE Int28CallOk;
+ BYTE Int24AbortFlag;
+ DOS_RW_REQUEST Request;
+ DWORD DriverEntryPoint;
+ BYTE Unused2[44];
+ BYTE PspCopyType;
+ BYTE Unused3;
+ BYTE UserNumber[3];
+ BYTE OemNumber;
+ WORD ErrorCodeTable;
+ DOS_CLOCK_TRANSFER_RECORD ClockTransferRecord;
+ BYTE ByteBuffer;
+ BYTE Unused4;
+ CHAR FileNameBuffer[256];
+ BYTE Unused5[53];
+ CHAR CurrentDirectory[81];
+ CHAR FcbFilename[12];
+ CHAR FcbRenameDest[12];
+ BYTE Unused6[8];
+ BYTE ExtendedAttribute;
+ BYTE FcbType;
+ BYTE DirSearchAttributes;
+ BYTE FileOpenMode;
+ BYTE FileFound;
+ BYTE DeviceNameFound;
+ BYTE SpliceFlag;
+ BYTE DosCallFlag;
+ BYTE Unused7[5];
+ BYTE InsertMode;
+ BYTE ParsedFcbExists;
+ BYTE VolumeIDFlag;
+ BYTE TerminationType;
+ BYTE CreateFileFlag;
+ BYTE FileDeletedChar;
+ DWORD CriticalErrorDpb;
+ DWORD UserRegistersStack;
+ WORD Int24StackPointer;
+ BYTE Unused8[14];
+ DWORD DeviceHeader;
+ DWORD CurrentSft;
+ DWORD CurrentDirPointer;
+ DWORD CallerFcb;
+ WORD SftNumber;
+ WORD TempFileHandle;
+ DWORD JftEntry;
+ WORD FirstArgument;
+ WORD SecondArgument;
+ WORD LastComponent;
+ WORD TransferOffset;
+ BYTE Unused9[38];
+ DWORD WorkingSft;
+ WORD Int21CallerBX;
+ WORD Int21CallerDS;
+ WORD Unused10;
+ DWORD PrevCallFrame;
+} DOS_SDA, *PDOS_SDA;
+
+typedef struct _DOS_DATA
{
- WORD TimeFormat;
- WORD CurrencySymbol;
- WORD ThousandSep;
- WORD DecimalSep;
-} DOS_COUNTRY_CODE_BUFFER, *PDOS_COUNTRY_CODE_BUFFER;
+/*
+ * 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)
+ DOS_SDA Sda;
+ CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
+ BYTE Sft[ANYSIZE_ARRAY];
+} DOS_DATA, *PDOS_DATA;
#pragma pack(pop)
/* VARIABLES ******************************************************************/
extern BOOLEAN DoEcho;
-extern WORD CurrentPsp;
-extern WORD DosLastError;
+extern PDOS_DATA DosData;
+extern PDOS_SYSVARS SysVars;
+extern PDOS_SDA Sda;
/* FUNCTIONS ******************************************************************/
* DOS Kernel Functions
* See dos.c
*/
-WORD DosOpenHandle(HANDLE Handle);
-PDOS_SFT_ENTRY DosGetSftEntry(WORD DosHandle);
-
-WORD DosCreateFileEx(LPWORD Handle,
- LPWORD CreationStatus,
- LPCSTR FilePath,
- BYTE AccessShareModes,
- WORD CreateActionFlags,
- WORD Attributes);
-WORD DosCreateFile(LPWORD Handle,
- LPCSTR FilePath,
- DWORD CreationDisposition,
- WORD Attributes);
-WORD DosOpenFile(LPWORD Handle,
- LPCSTR FilePath,
- BYTE AccessShareModes);
-WORD DosReadFile(WORD FileHandle,
- DWORD Buffer,
- WORD Count,
- LPWORD BytesRead);
-WORD DosWriteFile(WORD FileHandle,
- DWORD Buffer,
- WORD Count,
- LPWORD BytesWritten);
-WORD DosSeekFile(WORD FileHandle,
- LONG Offset,
- BYTE Origin,
- LPDWORD NewOffset);
-BOOL DosFlushFileBuffers(WORD FileHandle);
-
-VOID DosInitializePsp(WORD PspSegment, LPCSTR CommandLine, WORD ProgramSize, WORD Environment);
-DWORD DosLoadExecutable(
- IN DOS_EXEC_TYPE LoadType,
- IN LPCSTR ExecutablePath,
- IN LPCSTR CommandLine,
- IN LPCSTR Environment OPTIONAL,
- OUT PDWORD StackLocation OPTIONAL,
- OUT PDWORD EntryPoint OPTIONAL
-);
-WORD DosCreateProcess(
- DOS_EXEC_TYPE LoadType,
- LPCSTR ProgramName,
- PDOS_EXEC_PARAM_BLOCK Parameters
-);
-DWORD DosStartProcess(
- IN LPCSTR ExecutablePath,
- IN LPCSTR CommandLine,
- IN LPCSTR Environment OPTIONAL
-);
-VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode, WORD KeepResident);
-BOOLEAN DosHandleIoctl(BYTE ControlCode, WORD FileHandle);
BOOLEAN DosKRNLInitialize(VOID);