diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h index 471f6e067f4..d518e2e6ba9 100644 --- a/ntoskrnl/include/internal/io.h +++ b/ntoskrnl/include/internal/io.h @@ -538,6 +538,29 @@ typedef enum _SECURITY_DESCRIPTOR_TYPE SystemDefault, } SECURITY_DESCRIPTOR_TYPE, *PSECURITY_DESCRIPTOR_TYPE; +// +// Action types and data for IopQueueDeviceAction() +// +typedef enum _DEVICE_ACTION +{ + DeviceActionInvalidateDeviceRelations, + MaxDeviceAction +} DEVICE_ACTION; + +typedef struct _DEVICE_ACTION_DATA +{ + LIST_ENTRY RequestListEntry; + PDEVICE_OBJECT DeviceObject; + DEVICE_ACTION Action; + union + { + struct + { + DEVICE_RELATION_TYPE Type; + } InvalidateDeviceRelations; + }; +} DEVICE_ACTION_DATA, *PDEVICE_ACTION_DATA; + // // Resource code // @@ -1398,6 +1421,14 @@ IopStoreSystemPartitionInformation(IN PUNICODE_STRING NtSystemPartitionDeviceNam IN PUNICODE_STRING OsLoaderPathName ); +// +// Device action +// +VOID +IopQueueDeviceAction( + _In_ PDEVICE_ACTION_DATA ActionData +); + // // Global I/O Data // diff --git a/ntoskrnl/io/pnpmgr/pnpmgr.c b/ntoskrnl/io/pnpmgr/pnpmgr.c index b08f63eb289..aed457c993d 100644 --- a/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -38,14 +38,8 @@ WORK_QUEUE_ITEM IopDeviceActionWorkItem; BOOLEAN IopDeviceActionInProgress; KSPIN_LOCK IopDeviceActionLock; -typedef struct _DEVICE_ACTION_DATA -{ - LIST_ENTRY RequestListEntry; - PDEVICE_OBJECT DeviceObject; - DEVICE_RELATION_TYPE Type; -} DEVICE_ACTION_DATA, *PDEVICE_ACTION_DATA; - /* FUNCTIONS *****************************************************************/ + NTSTATUS NTAPI IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, @@ -1073,8 +1067,17 @@ IopDeviceActionWorker( DEVICE_ACTION_DATA, RequestListEntry); - IoSynchronousInvalidateDeviceRelations(Data->DeviceObject, - Data->Type); + switch (Data->Action) + { + case DeviceActionInvalidateDeviceRelations: + IoSynchronousInvalidateDeviceRelations(Data->DeviceObject, + Data->InvalidateDeviceRelations.Type); + break; + + default: + DPRINT1("Unimplemented device action %u\n", Data->Action); + break; + } ObDereferenceObject(Data->DeviceObject); ExFreePoolWithTag(Data, TAG_IO); @@ -1084,6 +1087,43 @@ IopDeviceActionWorker( KeReleaseSpinLock(&IopDeviceActionLock, OldIrql); } +VOID +IopQueueDeviceAction( + _In_ PDEVICE_ACTION_DATA ActionData) +{ + PDEVICE_ACTION_DATA Data; + KIRQL OldIrql; + + DPRINT("IopQueueDeviceAction(%p)\n", ActionData); + + Data = ExAllocatePoolWithTag(NonPagedPool, + sizeof(DEVICE_ACTION_DATA), + TAG_IO); + if (!Data) + return; + + ObReferenceObject(ActionData->DeviceObject); + RtlCopyMemory(Data, ActionData, sizeof(DEVICE_ACTION_DATA)); + + DPRINT("Action %u\n", Data->Action); + + KeAcquireSpinLock(&IopDeviceActionLock, &OldIrql); + InsertTailList(&IopDeviceActionRequestList, &Data->RequestListEntry); + if (IopDeviceActionInProgress) + { + KeReleaseSpinLock(&IopDeviceActionLock, OldIrql); + return; + } + IopDeviceActionInProgress = TRUE; + KeReleaseSpinLock(&IopDeviceActionLock, OldIrql); + + ExInitializeWorkItem(&IopDeviceActionWorkItem, + IopDeviceActionWorker, + NULL); + ExQueueWorkItem(&IopDeviceActionWorkItem, + DelayedWorkQueue); +} + NTSTATUS IopGetSystemPowerDeviceObject(PDEVICE_OBJECT *DeviceObject) { @@ -5112,34 +5152,13 @@ IoInvalidateDeviceRelations( IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type) { - PDEVICE_ACTION_DATA Data; - KIRQL OldIrql; + DEVICE_ACTION_DATA ActionData; - Data = ExAllocatePoolWithTag(NonPagedPool, - sizeof(DEVICE_ACTION_DATA), - TAG_IO); - if (!Data) - return; + ActionData.DeviceObject = DeviceObject; + ActionData.Action = DeviceActionInvalidateDeviceRelations; + ActionData.InvalidateDeviceRelations.Type = Type; - ObReferenceObject(DeviceObject); - Data->DeviceObject = DeviceObject; - Data->Type = Type; - - KeAcquireSpinLock(&IopDeviceActionLock, &OldIrql); - InsertTailList(&IopDeviceActionRequestList, &Data->RequestListEntry); - if (IopDeviceActionInProgress) - { - KeReleaseSpinLock(&IopDeviceActionLock, OldIrql); - return; - } - IopDeviceActionInProgress = TRUE; - KeReleaseSpinLock(&IopDeviceActionLock, OldIrql); - - ExInitializeWorkItem(&IopDeviceActionWorkItem, - IopDeviceActionWorker, - NULL); - ExQueueWorkItem(&IopDeviceActionWorkItem, - DelayedWorkQueue); + IopQueueDeviceAction(&ActionData); } /*