[PATCH v3 6/8] user32: Implement RegisterDeviceNotification()

Micah N Gorrell mgorrell at codeweavers.com
Thu Sep 12 13:03:18 CDT 2019


Implement RegisterDeviceNotification() and UnregisterDeviceNotification()
using I_ScRegisterDeviceNotification() and
I_ScUnregisterDeviceNotification() in sechost.dll

Signed-off-by: Micah N Gorrell <mgorrell at codeweavers.com>
---
 dlls/user32/Makefile.in |  2 +-
 dlls/user32/misc.c      | 73 +++++++++++++++++++++++++++++++++++------
 include/winuser.h       |  4 ++-
 3 files changed, 67 insertions(+), 12 deletions(-)

diff --git a/dlls/user32/Makefile.in b/dlls/user32/Makefile.in
index d420dcb45a..bd3660331e 100644
--- a/dlls/user32/Makefile.in
+++ b/dlls/user32/Makefile.in
@@ -1,7 +1,7 @@
 EXTRADEFS = -D_USER32_ -D_WINABLE_
 MODULE    = user32.dll
 IMPORTLIB = user32
-IMPORTS   = gdi32 version advapi32
+IMPORTS   = gdi32 version advapi32 sechost
 EXTRAINCL = $(PNG_CFLAGS)
 DELAYIMPORTS = hid imm32 setupapi usp10
 
diff --git a/dlls/user32/misc.c b/dlls/user32/misc.c
index bed5812a47..17d0b5bcd3 100644
--- a/dlls/user32/misc.c
+++ b/dlls/user32/misc.c
@@ -4,6 +4,7 @@
  * Copyright 1995 Thomas Sandford
  * Copyright 1997 Marcus Meissner
  * Copyright 1998 Turchanov Sergey
+ * Copyright 2019 Micah N Gorrell for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -30,6 +31,7 @@
 #include "wingdi.h"
 #include "controls.h"
 #include "user_private.h"
+#include "winsvc.h"
 
 #include "wine/unicode.h"
 #include "wine/debug.h"
@@ -288,17 +290,39 @@ DWORD WINAPI RegisterTasklist (DWORD x)
     return TRUE;
 }
 
+static DWORD CALLBACK devnotify_window_callback(HANDLE hRecipient, DWORD flags, DEV_BROADCAST_HDR *dbh)
+{
+    SendMessageTimeoutW(hRecipient, WM_DEVICECHANGE, flags,
+        (LPARAM) dbh, SMTO_ABORTIFHUNG, 2000, NULL);
+    return 0;
+}
+
+static DWORD CALLBACK devnotify_service_callback(HANDLE hRecipient, DWORD flags, DEV_BROADCAST_HDR *dbh)
+{
+    FIXME("Support for service handles is not yet implemented!\n");
+    ControlService(hRecipient, SERVICE_CONTROL_DEVICEEVENT, NULL);
+    return 0;
+}
+
+static DWORD CALLBACK devnotify_null_callback(HANDLE hRecipient, DWORD flags, DEV_BROADCAST_HDR *dbh)
+{
+    /* The WM_DEVICECHANGE event is broadcast directly from ntoskrnl.exe so
+     * nothing needs to be done here. */
+    return 0;
+}
 
 /***********************************************************************
  *		RegisterDeviceNotificationA (USER32.@)
  *
  * See RegisterDeviceNotificationW.
  */
-HDEVNOTIFY WINAPI RegisterDeviceNotificationA(HANDLE hnd, LPVOID notifyfilter, DWORD flags)
+HDEVNOTIFY WINAPI RegisterDeviceNotificationA(HANDLE hRecipient, LPVOID pNotificationFilter, DWORD dwFlags)
 {
-    FIXME("(hwnd=%p, filter=%p,flags=0x%08x) returns a fake device notification handle!\n",
-          hnd,notifyfilter,flags );
-    return (HDEVNOTIFY) 0xcafecafe;
+    TRACE("(hwnd=%p, filter=%p,flags=0x%08x)\n",
+        hRecipient,pNotificationFilter,dwFlags);
+    if (pNotificationFilter)
+        FIXME("The notification filter will requires an A->W when filter support is implemented\n");
+    return RegisterDeviceNotificationW(hRecipient, pNotificationFilter, dwFlags);
 }
 
 /***********************************************************************
@@ -326,19 +350,48 @@ HDEVNOTIFY WINAPI RegisterDeviceNotificationA(HANDLE hnd, LPVOID notifyfilter, D
  */
 HDEVNOTIFY WINAPI RegisterDeviceNotificationW(HANDLE hRecipient, LPVOID pNotificationFilter, DWORD dwFlags)
 {
-    FIXME("(hwnd=%p, filter=%p,flags=0x%08x) returns a fake device notification handle!\n",
-          hRecipient,pNotificationFilter,dwFlags );
-    return (HDEVNOTIFY) 0xcafeaffe;
+    DEVICE_NOTIFICATION_DETAILS details;
+
+    TRACE("(hwnd=%p, filter=%p,flags=0x%08x)\n",
+        hRecipient,pNotificationFilter,dwFlags);
+
+    if (dwFlags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES)
+    {
+        dwFlags &= ~DEVICE_NOTIFY_ALL_INTERFACE_CLASSES;
+        pNotificationFilter = NULL;
+    }
+
+    details.hRecipient = hRecipient;
+
+    switch (dwFlags) {
+    case DEVICE_NOTIFY_WINDOW_HANDLE:
+        details.pNotificationCallback = devnotify_window_callback;
+        break;
+
+    case DEVICE_NOTIFY_SERVICE_HANDLE:
+        details.pNotificationCallback = devnotify_service_callback;
+        break;
+
+    default:
+        SetLastError(ERROR_INVALID_FLAGS);
+        return 0;
+    }
+
+    if (!hRecipient)
+        details.pNotificationCallback = devnotify_null_callback;
+
+    return I_ScRegisterDeviceNotification(&details, pNotificationFilter, 0);
 }
 
 /***********************************************************************
  *		UnregisterDeviceNotification (USER32.@)
  *
  */
-BOOL  WINAPI UnregisterDeviceNotification(HDEVNOTIFY hnd)
+BOOL WINAPI UnregisterDeviceNotification(HDEVNOTIFY hnd)
 {
-    FIXME("(handle=%p), STUB!\n", hnd);
-    return TRUE;
+    TRACE("(hnd=%p)\n", hnd);
+
+    return I_ScUnregisterDeviceNotification(hnd);
 }
 
 /***********************************************************************
diff --git a/include/winuser.h b/include/winuser.h
index 51c73d25c2..b5dedc0db0 100644
--- a/include/winuser.h
+++ b/include/winuser.h
@@ -3112,7 +3112,9 @@ typedef struct tagTRACKMOUSEEVENT {
 typedef  PVOID           HDEVNOTIFY;
 typedef  HDEVNOTIFY     *PHDEVNOTIFY;
 
-#define DEVICE_NOTIFY_WINDOW_HANDLE     0x00000000
+#define DEVICE_NOTIFY_WINDOW_HANDLE         0x00000000
+#define DEVICE_NOTIFY_SERVICE_HANDLE        0x00000001
+#define DEVICE_NOTIFY_ALL_INTERFACE_CLASSES 0x00000004
 
 /* used for GetWindowInfo() */
 
-- 
2.23.0




More information about the wine-devel mailing list