https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9a07cde37f710c0be2706…
commit 9a07cde37f710c0be2706448d7a316e0f24b66f1
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sun Mar 1 23:29:23 2020 +0100
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sun Mar 1 23:32:25 2020 +0100
[NTOS:IO] Improve the device action worker
- Improve the device action worker to support more than just a single action
- Move the action queue code from IoInvalidateDeviceRelations to a new function
IopQueueDeviceAction.
---
ntoskrnl/include/internal/io.h | 31 +++++++++++++++
ntoskrnl/io/pnpmgr/pnpmgr.c | 89 +++++++++++++++++++++++++-----------------
2 files changed, 85 insertions(+), 35 deletions(-)
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;
-
- Data = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(DEVICE_ACTION_DATA),
- TAG_IO);
- if (!Data)
- return;
+ DEVICE_ACTION_DATA ActionData;
- ObReferenceObject(DeviceObject);
- Data->DeviceObject = DeviceObject;
- Data->Type = Type;
+ ActionData.DeviceObject = DeviceObject;
+ ActionData.Action = DeviceActionInvalidateDeviceRelations;
+ ActionData.InvalidateDeviceRelations.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);
}
/*