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

commit b0a73746cd627846c2a208a168f1c1bd705e8a05
Author:     Eric Kohl <[email protected]>
AuthorDate: Sun Mar 20 14:59:30 2022 +0100
Commit:     Eric Kohl <[email protected]>
CommitDate: Sun Mar 20 14:59:30 2022 +0100

    [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 ([email protected])
- *                   Herv� Poussineau ([email protected])
+ *                   Hervé Poussineau ([email protected])
  *                   Colin Finck ([email protected])
  */
 
@@ -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 <ms-dtyp.idl>
 
+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")
 

Reply via email to