mirror of
https://github.com/reactos/reactos.git
synced 2026-07-02 07:44:28 +08:00
[FAST486]
Update the copyright year (better late than never). Push the error code inside Fast486InterruptInternal, to make the size of the pushed value on the stack correct. Update the CPL in Fast486TaskSwitch. svn path=/trunk/; revision=67526
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* fast486.h
|
||||
*
|
||||
* Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Copyright (C) 2015 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* common.c
|
||||
*
|
||||
* Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Copyright (C) 2015 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -264,7 +264,9 @@ Fast486GetIntVector(PFAST486_STATE State,
|
||||
static inline BOOLEAN
|
||||
FASTCALL
|
||||
Fast486InterruptInternal(PFAST486_STATE State,
|
||||
PFAST486_IDT_ENTRY IdtEntry)
|
||||
PFAST486_IDT_ENTRY IdtEntry,
|
||||
BOOLEAN PushErrorCode,
|
||||
ULONG ErrorCode)
|
||||
{
|
||||
USHORT SegmentSelector = IdtEntry->Selector;
|
||||
ULONG Offset = MAKELONG(IdtEntry->Offset, IdtEntry->OffsetHigh);
|
||||
@@ -400,6 +402,16 @@ Fast486InterruptInternal(PFAST486_STATE State,
|
||||
/* Push the instruction pointer */
|
||||
if (!Fast486StackPush(State, State->InstPtr.Long)) goto Cleanup;
|
||||
|
||||
if (PushErrorCode)
|
||||
{
|
||||
/* Push the error code */
|
||||
if (!Fast486StackPush(State, ErrorCode))
|
||||
{
|
||||
/* An exception occurred */
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if ((GateType == FAST486_IDT_INT_GATE) || (GateType == FAST486_IDT_INT_GATE_32))
|
||||
{
|
||||
/* Disable interrupts after a jump to an interrupt gate handler */
|
||||
@@ -448,7 +460,7 @@ Fast486PerformInterrupt(PFAST486_STATE State,
|
||||
}
|
||||
|
||||
/* Perform the interrupt */
|
||||
if (!Fast486InterruptInternal(State, &IdtEntry))
|
||||
if (!Fast486InterruptInternal(State, &IdtEntry, FALSE, 0))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
@@ -463,6 +475,8 @@ Fast486ExceptionWithErrorCode(PFAST486_STATE State,
|
||||
FAST486_EXCEPTIONS ExceptionCode,
|
||||
ULONG ErrorCode)
|
||||
{
|
||||
FAST486_IDT_ENTRY IdtEntry;
|
||||
|
||||
/* Increment the exception count */
|
||||
State->ExceptionCount++;
|
||||
|
||||
@@ -491,8 +505,8 @@ Fast486ExceptionWithErrorCode(PFAST486_STATE State,
|
||||
/* Restore the IP to the saved IP */
|
||||
State->InstPtr = State->SavedInstPtr;
|
||||
|
||||
/* Perform the interrupt */
|
||||
if (!Fast486PerformInterrupt(State, ExceptionCode))
|
||||
/* Get the interrupt vector */
|
||||
if (!Fast486GetIntVector(State, ExceptionCode, &IdtEntry))
|
||||
{
|
||||
/*
|
||||
* If this function failed, that means Fast486Exception
|
||||
@@ -501,18 +515,18 @@ Fast486ExceptionWithErrorCode(PFAST486_STATE State,
|
||||
return;
|
||||
}
|
||||
|
||||
if (EXCEPTION_HAS_ERROR_CODE(ExceptionCode)
|
||||
&& (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE))
|
||||
/* Perform the interrupt */
|
||||
if (!Fast486InterruptInternal(State,
|
||||
&IdtEntry,
|
||||
EXCEPTION_HAS_ERROR_CODE(ExceptionCode)
|
||||
&& (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE),
|
||||
ErrorCode))
|
||||
{
|
||||
/* Push the error code */
|
||||
if (!Fast486StackPush(State, ErrorCode))
|
||||
{
|
||||
/*
|
||||
* If this function failed, that means Fast486Exception
|
||||
* was called again, so just return in this case.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* If this function failed, that means Fast486Exception
|
||||
* was called again, so just return in this case.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reset the exception count */
|
||||
@@ -702,11 +716,17 @@ Fast486TaskSwitch(PFAST486_STATE State, FAST486_TASK_SWITCH_TYPE Type, USHORT Se
|
||||
/* Flush the TLB */
|
||||
if (State->Tlb) RtlZeroMemory(State->Tlb, NUM_TLB_ENTRIES * sizeof(ULONG));
|
||||
|
||||
/* Update the CPL */
|
||||
State->Cpl = GET_SEGMENT_RPL(NewTss.Cs);
|
||||
|
||||
#ifndef FAST486_NO_PREFETCH
|
||||
/* Context switching invalidates the prefetch */
|
||||
State->PrefetchValid = FALSE;
|
||||
#endif
|
||||
|
||||
/* Update the CPL */
|
||||
State->Cpl = GET_SEGMENT_RPL(NewTss.Cs);
|
||||
|
||||
/* Load the registers */
|
||||
State->InstPtr.Long = State->SavedInstPtr.Long = NewTss.Eip;
|
||||
State->Flags.Long = NewTss.Eflags;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* common.h
|
||||
*
|
||||
* Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Copyright (C) 2015 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* common.inl
|
||||
*
|
||||
* Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Copyright (C) 2015 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -782,6 +782,9 @@ Fast486ProcessGate(PFAST486_STATE State, USHORT Selector, ULONG Offset, BOOLEAN
|
||||
{
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
|
||||
Fast486Exception(State, FAST486_EXCEPTION_UD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* fast486dbg.c
|
||||
*
|
||||
* Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Copyright (C) 2015 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* extraops.c
|
||||
*
|
||||
* Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Copyright (C) 2015 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* extraops.h
|
||||
*
|
||||
* Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Copyright (C) 2015 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* fast486.c
|
||||
*
|
||||
* Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Copyright (C) 2015 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* fpu.c
|
||||
*
|
||||
* Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Copyright (C) 2015 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* fpu.h
|
||||
*
|
||||
* Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Copyright (C) 2015 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* opcodes.c
|
||||
*
|
||||
* Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Copyright (C) 2015 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* opcodes.h
|
||||
*
|
||||
* Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Copyright (C) 2015 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* opgroups.c
|
||||
*
|
||||
* Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Copyright (C) 2015 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* opgroups.h
|
||||
*
|
||||
* Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Copyright (C) 2015 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -146,6 +146,7 @@ WORD DosCreateFileEx(LPWORD Handle,
|
||||
{
|
||||
WORD LastError;
|
||||
HANDLE FileHandle;
|
||||
PDOS_DEVICE_NODE Node;
|
||||
WORD DosHandle;
|
||||
ACCESS_MASK AccessMode = 0;
|
||||
DWORD ShareMode = 0;
|
||||
@@ -163,185 +164,193 @@ WORD DosCreateFileEx(LPWORD Handle,
|
||||
// explains what those AccessShareModes are (see the uStyle flag).
|
||||
//
|
||||
|
||||
/* Parse the access mode */
|
||||
switch (AccessShareModes & 0x03)
|
||||
Node = DosGetDevice(FilePath);
|
||||
if (Node != NULL)
|
||||
{
|
||||
/* 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;
|
||||
if (Node->OpenRoutine) Node->OpenRoutine(Node);
|
||||
}
|
||||
|
||||
/* Parse the share mode */
|
||||
switch ((AccessShareModes >> 4) & 0x07)
|
||||
else
|
||||
{
|
||||
/* 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:
|
||||
/* Parse the access mode */
|
||||
switch (AccessShareModes & 0x03)
|
||||
{
|
||||
if (LastError == ERROR_ALREADY_EXISTS)
|
||||
*CreationStatus = 0x01; // The file was opened
|
||||
else
|
||||
*CreationStatus = 0x02; // The file was created
|
||||
/* Read-only */
|
||||
case 0:
|
||||
AccessMode = GENERIC_READ;
|
||||
break;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
case 0x12:
|
||||
/* Parse the share mode */
|
||||
switch ((AccessShareModes >> 4) & 0x07)
|
||||
{
|
||||
if (LastError == ERROR_ALREADY_EXISTS)
|
||||
*CreationStatus = 0x03; // The file was replaced
|
||||
else
|
||||
*CreationStatus = 0x02; // The file was created
|
||||
/* Compatibility mode */
|
||||
case 0:
|
||||
ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
||||
break;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,11 +366,19 @@ WORD DosCreateFileEx(LPWORD Handle,
|
||||
Descriptor = DosGetFileDescriptor(DescriptorId);
|
||||
RtlZeroMemory(Descriptor, sizeof(*Descriptor));
|
||||
|
||||
Descriptor->OpenMode = AccessShareModes;
|
||||
Descriptor->Attributes = LOBYTE(GetFileAttributesA(FilePath));
|
||||
Descriptor->Size = GetFileSize(FileHandle, NULL);
|
||||
Descriptor->OwnerPsp = CurrentPsp;
|
||||
Descriptor->Win32Handle = FileHandle;
|
||||
if (Node != NULL)
|
||||
{
|
||||
Descriptor->DevicePointer = Node->Driver;
|
||||
Descriptor->DeviceInfo = Node->DeviceAttributes | (1 << 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
Descriptor->OpenMode = AccessShareModes;
|
||||
Descriptor->Attributes = LOBYTE(GetFileAttributesA(FilePath));
|
||||
Descriptor->Size = GetFileSize(FileHandle, NULL);
|
||||
Descriptor->OwnerPsp = CurrentPsp;
|
||||
Descriptor->Win32Handle = FileHandle;
|
||||
}
|
||||
|
||||
/* Open the DOS handle */
|
||||
DosHandle = DosOpenHandle(DescriptorId);
|
||||
@@ -383,6 +400,7 @@ WORD DosCreateFile(LPWORD Handle,
|
||||
WORD Attributes)
|
||||
{
|
||||
HANDLE FileHandle;
|
||||
PDOS_DEVICE_NODE Node;
|
||||
WORD DosHandle;
|
||||
BYTE DescriptorId;
|
||||
PDOS_FILE_DESCRIPTOR Descriptor;
|
||||
@@ -390,18 +408,26 @@ WORD DosCreateFile(LPWORD Handle,
|
||||
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,
|
||||
CreationDisposition,
|
||||
Attributes,
|
||||
NULL);
|
||||
if (FileHandle == INVALID_HANDLE_VALUE)
|
||||
Node = DosGetDevice(FilePath);
|
||||
if (Node != NULL)
|
||||
{
|
||||
/* Return the error code */
|
||||
return (WORD)GetLastError();
|
||||
if (Node->OpenRoutine) Node->OpenRoutine(Node);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create the file */
|
||||
FileHandle = CreateFileA(FilePath,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
NULL,
|
||||
CreationDisposition,
|
||||
Attributes,
|
||||
NULL);
|
||||
if (FileHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
/* Return the error code */
|
||||
return (WORD)GetLastError();
|
||||
}
|
||||
}
|
||||
|
||||
DescriptorId = DosFindFreeDescriptor();
|
||||
@@ -416,10 +442,18 @@ WORD DosCreateFile(LPWORD Handle,
|
||||
Descriptor = DosGetFileDescriptor(DescriptorId);
|
||||
RtlZeroMemory(Descriptor, sizeof(*Descriptor));
|
||||
|
||||
Descriptor->Attributes = LOBYTE(GetFileAttributesA(FilePath));
|
||||
Descriptor->Size = GetFileSize(FileHandle, NULL);
|
||||
Descriptor->OwnerPsp = CurrentPsp;
|
||||
Descriptor->Win32Handle = FileHandle;
|
||||
if (Node != NULL)
|
||||
{
|
||||
Descriptor->DevicePointer = Node->Driver;
|
||||
Descriptor->DeviceInfo = Node->DeviceAttributes | (1 << 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
Descriptor->Attributes = LOBYTE(GetFileAttributesA(FilePath));
|
||||
Descriptor->Size = GetFileSize(FileHandle, NULL);
|
||||
Descriptor->OwnerPsp = CurrentPsp;
|
||||
Descriptor->Win32Handle = FileHandle;
|
||||
}
|
||||
|
||||
/* Open the DOS handle */
|
||||
DosHandle = DosOpenHandle(DescriptorId);
|
||||
|
||||
Reference in New Issue
Block a user