user32: Add a filter member to device_notification_details.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2022-01-28 10:02:29 +01:00 committed by Alexandre Julliard
parent d44e752fa2
commit 41ff8effa3
3 changed files with 43 additions and 25 deletions

View File

@ -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() );

View File

@ -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;

View File

@ -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;