Small atom fixes.
[wine/multimedia.git] / multimedia / dplay.c
blob61eccf283f1e985021fc8ff08c802a32391d7271
1 /* Direct Play 3 and Direct Play Lobby 2 Implementation
3 * Copyright 1998 - Peter Hunnisett
5 * <presently under construction - contact hunnise@nortel.ca>
7 */
8 #include "interfaces.h"
9 #include "heap.h"
10 #include "winerror.h"
11 #include "debug.h"
12 #include "winnt.h"
13 #include "winreg.h"
14 #include "compobj.h"
15 #include "dplay.h"
17 #include "thread.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;
25 ULONG ref;
26 LPDPLCONNECTION lpSession;
29 struct IDirectPlayLobby2 {
30 LPDIRECTPLAYLOBBY2_VTABLE lpVtbl;
31 ULONG ref;
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;
42 struct IDirectPlay2 {
43 LPDIRECTPLAY2_VTABLE lpVtbl;
44 ULONG ref;
47 struct IDirectPlay3 {
48 LPDIRECTPLAY3_VTABLE lpVtbl;
49 ULONG ref;
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" );
67 if( !toDelete )
68 return;
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 );
101 toDelete = NULL;
105 #if 0
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" );
113 if( !src )
115 /* Nothing to copy...hmmm...*/
116 ERR( dplay, "nothing to copy\n" );
117 return;
120 /* Copy DPLCONNECTION struct. If dest isn't NULL then we have a DPLCONNECTION
121 struct but that's it
123 if( dest == NULL )
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 */
173 if( src->lpAddress )
175 /* What do we do here? */
180 #endif
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" );
191 /*for(;;)*/
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;
250 ExitThread(0);
251 return 0;
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,
289 REFIID riid,
290 LPVOID* ppvObj )
292 return DPERR_OUTOFMEMORY;
295 static HRESULT WINAPI IDirectPlayLobbyW_QueryInterface
296 ( LPDIRECTPLAYLOBBY this,
297 REFIID riid,
298 LPVOID* ppvObj )
300 return DPERR_OUTOFMEMORY;
303 static HRESULT WINAPI IDirectPlayLobby2A_QueryInterface
304 ( LPDIRECTPLAYLOBBY2A this,
305 REFIID riid,
306 LPVOID* ppvObj )
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 );
316 *ppvObj = this;
317 return S_OK;
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 ) );
327 if( !lpDpL )
329 return E_NOINTERFACE;
332 lpDpL->lpVtbl = &directPlayLobby2WVT;
333 lpDpL->ref = 1;
335 return S_OK;
338 /* Unexpected interface request! */
339 *ppvObj = NULL;
340 return E_NOINTERFACE;
343 static HRESULT WINAPI IDirectPlayLobby2W_QueryInterface
344 ( LPDIRECTPLAYLOBBY2 this,
345 REFIID riid,
346 LPVOID* ppvObj )
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 );
357 *ppvObj = this;
358 return S_OK;
360 else if( IsEqualGUID( &IID_IDirectPlayLobby2A, riid ) )
362 LPDIRECTPLAYLOBBY2A lpDpL = (LPDIRECTPLAYLOBBY2A)(*ppvObj);
364 lpDpL = (LPDIRECTPLAYLOBBY2A)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
365 sizeof( IDirectPlayLobby2A ) );
367 if( !lpDpL )
369 return E_NOINTERFACE;
372 lpDpL->lpVtbl = &directPlayLobby2AVT;
373 lpDpL->ref = 1;
375 return S_OK;
378 /* Unexpected interface request! */
379 *ppvObj = NULL;
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 )
391 ++(this->ref);
392 TRACE( dplay,"ref count now %lu\n", this->ref );
393 return (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
417 * memory.
419 static ULONG WINAPI IDirectPlayLobbyA_Release
420 ( LPDIRECTPLAYLOBBYA this )
422 TRACE( dplay, "ref count decremeneted from %lu\n", this->ref );
424 this->ref--;
426 /* Deallocate if this is the last reference to the object */
427 if( !(this->ref) )
429 deleteDPConnection( &(this->lpSession) );
430 HeapFree( GetProcessHeap(), 0, this );
431 return S_OK;
434 return this->ref;
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,
465 DWORD dwFlags,
466 LPDIRECTPLAY* lplpDP,
467 IUnknown* pUnk)
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,
475 DWORD dwFlags,
476 LPDIRECTPLAY* lplpDP,
477 IUnknown* pUnk)
479 return IDirectPlayLobbyA_Connect( (LPDIRECTPLAYLOBBYA)this, dwFlags, lplpDP, pUnk );
482 static HRESULT WINAPI IDirectPlayLobbyW_Connect
483 ( LPDIRECTPLAYLOBBY this,
484 DWORD dwFlags,
485 LPDIRECTPLAY* lplpDP,
486 IUnknown* pUnk)
488 LPDIRECTPLAY2A directPlay2A;
489 LPDIRECTPLAY2 directPlay2W;
490 HRESULT createRC;
492 FIXME( dplay, ": dwFlags=%08lx %p %p stub\n", dwFlags, lplpDP, pUnk );
494 #if 0
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 );
504 return createRC;
507 /* All the stuff below this is WRONG! */
508 if( this->lpSession->dwFlags == DPLCONNECTION_CREATESESSION )
510 DWORD threadIdSink;
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",
526 lpConn->dwFlags );
528 return DPERR_OUTOFMEMORY;
531 /* This does the work of the following methods...
532 IDirectPlay3::InitializeConnection,
533 IDirectPlay3::EnumSessions,
534 IDirectPlay3::Open
538 #endif
540 return DP_OK;
544 static HRESULT WINAPI IDirectPlayLobby2W_Connect
545 ( LPDIRECTPLAYLOBBY2 this,
546 DWORD dwFlags,
547 LPDIRECTPLAY* lplpDP,
548 IUnknown* pUnk)
550 return IDirectPlayLobbyW_Connect( (LPDIRECTPLAYLOBBY)this, dwFlags, lplpDP, pUnk );
553 /********************************************************************
555 * Creates a DirectPlay Address, given a service provider-specific network
556 * address.
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,
564 REFGUID guidSP,
565 REFGUID guidDataType,
566 LPCVOID lpData,
567 DWORD dwDataSize,
568 LPVOID lpAddress,
569 LPDWORD lpdwAddressSize )
571 FIXME( dplay, ":stub\n");
572 return DPERR_OUTOFMEMORY;
575 static HRESULT WINAPI IDirectPlayLobby2A_CreateAddress
576 ( LPDIRECTPLAYLOBBY2A this,
577 REFGUID guidSP,
578 REFGUID guidDataType,
579 LPCVOID lpData,
580 DWORD dwDataSize,
581 LPVOID lpAddress,
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,
590 REFGUID guidSP,
591 REFGUID guidDataType,
592 LPCVOID lpData,
593 DWORD dwDataSize,
594 LPVOID lpAddress,
595 LPDWORD lpdwAddressSize )
597 FIXME( dplay, ":stub\n");
598 return DPERR_OUTOFMEMORY;
602 static HRESULT WINAPI IDirectPlayLobby2W_CreateAddress
603 ( LPDIRECTPLAYLOBBY2 this,
604 REFGUID guidSP,
605 REFGUID guidDataType,
606 LPCVOID lpData,
607 DWORD dwDataSize,
608 LPVOID lpAddress,
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,
625 LPCVOID lpAddress,
626 DWORD dwAddressSize,
627 LPVOID lpContext )
629 FIXME( dplay, ":stub\n");
630 return DPERR_OUTOFMEMORY;
633 static HRESULT WINAPI IDirectPlayLobby2A_EnumAddress
634 ( LPDIRECTPLAYLOBBY2A this,
635 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
636 LPCVOID lpAddress,
637 DWORD dwAddressSize,
638 LPVOID lpContext )
640 return IDirectPlayLobbyA_EnumAddress( (LPDIRECTPLAYLOBBYA)this, lpEnumAddressCallback,
641 lpAddress, dwAddressSize, lpContext );
644 static HRESULT WINAPI IDirectPlayLobbyW_EnumAddress
645 ( LPDIRECTPLAYLOBBY this,
646 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
647 LPCVOID lpAddress,
648 DWORD dwAddressSize,
649 LPVOID lpContext )
651 FIXME( dplay, ":stub\n");
652 return DPERR_OUTOFMEMORY;
655 static HRESULT WINAPI IDirectPlayLobby2W_EnumAddress
656 ( LPDIRECTPLAYLOBBY2 this,
657 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
658 LPCVOID lpAddress,
659 DWORD dwAddressSize,
660 LPVOID lpContext )
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,
676 REFGUID guidSP,
677 LPVOID lpContext,
678 DWORD dwFlags )
680 FIXME( dplay, ":stub\n");
681 return DPERR_OUTOFMEMORY;
684 static HRESULT WINAPI IDirectPlayLobby2A_EnumAddressTypes
685 ( LPDIRECTPLAYLOBBY2A this,
686 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
687 REFGUID guidSP,
688 LPVOID lpContext,
689 DWORD dwFlags )
691 return IDirectPlayLobbyA_EnumAddressTypes( (LPDIRECTPLAYLOBBYA)this, lpEnumAddressTypeCallback,
692 guidSP, lpContext, dwFlags );
695 static HRESULT WINAPI IDirectPlayLobbyW_EnumAddressTypes
696 ( LPDIRECTPLAYLOBBY this,
697 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
698 REFGUID guidSP,
699 LPVOID lpContext,
700 DWORD dwFlags )
702 FIXME( dplay, ":stub\n");
703 return DPERR_OUTOFMEMORY;
706 static HRESULT WINAPI IDirectPlayLobby2W_EnumAddressTypes
707 ( LPDIRECTPLAYLOBBY2 this,
708 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
709 REFGUID guidSP,
710 LPVOID lpContext,
711 DWORD dwFlags )
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,
727 LPVOID lpContext,
728 DWORD dwFlags )
730 FIXME( dplay, ":stub\n");
731 return DPERR_OUTOFMEMORY;
734 static HRESULT WINAPI IDirectPlayLobby2W_EnumLocalApplications
735 ( LPDIRECTPLAYLOBBY2 this,
736 LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
737 LPVOID lpContext,
738 DWORD dwFlags )
740 return IDirectPlayLobbyW_EnumLocalApplications( (LPDIRECTPLAYLOBBY)this, a,
741 lpContext, dwFlags );
744 static HRESULT WINAPI IDirectPlayLobbyA_EnumLocalApplications
745 ( LPDIRECTPLAYLOBBYA this,
746 LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
747 LPVOID lpContext,
748 DWORD dwFlags )
750 FIXME( dplay, ":stub\n");
751 return DPERR_OUTOFMEMORY;
754 static HRESULT WINAPI IDirectPlayLobby2A_EnumLocalApplications
755 ( LPDIRECTPLAYLOBBY2A this,
756 LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
757 LPVOID lpContext,
758 DWORD dwFlags )
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,
777 DWORD dwAppID,
778 LPVOID lpData,
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 */
784 if ( !lpData )
786 /* Let's check the size of the buffer that the application has allocated */
787 if( *lpdwDataSize >= sizeof( DPLCONNECTION ) )
789 return DP_OK;
791 else
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) ) );
805 return DP_OK;
808 static HRESULT WINAPI IDirectPlayLobby2A_GetConnectionSettings
809 ( LPDIRECTPLAYLOBBY2A this,
810 DWORD dwAppID,
811 LPVOID lpData,
812 LPDWORD lpdwDataSize )
814 return IDirectPlayLobbyA_GetConnectionSettings( (LPDIRECTPLAYLOBBYA)this,
815 dwAppID, lpData, lpdwDataSize );
818 static HRESULT WINAPI IDirectPlayLobbyW_GetConnectionSettings
819 ( LPDIRECTPLAYLOBBY this,
820 DWORD dwAppID,
821 LPVOID lpData,
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 */
827 if ( !lpData )
829 /* Let's check the size of the buffer that the application has allocated */
830 if( *lpdwDataSize >= sizeof( DPLCONNECTION ) )
832 return DP_OK;
834 else
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) ) );
844 return DP_OK;
847 static HRESULT WINAPI IDirectPlayLobby2W_GetConnectionSettings
848 ( LPDIRECTPLAYLOBBY2 this,
849 DWORD dwAppID,
850 LPVOID lpData,
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,
865 DWORD dwFlags,
866 DWORD dwAppID,
867 LPDWORD lpdwMessageFlags,
868 LPVOID lpData,
869 LPDWORD lpdwDataSize )
871 FIXME( dplay, ":stub %p %08lx %08lx %p %p %p\n", this, dwFlags, dwAppID, lpdwMessageFlags, lpData,
872 lpdwDataSize );
873 return DPERR_OUTOFMEMORY;
876 static HRESULT WINAPI IDirectPlayLobby2A_ReceiveLobbyMessage
877 ( LPDIRECTPLAYLOBBY2A this,
878 DWORD dwFlags,
879 DWORD dwAppID,
880 LPDWORD lpdwMessageFlags,
881 LPVOID lpData,
882 LPDWORD lpdwDataSize )
884 return IDirectPlayLobbyA_ReceiveLobbyMessage( (LPDIRECTPLAYLOBBYA)this, dwFlags, dwAppID,
885 lpdwMessageFlags, lpData, lpdwDataSize );
889 static HRESULT WINAPI IDirectPlayLobbyW_ReceiveLobbyMessage
890 ( LPDIRECTPLAYLOBBY this,
891 DWORD dwFlags,
892 DWORD dwAppID,
893 LPDWORD lpdwMessageFlags,
894 LPVOID lpData,
895 LPDWORD lpdwDataSize )
897 FIXME( dplay, ":stub %p %08lx %08lx %p %p %p\n", this, dwFlags, dwAppID, lpdwMessageFlags, lpData,
898 lpdwDataSize );
899 return DPERR_OUTOFMEMORY;
902 static HRESULT WINAPI IDirectPlayLobby2W_ReceiveLobbyMessage
903 ( LPDIRECTPLAYLOBBY2 this,
904 DWORD dwFlags,
905 DWORD dwAppID,
906 LPDWORD lpdwMessageFlags,
907 LPVOID lpData,
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,
922 DWORD dwFlags,
923 LPDWORD lpdwAppID,
924 LPDPLCONNECTION lpConn,
925 HANDLE32 hReceiveEvent )
927 FIXME( dplay, ":stub\n");
928 return DPERR_OUTOFMEMORY;
931 static HRESULT WINAPI IDirectPlayLobby2A_RunApplication
932 ( LPDIRECTPLAYLOBBY2A this,
933 DWORD dwFlags,
934 LPDWORD lpdwAppID,
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,
944 DWORD dwFlags,
945 LPDWORD lpdwAppID,
946 LPDPLCONNECTION lpConn,
947 HANDLE32 hReceiveEvent )
949 FIXME( dplay, ":stub\n");
950 return DPERR_OUTOFMEMORY;
953 static HRESULT WINAPI IDirectPlayLobby2W_RunApplication
954 ( LPDIRECTPLAYLOBBY2 this,
955 DWORD dwFlags,
956 LPDWORD lpdwAppID,
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,
973 DWORD dwFlags,
974 DWORD dwAppID,
975 LPVOID lpData,
976 DWORD dwDataSize )
978 FIXME( dplay, ":stub\n");
979 return DPERR_OUTOFMEMORY;
982 static HRESULT WINAPI IDirectPlayLobby2A_SendLobbyMessage
983 ( LPDIRECTPLAYLOBBY2A this,
984 DWORD dwFlags,
985 DWORD dwAppID,
986 LPVOID lpData,
987 DWORD dwDataSize )
989 return IDirectPlayLobbyA_SendLobbyMessage( (LPDIRECTPLAYLOBBYA)this, dwFlags,
990 dwAppID, lpData, dwDataSize );
994 static HRESULT WINAPI IDirectPlayLobbyW_SendLobbyMessage
995 ( LPDIRECTPLAYLOBBY this,
996 DWORD dwFlags,
997 DWORD dwAppID,
998 LPVOID lpData,
999 DWORD dwDataSize )
1001 FIXME( dplay, ":stub\n");
1002 return DPERR_OUTOFMEMORY;
1005 static HRESULT WINAPI IDirectPlayLobby2W_SendLobbyMessage
1006 ( LPDIRECTPLAYLOBBY2 this,
1007 DWORD dwFlags,
1008 DWORD dwAppID,
1009 LPVOID lpData,
1010 DWORD dwDataSize )
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,
1024 DWORD dwFlags,
1025 DWORD dwAppID,
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.
1041 if( dwAppID )
1043 FIXME( dplay, ": Connection dwAppID=%08lx given. Not implemented yet.\n",
1044 dwAppID );
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,
1076 DWORD dwFlags,
1077 DWORD dwAppID,
1078 LPDPLCONNECTION lpConn )
1080 return IDirectPlayLobbyW_SetConnectionSettings( (LPDIRECTPLAYLOBBY)this,
1081 dwFlags, dwAppID, lpConn );
1084 static HRESULT WINAPI IDirectPlayLobbyA_SetConnectionSettings
1085 ( LPDIRECTPLAYLOBBYA this,
1086 DWORD dwFlags,
1087 DWORD dwAppID,
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,
1097 DWORD dwFlags,
1098 DWORD dwAppID,
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,
1112 DWORD dwFlags,
1113 DWORD dwAppID,
1114 HANDLE32 hReceiveEvent )
1116 FIXME( dplay, ":stub\n");
1117 return DPERR_OUTOFMEMORY;
1120 static HRESULT WINAPI IDirectPlayLobby2A_SetLobbyMessageEvent
1121 ( LPDIRECTPLAYLOBBY2A this,
1122 DWORD dwFlags,
1123 DWORD dwAppID,
1124 HANDLE32 hReceiveEvent )
1126 return IDirectPlayLobbyA_SetLobbyMessageEvent( (LPDIRECTPLAYLOBBYA)this, dwFlags,
1127 dwAppID, hReceiveEvent );
1130 static HRESULT WINAPI IDirectPlayLobbyW_SetLobbyMessageEvent
1131 ( LPDIRECTPLAYLOBBY this,
1132 DWORD dwFlags,
1133 DWORD dwAppID,
1134 HANDLE32 hReceiveEvent )
1136 FIXME( dplay, ":stub\n");
1137 return DPERR_OUTOFMEMORY;
1140 static HRESULT WINAPI IDirectPlayLobby2W_SetLobbyMessageEvent
1141 ( LPDIRECTPLAYLOBBY2 this,
1142 DWORD dwFlags,
1143 DWORD dwAppID,
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,
1160 LPVOID lpAddress,
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,
1171 LPVOID lpAddress,
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,
1260 IUnknown *lpUnk,
1261 LPVOID lpData,
1262 DWORD dwDataSize )
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 )
1272 *lplpDPL = NULL;
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 ) );
1280 if( ! (*lplpDPL) )
1282 return DPERR_OUTOFMEMORY;
1285 (*lplpDPL)->lpVtbl = &directPlayLobbyAVT;
1286 (*lplpDPL)->ref = 1;
1288 (*lplpDPL)->lpSession = (LPDPLCONNECTION)HeapAlloc( GetProcessHeap(),
1289 HEAP_ZERO_MEMORY,
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 );
1297 return DP_OK;
1300 /***************************************************************************
1301 * DirectPlayLobbyCreateW (DPLAYX.5)
1304 HRESULT WINAPI DirectPlayLobbyCreateW( LPGUID lpGUIDDSP,
1305 LPDIRECTPLAYLOBBY *lplpDPL,
1306 IUnknown *lpUnk,
1307 LPVOID lpData,
1308 DWORD dwDataSize )
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 )
1318 *lplpDPL = NULL;
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 ) );
1327 if( !*lplpDPL)
1329 return DPERR_OUTOFMEMORY;
1332 (*lplpDPL)->lpVtbl = &directPlayLobbyWVT;
1333 (*lplpDPL)->ref = 1;
1336 (*lplpDPL)->lpSession = (LPDPLCONNECTION)HeapAlloc( GetProcessHeap(),
1337 HEAP_ZERO_MEMORY,
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 );
1344 return DP_OK;
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
1356 * services.
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,
1374 LPVOID lpContext )
1377 HKEY hkResult;
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");
1397 return DP_OK;
1400 /* Traverse all the service providers we have available */
1401 for( dwIndex=0;
1402 RegEnumKey32A( hkResult, dwIndex, subKeyName, sizeOfSubKeyName ) !=
1403 ERROR_NO_MORE_ITEMS;
1404 ++dwIndex )
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" );
1420 continue;
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" );
1431 continue;
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") ;
1446 continue;
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" );
1456 break;
1460 return DP_OK;
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;
1488 TRACE(dplay,"\n" );
1490 if( pUnk != NULL )
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 ) );
1500 if( !*lplpDP )
1502 return DPERR_OUTOFMEMORY;
1505 (*lplpDP)->lpVtbl = &directPlay2AVT;
1506 (*lplpDP)->ref = 1;
1508 return DP_OK;