[PATCH v3 2/6] user32: Implement GetRegisteredRawInputDevices.
Rémi Bernon
rbernon at codeweavers.com
Fri Jul 3 04:57:03 CDT 2020
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
v3: return STATUS_BUFFER_TOO_SMALL when appropriate and use
wine_server_call_err to set last error from status.
The case where client buffer is not NULL but *device_count is 0 is
treated as an invalid parameter combination, as it is the case on
some windows versions. It then simplifies the server code where
we can handle get_reply_max_size() == 0 as the NULL buffer case.
dlls/dinput8/tests/device.c | 13 ----------
dlls/user32/rawinput.c | 50 +++++++++++++++++++++++++++++++++++--
dlls/user32/tests/input.c | 15 -----------
server/protocol.def | 6 +++++
server/queue.c | 22 ++++++++++++++++
5 files changed, 76 insertions(+), 30 deletions(-)
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c
index 39c635f2fb9..328174e5796 100644
--- a/dlls/dinput8/tests/device.c
+++ b/dlls/dinput8/tests/device.c
@@ -602,7 +602,6 @@ static void test_mouse_keyboard(void)
raw_devices_count = ARRAY_SIZE(raw_devices);
GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
- todo_wine
ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
hr = IDirectInputDevice8_Acquire(di_keyboard);
@@ -624,7 +623,6 @@ static void test_mouse_keyboard(void)
ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
raw_devices_count = ARRAY_SIZE(raw_devices);
GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
- todo_wine
ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
if (raw_devices[0].hwndTarget != NULL)
@@ -662,7 +660,6 @@ static void test_mouse_keyboard(void)
ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
raw_devices_count = ARRAY_SIZE(raw_devices);
GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
- todo_wine
ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
/* expect dinput8 to take over any activated raw input devices */
@@ -689,26 +686,18 @@ static void test_mouse_keyboard(void)
raw_devices_count = ARRAY_SIZE(raw_devices);
memset(raw_devices, 0, sizeof(raw_devices));
hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
- todo_wine
ok(hr == 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
- todo_wine
ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
- todo_wine
ok(raw_devices[0].usUsage == 2, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
todo_wine
ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
todo_wine
ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
- todo_wine
ok(raw_devices[1].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage);
- todo_wine
ok(raw_devices[1].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage);
ok(raw_devices[1].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags);
- todo_wine
ok(raw_devices[1].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget);
- todo_wine
ok(raw_devices[2].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage);
- todo_wine
ok(raw_devices[2].usUsage == 6, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage);
todo_wine
ok(raw_devices[2].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags);
@@ -727,12 +716,10 @@ static void test_mouse_keyboard(void)
hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
todo_wine
ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
- todo_wine
ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
todo_wine
ok(raw_devices[0].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
ok(raw_devices[0].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
- todo_wine
ok(raw_devices[0].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
IDirectInputDevice8_Release(di_mouse);
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index b5af008e885..f33f21eee9d 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -732,14 +732,60 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT
return *data_size;
}
+static int compare_raw_input_devices(const void *ap, const void *bp)
+{
+ const RAWINPUTDEVICE a = *(const RAWINPUTDEVICE *)ap;
+ const RAWINPUTDEVICE b = *(const RAWINPUTDEVICE *)bp;
+
+ if (a.usUsagePage != b.usUsagePage) return a.usUsagePage - b.usUsagePage;
+ if (a.usUsage != b.usUsage) return a.usUsage - b.usUsage;
+ return 0;
+}
+
/***********************************************************************
* GetRegisteredRawInputDevices (USER32.@)
*/
UINT WINAPI DECLSPEC_HOTPATCH GetRegisteredRawInputDevices(RAWINPUTDEVICE *devices, UINT *device_count, UINT size)
{
- FIXME("devices %p, device_count %p, size %u stub!\n", devices, device_count, size);
+ struct rawinput_device *buffer = NULL;
+ unsigned int i, status, count = ~0U, buffer_size;
- return 0;
+ TRACE("devices %p, device_count %p, size %u\n", devices, device_count, size);
+
+ if (size != sizeof(RAWINPUTDEVICE) || !device_count || (devices && !*device_count))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return ~0U;
+ }
+
+ buffer_size = *device_count * sizeof(*buffer);
+ if (devices && !(buffer = HeapAlloc(GetProcessHeap(), 0, buffer_size)))
+ return ~0U;
+
+ SERVER_START_REQ(get_rawinput_devices)
+ {
+ if (buffer) wine_server_set_reply(req, buffer, buffer_size);
+ status = wine_server_call_err(req);
+ *device_count = reply->device_count;
+ }
+ SERVER_END_REQ;
+
+ if (buffer && !status)
+ {
+ for (i = 0, count = *device_count; i < count; ++i)
+ {
+ devices[i].usUsagePage = buffer[i].usage_page;
+ devices[i].usUsage = buffer[i].usage;
+ devices[i].dwFlags = buffer[i].flags;
+ devices[i].hwndTarget = wine_server_ptr_handle(buffer[i].target);
+ }
+
+ qsort(devices, count, sizeof(*devices), compare_raw_input_devices);
+ }
+
+ if (buffer) HeapFree(GetProcessHeap(), 0, buffer);
+ else count = 0;
+ return count;
}
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
index 4310ad1f296..cea8f375398 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -1794,25 +1794,20 @@ static void test_RegisterRawInputDevices(void)
SetLastError(0xdeadbeef);
count = GetRegisteredRawInputDevices(NULL, NULL, 0);
- todo_wine
ok(count == ~0U, "GetRegisteredRawInputDevices returned %u\n", count);
- todo_wine
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetRegisteredRawInputDevices unexpected error %08x\n", GetLastError());
SetLastError(0xdeadbeef);
raw_devices_count = 0;
count = GetRegisteredRawInputDevices(NULL, &raw_devices_count, 0);
- todo_wine
ok(count == ~0U, "GetRegisteredRawInputDevices returned %u\n", count);
ok(raw_devices_count == 0, "Unexpected registered devices count: %u\n", raw_devices_count);
- todo_wine
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetRegisteredRawInputDevices unexpected error %08x\n", GetLastError());
SetLastError(0xdeadbeef);
raw_devices_count = 0;
count = GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
ok(count == 0, "GetRegisteredRawInputDevices returned %u\n", count);
- todo_wine
ok(raw_devices_count == 2, "Unexpected registered devices count: %u\n", raw_devices_count);
ok(GetLastError() == 0xdeadbeef, "GetRegisteredRawInputDevices unexpected error %08x\n", GetLastError());
@@ -1823,38 +1818,28 @@ static void test_RegisterRawInputDevices(void)
win_skip("Ignoring GetRegisteredRawInputDevices success\n");
else
{
- todo_wine
ok(count == ~0U, "GetRegisteredRawInputDevices returned %u\n", count);
ok(raw_devices_count == 0, "Unexpected registered devices count: %u\n", raw_devices_count);
- todo_wine
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetRegisteredRawInputDevices unexpected error %08x\n", GetLastError());
}
SetLastError(0xdeadbeef);
raw_devices_count = 1;
count = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
- todo_wine
ok(count == ~0U, "GetRegisteredRawInputDevices returned %u\n", count);
- todo_wine
ok(raw_devices_count == 2, "Unexpected registered devices count: %u\n", raw_devices_count);
- todo_wine
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetRegisteredRawInputDevices unexpected error %08x\n", GetLastError());
SetLastError(0xdeadbeef);
memset(raw_devices, 0, sizeof(raw_devices));
raw_devices_count = ARRAY_SIZE(raw_devices);
count = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
- todo_wine
ok(count == 2, "GetRegisteredRawInputDevices returned %u\n", count);
ok(raw_devices_count == 2, "Unexpected registered devices count: %u\n", raw_devices_count);
ok(GetLastError() == 0xdeadbeef, "GetRegisteredRawInputDevices unexpected error %08x\n", GetLastError());
- todo_wine
ok(raw_devices[0].usUsagePage == 0x01, "Unexpected usage page: %x\n", raw_devices[0].usUsagePage);
- todo_wine
ok(raw_devices[0].usUsage == 0x04, "Unexpected usage: %x\n", raw_devices[0].usUsage);
- todo_wine
ok(raw_devices[1].usUsagePage == 0x01, "Unexpected usage page: %x\n", raw_devices[1].usUsagePage);
- todo_wine
ok(raw_devices[1].usUsage == 0x05, "Unexpected usage: %x\n", raw_devices[1].usUsage);
/* RIDEV_REMOVE requires hwndTarget == NULL */
diff --git a/server/protocol.def b/server/protocol.def
index 6416306c0a1..56fda14932d 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3899,6 +3899,12 @@ struct handle_info
VARARG(devices,rawinput_devices);
@END
+/* Retrieve the list of registered rawinput devices */
+ at REQ(get_rawinput_devices)
+ at REPLY
+ unsigned int device_count;
+ VARARG(devices,rawinput_devices);
+ at END
/* Create a new job object */
@REQ(create_job)
diff --git a/server/queue.c b/server/queue.c
index 432885f9e4c..3ba774ebd1d 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -3283,3 +3283,25 @@ DECL_HANDLER(update_rawinput_devices)
e = find_rawinput_device( 1, 6 );
current->process->rawinput_kbd = e ? &e->device : NULL;
}
+
+DECL_HANDLER(get_rawinput_devices)
+{
+ struct rawinput_device_entry *e;
+ struct rawinput_device *devices;
+ unsigned int i = 0, device_count = list_count( ¤t->process->rawinput_devices );
+ unsigned int size = device_count * sizeof(*devices);
+
+ reply->device_count = device_count;
+
+ /* no buffer provided, nothing else to do */
+ if (!get_reply_max_size()) return;
+
+ if (size > get_reply_max_size())
+ set_error( STATUS_BUFFER_TOO_SMALL );
+ else if ((devices = mem_alloc( size )))
+ {
+ LIST_FOR_EACH_ENTRY( e, ¤t->process->rawinput_devices, struct rawinput_device_entry, entry )
+ devices[i++] = e->device;
+ set_reply_data_ptr( devices, size );
+ }
+}
--
2.27.0
More information about the wine-devel
mailing list