1 /* This contains the implementation of the interface Service
2 * Providers require to communicate with Direct Play
4 * Copyright 2000 Peter Hunnisett <hunnise@nortelnetworks.com>
9 #include "debugtools.h"
13 #include "dplay_global.h"
14 #include "name_server.h"
15 #include "dplayx_messages.h"
17 #include "dplayx_global.h" /* FIXME: For global hack */
19 /* FIXME: Need to add interface locking inside procedures */
21 DEFAULT_DEBUG_CHANNEL(dplay)
24 static BOOL DPSP_CreateIUnknown( LPVOID lpSP );
25 static BOOL DPSP_DestroyIUnknown( LPVOID lpSP );
26 static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp );
27 static BOOL DPSP_DestroyDirectPlaySP( LPVOID lpSP );
30 /* Predefine the interface */
31 typedef struct IDirectPlaySPImpl IDirectPlaySPImpl;
33 typedef struct tagDirectPlaySPIUnknownData
36 CRITICAL_SECTION DPSP_lock;
37 } DirectPlaySPIUnknownData;
39 typedef struct tagDirectPlaySPData
41 LPVOID lpSpRemoteData;
42 DWORD dwSpRemoteDataSize; /* Size of data pointed to by lpSpRemoteData */
45 DWORD dwSpLocalDataSize; /* Size of data pointed to by lpSpLocalData */
47 IDirectPlay2Impl* dplay; /* FIXME: This should perhaps be iface not impl */
49 LPVOID lpPlayerData; /* FIXME: Need to figure out how this actually behaves */
50 DWORD dwPlayerDataSize;
53 #define DPSP_IMPL_FIELDS \
54 ULONG ulInterfaceRef; \
55 DirectPlaySPIUnknownData* unk; \
58 struct IDirectPlaySPImpl
60 ICOM_VFIELD(IDirectPlaySP);
64 /* Forward declaration of virtual tables */
65 static ICOM_VTABLE(IDirectPlaySP) directPlaySPVT;
69 /* Create the SP interface */
71 HRESULT DPSP_CreateInterface( REFIID riid, LPVOID* ppvObj, IDirectPlay2Impl* dp )
73 TRACE( " for %s\n", debugstr_guid( riid ) );
75 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
76 sizeof( IDirectPlaySPImpl ) );
80 return DPERR_OUTOFMEMORY;
83 if( IsEqualGUID( &IID_IDirectPlaySP, riid ) )
85 ICOM_THIS(IDirectPlaySPImpl,*ppvObj);
86 ICOM_VTBL(This) = &directPlaySPVT;
90 /* Unsupported interface */
91 HeapFree( GetProcessHeap(), 0, *ppvObj );
98 if( DPSP_CreateIUnknown( *ppvObj ) &&
99 DPSP_CreateDirectPlaySP( *ppvObj, dp )
102 IDirectPlaySP_AddRef( (LPDIRECTPLAYSP)*ppvObj );
106 /* Initialize failed, destroy it */
107 DPSP_DestroyDirectPlaySP( *ppvObj );
108 DPSP_DestroyIUnknown( *ppvObj );
110 HeapFree( GetProcessHeap(), 0, *ppvObj );
113 return DPERR_NOMEMORY;
116 static BOOL DPSP_CreateIUnknown( LPVOID lpSP )
118 ICOM_THIS(IDirectPlaySPImpl,lpSP);
120 This->unk = (DirectPlaySPIUnknownData*)HeapAlloc( GetProcessHeap(),
122 sizeof( *(This->unk) ) );
124 if ( This->unk == NULL )
129 InitializeCriticalSection( &This->unk->DPSP_lock );
134 static BOOL DPSP_DestroyIUnknown( LPVOID lpSP )
136 ICOM_THIS(IDirectPlaySPImpl,lpSP);
138 DeleteCriticalSection( &This->unk->DPSP_lock );
139 HeapFree( GetProcessHeap(), 0, This->unk );
145 static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp )
147 ICOM_THIS(IDirectPlaySPImpl,lpSP);
149 This->sp = (DirectPlaySPData*)HeapAlloc( GetProcessHeap(),
151 sizeof( *(This->sp) ) );
153 if ( This->sp == NULL )
158 This->sp->dplay = dp;
160 /* Normally we should be keeping a reference, but since only the dplay
161 * interface that created us can destroy us, we do not keep a reference
162 * to it (ie we'd be stuck with always having one reference to the dplay
163 * object, and hence us, around).
164 * NOTE: The dp object does reference count us.
166 /* IDirectPlayX_AddRef( (LPDIRECTPLAY2)dp ); */
171 static BOOL DPSP_DestroyDirectPlaySP( LPVOID lpSP )
173 ICOM_THIS(IDirectPlaySPImpl,lpSP);
175 /* Normally we should be keeping a reference, but since only the dplay
176 * interface that created us can destroy us, we do not keep a reference
177 * to it (ie we'd be stuck with always having one reference to the dplay
178 * object, and hence us, around).
179 * NOTE: The dp object does reference count us.
181 /*IDirectPlayX_Release( (LPDIRECTPLAY2)This->sp->dplay ); */
183 HeapFree( GetProcessHeap(), 0, This->sp->lpSpRemoteData );
184 HeapFree( GetProcessHeap(), 0, This->sp->lpSpLocalData );
186 /* FIXME: Need to delete player queue */
188 HeapFree( GetProcessHeap(), 0, This->sp );
192 /* Interface implementation */
194 static HRESULT WINAPI DPSP_QueryInterface
195 ( LPDIRECTPLAYSP iface,
199 ICOM_THIS(IDirectPlaySPImpl,iface);
200 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
202 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
203 sizeof( IDirectPlaySPImpl ) );
205 if( *ppvObj == NULL )
207 return DPERR_OUTOFMEMORY;
210 CopyMemory( *ppvObj, iface, sizeof( IDirectPlaySPImpl ) );
211 (*(IDirectPlaySPImpl**)ppvObj)->ulInterfaceRef = 0;
213 if( IsEqualGUID( &IID_IDirectPlaySP, riid ) )
215 ICOM_THIS(IDirectPlaySPImpl,*ppvObj);
216 ICOM_VTBL(This) = &directPlaySPVT;
220 /* Unsupported interface */
221 HeapFree( GetProcessHeap(), 0, *ppvObj );
224 return E_NOINTERFACE;
227 IDirectPlaySP_AddRef( (LPDIRECTPLAYSP)*ppvObj );
232 static ULONG WINAPI DPSP_AddRef
233 ( LPDIRECTPLAYSP iface )
235 ULONG ulInterfaceRefCount, ulObjRefCount;
236 ICOM_THIS(IDirectPlaySPImpl,iface);
238 ulObjRefCount = InterlockedIncrement( &This->unk->ulObjRef );
239 ulInterfaceRefCount = InterlockedIncrement( &This->ulInterfaceRef );
241 TRACE( "ref count incremented to %lu:%lu for %p\n",
242 ulInterfaceRefCount, ulObjRefCount, This );
244 return ulObjRefCount;
247 static ULONG WINAPI DPSP_Release
248 ( LPDIRECTPLAYSP iface )
250 ULONG ulInterfaceRefCount, ulObjRefCount;
251 ICOM_THIS(IDirectPlaySPImpl,iface);
253 ulObjRefCount = InterlockedDecrement( &This->unk->ulObjRef );
254 ulInterfaceRefCount = InterlockedDecrement( &This->ulInterfaceRef );
256 TRACE( "ref count decremented to %lu:%lu for %p\n",
257 ulInterfaceRefCount, ulObjRefCount, This );
259 /* Deallocate if this is the last reference to the object */
260 if( ulObjRefCount == 0 )
262 DPSP_DestroyDirectPlaySP( This );
263 DPSP_DestroyIUnknown( This );
266 if( ulInterfaceRefCount == 0 )
268 HeapFree( GetProcessHeap(), 0, This );
271 return ulInterfaceRefCount;
274 static HRESULT WINAPI IDirectPlaySPImpl_AddMRUEntry
275 ( LPDIRECTPLAYSP iface,
283 ICOM_THIS(IDirectPlaySPImpl,iface);
285 FIXME( "(%p)->(%p,%p%p,0x%08lx,0x%08lx): stub\n",
286 This, lpSection, lpKey, lpData, dwDataSize, dwMaxEntries );
291 static HRESULT WINAPI IDirectPlaySPImpl_CreateAddress
292 ( LPDIRECTPLAYSP iface,
294 REFGUID guidDataType,
298 LPDWORD lpdwAddressSize
301 ICOM_THIS(IDirectPlaySPImpl,iface);
303 FIXME( "(%p)->(%s,%s,%p,0x%08lx,%p,%p): stub\n",
304 This, debugstr_guid(guidSP), debugstr_guid(guidDataType),
305 lpData, dwDataSize, lpAddress, lpdwAddressSize );
310 static HRESULT WINAPI IDirectPlaySPImpl_EnumAddress
311 ( LPDIRECTPLAYSP iface,
312 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
318 ICOM_THIS(IDirectPlaySPImpl,iface);
320 TRACE( "(%p)->(%p,%p,0x%08lx,%p)\n",
321 This, lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext );
323 DPL_EnumAddress( lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext );
328 static HRESULT WINAPI IDirectPlaySPImpl_EnumMRUEntries
329 ( LPDIRECTPLAYSP iface,
332 LPENUMMRUCALLBACK lpEnumMRUCallback,
336 ICOM_THIS(IDirectPlaySPImpl,iface);
338 FIXME( "(%p)->(%p,%p,%p,%p,): stub\n",
339 This, lpSection, lpKey, lpEnumMRUCallback, lpContext );
344 static HRESULT WINAPI IDirectPlaySPImpl_GetPlayerFlags
345 ( LPDIRECTPLAYSP iface,
347 LPDWORD lpdwPlayerFlags
350 ICOM_THIS(IDirectPlaySPImpl,iface);
352 FIXME( "(%p)->(0x%08lx,%p): stub\n",
353 This, idPlayer, lpdwPlayerFlags );
358 static HRESULT WINAPI IDirectPlaySPImpl_GetSPPlayerData
359 ( LPDIRECTPLAYSP iface,
362 LPDWORD lpdwDataSize,
366 ICOM_THIS(IDirectPlaySPImpl,iface);
368 TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
369 FIXME( "(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n",
370 This, idPlayer, lplpData, lpdwDataSize, dwFlags );
372 /* What to do in the case where there is nothing set yet? */
374 *lplpData = This->sp->lpPlayerData;
375 *lpdwDataSize = This->sp->dwPlayerDataSize;
380 static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
381 ( LPDIRECTPLAYSP iface,
382 LPVOID lpMessageBody,
383 DWORD dwMessageBodySize,
384 LPVOID lpMessageHeader
387 LPDPMSG_SENDENVELOPE lpMsg = (LPDPMSG_SENDENVELOPE)lpMessageBody;
388 HRESULT hr = DPERR_GENERIC;
392 ICOM_THIS(IDirectPlaySPImpl,iface);
394 TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
395 FIXME( "(%p)->(%p,0x%08lx,%p): mostly stub\n",
396 This, lpMessageBody, dwMessageBodySize, lpMessageHeader );
398 wCommandId = lpMsg->wCommandId;
399 wVersion = lpMsg->wVersion;
401 TRACE( "Incomming message has envelope of 0x%08lx, %u, %u\n",
402 lpMsg->dwMagic, wCommandId, wVersion );
404 if( lpMsg->dwMagic != DPMSGMAGIC_DPLAYMSG )
406 ERR( "Unknown magic 0x%08lx!\n", lpMsg->dwMagic );
409 switch( lpMsg->wCommandId )
411 /* Name server needs to handle this request */
412 case DPMSGCMD_ENUMSESSIONSREQUEST:
416 data.lpSPMessageHeader = lpMessageHeader;
417 data.idNameServer = 0;
420 NS_ReplyToEnumSessionsRequest( lpMessageBody, &data, This->sp->dplay );
422 hr = (This->sp->dplay->dp2->spData.lpCB->Reply)( &data );
426 ERR( "Reply failed 0x%08lx\n", hr );
432 /* Name server needs to handle this request */
433 case DPMSGCMD_ENUMSESSIONSREPLY:
435 NS_SetRemoteComputerAsNameServer( lpMessageHeader,
436 This->sp->dplay->dp2->spData.dwSPHeaderSize,
437 (LPDPMSG_ENUMSESSIONSREPLY)lpMessageBody,
438 This->sp->dplay->dp2->lpNameServerData );
440 /* No reply expected */
445 case DPMSGCMD_GETNAMETABLE:
446 case DPMSGCMD_GETNAMETABLEREPLY:
447 case DPMSGCMD_NEWPLAYERIDREPLY:
448 case DPMSGCMD_REQUESTNEWPLAYERID:
452 data.lpMessage = NULL;
453 data.dwMessageSize = 0;
455 /* Pass this message to the dplay interface to handle */
456 DP_HandleMessage( This->sp->dplay, lpMessageBody, dwMessageBodySize,
457 lpMessageHeader, wCommandId, wVersion,
458 &data.lpMessage, &data.dwMessageSize );
460 /* Do we want a reply? */
461 if( data.lpMessage != NULL )
465 data.lpSPMessageHeader = lpMessageHeader;
466 data.idNameServer = 0;
469 hr = (This->sp->dplay->dp2->spData.lpCB->Reply)( &data );
473 ERR( "Reply failed %s\n", DPLAYX_HresultToString(hr) );
481 FIXME( "Unknown Command of %u and size 0x%08lx\n",
482 lpMsg->wCommandId, dwMessageBodySize );
487 HANDLE hReceiveEvent = 0;
488 /* FIXME: Aquire some sort of interface lock */
489 /* FIXME: Need some sort of context for this callback. Need to determine
490 * how this is actually done with the SP
492 /* FIXME: Who needs to delete the message when done? */
493 switch( lpMsg->dwType )
495 case DPSYS_CREATEPLAYERORGROUP:
497 LPDPMSG_CREATEPLAYERORGROUP msg = (LPDPMSG_CREATEPLAYERORGROUP)lpMsg;
499 if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
501 hr = DP_IF_CreatePlayer( This, lpMessageHeader, msg->dpId,
502 &msg->dpnName, 0, msg->lpData,
503 msg->dwDataSize, msg->dwFlags, ... );
505 else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
507 /* Group in group situation? */
508 if( msg->dpIdParent == DPID_NOPARENT_GROUP )
510 hr = DP_IF_CreateGroup( This, lpMessageHeader, msg->dpId,
511 &msg->dpnName, 0, msg->lpData,
512 msg->dwDataSize, msg->dwFlags, ... );
514 else /* Group in Group */
516 hr = DP_IF_CreateGroupInGroup( This, lpMessageHeader, msg->dpIdParent,
517 &msg->dpnName, 0, msg->lpData,
518 msg->dwDataSize, msg->dwFlags, ... );
523 ERR( "Corrupt msg->dwPlayerType for DPSYS_CREATEPLAYERORGROUP\n" );
530 case DPSYS_DESTROYPLAYERORGROUP:
532 LPDPMSG_DESTROYPLAYERORGROUP msg = (LPDPMSG_DESTROYPLAYERORGROUP)lpMsg;
534 if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
536 hr = DP_IF_DestroyPlayer( This, msg->dpId, ... );
538 else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
540 hr = DP_IF_DestroyGroup( This, msg->dpId, ... );
544 ERR( "Corrupt msg->dwPlayerType for DPSYS_DESTROYPLAYERORGROUP\n" );
551 case DPSYS_ADDPLAYERTOGROUP:
553 LPDPMSG_ADDPLAYERTOGROUP msg = (LPDPMSG_ADDPLAYERTOGROUP)lpMsg;
555 hr = DP_IF_AddPlayerToGroup( This, msg->dpIdGroup, msg->dpIdPlayer, ... );
559 case DPSYS_DELETEPLAYERFROMGROUP:
561 LPDPMSG_DELETEPLAYERFROMGROUP msg = (LPDPMSG_DELETEPLAYERFROMGROUP)lpMsg;
563 hr = DP_IF_DeletePlayerFromGroup( This, msg->dpIdGroup, msg->dpIdPlayer,
569 case DPSYS_SESSIONLOST:
571 LPDPMSG_SESSIONLOST msg = (LPDPMSG_SESSIONLOST)lpMsg;
573 FIXME( "DPSYS_SESSIONLOST not handled\n" );
580 LPDPMSG_HOST msg = (LPDPMSG_HOST)lpMsg;
582 FIXME( "DPSYS_HOST not handled\n" );
587 case DPSYS_SETPLAYERORGROUPDATA:
589 LPDPMSG_SETPLAYERORGROUPDATA msg = (LPDPMSG_SETPLAYERORGROUPDATA)lpMsg;
591 if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
593 hr = DP_IF_SetPlayerData( This, msg->dpId, msg->lpData, msg->dwDataSize, DPSET_REMOTE, ... );
595 else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
597 hr = DP_IF_SetGroupData( This, msg->dpId, msg->lpData, msg->dwDataSize,
602 ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" );
609 case DPSYS_SETPLAYERORGROUPNAME:
611 LPDPMSG_SETPLAYERORGROUPNAME msg = (LPDPMSG_SETPLAYERORGROUPNAME)lpMsg;
613 if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
615 hr = DP_IF_SetPlayerName( This, msg->dpId, msg->dpnName, ... );
617 else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
619 hr = DP_IF_SetGroupName( This, msg->dpId, msg->dpnName, ... );
623 ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" );
630 case DPSYS_SETSESSIONDESC;
632 LPDPMSG_SETSESSIONDESC msg = (LPDPMSG_SETSESSIONDESC)lpMsg;
634 hr = DP_IF_SetSessionDesc( This, &msg->dpDesc );
639 case DPSYS_ADDGROUPTOGROUP:
641 LPDPMSG_ADDGROUPTOGROUP msg = (LPDPMSG_ADDGROUPTOGROUP)lpMsg;
643 hr = DP_IF_AddGroupToGroup( This, msg->dpIdParentGroup, msg->dpIdGroup,
649 case DPSYS_DELETEGROUPFROMGROUP:
651 LPDPMSG_DELETEGROUPFROMGROUP msg = (LPDPMSG_DELETEGROUPFROMGROUP)lpMsg;
653 hr = DP_IF_DeleteGroupFromGroup( This, msg->dpIdParentGroup,
654 msg->dpIdGroup, ... );
659 case DPSYS_SECUREMESSAGE:
661 LPDPMSG_SECUREMESSAGE msg = (LPDPMSG_SECUREMESSAGE)lpMsg;
663 FIXME( "DPSYS_SECUREMESSAGE not implemented\n" );
668 case DPSYS_STARTSESSION:
670 LPDPMSG_STARTSESSION msg = (LPDPMSG_STARTSESSION)lpMsg;
672 FIXME( "DPSYS_STARTSESSION not implemented\n" );
679 LPDPMSG_CHAT msg = (LPDPMSG_CHAT)lpMsg;
681 FIXME( "DPSYS_CHAT not implemeneted\n" );
686 case DPSYS_SETGROUPOWNER:
688 LPDPMSG_SETGROUPOWNER msg = (LPDPMSG_SETGROUPOWNER)lpMsg;
690 FIXME( "DPSYS_SETGROUPOWNER not implemented\n" );
695 case DPSYS_SENDCOMPLETE:
697 LPDPMSG_SENDCOMPLETE msg = (LPDPMSG_SENDCOMPLETE)lpMsg;
699 FIXME( "DPSYS_SENDCOMPLETE not implemented\n" );
706 /* NOTE: This should be a user defined type. There is nothing that we
707 * need to do with it except queue it.
709 TRACE( "Received user message type(?) 0x%08lx through SP.\n",
715 FIXME( "Queue message in the receive queue. Need some context data!\n" );
719 ERR( "Unable to perform action for msg type 0x%08lx\n", lpMsg->dwType );
721 /* If a receieve event was registered for this player, invoke it */
724 SetEvent( hReceiveEvent );
731 static HRESULT WINAPI IDirectPlaySPImpl_SetSPPlayerData
732 ( LPDIRECTPLAYSP iface,
739 ICOM_THIS(IDirectPlaySPImpl,iface);
741 /* FIXME: I'm not sure if this stuff should be associated with the DPlay
742 * player lists. How else would this stuff get deleted?
745 TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
746 FIXME( "(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub\n",
747 This, idPlayer, lpData, dwDataSize, dwFlags );
749 This->sp->lpPlayerData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
751 This->sp->dwPlayerDataSize = dwDataSize;
752 CopyMemory( This->sp->lpPlayerData, lpData, dwDataSize );
757 static HRESULT WINAPI IDirectPlaySPImpl_CreateCompoundAddress
758 ( LPDIRECTPLAYSP iface,
759 LPCDPCOMPOUNDADDRESSELEMENT lpElements,
760 DWORD dwElementCount,
762 LPDWORD lpdwAddressSize
765 ICOM_THIS(IDirectPlaySPImpl,iface);
767 FIXME( "(%p)->(%p,0x%08lx,%p,%p): stub\n",
768 This, lpElements, dwElementCount, lpAddress, lpdwAddressSize );
773 static HRESULT WINAPI IDirectPlaySPImpl_GetSPData
774 ( LPDIRECTPLAYSP iface,
776 LPDWORD lpdwDataSize,
780 ICOM_THIS(IDirectPlaySPImpl,iface);
782 TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
783 TRACE( "(%p)->(%p,%p,0x%08lx)\n",
784 This, lplpData, lpdwDataSize, dwFlags );
787 /* This is what the documentation says... */
790 return DPERR_INVALIDPARAMS;
793 /* ... but most service providers call this with 1 */
794 /* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
799 FIXME( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
803 /* FIXME: What to do in the case where this isn't initialized yet? */
805 /* Yes, we're supposed to return a pointer to the memory we have stored! */
806 if( dwFlags == DPSET_REMOTE )
808 *lpdwDataSize = This->sp->dwSpRemoteDataSize;
809 *lplpData = This->sp->lpSpRemoteData;
811 else if( dwFlags == DPSET_LOCAL )
813 *lpdwDataSize = This->sp->dwSpLocalDataSize;
814 *lplpData = This->sp->lpSpLocalData;
820 static HRESULT WINAPI IDirectPlaySPImpl_SetSPData
821 ( LPDIRECTPLAYSP iface,
829 ICOM_THIS(IDirectPlaySPImpl,iface);
831 TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
832 TRACE( "(%p)->(%p,0x%08lx,0x%08lx)\n",
833 This, lpData, dwDataSize, dwFlags );
836 /* This is what the documentation says... */
839 return DPERR_INVALIDPARAMS;
842 /* ... but most service providers call this with 1 */
843 /* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
848 FIXME( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
852 if( dwFlags == DPSET_REMOTE )
854 lpSpData = DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY, dwDataSize );
858 lpSpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
861 CopyMemory( lpSpData, lpData, dwDataSize );
863 /* If we have data already allocated, free it and replace it */
864 if( dwFlags == DPSET_REMOTE )
866 /* FIXME: This doesn't strictly make sense as there is no means to share
867 * this shared data. Must be misinterpreting something...
869 if( This->sp->lpSpRemoteData )
871 DPLAYX_PrivHeapFree( This->sp->lpSpRemoteData );
874 /* NOTE: dwDataSize is also stored in the heap structure */
875 This->sp->dwSpRemoteDataSize = dwDataSize;
876 This->sp->lpSpRemoteData = lpSpData;
878 else if ( dwFlags == DPSET_LOCAL )
880 if( This->sp->lpSpLocalData )
882 HeapFree( GetProcessHeap(), 0, This->sp->lpSpLocalData );
885 This->sp->lpSpLocalData = lpSpData;
886 This->sp->dwSpLocalDataSize = dwDataSize;
892 static VOID WINAPI IDirectPlaySPImpl_SendComplete
893 ( LPDIRECTPLAYSP iface,
898 ICOM_THIS(IDirectPlaySPImpl,iface);
900 FIXME( "(%p)->(%p,0x%08lx): stub\n",
901 This, unknownA, unknownB );
905 static struct ICOM_VTABLE(IDirectPlaySP) directPlaySPVT =
907 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
913 IDirectPlaySPImpl_AddMRUEntry,
914 IDirectPlaySPImpl_CreateAddress,
915 IDirectPlaySPImpl_EnumAddress,
916 IDirectPlaySPImpl_EnumMRUEntries,
917 IDirectPlaySPImpl_GetPlayerFlags,
918 IDirectPlaySPImpl_GetSPPlayerData,
919 IDirectPlaySPImpl_HandleMessage,
920 IDirectPlaySPImpl_SetSPPlayerData,
921 IDirectPlaySPImpl_CreateCompoundAddress,
922 IDirectPlaySPImpl_GetSPData,
923 IDirectPlaySPImpl_SetSPData,
924 IDirectPlaySPImpl_SendComplete