mirror of
https://github.com/reactos/reactos.git
synced 2024-10-05 00:43:21 +00:00
[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". svn path=/trunk/; revision=64447
This commit is contained in:
parent
47ed7c7a70
commit
96e5474b43
|
@ -2579,6 +2579,14 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
|||
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 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
|||
/* Extended Open/Create */
|
||||
case 0x6C:
|
||||
{
|
||||
WORD FileHandle;
|
||||
WORD CreationStatus;
|
||||
WORD ErrorCode;
|
||||
|
||||
/* Check for AL == 00 */
|
||||
if (getAL() != 0x00)
|
||||
{
|
||||
|
@ -2783,10 +2795,31 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -192,11 +192,31 @@ BOOL IsConsoleHandle(HANDLE hHandle);
|
|||
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);
|
||||
|
|
|
@ -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;
|
||||
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).aspx
|
||||
// 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\", CreationFlags 0x%04X, Attributes 0x%04X\n",
|
||||
FilePath,
|
||||
CreationFlags,
|
||||
Attributes);
|
||||
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 @@ WORD DosCreateFile(LPWORD Handle, LPCSTR FilePath, WORD CreationFlags, WORD Attr
|
|||
|
||||
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 @@ WORD DosCreateFile(LPWORD Handle, LPCSTR FilePath, WORD CreationFlags, WORD Attr
|
|||
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 DosOpenFile(LPWORD Handle, LPCSTR FilePath, BYTE AccessShareModes)
|
|||
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).aspx
|
||||
// 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 @@ WORD DosOpenFile(LPWORD Handle, LPCSTR FilePath, BYTE AccessShareModes)
|
|||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
if (FileHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
/* Return the error code */
|
||||
|
@ -182,10 +383,8 @@ WORD DosOpenFile(LPWORD Handle, LPCSTR FilePath, BYTE AccessShareModes)
|
|||
|
||||
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 @@ WORD DosOpenFile(LPWORD Handle, LPCSTR FilePath, BYTE AccessShareModes)
|
|||
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 @@ WORD DosReadFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesRead)
|
|||
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 @@ WORD DosWriteFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesWritte
|
|||
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;
|
||||
|
|
Loading…
Reference in a new issue