[NTOSKRNL] Add support for LUID mappings in ObQueryDeviceMapInformation

This commit is contained in:
Pierre Schweitzer 2019-06-01 17:28:11 +02:00
parent 1074a9aaff
commit 46b90ccb96
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
2 changed files with 114 additions and 10 deletions

View file

@ -292,7 +292,7 @@ ObpSetHandleAttributes(
IN ULONG_PTR Context IN ULONG_PTR Context
); );
VOID NTSTATUS
NTAPI NTAPI
ObQueryDeviceMapInformation( ObQueryDeviceMapInformation(
IN PEPROCESS Process, IN PEPROCESS Process,

View file

@ -143,6 +143,15 @@ ObSetDeviceMap(IN PEPROCESS Process,
} }
PDEVICE_MAP
NTAPI
ObpReferenceDeviceMap(VOID)
{
UNIMPLEMENTED;
return NULL;
}
VOID VOID
NTAPI NTAPI
ObDereferenceDeviceMap(IN PEPROCESS Process) ObDereferenceDeviceMap(IN PEPROCESS Process)
@ -226,30 +235,125 @@ ObInheritDeviceMap(IN PEPROCESS Parent,
} }
VOID NTSTATUS
NTAPI NTAPI
ObQueryDeviceMapInformation(IN PEPROCESS Process, ObQueryDeviceMapInformation(IN PEPROCESS Process,
IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo, IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo,
IN ULONG Flags) IN ULONG Flags)
{ {
PDEVICE_MAP DeviceMap; PDEVICE_MAP DeviceMap = NULL, GlobalDeviceMap;
BOOLEAN Dereference;
PROCESS_DEVICEMAP_INFORMATION MapInfo;
ULONG BitMask, i;
BOOLEAN ReturnAny;
NTSTATUS Status;
/* Validate flags */
if (Flags & ~PROCESS_LUID_DOSDEVICES_ONLY)
{
return STATUS_INVALID_PARAMETER;
}
Dereference = FALSE;
/* Do we want to return anything? */
ReturnAny = ~Flags & PROCESS_LUID_DOSDEVICES_ONLY;
/* If LUID mappings are enabled... */
if (ObpLUIDDeviceMapsEnabled != 0)
{
/* Check for process parameter validness */
if (Process != NULL && Process != PsGetCurrentProcess())
{
return STATUS_INVALID_PARAMETER;
}
/* And get the device map */
DeviceMap = ObpReferenceDeviceMap();
}
/* Acquire the device map lock */ /* Acquire the device map lock */
KeAcquireGuardedMutex(&ObpDeviceMapLock); KeAcquireGuardedMutex(&ObpDeviceMapLock);
/* Get the process device map or the system device map */ /*
DeviceMap = (Process != NULL) ? Process->DeviceMap : ObSystemDeviceMap; * If we had a device map, if because of LUID mappings,
* we'll have to dereference it afterwards
*/
if (DeviceMap != NULL) if (DeviceMap != NULL)
{ {
/* Make a copy */ Dereference = TRUE;
DeviceMapInfo->Query.DriveMap = DeviceMap->DriveMap; }
RtlCopyMemory(DeviceMapInfo->Query.DriveType, else
DeviceMap->DriveType, {
sizeof(DeviceMap->DriveType)); /* Get the process device map or the system device map */
DeviceMap = (Process != NULL) ? Process->DeviceMap : ObSystemDeviceMap;
}
/* Fail if no device map */
if (DeviceMap == NULL)
{
KeReleaseGuardedMutex(&ObpDeviceMapLock);
return STATUS_END_OF_FILE;
}
/* At that point, assume success */
Status = STATUS_SUCCESS;
/* Try to get the global device map if any */
GlobalDeviceMap = DeviceMap;
if (DeviceMap->GlobalDosDevicesDirectory != NULL)
{
if (DeviceMap->GlobalDosDevicesDirectory->DeviceMap != NULL)
{
GlobalDeviceMap = DeviceMap->GlobalDosDevicesDirectory->DeviceMap;
}
}
/* Now, setup our device map info, especially drive types */
MapInfo.Query.DriveMap = DeviceMap->DriveMap;
/* Browse every device */
for (i = 0, BitMask = 1; i < 32; ++i, BitMask *= 2)
{
/* Set the type given current device map */
MapInfo.Query.DriveType[i] = DeviceMap->DriveType[i];
/*
* If device is not existing and we're asked to return
* more than just LUID mapped, get the entry
* from global device map if not remote
*/
if (!(MapInfo.Query.DriveMap & BitMask) && ReturnAny)
{
if (ObpLUIDDeviceMapsEnabled != 0 ||
(GlobalDeviceMap->DriveType[i] != DOSDEVICE_DRIVE_REMOTE &&
GlobalDeviceMap->DriveType[i] != DOSDEVICE_DRIVE_CALCULATE))
{
MapInfo.Query.DriveType[i] = GlobalDeviceMap->DriveType[i];
MapInfo.Query.DriveMap |= BitMask & GlobalDeviceMap->DriveMap;
}
}
} }
/* Release the device map lock */ /* Release the device map lock */
KeReleaseGuardedMutex(&ObpDeviceMapLock); KeReleaseGuardedMutex(&ObpDeviceMapLock);
/* Dereference LUID device map */
if (Dereference)
{
ObfDereferenceDeviceMap(DeviceMap);
}
/* Copy back data */
_SEH2_TRY
{
RtlCopyMemory(DeviceMapInfo, &MapInfo, sizeof(PROCESS_DEVICEMAP_INFORMATION));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
return Status;
} }