https://git.reactos.org/?p=reactos.git;a=commitdiff;h=933dddeb075583e7584ff…
commit 933dddeb075583e7584ff4bb8644ae4fb6a31d68
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Sat Jun 1 13:35:41 2019 +0200
Commit: Pierre Schweitzer <pierre(a)reactos.org>
CommitDate: Sat Jun 1 13:35:41 2019 +0200
[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.
---
ntoskrnl/include/internal/ob.h | 6 +--
ntoskrnl/ob/devicemap.c | 85 +++++++++++++++++++++++++++++++++++++++---
ntoskrnl/ob/obname.c | 2 +-
3 files changed, 83 insertions(+), 10 deletions(-)
diff --git a/ntoskrnl/include/internal/ob.h b/ntoskrnl/include/internal/ob.h
index ce8c5a0dc75..b2d7037d9dc 100644
--- a/ntoskrnl/include/internal/ob.h
+++ b/ntoskrnl/include/internal/ob.h
@@ -399,9 +399,9 @@ ObReferenceFileObjectForWrite(
//
NTSTATUS
NTAPI
-ObpCreateDeviceMap(
- IN HANDLE DirectoryHandle
-);
+ObSetDeviceMap(
+ IN PEPROCESS Process,
+ IN HANDLE DirectoryHandle);
VOID
NTAPI
diff --git a/ntoskrnl/ob/devicemap.c b/ntoskrnl/ob/devicemap.c
index 32f45fa4a64..c79838bbabd 100644
--- a/ntoskrnl/ob/devicemap.c
+++ b/ntoskrnl/ob/devicemap.c
@@ -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;
}
diff --git a/ntoskrnl/ob/obname.c b/ntoskrnl/ob/obname.c
index f9ccb914022..6c996132d87 100644
--- a/ntoskrnl/ob/obname.c
+++ b/ntoskrnl/ob/obname.c
@@ -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;