Gives back the ERROR_FILE_NOT_FOUND to GetFileAttributes.
[wine/gsoc_dplay.git] / dlls / dplayx / dplaysp.c
blob6fc0443d6627734fc940730d2801adaaac5747cb
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>
5 */
7 #include <string.h>
8 #include "heap.h"
9 #include "winerror.h"
10 #include "debugtools.h"
12 #include "dpinit.h"
13 #include "dplaysp.h"
14 #include "dplay_global.h"
15 #include "name_server.h"
16 #include "dplayx_messages.h"
18 #include "dplayx_global.h" /* FIXME: For global hack */
20 /* FIXME: Need to add interface locking inside procedures */
22 DEFAULT_DEBUG_CHANNEL(dplay);
24 /* Prototypes */
25 static BOOL DPSP_CreateIUnknown( LPVOID lpSP );
26 static BOOL DPSP_DestroyIUnknown( LPVOID lpSP );
27 static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp );
28 static BOOL DPSP_DestroyDirectPlaySP( LPVOID lpSP );
30 /* Predefine the interface */
31 typedef struct IDirectPlaySPImpl IDirectPlaySPImpl;
33 typedef struct tagDirectPlaySPIUnknownData
35 ULONG ulObjRef;
36 CRITICAL_SECTION DPSP_lock;
37 } DirectPlaySPIUnknownData;
39 typedef struct tagDirectPlaySPData
41 LPVOID lpSpRemoteData;
42 DWORD dwSpRemoteDataSize; /* Size of data pointed to by lpSpRemoteData */
44 LPVOID lpSpLocalData;
45 DWORD dwSpLocalDataSize; /* Size of data pointed to by lpSpLocalData */
47 IDirectPlay2Impl* dplay; /* FIXME: This should perhaps be iface not impl */
49 } DirectPlaySPData;
51 #define DPSP_IMPL_FIELDS \
52 ULONG ulInterfaceRef; \
53 DirectPlaySPIUnknownData* unk; \
54 DirectPlaySPData* sp;
56 struct IDirectPlaySPImpl
58 ICOM_VFIELD(IDirectPlaySP);
59 DPSP_IMPL_FIELDS
62 /* Forward declaration of virtual tables */
63 static ICOM_VTABLE(IDirectPlaySP) directPlaySPVT;
65 /* This structure is passed to the DP object for safe keeping */
66 typedef struct tagDP_SPPLAYERDATA
68 LPVOID lpPlayerLocalData;
69 DWORD dwPlayerLocalDataSize;
71 LPVOID lpPlayerRemoteData;
72 DWORD dwPlayerRemoteDataSize;
73 } DP_SPPLAYERDATA, *LPDP_SPPLAYERDATA;
75 /* Create the SP interface */
76 extern
77 HRESULT DPSP_CreateInterface( REFIID riid, LPVOID* ppvObj, IDirectPlay2Impl* dp )
79 TRACE( " for %s\n", debugstr_guid( riid ) );
81 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
82 sizeof( IDirectPlaySPImpl ) );
84 if( *ppvObj == NULL )
86 return DPERR_OUTOFMEMORY;
89 if( IsEqualGUID( &IID_IDirectPlaySP, riid ) )
91 ICOM_THIS(IDirectPlaySPImpl,*ppvObj);
92 ICOM_VTBL(This) = &directPlaySPVT;
94 else
96 /* Unsupported interface */
97 HeapFree( GetProcessHeap(), 0, *ppvObj );
98 *ppvObj = NULL;
100 return E_NOINTERFACE;
103 /* Initialize it */
104 if( DPSP_CreateIUnknown( *ppvObj ) &&
105 DPSP_CreateDirectPlaySP( *ppvObj, dp )
108 IDirectPlaySP_AddRef( (LPDIRECTPLAYSP)*ppvObj );
109 return S_OK;
112 /* Initialize failed, destroy it */
113 DPSP_DestroyDirectPlaySP( *ppvObj );
114 DPSP_DestroyIUnknown( *ppvObj );
116 HeapFree( GetProcessHeap(), 0, *ppvObj );
117 *ppvObj = NULL;
119 return DPERR_NOMEMORY;
122 static BOOL DPSP_CreateIUnknown( LPVOID lpSP )
124 ICOM_THIS(IDirectPlaySPImpl,lpSP);
126 This->unk = (DirectPlaySPIUnknownData*)HeapAlloc( GetProcessHeap(),
127 HEAP_ZERO_MEMORY,
128 sizeof( *(This->unk) ) );
130 if ( This->unk == NULL )
132 return FALSE;
135 InitializeCriticalSection( &This->unk->DPSP_lock );
137 return TRUE;
140 static BOOL DPSP_DestroyIUnknown( LPVOID lpSP )
142 ICOM_THIS(IDirectPlaySPImpl,lpSP);
144 DeleteCriticalSection( &This->unk->DPSP_lock );
145 HeapFree( GetProcessHeap(), 0, This->unk );
147 return TRUE;
151 static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp )
153 ICOM_THIS(IDirectPlaySPImpl,lpSP);
155 This->sp = (DirectPlaySPData*)HeapAlloc( GetProcessHeap(),
156 HEAP_ZERO_MEMORY,
157 sizeof( *(This->sp) ) );
159 if ( This->sp == NULL )
161 return FALSE;
164 This->sp->dplay = dp;
166 /* Normally we should be keeping a reference, but since only the dplay
167 * interface that created us can destroy us, we do not keep a reference
168 * to it (ie we'd be stuck with always having one reference to the dplay
169 * object, and hence us, around).
170 * NOTE: The dp object does reference count us.
172 /* IDirectPlayX_AddRef( (LPDIRECTPLAY2)dp ); */
174 /* FIXME: This is a kludge to get around a problem where a queryinterface
175 * is used to get a new interface and then is closed. We will then
176 * reference garbage. However, with this we will never deallocate
177 * the interface we store. The correct fix is to require all
178 * DP internal interfaces to use the This->dp2 interface which
179 * should be changed to This->dp
181 IDirectPlayX_AddRef( (LPDIRECTPLAY2)dp );
183 return TRUE;
186 static BOOL DPSP_DestroyDirectPlaySP( LPVOID lpSP )
188 ICOM_THIS(IDirectPlaySPImpl,lpSP);
190 /* Normally we should be keeping a reference, but since only the dplay
191 * interface that created us can destroy us, we do not keep a reference
192 * to it (ie we'd be stuck with always having one reference to the dplay
193 * object, and hence us, around).
194 * NOTE: The dp object does reference count us.
196 /*IDirectPlayX_Release( (LPDIRECTPLAY2)This->sp->dplay ); */
198 HeapFree( GetProcessHeap(), 0, This->sp->lpSpRemoteData );
199 HeapFree( GetProcessHeap(), 0, This->sp->lpSpLocalData );
201 /* FIXME: Need to delete player queue */
203 HeapFree( GetProcessHeap(), 0, This->sp );
204 return TRUE;
207 /* Interface implementation */
209 static HRESULT WINAPI DPSP_QueryInterface
210 ( LPDIRECTPLAYSP iface,
211 REFIID riid,
212 LPVOID* ppvObj )
214 ICOM_THIS(IDirectPlaySPImpl,iface);
215 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
217 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
218 sizeof( *This ) );
220 if( *ppvObj == NULL )
222 return DPERR_OUTOFMEMORY;
225 CopyMemory( *ppvObj, This, sizeof( *This ) );
226 (*(IDirectPlaySPImpl**)ppvObj)->ulInterfaceRef = 0;
228 if( IsEqualGUID( &IID_IDirectPlaySP, riid ) )
230 ICOM_THIS(IDirectPlaySPImpl,*ppvObj);
231 ICOM_VTBL(This) = &directPlaySPVT;
233 else
235 /* Unsupported interface */
236 HeapFree( GetProcessHeap(), 0, *ppvObj );
237 *ppvObj = NULL;
239 return E_NOINTERFACE;
242 IDirectPlaySP_AddRef( (LPDIRECTPLAYSP)*ppvObj );
244 return S_OK;
247 static ULONG WINAPI DPSP_AddRef
248 ( LPDIRECTPLAYSP iface )
250 ULONG ulInterfaceRefCount, ulObjRefCount;
251 ICOM_THIS(IDirectPlaySPImpl,iface);
253 ulObjRefCount = InterlockedIncrement( &This->unk->ulObjRef );
254 ulInterfaceRefCount = InterlockedIncrement( &This->ulInterfaceRef );
256 TRACE( "ref count incremented to %lu:%lu for %p\n",
257 ulInterfaceRefCount, ulObjRefCount, This );
259 return ulObjRefCount;
262 static ULONG WINAPI DPSP_Release
263 ( LPDIRECTPLAYSP iface )
265 ULONG ulInterfaceRefCount, ulObjRefCount;
266 ICOM_THIS(IDirectPlaySPImpl,iface);
268 ulObjRefCount = InterlockedDecrement( &This->unk->ulObjRef );
269 ulInterfaceRefCount = InterlockedDecrement( &This->ulInterfaceRef );
271 TRACE( "ref count decremented to %lu:%lu for %p\n",
272 ulInterfaceRefCount, ulObjRefCount, This );
274 /* Deallocate if this is the last reference to the object */
275 if( ulObjRefCount == 0 )
277 DPSP_DestroyDirectPlaySP( This );
278 DPSP_DestroyIUnknown( This );
281 if( ulInterfaceRefCount == 0 )
283 HeapFree( GetProcessHeap(), 0, This );
286 return ulInterfaceRefCount;
289 static HRESULT WINAPI IDirectPlaySPImpl_AddMRUEntry
290 ( LPDIRECTPLAYSP iface,
291 LPCWSTR lpSection,
292 LPCWSTR lpKey,
293 LPCVOID lpData,
294 DWORD dwDataSize,
295 DWORD dwMaxEntries
298 ICOM_THIS(IDirectPlaySPImpl,iface);
300 FIXME( "(%p)->(%p,%p%p,0x%08lx,0x%08lx): stub\n",
301 This, lpSection, lpKey, lpData, dwDataSize, dwMaxEntries );
303 return DP_OK;
306 static HRESULT WINAPI IDirectPlaySPImpl_CreateAddress
307 ( LPDIRECTPLAYSP iface,
308 REFGUID guidSP,
309 REFGUID guidDataType,
310 LPCVOID lpData,
311 DWORD dwDataSize,
312 LPVOID lpAddress,
313 LPDWORD lpdwAddressSize
316 ICOM_THIS(IDirectPlaySPImpl,iface);
318 FIXME( "(%p)->(%s,%s,%p,0x%08lx,%p,%p): stub\n",
319 This, debugstr_guid(guidSP), debugstr_guid(guidDataType),
320 lpData, dwDataSize, lpAddress, lpdwAddressSize );
322 return DP_OK;
325 static HRESULT WINAPI IDirectPlaySPImpl_EnumAddress
326 ( LPDIRECTPLAYSP iface,
327 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
328 LPCVOID lpAddress,
329 DWORD dwAddressSize,
330 LPVOID lpContext
333 ICOM_THIS(IDirectPlaySPImpl,iface);
335 TRACE( "(%p)->(%p,%p,0x%08lx,%p)\n",
336 This, lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext );
338 DPL_EnumAddress( lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext );
340 return DP_OK;
343 static HRESULT WINAPI IDirectPlaySPImpl_EnumMRUEntries
344 ( LPDIRECTPLAYSP iface,
345 LPCWSTR lpSection,
346 LPCWSTR lpKey,
347 LPENUMMRUCALLBACK lpEnumMRUCallback,
348 LPVOID lpContext
351 ICOM_THIS(IDirectPlaySPImpl,iface);
353 FIXME( "(%p)->(%p,%p,%p,%p,): stub\n",
354 This, lpSection, lpKey, lpEnumMRUCallback, lpContext );
356 return DP_OK;
359 static HRESULT WINAPI IDirectPlaySPImpl_GetPlayerFlags
360 ( LPDIRECTPLAYSP iface,
361 DPID idPlayer,
362 LPDWORD lpdwPlayerFlags
365 ICOM_THIS(IDirectPlaySPImpl,iface);
367 FIXME( "(%p)->(0x%08lx,%p): stub\n",
368 This, idPlayer, lpdwPlayerFlags );
370 return DP_OK;
373 static HRESULT WINAPI IDirectPlaySPImpl_GetSPPlayerData
374 ( LPDIRECTPLAYSP iface,
375 DPID idPlayer,
376 LPVOID* lplpData,
377 LPDWORD lpdwDataSize,
378 DWORD dwFlags
381 HRESULT hr;
382 LPDP_SPPLAYERDATA lpPlayerData;
383 ICOM_THIS(IDirectPlaySPImpl,iface);
385 /* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
386 TRACE( "(%p)->(0x%08lx,%p,%p,0x%08lx)\n",
387 This, idPlayer, lplpData, lpdwDataSize, dwFlags );
389 hr = DP_GetSPPlayerData( This->sp->dplay, idPlayer, (LPVOID*)&lpPlayerData );
391 if( FAILED(hr) )
393 TRACE( "Couldn't get player data: %s\n", DPLAYX_HresultToString(hr) );
394 return DPERR_INVALIDPLAYER;
397 /* What to do in the case where there is nothing set yet? */
398 if( dwFlags == DPSET_LOCAL )
400 if( lpPlayerData->lpPlayerLocalData )
402 HeapFree( GetProcessHeap(), 0, lpPlayerData->lpPlayerLocalData );
405 *lplpData = lpPlayerData->lpPlayerLocalData;
406 *lpdwDataSize = lpPlayerData->dwPlayerLocalDataSize;
408 else if( dwFlags == DPSET_REMOTE )
410 if( lpPlayerData->lpPlayerRemoteData )
412 HeapFree( GetProcessHeap(), 0, lpPlayerData->lpPlayerRemoteData );
415 *lplpData = lpPlayerData->lpPlayerRemoteData;
416 *lpdwDataSize = lpPlayerData->dwPlayerRemoteDataSize;
419 if( *lplpData == NULL )
421 hr = DPERR_GENERIC;
424 return hr;
427 static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
428 ( LPDIRECTPLAYSP iface,
429 LPVOID lpMessageBody,
430 DWORD dwMessageBodySize,
431 LPVOID lpMessageHeader
434 LPDPMSG_SENDENVELOPE lpMsg = (LPDPMSG_SENDENVELOPE)lpMessageBody;
435 HRESULT hr = DPERR_GENERIC;
436 WORD wCommandId;
437 WORD wVersion;
439 ICOM_THIS(IDirectPlaySPImpl,iface);
441 /* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
442 FIXME( "(%p)->(%p,0x%08lx,%p): mostly stub\n",
443 This, lpMessageBody, dwMessageBodySize, lpMessageHeader );
445 wCommandId = lpMsg->wCommandId;
446 wVersion = lpMsg->wVersion;
448 TRACE( "Incomming message has envelope of 0x%08lx, %u, %u\n",
449 lpMsg->dwMagic, wCommandId, wVersion );
451 if( lpMsg->dwMagic != DPMSGMAGIC_DPLAYMSG )
453 ERR( "Unknown magic 0x%08lx!\n", lpMsg->dwMagic );
456 switch( lpMsg->wCommandId )
458 /* Name server needs to handle this request */
459 /* FIXME: This should be done in direct play handler */
460 case DPMSGCMD_ENUMSESSIONSREQUEST:
462 DPSP_REPLYDATA data;
464 data.lpSPMessageHeader = lpMessageHeader;
465 data.idNameServer = 0;
466 data.lpISP = iface;
468 NS_ReplyToEnumSessionsRequest( lpMessageBody, &data, This->sp->dplay );
470 hr = (This->sp->dplay->dp2->spData.lpCB->Reply)( &data );
472 if( FAILED(hr) )
474 ERR( "Reply failed 0x%08lx\n", hr );
477 break;
480 /* Name server needs to handle this request */
481 /* FIXME: This should be done in direct play handler */
482 case DPMSGCMD_ENUMSESSIONSREPLY:
484 NS_SetRemoteComputerAsNameServer( lpMessageHeader,
485 This->sp->dplay->dp2->spData.dwSPHeaderSize,
486 (LPDPMSG_ENUMSESSIONSREPLY)lpMessageBody,
487 This->sp->dplay->dp2->lpNameServerData );
489 /* No reply expected */
490 hr = DP_OK;
492 break;
495 /* Pass everything else to Direct Play */
496 default:
498 DPSP_REPLYDATA data;
500 data.lpMessage = NULL;
501 data.dwMessageSize = 0;
503 /* Pass this message to the dplay interface to handle */
504 hr = DP_HandleMessage( This->sp->dplay, lpMessageBody, dwMessageBodySize,
505 lpMessageHeader, wCommandId, wVersion,
506 &data.lpMessage, &data.dwMessageSize );
508 /* Do we want a reply? */
509 if( data.lpMessage != NULL )
511 HRESULT hr;
513 data.lpSPMessageHeader = lpMessageHeader;
514 data.idNameServer = 0;
515 data.lpISP = iface;
517 hr = (This->sp->dplay->dp2->spData.lpCB->Reply)( &data );
519 if( FAILED(hr) )
521 ERR( "Reply failed %s\n", DPLAYX_HresultToString(hr) );
525 break;
529 #if 0
530 HRESULT hr = DP_OK;
531 HANDLE hReceiveEvent = 0;
532 /* FIXME: Aquire some sort of interface lock */
533 /* FIXME: Need some sort of context for this callback. Need to determine
534 * how this is actually done with the SP
536 /* FIXME: Who needs to delete the message when done? */
537 switch( lpMsg->dwType )
539 case DPSYS_CREATEPLAYERORGROUP:
541 LPDPMSG_CREATEPLAYERORGROUP msg = (LPDPMSG_CREATEPLAYERORGROUP)lpMsg;
543 if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
545 hr = DP_IF_CreatePlayer( This, lpMessageHeader, msg->dpId,
546 &msg->dpnName, 0, msg->lpData,
547 msg->dwDataSize, msg->dwFlags, ... );
549 else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
551 /* Group in group situation? */
552 if( msg->dpIdParent == DPID_NOPARENT_GROUP )
554 hr = DP_IF_CreateGroup( This, lpMessageHeader, msg->dpId,
555 &msg->dpnName, 0, msg->lpData,
556 msg->dwDataSize, msg->dwFlags, ... );
558 else /* Group in Group */
560 hr = DP_IF_CreateGroupInGroup( This, lpMessageHeader, msg->dpIdParent,
561 &msg->dpnName, 0, msg->lpData,
562 msg->dwDataSize, msg->dwFlags, ... );
565 else /* Hmmm? */
567 ERR( "Corrupt msg->dwPlayerType for DPSYS_CREATEPLAYERORGROUP\n" );
568 return;
571 break;
574 case DPSYS_DESTROYPLAYERORGROUP:
576 LPDPMSG_DESTROYPLAYERORGROUP msg = (LPDPMSG_DESTROYPLAYERORGROUP)lpMsg;
578 if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
580 hr = DP_IF_DestroyPlayer( This, msg->dpId, ... );
582 else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
584 hr = DP_IF_DestroyGroup( This, msg->dpId, ... );
586 else /* Hmmm? */
588 ERR( "Corrupt msg->dwPlayerType for DPSYS_DESTROYPLAYERORGROUP\n" );
589 return;
592 break;
595 case DPSYS_ADDPLAYERTOGROUP:
597 LPDPMSG_ADDPLAYERTOGROUP msg = (LPDPMSG_ADDPLAYERTOGROUP)lpMsg;
599 hr = DP_IF_AddPlayerToGroup( This, msg->dpIdGroup, msg->dpIdPlayer, ... );
600 break;
603 case DPSYS_DELETEPLAYERFROMGROUP:
605 LPDPMSG_DELETEPLAYERFROMGROUP msg = (LPDPMSG_DELETEPLAYERFROMGROUP)lpMsg;
607 hr = DP_IF_DeletePlayerFromGroup( This, msg->dpIdGroup, msg->dpIdPlayer,
608 ... );
610 break;
613 case DPSYS_SESSIONLOST:
615 LPDPMSG_SESSIONLOST msg = (LPDPMSG_SESSIONLOST)lpMsg;
617 FIXME( "DPSYS_SESSIONLOST not handled\n" );
619 break;
622 case DPSYS_HOST:
624 LPDPMSG_HOST msg = (LPDPMSG_HOST)lpMsg;
626 FIXME( "DPSYS_HOST not handled\n" );
628 break;
631 case DPSYS_SETPLAYERORGROUPDATA:
633 LPDPMSG_SETPLAYERORGROUPDATA msg = (LPDPMSG_SETPLAYERORGROUPDATA)lpMsg;
635 if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
637 hr = DP_IF_SetPlayerData( This, msg->dpId, msg->lpData, msg->dwDataSize, DPSET_REMOTE, ... );
639 else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
641 hr = DP_IF_SetGroupData( This, msg->dpId, msg->lpData, msg->dwDataSize,
642 DPSET_REMOTE, ... );
644 else /* Hmmm? */
646 ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" );
647 return;
650 break;
653 case DPSYS_SETPLAYERORGROUPNAME:
655 LPDPMSG_SETPLAYERORGROUPNAME msg = (LPDPMSG_SETPLAYERORGROUPNAME)lpMsg;
657 if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
659 hr = DP_IF_SetPlayerName( This, msg->dpId, msg->dpnName, ... );
661 else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
663 hr = DP_IF_SetGroupName( This, msg->dpId, msg->dpnName, ... );
665 else /* Hmmm? */
667 ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" );
668 return;
671 break;
674 case DPSYS_SETSESSIONDESC;
676 LPDPMSG_SETSESSIONDESC msg = (LPDPMSG_SETSESSIONDESC)lpMsg;
678 hr = DP_IF_SetSessionDesc( This, &msg->dpDesc );
680 break;
683 case DPSYS_ADDGROUPTOGROUP:
685 LPDPMSG_ADDGROUPTOGROUP msg = (LPDPMSG_ADDGROUPTOGROUP)lpMsg;
687 hr = DP_IF_AddGroupToGroup( This, msg->dpIdParentGroup, msg->dpIdGroup,
688 ... );
690 break;
693 case DPSYS_DELETEGROUPFROMGROUP:
695 LPDPMSG_DELETEGROUPFROMGROUP msg = (LPDPMSG_DELETEGROUPFROMGROUP)lpMsg;
697 hr = DP_IF_DeleteGroupFromGroup( This, msg->dpIdParentGroup,
698 msg->dpIdGroup, ... );
700 break;
703 case DPSYS_SECUREMESSAGE:
705 LPDPMSG_SECUREMESSAGE msg = (LPDPMSG_SECUREMESSAGE)lpMsg;
707 FIXME( "DPSYS_SECUREMESSAGE not implemented\n" );
709 break;
712 case DPSYS_STARTSESSION:
714 LPDPMSG_STARTSESSION msg = (LPDPMSG_STARTSESSION)lpMsg;
716 FIXME( "DPSYS_STARTSESSION not implemented\n" );
718 break;
721 case DPSYS_CHAT:
723 LPDPMSG_CHAT msg = (LPDPMSG_CHAT)lpMsg;
725 FIXME( "DPSYS_CHAT not implemeneted\n" );
727 break;
730 case DPSYS_SETGROUPOWNER:
732 LPDPMSG_SETGROUPOWNER msg = (LPDPMSG_SETGROUPOWNER)lpMsg;
734 FIXME( "DPSYS_SETGROUPOWNER not implemented\n" );
736 break;
739 case DPSYS_SENDCOMPLETE:
741 LPDPMSG_SENDCOMPLETE msg = (LPDPMSG_SENDCOMPLETE)lpMsg;
743 FIXME( "DPSYS_SENDCOMPLETE not implemented\n" );
745 break;
748 default:
750 /* NOTE: This should be a user defined type. There is nothing that we
751 * need to do with it except queue it.
753 TRACE( "Received user message type(?) 0x%08lx through SP.\n",
754 lpMsg->dwType );
755 break;
759 FIXME( "Queue message in the receive queue. Need some context data!\n" );
761 if( FAILED(hr) )
763 ERR( "Unable to perform action for msg type 0x%08lx\n", lpMsg->dwType );
765 /* If a receieve event was registered for this player, invoke it */
766 if( hReceiveEvent )
768 SetEvent( hReceiveEvent );
770 #endif
772 return hr;
775 static HRESULT WINAPI IDirectPlaySPImpl_SetSPPlayerData
776 ( LPDIRECTPLAYSP iface,
777 DPID idPlayer,
778 LPVOID lpData,
779 DWORD dwDataSize,
780 DWORD dwFlags
783 HRESULT hr;
784 LPDP_SPPLAYERDATA lpPlayerEntry;
785 LPVOID lpPlayerData;
787 ICOM_THIS(IDirectPlaySPImpl,iface);
789 /* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
790 TRACE( "(%p)->(0x%08lx,%p,0x%08lx,0x%08lx)\n",
791 This, idPlayer, lpData, dwDataSize, dwFlags );
793 hr = DP_GetSPPlayerData( This->sp->dplay, idPlayer, (LPVOID*)&lpPlayerEntry );
794 if( FAILED(hr) )
796 /* Player must not exist */
797 return DPERR_INVALIDPLAYER;
800 lpPlayerData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
801 CopyMemory( lpPlayerData, lpData, dwDataSize );
803 if( dwFlags == DPSET_LOCAL )
805 lpPlayerEntry->lpPlayerLocalData = lpPlayerData;
806 lpPlayerEntry->dwPlayerLocalDataSize = dwDataSize;
808 else if( dwFlags == DPSET_REMOTE )
810 lpPlayerEntry->lpPlayerRemoteData = lpPlayerData;
811 lpPlayerEntry->dwPlayerRemoteDataSize = dwDataSize;
814 hr = DP_SetSPPlayerData( This->sp->dplay, idPlayer, lpPlayerEntry );
816 return hr;
819 static HRESULT WINAPI IDirectPlaySPImpl_CreateCompoundAddress
820 ( LPDIRECTPLAYSP iface,
821 LPCDPCOMPOUNDADDRESSELEMENT lpElements,
822 DWORD dwElementCount,
823 LPVOID lpAddress,
824 LPDWORD lpdwAddressSize
827 ICOM_THIS(IDirectPlaySPImpl,iface);
829 FIXME( "(%p)->(%p,0x%08lx,%p,%p): stub\n",
830 This, lpElements, dwElementCount, lpAddress, lpdwAddressSize );
832 return DP_OK;
835 static HRESULT WINAPI IDirectPlaySPImpl_GetSPData
836 ( LPDIRECTPLAYSP iface,
837 LPVOID* lplpData,
838 LPDWORD lpdwDataSize,
839 DWORD dwFlags
842 HRESULT hr = DP_OK;
843 ICOM_THIS(IDirectPlaySPImpl,iface);
845 /* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
846 TRACE( "(%p)->(%p,%p,0x%08lx)\n",
847 This, lplpData, lpdwDataSize, dwFlags );
849 #if 0
850 /* This is what the documentation says... */
851 if( dwFlags != DPSET_REMOTE )
853 return DPERR_INVALIDPARAMS;
855 #else
856 /* ... but most service providers call this with 1 */
857 /* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
858 * thing?
860 if( dwFlags != DPSET_REMOTE )
862 FIXME( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
864 #endif
866 /* FIXME: What to do in the case where this isn't initialized yet? */
868 /* Yes, we're supposed to return a pointer to the memory we have stored! */
869 if( dwFlags == DPSET_REMOTE )
871 *lpdwDataSize = This->sp->dwSpRemoteDataSize;
872 *lplpData = This->sp->lpSpRemoteData;
874 if( This->sp->lpSpRemoteData == NULL )
876 hr = DPERR_GENERIC;
879 else if( dwFlags == DPSET_LOCAL )
881 *lpdwDataSize = This->sp->dwSpLocalDataSize;
882 *lplpData = This->sp->lpSpLocalData;
884 if( This->sp->lpSpLocalData == NULL )
886 hr = DPERR_GENERIC;
890 return hr;
893 static HRESULT WINAPI IDirectPlaySPImpl_SetSPData
894 ( LPDIRECTPLAYSP iface,
895 LPVOID lpData,
896 DWORD dwDataSize,
897 DWORD dwFlags
900 LPVOID lpSpData;
902 ICOM_THIS(IDirectPlaySPImpl,iface);
904 /* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
905 TRACE( "(%p)->(%p,0x%08lx,0x%08lx)\n",
906 This, lpData, dwDataSize, dwFlags );
908 #if 0
909 /* This is what the documentation says... */
910 if( dwFlags != DPSET_REMOTE )
912 return DPERR_INVALIDPARAMS;
914 #else
915 /* ... but most service providers call this with 1 */
916 /* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
917 * thing?
919 if( dwFlags != DPSET_REMOTE )
921 FIXME( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
923 #endif
925 lpSpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
926 CopyMemory( lpSpData, lpData, dwDataSize );
928 /* If we have data already allocated, free it and replace it */
929 if( dwFlags == DPSET_REMOTE )
931 if( This->sp->lpSpRemoteData )
933 HeapFree( GetProcessHeap(), 0, This->sp->lpSpRemoteData );
936 This->sp->dwSpRemoteDataSize = dwDataSize;
937 This->sp->lpSpRemoteData = lpSpData;
939 else if ( dwFlags == DPSET_LOCAL )
941 if( This->sp->lpSpLocalData )
943 HeapFree( GetProcessHeap(), 0, This->sp->lpSpLocalData );
946 This->sp->lpSpLocalData = lpSpData;
947 This->sp->dwSpLocalDataSize = dwDataSize;
950 return DP_OK;
953 static VOID WINAPI IDirectPlaySPImpl_SendComplete
954 ( LPDIRECTPLAYSP iface,
955 LPVOID unknownA,
956 DWORD unknownB
959 ICOM_THIS(IDirectPlaySPImpl,iface);
961 FIXME( "(%p)->(%p,0x%08lx): stub\n",
962 This, unknownA, unknownB );
966 static struct ICOM_VTABLE(IDirectPlaySP) directPlaySPVT =
968 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
970 DPSP_QueryInterface,
971 DPSP_AddRef,
972 DPSP_Release,
974 IDirectPlaySPImpl_AddMRUEntry,
975 IDirectPlaySPImpl_CreateAddress,
976 IDirectPlaySPImpl_EnumAddress,
977 IDirectPlaySPImpl_EnumMRUEntries,
978 IDirectPlaySPImpl_GetPlayerFlags,
979 IDirectPlaySPImpl_GetSPPlayerData,
980 IDirectPlaySPImpl_HandleMessage,
981 IDirectPlaySPImpl_SetSPPlayerData,
982 IDirectPlaySPImpl_CreateCompoundAddress,
983 IDirectPlaySPImpl_GetSPData,
984 IDirectPlaySPImpl_SetSPData,
985 IDirectPlaySPImpl_SendComplete
989 /* DP external interfaces to call into DPSP interface */
991 /* Allocate the structure */
992 extern LPVOID DPSP_CreateSPPlayerData(void)
994 TRACE( "Creating SPPlayer data struct\n" );
995 return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
996 sizeof( DP_SPPLAYERDATA ) );