From cecab82329805d0992d7e4f1a7e3bdafcd897dc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Fri, 15 May 2015 23:13:40 +0000 Subject: [PATCH] [NTVDM] - Simplify CurrentDirectories array usage. - We can directly use a pointer to a DOS_DATA structure stored in the guest memory. - Use the DOS data structures for CurrentDrive (in DOS_DATA) and LastDrive (this is in fact NumLocalDrives in the SYSVARS list). - Use ANSI versions of GetLocaleInfo where applicable. svn path=/trunk/; revision=67750 --- reactos/subsystems/mvdm/ntvdm/dos/dem.c | 4 +- .../mvdm/ntvdm/dos/dos32krnl/bios.c | 6 +- .../mvdm/ntvdm/dos/dos32krnl/device.c | 4 +- .../subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c | 164 +++++++++--------- .../subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h | 5 +- 5 files changed, 90 insertions(+), 93 deletions(-) diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dem.c b/reactos/subsystems/mvdm/ntvdm/dos/dem.c index c42ab46cfb1..4ea219420b9 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dem.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dem.c @@ -28,7 +28,7 @@ /* PRIVATE VARIABLES **********************************************************/ -/**/extern BYTE CurrentDrive;/**/ +extern PDOS_DATA DosData; /* PRIVATE FUNCTIONS **********************************************************/ @@ -575,7 +575,7 @@ demFileFindFirst(OUT PVOID lpFindFileData, } /* Fill the block */ - FindFileBlock->DriveLetter = CurrentDrive + 'A'; + FindFileBlock->DriveLetter = DosData->Sda.CurrentDrive + 'A'; FindFileBlock->AttribMask = AttribMask; FindFileBlock->SearchHandle = SearchHandle; FindFileBlock->Attributes = LOBYTE(FindData.dwFileAttributes); diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/bios.c b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/bios.c index cac14e65ead..ff20adf6031 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/bios.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/bios.c @@ -74,7 +74,7 @@ BOOLEAN DosCheckInput(VOID) PDOS_DEVICE_NODE Node = DosGetDriverNode(Descriptor->DevicePointer); if (!Node->InputStatusRoutine) return FALSE; - + Result = Node->InputStatusRoutine(Node); return !(Result & DOS_DEVSTAT_BUSY); } @@ -199,7 +199,7 @@ BOOLEAN DosBIOSInitialize(VOID) } /* Set the drive */ - CurrentDrive = DosDirectory[0] - 'A'; + Sda->CurrentDrive = DosDirectory[0] - 'A'; /* Get the directory part of the path */ Path = strchr(DosDirectory, '\\'); @@ -212,7 +212,7 @@ BOOLEAN DosBIOSInitialize(VOID) /* Set the directory */ if (Path != NULL) { - strncpy(CurrentDirectories[CurrentDrive], Path, DOS_DIR_LENGTH); + strncpy(CurrentDirectories[Sda->CurrentDrive], Path, DOS_DIR_LENGTH); } /* Read CONFIG.SYS */ diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.c b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.c index 1f73d421d8e..7f98cc3abcd 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.c @@ -239,7 +239,7 @@ static VOID DosAddDriver(DWORD Driver) static VOID DosRemoveDriver(DWORD Driver) { - DWORD CurrentDriver = MAKELONG(FIELD_OFFSET(DOS_SYSVARS, NullDevice), DOS_DATA_SEGMENT); + DWORD CurrentDriver = MAKELONG(DOS_DATA_OFFSET(SysVars.NullDevice), DOS_DATA_SEGMENT); while (LOWORD(CurrentDriver) != 0xFFFF) { @@ -325,7 +325,7 @@ PDOS_DEVICE_NODE DosGetDriverNode(DWORD Driver) PDOS_DEVICE_NODE DosGetDevice(LPCSTR DeviceName) { - DWORD CurrentDriver = MAKELONG(FIELD_OFFSET(DOS_SYSVARS, NullDevice), DOS_DATA_SEGMENT); + DWORD CurrentDriver = MAKELONG(DOS_DATA_OFFSET(SysVars.NullDevice), DOS_DATA_SEGMENT); ANSI_STRING DeviceNameString; RtlInitAnsiString(&DeviceNameString, DeviceName); diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c index d89c9d84802..54bf5ca726d 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c @@ -36,12 +36,11 @@ CALLBACK16 DosContext; -/*static*/ BYTE CurrentDrive = 0x00; -static CHAR LastDrive = 'Z'; // The last drive can be redefined with the LASTDRIVE command. At the moment, set the real maximum possible, 'Z'. -static PCHAR CurrentDirectories; - /* PUBLIC VARIABLES ***********************************************************/ +/* Global DOS data area contained in guest memory */ +PDOS_DATA DosData; +/* Easy accessors to useful DOS data area parts */ PDOS_SYSVARS SysVars; PDOS_SDA Sda; @@ -55,7 +54,7 @@ static BOOLEAN DosChangeDrive(BYTE Drive) CHAR DirectoryPath[DOS_CMDLINE_LENGTH + 1]; /* Make sure the drive exists */ - if (Drive > (LastDrive - 'A')) return FALSE; + if (Drive >= SysVars->NumLocalDrives) return FALSE; RtlZeroMemory(DirectoryPath, sizeof(DirectoryPath)); @@ -63,14 +62,14 @@ static BOOLEAN DosChangeDrive(BYTE Drive) snprintf(DirectoryPath, DOS_CMDLINE_LENGTH, "%c:\\%s", - Drive + 'A', - &CurrentDirectories[Drive * DOS_DIR_LENGTH]); + 'A' + Drive, + DosData->CurrentDirectories[Drive]); /* Change the current directory of the process */ if (!SetCurrentDirectoryA(DirectoryPath)) return FALSE; /* Set the current drive */ - CurrentDrive = Drive; + Sda->CurrentDrive = Drive; /* Return success */ return TRUE; @@ -98,7 +97,7 @@ static BOOLEAN DosChangeDirectory(LPSTR Directory) DriveNumber = RtlUpperChar(Directory[0]) - 'A'; /* Make sure the drive exists */ - if (DriveNumber > (LastDrive - 'A')) + if (DriveNumber >= SysVars->NumLocalDrives) { Sda->LastErrorCode = ERROR_PATH_NOT_FOUND; return FALSE; @@ -107,7 +106,7 @@ static BOOLEAN DosChangeDirectory(LPSTR Directory) else { /* Keep the current drive number */ - DriveNumber = CurrentDrive; + DriveNumber = Sda->CurrentDrive; } /* Get the file attributes */ @@ -122,7 +121,7 @@ static BOOLEAN DosChangeDirectory(LPSTR Directory) } /* Check if this is the current drive */ - if (DriveNumber == CurrentDrive) + if (DriveNumber == Sda->CurrentDrive) { /* Change the directory */ if (!SetCurrentDirectoryA(Directory)) @@ -131,7 +130,7 @@ static BOOLEAN DosChangeDirectory(LPSTR Directory) return FALSE; } } - + /* Get the (possibly new) current directory (needed if we specified a relative directory) */ if (!GetCurrentDirectoryA(sizeof(CurrentDirectory), CurrentDirectory)) { @@ -157,11 +156,11 @@ static BOOLEAN DosChangeDirectory(LPSTR Directory) /* Set the directory for the drive */ if (Path != NULL) { - strncpy(&CurrentDirectories[DriveNumber * DOS_DIR_LENGTH], Path, DOS_DIR_LENGTH); + strncpy(DosData->CurrentDirectories[DriveNumber], Path, DOS_DIR_LENGTH); } else { - CurrentDirectories[DriveNumber * DOS_DIR_LENGTH] = '\0'; + DosData->CurrentDirectories[DriveNumber][0] = '\0'; } /* Return success */ @@ -198,8 +197,6 @@ VOID WINAPI DosInt21h(LPWORD Stack) SYSTEMTIME SystemTime; PCHAR String; PDOS_INPUT_BUFFER InputBuffer; - PDOS_COUNTRY_CODE_BUFFER CountryCodeBuffer; - INT Return; Sda->InDos++; @@ -487,7 +484,7 @@ VOID WINAPI DosInt21h(LPWORD Stack) case 0x0E: { DosChangeDrive(getDL()); - setAL(LastDrive - 'A' + 1); + setAL(SysVars->NumLocalDrives); break; } @@ -510,7 +507,7 @@ VOID WINAPI DosInt21h(LPWORD Stack) /* Get Default Drive */ case 0x19: { - setAL(CurrentDrive); + setAL(Sda->CurrentDrive); break; } @@ -582,8 +579,8 @@ VOID WINAPI DosInt21h(LPWORD Stack) PCHAR FileName = (PCHAR)SEG_OFF_TO_PTR(getDS(), getSI()); PDOS_FCB Fcb = (PDOS_FCB)SEG_OFF_TO_PTR(getES(), getDI()); BYTE Options = getAL(); - INT i; CHAR FillChar = ' '; + UINT i; if (FileName[1] == ':') { @@ -596,7 +593,7 @@ VOID WINAPI DosInt21h(LPWORD Stack) else { /* No drive number specified */ - if (Options & (1 << 1)) Fcb->DriveNumber = CurrentDrive + 1; + if (Options & (1 << 1)) Fcb->DriveNumber = Sda->CurrentDrive + 1; else Fcb->DriveNumber = 0; } @@ -811,13 +808,13 @@ VOID WINAPI DosInt21h(LPWORD Stack) /* Get Free Disk Space */ case 0x36: { - CHAR RootPath[3] = "?:\\"; + CHAR RootPath[] = "?:\\"; DWORD SectorsPerCluster; DWORD BytesPerSector; DWORD NumberOfFreeClusters; DWORD TotalNumberOfClusters; - if (getDL() == 0) RootPath[0] = 'A' + CurrentDrive; + if (getDL() == 0x00) RootPath[0] = 'A' + Sda->CurrentDrive; else RootPath[0] = 'A' + getDL() - 1; if (GetDiskFreeSpaceA(RootPath, @@ -898,14 +895,16 @@ VOID WINAPI DosInt21h(LPWORD Stack) /* Get/Set Country-dependent Information */ case 0x38: { - CountryCodeBuffer = (PDOS_COUNTRY_CODE_BUFFER)SEG_OFF_TO_PTR(getDS(), getDX()); + INT Return; + PDOS_COUNTRY_CODE_BUFFER CountryCodeBuffer = + (PDOS_COUNTRY_CODE_BUFFER)SEG_OFF_TO_PTR(getDS(), getDX()); if (getAL() == 0x00) { /* Get */ - Return = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDATE, - &CountryCodeBuffer->TimeFormat, - sizeof(CountryCodeBuffer->TimeFormat) / sizeof(TCHAR)); + Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDATE, + &CountryCodeBuffer->TimeFormat, + sizeof(CountryCodeBuffer->TimeFormat)); if (Return == 0) { Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; @@ -913,9 +912,9 @@ VOID WINAPI DosInt21h(LPWORD Stack) break; } - Return = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, - &CountryCodeBuffer->CurrencySymbol, - sizeof(CountryCodeBuffer->CurrencySymbol) / sizeof(TCHAR)); + Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, + &CountryCodeBuffer->CurrencySymbol, + sizeof(CountryCodeBuffer->CurrencySymbol)); if (Return == 0) { Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; @@ -923,9 +922,9 @@ VOID WINAPI DosInt21h(LPWORD Stack) break; } - Return = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, - &CountryCodeBuffer->ThousandSep, - sizeof(CountryCodeBuffer->ThousandSep) / sizeof(TCHAR)); + Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, + &CountryCodeBuffer->ThousandSep, + sizeof(CountryCodeBuffer->ThousandSep)); if (Return == 0) { Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; @@ -933,9 +932,9 @@ VOID WINAPI DosInt21h(LPWORD Stack) break; } - Return = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, - &CountryCodeBuffer->DecimalSep, - sizeof(CountryCodeBuffer->DecimalSep) / sizeof(TCHAR)); + Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, + &CountryCodeBuffer->DecimalSep, + sizeof(CountryCodeBuffer->DecimalSep)); if (Return == 0) { Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; @@ -1278,7 +1277,7 @@ VOID WINAPI DosInt21h(LPWORD Stack) /* Get the real drive number */ if (DriveNumber == 0) { - DriveNumber = CurrentDrive; + DriveNumber = Sda->CurrentDrive; } else { @@ -1286,13 +1285,13 @@ VOID WINAPI DosInt21h(LPWORD Stack) DriveNumber--; } - if (DriveNumber <= LastDrive - 'A') + if (DriveNumber < SysVars->NumLocalDrives) { /* * Copy the current directory into the target buffer. * It doesn't contain the drive letter and the backslash. */ - strncpy(String, &CurrentDirectories[DriveNumber * DOS_DIR_LENGTH], DOS_DIR_LENGTH); + strncpy(String, DosData->CurrentDirectories[DriveNumber], DOS_DIR_LENGTH); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; setAX(0x0100); // Undocumented, see Ralf Brown: http://www.ctyme.com/intr/rb-2933.htm } @@ -1499,7 +1498,7 @@ VOID WINAPI DosInt21h(LPWORD Stack) /* Return the DOS "list of lists" in ES:BX */ setES(DOS_DATA_SEGMENT); - setBX(FIELD_OFFSET(DOS_SYSVARS, FirstDpb)); + setBX(DOS_DATA_OFFSET(SysVars.FirstDpb)); break; } @@ -1933,7 +1932,7 @@ VOID WINAPI DosInt2Fh(LPWORD Stack) break; } - + default: { DPRINT1("DOS Internal System Function INT 0x2F, AH = %xh, AL = %xh NOT IMPLEMENTED!\n", @@ -1969,12 +1968,36 @@ BOOLEAN DosKRNLInitialize(VOID) FILE *Stream; WCHAR Buffer[256]; - /* Get a pointer to the current directory buffer */ - CurrentDirectories = (PCHAR)SEG_OFF_TO_PTR(DOS_DATA_SEGMENT, - DOS_DATA_OFFSET(CurrentDirectories)); + /* Initialize the global DOS data area */ + DosData = (PDOS_DATA)SEG_OFF_TO_PTR(DOS_DATA_SEGMENT, 0x0000); + RtlZeroMemory(DosData, sizeof(*DosData)); - /* Clear the current directory buffer */ - RtlZeroMemory(CurrentDirectories, NUM_DRIVES * DOS_DIR_LENGTH * sizeof(CHAR)); + /* Initialize the list of lists */ + SysVars = &DosData->SysVars; + RtlZeroMemory(SysVars, sizeof(*SysVars)); + SysVars->FirstMcb = FIRST_MCB_SEGMENT; + SysVars->FirstSft = MAKELONG(DOS_DATA_OFFSET(Sft), DOS_DATA_SEGMENT); + SysVars->CurrentDirs = MAKELONG(DOS_DATA_OFFSET(CurrentDirectories), + DOS_DATA_SEGMENT); + /* The last drive can be redefined with the LASTDRIVE command. At the moment, set the real maximum possible, 'Z'. */ + SysVars->NumLocalDrives = 'Z' - 'A' + 1; + + /* Initialize the NUL device driver */ + SysVars->NullDevice.Link = 0xFFFFFFFF; + SysVars->NullDevice.DeviceAttributes = DOS_DEVATTR_NUL | DOS_DEVATTR_CHARACTER; + SysVars->NullDevice.StrategyRoutine = FIELD_OFFSET(DOS_SYSVARS, NullDriverRoutine); + SysVars->NullDevice.InterruptRoutine = SysVars->NullDevice.StrategyRoutine + 6; + RtlFillMemory(SysVars->NullDevice.DeviceName, + sizeof(SysVars->NullDevice.DeviceName), + ' '); + RtlCopyMemory(SysVars->NullDevice.DeviceName, "NUL", strlen("NUL")); + RtlCopyMemory(SysVars->NullDriverRoutine, + NullDriverRoutine, + sizeof(NullDriverRoutine)); + + /* Initialize the swappable data area */ + Sda = &DosData->Sda; + RtlZeroMemory(Sda, sizeof(*Sda)); /* Get the current directory */ if (!GetCurrentDirectoryA(sizeof(CurrentDirectory), CurrentDirectory)) @@ -1991,7 +2014,7 @@ BOOLEAN DosKRNLInitialize(VOID) } /* Set the drive */ - CurrentDrive = RtlUpperChar(DosDirectory[0]) - 'A'; + Sda->CurrentDrive = RtlUpperChar(DosDirectory[0]) - 'A'; /* Get the directory part of the path */ Path = strchr(DosDirectory, '\\'); @@ -2004,45 +2027,9 @@ BOOLEAN DosKRNLInitialize(VOID) /* Set the directory */ if (Path != NULL) { - strncpy(&CurrentDirectories[CurrentDrive * DOS_DIR_LENGTH], Path, DOS_DIR_LENGTH); + strncpy(DosData->CurrentDirectories[Sda->CurrentDrive], Path, DOS_DIR_LENGTH); } - /* Read CONFIG.SYS */ - Stream = _wfopen(DOS_CONFIG_PATH, L"r"); - if (Stream != NULL) - { - while (fgetws(Buffer, 256, Stream)) - { - // TODO: Parse the line - } - fclose(Stream); - } - - /* Initialize the list of lists */ - SysVars = (PDOS_SYSVARS)SEG_OFF_TO_PTR(DOS_DATA_SEGMENT, DOS_DATA_OFFSET(SysVars)); - RtlZeroMemory(SysVars, sizeof(DOS_SYSVARS)); - SysVars->FirstMcb = FIRST_MCB_SEGMENT; - SysVars->FirstSft = MAKELONG(DOS_DATA_OFFSET(Sft), DOS_DATA_SEGMENT); - SysVars->CurrentDirs = MAKELONG(DOS_DATA_OFFSET(CurrentDirectories), - DOS_DATA_SEGMENT); - - /* Initialize the NUL device driver */ - SysVars->NullDevice.Link = 0xFFFFFFFF; - SysVars->NullDevice.DeviceAttributes = DOS_DEVATTR_NUL | DOS_DEVATTR_CHARACTER; - SysVars->NullDevice.StrategyRoutine = FIELD_OFFSET(DOS_SYSVARS, NullDriverRoutine); - SysVars->NullDevice.InterruptRoutine = SysVars->NullDevice.StrategyRoutine + 6; - RtlFillMemory(SysVars->NullDevice.DeviceName, - sizeof(SysVars->NullDevice.DeviceName), - ' '); - RtlCopyMemory(SysVars->NullDevice.DeviceName, "NUL", strlen("NUL")); - RtlCopyMemory(SysVars->NullDriverRoutine, - NullDriverRoutine, - sizeof(NullDriverRoutine)); - - /* Initialize the swappable data area */ - Sda = (PDOS_SDA)SEG_OFF_TO_PTR(DOS_DATA_SEGMENT, DOS_DATA_OFFSET(Sda)); - RtlZeroMemory(Sda, sizeof(DOS_SDA)); - /* Set the current PSP to the system PSP */ Sda->CurrentPsp = SYSTEM_PSP; @@ -2060,6 +2047,17 @@ BOOLEAN DosKRNLInitialize(VOID) RtlZeroMemory(&Sft->FileDescriptors[i], sizeof(DOS_FILE_DESCRIPTOR)); } + /* Read CONFIG.SYS */ + Stream = _wfopen(DOS_CONFIG_PATH, L"r"); + if (Stream != NULL) + { + while (fgetws(Buffer, 256, Stream)) + { + // TODO: Parse the line + } + fclose(Stream); + } + #endif /* Initialize the callback context */ diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h index 616f4cbd75e..8b869bd1240 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h @@ -88,7 +88,7 @@ typedef struct _DOS_SYSVARS DWORD CurrentDirs; BYTE Reserved1[6]; BYTE NumBlockDevices; - BYTE NumLocalDrives; + BYTE NumLocalDrives; // Set by LASTDRIVE DOS_DRIVER NullDevice; BYTE NullDriverRoutine[7]; } DOS_SYSVARS, *PDOS_SYSVARS; @@ -233,12 +233,11 @@ typedef struct _DOS_SDA DWORD PrevCallFrame; } DOS_SDA, *PDOS_SDA; -/* This structure is only used for DOS_DATA_OFFSET calculations */ typedef struct _DOS_DATA { DOS_SYSVARS SysVars; DOS_SDA Sda; - CHAR CurrentDirectories[NUM_DRIVES * DOS_DIR_LENGTH]; + CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH]; BYTE Sft[ANYSIZE_ARRAY]; } DOS_DATA, *PDOS_DATA;