From 6790e320bd9378275bbb300552fb82e20a39929a Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Tue, 11 Apr 2017 19:58:05 +0000 Subject: [PATCH] [NTOS:OB] - Move device map code into a separate file. - Create and inherit device maps instead of using a single global device map. svn path=/trunk/; revision=74296 --- reactos/ntoskrnl/include/internal/ob.h | 8 +- reactos/ntoskrnl/ntos.cmake | 1 + reactos/ntoskrnl/ob/devicemap.c | 227 +++++++++++++++++++++++++ reactos/ntoskrnl/ob/obname.c | 106 +----------- 4 files changed, 240 insertions(+), 102 deletions(-) create mode 100644 reactos/ntoskrnl/ob/devicemap.c diff --git a/reactos/ntoskrnl/include/internal/ob.h b/reactos/ntoskrnl/include/internal/ob.h index 84db9092db0..5bfec12ef83 100644 --- a/reactos/ntoskrnl/include/internal/ob.h +++ b/reactos/ntoskrnl/include/internal/ob.h @@ -387,6 +387,12 @@ ObpDeleteObjectType( // // DOS Devices Functions // +NTSTATUS +NTAPI +ObpCreateDeviceMap( + IN HANDLE DirectoryHandle +); + VOID NTAPI ObDereferenceDeviceMap( @@ -396,7 +402,7 @@ ObDereferenceDeviceMap( VOID FASTCALL ObfDereferenceDeviceMap( - IN PVOID DeviceMap + IN PDEVICE_MAP DeviceMap ); VOID diff --git a/reactos/ntoskrnl/ntos.cmake b/reactos/ntoskrnl/ntos.cmake index 5a84fa0437e..9affb1e68a3 100644 --- a/reactos/ntoskrnl/ntos.cmake +++ b/reactos/ntoskrnl/ntos.cmake @@ -225,6 +225,7 @@ list(APPEND SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/mm/region.c ${REACTOS_SOURCE_DIR}/ntoskrnl/mm/rmap.c ${REACTOS_SOURCE_DIR}/ntoskrnl/mm/section.c + ${REACTOS_SOURCE_DIR}/ntoskrnl/ob/devicemap.c ${REACTOS_SOURCE_DIR}/ntoskrnl/ob/obdir.c ${REACTOS_SOURCE_DIR}/ntoskrnl/ob/obhandle.c ${REACTOS_SOURCE_DIR}/ntoskrnl/ob/obinit.c diff --git a/reactos/ntoskrnl/ob/devicemap.c b/reactos/ntoskrnl/ob/devicemap.c new file mode 100644 index 00000000000..d79f7f6b4a1 --- /dev/null +++ b/reactos/ntoskrnl/ob/devicemap.c @@ -0,0 +1,227 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ob/devicemap.c + * PURPOSE: Device map implementation + * PROGRAMMERS: Eric Kohl (eric.kohl@reactos.org) + * Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ***************************************************************/ + +#include +#define NDEBUG +#include + +/* PRIVATE FUNCTIONS ******************************************************/ + +NTSTATUS +NTAPI +ObpCreateDeviceMap(IN HANDLE DirectoryHandle) +{ + POBJECT_DIRECTORY DirectoryObject = NULL; + PDEVICE_MAP DeviceMap = NULL; + NTSTATUS Status; + + Status = ObReferenceObjectByHandle(DirectoryHandle, + DIRECTORY_TRAVERSE, + ObDirectoryType, + KeGetPreviousMode(), + (PVOID*)&DirectoryObject, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("ObReferenceObjectByHandle() failed (Status 0x%08lx)\n", Status); + return Status; + } + + /* Allocate and initialize a new device map */ + DeviceMap = ExAllocatePoolWithTag(NonPagedPool, + sizeof(*DeviceMap), + 'mDbO'); + if (DeviceMap == NULL) + { + ObDereferenceObject(DirectoryObject); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Initialize the device map */ + RtlZeroMemory(DeviceMap, sizeof(*DeviceMap)); + DeviceMap->ReferenceCount = 1; + DeviceMap->DosDevicesDirectory = DirectoryObject; + + /* Acquire the device map lock */ + KeAcquireGuardedMutex(&ObpDeviceMapLock); + + /* Attach the device map to the directory object */ + DirectoryObject->DeviceMap = DeviceMap; + + /* Attach the device map to the process */ + ObSystemDeviceMap = DeviceMap; + PsGetCurrentProcess()->DeviceMap = DeviceMap; + + /* Release the device map lock */ + KeReleaseGuardedMutex(&ObpDeviceMapLock); + + return STATUS_SUCCESS; +} + + +VOID +NTAPI +ObDereferenceDeviceMap(IN PEPROCESS Process) +{ + PDEVICE_MAP DeviceMap; + + DPRINT("ObDereferenceDeviceMap()\n"); + + /* Get the pointer to this process devicemap and reset it + holding the device map lock */ + KeAcquireGuardedMutex(&ObpDeviceMapLock); + DeviceMap = Process->DeviceMap; + Process->DeviceMap = NULL; + KeReleaseGuardedMutex(&ObpDeviceMapLock); + + /* Continue only if there is a device map */ + if (DeviceMap == NULL) + return; + + /* Acquire the device map lock again */ + KeAcquireGuardedMutex(&ObpDeviceMapLock); + + /* Decrement the reference counter */ + DeviceMap->ReferenceCount--; + DPRINT("ReferenceCount: %lu\n", DeviceMap->ReferenceCount); + + /* Leave, if there are still references to this device map */ + if (DeviceMap->ReferenceCount != 0) + { + /* Release the device map lock and leave */ + KeReleaseGuardedMutex(&ObpDeviceMapLock); + return; + } + + /* Nobody is referencing it anymore, unlink the DOS directory */ + DeviceMap->DosDevicesDirectory->DeviceMap = NULL; + + /* Release the device map lock */ + KeReleaseGuardedMutex(&ObpDeviceMapLock); + + /* Dereference the DOS Devices Directory and free the DeviceMap */ + ObDereferenceObject(DeviceMap->DosDevicesDirectory); + ExFreePoolWithTag(DeviceMap, 'mDbO'); +} + + +VOID +FASTCALL +ObfDereferenceDeviceMap(IN PDEVICE_MAP DeviceMap) +{ + DPRINT("ObfDereferenceDeviceMap()\n"); + + /* Acquire the device map lock */ + KeAcquireGuardedMutex(&ObpDeviceMapLock); + + /* Decrement the reference counter */ + DeviceMap->ReferenceCount--; + DPRINT("ReferenceCount: %lu\n", DeviceMap->ReferenceCount); + + /* Leave, if there are still references to this device map */ + if (DeviceMap->ReferenceCount != 0) + { + /* Release the device map lock and leave */ + KeReleaseGuardedMutex(&ObpDeviceMapLock); + return; + } + + /* Nobody is referencing it anymore, unlink the DOS directory */ + DeviceMap->DosDevicesDirectory->DeviceMap = NULL; + + /* Release the devicemap lock */ + KeReleaseGuardedMutex(&ObpDeviceMapLock); + + /* Dereference the DOS Devices Directory and free the Device Map */ + ObDereferenceObject(DeviceMap->DosDevicesDirectory ); + ExFreePoolWithTag(DeviceMap, 'mDbO'); +} + + +VOID +NTAPI +ObInheritDeviceMap(IN PEPROCESS Parent, + IN PEPROCESS Process) +{ + PDEVICE_MAP DeviceMap; + + DPRINT("ObInheritDeviceMap()\n"); + + /* Acquire the device map lock */ + KeAcquireGuardedMutex(&ObpDeviceMapLock); + + /* Get the parent process device map or the system device map */ + DeviceMap = (Parent != NULL) ? Parent->DeviceMap : ObSystemDeviceMap; + if (DeviceMap != NULL) + { + /* Reference the device map and attach it to the new process */ + DeviceMap->ReferenceCount++; + DPRINT("ReferenceCount: %lu\n", DeviceMap->ReferenceCount); + + Process->DeviceMap = DeviceMap; + } + + /* Release the device map lock */ + KeReleaseGuardedMutex(&ObpDeviceMapLock); +} + + +VOID +NTAPI +ObQueryDeviceMapInformation(IN PEPROCESS Process, + IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo) +{ + PDEVICE_MAP DeviceMap; + + /* Acquire the device map lock */ + KeAcquireGuardedMutex(&ObpDeviceMapLock); + + /* Get the process device map or the system device map */ + DeviceMap = (Process != NULL) ? Process->DeviceMap : ObSystemDeviceMap; + if (DeviceMap != NULL) + { + /* Make a copy */ + DeviceMapInfo->Query.DriveMap = DeviceMap->DriveMap; + RtlCopyMemory(DeviceMapInfo->Query.DriveType, + DeviceMap->DriveType, + sizeof(DeviceMap->DriveType)); + } + + /* Release the device map lock */ + KeReleaseGuardedMutex(&ObpDeviceMapLock); +} + + +#if 0 +NTSTATUS +NTAPI +ObIsDosDeviceLocallyMapped( + IN ULONG Index, + OUT PUCHAR DosDeviceState) +{ + /* Check the index */ + if (Index < 1 || Index > 26) + return STATUS_INVALID_PARAMETER; + + /* Acquire the device map lock */ + KeAcquireGuardedMutex(&ObpDeviceMapLock); + + /* Get drive mapping status */ + *DosDeviceState = (ObSystemDeviceMap->DriveMap & (1 << Index)) != 0; + + /* Release the device map lock */ + KeReleaseGuardedMutex(&ObpDeviceMapLock); + + return STATUS_SUCCESS; +} +#endif + +/* EOF */ diff --git a/reactos/ntoskrnl/ob/obname.c b/reactos/ntoskrnl/ob/obname.c index 0a104bf9d23..b978a6bb0a9 100644 --- a/reactos/ntoskrnl/ob/obname.c +++ b/reactos/ntoskrnl/ob/obname.c @@ -153,6 +153,11 @@ ObpCreateDosDevicesDirectory(VOID) ExFreePoolWithTag(DosDevicesSD, TAG_SD); if (!NT_SUCCESS(Status)) return Status; + /* Create the system device map */ + Status = ObpCreateDeviceMap(Handle); + if (!NT_SUCCESS(Status)) + return Status; + /*********************************************\ |*** HACK until we support device mappings ***| |*** Add a symlink \??\ <--> \GLOBAL??\ ***| @@ -230,64 +235,10 @@ ObpCreateDosDevicesDirectory(VOID) &RootName); if (NT_SUCCESS(Status)) NtClose(SymHandle); - /* FIXME: Hack Hack! */ - ObSystemDeviceMap = ExAllocatePoolWithTag(NonPagedPool, - sizeof(*ObSystemDeviceMap), - 'mDbO'); - if (!ObSystemDeviceMap) return STATUS_INSUFFICIENT_RESOURCES; - RtlZeroMemory(ObSystemDeviceMap, sizeof(*ObSystemDeviceMap)); - /* Return status */ return Status; } -VOID -NTAPI -ObDereferenceDeviceMap(IN PEPROCESS Process) -{ - PDEVICE_MAP DeviceMap; - - /* Get the pointer to this process devicemap and reset it - holding devicemap lock */ - KeAcquireGuardedMutex(&ObpDeviceMapLock); - DeviceMap = Process->DeviceMap; - Process->DeviceMap = NULL; - KeReleaseGuardedMutex(&ObpDeviceMapLock); - - /* Continue only if there is a devicemap to dereference */ - if (DeviceMap) - { - KeAcquireGuardedMutex(&ObpDeviceMapLock); - - /* Delete the device map link and dereference it */ - if (--DeviceMap->ReferenceCount) - { - /* Nobody is referencing it anymore, unlink the DOS directory */ - DeviceMap->DosDevicesDirectory->DeviceMap = NULL; - - /* Release the devicemap lock */ - KeReleaseGuardedMutex(&ObpDeviceMapLock); - - /* Dereference the DOS Devices Directory and free the Device Map */ - ObDereferenceObject(DeviceMap->DosDevicesDirectory); - ExFreePool(DeviceMap); - } - else - { - /* Release the devicemap lock */ - KeReleaseGuardedMutex(&ObpDeviceMapLock); - } - } -} - -VOID -NTAPI -ObInheritDeviceMap(IN PEPROCESS Parent, - IN PEPROCESS Process) -{ - /* FIXME: Devicemap Support */ -} - /*++ * @name ObpDeleteNameCheck * @@ -1322,51 +1273,4 @@ ObQueryNameString(IN PVOID Object, return Status; } -VOID -NTAPI -ObQueryDeviceMapInformation(IN PEPROCESS Process, - IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo) -{ - /* - * FIXME: This is an ugly hack for now, to always return the System Device Map - * instead of returning the Process Device Map. Not important yet since we don't use it - */ - - KeAcquireGuardedMutex(&ObpDeviceMapLock); - - /* Make a copy */ - DeviceMapInfo->Query.DriveMap = ObSystemDeviceMap->DriveMap; - RtlCopyMemory(DeviceMapInfo->Query.DriveType, - ObSystemDeviceMap->DriveType, - sizeof(ObSystemDeviceMap->DriveType)); - - KeReleaseGuardedMutex(&ObpDeviceMapLock); -} - -NTSTATUS -NTAPI -ObIsDosDeviceLocallyMapped( - IN ULONG Index, - OUT PUCHAR DosDeviceState) -{ - /* check parameters */ - if (Index < 1 || Index > 26) - { - /* invalid index */ - return STATUS_INVALID_PARAMETER; - } - - /* acquire lock */ - KeAcquireGuardedMutex(&ObpDeviceMapLock); - - /* get drive mapping status */ - *DosDeviceState = (ObSystemDeviceMap->DriveMap & (1 << Index)) != 0; - - /* release lock */ - KeReleaseGuardedMutex(&ObpDeviceMapLock); - - /* done */ - return STATUS_SUCCESS; -} - /* EOF */