From 7c463a028b496e79cb574b336f0715d3ccf11b80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincas=20Mili=C5=ABnas?= Date: Sun, 26 Jun 2011 23:25:33 +0300 Subject: [PATCH 14/20] server+user32: Added GetRawInputDeviceInfoW implementation (try 16) --- dlls/user32/input.c | 42 +++++++++++++++++++++++++++++++- dlls/user32/tests/input.c | 28 +++++++++++----------- server/protocol.def | 10 +++++++ server/raw_input.c | 58 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+), 16 deletions(-) diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 8e33f13..59ec0ac 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -562,9 +562,47 @@ UINT WINAPI GetRawInputDeviceInfoA(HANDLE hDevice, UINT uiCommand, LPVOID pData, */ UINT WINAPI GetRawInputDeviceInfoW(HANDLE hDevice, UINT uiCommand, LPVOID pData, PUINT pcbSize) { - FIXME("(hDevice=%p, uiCommand=%d, pData=%p, pcbSize=%p) stub!\n", hDevice, uiCommand, pData, pcbSize); + BOOL ret; + UINT result, size_in_bytes; - return 0; + TRACE("(hDevice=%p, uiCommand=%d, pData=%p, pcbSize=%p)\n", hDevice, uiCommand, pData, pcbSize); + + if (pcbSize == NULL) + { + SetLastError( ERROR_NOACCESS ); + return (UINT)-1; + } + if (uiCommand == RIDI_DEVICEINFO && pData != NULL) + { + RID_DEVICE_INFO *info = (RID_DEVICE_INFO *)pData; + if (info->cbSize != sizeof( RID_DEVICE_INFO )) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return (UINT)-1; + } + } + + size_in_bytes = uiCommand == RIDI_DEVICENAME ? *pcbSize * sizeof( WCHAR ) : *pcbSize; + + SERVER_START_REQ( get_raw_input_device_info ) + { + req->handle = wine_server_user_handle( hDevice ); + req->command = uiCommand; + req->report_size_only = pData == NULL; + if (pData != NULL) + wine_server_set_reply( req, pData, size_in_bytes ); + ret = !wine_server_call_err( req ); + if (!ret || pData == NULL) + { + *pcbSize = reply->size; + result = 0; + } + else + result = reply->size; + } + SERVER_END_REQ; + + return ret ? result : (UINT)-1; } diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index b556126..c5045e8 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -1711,18 +1711,18 @@ static void test_get_raw_input_device_info_w(void) SetLastError(0xdeadbeef); ret = pGetRawInputDeviceInfoW(NULL, 0, NULL, NULL); error = GetLastError(); - todo_wine ok(ret == (UINT)-1, "GetRawInputDeviceInfoW returned wrong value: " + ok(ret == (UINT)-1, "GetRawInputDeviceInfoW returned wrong value: " "expected (UINT)-1, got %u\n", ret); - todo_wine ok(error == ERROR_NOACCESS, "GetRawInputDeviceInfoW returned " + ok(error == ERROR_NOACCESS, "GetRawInputDeviceInfoW returned " "wrong error code: %u\n", error); SetLastError(0xdeadbeef); size = 0; ret = pGetRawInputDeviceInfoW(NULL, 0, NULL, &size); error = GetLastError(); - todo_wine ok(ret == (UINT)-1, + ok(ret == (UINT)-1, "GetRawInputDeviceInfoW returned wrong value: expected (UINT)-1, got %u\n", ret); - todo_wine ok(error == ERROR_INVALID_HANDLE, + ok(error == ERROR_INVALID_HANDLE, "GetRawInputDeviceInfoW returned wrong error code: %u\n", error); ret = pGetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)); @@ -1742,51 +1742,51 @@ static void test_get_raw_input_device_info_w(void) size = 0; ret = pGetRawInputDeviceInfoW(devices[0].hDevice, 0, NULL, &size); error = GetLastError(); - todo_wine ok(ret == (UINT)-1, "GetRawInputDeviceInfoW returned wrong value: " + ok(ret == (UINT)-1, "GetRawInputDeviceInfoW returned wrong value: " "expected (UINT)-1, got %u\n", ret); - todo_wine ok(error == ERROR_INVALID_PARAMETER, "GetRawInputDeviceInfoW returned " + ok(error == ERROR_INVALID_PARAMETER, "GetRawInputDeviceInfoW returned " "wrong error code: %u\n", error); SetLastError(0xdeadbeef); size = 0; ret = pGetRawInputDeviceInfoW(devices[0].hDevice, RIDI_DEVICENAME, buffer, &size); error = GetLastError(); - todo_wine ok(ret == (UINT)-1, "GetRawInputDeviceInfoW returned wrong value: " + ok(ret == (UINT)-1, "GetRawInputDeviceInfoW returned wrong value: " "expected (UINT)-1, got %u\n", ret); - todo_wine ok(error == ERROR_INSUFFICIENT_BUFFER, "GetRawInputDeviceInfoW returned " + ok(error == ERROR_INSUFFICIENT_BUFFER, "GetRawInputDeviceInfoW returned " "wrong error code: %u\n", error); size = 0; ret = pGetRawInputDeviceInfoW(devices[0].hDevice, RIDI_DEVICENAME, NULL, &size); ok(ret == 0, "GetRawInputDeviceInfoW returned wrong value: expected 0, got %u\n", ret); - todo_wine ok(size > 5, "GetRawInputDeviceInfoW returned wrong " + ok(size > 5, "GetRawInputDeviceInfoW returned wrong " "device name size: expected x > 5, got %u\n", size); buffer[0] = 0; ret = pGetRawInputDeviceInfoW(devices[0].hDevice, RIDI_DEVICENAME, buffer, &size); - todo_wine ok(ret != (UINT)-1 && ret > 0, "GetRawInputDeviceInfoW returned wrong value: " + ok(ret != (UINT)-1 && ret > 0, "GetRawInputDeviceInfoW returned wrong value: " "expected 0 < x < (UINT)-1, got %u\n", ret); size = lstrlenW(buffer); - todo_wine ok(size > 5, "GetRawInputDeviceInfoW returned too short device name: " + ok(size > 5, "GetRawInputDeviceInfoW returned too short device name: " "expected x > 5, got %u\n", size); size = 0; ret = pGetRawInputDeviceInfoW(devices[0].hDevice, RIDI_DEVICEINFO, NULL, &size); ok(ret == 0, "GetRawInputDeviceInfoW returned wrong value: expected 0, got %u\n", ret); - todo_wine ok(size == sizeof(RID_DEVICE_INFO), "GetRawInputDeviceInfoW returned " + ok(size == sizeof(RID_DEVICE_INFO), "GetRawInputDeviceInfoW returned " "wrong device info size: expected sizeof(RID_DEVICE_INFO), got %u\n", size); size = sizeof(RID_DEVICE_INFO); info.cbSize = sizeof(RID_DEVICE_INFO); ret = pGetRawInputDeviceInfoW(devices[0].hDevice, RIDI_DEVICEINFO, &info, &size); - todo_wine ok(ret == sizeof(RID_DEVICE_INFO), "GetRawInputDeviceInfoW returned wrong value: " + ok(ret == sizeof(RID_DEVICE_INFO), "GetRawInputDeviceInfoW returned wrong value: " "expected sizeof(RID_DEVICE_INFO), got %u\n", ret); size = 0xdeadbeef; ret = pGetRawInputDeviceInfoW(devices[0].hDevice, RIDI_PREPARSEDDATA, NULL, &size); ok(ret == 0, "GetRawInputDeviceInfoW returned wrong value: " "expected 0, got %u\n", ret); - todo_wine ok(size == 0, "GetRawInputDeviceInfoW returned wrong preparsed data size: " + ok(size == 0, "GetRawInputDeviceInfoW returned wrong preparsed data size: " "expected 0, got %u\n", size); HeapFree(GetProcessHeap(), 0, devices); diff --git a/server/protocol.def b/server/protocol.def index d715a10..85efb12 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3374,3 +3374,13 @@ enum coords_relative unsigned int num_devices; /* number of raw input device in the system */ VARARG(devices,bytes); /* RAWINPUTDEVICELIST structures */ @END + +/* Get the raw input device info */ +@REQ(get_raw_input_device_info) + user_handle_t handle; /* raw input device handle */ + unsigned int command; /* desired characteristic of the device */ + unsigned int report_size_only; /* reply only the with the required size to store the data */ +@REPLY + data_size_t size; /* size of the data about the device */ + VARARG(info,bytes); /* string or data structure about the device */ +@END diff --git a/server/raw_input.c b/server/raw_input.c index 20a7331..b57181e 100644 --- a/server/raw_input.c +++ b/server/raw_input.c @@ -101,3 +101,61 @@ DECL_HANDLER(get_raw_input_device_list) result[i].dwType = raw_devices[i].info.dwType; } } + +/* Get the raw input device info */ +DECL_HANDLER(get_raw_input_device_info) +{ + BOOL valid = FALSE; + unsigned int i, size_in_bytes; + void *source = NULL; + + for (i = 0; i < NUM_RAW_DEVICES; i++) + { + if (raw_devices[i].handle != req->handle) + continue; + valid = TRUE; + + switch (req->command) + { + case RIDI_DEVICENAME: + /* reply->size is the character count */ + reply->size = lstrlenW( raw_devices[i].name ) + 1; + source = (void *)raw_devices[i].name; + break; + case RIDI_DEVICEINFO: + reply->size = sizeof( RID_DEVICE_INFO ); + source = (void *)&raw_devices[i].info; + break; + case RIDI_PREPARSEDDATA: + /* No preparsed data available */ + reply->size = 0; + break; + default: + set_error( STATUS_INVALID_PARAMETER ); + break; + } + if (get_error() > 0 || req->report_size_only) + break; + + size_in_bytes = req->command == RIDI_DEVICENAME ? + reply->size * sizeof( WCHAR ) : reply->size; + if (size_in_bytes > get_reply_max_size()) + { + set_error( STATUS_BUFFER_TOO_SMALL ); + } + else if (size_in_bytes > 0) + { + void *target = set_reply_data_size( size_in_bytes ); + if (!target) + { + set_error( STATUS_NO_MEMORY ); + break; + } + + memcpy( target, source, size_in_bytes ); + } + break; + } + if (!valid) + set_error( STATUS_INVALID_HANDLE ); +} -- 1.7.3.4