Author: hbelusca
Date: Thu Oct 2 00:26:13 2014
New Revision: 64447
URL:
http://svn.reactos.org/svn/reactos?rev=64447&view=rev
Log:
[NTVDM]
- INT 21h, AH=59h (Get Extended Error Information) is unimplemented but is used by many
applications. DPRINT a special message to remind that we need to implement it.
- Implement INT 21h, AH=6Ch "Extended Open/Create".
Modified:
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/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 Oct 2 00:26:13
2014
@@ -2579,6 +2579,14 @@
break;
}
+ /* Get Extended Error Information */
+ case 0x59:
+ {
+ DPRINT1("INT 21h, AH = 59h, BX = %04Xh - Get Extended Error Information
is UNIMPLEMENTED\n",
+ getBX());
+ break;
+ }
+
/* Create Temporary File */
case 0x5A:
{
@@ -2775,6 +2783,10 @@
/* Extended Open/Create */
case 0x6C:
{
+ WORD FileHandle;
+ WORD CreationStatus;
+ WORD ErrorCode;
+
/* Check for AL == 00 */
if (getAL() != 0x00)
{
@@ -2783,10 +2795,31 @@
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
+ /*
+ * See Ralf Brown:
http://www.ctyme.com/intr/rb-3179.htm
+ * for the full detailed description.
+ *
+ * WARNING: BH contains some extended flags that are NOT SUPPORTED.
+ */
+
+ ErrorCode = DosCreateFileEx(&FileHandle,
+ &CreationStatus,
+ (LPCSTR)SEG_OFF_TO_PTR(getDS(), getSI()),
+ getBL(),
+ getDL(),
+ getCX());
+
+ if (ErrorCode == ERROR_SUCCESS)
+ {
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
+ setCX(CreationStatus);
+ setAX(FileHandle);
+ }
+ else
+ {
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ setAX(ErrorCode);
+ }
break;
}
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 Oct 2 00:26:13
2014
@@ -192,11 +192,31 @@
WORD DosOpenHandle(HANDLE Handle);
HANDLE DosGetRealHandle(WORD DosHandle);
-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);
+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,
+ 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);
BOOL DosFlushFileBuffers(WORD FileHandle);
VOID DosInitializePsp(WORD PspSegment, LPCSTR CommandLine, WORD ProgramSize, WORD
Environment);
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 Oct 2
00:26:13 2014
@@ -12,36 +12,254 @@
#define NDEBUG
#include "emulator.h"
-// #include "callback.h"
#include "dos.h"
#include "dos/dem.h"
#include "bios/bios.h"
-/* PRIVATE VARIABLES **********************************************************/
-
/* PUBLIC FUNCTIONS ***********************************************************/
-WORD DosCreateFile(LPWORD Handle, LPCSTR FilePath, WORD CreationFlags, WORD Attributes)
-{
+WORD DosCreateFileEx(LPWORD Handle,
+ LPWORD CreationStatus,
+ LPCSTR FilePath,
+ BYTE AccessShareModes,
+ WORD CreateActionFlags,
+ WORD Attributes)
+{
+ WORD LastError;
HANDLE FileHandle;
WORD DosHandle;
-
- DPRINT("DosCreateFile: FilePath \"%s\", CreationFlags 0x%04X,
Attributes 0x%04X\n",
- FilePath,
- CreationFlags,
- Attributes);
+ ACCESS_MASK AccessMode = 0;
+ DWORD ShareMode = 0;
+ DWORD CreationDisposition = 0;
+ BOOL InheritableFile = FALSE;
+ SECURITY_ATTRIBUTES SecurityAttributes;
+
+ DPRINT1("DosCreateFileEx: FilePath \"%s\", AccessShareModes 0x%04X,
CreateActionFlags 0x%04X, Attributes 0x%04X\n",
+ FilePath, AccessShareModes, CreateActionFlags, Attributes);
+
+ //
+ // The article about OpenFile API:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365430(v=vs.85).a…
+ // explains what are those AccessShareModes (see the uStyle flag).
+ //
+
+ /* Parse the access mode */
+ switch (AccessShareModes & 0x03)
+ {
+ /* Read-only */
+ case 0:
+ AccessMode = GENERIC_READ;
+ break;
+
+ /* Write only */
+ case 1:
+ AccessMode = GENERIC_WRITE;
+ break;
+
+ /* Read and write */
+ case 2:
+ AccessMode = GENERIC_READ | GENERIC_WRITE;
+ break;
+
+ /* Invalid */
+ default:
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ /* Parse the share mode */
+ switch ((AccessShareModes >> 4) & 0x07)
+ {
+ /* Compatibility mode */
+ case 0:
+ ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+ break;
+
+ /* No sharing "DenyAll" */
+ case 1:
+ ShareMode = 0;
+ break;
+
+ /* No write share "DenyWrite" */
+ case 2:
+ ShareMode = FILE_SHARE_READ;
+ break;
+
+ /* No read share "DenyRead" */
+ case 3:
+ ShareMode = FILE_SHARE_WRITE;
+ break;
+
+ /* Full share "DenyNone" */
+ case 4:
+ ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
+ break;
+
+ /* Invalid */
+ default:
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ /*
+ * Parse the creation action flags:
+ *
+ * Bitfields for action:
+ * Bit(s) Description
+ *
+ * 7-4 Action if file does not exist.
+ * 0000 Fail
+ * 0001 Create
+ *
+ * 3-0 Action if file exists.
+ * 0000 Fail
+ * 0001 Open
+ * 0010 Replace/open
+ */
+ switch (CreateActionFlags)
+ {
+ /* If the file exists, fail, otherwise, fail also */
+ case 0x00:
+ // A special case is used after the call to CreateFileA if it succeeds,
+ // in order to close the opened handle and return an adequate error.
+ CreationDisposition = OPEN_EXISTING;
+ break;
+
+ /* If the file exists, open it, otherwise, fail */
+ case 0x01:
+ CreationDisposition = OPEN_EXISTING;
+ break;
+
+ /* If the file exists, replace it, otherwise, fail */
+ case 0x02:
+ CreationDisposition = TRUNCATE_EXISTING;
+ break;
+
+ /* If the file exists, fail, otherwise, create it */
+ case 0x10:
+ CreationDisposition = CREATE_NEW;
+ break;
+
+ /* If the file exists, open it, otherwise, create it */
+ case 0x11:
+ CreationDisposition = OPEN_ALWAYS;
+ break;
+
+ /* If the file exists, replace it, otherwise, create it */
+ case 0x12:
+ CreationDisposition = CREATE_ALWAYS;
+ break;
+
+ /* Invalid */
+ default:
+ 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,
+ AccessMode,
+ ShareMode,
+ &SecurityAttributes,
+ CreationDisposition,
+ Attributes,
+ NULL);
+
+ LastError = (WORD)GetLastError();
+
+ if (FileHandle == INVALID_HANDLE_VALUE)
+ {
+ /* Return the error code */
+ return LastError;
+ }
+
+ /*
+ * Special case: CreateActionFlags == 0, we must fail because
+ * the file exists (if it didn't exist we already failed).
+ */
+ if (CreateActionFlags == 0)
+ {
+ /* Close the file and return the error code */
+ CloseHandle(FileHandle);
+ return ERROR_FILE_EXISTS;
+ }
+
+ /* Set the creation status */
+ switch (CreateActionFlags)
+ {
+ case 0x01:
+ *CreationStatus = 0x01; // The file was opened
+ break;
+
+ case 0x02:
+ *CreationStatus = 0x03; // The file was replaced
+ break;
+
+ case 0x10:
+ *CreationStatus = 0x02; // The file was created
+ break;
+
+ case 0x11:
+ {
+ if (LastError == ERROR_ALREADY_EXISTS)
+ *CreationStatus = 0x01; // The file was opened
+ else
+ *CreationStatus = 0x02; // The file was created
+
+ break;
+ }
+
+ case 0x12:
+ {
+ if (LastError == ERROR_ALREADY_EXISTS)
+ *CreationStatus = 0x03; // The file was replaced
+ else
+ *CreationStatus = 0x02; // The file was created
+
+ break;
+ }
+ }
+
+ /* Open the DOS handle */
+ DosHandle = DosOpenHandle(FileHandle);
+
+ if (DosHandle == INVALID_DOS_HANDLE)
+ {
+ /* Close the file and return the error code */
+ CloseHandle(FileHandle);
+ return ERROR_TOO_MANY_OPEN_FILES;
+ }
+
+ /* It was successful */
+ *Handle = DosHandle;
+ return ERROR_SUCCESS;
+}
+
+WORD DosCreateFile(LPWORD Handle,
+ LPCSTR FilePath,
+ DWORD CreationDisposition,
+ WORD Attributes)
+{
+ HANDLE FileHandle;
+ WORD DosHandle;
+
+ DPRINT("DosCreateFile: FilePath \"%s\", CreationDisposition 0x%04X,
Attributes 0x%04X\n",
+ FilePath, CreationDisposition, Attributes);
/* Create the file */
FileHandle = CreateFileA(FilePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
- CreationFlags,
+ CreationDisposition,
Attributes,
NULL);
-
if (FileHandle == INVALID_HANDLE_VALUE)
{
/* Return the error code */
@@ -53,10 +271,8 @@
if (DosHandle == INVALID_DOS_HANDLE)
{
- /* Close the handle */
+ /* Close the file and return the error code */
CloseHandle(FileHandle);
-
- /* Return the error code */
return ERROR_TOO_MANY_OPEN_FILES;
}
@@ -65,7 +281,9 @@
return ERROR_SUCCESS;
}
-WORD DosOpenFile(LPWORD Handle, LPCSTR FilePath, BYTE AccessShareModes)
+WORD DosOpenFile(LPWORD Handle,
+ LPCSTR FilePath,
+ BYTE AccessShareModes)
{
HANDLE FileHandle;
ACCESS_MASK AccessMode = 0;
@@ -75,83 +293,67 @@
WORD DosHandle;
DPRINT("DosOpenFile: FilePath \"%s\", AccessShareModes
0x%04X\n",
- FilePath,
- AccessShareModes);
+ FilePath, AccessShareModes);
+
+ //
+ // The article about OpenFile API:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365430(v=vs.85).a…
+ // explains what are those AccessShareModes (see the uStyle flag).
+ //
/* Parse the access mode */
switch (AccessShareModes & 0x03)
{
+ /* Read-only */
case 0:
- {
- /* Read-only */
AccessMode = GENERIC_READ;
break;
- }
-
+
+ /* Write only */
case 1:
- {
- /* Write only */
AccessMode = GENERIC_WRITE;
break;
- }
-
+
+ /* Read and write */
case 2:
- {
- /* Read and write */
AccessMode = GENERIC_READ | GENERIC_WRITE;
break;
- }
-
+
+ /* Invalid */
default:
- {
- /* Invalid */
return ERROR_INVALID_PARAMETER;
- }
}
/* Parse the share mode */
switch ((AccessShareModes >> 4) & 0x07)
{
+ /* Compatibility mode */
case 0:
- {
- /* Compatibility mode */
ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
break;
- }
-
+
+ /* No sharing "DenyAll" */
case 1:
- {
- /* No sharing "DenyAll" */
ShareMode = 0;
break;
- }
-
+
+ /* No write share "DenyWrite" */
case 2:
- {
- /* No write share "DenyWrite" */
ShareMode = FILE_SHARE_READ;
break;
- }
-
+
+ /* No read share "DenyRead" */
case 3:
- {
- /* No read share "DenyRead" */
ShareMode = FILE_SHARE_WRITE;
break;
- }
-
+
+ /* Full share "DenyNone" */
case 4:
- {
- /* Full share "DenyNone" */
ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
break;
- }
-
+
+ /* Invalid */
default:
- {
- /* Invalid */
return ERROR_INVALID_PARAMETER;
- }
}
/* Check for inheritance */
@@ -170,7 +372,6 @@
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
-
if (FileHandle == INVALID_HANDLE_VALUE)
{
/* Return the error code */
@@ -182,10 +383,8 @@
if (DosHandle == INVALID_DOS_HANDLE)
{
- /* Close the handle */
+ /* Close the file and return the error code */
CloseHandle(FileHandle);
-
- /* Return the error code */
return ERROR_TOO_MANY_OPEN_FILES;
}
@@ -194,7 +393,10 @@
return ERROR_SUCCESS;
}
-WORD DosReadFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesRead)
+WORD DosReadFile(WORD FileHandle,
+ LPVOID Buffer,
+ WORD Count,
+ LPWORD BytesRead)
{
WORD Result = ERROR_SUCCESS;
DWORD BytesRead32 = 0;
@@ -259,7 +461,10 @@
return Result;
}
-WORD DosWriteFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesWritten)
+WORD DosWriteFile(WORD FileHandle,
+ LPVOID Buffer,
+ WORD Count,
+ LPWORD BytesWritten)
{
WORD Result = ERROR_SUCCESS;
DWORD BytesWritten32 = 0;
@@ -317,7 +522,10 @@
return Result;
}
-WORD DosSeekFile(WORD FileHandle, LONG Offset, BYTE Origin, LPDWORD NewOffset)
+WORD DosSeekFile(WORD FileHandle,
+ LONG Offset,
+ BYTE Origin,
+ LPDWORD NewOffset)
{
WORD Result = ERROR_SUCCESS;
DWORD FilePointer;