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

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

Version: ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ 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 ] ~

  1 /* This contains the implementation of the interface Service
  2  * Providers require to communicate with Direct Play
  3  *
  4  * Copyright 2000 Peter Hunnisett
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 #include <string.h>
 22 #include "winerror.h"
 23 #include "wine/debug.h"
 24 
 25 #include "dpinit.h"
 26 #include "wine/dplaysp.h"
 27 #include "dplay_global.h"
 28 #include "name_server.h"
 29 #include "dplayx_messages.h"
 30 
 31 #include "dplayx_global.h" /* FIXME: For global hack */
 32 
 33 /* FIXME: Need to add interface locking inside procedures */
 34 
 35 WINE_DEFAULT_DEBUG_CHANNEL(dplay);
 36 
 37 /* Prototypes */
 38 static BOOL DPSP_CreateIUnknown( LPVOID lpSP );
 39 static BOOL DPSP_DestroyIUnknown( LPVOID lpSP );
 40 static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp );
 41 static BOOL DPSP_DestroyDirectPlaySP( LPVOID lpSP );
 42 
 43 /* Predefine the interface */
 44 typedef struct IDirectPlaySPImpl IDirectPlaySPImpl;
 45 
 46 typedef struct tagDirectPlaySPIUnknownData
 47 {
 48   LONG              ulObjRef;
 49   CRITICAL_SECTION  DPSP_lock;
 50 } DirectPlaySPIUnknownData;
 51 
 52 typedef struct tagDirectPlaySPData
 53 {
 54   LPVOID lpSpRemoteData;
 55   DWORD  dwSpRemoteDataSize; /* Size of data pointed to by lpSpRemoteData */
 56 
 57   LPVOID lpSpLocalData;
 58   DWORD  dwSpLocalDataSize; /* Size of data pointed to by lpSpLocalData */
 59 
 60   IDirectPlay2Impl* dplay; /* FIXME: This should perhaps be iface not impl */
 61 
 62 } DirectPlaySPData;
 63 
 64 #define DPSP_IMPL_FIELDS \
 65    LONG ulInterfaceRef; \
 66    DirectPlaySPIUnknownData* unk; \
 67    DirectPlaySPData* sp;
 68 
 69 struct IDirectPlaySPImpl
 70 {
 71   const IDirectPlaySPVtbl *lpVtbl;
 72   DPSP_IMPL_FIELDS
 73 };
 74 
 75 /* Forward declaration of virtual tables */
 76 static const IDirectPlaySPVtbl directPlaySPVT;
 77 
 78 /* This structure is passed to the DP object for safe keeping */
 79 typedef struct tagDP_SPPLAYERDATA
 80 {
 81   LPVOID lpPlayerLocalData;
 82   DWORD  dwPlayerLocalDataSize;
 83 
 84   LPVOID lpPlayerRemoteData;
 85   DWORD  dwPlayerRemoteDataSize;
 86 } DP_SPPLAYERDATA, *LPDP_SPPLAYERDATA;
 87 
 88 /* Create the SP interface */
 89 HRESULT DPSP_CreateInterface( REFIID riid, LPVOID* ppvObj, IDirectPlay2Impl* dp )
 90 {
 91   TRACE( " for %s\n", debugstr_guid( riid ) );
 92 
 93   *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
 94                        sizeof( IDirectPlaySPImpl ) );
 95 
 96   if( *ppvObj == NULL )
 97   {
 98     return DPERR_OUTOFMEMORY;
 99   }
100 
101   if( IsEqualGUID( &IID_IDirectPlaySP, riid ) )
102   {
103     IDirectPlaySPImpl *This = *ppvObj;
104     This->lpVtbl = &directPlaySPVT;
105   }
106   else
107   {
108     /* Unsupported interface */
109     HeapFree( GetProcessHeap(), 0, *ppvObj );
110     *ppvObj = NULL;
111 
112     return E_NOINTERFACE;
113   }
114 
115   /* Initialize it */
116   if( DPSP_CreateIUnknown( *ppvObj ) &&
117       DPSP_CreateDirectPlaySP( *ppvObj, dp )
118     )
119   {
120     IDirectPlaySP_AddRef( (LPDIRECTPLAYSP)*ppvObj );
121     return S_OK;
122   }
123 
124   /* Initialize failed, destroy it */
125   DPSP_DestroyDirectPlaySP( *ppvObj );
126   DPSP_DestroyIUnknown( *ppvObj );
127 
128   HeapFree( GetProcessHeap(), 0, *ppvObj );
129   *ppvObj = NULL;
130 
131   return DPERR_NOMEMORY;
132 }
133 
134 static BOOL DPSP_CreateIUnknown( LPVOID lpSP )
135 {
136   IDirectPlaySPImpl *This = lpSP;
137 
138   This->unk = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( *(This->unk) ) );
139 
140   if ( This->unk == NULL )
141   {
142     return FALSE;
143   }
144 
145   InitializeCriticalSection( &This->unk->DPSP_lock );
146   This->unk->DPSP_lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectPlaySPImpl*->DirectPlaySPIUnknownData*->DPSP_lock");
147 
148   return TRUE;
149 }
150 
151 static BOOL DPSP_DestroyIUnknown( LPVOID lpSP )
152 {
153   IDirectPlaySPImpl *This = lpSP;
154 
155   This->unk->DPSP_lock.DebugInfo->Spare[0] = 0;
156   DeleteCriticalSection( &This->unk->DPSP_lock );
157   HeapFree( GetProcessHeap(), 0, This->unk );
158 
159   return TRUE;
160 }
161 
162 
163 static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp )
164 {
165   IDirectPlaySPImpl *This = lpSP;
166 
167   This->sp = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( *(This->sp) ) );
168 
169   if ( This->sp == NULL )
170   {
171     return FALSE;
172   }
173 
174   This->sp->dplay = dp;
175 
176   /* Normally we should be keeping a reference, but since only the dplay
177    * interface that created us can destroy us, we do not keep a reference
178    * to it (ie we'd be stuck with always having one reference to the dplay
179    * object, and hence us, around).
180    * NOTE: The dp object does reference count us.
181    *
182    * FIXME: This is a kludge to get around a problem where a queryinterface
183    *        is used to get a new interface and then is closed. We will then
184    *        reference garbage. However, with this we will never deallocate
185    *        the interface we store. The correct fix is to require all
186    *        DP internal interfaces to use the This->dp2 interface which
187    *        should be changed to This->dp
188    */
189   IDirectPlayX_AddRef( (LPDIRECTPLAY2)dp );
190 
191   return TRUE;
192 }
193 
194 static BOOL DPSP_DestroyDirectPlaySP( LPVOID lpSP )
195 {
196   IDirectPlaySPImpl *This = lpSP;
197 
198   /* Normally we should be keeping a reference, but since only the dplay
199    * interface that created us can destroy us, we do not keep a reference
200    * to it (ie we'd be stuck with always having one reference to the dplay
201    * object, and hence us, around).
202    * NOTE: The dp object does reference count us.
203    */
204   /*IDirectPlayX_Release( (LPDIRECTPLAY2)This->sp->dplay ); */
205 
206   HeapFree( GetProcessHeap(), 0, This->sp->lpSpRemoteData );
207   HeapFree( GetProcessHeap(), 0, This->sp->lpSpLocalData );
208 
209   /* FIXME: Need to delete player queue */
210 
211   HeapFree( GetProcessHeap(), 0, This->sp );
212   return TRUE;
213 }
214 
215 /* Interface implementation */
216 
217 static HRESULT WINAPI DPSP_QueryInterface
218 ( LPDIRECTPLAYSP iface,
219   REFIID riid,
220   LPVOID* ppvObj )
221 {
222   IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
223   TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
224 
225   *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
226                        sizeof( *This ) );
227 
228   if( *ppvObj == NULL )
229   {
230     return DPERR_OUTOFMEMORY;
231   }
232 
233   CopyMemory( *ppvObj, This, sizeof( *This )  );
234   (*(IDirectPlaySPImpl**)ppvObj)->ulInterfaceRef = 0;
235 
236   if( IsEqualGUID( &IID_IDirectPlaySP, riid ) )
237   {
238     IDirectPlaySPImpl *This = *ppvObj;
239     This->lpVtbl = &directPlaySPVT;
240   }
241   else
242   {
243     /* Unsupported interface */
244     HeapFree( GetProcessHeap(), 0, *ppvObj );
245     *ppvObj = NULL;
246 
247     return E_NOINTERFACE;
248   }
249 
250   IDirectPlaySP_AddRef( (LPDIRECTPLAYSP)*ppvObj );
251 
252   return S_OK;
253 }
254 
255 static ULONG WINAPI DPSP_AddRef
256 ( LPDIRECTPLAYSP iface )
257 {
258   ULONG ulInterfaceRefCount, ulObjRefCount;
259   IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
260 
261   ulObjRefCount       = InterlockedIncrement( &This->unk->ulObjRef );
262   ulInterfaceRefCount = InterlockedIncrement( &This->ulInterfaceRef );
263 
264   TRACE( "ref count incremented to %u:%u for %p\n",
265          ulInterfaceRefCount, ulObjRefCount, This );
266 
267   return ulObjRefCount;
268 }
269 
270 static ULONG WINAPI DPSP_Release
271 ( LPDIRECTPLAYSP iface )
272 {
273   ULONG ulInterfaceRefCount, ulObjRefCount;
274   IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
275 
276   ulObjRefCount       = InterlockedDecrement( &This->unk->ulObjRef );
277   ulInterfaceRefCount = InterlockedDecrement( &This->ulInterfaceRef );
278 
279   TRACE( "ref count decremented to %u:%u for %p\n",
280          ulInterfaceRefCount, ulObjRefCount, This );
281 
282   /* Deallocate if this is the last reference to the object */
283   if( ulObjRefCount == 0 )
284   {
285      DPSP_DestroyDirectPlaySP( This );
286      DPSP_DestroyIUnknown( This );
287   }
288 
289   if( ulInterfaceRefCount == 0 )
290   {
291     HeapFree( GetProcessHeap(), 0, This );
292   }
293 
294   return ulInterfaceRefCount;
295 }
296 
297 static HRESULT WINAPI IDirectPlaySPImpl_AddMRUEntry
298 ( LPDIRECTPLAYSP iface,
299   LPCWSTR lpSection,
300   LPCWSTR lpKey,
301   LPCVOID lpData,
302   DWORD   dwDataSize,
303   DWORD   dwMaxEntries
304 )
305 {
306   IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
307 
308   /* Should be able to call the comctl32 undocumented MRU routines.
309      I suspect that the interface works appropriately */
310   FIXME( "(%p)->(%p,%p%p,0x%08x,0x%08x): stub\n",
311          This, lpSection, lpKey, lpData, dwDataSize, dwMaxEntries );
312 
313   return DP_OK;
314 }
315 
316 static HRESULT WINAPI IDirectPlaySPImpl_CreateAddress
317 ( LPDIRECTPLAYSP iface,
318   REFGUID guidSP,
319   REFGUID guidDataType,
320   LPCVOID lpData,
321   DWORD   dwDataSize,
322   LPVOID  lpAddress,
323   LPDWORD lpdwAddressSize
324 )
325 {
326   IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
327 
328   FIXME( "(%p)->(%s,%s,%p,0x%08x,%p,%p): stub\n",
329          This, debugstr_guid(guidSP), debugstr_guid(guidDataType),
330          lpData, dwDataSize, lpAddress, lpdwAddressSize );
331 
332   return DP_OK;
333 }
334 
335 static HRESULT WINAPI IDirectPlaySPImpl_EnumAddress
336 ( LPDIRECTPLAYSP iface,
337   LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
338   LPCVOID lpAddress,
339   DWORD dwAddressSize,
340   LPVOID lpContext
341 )
342 {
343   IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
344 
345   TRACE( "(%p)->(%p,%p,0x%08x,%p)\n",
346          This, lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext );
347 
348   DPL_EnumAddress( lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext );
349 
350   return DP_OK;
351 }
352 
353 static HRESULT WINAPI IDirectPlaySPImpl_EnumMRUEntries
354 ( LPDIRECTPLAYSP iface,
355   LPCWSTR lpSection,
356   LPCWSTR lpKey,
357   LPENUMMRUCALLBACK lpEnumMRUCallback,
358   LPVOID lpContext
359 )
360 {
361   IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
362 
363   /* Should be able to call the comctl32 undocumented MRU routines.
364      I suspect that the interface works appropriately */
365   FIXME( "(%p)->(%p,%p,%p,%p,): stub\n",
366          This, lpSection, lpKey, lpEnumMRUCallback, lpContext );
367 
368   return DP_OK;
369 }
370 
371 static HRESULT WINAPI IDirectPlaySPImpl_GetPlayerFlags
372 ( LPDIRECTPLAYSP iface,
373   DPID idPlayer,
374   LPDWORD lpdwPlayerFlags
375 )
376 {
377   IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
378 
379   FIXME( "(%p)->(0x%08x,%p): stub\n",
380          This, idPlayer, lpdwPlayerFlags );
381 
382   return DP_OK;
383 }
384 
385 static HRESULT WINAPI IDirectPlaySPImpl_GetSPPlayerData
386 ( LPDIRECTPLAYSP iface,
387   DPID idPlayer,
388   LPVOID* lplpData,
389   LPDWORD lpdwDataSize,
390   DWORD dwFlags
391 )
392 {
393   HRESULT hr;
394   LPDP_SPPLAYERDATA lpPlayerData;
395   IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
396 
397   TRACE( "(%p)->(0x%08x,%p,%p,0x%08x)\n",
398          This, idPlayer, lplpData, lpdwDataSize, dwFlags );
399 
400   hr = DP_GetSPPlayerData( This->sp->dplay, idPlayer, (LPVOID*)&lpPlayerData );
401 
402   if( FAILED(hr) )
403   {
404     TRACE( "Couldn't get player data: %s\n", DPLAYX_HresultToString(hr) );
405     return DPERR_INVALIDPLAYER;
406   }
407 
408   /* What to do in the case where there is nothing set yet? */
409   if( dwFlags == DPSET_LOCAL )
410   {
411     HeapFree( GetProcessHeap(), 0, lpPlayerData->lpPlayerLocalData );
412     *lplpData     = lpPlayerData->lpPlayerLocalData;
413     *lpdwDataSize = lpPlayerData->dwPlayerLocalDataSize;
414   }
415   else if( dwFlags == DPSET_REMOTE )
416   {
417     HeapFree( GetProcessHeap(), 0, lpPlayerData->lpPlayerRemoteData );
418     *lplpData     = lpPlayerData->lpPlayerRemoteData;
419     *lpdwDataSize = lpPlayerData->dwPlayerRemoteDataSize;
420   }
421 
422   if( *lplpData == NULL )
423   {
424     hr = DPERR_GENERIC;
425   }
426 
427   return hr;
428 }
429 
430 static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
431 ( LPDIRECTPLAYSP iface,
432   LPVOID lpMessageBody,
433   DWORD  dwMessageBodySize,
434   LPVOID lpMessageHeader
435 )
436 {
437   LPDPMSG_SENDENVELOPE lpMsg = lpMessageBody;
438   HRESULT hr = DPERR_GENERIC;
439   WORD wCommandId;
440   WORD wVersion;
441   DPSP_REPLYDATA data;
442 
443   IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
444 
445   FIXME( "(%p)->(%p,0x%08x,%p): mostly stub\n",
446          This, lpMessageBody, dwMessageBodySize, lpMessageHeader );
447 
448   wCommandId = lpMsg->wCommandId;
449   wVersion   = lpMsg->wVersion;
450 
451   TRACE( "Incoming message has envelope of 0x%08x, %u, %u\n",
452          lpMsg->dwMagic, wCommandId, wVersion );
453 
454   if( lpMsg->dwMagic != DPMSGMAGIC_DPLAYMSG )
455   {
456     ERR( "Unknown magic 0x%08x!\n", lpMsg->dwMagic );
457     return DPERR_GENERIC;
458   }
459 
460 #if 0
461   {
462     const LPDWORD lpcHeader = lpMessageHeader;
463 
464     TRACE( "lpMessageHeader = [0x%08lx] [0x%08lx] [0x%08lx] [0x%08lx] [0x%08lx]\n",
465            lpcHeader[0], lpcHeader[1], lpcHeader[2], lpcHeader[3], lpcHeader[4] );
466    }
467 #endif
468 
469   /* Pass everything else to Direct Play */
470   data.lpMessage     = NULL;
471   data.dwMessageSize = 0;
472 
473   /* Pass this message to the dplay interface to handle */
474   hr = DP_HandleMessage( This->sp->dplay, lpMessageBody, dwMessageBodySize,
475                          lpMessageHeader, wCommandId, wVersion,
476                          &data.lpMessage, &data.dwMessageSize );
477 
478   if( FAILED(hr) )
479   {
480     ERR( "Command processing failed %s\n", DPLAYX_HresultToString(hr) );
481   }
482 
483   /* Do we want a reply? */
484   if( data.lpMessage != NULL )
485   {
486     data.lpSPMessageHeader = lpMessageHeader;
487     data.idNameServer      = 0;
488     data.lpISP             = iface;
489 
490     hr = (This->sp->dplay->dp2->spData.lpCB->Reply)( &data );
491 
492     if( FAILED(hr) )
493     {
494       ERR( "Reply failed %s\n", DPLAYX_HresultToString(hr) );
495     }
496   }
497 
498   return hr;
499 
500 #if 0
501   HRESULT hr = DP_OK;
502   HANDLE  hReceiveEvent = 0;
503   /* FIXME: Acquire some sort of interface lock */
504   /* FIXME: Need some sort of context for this callback. Need to determine
505    *        how this is actually done with the SP
506    */
507   /* FIXME: Who needs to delete the message when done? */
508   switch( lpMsg->dwType )
509   {
510     case DPSYS_CREATEPLAYERORGROUP:
511     {
512       LPDPMSG_CREATEPLAYERORGROUP msg = lpMsg;
513 
514       if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
515       {
516         hr = DP_IF_CreatePlayer( This, lpMessageHeader, msg->dpId,
517                                  &msg->dpnName, 0, msg->lpData,
518                                  msg->dwDataSize, msg->dwFlags, ... );
519       }
520       else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
521       {
522         /* Group in group situation? */
523         if( msg->dpIdParent == DPID_NOPARENT_GROUP )
524         {
525           hr = DP_IF_CreateGroup( This, lpMessageHeader, msg->dpId,
526                                   &msg->dpnName, 0, msg->lpData,
527                                   msg->dwDataSize, msg->dwFlags, ... );
528         }
529         else /* Group in Group */
530         {
531           hr = DP_IF_CreateGroupInGroup( This, lpMessageHeader, msg->dpIdParent,
532                                          &msg->dpnName, 0, msg->lpData,
533                                          msg->dwDataSize, msg->dwFlags, ... );
534         }
535       }
536       else /* Hmmm? */
537       {
538         ERR( "Corrupt msg->dwPlayerType for DPSYS_CREATEPLAYERORGROUP\n" );
539         return;
540       }
541 
542       break;
543     }
544 
545     case DPSYS_DESTROYPLAYERORGROUP:
546     {
547       LPDPMSG_DESTROYPLAYERORGROUP msg = lpMsg;
548 
549       if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
550       {
551         hr = DP_IF_DestroyPlayer( This, msg->dpId, ... );
552       }
553       else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
554       {
555         hr = DP_IF_DestroyGroup( This, msg->dpId, ... );
556       }
557       else /* Hmmm? */
558       {
559         ERR( "Corrupt msg->dwPlayerType for DPSYS_DESTROYPLAYERORGROUP\n" );
560         return;
561       }
562 
563       break;
564     }
565 
566     case DPSYS_ADDPLAYERTOGROUP:
567     {
568       LPDPMSG_ADDPLAYERTOGROUP msg = lpMsg;
569 
570       hr = DP_IF_AddPlayerToGroup( This, msg->dpIdGroup, msg->dpIdPlayer, ... );
571       break;
572     }
573 
574     case DPSYS_DELETEPLAYERFROMGROUP:
575     {
576       LPDPMSG_DELETEPLAYERFROMGROUP msg = lpMsg;
577 
578       hr = DP_IF_DeletePlayerFromGroup( This, msg->dpIdGroup, msg->dpIdPlayer,
579                                         ... );
580 
581       break;
582     }
583 
584     case DPSYS_SESSIONLOST:
585     {
586       LPDPMSG_SESSIONLOST msg = lpMsg;
587 
588       FIXME( "DPSYS_SESSIONLOST not handled\n" );
589 
590       break;
591     }
592 
593     case DPSYS_HOST:
594     {
595       LPDPMSG_HOST msg = lpMsg;
596 
597       FIXME( "DPSYS_HOST not handled\n" );
598 
599       break;
600     }
601 
602     case DPSYS_SETPLAYERORGROUPDATA:
603     {
604       LPDPMSG_SETPLAYERORGROUPDATA msg = lpMsg;
605 
606       if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
607       {
608         hr = DP_IF_SetPlayerData( This, msg->dpId, msg->lpData, msg->dwDataSize,                                  DPSET_REMOTE, ... );
609       }
610       else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
611       {
612         hr = DP_IF_SetGroupData( This, msg->dpId, msg->lpData, msg->dwDataSize,
613                                  DPSET_REMOTE, ... );
614       }
615       else /* Hmmm? */
616       {
617         ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" );
618         return;
619       }
620 
621       break;
622     }
623 
624     case DPSYS_SETPLAYERORGROUPNAME:
625     {
626       LPDPMSG_SETPLAYERORGROUPNAME msg = lpMsg;
627 
628       if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
629       {
630         hr = DP_IF_SetPlayerName( This, msg->dpId, msg->dpnName, ... );
631       }
632       else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
633       {
634         hr = DP_IF_SetGroupName( This, msg->dpId, msg->dpnName, ... );
635       }
636       else /* Hmmm? */
637       {
638         ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" );
639         return;
640       }
641 
642       break;
643     }
644 
645     case DPSYS_SETSESSIONDESC;
646     {
647       LPDPMSG_SETSESSIONDESC msg = lpMsg;
648 
649       hr = DP_IF_SetSessionDesc( This, &msg->dpDesc );
650 
651       break;
652     }
653 
654     case DPSYS_ADDGROUPTOGROUP:
655     {
656       LPDPMSG_ADDGROUPTOGROUP msg = lpMsg;
657 
658       hr = DP_IF_AddGroupToGroup( This, msg->dpIdParentGroup, msg->dpIdGroup,
659                                   ... );
660 
661       break;
662     }
663 
664     case DPSYS_DELETEGROUPFROMGROUP:
665     {
666       LPDPMSG_DELETEGROUPFROMGROUP msg = lpMsg;
667 
668       hr = DP_IF_DeleteGroupFromGroup( This, msg->dpIdParentGroup,
669                                        msg->dpIdGroup, ... );
670 
671       break;
672     }
673 
674     case DPSYS_SECUREMESSAGE:
675     {
676       LPDPMSG_SECUREMESSAGE msg = lpMsg;
677 
678       FIXME( "DPSYS_SECUREMESSAGE not implemented\n" );
679 
680       break;
681     }
682 
683     case DPSYS_STARTSESSION:
684     {
685       LPDPMSG_STARTSESSION msg = lpMsg;
686 
687       FIXME( "DPSYS_STARTSESSION not implemented\n" );
688 
689       break;
690     }
691 
692     case DPSYS_CHAT:
693     {
694       LPDPMSG_CHAT msg = lpMsg;
695 
696       FIXME( "DPSYS_CHAT not implemeneted\n" );
697 
698       break;
699     }
700 
701     case DPSYS_SETGROUPOWNER:
702     {
703       LPDPMSG_SETGROUPOWNER msg = lpMsg;
704 
705       FIXME( "DPSYS_SETGROUPOWNER not implemented\n" );
706 
707       break;
708     }
709 
710     case DPSYS_SENDCOMPLETE:
711     {
712       LPDPMSG_SENDCOMPLETE msg = lpMsg;
713 
714       FIXME( "DPSYS_SENDCOMPLETE not implemented\n" );
715 
716       break;
717     }
718 
719     default:
720     {
721       /* NOTE: This should be a user defined type. There is nothing that we
722        *       need to do with it except queue it.
723        */
724       TRACE( "Received user message type(?) 0x%08lx through SP.\n",
725               lpMsg->dwType );
726       break;
727     }
728   }
729 
730   FIXME( "Queue message in the receive queue. Need some context data!\n" );
731 
732   if( FAILED(hr) )
733   {
734     ERR( "Unable to perform action for msg type 0x%08lx\n", lpMsg->dwType );
735   }
736   /* If a receive event was registered for this player, invoke it */
737   if( hReceiveEvent )
738   {
739     SetEvent( hReceiveEvent );
740   }
741 #endif
742 }
743 
744 static HRESULT WINAPI IDirectPlaySPImpl_SetSPPlayerData
745 ( LPDIRECTPLAYSP iface,
746   DPID idPlayer,
747   LPVOID lpData,
748   DWORD dwDataSize,
749   DWORD dwFlags
750 )
751 {
752   HRESULT           hr;
753   LPDP_SPPLAYERDATA lpPlayerEntry;
754   LPVOID            lpPlayerData;
755 
756   IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
757 
758 /*  TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
759   TRACE( "(%p)->(0x%08x,%p,0x%08x,0x%08x)\n",
760          This, idPlayer, lpData, dwDataSize, dwFlags );
761 
762   hr = DP_GetSPPlayerData( This->sp->dplay, idPlayer, (LPVOID*)&lpPlayerEntry );
763   if( FAILED(hr) )
764   {
765     /* Player must not exist */
766     return DPERR_INVALIDPLAYER;
767   }
768 
769   lpPlayerData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
770   CopyMemory( lpPlayerData, lpData, dwDataSize );
771 
772   if( dwFlags == DPSET_LOCAL )
773   {
774     lpPlayerEntry->lpPlayerLocalData = lpPlayerData;
775     lpPlayerEntry->dwPlayerLocalDataSize = dwDataSize;
776   }
777   else if( dwFlags == DPSET_REMOTE )
778   {
779     lpPlayerEntry->lpPlayerRemoteData = lpPlayerData;
780     lpPlayerEntry->dwPlayerRemoteDataSize = dwDataSize;
781   }
782 
783   hr = DP_SetSPPlayerData( This->sp->dplay, idPlayer, lpPlayerEntry );
784 
785   return hr;
786 }
787 
788 static HRESULT WINAPI IDirectPlaySPImpl_CreateCompoundAddress
789 ( LPDIRECTPLAYSP iface,
790   LPCDPCOMPOUNDADDRESSELEMENT lpElements,
791   DWORD dwElementCount,
792   LPVOID lpAddress,
793   LPDWORD lpdwAddressSize
794 )
795 {
796   IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
797 
798   FIXME( "(%p)->(%p,0x%08x,%p,%p): stub\n",
799          This, lpElements, dwElementCount, lpAddress, lpdwAddressSize );
800 
801   return DP_OK;
802 }
803 
804 static HRESULT WINAPI IDirectPlaySPImpl_GetSPData
805 ( LPDIRECTPLAYSP iface,
806   LPVOID* lplpData,
807   LPDWORD lpdwDataSize,
808   DWORD dwFlags
809 )
810 {
811   HRESULT hr = DP_OK;
812   IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
813 
814 /*  TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
815   TRACE( "(%p)->(%p,%p,0x%08x)\n",
816          This, lplpData, lpdwDataSize, dwFlags );
817 
818 #if 0
819   /* This is what the documentation says... */
820   if( dwFlags != DPSET_REMOTE )
821   {
822     return DPERR_INVALIDPARAMS;
823   }
824 #else
825   /* ... but most service providers call this with 1 */
826   /* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
827    * thing?
828    */
829   if( dwFlags != DPSET_REMOTE )
830   {
831     TRACE( "Undocumented dwFlags 0x%08x used\n", dwFlags );
832   }
833 #endif
834 
835   /* FIXME: What to do in the case where this isn't initialized yet? */
836 
837   /* Yes, we're supposed to return a pointer to the memory we have stored! */
838   if( dwFlags == DPSET_REMOTE )
839   {
840     *lpdwDataSize = This->sp->dwSpRemoteDataSize;
841     *lplpData     = This->sp->lpSpRemoteData;
842 
843     if( This->sp->lpSpRemoteData == NULL )
844     {
845       hr = DPERR_GENERIC;
846     }
847   }
848   else if( dwFlags == DPSET_LOCAL )
849   {
850     *lpdwDataSize = This->sp->dwSpLocalDataSize;
851     *lplpData     = This->sp->lpSpLocalData;
852 
853     if( This->sp->lpSpLocalData == NULL )
854     {
855       hr = DPERR_GENERIC;
856     }
857   }
858 
859   return hr;
860 }
861 
862 static HRESULT WINAPI IDirectPlaySPImpl_SetSPData
863 ( LPDIRECTPLAYSP iface,
864   LPVOID lpData,
865   DWORD dwDataSize,
866   DWORD dwFlags
867 )
868 {
869   LPVOID lpSpData;
870 
871   IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
872 
873 /*  TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
874   TRACE( "(%p)->(%p,0x%08x,0x%08x)\n",
875          This, lpData, dwDataSize, dwFlags );
876 
877 #if 0
878   /* This is what the documentation says... */
879   if( dwFlags != DPSET_REMOTE )
880   {
881     return DPERR_INVALIDPARAMS;
882   }
883 #else
884   /* ... but most service providers call this with 1 */
885   /* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
886    * thing?
887    */
888   if( dwFlags != DPSET_REMOTE )
889   {
890     TRACE( "Undocumented dwFlags 0x%08x used\n", dwFlags );
891   }
892 #endif
893 
894   lpSpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
895   CopyMemory( lpSpData, lpData, dwDataSize );
896 
897   /* If we have data already allocated, free it and replace it */
898   if( dwFlags == DPSET_REMOTE )
899   {
900     HeapFree( GetProcessHeap(), 0, This->sp->lpSpRemoteData );
901     This->sp->dwSpRemoteDataSize = dwDataSize;
902     This->sp->lpSpRemoteData = lpSpData;
903   }
904   else if ( dwFlags == DPSET_LOCAL )
905   {
906     HeapFree( GetProcessHeap(), 0, This->sp->lpSpLocalData );
907     This->sp->lpSpLocalData     = lpSpData;
908     This->sp->dwSpLocalDataSize = dwDataSize;
909   }
910 
911   return DP_OK;
912 }
913 
914 static VOID WINAPI IDirectPlaySPImpl_SendComplete
915 ( LPDIRECTPLAYSP iface,
916   LPVOID unknownA,
917   DWORD unknownB
918 )
919 {
920   IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
921 
922   FIXME( "(%p)->(%p,0x%08x): stub\n",
923          This, unknownA, unknownB );
924 }
925 
926 static const IDirectPlaySPVtbl directPlaySPVT =
927 {
928 
929   DPSP_QueryInterface,
930   DPSP_AddRef,
931   DPSP_Release,
932 
933   IDirectPlaySPImpl_AddMRUEntry,
934   IDirectPlaySPImpl_CreateAddress,
935   IDirectPlaySPImpl_EnumAddress,
936   IDirectPlaySPImpl_EnumMRUEntries,
937   IDirectPlaySPImpl_GetPlayerFlags,
938   IDirectPlaySPImpl_GetSPPlayerData,
939   IDirectPlaySPImpl_HandleMessage,
940   IDirectPlaySPImpl_SetSPPlayerData,
941   IDirectPlaySPImpl_CreateCompoundAddress,
942   IDirectPlaySPImpl_GetSPData,
943   IDirectPlaySPImpl_SetSPData,
944   IDirectPlaySPImpl_SendComplete
945 };
946 
947 
948 /* DP external interfaces to call into DPSP interface */
949 
950 /* Allocate the structure */
951 LPVOID DPSP_CreateSPPlayerData(void)
952 {
953   TRACE( "Creating SPPlayer data struct\n" );
954   return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
955                     sizeof( DP_SPPLAYERDATA ) );
956 }
957 

~ [ 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.