From: Micah N Gorrell Subject: [PATCH resend 6/8] user32: Implement RegisterDeviceNotification() Message-Id: <20191017145317.1998353-6-mgorrell@codeweavers.com> Date: Thu, 17 Oct 2019 08:53:15 -0600 In-Reply-To: <20191017145317.1998353-1-mgorrell@codeweavers.com> References: <20191017145317.1998353-1-mgorrell@codeweavers.com> Implement RegisterDeviceNotification() and UnregisterDeviceNotification() using I_ScRegisterDeviceNotification() and I_ScUnregisterDeviceNotification() in sechost.dll Signed-off-by: Micah N Gorrell --- dlls/user32/Makefile.in | 2 +- dlls/user32/misc.c | 73 +++++++++++++++++++++++++++++++++++------ include/winuser.h | 4 ++- 3 files changed, 67 insertions(+), 12 deletions(-) diff --git a/dlls/user32/Makefile.in b/dlls/user32/Makefile.in index d420dcb45a..bd3660331e 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 = gdi32 version advapi32 +IMPORTS = gdi32 version advapi32 sechost EXTRAINCL = $(PNG_CFLAGS) DELAYIMPORTS = hid imm32 setupapi usp10 diff --git a/dlls/user32/misc.c b/dlls/user32/misc.c index bed5812a47..17d0b5bcd3 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 "winsvc.h" #include "wine/unicode.h" #include "wine/debug.h" @@ -288,17 +290,39 @@ DWORD WINAPI RegisterTasklist (DWORD x) return TRUE; } +static DWORD CALLBACK devnotify_window_callback(HANDLE hRecipient, DWORD flags, DEV_BROADCAST_HDR *dbh) +{ + SendMessageTimeoutW(hRecipient, WM_DEVICECHANGE, flags, + (LPARAM) dbh, SMTO_ABORTIFHUNG, 2000, NULL); + return 0; +} + +static DWORD CALLBACK devnotify_service_callback(HANDLE hRecipient, DWORD flags, DEV_BROADCAST_HDR *dbh) +{ + FIXME("Support for service handles is not yet implemented!\n"); + ControlService(hRecipient, SERVICE_CONTROL_DEVICEEVENT, NULL); + return 0; +} + +static DWORD CALLBACK devnotify_null_callback(HANDLE hRecipient, DWORD flags, DEV_BROADCAST_HDR *dbh) +{ + /* The WM_DEVICECHANGE event is broadcast directly from ntoskrnl.exe so + * nothing needs to be done here. */ + return 0; +} /*********************************************************************** * 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); } /*********************************************************************** @@ -326,19 +350,48 @@ HDEVNOTIFY WINAPI RegisterDeviceNotificationA(HANDLE hnd, LPVOID notifyfilter, D */ HDEVNOTIFY WINAPI RegisterDeviceNotificationW(HANDLE hRecipient, LPVOID pNotificationFilter, DWORD dwFlags) { - FIXME("(hwnd=%p, filter=%p,flags=0x%08x) returns a fake device notification handle!\n", - hRecipient,pNotificationFilter,dwFlags ); - return (HDEVNOTIFY) 0xcafeaffe; + DEVICE_NOTIFICATION_DETAILS details; + + TRACE("(hwnd=%p, filter=%p,flags=0x%08x)\n", + hRecipient,pNotificationFilter,dwFlags); + + if (dwFlags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES) + { + dwFlags &= ~DEVICE_NOTIFY_ALL_INTERFACE_CLASSES; + pNotificationFilter = NULL; + } + + details.hRecipient = hRecipient; + + switch (dwFlags) { + case DEVICE_NOTIFY_WINDOW_HANDLE: + details.pNotificationCallback = devnotify_window_callback; + break; + + case DEVICE_NOTIFY_SERVICE_HANDLE: + details.pNotificationCallback = devnotify_service_callback; + break; + + default: + SetLastError(ERROR_INVALID_FLAGS); + return 0; + } + + if (!hRecipient) + details.pNotificationCallback = devnotify_null_callback; + + return I_ScRegisterDeviceNotification(&details, pNotificationFilter, 0); } /*********************************************************************** * UnregisterDeviceNotification (USER32.@) * */ -BOOL WINAPI UnregisterDeviceNotification(HDEVNOTIFY hnd) +BOOL WINAPI UnregisterDeviceNotification(HDEVNOTIFY hnd) { - FIXME("(handle=%p), STUB!\n", hnd); - return TRUE; + TRACE("(hnd=%p)\n", hnd); + + return I_ScUnregisterDeviceNotification(hnd); } /*********************************************************************** diff --git a/include/winuser.h b/include/winuser.h index 51c73d25c2..b5dedc0db0 100644 --- a/include/winuser.h +++ b/include/winuser.h @@ -3112,7 +3112,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() */ -- 2.23.0