From 12a5971b7a31338b5171a37a672751cf7c3fb701 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 27 Nov 2023 22:36:05 +0100 Subject: [PATCH] [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 (xnavara@volny.cz) * Matthew Brace (ismarc@austin.rr.com) - * Hervé Poussineau (hpoussin@reactos.org) + * HervĂ© Poussineau (hpoussin@reactos.org) */ /* 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)