1 /* Direct Play 3 and Direct Play Lobby 2 Implementation
3 * Copyright 1998 - Peter Hunnisett
5 * <presently under construction - contact hunnise@nortel.ca>
8 #include "interfaces.h"
18 #include <sys/queue.h>
20 #define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
21 #define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2)
22 #define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2)
24 struct IDirectPlayLobby
{
25 LPDIRECTPLAYLOBBY_VTABLE lpVtbl
;
27 LPDPLCONNECTION lpSession
;
30 struct IDirectPlayLobby2
{
31 LPDIRECTPLAYLOBBY2_VTABLE lpVtbl
;
33 LPDPLCONNECTION lpSession
;
37 /* Forward declarations of virtual tables */
38 static DIRECTPLAYLOBBY_VTABLE directPlayLobbyAVT
;
39 static DIRECTPLAYLOBBY_VTABLE directPlayLobbyWVT
;
40 static DIRECTPLAYLOBBY2_VTABLE directPlayLobby2AVT
;
41 static DIRECTPLAYLOBBY2_VTABLE directPlayLobby2WVT
;
44 LPDIRECTPLAY2_VTABLE lpVtbl
;
49 LPDIRECTPLAY3_VTABLE lpVtbl
;
54 static DIRECTPLAY2_VTABLE directPlay2AVT
;
55 static DIRECTPLAY2_VTABLE directPlay2WVT
;
56 static DIRECTPLAY3_VTABLE directPlay3AVT
;
57 static DIRECTPLAY3_VTABLE directPlay3WVT
;
59 /* Routine to delete the entire DPLCONNECTION tree. Works for both unicode and ascii. */
60 void deleteDPConnection( LPDPLCONNECTION
* ptrToDelete
)
63 /* This is most definitely wrong. We're not even keeping dwCurrentPlayers over this */
64 LPDPLCONNECTION toDelete
= *ptrToDelete
;
66 FIXME( dplay
, "incomplete.\n" );
71 /* Clear out DPSESSIONDESC2 */
72 if( toDelete
->lpSessionDesc
)
74 if( toDelete
->lpSessionDesc
->sess
.lpszSessionName
)
75 HeapFree( GetProcessHeap(), 0, toDelete
->lpSessionDesc
->sess
.lpszSessionName
);
77 if( toDelete
->lpSessionDesc
->pass
.lpszPassword
)
78 HeapFree( GetProcessHeap(), 0, toDelete
->lpSessionDesc
->pass
.lpszPassword
);
80 if( toDelete
->lpSessionDesc
);
81 HeapFree( GetProcessHeap(), 0, toDelete
->lpSessionDesc
);
84 /* Clear out LPDPNAME */
85 if( toDelete
->lpPlayerName
)
87 if( toDelete
->lpPlayerName
->psn
.lpszShortName
)
88 HeapFree( GetProcessHeap(), 0, toDelete
->lpPlayerName
->psn
.lpszShortName
);
90 if( toDelete
->lpPlayerName
->pln
.lpszLongName
)
91 HeapFree( GetProcessHeap(), 0, toDelete
->lpPlayerName
->pln
.lpszLongName
);
93 if( toDelete
->lpPlayerName
)
94 HeapFree( GetProcessHeap(), 0, toDelete
->lpPlayerName
);
97 /* Clear out lpAddress. TO DO...Once we actually copy it. */
99 /* Clear out DPLCONNECTION */
100 HeapFree( GetProcessHeap(), 0, toDelete
);
107 /* Routine which copies and allocates all the store required for the DPLCONNECTION struct. */
108 void rebuildDPConnectionW( LPDPLCONNECTION dest
, LPDPLCONNECTION src
)
111 /* Need to delete everything that already exists first */
112 FIXME( dplay
, "function is incomplete.\n" );
116 /* Nothing to copy...hmmm...*/
117 ERR( dplay
, "nothing to copy\n" );
121 /* Copy DPLCONNECTION struct. If dest isn't NULL then we have a DPLCONNECTION
126 dest
= HeapAlloc( GetProcessHeap(), 0, sizeof( *src
) );
128 memcpy( dest
, src
, sizeof( *src
) );
130 /* Copy LPDPSESSIONDESC2 struct */
131 if( src
->lpSessionDesc
)
133 dest
->lpSessionDesc
= HeapAlloc( GetProcessHeap(), 0,
134 sizeof( *(src
->lpSessionDesc
) ) );
136 memcpy( dest
->lpSessionDesc
, src
->lpSessionDesc
,
137 sizeof( *(src
->lpSessionDesc
) ) );
139 if( src
->lpSessionDesc
)
141 /* Hmmm...do we have to assume the system heap? */
142 dest
->lpSessionDesc
->sess
.lpszSessionName
= HEAP_strdupW( GetProcessHeap(), 0,
143 src
->lpSessionDesc
->sess
.lpszSessionName
);
146 if( src
->lpSessionDesc
->pass
.lpszPassword
)
148 dest
->lpSessionDesc
->pass
.lpszPassword
= HEAP_strdupW( GetProcessHeap(), 0,
149 src
->lpSessionDesc
->pass
.lpszPassword
);
151 dest
->lpSessionDesc
->dwReserved1
= src
->lpSessionDesc
->dwReserved2
= 0;
154 /* Copy DPNAME struct */
155 if( src
->lpPlayerName
)
157 dest
->lpPlayerName
= HeapAlloc( GetProcessHeap(), 0, sizeof( *(src
->lpPlayerName
) ) );
158 memcpy( dest
->lpPlayerName
, src
->lpPlayerName
, sizeof( *(src
->lpPlayerName
) ) );
160 if( src
->lpPlayerName
->psn
.lpszShortName
)
162 dest
->lpPlayerName
->psn
.lpszShortName
= HEAP_strdupW( GetProcessHeap(), 0,
163 src
->lpPlayerName
->psn
.lpszShortName
);
166 if( src
->lpPlayerName
->pln
.lpszLongName
)
168 dest
->lpPlayerName
->pln
.lpszLongName
= HEAP_strdupW( GetProcessHeap(), 0,
169 src
->lpPlayerName
->pln
.lpszLongName
);
173 /* Copy Address of Service Provider -TBD */
176 /* What do we do here? */
183 /* Routine called when starting up the server thread */
184 DWORD
DPLobby_Spawn_Server( LPVOID startData
)
186 DPSESSIONDESC2
* lpSession
= (DPSESSIONDESC2
*) startData
;
187 DWORD sessionDwFlags
= lpSession
->dwFlags
;
189 TRACE( dplay
, "spawing thread for lpConn=%p dwFlags=%08lx\n", lpSession
, sessionDwFlags
);
190 FIXME( dplay
, "thread needs something to do\n" );
195 /* Check out the connection flags to determine what to do. Ensure we have
196 no leftover bits in this structure */
197 if( sessionDwFlags
& DPSESSION_CLIENTSERVER
)
199 /* This indicates that the application which is requesting the creation
200 * of this session is going to be the server (application/player)
202 if( sessionDwFlags
& DPSESSION_SECURESERVER
)
204 sessionDwFlags
&= ~DPSESSION_SECURESERVER
;
206 sessionDwFlags
&= ~DPSESSION_CLIENTSERVER
;
209 if( sessionDwFlags
& DPSESSION_JOINDISABLED
)
211 sessionDwFlags
&= ~DPSESSION_JOINDISABLED
;
214 if( sessionDwFlags
& DPSESSION_KEEPALIVE
)
216 sessionDwFlags
&= ~DPSESSION_KEEPALIVE
;
219 if( sessionDwFlags
& DPSESSION_MIGRATEHOST
)
221 sessionDwFlags
&= ~DPSESSION_MIGRATEHOST
;
224 if( sessionDwFlags
& DPSESSION_MULTICASTSERVER
)
226 sessionDwFlags
&= ~DPSESSION_MULTICASTSERVER
;
229 if( sessionDwFlags
& DPSESSION_NEWPLAYERSDISABLED
)
231 sessionDwFlags
&= ~DPSESSION_NEWPLAYERSDISABLED
;
234 if( sessionDwFlags
& DPSESSION_NODATAMESSAGES
)
236 sessionDwFlags
&= ~DPSESSION_NODATAMESSAGES
;
239 if( sessionDwFlags
& DPSESSION_NOMESSAGEID
)
241 sessionDwFlags
&= ~DPSESSION_NOMESSAGEID
;
244 if( sessionDwFlags
& DPSESSION_PASSWORDREQUIRED
)
246 sessionDwFlags
&= ~DPSESSION_PASSWORDREQUIRED
;
256 /*********************************************************
258 * Direct Play and Direct Play Lobby Interface Implementation
260 *********************************************************/
262 /* The COM interface for upversioning an interface
263 * We've been given a GUID (riid) and we need to replace the present
264 * interface with that of the requested interface.
266 * Snip from some Microsoft document:
267 * There are four requirements for implementations of QueryInterface (In these
268 * cases, "must succeed" means "must succeed barring catastrophic failure."):
270 * * The set of interfaces accessible on an object through
271 * IUnknown::QueryInterface must be static, not dynamic. This means that
272 * if a call to QueryInterface for a pointer to a specified interface
273 * succeeds the first time, it must succeed again, and if it fails the
274 * first time, it must fail on all subsequent queries.
275 * * It must be symmetric ~W if a client holds a pointer to an interface on
276 * an object, and queries for that interface, the call must succeed.
277 * * It must be reflexive ~W if a client holding a pointer to one interface
278 * queries successfully for another, a query through the obtained pointer
279 * for the first interface must succeed.
280 * * It must be transitive ~W if a client holding a pointer to one interface
281 * queries successfully for a second, and through that pointer queries
282 * successfully for a third interface, a query for the first interface
283 * through the pointer for the third interface must succeed.
285 * As you can see, this interface doesn't qualify but will most likely
286 * be good enough for the time being.
288 static HRESULT WINAPI IDirectPlayLobbyA_QueryInterface
289 ( LPDIRECTPLAYLOBBYA
this,
293 return DPERR_OUTOFMEMORY
;
296 static HRESULT WINAPI IDirectPlayLobbyW_QueryInterface
297 ( LPDIRECTPLAYLOBBY
this,
301 return DPERR_OUTOFMEMORY
;
304 static HRESULT WINAPI IDirectPlayLobby2A_QueryInterface
305 ( LPDIRECTPLAYLOBBY2A
this,
309 /* Compare riids. We know this object is a direct play lobby 2A object.
310 If we are asking about the same type of interface we're fine.
312 if( IsEqualGUID( &IID_IUnknown
, riid
) ||
313 IsEqualGUID( &IID_IDirectPlayLobby2A
, riid
)
316 this->lpVtbl
->fnAddRef( this );
320 /* They're requesting a unicode version of the interface */
321 else if( IsEqualGUID( &IID_IDirectPlayLobby2
, riid
) )
323 LPDIRECTPLAYLOBBY2 lpDpL
= (LPDIRECTPLAYLOBBY2
)(*ppvObj
);
325 lpDpL
= (LPDIRECTPLAYLOBBY2
)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
326 sizeof( IDirectPlayLobby2
) );
330 return E_NOINTERFACE
;
333 lpDpL
->lpVtbl
= &directPlayLobby2WVT
;
339 /* Unexpected interface request! */
341 return E_NOINTERFACE
;
344 static HRESULT WINAPI IDirectPlayLobby2W_QueryInterface
345 ( LPDIRECTPLAYLOBBY2
this,
350 /* Compare riids. We know this object is a direct play lobby 2 object.
351 If we are asking about the same type of interface we're fine.
353 if( IsEqualGUID( &IID_IUnknown
, riid
) ||
354 IsEqualGUID( &IID_IDirectPlayLobby2
, riid
)
357 this->lpVtbl
->fnAddRef( this );
361 else if( IsEqualGUID( &IID_IDirectPlayLobby2A
, riid
) )
363 LPDIRECTPLAYLOBBY2A lpDpL
= (LPDIRECTPLAYLOBBY2A
)(*ppvObj
);
365 lpDpL
= (LPDIRECTPLAYLOBBY2A
)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
366 sizeof( IDirectPlayLobby2A
) );
370 return E_NOINTERFACE
;
373 lpDpL
->lpVtbl
= &directPlayLobby2AVT
;
379 /* Unexpected interface request! */
381 return E_NOINTERFACE
;
386 * Simple procedure. Just increment the reference count to this
387 * structure and return the new reference count.
389 static ULONG WINAPI IDirectPlayLobbyA_AddRef
390 ( LPDIRECTPLAYLOBBYA
this )
393 TRACE( dplay
,"ref count now %lu\n", this->ref
);
396 static ULONG WINAPI IDirectPlayLobbyW_AddRef
397 ( LPDIRECTPLAYLOBBY
this )
399 return IDirectPlayLobbyA_AddRef( (LPDIRECTPLAYLOBBY
) this );
402 static ULONG WINAPI IDirectPlayLobby2A_AddRef
403 ( LPDIRECTPLAYLOBBY2A
this )
405 return IDirectPlayLobbyA_AddRef( (LPDIRECTPLAYLOBBY
) this );
408 static ULONG WINAPI IDirectPlayLobby2W_AddRef
409 ( LPDIRECTPLAYLOBBY2
this )
411 return IDirectPlayLobbyA_AddRef( (LPDIRECTPLAYLOBBY
) this );
416 * Simple COM procedure. Decrease the reference count to this object.
417 * If the object no longer has any reference counts, free up the associated
420 static ULONG WINAPI IDirectPlayLobbyA_Release
421 ( LPDIRECTPLAYLOBBYA
this )
423 TRACE( dplay
, "ref count decremeneted from %lu\n", this->ref
);
427 /* Deallocate if this is the last reference to the object */
430 deleteDPConnection( this->lpSession
);
431 HeapFree( GetProcessHeap(), 0, this );
438 static ULONG WINAPI IDirectPlayLobbyW_Release
439 ( LPDIRECTPLAYLOBBY
this )
441 return IDirectPlayLobbyA_Release( (LPDIRECTPLAYLOBBYA
) this );
443 static ULONG WINAPI IDirectPlayLobby2A_Release
444 ( LPDIRECTPLAYLOBBY2A
this )
446 return IDirectPlayLobbyA_Release( (LPDIRECTPLAYLOBBYA
) this );
449 static ULONG WINAPI IDirectPlayLobby2W_Release
450 ( LPDIRECTPLAYLOBBY2
this )
452 return IDirectPlayLobbyA_Release( (LPDIRECTPLAYLOBBYA
) this );
456 /********************************************************************
458 * Connects an application to the session specified by the DPLCONNECTION
459 * structure currently stored with the DirectPlayLobby object.
461 * Returns a IDirectPlay interface.
464 static HRESULT WINAPI IDirectPlayLobbyA_Connect
465 ( LPDIRECTPLAYLOBBYA
this,
467 LPDIRECTPLAY
* lplpDP
,
470 FIXME( dplay
, ": dwFlags=%08lx %p %p stub\n", dwFlags
, lplpDP
, pUnk
);
471 return DPERR_OUTOFMEMORY
;
474 static HRESULT WINAPI IDirectPlayLobby2A_Connect
475 ( LPDIRECTPLAYLOBBY2A
this,
477 LPDIRECTPLAY
* lplpDP
,
480 return IDirectPlayLobbyA_Connect( (LPDIRECTPLAYLOBBYA
)this, dwFlags
, lplpDP
, pUnk
);
483 static HRESULT WINAPI IDirectPlayLobbyW_Connect
484 ( LPDIRECTPLAYLOBBY
this,
486 LPDIRECTPLAY
* lplpDP
,
489 LPDIRECTPLAY2A directPlay2A
;
490 LPDIRECTPLAY2 directPlay2W
;
493 FIXME( dplay
, ": dwFlags=%08lx %p %p stub\n", dwFlags
, lplpDP
, pUnk
);
497 /* See dpbuild_4301.txt */
498 /* Create the direct play 2 W interface */
499 if( ( ( createRC
= DirectPlayCreate( NULL
, &directPlay2A
, pUnk
) ) != DP_OK
) ||
500 ( ( createRC
= directPlay2A
->lpVtbl
->fnQueryInterface
501 ( directPlay2A
, IID_IDirectPlay2
, &directPlay2W
) ) != DP_OK
)
504 ERR( dplay
, "error creating Direct Play 2 (W) interface. Return Code = %d.\n", createRC
);
508 /* All the stuff below this is WRONG! */
509 if( this->lpSession
->dwFlags
== DPLCONNECTION_CREATESESSION
)
513 /* Spawn a thread to deal with all of this and to handle the incomming requests */
514 threadIdSink
= CreateThread( NULL
, 0, &DPLobby_Spawn_Server
,
515 (LPVOID
)this->lpSession
->lpConn
->lpSessionDesc
, 0, &threadIdSink
);
518 else if ( this->lpSession
->dwFlags
== DPLCONNECTION_JOINSESSION
)
520 /* Let's search for a matching session */
521 FIXME( dplay
, "joining session not yet supported.\n");
522 return DPERR_OUTOFMEMORY
;
524 else /* Unknown type of connection request */
526 ERR( dplay
, ": Unknown connection request lpConn->dwFlags=%08lx\n",
529 return DPERR_OUTOFMEMORY
;
532 /* This does the work of the following methods...
533 IDirectPlay3::InitializeConnection,
534 IDirectPlay3::EnumSessions,
545 static HRESULT WINAPI IDirectPlayLobby2W_Connect
546 ( LPDIRECTPLAYLOBBY2
this,
548 LPDIRECTPLAY
* lplpDP
,
551 return IDirectPlayLobbyW_Connect( (LPDIRECTPLAYLOBBY
)this, dwFlags
, lplpDP
, pUnk
);
554 /********************************************************************
556 * Creates a DirectPlay Address, given a service provider-specific network
558 * Returns an address contains the globally unique identifier
559 * (GUID) of the service provider and data that the service provider can
560 * interpret as a network address.
563 static HRESULT WINAPI IDirectPlayLobbyA_CreateAddress
564 ( LPDIRECTPLAYLOBBY
this,
566 REFGUID guidDataType
,
570 LPDWORD lpdwAddressSize
)
572 FIXME( dplay
, ":stub\n");
573 return DPERR_OUTOFMEMORY
;
576 static HRESULT WINAPI IDirectPlayLobby2A_CreateAddress
577 ( LPDIRECTPLAYLOBBY2A
this,
579 REFGUID guidDataType
,
583 LPDWORD lpdwAddressSize
)
585 return IDirectPlayLobbyA_CreateAddress( (LPDIRECTPLAYLOBBY
)this, guidSP
, guidDataType
,
586 lpData
, dwDataSize
, lpAddress
, lpdwAddressSize
);
589 static HRESULT WINAPI IDirectPlayLobbyW_CreateAddress
590 ( LPDIRECTPLAYLOBBY
this,
592 REFGUID guidDataType
,
596 LPDWORD lpdwAddressSize
)
598 FIXME( dplay
, ":stub\n");
599 return DPERR_OUTOFMEMORY
;
603 static HRESULT WINAPI IDirectPlayLobby2W_CreateAddress
604 ( LPDIRECTPLAYLOBBY2
this,
606 REFGUID guidDataType
,
610 LPDWORD lpdwAddressSize
)
612 return IDirectPlayLobbyW_CreateAddress( (LPDIRECTPLAYLOBBY
)this, guidSP
, guidDataType
,
613 lpData
, dwDataSize
, lpAddress
, lpdwAddressSize
);
617 /********************************************************************
619 * Parses out chunks from the DirectPlay Address buffer by calling the
620 * given callback function, with lpContext, for each of the chunks.
623 static HRESULT WINAPI IDirectPlayLobbyA_EnumAddress
624 ( LPDIRECTPLAYLOBBYA
this,
625 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
,
630 FIXME( dplay
, ":stub\n");
631 return DPERR_OUTOFMEMORY
;
634 static HRESULT WINAPI IDirectPlayLobby2A_EnumAddress
635 ( LPDIRECTPLAYLOBBY2A
this,
636 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
,
641 return IDirectPlayLobbyA_EnumAddress( (LPDIRECTPLAYLOBBYA
)this, lpEnumAddressCallback
,
642 lpAddress
, dwAddressSize
, lpContext
);
645 static HRESULT WINAPI IDirectPlayLobbyW_EnumAddress
646 ( LPDIRECTPLAYLOBBY
this,
647 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
,
652 FIXME( dplay
, ":stub\n");
653 return DPERR_OUTOFMEMORY
;
656 static HRESULT WINAPI IDirectPlayLobby2W_EnumAddress
657 ( LPDIRECTPLAYLOBBY2
this,
658 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
,
663 return IDirectPlayLobbyW_EnumAddress( (LPDIRECTPLAYLOBBY
)this, lpEnumAddressCallback
,
664 lpAddress
, dwAddressSize
, lpContext
);
668 /********************************************************************
670 * Enumerates all the address types that a given service provider needs to
671 * build the DirectPlay Address.
674 static HRESULT WINAPI IDirectPlayLobbyA_EnumAddressTypes
675 ( LPDIRECTPLAYLOBBYA
this,
676 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
,
681 FIXME( dplay
, ":stub\n");
682 return DPERR_OUTOFMEMORY
;
685 static HRESULT WINAPI IDirectPlayLobby2A_EnumAddressTypes
686 ( LPDIRECTPLAYLOBBY2A
this,
687 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
,
692 return IDirectPlayLobbyA_EnumAddressTypes( (LPDIRECTPLAYLOBBYA
)this, lpEnumAddressTypeCallback
,
693 guidSP
, lpContext
, dwFlags
);
696 static HRESULT WINAPI IDirectPlayLobbyW_EnumAddressTypes
697 ( LPDIRECTPLAYLOBBY
this,
698 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
,
703 FIXME( dplay
, ":stub\n");
704 return DPERR_OUTOFMEMORY
;
707 static HRESULT WINAPI IDirectPlayLobby2W_EnumAddressTypes
708 ( LPDIRECTPLAYLOBBY2
this,
709 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
,
714 return IDirectPlayLobbyW_EnumAddressTypes( (LPDIRECTPLAYLOBBY
)this, lpEnumAddressTypeCallback
,
715 guidSP
, lpContext
, dwFlags
);
719 /********************************************************************
721 * Enumerates what applications are registered with DirectPlay by
722 * invoking the callback function with lpContext.
725 static HRESULT WINAPI IDirectPlayLobbyW_EnumLocalApplications
726 ( LPDIRECTPLAYLOBBY
this,
727 LPDPLENUMLOCALAPPLICATIONSCALLBACK a
,
731 FIXME( dplay
, ":stub\n");
732 return DPERR_OUTOFMEMORY
;
735 static HRESULT WINAPI IDirectPlayLobby2W_EnumLocalApplications
736 ( LPDIRECTPLAYLOBBY2
this,
737 LPDPLENUMLOCALAPPLICATIONSCALLBACK a
,
741 return IDirectPlayLobbyW_EnumLocalApplications( (LPDIRECTPLAYLOBBY
)this, a
,
742 lpContext
, dwFlags
);
745 static HRESULT WINAPI IDirectPlayLobbyA_EnumLocalApplications
746 ( LPDIRECTPLAYLOBBYA
this,
747 LPDPLENUMLOCALAPPLICATIONSCALLBACK a
,
751 FIXME( dplay
, ":stub\n");
752 return DPERR_OUTOFMEMORY
;
755 static HRESULT WINAPI IDirectPlayLobby2A_EnumLocalApplications
756 ( LPDIRECTPLAYLOBBY2A
this,
757 LPDPLENUMLOCALAPPLICATIONSCALLBACK a
,
761 return IDirectPlayLobbyA_EnumLocalApplications( (LPDIRECTPLAYLOBBYA
)this, a
,
762 lpContext
, dwFlags
);
766 /********************************************************************
768 * Retrieves the DPLCONNECTION structure that contains all the information
769 * needed to start and connect an application. This was generated using
770 * either the RunApplication or SetConnectionSettings methods.
772 * NOTES: If lpData is NULL then just return lpdwDataSize. This allows
773 * the data structure to be allocated by our caller which can then
774 * call this procedure/method again with a valid data pointer.
776 static HRESULT WINAPI IDirectPlayLobbyA_GetConnectionSettings
777 ( LPDIRECTPLAYLOBBYA
this,
780 LPDWORD lpdwDataSize
)
782 FIXME( dplay
, ": semi stub %p %08lx %p %p \n", this, dwAppID
, lpData
, lpdwDataSize
);
784 /* Application is requesting us to give the required size */
787 /* Let's check the size of the buffer that the application has allocated */
788 if( *lpdwDataSize
>= sizeof( DPLCONNECTION
) )
794 *lpdwDataSize
= sizeof( DPLCONNECTION
);
795 return DPERR_BUFFERTOOSMALL
;
799 /* Fill in the fields - let them just use the ptrs */
800 if( ((LPDPLCONNECTION
)lpData
)->lpSessionDesc
)
804 memcpy( lpData
, this->lpSession
, sizeof( *(this->lpSession
) ) );
809 static HRESULT WINAPI IDirectPlayLobby2A_GetConnectionSettings
810 ( LPDIRECTPLAYLOBBY2A
this,
813 LPDWORD lpdwDataSize
)
815 return IDirectPlayLobbyA_GetConnectionSettings( (LPDIRECTPLAYLOBBYA
)this,
816 dwAppID
, lpData
, lpdwDataSize
);
819 static HRESULT WINAPI IDirectPlayLobbyW_GetConnectionSettings
820 ( LPDIRECTPLAYLOBBY
this,
823 LPDWORD lpdwDataSize
)
825 FIXME( dplay
, ":semi stub %p %08lx %p %p \n", this, dwAppID
, lpData
, lpdwDataSize
);
827 /* Application is requesting us to give the required size */
830 /* Let's check the size of the buffer that the application has allocated */
831 if( *lpdwDataSize
>= sizeof( DPLCONNECTION
) )
837 *lpdwDataSize
= sizeof( DPLCONNECTION
);
838 return DPERR_BUFFERTOOSMALL
;
842 /* Fill in the fields - let them just use the ptrs */
843 memcpy( lpData
, this->lpSession
, sizeof( *(this->lpSession
) ) );
848 static HRESULT WINAPI IDirectPlayLobby2W_GetConnectionSettings
849 ( LPDIRECTPLAYLOBBY2
this,
852 LPDWORD lpdwDataSize
)
854 return IDirectPlayLobbyW_GetConnectionSettings( (LPDIRECTPLAYLOBBY
)this,
855 dwAppID
, lpData
, lpdwDataSize
);
858 /********************************************************************
860 * Retrieves the message sent between a lobby client and a DirectPlay
861 * application. All messages are queued until received.
864 static HRESULT WINAPI IDirectPlayLobbyA_ReceiveLobbyMessage
865 ( LPDIRECTPLAYLOBBYA
this,
868 LPDWORD lpdwMessageFlags
,
870 LPDWORD lpdwDataSize
)
872 FIXME( dplay
, ":stub %p %08lx %08lx %p %p %p\n", this, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
874 return DPERR_OUTOFMEMORY
;
877 static HRESULT WINAPI IDirectPlayLobby2A_ReceiveLobbyMessage
878 ( LPDIRECTPLAYLOBBY2A
this,
881 LPDWORD lpdwMessageFlags
,
883 LPDWORD lpdwDataSize
)
885 return IDirectPlayLobbyA_ReceiveLobbyMessage( (LPDIRECTPLAYLOBBYA
)this, dwFlags
, dwAppID
,
886 lpdwMessageFlags
, lpData
, lpdwDataSize
);
890 static HRESULT WINAPI IDirectPlayLobbyW_ReceiveLobbyMessage
891 ( LPDIRECTPLAYLOBBY
this,
894 LPDWORD lpdwMessageFlags
,
896 LPDWORD lpdwDataSize
)
898 FIXME( dplay
, ":stub %p %08lx %08lx %p %p %p\n", this, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
900 return DPERR_OUTOFMEMORY
;
903 static HRESULT WINAPI IDirectPlayLobby2W_ReceiveLobbyMessage
904 ( LPDIRECTPLAYLOBBY2
this,
907 LPDWORD lpdwMessageFlags
,
909 LPDWORD lpdwDataSize
)
911 return IDirectPlayLobbyW_ReceiveLobbyMessage( (LPDIRECTPLAYLOBBY
)this, dwFlags
, dwAppID
,
912 lpdwMessageFlags
, lpData
, lpdwDataSize
);
915 /********************************************************************
917 * Starts an application and passes to it all the information to
918 * connect to a session.
921 static HRESULT WINAPI IDirectPlayLobbyA_RunApplication
922 ( LPDIRECTPLAYLOBBYA
this,
925 LPDPLCONNECTION lpConn
,
926 HANDLE32 hReceiveEvent
)
928 FIXME( dplay
, ":stub\n");
929 return DPERR_OUTOFMEMORY
;
932 static HRESULT WINAPI IDirectPlayLobby2A_RunApplication
933 ( LPDIRECTPLAYLOBBY2A
this,
936 LPDPLCONNECTION lpConn
,
937 HANDLE32 hReceiveEvent
)
939 return IDirectPlayLobbyA_RunApplication( (LPDIRECTPLAYLOBBYA
)this, dwFlags
,
940 lpdwAppID
, lpConn
, hReceiveEvent
);
943 static HRESULT WINAPI IDirectPlayLobbyW_RunApplication
944 ( LPDIRECTPLAYLOBBY
this,
947 LPDPLCONNECTION lpConn
,
948 HANDLE32 hReceiveEvent
)
950 FIXME( dplay
, ":stub\n");
951 return DPERR_OUTOFMEMORY
;
954 static HRESULT WINAPI IDirectPlayLobby2W_RunApplication
955 ( LPDIRECTPLAYLOBBY2
this,
958 LPDPLCONNECTION lpConn
,
959 HANDLE32 hReceiveEvent
)
961 return IDirectPlayLobbyW_RunApplication( (LPDIRECTPLAYLOBBY
)this, dwFlags
,
962 lpdwAppID
, lpConn
, hReceiveEvent
);
966 /********************************************************************
968 * Sends a message between the application and the lobby client.
969 * All messages are queued until received.
972 static HRESULT WINAPI IDirectPlayLobbyA_SendLobbyMessage
973 ( LPDIRECTPLAYLOBBYA
this,
979 FIXME( dplay
, ":stub\n");
980 return DPERR_OUTOFMEMORY
;
983 static HRESULT WINAPI IDirectPlayLobby2A_SendLobbyMessage
984 ( LPDIRECTPLAYLOBBY2A
this,
990 return IDirectPlayLobbyA_SendLobbyMessage( (LPDIRECTPLAYLOBBYA
)this, dwFlags
,
991 dwAppID
, lpData
, dwDataSize
);
995 static HRESULT WINAPI IDirectPlayLobbyW_SendLobbyMessage
996 ( LPDIRECTPLAYLOBBY
this,
1002 FIXME( dplay
, ":stub\n");
1003 return DPERR_OUTOFMEMORY
;
1006 static HRESULT WINAPI IDirectPlayLobby2W_SendLobbyMessage
1007 ( LPDIRECTPLAYLOBBY2
this,
1013 return IDirectPlayLobbyW_SendLobbyMessage( (LPDIRECTPLAYLOBBY
)this, dwFlags
,
1014 dwAppID
, lpData
, dwDataSize
);
1017 /********************************************************************
1019 * Modifies the DPLCONNECTION structure to contain all information
1020 * needed to start and connect an application.
1023 static HRESULT WINAPI IDirectPlayLobbyW_SetConnectionSettings
1024 ( LPDIRECTPLAYLOBBY
this,
1027 LPDPLCONNECTION lpConn
)
1029 FIXME( dplay
, ": this=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p: semi stub\n",
1030 this, dwFlags
, dwAppID
, lpConn
);
1032 /* Paramater check */
1033 if( dwFlags
|| !this || !lpConn
)
1035 ERR( dplay
, "invalid parameters.\n");
1036 return DPERR_INVALIDPARAMS
;
1039 /* See if there is a connection associated with this request.
1040 * dwAppID == 0 indicates that this request isn't associated with a connection.
1044 FIXME( dplay
, ": Connection dwAppID=%08lx given. Not implemented yet.\n",
1047 /* Need to add a check for this application Id...*/
1048 return DPERR_NOTLOBBIED
;
1051 if( lpConn
->dwSize
!= sizeof(DPLCONNECTION
) )
1053 ERR( dplay
, ": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
1054 lpConn
->dwSize
, sizeof( DPLCONNECTION
) );
1055 return DPERR_INVALIDPARAMS
;
1058 /* Need to investigate the lpConn->lpSessionDesc to figure out
1059 * what type of session we need to join/create.
1061 if( (!lpConn
->lpSessionDesc
) ||
1062 ( lpConn
->lpSessionDesc
->dwSize
!= sizeof( DPSESSIONDESC2
) )
1065 ERR( dplay
, "DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
1066 lpConn
->lpSessionDesc
->dwSize
, sizeof( DPSESSIONDESC2
) );
1067 return DPERR_INVALIDPARAMS
;
1070 /* Need to actually store the stuff here */
1072 return DPERR_OUTOFMEMORY
;
1075 static HRESULT WINAPI IDirectPlayLobby2W_SetConnectionSettings
1076 ( LPDIRECTPLAYLOBBY2
this,
1079 LPDPLCONNECTION lpConn
)
1081 return IDirectPlayLobbyW_SetConnectionSettings( (LPDIRECTPLAYLOBBY
)this,
1082 dwFlags
, dwAppID
, lpConn
);
1085 static HRESULT WINAPI IDirectPlayLobbyA_SetConnectionSettings
1086 ( LPDIRECTPLAYLOBBYA
this,
1089 LPDPLCONNECTION lpConn
)
1091 FIXME( dplay
, ": this=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p: stub\n",
1092 this, dwFlags
, dwAppID
, lpConn
);
1093 return DPERR_OUTOFMEMORY
;
1096 static HRESULT WINAPI IDirectPlayLobby2A_SetConnectionSettings
1097 ( LPDIRECTPLAYLOBBY2A
this,
1100 LPDPLCONNECTION lpConn
)
1102 return IDirectPlayLobbyA_SetConnectionSettings( (LPDIRECTPLAYLOBBYA
)this,
1103 dwFlags
, dwAppID
, lpConn
);
1106 /********************************************************************
1108 * Registers an event that will be set when a lobby message is received.
1111 static HRESULT WINAPI IDirectPlayLobbyA_SetLobbyMessageEvent
1112 ( LPDIRECTPLAYLOBBYA
this,
1115 HANDLE32 hReceiveEvent
)
1117 FIXME( dplay
, ":stub\n");
1118 return DPERR_OUTOFMEMORY
;
1121 static HRESULT WINAPI IDirectPlayLobby2A_SetLobbyMessageEvent
1122 ( LPDIRECTPLAYLOBBY2A
this,
1125 HANDLE32 hReceiveEvent
)
1127 return IDirectPlayLobbyA_SetLobbyMessageEvent( (LPDIRECTPLAYLOBBYA
)this, dwFlags
,
1128 dwAppID
, hReceiveEvent
);
1131 static HRESULT WINAPI IDirectPlayLobbyW_SetLobbyMessageEvent
1132 ( LPDIRECTPLAYLOBBY
this,
1135 HANDLE32 hReceiveEvent
)
1137 FIXME( dplay
, ":stub\n");
1138 return DPERR_OUTOFMEMORY
;
1141 static HRESULT WINAPI IDirectPlayLobby2W_SetLobbyMessageEvent
1142 ( LPDIRECTPLAYLOBBY2
this,
1145 HANDLE32 hReceiveEvent
)
1147 return IDirectPlayLobbyW_SetLobbyMessageEvent( (LPDIRECTPLAYLOBBY
)this, dwFlags
,
1148 dwAppID
, hReceiveEvent
);
1152 /********************************************************************
1154 * Registers an event that will be set when a lobby message is received.
1157 static HRESULT WINAPI IDirectPlayLobby2W_CreateCompoundAddress
1158 ( LPDIRECTPLAYLOBBY2
this,
1159 LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1160 DWORD dwElementCount
,
1162 LPDWORD lpdwAddressSize
)
1164 FIXME( dplay
, ":stub\n");
1165 return DPERR_OUTOFMEMORY
;
1168 static HRESULT WINAPI IDirectPlayLobby2A_CreateCompoundAddress
1169 ( LPDIRECTPLAYLOBBY2A
this,
1170 LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1171 DWORD dwElementCount
,
1173 LPDWORD lpdwAddressSize
)
1175 FIXME( dplay
, ":stub\n");
1176 return DPERR_OUTOFMEMORY
;
1180 /* Direct Play Lobby 1 (ascii) Virtual Table for methods */
1181 static struct tagLPDIRECTPLAYLOBBY_VTABLE directPlayLobbyAVT
= {
1182 IDirectPlayLobbyA_QueryInterface
,
1183 IDirectPlayLobbyA_AddRef
,
1184 IDirectPlayLobbyA_Release
,
1185 IDirectPlayLobbyA_Connect
,
1186 IDirectPlayLobbyA_CreateAddress
,
1187 IDirectPlayLobbyA_EnumAddress
,
1188 IDirectPlayLobbyA_EnumAddressTypes
,
1189 IDirectPlayLobbyA_EnumLocalApplications
,
1190 IDirectPlayLobbyA_GetConnectionSettings
,
1191 IDirectPlayLobbyA_ReceiveLobbyMessage
,
1192 IDirectPlayLobbyA_RunApplication
,
1193 IDirectPlayLobbyA_SendLobbyMessage
,
1194 IDirectPlayLobbyA_SetConnectionSettings
,
1195 IDirectPlayLobbyA_SetLobbyMessageEvent
1198 /* Direct Play Lobby 1 (unicode) Virtual Table for methods */
1199 static struct tagLPDIRECTPLAYLOBBY_VTABLE directPlayLobbyWVT
= {
1200 IDirectPlayLobbyW_QueryInterface
,
1201 IDirectPlayLobbyW_AddRef
,
1202 IDirectPlayLobbyW_Release
,
1203 IDirectPlayLobbyW_Connect
,
1204 IDirectPlayLobbyW_CreateAddress
,
1205 IDirectPlayLobbyW_EnumAddress
,
1206 IDirectPlayLobbyW_EnumAddressTypes
,
1207 IDirectPlayLobbyW_EnumLocalApplications
,
1208 IDirectPlayLobbyW_GetConnectionSettings
,
1209 IDirectPlayLobbyW_ReceiveLobbyMessage
,
1210 IDirectPlayLobbyW_RunApplication
,
1211 IDirectPlayLobbyW_SendLobbyMessage
,
1212 IDirectPlayLobbyW_SetConnectionSettings
,
1213 IDirectPlayLobbyW_SetLobbyMessageEvent
1217 /* Direct Play Lobby 2 (ascii) Virtual Table for methods */
1218 static struct tagLPDIRECTPLAYLOBBY2_VTABLE directPlayLobby2AVT
= {
1219 IDirectPlayLobby2A_QueryInterface
,
1220 IDirectPlayLobby2A_AddRef
,
1221 IDirectPlayLobby2A_Release
,
1222 IDirectPlayLobby2A_Connect
,
1223 IDirectPlayLobby2A_CreateAddress
,
1224 IDirectPlayLobby2A_EnumAddress
,
1225 IDirectPlayLobby2A_EnumAddressTypes
,
1226 IDirectPlayLobby2A_EnumLocalApplications
,
1227 IDirectPlayLobby2A_GetConnectionSettings
,
1228 IDirectPlayLobby2A_ReceiveLobbyMessage
,
1229 IDirectPlayLobby2A_RunApplication
,
1230 IDirectPlayLobby2A_SendLobbyMessage
,
1231 IDirectPlayLobby2A_SetConnectionSettings
,
1232 IDirectPlayLobby2A_SetLobbyMessageEvent
,
1233 IDirectPlayLobby2A_CreateCompoundAddress
1236 /* Direct Play Lobby 2 (unicode) Virtual Table for methods */
1237 static struct tagLPDIRECTPLAYLOBBY2_VTABLE directPlayLobby2WVT
= {
1238 IDirectPlayLobby2W_QueryInterface
,
1239 IDirectPlayLobby2W_AddRef
,
1240 IDirectPlayLobby2W_Release
,
1241 IDirectPlayLobby2W_Connect
,
1242 IDirectPlayLobby2W_CreateAddress
,
1243 IDirectPlayLobby2W_EnumAddress
,
1244 IDirectPlayLobby2W_EnumAddressTypes
,
1245 IDirectPlayLobby2W_EnumLocalApplications
,
1246 IDirectPlayLobby2W_GetConnectionSettings
,
1247 IDirectPlayLobby2W_ReceiveLobbyMessage
,
1248 IDirectPlayLobby2W_RunApplication
,
1249 IDirectPlayLobby2W_SendLobbyMessage
,
1250 IDirectPlayLobby2W_SetConnectionSettings
,
1251 IDirectPlayLobby2W_SetLobbyMessageEvent
,
1252 IDirectPlayLobby2W_CreateCompoundAddress
1255 /***************************************************************************
1256 * DirectPlayLobbyCreateA (DPLAYX.4)
1259 HRESULT WINAPI
DirectPlayLobbyCreateA( LPGUID lpGUIDDSP
,
1260 LPDIRECTPLAYLOBBYA
*lplpDPL
,
1265 TRACE(dplay
,"lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
1266 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
1268 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
1269 * equal 0. These fields are mostly for future expansion.
1271 if ( lpGUIDDSP
|| lpUnk
|| lpData
|| dwDataSize
)
1274 return DPERR_INVALIDPARAMS
;
1277 /* Yes...really we should bre returning a lobby 1 object */
1278 *lplpDPL
= (LPDIRECTPLAYLOBBYA
)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
1279 sizeof( IDirectPlayLobbyA
) );
1283 return DPERR_OUTOFMEMORY
;
1286 (*lplpDPL
)->lpVtbl
= &directPlayLobbyAVT
;
1287 (*lplpDPL
)->ref
= 1;
1289 (*lplpDPL
)->lpSession
= (LPDPLCONNECTION
)HeapAlloc( GetProcessHeap(),
1291 sizeof( DPLCONNECTION
) );
1292 (*lplpDPL
)->lpSession
->dwSize
= sizeof( DPLCONNECTION
);
1294 (*lplpDPL
)->lpSession
->lpSessionDesc
= (LPDPSESSIONDESC2
)HeapAlloc(
1295 GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( DPSESSIONDESC2
) );
1296 (*lplpDPL
)->lpSession
->lpSessionDesc
->dwSize
= sizeof( DPSESSIONDESC2
);
1301 /***************************************************************************
1302 * DirectPlayLobbyCreateW (DPLAYX.5)
1305 HRESULT WINAPI
DirectPlayLobbyCreateW( LPGUID lpGUIDDSP
,
1306 LPDIRECTPLAYLOBBY
*lplpDPL
,
1311 TRACE(dplay
,"lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
1312 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
1314 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
1315 * equal 0. These fields are mostly for future expansion.
1317 if ( lpGUIDDSP
|| lpUnk
|| lpData
|| dwDataSize
)
1320 ERR( dplay
, "Bad parameters!\n" );
1321 return DPERR_INVALIDPARAMS
;
1324 /* Yes...really we should bre returning a lobby 1 object */
1325 *lplpDPL
= (LPDIRECTPLAYLOBBY
)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
1326 sizeof( IDirectPlayLobby
) );
1330 return DPERR_OUTOFMEMORY
;
1333 (*lplpDPL
)->lpVtbl
= &directPlayLobbyWVT
;
1334 (*lplpDPL
)->ref
= 1;
1337 (*lplpDPL
)->lpSession
= (LPDPLCONNECTION
)HeapAlloc( GetProcessHeap(),
1339 sizeof( DPLCONNECTION
) );
1340 (*lplpDPL
)->lpSession
->dwSize
= sizeof( DPLCONNECTION
);
1341 (*lplpDPL
)->lpSession
->lpSessionDesc
= (LPDPSESSIONDESC2
)HeapAlloc(
1342 GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( DPSESSIONDESC2
) );
1343 (*lplpDPL
)->lpSession
->lpSessionDesc
->dwSize
= sizeof( DPSESSIONDESC2
);
1349 /***************************************************************************
1350 * DirectPlayEnumerateA (DPLAYX.2)
1352 * The pointer to the structure lpContext will be filled with the
1353 * appropriate data for each service offered by the OS. These services are
1354 * not necessarily available on this particular machine but are defined
1355 * as simple service providers under the "Service Providers" registry key.
1356 * This structure is then passed to lpEnumCallback for each of the different
1359 * This API is useful only for applications written using DirectX3 or
1360 * worse. It is superceeded by IDirectPlay3::EnumConnections which also
1361 * gives information on the actual connections.
1363 * defn of a service provider:
1364 * A dynamic-link library used by DirectPlay to communicate over a network.
1365 * The service provider contains all the network-specific code required
1366 * to send and receive messages. Online services and network operators can
1367 * supply service providers to use specialized hardware, protocols, communications
1368 * media, and network resources.
1370 * TODO: Allocate string buffer space from the heap (length from reg)
1371 * Pass real device driver numbers...
1372 * Get the GUID properly...
1374 HRESULT WINAPI
DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback
,
1379 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
1380 LPSTR guidDataSubKey
= "Guid";
1381 LPSTR majVerDataSubKey
= "dwReserved1";
1382 DWORD dwIndex
, sizeOfSubKeyName
=50;
1383 char subKeyName
[51];
1385 TRACE( dplay
, ": lpEnumCallback=%p lpContext=%p\n", lpEnumCallback
, lpContext
);
1387 if( !lpEnumCallback
|| !*lpEnumCallback
)
1389 return DPERR_INVALIDPARAMS
;
1392 /* Need to loop over the service providers in the registry */
1393 if( RegOpenKeyEx32A( HKEY_LOCAL_MACHINE
, searchSubKey
,
1394 0, KEY_ENUMERATE_SUB_KEYS
, &hkResult
) != ERROR_SUCCESS
)
1396 /* Hmmm. Does this mean that there are no service providers? */
1397 ERR(dplay
, ": no service providers?\n");
1401 /* Traverse all the service providers we have available */
1403 RegEnumKey32A( hkResult
, dwIndex
, subKeyName
, sizeOfSubKeyName
) !=
1404 ERROR_NO_MORE_ITEMS
;
1407 HKEY hkServiceProvider
;
1408 GUID serviceProviderGUID
;
1409 DWORD returnTypeGUID
, returnTypeReserved1
, sizeOfReturnBuffer
=50;
1410 char returnBuffer
[51];
1411 DWORD majVersionNum
, minVersionNum
;
1412 LPWSTR lpWGUIDString
;
1414 TRACE( dplay
, " this time through: %s\n", subKeyName
);
1416 /* Get a handle for this particular service provider */
1417 if( RegOpenKeyEx32A( hkResult
, subKeyName
, 0, KEY_QUERY_VALUE
,
1418 &hkServiceProvider
) != ERROR_SUCCESS
)
1420 ERR( dplay
, ": what the heck is going on?\n" );
1424 /* Get the GUID, Device major number and device minor number
1425 * from the registry.
1427 if( RegQueryValueEx32A( hkServiceProvider
, guidDataSubKey
,
1428 NULL
, &returnTypeGUID
, returnBuffer
,
1429 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1431 ERR( dplay
, ": missing GUID registry data members\n" );
1435 /* FIXME: Check return types to ensure we're interpreting data right */
1436 lpWGUIDString
= HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer
);
1437 CLSIDFromString32( (LPCOLESTR32
)lpWGUIDString
, &serviceProviderGUID
);
1438 HeapFree( GetProcessHeap(), 0, lpWGUIDString
);
1440 sizeOfReturnBuffer
= 50;
1442 if( RegQueryValueEx32A( hkServiceProvider
, majVerDataSubKey
,
1443 NULL
, &returnTypeReserved1
, returnBuffer
,
1444 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1446 ERR( dplay
, ": missing dwReserved1 registry data members\n") ;
1449 /* FIXME: This couldn't possibly be right...*/
1450 majVersionNum
= GET_DWORD( returnBuffer
);
1452 /* The enumeration will return FALSE if we are not to continue */
1453 if( !lpEnumCallback( &serviceProviderGUID
, subKeyName
,
1454 majVersionNum
, (DWORD
)0, lpContext
) )
1456 WARN( dplay
, "lpEnumCallback returning FALSE\n" );
1465 /***************************************************************************
1466 * DirectPlayEnumerateW (DPLAYX.3)
1469 HRESULT WINAPI
DirectPlayEnumerateW( LPDPENUMDPCALLBACKW lpEnumCallback
, LPVOID lpContext
)
1472 FIXME( dplay
, ":stub\n");
1474 return DPERR_OUTOFMEMORY
;
1478 /***************************************************************************
1479 * DirectPlayCreate (DPLAYX.1) (DPLAY.1)
1482 HRESULT WINAPI DirectPlayCreate
1483 ( LPGUID lpGUID
, LPDIRECTPLAY2
*lplpDP
, IUnknown
*pUnk
)
1486 FIXME( dplay
, ":stub\n");
1487 return DPERR_OUTOFMEMORY
;
1493 /* Hmmm...wonder what this means! */
1494 ERR(dplay
, "What does a NULL here mean?\n" );
1495 return DPERR_OUTOFMEMORY
;
1498 *lplpDP
= (LPDIRECTPLAY
)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
1499 sizeof( **lplpDP
) );
1503 return DPERR_OUTOFMEMORY
;
1506 (*lplpDP
)->lpVtbl
= &directPlay2AVT
;