[NTOSKRNL]

- Use the LockQueueIoDatabaseLock spinlock to guard the device list instead of blindly raising the IRQL
- Add missing lock to IopEditDeviceList

svn path=/trunk/; revision=70496
This commit is contained in:
Ged Murphy 2016-01-05 18:58:32 +00:00
parent e77e4e378c
commit f8cbc3e48c

View file

@ -333,6 +333,10 @@ IopEditDeviceList(IN PDRIVER_OBJECT DriverObject,
IN IOP_DEVICE_LIST_OPERATION Type) IN IOP_DEVICE_LIST_OPERATION Type)
{ {
PDEVICE_OBJECT Previous; PDEVICE_OBJECT Previous;
KIRQL OldIrql;
/* Lock the Device list while we edit it */
OldIrql = KeAcquireQueuedSpinLock(LockQueueIoDatabaseLock);
/* Check the type of operation */ /* Check the type of operation */
if (Type == IopRemove) if (Type == IopRemove)
@ -353,7 +357,12 @@ IopEditDeviceList(IN PDRIVER_OBJECT DriverObject,
/* Not this one, keep moving */ /* Not this one, keep moving */
if (!Previous->NextDevice) if (!Previous->NextDevice)
{ {
DPRINT1("Failed to remove PDO %p on driver %wZ (not found)\n", DeviceObject, &DeviceObject->DriverObject->DriverName); DPRINT1("Failed to remove PDO %p on driver %wZ (not found)\n",
DeviceObject,
&DeviceObject->DriverObject->DriverName);
ASSERT(FALSE);
KeReleaseQueuedSpinLock(LockQueueIoDatabaseLock, OldIrql);
return; return;
} }
Previous = Previous->NextDevice; Previous = Previous->NextDevice;
@ -369,6 +378,9 @@ IopEditDeviceList(IN PDRIVER_OBJECT DriverObject,
DeviceObject->NextDevice = DriverObject->DeviceObject; DeviceObject->NextDevice = DriverObject->DeviceObject;
DriverObject->DeviceObject = DeviceObject; DriverObject->DeviceObject = DeviceObject;
} }
/* Release the device list lock */
KeReleaseQueuedSpinLock(LockQueueIoDatabaseLock, OldIrql);
} }
VOID VOID
@ -1090,8 +1102,8 @@ IoEnumerateDeviceObjectList(IN PDRIVER_OBJECT DriverObject,
PDEVICE_OBJECT CurrentDevice = DriverObject->DeviceObject; PDEVICE_OBJECT CurrentDevice = DriverObject->DeviceObject;
KIRQL OldIrql; KIRQL OldIrql;
/* Raise to dispatch level */ /* Lock the Device list while we enumerate it */
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); OldIrql = KeAcquireQueuedSpinLock(LockQueueIoDatabaseLock);
/* Find out how many devices we'll enumerate */ /* Find out how many devices we'll enumerate */
while ((CurrentDevice = CurrentDevice->NextDevice)) ActualDevices++; while ((CurrentDevice = CurrentDevice->NextDevice)) ActualDevices++;
@ -1106,7 +1118,7 @@ IoEnumerateDeviceObjectList(IN PDRIVER_OBJECT DriverObject,
if ((ActualDevices * sizeof(PDEVICE_OBJECT)) > DeviceObjectListSize) if ((ActualDevices * sizeof(PDEVICE_OBJECT)) > DeviceObjectListSize)
{ {
/* Fail because the buffer was too small */ /* Fail because the buffer was too small */
KeLowerIrql(OldIrql); KeReleaseQueuedSpinLock(LockQueueIoDatabaseLock, OldIrql);
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
} }
@ -1129,8 +1141,8 @@ IoEnumerateDeviceObjectList(IN PDRIVER_OBJECT DriverObject,
} }
} }
/* Return back to previous IRQL */ /* Release the device list lock */
KeLowerIrql(OldIrql); KeReleaseQueuedSpinLock(LockQueueIoDatabaseLock, OldIrql);
/* Return the status */ /* Return the status */
return STATUS_SUCCESS; return STATUS_SUCCESS;