Author: hbelusca Date: Thu May 15 23:13:06 2014 New Revision: 63309
URL: http://svn.reactos.org/svn/reactos?rev=63309&view=rev Log: [NTVDM] - Add some diagnostic DPRINTs (they are off by default), and fix few of them. - Fix/complete few comments. - Implement INT 21h, AH=56h (rename file), 5Ah (create temporary file), 5Bh (create new file), 68h and 6Ah ("commit" aka. flush file; they are the same function). - Stubplement INT 21h, AH=60h (canonicalize file name or path) and 6Ch (extended open or create file). For this latest one I will merge DosCreateFile and DosOpenFile into the same function (in fact a wrapper around CreateFileA, that is used both for creating and opening files).
Modified: trunk/reactos/subsystems/ntvdm/dos/dos32krnl/bios.c trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.h trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dosfiles.c
Modified: trunk/reactos/subsystems/ntvdm/dos/dos32krnl/bios.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/dos/dos32k... ============================================================================== --- trunk/reactos/subsystems/ntvdm/dos/dos32krnl/bios.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/ntvdm/dos/dos32krnl/bios.c [iso-8859-1] Thu May 15 23:13:06 2014 @@ -1,8 +1,8 @@ /* * COPYRIGHT: GPL - See COPYING in the top level directory * PROJECT: ReactOS Virtual DOS Machine - * FILE: dos.c - * PURPOSE: VDM DOS Kernel + * FILE: dos/dos32krnl/bios.c + * PURPOSE: DOS32 Bios * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org> */
@@ -30,6 +30,8 @@ { CHAR Character = '\0'; WORD BytesRead; + + DPRINT("DosReadCharacter\n");
/* Use the file reading function */ DosReadFile(FileHandle, &Character, 1, &BytesRead);
Modified: trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/dos/dos32k... ============================================================================== --- trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] Thu May 15 23:13:06 2014 @@ -2,8 +2,9 @@ * COPYRIGHT: GPL - See COPYING in the top level directory * PROJECT: ReactOS Virtual DOS Machine * FILE: dos/dos32krnl/dos.c - * PURPOSE: VDM DOS Kernel + * PURPOSE: DOS32 Kernel * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org> + * Hermes Belusca-Maito (hermes.belusca@sfr.fr) */
/* INCLUDES *******************************************************************/ @@ -1436,13 +1437,16 @@ /* Read Character from STDIN with Echo */ case 0x01: { + DPRINT("INT 21h, AH = 01h\n"); + // FIXME: Under DOS 2+, input / output handle may be redirected!!!! DoEcho = TRUE; Character = DosReadCharacter(DOS_INPUT_HANDLE); DoEcho = FALSE;
- // /* Let the BOP repeat if needed */ - // if (getCF()) break; + // FIXME: Check whether Ctrl-C / Ctrl-Break is pressed, and call INT 23h if so. + // Check also Ctrl-P and set echo-to-printer flag. + // Ctrl-Z is not interpreted.
setAL(Character); break; @@ -1536,6 +1540,8 @@ case 0x07: case 0x08: { + DPRINT("Char input without echo\n"); + // FIXME: Under DOS 2+, input handle may be redirected!!!! Character = DosReadCharacter(DOS_INPUT_HANDLE);
@@ -1566,7 +1572,7 @@ * See Ralf Brown: http://www.ctyme.com/intr/rb-2562.htm * for more information. */ - setAL('$'); + setAL('$'); // *String break; }
@@ -1576,7 +1582,7 @@ WORD Count = 0; InputBuffer = (PDOS_INPUT_BUFFER)SEG_OFF_TO_PTR(getDS(), getDX());
- DPRINT1("Read Buffered Input\n"); + DPRINT("Read Buffered Input\n");
while (Count < InputBuffer->MaxLength) { @@ -1584,13 +1590,16 @@
/* Try to read a character (wait) */ Character = DosReadCharacter(DOS_INPUT_HANDLE); + + // FIXME: Check whether Ctrl-C / Ctrl-Break is pressed, and call INT 23h if so.
/* Echo the character and append it to the buffer */ DosPrintCharacter(DOS_OUTPUT_HANDLE, Character); InputBuffer->Buffer[Count] = Character;
+ Count++; /* Carriage returns are also counted */ + if (Character == '\r') break; - Count++; }
/* Update the length */ @@ -1623,13 +1632,9 @@ InputFunction == 0x07 || InputFunction == 0x08 || InputFunction == 0x0A) { + /* Call ourselves recursively */ setAH(InputFunction); - /* - * Instead of calling ourselves really recursively as in: - * DosInt21h(Stack); - * prefer resetting the CF flag to let the BOP repeat. - */ - setCF(1); + DosInt21h(Stack); } break; } @@ -1737,7 +1742,7 @@ /* Create New PSP */ case 0x26: { - DPRINT1("INT 21h, 26h - Create New PSP is UNIMPLEMENTED\n"); + DPRINT1("INT 21h, AH = 26h - Create New PSP is UNIMPLEMENTED\n"); break; }
@@ -1993,15 +1998,16 @@ break; }
- /* Create File */ + /* Create or Truncate File */ case 0x3C: { WORD FileHandle; WORD ErrorCode = DosCreateFile(&FileHandle, (LPCSTR)SEG_OFF_TO_PTR(getDS(), getDX()), + CREATE_ALWAYS, getCX());
- if (ErrorCode == 0) + if (ErrorCode == ERROR_SUCCESS) { Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; setAX(FileHandle); @@ -2023,7 +2029,7 @@ (LPCSTR)SEG_OFF_TO_PTR(getDS(), getDX()), getAL());
- if (ErrorCode == 0) + if (ErrorCode == ERROR_SUCCESS) { Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; setAX(FileHandle); @@ -2058,6 +2064,8 @@ { WORD BytesRead = 0; WORD ErrorCode; + + DPRINT("INT 21h, AH = 3Fh\n");
DoEcho = TRUE; ErrorCode = DosReadFile(getBX(), @@ -2468,6 +2476,30 @@ break; }
+ /* Rename File */ + case 0x56: + { + LPSTR ExistingFileName = (LPSTR)SEG_OFF_TO_PTR(getDS(), getDX()); + LPSTR NewFileName = (LPSTR)SEG_OFF_TO_PTR(getES(), getDI()); + + /* + * See Ralf Brown: http://www.ctyme.com/intr/rb-2990.htm + * for more information. + */ + + if (MoveFileA(ExistingFileName, NewFileName)) + { + Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; + } + else + { + Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; + setAX(GetLastError()); + } + + break; + } + /* Get/Set Memory Management Options */ case 0x58: { @@ -2524,6 +2556,79 @@ break; }
+ /* Create Temporary File */ + case 0x5A: + { + LPSTR PathName = (LPSTR)SEG_OFF_TO_PTR(getDS(), getDX()); + LPSTR FileName = PathName; // The buffer for the path and the full file name is the same. + UINT uRetVal; + WORD FileHandle; + WORD ErrorCode; + + /* + * See Ralf Brown: http://www.ctyme.com/intr/rb-3014.htm + * for more information. + */ + + // FIXME: Check for buffer validity? + // It should be a ASCIZ path ending with a '' + 13 zero bytes + // to receive the generated filename. + + /* First create the temporary file */ + uRetVal = GetTempFileNameA(PathName, NULL, 0, FileName); + if (uRetVal == 0) + { + Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; + setAX(GetLastError()); + break; + } + + /* Now try to open it in read/write access */ + ErrorCode = DosOpenFile(&FileHandle, FileName, 2); + if (ErrorCode == ERROR_SUCCESS) + { + Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; + setAX(FileHandle); + } + else + { + Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; + setAX(ErrorCode); + } + + break; + } + + /* Create New File */ + case 0x5B: + { + WORD FileHandle; + WORD ErrorCode = DosCreateFile(&FileHandle, + (LPCSTR)SEG_OFF_TO_PTR(getDS(), getDX()), + CREATE_NEW, + getCX()); + + if (ErrorCode == ERROR_SUCCESS) + { + Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; + setAX(FileHandle); + } + else + { + Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; + setAX(ErrorCode); + } + + break; + } + + /* Canonicalize File Name or Path */ + case 0x60: + { + // TODO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + break; + } + /* Set Handle Count */ case 0x67: { @@ -2533,6 +2638,50 @@ setAX(DosLastError); } else Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; + + break; + } + + /* Commit File */ + case 0x68: + case 0x6A: + { + /* + * Function 6Ah is identical to function 68h, + * and sets AH to 68h if success. + * See Ralf Brown: http://www.ctyme.com/intr/rb-3176.htm + * for more information. + */ + setAH(0x68); + + if (DosFlushFileBuffers(getBX())) + { + Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; + } + else + { + Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; + setAX(GetLastError()); + } + + break; + } + + /* Extended Open/Create */ + case 0x6C: + { + /* Check for AL == 00 */ + if (getAL() != 0x00) + { + Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; + setAX(ERROR_INVALID_FUNCTION); + break; + } + + // TODO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // FIXME: Extend and merge DosOpenFile and DosCreateFile into + // a single wrapper around CreateFileA, which acts as: + // http://www.ctyme.com/intr/rb-3179.htm
break; } @@ -2562,6 +2711,8 @@ { /* * This is the DOS 2+ Fast Console Output Interrupt. + * The default handler under DOS 2.x and 3.x simply calls INT 10h/AH=0Eh. + * * See Ralf Brown: http://www.ctyme.com/intr/rb-4124.htm * for more information. */ @@ -2570,7 +2721,12 @@ USHORT AX = getAX(); USHORT BX = getBX();
- /* Set the parameters (AL = character, already set) */ + /* + * Set the parameters: + * AL contains the character to print (already set), + * BL contains the character attribute, + * BH contains the video page to use. + */ setBL(DOS_CHAR_ATTRIBUTE); setBH(Bda->VideoPage);
Modified: trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/dos/dos32k... ============================================================================== --- trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.h [iso-8859-1] Thu May 15 23:13:06 2014 @@ -1,8 +1,8 @@ /* * COPYRIGHT: GPL - See COPYING in the top level directory * PROJECT: ReactOS Virtual DOS Machine - * FILE: dos.h - * PURPOSE: VDM DOS Kernel + * FILE: dos/dos32krnl/dos.h + * PURPOSE: DOS32 Kernel * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org> */
@@ -191,8 +191,8 @@ WORD DosOpenHandle(HANDLE Handle); HANDLE DosGetRealHandle(WORD DosHandle);
-WORD DosCreateFile(LPWORD Handle, LPCSTR FilePath, WORD Attributes); -WORD DosOpenFile(LPWORD Handle, LPCSTR FilePath, BYTE AccessMode); +WORD DosCreateFile(LPWORD Handle, LPCSTR FilePath, WORD CreationFlags, WORD Attributes); +WORD DosOpenFile(LPWORD Handle, LPCSTR FilePath, BYTE AccessShareModes); WORD DosReadFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesRead); WORD DosWriteFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesWritten); WORD DosSeekFile(WORD FileHandle, LONG Offset, BYTE Origin, LPDWORD NewOffset);
Modified: trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dosfiles.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/dos/dos32k... ============================================================================== --- trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dosfiles.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dosfiles.c [iso-8859-1] Thu May 15 23:13:06 2014 @@ -2,8 +2,9 @@ * COPYRIGHT: GPL - See COPYING in the top level directory * PROJECT: ReactOS Virtual DOS Machine * FILE: dos/dos32krnl/dosfiles.c - * PURPOSE: DOS Files + * PURPOSE: DOS32 Files Support * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org> + * Hermes Belusca-Maito (hermes.belusca@sfr.fr) */
/* INCLUDES *******************************************************************/ @@ -22,13 +23,14 @@
/* PUBLIC FUNCTIONS ***********************************************************/
-WORD DosCreateFile(LPWORD Handle, LPCSTR FilePath, WORD Attributes) +WORD DosCreateFile(LPWORD Handle, LPCSTR FilePath, WORD CreationFlags, WORD Attributes) { HANDLE FileHandle; WORD DosHandle;
- DPRINT("DosCreateFile: FilePath "%s", Attributes 0x%04X\n", + DPRINT("DosCreateFile: FilePath "%s", CreationFlags 0x%04X, Attributes 0x%04X\n", FilePath, + CreationFlags, Attributes);
/* Create the file */ @@ -36,7 +38,7 @@ GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, - CREATE_ALWAYS, + CreationFlags, Attributes, NULL);
@@ -63,37 +65,40 @@ return ERROR_SUCCESS; }
-WORD DosOpenFile(LPWORD Handle, LPCSTR FilePath, BYTE AccessMode) +WORD DosOpenFile(LPWORD Handle, LPCSTR FilePath, BYTE AccessShareModes) { HANDLE FileHandle; - ACCESS_MASK Access = 0; + ACCESS_MASK AccessMode = 0; + DWORD ShareMode = 0; + BOOL InheritableFile = FALSE; + SECURITY_ATTRIBUTES SecurityAttributes; WORD DosHandle;
- DPRINT("DosOpenFile: FilePath "%s", AccessMode 0x%04X\n", + DPRINT("DosOpenFile: FilePath "%s", AccessShareModes 0x%04X\n", FilePath, - AccessMode); + AccessShareModes);
/* Parse the access mode */ - switch (AccessMode & 3) + switch (AccessShareModes & 0x03) { case 0: { /* Read-only */ - Access = GENERIC_READ; + AccessMode = GENERIC_READ; break; }
case 1: { /* Write only */ - Access = GENERIC_WRITE; + AccessMode = GENERIC_WRITE; break; }
case 2: { /* Read and write */ - Access = GENERIC_READ | GENERIC_WRITE; + AccessMode = GENERIC_READ | GENERIC_WRITE; break; }
@@ -104,11 +109,64 @@ } }
+ /* Parse the share mode */ + switch ((AccessShareModes >> 4) & 0x07) + { + case 0: + { + /* Compatibility mode */ + ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; + break; + } + + case 1: + { + /* No sharing "DenyAll" */ + ShareMode = 0; + break; + } + + case 2: + { + /* No write share "DenyWrite" */ + ShareMode = FILE_SHARE_READ; + break; + } + + case 3: + { + /* No read share "DenyRead" */ + ShareMode = FILE_SHARE_WRITE; + break; + } + + case 4: + { + /* Full share "DenyNone" */ + ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + break; + } + + default: + { + /* Invalid */ + return ERROR_INVALID_PARAMETER; + } + } + + /* Check for inheritance */ + InheritableFile = ((AccessShareModes & 0x80) == 0); + + /* Assign default security attributes to the file, and set the inheritance flag */ + SecurityAttributes.nLength = sizeof(SecurityAttributes); + SecurityAttributes.lpSecurityDescriptor = NULL; + SecurityAttributes.bInheritHandle = InheritableFile; + /* Open the file */ FileHandle = CreateFileA(FilePath, - Access, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, + AccessMode, + ShareMode, + &SecurityAttributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -142,7 +200,7 @@ DWORD BytesRead32 = 0; HANDLE Handle = DosGetRealHandle(FileHandle);
- DPRINT1("DosReadFile: FileHandle 0x%04X, Count 0x%04X\n", FileHandle, Count); + DPRINT("DosReadFile: FileHandle 0x%04X, Count 0x%04X\n", FileHandle, Count);
/* Make sure the handle is valid */ if (Handle == INVALID_HANDLE_VALUE) return ERROR_INVALID_HANDLE; @@ -207,9 +265,7 @@ DWORD BytesWritten32 = 0; HANDLE Handle = DosGetRealHandle(FileHandle);
- DPRINT1("DosWriteFile: FileHandle 0x%04X, Count 0x%04X\n", - FileHandle, - Count); + DPRINT("DosWriteFile: FileHandle 0x%04X, Count 0x%04X\n", FileHandle, Count);
/* Make sure the handle is valid */ if (Handle == INVALID_HANDLE_VALUE) return ERROR_INVALID_HANDLE; @@ -313,7 +369,6 @@ return ERROR_SUCCESS; }
-// This function is almost exclusively used as a DosFlushInputBuffer BOOL DosFlushFileBuffers(WORD FileHandle) { HANDLE Handle = DosGetRealHandle(FileHandle); @@ -322,9 +377,11 @@ if (Handle == INVALID_HANDLE_VALUE) return FALSE;
/* - * No need to check whether the handle is a console handle since - * FlushFileBuffers() automatically does this check and calls - * FlushConsoleInputBuffer() for us. + * This function can either flush files back to disks, or flush + * console input buffers, in which case there is no need to check + * whether the handle is a console handle. FlushFileBuffers() + * automatically does this check and calls FlushConsoleInputBuffer() + * if needed. */ return FlushFileBuffers(Handle); }