[PATCH 3/5] user32: Implemented RegisterDeviceNotification
Micah N Gorrell
mgorrell at codeweavers.com
Fri May 17 19:35:26 CDT 2019
Signed-off-by: Micah N Gorrell <mgorrell at 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();
+}
+
--
2.21.0
More information about the wine-devel
mailing list