Author: aandrejevic
Date: Sun Aug 11 20:54:07 2013
New Revision: 59700
URL:
http://svn.reactos.org/svn/reactos?rev=59700&view=rev
Log:
[NTVDM]
Keep a list of current directories for all drives.
Implement functions that change the default drive and current directory.
Modified:
branches/ntvdm/subsystems/ntvdm/dos.c
branches/ntvdm/subsystems/ntvdm/dos.h
Modified: branches/ntvdm/subsystems/ntvdm/dos.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos.c?re…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/dos.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/dos.c [iso-8859-1] Sun Aug 11 20:54:07 2013
@@ -19,6 +19,9 @@
static WORD CurrentPsp = SYSTEM_PSP;
static WORD DosLastError = 0;
static DWORD DiskTransferArea;
+static BYTE CurrentDrive;
+static CHAR LastDrive = 'E';
+static CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
static HANDLE DosSystemFileTable[DOS_SFT_SIZE];
static WORD DosSftRefCount[DOS_SFT_SIZE];
static BYTE DosAllocStrategy = DOS_ALLOC_BEST_FIT;
@@ -820,6 +823,81 @@
/* Clear the entry in the JFT */
HandleTable[DosHandle] = 0xFF;
+ return TRUE;
+}
+
+BOOLEAN DosChangeDrive(BYTE Drive)
+{
+ WCHAR DirectoryPath[DOS_CMDLINE_LENGTH];
+
+ /* Make sure the drive exists */
+ if (Drive > (LastDrive - 'A')) return FALSE;
+
+ /* Find the path to the new current directory */
+ swprintf(DirectoryPath, L"%c\\%S", Drive + 'A',
CurrentDirectories[Drive]);
+
+ /* Change the current directory of the process */
+ if (!SetCurrentDirectory(DirectoryPath)) return FALSE;
+
+ /* Set the current drive */
+ CurrentDrive = Drive;
+
+ /* Return success */
+ return TRUE;
+}
+
+BOOLEAN DosChangeDirectory(LPSTR Directory)
+{
+ BYTE DriveNumber;
+ DWORD Attributes;
+ LPSTR Path;
+
+ /* Make sure the directory path is not too long */
+ if (strlen(Directory) >= DOS_DIR_LENGTH)
+ {
+ DosLastError = ERROR_PATH_NOT_FOUND;
+ return FALSE;
+ }
+
+ /* Get the drive number */
+ DriveNumber = Directory[0] - 'A';
+
+ /* Make sure the drive exists */
+ if (DriveNumber > (LastDrive - 'A'))
+ {
+ DosLastError = ERROR_PATH_NOT_FOUND;
+ return FALSE;
+ }
+
+ /* Get the file attributes */
+ Attributes = GetFileAttributesA(Directory);
+
+ /* Make sure the path exists and is a directory */
+ if ((Attributes == INVALID_FILE_ATTRIBUTES)
+ || !(Attributes & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ DosLastError = ERROR_PATH_NOT_FOUND;
+ return FALSE;
+ }
+
+ /* Check if this is the current drive */
+ if (DriveNumber == CurrentDrive)
+ {
+ /* Change the directory */
+ if (!SetCurrentDirectoryA(Directory))
+ {
+ DosLastError = LOWORD(GetLastError());
+ return FALSE;
+ }
+ }
+
+ /* Get the directory part of the path */
+ Path = strchr(Directory, '\\') + 1;
+
+ /* Set the directory for the drive */
+ strcpy(CurrentDirectories[DriveNumber], Path);
+
+ /* Return success */
return TRUE;
}
@@ -1302,6 +1380,16 @@
break;
}
+ /* Set Default Drive */
+ case 0x0E:
+ {
+ DosChangeDrive(LOBYTE(Edx));
+ EmulatorSetRegister(EMULATOR_REG_AX,
+ (Eax & 0xFFFFFF00) | (LastDrive - 'A' + 1));
+
+ break;
+ }
+
/* Set Disk Transfer Area */
case 0x1A:
{
@@ -1472,7 +1560,7 @@
String = (PCHAR)((ULONG_PTR)BaseAddress
+ TO_LINEAR(DataSegment, LOWORD(Edx)));
- if (SetCurrentDirectoryA(String))
+ if (DosChangeDirectory(String))
{
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
}
@@ -1480,7 +1568,7 @@
{
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
EmulatorSetRegister(EMULATOR_REG_AX,
- (Eax & 0xFFFF0000) | LOWORD(GetLastError()));
+ (Eax & 0xFFFF0000) | DosLastError);
}
break;
@@ -1953,6 +2041,9 @@
LPSTR AsciiString;
LPSTR DestPtr = (LPSTR)((ULONG_PTR)BaseAddress + TO_LINEAR(SYSTEM_ENV_BLOCK, 0));
DWORD AsciiSize;
+ CHAR CurrentDirectory[MAX_PATH];
+ CHAR DosDirectory[DOS_DIR_LENGTH];
+ LPSTR Path;
/* Initialize the MCB */
Mcb->BlockType = 'Z';
@@ -2022,6 +2113,37 @@
/* Free the memory allocated for environment strings */
FreeEnvironmentStringsW(Environment);
+ /* Clear the current directory buffer */
+ ZeroMemory(CurrentDirectories, sizeof(CurrentDirectories));
+
+ /* Get the current directory */
+ if (!GetCurrentDirectoryA(MAX_PATH, CurrentDirectory))
+ {
+ // TODO: Use some kind of default path?
+ return FALSE;
+ }
+
+ /* Convert that to a DOS path */
+ if (!GetShortPathNameA(CurrentDirectory, DosDirectory, DOS_DIR_LENGTH))
+ {
+ // TODO: Use some kind of default path?
+ return FALSE;
+ }
+
+ /* Set the drive */
+ CurrentDrive = DosDirectory[0] - 'A';
+
+ /* Get the path */
+ Path = strchr(DosDirectory, '\\');
+ if (Path != NULL)
+ {
+ /* Skip the backslash */
+ Path++;
+ }
+
+ /* Set the directory */
+ if (Path != NULL) strcpy(CurrentDirectories[CurrentDrive], Path);
+
/* Read CONFIG.SYS */
Stream = _wfopen(DOS_CONFIG_PATH, L"r");
if (Stream != NULL)
Modified: branches/ntvdm/subsystems/ntvdm/dos.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos.h?re…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/dos.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/dos.h [iso-8859-1] Sun Aug 11 20:54:07 2013
@@ -34,6 +34,8 @@
#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)
enum DOS_ALLOC_STRATEGY
{