Do not clip source rectangle even by visible region for bitblts.
[wine/multimedia.git] / multimedia / dplay.c
blobe7316f86126b70e1c79c2db657fae4edff60597e
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"
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;
26 ULONG ref;
27 LPDPLCONNECTION lpSession;
30 struct IDirectPlayLobby2 {
31 LPDIRECTPLAYLOBBY2_VTABLE lpVtbl;
32 ULONG ref;
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;
43 struct IDirectPlay2 {
44 LPDIRECTPLAY2_VTABLE lpVtbl;
45 ULONG ref;
48 struct IDirectPlay3 {
49 LPDIRECTPLAY3_VTABLE lpVtbl;
50 ULONG ref;
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" );
68 if( !toDelete )
69 return;
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 );
102 toDelete = NULL;
106 #if 0
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" );
114 if( !src )
116 /* Nothing to copy...hmmm...*/
117 ERR( dplay, "nothing to copy\n" );
118 return;
121 /* Copy DPLCONNECTION struct. If dest isn't NULL then we have a DPLCONNECTION
122 struct but that's it
124 if( dest == NULL )
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 */
174 if( src->lpAddress )
176 /* What do we do here? */
181 #endif
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" );
192 /*for(;;)*/
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;
251 ExitThread(0);
252 return 0;
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,
290 REFIID riid,
291 LPVOID* ppvObj )
293 return DPERR_OUTOFMEMORY;
296 static HRESULT WINAPI IDirectPlayLobbyW_QueryInterface
297 ( LPDIRECTPLAYLOBBY this,
298 REFIID riid,
299 LPVOID* ppvObj )
301 return DPERR_OUTOFMEMORY;
304 static HRESULT WINAPI IDirectPlayLobby2A_QueryInterface
305 ( LPDIRECTPLAYLOBBY2A this,
306 REFIID riid,
307 LPVOID* ppvObj )
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 );
317 *ppvObj = this;
318 return S_OK;
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 ) );
328 if( !lpDpL )
330 return E_NOINTERFACE;
333 lpDpL->lpVtbl = &directPlayLobby2WVT;
334 lpDpL->ref = 1;
336 return S_OK;
339 /* Unexpected interface request! */
340 *ppvObj = NULL;
341 return E_NOINTERFACE;
344 static HRESULT WINAPI IDirectPlayLobby2W_QueryInterface
345 ( LPDIRECTPLAYLOBBY2 this,
346 REFIID riid,
347 LPVOID* ppvObj )
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 );
358 *ppvObj = this;
359 return S_OK;
361 else if( IsEqualGUID( &IID_IDirectPlayLobby2A, riid ) )
363 LPDIRECTPLAYLOBBY2A lpDpL = (LPDIRECTPLAYLOBBY2A)(*ppvObj);
365 lpDpL = (LPDIRECTPLAYLOBBY2A)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
366 sizeof( IDirectPlayLobby2A ) );
368 if( !lpDpL )
370 return E_NOINTERFACE;
373 lpDpL->lpVtbl = &directPlayLobby2AVT;
374 lpDpL->ref = 1;
376 return S_OK;
379 /* Unexpected interface request! */
380 *ppvObj = NULL;
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 )
392 ++(this->ref);
393 TRACE( dplay,"ref count now %lu\n", this->ref );
394 return (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
418 * memory.
420 static ULONG WINAPI IDirectPlayLobbyA_Release
421 ( LPDIRECTPLAYLOBBYA this )
423 TRACE( dplay, "ref count decremeneted from %lu\n", this->ref );
425 this->ref--;
427 /* Deallocate if this is the last reference to the object */
428 if( !(this->ref) )
430 deleteDPConnection( this->lpSession );
431 HeapFree( GetProcessHeap(), 0, this );
432 return S_OK;
435 return this->ref;
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,
466 DWORD dwFlags,
467 LPDIRECTPLAY* lplpDP,
468 IUnknown* pUnk)
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,
476 DWORD dwFlags,
477 LPDIRECTPLAY* lplpDP,
478 IUnknown* pUnk)
480 return IDirectPlayLobbyA_Connect( (LPDIRECTPLAYLOBBYA)this, dwFlags, lplpDP, pUnk );
483 static HRESULT WINAPI IDirectPlayLobbyW_Connect
484 ( LPDIRECTPLAYLOBBY this,
485 DWORD dwFlags,
486 LPDIRECTPLAY* lplpDP,
487 IUnknown* pUnk)
489 LPDIRECTPLAY2A directPlay2A;
490 LPDIRECTPLAY2 directPlay2W;
491 HRESULT createRC;
493 FIXME( dplay, ": dwFlags=%08lx %p %p stub\n", dwFlags, lplpDP, pUnk );
495 #if 0
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 );
505 return createRC;
508 /* All the stuff below this is WRONG! */
509 if( this->lpSession->dwFlags == DPLCONNECTION_CREATESESSION )
511 DWORD threadIdSink;
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",
527 lpConn->dwFlags );
529 return DPERR_OUTOFMEMORY;
532 /* This does the work of the following methods...
533 IDirectPlay3::InitializeConnection,
534 IDirectPlay3::EnumSessions,
535 IDirectPlay3::Open
539 #endif
541 return DP_OK;
545 static HRESULT WINAPI IDirectPlayLobby2W_Connect
546 ( LPDIRECTPLAYLOBBY2 this,
547 DWORD dwFlags,
548 LPDIRECTPLAY* lplpDP,
549 IUnknown* pUnk)
551 return IDirectPlayLobbyW_Connect( (LPDIRECTPLAYLOBBY)this, dwFlags, lplpDP, pUnk );
554 /********************************************************************
556 * Creates a DirectPlay Address, given a service provider-specific network
557 * address.
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,
565 REFGUID guidSP,
566 REFGUID guidDataType,
567 LPCVOID lpData,
568 DWORD dwDataSize,
569 LPVOID lpAddress,
570 LPDWORD lpdwAddressSize )
572 FIXME( dplay, ":stub\n");
573 return DPERR_OUTOFMEMORY;
576 static HRESULT WINAPI IDirectPlayLobby2A_CreateAddress
577 ( LPDIRECTPLAYLOBBY2A this,
578 REFGUID guidSP,
579 REFGUID guidDataType,
580 LPCVOID lpData,
581 DWORD dwDataSize,
582 LPVOID lpAddress,
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,
591 REFGUID guidSP,
592 REFGUID guidDataType,
593 LPCVOID lpData,
594 DWORD dwDataSize,
595 LPVOID lpAddress,
596 LPDWORD lpdwAddressSize )
598 FIXME( dplay, ":stub\n");
599 return DPERR_OUTOFMEMORY;
603 static HRESULT WINAPI IDirectPlayLobby2W_CreateAddress
604 ( LPDIRECTPLAYLOBBY2 this,
605 REFGUID guidSP,
606 REFGUID guidDataType,
607 LPCVOID lpData,
608 DWORD dwDataSize,
609 LPVOID lpAddress,
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,
626 LPCVOID lpAddress,
627 DWORD dwAddressSize,
628 LPVOID lpContext )
630 FIXME( dplay, ":stub\n");
631 return DPERR_OUTOFMEMORY;
634 static HRESULT WINAPI IDirectPlayLobby2A_EnumAddress
635 ( LPDIRECTPLAYLOBBY2A this,
636 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
637 LPCVOID lpAddress,
638 DWORD dwAddressSize,
639 LPVOID lpContext )
641 return IDirectPlayLobbyA_EnumAddress( (LPDIRECTPLAYLOBBYA)this, lpEnumAddressCallback,
642 lpAddress, dwAddressSize, lpContext );
645 static HRESULT WINAPI IDirectPlayLobbyW_EnumAddress
646 ( LPDIRECTPLAYLOBBY this,
647 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
648 LPCVOID lpAddress,
649 DWORD dwAddressSize,
650 LPVOID lpContext )
652 FIXME( dplay, ":stub\n");
653 return DPERR_OUTOFMEMORY;
656 static HRESULT WINAPI IDirectPlayLobby2W_EnumAddress
657 ( LPDIRECTPLAYLOBBY2 this,
658 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
659 LPCVOID lpAddress,
660 DWORD dwAddressSize,
661 LPVOID lpContext )
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,
677 REFGUID guidSP,
678 LPVOID lpContext,
679 DWORD dwFlags )
681 FIXME( dplay, ":stub\n");
682 return DPERR_OUTOFMEMORY;
685 static HRESULT WINAPI IDirectPlayLobby2A_EnumAddressTypes
686 ( LPDIRECTPLAYLOBBY2A this,
687 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
688 REFGUID guidSP,
689 LPVOID lpContext,
690 DWORD dwFlags )
692 return IDirectPlayLobbyA_EnumAddressTypes( (LPDIRECTPLAYLOBBYA)this, lpEnumAddressTypeCallback,
693 guidSP, lpContext, dwFlags );
696 static HRESULT WINAPI IDirectPlayLobbyW_EnumAddressTypes
697 ( LPDIRECTPLAYLOBBY this,
698 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
699 REFGUID guidSP,
700 LPVOID lpContext,
701 DWORD dwFlags )
703 FIXME( dplay, ":stub\n");
704 return DPERR_OUTOFMEMORY;
707 static HRESULT WINAPI IDirectPlayLobby2W_EnumAddressTypes
708 ( LPDIRECTPLAYLOBBY2 this,
709 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
710 REFGUID guidSP,
711 LPVOID lpContext,
712 DWORD dwFlags )
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,
728 LPVOID lpContext,
729 DWORD dwFlags )
731 FIXME( dplay, ":stub\n");
732 return DPERR_OUTOFMEMORY;
735 static HRESULT WINAPI IDirectPlayLobby2W_EnumLocalApplications
736 ( LPDIRECTPLAYLOBBY2 this,
737 LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
738 LPVOID lpContext,
739 DWORD dwFlags )
741 return IDirectPlayLobbyW_EnumLocalApplications( (LPDIRECTPLAYLOBBY)this, a,
742 lpContext, dwFlags );
745 static HRESULT WINAPI IDirectPlayLobbyA_EnumLocalApplications
746 ( LPDIRECTPLAYLOBBYA this,
747 LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
748 LPVOID lpContext,
749 DWORD dwFlags )
751 FIXME( dplay, ":stub\n");
752 return DPERR_OUTOFMEMORY;
755 static HRESULT WINAPI IDirectPlayLobby2A_EnumLocalApplications
756 ( LPDIRECTPLAYLOBBY2A this,
757 LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
758 LPVOID lpContext,
759 DWORD dwFlags )
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,
778 DWORD dwAppID,
779 LPVOID lpData,
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 */
785 if ( !lpData )
787 /* Let's check the size of the buffer that the application has allocated */
788 if( *lpdwDataSize >= sizeof( DPLCONNECTION ) )
790 return DP_OK;
792 else
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) ) );
806 return DP_OK;
809 static HRESULT WINAPI IDirectPlayLobby2A_GetConnectionSettings
810 ( LPDIRECTPLAYLOBBY2A this,
811 DWORD dwAppID,
812 LPVOID lpData,
813 LPDWORD lpdwDataSize )
815 return IDirectPlayLobbyA_GetConnectionSettings( (LPDIRECTPLAYLOBBYA)this,
816 dwAppID, lpData, lpdwDataSize );
819 static HRESULT WINAPI IDirectPlayLobbyW_GetConnectionSettings
820 ( LPDIRECTPLAYLOBBY this,
821 DWORD dwAppID,
822 LPVOID lpData,
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 */
828 if ( !lpData )
830 /* Let's check the size of the buffer that the application has allocated */
831 if( *lpdwDataSize >= sizeof( DPLCONNECTION ) )
833 return DP_OK;
835 else
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) ) );
845 return DP_OK;
848 static HRESULT WINAPI IDirectPlayLobby2W_GetConnectionSettings
849 ( LPDIRECTPLAYLOBBY2 this,
850 DWORD dwAppID,
851 LPVOID lpData,
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,
866 DWORD dwFlags,
867 DWORD dwAppID,
868 LPDWORD lpdwMessageFlags,
869 LPVOID lpData,
870 LPDWORD lpdwDataSize )
872 FIXME( dplay, ":stub %p %08lx %08lx %p %p %p\n", this, dwFlags, dwAppID, lpdwMessageFlags, lpData,
873 lpdwDataSize );
874 return DPERR_OUTOFMEMORY;
877 static HRESULT WINAPI IDirectPlayLobby2A_ReceiveLobbyMessage
878 ( LPDIRECTPLAYLOBBY2A this,
879 DWORD dwFlags,
880 DWORD dwAppID,
881 LPDWORD lpdwMessageFlags,
882 LPVOID lpData,
883 LPDWORD lpdwDataSize )
885 return IDirectPlayLobbyA_ReceiveLobbyMessage( (LPDIRECTPLAYLOBBYA)this, dwFlags, dwAppID,
886 lpdwMessageFlags, lpData, lpdwDataSize );
890 static HRESULT WINAPI IDirectPlayLobbyW_ReceiveLobbyMessage
891 ( LPDIRECTPLAYLOBBY this,
892 DWORD dwFlags,
893 DWORD dwAppID,
894 LPDWORD lpdwMessageFlags,
895 LPVOID lpData,
896 LPDWORD lpdwDataSize )
898 FIXME( dplay, ":stub %p %08lx %08lx %p %p %p\n", this, dwFlags, dwAppID, lpdwMessageFlags, lpData,
899 lpdwDataSize );
900 return DPERR_OUTOFMEMORY;
903 static HRESULT WINAPI IDirectPlayLobby2W_ReceiveLobbyMessage
904 ( LPDIRECTPLAYLOBBY2 this,
905 DWORD dwFlags,
906 DWORD dwAppID,
907 LPDWORD lpdwMessageFlags,
908 LPVOID lpData,
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,
923 DWORD dwFlags,
924 LPDWORD lpdwAppID,
925 LPDPLCONNECTION lpConn,
926 HANDLE32 hReceiveEvent )
928 FIXME( dplay, ":stub\n");
929 return DPERR_OUTOFMEMORY;
932 static HRESULT WINAPI IDirectPlayLobby2A_RunApplication
933 ( LPDIRECTPLAYLOBBY2A this,
934 DWORD dwFlags,
935 LPDWORD lpdwAppID,
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,
945 DWORD dwFlags,
946 LPDWORD lpdwAppID,
947 LPDPLCONNECTION lpConn,
948 HANDLE32 hReceiveEvent )
950 FIXME( dplay, ":stub\n");
951 return DPERR_OUTOFMEMORY;
954 static HRESULT WINAPI IDirectPlayLobby2W_RunApplication
955 ( LPDIRECTPLAYLOBBY2 this,
956 DWORD dwFlags,
957 LPDWORD lpdwAppID,
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,
974 DWORD dwFlags,
975 DWORD dwAppID,
976 LPVOID lpData,
977 DWORD dwDataSize )
979 FIXME( dplay, ":stub\n");
980 return DPERR_OUTOFMEMORY;
983 static HRESULT WINAPI IDirectPlayLobby2A_SendLobbyMessage
984 ( LPDIRECTPLAYLOBBY2A this,
985 DWORD dwFlags,
986 DWORD dwAppID,
987 LPVOID lpData,
988 DWORD dwDataSize )
990 return IDirectPlayLobbyA_SendLobbyMessage( (LPDIRECTPLAYLOBBYA)this, dwFlags,
991 dwAppID, lpData, dwDataSize );
995 static HRESULT WINAPI IDirectPlayLobbyW_SendLobbyMessage
996 ( LPDIRECTPLAYLOBBY this,
997 DWORD dwFlags,
998 DWORD dwAppID,
999 LPVOID lpData,
1000 DWORD dwDataSize )
1002 FIXME( dplay, ":stub\n");
1003 return DPERR_OUTOFMEMORY;
1006 static HRESULT WINAPI IDirectPlayLobby2W_SendLobbyMessage
1007 ( LPDIRECTPLAYLOBBY2 this,
1008 DWORD dwFlags,
1009 DWORD dwAppID,
1010 LPVOID lpData,
1011 DWORD dwDataSize )
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,
1025 DWORD dwFlags,
1026 DWORD dwAppID,
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.
1042 if( dwAppID )
1044 FIXME( dplay, ": Connection dwAppID=%08lx given. Not implemented yet.\n",
1045 dwAppID );
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,
1077 DWORD dwFlags,
1078 DWORD dwAppID,
1079 LPDPLCONNECTION lpConn )
1081 return IDirectPlayLobbyW_SetConnectionSettings( (LPDIRECTPLAYLOBBY)this,
1082 dwFlags, dwAppID, lpConn );
1085 static HRESULT WINAPI IDirectPlayLobbyA_SetConnectionSettings
1086 ( LPDIRECTPLAYLOBBYA this,
1087 DWORD dwFlags,
1088 DWORD dwAppID,
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,
1098 DWORD dwFlags,
1099 DWORD dwAppID,
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,
1113 DWORD dwFlags,
1114 DWORD dwAppID,
1115 HANDLE32 hReceiveEvent )
1117 FIXME( dplay, ":stub\n");
1118 return DPERR_OUTOFMEMORY;
1121 static HRESULT WINAPI IDirectPlayLobby2A_SetLobbyMessageEvent
1122 ( LPDIRECTPLAYLOBBY2A this,
1123 DWORD dwFlags,
1124 DWORD dwAppID,
1125 HANDLE32 hReceiveEvent )
1127 return IDirectPlayLobbyA_SetLobbyMessageEvent( (LPDIRECTPLAYLOBBYA)this, dwFlags,
1128 dwAppID, hReceiveEvent );
1131 static HRESULT WINAPI IDirectPlayLobbyW_SetLobbyMessageEvent
1132 ( LPDIRECTPLAYLOBBY this,
1133 DWORD dwFlags,
1134 DWORD dwAppID,
1135 HANDLE32 hReceiveEvent )
1137 FIXME( dplay, ":stub\n");
1138 return DPERR_OUTOFMEMORY;
1141 static HRESULT WINAPI IDirectPlayLobby2W_SetLobbyMessageEvent
1142 ( LPDIRECTPLAYLOBBY2 this,
1143 DWORD dwFlags,
1144 DWORD dwAppID,
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,
1161 LPVOID lpAddress,
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,
1172 LPVOID lpAddress,
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,
1261 IUnknown *lpUnk,
1262 LPVOID lpData,
1263 DWORD dwDataSize )
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 )
1273 *lplpDPL = NULL;
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 ) );
1281 if( ! (*lplpDPL) )
1283 return DPERR_OUTOFMEMORY;
1286 (*lplpDPL)->lpVtbl = &directPlayLobbyAVT;
1287 (*lplpDPL)->ref = 1;
1289 (*lplpDPL)->lpSession = (LPDPLCONNECTION)HeapAlloc( GetProcessHeap(),
1290 HEAP_ZERO_MEMORY,
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 );
1298 return DP_OK;
1301 /***************************************************************************
1302 * DirectPlayLobbyCreateW (DPLAYX.5)
1305 HRESULT WINAPI DirectPlayLobbyCreateW( LPGUID lpGUIDDSP,
1306 LPDIRECTPLAYLOBBY *lplpDPL,
1307 IUnknown *lpUnk,
1308 LPVOID lpData,
1309 DWORD dwDataSize )
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 )
1319 *lplpDPL = NULL;
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 ) );
1328 if( !*lplpDPL)
1330 return DPERR_OUTOFMEMORY;
1333 (*lplpDPL)->lpVtbl = &directPlayLobbyWVT;
1334 (*lplpDPL)->ref = 1;
1337 (*lplpDPL)->lpSession = (LPDPLCONNECTION)HeapAlloc( GetProcessHeap(),
1338 HEAP_ZERO_MEMORY,
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 );
1345 return DP_OK;
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
1357 * services.
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,
1375 LPVOID lpContext )
1378 HKEY hkResult;
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");
1398 return DP_OK;
1401 /* Traverse all the service providers we have available */
1402 for( dwIndex=0;
1403 RegEnumKey32A( hkResult, dwIndex, subKeyName, sizeOfSubKeyName ) !=
1404 ERROR_NO_MORE_ITEMS;
1405 ++dwIndex )
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" );
1421 continue;
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" );
1432 continue;
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") ;
1447 continue;
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" );
1457 break;
1461 return DP_OK;
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;
1489 TRACE(dplay,"\n" );
1491 if( pUnk != NULL )
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 ) );
1501 if( !*lplpDP )
1503 return DPERR_OUTOFMEMORY;
1506 (*lplpDP)->lpVtbl = &directPlay2AVT;
1507 (*lplpDP)->ref = 1;
1509 return DP_OK;