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 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 8 deletions(-)
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; }
/***********************************************************************
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=52443
Your paranoid android.
=== debian9 (64 bit WoW report) ===
user32: win.c:10133: Test failed: Expected foreground window 000E0120, got 00E300D4
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;
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..cbee9e36c5 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 585
#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=52445
Your paranoid android.
=== debian9 (64 bit WoW report) ===
user32: clipboard.c:1127: Test failed: WM_RENDERFORMAT received 000d, expected 0000
Signed-off-by: Micah N Gorrell mgorrell@codeweavers.com --- dlls/user32/tests/Makefile.in | 1 + dlls/user32/tests/misc.c | 89 +++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 dlls/user32/tests/misc.c
diff --git a/dlls/user32/tests/Makefile.in b/dlls/user32/tests/Makefile.in index 7149dc824e..da55fa58e5 100644 --- a/dlls/user32/tests/Makefile.in +++ b/dlls/user32/tests/Makefile.in @@ -15,6 +15,7 @@ C_SRCS = \ input.c \ listbox.c \ menu.c \ + misc.c \ monitor.c \ msg.c \ resource.c \ diff --git a/dlls/user32/tests/misc.c b/dlls/user32/tests/misc.c new file mode 100644 index 0000000000..c0a4af6636 --- /dev/null +++ b/dlls/user32/tests/misc.c @@ -0,0 +1,89 @@ +/* + * 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; + WNDCLASSEXW cls; + GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } }; + + memset(&cls, 0, sizeof(cls)); + cls.cbSize = sizeof(cls); + cls.hInstance = 0; + cls.lpszClassName = mainwindowclassW; + cls.lpfnWndProc = DefWindowProcW; + + RegisterClassExW(&cls); + + 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(misc) +{ + 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=52446
Your paranoid android.
=== wxppro (32 bit report) ===
user32: misc.c:58: Test failed: RegisterDeviceNotificationW failed when called with a NULL recipient window handle misc.c:60: Test failed: UnregisterDeviceNotification failed with a valid handle
=== w2003std (32 bit report) ===
user32: misc.c:58: Test failed: RegisterDeviceNotificationW failed when called with a NULL recipient window handle misc.c:60: Test failed: UnregisterDeviceNotification failed with a valid handle
=== wvistau64 (32 bit report) ===
user32: misc.c:58: Test failed: RegisterDeviceNotificationW failed when called with a NULL recipient window handle misc.c:60: Test failed: UnregisterDeviceNotification failed with a valid handle
=== wvistau64_zh_CN (32 bit report) ===
user32: misc.c:58: Test failed: RegisterDeviceNotificationW failed when called with a NULL recipient window handle misc.c:60: Test failed: UnregisterDeviceNotification failed with a valid handle
=== wvistau64_fr (32 bit report) ===
user32: misc.c:58: Test failed: RegisterDeviceNotificationW failed when called with a NULL recipient window handle misc.c:60: Test failed: UnregisterDeviceNotification failed with a valid handle
=== wvistau64_he (32 bit report) ===
user32: misc.c:58: Test failed: RegisterDeviceNotificationW failed when called with a NULL recipient window handle misc.c:60: Test failed: UnregisterDeviceNotification failed with a valid handle
=== w2008s64 (32 bit report) ===
user32: misc.c:58: Test failed: RegisterDeviceNotificationW failed when called with a NULL recipient window handle misc.c:60: Test failed: UnregisterDeviceNotification failed with a valid handle
=== w7u (32 bit report) ===
user32: misc.c:58: Test failed: RegisterDeviceNotificationW failed when called with a NULL recipient window handle misc.c:60: Test failed: UnregisterDeviceNotification failed with a valid handle
=== w7pro64 (32 bit report) ===
user32: misc.c:58: Test failed: RegisterDeviceNotificationW failed when called with a NULL recipient window handle misc.c:60: Test failed: UnregisterDeviceNotification failed with a valid handle
=== wvistau64 (64 bit report) ===
user32: misc.c:58: Test failed: RegisterDeviceNotificationW failed when called with a NULL recipient window handle misc.c:60: Test failed: UnregisterDeviceNotification failed with a valid handle
=== w2008s64 (64 bit report) ===
user32: misc.c:58: Test failed: RegisterDeviceNotificationW failed when called with a NULL recipient window handle misc.c:60: Test failed: UnregisterDeviceNotification failed with a valid handle
=== w7pro64 (64 bit report) ===
user32: misc.c:58: Test failed: RegisterDeviceNotificationW failed when called with a NULL recipient window handle misc.c:60: Test failed: UnregisterDeviceNotification failed with a valid handle
On 5/19/19 5:43 AM, Micah N Gorrell wrote:
Signed-off-by: Micah N Gorrell mgorrell@codeweavers.com
dlls/user32/tests/Makefile.in | 1 + dlls/user32/tests/misc.c | 89 +++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 dlls/user32/tests/misc.c
diff --git a/dlls/user32/tests/Makefile.in b/dlls/user32/tests/Makefile.in index 7149dc824e..da55fa58e5 100644 --- a/dlls/user32/tests/Makefile.in +++ b/dlls/user32/tests/Makefile.in @@ -15,6 +15,7 @@ C_SRCS = \ input.c \ listbox.c \ menu.c \
- misc.c \ monitor.c \ msg.c \ resource.c \
diff --git a/dlls/user32/tests/misc.c b/dlls/user32/tests/misc.c new file mode 100644 index 0000000000..c0a4af6636 --- /dev/null +++ b/dlls/user32/tests/misc.c @@ -0,0 +1,89 @@ +/*
- 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;
- WNDCLASSEXW cls;
- GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
Hi Micah,
You could just include hidclass.h to get GUID_DEVINTERFACE_HID. And testbots are failing. You need to fix the tests.
- memset(&cls, 0, sizeof(cls));
- cls.cbSize = sizeof(cls);
- cls.hInstance = 0;
- cls.lpszClassName = mainwindowclassW;
- cls.lpfnWndProc = DefWindowProcW;
- RegisterClassExW(&cls);
- 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));
Unnecessary white lines and same in below.
- 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(misc) +{
- RegisterDeviceNotificationTest();
+}
On Sun, May 19, 2019 at 02:08:26PM +0800, Zhiyi Zhang wrote:
On 5/19/19 5:43 AM, Micah N Gorrell wrote:
Signed-off-by: Micah N Gorrell mgorrell@codeweavers.com
dlls/user32/tests/Makefile.in | 1 + dlls/user32/tests/misc.c | 89 +++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 dlls/user32/tests/misc.c
diff --git a/dlls/user32/tests/Makefile.in b/dlls/user32/tests/Makefile.in index 7149dc824e..da55fa58e5 100644 --- a/dlls/user32/tests/Makefile.in +++ b/dlls/user32/tests/Makefile.in @@ -15,6 +15,7 @@ C_SRCS = \ input.c \ listbox.c \ menu.c \
- misc.c \ monitor.c \ msg.c \ resource.c \
diff --git a/dlls/user32/tests/misc.c b/dlls/user32/tests/misc.c new file mode 100644 index 0000000000..c0a4af6636 --- /dev/null +++ b/dlls/user32/tests/misc.c @@ -0,0 +1,89 @@ +/*
- 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;
- WNDCLASSEXW cls;
- GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
Hi Micah,
You could just include hidclass.h to get GUID_DEVINTERFACE_HID. And testbots are failing. You need to fix the tests.
Just including hidclass.h does not appear to be sufficient since it is an extern and the user32 tests do not link with hid. What is the right way to handle this from a test like this?
- memset(&cls, 0, sizeof(cls));
- cls.cbSize = sizeof(cls);
- cls.hInstance = 0;
- cls.lpszClassName = mainwindowclassW;
- cls.lpfnWndProc = DefWindowProcW;
- RegisterClassExW(&cls);
- 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));
Unnecessary white lines and same in below.
- 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(misc) +{
- RegisterDeviceNotificationTest();
+}
On 5/19/19 10:58 PM, Micah N Gorrell wrote:
On Sun, May 19, 2019 at 02:08:26PM +0800, Zhiyi Zhang wrote:
On 5/19/19 5:43 AM, Micah N Gorrell wrote:
Signed-off-by: Micah N Gorrell mgorrell@codeweavers.com
dlls/user32/tests/Makefile.in | 1 + dlls/user32/tests/misc.c | 89 +++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 dlls/user32/tests/misc.c
diff --git a/dlls/user32/tests/Makefile.in b/dlls/user32/tests/Makefile.in index 7149dc824e..da55fa58e5 100644 --- a/dlls/user32/tests/Makefile.in +++ b/dlls/user32/tests/Makefile.in @@ -15,6 +15,7 @@ C_SRCS = \ input.c \ listbox.c \ menu.c \
- misc.c \ monitor.c \ msg.c \ resource.c \
diff --git a/dlls/user32/tests/misc.c b/dlls/user32/tests/misc.c new file mode 100644 index 0000000000..c0a4af6636 --- /dev/null +++ b/dlls/user32/tests/misc.c @@ -0,0 +1,89 @@ +/*
- 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;
- WNDCLASSEXW cls;
- GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
Hi Micah,
You could just include hidclass.h to get GUID_DEVINTERFACE_HID. And testbots are failing. You need to fix the tests.
Just including hidclass.h does not appear to be sufficient since it is an extern and the user32 tests do not link with hid. What is the right way to handle this from a test like this?
Adding #include "initguid.h" should resolve it.
- memset(&cls, 0, sizeof(cls));
- cls.cbSize = sizeof(cls);
- cls.hInstance = 0;
- cls.lpszClassName = mainwindowclassW;
- cls.lpfnWndProc = DefWindowProcW;
- RegisterClassExW(&cls);
- 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));
Unnecessary white lines and same in below.
- 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(misc) +{
- RegisterDeviceNotificationTest();
+}