From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/dplay.c | 21 ++++++++++++--------- dlls/dplayx/tests/dplayx.c | 9 ++++----- 2 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index 32fbd35df50..3a4b7e958b6 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -4953,19 +4953,22 @@ static HRESULT DP_IF_EnumGroupsInGroup( IDirectPlayImpl *This, DPID group, GUID if ( ( gdata = DP_FindAnyGroup(This, group ) ) == NULL ) return DPERR_INVALIDGROUP;
- if ( DPQ_IS_EMPTY( gdata->groups ) ) - return DP_OK; + for( glist = DPQ_FIRST( gdata->groups ); glist; glist = DPQ_NEXT( glist->groups ) ) + { + DWORD groupFlags; + + if ( (glist->lpGData->dwFlags & flags) != (flags & ~DPENUMGROUPS_REMOTE) ) + continue; + if ( (glist->lpGData->dwFlags & DPENUMGROUPS_LOCAL) && (flags & DPENUMGROUPS_REMOTE) ) + continue;
+ groupFlags = glist->lpGData->dwFlags; + groupFlags &= ~(DPENUMGROUPS_LOCAL | DPLAYI_GROUP_DPLAYOWNS); + groupFlags |= flags;
- for( glist = DPQ_FIRST( gdata->groups ); ; glist = DPQ_NEXT( glist->groups ) ) - { - /* FIXME: Should check flags for match here */ if ( !(*enumplayercb)( glist->lpGData->dpid, DPPLAYERTYPE_GROUP, - ansi ? glist->lpGData->nameA : glist->lpGData->name, flags, context ) ) + ansi ? glist->lpGData->nameA : glist->lpGData->name, groupFlags, context ) ) return DP_OK; /* User requested break */ - - if ( DPQ_IS_ENDOFLIST( glist->groups ) ) - break; }
return DP_OK; diff --git a/dlls/dplayx/tests/dplayx.c b/dlls/dplayx/tests/dplayx.c index c589ab4e8b7..d415e5996ad 100644 --- a/dlls/dplayx/tests/dplayx.c +++ b/dlls/dplayx/tests/dplayx.c @@ -2830,7 +2830,7 @@ static BOOL CALLBACK checkPlayerListCallback( DPID dpid, DWORD playerType, const HRESULT hr;
if ( player->actualCount ) - todo_wine ok_( __FILE__, data->line )( 0, "duplicate player dpid %#lx.\n", dpid ); + ok_( __FILE__, data->line )( 0, "duplicate player dpid %#lx.\n", dpid ); ok_( __FILE__, data->line )( playerType == player->expectedPlayerType, "got player type %lu.\n", playerType ); if ( player->expectedShortName ) @@ -2853,8 +2853,7 @@ static BOOL CALLBACK checkPlayerListCallback( DPID dpid, DWORD playerType, const ok_( __FILE__, data->line )( !name->lpszLongNameA, "got long name %s.\n", wine_dbgstr_a( name->lpszLongNameA ) ); } - todo_wine_if( playerType == DPPLAYERTYPE_GROUP && flags == DPENUMPLAYERS_LOCAL ) - ok_( __FILE__, data->line )( flags == player->expectedFlags, "got flags %#lx.\n", flags ); + ok_( __FILE__, data->line )( flags == player->expectedFlags, "got flags %#lx.\n", flags );
memset( &playerData, 0xcc, sizeof( playerData ) ); playerDataSize = sizeof( playerData ); @@ -2993,8 +2992,8 @@ static void checkGroupList_( int line, IDirectPlay4 *dp, ExpectedPlayer *expecte hr = IDirectPlayX_EnumGroups( dp, NULL, checkPlayerListCallback, &data, DPENUMGROUPS_REMOTE ); ok_( __FILE__, line )( hr == DP_OK, "EnumGroups() returned %#lx.\n", hr );
- todo_wine ok_( __FILE__, line )( data.actualPlayerCount == data.expectedPlayerCount, "got group count %d.\n", - data.actualPlayerCount ); + ok_( __FILE__, line )( data.actualPlayerCount == data.expectedPlayerCount, "got group count %d.\n", + data.actualPlayerCount ); }
#define checkPlayerExists( dp, expectedDpid, expectedPlayerType, expectedShortName, expectedLongName, expectedFlags, \
From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/dplay.c | 5 ++--- dlls/dplayx/tests/dplayx.c | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index 3a4b7e958b6..e4f3fd84366 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -3078,12 +3078,11 @@ static HRESULT WINAPI IDirectPlay4Impl_GetGroupData( IDirectPlay4 *iface, DPID g src = gdata->lpRemoteData; }
+ *size = bufsize; + /* Is the user requesting to know how big a buffer is required? */ if ( !data || *size < bufsize ) - { - *size = bufsize; return DPERR_BUFFERTOOSMALL; - }
CopyMemory( data, src, bufsize );
diff --git a/dlls/dplayx/tests/dplayx.c b/dlls/dplayx/tests/dplayx.c index d415e5996ad..00b5aad6708 100644 --- a/dlls/dplayx/tests/dplayx.c +++ b/dlls/dplayx/tests/dplayx.c @@ -2862,9 +2862,8 @@ static BOOL CALLBACK checkPlayerListCallback( DPID dpid, DWORD playerType, const else hr = IDirectPlayX_GetGroupData( data->dp, dpid, playerData, &playerDataSize, DPGET_REMOTE ); ok_( __FILE__, data->line )( hr == DP_OK, "GetPlayerData() returned %#lx.\n", hr ); - todo_wine_if( playerType == DPPLAYERTYPE_GROUP ) - ok_( __FILE__, data->line )( playerDataSize == player->expectedPlayerDataSize, - "got player data size %lu.\n", playerDataSize ); + ok_( __FILE__, data->line )( playerDataSize == player->expectedPlayerDataSize, + "got player data size %lu.\n", playerDataSize ); ok_( __FILE__, data->line )( !memcmp( playerData, player->expectedPlayerData, player->expectedPlayerDataSize ), "player data doesn't match.\n" );
From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/dplay.c | 53 ++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 20 deletions(-)
diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index e4f3fd84366..9b3b69d0a70 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -1132,42 +1132,25 @@ static HRESULT WINAPI IDirectPlay4AImpl_AddPlayerToGroup( IDirectPlay4A *iface, return IDirectPlayX_AddPlayerToGroup( &This->IDirectPlay4_iface, group, player ); }
-static HRESULT WINAPI IDirectPlay4Impl_AddPlayerToGroup( IDirectPlay4 *iface, DPID group, - DPID player ) +static HRESULT DP_AddPlayerToGroup( IDirectPlayImpl *This, DPID group, DPID player ) { - IDirectPlayImpl *This = impl_from_IDirectPlay4( iface ); lpGroupData gdata; lpPlayerList plist; lpPlayerList newplist; - - TRACE( "(%p)->(0x%08lx,0x%08lx)\n", This, group, player ); - - if ( This->dp2->connectionInitialized == NO_PROVIDER ) - return DPERR_UNINITIALIZED; - - EnterCriticalSection( &This->lock ); + HRESULT hr;
/* 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++; @@ -1187,7 +1170,37 @@ static HRESULT WINAPI IDirectPlay4Impl_AddPlayerToGroup( IDirectPlay4 *iface, DP data.idGroup = group; data.lpISP = This->dp2->spData.lpISP;
- (*This->dp2->spData.lpCB->AddPlayerToGroup)( &data ); + hr = (*This->dp2->spData.lpCB->AddPlayerToGroup)( &data ); + if ( FAILED( hr ) ) + { + DPQ_REMOVE( gdata->players, newplist, players ); + --plist->lpPData->uRef; + free( newplist ); + return hr; + } + } + + return DP_OK; +} + +static HRESULT WINAPI IDirectPlay4Impl_AddPlayerToGroup( IDirectPlay4 *iface, DPID group, + DPID player ) +{ + IDirectPlayImpl *This = impl_from_IDirectPlay4( iface ); + HRESULT hr; + + TRACE( "(%p)->(0x%08lx,0x%08lx)\n", This, group, player ); + + if ( This->dp2->connectionInitialized == NO_PROVIDER ) + return DPERR_UNINITIALIZED; + + EnterCriticalSection( &This->lock ); + + hr = DP_AddPlayerToGroup( This, group, player ); + if ( FAILED( hr ) ) + { + LeaveCriticalSection( &This->lock ); + return hr; }
/* Inform all other peers of the addition of player to the group. If there are
From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/dplay.c | 2 +- dlls/dplayx/dplay_global.h | 1 + dlls/dplayx/dplayx_messages.c | 12 ++++++++++++ dlls/dplayx/tests/dplayx.c | 4 ++-- 4 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index 9b3b69d0a70..4a4fe8d2619 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -1132,7 +1132,7 @@ static HRESULT WINAPI IDirectPlay4AImpl_AddPlayerToGroup( IDirectPlay4A *iface, return IDirectPlayX_AddPlayerToGroup( &This->IDirectPlay4_iface, group, player ); }
-static HRESULT DP_AddPlayerToGroup( IDirectPlayImpl *This, DPID group, DPID player ) +HRESULT DP_AddPlayerToGroup( IDirectPlayImpl *This, DPID group, DPID player ) { lpGroupData gdata; lpPlayerList plist; diff --git a/dlls/dplayx/dplay_global.h b/dlls/dplayx/dplay_global.h index 392e0d3232d..8883a2b43ad 100644 --- a/dlls/dplayx/dplay_global.h +++ b/dlls/dplayx/dplay_global.h @@ -221,6 +221,7 @@ HRESULT DP_CreatePlayer( IDirectPlayImpl *This, void *msgHeader, DPID *lpid, DPN HRESULT DP_CreateGroup( IDirectPlayImpl *This, void *msgHeader, const DPID *lpid, const DPNAME *lpName, void *data, DWORD dataSize, DWORD dwFlags, DPID idParent, BOOL bAnsi ); +HRESULT DP_AddPlayerToGroup( IDirectPlayImpl *This, DPID group, DPID player );
/* DP SP external interfaces into DirectPlay */ extern HRESULT DP_GetSPPlayerData( IDirectPlayImpl *lpDP, DPID idPlayer, void **lplpData ); diff --git a/dlls/dplayx/dplayx_messages.c b/dlls/dplayx/dplayx_messages.c index 93a80283b69..d81e29a7e0b 100644 --- a/dlls/dplayx/dplayx_messages.c +++ b/dlls/dplayx/dplayx_messages.c @@ -679,6 +679,7 @@ HRESULT DP_MSG_ForwardPlayerCreation( IDirectPlayImpl *This, DPID dpidServer, WC for( i = 0; i < enumPlayersReply->groupCount; ++i ) { DPPLAYERINFO playerInfo; + int j;
hr = DP_MSG_ReadSuperPackedPlayer( (char *) enumPlayersReply, &offset, dwMsgSize, &playerInfo ); @@ -699,6 +700,17 @@ HRESULT DP_MSG_ForwardPlayerCreation( IDirectPlayImpl *This, DPID dpidServer, WC free( lpMsg ); return hr; } + + for( j = 0; j < playerInfo.playerCount; ++j ) + { + hr = DP_AddPlayerToGroup( This, playerInfo.id, playerInfo.playerIds[ j ] ); + if( FAILED( hr ) ) + { + free( msgHeader ); + free( lpMsg ); + return hr; + } + } } } else if( envelope->wCommandId == DPMSGCMD_GETNAMETABLEREPLY ) diff --git a/dlls/dplayx/tests/dplayx.c b/dlls/dplayx/tests/dplayx.c index 00b5aad6708..d8869b58a40 100644 --- a/dlls/dplayx/tests/dplayx.c +++ b/dlls/dplayx/tests/dplayx.c @@ -2969,8 +2969,8 @@ static void checkGroupPlayerList_( int line, DPID group, IDirectPlay4 *dp, Expec hr = IDirectPlayX_EnumGroupPlayers( dp, group, NULL, checkPlayerListCallback, &data, DPENUMPLAYERS_REMOTE ); ok_( __FILE__, line )( hr == DP_OK, "EnumGroupPlayers() returned %#lx.\n", hr );
- todo_wine ok_( __FILE__, line )( data.actualPlayerCount == data.expectedPlayerCount, "got player count %d.\n", - data.actualPlayerCount ); + ok_( __FILE__, line )( data.actualPlayerCount == data.expectedPlayerCount, "got player count %d.\n", + data.actualPlayerCount ); }
#define checkGroupList( dp, expectedGroups, expectedGroupCount ) \
From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/tests/dplayx.c | 128 +++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+)
diff --git a/dlls/dplayx/tests/dplayx.c b/dlls/dplayx/tests/dplayx.c index d8869b58a40..ffb66b538d0 100644 --- a/dlls/dplayx/tests/dplayx.c +++ b/dlls/dplayx/tests/dplayx.c @@ -978,6 +978,16 @@ typedef struct DWORD tickCount; } Ping;
+typedef struct +{ + MessageHeader header; + DPID toId; + DPID playerId; + DPID groupId; + DWORD createOffset; + DWORD passwordOffset; +} AddPlayerToGroup; + #include "poppack.h"
#define bindUdp( port ) bindUdp_( __LINE__, port ) @@ -2168,6 +2178,39 @@ static unsigned short receivePingReply_( int line, SOCKET sock, DPID expectedFro return port; }
+#define receiveAddPlayerToGroup( sock, expectedPlayerId, expectedGroupId ) \ + receiveAddPlayerToGroup_( __LINE__, sock, expectedPlayerId, expectedGroupId ) +static unsigned short receiveAddPlayerToGroup_( int line, SOCKET sock, DPID expectedPlayerId, DPID expectedGroupId ) +{ +#include "pshpack1.h" + struct + { + SpHeader spHeader; + AddPlayerToGroup request; + } request; +#include "poppack.h" + unsigned short port; + int wsResult; + + wsResult = receiveMessage_( line, sock, &request, sizeof( request ) ); + todo_wine ok_( __FILE__, line )( wsResult == sizeof( request ), "recv() returned %d.\n", wsResult ); + if ( wsResult == SOCKET_ERROR ) + return 0; + + port = checkSpHeader_( line, &request.spHeader, sizeof( request ) ); + checkMessageHeader_( line, &request.request.header, 13 ); + + ok_( __FILE__, line )( !request.request.toId, "got destination id %#lx.\n", request.request.toId ); + ok_( __FILE__, line )( request.request.playerId == expectedPlayerId, "got player id %#lx.\n", + request.request.playerId ); + ok_( __FILE__, line )( request.request.groupId == expectedGroupId, "got group id %#lx.\n", + request.request.groupId ); + ok_( __FILE__, line )( !request.request.createOffset, "got create offset %lu.\n", request.request.createOffset ); + ok_( __FILE__, line )( !request.request.passwordOffset, "got password offset %lu.\n", request.request.passwordOffset ); + + return port; +} + static void init_TCPIP_provider( IDirectPlay4 *pDP, LPCSTR strIPAddressString, WORD port ) {
@@ -8998,6 +9041,90 @@ static void test_PING(void) IDirectPlayX_Release( dp ); }
+/* AddPlayerToGroup */ + +#define checkAddPlayerToGroupMessage( dp, expectedGroupId, expectedPlayerId ) \ + checkAddPlayerToGroupMessage_( __LINE__, dp, expectedGroupId, expectedPlayerId ) +static DPID checkAddPlayerToGroupMessage_( int line, IDirectPlay4 *dp, DPID expectedGroupId, DPID expectedPlayerId ) +{ + DPMSG_ADDPLAYERTOGROUP *msg; + BYTE msgData[ 256 ]; + DWORD msgDataSize; + DPID fromId, toId; + HRESULT hr; + + memset( &msgData, 0, sizeof( msgData ) ); + msgDataSize = sizeof( msgData ); + fromId = 0xdeadbeef; + toId = 0xdeadbeef; + hr = IDirectPlayX_Receive( dp, &fromId, &toId, 0, msgData, &msgDataSize ); + todo_wine ok_( __FILE__, line )( hr == DP_OK, "got hr %#lx.\n", hr ); + if ( FAILED( hr ) ) + return 0; + ok_( __FILE__, line )( fromId == DPID_SYSMSG, "got source id %#lx.\n", fromId ); + + msg = (DPMSG_ADDPLAYERTOGROUP *) msgData; + ok_( __FILE__, line )( msg->dwType == DPSYS_ADDPLAYERTOGROUP, "got message type %#lx.\n", msg->dwType ); + ok_( __FILE__, line )( msg->dpIdGroup == expectedGroupId, "got id %#lx.\n", msg->dpIdGroup ); + ok_( __FILE__, line )( msg->dpIdPlayer == expectedPlayerId, "got id %#lx.\n", msg->dpIdPlayer ); + + return toId; +} + +static void test_AddPlayerToGroup(void) +{ + DPSESSIONDESC2 appGuidDpsd = + { + .dwSize = sizeof( DPSESSIONDESC2 ), + .guidApplication = appGuid, + .guidInstance = appGuid, + }; + DPSESSIONDESC2 serverDpsd = + { + .dwSize = sizeof( DPSESSIONDESC2 ), + .guidApplication = appGuid, + .guidInstance = appGuid, + .lpszSessionName = (WCHAR *) L"normal", + .dwReserved1 = 0xaabbccdd, + }; + IDirectPlay4 *dp; + SOCKET sendSock; + SOCKET recvSock; + HRESULT hr; + DPID dpid; + + hr = CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectPlay4A, (void **) &dp ); + ok( hr == DP_OK, "got hr %#lx.\n", hr ); + + hr = IDirectPlayX_AddPlayerToGroup( dp, 0x5e7, 0x07734 ); + ok( hr == DPERR_UNINITIALIZED, "got hr %#lx.\n", hr ); + + init_TCPIP_provider( dp, "127.0.0.1", 0 ); + + joinSession( dp, &appGuidDpsd, &serverDpsd, &sendSock, &recvSock, NULL ); + + hr = IDirectPlayX_AddPlayerToGroup( dp, 0x5e7, 0x07734 ); + ok( hr == DPERR_INVALIDPLAYER, "got hr %#lx.\n", hr ); + + createPlayer( dp, 0x07734, NULL, NULL, 0, 0, sendSock, recvSock ); + + hr = IDirectPlayX_AddPlayerToGroup( dp, 0x5e7, 0x07734 ); + ok( hr == DP_OK, "got hr %#lx.\n", hr ); + + dpid = checkAddPlayerToGroupMessage( dp, 0x5e7, 0x07734 ); + todo_wine ok( dpid == 0x07734, "got destination id %#lx.\n", dpid ); + + receiveAddPlayerToGroup( recvSock, 0x07734, 0x5e7 ); + + checkNoMorePlayerMessages( dp ); + checkNoMoreMessages( recvSock ); + + closesocket( recvSock ); + closesocket( sendSock ); + + IDirectPlayX_Release( dp ); +} + /* GetMessageCount */
static void test_GetMessageCount(void) @@ -10255,6 +10382,7 @@ START_TEST(dplayx) test_Send(); test_Receive(); test_PING(); + test_AddPlayerToGroup();
if (!winetest_interactive) {
From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/dplay.c | 23 +++++++++++++++++++++++ dlls/dplayx/tests/dplayx.c | 6 ++---- 2 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index 4a4fe8d2619..b355310f20d 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -1134,6 +1134,7 @@ static HRESULT WINAPI IDirectPlay4AImpl_AddPlayerToGroup( IDirectPlay4A *iface,
HRESULT DP_AddPlayerToGroup( IDirectPlayImpl *This, DPID group, DPID player ) { + DPMSG_ADDPLAYERTOGROUP addPlayerToGroupMsg; lpGroupData gdata; lpPlayerList plist; lpPlayerList newplist; @@ -1180,6 +1181,28 @@ HRESULT DP_AddPlayerToGroup( IDirectPlayImpl *This, DPID group, DPID player ) } }
+ addPlayerToGroupMsg.dwType = DPSYS_ADDPLAYERTOGROUP; + addPlayerToGroupMsg.dpIdGroup = group; + addPlayerToGroupMsg.dpIdPlayer = player; + + hr = DP_QueueMessage( This, DPID_SYSMSG, DPID_ALLPLAYERS, 0, &addPlayerToGroupMsg, + DP_CopyGeneric, sizeof( DPMSG_ADDPLAYERTOGROUP ) ); + if ( FAILED( hr ) ) + { + if ( This->dp2->spData.lpCB->RemovePlayerFromGroup ) + { + DPSP_REMOVEPLAYERFROMGROUPDATA data; + data.idPlayer = player; + data.idGroup = group; + data.lpISP = This->dp2->spData.lpISP; + This->dp2->spData.lpCB->RemovePlayerFromGroup( &data ); + } + DPQ_REMOVE( gdata->players, newplist, players ); + --plist->lpPData->uRef; + free( newplist ); + return hr; + } + return DP_OK; }
diff --git a/dlls/dplayx/tests/dplayx.c b/dlls/dplayx/tests/dplayx.c index ffb66b538d0..cb61c946bf4 100644 --- a/dlls/dplayx/tests/dplayx.c +++ b/dlls/dplayx/tests/dplayx.c @@ -9058,9 +9058,7 @@ static DPID checkAddPlayerToGroupMessage_( int line, IDirectPlay4 *dp, DPID expe fromId = 0xdeadbeef; toId = 0xdeadbeef; hr = IDirectPlayX_Receive( dp, &fromId, &toId, 0, msgData, &msgDataSize ); - todo_wine ok_( __FILE__, line )( hr == DP_OK, "got hr %#lx.\n", hr ); - if ( FAILED( hr ) ) - return 0; + ok_( __FILE__, line )( hr == DP_OK, "got hr %#lx.\n", hr ); ok_( __FILE__, line )( fromId == DPID_SYSMSG, "got source id %#lx.\n", fromId );
msg = (DPMSG_ADDPLAYERTOGROUP *) msgData; @@ -9112,7 +9110,7 @@ static void test_AddPlayerToGroup(void) ok( hr == DP_OK, "got hr %#lx.\n", hr );
dpid = checkAddPlayerToGroupMessage( dp, 0x5e7, 0x07734 ); - todo_wine ok( dpid == 0x07734, "got destination id %#lx.\n", dpid ); + ok( dpid == 0x07734, "got destination id %#lx.\n", dpid );
receiveAddPlayerToGroup( recvSock, 0x07734, 0x5e7 );
From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/dplay.c | 17 ++++---------- dlls/dplayx/dplayx_messages.c | 43 +++++++++++++++++++++++++++++++++++ dlls/dplayx/dplayx_messages.h | 13 +++++++++++ dlls/dplayx/tests/dplayx.c | 4 +--- 4 files changed, 61 insertions(+), 16 deletions(-)
diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index b355310f20d..7646f12fa76 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -1231,20 +1231,11 @@ static HRESULT WINAPI IDirectPlay4Impl_AddPlayerToGroup( IDirectPlay4 *iface, DP * Also, if this event was the result of another machine sending it to us, * don't bother rebroadcasting it. */ - if ( This->dp2->lpSessionDesc && - ( This->dp2->lpSessionDesc->dwFlags & DPSESSION_MULTICASTSERVER ) ) + hr = DP_MSG_SendAddPlayerToGroup( This, DPID_ALLPLAYERS, player, group ); + if( FAILED( hr ) ) { - DPMSG_ADDPLAYERTOGROUP msg; - msg.dwType = DPSYS_ADDPLAYERTOGROUP; - - msg.dpIdGroup = group; - msg.dpIdPlayer = player; - - /* FIXME: Correct to just use send effectively? */ - /* FIXME: Should size include data w/ message or just message "header" */ - /* FIXME: Check return code */ - IDirectPlayX_SendEx( iface, DPID_SERVERPLAYER, DPID_ALLPLAYERS, 0, &msg, sizeof( msg ), - 0, 0, NULL, NULL ); + LeaveCriticalSection( &This->lock ); + return hr; }
LeaveCriticalSection( &This->lock ); diff --git a/dlls/dplayx/dplayx_messages.c b/dlls/dplayx/dplayx_messages.c index d81e29a7e0b..9af044b4e4d 100644 --- a/dlls/dplayx/dplayx_messages.c +++ b/dlls/dplayx/dplayx_messages.c @@ -831,6 +831,49 @@ HRESULT DP_MSG_SendCreatePlayer( IDirectPlayImpl *This, DPID toId, DPID id, DWOR return DP_OK; }
+HRESULT DP_MSG_SendAddPlayerToGroup( IDirectPlayImpl *This, DPID toId, DPID playerId, DPID groupId ) +{ + DPSP_SENDTOGROUPEXDATA sendData; + DPSP_MSG_ADDPLAYERTOGROUP msg; + SGBUFFER buffers[ 2 ] = { 0 }; + HRESULT hr; + + msg.envelope.dwMagic = DPMSGMAGIC_DPLAYMSG; + msg.envelope.wCommandId = DPMSGCMD_ADDPLAYERTOGROUP; + msg.envelope.wVersion = DPMSGVER_DP6; + msg.toId = 0; + msg.playerId = playerId; + msg.groupId = groupId; + msg.createOffset = 0; + msg.passwordOffset = 0; + + buffers[ 0 ].len = This->dp2->spData.dwSPHeaderSize; + buffers[ 0 ].pData = NULL; + buffers[ 1 ].len = sizeof( msg ); + buffers[ 1 ].pData = (UCHAR *)&msg; + + sendData.lpISP = This->dp2->spData.lpISP; + sendData.dwFlags = DPSEND_GUARANTEED; + sendData.idGroupTo = toId; + sendData.idPlayerFrom = This->dp2->systemPlayerId; + sendData.lpSendBuffers = buffers; + sendData.cBuffers = ARRAYSIZE( buffers ); + sendData.dwMessageSize = DP_MSG_ComputeMessageSize( sendData.lpSendBuffers, sendData.cBuffers ); + sendData.dwPriority = 0; + sendData.dwTimeout = 0; + sendData.lpDPContext = NULL; + sendData.lpdwSPMsgID = NULL; + + hr = (*This->dp2->spData.lpCB->SendToGroupEx)( &sendData ); + if( FAILED( hr ) ) + { + ERR( "SendToGroupEx failed: %s\n", DPLAYX_HresultToString( hr ) ); + return hr; + } + + return DP_OK; +} + HRESULT DP_MSG_SendPingReply( IDirectPlayImpl *This, DPID toId, DPID fromId, DWORD tickCount ) { SGBUFFER buffers[ 2 ] = { 0 }; diff --git a/dlls/dplayx/dplayx_messages.h b/dlls/dplayx/dplayx_messages.h index 2a3a15d5c73..5b6ce52663f 100644 --- a/dlls/dplayx/dplayx_messages.h +++ b/dlls/dplayx/dplayx_messages.h @@ -57,6 +57,8 @@ HRESULT DP_MSG_ForwardPlayerCreation( IDirectPlayImpl *This, DPID dpidServer, WC HRESULT DP_MSG_SendCreatePlayer( IDirectPlayImpl *This, DPID toId, DPID id, DWORD flags, DPNAME *name, void *playerData, DWORD playerDataSize, DPID systemPlayerId ); +HRESULT DP_MSG_SendAddPlayerToGroup( IDirectPlayImpl *This, DPID toId, DPID playerId, + DPID groupId ); HRESULT DP_MSG_SendPingReply( IDirectPlayImpl *This, DPID toId, DPID fromId, DWORD tickCount ); HRESULT DP_MSG_SendAddForwardAck( IDirectPlayImpl *This, DPID id );
@@ -103,6 +105,7 @@ typedef struct #define DPMSGCMD_SYSTEMMESSAGE 10 #define DPMSGCMD_DELETEPLAYER 11 #define DPMSGCMD_DELETEGROUP 12 +#define DPMSGCMD_ADDPLAYERTOGROUP 13
#define DPMSGCMD_ENUMGROUPS 17
@@ -231,6 +234,16 @@ typedef struct tagDPMSG_NEWPLAYERIDREPLY } DPMSG_NEWPLAYERIDREPLY, *LPDPMSG_NEWPLAYERIDREPLY; typedef const DPMSG_NEWPLAYERIDREPLY* LPCDPMSG_NEWPLAYERIDREPLY;
+typedef struct +{ + DPMSG_SENDENVELOPE envelope; + DPID toId; + DPID playerId; + DPID groupId; + DWORD createOffset; + DWORD passwordOffset; +} DPSP_MSG_ADDPLAYERTOGROUP; + typedef struct tagDPMSG_FORWARDADDPLAYER { DPMSG_SENDENVELOPE envelope; diff --git a/dlls/dplayx/tests/dplayx.c b/dlls/dplayx/tests/dplayx.c index cb61c946bf4..08d2f48ae82 100644 --- a/dlls/dplayx/tests/dplayx.c +++ b/dlls/dplayx/tests/dplayx.c @@ -2193,9 +2193,7 @@ static unsigned short receiveAddPlayerToGroup_( int line, SOCKET sock, DPID expe int wsResult;
wsResult = receiveMessage_( line, sock, &request, sizeof( request ) ); - todo_wine ok_( __FILE__, line )( wsResult == sizeof( request ), "recv() returned %d.\n", wsResult ); - if ( wsResult == SOCKET_ERROR ) - return 0; + ok_( __FILE__, line )( wsResult == sizeof( request ), "recv() returned %d.\n", wsResult );
port = checkSpHeader_( line, &request.spHeader, sizeof( request ) ); checkMessageHeader_( line, &request.request.header, 13 );
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=149758
Your paranoid android.
=== w10pro64_en_AE_u8 (32 bit report) ===
dplayx: dplayx.c:3316: Test failed: recv() returned -1. dplayx.c:3316: Test failed: Open() returned 0x8007000e.
This merge request was approved by Alistair Leslie-Hughes.