[UMPNPMGR] Report device interface arrivals and removals to registered windows

- Other event types are not supported yet.
- Services notification is not supported yet.
This commit is contained in:
Eric Kohl
2025-04-27 17:09:50 +02:00
parent d1aa59982d
commit f8efb5d474
3 changed files with 83 additions and 0 deletions
+50
View File
@@ -118,6 +118,12 @@ VOID
ProcessDeviceClassChangeEvent(
_In_ PPLUGPLAY_EVENT_BLOCK PnpEvent)
{
RPC_STATUS RpcStatus;
PLIST_ENTRY Current;
PNOTIFY_ENTRY pNotifyData;
PDEV_BROADCAST_DEVICEINTERFACE_W pData;
DWORD dwSize;
DPRINT("ProcessDeviceClassChangeEvent(%p)\n", PnpEvent);
DPRINT("SymbolicLink: %S\n", PnpEvent->DeviceClass.SymbolicLinkName);
DPRINT("ClassGuid: {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
@@ -125,6 +131,50 @@ ProcessDeviceClassChangeEvent(
PnpEvent->DeviceClass.ClassGuid.Data4[0], PnpEvent->DeviceClass.ClassGuid.Data4[1], PnpEvent->DeviceClass.ClassGuid.Data4[2],
PnpEvent->DeviceClass.ClassGuid.Data4[3], PnpEvent->DeviceClass.ClassGuid.Data4[4], PnpEvent->DeviceClass.ClassGuid.Data4[5],
PnpEvent->DeviceClass.ClassGuid.Data4[6], PnpEvent->DeviceClass.ClassGuid.Data4[7]);
RtlAcquireResourceShared(&NotificationListLock, TRUE);
Current = NotificationListHead.Flink;
while (Current != &NotificationListHead)
{
pNotifyData = CONTAINING_RECORD(Current, NOTIFY_ENTRY, ListEntry);
if ((pNotifyData->dwType == CLASS_NOTIFICATION) &&
((pNotifyData->ulFlags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES) ||
(UuidEqual(&PnpEvent->DeviceClass.ClassGuid, &pNotifyData->ClassGuid, &RpcStatus))))
{
if ((pNotifyData->ulFlags & DEVICE_NOTIFY_WINDOW_HANDLE) == DEVICE_NOTIFY_WINDOW_HANDLE)
{
dwSize = sizeof(DEV_BROADCAST_DEVICEINTERFACE_W) + wcslen(PnpEvent->DeviceClass.SymbolicLinkName) * sizeof(WCHAR);
pData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
pData->dbcc_size = dwSize;
pData->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
CopyMemory(&pData->dbcc_classguid, &PnpEvent->DeviceClass.ClassGuid, sizeof(GUID));
wcscpy(pData->dbcc_name, PnpEvent->DeviceClass.SymbolicLinkName);
if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_INTERFACE_ARRIVAL, &RpcStatus))
{
DPRINT("Interface arrival: %S\n", PnpEvent->DeviceClass.SymbolicLinkName);
SendMessageW((HANDLE)pNotifyData->hRecipient, WM_DEVICECHANGE, DBT_DEVICEARRIVAL, (LPARAM)pData);
}
else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_INTERFACE_ARRIVAL, &RpcStatus))
{
DPRINT("Interface removal: %S\n", PnpEvent->DeviceClass.SymbolicLinkName);
SendMessageW((HANDLE)pNotifyData->hRecipient, WM_DEVICECHANGE, DBT_DEVICEREMOVECOMPLETE, (LPARAM)pData);
}
HeapFree(GetProcessHeap(), 0, pData);
}
else
{
DPRINT1("Service notification is not implemented yet!\n");
}
}
Current = Current->Flink;
}
RtlReleaseResource(&NotificationListLock);
}
+13
View File
@@ -26,6 +26,7 @@
#include <rtlfuncs.h>
#include <setypes.h>
#include <umpnpmgr/sysguid.h>
#include <wdmguid.h>
#include <cfgmgr32.h>
#include <regstr.h>
#include <userenv.h>
@@ -41,10 +42,21 @@ typedef struct
WCHAR DeviceIds[ANYSIZE_ARRAY];
} DeviceInstallParams;
typedef enum
{
CLASS_NOTIFICATION = 1,
TARGET_NOTIFICATION
} NOTIFICATION_TYPE;
typedef struct
{
LIST_ENTRY ListEntry;
NOTIFICATION_TYPE dwType;
PWSTR pszName;
DWORD_PTR hRecipient;
DWORD ulFlags;
GUID ClassGuid;
} NOTIFY_ENTRY, *PNOTIFY_ENTRY;
/* event.c */
@@ -78,6 +90,7 @@ DeviceInstallThread(
/* rpcserver.c */
extern LIST_ENTRY NotificationListHead;
extern RTL_RESOURCE NotificationListLock;
DWORD
WINAPI
+20
View File
@@ -37,8 +37,10 @@
/* GLOBALS ******************************************************************/
static WCHAR szRootDeviceInstanceID[] = L"HTREE\\ROOT\\0";
LUID LoadDriverPrivilege = {SE_LOAD_DRIVER_PRIVILEGE, 0};
LIST_ENTRY NotificationListHead;
RTL_RESOURCE NotificationListLock;
/* FUNCTIONS *****************************************************************/
@@ -53,6 +55,7 @@ RpcServerThread(LPVOID lpParameter)
DPRINT("RpcServerThread() called\n");
InitializeListHead(&NotificationListHead);
RtlInitializeResource(&NotificationListLock);
#if 0
/* 2k/XP/2k3-compatible protocol sequence/endpoint */
@@ -5051,6 +5054,8 @@ PNP_RegisterNotification(
pNotifyData = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NOTIFY_ENTRY));
if (pNotifyData == NULL)
return CR_OUT_OF_MEMORY;
pNotifyData->dwType = CLASS_NOTIFICATION;
if (pszName != NULL)
{
@@ -5064,8 +5069,20 @@ PNP_RegisterNotification(
}
}
pNotifyData->hRecipient = hRecipient;
pNotifyData->ulFlags = ulFlags;
if ((ulFlags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES) == 0)
{
CopyMemory(&pNotifyData->ClassGuid,
&pBroadcastDeviceInterface->dbcc_classguid,
sizeof(GUID));
}
/* Add the entry to the notification list */
RtlAcquireResourceExclusive(&NotificationListLock, TRUE);
InsertTailList(&NotificationListHead, &pNotifyData->ListEntry);
RtlReleaseResource(&NotificationListLock);
DPRINT("pNotifyData: %p\n", pNotifyData);
*pNotifyHandle = (PNP_NOTIFY_HANDLE)pNotifyData;
@@ -5108,7 +5125,10 @@ PNP_UnregisterNotification(
if (pEntry == NULL)
return CR_INVALID_DATA;
RtlAcquireResourceExclusive(&NotificationListLock, TRUE);
RemoveEntryList(&pEntry->ListEntry);
RtlReleaseResource(&NotificationListLock);
if (pEntry->pszName)
RtlFreeHeap(RtlGetProcessHeap(), 0, pEntry->pszName);
RtlFreeHeap(RtlGetProcessHeap(), 0, pEntry);