From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/dplay.c | 76 +++++++++++++++++++++++++++++++++++ dlls/dplayx/dplayx_messages.h | 11 ++++- dlls/dplayx/tests/dplayx.c | 12 +++--- 3 files changed, 91 insertions(+), 8 deletions(-)
diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index 47aa0dd0ea9..b24696060fd 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -427,6 +427,29 @@ static DWORD DP_CopyCreatePlayerOrGroup( DPMSG_GENERIC *genericDst, DPMSG_GENERI return offset; }
+static DWORD DP_CopySetPlayerOrGroupData( DPMSG_GENERIC *genericDst, DPMSG_GENERIC *genericSrc, + DWORD genericSize, BOOL ansi ) +{ + DPMSG_SETPLAYERORGROUPDATA *src = (DPMSG_SETPLAYERORGROUPDATA *) genericSrc; + DPMSG_SETPLAYERORGROUPDATA *dst = (DPMSG_SETPLAYERORGROUPDATA *) genericDst; + DWORD offset = sizeof( DPMSG_SETPLAYERORGROUPDATA ); + + if ( dst ) + *dst = *src; + + if ( src->lpData ) + { + if ( dst ) + { + dst->lpData = (char *) dst + offset; + memcpy( dst->lpData, src->lpData, src->dwDataSize ); + } + offset += src->dwDataSize; + } + + return offset; +} + /* *lplpReply will be non NULL iff there is something to reply */ HRESULT DP_HandleMessage( IDirectPlayImpl *This, void *messageBody, DWORD dwMessageBodySize, void *messageHeader, WORD wCommandId, WORD wVersion, @@ -535,6 +558,59 @@ HRESULT DP_HandleMessage( IDirectPlayImpl *This, void *messageBody, DP_MSG_ReplyReceived( This, wCommandId, messageBody, dwMessageBodySize, messageHeader ); break;
+ case DPMSGCMD_GROUPDATACHANGED: { + DPMSG_SETPLAYERORGROUPDATA setPlayerOrGroupDataMsg; + DPSP_MSG_GROUPDATACHANGED *msg; + struct GroupData *group; + HRESULT hr; + void *data; + + if( dwMessageBodySize < sizeof( DPSP_MSG_GROUPDATACHANGED ) ) + return DPERR_GENERIC; + msg = (DPSP_MSG_GROUPDATACHANGED *)messageBody; + + if( dwMessageBodySize < msg->dataOffset ) + return DPERR_GENERIC; + if( dwMessageBodySize - msg->dataOffset < msg->dataSize ) + return DPERR_GENERIC; + data = (char *)messageBody + msg->dataOffset; + + EnterCriticalSection( &This->lock ); + + if( !This->dp2->bConnectionOpen ) + { + LeaveCriticalSection( &This->lock ); + return DP_OK; + } + + group = DP_FindAnyGroup( This, msg->groupId ); + if( !group ) + { + LeaveCriticalSection( &This->lock ); + return DPERR_GENERIC; + } + + DP_SetGroupData( group, DPSET_REMOTE, data, msg->dataSize ); + + setPlayerOrGroupDataMsg.dwType = DPSYS_SETPLAYERORGROUPDATA; + setPlayerOrGroupDataMsg.dwPlayerType = DPPLAYERTYPE_GROUP; + setPlayerOrGroupDataMsg.dpId = msg->groupId; + setPlayerOrGroupDataMsg.lpData = data; + setPlayerOrGroupDataMsg.dwDataSize = msg->dataSize; + + hr = DP_QueueMessage( This, DPID_SYSMSG, DPID_ALLPLAYERS, 0, &setPlayerOrGroupDataMsg, + DP_CopySetPlayerOrGroupData, 0 ); + if ( FAILED( hr ) ) + { + LeaveCriticalSection( &This->lock ); + return hr; + } + + LeaveCriticalSection( &This->lock ); + + break; + } + case DPMSGCMD_JUSTENVELOPE: TRACE( "GOT THE SELF MESSAGE: %p -> 0x%08lx\n", messageHeader, ((const DWORD *)messageHeader)[1] ); NS_SetLocalAddr( This->dp2->lpNameServerData, messageHeader, 20 ); diff --git a/dlls/dplayx/dplayx_messages.h b/dlls/dplayx/dplayx_messages.h index 5b6ce52663f..9615effd936 100644 --- a/dlls/dplayx/dplayx_messages.h +++ b/dlls/dplayx/dplayx_messages.h @@ -107,7 +107,7 @@ typedef struct #define DPMSGCMD_DELETEGROUP 12 #define DPMSGCMD_ADDPLAYERTOGROUP 13
-#define DPMSGCMD_ENUMGROUPS 17 +#define DPMSGCMD_GROUPDATACHANGED 17
#define DPMSGCMD_FORWARDADDPLAYER 19
@@ -244,6 +244,15 @@ typedef struct DWORD passwordOffset; } DPSP_MSG_ADDPLAYERTOGROUP;
+typedef struct +{ + DPMSG_SENDENVELOPE envelope; + DPID toId; + DPID groupId; + DWORD dataSize; + DWORD dataOffset; +} DPSP_MSG_GROUPDATACHANGED; + typedef struct tagDPMSG_FORWARDADDPLAYER { DPMSG_SENDENVELOPE envelope; diff --git a/dlls/dplayx/tests/dplayx.c b/dlls/dplayx/tests/dplayx.c index c2ebb66b2ab..b70b47846c3 100644 --- a/dlls/dplayx/tests/dplayx.c +++ b/dlls/dplayx/tests/dplayx.c @@ -9194,9 +9194,7 @@ static DPID checkSetPlayerOrGroupDataMessage_( int line, IDirectPlay4 *dp, DWORD 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_SETPLAYERORGROUPDATA *) msgData; @@ -9258,18 +9256,18 @@ static void test_GROUPDATACHANGED(void) sendGroupDataChanged( sendSock, 2349, 0x5e7, expectedGroupData, sizeof( expectedGroupData ) );
waitResult = WaitForSingleObject( event, 2000 ); - todo_wine ok( waitResult == WAIT_OBJECT_0, "message wait returned %lu\n", waitResult ); + ok( waitResult == WAIT_OBJECT_0, "message wait returned %lu\n", waitResult );
dpid = checkSetPlayerOrGroupDataMessage( dp, DPPLAYERTYPE_GROUP, 0x5e7, expectedGroupData, sizeof( expectedGroupData ) ); - todo_wine ok( dpid == 0x11223344, "got destination id %#lx.\n", dpid ); + ok( dpid == 0x11223344, "got destination id %#lx.\n", dpid );
memset( groupData, 0xcc, sizeof( groupData ) ); groupDataSize = sizeof( groupData ); hr = IDirectPlayX_GetGroupData( dp, 0x5e7, groupData, &groupDataSize, DPGET_REMOTE ); ok( hr == DP_OK, "got hr %#lx.\n", hr ); - todo_wine ok( groupDataSize == sizeof( expectedGroupData ), "got group data size %lu.\n", groupDataSize ); - todo_wine ok( !memcmp( groupData, expectedGroupData, sizeof( expectedGroupData ) ), "group data didn't match.\n" ); + ok( groupDataSize == sizeof( expectedGroupData ), "got group data size %lu.\n", groupDataSize ); + ok( !memcmp( groupData, expectedGroupData, sizeof( expectedGroupData ) ), "group data didn't match.\n" );
checkNoMorePlayerMessages( dp );