[PATCH 2/5] user32: Add a filter member to device_notification_details.

Rémi Bernon rbernon at codeweavers.com
Fri Dec 24 08:49:10 CST 2021


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

diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c
index bd51d27580a..fea8dc07654 100644
--- a/dlls/dinput8/tests/hid.c
+++ b/dlls/dinput8/tests/hid.c
@@ -10150,82 +10150,58 @@ 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, "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, "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, "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, "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, "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 e6f4eb75db0..b2c768f77b7 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 7134ab0fbb2..5010fe93bd5 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -1171,6 +1171,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,
@@ -1197,11 +1202,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