From f8f15c4873c8f803a31737792afe17c9f874467f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincas=20Mili=C5=ABnas?= Date: Sun, 26 Jun 2011 23:21:15 +0300 Subject: [PATCH 13/20] server+user32: Added GetRawInputDeviceList implementation (try 16) --- dlls/user32/input.c | 37 ++++++++++++++-- dlls/user32/tests/input.c | 12 +++--- server/Makefile.in | 1 + server/protocol.def | 9 ++++ server/raw_input.c | 103 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 151 insertions(+), 11 deletions(-) create mode 100644 server/raw_input.c diff --git a/dlls/user32/input.c b/dlls/user32/input.c index cbdb0d9..8e33f13 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -476,12 +476,39 @@ BOOL WINAPI GetLastInputInfo(PLASTINPUTINFO plii) */ UINT WINAPI GetRawInputDeviceList(PRAWINPUTDEVICELIST pRawInputDeviceList, PUINT puiNumDevices, UINT cbSize) { - FIXME("(pRawInputDeviceList=%p, puiNumDevices=%p, cbSize=%d) stub!\n", pRawInputDeviceList, puiNumDevices, cbSize); + BOOL ret = FALSE; + UINT result; - if(pRawInputDeviceList) - memset(pRawInputDeviceList, 0, sizeof *pRawInputDeviceList); - *puiNumDevices = 0; - return 0; + TRACE("(pRawInputDeviceList=%p, puiNumDevices=%p, cbSize=%d)\n", pRawInputDeviceList, puiNumDevices, cbSize); + + if (cbSize != sizeof( RAWINPUTDEVICELIST )) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return (UINT)-1; + } + if (puiNumDevices == NULL) + { + SetLastError( ERROR_NOACCESS ); + return (UINT)-1; + } + + SERVER_START_REQ( get_raw_input_device_list ) + { + req->report_size_only = pRawInputDeviceList == NULL; + if (pRawInputDeviceList != NULL) + wine_server_set_reply( req, pRawInputDeviceList, *puiNumDevices * sizeof( RAWINPUTDEVICELIST ) ); + ret = !wine_server_call_err( req ); + if (!ret || pRawInputDeviceList == NULL) + { + *puiNumDevices = reply->num_devices; + result = 0; + } + else + result = reply->num_devices; + } + SERVER_END_REQ; + + return ret ? result : (UINT)-1; } diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index e19712e..b556126 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -1662,7 +1662,7 @@ static void test_get_raw_input_device_list(void) ret = pGetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)); ok(ret == 0, "GetRawInputDeviceList returned wrong value: " "expected 0, got %u\n", ret); - todo_wine ok(count >= 1, "GetRawInputDeviceList returned incorrect number of " + ok(count >= 1, "GetRawInputDeviceList returned incorrect number of " "raw input device available: expected x >= 1, got %u\n", count); device_list = HeapAlloc(GetProcessHeap(), 0, count * sizeof(RAWINPUTDEVICELIST)); @@ -1672,9 +1672,9 @@ static void test_get_raw_input_device_list(void) count2 = 0; ret = pGetRawInputDeviceList(device_list, &count2, sizeof(RAWINPUTDEVICELIST)); error = GetLastError(); - todo_wine ok(ret == (UINT)-1, "GetRawInputDeviceList returned wrong value: " + ok(ret == (UINT)-1, "GetRawInputDeviceList returned wrong value: " "expected (UINT)-1, got %u\n", ret); - todo_wine ok(error == ERROR_INSUFFICIENT_BUFFER, "GetRawInputDeviceList returned " + ok(error == ERROR_INSUFFICIENT_BUFFER, "GetRawInputDeviceList returned " "wrong error code: %u\n", error); ok(count2 == count, "GetRawInputDeviceList returned incorrect number of devices: " "expected %u, got %u\n", count, count2); @@ -1686,7 +1686,7 @@ static void test_get_raw_input_device_list(void) ok(count2 == count, "GetRawInputDeviceList returned incorrect number of devices: " "expected %u, got %u\n", count, count2); - todo_wine ok(device_list[0].hDevice != NULL, "First raw input device doesn't have " + ok(device_list[0].hDevice != NULL, "First raw input device doesn't have " "a non-null handle\n"); ok(device_list[0].dwType == RIM_TYPEMOUSE || device_list[0].dwType == RIM_TYPEKEYBOARD, "First raw input device wasn't a mouse or a keyboard"); @@ -1727,7 +1727,7 @@ static void test_get_raw_input_device_info_w(void) ret = pGetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)); ok(ret == 0, "GetRawInputDeviceList failed to return raw input device count\n"); - todo_wine ok(count > 0, "Should have at least one raw input device available\n"); + ok(count > 0, "Should have at least one raw input device available\n"); devices = HeapAlloc(GetProcessHeap(), 0, count * sizeof(RAWINPUTDEVICELIST)); ok(devices != NULL, "Failed to allocate memory for raw input devices\n"); @@ -1825,7 +1825,7 @@ static void test_get_raw_input_device_info_a(void) ret = pGetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)); ok(ret == 0, "GetRawInputDeviceList failed to return raw input device count\n"); - todo_wine ok(count > 0, "Should have at least one raw input device available\n"); + ok(count > 0, "Should have at least one raw input device available\n"); devices = HeapAlloc(GetProcessHeap(), 0, count * sizeof(RAWINPUTDEVICELIST)); ok(devices != NULL, "Failed to allocate memory for raw input devices\n"); diff --git a/server/Makefile.in b/server/Makefile.in index a2f1a52..c12b2df 100644 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -28,6 +28,7 @@ C_SRCS = \ procfs.c \ ptrace.c \ queue.c \ + raw_input.c \ region.c \ registry.c \ request.c \ diff --git a/server/protocol.def b/server/protocol.def index 123f16a..d715a10 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3365,3 +3365,12 @@ enum coords_relative @REQ(set_suspend_context) VARARG(context,context); /* thread context */ @END + + +/* Get the raw input device list */ +@REQ(get_raw_input_device_list) + unsigned int report_size_only; /* reply only with the device count */ +@REPLY + unsigned int num_devices; /* number of raw input device in the system */ + VARARG(devices,bytes); /* RAWINPUTDEVICELIST structures */ +@END diff --git a/server/raw_input.c b/server/raw_input.c new file mode 100644 index 0000000..20a7331 --- /dev/null +++ b/server/raw_input.c @@ -0,0 +1,103 @@ +/* + * Server-side Raw Input Handling + * + * Copyright (C) 2011 Vincas Mili��nas + * + * 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 "config.h" +#include "wine/port.h" + +#include +#include +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winternl.h" + +#include "object.h" +#include "process.h" +#include "request.h" +#include "user.h" + +#define MOUSE_DEVICE_HANDLE ((user_handle_t)0x01) +#define KEYBOARD_DEVICE_HANDLE ((user_handle_t)0x02) + +#define HID_USAGE_PAGE_GENERIC ((unsigned short)0x01) +#define HID_USAGE_GENERIC_MOUSE ((unsigned short)0x02) +#define HID_USAGE_GENERIC_KEYBOARD ((unsigned short)0x06) + +struct raw_device +{ + user_handle_t handle; + const WCHAR *name; + RID_DEVICE_INFO info; +}; + +static const WCHAR mouse_raw_input_device_name[] = + {'W','I','N','E',' ','R','a','w',' ','I','n','p','u','t',' ', + 'M','o','u','s','e','\0'}; +static const WCHAR keyboard_raw_input_device_name[] = + {'W','I','N','E',' ','R','a','w',' ','I','n','p','u','t',' ', + 'K','e','y','b','o','a','r','d','\0'}; + +/* standard raw input devices with typical device info values */ +static const struct raw_device raw_devices[] = +{ + {MOUSE_DEVICE_HANDLE, mouse_raw_input_device_name, + {sizeof( RID_DEVICE_INFO ), RIM_TYPEMOUSE, {.mouse = {1, 3, 100, FALSE}}}}, + {KEYBOARD_DEVICE_HANDLE, keyboard_raw_input_device_name, + {sizeof( RID_DEVICE_INFO ), RIM_TYPEKEYBOARD, {.keyboard = {4, 0, 1, 12, 3, 101}}}} +}; +#define NUM_RAW_DEVICES (sizeof( raw_devices ) / sizeof( raw_devices[0] )) + +/* Get the raw input device list */ +DECL_HANDLER(get_raw_input_device_list) +{ + unsigned int i, size_in_bytes; + RAWINPUTDEVICELIST *result; + + reply->num_devices = NUM_RAW_DEVICES; + if (!reply->num_devices || req->report_size_only) + return; + + size_in_bytes = reply->num_devices * sizeof( RAWINPUTDEVICELIST ); + if (size_in_bytes > get_reply_max_size()) + { + set_error( STATUS_BUFFER_TOO_SMALL ); + return; + } + + result = set_reply_data_size( size_in_bytes ); + if (!result) + { + set_error( STATUS_NO_MEMORY ); + return; + } + + for (i = 0; i < reply->num_devices; i++) + { + /* Currently fake handles are provided, however they are only used to + identify the devices for the GetRawInputDeviceInfo function, thus it + should not create any undesirable side effects */ + result[i].hDevice = (HANDLE)raw_devices[i].handle; + result[i].dwType = raw_devices[i].info.dwType; + } +} -- 1.7.3.4