Changeset 5311 for trunk/src/DPlayX/dplayx_messages.cpp
- Timestamp:
- Mar 14, 2001, 12:13:28 AM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/DPlayX/dplayx_messages.cpp
r4446 r5311 1 // $Id: dplayx_messages.cpp,v 1. 3 2000-10-06 19:49:05hugh Exp $1 // $Id: dplayx_messages.cpp,v 1.4 2001-03-13 23:13:27 hugh Exp $ 2 2 /* DirectPlay & DirectPlayLobby messaging implementation 3 3 * … … 24 24 #include "dplayx_global.h" 25 25 26 DEFAULT_DEBUG_CHANNEL(dplay) 26 DEFAULT_DEBUG_CHANNEL(dplay); 27 27 28 28 #undef debugstr_guid … … 39 39 40 40 static DWORD CALLBACK DPL_MSG_ThreadMain( LPVOID lpContext ); 41 static LPVOID DP_MSG_ExpectReply( IDirectPlay2AImpl* This, LPDPSP_SENDDATA data, 42 DWORD dwWaitTime, WORD wReplyCommandId, 43 LPVOID* lplpReplyMsg, LPDWORD lpdwMsgBodySize ); 41 44 42 45 /* Create the message reception thread to allow the application to receive … … 133 136 { 134 137 MSG lobbyMsg; 135 #ifdef STRICT 136 HANDLE hNullHandle = NULL; 137 #else 138 HANDLE hNullHandle = 0; 139 #endif 140 141 GetMessageW( &lobbyMsg, hNullHandle, 0, 0 ); 138 GetMessageW( &lobbyMsg, 0, 0, 0 ); 142 139 } 143 140 … … 149 146 } 150 147 148 /* DP messageing stuff */ 149 static HANDLE DP_MSG_BuildAndLinkReplyStruct( IDirectPlay2Impl* This, 150 LPDP_MSG_REPLY_STRUCT_LIST lpReplyStructList, 151 WORD wReplyCommandId ); 152 static LPVOID DP_MSG_CleanReplyStruct( LPDP_MSG_REPLY_STRUCT_LIST lpReplyStructList, 153 LPVOID* lplpReplyMsg, LPDWORD lpdwMsgBodySize ); 154 155 156 static 157 HANDLE DP_MSG_BuildAndLinkReplyStruct( IDirectPlay2Impl* This, 158 LPDP_MSG_REPLY_STRUCT_LIST lpReplyStructList, WORD wReplyCommandId ) 159 { 160 lpReplyStructList->replyExpected.hReceipt = CreateEventA( NULL, FALSE, FALSE, NULL ); 161 lpReplyStructList->replyExpected.wExpectedReply = wReplyCommandId; 162 lpReplyStructList->replyExpected.lpReplyMsg = NULL; 163 lpReplyStructList->replyExpected.dwMsgBodySize = 0; 164 165 /* Insert into the message queue while locked */ 166 EnterCriticalSection( &This->unk->DP_lock ); 167 DPQ_INSERT( This->dp2->replysExpected, lpReplyStructList, replysExpected ); 168 LeaveCriticalSection( &This->unk->DP_lock ); 169 170 return lpReplyStructList->replyExpected.hReceipt; 171 } 172 173 static 174 LPVOID DP_MSG_CleanReplyStruct( LPDP_MSG_REPLY_STRUCT_LIST lpReplyStructList, 175 LPVOID* lplpReplyMsg, LPDWORD lpdwMsgBodySize ) 176 { 177 CloseHandle( lpReplyStructList->replyExpected.hReceipt ); 178 179 *lplpReplyMsg = lpReplyStructList->replyExpected.lpReplyMsg; 180 *lpdwMsgBodySize = lpReplyStructList->replyExpected.dwMsgBodySize; 181 182 return lpReplyStructList->replyExpected.lpReplyMsg; 183 } 151 184 152 185 HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags, … … 156 189 LPDPMSG_REQUESTNEWPLAYERID lpMsgBody; 157 190 DWORD dwMsgSize; 158 DWORD dwWaitReturn;159 191 HRESULT hr = DP_OK; 160 192 … … 166 198 This->dp2->spData.dwSPHeaderSize ); 167 199 200 /* Compose dplay message envelope */ 168 201 lpMsgBody->envelope.dwMagic = DPMSGMAGIC_DPLAYMSG; 169 202 lpMsgBody->envelope.wCommandId = DPMSGCMD_REQUESTNEWPLAYERID; 170 203 lpMsgBody->envelope.wVersion = DPMSGVER_DP6; 171 204 205 /* Compose the body of the message */ 172 206 lpMsgBody->dwFlags = dwFlags; 173 207 174 /* FIXME: Need to have a more advanced queuing system as this needs to 175 * block on send until we get response. Otherwise we need to be 176 * able to ensure we can pick out the exact response. Of course, 177 * with something as non critical as this, would it matter? The 178 * id has been effectively reserved for this session... 179 */ 208 /* Send the message */ 180 209 { 181 210 DPSP_SENDDATA data; … … 189 218 data.lpISP = This->dp2->spData.lpISP; 190 219 191 /* Setup for receipt */ 192 This->dp2->hMsgReceipt = CreateEventA( NULL, FALSE, FALSE, NULL ); 193 194 TRACE( "Sending request for player id\n" ); 195 196 hr = (*This->dp2->spData.lpCB->Send)( &data ); 197 198 if( FAILED(hr) ) 199 { 200 ERR( "Request for new playerID send failed: %s\n", 201 DPLAYX_HresultToString( hr ) ); 202 return DPERR_NOCONNECTION; 203 } 204 } 205 206 dwWaitReturn = WaitForSingleObject( This->dp2->hMsgReceipt, 30000 ); 207 if( dwWaitReturn != WAIT_OBJECT_0 ) 208 { 209 ERR( "Wait failed 0x%08lx\n", dwWaitReturn ); 210 hr = DPERR_TIMEOUT; 211 } 212 213 CloseHandle( This->dp2->hMsgReceipt ); 214 This->dp2->hMsgReceipt = 0; 220 TRACE( "Asking for player id w/ dwFlags 0x%08lx\n", 221 lpMsgBody->dwFlags ); 222 223 224 DP_MSG_ExpectReply( This, &data, DPMSG_DEFAULT_WAIT_TIME, DPMSGCMD_NEWPLAYERIDREPLY, 225 &lpMsg, &dwMsgSize ); 226 227 } 228 215 229 216 230 /* Need to examine the data and extract the new player id */ … … 219 233 LPCDPMSG_NEWPLAYERIDREPLY lpcReply; 220 234 221 lpcReply = (LPCDPMSG_NEWPLAYERIDREPLY) This->dp2->lpMsgReceived;235 lpcReply = (LPCDPMSG_NEWPLAYERIDREPLY)lpMsg; 222 236 223 237 *lpdpidAllocatedId = lpcReply->dpidNewPlayerId; … … 227 241 /* FIXME: I think that the rest of the message has something to do 228 242 * with remote data for the player that perhaps I need to setup. 243 * However, with the information that is passed, all that it could 244 * be used for is a standardized intialization value, which I'm 245 * guessing we can do without. Unless the message content is the same 246 * for several different messages? 229 247 */ 248 249 HeapFree( GetProcessHeap(), 0, lpMsg ); 250 } 251 252 return hr; 253 } 254 255 HRESULT DP_MSG_ForwardPlayerCreation( IDirectPlay2AImpl* This, DPID dpidServer ) 256 { 257 LPVOID lpMsg; 258 LPDPMSG_FORWARDADDPLAYER lpMsgBody; 259 DWORD dwMsgSize; 260 HRESULT hr = DP_OK; 261 262 dwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpMsgBody ); 263 264 lpMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwMsgSize ); 265 266 lpMsgBody = (LPDPMSG_FORWARDADDPLAYER)( (BYTE*)lpMsg + 267 This->dp2->spData.dwSPHeaderSize ); 268 269 /* Compose dplay message envelope */ 270 lpMsgBody->envelope.dwMagic = DPMSGMAGIC_DPLAYMSG; 271 lpMsgBody->envelope.wCommandId = DPMSGCMD_FORWARDADDPLAYER; 272 lpMsgBody->envelope.wVersion = DPMSGVER_DP6; 273 230 274 #if 0 231 /* Set the passed service provider data */ 232 IDirectPlaySP_SetSPData( This->dp2->spData.lpISP, data, 233 msgsize, DPSET_REMOTE ); 234 275 { 276 LPBYTE lpPData; 277 DWORD dwDataSize; 278 279 /* SP Player remote data needs to be propagated at some point - is this the point? */ 280 IDirectPlaySP_GetSPPlayerData( This->dp2->spData.lpISP, dpidServer, (LPVOID*)&lpPData, &dwDataSize, DPSET_REMOTE ); 281 282 ERR( "Player Data size is 0x%08lx\n" 283 "[%02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x]\n" 284 "[%02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x]\n", 285 286 dwDataSize, 287 lpPData[0], lpPData[1], lpPData[2], lpPData[3], lpPData[4], 288 lpPData[5], lpPData[6], lpPData[7], lpPData[8], lpPData[9], 289 lpPData[10], lpPData[11], lpPData[12], lpPData[13], lpPData[14], 290 lpPData[15], lpPData[16], lpPData[17], lpPData[18], lpPData[19], 291 lpPData[20], lpPData[21], lpPData[22], lpPData[23], lpPData[24], 292 lpPData[25], lpPData[26], lpPData[27], lpPData[28], lpPData[29], 293 lpPData[30], lpPData[31] 294 ); 295 DebugBreak(); 296 } 235 297 #endif 236 298 237 HeapFree( GetProcessHeap(), 0, This->dp2->lpMsgReceived ); 238 This->dp2->lpMsgReceived = NULL; 299 /* Compose body of message */ 300 lpMsgBody->dpidAppServer = dpidServer; 301 lpMsgBody->unknown2[0] = 0x0; 302 lpMsgBody->unknown2[1] = 0x1c; 303 lpMsgBody->unknown2[2] = 0x6c; 304 lpMsgBody->unknown2[3] = 0x50; 305 lpMsgBody->unknown2[4] = 0x9; 306 307 lpMsgBody->dpidAppServer2 = dpidServer; 308 lpMsgBody->unknown3[0] = 0x0; 309 lpMsgBody->unknown3[0] = 0x0; 310 lpMsgBody->unknown3[0] = 0x20; 311 lpMsgBody->unknown3[0] = 0x0; 312 lpMsgBody->unknown3[0] = 0x0; 313 314 lpMsgBody->dpidAppServer3 = dpidServer; 315 lpMsgBody->unknown4[0] = 0x30; 316 lpMsgBody->unknown4[1] = 0xb; 317 lpMsgBody->unknown4[2] = 0x0; 318 lpMsgBody->unknown4[3] = 0x1e090002; 319 lpMsgBody->unknown4[4] = 0x0; 320 lpMsgBody->unknown4[5] = 0x0; 321 lpMsgBody->unknown4[6] = 0x0; 322 lpMsgBody->unknown4[7] = 0x32090002; 323 lpMsgBody->unknown4[8] = 0x0; 324 lpMsgBody->unknown4[9] = 0x0; 325 lpMsgBody->unknown4[10] = 0x0; 326 lpMsgBody->unknown4[11] = 0x0; 327 lpMsgBody->unknown4[12] = 0x0; 328 329 lpMsgBody->unknown5[0] = 0x0; 330 lpMsgBody->unknown5[1] = 0x0; 331 332 /* Send the message */ 333 { 334 DPSP_SENDDATA data; 335 336 data.dwFlags = DPSEND_GUARANTEED; 337 data.idPlayerTo = 0; /* Name server */ 338 data.idPlayerFrom = dpidServer; /* Sending from session server */ 339 data.lpMessage = lpMsg; 340 data.dwMessageSize = dwMsgSize; 341 data.bSystemMessage = TRUE; /* Allow reply to be sent */ 342 data.lpISP = This->dp2->spData.lpISP; 343 344 lpMsg = DP_MSG_ExpectReply( This, &data, 345 DPMSG_WAIT_60_SECS, 346 DPMSGCMD_GETNAMETABLEREPLY, 347 &lpMsg, &dwMsgSize ); 348 } 349 350 /* Need to examine the data and extract the new player id */ 351 if( lpMsg != NULL ) 352 { 353 FIXME( "Name Table reply received: stub\n" ); 239 354 } 240 355 … … 242 357 } 243 358 244 245 /* This function seems to cause a trap in the SP. It would seem unnecessary */ 246 /* FIXME: Remove this method if not required */ 247 HRESULT DP_MSG_OpenStream( IDirectPlay2AImpl* This ) 248 { 249 HRESULT hr; 250 DPSP_SENDDATA data; 251 252 data.dwFlags = DPSEND_OPENSTREAM; 253 data.idPlayerTo = 0; /* Name server */ 254 data.idPlayerFrom = 0; /* From DP itself */ 255 data.lpMessage = NULL; 256 data.dwMessageSize = This->dp2->spData.dwSPHeaderSize; 257 data.bSystemMessage = FALSE; /* FIXME? */ 258 data.lpISP = This->dp2->spData.lpISP; 259 260 hr = (*This->dp2->spData.lpCB->Send)( &data ); 359 /* Queue up a structure indicating that we want a reply of type wReplyCommandId. DPlay does 360 * not seem to offer any way of uniquely differentiating between replies of the same type 361 * relative to the request sent. There is an implicit assumption that there will be no 362 * ordering issues on sends and receives from the opposite machine. No wonder MS is not 363 * a networking company. 364 */ 365 static 366 LPVOID DP_MSG_ExpectReply( IDirectPlay2AImpl* This, LPDPSP_SENDDATA lpData, 367 DWORD dwWaitTime, WORD wReplyCommandId, 368 LPVOID* lplpReplyMsg, LPDWORD lpdwMsgBodySize ) 369 { 370 HRESULT hr; 371 HANDLE hMsgReceipt; 372 DP_MSG_REPLY_STRUCT_LIST replyStructList; 373 DWORD dwWaitReturn; 374 375 /* Setup for receipt */ 376 hMsgReceipt = DP_MSG_BuildAndLinkReplyStruct( This, &replyStructList, 377 wReplyCommandId ); 378 379 TRACE( "Sending msg and expecting cmd %u in reply within %lu ticks\n", 380 wReplyCommandId, dwWaitTime ); 381 hr = (*This->dp2->spData.lpCB->Send)( lpData ); 261 382 262 383 if( FAILED(hr) ) 263 384 { 264 ERR( "Request for open stream send failed: %s\n", 265 DPLAYX_HresultToString( hr ) ); 266 } 267 268 /* FIXME: hack to give some time for channel to open */ 269 SleepEx( 1000 /* 1 sec */, FALSE ); 270 271 return hr; 272 } 385 ERR( "Request for new playerID send failed: %s\n", 386 DPLAYX_HresultToString( hr ) ); 387 return NULL; 388 } 389 390 dwWaitReturn = WaitForSingleObject( hMsgReceipt, dwWaitTime ); 391 if( dwWaitReturn != WAIT_OBJECT_0 ) 392 { 393 ERR( "Wait failed 0x%08lx\n", dwWaitReturn ); 394 return NULL; 395 } 396 397 /* Clean Up */ 398 return DP_MSG_CleanReplyStruct( &replyStructList, lplpReplyMsg, lpdwMsgBodySize ); 399 } 400 401 /* Determine if there is a matching request for this incomming message and then copy 402 * all important data. It is quite silly to have to copy the message, but the documents 403 * indicate that a copy is taken. Silly really. 404 */ 405 void DP_MSG_ReplyReceived( IDirectPlay2AImpl* This, WORD wCommandId, 406 LPCVOID lpcMsgBody, DWORD dwMsgBodySize ) 407 { 408 LPDP_MSG_REPLY_STRUCT_LIST lpReplyList; 409 410 #if 0 411 if( wCommandId == DPMSGCMD_FORWARDADDPLAYER ) 412 { 413 DebugBreak(); 414 } 415 #endif 416 417 /* Find, and immediately remove (to avoid double triggering), the appropriate entry. Call locked to 418 * avoid problems. 419 */ 420 EnterCriticalSection( &This->unk->DP_lock ); 421 DPQ_REMOVE_ENTRY( This->dp2->replysExpected, replysExpected, replyExpected.wExpectedReply,\ 422 ==, wCommandId, lpReplyList ); 423 LeaveCriticalSection( &This->unk->DP_lock ); 424 425 if( lpReplyList != NULL ) 426 { 427 lpReplyList->replyExpected.dwMsgBodySize = dwMsgBodySize; 428 lpReplyList->replyExpected.lpReplyMsg = HeapAlloc( GetProcessHeap(), 429 HEAP_ZERO_MEMORY, 430 dwMsgBodySize ); 431 CopyMemory( lpReplyList->replyExpected.lpReplyMsg, 432 lpcMsgBody, dwMsgBodySize ); 433 434 /* Signal the thread which sent the message that it has a reply */ 435 SetEvent( lpReplyList->replyExpected.hReceipt ); 436 } 437 else 438 { 439 ERR( "No receipt event set - only expecting in reply mode\n" ); 440 DebugBreak(); 441 } 442 443 } 444 445 void DP_MSG_ErrorReceived( IDirectPlay2AImpl* This, WORD wCommandId, 446 LPCVOID lpMsgBody, DWORD dwMsgBodySize ) 447 { 448 LPCDPMSG_FORWARDADDPLAYERNACK lpcErrorMsg; 449 450 lpcErrorMsg = (LPCDPMSG_FORWARDADDPLAYERNACK)lpMsgBody; 451 452 ERR( "Received error message %u. Error is %s\n", 453 wCommandId, DPLAYX_HresultToString( lpcErrorMsg->errorCode) ); 454 DebugBreak(); 455 } 456
Note:
See TracChangeset
for help on using the changeset viewer.