From de17b3603726bd3fdf668b344f47dbf15425ca0f Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sat, 1 Jun 2019 21:22:30 +0200 Subject: [PATCH] [NTOSKRNL] Implement ObSetDirectoryDeviceMap --- ntoskrnl/ob/devicemap.c | 93 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/ntoskrnl/ob/devicemap.c b/ntoskrnl/ob/devicemap.c index 5dfe1994dd8..5d583e9388b 100644 --- a/ntoskrnl/ob/devicemap.c +++ b/ntoskrnl/ob/devicemap.c @@ -149,8 +149,97 @@ NTAPI ObSetDirectoryDeviceMap(OUT PDEVICE_MAP * DeviceMap, IN HANDLE DirectoryHandle) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + POBJECT_DIRECTORY DirectoryObject = NULL; + PDEVICE_MAP LocalMap = NULL, NewDeviceMap = NULL; + NTSTATUS Status; + POBJECT_HEADER ObjectHeader; + POBJECT_HEADER_NAME_INFO HeaderNameInfo; + + Status = ObReferenceObjectByHandle(DirectoryHandle, + DIRECTORY_TRAVERSE, + ObpDirectoryObjectType, + KernelMode, + (PVOID*)&DirectoryObject, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("ObReferenceObjectByHandle() failed (Status 0x%08lx)\n", Status); + return Status; + } + + /* Allocate and initialize a new device map */ + LocalMap = ExAllocatePoolWithTag(PagedPool, + sizeof(*LocalMap), + 'mDbO'); + if (LocalMap == NULL) + { + ObDereferenceObject(DirectoryObject); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Initialize the device map */ + RtlZeroMemory(LocalMap, sizeof(*LocalMap)); + LocalMap->ReferenceCount = 1; + LocalMap->DosDevicesDirectory = DirectoryObject; + + /* Acquire the device map lock */ + KeAcquireGuardedMutex(&ObpDeviceMapLock); + + /* Attach the device map to the directory object */ + if (DirectoryObject->DeviceMap == NULL) + { + DirectoryObject->DeviceMap = LocalMap; + } + else + { + NewDeviceMap = LocalMap; + + /* There's already a device map, + so reuse it */ + LocalMap = DirectoryObject->DeviceMap; + ++LocalMap->ReferenceCount; + } + + /* If current object isn't system one, save system one in current + * device map */ + if (DirectoryObject != ObSystemDeviceMap->DosDevicesDirectory) + { + /* We also need to make the object permanant */ + LocalMap->GlobalDosDevicesDirectory = ObSystemDeviceMap->DosDevicesDirectory; + } + + /* Release the device map lock */ + KeReleaseGuardedMutex(&ObpDeviceMapLock); + + if (DeviceMap != NULL) + { + *DeviceMap = LocalMap; + } + + /* Caller expects us to make the object permanant, so do it! */ + ObjectHeader = OBJECT_TO_OBJECT_HEADER(DirectoryObject); + HeaderNameInfo = ObpReferenceNameInfo(ObjectHeader); + + ObpEnterObjectTypeMutex(ObjectHeader->Type); + if (HeaderNameInfo != NULL && HeaderNameInfo->Directory != NULL) + { + ObjectHeader->Flags |= OB_FLAG_PERMANENT; + } + ObpLeaveObjectTypeMutex(ObjectHeader->Type); + + if (HeaderNameInfo != NULL) + { + ObpDereferenceNameInfo(HeaderNameInfo); + } + + /* Release useless device map if required */ + if (NewDeviceMap != NULL) + { + ObfDereferenceObject(DirectoryObject); + ExFreePoolWithTag(NewDeviceMap, 'mDbO'); + } + + return Status; }