[UMPNPMGR][SETUPAPI] Fix notification handles in PNP_RegisterNotification and PNP_UnregisterNotification

- Notification handles must be context handles
- Register and unregister notification targets
This commit is contained in:
Eric Kohl 2022-03-20 14:59:30 +01:00
parent d4a05ad7aa
commit b0a73746cd
4 changed files with 77 additions and 31 deletions

View file

@ -4,7 +4,7 @@
* FILE: base/services/umpnpmgr/install.c * FILE: base/services/umpnpmgr/install.c
* PURPOSE: Device installer * PURPOSE: Device installer
* PROGRAMMER: Eric Kohl (eric.kohl@reactos.org) * PROGRAMMER: Eric Kohl (eric.kohl@reactos.org)
* Hervé Poussineau (hpoussin@reactos.org) * Hervé Poussineau (hpoussin@reactos.org)
* Colin Finck (colin@reactos.org) * Colin Finck (colin@reactos.org)
*/ */
@ -39,6 +39,12 @@ typedef struct
WCHAR DeviceIds[ANYSIZE_ARRAY]; WCHAR DeviceIds[ANYSIZE_ARRAY];
} DeviceInstallParams; } DeviceInstallParams;
typedef struct
{
LIST_ENTRY ListEntry;
PWSTR pszName;
} NOTIFY_ENTRY, *PNOTIFY_ENTRY;
/* install.c */ /* install.c */
extern HANDLE hUserToken; extern HANDLE hUserToken;

View file

@ -38,6 +38,7 @@
static WCHAR szRootDeviceInstanceID[] = L"HTREE\\ROOT\\0"; static WCHAR szRootDeviceInstanceID[] = L"HTREE\\ROOT\\0";
LIST_ENTRY NotificationListHead;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -51,6 +52,8 @@ RpcServerThread(LPVOID lpParameter)
DPRINT("RpcServerThread() called\n"); DPRINT("RpcServerThread() called\n");
InitializeListHead(&NotificationListHead);
#if 0 #if 0
/* 2k/XP/2k3-compatible protocol sequence/endpoint */ /* 2k/XP/2k3-compatible protocol sequence/endpoint */
Status = RpcServerUseProtseqEpW(L"ncacn_np", 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 **********************************************************/ /* PUBLIC FUNCTIONS **********************************************************/
/* Function 0 */ /* Function 0 */
@ -4461,22 +4473,24 @@ PNP_RegisterNotification(
BYTE *pNotificationFilter, BYTE *pNotificationFilter,
DWORD ulNotificationFilterSize, DWORD ulNotificationFilterSize,
DWORD ulFlags, DWORD ulFlags,
DWORD *pulNotify, PNP_NOTIFY_HANDLE *pNotifyHandle,
DWORD ulUnknown8, DWORD ulUnknown8,
DWORD *pulUnknown9) DWORD *pulUnknown9)
{ {
PDEV_BROADCAST_DEVICEINTERFACE_W pBroadcastDeviceInterface; PDEV_BROADCAST_DEVICEINTERFACE_W pBroadcastDeviceInterface;
PDEV_BROADCAST_HANDLE pBroadcastDeviceHandle; PDEV_BROADCAST_HANDLE pBroadcastDeviceHandle;
#if 0 PNOTIFY_ENTRY pNotifyData = NULL;
PNOTIFY_DATA pNotifyData;
#endif
DPRINT1("PNP_RegisterNotification(%p %lx '%S' %p %lu 0x%lx %p %lx %p)\n", DPRINT1("PNP_RegisterNotification(%p %lx '%S' %p %lu 0x%lx %p %lx %p)\n",
hBinding, ulUnknown2, pszName, pNotificationFilter, 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 || if (pNotificationFilter == NULL ||
pulNotify == NULL ||
pulUnknown9 == NULL) pulUnknown9 == NULL)
return CR_INVALID_POINTER; return CR_INVALID_POINTER;
@ -4495,6 +4509,28 @@ PNP_RegisterNotification(
if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_DEVICEINTERFACE_W)) || if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_DEVICEINTERFACE_W)) ||
(pBroadcastDeviceInterface->dbcc_size < sizeof(DEV_BROADCAST_DEVICEINTERFACE_W))) (pBroadcastDeviceInterface->dbcc_size < sizeof(DEV_BROADCAST_DEVICEINTERFACE_W)))
return CR_INVALID_DATA; 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) else if (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype == DBT_DEVTYP_HANDLE)
{ {
@ -4514,17 +4550,6 @@ PNP_RegisterNotification(
return CR_INVALID_DATA; 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; return CR_SUCCESS;
} }
@ -4534,15 +4559,22 @@ DWORD
WINAPI WINAPI
PNP_UnregisterNotification( PNP_UnregisterNotification(
handle_t hBinding, handle_t hBinding,
DWORD ulNotify) PNP_NOTIFY_HANDLE *pNotifyHandle)
{ {
DPRINT1("PNP_UnregisterNotification(%p 0x%lx)\n", PNOTIFY_ENTRY pEntry;
hBinding, ulNotify);
#if 0 DPRINT1("PNP_UnregisterNotification(%p %p)\n",
UNIMPLEMENTED; hBinding, pNotifyHandle);
return CR_CALL_NOT_IMPLEMENTED;
#endif 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; return CR_SUCCESS;
} }

View file

@ -74,7 +74,7 @@ typedef struct _LOG_CONF_INFO
typedef struct _NOTIFY_DATA typedef struct _NOTIFY_DATA
{ {
ULONG ulMagic; ULONG ulMagic;
ULONG ulNotifyData; PVOID hNotifyHandle;
} NOTIFY_DATA, *PNOTIFY_DATA; } NOTIFY_DATA, *PNOTIFY_DATA;
#define NOTIFY_MAGIC 0x44556677 #define NOTIFY_MAGIC 0x44556677
@ -634,6 +634,7 @@ CMP_RegisterNotification(
return CR_OUT_OF_MEMORY; return CR_OUT_OF_MEMORY;
pNotifyData->ulMagic = NOTIFY_MAGIC; pNotifyData->ulMagic = NOTIFY_MAGIC;
pNotifyData->hNotifyHandle = NULL;
if ((ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_WINDOW_HANDLE) if ((ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_WINDOW_HANDLE)
{ {
@ -674,7 +675,7 @@ CMP_RegisterNotification(
(BYTE*)lpvNotificationFilter, (BYTE*)lpvNotificationFilter,
((DEV_BROADCAST_HDR*)lpvNotificationFilter)->dbch_size, ((DEV_BROADCAST_HDR*)lpvNotificationFilter)->dbch_size,
ulFlags, ulFlags,
&pNotifyData->ulNotifyData, &pNotifyData->hNotifyHandle,
GetCurrentProcessId(), GetCurrentProcessId(),
&ulUnknown9); /* ??? */ &ulUnknown9); /* ??? */
} }
@ -686,11 +687,12 @@ CMP_RegisterNotification(
if (ret == CR_SUCCESS) if (ret == CR_SUCCESS)
{ {
TRACE("hNotifyHandle: %p\n", pNotifyData->hNotifyHandle);
*phDevNotify = (HDEVNOTIFY)pNotifyData; *phDevNotify = (HDEVNOTIFY)pNotifyData;
} }
else else
{ {
if (pNotifyData != NULL) if (pNotifyData->hNotifyHandle == NULL)
HeapFree(GetProcessHeap(), 0, pNotifyData); HeapFree(GetProcessHeap(), 0, pNotifyData);
*phDevNotify = (HDEVNOTIFY)NULL; *phDevNotify = (HDEVNOTIFY)NULL;
@ -774,7 +776,7 @@ CMP_UnregisterNotification(
RpcTryExcept RpcTryExcept
{ {
ret = PNP_UnregisterNotification(BindingHandle, ret = PNP_UnregisterNotification(BindingHandle,
pNotifyData->ulNotifyData); &pNotifyData->hNotifyHandle);
} }
RpcExcept(EXCEPTION_EXECUTE_HANDLER) RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{ {
@ -783,7 +785,10 @@ CMP_UnregisterNotification(
RpcEndExcept; RpcEndExcept;
if (ret == CR_SUCCESS) if (ret == CR_SUCCESS)
{
pNotifyData->hNotifyHandle = NULL;
HeapFree(GetProcessHeap(), 0, pNotifyData); HeapFree(GetProcessHeap(), 0, pNotifyData);
}
return ret; return ret;
} }

View file

@ -4,6 +4,9 @@
#include <ms-dtyp.idl> #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_STRING_LEN = 32767;
const unsigned long PNP_MAX_DEVICE_ID_LEN = 200; const unsigned long PNP_MAX_DEVICE_ID_LEN = 200;
const unsigned long PNP_MAX_GUID_STRING_LEN = 39; const unsigned long PNP_MAX_GUID_STRING_LEN = 39;
@ -880,7 +883,7 @@ interface pnp
[in, size_is(ulNotificationFilterSize)] BYTE *pNotificationFilter, [in, size_is(ulNotificationFilterSize)] BYTE *pNotificationFilter,
[in] DWORD ulNotificationFilterSize, [in] DWORD ulNotificationFilterSize,
[in] DWORD ulFlags, [in] DWORD ulFlags,
[out] DWORD *pulNotifyData, [out] PPNP_NOTIFY_HANDLE pNotifyHandle,
[in] DWORD ulProcessId, [in] DWORD ulProcessId,
[in] DWORD *pulUnknown9); [in] DWORD *pulUnknown9);
@ -889,7 +892,7 @@ interface pnp
__stdcall __stdcall
PNP_UnregisterNotification( PNP_UnregisterNotification(
[in] handle_t hBinding, [in] handle_t hBinding,
[in] DWORD ulNotifyData); [in, out] PPNP_NOTIFY_HANDLE pNotifyHandle);
cpp_quote("#if _WIN32_WINNT >= 0x0501") cpp_quote("#if _WIN32_WINNT >= 0x0501")