From b0a73746cd627846c2a208a168f1c1bd705e8a05 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 20 Mar 2022 14:59:30 +0100 Subject: [PATCH] [UMPNPMGR][SETUPAPI] Fix notification handles in PNP_RegisterNotification and PNP_UnregisterNotification - Notification handles must be context handles - Register and unregister notification targets --- base/services/umpnpmgr/precomp.h | 8 ++- base/services/umpnpmgr/rpcserver.c | 80 +++++++++++++++++++++--------- dll/win32/setupapi/cfgmgr.c | 13 +++-- sdk/include/reactos/idl/pnp.idl | 7 ++- 4 files changed, 77 insertions(+), 31 deletions(-) diff --git a/base/services/umpnpmgr/precomp.h b/base/services/umpnpmgr/precomp.h index 82035203441..7977db7b568 100644 --- a/base/services/umpnpmgr/precomp.h +++ b/base/services/umpnpmgr/precomp.h @@ -4,7 +4,7 @@ * FILE: base/services/umpnpmgr/install.c * PURPOSE: Device installer * PROGRAMMER: Eric Kohl (eric.kohl@reactos.org) - * Hervé Poussineau (hpoussin@reactos.org) + * HervĂ© Poussineau (hpoussin@reactos.org) * Colin Finck (colin@reactos.org) */ @@ -39,6 +39,12 @@ typedef struct WCHAR DeviceIds[ANYSIZE_ARRAY]; } DeviceInstallParams; +typedef struct +{ + LIST_ENTRY ListEntry; + PWSTR pszName; +} NOTIFY_ENTRY, *PNOTIFY_ENTRY; + /* install.c */ extern HANDLE hUserToken; diff --git a/base/services/umpnpmgr/rpcserver.c b/base/services/umpnpmgr/rpcserver.c index 95f69db2470..34bdf848966 100644 --- a/base/services/umpnpmgr/rpcserver.c +++ b/base/services/umpnpmgr/rpcserver.c @@ -38,6 +38,7 @@ static WCHAR szRootDeviceInstanceID[] = L"HTREE\\ROOT\\0"; +LIST_ENTRY NotificationListHead; /* FUNCTIONS *****************************************************************/ @@ -51,6 +52,8 @@ RpcServerThread(LPVOID lpParameter) DPRINT("RpcServerThread() called\n"); + InitializeListHead(&NotificationListHead); + #if 0 /* 2k/XP/2k3-compatible protocol sequence/endpoint */ Status = RpcServerUseProtseqEpW(L"ncacn_np", @@ -535,6 +538,15 @@ GetConfigurationData( } +VOID +__RPC_USER +PNP_NOTIFY_HANDLE_rundown( + PNP_NOTIFY_HANDLE pHandle) +{ + DPRINT1("PNP_NOTIFY_HANDLE_rundown(%p)\n", pHandle); +} + + /* PUBLIC FUNCTIONS **********************************************************/ /* Function 0 */ @@ -4461,22 +4473,24 @@ PNP_RegisterNotification( BYTE *pNotificationFilter, DWORD ulNotificationFilterSize, DWORD ulFlags, - DWORD *pulNotify, + PNP_NOTIFY_HANDLE *pNotifyHandle, DWORD ulUnknown8, DWORD *pulUnknown9) { PDEV_BROADCAST_DEVICEINTERFACE_W pBroadcastDeviceInterface; PDEV_BROADCAST_HANDLE pBroadcastDeviceHandle; -#if 0 - PNOTIFY_DATA pNotifyData; -#endif + PNOTIFY_ENTRY pNotifyData = NULL; DPRINT1("PNP_RegisterNotification(%p %lx '%S' %p %lu 0x%lx %p %lx %p)\n", hBinding, ulUnknown2, pszName, pNotificationFilter, - ulNotificationFilterSize, ulFlags, pulNotify, ulUnknown8, pulUnknown9); + ulNotificationFilterSize, ulFlags, pNotifyHandle, ulUnknown8, pulUnknown9); + + if (pNotifyHandle == NULL) + return CR_INVALID_POINTER; + + *pNotifyHandle = NULL; if (pNotificationFilter == NULL || - pulNotify == NULL || pulUnknown9 == NULL) return CR_INVALID_POINTER; @@ -4495,6 +4509,28 @@ PNP_RegisterNotification( if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_DEVICEINTERFACE_W)) || (pBroadcastDeviceInterface->dbcc_size < sizeof(DEV_BROADCAST_DEVICEINTERFACE_W))) return CR_INVALID_DATA; + + pNotifyData = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NOTIFY_ENTRY)); + if (pNotifyData == NULL) + return CR_OUT_OF_MEMORY; + + if (pszName != NULL) + { + pNotifyData->pszName = RtlAllocateHeap(GetProcessHeap(), + HEAP_ZERO_MEMORY, + (wcslen(pszName) + 1) * sizeof(WCHAR)); + if (pNotifyData->pszName == NULL) + { + RtlFreeHeap(GetProcessHeap(), 0, pNotifyData); + return CR_OUT_OF_MEMORY; + } + } + + /* Add the entry to the notification list */ + InsertTailList(&NotificationListHead, &pNotifyData->ListEntry); + + DPRINT("pNotifyData: %p\n", pNotifyData); + *pNotifyHandle = (PNP_NOTIFY_HANDLE)pNotifyData; } else if (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype == DBT_DEVTYP_HANDLE) { @@ -4514,17 +4550,6 @@ PNP_RegisterNotification( return CR_INVALID_DATA; } - -#if 0 - pNotifyData = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NOTIFY_DATA)); - if (pNotifyData == NULL) - return CR_OUT_OF_MEMORY; - - *pulNotify = (DWORD)pNotifyData; -#endif - - *pulNotify = 1; - return CR_SUCCESS; } @@ -4534,15 +4559,22 @@ DWORD WINAPI PNP_UnregisterNotification( handle_t hBinding, - DWORD ulNotify) + PNP_NOTIFY_HANDLE *pNotifyHandle) { - DPRINT1("PNP_UnregisterNotification(%p 0x%lx)\n", - hBinding, ulNotify); + PNOTIFY_ENTRY pEntry; -#if 0 - UNIMPLEMENTED; - return CR_CALL_NOT_IMPLEMENTED; -#endif + DPRINT1("PNP_UnregisterNotification(%p %p)\n", + hBinding, pNotifyHandle); + + pEntry = (PNOTIFY_ENTRY)*pNotifyHandle; + if (pEntry == NULL) + return CR_INVALID_DATA; + + RemoveEntryList(&pEntry->ListEntry); + if (pEntry->pszName) + RtlFreeHeap(RtlGetProcessHeap(), 0, pEntry->pszName); + RtlFreeHeap(RtlGetProcessHeap(), 0, pEntry); + *pNotifyHandle = NULL; return CR_SUCCESS; } diff --git a/dll/win32/setupapi/cfgmgr.c b/dll/win32/setupapi/cfgmgr.c index b6827bc6925..e411c887f75 100644 --- a/dll/win32/setupapi/cfgmgr.c +++ b/dll/win32/setupapi/cfgmgr.c @@ -74,7 +74,7 @@ typedef struct _LOG_CONF_INFO typedef struct _NOTIFY_DATA { ULONG ulMagic; - ULONG ulNotifyData; + PVOID hNotifyHandle; } NOTIFY_DATA, *PNOTIFY_DATA; #define NOTIFY_MAGIC 0x44556677 @@ -634,6 +634,7 @@ CMP_RegisterNotification( return CR_OUT_OF_MEMORY; pNotifyData->ulMagic = NOTIFY_MAGIC; + pNotifyData->hNotifyHandle = NULL; if ((ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_WINDOW_HANDLE) { @@ -674,7 +675,7 @@ CMP_RegisterNotification( (BYTE*)lpvNotificationFilter, ((DEV_BROADCAST_HDR*)lpvNotificationFilter)->dbch_size, ulFlags, - &pNotifyData->ulNotifyData, + &pNotifyData->hNotifyHandle, GetCurrentProcessId(), &ulUnknown9); /* ??? */ } @@ -686,11 +687,12 @@ CMP_RegisterNotification( if (ret == CR_SUCCESS) { + TRACE("hNotifyHandle: %p\n", pNotifyData->hNotifyHandle); *phDevNotify = (HDEVNOTIFY)pNotifyData; } else { - if (pNotifyData != NULL) + if (pNotifyData->hNotifyHandle == NULL) HeapFree(GetProcessHeap(), 0, pNotifyData); *phDevNotify = (HDEVNOTIFY)NULL; @@ -774,7 +776,7 @@ CMP_UnregisterNotification( RpcTryExcept { ret = PNP_UnregisterNotification(BindingHandle, - pNotifyData->ulNotifyData); + &pNotifyData->hNotifyHandle); } RpcExcept(EXCEPTION_EXECUTE_HANDLER) { @@ -783,7 +785,10 @@ CMP_UnregisterNotification( RpcEndExcept; if (ret == CR_SUCCESS) + { + pNotifyData->hNotifyHandle = NULL; HeapFree(GetProcessHeap(), 0, pNotifyData); + } return ret; } diff --git a/sdk/include/reactos/idl/pnp.idl b/sdk/include/reactos/idl/pnp.idl index b3bcc221a49..f56b932120e 100644 --- a/sdk/include/reactos/idl/pnp.idl +++ b/sdk/include/reactos/idl/pnp.idl @@ -4,6 +4,9 @@ #include +typedef [context_handle] void *PNP_NOTIFY_HANDLE; +typedef PNP_NOTIFY_HANDLE *PPNP_NOTIFY_HANDLE; + const unsigned long PNP_MAX_STRING_LEN = 32767; const unsigned long PNP_MAX_DEVICE_ID_LEN = 200; const unsigned long PNP_MAX_GUID_STRING_LEN = 39; @@ -880,7 +883,7 @@ interface pnp [in, size_is(ulNotificationFilterSize)] BYTE *pNotificationFilter, [in] DWORD ulNotificationFilterSize, [in] DWORD ulFlags, - [out] DWORD *pulNotifyData, + [out] PPNP_NOTIFY_HANDLE pNotifyHandle, [in] DWORD ulProcessId, [in] DWORD *pulUnknown9); @@ -889,7 +892,7 @@ interface pnp __stdcall PNP_UnregisterNotification( [in] handle_t hBinding, - [in] DWORD ulNotifyData); + [in, out] PPNP_NOTIFY_HANDLE pNotifyHandle); cpp_quote("#if _WIN32_WINNT >= 0x0501")