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
23 #include "wine/debug.h"
25 #include "wine/dplaysp.h"
26 #include "dplay_global.h"
27 #include "name_server.h"
28 #include "dplayx_messages.h"
30 #include "dplayx_global.h" /* FIXME: For global hack */
32 /* FIXME: Need to add interface locking inside procedures */
34 WINE_DEFAULT_DEBUG_CHANNEL(dplay
);
37 static BOOL
DPSP_CreateIUnknown( LPVOID lpSP
);
38 static BOOL
DPSP_DestroyIUnknown( LPVOID lpSP
);
39 static BOOL
DPSP_CreateDirectPlaySP( void *lpSP
, IDirectPlayImpl
*dp
);
40 static BOOL
DPSP_DestroyDirectPlaySP( LPVOID lpSP
);
42 /* Predefine the interface */
43 typedef struct IDirectPlaySPImpl IDirectPlaySPImpl
;
45 typedef struct tagDirectPlaySPIUnknownData
48 CRITICAL_SECTION DPSP_lock
;
49 } DirectPlaySPIUnknownData
;
51 typedef struct tagDirectPlaySPData
53 LPVOID lpSpRemoteData
;
54 DWORD dwSpRemoteDataSize
; /* Size of data pointed to by lpSpRemoteData */
57 DWORD dwSpLocalDataSize
; /* Size of data pointed to by lpSpLocalData */
59 IDirectPlayImpl
*dplay
; /* FIXME: This should perhaps be iface not impl */
63 #define DPSP_IMPL_FIELDS \
64 LONG ulInterfaceRef; \
65 DirectPlaySPIUnknownData* unk; \
68 struct IDirectPlaySPImpl
70 const IDirectPlaySPVtbl
*lpVtbl
;
74 /* Forward declaration of virtual tables */
75 static const IDirectPlaySPVtbl directPlaySPVT
;
77 /* This structure is passed to the DP object for safe keeping */
78 typedef struct tagDP_SPPLAYERDATA
80 LPVOID lpPlayerLocalData
;
81 DWORD dwPlayerLocalDataSize
;
83 LPVOID lpPlayerRemoteData
;
84 DWORD dwPlayerRemoteDataSize
;
85 } DP_SPPLAYERDATA
, *LPDP_SPPLAYERDATA
;
87 /* Create the SP interface */
88 HRESULT
DPSP_CreateInterface( REFIID riid
, void **ppvObj
, IDirectPlayImpl
*dp
)
90 TRACE( " for %s\n", debugstr_guid( riid
) );
92 *ppvObj
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
93 sizeof( IDirectPlaySPImpl
) );
97 return DPERR_OUTOFMEMORY
;
100 if( IsEqualGUID( &IID_IDirectPlaySP
, riid
) )
102 IDirectPlaySPImpl
*This
= *ppvObj
;
103 This
->lpVtbl
= &directPlaySPVT
;
107 /* Unsupported interface */
108 HeapFree( GetProcessHeap(), 0, *ppvObj
);
111 return E_NOINTERFACE
;
115 if( DPSP_CreateIUnknown( *ppvObj
) &&
116 DPSP_CreateDirectPlaySP( *ppvObj
, dp
)
119 IDirectPlaySP_AddRef( (LPDIRECTPLAYSP
)*ppvObj
);
123 /* Initialize failed, destroy it */
124 DPSP_DestroyDirectPlaySP( *ppvObj
);
125 DPSP_DestroyIUnknown( *ppvObj
);
127 HeapFree( GetProcessHeap(), 0, *ppvObj
);
130 return DPERR_NOMEMORY
;
133 static BOOL
DPSP_CreateIUnknown( LPVOID lpSP
)
135 IDirectPlaySPImpl
*This
= lpSP
;
137 This
->unk
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *(This
->unk
) ) );
139 if ( This
->unk
== NULL
)
144 InitializeCriticalSection( &This
->unk
->DPSP_lock
);
145 This
->unk
->DPSP_lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": IDirectPlaySPImpl*->DirectPlaySPIUnknownData*->DPSP_lock");
150 static BOOL
DPSP_DestroyIUnknown( LPVOID lpSP
)
152 IDirectPlaySPImpl
*This
= lpSP
;
154 This
->unk
->DPSP_lock
.DebugInfo
->Spare
[0] = 0;
155 DeleteCriticalSection( &This
->unk
->DPSP_lock
);
156 HeapFree( GetProcessHeap(), 0, This
->unk
);
162 static BOOL
DPSP_CreateDirectPlaySP( void *lpSP
, IDirectPlayImpl
*dp
)
164 IDirectPlaySPImpl
*This
= lpSP
;
166 This
->sp
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *(This
->sp
) ) );
168 if ( This
->sp
== NULL
)
173 This
->sp
->dplay
= dp
;
178 static BOOL
DPSP_DestroyDirectPlaySP( LPVOID lpSP
)
180 IDirectPlaySPImpl
*This
= lpSP
;
182 HeapFree( GetProcessHeap(), 0, This
->sp
->lpSpRemoteData
);
183 HeapFree( GetProcessHeap(), 0, This
->sp
->lpSpLocalData
);
185 /* FIXME: Need to delete player queue */
187 HeapFree( GetProcessHeap(), 0, This
->sp
);
191 /* Interface implementation */
193 static HRESULT WINAPI DPSP_QueryInterface
194 ( LPDIRECTPLAYSP iface
,
198 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
199 TRACE("(%p)->(%s,%p)\n", This
, debugstr_guid( riid
), ppvObj
);
201 *ppvObj
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
204 if( *ppvObj
== NULL
)
206 return DPERR_OUTOFMEMORY
;
209 CopyMemory( *ppvObj
, This
, sizeof( *This
) );
210 (*(IDirectPlaySPImpl
**)ppvObj
)->ulInterfaceRef
= 0;
212 if( IsEqualGUID( &IID_IDirectPlaySP
, riid
) )
214 IDirectPlaySPImpl
*This
= *ppvObj
;
215 This
->lpVtbl
= &directPlaySPVT
;
219 /* Unsupported interface */
220 HeapFree( GetProcessHeap(), 0, *ppvObj
);
223 return E_NOINTERFACE
;
226 IDirectPlaySP_AddRef( (LPDIRECTPLAYSP
)*ppvObj
);
231 static ULONG WINAPI DPSP_AddRef
232 ( LPDIRECTPLAYSP iface
)
234 ULONG ulInterfaceRefCount
, ulObjRefCount
;
235 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
237 ulObjRefCount
= InterlockedIncrement( &This
->unk
->ulObjRef
);
238 ulInterfaceRefCount
= InterlockedIncrement( &This
->ulInterfaceRef
);
240 TRACE( "ref count incremented to %u:%u for %p\n",
241 ulInterfaceRefCount
, ulObjRefCount
, This
);
243 return ulObjRefCount
;
246 static ULONG WINAPI DPSP_Release
247 ( LPDIRECTPLAYSP iface
)
249 ULONG ulInterfaceRefCount
, ulObjRefCount
;
250 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
252 ulObjRefCount
= InterlockedDecrement( &This
->unk
->ulObjRef
);
253 ulInterfaceRefCount
= InterlockedDecrement( &This
->ulInterfaceRef
);
255 TRACE( "ref count decremented to %u:%u for %p\n",
256 ulInterfaceRefCount
, ulObjRefCount
, This
);
258 /* Deallocate if this is the last reference to the object */
259 if( ulObjRefCount
== 0 )
261 DPSP_DestroyDirectPlaySP( This
);
262 DPSP_DestroyIUnknown( This
);
265 if( ulInterfaceRefCount
== 0 )
267 HeapFree( GetProcessHeap(), 0, This
);
270 return ulInterfaceRefCount
;
273 static HRESULT WINAPI IDirectPlaySPImpl_AddMRUEntry
274 ( LPDIRECTPLAYSP iface
,
282 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
284 /* Should be able to call the comctl32 undocumented MRU routines.
285 I suspect that the interface works appropriately */
286 FIXME( "(%p)->(%p,%p%p,0x%08x,0x%08x): stub\n",
287 This
, lpSection
, lpKey
, lpData
, dwDataSize
, dwMaxEntries
);
292 static HRESULT WINAPI IDirectPlaySPImpl_CreateAddress
293 ( LPDIRECTPLAYSP iface
,
295 REFGUID guidDataType
,
299 LPDWORD lpdwAddressSize
302 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
304 FIXME( "(%p)->(%s,%s,%p,0x%08x,%p,%p): stub\n",
305 This
, debugstr_guid(guidSP
), debugstr_guid(guidDataType
),
306 lpData
, dwDataSize
, lpAddress
, lpdwAddressSize
);
311 static HRESULT WINAPI IDirectPlaySPImpl_EnumAddress
312 ( LPDIRECTPLAYSP iface
,
313 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
,
319 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
321 TRACE( "(%p)->(%p,%p,0x%08x,%p)\n",
322 This
, lpEnumAddressCallback
, lpAddress
, dwAddressSize
, lpContext
);
324 DPL_EnumAddress( lpEnumAddressCallback
, lpAddress
, dwAddressSize
, lpContext
);
329 static HRESULT WINAPI IDirectPlaySPImpl_EnumMRUEntries
330 ( LPDIRECTPLAYSP iface
,
333 LPENUMMRUCALLBACK lpEnumMRUCallback
,
337 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
339 /* Should be able to call the comctl32 undocumented MRU routines.
340 I suspect that the interface works appropriately */
341 FIXME( "(%p)->(%p,%p,%p,%p,): stub\n",
342 This
, lpSection
, lpKey
, lpEnumMRUCallback
, lpContext
);
347 static HRESULT WINAPI IDirectPlaySPImpl_GetPlayerFlags
348 ( LPDIRECTPLAYSP iface
,
350 LPDWORD lpdwPlayerFlags
353 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
355 FIXME( "(%p)->(0x%08x,%p): stub\n",
356 This
, idPlayer
, lpdwPlayerFlags
);
361 static HRESULT WINAPI IDirectPlaySPImpl_GetSPPlayerData
362 ( LPDIRECTPLAYSP iface
,
365 LPDWORD lpdwDataSize
,
370 LPDP_SPPLAYERDATA lpPlayerData
;
371 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
373 TRACE( "(%p)->(0x%08x,%p,%p,0x%08x)\n",
374 This
, idPlayer
, lplpData
, lpdwDataSize
, dwFlags
);
376 hr
= DP_GetSPPlayerData( This
->sp
->dplay
, idPlayer
, (LPVOID
*)&lpPlayerData
);
380 TRACE( "Couldn't get player data: %s\n", DPLAYX_HresultToString(hr
) );
381 return DPERR_INVALIDPLAYER
;
384 /* What to do in the case where there is nothing set yet? */
385 if( dwFlags
== DPSET_LOCAL
)
387 *lplpData
= lpPlayerData
->lpPlayerLocalData
;
388 *lpdwDataSize
= lpPlayerData
->dwPlayerLocalDataSize
;
390 else if( dwFlags
== DPSET_REMOTE
)
392 *lplpData
= lpPlayerData
->lpPlayerRemoteData
;
393 *lpdwDataSize
= lpPlayerData
->dwPlayerRemoteDataSize
;
396 if( *lplpData
== NULL
)
404 static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
405 ( LPDIRECTPLAYSP iface
,
406 LPVOID lpMessageBody
,
407 DWORD dwMessageBodySize
,
408 LPVOID lpMessageHeader
411 LPDPMSG_SENDENVELOPE lpMsg
= lpMessageBody
;
412 HRESULT hr
= DPERR_GENERIC
;
417 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
419 FIXME( "(%p)->(%p,0x%08x,%p): mostly stub\n",
420 This
, lpMessageBody
, dwMessageBodySize
, lpMessageHeader
);
422 wCommandId
= lpMsg
->wCommandId
;
423 wVersion
= lpMsg
->wVersion
;
425 TRACE( "Incoming message has envelope of 0x%08x, %u, %u\n",
426 lpMsg
->dwMagic
, wCommandId
, wVersion
);
428 if( lpMsg
->dwMagic
!= DPMSGMAGIC_DPLAYMSG
)
430 ERR( "Unknown magic 0x%08x!\n", lpMsg
->dwMagic
);
431 return DPERR_GENERIC
;
436 const LPDWORD lpcHeader
= lpMessageHeader
;
438 TRACE( "lpMessageHeader = [0x%08lx] [0x%08lx] [0x%08lx] [0x%08lx] [0x%08lx]\n",
439 lpcHeader
[0], lpcHeader
[1], lpcHeader
[2], lpcHeader
[3], lpcHeader
[4] );
443 /* Pass everything else to Direct Play */
444 data
.lpMessage
= NULL
;
445 data
.dwMessageSize
= 0;
447 /* Pass this message to the dplay interface to handle */
448 hr
= DP_HandleMessage( This
->sp
->dplay
, lpMessageBody
, dwMessageBodySize
,
449 lpMessageHeader
, wCommandId
, wVersion
,
450 &data
.lpMessage
, &data
.dwMessageSize
);
454 ERR( "Command processing failed %s\n", DPLAYX_HresultToString(hr
) );
457 /* Do we want a reply? */
458 if( data
.lpMessage
!= NULL
)
460 data
.lpSPMessageHeader
= lpMessageHeader
;
461 data
.idNameServer
= 0;
464 hr
= (This
->sp
->dplay
->dp2
->spData
.lpCB
->Reply
)( &data
);
468 ERR( "Reply failed %s\n", DPLAYX_HresultToString(hr
) );
476 HANDLE hReceiveEvent
= 0;
477 /* FIXME: Acquire some sort of interface lock */
478 /* FIXME: Need some sort of context for this callback. Need to determine
479 * how this is actually done with the SP
481 /* FIXME: Who needs to delete the message when done? */
482 switch( lpMsg
->dwType
)
484 case DPSYS_CREATEPLAYERORGROUP
:
486 LPDPMSG_CREATEPLAYERORGROUP msg
= lpMsg
;
488 if( msg
->dwPlayerType
== DPPLAYERTYPE_PLAYER
)
490 hr
= DP_IF_CreatePlayer( This
, lpMessageHeader
, msg
->dpId
,
491 &msg
->dpnName
, 0, msg
->lpData
,
492 msg
->dwDataSize
, msg
->dwFlags
, ... );
494 else if( msg
->dwPlayerType
== DPPLAYERTYPE_GROUP
)
496 /* Group in group situation? */
497 if( msg
->dpIdParent
== DPID_NOPARENT_GROUP
)
499 hr
= DP_IF_CreateGroup( This
, lpMessageHeader
, msg
->dpId
,
500 &msg
->dpnName
, 0, msg
->lpData
,
501 msg
->dwDataSize
, msg
->dwFlags
, ... );
503 else /* Group in Group */
505 hr
= DP_IF_CreateGroupInGroup( This
, lpMessageHeader
, msg
->dpIdParent
,
506 &msg
->dpnName
, 0, msg
->lpData
,
507 msg
->dwDataSize
, msg
->dwFlags
, ... );
512 ERR( "Corrupt msg->dwPlayerType for DPSYS_CREATEPLAYERORGROUP\n" );
519 case DPSYS_DESTROYPLAYERORGROUP
:
521 LPDPMSG_DESTROYPLAYERORGROUP msg
= lpMsg
;
523 if( msg
->dwPlayerType
== DPPLAYERTYPE_PLAYER
)
525 hr
= DP_IF_DestroyPlayer( This
, msg
->dpId
, ... );
527 else if( msg
->dwPlayerType
== DPPLAYERTYPE_GROUP
)
529 hr
= DP_IF_DestroyGroup( This
, msg
->dpId
, ... );
533 ERR( "Corrupt msg->dwPlayerType for DPSYS_DESTROYPLAYERORGROUP\n" );
540 case DPSYS_ADDPLAYERTOGROUP
:
542 LPDPMSG_ADDPLAYERTOGROUP msg
= lpMsg
;
544 hr
= DP_IF_AddPlayerToGroup( This
, msg
->dpIdGroup
, msg
->dpIdPlayer
, ... );
548 case DPSYS_DELETEPLAYERFROMGROUP
:
550 LPDPMSG_DELETEPLAYERFROMGROUP msg
= lpMsg
;
552 hr
= DP_IF_DeletePlayerFromGroup( This
, msg
->dpIdGroup
, msg
->dpIdPlayer
,
558 case DPSYS_SESSIONLOST
:
560 LPDPMSG_SESSIONLOST msg
= lpMsg
;
562 FIXME( "DPSYS_SESSIONLOST not handled\n" );
569 LPDPMSG_HOST msg
= lpMsg
;
571 FIXME( "DPSYS_HOST not handled\n" );
576 case DPSYS_SETPLAYERORGROUPDATA
:
578 LPDPMSG_SETPLAYERORGROUPDATA msg
= lpMsg
;
580 if( msg
->dwPlayerType
== DPPLAYERTYPE_PLAYER
)
582 hr
= DP_IF_SetPlayerData( This
, msg
->dpId
, msg
->lpData
, msg
->dwDataSize
, DPSET_REMOTE
, ... );
584 else if( msg
->dwPlayerType
== DPPLAYERTYPE_GROUP
)
586 hr
= DP_IF_SetGroupData( This
, msg
->dpId
, msg
->lpData
, msg
->dwDataSize
,
591 ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" );
598 case DPSYS_SETPLAYERORGROUPNAME
:
600 LPDPMSG_SETPLAYERORGROUPNAME msg
= lpMsg
;
602 if( msg
->dwPlayerType
== DPPLAYERTYPE_PLAYER
)
604 hr
= DP_IF_SetPlayerName( This
, msg
->dpId
, msg
->dpnName
, ... );
606 else if( msg
->dwPlayerType
== DPPLAYERTYPE_GROUP
)
608 hr
= DP_IF_SetGroupName( This
, msg
->dpId
, msg
->dpnName
, ... );
612 ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" );
619 case DPSYS_SETSESSIONDESC
;
621 LPDPMSG_SETSESSIONDESC msg
= lpMsg
;
623 hr
= DP_IF_SetSessionDesc( This
, &msg
->dpDesc
);
628 case DPSYS_ADDGROUPTOGROUP
:
630 LPDPMSG_ADDGROUPTOGROUP msg
= lpMsg
;
632 hr
= DP_IF_AddGroupToGroup( This
, msg
->dpIdParentGroup
, msg
->dpIdGroup
,
638 case DPSYS_DELETEGROUPFROMGROUP
:
640 LPDPMSG_DELETEGROUPFROMGROUP msg
= lpMsg
;
642 hr
= DP_IF_DeleteGroupFromGroup( This
, msg
->dpIdParentGroup
,
643 msg
->dpIdGroup
, ... );
648 case DPSYS_SECUREMESSAGE
:
650 LPDPMSG_SECUREMESSAGE msg
= lpMsg
;
652 FIXME( "DPSYS_SECUREMESSAGE not implemented\n" );
657 case DPSYS_STARTSESSION
:
659 LPDPMSG_STARTSESSION msg
= lpMsg
;
661 FIXME( "DPSYS_STARTSESSION not implemented\n" );
668 LPDPMSG_CHAT msg
= lpMsg
;
670 FIXME( "DPSYS_CHAT not implemeneted\n" );
675 case DPSYS_SETGROUPOWNER
:
677 LPDPMSG_SETGROUPOWNER msg
= lpMsg
;
679 FIXME( "DPSYS_SETGROUPOWNER not implemented\n" );
684 case DPSYS_SENDCOMPLETE
:
686 LPDPMSG_SENDCOMPLETE msg
= lpMsg
;
688 FIXME( "DPSYS_SENDCOMPLETE not implemented\n" );
695 /* NOTE: This should be a user defined type. There is nothing that we
696 * need to do with it except queue it.
698 TRACE( "Received user message type(?) 0x%08lx through SP.\n",
704 FIXME( "Queue message in the receive queue. Need some context data!\n" );
708 ERR( "Unable to perform action for msg type 0x%08lx\n", lpMsg
->dwType
);
710 /* If a receive event was registered for this player, invoke it */
713 SetEvent( hReceiveEvent
);
718 static HRESULT WINAPI IDirectPlaySPImpl_SetSPPlayerData
719 ( LPDIRECTPLAYSP iface
,
727 LPDP_SPPLAYERDATA lpPlayerEntry
;
730 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
732 /* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
733 TRACE( "(%p)->(0x%08x,%p,0x%08x,0x%08x)\n",
734 This
, idPlayer
, lpData
, dwDataSize
, dwFlags
);
736 hr
= DP_GetSPPlayerData( This
->sp
->dplay
, idPlayer
, (LPVOID
*)&lpPlayerEntry
);
739 /* Player must not exist */
740 return DPERR_INVALIDPLAYER
;
743 lpPlayerData
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDataSize
);
744 CopyMemory( lpPlayerData
, lpData
, dwDataSize
);
746 if( dwFlags
== DPSET_LOCAL
)
748 lpPlayerEntry
->lpPlayerLocalData
= lpPlayerData
;
749 lpPlayerEntry
->dwPlayerLocalDataSize
= dwDataSize
;
751 else if( dwFlags
== DPSET_REMOTE
)
753 lpPlayerEntry
->lpPlayerRemoteData
= lpPlayerData
;
754 lpPlayerEntry
->dwPlayerRemoteDataSize
= dwDataSize
;
757 hr
= DP_SetSPPlayerData( This
->sp
->dplay
, idPlayer
, lpPlayerEntry
);
762 static HRESULT WINAPI IDirectPlaySPImpl_CreateCompoundAddress
763 ( LPDIRECTPLAYSP iface
,
764 LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
765 DWORD dwElementCount
,
767 LPDWORD lpdwAddressSize
770 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
772 FIXME( "(%p)->(%p,0x%08x,%p,%p): stub\n",
773 This
, lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
);
778 static HRESULT WINAPI IDirectPlaySPImpl_GetSPData
779 ( LPDIRECTPLAYSP iface
,
781 LPDWORD lpdwDataSize
,
786 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
788 /* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
789 TRACE( "(%p)->(%p,%p,0x%08x)\n",
790 This
, lplpData
, lpdwDataSize
, dwFlags
);
793 /* This is what the documentation says... */
794 if( dwFlags
!= DPSET_REMOTE
)
796 return DPERR_INVALIDPARAMS
;
799 /* ... but most service providers call this with 1 */
800 /* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
803 if( dwFlags
!= DPSET_REMOTE
)
805 TRACE( "Undocumented dwFlags 0x%08x used\n", dwFlags
);
809 /* FIXME: What to do in the case where this isn't initialized yet? */
811 /* Yes, we're supposed to return a pointer to the memory we have stored! */
812 if( dwFlags
== DPSET_REMOTE
)
814 *lpdwDataSize
= This
->sp
->dwSpRemoteDataSize
;
815 *lplpData
= This
->sp
->lpSpRemoteData
;
817 if( This
->sp
->lpSpRemoteData
== NULL
)
822 else if( dwFlags
== DPSET_LOCAL
)
824 *lpdwDataSize
= This
->sp
->dwSpLocalDataSize
;
825 *lplpData
= This
->sp
->lpSpLocalData
;
827 if( This
->sp
->lpSpLocalData
== NULL
)
836 static HRESULT WINAPI IDirectPlaySPImpl_SetSPData
837 ( LPDIRECTPLAYSP iface
,
845 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
847 /* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
848 TRACE( "(%p)->(%p,0x%08x,0x%08x)\n",
849 This
, lpData
, dwDataSize
, dwFlags
);
852 /* This is what the documentation says... */
853 if( dwFlags
!= DPSET_REMOTE
)
855 return DPERR_INVALIDPARAMS
;
858 /* ... but most service providers call this with 1 */
859 /* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
862 if( dwFlags
!= DPSET_REMOTE
)
864 TRACE( "Undocumented dwFlags 0x%08x used\n", dwFlags
);
868 lpSpData
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDataSize
);
869 CopyMemory( lpSpData
, lpData
, dwDataSize
);
871 /* If we have data already allocated, free it and replace it */
872 if( dwFlags
== DPSET_REMOTE
)
874 HeapFree( GetProcessHeap(), 0, This
->sp
->lpSpRemoteData
);
875 This
->sp
->dwSpRemoteDataSize
= dwDataSize
;
876 This
->sp
->lpSpRemoteData
= lpSpData
;
878 else if ( dwFlags
== DPSET_LOCAL
)
880 HeapFree( GetProcessHeap(), 0, This
->sp
->lpSpLocalData
);
881 This
->sp
->lpSpLocalData
= lpSpData
;
882 This
->sp
->dwSpLocalDataSize
= dwDataSize
;
888 static VOID WINAPI IDirectPlaySPImpl_SendComplete
889 ( LPDIRECTPLAYSP iface
,
894 IDirectPlaySPImpl
*This
= (IDirectPlaySPImpl
*)iface
;
896 FIXME( "(%p)->(%p,0x%08x): stub\n",
897 This
, unknownA
, unknownB
);
900 static const IDirectPlaySPVtbl directPlaySPVT
=
907 IDirectPlaySPImpl_AddMRUEntry
,
908 IDirectPlaySPImpl_CreateAddress
,
909 IDirectPlaySPImpl_EnumAddress
,
910 IDirectPlaySPImpl_EnumMRUEntries
,
911 IDirectPlaySPImpl_GetPlayerFlags
,
912 IDirectPlaySPImpl_GetSPPlayerData
,
913 IDirectPlaySPImpl_HandleMessage
,
914 IDirectPlaySPImpl_SetSPPlayerData
,
915 IDirectPlaySPImpl_CreateCompoundAddress
,
916 IDirectPlaySPImpl_GetSPData
,
917 IDirectPlaySPImpl_SetSPData
,
918 IDirectPlaySPImpl_SendComplete
922 /* DP external interfaces to call into DPSP interface */
924 /* Allocate the structure */
925 LPVOID
DPSP_CreateSPPlayerData(void)
927 TRACE( "Creating SPPlayer data struct\n" );
928 return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
929 sizeof( DP_SPPLAYERDATA
) );