[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
This commit is contained in:
Eric Kohl 2017-04-11 19:58:05 +00:00
parent 6ca2243552
commit 6790e320bd
4 changed files with 240 additions and 102 deletions

View file

@ -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

View file

@ -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

View file

@ -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 <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
/* 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 */

View file

@ -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 */