https://git.reactos.org/?p=reactos.git;a=commitdiff;h=57c608680672fcab9461a0...
commit 57c608680672fcab9461a0a88ac5ea283a6d312f Author: Pierre Schweitzer pierre@reactos.org AuthorDate: Sat Jun 1 18:43:38 2019 +0200 Commit: Pierre Schweitzer pierre@reactos.org CommitDate: Sat Jun 1 18:43:38 2019 +0200
[NTOSKRNL] Implement ObpReferenceDeviceMap() --- ntoskrnl/ob/devicemap.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 2 deletions(-)
diff --git a/ntoskrnl/ob/devicemap.c b/ntoskrnl/ob/devicemap.c index 4dcaff1c832..12abcb90595 100644 --- a/ntoskrnl/ob/devicemap.c +++ b/ntoskrnl/ob/devicemap.c @@ -143,12 +143,142 @@ ObSetDeviceMap(IN PEPROCESS Process, }
+NTSTATUS +NTAPI +ObpSetCurrentProcessDeviceMap(VOID) +{ + return STATUS_NOT_IMPLEMENTED; +} + + PDEVICE_MAP NTAPI ObpReferenceDeviceMap(VOID) { - UNIMPLEMENTED; - return NULL; + LUID LogonId; + NTSTATUS Status; + PTOKEN Token = NULL; + PDEVICE_MAP DeviceMap; + PETHREAD CurrentThread; + BOOLEAN LookingForSystem; + LUID SystemLuid = SYSTEM_LUID; + BOOLEAN CopyOnOpen, EffectiveOnly; + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; + + LookingForSystem = FALSE; + + /* If LUID mapping is enable, try to get appropriate device map */ + if (ObpLUIDDeviceMapsEnabled != 0) + { + /* In case of impersonation, we've got a bit of work to do */ + CurrentThread = PsGetCurrentThread(); + if (CurrentThread->ActiveImpersonationInfo) + { + /* Get impersonation token */ + Token = PsReferenceImpersonationToken(CurrentThread, + &CopyOnOpen, + &EffectiveOnly, + &ImpersonationLevel); + /* Get logon LUID */ + if (Token != NULL) + { + Status = SeQueryAuthenticationIdToken(Token, &LogonId); + } + else + { + /* Force failure */ + Status = STATUS_NO_TOKEN; + } + + /* If we got logon LUID */ + if (NT_SUCCESS(Status)) + { + /* + * Check it's not system, system is easy to handle, + * we just need to return ObSystemDeviceMap + */ + if (!RtlEqualLuid(&LogonId, &SystemLuid)) + { + /* Ask Se for the device map */ + Status = SeGetLogonIdDeviceMap(&LogonId, &DeviceMap); + if (NT_SUCCESS(Status)) + { + /* Acquire the device map lock */ + KeAcquireGuardedMutex(&ObpDeviceMapLock); + + /* Reference the device map if any */ + if (DeviceMap != NULL) + { + ++DeviceMap->ReferenceCount; + } + + /* Release the device map lock */ + KeReleaseGuardedMutex(&ObpDeviceMapLock); + + /* If we got the device map, we're done! */ + if (DeviceMap != NULL) + { + ObDereferenceObject(Token); + + return DeviceMap; + } + } + } + else + { + LookingForSystem = TRUE; + } + } + } + + /* + * Fall back case of the LUID mapping, make sure there's a + * a device map attached to the current process + */ + if (PsGetCurrentProcess()->DeviceMap == NULL && + !NT_SUCCESS(ObpSetCurrentProcessDeviceMap())) + { + /* We may have failed after we got impersonation token */ + if (Token != NULL) + { + ObDereferenceObject(Token); + } + + return NULL; + } + } + + /* Acquire the device map lock */ + KeAcquireGuardedMutex(&ObpDeviceMapLock); + + /* If we're looking for system map, use it */ + if (LookingForSystem) + { + DeviceMap = ObSystemDeviceMap; + } + /* Otherwise, use current process device map */ + else + { + DeviceMap = PsGetCurrentProcess()->DeviceMap; + } + + /* If we got one, reference it */ + if (DeviceMap != NULL) + { + ++DeviceMap->ReferenceCount; + } + + /* Release the device map lock */ + KeReleaseGuardedMutex(&ObpDeviceMapLock); + + /* We may have impersonation token (if we failed in impersonation branch) */ + if (Token != NULL) + { + ObDereferenceObject(Token); + } + + /* Return the potentially found device map */ + return DeviceMap; }