1 /* This contains the implementation of the interface Service
2 * Providers require to communicate with Direct Play
4 * Copyright 2000 Peter Hunnisett
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.
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.
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
21 #include "dplayx_global.h"
23 /* FIXME: Need to add interface locking inside procedures */
26 static BOOL
DPSP_CreateIUnknown( LPVOID lpSP
);
27 static BOOL
DPSP_DestroyIUnknown( LPVOID lpSP
);
28 static BOOL
DPSP_CreateDirectPlaySP( void *lpSP
, IDirectPlayImpl
*dp
);
29 static BOOL
DPSP_DestroyDirectPlaySP( LPVOID lpSP
);
31 /* Predefine the interface */
32 typedef struct IDirectPlaySPImpl IDirectPlaySPImpl
;
34 typedef struct tagDirectPlaySPIUnknownData
37 CRITICAL_SECTION DPSP_lock
;
38 } DirectPlaySPIUnknownData
;
40 typedef struct tagDirectPlaySPData
42 LPVOID lpSpRemoteData
;
43 DWORD dwSpRemoteDataSize
; /* Size of data pointed to by lpSpRemoteData */
46 DWORD dwSpLocalDataSize
; /* Size of data pointed to by lpSpLocalData */
48 IDirectPlayImpl
*dplay
; /* FIXME: This should perhaps be iface not impl */
52 #define DPSP_IMPL_FIELDS \
53 LONG ulInterfaceRef; \
54 DirectPlaySPIUnknownData* unk; \
57 struct IDirectPlaySPImpl
59 const IDirectPlaySPVtbl
*lpVtbl
;
63 /* Forward declaration of virtual tables */
64 static const IDirectPlaySPVtbl directPlaySPVT
;
66 /* This structure is passed to the DP object for safe keeping */
67 typedef struct tagDP_SPPLAYERDATA
69 LPVOID lpPlayerLocalData
;
70 DWORD dwPlayerLocalDataSize
;
72 LPVOID lpPlayerRemoteData
;
73 DWORD dwPlayerRemoteDataSize
;
74 } DP_SPPLAYERDATA
, *LPDP_SPPLAYERDATA
;
76 /* Create the SP interface */
77 HRESULT
DPSP_CreateInterface( REFIID riid
, void **ppvObj
, IDirectPlayImpl
*dp
)
79 TRACE( " for %s\n", debugstr_guid( riid
) );
81 *ppvObj
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
82 sizeof( IDirectPlaySPImpl
) );
86 return DPERR_OUTOFMEMORY
;
89 if( IsEqualGUID( &IID_IDirectPlaySP
, riid
) )
91 IDirectPlaySPImpl
*This
= *ppvObj
;
92 This
->lpVtbl
= &directPlaySPVT
;
96 /* Unsupported interface */
97 HeapFree( GetProcessHeap(), 0, *ppvObj
);
100 return E_NOINTERFACE
;
104 if( DPSP_CreateIUnknown( *ppvObj
) &&
105 DPSP_CreateDirectPlaySP( *ppvObj
, dp
)
108 IDirectPlaySP_AddRef( (LPDIRECTPLAYSP
)*ppvObj
);
112 /* Initialize failed, destroy it */
113 DPSP_DestroyDirectPlaySP( *ppvObj
);
114 DPSP_DestroyIUnknown( *ppvObj
);
116 HeapFree( GetProcessHeap(), 0, *ppvObj
);
119 return DPERR_NOMEMORY
;
122 static BOOL
DPSP_CreateIUnknown( LPVOID lpSP
)
124 IDirectPlaySPImpl
*This
= lpSP
;
126 This
->unk
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *(This
->unk
) ) );
128 if ( This
->unk
== NULL
)
133 InitializeCriticalSection( &This
->unk
->DPSP_lock
);
134 This
->unk
->DPSP_lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": IDirectPlaySPImpl*->DirectPlaySPIUnknownData*->DPSP_lock");
139 static BOOL
DPSP_DestroyIUnknown( LPVOID lpSP
)
141 IDirectPlaySPImpl
*This
= lpSP
;
143 This
->unk
->DPSP_lock
.DebugInfo
->Spare
[0] = 0;
144 DeleteCriticalSection( &This
->unk
->DPSP_lock
);
145 HeapFree( GetProcessHeap(), 0, This
->unk
);
151 static BOOL
DPSP_CreateDirectPlaySP( void *lpSP
, IDirectPlayImpl
*dp
)
153 IDirectPlaySPImpl
*This
= lpSP
;
155 This
->sp
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *(This
->sp
) ) );
157 if ( This
->sp
== NULL
)
162 This
->sp
->dplay
= dp
;
167 static BOOL
DPSP_DestroyDirectPlaySP( LPVOID lpSP
)
169 IDirectPlaySPImpl
*This
= lpSP
;
171 HeapFree( GetProcessHeap(), 0, This
->sp
->lpSpRemoteData
);
172 HeapFree( GetProcessHeap(), 0, This
->sp
->lpSpLocalData
);
174 /* FIXME: Need to delete player queue */
176 HeapFree( GetProcessHeap(), 0, This
->sp
);
180 /* Interface implementation */
182 static HRESULT WINAPI DPSP_QueryInterface
183 ( LPDIRECTPLAYSP iface
,
187 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
188 TRACE("(%p)->(%s,%p)\n", This
, debugstr_guid( riid
), ppvObj
);
190 *ppvObj
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
193 if( *ppvObj
== NULL
)
195 return DPERR_OUTOFMEMORY
;
198 CopyMemory( *ppvObj
, This
, sizeof( *This
) );
199 (*(IDirectPlaySPImpl
**)ppvObj
)->ulInterfaceRef
= 0;
201 if( IsEqualGUID( &IID_IDirectPlaySP
, riid
) )
203 IDirectPlaySPImpl
*This
= *ppvObj
;
204 This
->lpVtbl
= &directPlaySPVT
;
208 /* Unsupported interface */
209 HeapFree( GetProcessHeap(), 0, *ppvObj
);
212 return E_NOINTERFACE
;
215 IDirectPlaySP_AddRef( (LPDIRECTPLAYSP
)*ppvObj
);
220 static ULONG WINAPI DPSP_AddRef
221 ( LPDIRECTPLAYSP iface
)
223 ULONG ulInterfaceRefCount
, ulObjRefCount
;
224 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
226 ulObjRefCount
= InterlockedIncrement( &This
->unk
->ulObjRef
);
227 ulInterfaceRefCount
= InterlockedIncrement( &This
->ulInterfaceRef
);
229 TRACE( "ref count incremented to %u:%u for %p\n",
230 ulInterfaceRefCount
, ulObjRefCount
, This
);
232 return ulObjRefCount
;
235 static ULONG WINAPI DPSP_Release
236 ( LPDIRECTPLAYSP iface
)
238 ULONG ulInterfaceRefCount
, ulObjRefCount
;
239 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
241 ulObjRefCount
= InterlockedDecrement( &This
->unk
->ulObjRef
);
242 ulInterfaceRefCount
= InterlockedDecrement( &This
->ulInterfaceRef
);
244 TRACE( "ref count decremented to %u:%u for %p\n",
245 ulInterfaceRefCount
, ulObjRefCount
, This
);
247 /* Deallocate if this is the last reference to the object */
248 if( ulObjRefCount
== 0 )
250 DPSP_DestroyDirectPlaySP( This
);
251 DPSP_DestroyIUnknown( This
);
254 if( ulInterfaceRefCount
== 0 )
256 HeapFree( GetProcessHeap(), 0, This
);
259 return ulInterfaceRefCount
;
262 static HRESULT WINAPI IDirectPlaySPImpl_AddMRUEntry
263 ( LPDIRECTPLAYSP iface
,
271 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
273 /* Should be able to call the comctl32 undocumented MRU routines.
274 I suspect that the interface works appropriately */
275 FIXME( "(%p)->(%p,%p%p,0x%08x,0x%08x): stub\n",
276 This
, lpSection
, lpKey
, lpData
, dwDataSize
, dwMaxEntries
);
281 static HRESULT WINAPI IDirectPlaySPImpl_CreateAddress
282 ( LPDIRECTPLAYSP iface
,
284 REFGUID guidDataType
,
288 LPDWORD lpdwAddressSize
291 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
293 FIXME( "(%p)->(%s,%s,%p,0x%08x,%p,%p): stub\n",
294 This
, debugstr_guid(guidSP
), debugstr_guid(guidDataType
),
295 lpData
, dwDataSize
, lpAddress
, lpdwAddressSize
);
300 static HRESULT WINAPI IDirectPlaySPImpl_EnumAddress
301 ( LPDIRECTPLAYSP iface
,
302 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
,
308 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
310 TRACE( "(%p)->(%p,%p,0x%08x,%p)\n",
311 This
, lpEnumAddressCallback
, lpAddress
, dwAddressSize
, lpContext
);
313 DPL_EnumAddress( lpEnumAddressCallback
, lpAddress
, dwAddressSize
, lpContext
);
318 static HRESULT WINAPI IDirectPlaySPImpl_EnumMRUEntries
319 ( LPDIRECTPLAYSP iface
,
322 LPENUMMRUCALLBACK lpEnumMRUCallback
,
326 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
328 /* Should be able to call the comctl32 undocumented MRU routines.
329 I suspect that the interface works appropriately */
330 FIXME( "(%p)->(%p,%p,%p,%p,): stub\n",
331 This
, lpSection
, lpKey
, lpEnumMRUCallback
, lpContext
);
336 static HRESULT WINAPI IDirectPlaySPImpl_GetPlayerFlags
337 ( LPDIRECTPLAYSP iface
,
339 LPDWORD lpdwPlayerFlags
342 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
344 FIXME( "(%p)->(0x%08x,%p): stub\n",
345 This
, idPlayer
, lpdwPlayerFlags
);
350 static HRESULT WINAPI IDirectPlaySPImpl_GetSPPlayerData
351 ( LPDIRECTPLAYSP iface
,
354 LPDWORD lpdwDataSize
,
359 LPDP_SPPLAYERDATA lpPlayerData
;
360 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
362 TRACE( "(%p)->(0x%08x,%p,%p,0x%08x)\n",
363 This
, idPlayer
, lplpData
, lpdwDataSize
, dwFlags
);
365 hr
= DP_GetSPPlayerData( This
->sp
->dplay
, idPlayer
, (LPVOID
*)&lpPlayerData
);
369 TRACE( "Couldn't get player data: %s\n", DPLAYX_HresultToString(hr
) );
370 return DPERR_INVALIDPLAYER
;
373 /* What to do in the case where there is nothing set yet? */
374 if( dwFlags
== DPSET_LOCAL
)
376 *lplpData
= lpPlayerData
->lpPlayerLocalData
;
377 *lpdwDataSize
= lpPlayerData
->dwPlayerLocalDataSize
;
379 else if( dwFlags
== DPSET_REMOTE
)
381 *lplpData
= lpPlayerData
->lpPlayerRemoteData
;
382 *lpdwDataSize
= lpPlayerData
->dwPlayerRemoteDataSize
;
385 if( *lplpData
== NULL
)
393 static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
394 ( LPDIRECTPLAYSP iface
,
395 LPVOID lpMessageBody
,
396 DWORD dwMessageBodySize
,
397 LPVOID lpMessageHeader
400 LPDPMSG_SENDENVELOPE lpMsg
= lpMessageBody
;
401 HRESULT hr
= DPERR_GENERIC
;
406 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
408 FIXME( "(%p)->(%p,0x%08x,%p): mostly stub\n",
409 This
, lpMessageBody
, dwMessageBodySize
, lpMessageHeader
);
411 wCommandId
= lpMsg
->wCommandId
;
412 wVersion
= lpMsg
->wVersion
;
414 TRACE( "Incoming message has envelope of 0x%08x, %u, %u\n",
415 lpMsg
->dwMagic
, wCommandId
, wVersion
);
417 if( lpMsg
->dwMagic
!= DPMSGMAGIC_DPLAYMSG
)
419 ERR( "Unknown magic 0x%08x!\n", lpMsg
->dwMagic
);
420 return DPERR_GENERIC
;
425 const LPDWORD lpcHeader
= lpMessageHeader
;
427 TRACE( "lpMessageHeader = [0x%08lx] [0x%08lx] [0x%08lx] [0x%08lx] [0x%08lx]\n",
428 lpcHeader
[0], lpcHeader
[1], lpcHeader
[2], lpcHeader
[3], lpcHeader
[4] );
432 /* Pass everything else to Direct Play */
433 data
.lpMessage
= NULL
;
434 data
.dwMessageSize
= 0;
436 /* Pass this message to the dplay interface to handle */
437 hr
= DP_HandleMessage( This
->sp
->dplay
, lpMessageBody
, dwMessageBodySize
,
438 lpMessageHeader
, wCommandId
, wVersion
,
439 &data
.lpMessage
, &data
.dwMessageSize
);
443 ERR( "Command processing failed %s\n", DPLAYX_HresultToString(hr
) );
446 /* Do we want a reply? */
447 if( data
.lpMessage
!= NULL
)
449 data
.lpSPMessageHeader
= lpMessageHeader
;
450 data
.idNameServer
= 0;
453 hr
= (This
->sp
->dplay
->dp2
->spData
.lpCB
->Reply
)( &data
);
457 ERR( "Reply failed %s\n", DPLAYX_HresultToString(hr
) );
465 HANDLE hReceiveEvent
= 0;
466 /* FIXME: Acquire some sort of interface lock */
467 /* FIXME: Need some sort of context for this callback. Need to determine
468 * how this is actually done with the SP
470 /* FIXME: Who needs to delete the message when done? */
471 switch( lpMsg
->dwType
)
473 case DPSYS_CREATEPLAYERORGROUP
:
475 LPDPMSG_CREATEPLAYERORGROUP msg
= lpMsg
;
477 if( msg
->dwPlayerType
== DPPLAYERTYPE_PLAYER
)
479 hr
= DP_IF_CreatePlayer( This
, lpMessageHeader
, msg
->dpId
,
480 &msg
->dpnName
, 0, msg
->lpData
,
481 msg
->dwDataSize
, msg
->dwFlags
, ... );
483 else if( msg
->dwPlayerType
== DPPLAYERTYPE_GROUP
)
485 /* Group in group situation? */
486 if( msg
->dpIdParent
== DPID_NOPARENT_GROUP
)
488 hr
= DP_IF_CreateGroup( This
, lpMessageHeader
, msg
->dpId
,
489 &msg
->dpnName
, 0, msg
->lpData
,
490 msg
->dwDataSize
, msg
->dwFlags
, ... );
492 else /* Group in Group */
494 hr
= DP_IF_CreateGroupInGroup( This
, lpMessageHeader
, msg
->dpIdParent
,
495 &msg
->dpnName
, 0, msg
->lpData
,
496 msg
->dwDataSize
, msg
->dwFlags
, ... );
501 ERR( "Corrupt msg->dwPlayerType for DPSYS_CREATEPLAYERORGROUP\n" );
508 case DPSYS_DESTROYPLAYERORGROUP
:
510 LPDPMSG_DESTROYPLAYERORGROUP msg
= lpMsg
;
512 if( msg
->dwPlayerType
== DPPLAYERTYPE_PLAYER
)
514 hr
= DP_IF_DestroyPlayer( This
, msg
->dpId
, ... );
516 else if( msg
->dwPlayerType
== DPPLAYERTYPE_GROUP
)
518 hr
= DP_IF_DestroyGroup( This
, msg
->dpId
, ... );
522 ERR( "Corrupt msg->dwPlayerType for DPSYS_DESTROYPLAYERORGROUP\n" );
529 case DPSYS_ADDPLAYERTOGROUP
:
531 LPDPMSG_ADDPLAYERTOGROUP msg
= lpMsg
;
533 hr
= DP_IF_AddPlayerToGroup( This
, msg
->dpIdGroup
, msg
->dpIdPlayer
, ... );
537 case DPSYS_DELETEPLAYERFROMGROUP
:
539 LPDPMSG_DELETEPLAYERFROMGROUP msg
= lpMsg
;
541 hr
= DP_IF_DeletePlayerFromGroup( This
, msg
->dpIdGroup
, msg
->dpIdPlayer
,
547 case DPSYS_SESSIONLOST
:
549 LPDPMSG_SESSIONLOST msg
= lpMsg
;
551 FIXME( "DPSYS_SESSIONLOST not handled\n" );
558 LPDPMSG_HOST msg
= lpMsg
;
560 FIXME( "DPSYS_HOST not handled\n" );
565 case DPSYS_SETPLAYERORGROUPDATA
:
567 LPDPMSG_SETPLAYERORGROUPDATA msg
= lpMsg
;
569 if( msg
->dwPlayerType
== DPPLAYERTYPE_PLAYER
)
571 hr
= DP_IF_SetPlayerData( This
, msg
->dpId
, msg
->lpData
, msg
->dwDataSize
, DPSET_REMOTE
, ... );
573 else if( msg
->dwPlayerType
== DPPLAYERTYPE_GROUP
)
575 hr
= DP_IF_SetGroupData( This
, msg
->dpId
, msg
->lpData
, msg
->dwDataSize
,
580 ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" );
587 case DPSYS_SETPLAYERORGROUPNAME
:
589 LPDPMSG_SETPLAYERORGROUPNAME msg
= lpMsg
;
591 if( msg
->dwPlayerType
== DPPLAYERTYPE_PLAYER
)
593 hr
= DP_IF_SetPlayerName( This
, msg
->dpId
, msg
->dpnName
, ... );
595 else if( msg
->dwPlayerType
== DPPLAYERTYPE_GROUP
)
597 hr
= DP_IF_SetGroupName( This
, msg
->dpId
, msg
->dpnName
, ... );
601 ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" );
608 case DPSYS_SETSESSIONDESC
;
610 LPDPMSG_SETSESSIONDESC msg
= lpMsg
;
612 hr
= DP_IF_SetSessionDesc( This
, &msg
->dpDesc
);
617 case DPSYS_ADDGROUPTOGROUP
:
619 LPDPMSG_ADDGROUPTOGROUP msg
= lpMsg
;
621 hr
= DP_IF_AddGroupToGroup( This
, msg
->dpIdParentGroup
, msg
->dpIdGroup
,
627 case DPSYS_DELETEGROUPFROMGROUP
:
629 LPDPMSG_DELETEGROUPFROMGROUP msg
= lpMsg
;
631 hr
= DP_IF_DeleteGroupFromGroup( This
, msg
->dpIdParentGroup
,
632 msg
->dpIdGroup
, ... );
637 case DPSYS_SECUREMESSAGE
:
639 LPDPMSG_SECUREMESSAGE msg
= lpMsg
;
641 FIXME( "DPSYS_SECUREMESSAGE not implemented\n" );
646 case DPSYS_STARTSESSION
:
648 LPDPMSG_STARTSESSION msg
= lpMsg
;
650 FIXME( "DPSYS_STARTSESSION not implemented\n" );
657 LPDPMSG_CHAT msg
= lpMsg
;
659 FIXME( "DPSYS_CHAT not implemeneted\n" );
664 case DPSYS_SETGROUPOWNER
:
666 LPDPMSG_SETGROUPOWNER msg
= lpMsg
;
668 FIXME( "DPSYS_SETGROUPOWNER not implemented\n" );
673 case DPSYS_SENDCOMPLETE
:
675 LPDPMSG_SENDCOMPLETE msg
= lpMsg
;
677 FIXME( "DPSYS_SENDCOMPLETE not implemented\n" );
684 /* NOTE: This should be a user defined type. There is nothing that we
685 * need to do with it except queue it.
687 TRACE( "Received user message type(?) 0x%08lx through SP.\n",
693 FIXME( "Queue message in the receive queue. Need some context data!\n" );
697 ERR( "Unable to perform action for msg type 0x%08lx\n", lpMsg
->dwType
);
699 /* If a receive event was registered for this player, invoke it */
702 SetEvent( hReceiveEvent
);
707 static HRESULT WINAPI IDirectPlaySPImpl_SetSPPlayerData
708 ( LPDIRECTPLAYSP iface
,
716 LPDP_SPPLAYERDATA lpPlayerEntry
;
719 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
721 /* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
722 TRACE( "(%p)->(0x%08x,%p,0x%08x,0x%08x)\n",
723 This
, idPlayer
, lpData
, dwDataSize
, dwFlags
);
725 hr
= DP_GetSPPlayerData( This
->sp
->dplay
, idPlayer
, (LPVOID
*)&lpPlayerEntry
);
728 /* Player must not exist */
729 return DPERR_INVALIDPLAYER
;
732 lpPlayerData
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDataSize
);
733 CopyMemory( lpPlayerData
, lpData
, dwDataSize
);
735 if( dwFlags
== DPSET_LOCAL
)
737 lpPlayerEntry
->lpPlayerLocalData
= lpPlayerData
;
738 lpPlayerEntry
->dwPlayerLocalDataSize
= dwDataSize
;
740 else if( dwFlags
== DPSET_REMOTE
)
742 lpPlayerEntry
->lpPlayerRemoteData
= lpPlayerData
;
743 lpPlayerEntry
->dwPlayerRemoteDataSize
= dwDataSize
;
746 hr
= DP_SetSPPlayerData( This
->sp
->dplay
, idPlayer
, lpPlayerEntry
);
751 static HRESULT WINAPI IDirectPlaySPImpl_CreateCompoundAddress
752 ( LPDIRECTPLAYSP iface
,
753 LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
754 DWORD dwElementCount
,
756 LPDWORD lpdwAddressSize
759 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
761 FIXME( "(%p)->(%p,0x%08x,%p,%p): stub\n",
762 This
, lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
);
767 static HRESULT WINAPI IDirectPlaySPImpl_GetSPData
768 ( LPDIRECTPLAYSP iface
,
770 LPDWORD lpdwDataSize
,
775 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
777 /* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
778 TRACE( "(%p)->(%p,%p,0x%08x)\n",
779 This
, lplpData
, lpdwDataSize
, dwFlags
);
782 /* This is what the documentation says... */
783 if( dwFlags
!= DPSET_REMOTE
)
785 return DPERR_INVALIDPARAMS
;
788 /* ... but most service providers call this with 1 */
789 /* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
792 if( dwFlags
!= DPSET_REMOTE
)
794 TRACE( "Undocumented dwFlags 0x%08x used\n", dwFlags
);
798 /* FIXME: What to do in the case where this isn't initialized yet? */
800 /* Yes, we're supposed to return a pointer to the memory we have stored! */
801 if( dwFlags
== DPSET_REMOTE
)
803 *lpdwDataSize
= This
->sp
->dwSpRemoteDataSize
;
804 *lplpData
= This
->sp
->lpSpRemoteData
;
806 if( This
->sp
->lpSpRemoteData
== NULL
)
811 else if( dwFlags
== DPSET_LOCAL
)
813 *lpdwDataSize
= This
->sp
->dwSpLocalDataSize
;
814 *lplpData
= This
->sp
->lpSpLocalData
;
816 if( This
->sp
->lpSpLocalData
== NULL
)
825 static HRESULT WINAPI IDirectPlaySPImpl_SetSPData
826 ( LPDIRECTPLAYSP iface
,
834 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
836 /* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
837 TRACE( "(%p)->(%p,0x%08x,0x%08x)\n",
838 This
, lpData
, dwDataSize
, dwFlags
);
841 /* This is what the documentation says... */
842 if( dwFlags
!= DPSET_REMOTE
)
844 return DPERR_INVALIDPARAMS
;
847 /* ... but most service providers call this with 1 */
848 /* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
851 if( dwFlags
!= DPSET_REMOTE
)
853 TRACE( "Undocumented dwFlags 0x%08x used\n", dwFlags
);
857 lpSpData
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDataSize
);
858 CopyMemory( lpSpData
, lpData
, dwDataSize
);
860 /* If we have data already allocated, free it and replace it */
861 if( dwFlags
== DPSET_REMOTE
)
863 HeapFree( GetProcessHeap(), 0, This
->sp
->lpSpRemoteData
);
864 This
->sp
->dwSpRemoteDataSize
= dwDataSize
;
865 This
->sp
->lpSpRemoteData
= lpSpData
;
867 else if ( dwFlags
== DPSET_LOCAL
)
869 HeapFree( GetProcessHeap(), 0, This
->sp
->lpSpLocalData
);
870 This
->sp
->lpSpLocalData
= lpSpData
;
871 This
->sp
->dwSpLocalDataSize
= dwDataSize
;
877 static VOID WINAPI IDirectPlaySPImpl_SendComplete
878 ( LPDIRECTPLAYSP iface
,
883 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
885 FIXME( "(%p)->(%p,0x%08x): stub\n",
886 This
, unknownA
, unknownB
);
889 static const IDirectPlaySPVtbl directPlaySPVT
=
896 IDirectPlaySPImpl_AddMRUEntry
,
897 IDirectPlaySPImpl_CreateAddress
,
898 IDirectPlaySPImpl_EnumAddress
,
899 IDirectPlaySPImpl_EnumMRUEntries
,
900 IDirectPlaySPImpl_GetPlayerFlags
,
901 IDirectPlaySPImpl_GetSPPlayerData
,
902 IDirectPlaySPImpl_HandleMessage
,
903 IDirectPlaySPImpl_SetSPPlayerData
,
904 IDirectPlaySPImpl_CreateCompoundAddress
,
905 IDirectPlaySPImpl_GetSPData
,
906 IDirectPlaySPImpl_SetSPData
,
907 IDirectPlaySPImpl_SendComplete
911 /* DP external interfaces to call into DPSP interface */
913 /* Allocate the structure */
914 LPVOID
DPSP_CreateSPPlayerData(void)
916 TRACE( "Creating SPPlayer data struct\n" );
917 return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
918 sizeof( DP_SPPLAYERDATA
) );