Signed-off-by: Micah N Gorrell mgorrell@codeweavers.com --- server/protocol.def | 23 ++++++++++ server/user.h | 3 +- server/window.c | 108 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+), 1 deletion(-)
diff --git a/server/protocol.def b/server/protocol.def index 21008d7a87..314a4477d0 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3684,6 +3684,29 @@ struct handle_info @END
+/* Register a handle for device notifications */ +@REQ(register_device_notification) + user_handle_t recipient; /* handle to a window or service that will receive device events */ +@REPLY + user_handle_t handle; /* handle associated with the registration */ +@END + + +/* Unregister device notifications for a handle */ +@REQ(unregister_device_notification) + user_handle_t notification; /* handle that was previously returned by register_device_notification */ +@END + + +/* Return a list of handles that have registered for device notifications */ +@REQ(get_device_notifications) +@REPLY + int count; /* total count of registered handles */ + VARARG(handles,user_handles); /* registered handles */ +@END + + + /* Make the current process a system process */ @REQ(make_process_system) @REPLY diff --git a/server/user.h b/server/user.h index eb1b7ce1e4..282cb63339 100644 --- a/server/user.h +++ b/server/user.h @@ -36,7 +36,8 @@ enum user_object { USER_WINDOW = 1, USER_HOOK, - USER_CLIENT /* arbitrary client handle */ + USER_CLIENT, /* arbitrary client handle */ + USER_DEVNOTIFY };
#define DESKTOP_ATOM ((atom_t)32769) diff --git a/server/window.c b/server/window.c index c9b131cba5..5116fb12ff 100644 --- a/server/window.c +++ b/server/window.c @@ -129,6 +129,18 @@ static struct window *taskman_window; #define WINPTR_TOPMOST ((struct window *)3L) #define WINPTR_NOTOPMOST ((struct window *)4L)
+struct device_notification +{ + user_handle_t recipient; /* the window handle to send notifications to */ + user_handle_t handle; /* full handle for this window */ + struct list entry; /* entry in global notifications list */ + + /* FIXME: Add support for notification filters */ +}; + +/* global list of handles that have registered for device notifications */ +static struct list device_notifications = LIST_INIT(device_notifications); + /* retrieve a pointer to a window from its handle */ static inline struct window *get_window( user_handle_t handle ) { @@ -2880,3 +2892,99 @@ DECL_HANDLER(set_window_layered_info) } else set_win32_error( ERROR_INVALID_WINDOW_HANDLE ); } + +/* retrieve a pointer to a device_notification from its handle */ +static inline struct device_notification *get_device_notification( user_handle_t handle ) +{ + struct device_notification *ret = get_user_object( handle, USER_DEVNOTIFY ); + if (!ret) set_win32_error( ERROR_INVALID_HANDLE ); + return ret; +} + +/* create a new device notification structure and link it into the global list */ +static struct device_notification *register_device_notification( struct window *recipient ) +{ + struct device_notification *notification; + + if (!recipient) + { + return NULL; + } + + if (!(notification = mem_alloc( sizeof(*notification) ))) goto failed; + if (!(notification->handle = alloc_user_handle( notification, USER_DEVNOTIFY ))) goto failed; + + notification->recipient = recipient->handle; + /* FIXME: Add support for notification filters */ + + list_add_tail( &device_notifications, ¬ification->entry ); + + return notification; +failed: + if (notification) + { + if (notification->handle) free_user_handle( notification->handle ); + free( notification ); + } + + return NULL; +} + +static void unregister_device_notification( struct device_notification *notification) +{ + list_remove( ¬ification->entry ); + free_user_handle( notification->handle ); + memset( notification, 0x55, sizeof(*notification) ); + free( notification ); +} + +static int get_device_notifications( struct user_handle_array *array ) +{ + struct device_notification *notification; + + LIST_FOR_EACH_ENTRY( notification, &device_notifications, struct device_notification, entry ) + { + /* FIXME: Implement notification filtering */ + if (!add_handle_to_array( array, notification->recipient )) return 0; + } + + return 1; +} + +/* register for device notifications */ +DECL_HANDLER(register_device_notification) +{ + struct device_notification *notification = NULL; + struct window *recipient = get_window( req->recipient ); + + reply->handle = 0; + if (!recipient) return; + + if (!(notification = register_device_notification( recipient ))) return; + + reply->handle = notification->handle; +} + +DECL_HANDLER(unregister_device_notification) +{ + struct device_notification *notification = get_device_notification( req->notification ); + if (notification) unregister_device_notification(notification); +} + +DECL_HANDLER(get_device_notifications) +{ + struct user_handle_array array; + data_size_t len; + + array.handles = NULL; + array.count = 0; + array.total = 0; + + if (!get_device_notifications( &array )) return; + + reply->count = array.count; + len = min( get_reply_max_size(), array.count * sizeof(user_handle_t) ); + if (len) set_reply_data_ptr( array.handles, len ); + else free( array.handles ); +} +
Signed-off-by: Micah N Gorrell mgorrell@codeweavers.com --- include/winuser.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/winuser.h b/include/winuser.h index 60bc473225..165f835b7d 100644 --- a/include/winuser.h +++ b/include/winuser.h @@ -3088,7 +3088,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() */
Signed-off-by: Micah N Gorrell mgorrell@codeweavers.com --- dlls/user32/misc.c | 74 ++++++++++++++++++++++++++++++++---- dlls/user32/tests/misc.c | 81 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 8 deletions(-) create mode 100644 dlls/user32/tests/misc.c
diff --git a/dlls/user32/misc.c b/dlls/user32/misc.c index 1a03d70dde..648f597837 100644 --- a/dlls/user32/misc.c +++ b/dlls/user32/misc.c @@ -33,6 +33,7 @@ #include "winternl.h" #include "controls.h" #include "user_private.h" +#include "wine/server.h"
#include "wine/unicode.h" #include "wine/debug.h" @@ -363,11 +364,9 @@ DWORD WINAPI RegisterTasklist (DWORD x) * * 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; + return RegisterDeviceNotificationW( hRecipient, pNotificationFilter, dwFlags ); }
/*********************************************************************** @@ -395,9 +394,52 @@ 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", + HWND ret = 0; + + TRACE("(hwnd=%p, filter=%p,flags=0x%08x)\n", hRecipient,pNotificationFilter,dwFlags ); - return (HDEVNOTIFY) 0xcafeaffe; + + if (dwFlags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES) + { + dwFlags &= ~DEVICE_NOTIFY_ALL_INTERFACE_CLASSES; + pNotificationFilter = NULL; + } + + /* Wine broadcasts WM_DEVICECHANGE anyway, so registering without a handle + * is a not needed and can be ignored. + */ + if (!hRecipient) + return (HDEVNOTIFY) 0xcafeaffe; + + switch (dwFlags) { + case DEVICE_NOTIFY_WINDOW_HANDLE: + break; + + case DEVICE_NOTIFY_SERVICE_HANDLE: + FIXME("Support for service handles is not yet implemented! Returns a fake device notification handle!\n"); + return (HDEVNOTIFY) 0xcafeaffe; + + default: + SetLastError(ERROR_INVALID_FLAGS); + return 0; + } + + /* This implementation is not overly concerned with sending too many + * messages, so support for filters is not yet implemented. + */ + if (pNotificationFilter) + FIXME("Notification filters are not yet implemented! All WM_DEVICECHANGE messages will be sent.\n"); + + SERVER_START_REQ( register_device_notification ) + { + req->recipient = wine_server_user_handle( hRecipient ); + + wine_server_call( req ); + ret = wine_server_ptr_handle( reply->handle ); + } + SERVER_END_REQ; + + return (HDEVNOTIFY) ret; }
/*********************************************************************** @@ -406,8 +448,24 @@ HDEVNOTIFY WINAPI RegisterDeviceNotificationW(HANDLE hRecipient, LPVOID pNotific */ BOOL WINAPI UnregisterDeviceNotification(HDEVNOTIFY hnd) { - FIXME("(handle=%p), STUB!\n", hnd); - return TRUE; + unsigned int res = 0; + + TRACE("(hnd=%p)\n", hnd); + + /* A fake device notification handle is returned in some cases */ + if ((HDEVNOTIFY) 0xcafeaffe == hnd) + return TRUE; + + SERVER_START_REQ( unregister_device_notification ) + { + req->notification = wine_server_user_handle( hnd ); + + res = wine_server_call( req ); + } + SERVER_END_REQ; + + if (res) SetLastError( RtlNtStatusToDosError( res ) ); + return !res; }
/*********************************************************************** diff --git a/dlls/user32/tests/misc.c b/dlls/user32/tests/misc.c new file mode 100644 index 0000000000..d057bc6afe --- /dev/null +++ b/dlls/user32/tests/misc.c @@ -0,0 +1,81 @@ +/* + * Unit tests for misc functions + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "dbt.h" + +static void RegisterDeviceNotificationTest(void) +{ + static const WCHAR mainwindowclassW[] = {'M','a','i','n','W','i','n','d','o','w','C','l','a','s','s',0}; + static const WCHAR message_windowW[] = {'m','e','s','s','a','g','e',' ','w','i','n','d','o','w',0}; + + HDEVNOTIFY hnotify1, hnotify2; + DEV_BROADCAST_DEVICEINTERFACE_W dbh; + HWND hwnd; + DWORD_PTR result; + GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } }; + + hwnd = CreateWindowExW(0, mainwindowclassW, message_windowW, 0, + 0, 0, 0, 0, HWND_MESSAGE, 0, 0, NULL); + ok( hwnd != 0, "CreateWindowExW with parent HWND_MESSAGE failed\n" ); + + memset(&dbh, 0, sizeof(dbh)); + + dbh.dbcc_size = sizeof(dbh); + dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + dbh.dbcc_classguid = GUID_DEVINTERFACE_HID; + + /* Test RegisterDeviceNotification behavior */ + hnotify1 = RegisterDeviceNotificationW( NULL, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE ); + ok( hnotify1 != 0, "RegisterDeviceNotificationW failed when called with a NULL recipient window handle\n" ); + + ok( UnregisterDeviceNotification( hnotify1 ), "UnregisterDeviceNotification failed with a valid handle\n" ); + + hnotify1 = RegisterDeviceNotificationW( hwnd, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE ); + ok( hnotify1 != 0, "RegisterDeviceNotificationW failed when called with a message only window as recipient\n" ); + + hnotify2 = RegisterDeviceNotificationW( hwnd, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE ); + ok( hnotify2 != 0, "RegisterDeviceNotificationW failed when called with a window that has already been registered as a recipient\n" ); + + UnregisterDeviceNotification( hnotify1 ); + UnregisterDeviceNotification( hnotify2 ); + + + hnotify1 = RegisterDeviceNotificationW( hwnd, &dbh, 0xffff ); + ok( hnotify1 == 0, "RegisterDeviceNotificationW accepted invalid flags\n" ); + + + ok( !UnregisterDeviceNotification( hnotify1 ), "UnregisterDeviceNotification succeeded with an already released handle\n" ); + ok( !UnregisterDeviceNotification( NULL ), "UnregisterDeviceNotification succeeded with NULL handle\n" ); + + /* FIXME: Find a way to trigger a device notification for testing */ + + DestroyWindow(hwnd); +} + + +START_TEST(device_notifications) +{ + RegisterDeviceNotificationTest(); +} +
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=52435
Your paranoid android.
=== wxppro (32 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== w2003std (32 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== wvistau64 (32 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== wvistau64_zh_CN (32 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== wvistau64_fr (32 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== wvistau64_he (32 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== w2008s64 (32 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== w7u (32 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== w7pro64 (32 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== w8 (32 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== w8adm (32 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== w864 (32 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== w1064v1507 (32 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== w1064v1809 (32 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== wvistau64 (64 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== w2008s64 (64 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== w7pro64 (64 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== w864 (64 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== w1064v1507 (64 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== w1064v1809 (64 bit report) ===
user32: Fatal: test 'misc' does not exist.
=== debian9 (32 bit WoW report) ===
user32: win.c:10127: Test failed: Expected foreground window 0, got 00E300D4 win.c:10133: Test failed: Expected foreground window 000E0120, got 00E300D4
=== debian9 (64 bit WoW report) ===
user32: msg.c:8713: Test failed: WaitForSingleObject failed 102 msg.c:8719: Test failed: destroy child on thread exit: 0: the msg 0x0082 was expected, but got msg 0x000f instead msg.c:8719: Test failed: destroy child on thread exit: 1: the msg 0x000f was expected, but got msg 0x0014 instead msg.c:8719: Test failed: destroy child on thread exit: 2: the msg sequence is not complete: expected 0014 - actual 0000
Signed-off-by: Micah N Gorrell mgorrell@codeweavers.com --- dlls/ntoskrnl.exe/ntoskrnl.c | 54 ++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 89f7674293..60da6154c0 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -1672,6 +1672,45 @@ static NTSTATUS create_device_symlink( DEVICE_OBJECT *device, UNICODE_STRING *sy return ret; }
+/******************************************************************* + * list_device_notifications + * + * Build an array of windows which have been registered to receive device + * notifications. The array must be freed with HeapFree. Returns NULL when no + * registered windows are found. + */ +static HWND *list_device_notifications( void ) +{ + HWND *list; + int i, count, size = 128; + + for (;;) + { + count = 0; + + if (!(list = heap_alloc( size * sizeof(HWND) ))) break; + + SERVER_START_REQ( get_device_notifications ) + { + wine_server_set_reply( req, list, (size-1) * sizeof(user_handle_t) ); + if (!wine_server_call( req )) count = reply->count; + } + SERVER_END_REQ; + if (count && count < size) + { + /* start from the end since HWND is potentially larger than user_handle_t */ + for (i = count - 1; i >= 0; i--) + list[i] = wine_server_ptr_handle( ((user_handle_t *)list)[i] ); + list[count] = 0; + return list; + } + heap_free( list ); + if (!count) break; + size = count + 1; /* restart with a large enough buffer */ + } + return NULL; +} + /*********************************************************************** * IoSetDeviceInterfaceState (NTOSKRNL.EXE.@) */ @@ -1699,6 +1738,8 @@ NTSTATUS WINAPI IoSetDeviceInterfaceState( UNICODE_STRING *name, BOOLEAN enable NTSTATUS ret; GUID class; ULONG len; + HWND *registrations; + unsigned int i;
TRACE("(%s, %d)\n", debugstr_us(name), enable);
@@ -1782,6 +1823,19 @@ NTSTATUS WINAPI IoSetDeviceInterfaceState( UNICODE_STRING *name, BOOLEAN enable BroadcastSystemMessageW( BSF_FORCEIFHUNG | BSF_QUERY, NULL, WM_DEVICECHANGE, enable ? DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE, (LPARAM)broadcast );
+ if ((registrations = list_device_notifications( ))) + { + for (i = 0; registrations[i]; i++) + { + TRACE("Sending WM_DEVICECHANGE to registered window %p\n", registrations[i]); + SendMessageTimeoutW( registrations[i], WM_DEVICECHANGE, + enable ? DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE, + (LPARAM)broadcast, SMTO_ABORTIFHUNG, 2000, NULL ); + } + + heap_free( registrations ); + } + heap_free( broadcast ); } return ret;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=52436
Your paranoid android.
=== debian9 (32 bit report) ===
user32: msg.c:8713: Test failed: WaitForSingleObject failed 102 msg.c:8719: Test failed: destroy child on thread exit: 0: the msg 0x0082 was expected, but got msg 0x000f instead msg.c:8719: Test failed: destroy child on thread exit: 1: the msg 0x000f was expected, but got msg 0x0014 instead msg.c:8719: Test failed: destroy child on thread exit: 2: the msg sequence is not complete: expected 0014 - actual 0000
=== debian9 (32 bit WoW report) ===
user32: msg.c:8713: Test failed: WaitForSingleObject failed 102 msg.c:8719: Test failed: destroy child on thread exit: 0: the msg 0x0082 was expected, but got msg 0x000f instead msg.c:8719: Test failed: destroy child on thread exit: 1: the msg 0x000f was expected, but got msg 0x0014 instead msg.c:8719: Test failed: destroy child on thread exit: 2: the msg sequence is not complete: expected 0014 - actual 0000
=== debian9 (64 bit WoW report) ===
user32: msg.c:8713: Test failed: WaitForSingleObject failed 102 msg.c:8719: Test failed: destroy child on thread exit: 0: the msg 0x0082 was expected, but got msg 0x000f instead msg.c:8719: Test failed: destroy child on thread exit: 1: the msg 0x000f was expected, but got msg 0x0014 instead msg.c:8719: Test failed: destroy child on thread exit: 2: the msg sequence is not complete: expected 0014 - actual 0000
Signed-off-by: Micah N Gorrell mgorrell@codeweavers.com --- include/wine/server_protocol.h | 53 +++++++++++++++++++++++++++++++++- server/request.h | 15 ++++++++++ server/trace.c | 35 ++++++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-)
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index a45d092deb..648ab153ec 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -5340,6 +5340,48 @@ struct get_kernel_object_handle_reply
+struct register_device_notification_request +{ + struct request_header __header; + user_handle_t recipient; +}; +struct register_device_notification_reply +{ + struct reply_header __header; + user_handle_t handle; + char __pad_12[4]; +}; + + + +struct unregister_device_notification_request +{ + struct request_header __header; + user_handle_t notification; +}; +struct unregister_device_notification_reply +{ + struct reply_header __header; +}; + + + +struct get_device_notifications_request +{ + struct request_header __header; + char __pad_12[4]; +}; +struct get_device_notifications_reply +{ + struct reply_header __header; + int count; + /* VARARG(handles,user_handles); */ + char __pad_12[4]; +}; + + + + struct make_process_system_request { struct request_header __header; @@ -6055,6 +6097,9 @@ enum request REQ_grab_kernel_object, REQ_release_kernel_object, REQ_get_kernel_object_handle, + REQ_register_device_notification, + REQ_unregister_device_notification, + REQ_get_device_notifications, REQ_make_process_system, REQ_get_token_statistics, REQ_create_completion, @@ -6360,6 +6405,9 @@ union generic_request struct grab_kernel_object_request grab_kernel_object_request; struct release_kernel_object_request release_kernel_object_request; struct get_kernel_object_handle_request get_kernel_object_handle_request; + struct register_device_notification_request register_device_notification_request; + struct unregister_device_notification_request unregister_device_notification_request; + struct get_device_notifications_request get_device_notifications_request; struct make_process_system_request make_process_system_request; struct get_token_statistics_request get_token_statistics_request; struct create_completion_request create_completion_request; @@ -6663,6 +6711,9 @@ union generic_reply struct grab_kernel_object_reply grab_kernel_object_reply; struct release_kernel_object_reply release_kernel_object_reply; struct get_kernel_object_handle_reply get_kernel_object_handle_reply; + struct register_device_notification_reply register_device_notification_reply; + struct unregister_device_notification_reply unregister_device_notification_reply; + struct get_device_notifications_reply get_device_notifications_reply; struct make_process_system_reply make_process_system_reply; struct get_token_statistics_reply get_token_statistics_reply; struct create_completion_reply create_completion_reply; @@ -6694,6 +6745,6 @@ union generic_reply struct resume_process_reply resume_process_reply; };
-#define SERVER_PROTOCOL_VERSION 583 +#define SERVER_PROTOCOL_VERSION 584
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/request.h b/server/request.h index 07918dff3f..6724789808 100644 --- a/server/request.h +++ b/server/request.h @@ -381,6 +381,9 @@ DECL_HANDLER(set_kernel_object_ptr); DECL_HANDLER(grab_kernel_object); DECL_HANDLER(release_kernel_object); DECL_HANDLER(get_kernel_object_handle); +DECL_HANDLER(register_device_notification); +DECL_HANDLER(unregister_device_notification); +DECL_HANDLER(get_device_notifications); DECL_HANDLER(make_process_system); DECL_HANDLER(get_token_statistics); DECL_HANDLER(create_completion); @@ -685,6 +688,9 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_grab_kernel_object, (req_handler)req_release_kernel_object, (req_handler)req_get_kernel_object_handle, + (req_handler)req_register_device_notification, + (req_handler)req_unregister_device_notification, + (req_handler)req_get_device_notifications, (req_handler)req_make_process_system, (req_handler)req_get_token_statistics, (req_handler)req_create_completion, @@ -2315,6 +2321,15 @@ C_ASSERT( FIELD_OFFSET(struct get_kernel_object_handle_request, access) == 24 ); C_ASSERT( sizeof(struct get_kernel_object_handle_request) == 32 ); C_ASSERT( FIELD_OFFSET(struct get_kernel_object_handle_reply, handle) == 8 ); C_ASSERT( sizeof(struct get_kernel_object_handle_reply) == 16 ); +C_ASSERT( FIELD_OFFSET(struct register_device_notification_request, recipient) == 12 ); +C_ASSERT( sizeof(struct register_device_notification_request) == 16 ); +C_ASSERT( FIELD_OFFSET(struct register_device_notification_reply, handle) == 8 ); +C_ASSERT( sizeof(struct register_device_notification_reply) == 16 ); +C_ASSERT( FIELD_OFFSET(struct unregister_device_notification_request, notification) == 12 ); +C_ASSERT( sizeof(struct unregister_device_notification_request) == 16 ); +C_ASSERT( sizeof(struct get_device_notifications_request) == 16 ); +C_ASSERT( FIELD_OFFSET(struct get_device_notifications_reply, count) == 8 ); +C_ASSERT( sizeof(struct get_device_notifications_reply) == 16 ); C_ASSERT( sizeof(struct make_process_system_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct make_process_system_reply, event) == 8 ); C_ASSERT( sizeof(struct make_process_system_reply) == 16 ); diff --git a/server/trace.c b/server/trace.c index 28bf3dd7ac..a90ddf6551 100644 --- a/server/trace.c +++ b/server/trace.c @@ -4336,6 +4336,31 @@ static void dump_get_kernel_object_handle_reply( const struct get_kernel_object_ fprintf( stderr, " handle=%04x", req->handle ); }
+static void dump_register_device_notification_request( const struct register_device_notification_request *req ) +{ + fprintf( stderr, " recipient=%08x", req->recipient ); +} + +static void dump_register_device_notification_reply( const struct register_device_notification_reply *req ) +{ + fprintf( stderr, " handle=%08x", req->handle ); +} + +static void dump_unregister_device_notification_request( const struct unregister_device_notification_request *req ) +{ + fprintf( stderr, " notification=%08x", req->notification ); +} + +static void dump_get_device_notifications_request( const struct get_device_notifications_request *req ) +{ +} + +static void dump_get_device_notifications_reply( const struct get_device_notifications_reply *req ) +{ + fprintf( stderr, " count=%d", req->count ); + dump_varargs_user_handles( ", handles=", cur_size ); +} + static void dump_make_process_system_request( const struct make_process_system_request *req ) { } @@ -4864,6 +4889,9 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_grab_kernel_object_request, (dump_func)dump_release_kernel_object_request, (dump_func)dump_get_kernel_object_handle_request, + (dump_func)dump_register_device_notification_request, + (dump_func)dump_unregister_device_notification_request, + (dump_func)dump_get_device_notifications_request, (dump_func)dump_make_process_system_request, (dump_func)dump_get_token_statistics_request, (dump_func)dump_create_completion_request, @@ -5165,6 +5193,9 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { NULL, NULL, (dump_func)dump_get_kernel_object_handle_reply, + (dump_func)dump_register_device_notification_reply, + NULL, + (dump_func)dump_get_device_notifications_reply, (dump_func)dump_make_process_system_reply, (dump_func)dump_get_token_statistics_reply, (dump_func)dump_create_completion_reply, @@ -5466,6 +5497,9 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "grab_kernel_object", "release_kernel_object", "get_kernel_object_handle", + "register_device_notification", + "unregister_device_notification", + "get_device_notifications", "make_process_system", "get_token_statistics", "create_completion", @@ -5535,6 +5569,7 @@ static const struct { "ERROR_HOTKEY_ALREADY_REGISTERED", 0xc0010000 | ERROR_HOTKEY_ALREADY_REGISTERED }, { "ERROR_HOTKEY_NOT_REGISTERED", 0xc0010000 | ERROR_HOTKEY_NOT_REGISTERED }, { "ERROR_INVALID_CURSOR_HANDLE", 0xc0010000 | ERROR_INVALID_CURSOR_HANDLE }, + { "ERROR_INVALID_HANDLE", 0xc0010000 | ERROR_INVALID_HANDLE }, { "ERROR_INVALID_INDEX", 0xc0010000 | ERROR_INVALID_INDEX }, { "ERROR_INVALID_WINDOW_HANDLE", 0xc0010000 | ERROR_INVALID_WINDOW_HANDLE }, { "ERROR_NO_MORE_USER_HANDLES", 0xc0010000 | ERROR_NO_MORE_USER_HANDLES },
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=52437
Your paranoid android.
=== debian9 (32 bit report) ===
user32: msg.c:8713: Test failed: WaitForSingleObject failed 102 msg.c:8719: Test failed: destroy child on thread exit: 0: the msg 0x0082 was expected, but got msg 0x000f instead msg.c:8719: Test failed: destroy child on thread exit: 1: the msg 0x000f was expected, but got msg 0x0014 instead msg.c:8719: Test failed: destroy child on thread exit: 2: the msg sequence is not complete: expected 0014 - actual 0000
=== debian9 (32 bit WoW report) ===
user32: msg.c:8713: Test failed: WaitForSingleObject failed 102 msg.c:8719: Test failed: destroy child on thread exit: 0: the msg 0x0082 was expected, but got msg 0x000f instead msg.c:8719: Test failed: destroy child on thread exit: 1: the msg 0x000f was expected, but got msg 0x0014 instead msg.c:8719: Test failed: destroy child on thread exit: 2: the msg sequence is not complete: expected 0014 - actual 0000