[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