From e6df76770ee59b34fc7eafffb92e3500f4b9faa4 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Tue, 5 May 2020 11:25:40 -0500 Subject: [PATCH] user32: Implement RegisterDeviceNotification(). Based on a patch by Micah N Gorrell. This fixes controller hotplugging in Into the Breach. Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/user32/Makefile.in | 2 +- dlls/user32/misc.c | 81 +++++++++++++++++++++++++---------------- include/winuser.h | 4 +- 3 files changed, 53 insertions(+), 34 deletions(-) diff --git a/dlls/user32/Makefile.in b/dlls/user32/Makefile.in index a91dd89c941..2d45552bcb2 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 = setupapi gdi32 version advapi32 kernelbase +IMPORTS = setupapi gdi32 version sechost advapi32 kernelbase EXTRAINCL = $(PNG_CFLAGS) DELAYIMPORTS = hid imm32 usp10 diff --git a/dlls/user32/misc.c b/dlls/user32/misc.c index 6e1f60612be..41909f90713 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 "dbt.h" #include "wine/unicode.h" #include "wine/debug.h" @@ -277,57 +279,72 @@ DWORD WINAPI RegisterTasklist (DWORD x) return TRUE; } +static DWORD CALLBACK devnotify_window_callback(HANDLE handle, DWORD flags, DEV_BROADCAST_HDR *header) +{ + SendMessageTimeoutW(handle, WM_DEVICECHANGE, flags, (LPARAM)header, SMTO_ABORTIFHUNG, 2000, NULL); + return 0; +} + +static DWORD CALLBACK devnotify_service_callback(HANDLE handle, DWORD flags, DEV_BROADCAST_HDR *header) +{ + FIXME("Support for service handles is not yet implemented!\n"); + return 0; +} + +struct device_notification_details +{ + DWORD (CALLBACK *cb)(HANDLE handle, DWORD flags, DEV_BROADCAST_HDR *header); + HANDLE handle; +}; + +extern HDEVNOTIFY WINAPI I_ScRegisterDeviceNotification( struct device_notification_details *details, + void *filter, DWORD flags ); +extern BOOL WINAPI I_ScUnregisterDeviceNotification( HDEVNOTIFY handle ); /*********************************************************************** * 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); } /*********************************************************************** * RegisterDeviceNotificationW (USER32.@) - * - * Registers a window with the system so that it will receive - * notifications about a device. - * - * PARAMS - * hRecipient [I] Window or service status handle that - * will receive notifications. - * pNotificationFilter [I] DEV_BROADCAST_HDR followed by some - * type-specific data. - * dwFlags [I] See notes - * - * RETURNS - * - * A handle to the device notification. - * - * NOTES - * - * The dwFlags parameter can be one of two values: - *| DEVICE_NOTIFY_WINDOW_HANDLE - hRecipient is a window handle - *| DEVICE_NOTIFY_SERVICE_HANDLE - hRecipient is a service status handle */ -HDEVNOTIFY WINAPI RegisterDeviceNotificationW(HANDLE hRecipient, LPVOID pNotificationFilter, DWORD dwFlags) +HDEVNOTIFY WINAPI RegisterDeviceNotificationW( HANDLE handle, void *filter, DWORD flags ) { - FIXME("(hwnd=%p, filter=%p,flags=0x%08x) returns a fake device notification handle!\n", - hRecipient,pNotificationFilter,dwFlags ); - return (HDEVNOTIFY) 0xcafeaffe; + struct device_notification_details details; + + 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); + + details.handle = handle; + + if (flags & DEVICE_NOTIFY_SERVICE_HANDLE) + details.cb = devnotify_service_callback; + else + details.cb = devnotify_window_callback; + + return I_ScRegisterDeviceNotification( &details, filter, 0 ); } /*********************************************************************** * UnregisterDeviceNotification (USER32.@) - * */ -BOOL WINAPI UnregisterDeviceNotification(HDEVNOTIFY hnd) +BOOL WINAPI UnregisterDeviceNotification( HDEVNOTIFY handle ) { - FIXME("(handle=%p), STUB!\n", hnd); - return TRUE; + TRACE("%p\n", handle); + + return I_ScUnregisterDeviceNotification( handle ); } /*********************************************************************** diff --git a/include/winuser.h b/include/winuser.h index 5fd774d2959..aa392d636c8 100644 --- a/include/winuser.h +++ b/include/winuser.h @@ -3114,7 +3114,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() */