dplayx: IDirectPlay4 / IDirectPlay4A have independent refcounts.
This commit is contained in:
parent
4a9cd63072
commit
719b5d931c
|
@ -355,6 +355,13 @@ static BOOL DP_DestroyDirectPlay2( LPVOID lpDP )
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dplay_destroy(IDirectPlayImpl *obj)
|
||||||
|
{
|
||||||
|
DP_DestroyDirectPlay2( obj );
|
||||||
|
obj->lock.DebugInfo->Spare[0] = 0;
|
||||||
|
DeleteCriticalSection( &obj->lock );
|
||||||
|
HeapFree( GetProcessHeap(), 0, obj );
|
||||||
|
}
|
||||||
|
|
||||||
/* Direct Play methods */
|
/* Direct Play methods */
|
||||||
|
|
||||||
|
@ -381,36 +388,6 @@ static HRESULT WINAPI DP_QueryInterface( IDirectPlayImpl *This, REFIID riid, voi
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shared between all dplay types */
|
|
||||||
static ULONG WINAPI DP_AddRef( IDirectPlayImpl *This )
|
|
||||||
{
|
|
||||||
ULONG ulInterfaceRefCount = InterlockedIncrement( &This->ulInterfaceRef );
|
|
||||||
|
|
||||||
TRACE( "ref count incremented to %u for %p\n", ulInterfaceRefCount, This );
|
|
||||||
|
|
||||||
return ulInterfaceRefCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG WINAPI DP_Release( IDirectPlayImpl *This )
|
|
||||||
{
|
|
||||||
ULONG ulInterfaceRefCount = InterlockedDecrement( &This->ulInterfaceRef );
|
|
||||||
|
|
||||||
TRACE( "ref count decremented to %u for %p\n", ulInterfaceRefCount, This );
|
|
||||||
|
|
||||||
/* Deallocate if this is the last reference to the object */
|
|
||||||
if( ulInterfaceRefCount == 0 )
|
|
||||||
{
|
|
||||||
/* If we're destroying the object, this must be the last ref
|
|
||||||
of the last interface */
|
|
||||||
DP_DestroyDirectPlay2( This );
|
|
||||||
This->lock.DebugInfo->Spare[0] = 0;
|
|
||||||
DeleteCriticalSection( &This->lock );
|
|
||||||
HeapFree( GetProcessHeap(), 0, This );
|
|
||||||
}
|
|
||||||
|
|
||||||
return ulInterfaceRefCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline DPID DP_NextObjectId(void)
|
static inline DPID DP_NextObjectId(void)
|
||||||
{
|
{
|
||||||
return (DPID)InterlockedIncrement( &kludgePlayerGroupId );
|
return (DPID)InterlockedIncrement( &kludgePlayerGroupId );
|
||||||
|
@ -610,25 +587,53 @@ static HRESULT WINAPI IDirectPlay4Impl_QueryInterface( IDirectPlay4 *iface, REFI
|
||||||
static ULONG WINAPI IDirectPlay4AImpl_AddRef(IDirectPlay4A *iface)
|
static ULONG WINAPI IDirectPlay4AImpl_AddRef(IDirectPlay4A *iface)
|
||||||
{
|
{
|
||||||
IDirectPlayImpl *This = impl_from_IDirectPlay4A( iface );
|
IDirectPlayImpl *This = impl_from_IDirectPlay4A( iface );
|
||||||
return DP_AddRef( This );
|
ULONG ref = InterlockedIncrement( &This->ref4A );
|
||||||
|
|
||||||
|
TRACE( "(%p) ref4A=%d\n", This, ref );
|
||||||
|
|
||||||
|
if ( ref == 1 )
|
||||||
|
InterlockedIncrement( &This->numIfaces );
|
||||||
|
|
||||||
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI IDirectPlay4Impl_AddRef(IDirectPlay4 *iface)
|
static ULONG WINAPI IDirectPlay4Impl_AddRef(IDirectPlay4 *iface)
|
||||||
{
|
{
|
||||||
IDirectPlayImpl *This = impl_from_IDirectPlay4( iface );
|
IDirectPlayImpl *This = impl_from_IDirectPlay4( iface );
|
||||||
return DP_AddRef( This );
|
ULONG ref = InterlockedIncrement( &This->ref4 );
|
||||||
|
|
||||||
|
TRACE( "(%p) ref4=%d\n", This, ref );
|
||||||
|
|
||||||
|
if ( ref == 1 )
|
||||||
|
InterlockedIncrement( &This->numIfaces );
|
||||||
|
|
||||||
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI IDirectPlay4AImpl_Release(IDirectPlay4A *iface)
|
static ULONG WINAPI IDirectPlay4AImpl_Release(IDirectPlay4A *iface)
|
||||||
{
|
{
|
||||||
IDirectPlayImpl *This = impl_from_IDirectPlay4A( iface );
|
IDirectPlayImpl *This = impl_from_IDirectPlay4A( iface );
|
||||||
return DP_Release( This );
|
ULONG ref = InterlockedDecrement( &This->ref4A );
|
||||||
|
|
||||||
|
TRACE( "(%p) ref4A=%d\n", This, ref );
|
||||||
|
|
||||||
|
if ( !ref && !InterlockedDecrement( &This->numIfaces ) )
|
||||||
|
dplay_destroy( This );
|
||||||
|
|
||||||
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI IDirectPlay4Impl_Release(IDirectPlay4 *iface)
|
static ULONG WINAPI IDirectPlay4Impl_Release(IDirectPlay4 *iface)
|
||||||
{
|
{
|
||||||
IDirectPlayImpl *This = impl_from_IDirectPlay4( iface );
|
IDirectPlayImpl *This = impl_from_IDirectPlay4( iface );
|
||||||
return DP_Release( This );
|
ULONG ref = InterlockedDecrement( &This->ref4 );
|
||||||
|
|
||||||
|
TRACE( "(%p) ref4=%d\n", This, ref );
|
||||||
|
|
||||||
|
if ( !ref && !InterlockedDecrement( &This->numIfaces ) )
|
||||||
|
dplay_destroy( This );
|
||||||
|
|
||||||
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IDirectPlay4AImpl_AddPlayerToGroup( IDirectPlay4A *iface, DPID idGroup,
|
static HRESULT WINAPI IDirectPlay4AImpl_AddPlayerToGroup( IDirectPlay4A *iface, DPID idGroup,
|
||||||
|
@ -4700,7 +4705,9 @@ HRESULT dplay_create( REFIID riid, void **ppv )
|
||||||
|
|
||||||
obj->IDirectPlay4A_iface.lpVtbl = &dp4A_vt;
|
obj->IDirectPlay4A_iface.lpVtbl = &dp4A_vt;
|
||||||
obj->IDirectPlay4_iface.lpVtbl = &dp4_vt;
|
obj->IDirectPlay4_iface.lpVtbl = &dp4_vt;
|
||||||
obj->ulInterfaceRef = 1;
|
obj->numIfaces = 1;
|
||||||
|
obj->ref4A = 1;
|
||||||
|
obj->ref4 = 0;
|
||||||
|
|
||||||
InitializeCriticalSection( &obj->lock );
|
InitializeCriticalSection( &obj->lock );
|
||||||
obj->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectPlayImpl.lock");
|
obj->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectPlayImpl.lock");
|
||||||
|
|
|
@ -184,7 +184,8 @@ typedef struct IDirectPlayImpl
|
||||||
{
|
{
|
||||||
IDirectPlay4A IDirectPlay4A_iface;
|
IDirectPlay4A IDirectPlay4A_iface;
|
||||||
IDirectPlay4 IDirectPlay4_iface;
|
IDirectPlay4 IDirectPlay4_iface;
|
||||||
LONG ulInterfaceRef;
|
LONG numIfaces; /* "in use interfaces" refcount */
|
||||||
|
LONG ref4A, ref4;
|
||||||
CRITICAL_SECTION lock;
|
CRITICAL_SECTION lock;
|
||||||
DirectPlay2Data *dp2;
|
DirectPlay2Data *dp2;
|
||||||
} IDirectPlayImpl;
|
} IDirectPlayImpl;
|
||||||
|
|
|
@ -6399,7 +6399,7 @@ static void test_COM(void)
|
||||||
hr = IDirectPlayX_QueryInterface(dp4, &IID_IDirectPlay2A, (void**)&dp2A);
|
hr = IDirectPlayX_QueryInterface(dp4, &IID_IDirectPlay2A, (void**)&dp2A);
|
||||||
ok(hr == S_OK, "QueryInterface for IID_IDirectPlay2A failed: %08x\n", hr);
|
ok(hr == S_OK, "QueryInterface for IID_IDirectPlay2A failed: %08x\n", hr);
|
||||||
refcount = IDirectPlay2_AddRef(dp2A);
|
refcount = IDirectPlay2_AddRef(dp2A);
|
||||||
todo_wine ok(refcount == 2, "refcount == %u, expected 2\n", refcount);
|
ok(refcount == 2, "refcount == %u, expected 2\n", refcount);
|
||||||
IDirectPlay2_Release(dp2A);
|
IDirectPlay2_Release(dp2A);
|
||||||
|
|
||||||
hr = IDirectPlayX_QueryInterface(dp4, &IID_IDirectPlay2, (void**)&dp2);
|
hr = IDirectPlayX_QueryInterface(dp4, &IID_IDirectPlay2, (void**)&dp2);
|
||||||
|
|
Loading…
Reference in New Issue