~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/dplayx/dplayx_messages.c

Version: ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  1 /* DirectPlay & DirectPlayLobby messaging implementation
  2  *
  3  * Copyright 2000,2001 - Peter Hunnisett
  4  *
  5  * This library is free software; you can redistribute it and/or
  6  * modify it under the terms of the GNU Lesser General Public
  7  * License as published by the Free Software Foundation; either
  8  * version 2.1 of the License, or (at your option) any later version.
  9  *
 10  * This library is distributed in the hope that it will be useful,
 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  * Lesser General Public License for more details.
 14  *
 15  * You should have received a copy of the GNU Lesser General Public
 16  * License along with this library; if not, write to the Free Software
 17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 18  *
 19  * NOTES
 20  *  o Messaging interface required for both DirectPlay and DirectPlayLobby.
 21  */
 22 
 23 #include <stdarg.h>
 24 #include <string.h>
 25 #include "windef.h"
 26 #include "winbase.h"
 27 #include "wingdi.h"
 28 #include "winuser.h"
 29 #include "winerror.h"
 30 
 31 #include "dplayx_messages.h"
 32 #include "dplay_global.h"
 33 #include "dplayx_global.h"
 34 #include "name_server.h"
 35 #include "wine/debug.h"
 36 
 37 WINE_DEFAULT_DEBUG_CHANNEL(dplay);
 38 
 39 typedef struct tagMSGTHREADINFO
 40 {
 41   HANDLE hStart;
 42   HANDLE hDeath;
 43   HANDLE hSettingRead;
 44   HANDLE hNotifyEvent;
 45 } MSGTHREADINFO, *LPMSGTHREADINFO;
 46 
 47 static DWORD CALLBACK DPL_MSG_ThreadMain( LPVOID lpContext );
 48 static LPVOID DP_MSG_ExpectReply( IDirectPlay2AImpl* This, LPDPSP_SENDDATA data,
 49                                   DWORD dwWaitTime, WORD wReplyCommandId,
 50                                   LPVOID* lplpReplyMsg, LPDWORD lpdwMsgBodySize );
 51 
 52 
 53 /* Create the message reception thread to allow the application to receive
 54  * asynchronous message reception
 55  */
 56 DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
 57                                          HANDLE hDeath, HANDLE hConnRead )
 58 {
 59   DWORD           dwMsgThreadId;
 60   LPMSGTHREADINFO lpThreadInfo;
 61 
 62   lpThreadInfo = HeapAlloc( GetProcessHeap(), 0, sizeof( *lpThreadInfo ) );
 63   if( lpThreadInfo == NULL )
 64   {
 65     return 0;
 66   }
 67 
 68   /* The notify event may or may not exist. Depends if async comm or not */
 69   if( hNotifyEvent &&
 70       !DuplicateHandle( GetCurrentProcess(), hNotifyEvent,
 71                         GetCurrentProcess(), &lpThreadInfo->hNotifyEvent,
 72                         0, FALSE, DUPLICATE_SAME_ACCESS ) )
 73   {
 74     ERR( "Unable to duplicate event handle\n" );
 75     goto error;
 76   }
 77 
 78   /* These 3 handles don't need to be duplicated because we don't keep a
 79    * reference to them where they're created. They're created specifically
 80    * for the message thread
 81    */
 82   lpThreadInfo->hStart       = hStart;
 83   lpThreadInfo->hDeath       = hDeath;
 84   lpThreadInfo->hSettingRead = hConnRead;
 85 
 86   if( !CreateThread( NULL,                  /* Security attribs */
 87                      0,                     /* Stack */
 88                      DPL_MSG_ThreadMain,    /* Msg reception function */
 89                      lpThreadInfo,          /* Msg reception func parameter */
 90                      0,                     /* Flags */
 91                      &dwMsgThreadId         /* Updated with thread id */
 92                    )
 93     )
 94   {
 95     ERR( "Unable to create msg thread\n" );
 96     goto error;
 97   }
 98 
 99   /* FIXME: Should I be closing the handle to the thread or does that
100             terminate the thread? */
101 
102   return dwMsgThreadId;
103 
104 error:
105 
106   HeapFree( GetProcessHeap(), 0, lpThreadInfo );
107 
108   return 0;
109 }
110 
111 static DWORD CALLBACK DPL_MSG_ThreadMain( LPVOID lpContext )
112 {
113   LPMSGTHREADINFO lpThreadInfo = (LPMSGTHREADINFO)lpContext;
114   DWORD dwWaitResult;
115 
116   TRACE( "Msg thread created. Waiting on app startup\n" );
117 
118   /* Wait to ensure that the lobby application is started w/ 1 min timeout */
119   dwWaitResult = WaitForSingleObject( lpThreadInfo->hStart, 10000 /* 10 sec */ );
120   if( dwWaitResult == WAIT_TIMEOUT )
121   {
122     FIXME( "Should signal app/wait creation failure (0x%08x)\n", dwWaitResult );
123     goto end_of_thread;
124   }
125 
126   /* Close this handle as it's not needed anymore */
127   CloseHandle( lpThreadInfo->hStart );
128   lpThreadInfo->hStart = 0;
129 
130   /* Wait until the lobby knows what it is */
131   dwWaitResult = WaitForSingleObject( lpThreadInfo->hSettingRead, INFINITE );
132   if( dwWaitResult == WAIT_TIMEOUT )
133   {
134     ERR( "App Read connection setting timeout fail (0x%08x)\n", dwWaitResult );
135   }
136 
137   /* Close this handle as it's not needed anymore */
138   CloseHandle( lpThreadInfo->hSettingRead );
139   lpThreadInfo->hSettingRead = 0;
140 
141   TRACE( "App created && initialized starting main message reception loop\n" );
142 
143   for ( ;; )
144   {
145     MSG lobbyMsg;
146     GetMessageW( &lobbyMsg, 0, 0, 0 );
147   }
148 
149 end_of_thread:
150   TRACE( "Msg thread exiting!\n" );
151   HeapFree( GetProcessHeap(), 0, lpThreadInfo );
152 
153   return 0;
154 }
155 
156 /* DP messaging stuff */
157 static HANDLE DP_MSG_BuildAndLinkReplyStruct( IDirectPlay2Impl* This,
158                                               LPDP_MSG_REPLY_STRUCT_LIST lpReplyStructList,
159                                               WORD wReplyCommandId );
160 static LPVOID DP_MSG_CleanReplyStruct( LPDP_MSG_REPLY_STRUCT_LIST lpReplyStructList,
161                                        LPVOID* lplpReplyMsg, LPDWORD lpdwMsgBodySize );
162 
163 
164 static
165 HANDLE DP_MSG_BuildAndLinkReplyStruct( IDirectPlay2Impl* This,
166                                        LPDP_MSG_REPLY_STRUCT_LIST lpReplyStructList, WORD wReplyCommandId )
167 {
168   lpReplyStructList->replyExpected.hReceipt       = CreateEventW( NULL, FALSE, FALSE, NULL );
169   lpReplyStructList->replyExpected.wExpectedReply = wReplyCommandId;
170   lpReplyStructList->replyExpected.lpReplyMsg     = NULL;
171   lpReplyStructList->replyExpected.dwMsgBodySize  = 0;
172 
173   /* Insert into the message queue while locked */
174   EnterCriticalSection( &This->unk->DP_lock );
175     DPQ_INSERT( This->dp2->replysExpected, lpReplyStructList, replysExpected );
176   LeaveCriticalSection( &This->unk->DP_lock );
177 
178   return lpReplyStructList->replyExpected.hReceipt;
179 }
180 
181 static
182 LPVOID DP_MSG_CleanReplyStruct( LPDP_MSG_REPLY_STRUCT_LIST lpReplyStructList,
183                                 LPVOID* lplpReplyMsg, LPDWORD lpdwMsgBodySize  )
184 {
185   CloseHandle( lpReplyStructList->replyExpected.hReceipt );
186 
187   *lplpReplyMsg    = lpReplyStructList->replyExpected.lpReplyMsg;
188   *lpdwMsgBodySize = lpReplyStructList->replyExpected.dwMsgBodySize;
189 
190   return lpReplyStructList->replyExpected.lpReplyMsg;
191 }
192 
193 HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
194                                     LPDPID lpdpidAllocatedId )
195 {
196   LPVOID                     lpMsg;
197   LPDPMSG_REQUESTNEWPLAYERID lpMsgBody;
198   DWORD                      dwMsgSize;
199   HRESULT                    hr = DP_OK;
200 
201   dwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpMsgBody );
202 
203   lpMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwMsgSize );
204 
205   lpMsgBody = (LPDPMSG_REQUESTNEWPLAYERID)( (BYTE*)lpMsg +
206                                              This->dp2->spData.dwSPHeaderSize );
207 
208   /* Compose dplay message envelope */
209   lpMsgBody->envelope.dwMagic    = DPMSGMAGIC_DPLAYMSG;
210   lpMsgBody->envelope.wCommandId = DPMSGCMD_REQUESTNEWPLAYERID;
211   lpMsgBody->envelope.wVersion   = DPMSGVER_DP6;
212 
213   /* Compose the body of the message */
214   lpMsgBody->dwFlags = dwFlags;
215 
216   /* Send the message */
217   {
218     DPSP_SENDDATA data;
219 
220     data.dwFlags        = DPSEND_GUARANTEED;
221     data.idPlayerTo     = 0; /* Name server */
222     data.idPlayerFrom   = 0; /* Sending from DP */
223     data.lpMessage      = lpMsg;
224     data.dwMessageSize  = dwMsgSize;
225     data.bSystemMessage = TRUE; /* Allow reply to be sent */
226     data.lpISP          = This->dp2->spData.lpISP;
227 
228     TRACE( "Asking for player id w/ dwFlags 0x%08x\n",
229            lpMsgBody->dwFlags );
230 
231     DP_MSG_ExpectReply( This, &data, DPMSG_DEFAULT_WAIT_TIME, DPMSGCMD_NEWPLAYERIDREPLY,
232                         &lpMsg, &dwMsgSize );
233   }
234 
235   /* Need to examine the data and extract the new player id */
236   if( SUCCEEDED(hr) )
237   {
238     LPCDPMSG_NEWPLAYERIDREPLY lpcReply;
239 
240     lpcReply = (LPCDPMSG_NEWPLAYERIDREPLY)lpMsg;
241 
242     *lpdpidAllocatedId = lpcReply->dpidNewPlayerId;
243 
244     TRACE( "Received reply for id = 0x%08x\n", lpcReply->dpidNewPlayerId );
245 
246     /* FIXME: I think that the rest of the message has something to do
247      *        with remote data for the player that perhaps I need to setup.
248      *        However, with the information that is passed, all that it could
249      *        be used for is a standardized initialization value, which I'm
250      *        guessing we can do without. Unless the message content is the same
251      *        for several different messages?
252      */
253 
254     HeapFree( GetProcessHeap(), 0, lpMsg );
255   }
256 
257   return hr;
258 }
259 
260 HRESULT DP_MSG_ForwardPlayerCreation( IDirectPlay2AImpl* This, DPID dpidServer )
261 {
262   LPVOID                   lpMsg;
263   LPDPMSG_FORWARDADDPLAYER lpMsgBody;
264   DWORD                    dwMsgSize;
265   HRESULT                  hr = DP_OK;
266 
267   dwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpMsgBody );
268 
269   lpMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwMsgSize );
270 
271   lpMsgBody = (LPDPMSG_FORWARDADDPLAYER)( (BYTE*)lpMsg +
272                                           This->dp2->spData.dwSPHeaderSize );
273 
274   /* Compose dplay message envelope */
275   lpMsgBody->envelope.dwMagic    = DPMSGMAGIC_DPLAYMSG;
276   lpMsgBody->envelope.wCommandId = DPMSGCMD_FORWARDADDPLAYER;
277   lpMsgBody->envelope.wVersion   = DPMSGVER_DP6;
278 
279 #if 0
280   {
281     LPBYTE lpPData;
282     DWORD  dwDataSize;
283 
284     /* SP Player remote data needs to be propagated at some point - is this the point? */
285     IDirectPlaySP_GetSPPlayerData( This->dp2->spData.lpISP, 0, (LPVOID*)&lpPData, &dwDataSize, DPSET_REMOTE );
286 
287     ERR( "Player Data size is 0x%08lx\n"
288          "[%02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x]\n"
289          "[%02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x]\n",
290 
291          dwDataSize,
292          lpPData[0], lpPData[1], lpPData[2], lpPData[3], lpPData[4],
293          lpPData[5], lpPData[6], lpPData[7], lpPData[8], lpPData[9],
294          lpPData[10], lpPData[11], lpPData[12], lpPData[13], lpPData[14],
295          lpPData[15], lpPData[16], lpPData[17], lpPData[18], lpPData[19],
296          lpPData[20], lpPData[21], lpPData[22], lpPData[23], lpPData[24],
297          lpPData[25], lpPData[26], lpPData[27], lpPData[28], lpPData[29],
298          lpPData[30], lpPData[31]
299         );
300     DebugBreak();
301   }
302 #endif
303 
304   /* Compose body of message */
305   lpMsgBody->dpidAppServer = dpidServer;
306   lpMsgBody->unknown2[0] = 0x0;
307   lpMsgBody->unknown2[1] = 0x1c;
308   lpMsgBody->unknown2[2] = 0x6c;
309   lpMsgBody->unknown2[3] = 0x50;
310   lpMsgBody->unknown2[4] = 0x9;
311 
312   lpMsgBody->dpidAppServer2 = dpidServer;
313   lpMsgBody->unknown3[0] = 0x0;
314   lpMsgBody->unknown3[0] = 0x0;
315   lpMsgBody->unknown3[0] = 0x20;
316   lpMsgBody->unknown3[0] = 0x0;
317   lpMsgBody->unknown3[0] = 0x0;
318 
319   lpMsgBody->dpidAppServer3 = dpidServer;
320   lpMsgBody->unknown4[0] =  0x30;
321   lpMsgBody->unknown4[1] =  0xb;
322   lpMsgBody->unknown4[2] =  0x0;
323 
324   lpMsgBody->unknown4[3] =  NS_GetNsMagic( This->dp2->lpNameServerData ) -
325                             0x02000000;
326   TRACE( "Setting first magic to 0x%08x\n", lpMsgBody->unknown4[3] );
327 
328   lpMsgBody->unknown4[4] =  0x0;
329   lpMsgBody->unknown4[5] =  0x0;
330   lpMsgBody->unknown4[6] =  0x0;
331 
332 #if 0
333   lpMsgBody->unknown4[7] =  NS_GetOtherMagic( This->dp2->lpNameServerData )
334 #else
335   lpMsgBody->unknown4[7] =  NS_GetNsMagic( This->dp2->lpNameServerData );
336 #endif
337   TRACE( "Setting second magic to 0x%08x\n", lpMsgBody->unknown4[7] );
338 
339   lpMsgBody->unknown4[8] =  0x0;
340   lpMsgBody->unknown4[9] =  0x0;
341   lpMsgBody->unknown4[10] = 0x0;
342   lpMsgBody->unknown4[11] = 0x0;
343 
344   lpMsgBody->unknown5[0] = 0x0;
345   lpMsgBody->unknown5[1] = 0x0;
346 
347   /* Send the message */
348   {
349     DPSP_SENDDATA data;
350 
351     data.dwFlags        = DPSEND_GUARANTEED;
352     data.idPlayerTo     = 0; /* Name server */
353     data.idPlayerFrom   = dpidServer; /* Sending from session server */
354     data.lpMessage      = lpMsg;
355     data.dwMessageSize  = dwMsgSize;
356     data.bSystemMessage = TRUE; /* Allow reply to be sent */
357     data.lpISP          = This->dp2->spData.lpISP;
358 
359     TRACE( "Sending forward player request with 0x%08x\n", dpidServer );
360 
361     lpMsg = DP_MSG_ExpectReply( This, &data,
362                                 DPMSG_WAIT_60_SECS,
363                                 DPMSGCMD_GETNAMETABLEREPLY,
364                                 &lpMsg, &dwMsgSize );
365   }
366 
367   /* Need to examine the data and extract the new player id */
368   if( lpMsg != NULL )
369   {
370     FIXME( "Name Table reply received: stub\n" );
371   }
372 
373   return hr;
374 }
375 
376 /* Queue up a structure indicating that we want a reply of type wReplyCommandId. DPlay does
377  * not seem to offer any way of uniquely differentiating between replies of the same type
378  * relative to the request sent. There is an implicit assumption that there will be no
379  * ordering issues on sends and receives from the opposite machine. No wonder MS is not
380  * a networking company.
381  */
382 static
383 LPVOID DP_MSG_ExpectReply( IDirectPlay2AImpl* This, LPDPSP_SENDDATA lpData,
384                            DWORD dwWaitTime, WORD wReplyCommandId,
385                            LPVOID* lplpReplyMsg, LPDWORD lpdwMsgBodySize )
386 {
387   HRESULT                  hr;
388   HANDLE                   hMsgReceipt;
389   DP_MSG_REPLY_STRUCT_LIST replyStructList;
390   DWORD                    dwWaitReturn;
391 
392   /* Setup for receipt */
393   hMsgReceipt = DP_MSG_BuildAndLinkReplyStruct( This, &replyStructList,
394                                                 wReplyCommandId );
395 
396   TRACE( "Sending msg and expecting cmd %u in reply within %u ticks\n",
397          wReplyCommandId, dwWaitTime );
398   hr = (*This->dp2->spData.lpCB->Send)( lpData );
399 
400   if( FAILED(hr) )
401   {
402     ERR( "Send failed: %s\n", DPLAYX_HresultToString( hr ) );
403     return NULL;
404   }
405 
406   /* The reply message will trigger the hMsgReceipt event effectively switching
407    * control back to this thread. See DP_MSG_ReplyReceived.
408    */
409   dwWaitReturn = WaitForSingleObject( hMsgReceipt, dwWaitTime );
410   if( dwWaitReturn != WAIT_OBJECT_0 )
411   {
412     ERR( "Wait failed 0x%08x\n", dwWaitReturn );
413     return NULL;
414   }
415 
416   /* Clean Up */
417   return DP_MSG_CleanReplyStruct( &replyStructList, lplpReplyMsg, lpdwMsgBodySize );
418 }
419 
420 /* Determine if there is a matching request for this incoming message and then copy
421  * all important data. It is quite silly to have to copy the message, but the documents
422  * indicate that a copy is taken. Silly really.
423  */
424 void DP_MSG_ReplyReceived( IDirectPlay2AImpl* This, WORD wCommandId,
425                            LPCVOID lpcMsgBody, DWORD dwMsgBodySize )
426 {
427   LPDP_MSG_REPLY_STRUCT_LIST lpReplyList;
428 
429 #if 0
430   if( wCommandId == DPMSGCMD_FORWARDADDPLAYER )
431   {
432     DebugBreak();
433   }
434 #endif
435 
436   /* Find, and immediately remove (to avoid double triggering), the appropriate entry. Call locked to
437    * avoid problems.
438    */
439   EnterCriticalSection( &This->unk->DP_lock );
440     DPQ_REMOVE_ENTRY( This->dp2->replysExpected, replysExpected, replyExpected.wExpectedReply,
441                      ==, wCommandId, lpReplyList );
442   LeaveCriticalSection( &This->unk->DP_lock );
443 
444   if( lpReplyList != NULL )
445   {
446     lpReplyList->replyExpected.dwMsgBodySize = dwMsgBodySize;
447     lpReplyList->replyExpected.lpReplyMsg = HeapAlloc( GetProcessHeap(),
448                                                        HEAP_ZERO_MEMORY,
449                                                        dwMsgBodySize );
450     CopyMemory( lpReplyList->replyExpected.lpReplyMsg,
451                 lpcMsgBody, dwMsgBodySize );
452 
453     /* Signal the thread which sent the message that it has a reply */
454     SetEvent( lpReplyList->replyExpected.hReceipt );
455   }
456   else
457   {
458     ERR( "No receipt event set - only expecting in reply mode\n" );
459     DebugBreak();
460   }
461 }
462 
463 void DP_MSG_ToSelf( IDirectPlay2AImpl* This, DPID dpidSelf )
464 {
465   LPVOID                   lpMsg;
466   LPDPMSG_SENDENVELOPE     lpMsgBody;
467   DWORD                    dwMsgSize;
468 
469   dwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpMsgBody );
470 
471   lpMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwMsgSize );
472 
473   lpMsgBody = (LPDPMSG_SENDENVELOPE)( (BYTE*)lpMsg +
474                                       This->dp2->spData.dwSPHeaderSize );
475 
476   /* Compose dplay message envelope */
477   lpMsgBody->dwMagic    = DPMSGMAGIC_DPLAYMSG;
478   lpMsgBody->wCommandId = DPMSGCMD_JUSTENVELOPE;
479   lpMsgBody->wVersion   = DPMSGVER_DP6;
480 
481   /* Send the message to ourselves */
482   {
483     DPSP_SENDDATA data;
484 
485     data.dwFlags        = 0;
486     data.idPlayerTo     = dpidSelf; /* Sending to session server */
487     data.idPlayerFrom   = 0; /* Sending from session server */
488     data.lpMessage      = lpMsg;
489     data.dwMessageSize  = dwMsgSize;
490     data.bSystemMessage = TRUE; /* Allow reply to be sent */
491     data.lpISP          = This->dp2->spData.lpISP;
492 
493     lpMsg = DP_MSG_ExpectReply( This, &data,
494                                 DPMSG_WAIT_5_SECS,
495                                 DPMSGCMD_JUSTENVELOPE,
496                                 &lpMsg, &dwMsgSize );
497   }
498 }
499 
500 void DP_MSG_ErrorReceived( IDirectPlay2AImpl* This, WORD wCommandId,
501                            LPCVOID lpMsgBody, DWORD dwMsgBodySize )
502 {
503   LPCDPMSG_FORWARDADDPLAYERNACK lpcErrorMsg;
504 
505   lpcErrorMsg = (LPCDPMSG_FORWARDADDPLAYERNACK)lpMsgBody;
506 
507   ERR( "Received error message %u. Error is %s\n",
508        wCommandId, DPLAYX_HresultToString( lpcErrorMsg->errorCode) );
509   DebugBreak();
510 }
511 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.