1 /* Direct Play Lobby 2 & 3 Implementation
3 * Copyright 1998,1999,2000 - Peter Hunnisett
5 * <presently under construction - contact hunnise@nortelnetworks.com>
14 #include "debugtools.h"
18 #include "dplayx_global.h"
19 #include "dplayx_messages.h"
21 DEFAULT_DEBUG_CHANNEL(dplay
)
23 /*****************************************************************************
24 * Predeclare the interface implementation structures
26 typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyAImpl
;
27 typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyWImpl
;
28 typedef struct IDirectPlayLobby2Impl IDirectPlayLobby2AImpl
;
29 typedef struct IDirectPlayLobby2Impl IDirectPlayLobby2WImpl
;
30 typedef struct IDirectPlayLobby3Impl IDirectPlayLobby3AImpl
;
31 typedef struct IDirectPlayLobby3Impl IDirectPlayLobby3WImpl
;
33 /* Forward declarations for this module helper methods */
34 HRESULT
DPL_CreateCompoundAddress ( LPCDPCOMPOUNDADDRESSELEMENT lpElements
, DWORD dwElementCount
,
35 LPVOID lpAddress
, LPDWORD lpdwAddressSize
, BOOL bAnsiInterface
);
37 HRESULT
DPL_CreateAddress( REFGUID guidSP
, REFGUID guidDataType
, LPCVOID lpData
, DWORD dwDataSize
,
38 LPVOID lpAddress
, LPDWORD lpdwAddressSize
, BOOL bAnsiInterface
);
42 static HRESULT
DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
, LPCVOID lpAddress
,
43 DWORD dwAddressSize
, LPVOID lpContext
);
45 static HRESULT WINAPI
DPL_ConnectEx( IDirectPlayLobbyAImpl
* This
,
46 DWORD dwFlags
, REFIID riid
,
47 LPVOID
* lplpDP
, IUnknown
* pUnk
);
51 /*****************************************************************************
52 * IDirectPlayLobby {1,2,3} implementation structure
54 * The philosophy behind this extra pointer derefernce is that I wanted to
55 * have the same structure for all types of objects without having to do
56 * alot of casting. I also only wanted to implement an interface in the
57 * object it was "released" with IUnknown interface being implemented in the 1 version.
58 * Of course, with these new interfaces comes the data required to keep the state required
59 * by these interfaces. So, basically, the pointers contain the data associated with
60 * a release. If you use the data associated with release 3 in a release 2 object, you'll
61 * get a run time trap, as that won't have any data.
65 typedef struct tagDirectPlayLobbyIUnknownData
68 CRITICAL_SECTION DPL_lock
;
69 } DirectPlayLobbyIUnknownData
;
71 typedef struct tagDirectPlayLobbyData
73 HKEY hkCallbackKeyHack
;
74 } DirectPlayLobbyData
;
76 typedef struct tagDirectPlayLobby2Data
79 } DirectPlayLobby2Data
;
81 typedef struct tagDirectPlayLobby3Data
84 } DirectPlayLobby3Data
;
86 #define DPL_IMPL_FIELDS \
87 DirectPlayLobbyIUnknownData* unk; \
88 DirectPlayLobbyData* dpl; \
89 DirectPlayLobby2Data* dpl2; \
90 DirectPlayLobby3Data* dpl3;
92 struct IDirectPlayLobbyImpl
94 ICOM_VFIELD(IDirectPlayLobby
);
98 struct IDirectPlayLobby2Impl
100 ICOM_VFIELD(IDirectPlayLobby2
);
104 struct IDirectPlayLobby3Impl
106 ICOM_VFIELD(IDirectPlayLobby3
);
111 /* Forward declarations of virtual tables */
112 static ICOM_VTABLE(IDirectPlayLobby
) directPlayLobbyWVT
;
113 static ICOM_VTABLE(IDirectPlayLobby2
) directPlayLobby2WVT
;
114 static ICOM_VTABLE(IDirectPlayLobby3
) directPlayLobby3WVT
;
116 static ICOM_VTABLE(IDirectPlayLobby
) directPlayLobbyAVT
;
117 static ICOM_VTABLE(IDirectPlayLobby2
) directPlayLobby2AVT
;
118 static ICOM_VTABLE(IDirectPlayLobby3
) directPlayLobby3AVT
;
123 /* The COM interface for upversioning an interface
124 * We've been given a GUID (riid) and we need to replace the present
125 * interface with that of the requested interface.
127 * Snip from some Microsoft document:
128 * There are four requirements for implementations of QueryInterface (In these
129 * cases, "must succeed" means "must succeed barring catastrophic failure."):
131 * * The set of interfaces accessible on an object through
132 * IUnknown::QueryInterface must be static, not dynamic. This means that
133 * if a call to QueryInterface for a pointer to a specified interface
134 * succeeds the first time, it must succeed again, and if it fails the
135 * first time, it must fail on all subsequent queries.
136 * * It must be symmetric ~W if a client holds a pointer to an interface on
137 * an object, and queries for that interface, the call must succeed.
138 * * It must be reflexive ~W if a client holding a pointer to one interface
139 * queries successfully for another, a query through the obtained pointer
140 * for the first interface must succeed.
141 * * It must be transitive ~W if a client holding a pointer to one interface
142 * queries successfully for a second, and through that pointer queries
143 * successfully for a third interface, a query for the first interface
144 * through the pointer for the third interface must succeed.
146 * As you can see, this interface doesn't qualify but will most likely
147 * be good enough for the time being.
151 BOOL
DPL_CreateIUnknown( LPVOID lpDPL
)
153 ICOM_THIS(IDirectPlayLobbyAImpl
,lpDPL
);
155 This
->unk
= (DirectPlayLobbyIUnknownData
*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
156 sizeof( *(This
->unk
) ) );
157 if ( This
->unk
== NULL
)
162 InitializeCriticalSection( &This
->unk
->DPL_lock
);
164 IDirectPlayLobby_AddRef( (LPDIRECTPLAYLOBBYA
)lpDPL
);
169 BOOL
DPL_DestroyIUnknown( LPVOID lpDPL
)
171 ICOM_THIS(IDirectPlayLobbyAImpl
,lpDPL
);
173 DeleteCriticalSection( &This
->unk
->DPL_lock
);
174 HeapFree( GetProcessHeap(), 0, This
->unk
);
179 BOOL
DPL_CreateLobby1( LPVOID lpDPL
)
181 ICOM_THIS(IDirectPlayLobbyAImpl
,lpDPL
);
183 This
->dpl
= (DirectPlayLobbyData
*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
184 sizeof( *(This
->dpl
) ) );
185 if ( This
->dpl
== NULL
)
193 BOOL
DPL_DestroyLobby1( LPVOID lpDPL
)
195 ICOM_THIS(IDirectPlayLobbyAImpl
,lpDPL
);
197 /* Delete the contents */
198 HeapFree( GetProcessHeap(), 0, This
->dpl
);
203 BOOL
DPL_CreateLobby2( LPVOID lpDPL
)
205 ICOM_THIS(IDirectPlayLobby2AImpl
,lpDPL
);
207 This
->dpl2
= (DirectPlayLobby2Data
*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
208 sizeof( *(This
->dpl2
) ) );
209 if ( This
->dpl2
== NULL
)
217 BOOL
DPL_DestroyLobby2( LPVOID lpDPL
)
219 ICOM_THIS(IDirectPlayLobby2AImpl
,lpDPL
);
221 HeapFree( GetProcessHeap(), 0, This
->dpl2
);
226 BOOL
DPL_CreateLobby3( LPVOID lpDPL
)
228 ICOM_THIS(IDirectPlayLobby3AImpl
,lpDPL
);
230 This
->dpl3
= (DirectPlayLobby3Data
*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
231 sizeof( *(This
->dpl3
) ) );
232 if ( This
->dpl3
== NULL
)
240 BOOL
DPL_DestroyLobby3( LPVOID lpDPL
)
242 ICOM_THIS(IDirectPlayLobby3AImpl
,lpDPL
);
244 HeapFree( GetProcessHeap(), 0, This
->dpl3
);
250 /* Helper function for DirectPlayLobby QueryInterface */
252 HRESULT directPlayLobby_QueryInterface
253 ( REFIID riid
, LPVOID
* ppvObj
)
255 if( IsEqualGUID( &IID_IDirectPlayLobby
, riid
) )
257 *ppvObj
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
258 sizeof( IDirectPlayLobbyWImpl
) );
260 if( *ppvObj
== NULL
)
262 return E_OUTOFMEMORY
;
265 /* new scope for variable declaration */
267 ICOM_THIS(IDirectPlayLobbyWImpl
,*ppvObj
);
269 ICOM_VTBL(This
) = &directPlayLobbyWVT
;
271 if ( DPL_CreateIUnknown( (LPVOID
)This
) &&
272 DPL_CreateLobby1( (LPVOID
)This
)
282 else if( IsEqualGUID( &IID_IDirectPlayLobbyA
, riid
) )
284 *ppvObj
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
285 sizeof( IDirectPlayLobbyAImpl
) );
287 if( *ppvObj
== NULL
)
289 return E_OUTOFMEMORY
;
293 ICOM_THIS(IDirectPlayLobbyAImpl
,*ppvObj
);
295 ICOM_VTBL(This
) = &directPlayLobbyAVT
;
297 if ( DPL_CreateIUnknown( (LPVOID
)This
) &&
298 DPL_CreateLobby1( (LPVOID
)This
)
307 else if( IsEqualGUID( &IID_IDirectPlayLobby2
, riid
) )
309 *ppvObj
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
310 sizeof( IDirectPlayLobby2WImpl
) );
312 if( *ppvObj
== NULL
)
314 return E_OUTOFMEMORY
;
318 ICOM_THIS(IDirectPlayLobby2WImpl
,*ppvObj
);
320 ICOM_VTBL(This
) = &directPlayLobby2WVT
;
322 if ( DPL_CreateIUnknown( (LPVOID
)This
) &&
323 DPL_CreateLobby1( (LPVOID
)This
) &&
324 DPL_CreateLobby2( (LPVOID
)This
)
333 else if( IsEqualGUID( &IID_IDirectPlayLobby2A
, riid
) )
335 *ppvObj
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
336 sizeof( IDirectPlayLobby2AImpl
) );
338 if( *ppvObj
== NULL
)
340 return E_OUTOFMEMORY
;
344 ICOM_THIS(IDirectPlayLobby2AImpl
,*ppvObj
);
346 ICOM_VTBL(This
) = &directPlayLobby2AVT
;
348 if ( DPL_CreateIUnknown( (LPVOID
)This
) &&
349 DPL_CreateLobby1( (LPVOID
)This
) &&
350 DPL_CreateLobby2( (LPVOID
)This
)
359 else if( IsEqualGUID( &IID_IDirectPlayLobby3
, riid
) )
361 *ppvObj
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
362 sizeof( IDirectPlayLobby3WImpl
) );
364 if( *ppvObj
== NULL
)
366 return E_OUTOFMEMORY
;
370 ICOM_THIS(IDirectPlayLobby3WImpl
,*ppvObj
);
372 ICOM_VTBL(This
) = &directPlayLobby3WVT
;
374 if ( DPL_CreateIUnknown( *ppvObj
) &&
375 DPL_CreateLobby1( *ppvObj
) &&
376 DPL_CreateLobby2( *ppvObj
) &&
377 DPL_CreateLobby3( *ppvObj
)
386 else if( IsEqualGUID( &IID_IDirectPlayLobby3A
, riid
) )
388 *ppvObj
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
389 sizeof( IDirectPlayLobby3AImpl
) );
391 if( *ppvObj
== NULL
)
393 return E_OUTOFMEMORY
;
397 ICOM_THIS(IDirectPlayLobby3AImpl
,*ppvObj
);
399 ICOM_VTBL(This
) = &directPlayLobby3AVT
;
401 if ( DPL_CreateIUnknown( *ppvObj
) &&
402 DPL_CreateLobby1( *ppvObj
) &&
403 DPL_CreateLobby2( *ppvObj
) &&
404 DPL_CreateLobby3( *ppvObj
)
414 /* Unsupported interface */
416 return E_NOINTERFACE
;
420 DPL_DestroyLobby3( *ppvObj
);
421 DPL_DestroyLobby2( *ppvObj
);
422 DPL_DestroyLobby1( *ppvObj
);
423 DPL_DestroyIUnknown( *ppvObj
);
424 HeapFree( GetProcessHeap(), 0, *ppvObj
);
427 return DPERR_NOMEMORY
;
430 static HRESULT WINAPI IDirectPlayLobbyAImpl_QueryInterface
431 ( LPDIRECTPLAYLOBBYA iface
,
435 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
436 TRACE("(%p)->(%p,%p)\n", This
, riid
, ppvObj
);
438 if( IsEqualGUID( &IID_IUnknown
, riid
) ||
439 IsEqualGUID( &IID_IDirectPlayLobbyA
, riid
)
442 IDirectPlayLobby_AddRef( iface
);
447 return directPlayLobby_QueryInterface( riid
, ppvObj
);
451 static HRESULT WINAPI IDirectPlayLobbyW_QueryInterface
452 ( LPDIRECTPLAYLOBBY iface
,
456 ICOM_THIS(IDirectPlayLobbyWImpl
,iface
);
457 TRACE("(%p)->(%p,%p)\n", This
, riid
, ppvObj
);
459 if( IsEqualGUID( &IID_IUnknown
, riid
) ||
460 IsEqualGUID( &IID_IDirectPlayLobby
, riid
)
463 IDirectPlayLobby_AddRef( iface
);
468 return directPlayLobby_QueryInterface( riid
, ppvObj
);
472 static HRESULT WINAPI IDirectPlayLobby2AImpl_QueryInterface
473 ( LPDIRECTPLAYLOBBY2A iface
,
477 ICOM_THIS(IDirectPlayLobby2AImpl
,iface
);
478 TRACE("(%p)->(%p,%p)\n", This
, riid
, ppvObj
);
480 /* Compare riids. We know this object is a direct play lobby 2A object.
481 If we are asking about the same type of interface we're fine.
483 if( IsEqualGUID( &IID_IUnknown
, riid
) ||
484 IsEqualGUID( &IID_IDirectPlayLobby2A
, riid
)
487 IDirectPlayLobby_AddRef( iface
);
491 return directPlayLobby_QueryInterface( riid
, ppvObj
);
494 static HRESULT WINAPI IDirectPlayLobby2WImpl_QueryInterface
495 ( LPDIRECTPLAYLOBBY2 iface
,
499 ICOM_THIS(IDirectPlayLobby2WImpl
,iface
);
501 /* Compare riids. We know this object is a direct play lobby 2 object.
502 If we are asking about the same type of interface we're fine.
504 if( IsEqualGUID( &IID_IUnknown
, riid
) ||
505 IsEqualGUID( &IID_IDirectPlayLobby2
, riid
)
508 IDirectPlayLobby_AddRef( iface
);
513 return directPlayLobby_QueryInterface( riid
, ppvObj
);
517 static HRESULT WINAPI IDirectPlayLobby3AImpl_QueryInterface
518 ( LPDIRECTPLAYLOBBY3A iface
,
522 ICOM_THIS(IDirectPlayLobby3AImpl
,iface
);
524 /* Compare riids. We know this object is a direct play lobby 3 object.
525 If we are asking about the same type of interface we're fine.
527 if( IsEqualGUID( &IID_IUnknown
, riid
) ||
528 IsEqualGUID( &IID_IDirectPlayLobby3A
, riid
)
531 IDirectPlayLobby_AddRef( iface
);
536 return directPlayLobby_QueryInterface( riid
, ppvObj
);
540 static HRESULT WINAPI IDirectPlayLobby3WImpl_QueryInterface
541 ( LPDIRECTPLAYLOBBY3 iface
,
545 ICOM_THIS(IDirectPlayLobby3WImpl
,iface
);
547 /* Compare riids. We know this object is a direct play lobby 3 object.
548 If we are asking about the same type of interface we're fine.
550 if( IsEqualGUID( &IID_IUnknown
, riid
) ||
551 IsEqualGUID( &IID_IDirectPlayLobby3
, riid
)
554 IDirectPlayLobby_AddRef( iface
);
559 return directPlayLobby_QueryInterface( riid
, ppvObj
);
564 * Simple procedure. Just increment the reference count to this
565 * structure and return the new reference count.
567 static ULONG WINAPI IDirectPlayLobbyImpl_AddRef
568 ( LPDIRECTPLAYLOBBY iface
)
571 ICOM_THIS(IDirectPlayLobbyWImpl
,iface
);
573 refCount
= InterlockedIncrement( &This
->unk
->ref
);
575 TRACE("ref count incremented to %lu for %p\n", refCount
, This
);
581 * Simple COM procedure. Decrease the reference count to this object.
582 * If the object no longer has any reference counts, free up the associated
585 static ULONG WINAPI IDirectPlayLobbyAImpl_Release
586 ( LPDIRECTPLAYLOBBYA iface
)
589 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
591 refCount
= InterlockedDecrement( &This
->unk
->ref
);
593 TRACE("ref count decremeneted to %lu for %p\n", refCount
, This
);
595 /* Deallocate if this is the last reference to the object */
598 DPL_DestroyLobby3( This
);
599 DPL_DestroyLobby2( This
);
600 DPL_DestroyLobby1( This
);
601 DPL_DestroyIUnknown( This
);
602 HeapFree( GetProcessHeap(), 0, This
);
609 /********************************************************************
611 * Connects an application to the session specified by the DPLCONNECTION
612 * structure currently stored with the DirectPlayLobby object.
614 * Returns a IDirectPlay interface.
617 static HRESULT WINAPI DPL_ConnectEx
618 ( IDirectPlayLobbyAImpl
* This
,
625 DWORD dwOpenFlags
= 0;
626 DWORD dwConnSize
= 0;
627 LPDPLCONNECTION lpConn
;
629 FIXME("(%p)->(0x%08lx,%p,%p): semi stub\n", This
, dwFlags
, lplpDP
, pUnk
);
631 if( dwFlags
|| pUnk
)
633 return DPERR_INVALIDPARAMS
;
636 /* Create the DirectPlay interface */
637 if( ( hr
= directPlay_QueryInterface( riid
, lplpDP
) ) != DP_OK
)
639 ERR( "error creating interface for %s:%s.\n",
640 debugstr_guid( riid
), DPLAYX_HresultToString( hr
) );
644 /* - Need to call IDirectPlay::EnumConnections with the service provider to get that good information
645 * - Need to call CreateAddress to create the lpConnection param for IDirectPlay::InitializeConnection
646 * - Call IDirectPlay::InitializeConnection
647 * - Call IDirectPlay::Open
650 /* FIXME: Is it safe/correct to use appID of 0? */
651 hr
= IDirectPlayLobby_GetConnectionSettings( (LPDIRECTPLAYLOBBY
)This
,
652 0, NULL
, &dwConnSize
);
653 if( hr
!= DPERR_BUFFERTOOSMALL
)
658 lpConn
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, dwConnSize
);
662 return DPERR_NOMEMORY
;
665 /* FIXME: Is it safe/correct to use appID of 0? */
666 hr
= IDirectPlayLobby_GetConnectionSettings( (LPDIRECTPLAYLOBBY
)This
,
667 0, lpConn
, &dwConnSize
);
673 /* Setup flags to pass into DirectPlay::Open */
674 if( dwFlags
& DPCONNECT_RETURNSTATUS
)
676 dwOpenFlags
|= DPOPEN_RETURNSTATUS
;
678 dwOpenFlags
|= lpConn
->dwFlags
;
680 hr
= IDirectPlayX_Open( (*(LPDIRECTPLAY2
*)lplpDP
), lpConn
->lpSessionDesc
,
683 HeapFree( GetProcessHeap(), 0, lpConn
);
688 static HRESULT WINAPI IDirectPlayLobbyAImpl_Connect
689 ( LPDIRECTPLAYLOBBYA iface
,
691 LPDIRECTPLAY2A
* lplpDP
,
694 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
695 return DPL_ConnectEx( This
, dwFlags
, &IID_IDirectPlay2A
,
696 (LPVOID
)lplpDP
, pUnk
);
699 static HRESULT WINAPI IDirectPlayLobbyWImpl_Connect
700 ( LPDIRECTPLAYLOBBY iface
,
702 LPDIRECTPLAY2
* lplpDP
,
705 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
); /* Yes cast to A */
706 return DPL_ConnectEx( This
, dwFlags
, &IID_IDirectPlay2
,
707 (LPVOID
)lplpDP
, pUnk
);
710 /********************************************************************
712 * Creates a DirectPlay Address, given a service provider-specific network
714 * Returns an address contains the globally unique identifier
715 * (GUID) of the service provider and data that the service provider can
716 * interpret as a network address.
718 * NOTE: It appears that this method is supposed to be really really stupid
719 * with no error checking on the contents.
721 static HRESULT WINAPI IDirectPlayLobbyAImpl_CreateAddress
722 ( LPDIRECTPLAYLOBBYA iface
,
724 REFGUID guidDataType
,
728 LPDWORD lpdwAddressSize
)
730 return DPL_CreateAddress( guidSP
, guidDataType
, lpData
, dwDataSize
,
731 lpAddress
, lpdwAddressSize
, TRUE
);
734 static HRESULT WINAPI IDirectPlayLobbyWImpl_CreateAddress
735 ( LPDIRECTPLAYLOBBY iface
,
737 REFGUID guidDataType
,
741 LPDWORD lpdwAddressSize
)
743 return DPL_CreateAddress( guidSP
, guidDataType
, lpData
, dwDataSize
,
744 lpAddress
, lpdwAddressSize
, FALSE
);
747 HRESULT
DPL_CreateAddress(
749 REFGUID guidDataType
,
753 LPDWORD lpdwAddressSize
,
754 BOOL bAnsiInterface
)
756 const DWORD dwNumAddElements
= 2; /* Service Provide & address data type */
757 DPCOMPOUNDADDRESSELEMENT addressElements
[ 2 /* dwNumAddElements */ ];
759 TRACE( "(%p)->(%p,%p,0x%08lx,%p,%p,%d)\n", guidSP
, guidDataType
, lpData
, dwDataSize
,
760 lpAddress
, lpdwAddressSize
, bAnsiInterface
);
762 addressElements
[ 0 ].guidDataType
= DPAID_ServiceProvider
;
763 addressElements
[ 0 ].dwDataSize
= sizeof( GUID
);
764 addressElements
[ 0 ].lpData
= (LPVOID
)guidSP
;
766 addressElements
[ 1 ].guidDataType
= *guidDataType
;
767 addressElements
[ 1 ].dwDataSize
= dwDataSize
;
768 addressElements
[ 1 ].lpData
= (LPVOID
)lpData
;
770 /* Call CreateCompoundAddress to cut down on code.
771 NOTE: We can do this because we don't support DPL 1 interfaces! */
772 return DPL_CreateCompoundAddress( addressElements
, dwNumAddElements
,
773 lpAddress
, lpdwAddressSize
, bAnsiInterface
);
778 /********************************************************************
780 * Parses out chunks from the DirectPlay Address buffer by calling the
781 * given callback function, with lpContext, for each of the chunks.
784 static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddress
785 ( LPDIRECTPLAYLOBBYA iface
,
786 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
,
791 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
793 TRACE("(%p)->(%p,%p,0x%08lx,%p)\n", This
, lpEnumAddressCallback
, lpAddress
,
794 dwAddressSize
, lpContext
);
796 return DPL_EnumAddress( lpEnumAddressCallback
, lpAddress
, dwAddressSize
, lpContext
);
799 static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumAddress
800 ( LPDIRECTPLAYLOBBY iface
,
801 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
,
806 ICOM_THIS(IDirectPlayLobbyWImpl
,iface
);
808 TRACE("(%p)->(%p,%p,0x%08lx,%p)\n", This
, lpEnumAddressCallback
, lpAddress
,
809 dwAddressSize
, lpContext
);
811 return DPL_EnumAddress( lpEnumAddressCallback
, lpAddress
, dwAddressSize
, lpContext
);
814 static HRESULT
DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
, LPCVOID lpAddress
,
815 DWORD dwAddressSize
, LPVOID lpContext
)
817 DWORD dwTotalSizeEnumerated
= 0;
819 /* FIXME: First chunk is always the total size chunk - Should we report it? */
821 while ( dwTotalSizeEnumerated
< dwAddressSize
)
823 LPDPADDRESS lpElements
= (LPDPADDRESS
)lpAddress
;
824 DWORD dwSizeThisEnumeration
;
826 /* Invoke the enum method. If false is returned, stop enumeration */
827 if ( !lpEnumAddressCallback( &lpElements
->guidDataType
, lpElements
->dwDataSize
,
828 lpElements
+ sizeof( DPADDRESS
), lpContext
) )
833 dwSizeThisEnumeration
= sizeof( DPADDRESS
) + lpElements
->dwDataSize
;
834 lpAddress
= (char *) lpAddress
+ dwSizeThisEnumeration
;
835 dwTotalSizeEnumerated
+= dwSizeThisEnumeration
;
841 /********************************************************************
843 * Enumerates all the address types that a given service provider needs to
844 * build the DirectPlay Address.
847 static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddressTypes
848 ( LPDIRECTPLAYLOBBYA iface
,
849 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
,
854 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
857 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
858 DWORD dwIndex
, sizeOfSubKeyName
=50;
862 TRACE(" (%p)->(%p,%p,%p,0x%08lx)\n", This
, lpEnumAddressTypeCallback
, guidSP
, lpContext
, dwFlags
);
866 return DPERR_INVALIDPARAMS
;
869 if( !lpEnumAddressTypeCallback
|| !*lpEnumAddressTypeCallback
)
871 return DPERR_INVALIDPARAMS
;
876 return DPERR_INVALIDOBJECT
;
879 /* Need to loop over the service providers in the registry */
880 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
881 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
883 /* Hmmm. Does this mean that there are no service providers? */
884 ERR(": no service providers?\n");
888 /* Traverse all the service providers we have available */
890 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
,
891 NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
892 ++dwIndex
, sizeOfSubKeyName
=50 )
895 HKEY hkServiceProvider
, hkServiceProviderAt
;
896 GUID serviceProviderGUID
;
897 DWORD returnTypeGUID
, sizeOfReturnBuffer
= 50;
899 char returnBuffer
[51];
900 LPWSTR lpWGUIDString
;
902 LPSTR atKey
= "Address Types";
903 LPSTR guidDataSubKey
= "Guid";
907 TRACE(" this time through: %s\n", subKeyName
);
909 /* Get a handle for this particular service provider */
910 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
911 &hkServiceProvider
) != ERROR_SUCCESS
)
913 ERR(": what the heck is going on?\n" );
917 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
918 NULL
, &returnTypeGUID
, returnBuffer
,
919 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
921 ERR(": missing GUID registry data members\n" );
925 /* FIXME: Check return types to ensure we're interpreting data right */
926 lpWGUIDString
= HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer
);
927 CLSIDFromString( (LPCOLESTR
)lpWGUIDString
, &serviceProviderGUID
);
928 HeapFree( GetProcessHeap(), 0, lpWGUIDString
);
929 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
931 /* Determine if this is the Service Provider that the user asked for */
932 if( !IsEqualGUID( &serviceProviderGUID
, guidSP
) )
937 /* Get a handle for this particular service provider */
938 if( RegOpenKeyExA( hkServiceProvider
, atKey
, 0, KEY_READ
,
939 &hkServiceProviderAt
) != ERROR_SUCCESS
)
941 TRACE(": No Address Types registry data sub key/members\n" );
945 /* Traverse all the address type we have available */
947 RegEnumKeyExA( hkServiceProviderAt
, dwAtIndex
, atSubKey
, &sizeOfSubKeyName
,
948 NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
949 ++dwAtIndex
, sizeOfSubKeyName
=50 )
951 TRACE( "Found Address Type GUID %s\n", atSubKey
);
953 /* FIXME: Check return types to ensure we're interpreting data right */
954 lpWGUIDString
= HEAP_strdupAtoW( GetProcessHeap(), 0, atSubKey
);
955 CLSIDFromString( (LPCOLESTR
)lpWGUIDString
, &serviceProviderGUID
);
956 HeapFree( GetProcessHeap(), 0, lpWGUIDString
);
957 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
959 /* The enumeration will return FALSE if we are not to continue */
960 if( !lpEnumAddressTypeCallback( &serviceProviderGUID
, lpContext
, 0 ) )
962 WARN("lpEnumCallback returning FALSE\n" );
963 break; /* FIXME: This most likely has to break from the procedure...*/
968 /* We only enumerate address types for 1 GUID. We've found it, so quit looking */
975 static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumAddressTypes
976 ( LPDIRECTPLAYLOBBY iface
,
977 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
,
983 return DPERR_OUTOFMEMORY
;
986 /********************************************************************
988 * Enumerates what applications are registered with DirectPlay by
989 * invoking the callback function with lpContext.
992 static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumLocalApplications
993 ( LPDIRECTPLAYLOBBY iface
,
994 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback
,
998 ICOM_THIS(IDirectPlayLobbyWImpl
,iface
);
1000 FIXME("(%p)->(%p,%p,0x%08lx):stub\n", This
, lpEnumLocalAppCallback
, lpContext
, dwFlags
);
1002 return DPERR_OUTOFMEMORY
;
1005 static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumLocalApplications
1006 ( LPDIRECTPLAYLOBBYA iface
,
1007 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback
,
1011 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
1014 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Applications";
1015 LPSTR guidDataSubKey
= "Guid";
1016 DWORD dwIndex
, sizeOfSubKeyName
=50;
1017 char subKeyName
[51];
1020 TRACE("(%p)->(%p,%p,0x%08lx)\n", This
, lpEnumLocalAppCallback
, lpContext
, dwFlags
);
1024 return DPERR_INVALIDPARAMS
;
1027 if( !lpEnumLocalAppCallback
|| !*lpEnumLocalAppCallback
)
1029 return DPERR_INVALIDPARAMS
;
1032 /* Need to loop over the service providers in the registry */
1033 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
1034 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
1036 /* Hmmm. Does this mean that there are no service providers? */
1037 ERR(": no service providers?\n");
1041 /* Traverse all registered applications */
1043 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
, NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
1044 ++dwIndex
, sizeOfSubKeyName
=50 )
1047 HKEY hkServiceProvider
;
1048 GUID serviceProviderGUID
;
1049 DWORD returnTypeGUID
, sizeOfReturnBuffer
= 50;
1050 char returnBuffer
[51];
1051 LPWSTR lpWGUIDString
;
1052 DPLAPPINFO dplAppInfo
;
1054 TRACE(" this time through: %s\n", subKeyName
);
1056 /* Get a handle for this particular service provider */
1057 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
1058 &hkServiceProvider
) != ERROR_SUCCESS
)
1060 ERR(": what the heck is going on?\n" );
1064 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
1065 NULL
, &returnTypeGUID
, returnBuffer
,
1066 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1068 ERR(": missing GUID registry data members\n" );
1072 /* FIXME: Check return types to ensure we're interpreting data right */
1073 lpWGUIDString
= HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer
);
1074 CLSIDFromString( (LPCOLESTR
)lpWGUIDString
, &serviceProviderGUID
);
1075 HeapFree( GetProcessHeap(), 0, lpWGUIDString
);
1076 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
1078 dplAppInfo
.dwSize
= sizeof( dplAppInfo
);
1079 dplAppInfo
.guidApplication
= serviceProviderGUID
;
1080 dplAppInfo
.appName
.lpszAppNameA
= subKeyName
;
1082 EnterCriticalSection( &This
->unk
->DPL_lock
);
1084 memcpy( &This
->dpl
->hkCallbackKeyHack
, &hkServiceProvider
, sizeof( hkServiceProvider
) );
1086 if( !lpEnumLocalAppCallback( &dplAppInfo
, lpContext
, dwFlags
) )
1088 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1092 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1098 /********************************************************************
1100 * Retrieves the DPLCONNECTION structure that contains all the information
1101 * needed to start and connect an application. This was generated using
1102 * either the RunApplication or SetConnectionSettings methods.
1104 * NOTES: If lpData is NULL then just return lpdwDataSize. This allows
1105 * the data structure to be allocated by our caller which can then
1106 * call this procedure/method again with a valid data pointer.
1108 static HRESULT WINAPI IDirectPlayLobbyAImpl_GetConnectionSettings
1109 ( LPDIRECTPLAYLOBBYA iface
,
1112 LPDWORD lpdwDataSize
)
1114 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
1116 BOOL bSendHaveReadSettingsMessage
= FALSE
;
1118 TRACE("(%p)->(0x%08lx,%p,%p)\n", This
, dwAppID
, lpData
, lpdwDataSize
);
1120 EnterCriticalSection( &This
->unk
->DPL_lock
);
1122 hr
= DPLAYX_GetConnectionSettingsA( dwAppID
,
1125 &bSendHaveReadSettingsMessage
1128 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1130 if( bSendHaveReadSettingsMessage
)
1132 FIXME( "Send a DPSYS_CONNECTIONSETTINGSREAD message\n" );
1138 static HRESULT WINAPI IDirectPlayLobbyWImpl_GetConnectionSettings
1139 ( LPDIRECTPLAYLOBBY iface
,
1142 LPDWORD lpdwDataSize
)
1144 ICOM_THIS(IDirectPlayLobbyWImpl
,iface
);
1146 BOOL bSendHaveReadSettingsMessage
= FALSE
;
1148 TRACE("(%p)->(0x%08lx,%p,%p)\n", This
, dwAppID
, lpData
, lpdwDataSize
);
1150 EnterCriticalSection( &This
->unk
->DPL_lock
);
1152 hr
= DPLAYX_GetConnectionSettingsW( dwAppID
,
1155 &bSendHaveReadSettingsMessage
1158 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1160 if( bSendHaveReadSettingsMessage
)
1162 FIXME( "Send a DPSYS_CONNECTIONSETTINGSREAD message\n" );
1168 /********************************************************************
1170 * Retrieves the message sent between a lobby client and a DirectPlay
1171 * application. All messages are queued until received.
1174 static HRESULT WINAPI IDirectPlayLobbyAImpl_ReceiveLobbyMessage
1175 ( LPDIRECTPLAYLOBBYA iface
,
1178 LPDWORD lpdwMessageFlags
,
1180 LPDWORD lpdwDataSize
)
1182 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
1183 FIXME(":stub %p %08lx %08lx %p %p %p\n", This
, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
1185 return DPERR_OUTOFMEMORY
;
1188 static HRESULT WINAPI IDirectPlayLobbyWImpl_ReceiveLobbyMessage
1189 ( LPDIRECTPLAYLOBBY iface
,
1192 LPDWORD lpdwMessageFlags
,
1194 LPDWORD lpdwDataSize
)
1196 ICOM_THIS(IDirectPlayLobbyWImpl
,iface
);
1197 FIXME(":stub %p %08lx %08lx %p %p %p\n", This
, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
1199 return DPERR_OUTOFMEMORY
;
1202 typedef struct tagRunApplicationEnumStruct
1204 IDirectPlayLobbyAImpl
* This
;
1209 LPSTR lpszCommandLine
;
1210 LPSTR lpszCurrentDirectory
;
1211 } RunApplicationEnumStruct
, *lpRunApplicationEnumStruct
;
1213 /* To be called by RunApplication to find how to invoke the function */
1214 static BOOL CALLBACK RunApplicationA_EnumLocalApplications
1215 ( LPCDPLAPPINFO lpAppInfo
,
1219 lpRunApplicationEnumStruct lpData
= (lpRunApplicationEnumStruct
)lpContext
;
1221 if( IsEqualGUID( &lpAppInfo
->guidApplication
, &lpData
->appGUID
) )
1223 char returnBuffer
[200];
1224 DWORD returnType
, sizeOfReturnBuffer
;
1225 LPSTR clSubKey
= "CommandLine";
1226 LPSTR cdSubKey
= "CurrentDirectory";
1227 LPSTR fileSubKey
= "File";
1228 LPSTR pathSubKey
= "Path";
1230 /* FIXME: Lazy man hack - dplay struct has the present reg key saved */
1232 sizeOfReturnBuffer
= 200;
1234 /* Get all the appropriate data from the registry */
1235 if( RegQueryValueExA( lpData
->This
->dpl
->hkCallbackKeyHack
, clSubKey
,
1236 NULL
, &returnType
, returnBuffer
,
1237 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1239 ERR( ": missing CommandLine registry data member\n" );
1243 lpData
->lpszCommandLine
= HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY
, returnBuffer
);
1246 sizeOfReturnBuffer
= 200;
1248 if( RegQueryValueExA( lpData
->This
->dpl
->hkCallbackKeyHack
, cdSubKey
,
1249 NULL
, &returnType
, returnBuffer
,
1250 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1252 ERR( ": missing CurrentDirectory registry data member\n" );
1256 lpData
->lpszCurrentDirectory
= HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY
, returnBuffer
);
1259 sizeOfReturnBuffer
= 200;
1261 if( RegQueryValueExA( lpData
->This
->dpl
->hkCallbackKeyHack
, fileSubKey
,
1262 NULL
, &returnType
, returnBuffer
,
1263 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1265 ERR( ": missing File registry data member\n" );
1269 lpData
->lpszFileName
= HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY
, returnBuffer
);
1272 sizeOfReturnBuffer
= 200;
1274 if( RegQueryValueExA( lpData
->This
->dpl
->hkCallbackKeyHack
, pathSubKey
,
1275 NULL
, &returnType
, returnBuffer
,
1276 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1278 ERR( ": missing Path registry data member\n" );
1282 lpData
->lpszPath
= HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY
, returnBuffer
);
1285 return FALSE
; /* No need to keep going as we found what we wanted */
1288 return TRUE
; /* Keep enumerating, haven't found the application yet */
1291 /********************************************************************
1293 * Starts an application and passes to it all the information to
1294 * connect to a session.
1297 static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication
1298 ( LPDIRECTPLAYLOBBYA iface
,
1301 LPDPLCONNECTION lpConn
,
1302 HANDLE hReceiveEvent
)
1304 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
1306 RunApplicationEnumStruct enumData
;
1308 STARTUPINFOA startupInfo
;
1309 PROCESS_INFORMATION newProcessInfo
;
1311 DWORD dwSuspendCount
;
1313 TRACE( "(%p)->(0x%08lx,%p,%p,%x)\n", This
, dwFlags
, lpdwAppID
, lpConn
, hReceiveEvent
);
1317 return DPERR_INVALIDPARAMS
;
1320 if( DPLAYX_AnyLobbiesWaitingForConnSettings() )
1322 FIXME( "Waiting lobby not being handled correctly\n" );
1325 EnterCriticalSection( &This
->unk
->DPL_lock
);
1327 ZeroMemory( &enumData
, sizeof( enumData
) );
1328 enumData
.This
= This
;
1329 enumData
.appGUID
= lpConn
->lpSessionDesc
->guidApplication
;
1331 /* Our callback function will fill up the enumData structure with all the information
1332 required to start a new process */
1333 IDirectPlayLobby_EnumLocalApplications( iface
, RunApplicationA_EnumLocalApplications
,
1334 (LPVOID
)(&enumData
), 0 );
1336 /* First the application name */
1337 strcpy( temp
, enumData
.lpszPath
);
1338 strcat( temp
, "\\" );
1339 strcat( temp
, enumData
.lpszFileName
);
1340 HeapFree( GetProcessHeap(), 0, enumData
.lpszPath
);
1341 HeapFree( GetProcessHeap(), 0, enumData
.lpszFileName
);
1342 appName
= HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY
, temp
);
1344 /* Now the command line */
1345 strcat( temp
, " " );
1346 strcat( temp
, enumData
.lpszCommandLine
);
1347 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1348 enumData
.lpszCommandLine
= HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY
, temp
);
1350 ZeroMemory( &startupInfo
, sizeof( startupInfo
) );
1351 startupInfo
.cb
= sizeof( startupInfo
);
1352 /* FIXME: Should any fields be filled in? */
1354 ZeroMemory( &newProcessInfo
, sizeof( newProcessInfo
) );
1356 if( !CreateProcessA( appName
,
1357 enumData
.lpszCommandLine
,
1361 CREATE_DEFAULT_ERROR_MODE
| CREATE_NEW_CONSOLE
| CREATE_SUSPENDED
, /* Creation Flags */
1363 enumData
.lpszCurrentDirectory
,
1369 ERR( "Failed to create process for app %s\n", appName
);
1371 HeapFree( GetProcessHeap(), 0, appName
);
1372 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1373 HeapFree( GetProcessHeap(), 0, enumData
.lpszCurrentDirectory
);
1375 return DPERR_CANTCREATEPROCESS
;
1378 HeapFree( GetProcessHeap(), 0, appName
);
1379 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1380 HeapFree( GetProcessHeap(), 0, enumData
.lpszCurrentDirectory
);
1382 /* Reserve this global application id! */
1383 if( !DPLAYX_CreateLobbyApplication( newProcessInfo
.dwProcessId
, hReceiveEvent
) )
1385 ERR( "Unable to create global application data for 0x%08lx\n",
1386 newProcessInfo
.dwProcessId
);
1389 hr
= IDirectPlayLobby_SetConnectionSettings( iface
, 0, newProcessInfo
.dwProcessId
, lpConn
);
1393 ERR( "SetConnectionSettings failure %s\n", DPLAYX_HresultToString( hr
) );
1397 /* Everything seems to have been set correctly, update the dwAppID */
1398 *lpdwAppID
= newProcessInfo
.dwProcessId
;
1402 FIXME( "Need to store msg thread id\n" );
1403 CreateMessageReceptionThread( hReceiveEvent
);
1406 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1408 /* Unsuspend the process - should return the prev suspension count */
1409 if( ( dwSuspendCount
= ResumeThread( newProcessInfo
.hThread
) ) != 1 )
1411 ERR( "ResumeThread failed with 0x%08lx\n", dwSuspendCount
);
1417 static HRESULT WINAPI IDirectPlayLobbyWImpl_RunApplication
1418 ( LPDIRECTPLAYLOBBY iface
,
1421 LPDPLCONNECTION lpConn
,
1422 HANDLE hReceiveEvent
)
1424 ICOM_THIS(IDirectPlayLobbyWImpl
,iface
);
1425 FIXME( "(%p)->(0x%08lx,%p,%p,%p):stub\n", This
, dwFlags
, lpdwAppID
, lpConn
, (void *)hReceiveEvent
);
1426 return DPERR_OUTOFMEMORY
;
1429 /********************************************************************
1431 * Sends a message between the application and the lobby client.
1432 * All messages are queued until received.
1435 static HRESULT WINAPI IDirectPlayLobbyAImpl_SendLobbyMessage
1436 ( LPDIRECTPLAYLOBBYA iface
,
1443 return DPERR_OUTOFMEMORY
;
1446 static HRESULT WINAPI IDirectPlayLobbyWImpl_SendLobbyMessage
1447 ( LPDIRECTPLAYLOBBY iface
,
1454 return DPERR_OUTOFMEMORY
;
1457 /********************************************************************
1459 * Modifies the DPLCONNECTION structure to contain all information
1460 * needed to start and connect an application.
1463 static HRESULT WINAPI IDirectPlayLobbyWImpl_SetConnectionSettings
1464 ( LPDIRECTPLAYLOBBY iface
,
1467 LPDPLCONNECTION lpConn
)
1469 ICOM_THIS(IDirectPlayLobbyWImpl
,iface
);
1472 TRACE("(%p)->(0x%08lx,0x%08lx,%p)\n", This
, dwFlags
, dwAppID
, lpConn
);
1474 EnterCriticalSection( &This
->unk
->DPL_lock
);
1476 hr
= DPLAYX_SetConnectionSettingsW( dwFlags
, dwAppID
, lpConn
);
1478 /* FIXME: Don't think that this is supposed to fail, but the docuementation
1479 is somewhat sketchy. I'll try creating a lobby application
1481 if( hr
== DPERR_NOTLOBBIED
)
1483 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1484 dwAppID
= GetCurrentProcessId();
1485 DPLAYX_CreateLobbyApplication( dwAppID
, 0 );
1486 hr
= DPLAYX_SetConnectionSettingsW( dwFlags
, dwAppID
, lpConn
);
1489 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1494 static HRESULT WINAPI IDirectPlayLobbyAImpl_SetConnectionSettings
1495 ( LPDIRECTPLAYLOBBYA iface
,
1498 LPDPLCONNECTION lpConn
)
1500 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
1503 TRACE("(%p)->(0x%08lx,0x%08lx,%p)\n", This
, dwFlags
, dwAppID
, lpConn
);
1505 EnterCriticalSection( &This
->unk
->DPL_lock
);
1507 hr
= DPLAYX_SetConnectionSettingsA( dwFlags
, dwAppID
, lpConn
);
1509 /* FIXME: Don't think that this is supposed to fail, but the docuementation
1510 is somewhat sketchy. I'll try creating a lobby application
1512 if( hr
== DPERR_NOTLOBBIED
)
1514 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1515 dwAppID
= GetCurrentProcessId();
1516 DPLAYX_CreateLobbyApplication( dwAppID
, 0 );
1517 hr
= DPLAYX_SetConnectionSettingsA( dwFlags
, dwAppID
, lpConn
);
1520 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1525 /********************************************************************
1527 * Registers an event that will be set when a lobby message is received.
1530 static HRESULT WINAPI IDirectPlayLobbyAImpl_SetLobbyMessageEvent
1531 ( LPDIRECTPLAYLOBBYA iface
,
1534 HANDLE hReceiveEvent
)
1537 return DPERR_OUTOFMEMORY
;
1540 static HRESULT WINAPI IDirectPlayLobbyWImpl_SetLobbyMessageEvent
1541 ( LPDIRECTPLAYLOBBY iface
,
1544 HANDLE hReceiveEvent
)
1547 return DPERR_OUTOFMEMORY
;
1552 static HRESULT WINAPI IDirectPlayLobby2WImpl_CreateCompoundAddress
1553 ( LPDIRECTPLAYLOBBY2 iface
,
1554 LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1555 DWORD dwElementCount
,
1557 LPDWORD lpdwAddressSize
)
1559 return DPL_CreateCompoundAddress( lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
, FALSE
);
1562 static HRESULT WINAPI IDirectPlayLobby2AImpl_CreateCompoundAddress
1563 ( LPDIRECTPLAYLOBBY2A iface
,
1564 LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1565 DWORD dwElementCount
,
1567 LPDWORD lpdwAddressSize
)
1569 return DPL_CreateCompoundAddress( lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
, TRUE
);
1572 HRESULT DPL_CreateCompoundAddress
1573 ( LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1574 DWORD dwElementCount
,
1576 LPDWORD lpdwAddressSize
,
1577 BOOL bAnsiInterface
)
1579 DWORD dwSizeRequired
= 0;
1581 LPCDPCOMPOUNDADDRESSELEMENT lpOrigElements
= lpElements
;
1583 TRACE("(%p,0x%08lx,%p,%p)\n", lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
);
1585 /* Parameter check */
1586 if( ( lpElements
== NULL
) ||
1587 ( dwElementCount
== 0 ) /* FIXME: Not sure if this is a failure case */
1590 return DPERR_INVALIDPARAMS
;
1593 /* Add the total size chunk */
1594 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( DWORD
);
1596 /* Calculate the size of the buffer required */
1597 for ( dwElements
= dwElementCount
; dwElements
> 0; --dwElements
, ++lpElements
)
1599 if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ServiceProvider
) ) ||
1600 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_LobbyProvider
) )
1603 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( GUID
);
1605 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Phone
) ) ||
1606 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Modem
) ) ||
1607 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INet
) )
1610 if( !bAnsiInterface
)
1612 ERR( "Ansi GUIDs used for unicode interface\n" );
1613 return DPERR_INVALIDFLAGS
;
1616 dwSizeRequired
+= sizeof( DPADDRESS
) + lpElements
->dwDataSize
;
1618 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_PhoneW
) ) ||
1619 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ModemW
) ) ||
1620 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetW
) )
1623 if( bAnsiInterface
)
1625 ERR( "Unicode GUIDs used for ansi interface\n" );
1626 return DPERR_INVALIDFLAGS
;
1629 FIXME( "Right size for unicode interface?\n" );
1630 dwSizeRequired
+= sizeof( DPADDRESS
) + lpElements
->dwDataSize
* sizeof( WCHAR
);
1632 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetPort
) )
1634 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( WORD
);
1636 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ComPort
) )
1638 FIXME( "Right size for unicode interface?\n" );
1639 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( DPCOMPORTADDRESS
); /* FIXME: Right size? */
1643 ERR( "Unknown GUID %s\n", debugstr_guid(&lpElements
->guidDataType
) );
1644 return DPERR_INVALIDFLAGS
;
1648 /* The user wants to know how big a buffer to allocate for us */
1649 if( ( lpAddress
== NULL
) ||
1650 ( *lpdwAddressSize
< dwSizeRequired
)
1653 *lpdwAddressSize
= dwSizeRequired
;
1654 return DPERR_BUFFERTOOSMALL
;
1657 /* Add the total size chunk */
1659 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1661 lpdpAddress
->guidDataType
= DPAID_TotalSize
;
1662 lpdpAddress
->dwDataSize
= sizeof( DWORD
);
1663 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1665 *(LPDWORD
)lpAddress
= dwSizeRequired
;
1666 lpAddress
= (char *) lpAddress
+ sizeof( DWORD
);
1669 /* Calculate the size of the buffer required */
1670 for( dwElements
= dwElementCount
, lpElements
= lpOrigElements
;
1672 --dwElements
, ++lpElements
)
1674 if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ServiceProvider
) ) ||
1675 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_LobbyProvider
) )
1678 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1680 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1681 lpdpAddress
->dwDataSize
= sizeof( GUID
);
1682 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1684 *((LPGUID
)lpAddress
) = *((LPGUID
)lpElements
->lpData
);
1685 lpAddress
= (char *) lpAddress
+ sizeof( GUID
);
1687 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Phone
) ) ||
1688 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Modem
) ) ||
1689 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INet
) )
1692 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1694 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1695 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1696 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1698 lstrcpynA( (LPSTR
)lpAddress
,
1699 (LPCSTR
)lpElements
->lpData
,
1700 lpElements
->dwDataSize
);
1701 lpAddress
= (char *) lpAddress
+ lpElements
->dwDataSize
;
1703 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_PhoneW
) ) ||
1704 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ModemW
) ) ||
1705 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetW
) )
1708 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1710 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1711 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1712 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1714 lstrcpynW( (LPWSTR
)lpAddress
,
1715 (LPCWSTR
)lpElements
->lpData
,
1716 lpElements
->dwDataSize
);
1717 lpAddress
= (char *) lpAddress
+ lpElements
->dwDataSize
* sizeof( WCHAR
);
1719 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetPort
) )
1721 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1723 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1724 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1725 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1727 *((LPWORD
)lpAddress
) = *((LPWORD
)lpElements
->lpData
);
1728 lpAddress
= (char *) lpAddress
+ sizeof( WORD
);
1730 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ComPort
) )
1732 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1734 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1735 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1736 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1738 memcpy( lpAddress
, lpElements
->lpData
, sizeof( DPADDRESS
) );
1739 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1748 static HRESULT WINAPI IDirectPlayLobby3WImpl_ConnectEx
1749 ( LPDIRECTPLAYLOBBY3 iface
, DWORD dwFlags
, REFIID riid
,
1750 LPVOID
* lplpDP
, IUnknown
* pUnk
)
1752 ICOM_THIS( IDirectPlayLobbyAImpl
, iface
);
1753 return DPL_ConnectEx( This
, dwFlags
, riid
, lplpDP
, pUnk
);
1756 static HRESULT WINAPI IDirectPlayLobby3AImpl_ConnectEx
1757 ( LPDIRECTPLAYLOBBY3A iface
, DWORD dwFlags
, REFIID riid
,
1758 LPVOID
* lplpDP
, IUnknown
* pUnk
)
1760 ICOM_THIS( IDirectPlayLobbyAImpl
, iface
);
1761 return DPL_ConnectEx( This
, dwFlags
, riid
, lplpDP
, pUnk
);
1764 static HRESULT WINAPI IDirectPlayLobby3WImpl_RegisterApplication
1765 ( LPDIRECTPLAYLOBBY3 iface
, DWORD dwFlags
, LPDPAPPLICATIONDESC lpAppDesc
)
1771 static HRESULT WINAPI IDirectPlayLobby3AImpl_RegisterApplication
1772 ( LPDIRECTPLAYLOBBY3A iface
, DWORD dwFlags
, LPDPAPPLICATIONDESC lpAppDesc
)
1778 static HRESULT WINAPI IDirectPlayLobby3WImpl_UnregisterApplication
1779 ( LPDIRECTPLAYLOBBY3 iface
, DWORD dwFlags
, REFGUID lpAppDesc
)
1785 static HRESULT WINAPI IDirectPlayLobby3AImpl_UnregisterApplication
1786 ( LPDIRECTPLAYLOBBY3A iface
, DWORD dwFlags
, REFGUID lpAppDesc
)
1792 static HRESULT WINAPI IDirectPlayLobby3WImpl_WaitForConnectionSettings
1793 ( LPDIRECTPLAYLOBBY3 iface
, DWORD dwFlags
)
1796 BOOL bStartWait
= (dwFlags
& DPLWAIT_CANCEL
) ? FALSE
: TRUE
;
1798 TRACE( "(%p)->(0x%08lx)\n", iface
, dwFlags
);
1800 if( DPLAYX_WaitForConnectionSettings( bStartWait
) )
1802 /* FIXME: What is the correct error return code? */
1803 hr
= DPERR_NOTLOBBIED
;
1809 static HRESULT WINAPI IDirectPlayLobby3AImpl_WaitForConnectionSettings
1810 ( LPDIRECTPLAYLOBBY3A iface
, DWORD dwFlags
)
1813 BOOL bStartWait
= (dwFlags
& DPLWAIT_CANCEL
) ? FALSE
: TRUE
;
1815 TRACE( "(%p)->(0x%08lx)\n", iface
, dwFlags
);
1817 if( DPLAYX_WaitForConnectionSettings( bStartWait
) )
1819 /* FIXME: What is the correct error return code? */
1820 hr
= DPERR_NOTLOBBIED
;
1827 /* Virtual Table definitions for DPL{1,2,3}{A,W} */
1829 /* Note: Hack so we can reuse the old functions without compiler warnings */
1830 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1831 # define XCAST(fun) (typeof(directPlayLobbyAVT.fn##fun))
1833 # define XCAST(fun) (void*)
1836 /* Direct Play Lobby 1 (ascii) Virtual Table for methods */
1837 /* All lobby 1 methods are exactly the same except QueryInterface */
1838 static struct ICOM_VTABLE(IDirectPlayLobby
) directPlayLobbyAVT
=
1840 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1842 IDirectPlayLobbyAImpl_QueryInterface
,
1843 XCAST(AddRef
)IDirectPlayLobbyImpl_AddRef
,
1844 XCAST(Release
)IDirectPlayLobbyAImpl_Release
,
1846 IDirectPlayLobbyAImpl_Connect
,
1847 IDirectPlayLobbyAImpl_CreateAddress
,
1848 IDirectPlayLobbyAImpl_EnumAddress
,
1849 IDirectPlayLobbyAImpl_EnumAddressTypes
,
1850 IDirectPlayLobbyAImpl_EnumLocalApplications
,
1851 IDirectPlayLobbyAImpl_GetConnectionSettings
,
1852 IDirectPlayLobbyAImpl_ReceiveLobbyMessage
,
1853 IDirectPlayLobbyAImpl_RunApplication
,
1854 IDirectPlayLobbyAImpl_SendLobbyMessage
,
1855 IDirectPlayLobbyAImpl_SetConnectionSettings
,
1856 IDirectPlayLobbyAImpl_SetLobbyMessageEvent
1861 /* Note: Hack so we can reuse the old functions without compiler warnings */
1862 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1863 # define XCAST(fun) (typeof(directPlayLobbyWVT.fn##fun))
1865 # define XCAST(fun) (void*)
1868 /* Direct Play Lobby 1 (unicode) Virtual Table for methods */
1869 static ICOM_VTABLE(IDirectPlayLobby
) directPlayLobbyWVT
=
1871 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1873 IDirectPlayLobbyW_QueryInterface
,
1874 XCAST(AddRef
)IDirectPlayLobbyImpl_AddRef
,
1875 XCAST(Release
)IDirectPlayLobbyAImpl_Release
,
1877 IDirectPlayLobbyWImpl_Connect
,
1878 IDirectPlayLobbyWImpl_CreateAddress
,
1879 IDirectPlayLobbyWImpl_EnumAddress
,
1880 IDirectPlayLobbyWImpl_EnumAddressTypes
,
1881 IDirectPlayLobbyWImpl_EnumLocalApplications
,
1882 IDirectPlayLobbyWImpl_GetConnectionSettings
,
1883 IDirectPlayLobbyWImpl_ReceiveLobbyMessage
,
1884 IDirectPlayLobbyWImpl_RunApplication
,
1885 IDirectPlayLobbyWImpl_SendLobbyMessage
,
1886 IDirectPlayLobbyWImpl_SetConnectionSettings
,
1887 IDirectPlayLobbyWImpl_SetLobbyMessageEvent
1891 /* Note: Hack so we can reuse the old functions without compiler warnings */
1892 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1893 # define XCAST(fun) (typeof(directPlayLobby2AVT.fn##fun))
1895 # define XCAST(fun) (void*)
1898 /* Direct Play Lobby 2 (ascii) Virtual Table for methods */
1899 static ICOM_VTABLE(IDirectPlayLobby2
) directPlayLobby2AVT
=
1901 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1903 IDirectPlayLobby2AImpl_QueryInterface
,
1904 XCAST(AddRef
)IDirectPlayLobbyImpl_AddRef
,
1905 XCAST(Release
)IDirectPlayLobbyAImpl_Release
,
1907 XCAST(Connect
)IDirectPlayLobbyAImpl_Connect
,
1908 XCAST(CreateAddress
)IDirectPlayLobbyAImpl_CreateAddress
,
1909 XCAST(EnumAddress
)IDirectPlayLobbyAImpl_EnumAddress
,
1910 XCAST(EnumAddressTypes
)IDirectPlayLobbyAImpl_EnumAddressTypes
,
1911 XCAST(EnumLocalApplications
)IDirectPlayLobbyAImpl_EnumLocalApplications
,
1912 XCAST(GetConnectionSettings
)IDirectPlayLobbyAImpl_GetConnectionSettings
,
1913 XCAST(ReceiveLobbyMessage
)IDirectPlayLobbyAImpl_ReceiveLobbyMessage
,
1914 XCAST(RunApplication
)IDirectPlayLobbyAImpl_RunApplication
,
1915 XCAST(SendLobbyMessage
)IDirectPlayLobbyAImpl_SendLobbyMessage
,
1916 XCAST(SetConnectionSettings
)IDirectPlayLobbyAImpl_SetConnectionSettings
,
1917 XCAST(SetLobbyMessageEvent
)IDirectPlayLobbyAImpl_SetLobbyMessageEvent
,
1919 IDirectPlayLobby2AImpl_CreateCompoundAddress
1923 /* Note: Hack so we can reuse the old functions without compiler warnings */
1924 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1925 # define XCAST(fun) (typeof(directPlayLobby2AVT.fn##fun))
1927 # define XCAST(fun) (void*)
1930 /* Direct Play Lobby 2 (unicode) Virtual Table for methods */
1931 static ICOM_VTABLE(IDirectPlayLobby2
) directPlayLobby2WVT
=
1933 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1935 IDirectPlayLobby2WImpl_QueryInterface
,
1936 XCAST(AddRef
)IDirectPlayLobbyImpl_AddRef
,
1937 XCAST(Release
)IDirectPlayLobbyAImpl_Release
,
1939 XCAST(Connect
)IDirectPlayLobbyWImpl_Connect
,
1940 XCAST(CreateAddress
)IDirectPlayLobbyWImpl_CreateAddress
,
1941 XCAST(EnumAddress
)IDirectPlayLobbyWImpl_EnumAddress
,
1942 XCAST(EnumAddressTypes
)IDirectPlayLobbyWImpl_EnumAddressTypes
,
1943 XCAST(EnumLocalApplications
)IDirectPlayLobbyWImpl_EnumLocalApplications
,
1944 XCAST(GetConnectionSettings
)IDirectPlayLobbyWImpl_GetConnectionSettings
,
1945 XCAST(ReceiveLobbyMessage
)IDirectPlayLobbyWImpl_ReceiveLobbyMessage
,
1946 XCAST(RunApplication
)IDirectPlayLobbyWImpl_RunApplication
,
1947 XCAST(SendLobbyMessage
)IDirectPlayLobbyWImpl_SendLobbyMessage
,
1948 XCAST(SetConnectionSettings
)IDirectPlayLobbyWImpl_SetConnectionSettings
,
1949 XCAST(SetLobbyMessageEvent
)IDirectPlayLobbyWImpl_SetLobbyMessageEvent
,
1951 IDirectPlayLobby2WImpl_CreateCompoundAddress
1955 /* Direct Play Lobby 3 (ascii) Virtual Table for methods */
1957 /* Note: Hack so we can reuse the old functions without compiler warnings */
1958 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1959 # define XCAST(fun) (typeof(directPlayLobby3AVT.fn##fun))
1961 # define XCAST(fun) (void*)
1964 static ICOM_VTABLE(IDirectPlayLobby3
) directPlayLobby3AVT
=
1966 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1967 IDirectPlayLobby3AImpl_QueryInterface
,
1968 XCAST(AddRef
)IDirectPlayLobbyImpl_AddRef
,
1969 XCAST(Release
)IDirectPlayLobbyAImpl_Release
,
1971 XCAST(Connect
)IDirectPlayLobbyAImpl_Connect
,
1972 XCAST(CreateAddress
)IDirectPlayLobbyAImpl_CreateAddress
,
1973 XCAST(EnumAddress
)IDirectPlayLobbyAImpl_EnumAddress
,
1974 XCAST(EnumAddressTypes
)IDirectPlayLobbyAImpl_EnumAddressTypes
,
1975 XCAST(EnumLocalApplications
)IDirectPlayLobbyAImpl_EnumLocalApplications
,
1976 XCAST(GetConnectionSettings
)IDirectPlayLobbyAImpl_GetConnectionSettings
,
1977 XCAST(ReceiveLobbyMessage
)IDirectPlayLobbyAImpl_ReceiveLobbyMessage
,
1978 XCAST(RunApplication
)IDirectPlayLobbyAImpl_RunApplication
,
1979 XCAST(SendLobbyMessage
)IDirectPlayLobbyAImpl_SendLobbyMessage
,
1980 XCAST(SetConnectionSettings
)IDirectPlayLobbyAImpl_SetConnectionSettings
,
1981 XCAST(SetLobbyMessageEvent
)IDirectPlayLobbyAImpl_SetLobbyMessageEvent
,
1983 XCAST(CreateCompoundAddress
)IDirectPlayLobby2AImpl_CreateCompoundAddress
,
1985 IDirectPlayLobby3AImpl_ConnectEx
,
1986 IDirectPlayLobby3AImpl_RegisterApplication
,
1987 IDirectPlayLobby3AImpl_UnregisterApplication
,
1988 IDirectPlayLobby3AImpl_WaitForConnectionSettings
1992 /* Direct Play Lobby 3 (unicode) Virtual Table for methods */
1994 /* Note: Hack so we can reuse the old functions without compiler warnings */
1995 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1996 # define XCAST(fun) (typeof(directPlayLobby3WVT.fn##fun))
1998 # define XCAST(fun) (void*)
2001 static ICOM_VTABLE(IDirectPlayLobby3
) directPlayLobby3WVT
=
2003 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2004 IDirectPlayLobby3WImpl_QueryInterface
,
2005 XCAST(AddRef
)IDirectPlayLobbyImpl_AddRef
,
2006 XCAST(Release
)IDirectPlayLobbyAImpl_Release
,
2008 XCAST(Connect
)IDirectPlayLobbyWImpl_Connect
,
2009 XCAST(CreateAddress
)IDirectPlayLobbyWImpl_CreateAddress
,
2010 XCAST(EnumAddress
)IDirectPlayLobbyWImpl_EnumAddress
,
2011 XCAST(EnumAddressTypes
)IDirectPlayLobbyWImpl_EnumAddressTypes
,
2012 XCAST(EnumLocalApplications
)IDirectPlayLobbyWImpl_EnumLocalApplications
,
2013 XCAST(GetConnectionSettings
)IDirectPlayLobbyWImpl_GetConnectionSettings
,
2014 XCAST(ReceiveLobbyMessage
)IDirectPlayLobbyWImpl_ReceiveLobbyMessage
,
2015 XCAST(RunApplication
)IDirectPlayLobbyWImpl_RunApplication
,
2016 XCAST(SendLobbyMessage
)IDirectPlayLobbyWImpl_SendLobbyMessage
,
2017 XCAST(SetConnectionSettings
)IDirectPlayLobbyWImpl_SetConnectionSettings
,
2018 XCAST(SetLobbyMessageEvent
)IDirectPlayLobbyWImpl_SetLobbyMessageEvent
,
2020 XCAST(CreateCompoundAddress
)IDirectPlayLobby2WImpl_CreateCompoundAddress
,
2022 IDirectPlayLobby3WImpl_ConnectEx
,
2023 IDirectPlayLobby3WImpl_RegisterApplication
,
2024 IDirectPlayLobby3WImpl_UnregisterApplication
,
2025 IDirectPlayLobby3WImpl_WaitForConnectionSettings
2030 /*********************************************************
2032 * Direct Play and Direct Play Lobby Interface Implementation
2034 *********************************************************/
2036 /***************************************************************************
2037 * DirectPlayLobbyCreateA (DPLAYX.4)
2040 HRESULT WINAPI
DirectPlayLobbyCreateA( LPGUID lpGUIDDSP
,
2041 LPDIRECTPLAYLOBBYA
*lplpDPL
,
2046 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
2047 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
2049 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
2050 * equal 0. These fields are mostly for future expansion.
2052 if ( lpGUIDDSP
|| lpUnk
|| lpData
|| dwDataSize
)
2055 return DPERR_INVALIDPARAMS
;
2058 return directPlayLobby_QueryInterface( &IID_IDirectPlayLobbyA
, (void**)lplpDPL
);
2061 /***************************************************************************
2062 * DirectPlayLobbyCreateW (DPLAYX.5)
2065 HRESULT WINAPI
DirectPlayLobbyCreateW( LPGUID lpGUIDDSP
,
2066 LPDIRECTPLAYLOBBY
*lplpDPL
,
2071 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
2072 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
2074 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
2075 * equal 0. These fields are mostly for future expansion.
2077 if ( lpGUIDDSP
|| lpData
|| dwDataSize
)
2080 ERR("Bad parameters!\n" );
2081 return DPERR_INVALIDPARAMS
;
2087 ERR("Bad parameters!\n" );
2088 return CLASS_E_NOAGGREGATION
;
2091 return directPlayLobby_QueryInterface( &IID_IDirectPlayLobby
, (void**)lplpDPL
);