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"
19 #define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
20 #define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2)
21 #define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2)
23 struct IDirectPlayLobby
{
24 LPDIRECTPLAYLOBBY_VTABLE lpVtbl
;
26 LPDPLCONNECTION lpSession
;
29 struct IDirectPlayLobby2
{
30 LPDIRECTPLAYLOBBY2_VTABLE lpVtbl
;
32 LPDPLCONNECTION lpSession
;
36 /* Forward declarations of virtual tables */
37 static DIRECTPLAYLOBBY_VTABLE directPlayLobbyAVT
;
38 static DIRECTPLAYLOBBY_VTABLE directPlayLobbyWVT
;
39 static DIRECTPLAYLOBBY2_VTABLE directPlayLobby2AVT
;
40 static DIRECTPLAYLOBBY2_VTABLE directPlayLobby2WVT
;
43 LPDIRECTPLAY2_VTABLE lpVtbl
;
48 LPDIRECTPLAY3_VTABLE lpVtbl
;
53 static DIRECTPLAY2_VTABLE directPlay2AVT
;
54 static DIRECTPLAY2_VTABLE directPlay2WVT
;
55 static DIRECTPLAY3_VTABLE directPlay3AVT
;
56 static DIRECTPLAY3_VTABLE directPlay3WVT
;
58 /* Routine to delete the entire DPLCONNECTION tree. Works for both unicode and ascii. */
59 void deleteDPConnection( LPDPLCONNECTION
* ptrToDelete
)
62 /* This is most definitely wrong. We're not even keeping dwCurrentPlayers over this */
63 LPDPLCONNECTION toDelete
= *ptrToDelete
;
65 FIXME( dplay
, "incomplete.\n" );
70 /* Clear out DPSESSIONDESC2 */
71 if( toDelete
->lpSessionDesc
)
73 if( toDelete
->lpSessionDesc
->sess
.lpszSessionName
)
74 HeapFree( GetProcessHeap(), 0, toDelete
->lpSessionDesc
->sess
.lpszSessionName
);
76 if( toDelete
->lpSessionDesc
->pass
.lpszPassword
)
77 HeapFree( GetProcessHeap(), 0, toDelete
->lpSessionDesc
->pass
.lpszPassword
);
79 if( toDelete
->lpSessionDesc
);
80 HeapFree( GetProcessHeap(), 0, toDelete
->lpSessionDesc
);
83 /* Clear out LPDPNAME */
84 if( toDelete
->lpPlayerName
)
86 if( toDelete
->lpPlayerName
->psn
.lpszShortName
)
87 HeapFree( GetProcessHeap(), 0, toDelete
->lpPlayerName
->psn
.lpszShortName
);
89 if( toDelete
->lpPlayerName
->pln
.lpszLongName
)
90 HeapFree( GetProcessHeap(), 0, toDelete
->lpPlayerName
->pln
.lpszLongName
);
92 if( toDelete
->lpPlayerName
)
93 HeapFree( GetProcessHeap(), 0, toDelete
->lpPlayerName
);
96 /* Clear out lpAddress. TO DO...Once we actually copy it. */
98 /* Clear out DPLCONNECTION */
99 HeapFree( GetProcessHeap(), 0, toDelete
);
106 /* Routine which copies and allocates all the store required for the DPLCONNECTION struct. */
107 void rebuildDPConnectionW( LPDPLCONNECTION dest
, LPDPLCONNECTION src
)
110 /* Need to delete everything that already exists first */
111 FIXME( dplay
, "function is incomplete.\n" );
115 /* Nothing to copy...hmmm...*/
116 ERR( dplay
, "nothing to copy\n" );
120 /* Copy DPLCONNECTION struct. If dest isn't NULL then we have a DPLCONNECTION
125 dest
= HeapAlloc( GetProcessHeap(), 0, sizeof( *src
) );
127 memcpy( dest
, src
, sizeof( *src
) );
129 /* Copy LPDPSESSIONDESC2 struct */
130 if( src
->lpSessionDesc
)
132 dest
->lpSessionDesc
= HeapAlloc( GetProcessHeap(), 0,
133 sizeof( *(src
->lpSessionDesc
) ) );
135 memcpy( dest
->lpSessionDesc
, src
->lpSessionDesc
,
136 sizeof( *(src
->lpSessionDesc
) ) );
138 if( src
->lpSessionDesc
)
140 /* Hmmm...do we have to assume the system heap? */
141 dest
->lpSessionDesc
->sess
.lpszSessionName
= HEAP_strdupW( GetProcessHeap(), 0,
142 src
->lpSessionDesc
->sess
.lpszSessionName
);
145 if( src
->lpSessionDesc
->pass
.lpszPassword
)
147 dest
->lpSessionDesc
->pass
.lpszPassword
= HEAP_strdupW( GetProcessHeap(), 0,
148 src
->lpSessionDesc
->pass
.lpszPassword
);
150 dest
->lpSessionDesc
->dwReserved1
= src
->lpSessionDesc
->dwReserved2
= 0;
153 /* Copy DPNAME struct */
154 if( src
->lpPlayerName
)
156 dest
->lpPlayerName
= HeapAlloc( GetProcessHeap(), 0, sizeof( *(src
->lpPlayerName
) ) );
157 memcpy( dest
->lpPlayerName
, src
->lpPlayerName
, sizeof( *(src
->lpPlayerName
) ) );
159 if( src
->lpPlayerName
->psn
.lpszShortName
)
161 dest
->lpPlayerName
->psn
.lpszShortName
= HEAP_strdupW( GetProcessHeap(), 0,
162 src
->lpPlayerName
->psn
.lpszShortName
);
165 if( src
->lpPlayerName
->pln
.lpszLongName
)
167 dest
->lpPlayerName
->pln
.lpszLongName
= HEAP_strdupW( GetProcessHeap(), 0,
168 src
->lpPlayerName
->pln
.lpszLongName
);
172 /* Copy Address of Service Provider -TBD */
175 /* What do we do here? */
182 /* Routine called when starting up the server thread */
183 DWORD
DPLobby_Spawn_Server( LPVOID startData
)
185 DPSESSIONDESC2
* lpSession
= (DPSESSIONDESC2
*) startData
;
186 DWORD sessionDwFlags
= lpSession
->dwFlags
;
188 TRACE( dplay
, "spawing thread for lpConn=%p dwFlags=%08lx\n", lpSession
, sessionDwFlags
);
189 FIXME( dplay
, "thread needs something to do\n" );
194 /* Check out the connection flags to determine what to do. Ensure we have
195 no leftover bits in this structure */
196 if( sessionDwFlags
& DPSESSION_CLIENTSERVER
)
198 /* This indicates that the application which is requesting the creation
199 * of this session is going to be the server (application/player)
201 if( sessionDwFlags
& DPSESSION_SECURESERVER
)
203 sessionDwFlags
&= ~DPSESSION_SECURESERVER
;
205 sessionDwFlags
&= ~DPSESSION_CLIENTSERVER
;
208 if( sessionDwFlags
& DPSESSION_JOINDISABLED
)
210 sessionDwFlags
&= ~DPSESSION_JOINDISABLED
;
213 if( sessionDwFlags
& DPSESSION_KEEPALIVE
)
215 sessionDwFlags
&= ~DPSESSION_KEEPALIVE
;
218 if( sessionDwFlags
& DPSESSION_MIGRATEHOST
)
220 sessionDwFlags
&= ~DPSESSION_MIGRATEHOST
;
223 if( sessionDwFlags
& DPSESSION_MULTICASTSERVER
)
225 sessionDwFlags
&= ~DPSESSION_MULTICASTSERVER
;
228 if( sessionDwFlags
& DPSESSION_NEWPLAYERSDISABLED
)
230 sessionDwFlags
&= ~DPSESSION_NEWPLAYERSDISABLED
;
233 if( sessionDwFlags
& DPSESSION_NODATAMESSAGES
)
235 sessionDwFlags
&= ~DPSESSION_NODATAMESSAGES
;
238 if( sessionDwFlags
& DPSESSION_NOMESSAGEID
)
240 sessionDwFlags
&= ~DPSESSION_NOMESSAGEID
;
243 if( sessionDwFlags
& DPSESSION_PASSWORDREQUIRED
)
245 sessionDwFlags
&= ~DPSESSION_PASSWORDREQUIRED
;
255 /*********************************************************
257 * Direct Play and Direct Play Lobby Interface Implementation
259 *********************************************************/
261 /* The COM interface for upversioning an interface
262 * We've been given a GUID (riid) and we need to replace the present
263 * interface with that of the requested interface.
265 * Snip from some Microsoft document:
266 * There are four requirements for implementations of QueryInterface (In these
267 * cases, "must succeed" means "must succeed barring catastrophic failure."):
269 * * The set of interfaces accessible on an object through
270 * IUnknown::QueryInterface must be static, not dynamic. This means that
271 * if a call to QueryInterface for a pointer to a specified interface
272 * succeeds the first time, it must succeed again, and if it fails the
273 * first time, it must fail on all subsequent queries.
274 * * It must be symmetric ~W if a client holds a pointer to an interface on
275 * an object, and queries for that interface, the call must succeed.
276 * * It must be reflexive ~W if a client holding a pointer to one interface
277 * queries successfully for another, a query through the obtained pointer
278 * for the first interface must succeed.
279 * * It must be transitive ~W if a client holding a pointer to one interface
280 * queries successfully for a second, and through that pointer queries
281 * successfully for a third interface, a query for the first interface
282 * through the pointer for the third interface must succeed.
284 * As you can see, this interface doesn't qualify but will most likely
285 * be good enough for the time being.
287 static HRESULT WINAPI IDirectPlayLobbyA_QueryInterface
288 ( LPDIRECTPLAYLOBBYA
this,
292 return DPERR_OUTOFMEMORY
;
295 static HRESULT WINAPI IDirectPlayLobbyW_QueryInterface
296 ( LPDIRECTPLAYLOBBY
this,
300 return DPERR_OUTOFMEMORY
;
303 static HRESULT WINAPI IDirectPlayLobby2A_QueryInterface
304 ( LPDIRECTPLAYLOBBY2A
this,
308 /* Compare riids. We know this object is a direct play lobby 2A object.
309 If we are asking about the same type of interface we're fine.
311 if( IsEqualGUID( &IID_IUnknown
, riid
) ||
312 IsEqualGUID( &IID_IDirectPlayLobby2A
, riid
)
315 this->lpVtbl
->fnAddRef( this );
319 /* They're requesting a unicode version of the interface */
320 else if( IsEqualGUID( &IID_IDirectPlayLobby2
, riid
) )
322 LPDIRECTPLAYLOBBY2 lpDpL
= (LPDIRECTPLAYLOBBY2
)(*ppvObj
);
324 lpDpL
= (LPDIRECTPLAYLOBBY2
)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
325 sizeof( IDirectPlayLobby2
) );
329 return E_NOINTERFACE
;
332 lpDpL
->lpVtbl
= &directPlayLobby2WVT
;
338 /* Unexpected interface request! */
340 return E_NOINTERFACE
;
343 static HRESULT WINAPI IDirectPlayLobby2W_QueryInterface
344 ( LPDIRECTPLAYLOBBY2
this,
349 /* Compare riids. We know this object is a direct play lobby 2 object.
350 If we are asking about the same type of interface we're fine.
352 if( IsEqualGUID( &IID_IUnknown
, riid
) ||
353 IsEqualGUID( &IID_IDirectPlayLobby2
, riid
)
356 this->lpVtbl
->fnAddRef( this );
360 else if( IsEqualGUID( &IID_IDirectPlayLobby2A
, riid
) )
362 LPDIRECTPLAYLOBBY2A lpDpL
= (LPDIRECTPLAYLOBBY2A
)(*ppvObj
);
364 lpDpL
= (LPDIRECTPLAYLOBBY2A
)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
365 sizeof( IDirectPlayLobby2A
) );
369 return E_NOINTERFACE
;
372 lpDpL
->lpVtbl
= &directPlayLobby2AVT
;
378 /* Unexpected interface request! */
380 return E_NOINTERFACE
;
385 * Simple procedure. Just increment the reference count to this
386 * structure and return the new reference count.
388 static ULONG WINAPI IDirectPlayLobbyA_AddRef
389 ( LPDIRECTPLAYLOBBYA
this )
392 TRACE( dplay
,"ref count now %lu\n", this->ref
);
395 static ULONG WINAPI IDirectPlayLobbyW_AddRef
396 ( LPDIRECTPLAYLOBBY
this )
398 return IDirectPlayLobbyA_AddRef( (LPDIRECTPLAYLOBBY
) this );
401 static ULONG WINAPI IDirectPlayLobby2A_AddRef
402 ( LPDIRECTPLAYLOBBY2A
this )
404 return IDirectPlayLobbyA_AddRef( (LPDIRECTPLAYLOBBY
) this );
407 static ULONG WINAPI IDirectPlayLobby2W_AddRef
408 ( LPDIRECTPLAYLOBBY2
this )
410 return IDirectPlayLobbyA_AddRef( (LPDIRECTPLAYLOBBY
) this );
415 * Simple COM procedure. Decrease the reference count to this object.
416 * If the object no longer has any reference counts, free up the associated
419 static ULONG WINAPI IDirectPlayLobbyA_Release
420 ( LPDIRECTPLAYLOBBYA
this )
422 TRACE( dplay
, "ref count decremeneted from %lu\n", this->ref
);
426 /* Deallocate if this is the last reference to the object */
429 deleteDPConnection( &(this->lpSession
) );
430 HeapFree( GetProcessHeap(), 0, this );
437 static ULONG WINAPI IDirectPlayLobbyW_Release
438 ( LPDIRECTPLAYLOBBY
this )
440 return IDirectPlayLobbyA_Release( (LPDIRECTPLAYLOBBYA
) this );
442 static ULONG WINAPI IDirectPlayLobby2A_Release
443 ( LPDIRECTPLAYLOBBY2A
this )
445 return IDirectPlayLobbyA_Release( (LPDIRECTPLAYLOBBYA
) this );
448 static ULONG WINAPI IDirectPlayLobby2W_Release
449 ( LPDIRECTPLAYLOBBY2
this )
451 return IDirectPlayLobbyA_Release( (LPDIRECTPLAYLOBBYA
) this );
455 /********************************************************************
457 * Connects an application to the session specified by the DPLCONNECTION
458 * structure currently stored with the DirectPlayLobby object.
460 * Returns a IDirectPlay interface.
463 static HRESULT WINAPI IDirectPlayLobbyA_Connect
464 ( LPDIRECTPLAYLOBBYA
this,
466 LPDIRECTPLAY
* lplpDP
,
469 FIXME( dplay
, ": dwFlags=%08lx %p %p stub\n", dwFlags
, lplpDP
, pUnk
);
470 return DPERR_OUTOFMEMORY
;
473 static HRESULT WINAPI IDirectPlayLobby2A_Connect
474 ( LPDIRECTPLAYLOBBY2A
this,
476 LPDIRECTPLAY
* lplpDP
,
479 return IDirectPlayLobbyA_Connect( (LPDIRECTPLAYLOBBYA
)this, dwFlags
, lplpDP
, pUnk
);
482 static HRESULT WINAPI IDirectPlayLobbyW_Connect
483 ( LPDIRECTPLAYLOBBY
this,
485 LPDIRECTPLAY
* lplpDP
,
488 LPDIRECTPLAY2A directPlay2A
;
489 LPDIRECTPLAY2 directPlay2W
;
492 FIXME( dplay
, ": dwFlags=%08lx %p %p stub\n", dwFlags
, lplpDP
, pUnk
);
496 /* See dpbuild_4301.txt */
497 /* Create the direct play 2 W interface */
498 if( ( ( createRC
= DirectPlayCreate( NULL
, &directPlay2A
, pUnk
) ) != DP_OK
) ||
499 ( ( createRC
= directPlay2A
->lpVtbl
->fnQueryInterface
500 ( directPlay2A
, IID_IDirectPlay2
, &directPlay2W
) ) != DP_OK
)
503 ERR( dplay
, "error creating Direct Play 2 (W) interface. Return Code = %d.\n", createRC
);
507 /* All the stuff below this is WRONG! */
508 if( this->lpSession
->dwFlags
== DPLCONNECTION_CREATESESSION
)
512 /* Spawn a thread to deal with all of this and to handle the incomming requests */
513 threadIdSink
= CreateThread( NULL
, 0, &DPLobby_Spawn_Server
,
514 (LPVOID
)this->lpSession
->lpConn
->lpSessionDesc
, 0, &threadIdSink
);
517 else if ( this->lpSession
->dwFlags
== DPLCONNECTION_JOINSESSION
)
519 /* Let's search for a matching session */
520 FIXME( dplay
, "joining session not yet supported.\n");
521 return DPERR_OUTOFMEMORY
;
523 else /* Unknown type of connection request */
525 ERR( dplay
, ": Unknown connection request lpConn->dwFlags=%08lx\n",
528 return DPERR_OUTOFMEMORY
;
531 /* This does the work of the following methods...
532 IDirectPlay3::InitializeConnection,
533 IDirectPlay3::EnumSessions,
544 static HRESULT WINAPI IDirectPlayLobby2W_Connect
545 ( LPDIRECTPLAYLOBBY2
this,
547 LPDIRECTPLAY
* lplpDP
,
550 return IDirectPlayLobbyW_Connect( (LPDIRECTPLAYLOBBY
)this, dwFlags
, lplpDP
, pUnk
);
553 /********************************************************************
555 * Creates a DirectPlay Address, given a service provider-specific network
557 * Returns an address contains the globally unique identifier
558 * (GUID) of the service provider and data that the service provider can
559 * interpret as a network address.
562 static HRESULT WINAPI IDirectPlayLobbyA_CreateAddress
563 ( LPDIRECTPLAYLOBBY
this,
565 REFGUID guidDataType
,
569 LPDWORD lpdwAddressSize
)
571 FIXME( dplay
, ":stub\n");
572 return DPERR_OUTOFMEMORY
;
575 static HRESULT WINAPI IDirectPlayLobby2A_CreateAddress
576 ( LPDIRECTPLAYLOBBY2A
this,
578 REFGUID guidDataType
,
582 LPDWORD lpdwAddressSize
)
584 return IDirectPlayLobbyA_CreateAddress( (LPDIRECTPLAYLOBBY
)this, guidSP
, guidDataType
,
585 lpData
, dwDataSize
, lpAddress
, lpdwAddressSize
);
588 static HRESULT WINAPI IDirectPlayLobbyW_CreateAddress
589 ( LPDIRECTPLAYLOBBY
this,
591 REFGUID guidDataType
,
595 LPDWORD lpdwAddressSize
)
597 FIXME( dplay
, ":stub\n");
598 return DPERR_OUTOFMEMORY
;
602 static HRESULT WINAPI IDirectPlayLobby2W_CreateAddress
603 ( LPDIRECTPLAYLOBBY2
this,
605 REFGUID guidDataType
,
609 LPDWORD lpdwAddressSize
)
611 return IDirectPlayLobbyW_CreateAddress( (LPDIRECTPLAYLOBBY
)this, guidSP
, guidDataType
,
612 lpData
, dwDataSize
, lpAddress
, lpdwAddressSize
);
616 /********************************************************************
618 * Parses out chunks from the DirectPlay Address buffer by calling the
619 * given callback function, with lpContext, for each of the chunks.
622 static HRESULT WINAPI IDirectPlayLobbyA_EnumAddress
623 ( LPDIRECTPLAYLOBBYA
this,
624 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
,
629 FIXME( dplay
, ":stub\n");
630 return DPERR_OUTOFMEMORY
;
633 static HRESULT WINAPI IDirectPlayLobby2A_EnumAddress
634 ( LPDIRECTPLAYLOBBY2A
this,
635 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
,
640 return IDirectPlayLobbyA_EnumAddress( (LPDIRECTPLAYLOBBYA
)this, lpEnumAddressCallback
,
641 lpAddress
, dwAddressSize
, lpContext
);
644 static HRESULT WINAPI IDirectPlayLobbyW_EnumAddress
645 ( LPDIRECTPLAYLOBBY
this,
646 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
,
651 FIXME( dplay
, ":stub\n");
652 return DPERR_OUTOFMEMORY
;
655 static HRESULT WINAPI IDirectPlayLobby2W_EnumAddress
656 ( LPDIRECTPLAYLOBBY2
this,
657 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
,
662 return IDirectPlayLobbyW_EnumAddress( (LPDIRECTPLAYLOBBY
)this, lpEnumAddressCallback
,
663 lpAddress
, dwAddressSize
, lpContext
);
667 /********************************************************************
669 * Enumerates all the address types that a given service provider needs to
670 * build the DirectPlay Address.
673 static HRESULT WINAPI IDirectPlayLobbyA_EnumAddressTypes
674 ( LPDIRECTPLAYLOBBYA
this,
675 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
,
680 FIXME( dplay
, ":stub\n");
681 return DPERR_OUTOFMEMORY
;
684 static HRESULT WINAPI IDirectPlayLobby2A_EnumAddressTypes
685 ( LPDIRECTPLAYLOBBY2A
this,
686 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
,
691 return IDirectPlayLobbyA_EnumAddressTypes( (LPDIRECTPLAYLOBBYA
)this, lpEnumAddressTypeCallback
,
692 guidSP
, lpContext
, dwFlags
);
695 static HRESULT WINAPI IDirectPlayLobbyW_EnumAddressTypes
696 ( LPDIRECTPLAYLOBBY
this,
697 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
,
702 FIXME( dplay
, ":stub\n");
703 return DPERR_OUTOFMEMORY
;
706 static HRESULT WINAPI IDirectPlayLobby2W_EnumAddressTypes
707 ( LPDIRECTPLAYLOBBY2
this,
708 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
,
713 return IDirectPlayLobbyW_EnumAddressTypes( (LPDIRECTPLAYLOBBY
)this, lpEnumAddressTypeCallback
,
714 guidSP
, lpContext
, dwFlags
);
718 /********************************************************************
720 * Enumerates what applications are registered with DirectPlay by
721 * invoking the callback function with lpContext.
724 static HRESULT WINAPI IDirectPlayLobbyW_EnumLocalApplications
725 ( LPDIRECTPLAYLOBBY
this,
726 LPDPLENUMLOCALAPPLICATIONSCALLBACK a
,
730 FIXME( dplay
, ":stub\n");
731 return DPERR_OUTOFMEMORY
;
734 static HRESULT WINAPI IDirectPlayLobby2W_EnumLocalApplications
735 ( LPDIRECTPLAYLOBBY2
this,
736 LPDPLENUMLOCALAPPLICATIONSCALLBACK a
,
740 return IDirectPlayLobbyW_EnumLocalApplications( (LPDIRECTPLAYLOBBY
)this, a
,
741 lpContext
, dwFlags
);
744 static HRESULT WINAPI IDirectPlayLobbyA_EnumLocalApplications
745 ( LPDIRECTPLAYLOBBYA
this,
746 LPDPLENUMLOCALAPPLICATIONSCALLBACK a
,
750 FIXME( dplay
, ":stub\n");
751 return DPERR_OUTOFMEMORY
;
754 static HRESULT WINAPI IDirectPlayLobby2A_EnumLocalApplications
755 ( LPDIRECTPLAYLOBBY2A
this,
756 LPDPLENUMLOCALAPPLICATIONSCALLBACK a
,
760 return IDirectPlayLobbyA_EnumLocalApplications( (LPDIRECTPLAYLOBBYA
)this, a
,
761 lpContext
, dwFlags
);
765 /********************************************************************
767 * Retrieves the DPLCONNECTION structure that contains all the information
768 * needed to start and connect an application. This was generated using
769 * either the RunApplication or SetConnectionSettings methods.
771 * NOTES: If lpData is NULL then just return lpdwDataSize. This allows
772 * the data structure to be allocated by our caller which can then
773 * call this procedure/method again with a valid data pointer.
775 static HRESULT WINAPI IDirectPlayLobbyA_GetConnectionSettings
776 ( LPDIRECTPLAYLOBBYA
this,
779 LPDWORD lpdwDataSize
)
781 FIXME( dplay
, ": semi stub %p %08lx %p %p \n", this, dwAppID
, lpData
, lpdwDataSize
);
783 /* Application is requesting us to give the required size */
786 /* Let's check the size of the buffer that the application has allocated */
787 if( *lpdwDataSize
>= sizeof( DPLCONNECTION
) )
793 *lpdwDataSize
= sizeof( DPLCONNECTION
);
794 return DPERR_BUFFERTOOSMALL
;
798 /* Fill in the fields - let them just use the ptrs */
799 if( ((LPDPLCONNECTION
)lpData
)->lpSessionDesc
)
803 memcpy( lpData
, this->lpSession
, sizeof( *(this->lpSession
) ) );
808 static HRESULT WINAPI IDirectPlayLobby2A_GetConnectionSettings
809 ( LPDIRECTPLAYLOBBY2A
this,
812 LPDWORD lpdwDataSize
)
814 return IDirectPlayLobbyA_GetConnectionSettings( (LPDIRECTPLAYLOBBYA
)this,
815 dwAppID
, lpData
, lpdwDataSize
);
818 static HRESULT WINAPI IDirectPlayLobbyW_GetConnectionSettings
819 ( LPDIRECTPLAYLOBBY
this,
822 LPDWORD lpdwDataSize
)
824 FIXME( dplay
, ":semi stub %p %08lx %p %p \n", this, dwAppID
, lpData
, lpdwDataSize
);
826 /* Application is requesting us to give the required size */
829 /* Let's check the size of the buffer that the application has allocated */
830 if( *lpdwDataSize
>= sizeof( DPLCONNECTION
) )
836 *lpdwDataSize
= sizeof( DPLCONNECTION
);
837 return DPERR_BUFFERTOOSMALL
;
841 /* Fill in the fields - let them just use the ptrs */
842 memcpy( lpData
, this->lpSession
, sizeof( *(this->lpSession
) ) );
847 static HRESULT WINAPI IDirectPlayLobby2W_GetConnectionSettings
848 ( LPDIRECTPLAYLOBBY2
this,
851 LPDWORD lpdwDataSize
)
853 return IDirectPlayLobbyW_GetConnectionSettings( (LPDIRECTPLAYLOBBY
)this,
854 dwAppID
, lpData
, lpdwDataSize
);
857 /********************************************************************
859 * Retrieves the message sent between a lobby client and a DirectPlay
860 * application. All messages are queued until received.
863 static HRESULT WINAPI IDirectPlayLobbyA_ReceiveLobbyMessage
864 ( LPDIRECTPLAYLOBBYA
this,
867 LPDWORD lpdwMessageFlags
,
869 LPDWORD lpdwDataSize
)
871 FIXME( dplay
, ":stub %p %08lx %08lx %p %p %p\n", this, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
873 return DPERR_OUTOFMEMORY
;
876 static HRESULT WINAPI IDirectPlayLobby2A_ReceiveLobbyMessage
877 ( LPDIRECTPLAYLOBBY2A
this,
880 LPDWORD lpdwMessageFlags
,
882 LPDWORD lpdwDataSize
)
884 return IDirectPlayLobbyA_ReceiveLobbyMessage( (LPDIRECTPLAYLOBBYA
)this, dwFlags
, dwAppID
,
885 lpdwMessageFlags
, lpData
, lpdwDataSize
);
889 static HRESULT WINAPI IDirectPlayLobbyW_ReceiveLobbyMessage
890 ( LPDIRECTPLAYLOBBY
this,
893 LPDWORD lpdwMessageFlags
,
895 LPDWORD lpdwDataSize
)
897 FIXME( dplay
, ":stub %p %08lx %08lx %p %p %p\n", this, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
899 return DPERR_OUTOFMEMORY
;
902 static HRESULT WINAPI IDirectPlayLobby2W_ReceiveLobbyMessage
903 ( LPDIRECTPLAYLOBBY2
this,
906 LPDWORD lpdwMessageFlags
,
908 LPDWORD lpdwDataSize
)
910 return IDirectPlayLobbyW_ReceiveLobbyMessage( (LPDIRECTPLAYLOBBY
)this, dwFlags
, dwAppID
,
911 lpdwMessageFlags
, lpData
, lpdwDataSize
);
914 /********************************************************************
916 * Starts an application and passes to it all the information to
917 * connect to a session.
920 static HRESULT WINAPI IDirectPlayLobbyA_RunApplication
921 ( LPDIRECTPLAYLOBBYA
this,
924 LPDPLCONNECTION lpConn
,
925 HANDLE32 hReceiveEvent
)
927 FIXME( dplay
, ":stub\n");
928 return DPERR_OUTOFMEMORY
;
931 static HRESULT WINAPI IDirectPlayLobby2A_RunApplication
932 ( LPDIRECTPLAYLOBBY2A
this,
935 LPDPLCONNECTION lpConn
,
936 HANDLE32 hReceiveEvent
)
938 return IDirectPlayLobbyA_RunApplication( (LPDIRECTPLAYLOBBYA
)this, dwFlags
,
939 lpdwAppID
, lpConn
, hReceiveEvent
);
942 static HRESULT WINAPI IDirectPlayLobbyW_RunApplication
943 ( LPDIRECTPLAYLOBBY
this,
946 LPDPLCONNECTION lpConn
,
947 HANDLE32 hReceiveEvent
)
949 FIXME( dplay
, ":stub\n");
950 return DPERR_OUTOFMEMORY
;
953 static HRESULT WINAPI IDirectPlayLobby2W_RunApplication
954 ( LPDIRECTPLAYLOBBY2
this,
957 LPDPLCONNECTION lpConn
,
958 HANDLE32 hReceiveEvent
)
960 return IDirectPlayLobbyW_RunApplication( (LPDIRECTPLAYLOBBY
)this, dwFlags
,
961 lpdwAppID
, lpConn
, hReceiveEvent
);
965 /********************************************************************
967 * Sends a message between the application and the lobby client.
968 * All messages are queued until received.
971 static HRESULT WINAPI IDirectPlayLobbyA_SendLobbyMessage
972 ( LPDIRECTPLAYLOBBYA
this,
978 FIXME( dplay
, ":stub\n");
979 return DPERR_OUTOFMEMORY
;
982 static HRESULT WINAPI IDirectPlayLobby2A_SendLobbyMessage
983 ( LPDIRECTPLAYLOBBY2A
this,
989 return IDirectPlayLobbyA_SendLobbyMessage( (LPDIRECTPLAYLOBBYA
)this, dwFlags
,
990 dwAppID
, lpData
, dwDataSize
);
994 static HRESULT WINAPI IDirectPlayLobbyW_SendLobbyMessage
995 ( LPDIRECTPLAYLOBBY
this,
1001 FIXME( dplay
, ":stub\n");
1002 return DPERR_OUTOFMEMORY
;
1005 static HRESULT WINAPI IDirectPlayLobby2W_SendLobbyMessage
1006 ( LPDIRECTPLAYLOBBY2
this,
1012 return IDirectPlayLobbyW_SendLobbyMessage( (LPDIRECTPLAYLOBBY
)this, dwFlags
,
1013 dwAppID
, lpData
, dwDataSize
);
1016 /********************************************************************
1018 * Modifies the DPLCONNECTION structure to contain all information
1019 * needed to start and connect an application.
1022 static HRESULT WINAPI IDirectPlayLobbyW_SetConnectionSettings
1023 ( LPDIRECTPLAYLOBBY
this,
1026 LPDPLCONNECTION lpConn
)
1028 FIXME( dplay
, ": this=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p: semi stub\n",
1029 this, dwFlags
, dwAppID
, lpConn
);
1031 /* Paramater check */
1032 if( dwFlags
|| !this || !lpConn
)
1034 ERR( dplay
, "invalid parameters.\n");
1035 return DPERR_INVALIDPARAMS
;
1038 /* See if there is a connection associated with this request.
1039 * dwAppID == 0 indicates that this request isn't associated with a connection.
1043 FIXME( dplay
, ": Connection dwAppID=%08lx given. Not implemented yet.\n",
1046 /* Need to add a check for this application Id...*/
1047 return DPERR_NOTLOBBIED
;
1050 if( lpConn
->dwSize
!= sizeof(DPLCONNECTION
) )
1052 ERR( dplay
, ": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
1053 lpConn
->dwSize
, sizeof( DPLCONNECTION
) );
1054 return DPERR_INVALIDPARAMS
;
1057 /* Need to investigate the lpConn->lpSessionDesc to figure out
1058 * what type of session we need to join/create.
1060 if( (!lpConn
->lpSessionDesc
) ||
1061 ( lpConn
->lpSessionDesc
->dwSize
!= sizeof( DPSESSIONDESC2
) )
1064 ERR( dplay
, "DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
1065 lpConn
->lpSessionDesc
->dwSize
, sizeof( DPSESSIONDESC2
) );
1066 return DPERR_INVALIDPARAMS
;
1069 /* Need to actually store the stuff here */
1071 return DPERR_OUTOFMEMORY
;
1074 static HRESULT WINAPI IDirectPlayLobby2W_SetConnectionSettings
1075 ( LPDIRECTPLAYLOBBY2
this,
1078 LPDPLCONNECTION lpConn
)
1080 return IDirectPlayLobbyW_SetConnectionSettings( (LPDIRECTPLAYLOBBY
)this,
1081 dwFlags
, dwAppID
, lpConn
);
1084 static HRESULT WINAPI IDirectPlayLobbyA_SetConnectionSettings
1085 ( LPDIRECTPLAYLOBBYA
this,
1088 LPDPLCONNECTION lpConn
)
1090 FIXME( dplay
, ": this=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p: stub\n",
1091 this, dwFlags
, dwAppID
, lpConn
);
1092 return DPERR_OUTOFMEMORY
;
1095 static HRESULT WINAPI IDirectPlayLobby2A_SetConnectionSettings
1096 ( LPDIRECTPLAYLOBBY2A
this,
1099 LPDPLCONNECTION lpConn
)
1101 return IDirectPlayLobbyA_SetConnectionSettings( (LPDIRECTPLAYLOBBYA
)this,
1102 dwFlags
, dwAppID
, lpConn
);
1105 /********************************************************************
1107 * Registers an event that will be set when a lobby message is received.
1110 static HRESULT WINAPI IDirectPlayLobbyA_SetLobbyMessageEvent
1111 ( LPDIRECTPLAYLOBBYA
this,
1114 HANDLE32 hReceiveEvent
)
1116 FIXME( dplay
, ":stub\n");
1117 return DPERR_OUTOFMEMORY
;
1120 static HRESULT WINAPI IDirectPlayLobby2A_SetLobbyMessageEvent
1121 ( LPDIRECTPLAYLOBBY2A
this,
1124 HANDLE32 hReceiveEvent
)
1126 return IDirectPlayLobbyA_SetLobbyMessageEvent( (LPDIRECTPLAYLOBBYA
)this, dwFlags
,
1127 dwAppID
, hReceiveEvent
);
1130 static HRESULT WINAPI IDirectPlayLobbyW_SetLobbyMessageEvent
1131 ( LPDIRECTPLAYLOBBY
this,
1134 HANDLE32 hReceiveEvent
)
1136 FIXME( dplay
, ":stub\n");
1137 return DPERR_OUTOFMEMORY
;
1140 static HRESULT WINAPI IDirectPlayLobby2W_SetLobbyMessageEvent
1141 ( LPDIRECTPLAYLOBBY2
this,
1144 HANDLE32 hReceiveEvent
)
1146 return IDirectPlayLobbyW_SetLobbyMessageEvent( (LPDIRECTPLAYLOBBY
)this, dwFlags
,
1147 dwAppID
, hReceiveEvent
);
1151 /********************************************************************
1153 * Registers an event that will be set when a lobby message is received.
1156 static HRESULT WINAPI IDirectPlayLobby2W_CreateCompoundAddress
1157 ( LPDIRECTPLAYLOBBY2
this,
1158 LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1159 DWORD dwElementCount
,
1161 LPDWORD lpdwAddressSize
)
1163 FIXME( dplay
, ":stub\n");
1164 return DPERR_OUTOFMEMORY
;
1167 static HRESULT WINAPI IDirectPlayLobby2A_CreateCompoundAddress
1168 ( LPDIRECTPLAYLOBBY2A
this,
1169 LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1170 DWORD dwElementCount
,
1172 LPDWORD lpdwAddressSize
)
1174 FIXME( dplay
, ":stub\n");
1175 return DPERR_OUTOFMEMORY
;
1179 /* Direct Play Lobby 1 (ascii) Virtual Table for methods */
1180 static struct tagLPDIRECTPLAYLOBBY_VTABLE directPlayLobbyAVT
= {
1181 IDirectPlayLobbyA_QueryInterface
,
1182 IDirectPlayLobbyA_AddRef
,
1183 IDirectPlayLobbyA_Release
,
1184 IDirectPlayLobbyA_Connect
,
1185 IDirectPlayLobbyA_CreateAddress
,
1186 IDirectPlayLobbyA_EnumAddress
,
1187 IDirectPlayLobbyA_EnumAddressTypes
,
1188 IDirectPlayLobbyA_EnumLocalApplications
,
1189 IDirectPlayLobbyA_GetConnectionSettings
,
1190 IDirectPlayLobbyA_ReceiveLobbyMessage
,
1191 IDirectPlayLobbyA_RunApplication
,
1192 IDirectPlayLobbyA_SendLobbyMessage
,
1193 IDirectPlayLobbyA_SetConnectionSettings
,
1194 IDirectPlayLobbyA_SetLobbyMessageEvent
1197 /* Direct Play Lobby 1 (unicode) Virtual Table for methods */
1198 static struct tagLPDIRECTPLAYLOBBY_VTABLE directPlayLobbyWVT
= {
1199 IDirectPlayLobbyW_QueryInterface
,
1200 IDirectPlayLobbyW_AddRef
,
1201 IDirectPlayLobbyW_Release
,
1202 IDirectPlayLobbyW_Connect
,
1203 IDirectPlayLobbyW_CreateAddress
,
1204 IDirectPlayLobbyW_EnumAddress
,
1205 IDirectPlayLobbyW_EnumAddressTypes
,
1206 IDirectPlayLobbyW_EnumLocalApplications
,
1207 IDirectPlayLobbyW_GetConnectionSettings
,
1208 IDirectPlayLobbyW_ReceiveLobbyMessage
,
1209 IDirectPlayLobbyW_RunApplication
,
1210 IDirectPlayLobbyW_SendLobbyMessage
,
1211 IDirectPlayLobbyW_SetConnectionSettings
,
1212 IDirectPlayLobbyW_SetLobbyMessageEvent
1216 /* Direct Play Lobby 2 (ascii) Virtual Table for methods */
1217 static struct tagLPDIRECTPLAYLOBBY2_VTABLE directPlayLobby2AVT
= {
1218 IDirectPlayLobby2A_QueryInterface
,
1219 IDirectPlayLobby2A_AddRef
,
1220 IDirectPlayLobby2A_Release
,
1221 IDirectPlayLobby2A_Connect
,
1222 IDirectPlayLobby2A_CreateAddress
,
1223 IDirectPlayLobby2A_EnumAddress
,
1224 IDirectPlayLobby2A_EnumAddressTypes
,
1225 IDirectPlayLobby2A_EnumLocalApplications
,
1226 IDirectPlayLobby2A_GetConnectionSettings
,
1227 IDirectPlayLobby2A_ReceiveLobbyMessage
,
1228 IDirectPlayLobby2A_RunApplication
,
1229 IDirectPlayLobby2A_SendLobbyMessage
,
1230 IDirectPlayLobby2A_SetConnectionSettings
,
1231 IDirectPlayLobby2A_SetLobbyMessageEvent
,
1232 IDirectPlayLobby2A_CreateCompoundAddress
1235 /* Direct Play Lobby 2 (unicode) Virtual Table for methods */
1236 static struct tagLPDIRECTPLAYLOBBY2_VTABLE directPlayLobby2WVT
= {
1237 IDirectPlayLobby2W_QueryInterface
,
1238 IDirectPlayLobby2W_AddRef
,
1239 IDirectPlayLobby2W_Release
,
1240 IDirectPlayLobby2W_Connect
,
1241 IDirectPlayLobby2W_CreateAddress
,
1242 IDirectPlayLobby2W_EnumAddress
,
1243 IDirectPlayLobby2W_EnumAddressTypes
,
1244 IDirectPlayLobby2W_EnumLocalApplications
,
1245 IDirectPlayLobby2W_GetConnectionSettings
,
1246 IDirectPlayLobby2W_ReceiveLobbyMessage
,
1247 IDirectPlayLobby2W_RunApplication
,
1248 IDirectPlayLobby2W_SendLobbyMessage
,
1249 IDirectPlayLobby2W_SetConnectionSettings
,
1250 IDirectPlayLobby2W_SetLobbyMessageEvent
,
1251 IDirectPlayLobby2W_CreateCompoundAddress
1254 /***************************************************************************
1255 * DirectPlayLobbyCreateA (DPLAYX.4)
1258 HRESULT WINAPI
DirectPlayLobbyCreateA( LPGUID lpGUIDDSP
,
1259 LPDIRECTPLAYLOBBYA
*lplpDPL
,
1264 TRACE(dplay
,"lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
1265 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
1267 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
1268 * equal 0. These fields are mostly for future expansion.
1270 if ( lpGUIDDSP
|| lpUnk
|| lpData
|| dwDataSize
)
1273 return DPERR_INVALIDPARAMS
;
1276 /* Yes...really we should bre returning a lobby 1 object */
1277 *lplpDPL
= (LPDIRECTPLAYLOBBYA
)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
1278 sizeof( IDirectPlayLobbyA
) );
1282 return DPERR_OUTOFMEMORY
;
1285 (*lplpDPL
)->lpVtbl
= &directPlayLobbyAVT
;
1286 (*lplpDPL
)->ref
= 1;
1288 (*lplpDPL
)->lpSession
= (LPDPLCONNECTION
)HeapAlloc( GetProcessHeap(),
1290 sizeof( DPLCONNECTION
) );
1291 (*lplpDPL
)->lpSession
->dwSize
= sizeof( DPLCONNECTION
);
1293 (*lplpDPL
)->lpSession
->lpSessionDesc
= (LPDPSESSIONDESC2
)HeapAlloc(
1294 GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( DPSESSIONDESC2
) );
1295 (*lplpDPL
)->lpSession
->lpSessionDesc
->dwSize
= sizeof( DPSESSIONDESC2
);
1300 /***************************************************************************
1301 * DirectPlayLobbyCreateW (DPLAYX.5)
1304 HRESULT WINAPI
DirectPlayLobbyCreateW( LPGUID lpGUIDDSP
,
1305 LPDIRECTPLAYLOBBY
*lplpDPL
,
1310 TRACE(dplay
,"lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
1311 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
1313 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
1314 * equal 0. These fields are mostly for future expansion.
1316 if ( lpGUIDDSP
|| lpUnk
|| lpData
|| dwDataSize
)
1319 ERR( dplay
, "Bad parameters!\n" );
1320 return DPERR_INVALIDPARAMS
;
1323 /* Yes...really we should bre returning a lobby 1 object */
1324 *lplpDPL
= (LPDIRECTPLAYLOBBY
)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
1325 sizeof( IDirectPlayLobby
) );
1329 return DPERR_OUTOFMEMORY
;
1332 (*lplpDPL
)->lpVtbl
= &directPlayLobbyWVT
;
1333 (*lplpDPL
)->ref
= 1;
1336 (*lplpDPL
)->lpSession
= (LPDPLCONNECTION
)HeapAlloc( GetProcessHeap(),
1338 sizeof( DPLCONNECTION
) );
1339 (*lplpDPL
)->lpSession
->dwSize
= sizeof( DPLCONNECTION
);
1340 (*lplpDPL
)->lpSession
->lpSessionDesc
= (LPDPSESSIONDESC2
)HeapAlloc(
1341 GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( DPSESSIONDESC2
) );
1342 (*lplpDPL
)->lpSession
->lpSessionDesc
->dwSize
= sizeof( DPSESSIONDESC2
);
1348 /***************************************************************************
1349 * DirectPlayEnumerateA (DPLAYX.2)
1351 * The pointer to the structure lpContext will be filled with the
1352 * appropriate data for each service offered by the OS. These services are
1353 * not necessarily available on this particular machine but are defined
1354 * as simple service providers under the "Service Providers" registry key.
1355 * This structure is then passed to lpEnumCallback for each of the different
1358 * This API is useful only for applications written using DirectX3 or
1359 * worse. It is superceeded by IDirectPlay3::EnumConnections which also
1360 * gives information on the actual connections.
1362 * defn of a service provider:
1363 * A dynamic-link library used by DirectPlay to communicate over a network.
1364 * The service provider contains all the network-specific code required
1365 * to send and receive messages. Online services and network operators can
1366 * supply service providers to use specialized hardware, protocols, communications
1367 * media, and network resources.
1369 * TODO: Allocate string buffer space from the heap (length from reg)
1370 * Pass real device driver numbers...
1371 * Get the GUID properly...
1373 HRESULT WINAPI
DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback
,
1378 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
1379 LPSTR guidDataSubKey
= "Guid";
1380 LPSTR majVerDataSubKey
= "dwReserved1";
1381 DWORD dwIndex
, sizeOfSubKeyName
=50;
1382 char subKeyName
[51];
1384 TRACE( dplay
, ": lpEnumCallback=%p lpContext=%p\n", lpEnumCallback
, lpContext
);
1386 if( !lpEnumCallback
|| !*lpEnumCallback
)
1388 return DPERR_INVALIDPARAMS
;
1391 /* Need to loop over the service providers in the registry */
1392 if( RegOpenKeyEx32A( HKEY_LOCAL_MACHINE
, searchSubKey
,
1393 0, KEY_ENUMERATE_SUB_KEYS
, &hkResult
) != ERROR_SUCCESS
)
1395 /* Hmmm. Does this mean that there are no service providers? */
1396 ERR(dplay
, ": no service providers?\n");
1400 /* Traverse all the service providers we have available */
1402 RegEnumKey32A( hkResult
, dwIndex
, subKeyName
, sizeOfSubKeyName
) !=
1403 ERROR_NO_MORE_ITEMS
;
1406 HKEY hkServiceProvider
;
1407 GUID serviceProviderGUID
;
1408 DWORD returnTypeGUID
, returnTypeReserved1
, sizeOfReturnBuffer
=50;
1409 char returnBuffer
[51];
1410 DWORD majVersionNum
, minVersionNum
;
1411 LPWSTR lpWGUIDString
;
1413 TRACE( dplay
, " this time through: %s\n", subKeyName
);
1415 /* Get a handle for this particular service provider */
1416 if( RegOpenKeyEx32A( hkResult
, subKeyName
, 0, KEY_QUERY_VALUE
,
1417 &hkServiceProvider
) != ERROR_SUCCESS
)
1419 ERR( dplay
, ": what the heck is going on?\n" );
1423 /* Get the GUID, Device major number and device minor number
1424 * from the registry.
1426 if( RegQueryValueEx32A( hkServiceProvider
, guidDataSubKey
,
1427 NULL
, &returnTypeGUID
, returnBuffer
,
1428 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1430 ERR( dplay
, ": missing GUID registry data members\n" );
1434 /* FIXME: Check return types to ensure we're interpreting data right */
1435 lpWGUIDString
= HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer
);
1436 CLSIDFromString32( (LPCOLESTR32
)lpWGUIDString
, &serviceProviderGUID
);
1437 HeapFree( GetProcessHeap(), 0, lpWGUIDString
);
1439 sizeOfReturnBuffer
= 50;
1441 if( RegQueryValueEx32A( hkServiceProvider
, majVerDataSubKey
,
1442 NULL
, &returnTypeReserved1
, returnBuffer
,
1443 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1445 ERR( dplay
, ": missing dwReserved1 registry data members\n") ;
1448 /* FIXME: This couldn't possibly be right...*/
1449 majVersionNum
= GET_DWORD( returnBuffer
);
1451 /* The enumeration will return FALSE if we are not to continue */
1452 if( !lpEnumCallback( &serviceProviderGUID
, subKeyName
,
1453 majVersionNum
, (DWORD
)0, lpContext
) )
1455 WARN( dplay
, "lpEnumCallback returning FALSE\n" );
1464 /***************************************************************************
1465 * DirectPlayEnumerateW (DPLAYX.3)
1468 HRESULT WINAPI
DirectPlayEnumerateW( LPDPENUMDPCALLBACKW lpEnumCallback
, LPVOID lpContext
)
1471 FIXME( dplay
, ":stub\n");
1473 return DPERR_OUTOFMEMORY
;
1477 /***************************************************************************
1478 * DirectPlayCreate (DPLAYX.1) (DPLAY.1)
1481 HRESULT WINAPI DirectPlayCreate
1482 ( LPGUID lpGUID
, LPDIRECTPLAY2
*lplpDP
, IUnknown
*pUnk
)
1485 FIXME( dplay
, ":stub\n");
1486 return DPERR_OUTOFMEMORY
;
1492 /* Hmmm...wonder what this means! */
1493 ERR(dplay
, "What does a NULL here mean?\n" );
1494 return DPERR_OUTOFMEMORY
;
1497 *lplpDP
= (LPDIRECTPLAY
)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
1498 sizeof( **lplpDP
) );
1502 return DPERR_OUTOFMEMORY
;
1505 (*lplpDP
)->lpVtbl
= &directPlay2AVT
;