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);