From a1e439008efdb5ce3aef739fa086aa8584528c5e Mon Sep 17 00:00:00 2001 From: Aleksandar Andrejevic Date: Sun, 3 May 2015 01:45:57 +0000 Subject: [PATCH] [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 --- .../include/reactos/libs/fast486/fast486.h | 2 +- reactos/lib/fast486/common.c | 52 ++- reactos/lib/fast486/common.h | 2 +- reactos/lib/fast486/common.inl | 5 +- reactos/lib/fast486/debug.c | 2 +- reactos/lib/fast486/extraops.c | 2 +- reactos/lib/fast486/extraops.h | 2 +- reactos/lib/fast486/fast486.c | 2 +- reactos/lib/fast486/fpu.c | 2 +- reactos/lib/fast486/fpu.h | 2 +- reactos/lib/fast486/opcodes.c | 2 +- reactos/lib/fast486/opcodes.h | 2 +- reactos/lib/fast486/opgroups.c | 2 +- reactos/lib/fast486/opgroups.h | 2 +- .../mvdm/ntvdm/dos/dos32krnl/dosfiles.c | 414 ++++++++++-------- 15 files changed, 276 insertions(+), 219 deletions(-) diff --git a/reactos/include/reactos/libs/fast486/fast486.h b/reactos/include/reactos/libs/fast486/fast486.h index 413f7c76bde..7f0a02f9249 100644 --- a/reactos/include/reactos/libs/fast486/fast486.h +++ b/reactos/include/reactos/libs/fast486/fast486.h @@ -2,7 +2,7 @@ * Fast486 386/486 CPU Emulation Library * fast486.h * - * Copyright (C) 2014 Aleksandar Andrejevic + * Copyright (C) 2015 Aleksandar Andrejevic * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/reactos/lib/fast486/common.c b/reactos/lib/fast486/common.c index a6d24590973..4f39e6a62ce 100644 --- a/reactos/lib/fast486/common.c +++ b/reactos/lib/fast486/common.c @@ -2,7 +2,7 @@ * Fast486 386/486 CPU Emulation Library * common.c * - * Copyright (C) 2014 Aleksandar Andrejevic + * Copyright (C) 2015 Aleksandar Andrejevic * * 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; diff --git a/reactos/lib/fast486/common.h b/reactos/lib/fast486/common.h index d0394c00cc2..07b21022380 100644 --- a/reactos/lib/fast486/common.h +++ b/reactos/lib/fast486/common.h @@ -2,7 +2,7 @@ * Fast486 386/486 CPU Emulation Library * common.h * - * Copyright (C) 2014 Aleksandar Andrejevic + * Copyright (C) 2015 Aleksandar Andrejevic * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/reactos/lib/fast486/common.inl b/reactos/lib/fast486/common.inl index 31e80ccdc38..a6b67ada50c 100644 --- a/reactos/lib/fast486/common.inl +++ b/reactos/lib/fast486/common.inl @@ -2,7 +2,7 @@ * Fast486 386/486 CPU Emulation Library * common.inl * - * Copyright (C) 2014 Aleksandar Andrejevic + * Copyright (C) 2015 Aleksandar Andrejevic * * 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: diff --git a/reactos/lib/fast486/debug.c b/reactos/lib/fast486/debug.c index 974e99b3588..af362f1328f 100644 --- a/reactos/lib/fast486/debug.c +++ b/reactos/lib/fast486/debug.c @@ -2,7 +2,7 @@ * Fast486 386/486 CPU Emulation Library * fast486dbg.c * - * Copyright (C) 2014 Aleksandar Andrejevic + * Copyright (C) 2015 Aleksandar Andrejevic * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/reactos/lib/fast486/extraops.c b/reactos/lib/fast486/extraops.c index 93fcbae19a6..9ad56b6c854 100644 --- a/reactos/lib/fast486/extraops.c +++ b/reactos/lib/fast486/extraops.c @@ -2,7 +2,7 @@ * Fast486 386/486 CPU Emulation Library * extraops.c * - * Copyright (C) 2014 Aleksandar Andrejevic + * Copyright (C) 2015 Aleksandar Andrejevic * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/reactos/lib/fast486/extraops.h b/reactos/lib/fast486/extraops.h index 0a8effd2ef7..edd5abe9369 100644 --- a/reactos/lib/fast486/extraops.h +++ b/reactos/lib/fast486/extraops.h @@ -2,7 +2,7 @@ * Fast486 386/486 CPU Emulation Library * extraops.h * - * Copyright (C) 2014 Aleksandar Andrejevic + * Copyright (C) 2015 Aleksandar Andrejevic * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/reactos/lib/fast486/fast486.c b/reactos/lib/fast486/fast486.c index 006bee5d16e..89669e4d944 100644 --- a/reactos/lib/fast486/fast486.c +++ b/reactos/lib/fast486/fast486.c @@ -2,7 +2,7 @@ * Fast486 386/486 CPU Emulation Library * fast486.c * - * Copyright (C) 2014 Aleksandar Andrejevic + * Copyright (C) 2015 Aleksandar Andrejevic * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/reactos/lib/fast486/fpu.c b/reactos/lib/fast486/fpu.c index 1e4ce789ec3..a9906447925 100644 --- a/reactos/lib/fast486/fpu.c +++ b/reactos/lib/fast486/fpu.c @@ -2,7 +2,7 @@ * Fast486 386/486 CPU Emulation Library * fpu.c * - * Copyright (C) 2014 Aleksandar Andrejevic + * Copyright (C) 2015 Aleksandar Andrejevic * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/reactos/lib/fast486/fpu.h b/reactos/lib/fast486/fpu.h index b14b12807cc..41796d22054 100644 --- a/reactos/lib/fast486/fpu.h +++ b/reactos/lib/fast486/fpu.h @@ -2,7 +2,7 @@ * Fast486 386/486 CPU Emulation Library * fpu.h * - * Copyright (C) 2014 Aleksandar Andrejevic + * Copyright (C) 2015 Aleksandar Andrejevic * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/reactos/lib/fast486/opcodes.c b/reactos/lib/fast486/opcodes.c index 87dce030b45..8f5e0c6aedc 100644 --- a/reactos/lib/fast486/opcodes.c +++ b/reactos/lib/fast486/opcodes.c @@ -2,7 +2,7 @@ * Fast486 386/486 CPU Emulation Library * opcodes.c * - * Copyright (C) 2014 Aleksandar Andrejevic + * Copyright (C) 2015 Aleksandar Andrejevic * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/reactos/lib/fast486/opcodes.h b/reactos/lib/fast486/opcodes.h index 193b38f5996..84c6b2d1418 100644 --- a/reactos/lib/fast486/opcodes.h +++ b/reactos/lib/fast486/opcodes.h @@ -2,7 +2,7 @@ * Fast486 386/486 CPU Emulation Library * opcodes.h * - * Copyright (C) 2014 Aleksandar Andrejevic + * Copyright (C) 2015 Aleksandar Andrejevic * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/reactos/lib/fast486/opgroups.c b/reactos/lib/fast486/opgroups.c index 60e778dc463..ccaab8bfaa0 100644 --- a/reactos/lib/fast486/opgroups.c +++ b/reactos/lib/fast486/opgroups.c @@ -2,7 +2,7 @@ * Fast486 386/486 CPU Emulation Library * opgroups.c * - * Copyright (C) 2014 Aleksandar Andrejevic + * Copyright (C) 2015 Aleksandar Andrejevic * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/reactos/lib/fast486/opgroups.h b/reactos/lib/fast486/opgroups.h index 38eed676af9..40186d4f683 100644 --- a/reactos/lib/fast486/opgroups.h +++ b/reactos/lib/fast486/opgroups.h @@ -2,7 +2,7 @@ * Fast486 386/486 CPU Emulation Library * opgroups.h * - * Copyright (C) 2014 Aleksandar Andrejevic + * Copyright (C) 2015 Aleksandar Andrejevic * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dosfiles.c b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dosfiles.c index a678b190af0..7ccb5c9eb19 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dosfiles.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dosfiles.c @@ -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);