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/dos32…
==============================================================================
--- 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/dos32…
==============================================================================
--- 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(a)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/dos32…
==============================================================================
--- 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/dos32…
==============================================================================
--- 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(a)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);
}