Ignore:
Timestamp:
Mar 14, 2001, 12:13:28 AM (24 years ago)
Author:
hugh
Message:

Synced with WINE

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:05 hugh Exp $
     1// $Id: dplayx_messages.cpp,v 1.4 2001-03-13 23:13:27 hugh Exp $
    22/* DirectPlay & DirectPlayLobby messaging implementation
    33 *
     
    2424#include "dplayx_global.h"
    2525
    26 DEFAULT_DEBUG_CHANNEL(dplay)
     26DEFAULT_DEBUG_CHANNEL(dplay);
    2727
    2828#undef  debugstr_guid
     
    3939
    4040static DWORD CALLBACK DPL_MSG_ThreadMain( LPVOID lpContext );
     41static LPVOID DP_MSG_ExpectReply( IDirectPlay2AImpl* This, LPDPSP_SENDDATA data,
     42                                  DWORD dwWaitTime, WORD wReplyCommandId,
     43                                  LPVOID* lplpReplyMsg, LPDWORD lpdwMsgBodySize );
    4144
    4245/* Create the message reception thread to allow the application to receive
     
    133136  {
    134137    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 );
    142139  }
    143140
     
    149146}
    150147
     148/* DP messageing stuff */
     149static HANDLE DP_MSG_BuildAndLinkReplyStruct( IDirectPlay2Impl* This,
     150                                              LPDP_MSG_REPLY_STRUCT_LIST lpReplyStructList,
     151                                              WORD wReplyCommandId );
     152static LPVOID DP_MSG_CleanReplyStruct( LPDP_MSG_REPLY_STRUCT_LIST lpReplyStructList,
     153                                       LPVOID* lplpReplyMsg, LPDWORD lpdwMsgBodySize );
     154
     155
     156static
     157HANDLE 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
     173static
     174LPVOID 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}
    151184
    152185HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
     
    156189  LPDPMSG_REQUESTNEWPLAYERID lpMsgBody;
    157190  DWORD                      dwMsgSize;
    158   DWORD                      dwWaitReturn;
    159191  HRESULT                    hr = DP_OK;
    160192
     
    166198                                             This->dp2->spData.dwSPHeaderSize );
    167199
     200  /* Compose dplay message envelope */
    168201  lpMsgBody->envelope.dwMagic    = DPMSGMAGIC_DPLAYMSG;
    169202  lpMsgBody->envelope.wCommandId = DPMSGCMD_REQUESTNEWPLAYERID;
    170203  lpMsgBody->envelope.wVersion   = DPMSGVER_DP6;
    171204
     205  /* Compose the body of the message */
    172206  lpMsgBody->dwFlags = dwFlags;
    173207
    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 */
    180209  {
    181210    DPSP_SENDDATA data;
     
    189218    data.lpISP          = This->dp2->spData.lpISP;
    190219
    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
    215229
    216230  /* Need to examine the data and extract the new player id */
     
    219233    LPCDPMSG_NEWPLAYERIDREPLY lpcReply;
    220234
    221     lpcReply = (LPCDPMSG_NEWPLAYERIDREPLY)This->dp2->lpMsgReceived;
     235    lpcReply = (LPCDPMSG_NEWPLAYERIDREPLY)lpMsg;
    222236
    223237    *lpdpidAllocatedId = lpcReply->dpidNewPlayerId;
     
    227241    /* FIXME: I think that the rest of the message has something to do
    228242     *        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?
    229247     */
     248
     249    HeapFree( GetProcessHeap(), 0, lpMsg );
     250  }
     251
     252  return hr;
     253}
     254
     255HRESULT 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
    230274#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  }
    235297#endif
    236298
    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" );
    239354  }
    240355
     
    242357}
    243358
    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 */
     365static
     366LPVOID 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 );
    261382
    262383  if( FAILED(hr) )
    263384  {
    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 */
     405void 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
     445void 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.