https://git.reactos.org/?p=reactos.git;a=commitdiff;h=12a5971b7a31338b5171a37a672751cf7c3fb701

commit 12a5971b7a31338b5171a37a672751cf7c3fb701
Author:     Eric Kohl <[email protected]>
AuthorDate: Mon Nov 27 22:36:05 2023 +0100
Commit:     Eric Kohl <[email protected]>
CommitDate: Mon Nov 27 22:36:52 2023 +0100

    [NTOS:PNP] Queue a device change event on interface enable or disable
---
 ntoskrnl/include/internal/io.h |  6 ++++++
 ntoskrnl/io/iomgr/deviface.c   |  3 ++-
 ntoskrnl/io/pnpmgr/plugplay.c  | 45 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h
index 680e20ef4e0..54a21832815 100644
--- a/ntoskrnl/include/internal/io.h
+++ b/ntoskrnl/include/internal/io.h
@@ -668,6 +668,12 @@ CODE_SEG("INIT")
 NTSTATUS
 IopInitPlugPlayEvents(VOID);
 
+NTSTATUS
+IopQueueDeviceChangeEvent(
+    _In_ const GUID *EventGuid,
+    _In_ const GUID *InterfaceClassGuid,
+    _In_ PUNICODE_STRING SymbolicLinkName);
+
 NTSTATUS
 IopQueueTargetDeviceEvent(
     const GUID *Guid,
diff --git a/ntoskrnl/io/iomgr/deviface.c b/ntoskrnl/io/iomgr/deviface.c
index d640f7087b9..ed81e4407c4 100644
--- a/ntoskrnl/io/iomgr/deviface.c
+++ b/ntoskrnl/io/iomgr/deviface.c
@@ -6,7 +6,7 @@
  *
  * PROGRAMMERS:     Filip Navara ([email protected])
  *                  Matthew Brace ([email protected])
- *                  Herv� Poussineau ([email protected])
+ *                  Hervé Poussineau ([email protected])
  */
 
 /* INCLUDES ******************************************************************/
@@ -1465,6 +1465,7 @@ IoSetDeviceInterfaceState(IN PUNICODE_STRING 
SymbolicLinkName,
     EventGuid = Enable ? &GUID_DEVICE_INTERFACE_ARRIVAL : 
&GUID_DEVICE_INTERFACE_REMOVAL;
 
     PiNotifyDeviceInterfaceChange(EventGuid, &DeviceGuid, SymbolicLinkName);
+    IopQueueDeviceChangeEvent(EventGuid, &DeviceGuid, SymbolicLinkName);
 
     ObDereferenceObject(PhysicalDeviceObject);
     DPRINT("Status %x\n", Status);
diff --git a/ntoskrnl/io/pnpmgr/plugplay.c b/ntoskrnl/io/pnpmgr/plugplay.c
index 9220b30dc9e..3b01ed06a1c 100644
--- a/ntoskrnl/io/pnpmgr/plugplay.c
+++ b/ntoskrnl/io/pnpmgr/plugplay.c
@@ -48,6 +48,51 @@ IopInitPlugPlayEvents(VOID)
     return STATUS_SUCCESS;
 }
 
+NTSTATUS
+IopQueueDeviceChangeEvent(
+    _In_ const GUID *EventGuid,
+    _In_ const GUID *InterfaceClassGuid,
+    _In_ PUNICODE_STRING SymbolicLinkName)
+{
+    PPNP_EVENT_ENTRY EventEntry;
+    UNICODE_STRING Copy;
+    ULONG TotalSize;
+
+    /* Allocate a big enough buffer */
+    Copy.Length = 0;
+    Copy.MaximumLength = SymbolicLinkName->Length + sizeof(UNICODE_NULL);
+    TotalSize =
+        FIELD_OFFSET(PLUGPLAY_EVENT_BLOCK, DeviceClass.SymbolicLinkName) +
+        Copy.MaximumLength;
+
+    EventEntry = ExAllocatePool(NonPagedPool,
+                                TotalSize + FIELD_OFFSET(PNP_EVENT_ENTRY, 
Event));
+    if (!EventEntry)
+        return STATUS_INSUFFICIENT_RESOURCES;
+    RtlZeroMemory(EventEntry, TotalSize + FIELD_OFFSET(PNP_EVENT_ENTRY, 
Event));
+
+    /* Fill the buffer with the event GUID */
+    RtlCopyMemory(&EventEntry->Event.EventGuid, EventGuid, sizeof(GUID));
+    EventEntry->Event.EventCategory = DeviceClassChangeEvent;
+    EventEntry->Event.TotalSize = TotalSize;
+
+    /* Fill the interface class GUID */
+    RtlCopyMemory(&EventEntry->Event.DeviceClass.ClassGuid, 
InterfaceClassGuid, sizeof(GUID));
+
+    /* Fill the symbolic link name */
+    RtlCopyMemory(&EventEntry->Event.DeviceClass.SymbolicLinkName,
+                  SymbolicLinkName->Buffer, SymbolicLinkName->Length);
+    EventEntry->Event.DeviceClass.SymbolicLinkName[SymbolicLinkName->Length / 
sizeof(WCHAR)] = UNICODE_NULL;
+
+    InsertHeadList(&IopPnpEventQueueHead,
+                   &EventEntry->ListEntry);
+    KeSetEvent(&IopPnpNotifyEvent,
+               0,
+               FALSE);
+
+    return STATUS_SUCCESS;
+}
+
 NTSTATUS
 IopQueueTargetDeviceEvent(const GUID *Guid,
                           PUNICODE_STRING DeviceIds)

Reply via email to