📄 dplayx_messages.c
字号:
return hr;
}
HRESULT DP_MSG_ForwardPlayerCreation( IDirectPlay2AImpl* This, DPID dpidServer )
{
LPVOID lpMsg;
LPDPMSG_FORWARDADDPLAYER lpMsgBody;
DWORD dwMsgSize;
HRESULT hr = DP_OK;
dwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpMsgBody );
lpMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwMsgSize );
lpMsgBody = (LPDPMSG_FORWARDADDPLAYER)( (BYTE*)lpMsg +
This->dp2->spData.dwSPHeaderSize );
/* Compose dplay message envelope */
lpMsgBody->envelope.dwMagic = DPMSGMAGIC_DPLAYMSG;
lpMsgBody->envelope.wCommandId = DPMSGCMD_FORWARDADDPLAYER;
lpMsgBody->envelope.wVersion = DPMSGVER_DP6;
#if 0
{
LPBYTE lpPData;
DWORD dwDataSize;
/* SP Player remote data needs to be propagated at some point - is this the point? */
IDirectPlaySP_GetSPPlayerData( This->dp2->spData.lpISP, 0, (LPVOID*)&lpPData, &dwDataSize, DPSET_REMOTE );
ERR( "Player Data size is 0x%08lx\n"
"[%02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x]\n"
"[%02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x]\n",
dwDataSize,
lpPData[0], lpPData[1], lpPData[2], lpPData[3], lpPData[4],
lpPData[5], lpPData[6], lpPData[7], lpPData[8], lpPData[9],
lpPData[10], lpPData[11], lpPData[12], lpPData[13], lpPData[14],
lpPData[15], lpPData[16], lpPData[17], lpPData[18], lpPData[19],
lpPData[20], lpPData[21], lpPData[22], lpPData[23], lpPData[24],
lpPData[25], lpPData[26], lpPData[27], lpPData[28], lpPData[29],
lpPData[30], lpPData[31]
);
DebugBreak();
}
#endif
/* Compose body of message */
lpMsgBody->dpidAppServer = dpidServer;
lpMsgBody->unknown2[0] = 0x0;
lpMsgBody->unknown2[1] = 0x1c;
lpMsgBody->unknown2[2] = 0x6c;
lpMsgBody->unknown2[3] = 0x50;
lpMsgBody->unknown2[4] = 0x9;
lpMsgBody->dpidAppServer2 = dpidServer;
lpMsgBody->unknown3[0] = 0x0;
lpMsgBody->unknown3[0] = 0x0;
lpMsgBody->unknown3[0] = 0x20;
lpMsgBody->unknown3[0] = 0x0;
lpMsgBody->unknown3[0] = 0x0;
lpMsgBody->dpidAppServer3 = dpidServer;
lpMsgBody->unknown4[0] = 0x30;
lpMsgBody->unknown4[1] = 0xb;
lpMsgBody->unknown4[2] = 0x0;
lpMsgBody->unknown4[3] = NS_GetNsMagic( This->dp2->lpNameServerData ) -
0x02000000;
TRACE( "Setting first magic to 0x%08lx\n", lpMsgBody->unknown4[3] );
lpMsgBody->unknown4[4] = 0x0;
lpMsgBody->unknown4[5] = 0x0;
lpMsgBody->unknown4[6] = 0x0;
#if 0
lpMsgBody->unknown4[7] = NS_GetOtherMagic( This->dp2->lpNameServerData )
#else
lpMsgBody->unknown4[7] = NS_GetNsMagic( This->dp2->lpNameServerData );
#endif
TRACE( "Setting second magic to 0x%08lx\n", lpMsgBody->unknown4[7] );
lpMsgBody->unknown4[8] = 0x0;
lpMsgBody->unknown4[9] = 0x0;
lpMsgBody->unknown4[10] = 0x0;
lpMsgBody->unknown4[11] = 0x0;
lpMsgBody->unknown5[0] = 0x0;
lpMsgBody->unknown5[1] = 0x0;
/* Send the message */
{
DPSP_SENDDATA data;
data.dwFlags = DPSEND_GUARANTEED;
data.idPlayerTo = 0; /* Name server */
data.idPlayerFrom = dpidServer; /* Sending from session server */
data.lpMessage = lpMsg;
data.dwMessageSize = dwMsgSize;
data.bSystemMessage = TRUE; /* Allow reply to be sent */
data.lpISP = This->dp2->spData.lpISP;
TRACE( "Sending forward player request with 0x%08lx\n", dpidServer );
lpMsg = DP_MSG_ExpectReply( This, &data,
DPMSG_WAIT_60_SECS,
DPMSGCMD_GETNAMETABLEREPLY,
&lpMsg, &dwMsgSize );
}
/* Need to examine the data and extract the new player id */
if( lpMsg != NULL )
{
FIXME( "Name Table reply received: stub\n" );
}
return hr;
}
/* Queue up a structure indicating that we want a reply of type wReplyCommandId. DPlay does
* not seem to offer any way of uniquely differentiating between replies of the same type
* relative to the request sent. There is an implicit assumption that there will be no
* ordering issues on sends and receives from the opposite machine. No wonder MS is not
* a networking company.
*/
static
LPVOID DP_MSG_ExpectReply( IDirectPlay2AImpl* This, LPDPSP_SENDDATA lpData,
DWORD dwWaitTime, WORD wReplyCommandId,
LPVOID* lplpReplyMsg, LPDWORD lpdwMsgBodySize )
{
HRESULT hr;
HANDLE hMsgReceipt;
DP_MSG_REPLY_STRUCT_LIST replyStructList;
DWORD dwWaitReturn;
/* Setup for receipt */
hMsgReceipt = DP_MSG_BuildAndLinkReplyStruct( This, &replyStructList,
wReplyCommandId );
TRACE( "Sending msg and expecting cmd %u in reply within %lu ticks\n",
wReplyCommandId, dwWaitTime );
hr = (*This->dp2->spData.lpCB->Send)( lpData );
if( FAILED(hr) )
{
ERR( "Send failed: %s\n", DPLAYX_HresultToString( hr ) );
return NULL;
}
/* The reply message will trigger the hMsgReceipt event effectively switching
* control back to this thread. See DP_MSG_ReplyReceived.
*/
dwWaitReturn = WaitForSingleObject( hMsgReceipt, dwWaitTime );
if( dwWaitReturn != WAIT_OBJECT_0 )
{
ERR( "Wait failed 0x%08lx\n", dwWaitReturn );
return NULL;
}
/* Clean Up */
return DP_MSG_CleanReplyStruct( &replyStructList, lplpReplyMsg, lpdwMsgBodySize );
}
/* Determine if there is a matching request for this incoming message and then copy
* all important data. It is quite silly to have to copy the message, but the documents
* indicate that a copy is taken. Silly really.
*/
void DP_MSG_ReplyReceived( IDirectPlay2AImpl* This, WORD wCommandId,
LPCVOID lpcMsgBody, DWORD dwMsgBodySize )
{
LPDP_MSG_REPLY_STRUCT_LIST lpReplyList;
#if 0
if( wCommandId == DPMSGCMD_FORWARDADDPLAYER )
{
DebugBreak();
}
#endif
/* Find, and immediately remove (to avoid double triggering), the appropriate entry. Call locked to
* avoid problems.
*/
EnterCriticalSection( &This->unk->DP_lock );
DPQ_REMOVE_ENTRY( This->dp2->replysExpected, replysExpected, replyExpected.wExpectedReply,\
==, wCommandId, lpReplyList );
LeaveCriticalSection( &This->unk->DP_lock );
if( lpReplyList != NULL )
{
lpReplyList->replyExpected.dwMsgBodySize = dwMsgBodySize;
lpReplyList->replyExpected.lpReplyMsg = HeapAlloc( GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwMsgBodySize );
CopyMemory( lpReplyList->replyExpected.lpReplyMsg,
lpcMsgBody, dwMsgBodySize );
/* Signal the thread which sent the message that it has a reply */
SetEvent( lpReplyList->replyExpected.hReceipt );
}
else
{
ERR( "No receipt event set - only expecting in reply mode\n" );
DebugBreak();
}
}
void DP_MSG_ToSelf( IDirectPlay2AImpl* This, DPID dpidSelf )
{
LPVOID lpMsg;
LPDPMSG_SENDENVELOPE lpMsgBody;
DWORD dwMsgSize;
dwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpMsgBody );
lpMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwMsgSize );
lpMsgBody = (LPDPMSG_SENDENVELOPE)( (BYTE*)lpMsg +
This->dp2->spData.dwSPHeaderSize );
/* Compose dplay message envelope */
lpMsgBody->dwMagic = DPMSGMAGIC_DPLAYMSG;
lpMsgBody->wCommandId = DPMSGCMD_JUSTENVELOPE;
lpMsgBody->wVersion = DPMSGVER_DP6;
/* Send the message to ourselves */
{
DPSP_SENDDATA data;
data.dwFlags = 0;
data.idPlayerTo = dpidSelf; /* Sending to session server */
data.idPlayerFrom = 0; /* Sending from session server */
data.lpMessage = lpMsg;
data.dwMessageSize = dwMsgSize;
data.bSystemMessage = TRUE; /* Allow reply to be sent */
data.lpISP = This->dp2->spData.lpISP;
lpMsg = DP_MSG_ExpectReply( This, &data,
DPMSG_WAIT_5_SECS,
DPMSGCMD_JUSTENVELOPE,
&lpMsg, &dwMsgSize );
}
}
void DP_MSG_ErrorReceived( IDirectPlay2AImpl* This, WORD wCommandId,
LPCVOID lpMsgBody, DWORD dwMsgBodySize )
{
LPCDPMSG_FORWARDADDPLAYERNACK lpcErrorMsg;
lpcErrorMsg = (LPCDPMSG_FORWARDADDPLAYERNACK)lpMsgBody;
ERR( "Received error message %u. Error is %s\n",
wCommandId, DPLAYX_HresultToString( lpcErrorMsg->errorCode) );
DebugBreak();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -