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/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 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/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 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/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 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).as... + // 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).as... + // 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;