Vitaliy Margolen : dinput: Keep the list of all the dinput devices created for each IDIrectInput object .

Alexandre Julliard julliard at wine.codeweavers.com
Mon Jul 9 10:24:57 CDT 2007


Module: wine
Branch: master
Commit: 448dde9be8e1334d20b404288367e1c47edb485c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=448dde9be8e1334d20b404288367e1c47edb485c

Author: Vitaliy Margolen <wine-patches at kievinfo.com>
Date:   Fri Jul  6 23:36:09 2007 -0600

dinput: Keep the list of all the dinput devices created for each IDIrectInput object.

---

 dlls/dinput/device.c         |    4 ++++
 dlls/dinput/device_private.h |    2 ++
 dlls/dinput/dinput_main.c    |   40 +++++++++++++++++++++++++++++++---------
 dlls/dinput/dinput_private.h |   12 +++++++-----
 4 files changed, 44 insertions(+), 14 deletions(-)

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 @@ ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE8A iface)
     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 @@ struct IDirectInputDevice2AImpl
     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 @@ HRESULT WINAPI DirectInputCreateEx(
         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_AddRef(LPDIRECTINPUT7A iface)
 
 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 @@ static HRESULT WINAPI IDirectInput7AImpl_CreateDeviceEx(LPDIRECTINPUT7A iface, R
   /* 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 @@ static HRESULT WINAPI IDirectInput7WImpl_CreateDeviceEx(LPDIRECTINPUT7W iface, R
   /* 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 */




More information about the wine-cvs mailing list