[NTOSKRNL] Modify ObpCreateDeviceMap so that it can handle any process

It is now able to set the newly created device map to any
process and will default to current process if none is provided.
It also sets system device map if no process is specified.
It also deferences existing device map in the process if needed.
Finaly, it will make the directory object permanant.
This commit is contained in:
Pierre Schweitzer 2019-06-01 13:35:41 +02:00
parent d5b88ff0ae
commit 933dddeb07
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
3 changed files with 83 additions and 10 deletions

View file

@ -399,9 +399,9 @@ ObReferenceFileObjectForWrite(
//
NTSTATUS
NTAPI
ObpCreateDeviceMap(
IN HANDLE DirectoryHandle
);
ObSetDeviceMap(
IN PEPROCESS Process,
IN HANDLE DirectoryHandle);
VOID
NTAPI

View file

@ -17,11 +17,14 @@
NTSTATUS
NTAPI
ObpCreateDeviceMap(IN HANDLE DirectoryHandle)
ObSetDeviceMap(IN PEPROCESS Process,
IN HANDLE DirectoryHandle)
{
POBJECT_DIRECTORY DirectoryObject = NULL;
PDEVICE_MAP DeviceMap = NULL;
PDEVICE_MAP DeviceMap = NULL, NewDeviceMap = NULL, OldDeviceMap;
NTSTATUS Status;
PEPROCESS WorkProcess;
BOOLEAN MakePermanant = FALSE;
Status = ObReferenceObjectByHandle(DirectoryHandle,
DIRECTORY_TRAVERSE,
@ -36,7 +39,7 @@ ObpCreateDeviceMap(IN HANDLE DirectoryHandle)
}
/* Allocate and initialize a new device map */
DeviceMap = ExAllocatePoolWithTag(NonPagedPool,
DeviceMap = ExAllocatePoolWithTag(PagedPool,
sizeof(*DeviceMap),
'mDbO');
if (DeviceMap == NULL)
@ -54,15 +57,85 @@ ObpCreateDeviceMap(IN HANDLE DirectoryHandle)
KeAcquireGuardedMutex(&ObpDeviceMapLock);
/* Attach the device map to the directory object */
DirectoryObject->DeviceMap = DeviceMap;
if (DirectoryObject->DeviceMap == NULL)
{
DirectoryObject->DeviceMap = DeviceMap;
}
else
{
NewDeviceMap = DeviceMap;
/* There's already a device map,
so reuse it */
DeviceMap = DirectoryObject->DeviceMap;
++DeviceMap->ReferenceCount;
}
/* Caller gave a process, use it */
if (Process != NULL)
{
WorkProcess = Process;
}
/* If no process given, use current and
* set system device map */
else
{
WorkProcess = PsGetCurrentProcess();
ObSystemDeviceMap = DeviceMap;
}
/* 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 */
DeviceMap->GlobalDosDevicesDirectory = ObSystemDeviceMap->DosDevicesDirectory;
MakePermanant = TRUE;
}
/* Save old process device map */
OldDeviceMap = WorkProcess->DeviceMap;
/* Attach the device map to the process */
ObSystemDeviceMap = DeviceMap;
PsGetCurrentProcess()->DeviceMap = DeviceMap;
WorkProcess->DeviceMap = DeviceMap;
/* Release the device map lock */
KeReleaseGuardedMutex(&ObpDeviceMapLock);
/* If we have to make the object permamant, do it now */
if (MakePermanant)
{
POBJECT_HEADER ObjectHeader;
POBJECT_HEADER_NAME_INFO HeaderNameInfo;
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');
}
/* And dereference previous process device map */
if (OldDeviceMap != NULL)
{
ObfDereferenceDeviceMap(OldDeviceMap);
}
return STATUS_SUCCESS;
}

View file

@ -173,7 +173,7 @@ ObpCreateDosDevicesDirectory(VOID)
goto done;
/* Create the system device map */
Status = ObpCreateDeviceMap(Handle);
Status = ObSetDeviceMap(NULL, Handle);
if (!NT_SUCCESS(Status))
goto done;