Rémi Bernon : win32u: Read rawinput device preparsed data using virtual memory.

Alexandre Julliard julliard at winehq.org
Wed Jul 27 16:17:08 CDT 2022


Module: wine
Branch: master
Commit: 4c584fe773a75632fbfbb371f23036f8fd1a453c
URL:    https://gitlab.winehq.org/wine/wine/-/commit/4c584fe773a75632fbfbb371f23036f8fd1a453c

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Tue Jul 26 09:17:12 2022 +0200

win32u: Read rawinput device preparsed data using virtual memory.

---

 dlls/dinput/tests/joystick8.c | 12 ++++++------
 dlls/win32u/rawinput.c        | 21 ++++++++++++++++++---
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c
index 3193ee12ddc..0981d917b2a 100644
--- a/dlls/dinput/tests/joystick8.c
+++ b/dlls/dinput/tests/joystick8.c
@@ -4308,7 +4308,12 @@ static void test_rawinput(void)
 
     count = ARRAY_SIZE(raw_device_list);
     res = GetRawInputDeviceList( raw_device_list, &count, sizeof(RAWINPUTDEVICELIST) );
-    todo_wine
+    if (!strcmp( winetest_platform, "wine" ) && res == device_count)
+    {
+        /* Wine refreshes its device list every 2s, but GetRawInputDeviceInfoW with an unknown handle will force it */
+        GetRawInputDeviceInfoW( (HANDLE)0xdeadbeef, RIDI_DEVICEINFO, NULL, &count );
+        res = GetRawInputDeviceList( raw_device_list, &count, sizeof(RAWINPUTDEVICELIST) );
+    }
     ok( res == device_count + 1, "GetRawInputDeviceList returned %lu\n", res );
     ok( count == ARRAY_SIZE(raw_device_list), "got count %u\n", count );
     device_count = res;
@@ -4326,9 +4331,7 @@ static void test_rawinput(void)
         if (wcsstr( path, expect_vidpid_str )) break;
     }
 
-    todo_wine
     ok( !!wcsstr( path, expect_vidpid_str ), "got path %s\n", debugstr_w(path) );
-    if (!wcsstr( path, expect_vidpid_str )) goto done;
 
 
     file = CreateFileW( path, FILE_READ_ACCESS | FILE_WRITE_ACCESS,
@@ -4346,12 +4349,9 @@ static void test_rawinput(void)
         while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
 
         ok( !wm_input_device_change_count, "got %u WM_INPUT_DEVICE_CHANGE\n", wm_input_device_change_count );
-        todo_wine
         ok( wm_input_count == 1, "got %u WM_INPUT\n", wm_input_count );
-        todo_wine
         ok( wm_input_len == offsetof(RAWINPUT, data.hid.bRawData[desc.caps.InputReportByteLength]),
             "got wm_input_len %u\n", wm_input_len );
-        todo_wine
         ok( !memcmp( rawinput->data.hid.bRawData, injected_input[i].report_buf, desc.caps.InputReportByteLength ),
             "got unexpected report data\n" );
         wm_input_count = 0;
diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c
index 6a018e15bb7..dd697017953 100644
--- a/dlls/win32u/rawinput.c
+++ b/dlls/win32u/rawinput.c
@@ -253,6 +253,8 @@ static struct device *add_device( HKEY key, DWORD type )
     NTSTATUS status;
     unsigned int i;
     UINT32 handle;
+    void *buffer;
+    SIZE_T size;
     HANDLE file;
 
     if (!query_reg_value( key, symbolic_linkW, value, sizeof(value_buffer) ))
@@ -327,9 +329,22 @@ static struct device *add_device( HKEY key, DWORD type )
             goto fail;
         }
 
-        status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io,
-                                        IOCTL_HID_GET_COLLECTION_DESCRIPTOR,
-                                        NULL, 0, preparsed, hid_info.DescriptorSize );
+        /* NtDeviceIoControlFile checks that the output buffer is writable using ntdll virtual
+         * memory protection information, we need an NtAllocateVirtualMemory allocated buffer.
+         */
+        buffer = NULL;
+        size = hid_info.DescriptorSize;
+        if (!(status = NtAllocateVirtualMemory( GetCurrentProcess(), &buffer, 0, &size,
+                                                MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE )))
+        {
+            size = 0;
+            status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io,
+                                            IOCTL_HID_GET_COLLECTION_DESCRIPTOR,
+                                            NULL, 0, buffer, hid_info.DescriptorSize );
+            if (!status) memcpy( preparsed, buffer, hid_info.DescriptorSize );
+            NtFreeVirtualMemory( GetCurrentProcess(), &buffer, &size, MEM_RELEASE );
+        }
+
         if (status)
         {
             ERR( "Failed to get collection descriptor, status %#x.\n", status );




More information about the wine-cvs mailing list