Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
June 2022
- 68 participants
- 3274 messages
[PATCH 2/5] evr: Release buffer after adding it to sample.
by Zhiyi Zhang
From: Zhiyi Zhang <zzhang(a)codeweavers.com>
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53201
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/evr/sample.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/dlls/evr/sample.c b/dlls/evr/sample.c
index f03292704b5..6a1bbf564f5 100644
--- a/dlls/evr/sample.c
+++ b/dlls/evr/sample.c
@@ -1747,7 +1747,10 @@ HRESULT WINAPI MFCreateVideoSampleFromSurface(IUnknown *surface, IMFSample **sam
}
if (buffer)
+ {
IMFSample_AddBuffer(object->sample, buffer);
+ IMFMediaBuffer_Release(buffer);
+ }
video_sample_create_tracking_thread();
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/345
June 30, 2022
[PATCH 1/5] winex11.drv: Use a global Vulkan instance in X11DRV_D3DKMTOpenAdapterFromLuid().
by Zhiyi Zhang
From: Zhiyi Zhang <zzhang(a)codeweavers.com>
This avoids opening multiple Vulkan instances when multiple D3D kernel mode adapters are open.
Some tests that leak reference to D3D adapters crash because of out of memory errors before this
patch.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53201
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53231
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53235
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/winex11.drv/x11drv_main.c | 62 ++++++++++++++++++++--------------
1 file changed, 36 insertions(+), 26 deletions(-)
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index dc987ae70a2..4e908f2918b 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -107,7 +107,6 @@ static pthread_mutex_t error_mutex = PTHREAD_MUTEX_INITIALIZER;
struct x11_d3dkmt_adapter
{
D3DKMT_HANDLE handle; /* Kernel mode graphics adapter handle */
- VkInstance vk_instance; /* Vulkan instance */
VkPhysicalDevice vk_device; /* Vulkan physical device */
struct list entry; /* List entry */
};
@@ -120,6 +119,7 @@ struct d3dkmt_vidpn_source
struct list entry; /* List entry */
};
+static VkInstance d3dkmt_vk_instance; /* Vulkan instance for D3DKMT functions */
static struct list x11_d3dkmt_adapters = LIST_INIT( x11_d3dkmt_adapters );
static struct list d3dkmt_vidpn_sources = LIST_INIT( d3dkmt_vidpn_sources ); /* VidPN source information list */
@@ -862,12 +862,17 @@ NTSTATUS CDECL X11DRV_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc )
{
if (adapter->handle == desc->hAdapter)
{
- vulkan_funcs->p_vkDestroyInstance(adapter->vk_instance, NULL);
list_remove(&adapter->entry);
free(adapter);
break;
}
}
+
+ if (list_empty(&x11_d3dkmt_adapters))
+ {
+ vulkan_funcs->p_vkDestroyInstance(d3dkmt_vk_instance, NULL);
+ d3dkmt_vk_instance = NULL;
+ }
pthread_mutex_unlock(&d3dkmt_mutex);
return STATUS_SUCCESS;
}
@@ -1134,7 +1139,6 @@ NTSTATUS CDECL X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *des
struct x11_d3dkmt_adapter *adapter;
VkInstanceCreateInfo create_info;
VkPhysicalDeviceIDProperties id;
- VkInstance vk_instance = NULL;
VkResult vr;
GUID uuid;
@@ -1152,30 +1156,35 @@ NTSTATUS CDECL X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *des
return STATUS_UNSUCCESSFUL;
}
- memset(&create_info, 0, sizeof(create_info));
- create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
- create_info.enabledExtensionCount = ARRAY_SIZE(extensions);
- create_info.ppEnabledExtensionNames = extensions;
+ pthread_mutex_lock(&d3dkmt_mutex);
- vr = vulkan_funcs->p_vkCreateInstance(&create_info, NULL, &vk_instance);
- if (vr != VK_SUCCESS)
+ if (!d3dkmt_vk_instance)
{
- WARN("Failed to create a Vulkan instance, vr %d.\n", vr);
- goto done;
+ memset(&create_info, 0, sizeof(create_info));
+ create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+ create_info.enabledExtensionCount = ARRAY_SIZE(extensions);
+ create_info.ppEnabledExtensionNames = extensions;
+
+ vr = vulkan_funcs->p_vkCreateInstance(&create_info, NULL, &d3dkmt_vk_instance);
+ if (vr != VK_SUCCESS)
+ {
+ WARN("Failed to create a Vulkan instance, vr %d.\n", vr);
+ goto done;
+ }
}
-#define LOAD_VK_FUNC(f) \
- if (!(p##f = (void *)vulkan_funcs->p_vkGetInstanceProcAddr(vk_instance, #f))) \
- { \
- WARN("Failed to load " #f ".\n"); \
- goto done; \
+#define LOAD_VK_FUNC(f) \
+ if (!(p##f = (void *)vulkan_funcs->p_vkGetInstanceProcAddr(d3dkmt_vk_instance, #f))) \
+ { \
+ WARN("Failed to load " #f ".\n"); \
+ goto done; \
}
LOAD_VK_FUNC(vkEnumeratePhysicalDevices)
LOAD_VK_FUNC(vkGetPhysicalDeviceProperties2KHR)
#undef LOAD_VK_FUNC
- vr = pvkEnumeratePhysicalDevices(vk_instance, &device_count, NULL);
+ vr = pvkEnumeratePhysicalDevices(d3dkmt_vk_instance, &device_count, NULL);
if (vr != VK_SUCCESS || !device_count)
{
WARN("No Vulkan device found, vr %d, device_count %d.\n", vr, device_count);
@@ -1185,7 +1194,7 @@ NTSTATUS CDECL X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *des
if (!(vk_physical_devices = calloc(device_count, sizeof(*vk_physical_devices))))
goto done;
- vr = pvkEnumeratePhysicalDevices(vk_instance, &device_count, vk_physical_devices);
+ vr = pvkEnumeratePhysicalDevices(d3dkmt_vk_instance, &device_count, vk_physical_devices);
if (vr != VK_SUCCESS)
{
WARN("vkEnumeratePhysicalDevices failed, vr %d.\n", vr);
@@ -1210,19 +1219,20 @@ NTSTATUS CDECL X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *des
}
adapter->handle = desc->hAdapter;
- adapter->vk_instance = vk_instance;
adapter->vk_device = vk_physical_devices[device_idx];
- pthread_mutex_lock(&d3dkmt_mutex);
list_add_head(&x11_d3dkmt_adapters, &adapter->entry);
- pthread_mutex_unlock(&d3dkmt_mutex);
- free(vk_physical_devices);
- return STATUS_SUCCESS;
+ status = STATUS_SUCCESS;
+ break;
}
done:
+ if (d3dkmt_vk_instance && list_empty(&x11_d3dkmt_adapters))
+ {
+ vulkan_funcs->p_vkDestroyInstance(d3dkmt_vk_instance, NULL);
+ d3dkmt_vk_instance = NULL;
+ }
+ pthread_mutex_unlock(&d3dkmt_mutex);
free(vk_physical_devices);
- if (vk_instance)
- vulkan_funcs->p_vkDestroyInstance(vk_instance, NULL);
return status;
}
@@ -1253,7 +1263,7 @@ NTSTATUS CDECL X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *d
if (adapter->handle != desc->hAdapter)
continue;
- if (!(pvkGetPhysicalDeviceMemoryProperties2KHR = (void *)vulkan_funcs->p_vkGetInstanceProcAddr(adapter->vk_instance, "vkGetPhysicalDeviceMemoryProperties2KHR")))
+ if (!(pvkGetPhysicalDeviceMemoryProperties2KHR = (void *)vulkan_funcs->p_vkGetInstanceProcAddr(d3dkmt_vk_instance, "vkGetPhysicalDeviceMemoryProperties2KHR")))
{
WARN("Failed to load vkGetPhysicalDeviceMemoryProperties2KHR.\n");
status = STATUS_UNSUCCESSFUL;
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/345
June 30, 2022
[PATCH 0/5] MR345: winex11.drv: Use a global Vulkan instance in X11DRV_D3DKMTOpenAdapterFromLuid().
by Zhiyi Zhang (ï¼ zhiyi)
This avoids opening multiple Vulkan instances when multiple D3D kernel mode adapters are open.
Some tests that leak reference to D3D adapters crash because of out of memory errors before this
patch.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53201
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53231
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53235
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/345
June 30, 2022
[PATCH] dlls/d3d10core: enable compilation with long types
by Eric Pouech
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
dlls/d3d10core/Makefile.in | 1 -
dlls/d3d10core/d3d10core_main.c | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/dlls/d3d10core/Makefile.in b/dlls/d3d10core/Makefile.in
index 9a828f17c031..9fe4ac96a78b 100644
--- a/dlls/d3d10core/Makefile.in
+++ b/dlls/d3d10core/Makefile.in
@@ -1,4 +1,3 @@
-EXTRADEFS = -DWINE_NO_LONG_TYPES
MODULE = d3d10core.dll
IMPORTLIB = d3d10core
IMPORTS = d3d11 dxgi
diff --git a/dlls/d3d10core/d3d10core_main.c b/dlls/d3d10core/d3d10core_main.c
index bbfa4e691afd..904a8afaadcf 100644
--- a/dlls/d3d10core/d3d10core_main.c
+++ b/dlls/d3d10core/d3d10core_main.c
@@ -51,7 +51,7 @@ HRESULT WINAPI D3D10CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapte
FreeLibrary(d3d11);
if (FAILED(hr))
{
- WARN("Failed to create device, hr %#x.\n", hr);
+ WARN("Failed to create device, hr %#lx.\n", hr);
return hr;
}
June 30, 2022
Re: [PATCH v3 0/3] MR330: Tests for properties.
by Ziqing Hui (ï¼ zhui)
On Thu Jun 30 01:20:10 2022 +0000, Nikolay Sivov wrote:
> Third patch crashes for me on Windows 10 21H1.
It passes all tests on testbot: https://testbot.winehq.org/JobDetails.pl?Key=117836
Of cause including win10 21H1 tests.
Also looks good on my local Win10 system.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/330#note_2991
June 30, 2022
Re: [PATCH v3 0/4] MR313: win32u: Finish moving raw input APIs.
by Zebediah Figura
On 6/28/22 12:24, Rémi Bernon (@rbernon) wrote:
> On Tue Jun 28 16:55:07 2022 +0000, **** wrote:
>> Zebediah Figura replied on the mailing list:
>> ```
>> On 6/28/22 02:10, Rémi Bernon (@rbernon) wrote:
>>> Rémi Bernon (@rbernon) commented about dlls/wow64win/user.c:
>>>> +
>>>> + if (size != sizeof(RAWINPUTDEVICELIST32))
>>>> + {
>>>> + SetLastError( ERROR_INVALID_PARAMETER );
>>>> + return ~0u;
>>>> + }
>>>> +
>>>> + if (devices32)
>>>> + {
>>>> + RAWINPUTDEVICELIST *devices64;
>>>> + unsigned int ret, i;
>>>> +
>>>> + if (!(devices64 = Wow64AllocateTemp( (*count) *
>> sizeof(*devices64) )))
>>>> + {
>>>> + SetLastError( ERROR_NOT_ENOUGH_MEMORY );
>>>> + return FALSE;
>>> This should be ~0u.
>>>
>> The bridge doesn't give me any context on which commit is being
>> responded to (is it not possible to reconstruct that information?) but
>> RegisterRawInputDevices() returns BOOL, so one of those three is correct.
>> The other two are errors; thanks for finding them. I've resent a new
>> version with them fixed.
>> ```
> It's in wow64_NtUserGetRawInputDeviceList, in PATCH 3.
>
Oops, indeed. I forgot that there were more than three functions that I
converted...
Sent a new version with that one fixed as well.
June 29, 2022
[PATCH v4 4/4] user32: Merge rawinput.c into input.c.
by Zebediah Figura
From: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/user32/Makefile.in | 1 -
dlls/user32/input.c | 49 +++++++++++++++++++++++
dlls/user32/rawinput.c | 88 -----------------------------------------
3 files changed, 49 insertions(+), 89 deletions(-)
delete mode 100644 dlls/user32/rawinput.c
diff --git a/dlls/user32/Makefile.in b/dlls/user32/Makefile.in
index 79821929390..3a01810991d 100644
--- a/dlls/user32/Makefile.in
+++ b/dlls/user32/Makefile.in
@@ -34,7 +34,6 @@ C_SRCS = \
nonclient.c \
painting.c \
property.c \
- rawinput.c \
resource.c \
scroll.c \
static.c \
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 52d4414b673..106f890da7a 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -6,6 +6,8 @@
* Copyright 1997 David Faure
* Copyright 1998 Morten Welinder
* Copyright 1998 Ulrich Weigand
+ * Copyright 2012 Henri Verbeet
+ * Copyright 2018 Zebediah Figura for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -623,3 +625,50 @@ BOOL WINAPI UnregisterDeviceNotification( HDEVNOTIFY handle )
return I_ScUnregisterDeviceNotification( handle );
}
+
+/***********************************************************************
+ * GetRawInputDeviceInfoA (USER32.@)
+ */
+UINT WINAPI GetRawInputDeviceInfoA( HANDLE device, UINT command, void *data, UINT *size )
+{
+ TRACE( "device %p, command %#x, data %p, size %p.\n", device, command, data, size );
+
+ /* RIDI_DEVICENAME size is in chars, not bytes */
+ if (command == RIDI_DEVICENAME)
+ {
+ WCHAR *nameW;
+ UINT ret, sizeW;
+
+ if (!size) return ~0U;
+
+ sizeW = *size;
+
+ if (data && sizeW > 0)
+ nameW = HeapAlloc( GetProcessHeap(), 0, sizeof(WCHAR) * sizeW );
+ else
+ nameW = NULL;
+
+ ret = NtUserGetRawInputDeviceInfo( device, command, nameW, &sizeW );
+
+ if (ret && ret != ~0U)
+ WideCharToMultiByte( CP_ACP, 0, nameW, -1, data, *size, NULL, NULL );
+
+ *size = sizeW;
+
+ HeapFree( GetProcessHeap(), 0, nameW );
+
+ return ret;
+ }
+
+ return NtUserGetRawInputDeviceInfo( device, command, data, size );
+}
+
+/***********************************************************************
+ * DefRawInputProc (USER32.@)
+ */
+LRESULT WINAPI DefRawInputProc( RAWINPUT **data, INT data_count, UINT header_size )
+{
+ FIXME( "data %p, data_count %d, header_size %u stub!\n", data, data_count, header_size );
+
+ return 0;
+}
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
deleted file mode 100644
index 98854d75690..00000000000
--- a/dlls/user32/rawinput.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Raw Input
- *
- * Copyright 2012 Henri Verbeet
- * Copyright 2018 Zebediah Figura for CodeWeavers
- *
- * 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 <stdarg.h>
-
-#include "ntstatus.h"
-#define WIN32_NO_STATUS
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winioctl.h"
-#include "winnls.h"
-#include "winreg.h"
-#include "winuser.h"
-#include "ddk/hidclass.h"
-#include "wine/debug.h"
-#include "wine/server.h"
-#include "wine/hid.h"
-
-#include "user_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(rawinput);
-
-/***********************************************************************
- * GetRawInputDeviceInfoA (USER32.@)
- */
-UINT WINAPI GetRawInputDeviceInfoA(HANDLE device, UINT command, void *data, UINT *data_size)
-{
- TRACE("device %p, command %#x, data %p, data_size %p.\n",
- device, command, data, data_size);
-
- /* RIDI_DEVICENAME data_size is in chars, not bytes */
- if (command == RIDI_DEVICENAME)
- {
- WCHAR *nameW;
- UINT ret, nameW_sz;
-
- if (!data_size) return ~0U;
-
- nameW_sz = *data_size;
-
- if (data && nameW_sz > 0)
- nameW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * nameW_sz);
- else
- nameW = NULL;
-
- ret = NtUserGetRawInputDeviceInfo( device, command, nameW, &nameW_sz );
-
- if (ret && ret != ~0U)
- WideCharToMultiByte(CP_ACP, 0, nameW, -1, data, *data_size, NULL, NULL);
-
- *data_size = nameW_sz;
-
- HeapFree(GetProcessHeap(), 0, nameW);
-
- return ret;
- }
-
- return NtUserGetRawInputDeviceInfo( device, command, data, data_size );
-}
-
-/***********************************************************************
- * DefRawInputProc (USER32.@)
- */
-LRESULT WINAPI DefRawInputProc(RAWINPUT **data, INT data_count, UINT header_size)
-{
- FIXME("data %p, data_count %d, header_size %u stub!\n", data, data_count, header_size);
-
- return 0;
-}
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/313
June 29, 2022
[PATCH v4 3/4] win32u: Move raw input device list management from user32.
by Zebediah Figura
From: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/user32/rawinput.c | 433 +---------------------------------
dlls/user32/user32.spec | 4 +-
dlls/user32/user_main.c | 2 -
dlls/user32/user_private.h | 6 -
dlls/win32u/message.c | 5 +-
dlls/win32u/ntuser_private.h | 2 -
dlls/win32u/rawinput.c | 434 ++++++++++++++++++++++++++++++++++-
dlls/win32u/syscall.c | 2 +
dlls/win32u/win32u.spec | 4 +-
dlls/win32u/win32u_private.h | 1 +
dlls/wow64win/syscall.h | 2 +
dlls/wow64win/user.c | 55 +++++
include/ntuser.h | 2 +
13 files changed, 503 insertions(+), 449 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index 588d1685cc0..98854d75690 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -39,368 +39,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(rawinput);
-struct device
-{
- WCHAR *path;
- HANDLE file;
- HANDLE handle;
- RID_DEVICE_INFO info;
- struct hid_preparsed_data *data;
-};
-
-static struct device *rawinput_devices;
-static unsigned int rawinput_devices_count, rawinput_devices_max;
-
-static CRITICAL_SECTION rawinput_devices_cs;
-static CRITICAL_SECTION_DEBUG rawinput_devices_cs_debug =
-{
- 0, 0, &rawinput_devices_cs,
- { &rawinput_devices_cs_debug.ProcessLocksList, &rawinput_devices_cs_debug.ProcessLocksList },
- 0, 0, { (DWORD_PTR)(__FILE__ ": rawinput_devices_cs") }
-};
-static CRITICAL_SECTION rawinput_devices_cs = { &rawinput_devices_cs_debug, -1, 0, 0, 0, 0 };
-
-static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
-{
- unsigned int new_capacity, max_capacity;
- void *new_elements;
-
- if (count <= *capacity)
- return TRUE;
-
- max_capacity = ~(SIZE_T)0 / size;
- if (count > max_capacity)
- return FALSE;
-
- new_capacity = max(4, *capacity);
- while (new_capacity < count && new_capacity <= max_capacity / 2)
- new_capacity *= 2;
- if (new_capacity < count)
- new_capacity = max_capacity;
-
- if (!(new_elements = realloc(*elements, new_capacity * size)))
- return FALSE;
-
- *elements = new_elements;
- *capacity = new_capacity;
-
- return TRUE;
-}
-
-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};
- struct hid_preparsed_data *preparsed = NULL;
- 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;
- HANDLE file;
-
- if (!query_reg_value( key, symbolic_linkW, value, sizeof(value_buffer) ))
- {
- ERR( "failed to get symbolic link value\n" );
- 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);
-
- file = CreateFileW( path, GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
- if (file == INVALID_HANDLE_VALUE)
- {
- ERR( "Failed to open device file %s, error %lu.\n", debugstr_w(path), GetLastError() );
- free( path );
- return NULL;
- }
-
- status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io,
- IOCTL_HID_GET_WINE_RAWINPUT_HANDLE,
- NULL, 0, &handle, sizeof(handle) );
- if (status)
- {
- ERR( "Failed to get raw input handle, status %#lx.\n", status );
- goto fail;
- }
-
- memset( &info, 0, sizeof(info) );
- info.cbSize = sizeof(info);
- info.dwType = type;
-
- switch (type)
- {
- case RIM_TYPEHID:
- status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io,
- IOCTL_HID_GET_COLLECTION_INFORMATION,
- NULL, 0, &hid_info, sizeof(hid_info) );
- if (status)
- {
- ERR( "Failed to get collection information, status %#lx.\n", status );
- goto fail;
- }
-
- info.hid.dwVendorId = hid_info.VendorID;
- info.hid.dwProductId = hid_info.ProductID;
- info.hid.dwVersionNumber = hid_info.VersionNumber;
-
- if (!(preparsed = malloc( hid_info.DescriptorSize )))
- {
- ERR( "Failed to allocate memory.\n" );
- goto fail;
- }
-
- status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io,
- IOCTL_HID_GET_COLLECTION_DESCRIPTOR,
- NULL, 0, preparsed, hid_info.DescriptorSize );
- if (status)
- {
- ERR( "Failed to get collection descriptor, status %#lx.\n", status );
- goto fail;
- }
-
- info.hid.usUsagePage = preparsed->usage_page;
- info.hid.usUsage = preparsed->usage;
- break;
-
- case RIM_TYPEMOUSE:
- info.mouse = mouse_info;
- break;
-
- case RIM_TYPEKEYBOARD:
- info.keyboard = keyboard_info;
- break;
- }
-
- for (i = 0; i < rawinput_devices_count && !device; ++i)
- if (rawinput_devices[i].handle == UlongToHandle(handle))
- device = rawinput_devices + i;
-
- if (device)
- {
- TRACE( "Updating device %#x / %s.\n", handle, debugstr_w(path) );
- free(device->data);
- CloseHandle(device->file);
- free( device->path );
- }
- else if (array_reserve((void **)&rawinput_devices, &rawinput_devices_max,
- rawinput_devices_count + 1, sizeof(*rawinput_devices)))
- {
- device = &rawinput_devices[rawinput_devices_count++];
- TRACE( "Adding device %#x / %s.\n", handle, debugstr_w(path) );
- }
- else
- {
- ERR("Failed to allocate memory.\n");
- goto fail;
- }
-
- device->path = path;
- device->file = file;
- device->handle = ULongToHandle(handle);
- device->info = info;
- device->data = preparsed;
-
- return device;
-
-fail:
- free( preparsed );
- CloseHandle( file );
- free( path );
- return NULL;
-}
-
-static HKEY reg_open_key( HKEY root, const WCHAR *name, ULONG name_len )
-{
- 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;
-}
-
-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}";
-
-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 );
- }
-
- NtClose( class_key );
-}
-
-void CDECL rawinput_update_device_list(void)
-{
- DWORD idx;
-
- TRACE("\n");
-
- EnterCriticalSection(&rawinput_devices_cs);
-
- /* destroy previous list */
- for (idx = 0; idx < rawinput_devices_count; ++idx)
- {
- free(rawinput_devices[idx].data);
- CloseHandle(rawinput_devices[idx].file);
- free( rawinput_devices[idx].path );
- }
- rawinput_devices_count = 0;
-
- 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);
-}
-
-
-static struct device *find_device_from_handle(HANDLE handle)
-{
- UINT i;
- for (i = 0; i < rawinput_devices_count; ++i)
- if (rawinput_devices[i].handle == handle)
- return rawinput_devices + i;
- rawinput_update_device_list();
- for (i = 0; i < rawinput_devices_count; ++i)
- if (rawinput_devices[i].handle == handle)
- return rawinput_devices + i;
- return NULL;
-}
-
-
-BOOL rawinput_device_get_usages(HANDLE handle, USAGE *usage_page, USAGE *usage)
-{
- struct device *device;
-
- *usage_page = *usage = 0;
-
- if (!(device = find_device_from_handle(handle))) return FALSE;
- if (device->info.dwType != RIM_TYPEHID) return FALSE;
-
- *usage_page = device->info.hid.usUsagePage;
- *usage = device->info.hid.usUsage;
- return TRUE;
-}
-
-
-/***********************************************************************
- * GetRawInputDeviceList (USER32.@)
- */
-UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_count, UINT size)
-{
- static UINT last_check;
- UINT i, ticks = GetTickCount();
-
- TRACE("devices %p, device_count %p, size %u.\n", devices, device_count, size);
-
- if (size != sizeof(*devices))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return ~0U;
- }
-
- if (!device_count)
- {
- SetLastError(ERROR_NOACCESS);
- return ~0U;
- }
-
- if (ticks - last_check > 2000)
- {
- last_check = ticks;
- rawinput_update_device_list();
- }
-
- if (!devices)
- {
- *device_count = rawinput_devices_count;
- return 0;
- }
-
- if (*device_count < rawinput_devices_count)
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- *device_count = rawinput_devices_count;
- return ~0U;
- }
-
- for (i = 0; i < rawinput_devices_count; ++i)
- {
- devices[i].hDevice = rawinput_devices[i].handle;
- devices[i].dwType = rawinput_devices[i].info.dwType;
- }
-
- return rawinput_devices_count;
-}
-
/***********************************************************************
* GetRawInputDeviceInfoA (USER32.@)
*/
@@ -424,7 +62,7 @@ UINT WINAPI GetRawInputDeviceInfoA(HANDLE device, UINT command, void *data, UINT
else
nameW = NULL;
- ret = GetRawInputDeviceInfoW(device, command, nameW, &nameW_sz);
+ ret = NtUserGetRawInputDeviceInfo( device, command, nameW, &nameW_sz );
if (ret && ret != ~0U)
WideCharToMultiByte(CP_ACP, 0, nameW, -1, data, *data_size, NULL, NULL);
@@ -436,74 +74,7 @@ UINT WINAPI GetRawInputDeviceInfoA(HANDLE device, UINT command, void *data, UINT
return ret;
}
- return GetRawInputDeviceInfoW(device, command, data, data_size);
-}
-
-/***********************************************************************
- * GetRawInputDeviceInfoW (USER32.@)
- */
-UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT *data_size)
-{
- struct hid_preparsed_data *preparsed;
- RID_DEVICE_INFO info;
- struct device *device;
- DWORD len, data_len;
-
- TRACE("handle %p, command %#x, data %p, data_size %p.\n",
- handle, command, data, data_size);
-
- if (!data_size)
- {
- SetLastError(ERROR_NOACCESS);
- return ~0U;
- }
- if (!(device = find_device_from_handle(handle)))
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return ~0U;
- }
-
- data_len = *data_size;
- switch (command)
- {
- case RIDI_DEVICENAME:
- if ((len = wcslen( device->path ) + 1) <= data_len && data)
- memcpy( data, device->path, len * sizeof(WCHAR) );
- *data_size = len;
- break;
-
- case RIDI_DEVICEINFO:
- if ((len = sizeof(info)) <= data_len && data)
- memcpy(data, &device->info, len);
- *data_size = len;
- break;
-
- case RIDI_PREPARSEDDATA:
- if (!(preparsed = device->data)) len = 0;
- else len = preparsed->caps_size + FIELD_OFFSET(struct hid_preparsed_data, value_caps[0]) +
- preparsed->number_link_collection_nodes * sizeof(struct hid_collection_node);
-
- if (preparsed && len <= data_len && data)
- memcpy(data, preparsed, len);
- *data_size = len;
- break;
-
- default:
- FIXME("command %#x not supported\n", command);
- SetLastError(ERROR_INVALID_PARAMETER);
- return ~0U;
- }
-
- if (!data)
- return 0;
-
- if (data_len < len)
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return ~0U;
- }
-
- return *data_size;
+ return NtUserGetRawInputDeviceInfo( device, command, data, data_size );
}
/***********************************************************************
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec
index 3e20277251a..e1cc18f7287 100644
--- a/dlls/user32/user32.spec
+++ b/dlls/user32/user32.spec
@@ -369,8 +369,8 @@
@ stdcall GetRawInputBuffer(ptr ptr long) NtUserGetRawInputBuffer
@ stdcall GetRawInputData(ptr long ptr ptr long) NtUserGetRawInputData
@ stdcall GetRawInputDeviceInfoA(ptr long ptr ptr)
-@ stdcall GetRawInputDeviceInfoW(ptr long ptr ptr)
-@ stdcall GetRawInputDeviceList(ptr ptr long)
+@ stdcall GetRawInputDeviceInfoW(ptr long ptr ptr) NtUserGetRawInputDeviceInfo
+@ stdcall GetRawInputDeviceList(ptr ptr long) NtUserGetRawInputDeviceList
# @ stub GetReasonTitleFromReasonCode
@ stdcall GetRegisteredRawInputDevices(ptr ptr long) NtUserGetRegisteredRawInputDevices
@ stdcall GetScrollBarInfo(long long ptr)
diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c
index 038f1f0796f..2391131e4a5 100644
--- a/dlls/user32/user_main.c
+++ b/dlls/user32/user_main.c
@@ -161,8 +161,6 @@ static const struct user_callbacks user_funcs =
free_win_ptr,
notify_ime,
post_dde_message,
- rawinput_update_device_list,
- rawinput_device_get_usages,
SCROLL_SetStandardScrollPainted,
unpack_dde_message,
register_imm,
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 71248e03bb8..a646f9a234d 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -60,14 +60,8 @@ extern HMODULE user32_module DECLSPEC_HIDDEN;
struct dce;
struct tagWND;
-struct hardware_msg_data;
-extern BOOL rawinput_device_get_usages(HANDLE handle, USAGE *usage_page, USAGE *usage);
-extern void CDECL rawinput_update_device_list(void);
-
extern BOOL post_dde_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, DWORD dest_tid,
DWORD type ) DECLSPEC_HIDDEN;
-extern BOOL process_rawinput_message( MSG *msg, UINT hw_id,
- const struct hardware_msg_data *msg_data ) DECLSPEC_HIDDEN;
extern BOOL unpack_dde_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam,
void **buffer, size_t size ) DECLSPEC_HIDDEN;
extern void free_cached_data( UINT format, HANDLE handle ) DECLSPEC_HIDDEN;
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c
index 94a1bc71520..0603a248f60 100644
--- a/dlls/win32u/message.c
+++ b/dlls/win32u/message.c
@@ -2381,9 +2381,8 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
hid_usage_page = ((USAGE *)rawinput->data.hid.bRawData)[0];
hid_usage = ((USAGE *)rawinput->data.hid.bRawData)[1];
}
- if (input->hi.uMsg == WM_INPUT && user_callbacks &&
- !user_callbacks->rawinput_device_get_usages( rawinput->header.hDevice,
- &hid_usage_page, &hid_usage ))
+ if (input->hi.uMsg == WM_INPUT &&
+ !rawinput_device_get_usages( rawinput->header.hDevice, &hid_usage_page, &hid_usage ))
{
WARN( "unable to get HID usages for device %p\n", rawinput->header.hDevice );
return STATUS_INVALID_HANDLE;
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h
index fd70c022c6f..82d70ec93bb 100644
--- a/dlls/win32u/ntuser_private.h
+++ b/dlls/win32u/ntuser_private.h
@@ -40,8 +40,6 @@ struct user_callbacks
void (CDECL *notify_ime)( HWND hwnd, UINT param );
BOOL (CDECL *post_dde_message)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, DWORD dest_tid,
DWORD type );
- void (CDECL *rawinput_update_device_list)(void);
- BOOL (CDECL *rawinput_device_get_usages)(HANDLE handle, USHORT *usage_page, USHORT *usage);
void (WINAPI *set_standard_scroll_painted)( HWND hwnd, INT bar, BOOL visible );
BOOL (CDECL *unpack_dde_message)( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam,
void **buffer, size_t size );
diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c
index 1caf11f2e76..81403771c4a 100644
--- a/dlls/win32u/rawinput.c
+++ b/dlls/win32u/rawinput.c
@@ -24,8 +24,14 @@
#endif
#include <stdbool.h>
+#include <pthread.h>
+
#include "win32u_private.h"
#include "ntuser_private.h"
+#define WIN32_NO_STATUS
+#include "winioctl.h"
+#include "ddk/hidclass.h"
+#include "wine/hid.h"
#include "wine/server.h"
#include "wine/debug.h"
@@ -188,6 +194,432 @@ static bool rawinput_from_hardware_message( RAWINPUT *rawinput, const struct har
return true;
}
+struct device
+{
+ WCHAR *path;
+ HANDLE file;
+ HANDLE handle;
+ RID_DEVICE_INFO info;
+ struct hid_preparsed_data *data;
+};
+
+static struct device *rawinput_devices;
+static unsigned int rawinput_devices_count, rawinput_devices_max;
+
+static pthread_mutex_t rawinput_devices_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static bool array_reserve( void **elements, unsigned int *capacity, unsigned int count, unsigned int size )
+{
+ unsigned int new_capacity, max_capacity;
+ void *new_elements;
+
+ if (count <= *capacity)
+ return true;
+
+ max_capacity = ~(unsigned int)0 / size;
+ if (count > max_capacity)
+ return false;
+
+ new_capacity = max( 4, *capacity );
+ while (new_capacity < count && new_capacity <= max_capacity / 2)
+ new_capacity *= 2;
+ if (new_capacity < count)
+ new_capacity = max_capacity;
+
+ if (!(new_elements = realloc( *elements, new_capacity * size )))
+ return false;
+
+ *elements = new_elements;
+ *capacity = new_capacity;
+
+ return true;
+}
+
+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};
+ struct hid_preparsed_data *preparsed = NULL;
+ HID_COLLECTION_INFORMATION hid_info;
+ struct device *device = NULL;
+ OBJECT_ATTRIBUTES attr;
+ UNICODE_STRING string;
+ RID_DEVICE_INFO info;
+ IO_STATUS_BLOCK io;
+ WCHAR *path, *pos;
+ NTSTATUS status;
+ unsigned int i;
+ UINT32 handle;
+ HANDLE file;
+
+ if (!query_reg_value( key, symbolic_linkW, value, sizeof(value_buffer) ))
+ {
+ ERR( "failed to get symbolic link value\n" );
+ 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 );
+
+ /* path is in DOS format and begins with \\?\ prefix */
+ path[1] = '?';
+
+ RtlInitUnicodeString( &string, path );
+ InitializeObjectAttributes( &attr, &string, OBJ_CASE_INSENSITIVE, NULL, NULL );
+ if ((status = NtOpenFile( &file, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &attr, &io,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT )))
+ {
+ ERR( "Failed to open device file %s, status %#x.\n", debugstr_w(path), status );
+ free( path );
+ return NULL;
+ }
+
+ path[1] = '\\';
+
+ status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io, IOCTL_HID_GET_WINE_RAWINPUT_HANDLE,
+ NULL, 0, &handle, sizeof(handle) );
+ if (status)
+ {
+ ERR( "Failed to get raw input handle, status %#x.\n", status );
+ goto fail;
+ }
+
+ memset( &info, 0, sizeof(info) );
+ info.cbSize = sizeof(info);
+ info.dwType = type;
+
+ switch (type)
+ {
+ case RIM_TYPEHID:
+ status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io,
+ IOCTL_HID_GET_COLLECTION_INFORMATION,
+ NULL, 0, &hid_info, sizeof(hid_info) );
+ if (status)
+ {
+ ERR( "Failed to get collection information, status %#x.\n", status );
+ goto fail;
+ }
+
+ info.hid.dwVendorId = hid_info.VendorID;
+ info.hid.dwProductId = hid_info.ProductID;
+ info.hid.dwVersionNumber = hid_info.VersionNumber;
+
+ if (!(preparsed = malloc( hid_info.DescriptorSize )))
+ {
+ ERR( "Failed to allocate memory.\n" );
+ goto fail;
+ }
+
+ status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io,
+ IOCTL_HID_GET_COLLECTION_DESCRIPTOR,
+ NULL, 0, preparsed, hid_info.DescriptorSize );
+ if (status)
+ {
+ ERR( "Failed to get collection descriptor, status %#x.\n", status );
+ goto fail;
+ }
+
+ info.hid.usUsagePage = preparsed->usage_page;
+ info.hid.usUsage = preparsed->usage;
+ break;
+
+ case RIM_TYPEMOUSE:
+ info.mouse = mouse_info;
+ break;
+
+ case RIM_TYPEKEYBOARD:
+ info.keyboard = keyboard_info;
+ break;
+ }
+
+ for (i = 0; i < rawinput_devices_count && !device; ++i)
+ {
+ if (rawinput_devices[i].handle == UlongToHandle(handle))
+ device = rawinput_devices + i;
+ }
+
+ if (device)
+ {
+ TRACE( "Updating device %#x / %s.\n", handle, debugstr_w(path) );
+ free( device->data );
+ NtClose( device->file );
+ free( device->path );
+ }
+ else if (array_reserve( (void **)&rawinput_devices, &rawinput_devices_max,
+ rawinput_devices_count + 1, sizeof(*rawinput_devices) ))
+ {
+ device = &rawinput_devices[rawinput_devices_count++];
+ TRACE( "Adding device %#x / %s.\n", handle, debugstr_w(path) );
+ }
+ else
+ {
+ ERR( "Failed to allocate memory.\n" );
+ goto fail;
+ }
+
+ device->path = path;
+ device->file = file;
+ device->handle = ULongToHandle(handle);
+ device->info = info;
+ device->data = preparsed;
+
+ return device;
+
+fail:
+ free( preparsed );
+ NtClose( file );
+ free( path );
+ return NULL;
+}
+
+static const WCHAR device_classesW[] =
+{
+ '\\','R','e','g','i','s','t','r','y',
+ '\\','M','a','c','h','i','n','e',
+ '\\','S','y','s','t','e','m',
+ '\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t',
+ '\\','C','o','n','t','r','o','l',
+ '\\','D','e','v','i','c','e','C','l','a','s','s','e','s','\\',0
+};
+static const WCHAR guid_devinterface_hidW[] =
+{
+ '{','4','d','1','e','5','5','b','2','-','f','1','6','f','-','1','1','c','f',
+ '-','8','8','c','b','-','0','0','1','1','1','1','0','0','0','0','3','0','}',0
+};
+static const WCHAR guid_devinterface_keyboardW[] =
+{
+ '{','8','8','4','b','9','6','c','3','-','5','6','e','f','-','1','1','d','1',
+ '-','b','c','8','c','-','0','0','a','0','c','9','1','4','0','5','d','d','}',0
+};
+static const WCHAR guid_devinterface_mouseW[] =
+{
+ '{','3','7','8','d','e','4','4','c','-','5','6','e','f','-','1','1','d','1',
+ '-','b','c','8','c','-','0','0','a','0','c','9','1','4','0','5','d','d','}',0
+};
+
+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 );
+ }
+
+ NtClose( class_key );
+}
+
+static void rawinput_update_device_list(void)
+{
+ unsigned int i;
+
+ TRACE( "\n" );
+
+ pthread_mutex_lock( &rawinput_devices_mutex );
+
+ /* destroy previous list */
+ for (i = 0; i < rawinput_devices_count; ++i)
+ {
+ free( rawinput_devices[i].data );
+ NtClose( rawinput_devices[i].file );
+ free( rawinput_devices[i].path );
+ }
+ rawinput_devices_count = 0;
+
+ enumerate_devices( RIM_TYPEHID, guid_devinterface_hidW );
+ enumerate_devices( RIM_TYPEMOUSE, guid_devinterface_mouseW );
+ enumerate_devices( RIM_TYPEKEYBOARD, guid_devinterface_keyboardW );
+
+ pthread_mutex_unlock( &rawinput_devices_mutex );
+}
+
+static struct device *find_device_from_handle( HANDLE handle )
+{
+ unsigned int i;
+
+ for (i = 0; i < rawinput_devices_count; ++i)
+ {
+ if (rawinput_devices[i].handle == handle)
+ return rawinput_devices + i;
+ }
+
+ rawinput_update_device_list();
+
+ for (i = 0; i < rawinput_devices_count; ++i)
+ {
+ if (rawinput_devices[i].handle == handle)
+ return rawinput_devices + i;
+ }
+ return NULL;
+}
+
+BOOL rawinput_device_get_usages( HANDLE handle, USAGE *usage_page, USAGE *usage )
+{
+ struct device *device;
+
+ *usage_page = *usage = 0;
+
+ if (!(device = find_device_from_handle( handle ))) return FALSE;
+ if (device->info.dwType != RIM_TYPEHID) return FALSE;
+
+ *usage_page = device->info.hid.usUsagePage;
+ *usage = device->info.hid.usUsage;
+ return TRUE;
+}
+
+/**********************************************************************
+ * NtUserGetRawInputDeviceList (win32u.@)
+ */
+UINT WINAPI NtUserGetRawInputDeviceList( RAWINPUTDEVICELIST *devices, UINT *device_count, UINT size )
+{
+ static unsigned int last_check;
+ unsigned int i, ticks = NtGetTickCount();
+
+ TRACE("devices %p, device_count %p, size %u.\n", devices, device_count, size);
+
+ if (size != sizeof(*devices))
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return ~0u;
+ }
+
+ if (!device_count)
+ {
+ SetLastError( ERROR_NOACCESS );
+ return ~0u;
+ }
+
+ if (ticks - last_check > 2000)
+ {
+ last_check = ticks;
+ rawinput_update_device_list();
+ }
+
+ if (!devices)
+ {
+ *device_count = rawinput_devices_count;
+ return 0;
+ }
+
+ if (*device_count < rawinput_devices_count)
+ {
+ SetLastError( ERROR_INSUFFICIENT_BUFFER );
+ *device_count = rawinput_devices_count;
+ return ~0u;
+ }
+
+ for (i = 0; i < rawinput_devices_count; ++i)
+ {
+ devices[i].hDevice = rawinput_devices[i].handle;
+ devices[i].dwType = rawinput_devices[i].info.dwType;
+ }
+
+ return rawinput_devices_count;
+}
+
+/**********************************************************************
+ * NtUserGetRawInputDeviceInfo (win32u.@)
+ */
+UINT WINAPI NtUserGetRawInputDeviceInfo( HANDLE handle, UINT command, void *data, UINT *data_size )
+{
+ const struct hid_preparsed_data *preparsed;
+ struct device *device;
+ RID_DEVICE_INFO info;
+ DWORD len, data_len;
+
+ TRACE( "handle %p, command %#x, data %p, data_size %p.\n", handle, command, data, data_size );
+
+ if (!data_size)
+ {
+ SetLastError( ERROR_NOACCESS );
+ return ~0u;
+ }
+ if (!(device = find_device_from_handle( handle )))
+ {
+ SetLastError( ERROR_INVALID_HANDLE );
+ return ~0u;
+ }
+
+ data_len = *data_size;
+ switch (command)
+ {
+ case RIDI_DEVICENAME:
+ if ((len = wcslen( device->path ) + 1) <= data_len && data)
+ memcpy( data, device->path, len * sizeof(WCHAR) );
+ *data_size = len;
+ break;
+
+ case RIDI_DEVICEINFO:
+ if ((len = sizeof(info)) <= data_len && data)
+ memcpy( data, &device->info, len );
+ *data_size = len;
+ break;
+
+ case RIDI_PREPARSEDDATA:
+ if (!(preparsed = device->data))
+ len = 0;
+ else
+ len = preparsed->caps_size + FIELD_OFFSET(struct hid_preparsed_data, value_caps[0]) +
+ preparsed->number_link_collection_nodes * sizeof(struct hid_collection_node);
+
+ if (preparsed && len <= data_len && data)
+ memcpy( data, preparsed, len );
+ *data_size = len;
+ break;
+
+ default:
+ FIXME( "command %#x not supported\n", command );
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return ~0u;
+ }
+
+ if (!data)
+ return 0;
+
+ if (data_len < len)
+ {
+ SetLastError( ERROR_INSUFFICIENT_BUFFER );
+ return ~0u;
+ }
+
+ return *data_size;
+}
+
/**********************************************************************
* NtUserGetRawInputBuffer (win32u.@)
*/
@@ -353,7 +785,7 @@ BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_d
if (msg->message == WM_INPUT_DEVICE_CHANGE)
{
- if (user_callbacks) user_callbacks->rawinput_update_device_list();
+ rawinput_update_device_list();
}
else
{
diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c
index 49746725816..e68519f15e5 100644
--- a/dlls/win32u/syscall.c
+++ b/dlls/win32u/syscall.c
@@ -147,6 +147,8 @@ static void * const syscalls[] =
NtUserGetProp,
NtUserGetRawInputBuffer,
NtUserGetRawInputData,
+ NtUserGetRawInputDeviceInfo,
+ NtUserGetRawInputDeviceList,
NtUserGetRegisteredRawInputDevices,
NtUserGetSystemDpiForProcess,
NtUserGetThreadDesktop,
diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec
index dab6e2a5ed8..68201f763ab 100644
--- a/dlls/win32u/win32u.spec
+++ b/dlls/win32u/win32u.spec
@@ -985,8 +985,8 @@
@ stub NtUserGetQueueStatusReadonly
@ stdcall -syscall NtUserGetRawInputBuffer(ptr ptr long)
@ stdcall -syscall NtUserGetRawInputData(ptr long ptr ptr long)
-@ stub NtUserGetRawInputDeviceInfo
-@ stub NtUserGetRawInputDeviceList
+@ stdcall -syscall NtUserGetRawInputDeviceInfo(ptr long ptr ptr)
+@ stdcall -syscall NtUserGetRawInputDeviceList(ptr ptr long)
@ stub NtUserGetRawPointerDeviceData
@ stdcall -syscall NtUserGetRegisteredRawInputDevices(ptr ptr long)
@ stub NtUserGetRequiredCursorSizes
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h
index a3f3855de7a..d3f359fd4ee 100644
--- a/dlls/win32u/win32u_private.h
+++ b/dlls/win32u/win32u_private.h
@@ -437,6 +437,7 @@ extern LRESULT send_message_timeout( HWND hwnd, UINT msg, WPARAM wparam, LPARAM
/* rawinput.c */
extern BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ) DECLSPEC_HIDDEN;
+extern BOOL rawinput_device_get_usages( HANDLE handle, USHORT *usage_page, USHORT *usage ) DECLSPEC_HIDDEN;
/* sysparams.c */
extern BOOL enable_thunk_lock DECLSPEC_HIDDEN;
diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h
index 903f146025d..30b6795f8e8 100644
--- a/dlls/wow64win/syscall.h
+++ b/dlls/wow64win/syscall.h
@@ -134,6 +134,8 @@
SYSCALL_ENTRY( NtUserGetProp ) \
SYSCALL_ENTRY( NtUserGetRawInputBuffer ) \
SYSCALL_ENTRY( NtUserGetRawInputData ) \
+ SYSCALL_ENTRY( NtUserGetRawInputDeviceInfo ) \
+ SYSCALL_ENTRY( NtUserGetRawInputDeviceList ) \
SYSCALL_ENTRY( NtUserGetRegisteredRawInputDevices ) \
SYSCALL_ENTRY( NtUserGetSystemDpiForProcess ) \
SYSCALL_ENTRY( NtUserGetThreadDesktop ) \
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c
index 87c522071aa..ca84c4a7bab 100644
--- a/dlls/wow64win/user.c
+++ b/dlls/wow64win/user.c
@@ -72,6 +72,12 @@ typedef struct
UINT32 hwndTarget;
} RAWINPUTDEVICE32;
+typedef struct
+{
+ UINT32 hDevice;
+ DWORD dwType;
+} RAWINPUTDEVICELIST32;
+
static MSG *msg_32to64( MSG *msg, MSG32 *msg32 )
{
if (!msg32) return NULL;
@@ -1056,3 +1062,52 @@ NTSTATUS WINAPI wow64_NtUserGetRegisteredRawInputDevices( UINT *args )
return NtUserGetRegisteredRawInputDevices( NULL, count, sizeof(RAWINPUTDEVICE) );
}
}
+
+NTSTATUS WINAPI wow64_NtUserGetRawInputDeviceInfo( UINT *args )
+{
+ HANDLE handle = get_handle( &args );
+ UINT command = get_ulong( &args );
+ void *data = get_ptr( &args );
+ UINT *data_size = get_ptr( &args );
+
+ return NtUserGetRawInputDeviceInfo( handle, command, data, data_size );
+}
+
+NTSTATUS WINAPI wow64_NtUserGetRawInputDeviceList( UINT *args )
+{
+ RAWINPUTDEVICELIST32 *devices32 = get_ptr( &args );
+ UINT *count = get_ptr( &args );
+ UINT size = get_ulong( &args );
+
+ if (size != sizeof(RAWINPUTDEVICELIST32))
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return ~0u;
+ }
+
+ if (devices32)
+ {
+ RAWINPUTDEVICELIST *devices64;
+ unsigned int ret, i;
+
+ if (!(devices64 = Wow64AllocateTemp( (*count) * sizeof(*devices64) )))
+ {
+ SetLastError( ERROR_NOT_ENOUGH_MEMORY );
+ return ~0u;
+ }
+
+ ret = NtUserGetRawInputDeviceList( devices64, count, sizeof(RAWINPUTDEVICELIST) );
+ if (ret == ~0u) return ret;
+
+ for (i = 0; i < *count; ++i)
+ {
+ devices32[i].hDevice = (UINT_PTR)devices64[i].hDevice;
+ devices32[i].dwType = devices64[i].dwType;
+ }
+ return ret;
+ }
+ else
+ {
+ return NtUserGetRawInputDeviceList( NULL, count, sizeof(RAWINPUTDEVICELIST) );
+ }
+}
diff --git a/include/ntuser.h b/include/ntuser.h
index 9c4aaf041a4..3862eb55054 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -621,6 +621,8 @@ ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process );
DWORD WINAPI NtUserGetQueueStatus( UINT flags );
UINT WINAPI NtUserGetRawInputBuffer( RAWINPUT *data, UINT *data_size, UINT header_size );
UINT WINAPI NtUserGetRawInputData( HRAWINPUT rawinput, UINT command, void *data, UINT *data_size, UINT header_size );
+UINT WINAPI NtUserGetRawInputDeviceInfo( HANDLE handle, UINT command, void *data, UINT *data_size );
+UINT WINAPI NtUserGetRawInputDeviceList( RAWINPUTDEVICELIST *devices, UINT *device_count, UINT size );
UINT WINAPI NtUserGetRegisteredRawInputDevices( RAWINPUTDEVICE *devices, UINT *device_count, UINT size );
ULONG WINAPI NtUserGetSystemDpiForProcess( HANDLE process );
HMENU WINAPI NtUserGetSystemMenu( HWND hwnd, BOOL revert );
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/313
June 29, 2022
[PATCH v4 2/4] win32u: Move NtUserGetRegisteredRawInputDevices from user32.
by Zebediah Figura
From: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/user32/rawinput.c | 57 ---------------------------------------
dlls/user32/user32.spec | 2 +-
dlls/win32u/rawinput.c | 59 +++++++++++++++++++++++++++++++++++++++++
dlls/win32u/syscall.c | 1 +
dlls/win32u/win32u.spec | 2 +-
dlls/wow64win/syscall.h | 1 +
dlls/wow64win/user.c | 41 ++++++++++++++++++++++++++++
include/ntuser.h | 1 +
8 files changed, 105 insertions(+), 59 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index 1b02be1398d..588d1685cc0 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -506,63 +506,6 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT
return *data_size;
}
-static int __cdecl 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)
-{
- struct rawinput_device *buffer = NULL;
- unsigned int i, status, count = ~0U, buffer_size;
-
- 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;
-}
-
-
/***********************************************************************
* DefRawInputProc (USER32.@)
*/
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec
index dbe2a4c1430..3e20277251a 100644
--- a/dlls/user32/user32.spec
+++ b/dlls/user32/user32.spec
@@ -372,7 +372,7 @@
@ stdcall GetRawInputDeviceInfoW(ptr long ptr ptr)
@ stdcall GetRawInputDeviceList(ptr ptr long)
# @ stub GetReasonTitleFromReasonCode
-@ stdcall GetRegisteredRawInputDevices(ptr ptr long)
+@ stdcall GetRegisteredRawInputDevices(ptr ptr long) NtUserGetRegisteredRawInputDevices
@ stdcall GetScrollBarInfo(long long ptr)
@ stdcall GetScrollInfo(long long ptr)
@ stdcall GetScrollPos(long long)
diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c
index 359faa39083..1caf11f2e76 100644
--- a/dlls/win32u/rawinput.c
+++ b/dlls/win32u/rawinput.c
@@ -427,3 +427,62 @@ BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT d
return ret;
}
+
+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;
+}
+
+/**********************************************************************
+ * NtUserGetRegisteredRawInputDevices (win32u.@)
+ */
+UINT WINAPI NtUserGetRegisteredRawInputDevices( RAWINPUTDEVICE *devices, UINT *device_count, UINT size )
+{
+ struct rawinput_device *buffer = NULL;
+ unsigned int i, status, buffer_size;
+
+ 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 = malloc( 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 (status)
+ {
+ free( buffer );
+ return ~0u;
+ }
+
+ if (!devices) return 0;
+
+ for (i = 0; i < *device_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, *device_count, sizeof(*devices), compare_raw_input_devices );
+
+ free( buffer );
+ return *device_count;
+}
diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c
index 3f2c596f727..49746725816 100644
--- a/dlls/win32u/syscall.c
+++ b/dlls/win32u/syscall.c
@@ -147,6 +147,7 @@ static void * const syscalls[] =
NtUserGetProp,
NtUserGetRawInputBuffer,
NtUserGetRawInputData,
+ NtUserGetRegisteredRawInputDevices,
NtUserGetSystemDpiForProcess,
NtUserGetThreadDesktop,
NtUserGetTitleBarInfo,
diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec
index 687ef3af8dc..dab6e2a5ed8 100644
--- a/dlls/win32u/win32u.spec
+++ b/dlls/win32u/win32u.spec
@@ -988,7 +988,7 @@
@ stub NtUserGetRawInputDeviceInfo
@ stub NtUserGetRawInputDeviceList
@ stub NtUserGetRawPointerDeviceData
-@ stub NtUserGetRegisteredRawInputDevices
+@ stdcall -syscall NtUserGetRegisteredRawInputDevices(ptr ptr long)
@ stub NtUserGetRequiredCursorSizes
@ stub NtUserGetResizeDCompositionSynchronizationObject
@ stub NtUserGetScrollBarInfo
diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h
index 531f9f7f9cd..903f146025d 100644
--- a/dlls/wow64win/syscall.h
+++ b/dlls/wow64win/syscall.h
@@ -134,6 +134,7 @@
SYSCALL_ENTRY( NtUserGetProp ) \
SYSCALL_ENTRY( NtUserGetRawInputBuffer ) \
SYSCALL_ENTRY( NtUserGetRawInputData ) \
+ SYSCALL_ENTRY( NtUserGetRegisteredRawInputDevices ) \
SYSCALL_ENTRY( NtUserGetSystemDpiForProcess ) \
SYSCALL_ENTRY( NtUserGetThreadDesktop ) \
SYSCALL_ENTRY( NtUserGetTitleBarInfo ) \
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c
index 231f6a04a1e..87c522071aa 100644
--- a/dlls/wow64win/user.c
+++ b/dlls/wow64win/user.c
@@ -1015,3 +1015,44 @@ NTSTATUS WINAPI wow64_NtUserRegisterRawInputDevices( UINT *args )
return NtUserRegisterRawInputDevices( devices64, count, sizeof(*devices64) );
}
+
+NTSTATUS WINAPI wow64_NtUserGetRegisteredRawInputDevices( UINT *args )
+{
+ RAWINPUTDEVICE32 *devices32 = get_ptr( &args );
+ UINT *count = get_ptr( &args );
+ UINT size = get_ulong( &args );
+
+ if (size != sizeof(RAWINPUTDEVICE32))
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return ~0u;
+ }
+
+ if (devices32)
+ {
+ RAWINPUTDEVICE *devices64;
+ unsigned int ret, i;
+
+ if (!(devices64 = Wow64AllocateTemp( (*count) * sizeof(*devices64) )))
+ {
+ SetLastError( ERROR_NOT_ENOUGH_MEMORY );
+ return ~0u;
+ }
+
+ ret = NtUserGetRegisteredRawInputDevices( devices64, count, sizeof(RAWINPUTDEVICE) );
+ if (ret == ~0u) return ret;
+
+ for (i = 0; i < *count; ++i)
+ {
+ devices32[i].usUsagePage = devices64[i].usUsagePage;
+ devices32[i].usUsage = devices64[i].usUsage;
+ devices32[i].dwFlags = devices64[i].dwFlags;
+ devices32[i].hwndTarget = (ULONG_PTR)devices64[i].hwndTarget;
+ }
+ return ret;
+ }
+ else
+ {
+ return NtUserGetRegisteredRawInputDevices( NULL, count, sizeof(RAWINPUTDEVICE) );
+ }
+}
diff --git a/include/ntuser.h b/include/ntuser.h
index cb5696ec827..9c4aaf041a4 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -621,6 +621,7 @@ ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process );
DWORD WINAPI NtUserGetQueueStatus( UINT flags );
UINT WINAPI NtUserGetRawInputBuffer( RAWINPUT *data, UINT *data_size, UINT header_size );
UINT WINAPI NtUserGetRawInputData( HRAWINPUT rawinput, UINT command, void *data, UINT *data_size, UINT header_size );
+UINT WINAPI NtUserGetRegisteredRawInputDevices( RAWINPUTDEVICE *devices, UINT *device_count, UINT size );
ULONG WINAPI NtUserGetSystemDpiForProcess( HANDLE process );
HMENU WINAPI NtUserGetSystemMenu( HWND hwnd, BOOL revert );
HDESK WINAPI NtUserGetThreadDesktop( DWORD thread );
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/313
June 29, 2022
[PATCH v4 1/4] win32u: Move NtUserRegisterRawInputDevices from user32.
by Zebediah Figura
From: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/user32/rawinput.c | 63 -----------------------------------------
dlls/user32/user32.spec | 2 +-
dlls/win32u/rawinput.c | 61 +++++++++++++++++++++++++++++++++++++++
dlls/win32u/syscall.c | 1 +
dlls/win32u/win32u.spec | 2 +-
dlls/wow64win/syscall.h | 1 +
dlls/wow64win/user.c | 40 ++++++++++++++++++++++++++
include/ntuser.h | 1 +
8 files changed, 106 insertions(+), 65 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index d6290f08d12..1b02be1398d 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -401,69 +401,6 @@ UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_coun
return rawinput_devices_count;
}
-/***********************************************************************
- * RegisterRawInputDevices (USER32.@)
- */
-BOOL WINAPI DECLSPEC_HOTPATCH RegisterRawInputDevices(const RAWINPUTDEVICE *devices, UINT device_count, UINT size)
-{
- struct rawinput_device *d;
- BOOL ret;
- UINT i;
-
- TRACE("devices %p, device_count %u, size %u.\n", devices, device_count, size);
-
- if (size != sizeof(*devices))
- {
- WARN("Invalid structure size %u.\n", size);
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- for (i = 0; i < device_count; ++i)
- {
- if ((devices[i].dwFlags & RIDEV_INPUTSINK) &&
- (devices[i].hwndTarget == NULL))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- if ((devices[i].dwFlags & RIDEV_REMOVE) &&
- (devices[i].hwndTarget != NULL))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- }
-
- if (!(d = HeapAlloc( GetProcessHeap(), 0, device_count * sizeof(*d) ))) return FALSE;
-
- for (i = 0; i < device_count; ++i)
- {
- TRACE("device %u: page %#x, usage %#x, flags %#lx, target %p.\n",
- i, devices[i].usUsagePage, devices[i].usUsage,
- devices[i].dwFlags, devices[i].hwndTarget);
- if (devices[i].dwFlags & ~(RIDEV_REMOVE|RIDEV_NOLEGACY|RIDEV_INPUTSINK|RIDEV_DEVNOTIFY))
- FIXME("Unhandled flags %#lx for device %u.\n", devices[i].dwFlags, i);
-
- d[i].usage_page = devices[i].usUsagePage;
- d[i].usage = devices[i].usUsage;
- d[i].flags = devices[i].dwFlags;
- d[i].target = wine_server_user_handle( devices[i].hwndTarget );
- }
-
- SERVER_START_REQ( update_rawinput_devices )
- {
- wine_server_add_data( req, d, device_count * sizeof(*d) );
- ret = !wine_server_call( req );
- }
- SERVER_END_REQ;
-
- HeapFree( GetProcessHeap(), 0, d );
-
- return ret;
-}
-
/***********************************************************************
* GetRawInputDeviceInfoA (USER32.@)
*/
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec
index 887394227a3..dbe2a4c1430 100644
--- a/dlls/user32/user32.spec
+++ b/dlls/user32/user32.spec
@@ -605,7 +605,7 @@
@ stub RegisterNetworkCapabilities
@ stdcall RegisterPointerDeviceNotifications(long long)
@ stdcall RegisterPowerSettingNotification(long ptr long)
-@ stdcall RegisterRawInputDevices(ptr long long)
+@ stdcall RegisterRawInputDevices(ptr long long) NtUserRegisterRawInputDevices
@ stdcall RegisterServicesProcess(long)
@ stdcall RegisterShellHookWindow (long)
@ stdcall RegisterSuspendResumeNotification(long long)
diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c
index d6d4e0c13f7..359faa39083 100644
--- a/dlls/win32u/rawinput.c
+++ b/dlls/win32u/rawinput.c
@@ -366,3 +366,64 @@ BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_d
msg->pt = point_phys_to_win_dpi( msg->hwnd, msg->pt );
return TRUE;
}
+
+/**********************************************************************
+ * NtUserRegisterRawInputDevices (win32u.@)
+ */
+BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT device_count, UINT size )
+{
+ struct rawinput_device *server_devices;
+ BOOL ret;
+ UINT i;
+
+ TRACE( "devices %p, device_count %u, size %u.\n", devices, device_count, size );
+
+ if (size != sizeof(*devices))
+ {
+ WARN( "Invalid structure size %u.\n", size );
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
+
+ for (i = 0; i < device_count; ++i)
+ {
+ if ((devices[i].dwFlags & RIDEV_INPUTSINK) && !devices[i].hwndTarget)
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
+
+ if ((devices[i].dwFlags & RIDEV_REMOVE) && devices[i].hwndTarget)
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
+ }
+
+ if (!(server_devices = malloc( device_count * sizeof(*server_devices) ))) return FALSE;
+
+ for (i = 0; i < device_count; ++i)
+ {
+ TRACE( "device %u: page %#x, usage %#x, flags %#x, target %p.\n",
+ i, devices[i].usUsagePage, devices[i].usUsage,
+ devices[i].dwFlags, devices[i].hwndTarget );
+ if (devices[i].dwFlags & ~(RIDEV_REMOVE|RIDEV_NOLEGACY|RIDEV_INPUTSINK|RIDEV_DEVNOTIFY))
+ FIXME( "Unhandled flags %#x for device %u.\n", devices[i].dwFlags, i );
+
+ server_devices[i].usage_page = devices[i].usUsagePage;
+ server_devices[i].usage = devices[i].usUsage;
+ server_devices[i].flags = devices[i].dwFlags;
+ server_devices[i].target = wine_server_user_handle( devices[i].hwndTarget );
+ }
+
+ SERVER_START_REQ( update_rawinput_devices )
+ {
+ wine_server_add_data( req, server_devices, device_count * sizeof(*server_devices) );
+ ret = !wine_server_call( req );
+ }
+ SERVER_END_REQ;
+
+ free( server_devices );
+
+ return ret;
+}
diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c
index 12af30f6c98..3f2c596f727 100644
--- a/dlls/win32u/syscall.c
+++ b/dlls/win32u/syscall.c
@@ -160,6 +160,7 @@ static void * const syscalls[] =
NtUserOpenDesktop,
NtUserOpenInputDesktop,
NtUserOpenWindowStation,
+ NtUserRegisterRawInputDevices,
NtUserRemoveClipboardFormatListener,
NtUserRemoveMenu,
NtUserRemoveProp,
diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec
index c71f0d20429..687ef3af8dc 100644
--- a/dlls/win32u/win32u.spec
+++ b/dlls/win32u/win32u.spec
@@ -1130,7 +1130,7 @@
@ stub NtUserRegisterManipulationThread
@ stub NtUserRegisterPointerDeviceNotifications
@ stub NtUserRegisterPointerInputTarget
-@ stub NtUserRegisterRawInputDevices
+@ stdcall -syscall NtUserRegisterRawInputDevices(ptr long long)
@ stub NtUserRegisterServicesProcess
@ stub NtUserRegisterSessionPort
@ stub NtUserRegisterShellPTPListener
diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h
index 618a7990554..531f9f7f9cd 100644
--- a/dlls/wow64win/syscall.h
+++ b/dlls/wow64win/syscall.h
@@ -147,6 +147,7 @@
SYSCALL_ENTRY( NtUserOpenDesktop ) \
SYSCALL_ENTRY( NtUserOpenInputDesktop ) \
SYSCALL_ENTRY( NtUserOpenWindowStation ) \
+ SYSCALL_ENTRY( NtUserRegisterRawInputDevices ) \
SYSCALL_ENTRY( NtUserRemoveClipboardFormatListener ) \
SYSCALL_ENTRY( NtUserRemoveMenu ) \
SYSCALL_ENTRY( NtUserRemoveProp ) \
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c
index 9c6730b24ae..231f6a04a1e 100644
--- a/dlls/wow64win/user.c
+++ b/dlls/wow64win/user.c
@@ -64,6 +64,14 @@ typedef struct
UINT32 wParam;
} RAWINPUTHEADER32;
+typedef struct
+{
+ USHORT usUsagePage;
+ USHORT usUsage;
+ DWORD dwFlags;
+ UINT32 hwndTarget;
+} RAWINPUTDEVICE32;
+
static MSG *msg_32to64( MSG *msg, MSG32 *msg32 )
{
if (!msg32) return NULL;
@@ -975,3 +983,35 @@ NTSTATUS WINAPI wow64_NtUserGetRawInputBuffer( UINT *args )
* whether it's operating under WoW64 or not. */
return NtUserGetRawInputBuffer( data, data_size, sizeof(RAWINPUTHEADER) );
}
+
+NTSTATUS WINAPI wow64_NtUserRegisterRawInputDevices( UINT *args )
+{
+ const RAWINPUTDEVICE32 *devices32 = get_ptr( &args );
+ UINT count = get_ulong( &args );
+ UINT size = get_ulong( &args );
+
+ RAWINPUTDEVICE *devices64;
+ unsigned int i;
+
+ if (size != sizeof(RAWINPUTDEVICE32))
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
+
+ if (!(devices64 = Wow64AllocateTemp( count * sizeof(*devices64) )))
+ {
+ SetLastError( ERROR_NOT_ENOUGH_MEMORY );
+ return FALSE;
+ }
+
+ for (i = 0; i < count; ++i)
+ {
+ devices64[i].usUsagePage = devices32[i].usUsagePage;
+ devices64[i].usUsage = devices32[i].usUsage;
+ devices64[i].dwFlags = devices32[i].dwFlags;
+ devices64[i].hwndTarget = UlongToPtr( devices32[i].hwndTarget );
+ }
+
+ return NtUserRegisterRawInputDevices( devices64, count, sizeof(*devices64) );
+}
diff --git a/include/ntuser.h b/include/ntuser.h
index 18ddbcaa4a4..cb5696ec827 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -663,6 +663,7 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *
struct client_menu_name *client_menu_name, DWORD fnid, DWORD flags,
DWORD *wow );
BOOL WINAPI NtUserRegisterHotKey( HWND hwnd, INT id, UINT modifiers, UINT vk );
+BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT device_count, UINT size );
INT WINAPI NtUserReleaseDC( HWND hwnd, HDC hdc );
BOOL WINAPI NtUserRemoveClipboardFormatListener( HWND hwnd );
BOOL WINAPI NtUserRemoveMenu( HMENU menu, UINT id, UINT flags );
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/313
June 29, 2022