dplayx: Merge the IDirectPlay4_EnumSessions helper.
This commit is contained in:
parent
5dc2b8f69c
commit
31065c62d4
|
@ -130,10 +130,6 @@ static HRESULT DP_SP_SendEx
|
||||||
static HRESULT DP_IF_CancelMessage
|
static HRESULT DP_IF_CancelMessage
|
||||||
( IDirectPlay4Impl* This, DWORD dwMsgID, DWORD dwFlags,
|
( IDirectPlay4Impl* This, DWORD dwMsgID, DWORD dwFlags,
|
||||||
DWORD dwMinPriority, DWORD dwMaxPriority, BOOL bAnsi );
|
DWORD dwMinPriority, DWORD dwMaxPriority, BOOL bAnsi );
|
||||||
static HRESULT DP_IF_EnumSessions
|
|
||||||
( IDirectPlay2Impl* This, LPDPSESSIONDESC2 lpsd, DWORD dwTimeout,
|
|
||||||
LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
|
|
||||||
LPVOID lpContext, DWORD dwFlags, BOOL bAnsi );
|
|
||||||
static BOOL CALLBACK cbDPCreateEnumConnections( LPCGUID lpguidSP,
|
static BOOL CALLBACK cbDPCreateEnumConnections( LPCGUID lpguidSP,
|
||||||
LPVOID lpConnection, DWORD dwConnectionSize, LPCDPNAME lpName,
|
LPVOID lpConnection, DWORD dwConnectionSize, LPCDPNAME lpName,
|
||||||
DWORD dwFlags, LPVOID lpContext );
|
DWORD dwFlags, LPVOID lpContext );
|
||||||
|
@ -1826,186 +1822,136 @@ static void DP_KillEnumSessionThread( IDirectPlay2Impl* This )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT DP_IF_EnumSessions
|
static HRESULT WINAPI IDirectPlay4AImpl_EnumSessions( IDirectPlay4A *iface, DPSESSIONDESC2 *sdesc,
|
||||||
( IDirectPlay2Impl* This, LPDPSESSIONDESC2 lpsd, DWORD dwTimeout,
|
DWORD timeout, LPDPENUMSESSIONSCALLBACK2 enumsessioncb, void *context, DWORD flags )
|
||||||
LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
|
|
||||||
LPVOID lpContext, DWORD dwFlags, BOOL bAnsi )
|
|
||||||
{
|
{
|
||||||
HRESULT hr = DP_OK;
|
IDirectPlayImpl *This = impl_from_IDirectPlay4A( iface );
|
||||||
|
return IDirectPlayX_EnumSessions( &This->IDirectPlay4_iface, sdesc, timeout, enumsessioncb,
|
||||||
|
context, flags );
|
||||||
|
}
|
||||||
|
|
||||||
TRACE( "(%p)->(%p,0x%08x,%p,%p,0x%08x,%u)\n",
|
static HRESULT WINAPI IDirectPlay4Impl_EnumSessions( IDirectPlay4 *iface, DPSESSIONDESC2 *sdesc,
|
||||||
This, lpsd, dwTimeout, lpEnumSessionsCallback2, lpContext, dwFlags,
|
DWORD timeout, LPDPENUMSESSIONSCALLBACK2 enumsessioncb, void *context, DWORD flags )
|
||||||
bAnsi );
|
{
|
||||||
if( This->dp2->connectionInitialized == NO_PROVIDER )
|
IDirectPlayImpl *This = impl_from_IDirectPlay4( iface );
|
||||||
{
|
void *connection;
|
||||||
return DPERR_UNINITIALIZED;
|
DWORD size;
|
||||||
}
|
HRESULT hr = DP_OK;
|
||||||
|
|
||||||
/* Can't enumerate if the interface is already open */
|
TRACE( "(%p)->(%p,0x%08x,%p,%p,0x%08x)\n", This, sdesc, timeout, enumsessioncb,
|
||||||
if( This->dp2->bConnectionOpen )
|
context, flags );
|
||||||
{
|
|
||||||
return DPERR_GENERIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 1
|
if ( This->dp2->connectionInitialized == NO_PROVIDER )
|
||||||
/* The loading of a lobby provider _seems_ to require a backdoor loading
|
return DPERR_UNINITIALIZED;
|
||||||
* of the service provider to also associate with this DP object. This is
|
|
||||||
* because the app doesn't seem to have to call EnumConnections and
|
|
||||||
* InitializeConnection for the SP before calling this method. As such
|
|
||||||
* we'll do their dirty work for them with a quick hack so as to always
|
|
||||||
* load the TCP/IP service provider.
|
|
||||||
*
|
|
||||||
* The correct solution would seem to involve creating a dialog box which
|
|
||||||
* contains the possible SPs. These dialog boxes most likely follow SDK
|
|
||||||
* examples.
|
|
||||||
*/
|
|
||||||
if( This->dp2->bDPLSPInitialized && !This->dp2->bSPInitialized )
|
|
||||||
{
|
|
||||||
LPVOID lpConnection;
|
|
||||||
DWORD dwSize;
|
|
||||||
|
|
||||||
WARN( "Hack providing TCP/IP SP for lobby provider activated\n" );
|
/* Can't enumerate if the interface is already open */
|
||||||
|
if ( This->dp2->bConnectionOpen )
|
||||||
|
return DPERR_GENERIC;
|
||||||
|
|
||||||
if( !DP_BuildSPCompoundAddr( (LPGUID)&DPSPGUID_TCPIP, &lpConnection, &dwSize ) )
|
/* The loading of a lobby provider _seems_ to require a backdoor loading
|
||||||
{
|
* of the service provider to also associate with this DP object. This is
|
||||||
ERR( "Can't build compound addr\n" );
|
* because the app doesn't seem to have to call EnumConnections and
|
||||||
return DPERR_GENERIC;
|
* InitializeConnection for the SP before calling this method. As such
|
||||||
}
|
* we'll do their dirty work for them with a quick hack so as to always
|
||||||
|
* load the TCP/IP service provider.
|
||||||
hr = IDirectPlayX_InitializeConnection( &This->IDirectPlay4_iface, lpConnection, 0 );
|
*
|
||||||
if( FAILED(hr) )
|
* The correct solution would seem to involve creating a dialog box which
|
||||||
{
|
* contains the possible SPs. These dialog boxes most likely follow SDK
|
||||||
return hr;
|
* examples.
|
||||||
}
|
*/
|
||||||
|
if ( This->dp2->bDPLSPInitialized && !This->dp2->bSPInitialized )
|
||||||
/* Free up the address buffer */
|
|
||||||
HeapFree( GetProcessHeap(), 0, lpConnection );
|
|
||||||
|
|
||||||
/* The SP is now initialized */
|
|
||||||
This->dp2->bSPInitialized = TRUE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Use the service provider default? */
|
|
||||||
if( dwTimeout == 0 )
|
|
||||||
{
|
|
||||||
DPCAPS spCaps;
|
|
||||||
spCaps.dwSize = sizeof( spCaps );
|
|
||||||
|
|
||||||
IDirectPlayX_GetCaps( &This->IDirectPlay4_iface, &spCaps, 0 );
|
|
||||||
dwTimeout = spCaps.dwTimeout;
|
|
||||||
|
|
||||||
/* The service provider doesn't provide one either! */
|
|
||||||
if( dwTimeout == 0 )
|
|
||||||
{
|
{
|
||||||
/* Provide the TCP/IP default */
|
WARN( "Hack providing TCP/IP SP for lobby provider activated\n" );
|
||||||
dwTimeout = DPMSG_WAIT_5_SECS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( dwFlags & DPENUMSESSIONS_STOPASYNC )
|
if ( !DP_BuildSPCompoundAddr( (GUID*)&DPSPGUID_TCPIP, &connection, &size ) )
|
||||||
{
|
|
||||||
DP_KillEnumSessionThread( This );
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ( dwFlags & DPENUMSESSIONS_ASYNC ) )
|
|
||||||
{
|
|
||||||
/* Enumerate everything presently in the local session cache */
|
|
||||||
DP_InvokeEnumSessionCallbacks( lpEnumSessionsCallback2,
|
|
||||||
This->dp2->lpNameServerData, dwTimeout,
|
|
||||||
lpContext );
|
|
||||||
|
|
||||||
if( This->dp2->dwEnumSessionLock != 0 )
|
|
||||||
return DPERR_CONNECTING;
|
|
||||||
|
|
||||||
/* See if we've already created a thread to service this interface */
|
|
||||||
if( This->dp2->hEnumSessionThread == INVALID_HANDLE_VALUE )
|
|
||||||
{
|
|
||||||
DWORD dwThreadId;
|
|
||||||
This->dp2->dwEnumSessionLock++;
|
|
||||||
|
|
||||||
/* Send the first enum request inline since the user may cancel a dialog
|
|
||||||
* if one is presented. Also, may also have a connecting return code.
|
|
||||||
*/
|
|
||||||
hr = NS_SendSessionRequestBroadcast( &lpsd->guidApplication,
|
|
||||||
dwFlags, &This->dp2->spData );
|
|
||||||
|
|
||||||
if( SUCCEEDED(hr) )
|
|
||||||
{
|
|
||||||
EnumSessionAsyncCallbackData* lpData
|
|
||||||
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( *lpData ) );
|
|
||||||
/* FIXME: need to kill the thread on object deletion */
|
|
||||||
lpData->lpSpData = &This->dp2->spData;
|
|
||||||
|
|
||||||
lpData->requestGuid = lpsd->guidApplication;
|
|
||||||
lpData->dwEnumSessionFlags = dwFlags;
|
|
||||||
lpData->dwTimeout = dwTimeout;
|
|
||||||
|
|
||||||
This->dp2->hKillEnumSessionThreadEvent =
|
|
||||||
CreateEventW( NULL, TRUE, FALSE, NULL );
|
|
||||||
|
|
||||||
if( !DuplicateHandle( GetCurrentProcess(),
|
|
||||||
This->dp2->hKillEnumSessionThreadEvent,
|
|
||||||
GetCurrentProcess(),
|
|
||||||
&lpData->hSuicideRequest,
|
|
||||||
0, FALSE, DUPLICATE_SAME_ACCESS )
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ERR( "Can't duplicate thread killing handle\n" );
|
ERR( "Can't build compound addr\n" );
|
||||||
|
return DPERR_GENERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE( ": creating EnumSessionsRequest thread\n" );
|
hr = IDirectPlayX_InitializeConnection( &This->IDirectPlay4_iface, connection, 0 );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
This->dp2->hEnumSessionThread = CreateThread( NULL,
|
HeapFree( GetProcessHeap(), 0, connection );
|
||||||
0,
|
This->dp2->bSPInitialized = TRUE;
|
||||||
DP_EnumSessionsSendAsyncRequestThread,
|
|
||||||
lpData,
|
|
||||||
0,
|
|
||||||
&dwThreadId );
|
|
||||||
}
|
|
||||||
This->dp2->dwEnumSessionLock--;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Invalidate the session cache for the interface */
|
|
||||||
NS_InvalidateSessionCache( This->dp2->lpNameServerData );
|
|
||||||
|
|
||||||
/* Send the broadcast for session enumeration */
|
|
||||||
hr = NS_SendSessionRequestBroadcast( &lpsd->guidApplication,
|
|
||||||
dwFlags,
|
|
||||||
&This->dp2->spData );
|
|
||||||
|
|
||||||
|
|
||||||
SleepEx( dwTimeout, FALSE );
|
/* Use the service provider default? */
|
||||||
|
if ( !timeout )
|
||||||
|
{
|
||||||
|
DPCAPS caps;
|
||||||
|
caps.dwSize = sizeof( caps );
|
||||||
|
|
||||||
DP_InvokeEnumSessionCallbacks( lpEnumSessionsCallback2,
|
IDirectPlayX_GetCaps( &This->IDirectPlay4_iface, &caps, 0 );
|
||||||
This->dp2->lpNameServerData, dwTimeout,
|
timeout = caps.dwTimeout;
|
||||||
lpContext );
|
if ( !timeout )
|
||||||
}
|
timeout = DPMSG_WAIT_5_SECS; /* Provide the TCP/IP default */
|
||||||
|
}
|
||||||
|
|
||||||
return hr;
|
if ( flags & DPENUMSESSIONS_STOPASYNC )
|
||||||
}
|
{
|
||||||
|
DP_KillEnumSessionThread( This );
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IDirectPlay4AImpl_EnumSessions( IDirectPlay4A *iface, DPSESSIONDESC2 *lpsd,
|
if ( flags & DPENUMSESSIONS_ASYNC )
|
||||||
DWORD dwTimeout, LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2, void *lpContext,
|
{
|
||||||
DWORD dwFlags )
|
/* Enumerate everything presently in the local session cache */
|
||||||
{
|
DP_InvokeEnumSessionCallbacks( enumsessioncb, This->dp2->lpNameServerData, timeout,
|
||||||
IDirectPlayImpl *This = impl_from_IDirectPlay4A( iface );
|
context );
|
||||||
return DP_IF_EnumSessions( This, lpsd, dwTimeout, lpEnumSessionsCallback2,
|
|
||||||
lpContext, dwFlags, TRUE );
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI DirectPlay2WImpl_EnumSessions
|
if ( This->dp2->dwEnumSessionLock )
|
||||||
( LPDIRECTPLAY2 iface, LPDPSESSIONDESC2 lpsd, DWORD dwTimeout,
|
return DPERR_CONNECTING;
|
||||||
LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
|
|
||||||
LPVOID lpContext, DWORD dwFlags )
|
/* See if we've already created a thread to service this interface */
|
||||||
{
|
if ( This->dp2->hEnumSessionThread == INVALID_HANDLE_VALUE )
|
||||||
IDirectPlay2Impl *This = (IDirectPlay2Impl *)iface;
|
{
|
||||||
return DP_IF_EnumSessions( This, lpsd, dwTimeout, lpEnumSessionsCallback2,
|
DWORD tid;
|
||||||
lpContext, dwFlags, FALSE );
|
This->dp2->dwEnumSessionLock++;
|
||||||
|
|
||||||
|
/* Send the first enum request inline since the user may cancel a dialog
|
||||||
|
* if one is presented. Also, may also have a connecting return code.
|
||||||
|
*/
|
||||||
|
hr = NS_SendSessionRequestBroadcast( &sdesc->guidApplication, flags,
|
||||||
|
&This->dp2->spData );
|
||||||
|
|
||||||
|
if ( SUCCEEDED(hr) )
|
||||||
|
{
|
||||||
|
EnumSessionAsyncCallbackData* data = HeapAlloc( GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY, sizeof( *data ) );
|
||||||
|
/* FIXME: need to kill the thread on object deletion */
|
||||||
|
data->lpSpData = &This->dp2->spData;
|
||||||
|
data->requestGuid = sdesc->guidApplication;
|
||||||
|
data->dwEnumSessionFlags = flags;
|
||||||
|
data->dwTimeout = timeout;
|
||||||
|
|
||||||
|
This->dp2->hKillEnumSessionThreadEvent = CreateEventW( NULL, TRUE, FALSE, NULL );
|
||||||
|
if ( !DuplicateHandle( GetCurrentProcess(), This->dp2->hKillEnumSessionThreadEvent,
|
||||||
|
GetCurrentProcess(), &data->hSuicideRequest, 0, FALSE,
|
||||||
|
DUPLICATE_SAME_ACCESS ) )
|
||||||
|
ERR( "Can't duplicate thread killing handle\n" );
|
||||||
|
|
||||||
|
TRACE( ": creating EnumSessionsRequest thread\n" );
|
||||||
|
This->dp2->hEnumSessionThread = CreateThread( NULL, 0,
|
||||||
|
DP_EnumSessionsSendAsyncRequestThread, data, 0, &tid );
|
||||||
|
}
|
||||||
|
This->dp2->dwEnumSessionLock--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Invalidate the session cache for the interface */
|
||||||
|
NS_InvalidateSessionCache( This->dp2->lpNameServerData );
|
||||||
|
/* Send the broadcast for session enumeration */
|
||||||
|
hr = NS_SendSessionRequestBroadcast( &sdesc->guidApplication, flags, &This->dp2->spData );
|
||||||
|
SleepEx( timeout, FALSE );
|
||||||
|
DP_InvokeEnumSessionCallbacks( enumsessioncb, This->dp2->lpNameServerData, timeout,
|
||||||
|
context );
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IDirectPlay4AImpl_GetCaps( IDirectPlay4A *iface, DPCAPS *caps, DWORD flags )
|
static HRESULT WINAPI IDirectPlay4AImpl_GetCaps( IDirectPlay4A *iface, DPCAPS *caps, DWORD flags )
|
||||||
|
@ -4275,7 +4221,7 @@ static const IDirectPlay4Vtbl dp4_vt =
|
||||||
IDirectPlay4Impl_EnumGroupPlayers,
|
IDirectPlay4Impl_EnumGroupPlayers,
|
||||||
IDirectPlay4Impl_EnumGroups,
|
IDirectPlay4Impl_EnumGroups,
|
||||||
IDirectPlay4Impl_EnumPlayers,
|
IDirectPlay4Impl_EnumPlayers,
|
||||||
XCAST(EnumSessions)DirectPlay2WImpl_EnumSessions,
|
IDirectPlay4Impl_EnumSessions,
|
||||||
IDirectPlay4Impl_GetCaps,
|
IDirectPlay4Impl_GetCaps,
|
||||||
IDirectPlay4Impl_GetGroupData,
|
IDirectPlay4Impl_GetGroupData,
|
||||||
XCAST(GetGroupName)DirectPlay2WImpl_GetGroupName,
|
XCAST(GetGroupName)DirectPlay2WImpl_GetGroupName,
|
||||||
|
|
Loading…
Reference in New Issue