dinput: Keep the list of all the dinput devices created for each IDIrectInput object.
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 35bf117..618665f 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -688,6 +688,10 @@
HeapFree(GetProcessHeap(), 0, This->data_format.wine_df);
release_DataFormat(&This->data_format);
+ EnterCriticalSection( &This->dinput->crit );
+ list_remove( &This->entry );
+ LeaveCriticalSection( &This->dinput->crit );
+
IDirectInput_Release((LPDIRECTINPUTDEVICE8A)This->dinput);
This->crit.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->crit);
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index 6295d6c..2ac609b 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -25,6 +25,7 @@
#include "windef.h"
#include "winbase.h"
#include "dinput.h"
+#include "wine/list.h"
#include "dinput_private.h"
typedef struct
@@ -55,6 +56,7 @@
GUID guid;
CRITICAL_SECTION crit;
IDirectInputImpl *dinput;
+ struct list entry; /* entry into IDirectInput devices list */
HANDLE hEvent;
DWORD dwCoopLevel;
HWND win;
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index 28718fa..52be7f3 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -43,6 +43,7 @@
#include "winuser.h"
#include "winerror.h"
#include "dinput_private.h"
+#include "device_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(dinput);
@@ -129,6 +130,11 @@
This->dwVersion = dwVersion;
This->evsequence = 1;
*ppDI = This;
+
+ InitializeCriticalSection(&This->crit);
+ This->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectInputImpl*->crit");
+
+ list_init( &This->devices_list );
}
return res;
}
@@ -254,15 +260,19 @@
static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUT7A iface)
{
- IDirectInputImpl *This = (IDirectInputImpl *)iface;
- ULONG ref;
- ref = InterlockedDecrement(&(This->ref));
- if (ref == 0)
- {
- HeapFree(GetProcessHeap(), 0, This);
- release_hook_thread();
- }
- return ref;
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ ULONG ref;
+
+ ref = InterlockedDecrement( &This->ref );
+ if (ref) return ref;
+
+ release_hook_thread();
+
+ This->crit.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection( &This->crit );
+ HeapFree( GetProcessHeap(), 0, This );
+
+ return 0;
}
static HRESULT WINAPI IDirectInputAImpl_QueryInterface(LPDIRECTINPUT7A iface, REFIID riid, LPVOID *ppobj) {
@@ -355,9 +365,15 @@
/* Loop on all the devices to see if anyone matches the given GUID */
for (i = 0; i < NB_DINPUT_DEVICES; i++) {
HRESULT ret;
+
if (!dinput_devices[i]->create_deviceA) continue;
if ((ret = dinput_devices[i]->create_deviceA(This, rguid, riid, (LPDIRECTINPUTDEVICEA*) pvOut)) == DI_OK)
+ {
+ EnterCriticalSection( &This->crit );
+ list_add_tail( &This->devices_list, &(*(IDirectInputDevice2AImpl**)pvOut)->entry );
+ LeaveCriticalSection( &This->crit );
return DI_OK;
+ }
if (ret == DIERR_NOINTERFACE)
ret_value = DIERR_NOINTERFACE;
@@ -380,9 +396,15 @@
/* Loop on all the devices to see if anyone matches the given GUID */
for (i = 0; i < NB_DINPUT_DEVICES; i++) {
HRESULT ret;
+
if (!dinput_devices[i]->create_deviceW) continue;
if ((ret = dinput_devices[i]->create_deviceW(This, rguid, riid, (LPDIRECTINPUTDEVICEW*) pvOut)) == DI_OK)
+ {
+ EnterCriticalSection( &This->crit );
+ list_add_tail( &This->devices_list, &(*(IDirectInputDevice2AImpl**)pvOut)->entry );
+ LeaveCriticalSection( &This->crit );
return DI_OK;
+ }
if (ret == DIERR_NOINTERFACE)
ret_value = DIERR_NOINTERFACE;
diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h
index d3f58a3..b29f61e 100644
--- a/dlls/dinput/dinput_private.h
+++ b/dlls/dinput/dinput_private.h
@@ -24,18 +24,20 @@
#include "windef.h"
#include "winbase.h"
#include "dinput.h"
+#include "wine/list.h"
/* Implementation specification */
typedef struct IDirectInputImpl IDirectInputImpl;
struct IDirectInputImpl
{
- const void *lpVtbl;
- LONG ref;
+ const void *lpVtbl;
+ LONG ref;
- /* Used to have an unique sequence number for all the events */
- DWORD evsequence;
+ CRITICAL_SECTION crit;
- DWORD dwVersion;
+ DWORD evsequence; /* unique sequence number for events */
+ DWORD dwVersion; /* direct input version number */
+ struct list devices_list; /* list of all created dinput devices */
};
/* Function called by all devices that Wine supports */