From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/device.c | 5 ++--- dlls/dinput/dinput.c | 30 ++++++++++++++++++++++++------ dlls/dinput/dinput_private.h | 4 ++++ dlls/dinput/tests/device8.c | 1 - dlls/dinput/tests/hid.c | 2 -- 5 files changed, 30 insertions(+), 12 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index afb3a1512bb..7f97067bd81 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -716,7 +716,7 @@ void dinput_device_internal_release( struct dinput_device *impl )
free( impl->action_map );
- IDirectInput_Release( &impl->dinput->IDirectInput7A_iface ); + dinput_internal_release( impl->dinput ); impl->crit.DebugInfo->Spare[0] = 0; DeleteCriticalSection( &impl->crit );
@@ -2125,8 +2125,7 @@ void dinput_device_init( struct dinput_device *device, const struct dinput_devic device->device_gain = 10000; device->force_feedback_state = DIGFFS_STOPPED | DIGFFS_EMPTY; InitializeCriticalSection( &device->crit ); - device->dinput = dinput; - IDirectInput_AddRef( &dinput->IDirectInput7A_iface ); + dinput_internal_addref( (device->dinput = dinput) ); device->vtbl = vtbl; }
diff --git a/dlls/dinput/dinput.c b/dlls/dinput/dinput.c index 08d36246071..7cf06364dc3 100644 --- a/dlls/dinput/dinput.c +++ b/dlls/dinput/dinput.c @@ -107,6 +107,28 @@ static HRESULT WINAPI dinput7_EnumDevices( IDirectInput7W *iface, DWORD type, LP return IDirectInput8_EnumDevices( &impl->IDirectInput8W_iface, type, callback, context, flags ); }
+void dinput_internal_addref( struct dinput *impl ) +{ + ULONG ref = InterlockedIncrement( &impl->internal_ref ); + TRACE( "impl %p, internal ref %lu.\n", impl, ref ); +} + +void dinput_internal_release( struct dinput *impl ) +{ + ULONG ref = InterlockedDecrement( &impl->internal_ref ); + TRACE( "impl %p, internal ref %lu.\n", impl, ref ); + + if (!ref) + { + struct DevicePlayer *device_player, *device_player2; + + LIST_FOR_EACH_ENTRY_SAFE( device_player, device_player2, &impl->device_players, struct DevicePlayer, entry ) + free( device_player ); + + free( impl ); + } +} + static ULONG WINAPI dinput7_AddRef( IDirectInput7W *iface ) { struct dinput *impl = impl_from_IDirectInput7W( iface ); @@ -124,12 +146,7 @@ static ULONG WINAPI dinput7_Release( IDirectInput7W *iface )
if (!ref) { - struct DevicePlayer *device_player, *device_player2; - - LIST_FOR_EACH_ENTRY_SAFE( device_player, device_player2, &impl->device_players, struct DevicePlayer, entry ) - free( device_player ); - - free( impl ); + dinput_internal_release( impl ); }
return ref; @@ -792,6 +809,7 @@ static HRESULT dinput_create( IUnknown **out ) impl->IDirectInput8A_iface.lpVtbl = &dinput8_a_vtbl; impl->IDirectInput8W_iface.lpVtbl = &dinput8_vtbl; impl->IDirectInputJoyConfig8_iface.lpVtbl = &joy_config_vtbl; + impl->internal_ref = 1; impl->ref = 1;
list_init( &impl->device_players ); diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h index 79a5baabb6e..fb9558716a3 100644 --- a/dlls/dinput/dinput_private.h +++ b/dlls/dinput/dinput_private.h @@ -36,6 +36,7 @@ struct dinput IDirectInput8A IDirectInput8A_iface; IDirectInput8W IDirectInput8W_iface; IDirectInputJoyConfig8 IDirectInputJoyConfig8_iface; + LONG internal_ref; LONG ref;
DWORD dwVersion; /* direct input version number */ @@ -46,6 +47,9 @@ struct dinput extern const IDirectInput7AVtbl dinput7_a_vtbl DECLSPEC_HIDDEN; extern const IDirectInput8AVtbl dinput8_a_vtbl DECLSPEC_HIDDEN;
+extern void dinput_internal_addref( struct dinput *dinput ); +extern void dinput_internal_release( struct dinput *dinput ); + extern HRESULT mouse_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version ); extern HRESULT mouse_create_device( struct dinput *dinput, const GUID *guid, IDirectInputDevice8W **out ); extern HRESULT keyboard_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version ); diff --git a/dlls/dinput/tests/device8.c b/dlls/dinput/tests/device8.c index 86f0360c0f1..449402621a7 100644 --- a/dlls/dinput/tests/device8.c +++ b/dlls/dinput/tests/device8.c @@ -116,7 +116,6 @@ static HRESULT create_dinput_device( DWORD version, const GUID *guid, IDirectInp ok( hr == DI_OK, "CreateDevice returned %#lx\n", hr );
ref = IDirectInput_Release( dinput ); - todo_wine ok( ref == 0, "Release returned %ld\n", ref );
return DI_OK; diff --git a/dlls/dinput/tests/hid.c b/dlls/dinput/tests/hid.c index a5ede6ee29b..facbf69fcec 100644 --- a/dlls/dinput/tests/hid.c +++ b/dlls/dinput/tests/hid.c @@ -3689,7 +3689,6 @@ HRESULT dinput_test_create_device( DWORD version, DIDEVICEINSTANCEW *devinst, ID ok( hr == DI_OK, "CreateDevice returned %#lx\n", hr );
ref = IDirectInput8_Release( di8 ); - todo_wine ok( ref == 0, "Release returned %ld\n", ref ); } else @@ -3716,7 +3715,6 @@ HRESULT dinput_test_create_device( DWORD version, DIDEVICEINSTANCEW *devinst, ID ok( hr == DI_OK, "CreateDevice returned %#lx\n", hr );
ref = IDirectInput_Release( di ); - todo_wine ok( ref == 0, "Release returned %ld\n", ref ); }