Zebediah Figura : user32: Use registry APIs to enumerate raw input devices.
Alexandre Julliard
julliard at winehq.org
Fri Jun 10 16:28:26 CDT 2022
Module: wine
Branch: master
Commit: b0731f6e7e281620fe6e6b809ea84be72ea77b9e
URL: https://source.winehq.org/git/wine.git/?a=commit;h=b0731f6e7e281620fe6e6b809ea84be72ea77b9e
Author: Zebediah Figura <zfigura at codeweavers.com>
Date: Sun May 15 12:31:09 2022 -0500
user32: Use registry APIs to enumerate raw input devices.
---
dlls/user32/rawinput.c | 119 ++++++++++++++++++++++++++++++++++---------------
1 file changed, 84 insertions(+), 35 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index 3750332c0cf..ab542956f11 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -30,18 +30,13 @@
#include "winnls.h"
#include "winreg.h"
#include "winuser.h"
-#include "setupapi.h"
+#include "ddk/hidclass.h"
#include "wine/debug.h"
#include "wine/server.h"
#include "wine/hid.h"
#include "user_private.h"
-#include "initguid.h"
-#include "ddk/hidclass.h"
-#include "ntddmou.h"
-#include "ntddkbd.h"
-
WINE_DEFAULT_DEBUG_CHANNEL(rawinput);
struct device
@@ -92,40 +87,47 @@ static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int
return TRUE;
}
-static struct device *add_device( HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface, DWORD type )
+static ULONG query_reg_value( HKEY hkey, const WCHAR *name,
+ KEY_VALUE_PARTIAL_INFORMATION *info, ULONG size )
{
+ unsigned int name_size = name ? lstrlenW( name ) * sizeof(WCHAR) : 0;
+ UNICODE_STRING nameW = { name_size, name_size, (WCHAR *)name };
+
+ if (NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation,
+ info, size, &size ))
+ return 0;
+
+ return size - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
+}
+
+static struct device *add_device( HKEY key, DWORD type )
+{
+ static const WCHAR symbolic_linkW[] = {'S','y','m','b','o','l','i','c','L','i','n','k',0};
+ char value_buffer[4096];
+ KEY_VALUE_PARTIAL_INFORMATION *value = (KEY_VALUE_PARTIAL_INFORMATION *)value_buffer;
static const RID_DEVICE_INFO_KEYBOARD keyboard_info = {0, 0, 1, 12, 3, 101};
static const RID_DEVICE_INFO_MOUSE mouse_info = {1, 5, 0, FALSE};
- SP_DEVINFO_DATA device_data = {sizeof(device_data)};
struct hid_preparsed_data *preparsed = NULL;
- SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail;
HID_COLLECTION_INFORMATION hid_info;
struct device *device = NULL;
RID_DEVICE_INFO info;
IO_STATUS_BLOCK io;
WCHAR *path, *pos;
NTSTATUS status;
+ unsigned int i;
UINT32 handle;
- DWORD i, size;
HANDLE file;
- SetupDiGetDeviceInterfaceDetailW(set, iface, NULL, 0, &size, &device_data);
- if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ if (!query_reg_value( key, symbolic_linkW, value, sizeof(value_buffer) ))
{
- ERR("Failed to get device path, error %#lx.\n", GetLastError());
- return FALSE;
+ ERR( "failed to get symbolic link value\n" );
+ return NULL;
}
- if (!(detail = malloc(size)))
- {
- ERR("Failed to allocate memory.\n");
- return FALSE;
- }
- detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
- SetupDiGetDeviceInterfaceDetailW(set, iface, detail, size, NULL, NULL);
- path = wcsdup( detail->DevicePath );
- free( detail );
- if (!path) return NULL;
+ if (!(path = malloc( value->DataLength + sizeof(WCHAR) )))
+ return NULL;
+ memcpy( path, value->Data, value->DataLength );
+ path[value->DataLength / sizeof(WCHAR)] = 0;
/* upper case everything but the GUID */
for (pos = path; *pos && *pos != '{'; pos++) *pos = towupper(*pos);
@@ -234,18 +236,65 @@ fail:
return NULL;
}
-static void enumerate_devices( DWORD type, const GUID *guid )
+static HKEY reg_open_key( HKEY root, const WCHAR *name, ULONG name_len )
{
- SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)};
- HDEVINFO set;
- DWORD idx;
+ UNICODE_STRING nameW = { name_len, name_len, (WCHAR *)name };
+ OBJECT_ATTRIBUTES attr;
+ HANDLE ret;
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = root;
+ attr.ObjectName = &nameW;
+ attr.Attributes = 0;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+
+ if (NtOpenKeyEx( &ret, MAXIMUM_ALLOWED, &attr, 0 )) return 0;
+ return ret;
+}
- set = SetupDiGetClassDevsW( guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT );
+static const WCHAR device_classesW[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\DeviceClasses\\";
+static const WCHAR guid_devinterface_hidW[] = L"{4d1e55b2-f16f-11cf-88cb-001111000030}";
+static const WCHAR guid_devinterface_keyboardW[] = L"{884b96c3-56ef-11d1-bc8c-00a0c91405dd}";
+static const WCHAR guid_devinterface_mouseW[] = L"{378de44c-56ef-11d1-bc8c-00a0c91405dd}";
- for (idx = 0; SetupDiEnumDeviceInterfaces( set, NULL, &GUID_DEVINTERFACE_HID, idx, &iface); ++idx )
- add_device( set, &iface, type );
+static void enumerate_devices( DWORD type, const WCHAR *class )
+{
+ WCHAR buffer[1024];
+ KEY_NODE_INFORMATION *subkey_info = (void *)buffer;
+ HKEY class_key, device_key, iface_key;
+ unsigned int i, j;
+ DWORD size;
+
+ wcscpy( buffer, device_classesW );
+ wcscat( buffer, class );
+ if (!(class_key = reg_open_key( NULL, buffer, wcslen( buffer ) * sizeof(WCHAR) )))
+ return;
+
+ for (i = 0; !NtEnumerateKey( class_key, i, KeyNodeInformation, buffer, sizeof(buffer), &size ); ++i)
+ {
+ if (!(device_key = reg_open_key( class_key, subkey_info->Name, subkey_info->NameLength )))
+ {
+ ERR( "failed to open %s\n", debugstr_wn(subkey_info->Name, subkey_info->NameLength / sizeof(WCHAR)) );
+ continue;
+ }
+
+ for (j = 0; !NtEnumerateKey( device_key, j, KeyNodeInformation, buffer, sizeof(buffer), &size ); ++j)
+ {
+ if (!(iface_key = reg_open_key( device_key, subkey_info->Name, subkey_info->NameLength )))
+ {
+ ERR( "failed to open %s\n", debugstr_wn(subkey_info->Name, subkey_info->NameLength / sizeof(WCHAR)) );
+ continue;
+ }
+
+ add_device( iface_key, type );
+ NtClose( iface_key );
+ }
+
+ NtClose( device_key );
+ }
- SetupDiDestroyDeviceInfoList( set );
+ NtClose( class_key );
}
void rawinput_update_device_list(void)
@@ -265,9 +314,9 @@ void rawinput_update_device_list(void)
}
rawinput_devices_count = 0;
- enumerate_devices( RIM_TYPEHID, &GUID_DEVINTERFACE_HID );
- enumerate_devices( RIM_TYPEMOUSE, &GUID_DEVINTERFACE_MOUSE );
- enumerate_devices( RIM_TYPEKEYBOARD, &GUID_DEVINTERFACE_KEYBOARD );
+ enumerate_devices( RIM_TYPEHID, guid_devinterface_hidW );
+ enumerate_devices( RIM_TYPEMOUSE, guid_devinterface_mouseW );
+ enumerate_devices( RIM_TYPEKEYBOARD, guid_devinterface_keyboardW );
LeaveCriticalSection(&rawinput_devices_cs);
}
More information about the wine-cvs
mailing list