From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/tests/dplayx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/dplayx/tests/dplayx.c b/dlls/dplayx/tests/dplayx.c index ca0507ce45f..8e74d741720 100644 --- a/dlls/dplayx/tests/dplayx.c +++ b/dlls/dplayx/tests/dplayx.c @@ -1480,7 +1480,7 @@ static void sendSuperEnumPlayersReply_( int line, SOCKET sock, unsigned short tc .flags = 0x8, .id = 0x1337, .infoMask = 0x17, - .versionOrSystemPlayerId = 14, + .versionOrSystemPlayerId = 0x51573, }, .shortName = SHORT_NAME, .longName = LONG_NAME,
From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/tests/dplayx.c | 148 ++++++++++++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 1 deletion(-)
diff --git a/dlls/dplayx/tests/dplayx.c b/dlls/dplayx/tests/dplayx.c index 8e74d741720..4d5346b1fa7 100644 --- a/dlls/dplayx/tests/dplayx.c +++ b/dlls/dplayx/tests/dplayx.c @@ -965,6 +965,12 @@ typedef struct PackedPlayer playerInfo; } CreatePlayer;
+typedef struct +{ + DPID fromId; + DPID toId; +} GameMessage; + #include "poppack.h"
#define bindUdp( port ) bindUdp_( __LINE__, port ) @@ -1176,6 +1182,14 @@ static void checkPackedPlayer_( int line, PackedPlayer *player, DWORD expectedFl ok_( __FILE__, line )( !player->parentId, "got parent id %#lx.\n", player->parentId ); }
+#define checkGameMessage( message, expectedFromId, expectedToId ) \ + checkGameMessage_( __LINE__, message, expectedFromId, expectedToId ) +static void checkGameMessage_( int line, GameMessage *message, DPID expectedFromId, DPID expectedToId ) +{ + ok_( __FILE__, line )( message->fromId == expectedFromId, "got source id %#lx.\n", message->fromId ); + ok_( __FILE__, line )( message->toId == expectedToId, "got destination id %#lx.\n", message->toId ); +} + #define receiveEnumSessionsRequest( sock, expectedAppGuid, expectedPassword, expectedFlags ) \ receiveEnumSessionsRequest_( __LINE__, sock, expectedAppGuid, expectedPassword, expectedFlags ) static unsigned short receiveEnumSessionsRequest_( int line, SOCKET sock, const GUID *expectedAppGuid, @@ -1828,6 +1842,34 @@ static void sendCreatePlayer_( int line, SOCKET sock, unsigned short tcpPort, un ok_( __FILE__, line )( wsResult == sizeof( reserved ), "send() returned %d.\n", wsResult ); }
+#define receiveGuaranteedGameMessage( sock, expectedFromId, expectedToId, expectedData, expectedDataSize ) \ + receiveGuaranteedGameMessage_( __LINE__, sock, expectedFromId, expectedToId, expectedData, expectedDataSize ) +static unsigned short receiveGuaranteedGameMessage_( int line, SOCKET sock, DPID expectedFromId, DPID expectedToId, + void *expectedData, DWORD expectedDataSize ) +{ + struct + { + SpHeader spHeader; + GameMessage request; + BYTE data[ 256 ]; + } request; + unsigned short port; + int wsResult; + + DWORD expectedSize = sizeof( request.spHeader ) + sizeof( request.request ) + expectedDataSize; + + wsResult = receiveMessage_( line, sock, &request, expectedSize ); + todo_wine ok_( __FILE__, line )( wsResult == expectedSize, "recv() returned %d.\n", wsResult ); + if ( wsResult == SOCKET_ERROR ) + return 0; + + port = checkSpHeader_( line, &request.spHeader, expectedSize ); + checkGameMessage_( line, &request.request, expectedFromId, expectedToId ); + ok_( __FILE__, line )( !memcmp( &request.data, expectedData, expectedDataSize ), "message data didn't match.\n" ); + + return port; +} + static void init_TCPIP_provider( IDirectPlay4 *pDP, LPCSTR strIPAddressString, WORD port ) {
@@ -4227,6 +4269,32 @@ static DPID checkCreatePlayerOrGroupMessage_( int line, IDirectPlay4 *dp, DWORD return toId; }
+#define checkPlayerMessage( dp, expectedFromId, expectedData, expectedDataSize ) \ + checkPlayerMessage_( __LINE__, dp, expectedFromId, expectedData, expectedDataSize ) +static DPID checkPlayerMessage_( int line, IDirectPlay4 *dp, DPID expectedFromId, void *expectedData, + DWORD expectedDataSize ) +{ + DPID fromId, toId; + BYTE data[ 1024 ]; + DWORD dataSize; + HRESULT hr; + + fromId = 0xdeadbeef; + toId = 0xdeadbeef; + memset( data, 0xcc, sizeof( data ) ); + dataSize = sizeof( data ); + hr = IDirectPlayX_Receive( dp, &fromId, &toId, 0, data, &dataSize ); + todo_wine ok_( __FILE__, line )( hr == DP_OK, "got hr %#lx.\n", hr ); + if ( FAILED( hr ) ) + return toId; + + ok_( __FILE__, line )( fromId == expectedFromId, "got source id %#lx.\n", fromId ); + ok_( __FILE__, line )( !memcmp( data, expectedData, expectedDataSize ), "message data didn't match.\n" ); + ok_( __FILE__, line )( dataSize == expectedDataSize, "got data size %lu.\n", dataSize ); + + return toId; +} + #define checkNoMorePlayerMessages( dp ) checkNoMorePlayerMessages_( __LINE__, dp ) static void checkNoMorePlayerMessages_( int line, IDirectPlay4 *dp ) { @@ -7575,6 +7643,83 @@ static void test_groups_cs(void) /* Send */
static void test_Send(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, + }; + BYTE data[] = { 1, 2, 3, 4, 5, 6, 7, 8, }; + 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_Send( dp, 0x07734, 0x1337, DPSEND_GUARANTEED, data, sizeof( data ) ); + ok( hr == DPERR_UNINITIALIZED, "got hr %#lx.\n", hr ); + + init_TCPIP_provider( dp, "127.0.0.1", 0 ); + + hr = IDirectPlayX_Send( dp, 0x07734, 0x1337, DPSEND_GUARANTEED, data, sizeof( data ) ); + ok( hr == DPERR_INVALIDPLAYER, "got hr %#lx.\n", hr ); + + joinSession( dp, &appGuidDpsd, &serverDpsd, &sendSock, &recvSock ); + + createPlayer( dp, 0x07734, NULL, NULL, 0, 0, sendSock, recvSock ); + createPlayer( dp, 0x14, NULL, NULL, 0, 0, sendSock, recvSock ); + + checkCreatePlayerOrGroupMessage( dp, DPPLAYERTYPE_PLAYER, 0x14, 2, NULL, 0, NULL, NULL, 0, DPPLAYER_LOCAL ); + + hr = IDirectPlayX_Send( dp, 0x07734, 0xdeadbeef, DPSEND_GUARANTEED, data, sizeof( data ) ); + todo_wine ok( hr == DPERR_INVALIDPARAM, "got hr %#lx.\n", hr ); + + hr = IDirectPlayX_Send( dp, 0x07734, 0x1337, DPSEND_GUARANTEED, data, sizeof( data ) ); + ok( hr == DP_OK, "got hr %#lx.\n", hr ); + + receiveGuaranteedGameMessage( recvSock, 0x07734, 0x1337, data, sizeof( data ) ); + + hr = IDirectPlayX_Send( dp, 0x07734, 0x14, DPSEND_GUARANTEED, data, sizeof( data ) ); + ok( hr == DP_OK, "got hr %#lx.\n", hr ); + + dpid = checkPlayerMessage( dp, 0x07734, data, sizeof( data ) ); + todo_wine ok( dpid == 0x14, "got destination id %#lx.\n", dpid ); + + hr = IDirectPlayX_Send( dp, 0x07734, 0x07734, DPSEND_GUARANTEED, data, sizeof( data ) ); + ok( hr == DP_OK, "got hr %#lx.\n", hr ); + + checkNoMorePlayerMessages( dp ); + checkNoMoreMessages( recvSock ); + + hr = IDirectPlayX_Send( dp, 0x07734, DPID_ALLPLAYERS, DPSEND_GUARANTEED, data, sizeof( data ) ); + ok( hr == DP_OK, "got hr %#lx.\n", hr ); + + dpid = checkPlayerMessage( dp, 0x07734, data, sizeof( data ) ); + todo_wine ok( dpid == 0x14, "got destination id %#lx.\n", dpid ); + receiveGuaranteedGameMessage( recvSock, 0x07734, DPID_ALLPLAYERS, data, sizeof( data ) ); + + checkNoMorePlayerMessages( dp ); + checkNoMoreMessages( recvSock ); + + closesocket( recvSock ); + closesocket( sendSock ); + + IDirectPlayX_Release( dp ); +} + +static void test_interactive_Send(void) {
IDirectPlay4 *pDP[2]; @@ -9445,6 +9590,7 @@ START_TEST(dplayx) test_ADDFORWARD(); test_CreatePlayer(); test_CREATEPLAYER(); + test_Send();
if (!winetest_interactive) { @@ -9481,7 +9627,7 @@ START_TEST(dplayx) test_groups_p2p(); test_groups_cs();
- test_Send(); + test_interactive_Send(); test_Receive(); test_GetMessageCount(); test_GetMessageQueue();
From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/dplay.c | 42 +++++++++++++++++++++++++++++--------- dlls/dplayx/dplay_global.h | 4 +++- dlls/dplayx/tests/dplayx.c | 8 +++----- 3 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index 46876566e33..6dfc2439624 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -323,7 +323,8 @@ static void *DP_DuplicateString( void *src, BOOL dstAnsi, BOOL srcAnsi ) }
static HRESULT DP_QueuePlayerMessage( IDirectPlayImpl *This, DPID fromId, struct PlayerData *player, - DPID excludeId, void *msg, FN_COPY_MESSAGE *copyMessage ) + DPID excludeId, void *msg, FN_COPY_MESSAGE *copyMessage, + DWORD genericSize ) { struct DPMSG *elem; DWORD msgSize; @@ -339,18 +340,19 @@ static HRESULT DP_QueuePlayerMessage( IDirectPlayImpl *This, DPID fromId, struct if( !elem ) return DPERR_OUTOFMEMORY;
- msgSize = copyMessage( NULL, msg, FALSE ); + msgSize = copyMessage( NULL, msg, genericSize, FALSE ); elem->msg = malloc( msgSize ); if ( !elem->msg ) { free( elem ); return DPERR_OUTOFMEMORY; } - copyMessage( elem->msg, msg, FALSE ); + copyMessage( elem->msg, msg, genericSize, FALSE );
elem->fromId = fromId; elem->toId = player->dpid; elem->copyMessage = copyMessage; + elem->genericSize = genericSize;
DPQ_INSERT_IN_TAIL( This->dp2->receiveMsgs, elem, msgs );
@@ -361,7 +363,7 @@ static HRESULT DP_QueuePlayerMessage( IDirectPlayImpl *This, DPID fromId, struct }
static HRESULT DP_QueueMessage( IDirectPlayImpl *This, DPID fromId, DPID toId, DPID excludeId, - void *msg, FN_COPY_MESSAGE *copyMessage ) + void *msg, FN_COPY_MESSAGE *copyMessage, DWORD genericSize ) { struct PlayerList *plist; struct GroupData *group; @@ -369,14 +371,16 @@ static HRESULT DP_QueueMessage( IDirectPlayImpl *This, DPID fromId, DPID toId, D
plist = DP_FindPlayer( This, toId ); if ( plist ) - return DP_QueuePlayerMessage( This, fromId, plist->lpPData, excludeId, msg, copyMessage ); + return DP_QueuePlayerMessage( This, fromId, plist->lpPData, excludeId, msg, copyMessage, + genericSize );
group = DP_FindAnyGroup( This, toId ); if( group ) { for( plist = DPQ_FIRST( group->players ); plist; plist = DPQ_NEXT( plist->players ) ) { - hr = DP_QueuePlayerMessage( This, fromId, plist->lpPData, excludeId, msg, copyMessage ); + hr = DP_QueuePlayerMessage( This, fromId, plist->lpPData, excludeId, msg, copyMessage, + genericSize ); if ( FAILED( hr ) ) return hr; } @@ -387,8 +391,19 @@ static HRESULT DP_QueueMessage( IDirectPlayImpl *This, DPID fromId, DPID toId, D return DPERR_INVALIDPLAYER; }
+static DWORD DP_CopyGeneric( DPMSG_GENERIC *genericDst, DPMSG_GENERIC *genericSrc, + DWORD genericSize, BOOL ansi ) +{ + if ( !genericDst ) + return genericSize; + + memcpy( genericDst, genericSrc, genericSize ); + + return genericSize; +} + static DWORD DP_CopyCreatePlayerOrGroup( DPMSG_GENERIC *genericDst, DPMSG_GENERIC *genericSrc, - BOOL ansi ) + DWORD genericSize, BOOL ansi ) { DPMSG_CREATEPLAYERORGROUP *src = (DPMSG_CREATEPLAYERORGROUP *) genericSrc; DPMSG_CREATEPLAYERORGROUP *dst = (DPMSG_CREATEPLAYERORGROUP *) genericDst; @@ -1746,7 +1761,7 @@ HRESULT DP_CreatePlayer( IDirectPlayImpl *This, void *msgHeader, DPID *lpid, DPN msg.dwFlags = dwFlags;
hr = DP_QueueMessage( This, DPID_SYSMSG, DPID_ALLPLAYERS, *lpid, &msg, - DP_CopyCreatePlayerOrGroup ); + DP_CopyCreatePlayerOrGroup, 0 ); if ( FAILED( hr ) ) { DP_DeleteSPPlayer( This, *lpid ); @@ -3807,14 +3822,14 @@ static HRESULT DP_IF_Receive( IDirectPlayImpl *This, DPID *lpidFrom, DPID *lpidT return DPERR_NOMESSAGES; }
- msgSize = lpMsg->copyMessage( NULL, lpMsg->msg, bAnsi ); + msgSize = lpMsg->copyMessage( NULL, lpMsg->msg, lpMsg->genericSize, bAnsi );
*lpidFrom = lpMsg->fromId; *lpidTo = lpMsg->toId; *lpdwDataSize = msgSize;
/* Copy into the provided buffer */ - if (lpData) lpMsg->copyMessage( lpData, lpMsg->msg, bAnsi ); + if (lpData) lpMsg->copyMessage( lpData, lpMsg->msg, lpMsg->genericSize, bAnsi );
if( !( dwFlags & DPRECEIVE_PEEK ) ) { @@ -5619,6 +5634,13 @@ static HRESULT WINAPI IDirectPlay4Impl_SendEx( IDirectPlay4 *iface, DPID from, D return DPERR_INVALIDPLAYER; }
+ hr = DP_QueueMessage( This, from, to, from, data, DP_CopyGeneric, size ); + if ( FAILED( hr ) ) + { + LeaveCriticalSection( &This->lock ); + return hr; + } + /* Verify that the message is being sent to a valid player, group or to * everyone. If it's valid, send it to those players. */ diff --git a/dlls/dplayx/dplay_global.h b/dlls/dplayx/dplay_global.h index b011c183c7d..79710733e24 100644 --- a/dlls/dplayx/dplay_global.h +++ b/dlls/dplayx/dplay_global.h @@ -131,7 +131,8 @@ struct GroupList }; typedef struct GroupList* lpGroupList;
-typedef DWORD FN_COPY_MESSAGE( DPMSG_GENERIC *genericDst, DPMSG_GENERIC *genericSrc, BOOL ansi ); +typedef DWORD FN_COPY_MESSAGE( DPMSG_GENERIC *genericDst, DPMSG_GENERIC *genericSrc, + DWORD genericSize, BOOL ansi );
struct DPMSG { @@ -140,6 +141,7 @@ struct DPMSG DPID toId; DPMSG_GENERIC* msg; FN_COPY_MESSAGE *copyMessage; + DWORD genericSize; }; typedef struct DPMSG* LPDPMSG;
diff --git a/dlls/dplayx/tests/dplayx.c b/dlls/dplayx/tests/dplayx.c index 4d5346b1fa7..9fc6d36b8ce 100644 --- a/dlls/dplayx/tests/dplayx.c +++ b/dlls/dplayx/tests/dplayx.c @@ -4284,9 +4284,7 @@ static DPID checkPlayerMessage_( int line, IDirectPlay4 *dp, DPID expectedFromId memset( data, 0xcc, sizeof( data ) ); dataSize = sizeof( data ); hr = IDirectPlayX_Receive( dp, &fromId, &toId, 0, data, &dataSize ); - todo_wine ok_( __FILE__, line )( hr == DP_OK, "got hr %#lx.\n", hr ); - if ( FAILED( hr ) ) - return toId; + ok_( __FILE__, line )( hr == DP_OK, "got hr %#lx.\n", hr );
ok_( __FILE__, line )( fromId == expectedFromId, "got source id %#lx.\n", fromId ); ok_( __FILE__, line )( !memcmp( data, expectedData, expectedDataSize ), "message data didn't match.\n" ); @@ -7695,7 +7693,7 @@ static void test_Send(void) ok( hr == DP_OK, "got hr %#lx.\n", hr );
dpid = checkPlayerMessage( dp, 0x07734, data, sizeof( data ) ); - todo_wine ok( dpid == 0x14, "got destination id %#lx.\n", dpid ); + ok( dpid == 0x14, "got destination id %#lx.\n", dpid );
hr = IDirectPlayX_Send( dp, 0x07734, 0x07734, DPSEND_GUARANTEED, data, sizeof( data ) ); ok( hr == DP_OK, "got hr %#lx.\n", hr ); @@ -7707,7 +7705,7 @@ static void test_Send(void) ok( hr == DP_OK, "got hr %#lx.\n", hr );
dpid = checkPlayerMessage( dp, 0x07734, data, sizeof( data ) ); - todo_wine ok( dpid == 0x14, "got destination id %#lx.\n", dpid ); + ok( dpid == 0x14, "got destination id %#lx.\n", dpid ); receiveGuaranteedGameMessage( recvSock, 0x07734, DPID_ALLPLAYERS, data, sizeof( data ) );
checkNoMorePlayerMessages( dp );
From: Anton Baskanov baskanov@gmail.com
It will be handled by DP_FindAnyGroup(). --- dlls/dplayx/dplay.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index 6dfc2439624..5b0953f7adb 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -5644,17 +5644,7 @@ static HRESULT WINAPI IDirectPlay4Impl_SendEx( IDirectPlay4 *iface, DPID from, D /* Verify that the message is being sent to a valid player, group or to * everyone. If it's valid, send it to those players. */ - if ( to == DPID_ALLPLAYERS ) - { - /* See if SP has the ability to multicast. If so, use it */ - if ( This->dp2->spData.lpCB->SendToGroupEx ) - FIXME( "Use group sendex to group 0\n" ); - else if ( This->dp2->spData.lpCB->SendToGroup ) /* obsolete interface */ - FIXME( "Use obsolete group send to group 0\n" ); - else /* No multicast, multiplicate */ - FIXME( "Send to all players using EnumPlayersInGroup\n" ); - } - else if ( DP_FindPlayer( This, to ) ) + if ( DP_FindPlayer( This, to ) ) { /* Have the service provider send this message */ /* FIXME: Could optimize for local interface sends */
From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/dplay.c | 92 +++++++++++++++++++++++------------ dlls/dplayx/dplay_global.h | 1 - dlls/dplayx/dplayx_messages.h | 1 + dlls/dplayx/tests/dplayx.c | 4 +- 4 files changed, 63 insertions(+), 35 deletions(-)
diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index 5b0953f7adb..3fd813f311b 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -62,8 +62,6 @@ static HRESULT DP_SetSessionDesc( IDirectPlayImpl *This, const DPSESSIONDESC2 *l DWORD dwFlags, BOOL bInitial, BOOL bAnsi ); static void DP_SetPlayerData( lpPlayerData lpPData, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize ); -static HRESULT DP_SP_SendEx( IDirectPlayImpl *This, DWORD dwFlags, void *lpData, DWORD dwDataSize, - DWORD dwPriority, DWORD dwTimeout, void *lpContext, DWORD *lpdwMsgID ); static BOOL DP_BuildSPCompoundAddr( LPGUID lpcSpGuid, LPVOID* lplpAddrBuf, LPDWORD lpdwBufSize );
@@ -140,7 +138,6 @@ static BOOL DP_CreateDirectPlay2( LPVOID lpDP ) This->dp2->bHostInterface = FALSE;
DPQ_INIT(This->dp2->receiveMsgs); - DPQ_INIT(This->dp2->sendMsgs); DPQ_INIT(This->dp2->repliesExpected);
if( !NS_InitializeSessionCache( &This->dp2->lpNameServerData ) ) @@ -5607,9 +5604,11 @@ static HRESULT WINAPI IDirectPlay4Impl_SendEx( IDirectPlay4 *iface, DPID from, D DWORD *msgid ) { IDirectPlayImpl *This = impl_from_IDirectPlay4( iface ); + DPMSG_SYSMSGENVELOPE envelope; + SGBUFFER buffers[ 3 ] = { 0 }; HRESULT hr;
- FIXME( "(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx,0x%08lx,0x%08lx,%p,%p): semi-stub\n", + TRACE( "(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx,0x%08lx,0x%08lx,%p,%p)\n", This, from, to, flags, data, size, priority, timeout, context, msgid );
if ( This->dp2->connectionInitialized == NO_PROVIDER ) @@ -5641,22 +5640,74 @@ static HRESULT WINAPI IDirectPlay4Impl_SendEx( IDirectPlay4 *iface, DPID from, D return hr; }
+ envelope.dwPlayerFrom = from; + envelope.dwPlayerTo = to; + + buffers[ 0 ].len = This->dp2->spData.dwSPHeaderSize; + buffers[ 0 ].pData = NULL; + buffers[ 1 ].len = sizeof( envelope ); + buffers[ 1 ].pData = (UCHAR *)&envelope; + buffers[ 2 ].len = size; + buffers[ 2 ].pData = data; + /* Verify that the message is being sent to a valid player, group or to * everyone. If it's valid, send it to those players. */ if ( DP_FindPlayer( This, to ) ) { - /* Have the service provider send this message */ - /* FIXME: Could optimize for local interface sends */ - hr = DP_SP_SendEx( This, flags, data, size, priority, timeout, context, msgid ); - LeaveCriticalSection( &This->lock ); - return hr; + if ( This->dp2->spData.lpCB->SendEx ) + { + DPSP_SENDEXDATA sendData; + + sendData.lpISP = This->dp2->spData.lpISP; + sendData.dwFlags = flags; + sendData.idPlayerTo = to; + sendData.idPlayerFrom = from; + sendData.lpSendBuffers = ( flags & DPSEND_GUARANTEED ) ? buffers : &buffers[ 1 ]; + sendData.cBuffers = ( flags & DPSEND_GUARANTEED ) ? 3 : 2; + sendData.dwMessageSize = DP_MSG_ComputeMessageSize( sendData.lpSendBuffers, + sendData.cBuffers ); + sendData.dwPriority = priority; + sendData.dwTimeout = timeout; + sendData.lpDPContext = context; + sendData.lpdwSPMsgID = msgid; + sendData.bSystemMessage = FALSE; + + hr = This->dp2->spData.lpCB->SendEx( &sendData ); + + LeaveCriticalSection( &This->lock ); + + return hr; + } + else + FIXME( "Use obsolete send\n" ); } else if ( DP_FindAnyGroup( This, to ) ) { /* See if SP has the ability to multicast. If so, use it */ if ( This->dp2->spData.lpCB->SendToGroupEx ) - FIXME( "Use group sendex\n" ); + { + DPSP_SENDTOGROUPEXDATA sendData; + + sendData.lpISP = This->dp2->spData.lpISP; + sendData.dwFlags = flags; + sendData.idGroupTo = to; + sendData.idPlayerFrom = from; + sendData.lpSendBuffers = ( flags & DPSEND_GUARANTEED ) ? buffers : &buffers[ 1 ]; + sendData.cBuffers = ( flags & DPSEND_GUARANTEED ) ? 3 : 2; + sendData.dwMessageSize = DP_MSG_ComputeMessageSize( sendData.lpSendBuffers, + sendData.cBuffers ); + sendData.dwPriority = priority; + sendData.dwTimeout = timeout; + sendData.lpDPContext = context; + sendData.lpdwSPMsgID = msgid; + + hr = This->dp2->spData.lpCB->SendToGroupEx( &sendData ); + + LeaveCriticalSection( &This->lock ); + + return hr; + } else if ( This->dp2->spData.lpCB->SendToGroup ) /* obsolete interface */ FIXME( "Use obsolete group send to group\n" ); else /* No multicast, multiplicate */ @@ -5671,30 +5722,9 @@ static HRESULT WINAPI IDirectPlay4Impl_SendEx( IDirectPlay4 *iface, DPID from, D
LeaveCriticalSection( &This->lock );
- /* FIXME: Should return what the send returned */ return DP_OK; }
-static HRESULT DP_SP_SendEx( IDirectPlayImpl *This, DWORD dwFlags, void *lpData, DWORD dwDataSize, - DWORD dwPriority, DWORD dwTimeout, void *lpContext, DWORD *lpdwMsgID ) -{ - LPDPMSG lpMElem; - - FIXME( ": stub\n" ); - - /* FIXME: This queuing should only be for async messages */ - - lpMElem = calloc( 1, sizeof( *lpMElem ) ); - lpMElem->msg = malloc( dwDataSize ); - - CopyMemory( lpMElem->msg, lpData, dwDataSize ); - - /* FIXME: Need to queue based on priority */ - DPQ_INSERT( This->dp2->sendMsgs, lpMElem, msgs ); - - return DP_OK; -} - static HRESULT WINAPI IDirectPlay4AImpl_GetMessageQueue( IDirectPlay4A *iface, DPID from, DPID to, DWORD flags, DWORD *msgs, DWORD *bytes ) { diff --git a/dlls/dplayx/dplay_global.h b/dlls/dplayx/dplay_global.h index 79710733e24..b371eda9df6 100644 --- a/dlls/dplayx/dplay_global.h +++ b/dlls/dplayx/dplay_global.h @@ -174,7 +174,6 @@ typedef struct tagDirectPlay2Data
/* I/O Msg queues */ DPQ_HEAD( DPMSG ) receiveMsgs; /* Msg receive queue */ - DPQ_HEAD( DPMSG ) sendMsgs; /* Msg send pending queue */
/* Information about the service provider active on this connection */ SPINITDATA spData; diff --git a/dlls/dplayx/dplayx_messages.h b/dlls/dplayx/dplayx_messages.h index 37f3ce0a1bd..fd432e5cb6c 100644 --- a/dlls/dplayx/dplayx_messages.h +++ b/dlls/dplayx/dplayx_messages.h @@ -48,6 +48,7 @@ typedef struct DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart, HANDLE hDeath, HANDLE hConnRead );
+DWORD DP_MSG_ComputeMessageSize( SGBUFFER *buffers, DWORD bufferCount ); HRESULT DP_MSG_SendRequestPlayerId( IDirectPlayImpl *This, DWORD dwFlags, LPDPID lpdipidAllocatedId ); HRESULT DP_MSG_ReadPackedPlayer( char *data, DWORD *offset, DWORD maxSize, diff --git a/dlls/dplayx/tests/dplayx.c b/dlls/dplayx/tests/dplayx.c index 9fc6d36b8ce..e396966cb3b 100644 --- a/dlls/dplayx/tests/dplayx.c +++ b/dlls/dplayx/tests/dplayx.c @@ -1859,9 +1859,7 @@ static unsigned short receiveGuaranteedGameMessage_( int line, SOCKET sock, DPID DWORD expectedSize = sizeof( request.spHeader ) + sizeof( request.request ) + expectedDataSize;
wsResult = receiveMessage_( line, sock, &request, expectedSize ); - todo_wine ok_( __FILE__, line )( wsResult == expectedSize, "recv() returned %d.\n", wsResult ); - if ( wsResult == SOCKET_ERROR ) - return 0; + ok_( __FILE__, line )( wsResult == expectedSize, "recv() returned %d.\n", wsResult );
port = checkSpHeader_( line, &request.spHeader, expectedSize ); checkGameMessage_( line, &request.request, expectedFromId, expectedToId );
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=149468
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
dplayx: dplayx.c:2912: Test failed: got flags 0.
This merge request was approved by Alistair Leslie-Hughes.