From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/dplay.c | 116 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 105 insertions(+), 11 deletions(-)
diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index 8f3d765a078..bb8c62c8ee9 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -937,18 +937,29 @@ static HRESULT WINAPI IDirectPlay4Impl_AddPlayerToGroup( IDirectPlay4 *iface, DP if ( This->dp2->connectionInitialized == NO_PROVIDER ) return DPERR_UNINITIALIZED;
+ EnterCriticalSection( &This->lock ); + /* Find the group */ if ( ( gdata = DP_FindAnyGroup( This, group ) ) == NULL ) + { + LeaveCriticalSection( &This->lock ); return DPERR_INVALIDGROUP; + }
/* Find the player */ if ( ( plist = DP_FindPlayer( This, player ) ) == NULL ) + { + LeaveCriticalSection( &This->lock ); return DPERR_INVALIDPLAYER; + }
/* Create a player list (ie "shortcut" ) */ newplist = calloc( 1, sizeof( *newplist ) ); if ( !newplist ) + { + LeaveCriticalSection( &This->lock ); return DPERR_CANTADDPLAYER; + }
/* Add the shortcut */ plist->lpPData->uRef++; @@ -992,6 +1003,8 @@ static HRESULT WINAPI IDirectPlay4Impl_AddPlayerToGroup( IDirectPlay4 *iface, DP 0, 0, NULL, NULL ); }
+ LeaveCriticalSection( &This->lock ); + return DP_OK; }
@@ -1761,10 +1774,15 @@ static HRESULT DP_IF_CreatePlayer( IDirectPlayImpl *This, void *lpMsgHdr, DPID * */ }
+ EnterCriticalSection( &This->lock ); + /* We pass creation flags, so we can distinguish sysplayers and not count them in the current player total */ hr = DP_CreatePlayer( This, NULL, lpidPlayer, lpPlayerName, lpData, dwDataSize, NULL, 0, dwCreateFlags, hEvent, bAnsi ); + + LeaveCriticalSection( &This->lock ); + if( FAILED( hr ) ) return hr;
@@ -1947,19 +1965,30 @@ static HRESULT WINAPI IDirectPlay4Impl_DeletePlayerFromGroup( IDirectPlay4 *ifac
TRACE( "(%p)->(0x%08lx,0x%08lx)\n", This, group, player );
+ EnterCriticalSection( &This->lock ); + /* Find the group */ if ( ( gdata = DP_FindAnyGroup( This, group ) ) == NULL ) + { + LeaveCriticalSection( &This->lock ); return DPERR_INVALIDGROUP; + }
/* Find the player */ if ( DP_FindPlayer( This, player ) == NULL ) + { + LeaveCriticalSection( &This->lock ); return DPERR_INVALIDPLAYER; + }
/* Remove the player shortcut from the group */ DPQ_REMOVE_ENTRY( gdata->players, players, lpPData->dpid, ==, player, plist );
if ( !plist ) + { + LeaveCriticalSection( &This->lock ); return DPERR_INVALIDPLAYER; + }
/* One less reference */ plist->lpPData->uRef--; @@ -1982,6 +2011,8 @@ static HRESULT WINAPI IDirectPlay4Impl_DeletePlayerFromGroup( IDirectPlay4 *ifac /* Need to send a DELETEPLAYERFROMGROUP message */ FIXME( "Need to send a message\n" );
+ LeaveCriticalSection( &This->lock ); + return hr; }
@@ -2126,8 +2157,11 @@ static HRESULT DP_IF_DestroyPlayer( IDirectPlayImpl *This, void *lpMsgHdr, DPID return DPERR_UNINITIALIZED; }
+ EnterCriticalSection( &This->lock ); + if( DP_FindPlayer( This, idPlayer ) == NULL ) { + LeaveCriticalSection( &This->lock ); return DPERR_INVALIDPLAYER; }
@@ -2161,6 +2195,8 @@ static HRESULT DP_IF_DestroyPlayer( IDirectPlayImpl *This, void *lpMsgHdr, DPID
FIXME( "Send a DELETEPLAYERORGROUP msg\n" );
+ LeaveCriticalSection( &This->lock ); + return DP_OK; }
@@ -2273,15 +2309,17 @@ static HRESULT DP_IF_EnumGroupPlayers( IDirectPlayImpl *This, DPID group, GUID * if ( This->dp2->connectionInitialized == NO_PROVIDER ) return DPERR_UNINITIALIZED;
+ EnterCriticalSection( &This->lock ); + /* Find the group */ if ( ( gdata = DP_FindAnyGroup( This, group ) ) == NULL ) + { + LeaveCriticalSection( &This->lock ); return DPERR_INVALIDGROUP; - - if ( DPQ_IS_EMPTY( gdata->players ) ) - return DP_OK; + }
/* Walk the players in this group */ - for( plist = DPQ_FIRST( gdata->players ); ; plist = DPQ_NEXT( plist->players ) ) + for( plist = DPQ_FIRST( gdata->players ); plist; plist = DPQ_NEXT( plist->players ) ) { /* We do not enum the name server or app server as they are of no * consequence to the end user. @@ -2293,12 +2331,12 @@ static HRESULT DP_IF_EnumGroupPlayers( IDirectPlayImpl *This, DPID group, GUID * ansi ? plist->lpPData->nameA : plist->lpPData->name, plist->lpPData->dwFlags, context ) ) /* User requested break */ - return DP_OK; + break; } - - if ( DPQ_IS_ENDOFLIST( plist->players ) ) - break; } + + LeaveCriticalSection( &This->lock ); + return DP_OK; }
@@ -3082,8 +3120,13 @@ static HRESULT WINAPI IDirectPlay4Impl_GetPlayerData( IDirectPlay4 *iface, DPID if ( This->dp2->connectionInitialized == NO_PROVIDER ) return DPERR_UNINITIALIZED;
+ EnterCriticalSection( &This->lock ); + if ( ( plist = DP_FindPlayer( This, player ) ) == NULL ) + { + LeaveCriticalSection( &This->lock ); return DPERR_INVALIDPLAYER; + }
if ( flags & DPSET_LOCAL ) { @@ -3100,11 +3143,14 @@ static HRESULT WINAPI IDirectPlay4Impl_GetPlayerData( IDirectPlay4 *iface, DPID if ( !data || *size < bufsize ) { *size = bufsize; + LeaveCriticalSection( &This->lock ); return DPERR_BUFFERTOOSMALL; }
CopyMemory( data, src, bufsize );
+ LeaveCriticalSection( &This->lock ); + return DP_OK; }
@@ -3122,8 +3168,11 @@ static HRESULT DP_IF_GetPlayerName( IDirectPlayImpl *This, DPID idPlayer, void * return DPERR_UNINITIALIZED; }
+ EnterCriticalSection( &This->lock ); + if( ( lpPList = DP_FindPlayer( This, idPlayer ) ) == NULL ) { + LeaveCriticalSection( &This->lock ); return DPERR_INVALIDPLAYER; }
@@ -3135,11 +3184,14 @@ static HRESULT DP_IF_GetPlayerName( IDirectPlayImpl *This, DPID idPlayer, void * ) { *lpdwDataSize = dwRequiredDataSize; + LeaveCriticalSection( &This->lock ); return DPERR_BUFFERTOOSMALL; }
DP_CopyName( lpData, bAnsi ? lpPList->lpPData->nameA : lpPList->lpPData->name, bAnsi, bAnsi );
+ LeaveCriticalSection( &This->lock ); + return DP_OK; }
@@ -3457,6 +3509,9 @@ static HRESULT DP_SecureOpen( IDirectPlayImpl *This, const DPSESSIONDESC2 *lpsd, return hr; }
+ /* No need to enter the critical section here as the messaging thread won't access the data + * while bConnectionOpen is FALSE. */ + hr = DP_CreatePlayer( This, NULL, &dpidServerId, NULL, NULL, 0, NULL, 0, createFlags, NULL, bAnsi ); if( FAILED( hr ) ) @@ -3892,9 +3947,14 @@ static HRESULT WINAPI IDirectPlay4Impl_SetPlayerData( IDirectPlay4 *iface, DPID if ( !data && size ) return DPERR_INVALIDPARAMS;
+ EnterCriticalSection( &This->lock ); + /* Find the pointer to the data for this player */ if ( (plist = DP_FindPlayer( This, player )) == NULL ) + { + LeaveCriticalSection( &This->lock ); return DPERR_INVALIDPLAYER; + }
if ( !(flags & DPSET_LOCAL) ) { @@ -3909,6 +3969,8 @@ static HRESULT WINAPI IDirectPlay4Impl_SetPlayerData( IDirectPlay4 *iface, DPID if ( !(flags & DPSET_LOCAL) ) FIXME( "Send msg?\n" );
+ LeaveCriticalSection( &This->lock ); + return DP_OK; }
@@ -3927,19 +3989,26 @@ static HRESULT DP_IF_SetPlayerName( IDirectPlayImpl *This, DPID idPlayer, DPNAME return DPERR_UNINITIALIZED; }
+ EnterCriticalSection( &This->lock ); + if( ( lpPList = DP_FindPlayer( This, idPlayer ) ) == NULL ) { + LeaveCriticalSection( &This->lock ); return DPERR_INVALIDGROUP; }
name = DP_DuplicateName( lpPlayerName, FALSE, bAnsi ); if ( !name ) + { + LeaveCriticalSection( &This->lock ); return DPERR_OUTOFMEMORY; + }
nameA = DP_DuplicateName( lpPlayerName, TRUE, bAnsi ); if ( !nameA ) { free( name ); + LeaveCriticalSection( &This->lock ); return DPERR_OUTOFMEMORY; }
@@ -3949,6 +4018,8 @@ static HRESULT DP_IF_SetPlayerName( IDirectPlayImpl *This, DPID idPlayer, DPNAME /* Should send a DPMSG_SETPLAYERORGROUPNAME message */ FIXME( "Message not sent and dwFlags ignored\n" );
+ LeaveCriticalSection( &This->lock ); + return DP_OK; }
@@ -5363,6 +5434,7 @@ static HRESULT WINAPI IDirectPlay4Impl_SendEx( IDirectPlay4 *iface, DPID from, D DWORD *msgid ) { IDirectPlayImpl *This = impl_from_IDirectPlay4( iface ); + HRESULT hr;
FIXME( "(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx,0x%08lx,0x%08lx,%p,%p): semi-stub\n", This, from, to, flags, data, size, priority, timeout, context, msgid ); @@ -5377,12 +5449,15 @@ static HRESULT WINAPI IDirectPlay4Impl_SendEx( IDirectPlay4 *iface, DPID from, D
/* NOTE: Can't send messages to yourself - this will be trapped in receive */
+ EnterCriticalSection( &This->lock ); + /* Verify that the message is being sent from a valid local player. The * from player may be anonymous DPID_UNKNOWN */ if ( from != DPID_UNKNOWN && !DP_FindPlayer( This, from ) ) { WARN( "INFO: Invalid from player 0x%08lx\n", from ); + LeaveCriticalSection( &This->lock ); return DPERR_INVALIDPLAYER; }
@@ -5403,7 +5478,9 @@ static HRESULT WINAPI IDirectPlay4Impl_SendEx( IDirectPlay4 *iface, DPID from, D { /* Have the service provider send this message */ /* FIXME: Could optimize for local interface sends */ - return DP_SP_SendEx( This, flags, data, size, priority, timeout, context, msgid ); + hr = DP_SP_SendEx( This, flags, data, size, priority, timeout, context, msgid ); + LeaveCriticalSection( &This->lock ); + return hr; } else if ( DP_FindAnyGroup( This, to ) ) { @@ -5417,7 +5494,12 @@ static HRESULT WINAPI IDirectPlay4Impl_SendEx( IDirectPlay4 *iface, DPID from, D
} else + { + LeaveCriticalSection( &This->lock ); return DPERR_INVALIDPLAYER; + } + + LeaveCriticalSection( &This->lock );
/* FIXME: Should return what the send returned */ return DP_OK; @@ -5883,29 +5965,41 @@ HRESULT dplay_create( REFIID riid, void **ppv )
HRESULT DP_GetSPPlayerData( IDirectPlayImpl *lpDP, DPID idPlayer, void **lplpData ) { - lpPlayerList lpPlayer = DP_FindPlayer( lpDP, idPlayer ); + lpPlayerList lpPlayer; + + EnterCriticalSection( &lpDP->lock );
+ lpPlayer = DP_FindPlayer( lpDP, idPlayer ); if( lpPlayer == NULL ) { + LeaveCriticalSection( &lpDP->lock ); return DPERR_INVALIDPLAYER; }
*lplpData = lpPlayer->lpPData->lpSPPlayerData;
+ LeaveCriticalSection( &lpDP->lock ); + return DP_OK; }
HRESULT DP_SetSPPlayerData( IDirectPlayImpl *lpDP, DPID idPlayer, void *lpData ) { - lpPlayerList lpPlayer = DP_FindPlayer( lpDP, idPlayer ); + lpPlayerList lpPlayer; + + EnterCriticalSection( &lpDP->lock );
+ lpPlayer = DP_FindPlayer( lpDP, idPlayer ); if( lpPlayer == NULL ) { + LeaveCriticalSection( &lpDP->lock ); return DPERR_INVALIDPLAYER; }
lpPlayer->lpPData->lpSPPlayerData = lpData;
+ LeaveCriticalSection( &lpDP->lock ); + return DP_OK; }