Lots of spelling fixes that accumulated in my tree again, made several
[wine/testsucceed.git] / dlls / dplayx / dplay.c
bloba519b8345c115ae69016b92a3dac2aaeb7a9232f
1 /* Direct Play 2,3,4 Implementation
3 * Copyright 1998,1999,2000 - Peter Hunnisett
5 * <presently under construction - contact hunnise@nortelnetworks.com>
7 */
8 #include <string.h>
10 #include "winerror.h"
11 #include "winbase.h"
12 #include "winnt.h"
13 #include "winreg.h"
14 #include "dplay.h"
15 #include "heap.h"
16 #include "debugtools.h"
18 #include "dpinit.h"
19 #include "dplayx_global.h"
20 #include "name_server.h"
21 #include "dplayx_queue.h"
23 /* FIXME: This stuff shouldn't really be here. It indicates a poor architectural coupling */
24 #include "dplobby.h"
25 extern HRESULT DPL_CreateCompoundAddress ( LPCDPCOMPOUNDADDRESSELEMENT lpElements, DWORD dwElementCount,
26 LPVOID lpAddress, LPDWORD lpdwAddressSize, BOOL bAnsiInterface );
28 DEFAULT_DEBUG_CHANNEL(dplay)
31 /*****************************************************************************
32 * Predeclare the interface implementation structures
34 typedef struct IDirectPlay2Impl IDirectPlay2AImpl;
35 typedef struct IDirectPlay2Impl IDirectPlay2Impl;
36 typedef struct IDirectPlay3Impl IDirectPlay3AImpl;
37 typedef struct IDirectPlay3Impl IDirectPlay3Impl;
38 typedef struct IDirectPlay4Impl IDirectPlay4AImpl;
39 typedef struct IDirectPlay4Impl IDirectPlay4Impl;
41 /*****************************************************************************
42 * IDirectPlay implementation structure
44 * The philosophy behind this extra pointer dereference is that I wanted to
45 * have the same structure for all types of objects without having to do
46 * alot of casting. I also only wanted to implement an interface in the
47 * object it was "released" with IUnknown interface being implemented in the 1 version.
48 * Of course, with these new interfaces comes the data required to keep the state required
49 * by these interfaces. So, basically, the pointers contain the data associated with
50 * a release. If you use the data associated with release 3 in a release 2 object, you'll
51 * get a run time trap, as that won't have any data.
54 typedef struct tagDirectPlayIUnknownData
56 DWORD ref;
57 CRITICAL_SECTION DP_lock;
58 } DirectPlayIUnknownData;
60 typedef struct tagEnumSessionAsyncCallbackData
62 LPDPENUMSESSIONSCALLBACK2 cb;
63 LPVOID lpContext;
64 DWORD dwTimeout;
65 } EnumSessionAsyncCallbackData;
68 struct PlayerData
70 /* Individual player information */
71 DPID dpid;
73 DPNAME name;
74 HANDLE hEvent;
75 LPVOID lpData;
76 DWORD dwDataSize;
78 typedef struct PlayerData* lpPlayerData;
80 struct PlayerList
82 TAILQ_ENTRY(PlayerList) players;
84 struct PlayerData playerData;
86 typedef struct PlayerList* lpPlayerList;
88 struct GroupData
90 TAILQ_ENTRY(GroupList) groups; /* A group has [0..n] groups */
91 TAILQ_ENTRY(PlayerList) players; /* A group has [0..n] players */
93 /* Individual group information */
94 DPID dpid;
95 DPNAME name;
96 LPVOID lpData;
97 DWORD dwDataSize;
99 typedef struct GroupData* lpGroupData;
101 struct GroupList
103 TAILQ_ENTRY(GroupList) groups;
105 struct GroupData groupData;
107 typedef struct GroupList* lpGroupList;
109 /* Contains all dp1 and dp2 data members */
110 typedef struct tagDirectPlay2Data
112 BOOL bConnectionOpen;
114 HANDLE hEnumSessionThread;
116 EnumSessionAsyncCallbackData enumSessionAsyncCallbackData;
118 LPVOID lpNameServerData; /* DPlay interface doesn't know contents */
120 BOOL bHostInterface; /* Did this interface create the session */
122 TAILQ_HEAD( ,PlayerList) players;
123 TAILQ_HEAD( ,GroupList) groups;
124 } DirectPlay2Data;
126 typedef struct tagDirectPlay3Data
128 BOOL bConnectionInitialized;
129 } DirectPlay3Data;
131 typedef struct tagDirectPlay4Data
133 BOOL dummy;
134 } DirectPlay4Data;
136 #define DP_IMPL_FIELDS \
137 DirectPlayIUnknownData* unk; \
138 DirectPlay2Data* dp2; \
139 DirectPlay3Data* dp3; \
140 DirectPlay4Data* dp4;
142 struct IDirectPlay2Impl
144 ICOM_VFIELD(IDirectPlay2);
145 DP_IMPL_FIELDS
148 struct IDirectPlay3Impl
150 ICOM_VFIELD(IDirectPlay3);
151 DP_IMPL_FIELDS
154 struct IDirectPlay4Impl
156 ICOM_VFIELD(IDirectPlay4);
157 DP_IMPL_FIELDS
160 /* Forward declarations of virtual tables */
161 static ICOM_VTABLE(IDirectPlay2) directPlay2AVT;
162 static ICOM_VTABLE(IDirectPlay3) directPlay3AVT;
163 static ICOM_VTABLE(IDirectPlay4) directPlay4AVT;
165 static ICOM_VTABLE(IDirectPlay2) directPlay2WVT;
166 static ICOM_VTABLE(IDirectPlay3) directPlay3WVT;
167 static ICOM_VTABLE(IDirectPlay4) directPlay4WVT;
169 /* Local function prototypes */
170 static lpPlayerData DP_FindPlayer( IDirectPlay2AImpl* This, DPID dpid );
171 static lpPlayerData DP_CreatePlayer( IDirectPlay2* iface, LPDPID lpid,
172 LPDPNAME lpName, HANDLE hEvent,
173 BOOL bAnsi );
174 static BOOL DP_CopyDPNAMEStruct( LPDPNAME lpDst, LPDPNAME lpSrc, BOOL bAnsi );
175 static void DP_SetPlayerData( lpPlayerData lpPData, LPVOID lpData,
176 DWORD dwDataSize );
178 static lpGroupData DP_FindGroup( IDirectPlay2AImpl* This, DPID dpid );
179 static lpGroupData DP_CreateGroup( IDirectPlay2* iface, LPDPID lpid,
180 LPDPNAME lpName, BOOL bAnsi );
181 static void DP_SetGroupData( lpGroupData lpGData, LPVOID lpData,
182 DWORD dwDataSize );
187 static DWORD kludgePlayerGroupId = 100;
190 /* ------------------------------------------------------------------ */
193 BOOL DP_CreateIUnknown( LPVOID lpDP )
195 ICOM_THIS(IDirectPlay2AImpl,lpDP);
197 This->unk = (DirectPlayIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
198 sizeof( *(This->unk) ) );
199 if ( This->unk == NULL )
201 return FALSE;
204 InitializeCriticalSection( &This->unk->DP_lock );
206 IDirectPlay_AddRef( (LPDIRECTPLAY2A)lpDP );
208 return TRUE;
211 BOOL DP_DestroyIUnknown( LPVOID lpDP )
213 ICOM_THIS(IDirectPlay2AImpl,lpDP);
215 DeleteCriticalSection( &This->unk->DP_lock );
216 HeapFree( GetProcessHeap(), 0, This->unk );
218 return TRUE;
221 BOOL DP_CreateDirectPlay2( LPVOID lpDP )
223 ICOM_THIS(IDirectPlay2AImpl,lpDP);
225 This->dp2 = (DirectPlay2Data*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
226 sizeof( *(This->dp2) ) );
227 if ( This->dp2 == NULL )
229 return FALSE;
232 This->dp2->bConnectionOpen = FALSE;
234 This->dp2->hEnumSessionThread = INVALID_HANDLE_VALUE;
236 This->dp2->enumSessionAsyncCallbackData.cb = NULL;
237 This->dp2->enumSessionAsyncCallbackData.lpContext = NULL;
238 This->dp2->enumSessionAsyncCallbackData.dwTimeout = INFINITE;
240 This->dp2->bHostInterface = FALSE;
242 TAILQ_INIT(&This->dp2->players);
243 TAILQ_INIT(&This->dp2->groups);
245 if( !NS_InitializeSessionCache( &This->dp2->lpNameServerData ) )
247 return FALSE;
250 return TRUE;
253 BOOL DP_DestroyDirectPlay2( LPVOID lpDP )
255 ICOM_THIS(IDirectPlay2AImpl,lpDP);
257 FIXME( ": memory leak\n" );
259 if( This->dp2->hEnumSessionThread != INVALID_HANDLE_VALUE )
261 TerminateThread( This->dp2->hEnumSessionThread, 0 );
262 CloseHandle( This->dp2->hEnumSessionThread );
265 /* Delete the player and group lists */
267 NS_DeleteSessionCache( This->dp2->lpNameServerData );
269 /* Delete the contents */
270 HeapFree( GetProcessHeap(), 0, This->dp2 );
272 return TRUE;
275 BOOL DP_CreateDirectPlay3( LPVOID lpDP )
277 ICOM_THIS(IDirectPlay3AImpl,lpDP);
279 This->dp3 = (DirectPlay3Data*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
280 sizeof( *(This->dp3) ) );
281 if ( This->dp3 == NULL )
283 return FALSE;
286 This->dp3->bConnectionInitialized = FALSE;
288 return TRUE;
291 BOOL DP_DestroyDirectPlay3( LPVOID lpDP )
293 ICOM_THIS(IDirectPlay3AImpl,lpDP);
295 /* Delete the contents */
296 HeapFree( GetProcessHeap(), 0, This->dp3 );
298 return TRUE;
301 BOOL DP_CreateDirectPlay4( LPVOID lpDP )
303 ICOM_THIS(IDirectPlay4AImpl,lpDP);
305 This->dp4 = (DirectPlay4Data*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
306 sizeof( *(This->dp4) ) );
307 if ( This->dp4 == NULL )
309 return FALSE;
312 return TRUE;
315 BOOL DP_DestroyDirectPlay4( LPVOID lpDP )
317 ICOM_THIS(IDirectPlay3AImpl,lpDP);
319 /* Delete the contents */
320 HeapFree( GetProcessHeap(), 0, This->dp4 );
322 return TRUE;
326 /* Get a new interface. To be used by QueryInterface. */
327 extern
328 HRESULT directPlay_QueryInterface
329 ( REFIID riid, LPVOID* ppvObj )
332 if( IsEqualGUID( &IID_IDirectPlay2, riid ) )
334 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
335 sizeof( IDirectPlay2Impl ) );
337 if( *ppvObj == NULL )
339 return DPERR_OUTOFMEMORY;
342 /* new scope for variable declaration */
344 ICOM_THIS(IDirectPlay2Impl,*ppvObj);
346 ICOM_VTBL(This) = &directPlay2WVT;
348 if ( DP_CreateIUnknown( (LPVOID)This ) &&
349 DP_CreateDirectPlay2( (LPVOID)This )
352 return S_OK;
357 goto error;
359 else if( IsEqualGUID( &IID_IDirectPlay2A, riid ) )
361 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
362 sizeof( IDirectPlay2AImpl ) );
364 if( *ppvObj == NULL )
366 return DPERR_OUTOFMEMORY;
369 /* new scope for variable declaration */
371 ICOM_THIS(IDirectPlay2AImpl,*ppvObj);
373 ICOM_VTBL(This) = &directPlay2AVT;
375 if ( DP_CreateIUnknown( (LPVOID)This ) &&
376 DP_CreateDirectPlay2( (LPVOID)This )
379 return S_OK;
384 goto error;
386 else if( IsEqualGUID( &IID_IDirectPlay3, riid ) )
388 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
389 sizeof( IDirectPlay3Impl ) );
391 if( *ppvObj == NULL )
393 return DPERR_OUTOFMEMORY;
396 /* new scope for variable declaration */
398 ICOM_THIS(IDirectPlay3Impl,*ppvObj);
400 ICOM_VTBL(This) = &directPlay3WVT;
402 if ( DP_CreateIUnknown( (LPVOID)This ) &&
403 DP_CreateDirectPlay2( (LPVOID)This ) &&
404 DP_CreateDirectPlay3( (LPVOID)This )
407 return S_OK;
412 goto error;
414 else if( IsEqualGUID( &IID_IDirectPlay3A, riid ) )
416 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
417 sizeof( IDirectPlay3AImpl ) );
419 if( *ppvObj == NULL )
421 return DPERR_OUTOFMEMORY;
424 /* new scope for variable declaration */
426 ICOM_THIS(IDirectPlay3AImpl,*ppvObj);
428 ICOM_VTBL(This) = &directPlay3AVT;
430 if ( DP_CreateIUnknown( (LPVOID)This ) &&
431 DP_CreateDirectPlay2( (LPVOID)This ) &&
432 DP_CreateDirectPlay3( (LPVOID)This )
435 return S_OK;
440 goto error;
442 else if( IsEqualGUID( &IID_IDirectPlay4, riid ) )
444 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
445 sizeof( IDirectPlay4Impl ) );
447 if( *ppvObj == NULL )
449 return DPERR_OUTOFMEMORY;
452 /* new scope for variable declaration */
454 ICOM_THIS(IDirectPlay4Impl,*ppvObj);
456 ICOM_VTBL(This) = &directPlay4WVT;
458 if ( DP_CreateIUnknown( (LPVOID)This ) &&
459 DP_CreateDirectPlay2( (LPVOID)This ) &&
460 DP_CreateDirectPlay3( (LPVOID)This ) &&
461 DP_CreateDirectPlay4( (LPVOID)This )
464 return S_OK;
469 goto error;
471 else if( IsEqualGUID( &IID_IDirectPlay4A, riid ) )
473 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
474 sizeof( IDirectPlay4AImpl ) );
476 if( *ppvObj == NULL )
478 return DPERR_OUTOFMEMORY;
481 /* new scope for variable declaration */
483 ICOM_THIS(IDirectPlay4AImpl,*ppvObj);
485 ICOM_VTBL(This) = &directPlay4AVT;
487 if ( DP_CreateIUnknown( (LPVOID)This ) &&
488 DP_CreateDirectPlay2( (LPVOID)This ) &&
489 DP_CreateDirectPlay3( (LPVOID)This ) &&
490 DP_CreateDirectPlay4( (LPVOID)This )
493 return S_OK;
498 goto error;
501 /* Unsupported interface */
502 *ppvObj = NULL;
503 return E_NOINTERFACE;
505 error:
507 DP_DestroyDirectPlay4( *ppvObj );
508 DP_DestroyDirectPlay3( *ppvObj );
509 DP_DestroyDirectPlay2( *ppvObj );
510 DP_DestroyIUnknown( *ppvObj );
511 HeapFree( GetProcessHeap(), 0, *ppvObj );
513 *ppvObj = NULL;
514 return DPERR_NOMEMORY;
519 /* Direct Play methods */
520 static HRESULT WINAPI DirectPlay2W_QueryInterface
521 ( LPDIRECTPLAY2 iface, REFIID riid, LPVOID* ppvObj )
523 ICOM_THIS(IDirectPlay2Impl,iface);
524 TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
526 if( IsEqualGUID( &IID_IUnknown, riid ) ||
527 IsEqualGUID( &IID_IDirectPlay2, riid )
530 IDirectPlayX_AddRef( iface );
531 *ppvObj = This;
532 return S_OK;
534 return directPlay_QueryInterface( riid, ppvObj );
537 static HRESULT WINAPI DirectPlay2A_QueryInterface
538 ( LPDIRECTPLAY2A iface, REFIID riid, LPVOID* ppvObj )
540 ICOM_THIS(IDirectPlay2Impl,iface);
541 TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
543 if( IsEqualGUID( &IID_IUnknown, riid ) ||
544 IsEqualGUID( &IID_IDirectPlay2A, riid )
547 IDirectPlayX_AddRef( iface );
548 *ppvObj = This;
549 return S_OK;
552 return directPlay_QueryInterface( riid, ppvObj );
555 static HRESULT WINAPI DirectPlay3WImpl_QueryInterface
556 ( LPDIRECTPLAY3 iface, REFIID riid, LPVOID* ppvObj )
558 ICOM_THIS(IDirectPlay3Impl,iface);
559 TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
561 if( IsEqualGUID( &IID_IUnknown, riid ) ||
562 IsEqualGUID( &IID_IDirectPlay3, riid )
565 IDirectPlayX_AddRef( iface );
566 *ppvObj = This;
567 return S_OK;
570 return directPlay_QueryInterface( riid, ppvObj );
573 static HRESULT WINAPI DirectPlay3AImpl_QueryInterface
574 ( LPDIRECTPLAY3A iface, REFIID riid, LPVOID* ppvObj )
576 ICOM_THIS(IDirectPlay3Impl,iface);
577 TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
579 if( IsEqualGUID( &IID_IUnknown, riid ) ||
580 IsEqualGUID( &IID_IDirectPlay3A, riid )
583 IDirectPlayX_AddRef( iface );
584 *ppvObj = This;
585 return S_OK;
588 return directPlay_QueryInterface( riid, ppvObj );
591 static HRESULT WINAPI DirectPlay4WImpl_QueryInterface
592 ( LPDIRECTPLAY4 iface, REFIID riid, LPVOID* ppvObj )
594 ICOM_THIS(IDirectPlay4Impl,iface);
595 TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
597 if( IsEqualGUID( &IID_IUnknown, riid ) ||
598 IsEqualGUID( &IID_IDirectPlay4, riid )
601 IDirectPlayX_AddRef( iface );
602 *ppvObj = This;
603 return S_OK;
606 return directPlay_QueryInterface( riid, ppvObj );
610 static HRESULT WINAPI DirectPlay4AImpl_QueryInterface
611 ( LPDIRECTPLAY4A iface, REFIID riid, LPVOID* ppvObj )
613 ICOM_THIS(IDirectPlay4Impl,iface);
614 TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
616 if( IsEqualGUID( &IID_IUnknown, riid ) ||
617 IsEqualGUID( &IID_IDirectPlay4A, riid )
620 IDirectPlayX_AddRef( iface );
621 *ppvObj = This;
622 return S_OK;
625 return directPlay_QueryInterface( riid, ppvObj );
629 /* Shared between all dplay types */
630 static ULONG WINAPI DirectPlay2AImpl_AddRef
631 ( LPDIRECTPLAY3 iface )
633 ULONG refCount;
634 ICOM_THIS(IDirectPlay3Impl,iface);
636 EnterCriticalSection( &This->unk->DP_lock );
638 refCount = ++(This->unk->ref);
640 LeaveCriticalSection( &This->unk->DP_lock );
642 TRACE("ref count incremented to %lu for %p\n", refCount, This );
644 return refCount;
647 static ULONG WINAPI DirectPlay2AImpl_Release
648 ( LPDIRECTPLAY3 iface )
650 ULONG refCount;
652 ICOM_THIS(IDirectPlay3Impl,iface);
654 EnterCriticalSection( &This->unk->DP_lock );
656 refCount = --(This->unk->ref);
658 LeaveCriticalSection( &This->unk->DP_lock );
660 TRACE("ref count decremented to %lu for %p\n", refCount, This );
662 /* Deallocate if this is the last reference to the object */
663 if( refCount == 0 )
665 DP_DestroyDirectPlay4( This );
666 DP_DestroyDirectPlay3( This );
667 DP_DestroyDirectPlay2( This );
668 DP_DestroyIUnknown( This );
669 HeapFree( GetProcessHeap(), 0, This );
672 return refCount;
675 static HRESULT WINAPI DirectPlay2AImpl_AddPlayerToGroup
676 ( LPDIRECTPLAY2A iface, DPID idGroup, DPID idPlayer )
678 ICOM_THIS(IDirectPlay2Impl,iface);
679 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idPlayer );
680 return DP_OK;
683 static HRESULT WINAPI DirectPlay2WImpl_AddPlayerToGroup
684 ( LPDIRECTPLAY2 iface, DPID idGroup, DPID idPlayer )
686 ICOM_THIS(IDirectPlay2Impl,iface);
687 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idPlayer );
688 return DP_OK;
692 static HRESULT WINAPI DirectPlay2AImpl_Close
693 ( LPDIRECTPLAY2A iface )
695 ICOM_THIS(IDirectPlay2Impl,iface);
696 FIXME("(%p)->(): stub\n", This );
697 return DP_OK;
700 static HRESULT WINAPI DirectPlay2WImpl_Close
701 ( LPDIRECTPLAY2 iface )
703 ICOM_THIS(IDirectPlay2Impl,iface);
704 FIXME("(%p)->(): stub\n", This );
705 return DP_OK;
708 static
709 lpGroupData DP_CreateGroup( IDirectPlay2* iface, LPDPID lpid,
710 LPDPNAME lpName, BOOL bAnsi )
712 ICOM_THIS(IDirectPlay2Impl,iface);
713 lpGroupList lpGroup;
715 TRACE( "(%p)->(%p,%p,%u)\n", This, lpid, lpName, bAnsi );
717 /* Allocate the new space and add to end of interface player list */
718 lpGroup = (lpGroupList) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
719 sizeof( *lpGroup ) );
721 if( lpGroup == NULL )
723 return NULL;
726 TAILQ_INSERT_TAIL(&This->dp2->groups,lpGroup,groups);
728 if( *lpid == DPID_UNKNOWN )
730 /* Assign the next available player ID - FIXME crap solution */
731 lpGroup->groupData.dpid = kludgePlayerGroupId++;
733 else
735 /* Set the desired player ID - no sanity checking to see if it exists */
736 lpGroup->groupData.dpid = *lpid;
739 DP_CopyDPNAMEStruct( &lpGroup->groupData.name, lpName, bAnsi );
741 return &lpGroup->groupData;
744 static lpGroupData DP_FindGroup( IDirectPlay2AImpl* This, DPID dpid )
746 lpGroupList lpGroups;
748 TRACE( "(%p)->(0x%08lx)\n", This, dpid );
750 TAILQ_FIND_ENTRY( &This->dp2->groups, groups, groupData.dpid, dpid, lpGroups );
752 if( lpGroups )
754 return &lpGroups->groupData;
756 else
758 return NULL;
763 static HRESULT WINAPI DirectPlay2AImpl_CreateGroup
764 ( LPDIRECTPLAY2A iface, LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
766 lpGroupData lpGData;
768 ICOM_THIS(IDirectPlay2Impl,iface);
770 FIXME("(%p)->(%p,%p,%p,0x%08lx,0x%08lx): stub\n", This, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags );
772 lpGData = DP_CreateGroup( iface, lpidGroup, lpGroupName, TRUE /* Ansi */ );
774 if( lpGData == NULL )
776 return DPERR_CANTADDPLAYER; /* yes player not group */
779 DP_SetGroupData( lpGData, lpData, dwDataSize );
781 /* FIXME: Should send DPMSG_CREATEPLAYERORGROUP message to everyone,
782 local and remote, that belongs to this session. This will not
783 be done by calling SetPlayerData */
784 FIXME( "Should broadcast group creation to everything in session\n" );
786 return DP_OK;
789 static void
790 DP_SetGroupData( lpGroupData lpGData, LPVOID lpData, DWORD dwDataSize )
792 /* Clear out the data with this player */
793 if( lpGData->dwDataSize != 0 )
795 HeapFree( GetProcessHeap(), 0, lpGData->lpData );
796 lpGData->lpData = NULL;
797 lpGData->dwDataSize = 0;
800 /* Reallocate for new data */
801 if( lpData )
803 lpGData->lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
804 sizeof( dwDataSize ) );
805 memcpy( lpGData->lpData, lpData, dwDataSize );
806 lpGData->dwDataSize = dwDataSize;
812 static HRESULT WINAPI DirectPlay2WImpl_CreateGroup
813 ( LPDIRECTPLAY2 iface, LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
815 ICOM_THIS(IDirectPlay2Impl,iface);
816 FIXME("(%p)->(%p,%p,%p,0x%08lx,0x%08lx): stub\n", This, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags );
817 return DP_OK;
820 /* This function will just create the storage for the new player.
821 * In the future it may want to intialize, but for the time being
822 * that will be done seperately.
824 * If *lpid == DPID_UNKNOWN then assign the next available player
826 static
827 lpPlayerData DP_CreatePlayer( IDirectPlay2* iface, LPDPID lpid,
828 LPDPNAME lpName, HANDLE hEvent, BOOL bAnsi )
830 ICOM_THIS(IDirectPlay2Impl,iface);
831 lpPlayerList lpPlayer;
833 TRACE( "(%p)->(%p,%p,%u)\n", This, lpid, lpName, bAnsi );
835 /* Allocate the new space and add to end of interface player list */
836 lpPlayer = (lpPlayerList) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
837 sizeof( *lpPlayer ) );
839 if( lpPlayer == NULL )
841 return NULL;
844 TAILQ_INSERT_TAIL(&This->dp2->players,lpPlayer,players);
846 if( *lpid == DPID_UNKNOWN )
848 /* Assign the next available player ID - FIXME crap solution */
849 lpPlayer->playerData.dpid = kludgePlayerGroupId++;
851 else
853 /* Set the desired player ID - no sanity checking to see if it exists */
854 lpPlayer->playerData.dpid = *lpid;
857 DP_CopyDPNAMEStruct( &lpPlayer->playerData.name, lpName, bAnsi );
859 lpPlayer->playerData.hEvent = hEvent;
861 return &lpPlayer->playerData;
864 static lpPlayerData DP_FindPlayer( IDirectPlay2AImpl* This, DPID dpid )
866 lpPlayerList lpPlayers;
868 TRACE( "(%p)->(0x%08lx)\n", This, dpid );
870 TAILQ_FIND_ENTRY( &This->dp2->players, players, playerData.dpid, dpid, lpPlayers );
872 if( lpPlayers )
874 return &lpPlayers->playerData;
876 else
878 return NULL;
882 /* Basic area for Dst must already be allocated */
883 static BOOL DP_CopyDPNAMEStruct( LPDPNAME lpDst, LPDPNAME lpSrc, BOOL bAnsi )
885 if( lpSrc == NULL )
887 ZeroMemory( lpDst, sizeof( *lpDst ) );
888 lpDst->dwSize = sizeof( *lpDst );
889 return TRUE;
892 if( lpSrc->dwSize != sizeof( *lpSrc) )
894 return FALSE;
897 /* Delete any existing pointers */
898 if( lpDst->psn.lpszShortNameA )
900 HeapFree( GetProcessHeap(), 0, lpDst->psn.lpszShortNameA );
903 if( lpDst->pln.lpszLongNameA )
905 HeapFree( GetProcessHeap(), 0, lpDst->psn.lpszShortNameA );
908 /* Copy as required */
909 memcpy( lpDst, lpSrc, lpSrc->dwSize );
911 if( bAnsi )
913 if( lpSrc->psn.lpszShortNameA )
915 lpDst->psn.lpszShortNameA =
916 HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY,
917 lpSrc->psn.lpszShortNameA );
919 if( lpSrc->pln.lpszLongNameA )
921 lpDst->pln.lpszLongNameA =
922 HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY,
923 lpSrc->pln.lpszLongNameA );
926 else
928 if( lpSrc->psn.lpszShortNameA )
930 lpDst->psn.lpszShortName =
931 HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY,
932 lpSrc->psn.lpszShortName );
934 if( lpSrc->pln.lpszLongNameA )
936 lpDst->pln.lpszLongName =
937 HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY,
938 lpSrc->pln.lpszLongName );
942 return TRUE;
945 static void
946 DP_SetPlayerData( lpPlayerData lpPData, LPVOID lpData, DWORD dwDataSize )
948 /* Clear out the data with this player */
949 if( lpPData->dwDataSize != 0 )
951 HeapFree( GetProcessHeap(), 0, lpPData->lpData );
952 lpPData->lpData = NULL;
953 lpPData->dwDataSize = 0;
956 /* Reallocate for new data */
957 if( lpData )
959 lpPData->lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
960 sizeof( dwDataSize ) );
961 memcpy( lpPData->lpData, lpData, dwDataSize );
962 lpPData->dwDataSize = dwDataSize;
967 static HRESULT WINAPI DirectPlay2AImpl_CreatePlayer
968 ( LPDIRECTPLAY2A iface,
969 LPDPID lpidPlayer,
970 LPDPNAME lpPlayerName,
971 HANDLE hEvent,
972 LPVOID lpData,
973 DWORD dwDataSize,
974 DWORD dwFlags )
976 lpPlayerData lpPData;
977 ICOM_THIS(IDirectPlay2Impl,iface);
979 TRACE("(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx)\n", This, lpidPlayer, lpPlayerName, hEvent, lpData, dwDataSize, dwFlags );
981 if( dwFlags == 0 )
983 dwFlags = DPPLAYER_SPECTATOR;
986 /* Verify we know how to handle all the flags */
987 if( !( ( dwFlags & DPPLAYER_SERVERPLAYER ) ||
988 ( dwFlags & DPPLAYER_SPECTATOR )
992 /* Assume non fatal failure */
993 ERR( "unknown dwFlags = 0x%08lx\n", dwFlags );
996 if ( dwFlags & DPPLAYER_SERVERPLAYER )
998 /* We have a request to create the "master" of the session.
999 * This computer needs to be the session host and the server
1000 * player can't have been created yet.
1002 if( ( !This->dp2->bHostInterface ) ||
1003 ( DP_FindPlayer( This, DPID_SERVERPLAYER ) )
1006 return DPERR_CANTCREATEPLAYER;
1009 *lpidPlayer = DPID_SERVERPLAYER;
1011 else
1013 *lpidPlayer = DPID_UNKNOWN;
1016 lpPData = DP_CreatePlayer( iface, lpidPlayer,
1017 lpPlayerName, hEvent, TRUE /*Ansi*/ );
1019 if( lpPData == NULL )
1021 return DPERR_CANTADDPLAYER;
1024 /* Update the information and send it to all players in the session */
1025 DP_SetPlayerData( lpPData, lpData, dwDataSize );
1028 /* FIXME: Should send DPMSG_CREATEPLAYERORGROUP message to everyone,
1029 local and remote, that belongs to this session. This will not
1030 be done by calling SetPlayerData */
1031 FIXME( "Should broadcast player creation to everything in session\n" );
1033 return DP_OK;
1036 static HRESULT WINAPI DirectPlay2WImpl_CreatePlayer
1037 ( LPDIRECTPLAY2 iface, LPDPID lpidPlayer, LPDPNAME lpPlayerName, HANDLE hEvent, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
1039 ICOM_THIS(IDirectPlay2Impl,iface);
1040 FIXME("(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx): stub\n", This, lpidPlayer, lpPlayerName, hEvent, lpData, dwDataSize, dwFlags );
1041 return DP_OK;
1044 static HRESULT WINAPI DirectPlay2AImpl_DeletePlayerFromGroup
1045 ( LPDIRECTPLAY2A iface, DPID idGroup, DPID idPlayer )
1047 ICOM_THIS(IDirectPlay2Impl,iface);
1048 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idPlayer );
1049 return DP_OK;
1052 static HRESULT WINAPI DirectPlay2WImpl_DeletePlayerFromGroup
1053 ( LPDIRECTPLAY2 iface, DPID idGroup, DPID idPlayer )
1055 ICOM_THIS(IDirectPlay2Impl,iface);
1056 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idPlayer );
1057 return DP_OK;
1060 static HRESULT WINAPI DirectPlay2AImpl_DestroyGroup
1061 ( LPDIRECTPLAY2A iface, DPID idGroup )
1063 ICOM_THIS(IDirectPlay2Impl,iface);
1064 FIXME("(%p)->(0x%08lx): stub\n", This, idGroup );
1065 return DP_OK;
1068 static HRESULT WINAPI DirectPlay2WImpl_DestroyGroup
1069 ( LPDIRECTPLAY2 iface, DPID idGroup )
1071 ICOM_THIS(IDirectPlay2Impl,iface);
1072 FIXME("(%p)->(0x%08lx): stub\n", This, idGroup );
1073 return DP_OK;
1076 static HRESULT WINAPI DirectPlay2AImpl_DestroyPlayer
1077 ( LPDIRECTPLAY2A iface, DPID idPlayer )
1079 ICOM_THIS(IDirectPlay2Impl,iface);
1080 FIXME("(%p)->(0x%08lx): stub\n", This, idPlayer );
1081 return DP_OK;
1084 static HRESULT WINAPI DirectPlay2WImpl_DestroyPlayer
1085 ( LPDIRECTPLAY2 iface, DPID idPlayer )
1087 ICOM_THIS(IDirectPlay2Impl,iface);
1088 FIXME("(%p)->(0x%08lx): stub\n", This, idPlayer );
1089 return DP_OK;
1092 static HRESULT WINAPI DirectPlay2AImpl_EnumGroupPlayers
1093 ( LPDIRECTPLAY2A iface, DPID idGroup, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
1094 LPVOID lpContext, DWORD dwFlags )
1096 ICOM_THIS(IDirectPlay2Impl,iface);
1097 FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub\n", This, idGroup, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
1098 return DP_OK;
1101 static HRESULT WINAPI DirectPlay2WImpl_EnumGroupPlayers
1102 ( LPDIRECTPLAY2 iface, DPID idGroup, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
1103 LPVOID lpContext, DWORD dwFlags )
1105 ICOM_THIS(IDirectPlay2Impl,iface);
1106 FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub\n", This, idGroup, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
1107 return DP_OK;
1110 static HRESULT WINAPI DirectPlay2AImpl_EnumGroups
1111 ( LPDIRECTPLAY2A iface, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
1113 ICOM_THIS(IDirectPlay2Impl,iface);
1114 FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
1115 return DP_OK;
1118 static HRESULT WINAPI DirectPlay2WImpl_EnumGroups
1119 ( LPDIRECTPLAY2 iface, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
1121 ICOM_THIS(IDirectPlay2Impl,iface);
1122 FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
1123 return DP_OK;
1126 static HRESULT WINAPI DirectPlay2AImpl_EnumPlayers
1127 ( LPDIRECTPLAY2A iface, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
1129 ICOM_THIS(IDirectPlay2Impl,iface);
1131 FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
1133 return DP_OK;
1136 static HRESULT WINAPI DirectPlay2WImpl_EnumPlayers
1137 ( LPDIRECTPLAY2 iface, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
1139 ICOM_THIS(IDirectPlay2Impl,iface);
1140 FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n",
1141 This, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
1142 return DP_OK;
1145 /* This function should call the registered callback function that the user
1146 passed into EnumSessions for each entry available.
1148 static void DP_InvokeEnumSessionCallbacksA( LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
1149 LPVOID lpNSInfo,
1150 DWORD dwTimeout,
1151 LPVOID lpContext )
1153 LPDPSESSIONDESC2 lpSessionDesc;
1155 FIXME( ": not checking for conditions\n" );
1157 NS_ResetSessionEnumeration( lpNSInfo );
1159 /* Enumerate all sessions */
1160 while( (lpSessionDesc = NS_WalkSessions( lpNSInfo ) ) != NULL )
1162 TRACE( "EnumSessionsCallback2 invoked\n" );
1163 if( !lpEnumSessionsCallback2( lpSessionDesc, &dwTimeout, 0, lpContext ) )
1165 return;
1171 static DWORD CALLBACK DP_EnumSessionsSpwanThreadA( LPVOID lpContext )
1173 ICOM_THIS(IDirectPlay2Impl,lpContext);
1174 DWORD dwTimeout = This->dp2->enumSessionAsyncCallbackData.dwTimeout;
1176 TRACE( "(%p)->(0x%08lx)\n", This, dwTimeout );
1178 /* FIXME: Don't think this is exactly right. It'll do for now */
1179 for( ;; )
1181 /* 2: Send the broadcast for session enumeration */
1182 NS_SendSessionRequestBroadcast( This->dp2->lpNameServerData );
1184 SleepEx( dwTimeout, FALSE );
1186 DP_InvokeEnumSessionCallbacksA( This->dp2->enumSessionAsyncCallbackData.cb,
1187 This->dp2->lpNameServerData,
1188 dwTimeout,
1189 This->dp2->enumSessionAsyncCallbackData.lpContext );
1191 /* All sessions have been enumerated. Invoke the callback function
1192 once more indicating a timeout has occured. This is the way
1193 that the application can indicate that it wishes to continue with the
1194 enumeration */
1195 if( !(This->dp2->enumSessionAsyncCallbackData.cb)( NULL, &dwTimeout, DPESC_TIMEDOUT, lpContext ) )
1197 /* The application doesn't want us to continue - end this thread */
1198 return 0;
1203 return 1;
1206 static HRESULT WINAPI DirectPlay2AImpl_EnumSessions
1207 ( LPDIRECTPLAY2A iface, LPDPSESSIONDESC2 lpsd, DWORD dwTimeout, LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
1208 LPVOID lpContext, DWORD dwFlags )
1210 ICOM_THIS(IDirectPlay2Impl,iface);
1212 TRACE("(%p)->(%p,0x%08lx,%p,%p,0x%08lx)\n", This, lpsd, dwTimeout, lpEnumSessionsCallback2, lpContext, dwFlags );
1214 if( dwTimeout == 0 )
1216 /* Should actually be getting the dwTimeout value through
1217 IDirectPlay_GetCaps( This, ...) */
1218 FIXME( ": should provide a dependent dwTimeout\n" );
1219 dwTimeout = 5 * 1000; /* 5 seconds */
1222 if( dwFlags & DPENUMSESSIONS_STOPASYNC )
1224 /* Does a thread exist? If so we were doing an async enum session */
1225 if( This->dp2->hEnumSessionThread != INVALID_HANDLE_VALUE )
1227 /* FIXME: This needs to be send an event to the thread to clean itself up nicely */
1228 TerminateThread( This->dp2->hEnumSessionThread, 0 );
1229 CloseHandle( This->dp2->hEnumSessionThread );
1231 This->dp2->hEnumSessionThread = INVALID_HANDLE_VALUE;
1233 This->dp2->enumSessionAsyncCallbackData.cb = NULL;
1234 This->dp2->enumSessionAsyncCallbackData.lpContext = NULL;
1235 This->dp2->enumSessionAsyncCallbackData.dwTimeout = INFINITE;
1237 return DP_OK;
1240 /* Indicate some sort of error... */
1241 WARN( "STOPASYNC attempted when no async running\n" );
1242 return DP_OK;
1245 /* FIXME: Interface locking sucks in this method */
1247 if( ( dwFlags & DPENUMSESSIONS_ASYNC ) )
1249 DWORD dwThreadId;
1251 /* Enumerate everything presently in the local session cache */
1252 DP_InvokeEnumSessionCallbacksA( lpEnumSessionsCallback2, This->dp2->lpNameServerData, dwTimeout, lpContext );
1254 /* See if we've already created a thread to service this interface */
1255 if( This->dp2->hEnumSessionThread == INVALID_HANDLE_VALUE )
1257 /* FIXME: Should be adding a reference here - another thread now knows
1258 how to call this interface */
1259 This->dp2->enumSessionAsyncCallbackData.cb = lpEnumSessionsCallback2;
1260 This->dp2->enumSessionAsyncCallbackData.lpContext = lpContext;
1261 This->dp2->enumSessionAsyncCallbackData.dwTimeout = dwTimeout;
1263 TRACE( ": creating EnumSessions thread\n" );
1265 This->dp2->hEnumSessionThread = CreateThread( NULL,
1267 DP_EnumSessionsSpwanThreadA,
1268 This,
1270 &dwThreadId );
1274 else
1276 /* Send the broadcast for session enumeration */
1277 NS_SendSessionRequestBroadcast( This->dp2->lpNameServerData );
1279 SleepEx( dwTimeout, FALSE );
1281 DP_InvokeEnumSessionCallbacksA( lpEnumSessionsCallback2, This->dp2->lpNameServerData, dwTimeout, lpContext );
1284 return DP_OK;
1287 static HRESULT WINAPI DirectPlay2WImpl_EnumSessions
1288 ( LPDIRECTPLAY2 iface, LPDPSESSIONDESC2 lpsd, DWORD dwTimeout, LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
1289 LPVOID lpContext, DWORD dwFlags )
1291 ICOM_THIS(IDirectPlay2Impl,iface);
1292 FIXME("(%p)->(%p,0x%08lx,%p,%p,0x%08lx): stub\n", This, lpsd, dwTimeout, lpEnumSessionsCallback2, lpContext, dwFlags );
1293 return DP_OK;
1296 static HRESULT WINAPI DirectPlay2AImpl_GetCaps
1297 ( LPDIRECTPLAY2A iface, LPDPCAPS lpDPCaps, DWORD dwFlags )
1299 ICOM_THIS(IDirectPlay2Impl,iface);
1300 FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpDPCaps, dwFlags );
1301 return DP_OK;
1304 static HRESULT WINAPI DirectPlay2WImpl_GetCaps
1305 ( LPDIRECTPLAY2 iface, LPDPCAPS lpDPCaps, DWORD dwFlags )
1307 ICOM_THIS(IDirectPlay2Impl,iface);
1308 FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpDPCaps, dwFlags );
1309 return DP_OK;
1312 static HRESULT WINAPI DirectPlay2AImpl_GetGroupData
1313 ( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize, DWORD dwFlags )
1315 ICOM_THIS(IDirectPlay2Impl,iface);
1316 FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, idGroup, lpData, lpdwDataSize, dwFlags );
1317 return DP_OK;
1320 static HRESULT WINAPI DirectPlay2WImpl_GetGroupData
1321 ( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize, DWORD dwFlags )
1323 ICOM_THIS(IDirectPlay2Impl,iface);
1324 FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, idGroup, lpData, lpdwDataSize, dwFlags );
1325 return DP_OK;
1328 static HRESULT WINAPI DirectPlay2AImpl_GetGroupName
1329 ( LPDIRECTPLAY2A iface, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize )
1331 ICOM_THIS(IDirectPlay2Impl,iface);
1332 FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idGroup, lpData, lpdwDataSize );
1333 return DP_OK;
1336 static HRESULT WINAPI DirectPlay2WImpl_GetGroupName
1337 ( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize )
1339 ICOM_THIS(IDirectPlay2Impl,iface);
1340 FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idGroup, lpData, lpdwDataSize );
1341 return DP_OK;
1344 static HRESULT WINAPI DirectPlay2AImpl_GetMessageCount
1345 ( LPDIRECTPLAY2A iface, DPID idPlayer, LPDWORD lpdwCount )
1347 ICOM_THIS(IDirectPlay2Impl,iface);
1348 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idPlayer, lpdwCount );
1349 return DP_OK;
1352 static HRESULT WINAPI DirectPlay2WImpl_GetMessageCount
1353 ( LPDIRECTPLAY2 iface, DPID idPlayer, LPDWORD lpdwCount )
1355 ICOM_THIS(IDirectPlay2Impl,iface);
1356 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idPlayer, lpdwCount );
1357 return DP_OK;
1360 static HRESULT WINAPI DirectPlay2AImpl_GetPlayerAddress
1361 ( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize )
1363 ICOM_THIS(IDirectPlay2Impl,iface);
1364 FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idPlayer, lpData, lpdwDataSize );
1365 return DP_OK;
1368 static HRESULT WINAPI DirectPlay2WImpl_GetPlayerAddress
1369 ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize )
1371 ICOM_THIS(IDirectPlay2Impl,iface);
1372 FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idPlayer, lpData, lpdwDataSize );
1373 return DP_OK;
1376 static HRESULT WINAPI DirectPlay2AImpl_GetPlayerCaps
1377 ( LPDIRECTPLAY2A iface, DPID idPlayer, LPDPCAPS lpPlayerCaps, DWORD dwFlags )
1379 ICOM_THIS(IDirectPlay2Impl,iface);
1380 FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idPlayer, lpPlayerCaps, dwFlags );
1381 return DP_OK;
1384 static HRESULT WINAPI DirectPlay2WImpl_GetPlayerCaps
1385 ( LPDIRECTPLAY2 iface, DPID idPlayer, LPDPCAPS lpPlayerCaps, DWORD dwFlags )
1387 ICOM_THIS(IDirectPlay2Impl,iface);
1388 FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idPlayer, lpPlayerCaps, dwFlags );
1389 return DP_OK;
1392 static HRESULT WINAPI DirectPlay2AImpl_GetPlayerData
1393 ( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize, DWORD dwFlags )
1395 ICOM_THIS(IDirectPlay2Impl,iface);
1396 FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, idPlayer, lpData, lpdwDataSize, dwFlags );
1397 return DP_OK;
1400 static HRESULT WINAPI DirectPlay2WImpl_GetPlayerData
1401 ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize, DWORD dwFlags )
1403 ICOM_THIS(IDirectPlay2Impl,iface);
1404 FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, idPlayer, lpData, lpdwDataSize, dwFlags );
1405 return DP_OK;
1408 static HRESULT WINAPI DirectPlay2AImpl_GetPlayerName
1409 ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize )
1411 ICOM_THIS(IDirectPlay2Impl,iface);
1412 FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idPlayer, lpData, lpdwDataSize );
1413 return DP_OK;
1416 static HRESULT WINAPI DirectPlay2WImpl_GetPlayerName
1417 ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize )
1419 ICOM_THIS(IDirectPlay2Impl,iface);
1420 FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idPlayer, lpData, lpdwDataSize );
1421 return DP_OK;
1424 static HRESULT WINAPI DirectPlay2AImpl_GetSessionDesc
1425 ( LPDIRECTPLAY2A iface, LPVOID lpData, LPDWORD lpdwDataSize )
1427 ICOM_THIS(IDirectPlay2Impl,iface);
1428 FIXME("(%p)->(%p,%p): stub\n", This, lpData, lpdwDataSize );
1429 return DP_OK;
1432 static HRESULT WINAPI DirectPlay2WImpl_GetSessionDesc
1433 ( LPDIRECTPLAY2 iface, LPVOID lpData, LPDWORD lpdwDataSize )
1435 ICOM_THIS(IDirectPlay2Impl,iface);
1436 FIXME("(%p)->(%p,%p): stub\n", This, lpData, lpdwDataSize );
1437 return DP_OK;
1440 /* Intended only for COM compatibility. Always returns an error. */
1441 static HRESULT WINAPI DirectPlay2AImpl_Initialize
1442 ( LPDIRECTPLAY2A iface, LPGUID lpGUID )
1444 ICOM_THIS(IDirectPlay2Impl,iface);
1445 TRACE("(%p)->(%p): stub\n", This, lpGUID );
1446 return DPERR_ALREADYINITIALIZED;
1449 /* Intended only for COM compatibility. Always returns an error. */
1450 static HRESULT WINAPI DirectPlay2WImpl_Initialize
1451 ( LPDIRECTPLAY2 iface, LPGUID lpGUID )
1453 ICOM_THIS(IDirectPlay2Impl,iface);
1454 TRACE("(%p)->(%p): stub\n", This, lpGUID );
1455 return DPERR_ALREADYINITIALIZED;
1459 static HRESULT WINAPI DirectPlay2AImpl_Open
1460 ( LPDIRECTPLAY2A iface, LPDPSESSIONDESC2 lpsd, DWORD dwFlags )
1462 ICOM_THIS(IDirectPlay2Impl,iface);
1464 FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpsd, dwFlags );
1466 if( This->dp2->bConnectionOpen )
1468 TRACE( ": rejecting already open connection.\n" );
1469 return DPERR_ALREADYINITIALIZED;
1472 /* When we open we need to stop any EnumSession activity */
1473 IDirectPlayX_EnumSessions( iface, NULL, 0, NULL, NULL, DPENUMSESSIONS_STOPASYNC );
1475 if( dwFlags & DPOPEN_CREATE )
1477 dwFlags &= ~DPOPEN_CREATE;
1479 /* Rightoo - this computer is the host and the local computer needs to be
1480 the name server so that others can join this session */
1481 NS_SetLocalComputerAsNameServer( lpsd );
1483 This->dp2->bHostInterface = TRUE;
1486 if( dwFlags )
1488 ERR( ": ignored dwFlags 0x%08lx\n", dwFlags );
1491 return DP_OK;
1494 static HRESULT WINAPI DirectPlay2WImpl_Open
1495 ( LPDIRECTPLAY2 iface, LPDPSESSIONDESC2 lpsd, DWORD dwFlags )
1497 ICOM_THIS(IDirectPlay2Impl,iface);
1498 FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpsd, dwFlags );
1499 return DP_OK;
1502 static HRESULT WINAPI DirectPlay2AImpl_Receive
1503 ( LPDIRECTPLAY2A iface, LPDPID lpidFrom, LPDPID lpidTo, DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize )
1505 ICOM_THIS(IDirectPlay2Impl,iface);
1506 FIXME("(%p)->(%p,%p,0x%08lx,%p,%p): stub\n", This, lpidFrom, lpidTo, dwFlags, lpData, lpdwDataSize );
1507 return DP_OK;
1510 static HRESULT WINAPI DirectPlay2WImpl_Receive
1511 ( LPDIRECTPLAY2 iface, LPDPID lpidFrom, LPDPID lpidTo, DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize )
1513 ICOM_THIS(IDirectPlay2Impl,iface);
1514 FIXME("(%p)->(%p,%p,0x%08lx,%p,%p): stub\n", This, lpidFrom, lpidTo, dwFlags, lpData, lpdwDataSize );
1515 return DP_OK;
1518 static HRESULT WINAPI DirectPlay2AImpl_Send
1519 ( LPDIRECTPLAY2A iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize )
1521 ICOM_THIS(IDirectPlay2Impl,iface);
1522 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx): stub\n", This, idFrom, idTo, dwFlags, lpData, dwDataSize );
1523 return DP_OK;
1526 static HRESULT WINAPI DirectPlay2WImpl_Send
1527 ( LPDIRECTPLAY2 iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize )
1529 ICOM_THIS(IDirectPlay2Impl,iface);
1530 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx): stub\n", This, idFrom, idTo, dwFlags, lpData, dwDataSize );
1531 return DP_OK;
1534 static HRESULT WINAPI DirectPlay2AImpl_SetGroupData
1535 ( LPDIRECTPLAY2A iface, DPID idGroup, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
1537 lpGroupData lpGData;
1538 ICOM_THIS(IDirectPlay2Impl,iface);
1540 FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): dwFlags ignored\n", This, idGroup, lpData, dwDataSize, dwFlags );
1542 /* Parameter check */
1543 if( lpData == NULL )
1545 if( dwDataSize != 0 )
1547 return DPERR_INVALIDPARAMS;
1551 /* Find the pointer to the data for this player */
1552 if( ( lpGData = DP_FindGroup( This, idGroup ) ) == NULL )
1554 return DPERR_INVALIDOBJECT;
1557 DP_SetGroupData( lpGData, lpData, dwDataSize );
1559 return DP_OK;
1562 static HRESULT WINAPI DirectPlay2WImpl_SetGroupData
1563 ( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
1565 ICOM_THIS(IDirectPlay2Impl,iface);
1566 FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub\n", This, idGroup, lpData, dwDataSize, dwFlags );
1567 return DP_OK;
1570 static HRESULT WINAPI DirectPlay2AImpl_SetGroupName
1571 ( LPDIRECTPLAY2A iface, DPID idGroup, LPDPNAME lpGroupName, DWORD dwFlags )
1573 ICOM_THIS(IDirectPlay2Impl,iface);
1574 FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idGroup, lpGroupName, dwFlags );
1575 return DP_OK;
1578 static HRESULT WINAPI DirectPlay2WImpl_SetGroupName
1579 ( LPDIRECTPLAY2 iface, DPID idGroup, LPDPNAME lpGroupName, DWORD dwFlags )
1581 ICOM_THIS(IDirectPlay2Impl,iface);
1582 FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idGroup, lpGroupName, dwFlags );
1583 return DP_OK;
1586 static HRESULT WINAPI DirectPlay2AImpl_SetPlayerData
1587 ( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
1589 lpPlayerData lpPData;
1590 ICOM_THIS(IDirectPlay2Impl,iface);
1592 TRACE("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx)\n", This, idPlayer, lpData, dwDataSize, dwFlags );
1594 /* Parameter check */
1595 if( lpData == NULL )
1597 if( dwDataSize != 0 )
1599 return DPERR_INVALIDPARAMS;
1603 /* Find the pointer to the data for this player */
1604 if( ( lpPData = DP_FindPlayer( This, idPlayer ) ) == NULL )
1606 return DPERR_INVALIDOBJECT;
1609 DP_SetPlayerData( lpPData, lpData, dwDataSize );
1611 if( !(dwFlags & DPSET_LOCAL ) ) /* Is DPSET_REMOTE? */
1613 FIXME( "Change not propagated to all players in the session\n" );
1616 return DP_OK;
1619 static HRESULT WINAPI DirectPlay2WImpl_SetPlayerData
1620 ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
1622 ICOM_THIS(IDirectPlay2Impl,iface);
1623 FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub\n", This, idPlayer, lpData, dwDataSize, dwFlags );
1624 return DP_OK;
1627 static HRESULT WINAPI DirectPlay2AImpl_SetPlayerName
1628 ( LPDIRECTPLAY2A iface, DPID idPlayer, LPDPNAME lpPlayerName, DWORD dwFlags )
1630 ICOM_THIS(IDirectPlay2Impl,iface);
1632 FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idPlayer, lpPlayerName, dwFlags );
1634 return DP_OK;
1637 static HRESULT WINAPI DirectPlay2WImpl_SetPlayerName
1638 ( LPDIRECTPLAY2 iface, DPID idPlayer, LPDPNAME lpPlayerName, DWORD dwFlags )
1640 ICOM_THIS(IDirectPlay2Impl,iface);
1641 FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idPlayer, lpPlayerName, dwFlags );
1642 return DP_OK;
1645 static HRESULT WINAPI DirectPlay2AImpl_SetSessionDesc
1646 ( LPDIRECTPLAY2A iface, LPDPSESSIONDESC2 lpSessDesc, DWORD dwFlags )
1648 ICOM_THIS(IDirectPlay2Impl,iface);
1649 FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpSessDesc, dwFlags );
1650 return DP_OK;
1653 static HRESULT WINAPI DirectPlay2WImpl_SetSessionDesc
1654 ( LPDIRECTPLAY2 iface, LPDPSESSIONDESC2 lpSessDesc, DWORD dwFlags )
1656 ICOM_THIS(IDirectPlay2Impl,iface);
1657 FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpSessDesc, dwFlags );
1658 return DP_OK;
1661 static HRESULT WINAPI DirectPlay3AImpl_AddGroupToGroup
1662 ( LPDIRECTPLAY3A iface, DPID idParentGroup, DPID idGroup )
1664 ICOM_THIS(IDirectPlay3Impl,iface);
1665 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idParentGroup, idGroup );
1666 return DP_OK;
1669 static HRESULT WINAPI DirectPlay3WImpl_AddGroupToGroup
1670 ( LPDIRECTPLAY3 iface, DPID idParentGroup, DPID idGroup )
1672 ICOM_THIS(IDirectPlay3Impl,iface);
1673 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idParentGroup, idGroup );
1674 return DP_OK;
1677 static HRESULT WINAPI DirectPlay3AImpl_CreateGroupInGroup
1678 ( LPDIRECTPLAY3A iface, DPID idParentGroup, LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
1680 ICOM_THIS(IDirectPlay3Impl,iface);
1681 FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx): stub\n", This, idParentGroup, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags );
1682 return DP_OK;
1685 static HRESULT WINAPI DirectPlay3WImpl_CreateGroupInGroup
1686 ( LPDIRECTPLAY3 iface, DPID idParentGroup, LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
1688 ICOM_THIS(IDirectPlay3Impl,iface);
1689 FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx): stub\n", This, idParentGroup, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags );
1690 return DP_OK;
1693 static HRESULT WINAPI DirectPlay3AImpl_DeleteGroupFromGroup
1694 ( LPDIRECTPLAY3A iface, DPID idParentGroup, DPID idGroup )
1696 ICOM_THIS(IDirectPlay3Impl,iface);
1697 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idParentGroup, idGroup );
1698 return DP_OK;
1701 static HRESULT WINAPI DirectPlay3WImpl_DeleteGroupFromGroup
1702 ( LPDIRECTPLAY3 iface, DPID idParentGroup, DPID idGroup )
1704 ICOM_THIS(IDirectPlay3Impl,iface);
1705 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idParentGroup, idGroup );
1706 return DP_OK;
1709 static HRESULT WINAPI DirectPlay3AImpl_EnumConnections
1710 ( LPDIRECTPLAY3A iface, LPCGUID lpguidApplication, LPDPENUMCONNECTIONSCALLBACK lpEnumCallback, LPVOID lpContext, DWORD dwFlags )
1712 ICOM_THIS(IDirectPlay3Impl,iface);
1713 TRACE("(%p)->(%p,%p,%p,0x%08lx)\n", This, lpguidApplication, lpEnumCallback, lpContext, dwFlags );
1715 /* A default dwFlags (0) is backwards compatible -- DPCONNECTION_DIRECTPLAY */
1716 if( dwFlags == 0 )
1718 dwFlags = DPCONNECTION_DIRECTPLAY;
1721 if( ! ( ( dwFlags & DPCONNECTION_DIRECTPLAY ) ||
1722 ( dwFlags & DPCONNECTION_DIRECTPLAYLOBBY ) )
1725 return DPERR_INVALIDFLAGS;
1728 if( !lpEnumCallback || !*lpEnumCallback )
1730 return DPERR_INVALIDPARAMS;
1733 /* Enumerate DirectPlay service providers */
1734 if( dwFlags & DPCONNECTION_DIRECTPLAY )
1736 HKEY hkResult;
1737 LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
1738 LPSTR guidDataSubKey = "Guid";
1739 char subKeyName[51];
1740 DWORD dwIndex, sizeOfSubKeyName=50;
1741 FILETIME filetime;
1743 /* Need to loop over the service providers in the registry */
1744 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
1745 0, KEY_READ, &hkResult ) != ERROR_SUCCESS )
1747 /* Hmmm. Does this mean that there are no service providers? */
1748 ERR(": no service providers?\n");
1749 return DP_OK;
1753 /* Traverse all the service providers we have available */
1754 for( dwIndex=0;
1755 RegEnumKeyExA( hkResult, dwIndex, subKeyName, &sizeOfSubKeyName,
1756 NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS;
1757 ++dwIndex, sizeOfSubKeyName=51 )
1760 HKEY hkServiceProvider;
1761 GUID serviceProviderGUID;
1762 DWORD returnTypeGUID, sizeOfReturnBuffer = 50;
1763 char returnBuffer[51];
1764 LPWSTR lpWGUIDString;
1765 DPNAME dpName;
1766 HRESULT hr;
1768 DPCOMPOUNDADDRESSELEMENT dpCompoundAddress;
1769 LPVOID lpAddressBuffer = NULL;
1770 DWORD dwAddressBufferSize = 0;
1772 TRACE(" this time through: %s\n", subKeyName );
1774 /* Get a handle for this particular service provider */
1775 if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_READ,
1776 &hkServiceProvider ) != ERROR_SUCCESS )
1778 ERR(": what the heck is going on?\n" );
1779 continue;
1782 if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
1783 NULL, &returnTypeGUID, returnBuffer,
1784 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
1786 ERR(": missing GUID registry data members\n" );
1787 continue;
1790 /* FIXME: Check return types to ensure we're interpreting data right */
1791 lpWGUIDString = HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer );
1792 CLSIDFromString( (LPCOLESTR)lpWGUIDString, &serviceProviderGUID );
1793 HeapFree( GetProcessHeap(), 0, lpWGUIDString );
1794 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
1796 /* Fill in the DPNAME struct for the service provider */
1797 dpName.dwSize = sizeof( dpName );
1798 dpName.dwFlags = 0;
1799 dpName.psn.lpszShortNameA = subKeyName;
1800 dpName.pln.lpszLongNameA = NULL;
1802 /* Create the compound address for the service provider.
1803 NOTE: This is a gruesome architectural scar right now. DP uses DPL and DPL uses DP
1804 nast stuff. This may be why the native dll just gets around this little bit by
1805 allocating an 80 byte buffer which isn't even a filled with a valid compound
1806 address. Oh well. Creating a proper compound address is the way to go anyways
1807 despite this method taking slightly more heap space and realtime :) */
1808 dpCompoundAddress.guidDataType = DPAID_ServiceProvider;
1809 dpCompoundAddress.dwDataSize = sizeof( GUID );
1810 dpCompoundAddress.lpData = &serviceProviderGUID;
1812 if( ( hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, lpAddressBuffer,
1813 &dwAddressBufferSize, TRUE ) ) != DPERR_BUFFERTOOSMALL )
1815 ERR( "can't get buffer size: %s\n", DPLAYX_HresultToString( hr ) );
1816 return hr;
1819 /* Now allocate the buffer */
1820 lpAddressBuffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAddressBufferSize );
1822 if( ( hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, lpAddressBuffer,
1823 &dwAddressBufferSize, TRUE ) ) != DP_OK )
1825 ERR( "can't create address: %s\n", DPLAYX_HresultToString( hr ) );
1826 return hr;
1829 /* The enumeration will return FALSE if we are not to continue */
1830 if( !lpEnumCallback( &serviceProviderGUID, lpAddressBuffer, dwAddressBufferSize,
1831 &dpName, DPCONNECTION_DIRECTPLAY, lpContext ) )
1833 WARN("lpEnumCallback returning FALSE\n" );
1835 return DP_OK;
1840 /* Enumerate DirectPlayLobby service providers */
1841 if( dwFlags & DPCONNECTION_DIRECTPLAYLOBBY )
1843 HKEY hkResult;
1844 LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Lobby Providers";
1845 LPSTR guidDataSubKey = "Guid";
1846 char subKeyName[51];
1847 DWORD dwIndex, sizeOfSubKeyName=50;
1848 FILETIME filetime;
1850 /* Need to loop over the service providers in the registry */
1851 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
1852 0, KEY_READ, &hkResult ) != ERROR_SUCCESS )
1854 /* Hmmm. Does this mean that there are no service providers? */
1855 ERR(": no service providers?\n");
1856 return DP_OK;
1860 /* Traverse all the service providers we have available */
1861 for( dwIndex=0;
1862 RegEnumKeyExA( hkResult, dwIndex, subKeyName, &sizeOfSubKeyName,
1863 NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS;
1864 ++dwIndex, sizeOfSubKeyName=51 )
1867 HKEY hkServiceProvider;
1868 GUID serviceProviderGUID;
1869 DWORD returnTypeGUID, sizeOfReturnBuffer = 50;
1870 char returnBuffer[51];
1871 LPWSTR lpWGUIDString;
1872 DPNAME dpName;
1873 HRESULT hr;
1875 DPCOMPOUNDADDRESSELEMENT dpCompoundAddress;
1876 LPVOID lpAddressBuffer = NULL;
1877 DWORD dwAddressBufferSize = 0;
1879 TRACE(" this time through: %s\n", subKeyName );
1881 /* Get a handle for this particular service provider */
1882 if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_READ,
1883 &hkServiceProvider ) != ERROR_SUCCESS )
1885 ERR(": what the heck is going on?\n" );
1886 continue;
1889 if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
1890 NULL, &returnTypeGUID, returnBuffer,
1891 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
1893 ERR(": missing GUID registry data members\n" );
1894 continue;
1897 /* FIXME: Check return types to ensure we're interpreting data right */
1898 lpWGUIDString = HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer );
1899 CLSIDFromString( (LPCOLESTR)lpWGUIDString, &serviceProviderGUID );
1900 HeapFree( GetProcessHeap(), 0, lpWGUIDString );
1901 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
1903 /* Fill in the DPNAME struct for the service provider */
1904 dpName.dwSize = sizeof( dpName );
1905 dpName.dwFlags = 0;
1906 dpName.psn.lpszShortNameA = subKeyName;
1907 dpName.pln.lpszLongNameA = NULL;
1909 /* Create the compound address for the service provider.
1910 NOTE: This is a gruesome architectural scar right now. DP uses DPL and DPL uses DP
1911 nast stuff. This may be why the native dll just gets around this little bit by
1912 allocating an 80 byte buffer which isn't even a filled with a valid compound
1913 address. Oh well. Creating a proper compound address is the way to go anyways
1914 despite this method taking slightly more heap space and realtime :) */
1915 dpCompoundAddress.guidDataType = DPAID_ServiceProvider;
1916 dpCompoundAddress.dwDataSize = sizeof( GUID );
1917 dpCompoundAddress.lpData = &serviceProviderGUID;
1919 if( ( hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, lpAddressBuffer,
1920 &dwAddressBufferSize, TRUE ) ) != DPERR_BUFFERTOOSMALL )
1922 ERR( "can't get buffer size: %s\n", DPLAYX_HresultToString( hr ) );
1923 return hr;
1926 /* Now allocate the buffer */
1927 lpAddressBuffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAddressBufferSize );
1929 if( ( hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, lpAddressBuffer,
1930 &dwAddressBufferSize, TRUE ) ) != DP_OK )
1932 ERR( "can't create address: %s\n", DPLAYX_HresultToString( hr ) );
1933 return hr;
1936 /* The enumeration will return FALSE if we are not to continue */
1937 if( !lpEnumCallback( &serviceProviderGUID, lpAddressBuffer, dwAddressBufferSize,
1938 &dpName, DPCONNECTION_DIRECTPLAY, lpContext ) )
1940 WARN("lpEnumCallback returning FALSE\n" );
1942 return DP_OK;
1947 return DP_OK;
1950 static HRESULT WINAPI DirectPlay3WImpl_EnumConnections
1951 ( LPDIRECTPLAY3 iface, LPCGUID lpguidApplication, LPDPENUMCONNECTIONSCALLBACK lpEnumCallback, LPVOID lpContext, DWORD dwFlags )
1953 ICOM_THIS(IDirectPlay3Impl,iface);
1954 FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidApplication, lpEnumCallback, lpContext, dwFlags );
1955 return DP_OK;
1958 static HRESULT WINAPI DirectPlay3AImpl_EnumGroupsInGroup
1959 ( LPDIRECTPLAY3A iface, DPID idGroup, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumCallback, LPVOID lpContext, DWORD dwFlags )
1961 ICOM_THIS(IDirectPlay3Impl,iface);
1962 FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub\n", This, idGroup, lpguidInstance, lpEnumCallback, lpContext, dwFlags );
1963 return DP_OK;
1966 static HRESULT WINAPI DirectPlay3WImpl_EnumGroupsInGroup
1967 ( LPDIRECTPLAY3 iface, DPID idGroup, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumCallback, LPVOID lpContext, DWORD dwFlags )
1969 ICOM_THIS(IDirectPlay3Impl,iface);
1970 FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub\n", This, idGroup, lpguidInstance, lpEnumCallback, lpContext, dwFlags );
1971 return DP_OK;
1974 static HRESULT WINAPI DirectPlay3AImpl_GetGroupConnectionSettings
1975 ( LPDIRECTPLAY3A iface, DWORD dwFlags, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize )
1977 ICOM_THIS(IDirectPlay3Impl,iface);
1978 FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, dwFlags, idGroup, lpData, lpdwDataSize );
1979 return DP_OK;
1982 static HRESULT WINAPI DirectPlay3WImpl_GetGroupConnectionSettings
1983 ( LPDIRECTPLAY3 iface, DWORD dwFlags, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize )
1985 ICOM_THIS(IDirectPlay3Impl,iface);
1986 FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, dwFlags, idGroup, lpData, lpdwDataSize );
1987 return DP_OK;
1990 static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
1991 ( LPDIRECTPLAY3A iface, LPVOID lpConnection, DWORD dwFlags )
1993 HMODULE hServiceProvider;
1994 /*DWORD dwReturnValue; */
1995 typedef DWORD (WINAPI *SP_SPInit)(LPVOID, LPVOID, LPVOID ); /* FIXME: How many arguments? */
1996 SP_SPInit SPInit;
1998 ICOM_THIS(IDirectPlay3Impl,iface);
2000 FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpConnection, dwFlags );
2002 if( dwFlags != 0 )
2004 return DPERR_INVALIDFLAGS;
2007 if( This->dp3->bConnectionInitialized == TRUE )
2009 return DPERR_ALREADYINITIALIZED;
2012 /* Parse lpConnection as a compound address for the service provider */
2013 /* Take service provider GUID and find the path to it */
2015 /* FIXME: Hard coded to only load the tcp/ip service provider for now... */
2016 hServiceProvider = LoadLibraryA( "dpwsockx.dll" );
2018 if( hServiceProvider == 0 )
2020 ERR( "Unable to load service provider\n" );
2021 return DPERR_UNAVAILABLE;
2024 /* Initialize the service provider by calling SPInit */
2025 SPInit = (SP_SPInit)GetProcAddress( hServiceProvider, "SPInit" );
2027 if( SPInit == NULL )
2029 ERR( "Service provider doesn't provide SPInit interface?\n" );
2032 #if 0
2033 /* NOTE: This will crash until I know what parameters/interface this has */
2034 /* FIXME: Take a guess that we just pass the compound address to the SP */
2035 /* Hmmm...how to say which parameters need to be gotten from the SP. They must
2036 come from the compound address, but how do we communicate what's required? */
2037 dwReturnValue = (*SPInit)( lpConnection, NULL, NULL );
2038 #endif
2040 /* This interface is now initialized */
2041 This->dp3->bConnectionInitialized = TRUE;
2043 return DP_OK;
2046 static HRESULT WINAPI DirectPlay3WImpl_InitializeConnection
2047 ( LPDIRECTPLAY3 iface, LPVOID lpConnection, DWORD dwFlags )
2049 ICOM_THIS(IDirectPlay3Impl,iface);
2050 FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpConnection, dwFlags );
2051 return DP_OK;
2054 static HRESULT WINAPI DirectPlay3AImpl_SecureOpen
2055 ( LPDIRECTPLAY3A iface, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags, LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials )
2057 ICOM_THIS(IDirectPlay3Impl,iface);
2059 FIXME("(%p)->(%p,0x%08lx,%p,%p): stub\n", This, lpsd, dwFlags, lpSecurity, lpCredentials );
2061 if( This->dp2->bConnectionOpen )
2063 TRACE( ": rejecting already open connection.\n" );
2064 return DPERR_ALREADYINITIALIZED;
2067 /* When we open we need to stop any EnumSession activity */
2068 IDirectPlayX_EnumSessions( iface, NULL, 0, NULL, NULL, DPENUMSESSIONS_STOPASYNC );
2070 if( dwFlags & DPOPEN_CREATE )
2072 dwFlags &= ~DPOPEN_CREATE;
2074 /* Rightoo - this computer is the host and the local computer needs to be
2075 the name server so that others can join this session */
2076 NS_SetLocalComputerAsNameServer( lpsd );
2078 This->dp2->bHostInterface = TRUE;
2081 if( dwFlags )
2083 ERR( ": ignored dwFlags 0x%08lx\n", dwFlags );
2086 return DP_OK;
2090 static HRESULT WINAPI DirectPlay3WImpl_SecureOpen
2091 ( LPDIRECTPLAY3 iface, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags, LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials )
2093 ICOM_THIS(IDirectPlay3Impl,iface);
2094 FIXME("(%p)->(%p,0x%08lx,%p,%p): stub\n", This, lpsd, dwFlags, lpSecurity, lpCredentials );
2095 return DP_OK;
2098 static HRESULT WINAPI DirectPlay3AImpl_SendChatMessage
2099 ( LPDIRECTPLAY3A iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPDPCHAT lpChatMessage )
2101 ICOM_THIS(IDirectPlay3Impl,iface);
2102 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p): stub\n", This, idFrom, idTo, dwFlags, lpChatMessage );
2103 return DP_OK;
2106 static HRESULT WINAPI DirectPlay3WImpl_SendChatMessage
2107 ( LPDIRECTPLAY3 iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPDPCHAT lpChatMessage )
2109 ICOM_THIS(IDirectPlay3Impl,iface);
2110 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p): stub\n", This, idFrom, idTo, dwFlags, lpChatMessage );
2111 return DP_OK;
2114 static HRESULT WINAPI DirectPlay3AImpl_SetGroupConnectionSettings
2115 ( LPDIRECTPLAY3A iface, DWORD dwFlags, DPID idGroup, LPDPLCONNECTION lpConnection )
2117 ICOM_THIS(IDirectPlay3Impl,iface);
2118 FIXME("(%p)->(0x%08lx,0x%08lx,%p): stub\n", This, dwFlags, idGroup, lpConnection );
2119 return DP_OK;
2122 static HRESULT WINAPI DirectPlay3WImpl_SetGroupConnectionSettings
2123 ( LPDIRECTPLAY3 iface, DWORD dwFlags, DPID idGroup, LPDPLCONNECTION lpConnection )
2125 ICOM_THIS(IDirectPlay3Impl,iface);
2126 FIXME("(%p)->(0x%08lx,0x%08lx,%p): stub\n", This, dwFlags, idGroup, lpConnection );
2127 return DP_OK;
2130 static HRESULT WINAPI DirectPlay3AImpl_StartSession
2131 ( LPDIRECTPLAY3A iface, DWORD dwFlags, DPID idGroup )
2133 ICOM_THIS(IDirectPlay3Impl,iface);
2134 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, dwFlags, idGroup );
2135 return DP_OK;
2138 static HRESULT WINAPI DirectPlay3WImpl_StartSession
2139 ( LPDIRECTPLAY3 iface, DWORD dwFlags, DPID idGroup )
2141 ICOM_THIS(IDirectPlay3Impl,iface);
2142 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, dwFlags, idGroup );
2143 return DP_OK;
2146 static HRESULT WINAPI DirectPlay3AImpl_GetGroupFlags
2147 ( LPDIRECTPLAY3A iface, DPID idGroup, LPDWORD lpdwFlags )
2149 ICOM_THIS(IDirectPlay3Impl,iface);
2150 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpdwFlags );
2151 return DP_OK;
2154 static HRESULT WINAPI DirectPlay3WImpl_GetGroupFlags
2155 ( LPDIRECTPLAY3 iface, DPID idGroup, LPDWORD lpdwFlags )
2157 ICOM_THIS(IDirectPlay3Impl,iface);
2158 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpdwFlags );
2159 return DP_OK;
2162 static HRESULT WINAPI DirectPlay3AImpl_GetGroupParent
2163 ( LPDIRECTPLAY3A iface, DPID idGroup, LPDPID lpidGroup )
2165 ICOM_THIS(IDirectPlay3Impl,iface);
2166 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpidGroup );
2167 return DP_OK;
2170 static HRESULT WINAPI DirectPlay3WImpl_GetGroupParent
2171 ( LPDIRECTPLAY3 iface, DPID idGroup, LPDPID lpidGroup )
2173 ICOM_THIS(IDirectPlay3Impl,iface);
2174 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpidGroup );
2175 return DP_OK;
2178 static HRESULT WINAPI DirectPlay3AImpl_GetPlayerAccount
2179 ( LPDIRECTPLAY3A iface, DPID idPlayer, DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize )
2181 ICOM_THIS(IDirectPlay3Impl,iface);
2182 FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, idPlayer, dwFlags, lpData, lpdwDataSize );
2183 return DP_OK;
2186 static HRESULT WINAPI DirectPlay3WImpl_GetPlayerAccount
2187 ( LPDIRECTPLAY3 iface, DPID idPlayer, DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize )
2189 ICOM_THIS(IDirectPlay3Impl,iface);
2190 FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, idPlayer, dwFlags, lpData, lpdwDataSize );
2191 return DP_OK;
2194 static HRESULT WINAPI DirectPlay3AImpl_GetPlayerFlags
2195 ( LPDIRECTPLAY3A iface, DPID idPlayer, LPDWORD lpdwFlags )
2197 ICOM_THIS(IDirectPlay3Impl,iface);
2198 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idPlayer, lpdwFlags );
2199 return DP_OK;
2202 static HRESULT WINAPI DirectPlay3WImpl_GetPlayerFlags
2203 ( LPDIRECTPLAY3 iface, DPID idPlayer, LPDWORD lpdwFlags )
2205 ICOM_THIS(IDirectPlay3Impl,iface);
2206 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idPlayer, lpdwFlags );
2207 return DP_OK;
2210 static HRESULT WINAPI DirectPlay4AImpl_GetGroupOwner
2211 ( LPDIRECTPLAY4A iface, DPID idGroup, LPDPID lpidGroupOwner )
2213 ICOM_THIS(IDirectPlay4Impl,iface);
2214 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpidGroupOwner );
2215 return DP_OK;
2218 static HRESULT WINAPI DirectPlay4WImpl_GetGroupOwner
2219 ( LPDIRECTPLAY4 iface, DPID idGroup, LPDPID lpidGroupOwner )
2221 ICOM_THIS(IDirectPlay4Impl,iface);
2222 FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpidGroupOwner );
2223 return DP_OK;
2226 static HRESULT WINAPI DirectPlay4AImpl_SetGroupOwner
2227 ( LPDIRECTPLAY4A iface, DPID idGroup , DPID idGroupOwner )
2229 ICOM_THIS(IDirectPlay4Impl,iface);
2230 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idGroupOwner );
2231 return DP_OK;
2234 static HRESULT WINAPI DirectPlay4WImpl_SetGroupOwner
2235 ( LPDIRECTPLAY4 iface, DPID idGroup , DPID idGroupOwner )
2237 ICOM_THIS(IDirectPlay4Impl,iface);
2238 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idGroupOwner );
2239 return DP_OK;
2242 static HRESULT WINAPI DirectPlay4AImpl_SendEx
2243 ( LPDIRECTPLAY4A iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize, DWORD dwPriority, DWORD dwTimeout, LPVOID lpContext, LPDWORD lpdwMsgID )
2245 ICOM_THIS(IDirectPlay4Impl,iface);
2246 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 );
2247 return DP_OK;
2250 static HRESULT WINAPI DirectPlay4WImpl_SendEx
2251 ( LPDIRECTPLAY4 iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize, DWORD dwPriority, DWORD dwTimeout, LPVOID lpContext, LPDWORD lpdwMsgID )
2253 ICOM_THIS(IDirectPlay4Impl,iface);
2254 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 );
2255 return DP_OK;
2258 static HRESULT WINAPI DirectPlay4AImpl_GetMessageQueue
2259 ( LPDIRECTPLAY4A iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPDWORD lpdwNumMsgs, LPDWORD lpdwNumBytes )
2261 ICOM_THIS(IDirectPlay4Impl,iface);
2262 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,%p): stub\n", This, idFrom, idTo, dwFlags, lpdwNumMsgs, lpdwNumBytes );
2263 return DP_OK;
2266 static HRESULT WINAPI DirectPlay4WImpl_GetMessageQueue
2267 ( LPDIRECTPLAY4 iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPDWORD lpdwNumMsgs, LPDWORD lpdwNumBytes )
2269 ICOM_THIS(IDirectPlay4Impl,iface);
2270 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,%p): stub\n", This, idFrom, idTo, dwFlags, lpdwNumMsgs, lpdwNumBytes );
2271 return DP_OK;
2274 static HRESULT WINAPI DirectPlay4AImpl_CancelMessage
2275 ( LPDIRECTPLAY4A iface, DWORD dwMsgID, DWORD dwFlags )
2277 ICOM_THIS(IDirectPlay4Impl,iface);
2278 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, dwMsgID, dwFlags );
2279 return DP_OK;
2282 static HRESULT WINAPI DirectPlay4WImpl_CancelMessage
2283 ( LPDIRECTPLAY4 iface, DWORD dwMsgID, DWORD dwFlags )
2285 ICOM_THIS(IDirectPlay4Impl,iface);
2286 FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, dwMsgID, dwFlags );
2287 return DP_OK;
2290 static HRESULT WINAPI DirectPlay4AImpl_CancelPriority
2291 ( LPDIRECTPLAY4A iface, DWORD dwMinPriority, DWORD dwMaxPriority, DWORD dwFlags )
2293 ICOM_THIS(IDirectPlay4Impl,iface);
2294 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx): stub\n", This, dwMinPriority, dwMaxPriority, dwFlags );
2295 return DP_OK;
2298 static HRESULT WINAPI DirectPlay4WImpl_CancelPriority
2299 ( LPDIRECTPLAY4 iface, DWORD dwMinPriority, DWORD dwMaxPriority, DWORD dwFlags )
2301 ICOM_THIS(IDirectPlay4Impl,iface);
2302 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx): stub\n", This, dwMinPriority, dwMaxPriority, dwFlags );
2303 return DP_OK;
2306 /* Note: Hack so we can reuse the old functions without compiler warnings */
2307 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
2308 # define XCAST(fun) (typeof(directPlay2WVT.fn##fun))
2309 #else
2310 # define XCAST(fun) (void*)
2311 #endif
2313 static ICOM_VTABLE(IDirectPlay2) directPlay2WVT =
2315 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2316 DirectPlay2W_QueryInterface,
2317 XCAST(AddRef)DirectPlay2AImpl_AddRef,
2318 XCAST(Release)DirectPlay2AImpl_Release,
2320 DirectPlay2WImpl_AddPlayerToGroup,
2321 DirectPlay2WImpl_Close,
2322 DirectPlay2WImpl_CreateGroup,
2323 DirectPlay2WImpl_CreatePlayer,
2324 DirectPlay2WImpl_DeletePlayerFromGroup,
2325 DirectPlay2WImpl_DestroyGroup,
2326 DirectPlay2WImpl_DestroyPlayer,
2327 DirectPlay2WImpl_EnumGroupPlayers,
2328 DirectPlay2WImpl_EnumGroups,
2329 DirectPlay2WImpl_EnumPlayers,
2330 DirectPlay2WImpl_EnumSessions,
2331 DirectPlay2WImpl_GetCaps,
2332 DirectPlay2WImpl_GetGroupData,
2333 DirectPlay2WImpl_GetGroupName,
2334 DirectPlay2WImpl_GetMessageCount,
2335 DirectPlay2WImpl_GetPlayerAddress,
2336 DirectPlay2WImpl_GetPlayerCaps,
2337 DirectPlay2WImpl_GetPlayerData,
2338 DirectPlay2WImpl_GetPlayerName,
2339 DirectPlay2WImpl_GetSessionDesc,
2340 DirectPlay2WImpl_Initialize,
2341 DirectPlay2WImpl_Open,
2342 DirectPlay2WImpl_Receive,
2343 DirectPlay2WImpl_Send,
2344 DirectPlay2WImpl_SetGroupData,
2345 DirectPlay2WImpl_SetGroupName,
2346 DirectPlay2WImpl_SetPlayerData,
2347 DirectPlay2WImpl_SetPlayerName,
2348 DirectPlay2WImpl_SetSessionDesc
2350 #undef XCAST
2352 /* Note: Hack so we can reuse the old functions without compiler warnings */
2353 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
2354 # define XCAST(fun) (typeof(directPlay2AVT.fn##fun))
2355 #else
2356 # define XCAST(fun) (void*)
2357 #endif
2359 static ICOM_VTABLE(IDirectPlay2) directPlay2AVT =
2361 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2362 DirectPlay2A_QueryInterface,
2363 XCAST(AddRef)DirectPlay2AImpl_AddRef,
2364 XCAST(Release)DirectPlay2AImpl_Release,
2366 DirectPlay2AImpl_AddPlayerToGroup,
2367 DirectPlay2AImpl_Close,
2368 DirectPlay2AImpl_CreateGroup,
2369 DirectPlay2AImpl_CreatePlayer,
2370 DirectPlay2AImpl_DeletePlayerFromGroup,
2371 DirectPlay2AImpl_DestroyGroup,
2372 DirectPlay2AImpl_DestroyPlayer,
2373 DirectPlay2AImpl_EnumGroupPlayers,
2374 DirectPlay2AImpl_EnumGroups,
2375 DirectPlay2AImpl_EnumPlayers,
2376 DirectPlay2AImpl_EnumSessions,
2377 DirectPlay2AImpl_GetCaps,
2378 DirectPlay2AImpl_GetGroupData,
2379 DirectPlay2AImpl_GetGroupName,
2380 DirectPlay2AImpl_GetMessageCount,
2381 DirectPlay2AImpl_GetPlayerAddress,
2382 DirectPlay2AImpl_GetPlayerCaps,
2383 DirectPlay2AImpl_GetPlayerData,
2384 DirectPlay2AImpl_GetPlayerName,
2385 DirectPlay2AImpl_GetSessionDesc,
2386 DirectPlay2AImpl_Initialize,
2387 DirectPlay2AImpl_Open,
2388 DirectPlay2AImpl_Receive,
2389 DirectPlay2AImpl_Send,
2390 DirectPlay2AImpl_SetGroupData,
2391 DirectPlay2AImpl_SetGroupName,
2392 DirectPlay2AImpl_SetPlayerData,
2393 DirectPlay2AImpl_SetPlayerName,
2394 DirectPlay2AImpl_SetSessionDesc
2396 #undef XCAST
2399 /* Note: Hack so we can reuse the old functions without compiler warnings */
2400 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
2401 # define XCAST(fun) (typeof(directPlay3AVT.fn##fun))
2402 #else
2403 # define XCAST(fun) (void*)
2404 #endif
2406 static ICOM_VTABLE(IDirectPlay3) directPlay3AVT =
2408 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2409 DirectPlay3AImpl_QueryInterface,
2410 XCAST(AddRef)DirectPlay2AImpl_AddRef,
2411 XCAST(Release)DirectPlay2AImpl_Release,
2413 XCAST(AddPlayerToGroup)DirectPlay2AImpl_AddPlayerToGroup,
2414 XCAST(Close)DirectPlay2AImpl_Close,
2415 XCAST(CreateGroup)DirectPlay2AImpl_CreateGroup,
2416 XCAST(CreatePlayer)DirectPlay2AImpl_CreatePlayer,
2417 XCAST(DeletePlayerFromGroup)DirectPlay2AImpl_DeletePlayerFromGroup,
2418 XCAST(DestroyGroup)DirectPlay2AImpl_DestroyGroup,
2419 XCAST(DestroyPlayer)DirectPlay2AImpl_DestroyPlayer,
2420 XCAST(EnumGroupPlayers)DirectPlay2AImpl_EnumGroupPlayers,
2421 XCAST(EnumGroups)DirectPlay2AImpl_EnumGroups,
2422 XCAST(EnumPlayers)DirectPlay2AImpl_EnumPlayers,
2423 XCAST(EnumSessions)DirectPlay2AImpl_EnumSessions,
2424 XCAST(GetCaps)DirectPlay2AImpl_GetCaps,
2425 XCAST(GetGroupData)DirectPlay2AImpl_GetGroupData,
2426 XCAST(GetGroupName)DirectPlay2AImpl_GetGroupName,
2427 XCAST(GetMessageCount)DirectPlay2AImpl_GetMessageCount,
2428 XCAST(GetPlayerAddress)DirectPlay2AImpl_GetPlayerAddress,
2429 XCAST(GetPlayerCaps)DirectPlay2AImpl_GetPlayerCaps,
2430 XCAST(GetPlayerData)DirectPlay2AImpl_GetPlayerData,
2431 XCAST(GetPlayerName)DirectPlay2AImpl_GetPlayerName,
2432 XCAST(GetSessionDesc)DirectPlay2AImpl_GetSessionDesc,
2433 XCAST(Initialize)DirectPlay2AImpl_Initialize,
2434 XCAST(Open)DirectPlay2AImpl_Open,
2435 XCAST(Receive)DirectPlay2AImpl_Receive,
2436 XCAST(Send)DirectPlay2AImpl_Send,
2437 XCAST(SetGroupData)DirectPlay2AImpl_SetGroupData,
2438 XCAST(SetGroupName)DirectPlay2AImpl_SetGroupName,
2439 XCAST(SetPlayerData)DirectPlay2AImpl_SetPlayerData,
2440 XCAST(SetPlayerName)DirectPlay2AImpl_SetPlayerName,
2441 XCAST(SetSessionDesc)DirectPlay2AImpl_SetSessionDesc,
2443 DirectPlay3AImpl_AddGroupToGroup,
2444 DirectPlay3AImpl_CreateGroupInGroup,
2445 DirectPlay3AImpl_DeleteGroupFromGroup,
2446 DirectPlay3AImpl_EnumConnections,
2447 DirectPlay3AImpl_EnumGroupsInGroup,
2448 DirectPlay3AImpl_GetGroupConnectionSettings,
2449 DirectPlay3AImpl_InitializeConnection,
2450 DirectPlay3AImpl_SecureOpen,
2451 DirectPlay3AImpl_SendChatMessage,
2452 DirectPlay3AImpl_SetGroupConnectionSettings,
2453 DirectPlay3AImpl_StartSession,
2454 DirectPlay3AImpl_GetGroupFlags,
2455 DirectPlay3AImpl_GetGroupParent,
2456 DirectPlay3AImpl_GetPlayerAccount,
2457 DirectPlay3AImpl_GetPlayerFlags
2459 #undef XCAST
2461 /* Note: Hack so we can reuse the old functions without compiler warnings */
2462 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
2463 # define XCAST(fun) (typeof(directPlay3WVT.fn##fun))
2464 #else
2465 # define XCAST(fun) (void*)
2466 #endif
2467 static ICOM_VTABLE(IDirectPlay3) directPlay3WVT =
2469 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2470 DirectPlay3WImpl_QueryInterface,
2471 XCAST(AddRef)DirectPlay2AImpl_AddRef,
2472 XCAST(Release)DirectPlay2AImpl_Release,
2474 XCAST(AddPlayerToGroup)DirectPlay2WImpl_AddPlayerToGroup,
2475 XCAST(Close)DirectPlay2WImpl_Close,
2476 XCAST(CreateGroup)DirectPlay2WImpl_CreateGroup,
2477 XCAST(CreatePlayer)DirectPlay2WImpl_CreatePlayer,
2478 XCAST(DeletePlayerFromGroup)DirectPlay2WImpl_DeletePlayerFromGroup,
2479 XCAST(DestroyGroup)DirectPlay2WImpl_DestroyGroup,
2480 XCAST(DestroyPlayer)DirectPlay2WImpl_DestroyPlayer,
2481 XCAST(EnumGroupPlayers)DirectPlay2WImpl_EnumGroupPlayers,
2482 XCAST(EnumGroups)DirectPlay2WImpl_EnumGroups,
2483 XCAST(EnumPlayers)DirectPlay2WImpl_EnumPlayers,
2484 XCAST(EnumSessions)DirectPlay2WImpl_EnumSessions,
2485 XCAST(GetCaps)DirectPlay2WImpl_GetCaps,
2486 XCAST(GetGroupData)DirectPlay2WImpl_GetGroupData,
2487 XCAST(GetGroupName)DirectPlay2WImpl_GetGroupName,
2488 XCAST(GetMessageCount)DirectPlay2WImpl_GetMessageCount,
2489 XCAST(GetPlayerAddress)DirectPlay2WImpl_GetPlayerAddress,
2490 XCAST(GetPlayerCaps)DirectPlay2WImpl_GetPlayerCaps,
2491 XCAST(GetPlayerData)DirectPlay2WImpl_GetPlayerData,
2492 XCAST(GetPlayerName)DirectPlay2WImpl_GetPlayerName,
2493 XCAST(GetSessionDesc)DirectPlay2WImpl_GetSessionDesc,
2494 XCAST(Initialize)DirectPlay2WImpl_Initialize,
2495 XCAST(Open)DirectPlay2WImpl_Open,
2496 XCAST(Receive)DirectPlay2WImpl_Receive,
2497 XCAST(Send)DirectPlay2WImpl_Send,
2498 XCAST(SetGroupData)DirectPlay2WImpl_SetGroupData,
2499 XCAST(SetGroupName)DirectPlay2WImpl_SetGroupName,
2500 XCAST(SetPlayerData)DirectPlay2WImpl_SetPlayerData,
2501 XCAST(SetPlayerName)DirectPlay2WImpl_SetPlayerName,
2502 XCAST(SetSessionDesc)DirectPlay2WImpl_SetSessionDesc,
2504 DirectPlay3WImpl_AddGroupToGroup,
2505 DirectPlay3WImpl_CreateGroupInGroup,
2506 DirectPlay3WImpl_DeleteGroupFromGroup,
2507 DirectPlay3WImpl_EnumConnections,
2508 DirectPlay3WImpl_EnumGroupsInGroup,
2509 DirectPlay3WImpl_GetGroupConnectionSettings,
2510 DirectPlay3WImpl_InitializeConnection,
2511 DirectPlay3WImpl_SecureOpen,
2512 DirectPlay3WImpl_SendChatMessage,
2513 DirectPlay3WImpl_SetGroupConnectionSettings,
2514 DirectPlay3WImpl_StartSession,
2515 DirectPlay3WImpl_GetGroupFlags,
2516 DirectPlay3WImpl_GetGroupParent,
2517 DirectPlay3WImpl_GetPlayerAccount,
2518 DirectPlay3WImpl_GetPlayerFlags
2520 #undef XCAST
2522 /* Note: Hack so we can reuse the old functions without compiler warnings */
2523 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
2524 # define XCAST(fun) (typeof(directPlay4WVT.fn##fun))
2525 #else
2526 # define XCAST(fun) (void*)
2527 #endif
2528 static ICOM_VTABLE(IDirectPlay4) directPlay4WVT =
2530 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2531 DirectPlay4WImpl_QueryInterface,
2532 XCAST(AddRef)DirectPlay2AImpl_AddRef,
2533 XCAST(Release)DirectPlay2AImpl_Release,
2535 XCAST(AddPlayerToGroup)DirectPlay2WImpl_AddPlayerToGroup,
2536 XCAST(Close)DirectPlay2WImpl_Close,
2537 XCAST(CreateGroup)DirectPlay2WImpl_CreateGroup,
2538 XCAST(CreatePlayer)DirectPlay2WImpl_CreatePlayer,
2539 XCAST(DeletePlayerFromGroup)DirectPlay2WImpl_DeletePlayerFromGroup,
2540 XCAST(DestroyGroup)DirectPlay2WImpl_DestroyGroup,
2541 XCAST(DestroyPlayer)DirectPlay2WImpl_DestroyPlayer,
2542 XCAST(EnumGroupPlayers)DirectPlay2WImpl_EnumGroupPlayers,
2543 XCAST(EnumGroups)DirectPlay2WImpl_EnumGroups,
2544 XCAST(EnumPlayers)DirectPlay2WImpl_EnumPlayers,
2545 XCAST(EnumSessions)DirectPlay2WImpl_EnumSessions,
2546 XCAST(GetCaps)DirectPlay2WImpl_GetCaps,
2547 XCAST(GetGroupData)DirectPlay2WImpl_GetGroupData,
2548 XCAST(GetGroupName)DirectPlay2WImpl_GetGroupName,
2549 XCAST(GetMessageCount)DirectPlay2WImpl_GetMessageCount,
2550 XCAST(GetPlayerAddress)DirectPlay2WImpl_GetPlayerAddress,
2551 XCAST(GetPlayerCaps)DirectPlay2WImpl_GetPlayerCaps,
2552 XCAST(GetPlayerData)DirectPlay2WImpl_GetPlayerData,
2553 XCAST(GetPlayerName)DirectPlay2WImpl_GetPlayerName,
2554 XCAST(GetSessionDesc)DirectPlay2WImpl_GetSessionDesc,
2555 XCAST(Initialize)DirectPlay2WImpl_Initialize,
2556 XCAST(Open)DirectPlay2WImpl_Open,
2557 XCAST(Receive)DirectPlay2WImpl_Receive,
2558 XCAST(Send)DirectPlay2WImpl_Send,
2559 XCAST(SetGroupData)DirectPlay2WImpl_SetGroupData,
2560 XCAST(SetGroupName)DirectPlay2WImpl_SetGroupName,
2561 XCAST(SetPlayerData)DirectPlay2WImpl_SetPlayerData,
2562 XCAST(SetPlayerName)DirectPlay2WImpl_SetPlayerName,
2563 XCAST(SetSessionDesc)DirectPlay2WImpl_SetSessionDesc,
2565 XCAST(AddGroupToGroup)DirectPlay3WImpl_AddGroupToGroup,
2566 XCAST(CreateGroupInGroup)DirectPlay3WImpl_CreateGroupInGroup,
2567 XCAST(DeleteGroupFromGroup)DirectPlay3WImpl_DeleteGroupFromGroup,
2568 XCAST(EnumConnections)DirectPlay3WImpl_EnumConnections,
2569 XCAST(EnumGroupsInGroup)DirectPlay3WImpl_EnumGroupsInGroup,
2570 XCAST(GetGroupConnectionSettings)DirectPlay3WImpl_GetGroupConnectionSettings,
2571 XCAST(InitializeConnection)DirectPlay3WImpl_InitializeConnection,
2572 XCAST(SecureOpen)DirectPlay3WImpl_SecureOpen,
2573 XCAST(SendChatMessage)DirectPlay3WImpl_SendChatMessage,
2574 XCAST(SetGroupConnectionSettings)DirectPlay3WImpl_SetGroupConnectionSettings,
2575 XCAST(StartSession)DirectPlay3WImpl_StartSession,
2576 XCAST(GetGroupFlags)DirectPlay3WImpl_GetGroupFlags,
2577 XCAST(GetGroupParent)DirectPlay3WImpl_GetGroupParent,
2578 XCAST(GetPlayerAccount)DirectPlay3WImpl_GetPlayerAccount,
2579 XCAST(GetPlayerFlags)DirectPlay3WImpl_GetPlayerFlags,
2581 DirectPlay4WImpl_GetGroupOwner,
2582 DirectPlay4WImpl_SetGroupOwner,
2583 DirectPlay4WImpl_SendEx,
2584 DirectPlay4WImpl_GetMessageQueue,
2585 DirectPlay4WImpl_CancelMessage,
2586 DirectPlay4WImpl_CancelPriority
2588 #undef XCAST
2591 /* Note: Hack so we can reuse the old functions without compiler warnings */
2592 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
2593 # define XCAST(fun) (typeof(directPlay4AVT.fn##fun))
2594 #else
2595 # define XCAST(fun) (void*)
2596 #endif
2597 static ICOM_VTABLE(IDirectPlay4) directPlay4AVT =
2599 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2600 DirectPlay4AImpl_QueryInterface,
2601 XCAST(AddRef)DirectPlay2AImpl_AddRef,
2602 XCAST(Release)DirectPlay2AImpl_Release,
2604 XCAST(AddPlayerToGroup)DirectPlay2AImpl_AddPlayerToGroup,
2605 XCAST(Close)DirectPlay2AImpl_Close,
2606 XCAST(CreateGroup)DirectPlay2AImpl_CreateGroup,
2607 XCAST(CreatePlayer)DirectPlay2AImpl_CreatePlayer,
2608 XCAST(DeletePlayerFromGroup)DirectPlay2AImpl_DeletePlayerFromGroup,
2609 XCAST(DestroyGroup)DirectPlay2AImpl_DestroyGroup,
2610 XCAST(DestroyPlayer)DirectPlay2AImpl_DestroyPlayer,
2611 XCAST(EnumGroupPlayers)DirectPlay2AImpl_EnumGroupPlayers,
2612 XCAST(EnumGroups)DirectPlay2AImpl_EnumGroups,
2613 XCAST(EnumPlayers)DirectPlay2AImpl_EnumPlayers,
2614 XCAST(EnumSessions)DirectPlay2AImpl_EnumSessions,
2615 XCAST(GetCaps)DirectPlay2AImpl_GetCaps,
2616 XCAST(GetGroupData)DirectPlay2AImpl_GetGroupData,
2617 XCAST(GetGroupName)DirectPlay2AImpl_GetGroupName,
2618 XCAST(GetMessageCount)DirectPlay2AImpl_GetMessageCount,
2619 XCAST(GetPlayerAddress)DirectPlay2AImpl_GetPlayerAddress,
2620 XCAST(GetPlayerCaps)DirectPlay2AImpl_GetPlayerCaps,
2621 XCAST(GetPlayerData)DirectPlay2AImpl_GetPlayerData,
2622 XCAST(GetPlayerName)DirectPlay2AImpl_GetPlayerName,
2623 XCAST(GetSessionDesc)DirectPlay2AImpl_GetSessionDesc,
2624 XCAST(Initialize)DirectPlay2AImpl_Initialize,
2625 XCAST(Open)DirectPlay2AImpl_Open,
2626 XCAST(Receive)DirectPlay2AImpl_Receive,
2627 XCAST(Send)DirectPlay2AImpl_Send,
2628 XCAST(SetGroupData)DirectPlay2AImpl_SetGroupData,
2629 XCAST(SetGroupName)DirectPlay2AImpl_SetGroupName,
2630 XCAST(SetPlayerData)DirectPlay2AImpl_SetPlayerData,
2631 XCAST(SetPlayerName)DirectPlay2AImpl_SetPlayerName,
2632 XCAST(SetSessionDesc)DirectPlay2AImpl_SetSessionDesc,
2634 XCAST(AddGroupToGroup)DirectPlay3AImpl_AddGroupToGroup,
2635 XCAST(CreateGroupInGroup)DirectPlay3AImpl_CreateGroupInGroup,
2636 XCAST(DeleteGroupFromGroup)DirectPlay3AImpl_DeleteGroupFromGroup,
2637 XCAST(EnumConnections)DirectPlay3AImpl_EnumConnections,
2638 XCAST(EnumGroupsInGroup)DirectPlay3AImpl_EnumGroupsInGroup,
2639 XCAST(GetGroupConnectionSettings)DirectPlay3AImpl_GetGroupConnectionSettings,
2640 XCAST(InitializeConnection)DirectPlay3AImpl_InitializeConnection,
2641 XCAST(SecureOpen)DirectPlay3AImpl_SecureOpen,
2642 XCAST(SendChatMessage)DirectPlay3AImpl_SendChatMessage,
2643 XCAST(SetGroupConnectionSettings)DirectPlay3AImpl_SetGroupConnectionSettings,
2644 XCAST(StartSession)DirectPlay3AImpl_StartSession,
2645 XCAST(GetGroupFlags)DirectPlay3AImpl_GetGroupFlags,
2646 XCAST(GetGroupParent)DirectPlay3AImpl_GetGroupParent,
2647 XCAST(GetPlayerAccount)DirectPlay3AImpl_GetPlayerAccount,
2648 XCAST(GetPlayerFlags)DirectPlay3AImpl_GetPlayerFlags,
2650 DirectPlay4AImpl_GetGroupOwner,
2651 DirectPlay4AImpl_SetGroupOwner,
2652 DirectPlay4AImpl_SendEx,
2653 DirectPlay4AImpl_GetMessageQueue,
2654 DirectPlay4AImpl_CancelMessage,
2655 DirectPlay4AImpl_CancelPriority
2657 #undef XCAST
2660 /***************************************************************************
2661 * DirectPlayEnumerateA (DPLAYX.2)
2663 * The pointer to the structure lpContext will be filled with the
2664 * appropriate data for each service offered by the OS. These services are
2665 * not necessarily available on this particular machine but are defined
2666 * as simple service providers under the "Service Providers" registry key.
2667 * This structure is then passed to lpEnumCallback for each of the different
2668 * services.
2670 * This API is useful only for applications written using DirectX3 or
2671 * worse. It is superceeded by IDirectPlay3::EnumConnections which also
2672 * gives information on the actual connections.
2674 * defn of a service provider:
2675 * A dynamic-link library used by DirectPlay to communicate over a network.
2676 * The service provider contains all the network-specific code required
2677 * to send and receive messages. Online services and network operators can
2678 * supply service providers to use specialized hardware, protocols, communications
2679 * media, and network resources.
2681 * TODO: Allocate string buffer space from the heap (length from reg)
2682 * Pass real device driver numbers...
2683 * Get the GUID properly...
2685 HRESULT WINAPI DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback,
2686 LPVOID lpContext )
2689 HKEY hkResult;
2690 LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
2691 DWORD dwIndex;
2692 DWORD sizeOfSubKeyName=50;
2693 char subKeyName[51];
2694 FILETIME filetime;
2696 TRACE(": lpEnumCallback=%p lpContext=%p\n", lpEnumCallback, lpContext );
2698 if( !lpEnumCallback || !*lpEnumCallback )
2700 return DPERR_INVALIDPARAMS;
2703 /* Need to loop over the service providers in the registry */
2704 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
2705 0, KEY_READ, &hkResult ) != ERROR_SUCCESS )
2707 /* Hmmm. Does this mean that there are no service providers? */
2708 ERR(": no service providers?\n");
2709 return DP_OK;
2712 /* Traverse all the service providers we have available */
2713 for( dwIndex=0;
2714 RegEnumKeyExA( hkResult, dwIndex, subKeyName, &sizeOfSubKeyName,
2715 NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS;
2716 ++dwIndex, sizeOfSubKeyName=50 )
2718 LPSTR majVerDataSubKey = "dwReserved1";
2719 LPSTR minVerDataSubKey = "dwReserved2";
2720 LPSTR guidDataSubKey = "Guid";
2721 HKEY hkServiceProvider;
2722 GUID serviceProviderGUID;
2723 DWORD returnTypeGUID, returnTypeReserved, sizeOfReturnBuffer = 50;
2724 char returnBuffer[51];
2725 DWORD majVersionNum , minVersionNum = 0;
2726 LPWSTR lpWGUIDString;
2728 TRACE(" this time through: %s\n", subKeyName );
2730 /* Get a handle for this particular service provider */
2731 if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_READ,
2732 &hkServiceProvider ) != ERROR_SUCCESS )
2734 ERR(": what the heck is going on?\n" );
2735 continue;
2738 /* Get the GUID, Device major number and device minor number
2739 * from the registry.
2741 if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
2742 NULL, &returnTypeGUID, returnBuffer,
2743 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
2745 ERR(": missing GUID registry data members\n" );
2746 continue;
2749 /* FIXME: Check return types to ensure we're interpreting data right */
2750 lpWGUIDString = HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer );
2751 CLSIDFromString( (LPCOLESTR)lpWGUIDString, &serviceProviderGUID );
2752 HeapFree( GetProcessHeap(), 0, lpWGUIDString );
2754 /* FIXME: Need to know which of dwReserved1 and dwReserved2 are maj and min */
2756 sizeOfReturnBuffer = 50;
2757 if( RegQueryValueExA( hkServiceProvider, majVerDataSubKey,
2758 NULL, &returnTypeReserved, returnBuffer,
2759 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
2761 ERR(": missing dwReserved1 registry data members\n") ;
2762 continue;
2765 majVersionNum = GET_DWORD( returnBuffer );
2767 sizeOfReturnBuffer = 50;
2768 if( RegQueryValueExA( hkServiceProvider, minVerDataSubKey,
2769 NULL, &returnTypeReserved, returnBuffer,
2770 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
2772 ERR(": missing dwReserved2 registry data members\n") ;
2773 continue;
2776 minVersionNum = GET_DWORD( returnBuffer );
2779 /* The enumeration will return FALSE if we are not to continue */
2780 if( !lpEnumCallback( &serviceProviderGUID , subKeyName,
2781 majVersionNum, minVersionNum, lpContext ) )
2783 WARN("lpEnumCallback returning FALSE\n" );
2784 break;
2788 return DP_OK;
2792 /***************************************************************************
2793 * DirectPlayEnumerateW (DPLAYX.3)
2796 HRESULT WINAPI DirectPlayEnumerateW( LPDPENUMDPCALLBACKW lpEnumCallback, LPVOID lpContext )
2799 FIXME(":stub\n");
2801 return DPERR_OUTOFMEMORY;
2805 /***************************************************************************
2806 * DirectPlayCreate (DPLAYX.1) (DPLAY.1)
2809 HRESULT WINAPI DirectPlayCreate
2810 ( LPGUID lpGUID, LPDIRECTPLAY2 *lplpDP, IUnknown *pUnk)
2812 TRACE( "lpGUID=%s lplpDP=%p pUnk=%p\n", debugstr_guid(lpGUID), lplpDP, pUnk );
2814 if( pUnk != NULL )
2816 return CLASS_E_NOAGGREGATION;
2820 /* Create an IDirectPlay object. We don't support that so we'll cheat and
2821 give them an IDirectPlay2A object and hope that doesn't cause problems */
2822 if( directPlay_QueryInterface( &IID_IDirectPlay2A, (LPVOID*)lplpDP ) != DP_OK )
2824 return DPERR_UNAVAILABLE;
2827 if( IsEqualGUID( &GUID_NULL, lpGUID ) )
2829 /* The GUID_NULL means don't bind a service provider. Just return the
2830 interface */
2831 return DP_OK;
2835 /* Bind the desired service provider */
2836 if( ( IsEqualGUID( lpGUID, &DPSPGUID_MODEM ) ) ||
2837 ( IsEqualGUID( lpGUID, &DPSPGUID_SERIAL ) ) ||
2838 ( IsEqualGUID( lpGUID, &DPSPGUID_TCPIP ) ) ||
2839 ( IsEqualGUID( lpGUID, &DPSPGUID_IPX ) )
2842 FIXME( "Service provider binding not supported yet\n" );
2843 IDirectPlayX_Release( *lplpDP );
2844 *lplpDP = NULL;
2845 return DPERR_INVALIDPARAMS;
2848 ERR( "unknown Service Provider %s\n", debugstr_guid(lpGUID) );
2850 IDirectPlayX_Release( *lplpDP );
2851 *lplpDP = NULL;
2853 return DPERR_INVALIDPARAMS;