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
December 2021
- 85 participants
- 1732 messages
[PATCH] wined3d: Decrement reference count and take the lock atomically for cached objects.
by Jan Sikorski
Samplers, blend states, rasterizer states and depth stencil states can
be retrieved from the cache in struct d3d_device even after the
reference count reaches zero, causing memory corruption.
Signed-off-by: Jan Sikorski <jsikorski(a)codeweavers.com>
---
dlls/wined3d/sampler.c | 3 +--
dlls/wined3d/state.c | 9 +++------
dlls/wined3d/wined3d_private.h | 20 ++++++++++++++++++++
3 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/dlls/wined3d/sampler.c b/dlls/wined3d/sampler.c
index bba3165316e..fa648304d07 100644
--- a/dlls/wined3d/sampler.c
+++ b/dlls/wined3d/sampler.c
@@ -35,13 +35,12 @@ ULONG CDECL wined3d_sampler_incref(struct wined3d_sampler *sampler)
ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler)
{
- ULONG refcount = InterlockedDecrement(&sampler->refcount);
+ ULONG refcount = wined3d_atomic_decrement_mutex_lock(&sampler->refcount);
TRACE("%p decreasing refcount to %u.\n", sampler, refcount);
if (!refcount)
{
- wined3d_mutex_lock();
sampler->parent_ops->wined3d_object_destroyed(sampler->parent);
sampler->device->adapter->adapter_ops->adapter_destroy_sampler(sampler);
wined3d_mutex_unlock();
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index c76e0c2b604..87ebefea9d0 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -55,14 +55,13 @@ static void wined3d_blend_state_destroy_object(void *object)
ULONG CDECL wined3d_blend_state_decref(struct wined3d_blend_state *state)
{
- ULONG refcount = InterlockedDecrement(&state->refcount);
+ ULONG refcount = wined3d_atomic_decrement_mutex_lock(&state->refcount);
struct wined3d_device *device = state->device;
TRACE("%p decreasing refcount to %u.\n", state, refcount);
if (!refcount)
{
- wined3d_mutex_lock();
state->parent_ops->wined3d_object_destroyed(state->parent);
wined3d_cs_destroy_object(device->cs, wined3d_blend_state_destroy_object, state);
wined3d_mutex_unlock();
@@ -131,14 +130,13 @@ static void wined3d_depth_stencil_state_destroy_object(void *object)
ULONG CDECL wined3d_depth_stencil_state_decref(struct wined3d_depth_stencil_state *state)
{
- ULONG refcount = InterlockedDecrement(&state->refcount);
+ ULONG refcount = wined3d_atomic_decrement_mutex_lock(&state->refcount);
struct wined3d_device *device = state->device;
TRACE("%p decreasing refcount to %u.\n", state, refcount);
if (!refcount)
{
- wined3d_mutex_lock();
state->parent_ops->wined3d_object_destroyed(state->parent);
wined3d_cs_destroy_object(device->cs, wined3d_depth_stencil_state_destroy_object, state);
wined3d_mutex_unlock();
@@ -196,14 +194,13 @@ static void wined3d_rasterizer_state_destroy_object(void *object)
ULONG CDECL wined3d_rasterizer_state_decref(struct wined3d_rasterizer_state *state)
{
- ULONG refcount = InterlockedDecrement(&state->refcount);
+ ULONG refcount = wined3d_atomic_decrement_mutex_lock(&state->refcount);
struct wined3d_device *device = state->device;
TRACE("%p decreasing refcount to %u.\n", state, refcount);
if (!refcount)
{
- wined3d_mutex_lock();
state->parent_ops->wined3d_object_destroyed(state->parent);
wined3d_cs_destroy_object(device->cs, wined3d_rasterizer_state_destroy_object, state);
wined3d_mutex_unlock();
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 2fce585c6b1..6047defcc2e 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -4155,6 +4155,26 @@ const char *wined3d_debug_view_desc(const struct wined3d_view_desc *d,
const struct wined3d_resource *resource) DECLSPEC_HIDDEN;
const char *wined3d_debug_vkresult(VkResult vr) DECLSPEC_HIDDEN;
+static inline ULONG wined3d_atomic_decrement_mutex_lock(volatile LONG *refcount)
+{
+ ULONG count, old_count = *refcount;
+ do
+ {
+ if ((count = old_count) == 1)
+ {
+ wined3d_mutex_lock();
+ count = InterlockedDecrement(refcount);
+ if (count) wined3d_mutex_unlock();
+ return count;
+ }
+
+ old_count = InterlockedCompareExchange(refcount, count - 1, count);
+ }
+ while (old_count != count);
+
+ return count - 1;
+}
+
struct wined3d_client_resource
{
/* The resource's persistently mapped address, which we may use to perform
--
2.32.0
Dec. 1, 2021
[PATCH] winevulkan: Update to VK spec version 1.2.201.
by Georg Lehmann
Signed-off-by: Georg Lehmann <dadschoorse(a)gmail.com>
---
dlls/winevulkan/make_vulkan | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index e5f8d1a46c6..7a9bac7e55e 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -64,7 +64,7 @@ from enum import Enum
LOGGER = logging.Logger("vulkan")
LOGGER.addHandler(logging.StreamHandler())
-VK_XML_VERSION = "1.2.200"
+VK_XML_VERSION = "1.2.201"
WINE_VK_VERSION = (1, 2)
# Filenames to create.
@@ -119,9 +119,6 @@ UNSUPPORTED_EXTENSIONS = [
# Deprecated extensions
"VK_NV_external_memory_capabilities",
"VK_NV_external_memory_win32",
-
- # Broken extensions
- "VK_ARM_rasterization_order_attachment_access", # https://github.com/KhronosGroup/Vulkan-Docs/issues/1703
]
# Either internal extensions which aren't present on the win32 platform which
--
2.34.1
Dec. 1, 2021
[PATCH 7/7] dinput: Improve GetForceFeedbackState / GetEffectStatus stubs.
by Rémi Bernon
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52062
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/dinput/device.c | 12 ++++++++++--
dlls/dinput/device_private.h | 1 +
dlls/dinput/joystick_hid.c | 22 ++++++++++++++++++++--
dlls/dinput8/tests/hid.c | 18 ------------------
4 files changed, 31 insertions(+), 22 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 19fbe724b56..cca7f796fdc 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -1763,6 +1763,7 @@ static HRESULT WINAPI dinput_device_GetEffectInfo( IDirectInputDevice8W *iface,
static HRESULT WINAPI dinput_device_GetForceFeedbackState( IDirectInputDevice8W *iface, DWORD *out )
{
struct dinput_device *impl = impl_from_IDirectInputDevice8W( iface );
+ HRESULT hr = DI_OK;
FIXME( "iface %p, out %p semi-stub!\n", iface, out );
@@ -1770,9 +1771,15 @@ static HRESULT WINAPI dinput_device_GetForceFeedbackState( IDirectInputDevice8W
*out = 0;
if (!(impl->caps.dwFlags & DIDC_FORCEFEEDBACK)) return DIERR_UNSUPPORTED;
- if (!impl->acquired || !(impl->dwCoopLevel & DISCL_EXCLUSIVE)) return DIERR_NOTEXCLUSIVEACQUIRED;
- return DI_OK;
+ EnterCriticalSection( &impl->crit );
+ if (!impl->acquired || !(impl->dwCoopLevel & DISCL_EXCLUSIVE))
+ hr = DIERR_NOTEXCLUSIVEACQUIRED;
+ else
+ *out = impl->force_feedback_state;
+ LeaveCriticalSection( &impl->crit );
+
+ return hr;
}
static HRESULT WINAPI dinput_device_SendForceFeedbackCommand( IDirectInputDevice8W *iface, DWORD command )
@@ -2146,6 +2153,7 @@ HRESULT dinput_device_alloc( SIZE_T size, const struct dinput_device_vtbl *vtbl,
This->caps.dwFlags = DIDC_ATTACHED | DIDC_EMULATED;
This->device_format = format;
This->device_gain = 10000;
+ This->force_feedback_state = DIGFFS_STOPPED | DIGFFS_EMPTY;
InitializeCriticalSection( &This->crit );
This->dinput = dinput;
IDirectInput_AddRef( &dinput->IDirectInput7A_iface );
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index e2cae26aea2..00a80b16590 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -112,6 +112,7 @@ struct dinput_device
BOOL autocenter;
LONG device_gain;
+ DWORD force_feedback_state;
struct object_properties *object_properties;
};
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c
index a1e8e30bc29..99fe98d95ce 100644
--- a/dlls/dinput/joystick_hid.c
+++ b/dlls/dinput/joystick_hid.c
@@ -221,6 +221,7 @@ struct hid_joystick_effect
DIEFFECT params;
DWORD modified;
DWORD flags;
+ DWORD status;
char *effect_control_buf;
char *effect_update_buf;
@@ -2653,6 +2654,9 @@ static HRESULT WINAPI hid_joystick_effect_Start( IDirectInputEffect *iface, DWOR
if (status != HIDP_STATUS_SUCCESS) hr = status;
else if (WriteFile( device, impl->effect_control_buf, report_len, NULL, NULL )) hr = DI_OK;
else hr = DIERR_INPUTLOST;
+
+ if (SUCCEEDED(hr)) impl->status |= DIEGES_PLAYING;
+ else impl->status &= ~DIEGES_PLAYING;
}
LeaveCriticalSection( &impl->joystick->base.crit );
@@ -2699,6 +2703,8 @@ static HRESULT WINAPI hid_joystick_effect_Stop( IDirectInputEffect *iface )
if (status != HIDP_STATUS_SUCCESS) hr = status;
else if (WriteFile( device, impl->effect_control_buf, report_len, NULL, NULL )) hr = DI_OK;
else hr = DIERR_INPUTLOST;
+
+ impl->status &= ~DIEGES_PLAYING;
}
LeaveCriticalSection( &impl->joystick->base.crit );
@@ -2708,7 +2714,7 @@ static HRESULT WINAPI hid_joystick_effect_Stop( IDirectInputEffect *iface )
static HRESULT WINAPI hid_joystick_effect_GetEffectStatus( IDirectInputEffect *iface, DWORD *status )
{
struct hid_joystick_effect *impl = impl_from_IDirectInputEffect( iface );
- HRESULT hr;
+ HRESULT hr = DI_OK;
FIXME( "iface %p, status %p semi-stub!\n", iface, status );
@@ -2721,7 +2727,7 @@ static HRESULT WINAPI hid_joystick_effect_GetEffectStatus( IDirectInputEffect *i
else if (!impl->index)
hr = DIERR_NOTDOWNLOADED;
else
- hr = DI_OK;
+ *status = impl->status;
LeaveCriticalSection( &impl->joystick->base.crit );
return hr;
@@ -2945,12 +2951,22 @@ static HRESULT WINAPI hid_joystick_effect_Download( IDirectInputEffect *iface )
if (!WriteFile( device, impl->effect_update_buf, report_len, NULL, NULL )) hr = DIERR_INPUTLOST;
else impl->modified = 0;
+
+ if (SUCCEEDED(hr)) impl->joystick->base.force_feedback_state &= ~DIGFFS_EMPTY;
}
LeaveCriticalSection( &impl->joystick->base.crit );
return hr;
}
+static void check_empty_force_feedback_state( struct hid_joystick *joystick )
+{
+ struct hid_joystick_effect *effect;
+ LIST_FOR_EACH_ENTRY( effect, &joystick->effect_list, struct hid_joystick_effect, entry )
+ if (effect->index) return;
+ joystick->base.force_feedback_state |= DIGFFS_EMPTY;
+}
+
static HRESULT WINAPI hid_joystick_effect_Unload( IDirectInputEffect *iface )
{
struct hid_joystick_effect *impl = impl_from_IDirectInputEffect( iface );
@@ -2986,6 +3002,7 @@ static HRESULT WINAPI hid_joystick_effect_Unload( IDirectInputEffect *iface )
impl->modified = impl->flags;
impl->index = 0;
+ check_empty_force_feedback_state( joystick );
}
LeaveCriticalSection( &joystick->base.crit );
@@ -3045,6 +3062,7 @@ static HRESULT hid_joystick_create_effect( IDirectInputDevice8W *iface, IDirectI
impl->params.rgdwAxes = impl->axes;
impl->params.rglDirection = impl->directions;
impl->params.dwTriggerButton = -1;
+ impl->status = 0;
*out = &impl->IDirectInputEffect_iface;
return DI_OK;
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c
index bfd0185303d..d9ecf4a5dd5 100644
--- a/dlls/dinput8/tests/hid.c
+++ b/dlls/dinput8/tests/hid.c
@@ -9118,7 +9118,6 @@ static void test_device_managed_effect(void)
hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
flags = DIGFFS_STOPPED|DIGFFS_EMPTY;
- todo_wine
ok( res == flags, "got state %#x\n", res );
set_hid_expect( file, NULL, 0 );
@@ -9182,7 +9181,6 @@ static void test_device_managed_effect(void)
hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
flags = DIGFFS_STOPPED|DIGFFS_EMPTY;
- todo_wine
ok( res == flags, "got state %#x\n", res );
set_hid_expect( file, NULL, 0 );
@@ -9200,7 +9198,6 @@ static void test_device_managed_effect(void)
hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
flags = DIGFFS_STOPPED;
- todo_wine
ok( res == flags, "got state %#x\n", res );
set_hid_expect( file, NULL, 0 );
@@ -9227,12 +9224,10 @@ static void test_device_managed_effect(void)
res = 0xdeadbeef;
hr = IDirectInputEffect_GetEffectStatus( effect2, &res );
ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
- todo_wine
ok( res == DIEGES_PLAYING, "got status %#x\n", res );
res = 0xdeadbeef;
hr = IDirectInputEffect_GetEffectStatus( effect, &res );
ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
- todo_wine
ok( res == DIEGES_PLAYING, "got status %#x\n", res );
set_hid_expect( file, &expect_stop_2, sizeof(expect_stop_2) );
hr = IDirectInputEffect_Stop( effect2 );
@@ -9255,14 +9250,12 @@ static void test_device_managed_effect(void)
res = 0xdeadbeef;
hr = IDirectInputEffect_GetEffectStatus( effect, &res );
ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
- todo_wine
ok( res == DIEGES_PLAYING, "got status %#x\n", res );
set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
res = 0xdeadbeef;
hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
flags = DIGFFS_STOPPED;
- todo_wine
ok( res == flags, "got state %#x\n", res );
set_hid_expect( file, NULL, 0 );
@@ -9273,14 +9266,12 @@ static void test_device_managed_effect(void)
res = 0xdeadbeef;
hr = IDirectInputEffect_GetEffectStatus( effect, &res );
ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
- todo_wine
ok( res == DIEGES_PLAYING, "got status %#x\n", res );
set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
res = 0xdeadbeef;
hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
flags = DIGFFS_STOPPED;
- todo_wine
ok( res == flags, "got state %#x\n", res );
set_hid_expect( file, NULL, 0 );
@@ -9291,14 +9282,12 @@ static void test_device_managed_effect(void)
res = 0xdeadbeef;
hr = IDirectInputEffect_GetEffectStatus( effect, &res );
ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
- todo_wine
ok( res == DIEGES_PLAYING, "got status %#x\n", res );
set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
res = 0xdeadbeef;
hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
flags = DIGFFS_STOPPED;
- todo_wine
ok( res == flags, "got state %#x\n", res );
set_hid_expect( file, NULL, 0 );
@@ -9309,14 +9298,12 @@ static void test_device_managed_effect(void)
res = 0xdeadbeef;
hr = IDirectInputEffect_GetEffectStatus( effect, &res );
ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
- todo_wine
ok( res == DIEGES_PLAYING, "got status %#x\n", res );
set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
res = 0xdeadbeef;
hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
flags = DIGFFS_STOPPED;
- todo_wine
ok( res == flags, "got state %#x\n", res );
set_hid_expect( file, NULL, 0 );
@@ -9327,14 +9314,12 @@ static void test_device_managed_effect(void)
res = 0xdeadbeef;
hr = IDirectInputEffect_GetEffectStatus( effect, &res );
ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
- todo_wine
ok( res == DIEGES_PLAYING, "got status %#x\n", res );
set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
res = 0xdeadbeef;
hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
flags = DIGFFS_STOPPED;
- todo_wine
ok( res == flags, "got state %#x\n", res );
set_hid_expect( file, NULL, 0 );
@@ -9351,7 +9336,6 @@ static void test_device_managed_effect(void)
hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
flags = DIGFFS_STOPPED;
- todo_wine
ok( res == flags, "got state %#x\n", res );
set_hid_expect( file, NULL, 0 );
@@ -9457,7 +9441,6 @@ static void test_device_managed_effect(void)
res = 0xdeadbeef;
hr = IDirectInputEffect_GetEffectStatus( effect, &res );
ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
- todo_wine
ok( res == DIEGES_PLAYING, "got status %#x\n", res );
set_hid_expect( file, expect_destroy, sizeof(expect_destroy) );
ref = IDirectInputEffect_Release( effect );
@@ -9484,7 +9467,6 @@ static void test_device_managed_effect(void)
res = 0xdeadbeef;
hr = IDirectInputEffect_GetEffectStatus( effect, &res );
ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
- todo_wine
ok( res == DIEGES_PLAYING, "got status %#x\n", res );
set_hid_expect( file, expect_destroy, sizeof(expect_destroy) );
ref = IDirectInputEffect_Release( effect );
--
2.34.0
Dec. 1, 2021
[PATCH 6/7] dinput: Send Device Gain Reports only on DISFFC_RESET command.
by Rémi Bernon
From: Ivo Ivanov <logos128(a)gmail.com>
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52062
Signed-off-by: Ivo Ivanov <logos128(a)gmail.com>
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/dinput/joystick_hid.c | 2 +-
dlls/dinput8/tests/hid.c | 45 --------------------------------------
2 files changed, 1 insertion(+), 46 deletions(-)
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c
index 06be759b685..a1e8e30bc29 100644
--- a/dlls/dinput/joystick_hid.c
+++ b/dlls/dinput/joystick_hid.c
@@ -1065,7 +1065,7 @@ static HRESULT hid_joystick_send_force_feedback_command( IDirectInputDevice8W *i
if (status != HIDP_STATUS_SUCCESS) return status;
if (!WriteFile( impl->device, report_buf, report_len, NULL, NULL )) return DIERR_INPUTLOST;
- if (!unacquire) hid_joystick_send_device_gain( iface, impl->base.device_gain );
+ if (!unacquire && command == DISFFC_RESET) hid_joystick_send_device_gain( iface, impl->base.device_gain );
return DI_OK;
}
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c
index b57c5e9e841..bfd0185303d 100644
--- a/dlls/dinput8/tests/hid.c
+++ b/dlls/dinput8/tests/hid.c
@@ -8628,15 +8628,6 @@ static void test_device_managed_effect(void)
.report_len = 2,
.report_buf = {1, 0x04},
},
- /* device gain */
- {
- .code = IOCTL_HID_WRITE_REPORT,
- .report_id = 6,
- .report_len = 2,
- .report_buf = {6, 0xff},
- .todo = TRUE,
- .wine_only = TRUE,
- },
};
struct hid_expect expect_disable_actuators[] =
{
@@ -8647,15 +8638,6 @@ static void test_device_managed_effect(void)
.report_len = 2,
.report_buf = {1, 0x05},
},
- /* device gain */
- {
- .code = IOCTL_HID_WRITE_REPORT,
- .report_id = 6,
- .report_len = 2,
- .report_buf = {6, 0xff},
- .todo = TRUE,
- .wine_only = TRUE,
- },
};
struct hid_expect expect_stop_all[] =
{
@@ -8666,15 +8648,6 @@ static void test_device_managed_effect(void)
.report_len = 2,
.report_buf = {1, 0x06},
},
- /* device gain */
- {
- .code = IOCTL_HID_WRITE_REPORT,
- .report_id = 6,
- .report_len = 2,
- .report_buf = {6, 0xff},
- .todo = TRUE,
- .wine_only = TRUE,
- },
};
struct hid_expect expect_device_pause[] =
{
@@ -8685,15 +8658,6 @@ static void test_device_managed_effect(void)
.report_len = 2,
.report_buf = {1, 0x02},
},
- /* device gain */
- {
- .code = IOCTL_HID_WRITE_REPORT,
- .report_id = 6,
- .report_len = 2,
- .report_buf = {6, 0xff},
- .todo = TRUE,
- .wine_only = TRUE,
- },
};
struct hid_expect expect_device_continue[] =
{
@@ -8704,15 +8668,6 @@ static void test_device_managed_effect(void)
.report_len = 2,
.report_buf = {1, 0x03},
},
- /* device gain */
- {
- .code = IOCTL_HID_WRITE_REPORT,
- .report_id = 6,
- .report_len = 2,
- .report_buf = {6, 0xff},
- .todo = TRUE,
- .wine_only = TRUE,
- },
};
struct hid_expect expect_create[] =
{
--
2.34.0
Dec. 1, 2021
[PATCH 5/7] dinput8/tests: Add some more GetForceFeedbackState / GetEffectStatus tests.
by Rémi Bernon
From: Ivo Ivanov <logos128(a)gmail.com>
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52062
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/dinput8/tests/hid.c | 403 ++++++++++++++++++++++++++++++++++++---
1 file changed, 375 insertions(+), 28 deletions(-)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c
index d0ca3746e96..b57c5e9e841 100644
--- a/dlls/dinput8/tests/hid.c
+++ b/dlls/dinput8/tests/hid.c
@@ -8254,10 +8254,15 @@ static void test_device_managed_effect(void)
USAGE(1, PID_USAGE_DEVICE_CONTROL),
COLLECTION(1, Logical),
USAGE(1, PID_USAGE_DC_DEVICE_RESET),
+ USAGE(1, PID_USAGE_DC_DEVICE_PAUSE),
+ USAGE(1, PID_USAGE_DC_DEVICE_CONTINUE),
+ USAGE(1, PID_USAGE_DC_ENABLE_ACTUATORS),
+ USAGE(1, PID_USAGE_DC_DISABLE_ACTUATORS),
+ USAGE(1, PID_USAGE_DC_STOP_ALL_EFFECTS),
LOGICAL_MINIMUM(1, 1),
- LOGICAL_MAXIMUM(1, 2),
+ LOGICAL_MAXIMUM(1, 6),
PHYSICAL_MINIMUM(1, 1),
- PHYSICAL_MAXIMUM(1, 2),
+ PHYSICAL_MAXIMUM(1, 6),
REPORT_SIZE(1, 8),
REPORT_COUNT(1, 1),
OUTPUT(1, Data|Ary|Abs),
@@ -8393,6 +8398,24 @@ static void test_device_managed_effect(void)
COLLECTION(1, Logical),
REPORT_ID(1, 4),
+ USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
+ LOGICAL_MINIMUM(1, 1),
+ LOGICAL_MAXIMUM(1, 0x7f),
+ PHYSICAL_MINIMUM(1, 1),
+ PHYSICAL_MAXIMUM(1, 0x7f),
+ REPORT_SIZE(1, 8),
+ REPORT_COUNT(1, 1),
+ OUTPUT(1, Data|Var|Abs),
+
+ USAGE(1, PID_USAGE_PARAMETER_BLOCK_OFFSET),
+ LOGICAL_MINIMUM(1, 0),
+ LOGICAL_MAXIMUM(1, 1),
+ PHYSICAL_MINIMUM(1, 0),
+ PHYSICAL_MAXIMUM(1, 1),
+ REPORT_SIZE(1, 4),
+ REPORT_COUNT(1, 1),
+ OUTPUT(1, Data|Var|Abs),
+
USAGE(1, PID_USAGE_TYPE_SPECIFIC_BLOCK_OFFSET),
COLLECTION(1, Logical),
USAGE(4, (HID_USAGE_PAGE_ORDINAL << 16)|1),
@@ -8405,9 +8428,6 @@ static void test_device_managed_effect(void)
REPORT_COUNT(1, 2),
OUTPUT(1, Data|Var|Abs),
END_COLLECTION,
- REPORT_SIZE(1, 4),
- REPORT_COUNT(1, 1),
- OUTPUT(1, Cnst|Var|Abs),
USAGE(1, PID_USAGE_CP_OFFSET),
LOGICAL_MINIMUM(1, 0x80),
@@ -8560,8 +8580,8 @@ static void test_device_managed_effect(void)
LOGICAL_MAXIMUM(4, 0xffff),
PHYSICAL_MINIMUM(1, 0),
PHYSICAL_MAXIMUM(4, 0xffff),
- REPORT_SIZE(1, 1),
- REPORT_COUNT(1, 16),
+ REPORT_SIZE(1, 16),
+ REPORT_COUNT(1, 1),
FEATURE(1, Data|Var|Abs),
END_COLLECTION,
END_COLLECTION,
@@ -8574,7 +8594,7 @@ static void test_device_managed_effect(void)
};
struct hid_expect expect_acquire[] =
{
- /* device reset */
+ /* device control */
{
.code = IOCTL_HID_WRITE_REPORT,
.report_id = 1,
@@ -8591,7 +8611,7 @@ static void test_device_managed_effect(void)
};
struct hid_expect expect_reset[] =
{
- /* device reset */
+ /* device control */
{
.code = IOCTL_HID_WRITE_REPORT,
.report_id = 1,
@@ -8599,6 +8619,101 @@ static void test_device_managed_effect(void)
.report_buf = {1, 0x01},
},
};
+ struct hid_expect expect_enable_actuators[] =
+ {
+ /* device control */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 1,
+ .report_len = 2,
+ .report_buf = {1, 0x04},
+ },
+ /* device gain */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 6,
+ .report_len = 2,
+ .report_buf = {6, 0xff},
+ .todo = TRUE,
+ .wine_only = TRUE,
+ },
+ };
+ struct hid_expect expect_disable_actuators[] =
+ {
+ /* device control */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 1,
+ .report_len = 2,
+ .report_buf = {1, 0x05},
+ },
+ /* device gain */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 6,
+ .report_len = 2,
+ .report_buf = {6, 0xff},
+ .todo = TRUE,
+ .wine_only = TRUE,
+ },
+ };
+ struct hid_expect expect_stop_all[] =
+ {
+ /* device control */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 1,
+ .report_len = 2,
+ .report_buf = {1, 0x06},
+ },
+ /* device gain */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 6,
+ .report_len = 2,
+ .report_buf = {6, 0xff},
+ .todo = TRUE,
+ .wine_only = TRUE,
+ },
+ };
+ struct hid_expect expect_device_pause[] =
+ {
+ /* device control */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 1,
+ .report_len = 2,
+ .report_buf = {1, 0x02},
+ },
+ /* device gain */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 6,
+ .report_len = 2,
+ .report_buf = {6, 0xff},
+ .todo = TRUE,
+ .wine_only = TRUE,
+ },
+ };
+ struct hid_expect expect_device_continue[] =
+ {
+ /* device control */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 1,
+ .report_len = 2,
+ .report_buf = {1, 0x03},
+ },
+ /* device gain */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 6,
+ .report_len = 2,
+ .report_buf = {6, 0xff},
+ .todo = TRUE,
+ .wine_only = TRUE,
+ },
+ };
struct hid_expect expect_create[] =
{
/* create new effect */
@@ -8619,15 +8734,15 @@ static void test_device_managed_effect(void)
{
.code = IOCTL_HID_WRITE_REPORT,
.report_id = 4,
- .report_len = 8,
- .report_buf = {4,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
+ .report_len = 9,
+ .report_buf = {4,0x01,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
},
/* set condition */
{
.code = IOCTL_HID_WRITE_REPORT,
.report_id = 4,
- .report_len = 8,
- .report_buf = {4,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
+ .report_len = 9,
+ .report_buf = {4,0x01,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
},
/* update effect */
{
@@ -8637,6 +8752,44 @@ static void test_device_managed_effect(void)
.report_buf = {3,0x01,0x03,0x08,0x01,0x00,0x06,0x00,0x01,0x55,0x00},
},
};
+ struct hid_expect expect_create_2[] =
+ {
+ /* create new effect */
+ {
+ .code = IOCTL_HID_SET_FEATURE,
+ .report_id = 2,
+ .report_len = 2,
+ .report_buf = {2,0x03},
+ },
+ /* block load */
+ {
+ .code = IOCTL_HID_GET_FEATURE,
+ .report_id = 3,
+ .report_len = 5,
+ .report_buf = {3,0x02,0x01,0x00,0x00},
+ },
+ /* set condition */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 4,
+ .report_len = 9,
+ .report_buf = {4,0x02,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
+ },
+ /* set condition */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 4,
+ .report_len = 9,
+ .report_buf = {4,0x02,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
+ },
+ /* update effect */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 3,
+ .report_len = 11,
+ .report_buf = {3,0x02,0x03,0x08,0x01,0x00,0x06,0x00,0x01,0x55,0x00},
+ },
+ };
struct hid_expect expect_create_delay[] =
{
/* create new effect */
@@ -8657,15 +8810,15 @@ static void test_device_managed_effect(void)
{
.code = IOCTL_HID_WRITE_REPORT,
.report_id = 4,
- .report_len = 8,
- .report_buf = {4,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
+ .report_len = 9,
+ .report_buf = {4,0x01,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
},
/* set condition */
{
.code = IOCTL_HID_WRITE_REPORT,
.report_id = 4,
- .report_len = 8,
- .report_buf = {4,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
+ .report_len = 9,
+ .report_buf = {4,0x01,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
},
/* update effect */
{
@@ -8695,15 +8848,15 @@ static void test_device_managed_effect(void)
{
.code = IOCTL_HID_WRITE_REPORT,
.report_id = 4,
- .report_len = 8,
- .report_buf = {4,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
+ .report_len = 9,
+ .report_buf = {4,0x01,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
},
/* set condition */
{
.code = IOCTL_HID_WRITE_REPORT,
.report_id = 4,
- .report_len = 8,
- .report_buf = {4,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
+ .report_len = 9,
+ .report_buf = {4,0x01,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
},
/* update effect */
{
@@ -8721,6 +8874,14 @@ static void test_device_managed_effect(void)
.report_len = 4,
.report_buf = {2,0x01,0x01,0x01},
};
+ struct hid_expect expect_start_2 =
+ {
+ /* effect control */
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 2,
+ .report_len = 4,
+ .report_buf = {2,0x02,0x02,0x01},
+ };
struct hid_expect expect_stop =
{
/* effect control */
@@ -8729,6 +8890,14 @@ static void test_device_managed_effect(void)
.report_len = 4,
.report_buf = {2,0x01,0x03,0x00},
};
+ struct hid_expect expect_stop_2 =
+ {
+ /* effect control */
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 2,
+ .report_len = 4,
+ .report_buf = {2,0x02,0x03,0x00},
+ };
struct hid_expect expect_destroy[] =
{
/* effect operation */
@@ -8746,6 +8915,23 @@ static void test_device_managed_effect(void)
.report_buf = {5,0x01},
},
};
+ struct hid_expect expect_destroy_2[] =
+ {
+ /* effect operation */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 2,
+ .report_len = 4,
+ .report_buf = {2,0x02,0x03,0x00},
+ },
+ /* block free */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 5,
+ .report_len = 2,
+ .report_buf = {5,0x02},
+ },
+ };
struct hid_expect device_state_input[] =
{
/* effect state */
@@ -8763,6 +8949,23 @@ static void test_device_managed_effect(void)
.report_buf = {1,0x12,0x34,0x56,0xff},
},
};
+ struct hid_expect device_state_input_0[] =
+ {
+ /* effect state */
+ {
+ .code = IOCTL_HID_READ_REPORT,
+ .report_id = 2,
+ .report_len = 4,
+ .report_buf = {2,0xff,0x00,0xff},
+ },
+ /* device state */
+ {
+ .code = IOCTL_HID_READ_REPORT,
+ .report_id = 1,
+ .report_len = 5,
+ .report_buf = {1,0x56,0x12,0x34,0xff},
+ },
+ };
struct hid_expect device_state_input_1[] =
{
/* effect state */
@@ -8770,7 +8973,7 @@ static void test_device_managed_effect(void)
.code = IOCTL_HID_READ_REPORT,
.report_id = 2,
.report_len = 4,
- .report_buf = {2,0x00,0x01,0x00},
+ .report_buf = {2,0x00,0x01,0x01},
},
/* device state */
{
@@ -8787,7 +8990,7 @@ static void test_device_managed_effect(void)
.code = IOCTL_HID_READ_REPORT,
.report_id = 2,
.report_len = 4,
- .report_buf = {2,0x03,0x00,0x00},
+ .report_buf = {2,0x03,0x00,0x01},
},
/* device state */
{
@@ -8804,7 +9007,7 @@ static void test_device_managed_effect(void)
.code = IOCTL_HID_GET_FEATURE,
.report_id = 1,
.report_len = 5,
- .report_buf = {1,0x10,0x00,0x01,0x03},
+ .report_buf = {1,0x10,0x00,0x04,0x03},
.todo = TRUE,
},
/* device pool */
@@ -8812,7 +9015,7 @@ static void test_device_managed_effect(void)
.code = IOCTL_HID_GET_FEATURE,
.report_id = 1,
.report_len = 5,
- .report_buf = {1,0x10,0x00,0x01,0x03},
+ .report_buf = {1,0x10,0x00,0x04,0x03},
.todo = TRUE,
},
};
@@ -8900,7 +9103,7 @@ static void test_device_managed_effect(void)
DIDEVICEINSTANCEW devinst = {.dwSize = sizeof(DIDEVICEINSTANCEW)};
WCHAR cwd[MAX_PATH], tempdir[MAX_PATH];
IDirectInputDevice8W *device;
- IDirectInputEffect *effect;
+ IDirectInputEffect *effect, *effect2;
HANDLE file, event;
ULONG res, ref;
DIEFFECT desc;
@@ -9058,11 +9261,156 @@ static void test_device_managed_effect(void)
ok( hr == DI_OK, "Start returned %#x\n", hr );
set_hid_expect( file, NULL, 0 );
+ set_hid_expect( file, expect_create_2, sizeof(expect_create_2) );
+ hr = IDirectInputDevice8_CreateEffect( device, &GUID_Spring, &expect_desc, &effect2, NULL );
+ ok( hr == DI_OK, "CreateEffect returned %#x\n", hr );
+ set_hid_expect( file, NULL, 0 );
+ set_hid_expect( file, &expect_start_2, sizeof(expect_start_2) );
+ hr = IDirectInputEffect_Start( effect2, 1, DIES_SOLO );
+ ok( hr == DI_OK, "Start returned %#x\n", hr );
+ set_hid_expect( file, NULL, 0 );
+ res = 0xdeadbeef;
+ hr = IDirectInputEffect_GetEffectStatus( effect2, &res );
+ ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
+ todo_wine
+ ok( res == DIEGES_PLAYING, "got status %#x\n", res );
res = 0xdeadbeef;
hr = IDirectInputEffect_GetEffectStatus( effect, &res );
ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
todo_wine
ok( res == DIEGES_PLAYING, "got status %#x\n", res );
+ set_hid_expect( file, &expect_stop_2, sizeof(expect_stop_2) );
+ hr = IDirectInputEffect_Stop( effect2 );
+ ok( hr == DI_OK, "Stop returned %#x\n", hr );
+ set_hid_expect( file, NULL, 0 );
+ res = 0xdeadbeef;
+ hr = IDirectInputEffect_GetEffectStatus( effect2, &res );
+ ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
+ ok( res == 0, "got status %#x\n", res );
+ set_hid_expect( file, expect_destroy_2, sizeof(expect_destroy_2) );
+ ref = IDirectInputEffect_Release( effect2 );
+ ok( ref == 0, "Release returned %d\n", ref );
+ set_hid_expect( file, NULL, 0 );
+
+ /* sending commands has no direct effect on status */
+ set_hid_expect( file, expect_stop_all, sizeof(expect_stop_all) );
+ hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_STOPALL );
+ ok( hr == DI_OK, "SendForceFeedbackCommand returned %#x\n", hr );
+ set_hid_expect( file, NULL, 0 );
+ res = 0xdeadbeef;
+ hr = IDirectInputEffect_GetEffectStatus( effect, &res );
+ ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
+ todo_wine
+ ok( res == DIEGES_PLAYING, "got status %#x\n", res );
+ set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
+ res = 0xdeadbeef;
+ hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
+ ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
+ flags = DIGFFS_STOPPED;
+ todo_wine
+ ok( res == flags, "got state %#x\n", res );
+ set_hid_expect( file, NULL, 0 );
+
+ set_hid_expect( file, expect_device_pause, sizeof(expect_device_pause) );
+ hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_PAUSE );
+ ok( hr == DI_OK, "SendForceFeedbackCommand returned %#x\n", hr );
+ set_hid_expect( file, NULL, 0 );
+ res = 0xdeadbeef;
+ hr = IDirectInputEffect_GetEffectStatus( effect, &res );
+ ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
+ todo_wine
+ ok( res == DIEGES_PLAYING, "got status %#x\n", res );
+ set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
+ res = 0xdeadbeef;
+ hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
+ ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
+ flags = DIGFFS_STOPPED;
+ todo_wine
+ ok( res == flags, "got state %#x\n", res );
+ set_hid_expect( file, NULL, 0 );
+
+ set_hid_expect( file, expect_device_continue, sizeof(expect_device_continue) );
+ hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_CONTINUE );
+ ok( hr == DI_OK, "SendForceFeedbackCommand returned %#x\n", hr );
+ set_hid_expect( file, NULL, 0 );
+ res = 0xdeadbeef;
+ hr = IDirectInputEffect_GetEffectStatus( effect, &res );
+ ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
+ todo_wine
+ ok( res == DIEGES_PLAYING, "got status %#x\n", res );
+ set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
+ res = 0xdeadbeef;
+ hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
+ ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
+ flags = DIGFFS_STOPPED;
+ todo_wine
+ ok( res == flags, "got state %#x\n", res );
+ set_hid_expect( file, NULL, 0 );
+
+ set_hid_expect( file, expect_disable_actuators, sizeof(expect_disable_actuators) );
+ hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_SETACTUATORSOFF );
+ ok( hr == DI_OK, "SendForceFeedbackCommand returned %#x\n", hr );
+ set_hid_expect( file, NULL, 0 );
+ res = 0xdeadbeef;
+ hr = IDirectInputEffect_GetEffectStatus( effect, &res );
+ ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
+ todo_wine
+ ok( res == DIEGES_PLAYING, "got status %#x\n", res );
+ set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
+ res = 0xdeadbeef;
+ hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
+ ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
+ flags = DIGFFS_STOPPED;
+ todo_wine
+ ok( res == flags, "got state %#x\n", res );
+ set_hid_expect( file, NULL, 0 );
+
+ set_hid_expect( file, expect_enable_actuators, sizeof(expect_enable_actuators) );
+ hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_SETACTUATORSON );
+ ok( hr == DI_OK, "SendForceFeedbackCommand returned %#x\n", hr );
+ set_hid_expect( file, NULL, 0 );
+ res = 0xdeadbeef;
+ hr = IDirectInputEffect_GetEffectStatus( effect, &res );
+ ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
+ todo_wine
+ ok( res == DIEGES_PLAYING, "got status %#x\n", res );
+ set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
+ res = 0xdeadbeef;
+ hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
+ ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
+ flags = DIGFFS_STOPPED;
+ todo_wine
+ ok( res == flags, "got state %#x\n", res );
+ set_hid_expect( file, NULL, 0 );
+
+ set_hid_expect( file, &expect_stop, sizeof(expect_stop) );
+ hr = IDirectInputEffect_Stop( effect );
+ ok( hr == DI_OK, "Stop returned %#x\n", hr );
+ set_hid_expect( file, NULL, 0 );
+ res = 0xdeadbeef;
+ hr = IDirectInputEffect_GetEffectStatus( effect, &res );
+ ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
+ ok( res == 0, "got status %#x\n", res );
+ set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
+ res = 0xdeadbeef;
+ hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
+ ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
+ flags = DIGFFS_STOPPED;
+ todo_wine
+ ok( res == flags, "got state %#x\n", res );
+ set_hid_expect( file, NULL, 0 );
+
+ send_hid_input( file, device_state_input_0, sizeof(device_state_input_0) );
+ res = WaitForSingleObject( event, 100 );
+ ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#x\n", res );
+ set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
+ res = 0xdeadbeef;
+ hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
+ ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
+ flags = DIGFFS_PAUSED|DIGFFS_ACTUATORSON|DIGFFS_POWERON|DIGFFS_SAFETYSWITCHON|DIGFFS_USERFFSWITCHON;
+ todo_wine
+ ok( res == flags, "got state %#x\n", res );
+ set_hid_expect( file, NULL, 0 );
send_hid_input( file, device_state_input_1, sizeof(device_state_input_1) );
res = WaitForSingleObject( event, 100 );
@@ -9087,8 +9435,7 @@ static void test_device_managed_effect(void)
res = 0xdeadbeef;
hr = IDirectInputEffect_GetEffectStatus( effect, &res );
ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
- todo_wine
- ok( res == DIEGES_PLAYING, "got status %#x\n", res );
+ ok( res == 0, "got status %#x\n", res );
set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
res = 0xdeadbeef;
hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
--
2.34.0
Dec. 1, 2021
[PATCH 4/7] dinput8/tests: Add dwStartDelay / dwDuration GetEffectStatus tests.
by Rémi Bernon
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52062
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/dinput8/tests/hid.c | 129 +++++++++++++++++++++++++++++++++++++++
1 file changed, 129 insertions(+)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c
index 57e5672bd92..d0ca3746e96 100644
--- a/dlls/dinput8/tests/hid.c
+++ b/dlls/dinput8/tests/hid.c
@@ -8637,6 +8637,82 @@ static void test_device_managed_effect(void)
.report_buf = {3,0x01,0x03,0x08,0x01,0x00,0x06,0x00,0x01,0x55,0x00},
},
};
+ struct hid_expect expect_create_delay[] =
+ {
+ /* create new effect */
+ {
+ .code = IOCTL_HID_SET_FEATURE,
+ .report_id = 2,
+ .report_len = 2,
+ .report_buf = {2,0x03},
+ },
+ /* block load */
+ {
+ .code = IOCTL_HID_GET_FEATURE,
+ .report_id = 3,
+ .report_len = 5,
+ .report_buf = {3,0x01,0x01,0x00,0x00},
+ },
+ /* set condition */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 4,
+ .report_len = 8,
+ .report_buf = {4,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
+ },
+ /* set condition */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 4,
+ .report_len = 8,
+ .report_buf = {4,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
+ },
+ /* update effect */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 3,
+ .report_len = 11,
+ .report_buf = {3,0x01,0x03,0x08,0x01,0x00,0xff,0x7f,0x01,0x55,0x00},
+ },
+ };
+ struct hid_expect expect_create_duration[] =
+ {
+ /* create new effect */
+ {
+ .code = IOCTL_HID_SET_FEATURE,
+ .report_id = 2,
+ .report_len = 2,
+ .report_buf = {2,0x03},
+ },
+ /* block load */
+ {
+ .code = IOCTL_HID_GET_FEATURE,
+ .report_id = 3,
+ .report_len = 5,
+ .report_buf = {3,0x01,0x01,0x00,0x00},
+ },
+ /* set condition */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 4,
+ .report_len = 8,
+ .report_buf = {4,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
+ },
+ /* set condition */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 4,
+ .report_len = 8,
+ .report_buf = {4,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
+ },
+ /* update effect */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 3,
+ .report_len = 11,
+ .report_buf = {3,0x01,0x03,0x08,0x00,0x00,0x00,0x00,0x01,0x55,0x00},
+ },
+ };
struct hid_expect expect_start =
{
/* effect control */
@@ -8827,6 +8903,7 @@ static void test_device_managed_effect(void)
IDirectInputEffect *effect;
HANDLE file, event;
ULONG res, ref;
+ DIEFFECT desc;
DWORD flags;
HRESULT hr;
HWND hwnd;
@@ -9060,6 +9137,58 @@ static void test_device_managed_effect(void)
ref = IDirectInputEffect_Release( effect );
ok( ref == 0, "Release returned %d\n", ref );
+ /* start delay has no direct effect on effect status */
+ desc = expect_desc;
+ desc.dwStartDelay = 32767000;
+ set_hid_expect( file, expect_create_delay, sizeof(expect_create_delay) );
+ hr = IDirectInputDevice8_CreateEffect( device, &GUID_Spring, &desc, &effect, NULL );
+ ok( hr == DI_OK, "CreateEffect returned %#x\n", hr );
+ set_hid_expect( file, NULL, 0 );
+ res = 0xdeadbeef;
+ hr = IDirectInputEffect_GetEffectStatus( effect, &res );
+ ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
+ ok( res == 0, "got status %#x\n", res );
+ set_hid_expect( file, &expect_start, sizeof(expect_start) );
+ hr = IDirectInputEffect_Start( effect, 1, 0 );
+ ok( hr == DI_OK, "Start returned %#x\n", hr );
+ set_hid_expect( file, NULL, 0 );
+ res = 0xdeadbeef;
+ hr = IDirectInputEffect_GetEffectStatus( effect, &res );
+ ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
+ todo_wine
+ ok( res == DIEGES_PLAYING, "got status %#x\n", res );
+ set_hid_expect( file, expect_destroy, sizeof(expect_destroy) );
+ ref = IDirectInputEffect_Release( effect );
+ ok( ref == 0, "Release returned %d\n", ref );
+ set_hid_expect( file, NULL, 0 );
+
+ /* duration has no direct effect on effect status */
+ desc = expect_desc;
+ desc.dwDuration = 100;
+ desc.dwStartDelay = 0;
+ set_hid_expect( file, expect_create_duration, sizeof(expect_create_duration) );
+ hr = IDirectInputDevice8_CreateEffect( device, &GUID_Spring, &desc, &effect, NULL );
+ ok( hr == DI_OK, "CreateEffect returned %#x\n", hr );
+ set_hid_expect( file, NULL, 0 );
+ res = 0xdeadbeef;
+ hr = IDirectInputEffect_GetEffectStatus( effect, &res );
+ ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
+ ok( res == 0, "got status %#x\n", res );
+ set_hid_expect( file, &expect_start, sizeof(expect_start) );
+ hr = IDirectInputEffect_Start( effect, 1, 0 );
+ ok( hr == DI_OK, "Start returned %#x\n", hr );
+ set_hid_expect( file, NULL, 0 );
+ Sleep( 100 );
+ res = 0xdeadbeef;
+ hr = IDirectInputEffect_GetEffectStatus( effect, &res );
+ ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
+ todo_wine
+ ok( res == DIEGES_PLAYING, "got status %#x\n", res );
+ set_hid_expect( file, expect_destroy, sizeof(expect_destroy) );
+ ref = IDirectInputEffect_Release( effect );
+ ok( ref == 0, "Release returned %d\n", ref );
+ set_hid_expect( file, NULL, 0 );
+
set_hid_expect( file, expect_reset, sizeof(struct hid_expect) );
hr = IDirectInputDevice8_Unacquire( device );
ok( hr == DI_OK, "Unacquire returned: %#x\n", hr );
--
2.34.0
Dec. 1, 2021
[PATCH 3/7] dinput8/tests: Add a device gain report to test_device_managed_effect.
by Rémi Bernon
From: Ivo Ivanov <logos128(a)gmail.com>
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52062
Signed-off-by: Ivo Ivanov <logos128(a)gmail.com>
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/dinput8/tests/hid.c | 35 +++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c
index c0bfc8e8b30..57e5672bd92 100644
--- a/dlls/dinput8/tests/hid.c
+++ b/dlls/dinput8/tests/hid.c
@@ -8462,6 +8462,20 @@ static void test_device_managed_effect(void)
OUTPUT(1, Data|Var|Abs),
END_COLLECTION,
+ USAGE(1, PID_USAGE_DEVICE_GAIN_REPORT),
+ COLLECTION(1, Logical),
+ REPORT_ID(1, 6),
+
+ USAGE(1, PID_USAGE_DEVICE_GAIN),
+ LOGICAL_MINIMUM(1, 0),
+ LOGICAL_MAXIMUM(2, 0x00ff),
+ PHYSICAL_MINIMUM(1, 0),
+ PHYSICAL_MAXIMUM(2, 0x2710),
+ REPORT_SIZE(1, 8),
+ REPORT_COUNT(1, 1),
+ OUTPUT(1, Data|Var|Abs),
+ END_COLLECTION,
+
USAGE(1, PID_USAGE_POOL_REPORT),
COLLECTION(1, Logical),
REPORT_ID(1, 1),
@@ -8558,6 +8572,23 @@ static void test_device_managed_effect(void)
{
.InputReportByteLength = 5,
};
+ struct hid_expect expect_acquire[] =
+ {
+ /* device reset */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 1,
+ .report_len = 2,
+ .report_buf = {1, 0x01},
+ },
+ /* device gain */
+ {
+ .code = IOCTL_HID_WRITE_REPORT,
+ .report_id = 6,
+ .report_len = 2,
+ .report_buf = {6, 0xff},
+ },
+ };
struct hid_expect expect_reset[] =
{
/* device reset */
@@ -8835,7 +8866,7 @@ static void test_device_managed_effect(void)
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_RESET );
ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "SendForceFeedbackCommand returned %#x\n", hr );
- set_hid_expect( file, expect_reset, sizeof(expect_reset) );
+ set_hid_expect( file, expect_acquire, sizeof(expect_acquire) );
hr = IDirectInputDevice8_Acquire( device );
ok( hr == DI_OK, "Acquire returned: %#x\n", hr );
wait_hid_expect( file, 100 );
@@ -8901,7 +8932,7 @@ static void test_device_managed_effect(void)
hr = IDirectInputEffect_GetEffectStatus( effect, &res );
ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "GetEffectStatus returned %#x\n", hr );
- set_hid_expect( file, expect_reset, sizeof(expect_reset) );
+ set_hid_expect( file, expect_acquire, sizeof(expect_acquire) );
hr = IDirectInputDevice8_Acquire( device );
ok( hr == DI_OK, "Acquire returned: %#x\n", hr );
wait_hid_expect( file, 100 );
--
2.34.0
Dec. 1, 2021
[PATCH 2/7] dinput8/tests: Add a check_buffer helper to print buffer data.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/dinput8/tests/driver_hid.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/dlls/dinput8/tests/driver_hid.c b/dlls/dinput8/tests/driver_hid.c
index 9a58b1c7d44..545dff0c2dc 100644
--- a/dlls/dinput8/tests/driver_hid.c
+++ b/dlls/dinput8/tests/driver_hid.c
@@ -467,6 +467,25 @@ static NTSTATUS WINAPI driver_power( DEVICE_OBJECT *device, IRP *irp )
return PoCallDriver( ext->NextDeviceObject, irp );
}
+#define check_buffer( a, b ) check_buffer_( __LINE__, a, b )
+static void check_buffer_( int line, HID_XFER_PACKET *packet, struct hid_expect *expect )
+{
+ ULONG match_len, i;
+
+ match_len = RtlCompareMemory( packet->reportBuffer, expect->report_buf, expect->report_len );
+ ok( match_len == expect->report_len, "unexpected data:\n" );
+ if (match_len == expect->report_len) return;
+
+ for (i = 0; i < packet->reportBufferLen;)
+ {
+ char buffer[256], *buf = buffer;
+ buf += sprintf( buf, "%08x ", i );
+ do buf += sprintf( buf, " %02x", packet->reportBuffer[i] );
+ while (++i % 16 && i < packet->reportBufferLen);
+ ok( 0, " %s\n", buffer );
+ }
+}
+
static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
{
IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp );
@@ -574,8 +593,7 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
ok( code == expect.code, "got %#x, expected %#x\n", code, expect.code );
ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId );
ok( packet->reportBufferLen == expect.report_len, "got len %u\n", packet->reportBufferLen );
- ok( RtlCompareMemory( packet->reportBuffer, expect.report_buf, expect.report_len ) == expect.report_len,
- "unexpected data\n" );
+ check_buffer( packet, &expect );
winetest_pop_context();
irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len;
@@ -621,8 +639,7 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
ok( code == expect.code, "got %#x, expected %#x\n", code, expect.code );
ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId );
ok( packet->reportBufferLen == expect.report_len, "got len %u\n", packet->reportBufferLen );
- ok( RtlCompareMemory( packet->reportBuffer, expect.report_buf, expect.report_len ) == expect.report_len,
- "unexpected data\n" );
+ check_buffer( packet, &expect );
winetest_pop_context();
irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len;
@@ -668,8 +685,7 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
ok( code == expect.code, "got %#x, expected %#x\n", code, expect.code );
ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId );
ok( packet->reportBufferLen == expect.report_len, "got len %u\n", packet->reportBufferLen );
- ok( RtlCompareMemory( packet->reportBuffer, expect.report_buf, expect.report_len ) == expect.report_len,
- "unexpected data\n" );
+ check_buffer( packet, &expect );
winetest_pop_context();
irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len;
--
2.34.0
Dec. 1, 2021
[PATCH 1/7] dinput8/tests: Provide an explicit test context to the driver.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/dinput8/tests/driver_hid.c | 51 ++++++++++++++++-------
dlls/dinput8/tests/driver_hid.h | 2 +-
dlls/dinput8/tests/hid.c | 73 +++++++++++++++++++--------------
3 files changed, 80 insertions(+), 46 deletions(-)
diff --git a/dlls/dinput8/tests/driver_hid.c b/dlls/dinput8/tests/driver_hid.c
index db7b3185906..9a58b1c7d44 100644
--- a/dlls/dinput8/tests/driver_hid.c
+++ b/dlls/dinput8/tests/driver_hid.c
@@ -56,6 +56,7 @@ struct expect_queue
struct hid_expect spurious;
struct hid_expect *buffer;
IRP *pending_wait;
+ char context[64];
};
static void expect_queue_init( struct expect_queue *queue )
@@ -93,6 +94,7 @@ static void expect_queue_cleanup( struct expect_queue *queue )
static void expect_queue_reset( struct expect_queue *queue, void *buffer, unsigned int size )
{
struct hid_expect *missing, *missing_end, *tmp;
+ char context[64];
KIRQL irql;
missing = ExAllocatePool( PagedPool, EXPECT_QUEUE_BUFFER_SIZE );
@@ -108,12 +110,13 @@ static void expect_queue_reset( struct expect_queue *queue, void *buffer, unsign
if (size) memcpy( queue->end, buffer, size );
queue->end = queue->end + size / sizeof(struct hid_expect);
+ memcpy( context, queue->context, sizeof(context) );
KeReleaseSpinLock( &queue->lock, irql );
tmp = missing;
while (tmp != missing_end)
{
- winetest_push_context( "%s expect[%d]", tmp->context, tmp - missing );
+ winetest_push_context( "%s expect[%d]", context, tmp - missing );
if (tmp->broken)
{
todo_wine_if( tmp->todo )
@@ -180,7 +183,8 @@ static NTSTATUS expect_queue_wait( struct expect_queue *queue, IRP *irp )
}
static void expect_queue_next( struct expect_queue *queue, ULONG code, HID_XFER_PACKET *packet,
- LONG *index, struct hid_expect *expect, BOOL compare_buf )
+ LONG *index, struct hid_expect *expect, BOOL compare_buf,
+ char *context, ULONG context_size )
{
struct hid_expect *missing, *missing_end, *tmp;
ULONG len = packet->reportBufferLen;
@@ -219,6 +223,7 @@ static void expect_queue_next( struct expect_queue *queue, ULONG code, HID_XFER_
queue->pending_wait = NULL;
if (!IoSetCancelRoutine( irp, NULL )) irp = NULL;
}
+ memcpy( context, queue->context, context_size );
KeReleaseSpinLock( &queue->lock, irql );
if (irp)
@@ -228,9 +233,9 @@ static void expect_queue_next( struct expect_queue *queue, ULONG code, HID_XFER_
IoCompleteRequest( irp, IO_NO_INCREMENT );
}
- ok( tmp != &queue->spurious, "got spurious packet\n" );
+ ok( tmp != &queue->spurious, "%s got spurious packet\n", context );
- winetest_push_context( "%s expect[%d]", tmp->context, tmp - queue->buffer );
+ winetest_push_context( "%s expect[%d]", context, tmp - queue->buffer );
todo_wine_if( tmp->todo )
ok( !tmp->wine_only, "found code %#x id %u len %u\n", tmp->code, tmp->report_id, tmp->report_len );
winetest_pop_context();
@@ -238,7 +243,7 @@ static void expect_queue_next( struct expect_queue *queue, ULONG code, HID_XFER_
tmp = missing;
while (tmp != missing_end)
{
- winetest_push_context( "%s expect[%d]", tmp->context, tmp - missing );
+ winetest_push_context( "%s expect[%d]", context, tmp - missing );
if (tmp->broken)
{
todo_wine_if( tmp->todo )
@@ -471,6 +476,7 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
ULONG out_size = stack->Parameters.DeviceIoControl.OutputBufferLength;
const ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
struct hid_expect expect = {0};
+ char context[64];
NTSTATUS ret;
BOOL removed;
KIRQL irql;
@@ -563,8 +569,8 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
ok( !out_size, "got output size %u\n", out_size );
ok( packet->reportBufferLen >= expected_size, "got report size %u\n", packet->reportBufferLen );
- expect_queue_next( &expect_queue, code, packet, &index, &expect, TRUE );
- winetest_push_context( "%s expect[%d]", expect.context, index );
+ expect_queue_next( &expect_queue, code, packet, &index, &expect, TRUE, context, sizeof(context) );
+ winetest_push_context( "%s expect[%d]", context, index );
ok( code == expect.code, "got %#x, expected %#x\n", code, expect.code );
ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId );
ok( packet->reportBufferLen == expect.report_len, "got len %u\n", packet->reportBufferLen );
@@ -587,8 +593,8 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
ok( packet->reportBufferLen >= expected_size, "got len %u\n", packet->reportBufferLen );
ok( !!packet->reportBuffer, "got buffer %p\n", packet->reportBuffer );
- expect_queue_next( &expect_queue, code, packet, &index, &expect, FALSE );
- winetest_push_context( "%s expect[%d]", expect.context, index );
+ expect_queue_next( &expect_queue, code, packet, &index, &expect, FALSE, context, sizeof(context) );
+ winetest_push_context( "%s expect[%d]", context, index );
ok( code == expect.code, "got %#x, expected %#x\n", code, expect.code );
ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId );
ok( packet->reportBufferLen == expect.report_len, "got len %u\n", packet->reportBufferLen );
@@ -610,8 +616,8 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
ok( packet->reportBufferLen >= expected_size, "got len %u\n", packet->reportBufferLen );
ok( !!packet->reportBuffer, "got buffer %p\n", packet->reportBuffer );
- expect_queue_next( &expect_queue, code, packet, &index, &expect, TRUE );
- winetest_push_context( "%s expect[%d]", expect.context, index );
+ expect_queue_next( &expect_queue, code, packet, &index, &expect, TRUE, context, sizeof(context) );
+ winetest_push_context( "%s expect[%d]", context, index );
ok( code == expect.code, "got %#x, expected %#x\n", code, expect.code );
ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId );
ok( packet->reportBufferLen == expect.report_len, "got len %u\n", packet->reportBufferLen );
@@ -634,8 +640,8 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
ok( packet->reportBufferLen >= expected_size, "got len %u\n", packet->reportBufferLen );
ok( !!packet->reportBuffer, "got buffer %p\n", packet->reportBuffer );
- expect_queue_next( &expect_queue, code, packet, &index, &expect, FALSE );
- winetest_push_context( "%s expect[%d]", expect.context, index );
+ expect_queue_next( &expect_queue, code, packet, &index, &expect, FALSE, context, sizeof(context) );
+ winetest_push_context( "%s expect[%d]", context, index );
ok( code == expect.code, "got %#x, expected %#x\n", code, expect.code );
ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId );
ok( packet->reportBufferLen == expect.report_len, "got len %u\n", packet->reportBufferLen );
@@ -657,8 +663,8 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
ok( packet->reportBufferLen >= expected_size, "got len %u\n", packet->reportBufferLen );
ok( !!packet->reportBuffer, "got buffer %p\n", packet->reportBuffer );
- expect_queue_next( &expect_queue, code, packet, &index, &expect, TRUE );
- winetest_push_context( "%s expect[%d]", expect.context, index );
+ expect_queue_next( &expect_queue, code, packet, &index, &expect, TRUE, context, sizeof(context) );
+ winetest_push_context( "%s expect[%d]", context, index );
ok( code == expect.code, "got %#x, expected %#x\n", code, expect.code );
ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId );
ok( packet->reportBufferLen == expect.report_len, "got len %u\n", packet->reportBufferLen );
@@ -702,6 +708,7 @@ static NTSTATUS WINAPI driver_ioctl( DEVICE_OBJECT *device, IRP *irp )
IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp );
ULONG in_size = stack->Parameters.DeviceIoControl.InputBufferLength;
ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
+ KIRQL irql;
switch (code)
{
@@ -714,6 +721,14 @@ static NTSTATUS WINAPI driver_ioctl( DEVICE_OBJECT *device, IRP *irp )
return expect_queue_wait( &expect_queue, irp );
case IOCTL_WINETEST_HID_SEND_INPUT:
input_queue_reset( &input_queue, irp->AssociatedIrp.SystemBuffer, in_size );
+ irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest( irp, IO_NO_INCREMENT );
+ return STATUS_SUCCESS;
+ case IOCTL_WINETEST_HID_SET_CONTEXT:
+ KeAcquireSpinLock( &expect_queue.lock, &irql );
+ memcpy( expect_queue.context, irp->AssociatedIrp.SystemBuffer, in_size );
+ KeReleaseSpinLock( &expect_queue.lock, irql );
+
irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest( irp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
@@ -837,6 +852,12 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *registry )
ok( !ret, "ZwQueryValueKey returned %#x\n", ret );
input_queue_reset( &input_queue, buffer + info_size, size - info_size );
+ RtlInitUnicodeString( &name_str, L"Context" );
+ size = info_size + sizeof(expect_queue.context);
+ ret = ZwQueryValueKey( hkey, &name_str, KeyValuePartialInformation, buffer, size, &size );
+ ok( !ret, "ZwQueryValueKey returned %#x\n", ret );
+ memcpy( expect_queue.context, buffer + info_size, size - info_size );
+
driver->DriverExtension->AddDevice = driver_add_device;
driver->DriverUnload = driver_unload;
driver->MajorFunction[IRP_MJ_PNP] = driver_pnp;
diff --git a/dlls/dinput8/tests/driver_hid.h b/dlls/dinput8/tests/driver_hid.h
index 191c0c7bae2..3d31b4ee824 100644
--- a/dlls/dinput8/tests/driver_hid.h
+++ b/dlls/dinput8/tests/driver_hid.h
@@ -42,6 +42,7 @@ DEFINE_GUID(control_class,0xdeadbeef,0x29ef,0x4538,0xa5,0xfd,0xb6,0x95,0x73,0xa3
#define IOCTL_WINETEST_HID_SET_EXPECT CTL_CODE(FILE_DEVICE_KEYBOARD, 0x800, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_WINETEST_HID_WAIT_EXPECT CTL_CODE(FILE_DEVICE_KEYBOARD, 0x801, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_WINETEST_HID_SEND_INPUT CTL_CODE(FILE_DEVICE_KEYBOARD, 0x802, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
+#define IOCTL_WINETEST_HID_SET_CONTEXT CTL_CODE(FILE_DEVICE_KEYBOARD, 0x803, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
struct hid_expect
{
@@ -54,7 +55,6 @@ struct hid_expect
BYTE report_id;
BYTE report_len;
BYTE report_buf[128];
- char context[64];
};
/* kernel/user shared data */
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c
index a8ea8eaea9f..c0bfc8e8b30 100644
--- a/dlls/dinput8/tests/hid.c
+++ b/dlls/dinput8/tests/hid.c
@@ -765,21 +765,25 @@ static BOOL sync_ioctl_( int line, HANDLE file, DWORD code, void *in_buf, DWORD
return ret;
}
+#define fill_context( line, a, b ) \
+ do { \
+ const char *source_file; \
+ source_file = strrchr( __FILE__, '/' ); \
+ if (!source_file) source_file = strrchr( __FILE__, '\\' ); \
+ if (!source_file) source_file = __FILE__; \
+ else source_file++; \
+ snprintf( a, b, "%s:%d", source_file, line ); \
+ } while (0)
+
#define set_hid_expect( a, b, c ) set_hid_expect_( __LINE__, a, b, c )
static void set_hid_expect_( int line, HANDLE file, struct hid_expect *expect, DWORD expect_size )
{
- const char *source_file;
+ char context[64];
BOOL ret;
- int i;
-
- source_file = strrchr( __FILE__, '/' );
- if (!source_file) source_file = strrchr( __FILE__, '\\' );
- if (!source_file) source_file = __FILE__;
- else source_file++;
-
- for (i = 0; i < expect_size / sizeof(struct hid_expect); ++i)
- snprintf( expect[i].context, ARRAY_SIZE(expect[i].context), "%s:%d", source_file, line );
+ fill_context( line, context, ARRAY_SIZE(context) );
+ ret = sync_ioctl_( line, file, IOCTL_WINETEST_HID_SET_CONTEXT, context, ARRAY_SIZE(context), NULL, 0, INFINITE );
+ ok_(__FILE__, line)( ret, "IOCTL_WINETEST_HID_SET_CONTEXT failed, last error %u\n", GetLastError() );
ret = sync_ioctl_( line, file, IOCTL_WINETEST_HID_SET_EXPECT, expect, expect_size, NULL, 0, INFINITE );
ok_(__FILE__, line)( ret, "IOCTL_WINETEST_HID_SET_EXPECT failed, last error %u\n", GetLastError() );
}
@@ -796,18 +800,12 @@ static void wait_hid_expect_( int line, HANDLE file, DWORD timeout )
#define send_hid_input( a, b, c ) send_hid_input_( __LINE__, a, b, c )
static void send_hid_input_( int line, HANDLE file, struct hid_expect *expect, DWORD expect_size )
{
- const char *source_file;
+ char context[64];
BOOL ret;
- int i;
-
- source_file = strrchr( __FILE__, '/' );
- if (!source_file) source_file = strrchr( __FILE__, '\\' );
- if (!source_file) source_file = __FILE__;
- else source_file++;
-
- for (i = 0; i < expect_size / sizeof(struct hid_expect); ++i)
- snprintf( expect[i].context, ARRAY_SIZE(expect[i].context), "%s:%d", source_file, line );
+ fill_context( line, context, ARRAY_SIZE(context) );
+ ret = sync_ioctl_( line, file, IOCTL_WINETEST_HID_SET_CONTEXT, context, ARRAY_SIZE(context), NULL, 0, INFINITE );
+ ok_(__FILE__, line)( ret, "IOCTL_WINETEST_HID_SET_CONTEXT failed, last error %u\n", GetLastError() );
ret = sync_ioctl( file, IOCTL_WINETEST_HID_SEND_INPUT, expect, expect_size, NULL, 0, INFINITE );
ok( ret, "IOCTL_WINETEST_HID_SEND_INPUT failed, last error %u\n", GetLastError() );
}
@@ -2750,6 +2748,7 @@ static void test_hid_driver( DWORD report_id, DWORD polled )
};
WCHAR cwd[MAX_PATH], tempdir[MAX_PATH];
+ char context[64];
LSTATUS status;
HKEY hkey;
@@ -2782,6 +2781,10 @@ static void test_hid_driver( DWORD report_id, DWORD polled )
status = RegSetValueExW( hkey, L"Input", 0, REG_BINARY, (void *)&expect_in, polled ? sizeof(expect_in) : 0 );
ok( !status, "RegSetValueExW returned %#x\n", status );
+ fill_context( __LINE__, context, ARRAY_SIZE(context) );
+ status = RegSetValueExW( hkey, L"Context", 0, REG_BINARY, (void *)context, sizeof(context) );
+ ok( !status, "RegSetValueExW returned %#x\n", status );
+
if (pnp_driver_start( L"driver_hid.dll" )) test_hid_device( report_id, polled, &caps );
pnp_driver_stop();
@@ -3102,6 +3105,7 @@ static void test_hidp_kdr(void)
PHIDP_PREPARSED_DATA preparsed_data;
DWORD i, report_id = 0, polled = 0;
struct hidp_kdr *kdr;
+ char context[64];
LSTATUS status;
HDEVINFO set;
HANDLE file;
@@ -3137,6 +3141,10 @@ static void test_hidp_kdr(void)
status = RegSetValueExW( hkey, L"Input", 0, REG_BINARY, NULL, 0 );
ok( !status, "RegSetValueExW returned %#x\n", status );
+ fill_context( __LINE__, context, ARRAY_SIZE(context) );
+ status = RegSetValueExW( hkey, L"Context", 0, REG_BINARY, (void *)context, sizeof(context) );
+ ok( !status, "RegSetValueExW returned %#x\n", status );
+
if (!pnp_driver_start( L"driver_hid.dll" )) goto done;
set = SetupDiGetClassDevsW( &GUID_DEVINTERFACE_HID, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT );
@@ -3291,8 +3299,9 @@ static void cleanup_registry_keys(void)
RegCloseKey( root_key );
}
-static BOOL dinput_driver_start( const BYTE *desc_buf, ULONG desc_len, const HIDP_CAPS *caps,
- struct hid_expect *expect, ULONG expect_size )
+#define dinput_driver_start( a, b, c, d, e ) dinput_driver_start_( __LINE__, a, b, c, d, e )
+static BOOL dinput_driver_start_( int line, const BYTE *desc_buf, ULONG desc_len, const HIDP_CAPS *caps,
+ struct hid_expect *expect, ULONG expect_size )
{
static const HID_DEVICE_ATTRIBUTES attributes =
{
@@ -3303,26 +3312,30 @@ static BOOL dinput_driver_start( const BYTE *desc_buf, ULONG desc_len, const HID
};
DWORD report_id = 1;
DWORD polled = 0;
+ char context[64];
LSTATUS status;
HKEY hkey;
status = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Services\\winetest",
0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL );
- ok( !status, "RegCreateKeyExW returned %#x\n", status );
+ ok_(__FILE__, line)( !status, "RegCreateKeyExW returned %#x\n", status );
status = RegSetValueExW( hkey, L"ReportID", 0, REG_DWORD, (void *)&report_id, sizeof(report_id) );
- ok( !status, "RegSetValueExW returned %#x\n", status );
+ ok_(__FILE__, line)( !status, "RegSetValueExW returned %#x\n", status );
status = RegSetValueExW( hkey, L"PolledMode", 0, REG_DWORD, (void *)&polled, sizeof(polled) );
- ok( !status, "RegSetValueExW returned %#x\n", status );
+ ok_(__FILE__, line)( !status, "RegSetValueExW returned %#x\n", status );
status = RegSetValueExW( hkey, L"Descriptor", 0, REG_BINARY, (void *)desc_buf, desc_len );
- ok( !status, "RegSetValueExW returned %#x\n", status );
+ ok_(__FILE__, line)( !status, "RegSetValueExW returned %#x\n", status );
status = RegSetValueExW( hkey, L"Attributes", 0, REG_BINARY, (void *)&attributes, sizeof(attributes) );
- ok( !status, "RegSetValueExW returned %#x\n", status );
+ ok_(__FILE__, line)( !status, "RegSetValueExW returned %#x\n", status );
status = RegSetValueExW( hkey, L"Caps", 0, REG_BINARY, (void *)caps, sizeof(*caps) );
- ok( !status, "RegSetValueExW returned %#x\n", status );
+ ok_(__FILE__, line)( !status, "RegSetValueExW returned %#x\n", status );
status = RegSetValueExW( hkey, L"Expect", 0, REG_BINARY, (void *)expect, expect_size );
- ok( !status, "RegSetValueExW returned %#x\n", status );
+ ok_(__FILE__, line)( !status, "RegSetValueExW returned %#x\n", status );
status = RegSetValueExW( hkey, L"Input", 0, REG_BINARY, NULL, 0 );
- ok( !status, "RegSetValueExW returned %#x\n", status );
+ ok_(__FILE__, line)( !status, "RegSetValueExW returned %#x\n", status );
+ fill_context( line, context, ARRAY_SIZE(context) );
+ status = RegSetValueExW( hkey, L"Context", 0, REG_BINARY, (void *)context, sizeof(context) );
+ ok_(__FILE__, line)( !status, "RegSetValueExW returned %#x\n", status );
return pnp_driver_start( L"driver_hid.dll" );
}
--
2.34.0
Dec. 1, 2021
[PATCH] ntdll/tests: Fix iret to invalid selector test on x64.
by Paul Gofman
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/ntdll/tests/exception.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index a592ca9cf3c..0c66035568c 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -2833,8 +2833,8 @@ static const struct exception
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
/* test iret to invalid selector */
- { { 0x6a, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0xcf, 0x83, 0xc4, 0x18, 0xc3 },
- /* 15: pushq $0; pushq $0; pushq $0; iret; addl $24,%esp; ret */
+ { { 0x6a, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0xcf, 0x48, 0x83, 0xc4, 0x18, 0xc3 },
+ /* 15: pushq $0; pushq $0; pushq $0; iret; addq $24,%rsp; ret */
6, 1, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffffffffffff } },
/* 15 */
/* test loading an invalid selector */
--
2.33.1
Dec. 1, 2021