1 /* Direct Play 2,3,4 Implementation
3 * Copyright 1998,1999,2000 - Peter Hunnisett
5 * <presently under construction - contact hunnise@nortelnetworks.com>
16 #include "debugtools.h"
19 #include "dplayx_global.h"
20 #include "name_server.h"
21 #include "dplayx_queue.h"
23 DEFAULT_DEBUG_CHANNEL(dplay)
26 /* FIXME: This stuff shouldn't really be here. It indicates a poor architectural coupling */
28 extern HRESULT DPL_CreateCompoundAddress ( LPCDPCOMPOUNDADDRESSELEMENT lpElements, DWORD dwElementCount,
29 LPVOID lpAddress, LPDWORD lpdwAddressSize, BOOL bAnsiInterface );
32 /*****************************************************************************
33 * Predeclare the interface implementation structures
35 typedef struct IDirectPlay2Impl IDirectPlay2AImpl;
36 typedef struct IDirectPlay2Impl IDirectPlay2Impl;
37 typedef struct IDirectPlay3Impl IDirectPlay3AImpl;
38 typedef struct IDirectPlay3Impl IDirectPlay3Impl;
39 typedef struct IDirectPlay4Impl IDirectPlay4AImpl;
40 typedef struct IDirectPlay4Impl IDirectPlay4Impl;
42 /*****************************************************************************
43 * IDirectPlay implementation structure
45 * The philosophy behind this extra pointer dereference is that I wanted to
46 * have the same structure for all types of objects without having to do
47 * alot of casting. I also only wanted to implement an interface in the
48 * object it was "released" with IUnknown interface being implemented in the 1 version.
49 * Of course, with these new interfaces comes the data required to keep the state required
50 * by these interfaces. So, basically, the pointers contain the data associated with
51 * a release. If you use the data associated with release 3 in a release 2 object, you'll
52 * get a run time trap, as that won't have any data.
55 typedef struct tagDirectPlayIUnknownData
58 CRITICAL_SECTION DP_lock;
59 } DirectPlayIUnknownData;
61 typedef struct tagEnumSessionAsyncCallbackData
63 LPDPENUMSESSIONSCALLBACK2 cb;
66 } EnumSessionAsyncCallbackData;
71 /* Individual player information */
79 typedef struct PlayerData* lpPlayerData;
83 DPQ_ENTRY(PlayerList) players;
87 typedef struct PlayerList* lpPlayerList;
91 /* Internal information */
92 struct GroupData* parent; /* If parent == NULL it's a top level group */
94 DPQ_HEAD(GroupList) groups; /* A group has [0..n] groups */
95 DPQ_HEAD(PlayerList) players; /* A group has [0..n] players */
97 DPID idGroupOwner; /* ID of player who owns the group */
99 /* Individual group information exposed to outside */
105 typedef struct GroupData* lpGroupData;
109 DPQ_ENTRY(GroupList) groups;
113 typedef struct GroupList* lpGroupList;
115 /* Contains all dp1 and dp2 data members */
116 typedef struct tagDirectPlay2Data
118 BOOL bConnectionOpen;
120 HANDLE hEnumSessionThread;
122 EnumSessionAsyncCallbackData enumSessionAsyncCallbackData;
124 LPVOID lpNameServerData; /* DPlay interface doesn't know contents */
126 BOOL bHostInterface; /* Did this interface create the session */
128 DPQ_HEAD(PlayerList) players; /* All players w/ interface */
129 DPQ_HEAD(GroupList) groups; /* All main groups w/ interface */
132 typedef struct tagDirectPlay3Data
134 BOOL bConnectionInitialized;
137 typedef struct tagDirectPlay4Data
142 #define DP_IMPL_FIELDS \
143 DirectPlayIUnknownData* unk; \
144 DirectPlay2Data* dp2; \
145 DirectPlay3Data* dp3; \
146 DirectPlay4Data* dp4;
148 struct IDirectPlay2Impl
150 ICOM_VFIELD(IDirectPlay2);
154 struct IDirectPlay3Impl
156 ICOM_VFIELD(IDirectPlay3);
160 struct IDirectPlay4Impl
162 ICOM_VFIELD(IDirectPlay4);
166 /* Forward declarations of virtual tables */
167 static ICOM_VTABLE(IDirectPlay2) directPlay2AVT;
168 static ICOM_VTABLE(IDirectPlay3) directPlay3AVT;
169 static ICOM_VTABLE(IDirectPlay4) directPlay4AVT;
171 static ICOM_VTABLE(IDirectPlay2) directPlay2WVT;
172 static ICOM_VTABLE(IDirectPlay3) directPlay3WVT;
173 static ICOM_VTABLE(IDirectPlay4) directPlay4WVT;
175 /* Local function prototypes */
176 static lpPlayerList DP_FindPlayer( IDirectPlay2AImpl* This, DPID dpid );
177 static lpPlayerData DP_CreatePlayer( IDirectPlay2Impl* iface, LPDPID lpid,
178 LPDPNAME lpName, HANDLE hEvent,
180 static BOOL DP_CopyDPNAMEStruct( LPDPNAME lpDst, LPDPNAME lpSrc, BOOL bAnsi );
181 static void DP_SetPlayerData( lpPlayerData lpPData, LPVOID lpData,
184 static lpGroupList DP_FindTopGroup( IDirectPlay2AImpl* This, DPID dpid );
185 static lpGroupData DP_CreateGroup( IDirectPlay2AImpl* iface, LPDPID lpid,
186 LPDPNAME lpName, lpGroupData lpParentData,
188 static void DP_SetGroupData( lpGroupData lpGData, LPVOID lpData,
190 static void DP_DeleteDPNameStruct( LPDPNAME lpDPName );
191 static void DP_DeletePlayer( IDirectPlay2Impl* This, DPID dpid );
192 static BOOL cbDeletePlayerFromAllGroups( DPID dpId, DWORD dwPlayerType,
193 LPCDPNAME lpName, DWORD dwFlags,
195 static lpGroupList DP_FindAnyGroup( IDirectPlay2AImpl* This, DPID dpid );
196 static BOOL cbRemoveGroupOrPlayer( DPID dpId, DWORD dwPlayerType,
197 LPCDPNAME lpName, DWORD dwFlags,
199 static void DP_DeleteGroup( IDirectPlay2Impl* This, DPID dpid );
201 /* Helper methods for player/group interfaces */
202 static HRESULT WINAPI DP_IF_DeletePlayerFromGroup
203 ( IDirectPlay2Impl* This, DPID idGroup, DPID idPlayer, BOOL bAnsi );
204 static HRESULT WINAPI DP_IF_CreatePlayer
205 ( IDirectPlay2Impl* This, LPDPID lpidPlayer, LPDPNAME lpPlayerName,
206 HANDLE hEvent, LPVOID lpData, DWORD dwDataSize,
207 DWORD dwFlags, BOOL bAnsi );
208 static HRESULT WINAPI DP_IF_DestroyGroup
209 ( IDirectPlay2Impl* This, DPID idGroup, BOOL bAnsi );
210 static HRESULT WINAPI DP_IF_DestroyPlayer
211 ( IDirectPlay2Impl* This, DPID idPlayer, BOOL bAnsi );
212 static HRESULT WINAPI DP_IF_EnumGroupPlayers
213 ( IDirectPlay2Impl* This, DPID idGroup, LPGUID lpguidInstance,
214 LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
215 LPVOID lpContext, DWORD dwFlags, BOOL bAnsi );
216 static HRESULT WINAPI DP_IF_EnumGroups
217 ( IDirectPlay2Impl* This, LPGUID lpguidInstance,
218 LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
219 LPVOID lpContext, DWORD dwFlags, BOOL bAnsi );
220 static HRESULT WINAPI DP_IF_EnumPlayers
221 ( IDirectPlay2Impl* This, LPGUID lpguidInstance,
222 LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
223 LPVOID lpContext, DWORD dwFlags, BOOL bAnsi );
224 static HRESULT WINAPI DP_IF_GetGroupData
225 ( IDirectPlay2Impl* This, DPID idGroup, LPVOID lpData,
226 LPDWORD lpdwDataSize, DWORD dwFlags, BOOL bAnsi );
227 static HRESULT WINAPI DP_IF_GetGroupName
228 ( IDirectPlay2Impl* This, DPID idGroup, LPVOID lpData,
229 LPDWORD lpdwDataSize, BOOL bAnsi );
230 static HRESULT WINAPI DP_IF_GetPlayerData
231 ( IDirectPlay2Impl* This, DPID idPlayer, LPVOID lpData,
232 LPDWORD lpdwDataSize, DWORD dwFlags, BOOL bAnsi );
233 static HRESULT WINAPI DP_IF_GetPlayerName
234 ( IDirectPlay2Impl* This, DPID idPlayer, LPVOID lpData,
235 LPDWORD lpdwDataSize, BOOL bAnsi );
236 static HRESULT WINAPI DP_IF_SetGroupName
237 ( IDirectPlay2Impl* This, DPID idGroup, LPDPNAME lpGroupName,
238 DWORD dwFlags, BOOL bAnsi );
239 static HRESULT WINAPI DP_IF_SetPlayerData
240 ( IDirectPlay2Impl* This, DPID idPlayer, LPVOID lpData,
241 DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi );
242 static HRESULT WINAPI DP_IF_SetPlayerName
243 ( IDirectPlay2Impl* This, DPID idPlayer, LPDPNAME lpPlayerName,
244 DWORD dwFlags, BOOL bAnsi );
245 static HRESULT WINAPI DP_IF_AddGroupToGroup
246 ( IDirectPlay3Impl* This, DPID idParentGroup, DPID idGroup );
247 static HRESULT WINAPI DP_IF_CreateGroupInGroup
248 ( IDirectPlay3Impl* This, DPID idParentGroup, LPDPID lpidGroup,
249 LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize,
251 static HRESULT WINAPI DP_IF_DeleteGroupFromGroup
252 ( IDirectPlay3Impl* This, DPID idParentGroup, DPID idGroup );
255 static HRESULT WINAPI DP_SecureOpen
256 ( IDirectPlay2Impl* This, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags,
257 LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials );
263 static DWORD kludgePlayerGroupId = 1000;
265 /* ------------------------------------------------------------------ */
268 BOOL DP_CreateIUnknown( LPVOID lpDP )
270 ICOM_THIS(IDirectPlay2AImpl,lpDP);
272 This->unk = (DirectPlayIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
273 sizeof( *(This->unk) ) );
274 if ( This->unk == NULL )
279 InitializeCriticalSection( &This->unk->DP_lock );
281 IDirectPlay_AddRef( (LPDIRECTPLAY2A)lpDP );
286 BOOL DP_DestroyIUnknown( LPVOID lpDP )
288 ICOM_THIS(IDirectPlay2AImpl,lpDP);
290 DeleteCriticalSection( &This->unk->DP_lock );
291 HeapFree( GetProcessHeap(), 0, This->unk );
296 BOOL DP_CreateDirectPlay2( LPVOID lpDP )
298 ICOM_THIS(IDirectPlay2AImpl,lpDP);
300 This->dp2 = (DirectPlay2Data*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
301 sizeof( *(This->dp2) ) );
302 if ( This->dp2 == NULL )
307 This->dp2->bConnectionOpen = FALSE;
309 This->dp2->hEnumSessionThread = INVALID_HANDLE_VALUE;
311 This->dp2->enumSessionAsyncCallbackData.cb = NULL;
312 This->dp2->enumSessionAsyncCallbackData.lpContext = NULL;
313 This->dp2->enumSessionAsyncCallbackData.dwTimeout = INFINITE;
315 This->dp2->bHostInterface = FALSE;
317 DPQ_INIT(This->dp2->players);
318 DPQ_INIT(This->dp2->groups);
320 if( !NS_InitializeSessionCache( &This->dp2->lpNameServerData ) )
328 BOOL DP_DestroyDirectPlay2( LPVOID lpDP )
330 ICOM_THIS(IDirectPlay2AImpl,lpDP);
332 FIXME( ": memory leak\n" );
334 if( This->dp2->hEnumSessionThread != INVALID_HANDLE_VALUE )
336 TerminateThread( This->dp2->hEnumSessionThread, 0 );
337 CloseHandle( This->dp2->hEnumSessionThread );
340 /* Delete the player and group lists */
342 NS_DeleteSessionCache( This->dp2->lpNameServerData );
344 /* Delete the contents */
345 HeapFree( GetProcessHeap(), 0, This->dp2 );
350 BOOL DP_CreateDirectPlay3( LPVOID lpDP )
352 ICOM_THIS(IDirectPlay3AImpl,lpDP);
354 This->dp3 = (DirectPlay3Data*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
355 sizeof( *(This->dp3) ) );
356 if ( This->dp3 == NULL )
361 This->dp3->bConnectionInitialized = FALSE;
366 BOOL DP_DestroyDirectPlay3( LPVOID lpDP )
368 ICOM_THIS(IDirectPlay3AImpl,lpDP);
370 /* Delete the contents */
371 HeapFree( GetProcessHeap(), 0, This->dp3 );
376 BOOL DP_CreateDirectPlay4( LPVOID lpDP )
378 ICOM_THIS(IDirectPlay4AImpl,lpDP);
380 This->dp4 = (DirectPlay4Data*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
381 sizeof( *(This->dp4) ) );
382 if ( This->dp4 == NULL )
390 BOOL DP_DestroyDirectPlay4( LPVOID lpDP )
392 ICOM_THIS(IDirectPlay3AImpl,lpDP);
394 /* Delete the contents */
395 HeapFree( GetProcessHeap(), 0, This->dp4 );
401 /* Get a new interface. To be used by QueryInterface. */
403 HRESULT directPlay_QueryInterface
404 ( REFIID riid, LPVOID* ppvObj )
407 if( IsEqualGUID( &IID_IDirectPlay2, riid ) )
409 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
410 sizeof( IDirectPlay2Impl ) );
412 if( *ppvObj == NULL )
414 return DPERR_OUTOFMEMORY;
417 /* new scope for variable declaration */
419 ICOM_THIS(IDirectPlay2Impl,*ppvObj);
421 ICOM_VTBL(This) = &directPlay2WVT;
423 if ( DP_CreateIUnknown( (LPVOID)This ) &&
424 DP_CreateDirectPlay2( (LPVOID)This )
434 else if( IsEqualGUID( &IID_IDirectPlay2A, riid ) )
436 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
437 sizeof( IDirectPlay2AImpl ) );
439 if( *ppvObj == NULL )
441 return DPERR_OUTOFMEMORY;
444 /* new scope for variable declaration */
446 ICOM_THIS(IDirectPlay2AImpl,*ppvObj);
448 ICOM_VTBL(This) = &directPlay2AVT;
450 if ( DP_CreateIUnknown( (LPVOID)This ) &&
451 DP_CreateDirectPlay2( (LPVOID)This )
461 else if( IsEqualGUID( &IID_IDirectPlay3, riid ) )
463 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
464 sizeof( IDirectPlay3Impl ) );
466 if( *ppvObj == NULL )
468 return DPERR_OUTOFMEMORY;
471 /* new scope for variable declaration */
473 ICOM_THIS(IDirectPlay3Impl,*ppvObj);
475 ICOM_VTBL(This) = &directPlay3WVT;
477 if ( DP_CreateIUnknown( (LPVOID)This ) &&
478 DP_CreateDirectPlay2( (LPVOID)This ) &&
479 DP_CreateDirectPlay3( (LPVOID)This )
489 else if( IsEqualGUID( &IID_IDirectPlay3A, riid ) )
491 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
492 sizeof( IDirectPlay3AImpl ) );
494 if( *ppvObj == NULL )
496 return DPERR_OUTOFMEMORY;
499 /* new scope for variable declaration */
501 ICOM_THIS(IDirectPlay3AImpl,*ppvObj);
503 ICOM_VTBL(This) = &directPlay3AVT;
505 if ( DP_CreateIUnknown( (LPVOID)This ) &&
506 DP_CreateDirectPlay2( (LPVOID)This ) &&
507 DP_CreateDirectPlay3( (LPVOID)This )
517 else if( IsEqualGUID( &IID_IDirectPlay4, riid ) )
519 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
520 sizeof( IDirectPlay4Impl ) );
522 if( *ppvObj == NULL )
524 return DPERR_OUTOFMEMORY;
527 /* new scope for variable declaration */
529 ICOM_THIS(IDirectPlay4Impl,*ppvObj);
531 ICOM_VTBL(This) = &directPlay4WVT;
533 if ( DP_CreateIUnknown( (LPVOID)This ) &&
534 DP_CreateDirectPlay2( (LPVOID)This ) &&
535 DP_CreateDirectPlay3( (LPVOID)This ) &&
536 DP_CreateDirectPlay4( (LPVOID)This )
546 else if( IsEqualGUID( &IID_IDirectPlay4A, riid ) )
548 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
549 sizeof( IDirectPlay4AImpl ) );
551 if( *ppvObj == NULL )
553 return DPERR_OUTOFMEMORY;
556 /* new scope for variable declaration */
558 ICOM_THIS(IDirectPlay4AImpl,*ppvObj);
560 ICOM_VTBL(This) = &directPlay4AVT;
562 if ( DP_CreateIUnknown( (LPVOID)This ) &&
563 DP_CreateDirectPlay2( (LPVOID)This ) &&
564 DP_CreateDirectPlay3( (LPVOID)This ) &&
565 DP_CreateDirectPlay4( (LPVOID)This )
576 /* Unsupported interface */
578 return E_NOINTERFACE;
582 DP_DestroyDirectPlay4( *ppvObj );
583 DP_DestroyDirectPlay3( *ppvObj );
584 DP_DestroyDirectPlay2( *ppvObj );
585 DP_DestroyIUnknown( *ppvObj );
586 HeapFree( GetProcessHeap(), 0, *ppvObj );
589 return DPERR_NOMEMORY;
594 /* Direct Play methods */
595 static HRESULT WINAPI DirectPlay2W_QueryInterface
596 ( LPDIRECTPLAY2 iface, REFIID riid, LPVOID* ppvObj )
598 ICOM_THIS(IDirectPlay2Impl,iface);
599 TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
601 if( IsEqualGUID( &IID_IUnknown, riid ) ||
602 IsEqualGUID( &IID_IDirectPlay2, riid )
605 IDirectPlayX_AddRef( iface );
609 return directPlay_QueryInterface( riid, ppvObj );
612 static HRESULT WINAPI DirectPlay2A_QueryInterface
613 ( LPDIRECTPLAY2A iface, REFIID riid, LPVOID* ppvObj )
615 ICOM_THIS(IDirectPlay2Impl,iface);
616 TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
618 if( IsEqualGUID( &IID_IUnknown, riid ) ||
619 IsEqualGUID( &IID_IDirectPlay2A, riid )
622 IDirectPlayX_AddRef( iface );
627 return directPlay_QueryInterface( riid, ppvObj );
630 static HRESULT WINAPI DirectPlay3WImpl_QueryInterface
631 ( LPDIRECTPLAY3 iface, REFIID riid, LPVOID* ppvObj )
633 ICOM_THIS(IDirectPlay3Impl,iface);
634 TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
636 if( IsEqualGUID( &IID_IUnknown, riid ) ||
637 IsEqualGUID( &IID_IDirectPlay3, riid )
640 IDirectPlayX_AddRef( iface );
645 return directPlay_QueryInterface( riid, ppvObj );
648 static HRESULT WINAPI DirectPlay3AImpl_QueryInterface
649 ( LPDIRECTPLAY3A iface, REFIID riid, LPVOID* ppvObj )
651 ICOM_THIS(IDirectPlay3Impl,iface);
652 TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
654 if( IsEqualGUID( &IID_IUnknown, riid ) ||
655 IsEqualGUID( &IID_IDirectPlay3A, riid )
658 IDirectPlayX_AddRef( iface );
663 return directPlay_QueryInterface( riid, ppvObj );
666 static HRESULT WINAPI DirectPlay4WImpl_QueryInterface
667 ( LPDIRECTPLAY4 iface, REFIID riid, LPVOID* ppvObj )
669 ICOM_THIS(IDirectPlay4Impl,iface);
670 TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
672 if( IsEqualGUID( &IID_IUnknown, riid ) ||
673 IsEqualGUID( &IID_IDirectPlay4, riid )
676 IDirectPlayX_AddRef( iface );
681 return directPlay_QueryInterface( riid, ppvObj );
685 static HRESULT WINAPI DirectPlay4AImpl_QueryInterface
686 ( LPDIRECTPLAY4A iface, REFIID riid, LPVOID* ppvObj )
688 ICOM_THIS(IDirectPlay4Impl,iface);
689 TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
691 if( IsEqualGUID( &IID_IUnknown, riid ) ||
692 IsEqualGUID( &IID_IDirectPlay4A, riid )
695 IDirectPlayX_AddRef( iface );
700 return directPlay_QueryInterface( riid, ppvObj );
704 /* Shared between all dplay types */
705 static ULONG WINAPI DirectPlay2AImpl_AddRef
706 ( LPDIRECTPLAY3 iface )
709 ICOM_THIS(IDirectPlay3Impl,iface);
711 refCount = InterlockedIncrement( &This->unk->ref );
713 TRACE("ref count incremented to %lu for %p\n", refCount, This );
718 static ULONG WINAPI DirectPlay2AImpl_Release
719 ( LPDIRECTPLAY3 iface )
723 ICOM_THIS(IDirectPlay3Impl,iface);
725 refCount = InterlockedDecrement( &This->unk->ref );
727 TRACE("ref count decremented to %lu for %p\n", refCount, This );
729 /* Deallocate if this is the last reference to the object */
732 DP_DestroyDirectPlay4( This );
733 DP_DestroyDirectPlay3( This );
734 DP_DestroyDirectPlay2( This );
735 DP_DestroyIUnknown( This );
736 HeapFree( GetProcessHeap(), 0, This );
742 static HRESULT WINAPI DirectPlay2AImpl_AddPlayerToGroup
743 ( LPDIRECTPLAY2A iface, DPID idGroup, DPID idPlayer )
746 lpPlayerList lpPList;
747 lpPlayerList lpNewPList;
749 ICOM_THIS(IDirectPlay2AImpl,iface);
751 TRACE("(%p)->(0x%08lx,0x%08lx)\n", This, idGroup, idPlayer );
754 if( ( lpGList = DP_FindAnyGroup( This, idGroup ) ) == NULL )
756 return DPERR_INVALIDGROUP;
759 /* Find the player */
760 if( ( lpPList = DP_FindPlayer( This, idPlayer ) ) == NULL )
762 return DPERR_INVALIDPLAYER;
765 /* Create a player list (ie "shortcut" ) */
766 lpNewPList = (lpPlayerList)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
767 sizeof( *lpNewPList ) );
768 if( lpNewPList == NULL )
770 return DPERR_CANTADDPLAYER;
773 /* Add the shortcut */
774 lpNewPList->lpPData = lpPList->lpPData;
776 /* Add the player to the list of players for this group */
777 DPQ_INSERT(lpGList->lpGData->players,lpNewPList,players);
779 /* Send a ADDPLAYERTOGROUP message */
780 FIXME( "Not sending message\n" );
785 static HRESULT WINAPI DirectPlay2WImpl_AddPlayerToGroup
786 ( LPDIRECTPLAY2 iface, DPID idGroup, DPID idPlayer )
788 ICOM_THIS(IDirectPlay2Impl,iface);
789 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idPlayer );
794 static HRESULT WINAPI DirectPlay2AImpl_Close
795 ( LPDIRECTPLAY2A iface )
797 ICOM_THIS(IDirectPlay2Impl,iface);
798 FIXME("(%p)->(): stub\n", This );
802 static HRESULT WINAPI DirectPlay2WImpl_Close
803 ( LPDIRECTPLAY2 iface )
805 ICOM_THIS(IDirectPlay2Impl,iface);
806 FIXME("(%p)->(): stub\n", This );
811 lpGroupData DP_CreateGroup( IDirectPlay2AImpl* This, LPDPID lpid,
812 LPDPNAME lpName, lpGroupData lpParentData,
817 TRACE( "(%p)->(%p,%p,%u)\n", This, lpid, lpName, bAnsi );
819 /* Allocate the new space and add to end of high level group list */
820 lpGroup = (lpGroupList) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
821 sizeof( *lpGroup ) );
823 if( lpGroup == NULL )
828 /* Allocate storage for the group and associate it with the list element */
829 lpGroup->lpGData = (lpGroupData) HeapAlloc( GetProcessHeap(),
831 sizeof(*(lpGroup->lpGData)) );
833 if( lpGroup->lpGData == NULL )
835 /* FIXME: Memory leak */
839 DPQ_INSERT(This->dp2->groups,lpGroup,groups);
841 if( *lpid == DPID_UNKNOWN )
843 /* Assign the next available player ID - FIXME crap solution */
844 lpGroup->lpGData->dpid = kludgePlayerGroupId++;
848 /* Set the desired player ID - no sanity checking to see if it exists */
849 lpGroup->lpGData->dpid = *lpid;
852 DP_CopyDPNAMEStruct( &lpGroup->lpGData->name, lpName, bAnsi );
854 lpGroup->lpGData->parent = lpParentData;
856 return lpGroup->lpGData;
859 /* This method assumes that all links to it are already deleted */
861 DP_DeleteGroup( IDirectPlay2Impl* This, DPID dpid )
865 TRACE( "(%p)->(0x%08lx)\n", This, dpid );
867 DPQ_REMOVE_ENTRY( This->dp2->groups, groups, lpGData->dpid, dpid, lpGList );
869 if( lpGList == NULL )
871 ERR( "DPID 0x%08lx not found\n", dpid );
876 DP_DeleteDPNameStruct( &lpGList->lpGData->name );
877 HeapFree( GetProcessHeap(), 0, lpGList->lpGData );
879 /* Remove and Delete Player List object */
880 HeapFree( GetProcessHeap(), 0, lpGList );
884 /* This function only finds top level groups */
885 static lpGroupList DP_FindTopGroup( IDirectPlay2AImpl* This, DPID dpid )
887 lpGroupList lpGroups;
889 TRACE( "(%p)->(0x%08lx)\n", This, dpid );
891 /* Does the group exist? */
892 if( ( lpGroups = DP_FindAnyGroup( This, dpid ) ) == NULL )
897 /* Is this group a top level group? */
898 if( lpGroups->lpGData->parent )
908 static lpGroupList DP_FindAnyGroup( IDirectPlay2AImpl* This, DPID dpid )
910 lpGroupList lpGroups;
912 TRACE( "(%p)->(0x%08lx)\n", This, dpid );
914 DPQ_FIND_ENTRY( This->dp2->groups, groups, lpGData->dpid, dpid, lpGroups );
919 static HRESULT WINAPI DirectPlay2AImpl_CreateGroup
920 ( LPDIRECTPLAY2A iface, LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
924 ICOM_THIS(IDirectPlay2Impl,iface);
926 FIXME("(%p)->(%p,%p,%p,0x%08lx,0x%08lx): stub\n", This, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags );
928 lpGData = DP_CreateGroup( This, lpidGroup, lpGroupName,
929 NULL /* Top level group */, TRUE /* Ansi */ );
931 if( lpGData == NULL )
933 return DPERR_CANTADDPLAYER; /* yes player not group */
936 DP_SetGroupData( lpGData, lpData, dwDataSize );
938 /* FIXME: Should send DPMSG_CREATEPLAYERORGROUP message to everyone,
939 local and remote, that belongs to this session. This will not
940 be done by calling SetPlayerData */
941 FIXME( "Should broadcast group creation to everything in session\n" );
947 DP_SetGroupData( lpGroupData lpGData, LPVOID lpData, DWORD dwDataSize )
949 /* Clear out the data with this player */
950 if( lpGData->dwDataSize != 0 )
952 HeapFree( GetProcessHeap(), 0, lpGData->lpData );
953 lpGData->lpData = NULL;
954 lpGData->dwDataSize = 0;
957 /* Reallocate for new data */
960 lpGData->lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
961 sizeof( dwDataSize ) );
962 memcpy( lpGData->lpData, lpData, dwDataSize );
963 lpGData->dwDataSize = dwDataSize;
969 static HRESULT WINAPI DirectPlay2WImpl_CreateGroup
970 ( LPDIRECTPLAY2 iface, LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
972 ICOM_THIS(IDirectPlay2Impl,iface);
973 FIXME("(%p)->(%p,%p,%p,0x%08lx,0x%08lx): stub\n", This, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags );
977 /* This function will just create the storage for the new player.
978 * In the future it may want to intialize, but for the time being
979 * that will be done seperately.
981 * If *lpid == DPID_UNKNOWN then assign the next available player
984 lpPlayerData DP_CreatePlayer( IDirectPlay2Impl* This, LPDPID lpid,
985 LPDPNAME lpName, HANDLE hEvent, BOOL bAnsi )
987 lpPlayerList lpPlayer;
989 TRACE( "(%p)->(%p,%p,%u)\n", This, lpid, lpName, bAnsi );
991 /* Allocate the new space and add to end of interface player list */
992 lpPlayer = (lpPlayerList) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
993 sizeof( *lpPlayer ) );
995 if( lpPlayer == NULL )
1000 /* Allocate the storage for the player and associate it with list element */
1001 lpPlayer->lpPData = (lpPlayerData) HeapAlloc( GetProcessHeap(),
1003 sizeof(*(lpPlayer->lpPData)) );
1004 if( lpPlayer->lpPData == NULL )
1006 /* FIXME: Memory leak */
1010 /* Insert the player list into the master list of players */
1011 DPQ_INSERT( This->dp2->players, lpPlayer, players );
1013 if( *lpid == DPID_UNKNOWN )
1015 /* Assign the next available player ID - FIXME crap solution */
1016 lpPlayer->lpPData->dpid = kludgePlayerGroupId++;
1020 /* Set the desired player ID - no sanity checking to see if it exists */
1021 lpPlayer->lpPData->dpid = *lpid;
1024 DP_CopyDPNAMEStruct( &lpPlayer->lpPData->name, lpName, bAnsi );
1026 lpPlayer->lpPData->hEvent = hEvent;
1028 return lpPlayer->lpPData;
1031 /* Delete the contents of the DPNAME struct */
1033 DP_DeleteDPNameStruct( LPDPNAME lpDPName )
1035 HeapFree( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDPName->psn.lpszShortNameA );
1036 HeapFree( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDPName->pln.lpszLongNameA );
1039 /* This method assumes that all links to it are already deleted */
1041 DP_DeletePlayer( IDirectPlay2Impl* This, DPID dpid )
1043 lpPlayerList lpPlayers;
1045 TRACE( "(%p)->(0x%08lx)\n", This, dpid );
1047 DPQ_REMOVE_ENTRY( This->dp2->players, players, lpPData->dpid, dpid, lpPlayers );
1049 if( lpPlayers == NULL )
1051 ERR( "DPID 0x%08lx not found\n", dpid );
1056 DP_DeleteDPNameStruct( &lpPlayers->lpPData->name );
1057 HeapFree( GetProcessHeap(), 0, lpPlayers->lpPData );
1059 /* Delete Player List object */
1060 HeapFree( GetProcessHeap(), 0, lpPlayers );
1064 static lpPlayerList DP_FindPlayer( IDirectPlay2AImpl* This, DPID dpid )
1066 lpPlayerList lpPlayers;
1068 TRACE( "(%p)->(0x%08lx)\n", This, dpid );
1070 DPQ_FIND_ENTRY( This->dp2->players, players, lpPData->dpid, dpid, lpPlayers );
1075 /* Basic area for Dst must already be allocated */
1076 static BOOL DP_CopyDPNAMEStruct( LPDPNAME lpDst, LPDPNAME lpSrc, BOOL bAnsi )
1080 ZeroMemory( lpDst, sizeof( *lpDst ) );
1081 lpDst->dwSize = sizeof( *lpDst );
1085 if( lpSrc->dwSize != sizeof( *lpSrc) )
1090 /* Delete any existing pointers */
1091 if( lpDst->psn.lpszShortNameA )
1093 HeapFree( GetProcessHeap(), 0, lpDst->psn.lpszShortNameA );
1096 if( lpDst->pln.lpszLongNameA )
1098 HeapFree( GetProcessHeap(), 0, lpDst->psn.lpszShortNameA );
1101 /* Copy as required */
1102 memcpy( lpDst, lpSrc, lpSrc->dwSize );
1106 if( lpSrc->psn.lpszShortNameA )
1108 lpDst->psn.lpszShortNameA =
1109 HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY,
1110 lpSrc->psn.lpszShortNameA );
1112 if( lpSrc->pln.lpszLongNameA )
1114 lpDst->pln.lpszLongNameA =
1115 HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY,
1116 lpSrc->pln.lpszLongNameA );
1121 if( lpSrc->psn.lpszShortNameA )
1123 lpDst->psn.lpszShortName =
1124 HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY,
1125 lpSrc->psn.lpszShortName );
1127 if( lpSrc->pln.lpszLongNameA )
1129 lpDst->pln.lpszLongName =
1130 HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY,
1131 lpSrc->pln.lpszLongName );
1139 DP_SetPlayerData( lpPlayerData lpPData, LPVOID lpData, DWORD dwDataSize )
1141 /* Clear out the data with this player */
1142 if( lpPData->dwDataSize != 0 )
1144 HeapFree( GetProcessHeap(), 0, lpPData->lpData );
1145 lpPData->lpData = NULL;
1146 lpPData->dwDataSize = 0;
1149 /* Reallocate for new data */
1152 lpPData->lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
1153 sizeof( dwDataSize ) );
1154 memcpy( lpPData->lpData, lpData, dwDataSize );
1155 lpPData->dwDataSize = dwDataSize;
1160 static HRESULT WINAPI DP_IF_CreatePlayer
1161 ( IDirectPlay2Impl* This,
1163 LPDPNAME lpPlayerName,
1170 lpPlayerData lpPData;
1172 TRACE( "(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx,%u)\n",
1173 This, lpidPlayer, lpPlayerName, hEvent, lpData,
1174 dwDataSize, dwFlags, bAnsi );
1178 dwFlags = DPPLAYER_SPECTATOR;
1181 /* Verify we know how to handle all the flags */
1182 if( !( ( dwFlags & DPPLAYER_SERVERPLAYER ) ||
1183 ( dwFlags & DPPLAYER_SPECTATOR )
1187 /* Assume non fatal failure */
1188 ERR( "unknown dwFlags = 0x%08lx\n", dwFlags );
1191 if ( dwFlags & DPPLAYER_SERVERPLAYER )
1193 /* We have a request to create the "master" of the session.
1194 * This computer needs to be the session host and the server
1195 * player can't have been created yet.
1197 if( ( !This->dp2->bHostInterface ) ||
1198 ( DP_FindPlayer( This, DPID_SERVERPLAYER ) )
1201 TRACE( "Denying SERVERPLAYER creation\n" );
1202 return DPERR_CANTCREATEPLAYER;
1205 *lpidPlayer = DPID_SERVERPLAYER;
1209 *lpidPlayer = DPID_UNKNOWN;
1212 lpPData = DP_CreatePlayer( This, lpidPlayer,
1213 lpPlayerName, hEvent, bAnsi );
1215 if( lpPData == NULL )
1217 return DPERR_CANTADDPLAYER;
1220 /* Update the information and send it to all players in the session */
1221 DP_SetPlayerData( lpPData, lpData, dwDataSize );
1224 /* FIXME: Should send DPMSG_CREATEPLAYERORGROUP message to everyone,
1225 local and remote, that belongs to this session. This will not
1226 be done by calling SetPlayerData */
1227 FIXME( "Should broadcast player creation to everything in session\n" );
1232 static HRESULT WINAPI DirectPlay2AImpl_CreatePlayer
1233 ( LPDIRECTPLAY2A iface, LPDPID lpidPlayer, LPDPNAME lpPlayerName, HANDLE hEvent, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
1235 ICOM_THIS(IDirectPlay2Impl,iface);
1236 return DP_IF_CreatePlayer( This, lpidPlayer, lpPlayerName, hEvent,
1237 lpData, dwDataSize, dwFlags, TRUE );
1240 static HRESULT WINAPI DirectPlay2WImpl_CreatePlayer
1241 ( LPDIRECTPLAY2 iface, LPDPID lpidPlayer, LPDPNAME lpPlayerName, HANDLE hEvent, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
1243 ICOM_THIS(IDirectPlay2Impl,iface);
1244 return DP_IF_CreatePlayer( This, lpidPlayer, lpPlayerName, hEvent,
1245 lpData, dwDataSize, dwFlags, FALSE );
1248 static HRESULT WINAPI DP_IF_DeletePlayerFromGroup
1249 ( IDirectPlay2Impl* This, DPID idGroup, DPID idPlayer, BOOL bAnsi )
1251 lpGroupList lpGList;
1252 lpPlayerList lpPList;
1254 TRACE("(%p)->(0x%08lx,0x%08lx,%u)\n", This, idGroup, idPlayer, bAnsi );
1256 /* Find the group */
1257 if( ( lpGList = DP_FindAnyGroup( This, idGroup ) ) == NULL )
1259 return DPERR_INVALIDGROUP;
1262 /* Find the player */
1263 if( ( lpPList = DP_FindPlayer( This, idPlayer ) ) == NULL )
1265 return DPERR_INVALIDPLAYER;
1268 /* Remove the player shortcut from the group */
1269 DPQ_REMOVE_ENTRY( lpGList->lpGData->players, players, lpPData->dpid, idPlayer, lpPList );
1271 if( lpPList == NULL )
1276 /* Delete the Player List element */
1277 HeapFree( GetProcessHeap(), 0, lpPList );
1279 /* Need to send a DELETEPLAYERFROMGROUP message */
1280 FIXME( "Need to send a message\n" );
1285 static HRESULT WINAPI DirectPlay2AImpl_DeletePlayerFromGroup
1286 ( LPDIRECTPLAY2A iface, DPID idGroup, DPID idPlayer )
1288 ICOM_THIS(IDirectPlay2Impl,iface);
1289 return DP_IF_DeletePlayerFromGroup( This, idGroup, idPlayer, TRUE );
1292 static HRESULT WINAPI DirectPlay2WImpl_DeletePlayerFromGroup
1293 ( LPDIRECTPLAY2 iface, DPID idGroup, DPID idPlayer )
1295 ICOM_THIS(IDirectPlay2Impl,iface);
1296 return DP_IF_DeletePlayerFromGroup( This, idGroup, idPlayer, FALSE );
1299 typedef struct _DPRGOPContext
1301 LPDIRECTPLAY3 iface;
1304 } DPRGOPContext, *lpDPRGOPContext;
1307 cbRemoveGroupOrPlayer(
1314 lpDPRGOPContext lpCtxt = (lpDPRGOPContext)lpContext;
1315 TRACE( "Removing element:0x%08lx (type:0x%08lx) from element:0x%08lx\n",
1316 dpId, dwPlayerType, lpCtxt->idGroup );
1318 if( dwPlayerType == DPPLAYERTYPE_GROUP )
1320 if( FAILED( IDirectPlayX_DeleteGroupFromGroup( lpCtxt->iface,
1321 lpCtxt->idGroup, dpId )
1325 ERR( "Unable to delete group 0x%08lx from group 0x%08lx\n",
1326 dpId, lpCtxt->idGroup );
1331 if( FAILED( IDirectPlayX_DeletePlayerFromGroup( lpCtxt->iface,
1332 lpCtxt->idGroup, dpId )
1336 ERR( "Unable to delete player 0x%08lx from grp 0x%08lx\n",
1337 dpId, lpCtxt->idGroup );
1341 return TRUE; /* Continue enumeration */
1344 static HRESULT WINAPI DP_IF_DestroyGroup
1345 ( IDirectPlay2Impl* This, DPID idGroup, BOOL bAnsi )
1347 lpGroupList lpGList;
1348 DPRGOPContext context;
1350 FIXME("(%p)->(0x%08lx,%u): semi stub\n", This, idGroup, bAnsi );
1352 /* Find the group */
1353 if( ( lpGList = DP_FindAnyGroup( This, idGroup ) ) == NULL )
1355 return DPERR_INVALIDPLAYER; /* yes player */
1358 /* Yes we're performing a dangerous cast, but it will not be used
1359 unless it's actually a dp3 interface because we will have no
1360 nested groups to delete and we're performing a check below */
1361 context.iface = (LPDIRECTPLAY3)This;
1362 context.bAnsi = bAnsi;
1363 context.idGroup = idGroup;
1365 /* We should only concern ourselves with a group having groups if this is
1366 DirectPlay 3 or greater */
1369 /* Remove all links to groups that this group has since this is dp3 */
1370 IDirectPlayX_EnumGroupsInGroup( (LPDIRECTPLAY3A)This, idGroup, NULL,
1371 cbRemoveGroupOrPlayer, (LPVOID)&context, 0 );
1372 /* FIXME: Is it allowed to delete a sub group with a parent? Must be */
1373 if( lpGList->lpGData->parent )
1375 IDirectPlayX_DeleteGroupFromGroup( (LPDIRECTPLAY3A)This,
1376 lpGList->lpGData->parent->dpid,
1382 /* Remove all players that this group has */
1383 IDirectPlayX_EnumGroupPlayers( (LPDIRECTPLAY3A)This, idGroup, NULL,
1384 cbRemoveGroupOrPlayer, (LPVOID)&context, 0 );
1386 /* Now delete this group data and list */
1387 DP_DeleteGroup( This, idGroup );
1389 /* Send out a DESTORYPLAYERORGROUP message */
1394 static HRESULT WINAPI DirectPlay2AImpl_DestroyGroup
1395 ( LPDIRECTPLAY2A iface, DPID idGroup )
1397 ICOM_THIS(IDirectPlay2Impl,iface);
1398 return DP_IF_DestroyGroup( This, idGroup, TRUE );
1401 static HRESULT WINAPI DirectPlay2WImpl_DestroyGroup
1402 ( LPDIRECTPLAY2 iface, DPID idGroup )
1404 ICOM_THIS(IDirectPlay2Impl,iface);
1405 return DP_IF_DestroyGroup( This, idGroup, FALSE );
1408 typedef struct _DPFAGContext
1410 LPDIRECTPLAY2 iface;
1412 } DPFAGContext, *lpDPFAGContext;
1414 static HRESULT WINAPI DP_IF_DestroyPlayer
1415 ( IDirectPlay2Impl* This, DPID idPlayer, BOOL bAnsi )
1417 DPFAGContext cbContext;
1419 FIXME("(%p)->(0x%08lx,%u): semi stub\n", This, idPlayer, bAnsi );
1421 if( DP_FindPlayer( This, idPlayer ) )
1423 return DPERR_INVALIDPLAYER;
1426 /* FIXME: If the player is remote, we must be the host to delete this */
1428 cbContext.iface = (LPDIRECTPLAY2)This;
1429 cbContext.idPlayer = idPlayer;
1431 /* Find each group and call DeletePlayerFromGroup if the player is a
1432 member of the group */
1433 IDirectPlayX_EnumGroups( (LPDIRECTPLAY2)This, NULL, cbDeletePlayerFromAllGroups,
1434 (LPVOID)&cbContext, DPENUMGROUPS_ALL);
1436 /* Now delete player and player list */
1437 DP_DeletePlayer( This, idPlayer );
1439 /* FIXME: Send a DELETEPLAYERORGROUP msg */
1445 cbDeletePlayerFromAllGroups(
1452 lpDPFAGContext lpCtxt = (lpDPFAGContext)lpContext;
1454 if( dwPlayerType == DPPLAYERTYPE_GROUP )
1456 IDirectPlayX_DeletePlayerFromGroup( lpCtxt->iface, lpCtxt->idPlayer, dpId );
1458 /* Enumerate all groups in this group - yes this is pseudo recursive */
1459 IDirectPlayX_EnumGroupsInGroup( (LPDIRECTPLAY3A)lpCtxt->iface, /*FIXME*/
1461 cbDeletePlayerFromAllGroups,
1462 lpContext, DPENUMGROUPS_ALL );
1466 ERR( "Group callback has dwPlayerType = 0x%08lx\n", dwPlayerType );
1472 static HRESULT WINAPI DirectPlay2AImpl_DestroyPlayer
1473 ( LPDIRECTPLAY2A iface, DPID idPlayer )
1475 ICOM_THIS(IDirectPlay2Impl,iface);
1476 return DP_IF_DestroyPlayer( This, idPlayer, TRUE );
1479 static HRESULT WINAPI DirectPlay2WImpl_DestroyPlayer
1480 ( LPDIRECTPLAY2 iface, DPID idPlayer )
1482 ICOM_THIS(IDirectPlay2Impl,iface);
1483 return DP_IF_DestroyPlayer( This, idPlayer, FALSE );
1486 static HRESULT WINAPI DP_IF_EnumGroupPlayers
1487 ( IDirectPlay2Impl* This, DPID idGroup, LPGUID lpguidInstance,
1488 LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
1489 LPVOID lpContext, DWORD dwFlags, BOOL bAnsi )
1491 FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx,%u): stub\n",
1492 This, idGroup, lpguidInstance, lpEnumPlayersCallback2,
1493 lpContext, dwFlags, bAnsi );
1497 static HRESULT WINAPI DirectPlay2AImpl_EnumGroupPlayers
1498 ( LPDIRECTPLAY2A iface, DPID idGroup, LPGUID lpguidInstance,
1499 LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
1500 LPVOID lpContext, DWORD dwFlags )
1502 ICOM_THIS(IDirectPlay2Impl,iface);
1503 return DP_IF_EnumGroupPlayers( This, idGroup, lpguidInstance,
1504 lpEnumPlayersCallback2, lpContext,
1508 static HRESULT WINAPI DirectPlay2WImpl_EnumGroupPlayers
1509 ( LPDIRECTPLAY2 iface, DPID idGroup, LPGUID lpguidInstance,
1510 LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
1511 LPVOID lpContext, DWORD dwFlags )
1513 ICOM_THIS(IDirectPlay2Impl,iface);
1514 return DP_IF_EnumGroupPlayers( This, idGroup, lpguidInstance,
1515 lpEnumPlayersCallback2, lpContext,
1519 /* NOTE: This only enumerates top level groups (created with CreateGroup) */
1520 static HRESULT WINAPI DP_IF_EnumGroups
1521 ( IDirectPlay2Impl* This, LPGUID lpguidInstance,
1522 LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
1523 LPVOID lpContext, DWORD dwFlags, BOOL bAnsi )
1525 lpGroupList lpGList;
1527 FIXME("(%p)->(%p,%p,%p,0x%08lx,%u): semi stub\n",
1528 This, lpguidInstance, lpEnumPlayersCallback2,
1529 lpContext, dwFlags, bAnsi );
1531 lpGList = This->dp2->groups.lpQHFirst;
1535 /* Is this a top level group? */
1536 if( lpGList->lpGData->parent )
1541 /* FIXME: Should check dwFlags for match here */
1543 if( !(*lpEnumPlayersCallback2)( lpGList->lpGData->dpid, DPPLAYERTYPE_GROUP,
1544 &lpGList->lpGData->name, dwFlags,
1547 break; /* User requested break */
1550 if( ( lpGList = lpGList->groups.lpQNext ) == This->dp2->groups.lpQHFirst )
1559 static HRESULT WINAPI DirectPlay2AImpl_EnumGroups
1560 ( LPDIRECTPLAY2A iface, LPGUID lpguidInstance,
1561 LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
1562 LPVOID lpContext, DWORD dwFlags )
1564 ICOM_THIS(IDirectPlay2Impl,iface);
1565 return DP_IF_EnumGroups( This, lpguidInstance, lpEnumPlayersCallback2,
1566 lpContext, dwFlags, TRUE );
1569 static HRESULT WINAPI DirectPlay2WImpl_EnumGroups
1570 ( LPDIRECTPLAY2 iface, LPGUID lpguidInstance,
1571 LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
1572 LPVOID lpContext, DWORD dwFlags )
1574 ICOM_THIS(IDirectPlay2Impl,iface);
1575 return DP_IF_EnumGroups( This, lpguidInstance, lpEnumPlayersCallback2,
1576 lpContext, dwFlags, FALSE );
1579 static HRESULT WINAPI DP_IF_EnumPlayers
1580 ( IDirectPlay2Impl* This, LPGUID lpguidInstance,
1581 LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
1582 LPVOID lpContext, DWORD dwFlags, BOOL bAnsi )
1585 FIXME("(%p)->(%p,%p,%p,0x%08lx,%u): stub\n",
1586 This, lpguidInstance, lpEnumPlayersCallback2,
1587 lpContext, dwFlags, bAnsi );
1592 static HRESULT WINAPI DirectPlay2AImpl_EnumPlayers
1593 ( LPDIRECTPLAY2A iface, LPGUID lpguidInstance,
1594 LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
1595 LPVOID lpContext, DWORD dwFlags )
1597 ICOM_THIS(IDirectPlay2Impl,iface);
1598 return DP_IF_EnumPlayers( This, lpguidInstance, lpEnumPlayersCallback2,
1599 lpContext, dwFlags, TRUE );
1602 static HRESULT WINAPI DirectPlay2WImpl_EnumPlayers
1603 ( LPDIRECTPLAY2 iface, LPGUID lpguidInstance,
1604 LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
1605 LPVOID lpContext, DWORD dwFlags )
1607 ICOM_THIS(IDirectPlay2Impl,iface);
1608 return DP_IF_EnumPlayers( This, lpguidInstance, lpEnumPlayersCallback2,
1609 lpContext, dwFlags, FALSE );
1612 /* This function should call the registered callback function that the user
1613 passed into EnumSessions for each entry available.
1615 static void DP_InvokeEnumSessionCallbacksA( LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
1620 LPDPSESSIONDESC2 lpSessionDesc;
1622 FIXME( ": not checking for conditions\n" );
1624 NS_ResetSessionEnumeration( lpNSInfo );
1626 /* Enumerate all sessions */
1627 while( (lpSessionDesc = NS_WalkSessions( lpNSInfo ) ) != NULL )
1629 TRACE( "EnumSessionsCallback2 invoked\n" );
1630 if( !lpEnumSessionsCallback2( lpSessionDesc, &dwTimeout, 0, lpContext ) )
1638 static DWORD CALLBACK DP_EnumSessionsSpwanThreadA( LPVOID lpContext )
1640 ICOM_THIS(IDirectPlay2Impl,lpContext);
1641 DWORD dwTimeout = This->dp2->enumSessionAsyncCallbackData.dwTimeout;
1643 TRACE( "(%p)->(0x%08lx)\n", This, dwTimeout );
1645 /* FIXME: Don't think this is exactly right. It'll do for now */
1648 /* 2: Send the broadcast for session enumeration */
1649 NS_SendSessionRequestBroadcast( This->dp2->lpNameServerData );
1651 SleepEx( dwTimeout, FALSE );
1653 DP_InvokeEnumSessionCallbacksA( This->dp2->enumSessionAsyncCallbackData.cb,
1654 This->dp2->lpNameServerData,
1656 This->dp2->enumSessionAsyncCallbackData.lpContext );
1658 /* All sessions have been enumerated. Invoke the callback function
1659 once more indicating a timeout has occured. This is the way
1660 that the application can indicate that it wishes to continue with the
1662 if( !(This->dp2->enumSessionAsyncCallbackData.cb)( NULL, &dwTimeout, DPESC_TIMEDOUT, lpContext ) )
1664 /* The application doesn't want us to continue - end this thread */
1673 static HRESULT WINAPI DirectPlay2AImpl_EnumSessions
1674 ( LPDIRECTPLAY2A iface, LPDPSESSIONDESC2 lpsd, DWORD dwTimeout, LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
1675 LPVOID lpContext, DWORD dwFlags )
1677 ICOM_THIS(IDirectPlay2Impl,iface);
1679 TRACE("(%p)->(%p,0x%08lx,%p,%p,0x%08lx)\n", This, lpsd, dwTimeout, lpEnumSessionsCallback2, lpContext, dwFlags );
1681 if( dwTimeout == 0 )
1683 /* Should actually be getting the dwTimeout value through
1684 IDirectPlay_GetCaps( This, ...) */
1685 FIXME( ": should provide a dependent dwTimeout\n" );
1686 dwTimeout = 5 * 1000; /* 5 seconds */
1689 if( dwFlags & DPENUMSESSIONS_STOPASYNC )
1691 /* Does a thread exist? If so we were doing an async enum session */
1692 if( This->dp2->hEnumSessionThread != INVALID_HANDLE_VALUE )
1694 /* FIXME: This needs to be send an event to the thread to clean itself up nicely */
1695 TerminateThread( This->dp2->hEnumSessionThread, 0 );
1696 CloseHandle( This->dp2->hEnumSessionThread );
1698 This->dp2->hEnumSessionThread = INVALID_HANDLE_VALUE;
1700 This->dp2->enumSessionAsyncCallbackData.cb = NULL;
1701 This->dp2->enumSessionAsyncCallbackData.lpContext = NULL;
1702 This->dp2->enumSessionAsyncCallbackData.dwTimeout = INFINITE;
1707 /* Indicate some sort of error... */
1708 WARN( "STOPASYNC attempted when no async running\n" );
1712 /* FIXME: Interface locking sucks in this method */
1714 if( ( dwFlags & DPENUMSESSIONS_ASYNC ) )
1718 /* Enumerate everything presently in the local session cache */
1719 DP_InvokeEnumSessionCallbacksA( lpEnumSessionsCallback2, This->dp2->lpNameServerData, dwTimeout, lpContext );
1721 /* See if we've already created a thread to service this interface */
1722 if( This->dp2->hEnumSessionThread == INVALID_HANDLE_VALUE )
1724 /* FIXME: Should be adding a reference here - another thread now knows
1725 how to call this interface */
1726 This->dp2->enumSessionAsyncCallbackData.cb = lpEnumSessionsCallback2;
1727 This->dp2->enumSessionAsyncCallbackData.lpContext = lpContext;
1728 This->dp2->enumSessionAsyncCallbackData.dwTimeout = dwTimeout;
1730 TRACE( ": creating EnumSessions thread\n" );
1732 This->dp2->hEnumSessionThread = CreateThread( NULL,
1734 DP_EnumSessionsSpwanThreadA,
1743 /* Send the broadcast for session enumeration */
1744 NS_SendSessionRequestBroadcast( This->dp2->lpNameServerData );
1746 SleepEx( dwTimeout, FALSE );
1748 DP_InvokeEnumSessionCallbacksA( lpEnumSessionsCallback2, This->dp2->lpNameServerData, dwTimeout, lpContext );
1754 static HRESULT WINAPI DirectPlay2WImpl_EnumSessions
1755 ( LPDIRECTPLAY2 iface, LPDPSESSIONDESC2 lpsd, DWORD dwTimeout, LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
1756 LPVOID lpContext, DWORD dwFlags )
1758 ICOM_THIS(IDirectPlay2Impl,iface);
1759 FIXME("(%p)->(%p,0x%08lx,%p,%p,0x%08lx): stub\n", This, lpsd, dwTimeout, lpEnumSessionsCallback2, lpContext, dwFlags );
1763 static HRESULT WINAPI DirectPlay2AImpl_GetCaps
1764 ( LPDIRECTPLAY2A iface, LPDPCAPS lpDPCaps, DWORD dwFlags )
1766 ICOM_THIS(IDirectPlay2Impl,iface);
1767 FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpDPCaps, dwFlags );
1771 static HRESULT WINAPI DirectPlay2WImpl_GetCaps
1772 ( LPDIRECTPLAY2 iface, LPDPCAPS lpDPCaps, DWORD dwFlags )
1774 ICOM_THIS(IDirectPlay2Impl,iface);
1775 FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpDPCaps, dwFlags );
1779 static HRESULT WINAPI DP_IF_GetGroupData
1780 ( IDirectPlay2Impl* This, DPID idGroup, LPVOID lpData,
1781 LPDWORD lpdwDataSize, DWORD dwFlags, BOOL bAnsi )
1783 lpGroupList lpGList;
1785 FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx,%u): dwFlags ignored\n",
1786 This, idGroup, lpData, lpdwDataSize, dwFlags, bAnsi );
1788 if( ( lpGList = DP_FindAnyGroup( This, idGroup ) ) == NULL )
1790 return DPERR_INVALIDGROUP;
1793 /* Is the user requesting to know how big a buffer is required? */
1794 if( ( lpData == NULL ) ||
1795 ( *lpdwDataSize < lpGList->lpGData->dwDataSize )
1798 *lpdwDataSize = lpGList->lpGData->dwDataSize;
1799 return DPERR_BUFFERTOOSMALL;
1802 memcpy( lpData, lpGList->lpGData->lpData, lpGList->lpGData->dwDataSize );
1807 static HRESULT WINAPI DirectPlay2AImpl_GetGroupData
1808 ( LPDIRECTPLAY2A iface, DPID idGroup, LPVOID lpData,
1809 LPDWORD lpdwDataSize, DWORD dwFlags )
1811 ICOM_THIS(IDirectPlay2Impl,iface);
1812 return DP_IF_GetGroupData( This, idGroup, lpData, lpdwDataSize,
1816 static HRESULT WINAPI DirectPlay2WImpl_GetGroupData
1817 ( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData,
1818 LPDWORD lpdwDataSize, DWORD dwFlags )
1820 ICOM_THIS(IDirectPlay2Impl,iface);
1821 return DP_IF_GetGroupData( This, idGroup, lpData, lpdwDataSize,
1825 static HRESULT WINAPI DP_IF_GetGroupName
1826 ( IDirectPlay2Impl* This, DPID idGroup, LPVOID lpData,
1827 LPDWORD lpdwDataSize, BOOL bAnsi )
1829 lpGroupList lpGList;
1830 LPDPNAME lpName = (LPDPNAME)lpData;
1831 DWORD dwRequiredDataSize;
1833 FIXME("(%p)->(0x%08lx,%p,%p,%u) ANSI ignored\n",
1834 This, idGroup, lpData, lpdwDataSize, bAnsi );
1836 if( ( lpGList = DP_FindAnyGroup( This, idGroup ) ) == NULL )
1838 return DPERR_INVALIDGROUP;
1841 dwRequiredDataSize = lpGList->lpGData->name.dwSize;
1843 if( lpGList->lpGData->name.psn.lpszShortNameA )
1845 dwRequiredDataSize += strlen( lpGList->lpGData->name.psn.lpszShortNameA ) + 1;
1848 if( lpGList->lpGData->name.pln.lpszLongNameA )
1850 dwRequiredDataSize += strlen( lpGList->lpGData->name.pln.lpszLongNameA ) + 1;
1853 if( ( lpData == NULL ) ||
1854 ( *lpdwDataSize < dwRequiredDataSize )
1857 *lpdwDataSize = dwRequiredDataSize;
1858 return DPERR_BUFFERTOOSMALL;
1861 /* Copy the structure */
1862 memcpy( lpName, &lpGList->lpGData->name, lpGList->lpGData->name.dwSize );
1864 if( lpGList->lpGData->name.psn.lpszShortNameA )
1866 strcpy( ((BYTE*)lpName)+lpGList->lpGData->name.dwSize,
1867 lpGList->lpGData->name.psn.lpszShortNameA );
1871 lpName->psn.lpszShortNameA = NULL;
1874 if( lpGList->lpGData->name.psn.lpszShortNameA )
1876 strcpy( ((BYTE*)lpName)+lpGList->lpGData->name.dwSize,
1877 lpGList->lpGData->name.pln.lpszLongNameA );
1881 lpName->pln.lpszLongNameA = NULL;
1887 static HRESULT WINAPI DirectPlay2AImpl_GetGroupName
1888 ( LPDIRECTPLAY2A iface, DPID idGroup, LPVOID lpData,
1889 LPDWORD lpdwDataSize )
1891 ICOM_THIS(IDirectPlay2Impl,iface);
1892 return DP_IF_GetGroupName( This, idGroup, lpData, lpdwDataSize, TRUE );
1895 static HRESULT WINAPI DirectPlay2WImpl_GetGroupName
1896 ( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData,
1897 LPDWORD lpdwDataSize )
1899 ICOM_THIS(IDirectPlay2Impl,iface);
1900 return DP_IF_GetGroupName( This, idGroup, lpData, lpdwDataSize, FALSE );
1903 static HRESULT WINAPI DirectPlay2AImpl_GetMessageCount
1904 ( LPDIRECTPLAY2A iface, DPID idPlayer, LPDWORD lpdwCount )
1906 ICOM_THIS(IDirectPlay2Impl,iface);
1907 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idPlayer, lpdwCount );
1911 static HRESULT WINAPI DirectPlay2WImpl_GetMessageCount
1912 ( LPDIRECTPLAY2 iface, DPID idPlayer, LPDWORD lpdwCount )
1914 ICOM_THIS(IDirectPlay2Impl,iface);
1915 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idPlayer, lpdwCount );
1919 static HRESULT WINAPI DirectPlay2AImpl_GetPlayerAddress
1920 ( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize )
1922 ICOM_THIS(IDirectPlay2Impl,iface);
1923 FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idPlayer, lpData, lpdwDataSize );
1927 static HRESULT WINAPI DirectPlay2WImpl_GetPlayerAddress
1928 ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize )
1930 ICOM_THIS(IDirectPlay2Impl,iface);
1931 FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idPlayer, lpData, lpdwDataSize );
1935 static HRESULT WINAPI DirectPlay2AImpl_GetPlayerCaps
1936 ( LPDIRECTPLAY2A iface, DPID idPlayer, LPDPCAPS lpPlayerCaps, DWORD dwFlags )
1938 ICOM_THIS(IDirectPlay2Impl,iface);
1939 FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idPlayer, lpPlayerCaps, dwFlags );
1943 static HRESULT WINAPI DirectPlay2WImpl_GetPlayerCaps
1944 ( LPDIRECTPLAY2 iface, DPID idPlayer, LPDPCAPS lpPlayerCaps, DWORD dwFlags )
1946 ICOM_THIS(IDirectPlay2Impl,iface);
1947 FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idPlayer, lpPlayerCaps, dwFlags );
1951 static HRESULT WINAPI DP_IF_GetPlayerData
1952 ( IDirectPlay2Impl* This, DPID idPlayer, LPVOID lpData,
1953 LPDWORD lpdwDataSize, DWORD dwFlags, BOOL bAnsi )
1955 lpPlayerList lpPList;
1957 FIXME( "(%p)->(0x%08lx,%p,%p,0x%08lx,%u): stub\n",
1958 This, idPlayer, lpData, lpdwDataSize, dwFlags, bAnsi );
1960 if( ( lpPList = DP_FindPlayer( This, idPlayer ) ) == NULL )
1962 return DPERR_INVALIDPLAYER;
1965 /* Is the user requesting to know how big a buffer is required? */
1966 if( ( lpData == NULL ) ||
1967 ( *lpdwDataSize < lpPList->lpPData->dwDataSize )
1970 *lpdwDataSize = lpPList->lpPData->dwDataSize;
1971 return DPERR_BUFFERTOOSMALL;
1974 memcpy( lpData, lpPList->lpPData->lpData, lpPList->lpPData->dwDataSize );
1979 static HRESULT WINAPI DirectPlay2AImpl_GetPlayerData
1980 ( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData,
1981 LPDWORD lpdwDataSize, DWORD dwFlags )
1983 ICOM_THIS(IDirectPlay2Impl,iface);
1984 return DP_IF_GetPlayerData( This, idPlayer, lpData, lpdwDataSize,
1988 static HRESULT WINAPI DirectPlay2WImpl_GetPlayerData
1989 ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData,
1990 LPDWORD lpdwDataSize, DWORD dwFlags )
1992 ICOM_THIS(IDirectPlay2Impl,iface);
1993 return DP_IF_GetPlayerData( This, idPlayer, lpData, lpdwDataSize,
1997 static HRESULT WINAPI DP_IF_GetPlayerName
1998 ( IDirectPlay2Impl* This, DPID idPlayer, LPVOID lpData,
1999 LPDWORD lpdwDataSize, BOOL bAnsi )
2001 lpPlayerList lpPList;
2002 LPDPNAME lpName = (LPDPNAME)lpData;
2003 DWORD dwRequiredDataSize;
2005 FIXME( "(%p)->(0x%08lx,%p,%p,%u): ANSI \n",
2006 This, idPlayer, lpData, lpdwDataSize, bAnsi );
2008 if( ( lpPList = DP_FindPlayer( This, idPlayer ) ) == NULL )
2010 return DPERR_INVALIDPLAYER;
2013 dwRequiredDataSize = lpPList->lpPData->name.dwSize;
2015 if( lpPList->lpPData->name.psn.lpszShortNameA )
2017 dwRequiredDataSize += strlen( lpPList->lpPData->name.psn.lpszShortNameA ) + 1;
2020 if( lpPList->lpPData->name.pln.lpszLongNameA )
2022 dwRequiredDataSize += strlen( lpPList->lpPData->name.pln.lpszLongNameA ) + 1;
2025 if( ( lpData == NULL ) ||
2026 ( *lpdwDataSize < dwRequiredDataSize )
2029 *lpdwDataSize = dwRequiredDataSize;
2030 return DPERR_BUFFERTOOSMALL;
2033 /* Copy the structure */
2034 memcpy( lpName, &lpPList->lpPData->name, lpPList->lpPData->name.dwSize );
2036 if( lpPList->lpPData->name.psn.lpszShortNameA )
2038 strcpy( ((BYTE*)lpName)+lpPList->lpPData->name.dwSize,
2039 lpPList->lpPData->name.psn.lpszShortNameA );
2043 lpName->psn.lpszShortNameA = NULL;
2046 if( lpPList->lpPData->name.psn.lpszShortNameA )
2048 strcpy( ((BYTE*)lpName)+lpPList->lpPData->name.dwSize,
2049 lpPList->lpPData->name.pln.lpszLongNameA );
2053 lpName->pln.lpszLongNameA = NULL;
2059 static HRESULT WINAPI DirectPlay2AImpl_GetPlayerName
2060 ( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData,
2061 LPDWORD lpdwDataSize )
2063 ICOM_THIS(IDirectPlay2Impl,iface);
2064 return DP_IF_GetPlayerName( This, idPlayer, lpData, lpdwDataSize, TRUE );
2067 static HRESULT WINAPI DirectPlay2WImpl_GetPlayerName
2068 ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData,
2069 LPDWORD lpdwDataSize )
2071 ICOM_THIS(IDirectPlay2Impl,iface);
2072 return DP_IF_GetPlayerName( This, idPlayer, lpData, lpdwDataSize, FALSE );
2075 static HRESULT WINAPI DirectPlay2AImpl_GetSessionDesc
2076 ( LPDIRECTPLAY2A iface, LPVOID lpData, LPDWORD lpdwDataSize )
2078 ICOM_THIS(IDirectPlay2Impl,iface);
2079 FIXME("(%p)->(%p,%p): stub\n", This, lpData, lpdwDataSize );
2083 static HRESULT WINAPI DirectPlay2WImpl_GetSessionDesc
2084 ( LPDIRECTPLAY2 iface, LPVOID lpData, LPDWORD lpdwDataSize )
2086 ICOM_THIS(IDirectPlay2Impl,iface);
2087 FIXME("(%p)->(%p,%p): stub\n", This, lpData, lpdwDataSize );
2091 /* Intended only for COM compatibility. Always returns an error. */
2092 static HRESULT WINAPI DirectPlay2AImpl_Initialize
2093 ( LPDIRECTPLAY2A iface, LPGUID lpGUID )
2095 ICOM_THIS(IDirectPlay2Impl,iface);
2096 TRACE("(%p)->(%p): stub\n", This, lpGUID );
2097 return DPERR_ALREADYINITIALIZED;
2100 /* Intended only for COM compatibility. Always returns an error. */
2101 static HRESULT WINAPI DirectPlay2WImpl_Initialize
2102 ( LPDIRECTPLAY2 iface, LPGUID lpGUID )
2104 ICOM_THIS(IDirectPlay2Impl,iface);
2105 TRACE("(%p)->(%p): stub\n", This, lpGUID );
2106 return DPERR_ALREADYINITIALIZED;
2110 static HRESULT WINAPI DP_SecureOpen
2111 ( IDirectPlay2Impl* This, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags,
2112 LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials )
2114 FIXME( "(%p)->(%p,0x%08lx,%p,%p): semi stub\n",
2115 This, lpsd, dwFlags, lpSecurity, lpCredentials );
2117 if( This->dp2->bConnectionOpen )
2119 TRACE( ": rejecting already open connection.\n" );
2120 return DPERR_ALREADYINITIALIZED;
2123 /* When we open we need to stop any EnumSession activity */
2124 /* FIXME: Perhaps some sort of internal interface would be better */
2125 IDirectPlayX_EnumSessions( (LPDIRECTPLAY2A)This, NULL, 0, NULL, NULL,
2126 DPENUMSESSIONS_STOPASYNC );
2128 if( dwFlags & DPOPEN_CREATE )
2130 dwFlags &= ~DPOPEN_CREATE;
2132 /* Rightoo - this computer is the host and the local computer needs to be
2133 the name server so that others can join this session */
2134 NS_SetLocalComputerAsNameServer( lpsd );
2136 This->dp2->bHostInterface = TRUE;
2141 ERR( ": ignored dwFlags 0x%08lx\n", dwFlags );
2147 static HRESULT WINAPI DirectPlay2AImpl_Open
2148 ( LPDIRECTPLAY2A iface, LPDPSESSIONDESC2 lpsd, DWORD dwFlags )
2150 ICOM_THIS(IDirectPlay2Impl,iface);
2151 TRACE("(%p)->(%p,0x%08lx)\n", This, lpsd, dwFlags );
2152 return DP_SecureOpen( This, lpsd, dwFlags, NULL, NULL );
2155 static HRESULT WINAPI DirectPlay2WImpl_Open
2156 ( LPDIRECTPLAY2 iface, LPDPSESSIONDESC2 lpsd, DWORD dwFlags )
2158 ICOM_THIS(IDirectPlay2Impl,iface);
2159 TRACE("(%p)->(%p,0x%08lx)\n", This, lpsd, dwFlags );
2160 return DP_SecureOpen( This, lpsd, dwFlags, NULL, NULL );
2163 static HRESULT WINAPI DirectPlay2AImpl_Receive
2164 ( LPDIRECTPLAY2A iface, LPDPID lpidFrom, LPDPID lpidTo, DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize )
2166 ICOM_THIS(IDirectPlay2Impl,iface);
2167 FIXME("(%p)->(%p,%p,0x%08lx,%p,%p): stub\n", This, lpidFrom, lpidTo, dwFlags, lpData, lpdwDataSize );
2171 static HRESULT WINAPI DirectPlay2WImpl_Receive
2172 ( LPDIRECTPLAY2 iface, LPDPID lpidFrom, LPDPID lpidTo, DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize )
2174 ICOM_THIS(IDirectPlay2Impl,iface);
2175 FIXME("(%p)->(%p,%p,0x%08lx,%p,%p): stub\n", This, lpidFrom, lpidTo, dwFlags, lpData, lpdwDataSize );
2179 static HRESULT WINAPI DirectPlay2AImpl_Send
2180 ( LPDIRECTPLAY2A iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize )
2182 ICOM_THIS(IDirectPlay2Impl,iface);
2183 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx): stub\n", This, idFrom, idTo, dwFlags, lpData, dwDataSize );
2187 static HRESULT WINAPI DirectPlay2WImpl_Send
2188 ( LPDIRECTPLAY2 iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize )
2190 ICOM_THIS(IDirectPlay2Impl,iface);
2191 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx): stub\n", This, idFrom, idTo, dwFlags, lpData, dwDataSize );
2195 static HRESULT WINAPI DP_IF_SetGroupData
2196 ( IDirectPlay2Impl* This, DPID idGroup, LPVOID lpData,
2197 DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi )
2199 lpGroupList lpGList;
2201 FIXME( "(%p)->(0x%08lx,%p,0x%08lx,0x%08lx,%u): dwFlags ignored\n",
2202 This, idGroup, lpData, dwDataSize, dwFlags, bAnsi );
2204 /* Parameter check */
2205 if( ( lpData == NULL ) &&
2209 return DPERR_INVALIDPARAMS;
2212 /* Find the pointer to the data for this player */
2213 if( ( lpGList = DP_FindAnyGroup( This, idGroup ) ) == NULL )
2215 return DPERR_INVALIDOBJECT;
2218 DP_SetGroupData( lpGList->lpGData, lpData, dwDataSize );
2223 static HRESULT WINAPI DirectPlay2AImpl_SetGroupData
2224 ( LPDIRECTPLAY2A iface, DPID idGroup, LPVOID lpData,
2225 DWORD dwDataSize, DWORD dwFlags )
2227 ICOM_THIS(IDirectPlay2Impl,iface);
2228 return DP_IF_SetGroupData( This, idGroup, lpData, dwDataSize, dwFlags, TRUE );
2231 static HRESULT WINAPI DirectPlay2WImpl_SetGroupData
2232 ( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData,
2233 DWORD dwDataSize, DWORD dwFlags )
2235 ICOM_THIS(IDirectPlay2Impl,iface);
2236 return DP_IF_SetGroupData( This, idGroup, lpData, dwDataSize, dwFlags, FALSE );
2239 static HRESULT WINAPI DP_IF_SetGroupName
2240 ( IDirectPlay2Impl* This, DPID idGroup, LPDPNAME lpGroupName,
2241 DWORD dwFlags, BOOL bAnsi )
2243 lpGroupList lpGList;
2245 TRACE( "(%p)->(0x%08lx,%p,0x%08lx,%u)\n", This, idGroup,
2246 lpGroupName, dwFlags, bAnsi );
2248 if( ( lpGList = DP_FindAnyGroup( This, idGroup ) ) == NULL )
2250 return DPERR_INVALIDGROUP;
2253 DP_CopyDPNAMEStruct( &lpGList->lpGData->name, lpGroupName, bAnsi );
2255 /* Should send a DPMSG_SETPLAYERORGROUPNAME message */
2256 FIXME( "Message not sent and dwFlags ignored\n" );
2261 static HRESULT WINAPI DirectPlay2AImpl_SetGroupName
2262 ( LPDIRECTPLAY2A iface, DPID idGroup, LPDPNAME lpGroupName,
2265 ICOM_THIS(IDirectPlay2Impl,iface);
2266 return DP_IF_SetGroupName( This, idGroup, lpGroupName, dwFlags, TRUE );
2269 static HRESULT WINAPI DirectPlay2WImpl_SetGroupName
2270 ( LPDIRECTPLAY2 iface, DPID idGroup, LPDPNAME lpGroupName,
2273 ICOM_THIS(IDirectPlay2Impl,iface);
2274 return DP_IF_SetGroupName( This, idGroup, lpGroupName, dwFlags, FALSE );
2277 static HRESULT WINAPI DP_IF_SetPlayerData
2278 ( IDirectPlay2Impl* This, DPID idPlayer, LPVOID lpData,
2279 DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi )
2281 lpPlayerList lpPList;
2283 TRACE( "(%p)->(0x%08lx,%p,0x%08lx,0x%08lx,%u)\n",
2284 This, idPlayer, lpData, dwDataSize, dwFlags, bAnsi );
2286 /* Parameter check */
2287 if( ( lpData == NULL ) &&
2291 return DPERR_INVALIDPARAMS;
2294 /* Find the pointer to the data for this player */
2295 if( ( lpPList = DP_FindPlayer( This, idPlayer ) ) == NULL )
2297 return DPERR_INVALIDPLAYER;
2300 DP_SetPlayerData( lpPList->lpPData, lpData, dwDataSize );
2302 if( !(dwFlags & DPSET_LOCAL ) ) /* Is DPSET_REMOTE? */
2304 FIXME( "Change not propagated to all players in the session\n" );
2310 static HRESULT WINAPI DirectPlay2AImpl_SetPlayerData
2311 ( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData,
2312 DWORD dwDataSize, DWORD dwFlags )
2314 ICOM_THIS(IDirectPlay2Impl,iface);
2315 return DP_IF_SetPlayerData( This, idPlayer, lpData, dwDataSize,
2319 static HRESULT WINAPI DirectPlay2WImpl_SetPlayerData
2320 ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData,
2321 DWORD dwDataSize, DWORD dwFlags )
2323 ICOM_THIS(IDirectPlay2Impl,iface);
2324 return DP_IF_SetPlayerData( This, idPlayer, lpData, dwDataSize,
2328 static HRESULT WINAPI DP_IF_SetPlayerName
2329 ( IDirectPlay2Impl* This, DPID idPlayer, LPDPNAME lpPlayerName,
2330 DWORD dwFlags, BOOL bAnsi )
2332 lpPlayerList lpPList;
2334 TRACE( "(%p)->(0x%08lx,%p,0x%08lx,%u)\n",
2335 This, idPlayer, lpPlayerName, dwFlags, bAnsi );
2337 if( ( lpPList = DP_FindPlayer( This, idPlayer ) ) == NULL )
2339 return DPERR_INVALIDGROUP;
2342 DP_CopyDPNAMEStruct( &lpPList->lpPData->name, lpPlayerName, bAnsi );
2344 /* Should send a DPMSG_SETPLAYERORGROUPNAME message */
2345 FIXME( "Message not sent and dwFlags ignored\n" );
2350 static HRESULT WINAPI DirectPlay2AImpl_SetPlayerName
2351 ( LPDIRECTPLAY2A iface, DPID idPlayer, LPDPNAME lpPlayerName,
2354 ICOM_THIS(IDirectPlay2Impl,iface);
2355 return DP_IF_SetPlayerName( This, idPlayer, lpPlayerName, dwFlags, TRUE );
2358 static HRESULT WINAPI DirectPlay2WImpl_SetPlayerName
2359 ( LPDIRECTPLAY2 iface, DPID idPlayer, LPDPNAME lpPlayerName,
2362 ICOM_THIS(IDirectPlay2Impl,iface);
2363 return DP_IF_SetPlayerName( This, idPlayer, lpPlayerName, dwFlags, FALSE );
2366 static HRESULT WINAPI DirectPlay2AImpl_SetSessionDesc
2367 ( LPDIRECTPLAY2A iface, LPDPSESSIONDESC2 lpSessDesc, DWORD dwFlags )
2369 ICOM_THIS(IDirectPlay2Impl,iface);
2370 FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpSessDesc, dwFlags );
2374 static HRESULT WINAPI DirectPlay2WImpl_SetSessionDesc
2375 ( LPDIRECTPLAY2 iface, LPDPSESSIONDESC2 lpSessDesc, DWORD dwFlags )
2377 ICOM_THIS(IDirectPlay2Impl,iface);
2378 FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpSessDesc, dwFlags );
2382 static HRESULT WINAPI DP_IF_AddGroupToGroup
2383 ( IDirectPlay3Impl* This, DPID idParentGroup, DPID idGroup )
2385 lpGroupList lpGParentList;
2386 lpGroupList lpGList;
2387 lpGroupList lpNewGList;
2389 TRACE( "(%p)->(0x%08lx,0x%08lx)\n", This, idParentGroup, idGroup );
2391 if( ( lpGParentList = DP_FindAnyGroup( (IDirectPlay2AImpl*)This, idParentGroup ) ) == NULL )
2393 return DPERR_INVALIDGROUP;
2396 if( ( lpGList = DP_FindAnyGroup( (IDirectPlay2AImpl*)This, idGroup ) ) == NULL )
2398 return DPERR_INVALIDGROUP;
2401 /* Create a player list (ie "shortcut" ) */
2402 lpNewGList = (lpGroupList)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
2403 sizeof( *lpNewGList ) );
2404 if( lpNewGList == NULL )
2406 return DPERR_CANTADDPLAYER;
2409 /* Add the shortcut */
2410 lpNewGList->lpGData = lpGList->lpGData;
2412 /* Add the player to the list of players for this group */
2413 DPQ_INSERT( lpGList->lpGData->groups, lpNewGList, groups );
2415 /* Send a ADDGROUPTOGROUP message */
2416 FIXME( "Not sending message\n" );
2421 static HRESULT WINAPI DirectPlay3AImpl_AddGroupToGroup
2422 ( LPDIRECTPLAY3A iface, DPID idParentGroup, DPID idGroup )
2424 ICOM_THIS(IDirectPlay3Impl,iface);
2425 return DP_IF_AddGroupToGroup( This, idParentGroup, idGroup );
2428 static HRESULT WINAPI DirectPlay3WImpl_AddGroupToGroup
2429 ( LPDIRECTPLAY3 iface, DPID idParentGroup, DPID idGroup )
2431 ICOM_THIS(IDirectPlay3Impl,iface);
2432 return DP_IF_AddGroupToGroup( This, idParentGroup, idGroup );
2435 static HRESULT WINAPI DP_IF_CreateGroupInGroup
2436 ( IDirectPlay3Impl* This, DPID idParentGroup, LPDPID lpidGroup,
2437 LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize,
2440 lpGroupList lpGParentList;
2441 lpGroupList lpGList;
2442 lpGroupData lpGData;
2444 TRACE( "(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx)\n",
2445 This, idParentGroup, lpidGroup, lpGroupName, lpData,
2446 dwDataSize, dwFlags );
2448 /* Verify that the specified parent is valid */
2449 if( ( lpGParentList = DP_FindAnyGroup( (IDirectPlay2AImpl*)This,
2450 idParentGroup ) ) == NULL
2453 return DPERR_INVALIDGROUP;
2456 lpGData = DP_CreateGroup( (IDirectPlay2AImpl*)This, lpidGroup, lpGroupName,
2457 lpGParentList->lpGData, TRUE /* Ansi */ );
2459 if( lpGData == NULL )
2461 return DPERR_CANTADDPLAYER; /* yes player not group */
2464 DP_SetGroupData( lpGData, lpData, dwDataSize );
2466 /* The list has now been inserted into the interface group list. We now
2467 need to put a "shortcut" to this group in the parent group */
2468 lpGList = (lpGroupList)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
2469 sizeof( *lpGList ) );
2470 if( lpGList == NULL )
2472 FIXME( "Memory leak\n" );
2473 return DPERR_CANTADDPLAYER; /* yes player not group */
2476 lpGList->lpGData = lpGData;
2478 DPQ_INSERT( lpGParentList->lpGData->groups, lpGList, groups );
2481 /* FIXME: Should send DPMSG_CREATEPLAYERORGROUP message to everyone,
2482 local and remote, that belongs to this session. This will not
2483 be done by calling SetPlayerData */
2484 FIXME( "Should broadcast group creation to everything in session\n" );
2489 static HRESULT WINAPI DirectPlay3AImpl_CreateGroupInGroup
2490 ( LPDIRECTPLAY3A iface, DPID idParentGroup, LPDPID lpidGroup,
2491 LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize,
2494 ICOM_THIS(IDirectPlay3Impl,iface);
2495 return DP_IF_CreateGroupInGroup( This, idParentGroup, lpidGroup, lpGroupName,
2496 lpData, dwDataSize, dwFlags );
2499 static HRESULT WINAPI DirectPlay3WImpl_CreateGroupInGroup
2500 ( LPDIRECTPLAY3 iface, DPID idParentGroup, LPDPID lpidGroup,
2501 LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize,
2504 ICOM_THIS(IDirectPlay3Impl,iface);
2505 return DP_IF_CreateGroupInGroup( This, idParentGroup, lpidGroup, lpGroupName,
2506 lpData, dwDataSize, dwFlags );
2509 static HRESULT WINAPI DP_IF_DeleteGroupFromGroup
2510 ( IDirectPlay3Impl* This, DPID idParentGroup, DPID idGroup )
2512 lpGroupList lpGList;
2513 lpGroupList lpGParentList;
2515 TRACE("(%p)->(0x%08lx,0x%08lx)\n", This, idParentGroup, idGroup );
2517 /* Is the parent group valid? */
2518 if( ( lpGParentList = DP_FindAnyGroup( (IDirectPlay2AImpl*)This, idParentGroup ) ) == NULL )
2520 return DPERR_INVALIDGROUP;
2523 /* Remove the group from the parent group queue */
2524 DPQ_REMOVE_ENTRY( lpGParentList->lpGData->groups, groups, lpGData->dpid, idGroup, lpGList );
2526 if( lpGList == NULL )
2528 return DPERR_INVALIDGROUP;
2531 /* Free up the list item */
2532 HeapFree( GetProcessHeap(), 0, lpGList );
2534 /* Should send a DELETEGROUPFROMGROUP message */
2535 FIXME( "message not sent\n" );
2540 static HRESULT WINAPI DirectPlay3AImpl_DeleteGroupFromGroup
2541 ( LPDIRECTPLAY3 iface, DPID idParentGroup, DPID idGroup )
2543 ICOM_THIS(IDirectPlay3Impl,iface);
2544 return DP_IF_DeleteGroupFromGroup( This, idParentGroup, idGroup );
2547 static HRESULT WINAPI DirectPlay3WImpl_DeleteGroupFromGroup
2548 ( LPDIRECTPLAY3 iface, DPID idParentGroup, DPID idGroup )
2550 ICOM_THIS(IDirectPlay3Impl,iface);
2551 return DP_IF_DeleteGroupFromGroup( This, idParentGroup, idGroup );
2554 static HRESULT WINAPI DirectPlay3AImpl_EnumConnections
2555 ( LPDIRECTPLAY3A iface, LPCGUID lpguidApplication, LPDPENUMCONNECTIONSCALLBACK lpEnumCallback, LPVOID lpContext, DWORD dwFlags )
2557 ICOM_THIS(IDirectPlay3Impl,iface);
2558 TRACE("(%p)->(%p,%p,%p,0x%08lx)\n", This, lpguidApplication, lpEnumCallback, lpContext, dwFlags );
2560 /* A default dwFlags (0) is backwards compatible -- DPCONNECTION_DIRECTPLAY */
2563 dwFlags = DPCONNECTION_DIRECTPLAY;
2566 if( ! ( ( dwFlags & DPCONNECTION_DIRECTPLAY ) ||
2567 ( dwFlags & DPCONNECTION_DIRECTPLAYLOBBY ) )
2570 return DPERR_INVALIDFLAGS;
2573 if( !lpEnumCallback || !*lpEnumCallback )
2575 return DPERR_INVALIDPARAMS;
2578 /* Enumerate DirectPlay service providers */
2579 if( dwFlags & DPCONNECTION_DIRECTPLAY )
2582 LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
2583 LPSTR guidDataSubKey = "Guid";
2584 char subKeyName[51];
2585 DWORD dwIndex, sizeOfSubKeyName=50;
2588 /* Need to loop over the service providers in the registry */
2589 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
2590 0, KEY_READ, &hkResult ) != ERROR_SUCCESS )
2592 /* Hmmm. Does this mean that there are no service providers? */
2593 ERR(": no service providers?\n");
2598 /* Traverse all the service providers we have available */
2600 RegEnumKeyExA( hkResult, dwIndex, subKeyName, &sizeOfSubKeyName,
2601 NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS;
2602 ++dwIndex, sizeOfSubKeyName=51 )
2605 HKEY hkServiceProvider;
2606 GUID serviceProviderGUID;
2607 DWORD returnTypeGUID, sizeOfReturnBuffer = 50;
2608 char returnBuffer[51];
2609 LPWSTR lpWGUIDString;
2613 DPCOMPOUNDADDRESSELEMENT dpCompoundAddress;
2614 LPVOID lpAddressBuffer = NULL;
2615 DWORD dwAddressBufferSize = 0;
2617 TRACE(" this time through: %s\n", subKeyName );
2619 /* Get a handle for this particular service provider */
2620 if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_READ,
2621 &hkServiceProvider ) != ERROR_SUCCESS )
2623 ERR(": what the heck is going on?\n" );
2627 if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
2628 NULL, &returnTypeGUID, returnBuffer,
2629 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
2631 ERR(": missing GUID registry data members\n" );
2635 /* FIXME: Check return types to ensure we're interpreting data right */
2636 lpWGUIDString = HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer );
2637 CLSIDFromString( (LPCOLESTR)lpWGUIDString, &serviceProviderGUID );
2638 HeapFree( GetProcessHeap(), 0, lpWGUIDString );
2639 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
2641 /* Fill in the DPNAME struct for the service provider */
2642 dpName.dwSize = sizeof( dpName );
2644 dpName.psn.lpszShortNameA = subKeyName;
2645 dpName.pln.lpszLongNameA = NULL;
2647 /* Create the compound address for the service provider.
2648 NOTE: This is a gruesome architectural scar right now. DP uses DPL and DPL uses DP
2649 nast stuff. This may be why the native dll just gets around this little bit by
2650 allocating an 80 byte buffer which isn't even a filled with a valid compound
2651 address. Oh well. Creating a proper compound address is the way to go anyways
2652 despite this method taking slightly more heap space and realtime :) */
2653 dpCompoundAddress.guidDataType = DPAID_ServiceProvider;
2654 dpCompoundAddress.dwDataSize = sizeof( GUID );
2655 dpCompoundAddress.lpData = &serviceProviderGUID;
2657 if( ( hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, lpAddressBuffer,
2658 &dwAddressBufferSize, TRUE ) ) != DPERR_BUFFERTOOSMALL )
2660 ERR( "can't get buffer size: %s\n", DPLAYX_HresultToString( hr ) );
2664 /* Now allocate the buffer */
2665 lpAddressBuffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAddressBufferSize );
2667 if( ( hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, lpAddressBuffer,
2668 &dwAddressBufferSize, TRUE ) ) != DP_OK )
2670 ERR( "can't create address: %s\n", DPLAYX_HresultToString( hr ) );
2674 /* The enumeration will return FALSE if we are not to continue */
2675 if( !lpEnumCallback( &serviceProviderGUID, lpAddressBuffer, dwAddressBufferSize,
2676 &dpName, DPCONNECTION_DIRECTPLAY, lpContext ) )
2678 WARN("lpEnumCallback returning FALSE\n" );
2685 /* Enumerate DirectPlayLobby service providers */
2686 if( dwFlags & DPCONNECTION_DIRECTPLAYLOBBY )
2689 LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Lobby Providers";
2690 LPSTR guidDataSubKey = "Guid";
2691 char subKeyName[51];
2692 DWORD dwIndex, sizeOfSubKeyName=50;
2695 /* Need to loop over the service providers in the registry */
2696 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
2697 0, KEY_READ, &hkResult ) != ERROR_SUCCESS )
2699 /* Hmmm. Does this mean that there are no service providers? */
2700 ERR(": no service providers?\n");
2705 /* Traverse all the service providers we have available */
2707 RegEnumKeyExA( hkResult, dwIndex, subKeyName, &sizeOfSubKeyName,
2708 NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS;
2709 ++dwIndex, sizeOfSubKeyName=51 )
2712 HKEY hkServiceProvider;
2713 GUID serviceProviderGUID;
2714 DWORD returnTypeGUID, sizeOfReturnBuffer = 50;
2715 char returnBuffer[51];
2716 LPWSTR lpWGUIDString;
2720 DPCOMPOUNDADDRESSELEMENT dpCompoundAddress;
2721 LPVOID lpAddressBuffer = NULL;
2722 DWORD dwAddressBufferSize = 0;
2724 TRACE(" this time through: %s\n", subKeyName );
2726 /* Get a handle for this particular service provider */
2727 if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_READ,
2728 &hkServiceProvider ) != ERROR_SUCCESS )
2730 ERR(": what the heck is going on?\n" );
2734 if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
2735 NULL, &returnTypeGUID, returnBuffer,
2736 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
2738 ERR(": missing GUID registry data members\n" );
2742 /* FIXME: Check return types to ensure we're interpreting data right */
2743 lpWGUIDString = HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer );
2744 CLSIDFromString( (LPCOLESTR)lpWGUIDString, &serviceProviderGUID );
2745 HeapFree( GetProcessHeap(), 0, lpWGUIDString );
2746 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
2748 /* Fill in the DPNAME struct for the service provider */
2749 dpName.dwSize = sizeof( dpName );
2751 dpName.psn.lpszShortNameA = subKeyName;
2752 dpName.pln.lpszLongNameA = NULL;
2754 /* Create the compound address for the service provider.
2755 NOTE: This is a gruesome architectural scar right now. DP uses DPL and DPL uses DP
2756 nast stuff. This may be why the native dll just gets around this little bit by
2757 allocating an 80 byte buffer which isn't even a filled with a valid compound
2758 address. Oh well. Creating a proper compound address is the way to go anyways
2759 despite this method taking slightly more heap space and realtime :) */
2760 dpCompoundAddress.guidDataType = DPAID_ServiceProvider;
2761 dpCompoundAddress.dwDataSize = sizeof( GUID );
2762 dpCompoundAddress.lpData = &serviceProviderGUID;
2764 if( ( hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, lpAddressBuffer,
2765 &dwAddressBufferSize, TRUE ) ) != DPERR_BUFFERTOOSMALL )
2767 ERR( "can't get buffer size: %s\n", DPLAYX_HresultToString( hr ) );
2771 /* Now allocate the buffer */
2772 lpAddressBuffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAddressBufferSize );
2774 if( ( hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, lpAddressBuffer,
2775 &dwAddressBufferSize, TRUE ) ) != DP_OK )
2777 ERR( "can't create address: %s\n", DPLAYX_HresultToString( hr ) );
2781 /* The enumeration will return FALSE if we are not to continue */
2782 if( !lpEnumCallback( &serviceProviderGUID, lpAddressBuffer, dwAddressBufferSize,
2783 &dpName, DPCONNECTION_DIRECTPLAY, lpContext ) )
2785 WARN("lpEnumCallback returning FALSE\n" );
2795 static HRESULT WINAPI DirectPlay3WImpl_EnumConnections
2796 ( LPDIRECTPLAY3 iface, LPCGUID lpguidApplication, LPDPENUMCONNECTIONSCALLBACK lpEnumCallback, LPVOID lpContext, DWORD dwFlags )
2798 ICOM_THIS(IDirectPlay3Impl,iface);
2799 FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidApplication, lpEnumCallback, lpContext, dwFlags );
2803 static HRESULT WINAPI DirectPlay3AImpl_EnumGroupsInGroup
2804 ( LPDIRECTPLAY3A iface, DPID idGroup, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
2806 lpGroupList lpGList;
2807 lpGroupList lpGiGList;
2808 ICOM_THIS(IDirectPlay3AImpl,iface);
2810 FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): semi stub\n", This, idGroup, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
2812 if( ( lpGList = DP_FindAnyGroup( (IDirectPlay2AImpl*)This, idGroup ) ) == NULL )
2814 return DPERR_INVALIDGROUP;
2817 lpGiGList = lpGList->lpGData->groups.lpQHFirst;
2821 /* FIXME: Should check dwFlags for match here */
2823 if( !(*lpEnumPlayersCallback2)( lpGList->lpGData->dpid, DPPLAYERTYPE_GROUP,
2824 &lpGList->lpGData->name, dwFlags,
2827 return DP_OK; /* User requested break */
2830 if( ( lpGiGList = lpGiGList->groups.lpQNext ) == lpGList->lpGData->groups.lpQHFirst )
2832 return DP_OK; /* End of groups */
2839 static HRESULT WINAPI DirectPlay3WImpl_EnumGroupsInGroup
2840 ( LPDIRECTPLAY3 iface, DPID idGroup, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
2842 ICOM_THIS(IDirectPlay3Impl,iface);
2843 FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub\n", This, idGroup, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
2847 static HRESULT WINAPI DirectPlay3AImpl_GetGroupConnectionSettings
2848 ( LPDIRECTPLAY3A iface, DWORD dwFlags, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize )
2850 ICOM_THIS(IDirectPlay3Impl,iface);
2851 FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, dwFlags, idGroup, lpData, lpdwDataSize );
2855 static HRESULT WINAPI DirectPlay3WImpl_GetGroupConnectionSettings
2856 ( LPDIRECTPLAY3 iface, DWORD dwFlags, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize )
2858 ICOM_THIS(IDirectPlay3Impl,iface);
2859 FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, dwFlags, idGroup, lpData, lpdwDataSize );
2863 static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
2864 ( LPDIRECTPLAY3A iface, LPVOID lpConnection, DWORD dwFlags )
2866 HMODULE hServiceProvider;
2867 /*DWORD dwReturnValue; */
2868 typedef DWORD (WINAPI *SP_SPInit)(LPVOID, LPVOID, LPVOID ); /* FIXME: How many arguments? */
2871 ICOM_THIS(IDirectPlay3Impl,iface);
2873 FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpConnection, dwFlags );
2877 return DPERR_INVALIDFLAGS;
2880 if( This->dp3->bConnectionInitialized == TRUE )
2882 return DPERR_ALREADYINITIALIZED;
2885 /* Parse lpConnection as a compound address for the service provider */
2886 /* Take service provider GUID and find the path to it */
2888 /* FIXME: Hard coded to only load the tcp/ip service provider for now... */
2889 hServiceProvider = LoadLibraryA( "dpwsockx.dll" );
2891 if( hServiceProvider == 0 )
2893 ERR( "Unable to load service provider\n" );
2894 return DPERR_UNAVAILABLE;
2897 /* Initialize the service provider by calling SPInit */
2898 SPInit = (SP_SPInit)GetProcAddress( hServiceProvider, "SPInit" );
2900 if( SPInit == NULL )
2902 ERR( "Service provider doesn't provide SPInit interface?\n" );
2906 /* NOTE: This will crash until I know what parameters/interface this has */
2907 /* FIXME: Take a guess that we just pass the compound address to the SP */
2908 /* Hmmm...how to say which parameters need to be gotten from the SP. They must
2909 come from the compound address, but how do we communicate what's required? */
2910 dwReturnValue = (*SPInit)( lpConnection, NULL, NULL );
2913 /* This interface is now initialized */
2914 This->dp3->bConnectionInitialized = TRUE;
2919 static HRESULT WINAPI DirectPlay3WImpl_InitializeConnection
2920 ( LPDIRECTPLAY3 iface, LPVOID lpConnection, DWORD dwFlags )
2922 ICOM_THIS(IDirectPlay3Impl,iface);
2923 FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpConnection, dwFlags );
2927 static HRESULT WINAPI DirectPlay3AImpl_SecureOpen
2928 ( LPDIRECTPLAY3A iface, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags,
2929 LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials )
2931 ICOM_THIS(IDirectPlay2Impl,iface); /* Yes a dp 2 interface */
2932 return DP_SecureOpen( This, lpsd, dwFlags, lpSecurity, lpCredentials );
2935 static HRESULT WINAPI DirectPlay3WImpl_SecureOpen
2936 ( LPDIRECTPLAY3 iface, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags,
2937 LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials )
2939 ICOM_THIS(IDirectPlay2Impl,iface); /* Yes a dp 2 interface */
2940 return DP_SecureOpen( This, lpsd, dwFlags, lpSecurity, lpCredentials );
2943 static HRESULT WINAPI DirectPlay3AImpl_SendChatMessage
2944 ( LPDIRECTPLAY3A iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPDPCHAT lpChatMessage )
2946 ICOM_THIS(IDirectPlay3Impl,iface);
2947 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p): stub\n", This, idFrom, idTo, dwFlags, lpChatMessage );
2951 static HRESULT WINAPI DirectPlay3WImpl_SendChatMessage
2952 ( LPDIRECTPLAY3 iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPDPCHAT lpChatMessage )
2954 ICOM_THIS(IDirectPlay3Impl,iface);
2955 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p): stub\n", This, idFrom, idTo, dwFlags, lpChatMessage );
2959 static HRESULT WINAPI DirectPlay3AImpl_SetGroupConnectionSettings
2960 ( LPDIRECTPLAY3A iface, DWORD dwFlags, DPID idGroup, LPDPLCONNECTION lpConnection )
2962 ICOM_THIS(IDirectPlay3Impl,iface);
2963 FIXME("(%p)->(0x%08lx,0x%08lx,%p): stub\n", This, dwFlags, idGroup, lpConnection );
2967 static HRESULT WINAPI DirectPlay3WImpl_SetGroupConnectionSettings
2968 ( LPDIRECTPLAY3 iface, DWORD dwFlags, DPID idGroup, LPDPLCONNECTION lpConnection )
2970 ICOM_THIS(IDirectPlay3Impl,iface);
2971 FIXME("(%p)->(0x%08lx,0x%08lx,%p): stub\n", This, dwFlags, idGroup, lpConnection );
2975 static HRESULT WINAPI DirectPlay3AImpl_StartSession
2976 ( LPDIRECTPLAY3A iface, DWORD dwFlags, DPID idGroup )
2978 ICOM_THIS(IDirectPlay3Impl,iface);
2979 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, dwFlags, idGroup );
2983 static HRESULT WINAPI DirectPlay3WImpl_StartSession
2984 ( LPDIRECTPLAY3 iface, DWORD dwFlags, DPID idGroup )
2986 ICOM_THIS(IDirectPlay3Impl,iface);
2987 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, dwFlags, idGroup );
2991 static HRESULT WINAPI DirectPlay3AImpl_GetGroupFlags
2992 ( LPDIRECTPLAY3A iface, DPID idGroup, LPDWORD lpdwFlags )
2994 ICOM_THIS(IDirectPlay3Impl,iface);
2995 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpdwFlags );
2999 static HRESULT WINAPI DirectPlay3WImpl_GetGroupFlags
3000 ( LPDIRECTPLAY3 iface, DPID idGroup, LPDWORD lpdwFlags )
3002 ICOM_THIS(IDirectPlay3Impl,iface);
3003 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpdwFlags );
3007 static HRESULT WINAPI DirectPlay3AImpl_GetGroupParent
3008 ( LPDIRECTPLAY3A iface, DPID idGroup, LPDPID lpidGroup )
3010 lpGroupList lpGList;
3012 ICOM_THIS(IDirectPlay3AImpl,iface);
3014 TRACE("(%p)->(0x%08lx,%p)\n", This, idGroup, lpidGroup );
3016 if( ( lpGList = DP_FindAnyGroup( (IDirectPlay2AImpl*)This, idGroup ) ) == NULL )
3018 return DPERR_INVALIDGROUP;
3021 *lpidGroup = lpGList->lpGData->dpid;
3026 static HRESULT WINAPI DirectPlay3WImpl_GetGroupParent
3027 ( LPDIRECTPLAY3 iface, DPID idGroup, LPDPID lpidGroup )
3029 ICOM_THIS(IDirectPlay3Impl,iface);
3030 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpidGroup );
3034 static HRESULT WINAPI DirectPlay3AImpl_GetPlayerAccount
3035 ( LPDIRECTPLAY3A iface, DPID idPlayer, DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize )
3037 ICOM_THIS(IDirectPlay3Impl,iface);
3038 FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, idPlayer, dwFlags, lpData, lpdwDataSize );
3042 static HRESULT WINAPI DirectPlay3WImpl_GetPlayerAccount
3043 ( LPDIRECTPLAY3 iface, DPID idPlayer, DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize )
3045 ICOM_THIS(IDirectPlay3Impl,iface);
3046 FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, idPlayer, dwFlags, lpData, lpdwDataSize );
3050 static HRESULT WINAPI DirectPlay3AImpl_GetPlayerFlags
3051 ( LPDIRECTPLAY3A iface, DPID idPlayer, LPDWORD lpdwFlags )
3053 ICOM_THIS(IDirectPlay3Impl,iface);
3054 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idPlayer, lpdwFlags );
3058 static HRESULT WINAPI DirectPlay3WImpl_GetPlayerFlags
3059 ( LPDIRECTPLAY3 iface, DPID idPlayer, LPDWORD lpdwFlags )
3061 ICOM_THIS(IDirectPlay3Impl,iface);
3062 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idPlayer, lpdwFlags );
3066 static HRESULT WINAPI DirectPlay4AImpl_GetGroupOwner
3067 ( LPDIRECTPLAY4A iface, DPID idGroup, LPDPID lpidGroupOwner )
3069 ICOM_THIS(IDirectPlay4Impl,iface);
3070 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpidGroupOwner );
3074 static HRESULT WINAPI DirectPlay4WImpl_GetGroupOwner
3075 ( LPDIRECTPLAY4 iface, DPID idGroup, LPDPID lpidGroupOwner )
3077 ICOM_THIS(IDirectPlay4Impl,iface);
3078 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpidGroupOwner );
3082 static HRESULT WINAPI DirectPlay4AImpl_SetGroupOwner
3083 ( LPDIRECTPLAY4A iface, DPID idGroup , DPID idGroupOwner )
3085 ICOM_THIS(IDirectPlay4Impl,iface);
3086 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idGroupOwner );
3090 static HRESULT WINAPI DirectPlay4WImpl_SetGroupOwner
3091 ( LPDIRECTPLAY4 iface, DPID idGroup , DPID idGroupOwner )
3093 ICOM_THIS(IDirectPlay4Impl,iface);
3094 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idGroupOwner );
3098 static HRESULT WINAPI DirectPlay4AImpl_SendEx
3099 ( LPDIRECTPLAY4A iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize, DWORD dwPriority, DWORD dwTimeout, LPVOID lpContext, LPDWORD lpdwMsgID )
3101 ICOM_THIS(IDirectPlay4Impl,iface);
3102 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx,0x%08lx,0x%08lx,%p,%p): stub\n", This, idFrom, idTo, dwFlags, lpData, dwDataSize, dwPriority, dwTimeout, lpContext, lpdwMsgID );
3106 static HRESULT WINAPI DirectPlay4WImpl_SendEx
3107 ( LPDIRECTPLAY4 iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize, DWORD dwPriority, DWORD dwTimeout, LPVOID lpContext, LPDWORD lpdwMsgID )
3109 ICOM_THIS(IDirectPlay4Impl,iface);
3110 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx,0x%08lx,0x%08lx,%p,%p): stub\n", This, idFrom, idTo, dwFlags, lpData, dwDataSize, dwPriority, dwTimeout, lpContext, lpdwMsgID );
3114 static HRESULT WINAPI DirectPlay4AImpl_GetMessageQueue
3115 ( LPDIRECTPLAY4A iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPDWORD lpdwNumMsgs, LPDWORD lpdwNumBytes )
3117 ICOM_THIS(IDirectPlay4Impl,iface);
3118 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,%p): stub\n", This, idFrom, idTo, dwFlags, lpdwNumMsgs, lpdwNumBytes );
3122 static HRESULT WINAPI DirectPlay4WImpl_GetMessageQueue
3123 ( LPDIRECTPLAY4 iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPDWORD lpdwNumMsgs, LPDWORD lpdwNumBytes )
3125 ICOM_THIS(IDirectPlay4Impl,iface);
3126 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,%p): stub\n", This, idFrom, idTo, dwFlags, lpdwNumMsgs, lpdwNumBytes );
3130 static HRESULT WINAPI DirectPlay4AImpl_CancelMessage
3131 ( LPDIRECTPLAY4A iface, DWORD dwMsgID, DWORD dwFlags )
3133 ICOM_THIS(IDirectPlay4Impl,iface);
3134 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, dwMsgID, dwFlags );
3138 static HRESULT WINAPI DirectPlay4WImpl_CancelMessage
3139 ( LPDIRECTPLAY4 iface, DWORD dwMsgID, DWORD dwFlags )
3141 ICOM_THIS(IDirectPlay4Impl,iface);
3142 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, dwMsgID, dwFlags );
3146 static HRESULT WINAPI DirectPlay4AImpl_CancelPriority
3147 ( LPDIRECTPLAY4A iface, DWORD dwMinPriority, DWORD dwMaxPriority, DWORD dwFlags )
3149 ICOM_THIS(IDirectPlay4Impl,iface);
3150 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx): stub\n", This, dwMinPriority, dwMaxPriority, dwFlags );
3154 static HRESULT WINAPI DirectPlay4WImpl_CancelPriority
3155 ( LPDIRECTPLAY4 iface, DWORD dwMinPriority, DWORD dwMaxPriority, DWORD dwFlags )
3157 ICOM_THIS(IDirectPlay4Impl,iface);
3158 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx): stub\n", This, dwMinPriority, dwMaxPriority, dwFlags );
3162 /* Note: Hack so we can reuse the old functions without compiler warnings */
3163 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
3164 # define XCAST(fun) (typeof(directPlay2WVT.fn##fun))
3166 # define XCAST(fun) (void*)
3169 static ICOM_VTABLE(IDirectPlay2) directPlay2WVT =
3171 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3172 DirectPlay2W_QueryInterface,
3173 XCAST(AddRef)DirectPlay2AImpl_AddRef,
3174 XCAST(Release)DirectPlay2AImpl_Release,
3176 DirectPlay2WImpl_AddPlayerToGroup,
3177 DirectPlay2WImpl_Close,
3178 DirectPlay2WImpl_CreateGroup,
3179 DirectPlay2WImpl_CreatePlayer,
3180 DirectPlay2WImpl_DeletePlayerFromGroup,
3181 DirectPlay2WImpl_DestroyGroup,
3182 DirectPlay2WImpl_DestroyPlayer,
3183 DirectPlay2WImpl_EnumGroupPlayers,
3184 DirectPlay2WImpl_EnumGroups,
3185 DirectPlay2WImpl_EnumPlayers,
3186 DirectPlay2WImpl_EnumSessions,
3187 DirectPlay2WImpl_GetCaps,
3188 DirectPlay2WImpl_GetGroupData,
3189 DirectPlay2WImpl_GetGroupName,
3190 DirectPlay2WImpl_GetMessageCount,
3191 DirectPlay2WImpl_GetPlayerAddress,
3192 DirectPlay2WImpl_GetPlayerCaps,
3193 DirectPlay2WImpl_GetPlayerData,
3194 DirectPlay2WImpl_GetPlayerName,
3195 DirectPlay2WImpl_GetSessionDesc,
3196 DirectPlay2WImpl_Initialize,
3197 DirectPlay2WImpl_Open,
3198 DirectPlay2WImpl_Receive,
3199 DirectPlay2WImpl_Send,
3200 DirectPlay2WImpl_SetGroupData,
3201 DirectPlay2WImpl_SetGroupName,
3202 DirectPlay2WImpl_SetPlayerData,
3203 DirectPlay2WImpl_SetPlayerName,
3204 DirectPlay2WImpl_SetSessionDesc
3208 /* Note: Hack so we can reuse the old functions without compiler warnings */
3209 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
3210 # define XCAST(fun) (typeof(directPlay2AVT.fn##fun))
3212 # define XCAST(fun) (void*)
3215 static ICOM_VTABLE(IDirectPlay2) directPlay2AVT =
3217 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3218 DirectPlay2A_QueryInterface,
3219 XCAST(AddRef)DirectPlay2AImpl_AddRef,
3220 XCAST(Release)DirectPlay2AImpl_Release,
3222 DirectPlay2AImpl_AddPlayerToGroup,
3223 DirectPlay2AImpl_Close,
3224 DirectPlay2AImpl_CreateGroup,
3225 DirectPlay2AImpl_CreatePlayer,
3226 DirectPlay2AImpl_DeletePlayerFromGroup,
3227 DirectPlay2AImpl_DestroyGroup,
3228 DirectPlay2AImpl_DestroyPlayer,
3229 DirectPlay2AImpl_EnumGroupPlayers,
3230 DirectPlay2AImpl_EnumGroups,
3231 DirectPlay2AImpl_EnumPlayers,
3232 DirectPlay2AImpl_EnumSessions,
3233 DirectPlay2AImpl_GetCaps,
3234 DirectPlay2AImpl_GetGroupData,
3235 DirectPlay2AImpl_GetGroupName,
3236 DirectPlay2AImpl_GetMessageCount,
3237 DirectPlay2AImpl_GetPlayerAddress,
3238 DirectPlay2AImpl_GetPlayerCaps,
3239 DirectPlay2AImpl_GetPlayerData,
3240 DirectPlay2AImpl_GetPlayerName,
3241 DirectPlay2AImpl_GetSessionDesc,
3242 DirectPlay2AImpl_Initialize,
3243 DirectPlay2AImpl_Open,
3244 DirectPlay2AImpl_Receive,
3245 DirectPlay2AImpl_Send,
3246 DirectPlay2AImpl_SetGroupData,
3247 DirectPlay2AImpl_SetGroupName,
3248 DirectPlay2AImpl_SetPlayerData,
3249 DirectPlay2AImpl_SetPlayerName,
3250 DirectPlay2AImpl_SetSessionDesc
3255 /* Note: Hack so we can reuse the old functions without compiler warnings */
3256 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
3257 # define XCAST(fun) (typeof(directPlay3AVT.fn##fun))
3259 # define XCAST(fun) (void*)
3262 static ICOM_VTABLE(IDirectPlay3) directPlay3AVT =
3264 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3265 DirectPlay3AImpl_QueryInterface,
3266 XCAST(AddRef)DirectPlay2AImpl_AddRef,
3267 XCAST(Release)DirectPlay2AImpl_Release,
3269 XCAST(AddPlayerToGroup)DirectPlay2AImpl_AddPlayerToGroup,
3270 XCAST(Close)DirectPlay2AImpl_Close,
3271 XCAST(CreateGroup)DirectPlay2AImpl_CreateGroup,
3272 XCAST(CreatePlayer)DirectPlay2AImpl_CreatePlayer,
3273 XCAST(DeletePlayerFromGroup)DirectPlay2AImpl_DeletePlayerFromGroup,
3274 XCAST(DestroyGroup)DirectPlay2AImpl_DestroyGroup,
3275 XCAST(DestroyPlayer)DirectPlay2AImpl_DestroyPlayer,
3276 XCAST(EnumGroupPlayers)DirectPlay2AImpl_EnumGroupPlayers,
3277 XCAST(EnumGroups)DirectPlay2AImpl_EnumGroups,
3278 XCAST(EnumPlayers)DirectPlay2AImpl_EnumPlayers,
3279 XCAST(EnumSessions)DirectPlay2AImpl_EnumSessions,
3280 XCAST(GetCaps)DirectPlay2AImpl_GetCaps,
3281 XCAST(GetGroupData)DirectPlay2AImpl_GetGroupData,
3282 XCAST(GetGroupName)DirectPlay2AImpl_GetGroupName,
3283 XCAST(GetMessageCount)DirectPlay2AImpl_GetMessageCount,
3284 XCAST(GetPlayerAddress)DirectPlay2AImpl_GetPlayerAddress,
3285 XCAST(GetPlayerCaps)DirectPlay2AImpl_GetPlayerCaps,
3286 XCAST(GetPlayerData)DirectPlay2AImpl_GetPlayerData,
3287 XCAST(GetPlayerName)DirectPlay2AImpl_GetPlayerName,
3288 XCAST(GetSessionDesc)DirectPlay2AImpl_GetSessionDesc,
3289 XCAST(Initialize)DirectPlay2AImpl_Initialize,
3290 XCAST(Open)DirectPlay2AImpl_Open,
3291 XCAST(Receive)DirectPlay2AImpl_Receive,
3292 XCAST(Send)DirectPlay2AImpl_Send,
3293 XCAST(SetGroupData)DirectPlay2AImpl_SetGroupData,
3294 XCAST(SetGroupName)DirectPlay2AImpl_SetGroupName,
3295 XCAST(SetPlayerData)DirectPlay2AImpl_SetPlayerData,
3296 XCAST(SetPlayerName)DirectPlay2AImpl_SetPlayerName,
3297 XCAST(SetSessionDesc)DirectPlay2AImpl_SetSessionDesc,
3299 DirectPlay3AImpl_AddGroupToGroup,
3300 DirectPlay3AImpl_CreateGroupInGroup,
3301 DirectPlay3AImpl_DeleteGroupFromGroup,
3302 DirectPlay3AImpl_EnumConnections,
3303 DirectPlay3AImpl_EnumGroupsInGroup,
3304 DirectPlay3AImpl_GetGroupConnectionSettings,
3305 DirectPlay3AImpl_InitializeConnection,
3306 DirectPlay3AImpl_SecureOpen,
3307 DirectPlay3AImpl_SendChatMessage,
3308 DirectPlay3AImpl_SetGroupConnectionSettings,
3309 DirectPlay3AImpl_StartSession,
3310 DirectPlay3AImpl_GetGroupFlags,
3311 DirectPlay3AImpl_GetGroupParent,
3312 DirectPlay3AImpl_GetPlayerAccount,
3313 DirectPlay3AImpl_GetPlayerFlags
3317 /* Note: Hack so we can reuse the old functions without compiler warnings */
3318 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
3319 # define XCAST(fun) (typeof(directPlay3WVT.fn##fun))
3321 # define XCAST(fun) (void*)
3323 static ICOM_VTABLE(IDirectPlay3) directPlay3WVT =
3325 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3326 DirectPlay3WImpl_QueryInterface,
3327 XCAST(AddRef)DirectPlay2AImpl_AddRef,
3328 XCAST(Release)DirectPlay2AImpl_Release,
3330 XCAST(AddPlayerToGroup)DirectPlay2WImpl_AddPlayerToGroup,
3331 XCAST(Close)DirectPlay2WImpl_Close,
3332 XCAST(CreateGroup)DirectPlay2WImpl_CreateGroup,
3333 XCAST(CreatePlayer)DirectPlay2WImpl_CreatePlayer,
3334 XCAST(DeletePlayerFromGroup)DirectPlay2WImpl_DeletePlayerFromGroup,
3335 XCAST(DestroyGroup)DirectPlay2WImpl_DestroyGroup,
3336 XCAST(DestroyPlayer)DirectPlay2WImpl_DestroyPlayer,
3337 XCAST(EnumGroupPlayers)DirectPlay2WImpl_EnumGroupPlayers,
3338 XCAST(EnumGroups)DirectPlay2WImpl_EnumGroups,
3339 XCAST(EnumPlayers)DirectPlay2WImpl_EnumPlayers,
3340 XCAST(EnumSessions)DirectPlay2WImpl_EnumSessions,
3341 XCAST(GetCaps)DirectPlay2WImpl_GetCaps,
3342 XCAST(GetGroupData)DirectPlay2WImpl_GetGroupData,
3343 XCAST(GetGroupName)DirectPlay2WImpl_GetGroupName,
3344 XCAST(GetMessageCount)DirectPlay2WImpl_GetMessageCount,
3345 XCAST(GetPlayerAddress)DirectPlay2WImpl_GetPlayerAddress,
3346 XCAST(GetPlayerCaps)DirectPlay2WImpl_GetPlayerCaps,
3347 XCAST(GetPlayerData)DirectPlay2WImpl_GetPlayerData,
3348 XCAST(GetPlayerName)DirectPlay2WImpl_GetPlayerName,
3349 XCAST(GetSessionDesc)DirectPlay2WImpl_GetSessionDesc,
3350 XCAST(Initialize)DirectPlay2WImpl_Initialize,
3351 XCAST(Open)DirectPlay2WImpl_Open,
3352 XCAST(Receive)DirectPlay2WImpl_Receive,
3353 XCAST(Send)DirectPlay2WImpl_Send,
3354 XCAST(SetGroupData)DirectPlay2WImpl_SetGroupData,
3355 XCAST(SetGroupName)DirectPlay2WImpl_SetGroupName,
3356 XCAST(SetPlayerData)DirectPlay2WImpl_SetPlayerData,
3357 XCAST(SetPlayerName)DirectPlay2WImpl_SetPlayerName,
3358 XCAST(SetSessionDesc)DirectPlay2WImpl_SetSessionDesc,
3360 DirectPlay3WImpl_AddGroupToGroup,
3361 DirectPlay3WImpl_CreateGroupInGroup,
3362 DirectPlay3WImpl_DeleteGroupFromGroup,
3363 DirectPlay3WImpl_EnumConnections,
3364 DirectPlay3WImpl_EnumGroupsInGroup,
3365 DirectPlay3WImpl_GetGroupConnectionSettings,
3366 DirectPlay3WImpl_InitializeConnection,
3367 DirectPlay3WImpl_SecureOpen,
3368 DirectPlay3WImpl_SendChatMessage,
3369 DirectPlay3WImpl_SetGroupConnectionSettings,
3370 DirectPlay3WImpl_StartSession,
3371 DirectPlay3WImpl_GetGroupFlags,
3372 DirectPlay3WImpl_GetGroupParent,
3373 DirectPlay3WImpl_GetPlayerAccount,
3374 DirectPlay3WImpl_GetPlayerFlags
3378 /* Note: Hack so we can reuse the old functions without compiler warnings */
3379 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
3380 # define XCAST(fun) (typeof(directPlay4WVT.fn##fun))
3382 # define XCAST(fun) (void*)
3384 static ICOM_VTABLE(IDirectPlay4) directPlay4WVT =
3386 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3387 DirectPlay4WImpl_QueryInterface,
3388 XCAST(AddRef)DirectPlay2AImpl_AddRef,
3389 XCAST(Release)DirectPlay2AImpl_Release,
3391 XCAST(AddPlayerToGroup)DirectPlay2WImpl_AddPlayerToGroup,
3392 XCAST(Close)DirectPlay2WImpl_Close,
3393 XCAST(CreateGroup)DirectPlay2WImpl_CreateGroup,
3394 XCAST(CreatePlayer)DirectPlay2WImpl_CreatePlayer,
3395 XCAST(DeletePlayerFromGroup)DirectPlay2WImpl_DeletePlayerFromGroup,
3396 XCAST(DestroyGroup)DirectPlay2WImpl_DestroyGroup,
3397 XCAST(DestroyPlayer)DirectPlay2WImpl_DestroyPlayer,
3398 XCAST(EnumGroupPlayers)DirectPlay2WImpl_EnumGroupPlayers,
3399 XCAST(EnumGroups)DirectPlay2WImpl_EnumGroups,
3400 XCAST(EnumPlayers)DirectPlay2WImpl_EnumPlayers,
3401 XCAST(EnumSessions)DirectPlay2WImpl_EnumSessions,
3402 XCAST(GetCaps)DirectPlay2WImpl_GetCaps,
3403 XCAST(GetGroupData)DirectPlay2WImpl_GetGroupData,
3404 XCAST(GetGroupName)DirectPlay2WImpl_GetGroupName,
3405 XCAST(GetMessageCount)DirectPlay2WImpl_GetMessageCount,
3406 XCAST(GetPlayerAddress)DirectPlay2WImpl_GetPlayerAddress,
3407 XCAST(GetPlayerCaps)DirectPlay2WImpl_GetPlayerCaps,
3408 XCAST(GetPlayerData)DirectPlay2WImpl_GetPlayerData,
3409 XCAST(GetPlayerName)DirectPlay2WImpl_GetPlayerName,
3410 XCAST(GetSessionDesc)DirectPlay2WImpl_GetSessionDesc,
3411 XCAST(Initialize)DirectPlay2WImpl_Initialize,
3412 XCAST(Open)DirectPlay2WImpl_Open,
3413 XCAST(Receive)DirectPlay2WImpl_Receive,
3414 XCAST(Send)DirectPlay2WImpl_Send,
3415 XCAST(SetGroupData)DirectPlay2WImpl_SetGroupData,
3416 XCAST(SetGroupName)DirectPlay2WImpl_SetGroupName,
3417 XCAST(SetPlayerData)DirectPlay2WImpl_SetPlayerData,
3418 XCAST(SetPlayerName)DirectPlay2WImpl_SetPlayerName,
3419 XCAST(SetSessionDesc)DirectPlay2WImpl_SetSessionDesc,
3421 XCAST(AddGroupToGroup)DirectPlay3WImpl_AddGroupToGroup,
3422 XCAST(CreateGroupInGroup)DirectPlay3WImpl_CreateGroupInGroup,
3423 XCAST(DeleteGroupFromGroup)DirectPlay3WImpl_DeleteGroupFromGroup,
3424 XCAST(EnumConnections)DirectPlay3WImpl_EnumConnections,
3425 XCAST(EnumGroupsInGroup)DirectPlay3WImpl_EnumGroupsInGroup,
3426 XCAST(GetGroupConnectionSettings)DirectPlay3WImpl_GetGroupConnectionSettings,
3427 XCAST(InitializeConnection)DirectPlay3WImpl_InitializeConnection,
3428 XCAST(SecureOpen)DirectPlay3WImpl_SecureOpen,
3429 XCAST(SendChatMessage)DirectPlay3WImpl_SendChatMessage,
3430 XCAST(SetGroupConnectionSettings)DirectPlay3WImpl_SetGroupConnectionSettings,
3431 XCAST(StartSession)DirectPlay3WImpl_StartSession,
3432 XCAST(GetGroupFlags)DirectPlay3WImpl_GetGroupFlags,
3433 XCAST(GetGroupParent)DirectPlay3WImpl_GetGroupParent,
3434 XCAST(GetPlayerAccount)DirectPlay3WImpl_GetPlayerAccount,
3435 XCAST(GetPlayerFlags)DirectPlay3WImpl_GetPlayerFlags,
3437 DirectPlay4WImpl_GetGroupOwner,
3438 DirectPlay4WImpl_SetGroupOwner,
3439 DirectPlay4WImpl_SendEx,
3440 DirectPlay4WImpl_GetMessageQueue,
3441 DirectPlay4WImpl_CancelMessage,
3442 DirectPlay4WImpl_CancelPriority
3447 /* Note: Hack so we can reuse the old functions without compiler warnings */
3448 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
3449 # define XCAST(fun) (typeof(directPlay4AVT.fn##fun))
3451 # define XCAST(fun) (void*)
3453 static ICOM_VTABLE(IDirectPlay4) directPlay4AVT =
3455 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3456 DirectPlay4AImpl_QueryInterface,
3457 XCAST(AddRef)DirectPlay2AImpl_AddRef,
3458 XCAST(Release)DirectPlay2AImpl_Release,
3460 XCAST(AddPlayerToGroup)DirectPlay2AImpl_AddPlayerToGroup,
3461 XCAST(Close)DirectPlay2AImpl_Close,
3462 XCAST(CreateGroup)DirectPlay2AImpl_CreateGroup,
3463 XCAST(CreatePlayer)DirectPlay2AImpl_CreatePlayer,
3464 XCAST(DeletePlayerFromGroup)DirectPlay2AImpl_DeletePlayerFromGroup,
3465 XCAST(DestroyGroup)DirectPlay2AImpl_DestroyGroup,
3466 XCAST(DestroyPlayer)DirectPlay2AImpl_DestroyPlayer,
3467 XCAST(EnumGroupPlayers)DirectPlay2AImpl_EnumGroupPlayers,
3468 XCAST(EnumGroups)DirectPlay2AImpl_EnumGroups,
3469 XCAST(EnumPlayers)DirectPlay2AImpl_EnumPlayers,
3470 XCAST(EnumSessions)DirectPlay2AImpl_EnumSessions,
3471 XCAST(GetCaps)DirectPlay2AImpl_GetCaps,
3472 XCAST(GetGroupData)DirectPlay2AImpl_GetGroupData,
3473 XCAST(GetGroupName)DirectPlay2AImpl_GetGroupName,
3474 XCAST(GetMessageCount)DirectPlay2AImpl_GetMessageCount,
3475 XCAST(GetPlayerAddress)DirectPlay2AImpl_GetPlayerAddress,
3476 XCAST(GetPlayerCaps)DirectPlay2AImpl_GetPlayerCaps,
3477 XCAST(GetPlayerData)DirectPlay2AImpl_GetPlayerData,
3478 XCAST(GetPlayerName)DirectPlay2AImpl_GetPlayerName,
3479 XCAST(GetSessionDesc)DirectPlay2AImpl_GetSessionDesc,
3480 XCAST(Initialize)DirectPlay2AImpl_Initialize,
3481 XCAST(Open)DirectPlay2AImpl_Open,
3482 XCAST(Receive)DirectPlay2AImpl_Receive,
3483 XCAST(Send)DirectPlay2AImpl_Send,
3484 XCAST(SetGroupData)DirectPlay2AImpl_SetGroupData,
3485 XCAST(SetGroupName)DirectPlay2AImpl_SetGroupName,
3486 XCAST(SetPlayerData)DirectPlay2AImpl_SetPlayerData,
3487 XCAST(SetPlayerName)DirectPlay2AImpl_SetPlayerName,
3488 XCAST(SetSessionDesc)DirectPlay2AImpl_SetSessionDesc,
3490 XCAST(AddGroupToGroup)DirectPlay3AImpl_AddGroupToGroup,
3491 XCAST(CreateGroupInGroup)DirectPlay3AImpl_CreateGroupInGroup,
3492 XCAST(DeleteGroupFromGroup)DirectPlay3AImpl_DeleteGroupFromGroup,
3493 XCAST(EnumConnections)DirectPlay3AImpl_EnumConnections,
3494 XCAST(EnumGroupsInGroup)DirectPlay3AImpl_EnumGroupsInGroup,
3495 XCAST(GetGroupConnectionSettings)DirectPlay3AImpl_GetGroupConnectionSettings,
3496 XCAST(InitializeConnection)DirectPlay3AImpl_InitializeConnection,
3497 XCAST(SecureOpen)DirectPlay3AImpl_SecureOpen,
3498 XCAST(SendChatMessage)DirectPlay3AImpl_SendChatMessage,
3499 XCAST(SetGroupConnectionSettings)DirectPlay3AImpl_SetGroupConnectionSettings,
3500 XCAST(StartSession)DirectPlay3AImpl_StartSession,
3501 XCAST(GetGroupFlags)DirectPlay3AImpl_GetGroupFlags,
3502 XCAST(GetGroupParent)DirectPlay3AImpl_GetGroupParent,
3503 XCAST(GetPlayerAccount)DirectPlay3AImpl_GetPlayerAccount,
3504 XCAST(GetPlayerFlags)DirectPlay3AImpl_GetPlayerFlags,
3506 DirectPlay4AImpl_GetGroupOwner,
3507 DirectPlay4AImpl_SetGroupOwner,
3508 DirectPlay4AImpl_SendEx,
3509 DirectPlay4AImpl_GetMessageQueue,
3510 DirectPlay4AImpl_CancelMessage,
3511 DirectPlay4AImpl_CancelPriority
3516 /***************************************************************************
3517 * DirectPlayEnumerateA (DPLAYX.2)
3519 * The pointer to the structure lpContext will be filled with the
3520 * appropriate data for each service offered by the OS. These services are
3521 * not necessarily available on this particular machine but are defined
3522 * as simple service providers under the "Service Providers" registry key.
3523 * This structure is then passed to lpEnumCallback for each of the different
3526 * This API is useful only for applications written using DirectX3 or
3527 * worse. It is superceeded by IDirectPlay3::EnumConnections which also
3528 * gives information on the actual connections.
3530 * defn of a service provider:
3531 * A dynamic-link library used by DirectPlay to communicate over a network.
3532 * The service provider contains all the network-specific code required
3533 * to send and receive messages. Online services and network operators can
3534 * supply service providers to use specialized hardware, protocols, communications
3535 * media, and network resources.
3537 * TODO: Allocate string buffer space from the heap (length from reg)
3538 * Pass real device driver numbers...
3539 * Get the GUID properly...
3541 HRESULT WINAPI DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback,
3546 LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
3548 DWORD sizeOfSubKeyName=50;
3549 char subKeyName[51];
3552 TRACE(": lpEnumCallback=%p lpContext=%p\n", lpEnumCallback, lpContext );
3554 if( !lpEnumCallback || !*lpEnumCallback )
3556 return DPERR_INVALIDPARAMS;
3559 /* Need to loop over the service providers in the registry */
3560 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
3561 0, KEY_READ, &hkResult ) != ERROR_SUCCESS )
3563 /* Hmmm. Does this mean that there are no service providers? */
3564 ERR(": no service providers?\n");
3568 /* Traverse all the service providers we have available */
3570 RegEnumKeyExA( hkResult, dwIndex, subKeyName, &sizeOfSubKeyName,
3571 NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS;
3572 ++dwIndex, sizeOfSubKeyName=50 )
3574 LPSTR majVerDataSubKey = "dwReserved1";
3575 LPSTR minVerDataSubKey = "dwReserved2";
3576 LPSTR guidDataSubKey = "Guid";
3577 HKEY hkServiceProvider;
3578 GUID serviceProviderGUID;
3579 DWORD returnTypeGUID, returnTypeReserved, sizeOfReturnBuffer = 50;
3580 char returnBuffer[51];
3581 DWORD majVersionNum , minVersionNum = 0;
3582 LPWSTR lpWGUIDString;
3584 TRACE(" this time through: %s\n", subKeyName );
3586 /* Get a handle for this particular service provider */
3587 if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_READ,
3588 &hkServiceProvider ) != ERROR_SUCCESS )
3590 ERR(": what the heck is going on?\n" );
3594 /* Get the GUID, Device major number and device minor number
3595 * from the registry.
3597 if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
3598 NULL, &returnTypeGUID, returnBuffer,
3599 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
3601 ERR(": missing GUID registry data members\n" );
3605 /* FIXME: Check return types to ensure we're interpreting data right */
3606 lpWGUIDString = HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer );
3607 CLSIDFromString( (LPCOLESTR)lpWGUIDString, &serviceProviderGUID );
3608 HeapFree( GetProcessHeap(), 0, lpWGUIDString );
3610 /* FIXME: Need to know which of dwReserved1 and dwReserved2 are maj and min */
3612 sizeOfReturnBuffer = 50;
3613 if( RegQueryValueExA( hkServiceProvider, majVerDataSubKey,
3614 NULL, &returnTypeReserved, returnBuffer,
3615 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
3617 ERR(": missing dwReserved1 registry data members\n") ;
3621 majVersionNum = GET_DWORD( returnBuffer );
3623 sizeOfReturnBuffer = 50;
3624 if( RegQueryValueExA( hkServiceProvider, minVerDataSubKey,
3625 NULL, &returnTypeReserved, returnBuffer,
3626 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
3628 ERR(": missing dwReserved2 registry data members\n") ;
3632 minVersionNum = GET_DWORD( returnBuffer );
3635 /* The enumeration will return FALSE if we are not to continue */
3636 if( !lpEnumCallback( &serviceProviderGUID , subKeyName,
3637 majVersionNum, minVersionNum, lpContext ) )
3639 WARN("lpEnumCallback returning FALSE\n" );
3648 /***************************************************************************
3649 * DirectPlayEnumerateW (DPLAYX.3)
3652 HRESULT WINAPI DirectPlayEnumerateW( LPDPENUMDPCALLBACKW lpEnumCallback, LPVOID lpContext )
3657 return DPERR_OUTOFMEMORY;
3661 /***************************************************************************
3662 * DirectPlayCreate (DPLAYX.1) (DPLAY.1)
3665 HRESULT WINAPI DirectPlayCreate
3666 ( LPGUID lpGUID, LPDIRECTPLAY2 *lplpDP, IUnknown *pUnk)
3668 TRACE( "lpGUID=%s lplpDP=%p pUnk=%p\n", debugstr_guid(lpGUID), lplpDP, pUnk );
3672 return CLASS_E_NOAGGREGATION;
3676 /* Create an IDirectPlay object. We don't support that so we'll cheat and
3677 give them an IDirectPlay2A object and hope that doesn't cause problems */
3678 if( directPlay_QueryInterface( &IID_IDirectPlay2A, (LPVOID*)lplpDP ) != DP_OK )
3680 return DPERR_UNAVAILABLE;
3683 if( IsEqualGUID( &GUID_NULL, lpGUID ) )
3685 /* The GUID_NULL means don't bind a service provider. Just return the
3691 /* Bind the desired service provider */
3692 if( ( IsEqualGUID( lpGUID, &DPSPGUID_MODEM ) ) ||
3693 ( IsEqualGUID( lpGUID, &DPSPGUID_SERIAL ) ) ||
3694 ( IsEqualGUID( lpGUID, &DPSPGUID_TCPIP ) ) ||
3695 ( IsEqualGUID( lpGUID, &DPSPGUID_IPX ) )
3698 FIXME( "Service provider binding not supported yet\n" );
3699 IDirectPlayX_Release( *lplpDP );
3701 return DPERR_INVALIDPARAMS;
3704 ERR( "unknown Service Provider %s\n", debugstr_guid(lpGUID) );
3706 IDirectPlayX_Release( *lplpDP );
3709 return DPERR_INVALIDPARAMS;