[PATCH 1/4] user32: Add a filter member to device_notification_details.

Rémi Bernon rbernon at codeweavers.com
Fri Jan 28 03:02:29 CST 2022


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/dinput/tests/hotplug.c | 24 -----------------------
 dlls/sechost/service.c      |  5 +++++
 dlls/user32/input.c         | 39 ++++++++++++++++++++++++++++++++++++-
 3 files changed, 43 insertions(+), 25 deletions(-)

diff --git a/dlls/dinput/tests/hotplug.c b/dlls/dinput/tests/hotplug.c
index d271d9bc1db..5cb8358e3a9 100644
--- a/dlls/dinput/tests/hotplug.c
+++ b/dlls/dinput/tests/hotplug.c
@@ -252,87 +252,63 @@ static void test_RegisterDeviceNotification(void)
 
     SetLastError( 0xdeadbeef );
     devnotify = RegisterDeviceNotificationA( NULL, NULL, 0 );
-    todo_wine
     ok( !devnotify, "RegisterDeviceNotificationA succeeded\n" );
-    todo_wine
     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %u\n", GetLastError() );
-    if (devnotify) UnregisterDeviceNotification( devnotify );
 
     SetLastError( 0xdeadbeef );
     devnotify = RegisterDeviceNotificationA( (HWND)0xdeadbeef, NULL, 0 );
-    todo_wine
     ok( !devnotify, "RegisterDeviceNotificationA succeeded\n" );
-    todo_wine
     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %u\n", GetLastError() );
-    if (devnotify) UnregisterDeviceNotification( devnotify );
 
     SetLastError( 0xdeadbeef );
     devnotify = RegisterDeviceNotificationA( hwnd, NULL, 2 );
-    todo_wine
     ok( !devnotify, "RegisterDeviceNotificationA succeeded\n" );
-    todo_wine
     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %u\n", GetLastError() );
-    if (devnotify) UnregisterDeviceNotification( devnotify );
 
     SetLastError( 0xdeadbeef );
     memset( header, 0, sizeof(DEV_BROADCAST_OEM) );
     header->dbch_size = sizeof(DEV_BROADCAST_OEM);
     header->dbch_devicetype = DBT_DEVTYP_OEM;
     devnotify = RegisterDeviceNotificationA( hwnd, header, 0 );
-    todo_wine
     ok( !devnotify, "RegisterDeviceNotificationA succeeded\n" );
-    todo_wine
     ok( GetLastError() == ERROR_INVALID_DATA || GetLastError() == ERROR_SERVICE_SPECIFIC_ERROR,
         "got error %u\n", GetLastError() );
-    if (devnotify) UnregisterDeviceNotification( devnotify );
 
     SetLastError( 0xdeadbeef );
     memset( header, 0, sizeof(DEV_BROADCAST_DEVNODE) );
     header->dbch_size = sizeof(DEV_BROADCAST_DEVNODE);
     header->dbch_devicetype = DBT_DEVTYP_DEVNODE;
     devnotify = RegisterDeviceNotificationA( hwnd, header, 0 );
-    todo_wine
     ok( !devnotify, "RegisterDeviceNotificationA succeeded\n" );
-    todo_wine
     ok( GetLastError() == ERROR_INVALID_DATA || GetLastError() == ERROR_SERVICE_SPECIFIC_ERROR,
         "got error %u\n", GetLastError() );
-    if (devnotify) UnregisterDeviceNotification( devnotify );
 
     SetLastError( 0xdeadbeef );
     memset( header, 0, sizeof(DEV_BROADCAST_VOLUME) );
     header->dbch_size = sizeof(DEV_BROADCAST_VOLUME);
     header->dbch_devicetype = DBT_DEVTYP_VOLUME;
     devnotify = RegisterDeviceNotificationA( hwnd, header, 0 );
-    todo_wine
     ok( !devnotify, "RegisterDeviceNotificationA succeeded\n" );
-    todo_wine
     ok( GetLastError() == ERROR_INVALID_DATA || GetLastError() == ERROR_SERVICE_SPECIFIC_ERROR,
         "got error %u\n", GetLastError() );
-    if (devnotify) UnregisterDeviceNotification( devnotify );
 
     SetLastError( 0xdeadbeef );
     memset( header, 0, sizeof(DEV_BROADCAST_PORT_A) );
     header->dbch_size = sizeof(DEV_BROADCAST_PORT_A);
     header->dbch_devicetype = DBT_DEVTYP_PORT;
     devnotify = RegisterDeviceNotificationA( hwnd, header, 0 );
-    todo_wine
     ok( !devnotify, "RegisterDeviceNotificationA succeeded\n" );
-    todo_wine
     ok( GetLastError() == ERROR_INVALID_DATA || GetLastError() == ERROR_SERVICE_SPECIFIC_ERROR,
         "got error %u\n", GetLastError() );
-    if (devnotify) UnregisterDeviceNotification( devnotify );
 
     SetLastError( 0xdeadbeef );
     memset( header, 0, sizeof(DEV_BROADCAST_NET) );
     header->dbch_size = sizeof(DEV_BROADCAST_NET);
     header->dbch_devicetype = DBT_DEVTYP_NET;
     devnotify = RegisterDeviceNotificationA( hwnd, header, 0 );
-    todo_wine
     ok( !devnotify, "RegisterDeviceNotificationA succeeded\n" );
-    todo_wine
     ok( GetLastError() == ERROR_INVALID_DATA || GetLastError() == ERROR_SERVICE_SPECIFIC_ERROR,
         "got error %u\n", GetLastError() );
-    if (devnotify) UnregisterDeviceNotification( devnotify );
 
     devnotify = RegisterDeviceNotificationA( hwnd, &iface_filter_a, DEVICE_NOTIFY_WINDOW_HANDLE );
     ok( !!devnotify, "RegisterDeviceNotificationA failed, error %u\n", GetLastError() );
diff --git a/dlls/sechost/service.c b/dlls/sechost/service.c
index 4dfb40b4bac..00485869e9c 100644
--- a/dlls/sechost/service.c
+++ b/dlls/sechost/service.c
@@ -1974,6 +1974,11 @@ struct device_notification_details
 {
     DWORD (CALLBACK *cb)(HANDLE handle, DWORD flags, DEV_BROADCAST_HDR *header);
     HANDLE handle;
+    union
+    {
+        DEV_BROADCAST_HDR header;
+        DEV_BROADCAST_DEVICEINTERFACE_W iface;
+    } filter;
 };
 
 static HANDLE device_notify_thread;
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 08a00c0e647..67ca7e178f2 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -1170,6 +1170,11 @@ struct device_notification_details
 {
     DWORD (CALLBACK *cb)(HANDLE handle, DWORD flags, DEV_BROADCAST_HDR *header);
     HANDLE handle;
+    union
+    {
+        DEV_BROADCAST_HDR header;
+        DEV_BROADCAST_DEVICEINTERFACE_W iface;
+    } filter;
 };
 
 extern HDEVNOTIFY WINAPI I_ScRegisterDeviceNotification( struct device_notification_details *details,
@@ -1196,11 +1201,43 @@ HDEVNOTIFY WINAPI RegisterDeviceNotificationA(HANDLE hRecipient, LPVOID pNotific
 HDEVNOTIFY WINAPI RegisterDeviceNotificationW( HANDLE handle, void *filter, DWORD flags )
 {
     struct device_notification_details details;
+    DEV_BROADCAST_HDR *header = filter;
 
     TRACE("handle %p, filter %p, flags %#x\n", handle, filter, flags);
 
     if (flags & ~(DEVICE_NOTIFY_SERVICE_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES))
-        FIXME("unhandled flags %#x\n", flags);
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return NULL;
+    }
+
+    if (!(flags & DEVICE_NOTIFY_SERVICE_HANDLE) && !IsWindow( handle ))
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return NULL;
+    }
+
+    if (!header) details.filter.header.dbch_devicetype = 0;
+    else if (header->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
+    {
+        DEV_BROADCAST_DEVICEINTERFACE_W *iface = (DEV_BROADCAST_DEVICEINTERFACE_W *)header;
+        details.filter.iface = *iface;
+
+        if (flags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES)
+            details.filter.iface.dbcc_size = offsetof( DEV_BROADCAST_DEVICEINTERFACE_W, dbcc_classguid );
+        else
+            details.filter.iface.dbcc_size = offsetof( DEV_BROADCAST_DEVICEINTERFACE_W, dbcc_name );
+    }
+    else if (header->dbch_devicetype == DBT_DEVTYP_HANDLE)
+    {
+        FIXME( "DBT_DEVTYP_HANDLE filter type not implemented\n" );
+        details.filter.header.dbch_devicetype = 0;
+    }
+    else
+    {
+        SetLastError( ERROR_INVALID_DATA );
+        return NULL;
+    }
 
     details.handle = handle;
 
-- 
2.34.1




More information about the wine-devel mailing list