1 /* Direct Play Lobby 2 & 3 Implementation
3 * Copyright 1998,1999,2000 - Peter Hunnisett
5 * <presently under construction - contact hunnise@nortelnetworks.com>
13 #include "debugtools.h"
17 #include "dplayx_global.h"
18 #include "dplayx_messages.h"
19 #include "dplayx_queue.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 extern 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
);
49 BOOL
DPL_CreateAndSetLobbyHandles( DWORD dwDestProcessId
, HANDLE hDestProcess
,
50 LPHANDLE lphStart
, LPHANDLE lphDeath
,
54 /*****************************************************************************
55 * IDirectPlayLobby {1,2,3} implementation structure
57 * The philosophy behind this extra pointer derefernce is that I wanted to
58 * have the same structure for all types of objects without having to do
59 * alot of casting. I also only wanted to implement an interface in the
60 * object it was "released" with IUnknown interface being implemented in the 1 version.
61 * Of course, with these new interfaces comes the data required to keep the state required
62 * by these interfaces. So, basically, the pointers contain the data associated with
63 * a release. If you use the data associated with release 3 in a release 2 object, you'll
64 * get a run time trap, as that won't have any data.
69 DPQ_ENTRY( DPLMSG
) msgs
; /* Link to next queued message */
71 typedef struct DPLMSG
* LPDPLMSG
;
73 typedef struct tagDirectPlayLobbyIUnknownData
76 CRITICAL_SECTION DPL_lock
;
77 } DirectPlayLobbyIUnknownData
;
79 typedef struct tagDirectPlayLobbyData
81 HKEY hkCallbackKeyHack
;
83 DPQ_HEAD( DPLMSG
) msgs
; /* List of messages received */
84 } DirectPlayLobbyData
;
86 typedef struct tagDirectPlayLobby2Data
89 } DirectPlayLobby2Data
;
91 typedef struct tagDirectPlayLobby3Data
94 } DirectPlayLobby3Data
;
96 #define DPL_IMPL_FIELDS \
97 ULONG ulInterfaceRef; \
98 DirectPlayLobbyIUnknownData* unk; \
99 DirectPlayLobbyData* dpl; \
100 DirectPlayLobby2Data* dpl2; \
101 DirectPlayLobby3Data* dpl3;
103 struct IDirectPlayLobbyImpl
105 ICOM_VFIELD(IDirectPlayLobby
);
109 struct IDirectPlayLobby2Impl
111 ICOM_VFIELD(IDirectPlayLobby2
);
115 struct IDirectPlayLobby3Impl
117 ICOM_VFIELD(IDirectPlayLobby3
);
122 /* Forward declarations of virtual tables */
123 static ICOM_VTABLE(IDirectPlayLobby
) directPlayLobbyWVT
;
124 static ICOM_VTABLE(IDirectPlayLobby2
) directPlayLobby2WVT
;
125 static ICOM_VTABLE(IDirectPlayLobby3
) directPlayLobby3WVT
;
127 static ICOM_VTABLE(IDirectPlayLobby
) directPlayLobbyAVT
;
128 static ICOM_VTABLE(IDirectPlayLobby2
) directPlayLobby2AVT
;
129 static ICOM_VTABLE(IDirectPlayLobby3
) directPlayLobby3AVT
;
134 static BOOL
DPL_CreateIUnknown( LPVOID lpDPL
)
136 ICOM_THIS(IDirectPlayLobbyAImpl
,lpDPL
);
138 This
->unk
= (DirectPlayLobbyIUnknownData
*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
139 sizeof( *(This
->unk
) ) );
140 if ( This
->unk
== NULL
)
145 InitializeCriticalSection( &This
->unk
->DPL_lock
);
150 static BOOL
DPL_DestroyIUnknown( LPVOID lpDPL
)
152 ICOM_THIS(IDirectPlayLobbyAImpl
,lpDPL
);
154 DeleteCriticalSection( &This
->unk
->DPL_lock
);
155 HeapFree( GetProcessHeap(), 0, This
->unk
);
160 static BOOL
DPL_CreateLobby1( LPVOID lpDPL
)
162 ICOM_THIS(IDirectPlayLobbyAImpl
,lpDPL
);
164 This
->dpl
= (DirectPlayLobbyData
*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
165 sizeof( *(This
->dpl
) ) );
166 if ( This
->dpl
== NULL
)
171 DPQ_INIT( This
->dpl
->msgs
);
176 static BOOL
DPL_DestroyLobby1( LPVOID lpDPL
)
178 ICOM_THIS(IDirectPlayLobbyAImpl
,lpDPL
);
180 if( This
->dpl
->dwMsgThread
)
182 FIXME( "Should kill the msg thread\n" );
185 DPQ_DELETEQ( This
->dpl
->msgs
, msgs
, LPDPLMSG
, cbDeleteElemFromHeap
);
187 /* Delete the contents */
188 HeapFree( GetProcessHeap(), 0, This
->dpl
);
193 static BOOL
DPL_CreateLobby2( LPVOID lpDPL
)
195 ICOM_THIS(IDirectPlayLobby2AImpl
,lpDPL
);
197 This
->dpl2
= (DirectPlayLobby2Data
*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
198 sizeof( *(This
->dpl2
) ) );
199 if ( This
->dpl2
== NULL
)
207 static BOOL
DPL_DestroyLobby2( LPVOID lpDPL
)
209 ICOM_THIS(IDirectPlayLobby2AImpl
,lpDPL
);
211 HeapFree( GetProcessHeap(), 0, This
->dpl2
);
216 static BOOL
DPL_CreateLobby3( LPVOID lpDPL
)
218 ICOM_THIS(IDirectPlayLobby3AImpl
,lpDPL
);
220 This
->dpl3
= (DirectPlayLobby3Data
*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
221 sizeof( *(This
->dpl3
) ) );
222 if ( This
->dpl3
== NULL
)
230 static BOOL
DPL_DestroyLobby3( LPVOID lpDPL
)
232 ICOM_THIS(IDirectPlayLobby3AImpl
,lpDPL
);
234 HeapFree( GetProcessHeap(), 0, This
->dpl3
);
240 /* The COM interface for upversioning an interface
241 * We've been given a GUID (riid) and we need to replace the present
242 * interface with that of the requested interface.
244 * Snip from some Microsoft document:
245 * There are four requirements for implementations of QueryInterface (In these
246 * cases, "must succeed" means "must succeed barring catastrophic failure."):
248 * * The set of interfaces accessible on an object through
249 * IUnknown::QueryInterface must be static, not dynamic. This means that
250 * if a call to QueryInterface for a pointer to a specified interface
251 * succeeds the first time, it must succeed again, and if it fails the
252 * first time, it must fail on all subsequent queries.
253 * * It must be symmetric ~W if a client holds a pointer to an interface on
254 * an object, and queries for that interface, the call must succeed.
255 * * It must be reflexive ~W if a client holding a pointer to one interface
256 * queries successfully for another, a query through the obtained pointer
257 * for the first interface must succeed.
258 * * It must be transitive ~W if a client holding a pointer to one interface
259 * queries successfully for a second, and through that pointer queries
260 * successfully for a third interface, a query for the first interface
261 * through the pointer for the third interface must succeed.
264 HRESULT DPL_CreateInterface
265 ( REFIID riid
, LPVOID
* ppvObj
)
267 TRACE( " for %s\n", debugstr_guid( riid
) );
269 *ppvObj
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
270 sizeof( IDirectPlayLobbyWImpl
) );
272 if( *ppvObj
== NULL
)
274 return DPERR_OUTOFMEMORY
;
277 if( IsEqualGUID( &IID_IDirectPlayLobby
, riid
) )
279 ICOM_THIS(IDirectPlayLobbyWImpl
,*ppvObj
);
280 ICOM_VTBL(This
) = &directPlayLobbyWVT
;
282 else if( IsEqualGUID( &IID_IDirectPlayLobbyA
, riid
) )
284 ICOM_THIS(IDirectPlayLobbyAImpl
,*ppvObj
);
285 ICOM_VTBL(This
) = &directPlayLobbyAVT
;
287 else if( IsEqualGUID( &IID_IDirectPlayLobby2
, riid
) )
289 ICOM_THIS(IDirectPlayLobby2WImpl
,*ppvObj
);
290 ICOM_VTBL(This
) = &directPlayLobby2WVT
;
292 else if( IsEqualGUID( &IID_IDirectPlayLobby2A
, riid
) )
294 ICOM_THIS(IDirectPlayLobby2AImpl
,*ppvObj
);
295 ICOM_VTBL(This
) = &directPlayLobby2AVT
;
297 else if( IsEqualGUID( &IID_IDirectPlayLobby3
, riid
) )
299 ICOM_THIS(IDirectPlayLobby3WImpl
,*ppvObj
);
300 ICOM_VTBL(This
) = &directPlayLobby3WVT
;
302 else if( IsEqualGUID( &IID_IDirectPlayLobby3A
, riid
) )
304 ICOM_THIS(IDirectPlayLobby3AImpl
,*ppvObj
);
305 ICOM_VTBL(This
) = &directPlayLobby3AVT
;
309 /* Unsupported interface */
310 HeapFree( GetProcessHeap(), 0, *ppvObj
);
313 return E_NOINTERFACE
;
317 if ( DPL_CreateIUnknown( *ppvObj
) &&
318 DPL_CreateLobby1( *ppvObj
) &&
319 DPL_CreateLobby2( *ppvObj
) &&
320 DPL_CreateLobby3( *ppvObj
)
323 IDirectPlayLobby_AddRef( (LPDIRECTPLAYLOBBY
)*ppvObj
);
327 /* Initialize failed, destroy it */
328 DPL_DestroyLobby3( *ppvObj
);
329 DPL_DestroyLobby2( *ppvObj
);
330 DPL_DestroyLobby1( *ppvObj
);
331 DPL_DestroyIUnknown( *ppvObj
);
332 HeapFree( GetProcessHeap(), 0, *ppvObj
);
335 return DPERR_NOMEMORY
;
338 static HRESULT WINAPI DPL_QueryInterface
339 ( LPDIRECTPLAYLOBBYA iface
,
343 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
344 TRACE("(%p)->(%s,%p)\n", This
, debugstr_guid( riid
), ppvObj
);
346 *ppvObj
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
349 if( *ppvObj
== NULL
)
351 return DPERR_OUTOFMEMORY
;
354 CopyMemory( *ppvObj
, This
, sizeof( *This
) );
355 (*(IDirectPlayLobbyAImpl
**)ppvObj
)->ulInterfaceRef
= 0;
357 if( IsEqualGUID( &IID_IDirectPlayLobby
, riid
) )
359 ICOM_THIS(IDirectPlayLobbyWImpl
,*ppvObj
);
360 ICOM_VTBL(This
) = &directPlayLobbyWVT
;
362 else if( IsEqualGUID( &IID_IDirectPlayLobbyA
, riid
) )
364 ICOM_THIS(IDirectPlayLobbyAImpl
,*ppvObj
);
365 ICOM_VTBL(This
) = &directPlayLobbyAVT
;
367 else if( IsEqualGUID( &IID_IDirectPlayLobby2
, riid
) )
369 ICOM_THIS(IDirectPlayLobby2WImpl
,*ppvObj
);
370 ICOM_VTBL(This
) = &directPlayLobby2WVT
;
372 else if( IsEqualGUID( &IID_IDirectPlayLobby2A
, riid
) )
374 ICOM_THIS(IDirectPlayLobby2AImpl
,*ppvObj
);
375 ICOM_VTBL(This
) = &directPlayLobby2AVT
;
377 else if( IsEqualGUID( &IID_IDirectPlayLobby3
, riid
) )
379 ICOM_THIS(IDirectPlayLobby3WImpl
,*ppvObj
);
380 ICOM_VTBL(This
) = &directPlayLobby3WVT
;
382 else if( IsEqualGUID( &IID_IDirectPlayLobby3A
, riid
) )
384 ICOM_THIS(IDirectPlayLobby3AImpl
,*ppvObj
);
385 ICOM_VTBL(This
) = &directPlayLobby3AVT
;
389 /* Unsupported interface */
390 HeapFree( GetProcessHeap(), 0, *ppvObj
);
393 return E_NOINTERFACE
;
396 IDirectPlayLobby_AddRef( (LPDIRECTPLAYLOBBY
)*ppvObj
);
402 * Simple procedure. Just increment the reference count to this
403 * structure and return the new reference count.
405 static ULONG WINAPI DPL_AddRef
406 ( LPDIRECTPLAYLOBBY iface
)
408 ULONG ulInterfaceRefCount
, ulObjRefCount
;
409 ICOM_THIS(IDirectPlayLobbyWImpl
,iface
);
411 ulObjRefCount
= InterlockedIncrement( &This
->unk
->ulObjRef
);
412 ulInterfaceRefCount
= InterlockedIncrement( &This
->ulInterfaceRef
);
414 TRACE( "ref count incremented to %lu:%lu for %p\n",
415 ulInterfaceRefCount
, ulObjRefCount
, This
);
417 return ulObjRefCount
;
421 * Simple COM procedure. Decrease the reference count to this object.
422 * If the object no longer has any reference counts, free up the associated
425 static ULONG WINAPI DPL_Release
426 ( LPDIRECTPLAYLOBBYA iface
)
428 ULONG ulInterfaceRefCount
, ulObjRefCount
;
429 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
431 ulObjRefCount
= InterlockedDecrement( &This
->unk
->ulObjRef
);
432 ulInterfaceRefCount
= InterlockedDecrement( &This
->ulInterfaceRef
);
434 TRACE( "ref count decremented to %lu:%lu for %p\n",
435 ulInterfaceRefCount
, ulObjRefCount
, This
);
437 /* Deallocate if this is the last reference to the object */
438 if( ulObjRefCount
== 0 )
440 DPL_DestroyLobby3( This
);
441 DPL_DestroyLobby2( This
);
442 DPL_DestroyLobby1( This
);
443 DPL_DestroyIUnknown( This
);
446 if( ulInterfaceRefCount
== 0 )
448 HeapFree( GetProcessHeap(), 0, This
);
451 return ulInterfaceRefCount
;
455 /********************************************************************
457 * Connects an application to the session specified by the DPLCONNECTION
458 * structure currently stored with the DirectPlayLobby object.
460 * Returns a IDirectPlay interface.
463 static HRESULT WINAPI DPL_ConnectEx
464 ( IDirectPlayLobbyAImpl
* This
,
471 DWORD dwOpenFlags
= 0;
472 DWORD dwConnSize
= 0;
473 LPDPLCONNECTION lpConn
;
475 FIXME("(%p)->(0x%08lx,%p,%p): semi stub\n", This
, dwFlags
, lplpDP
, pUnk
);
479 return DPERR_INVALIDPARAMS
;
482 /* Backwards compatibility */
485 dwFlags
= DPCONNECT_RETURNSTATUS
;
488 /* Create the DirectPlay interface */
489 if( ( hr
= DP_CreateInterface( riid
, lplpDP
) ) != DP_OK
)
491 ERR( "error creating interface for %s:%s.\n",
492 debugstr_guid( riid
), DPLAYX_HresultToString( hr
) );
496 /* FIXME: Is it safe/correct to use appID of 0? */
497 hr
= IDirectPlayLobby_GetConnectionSettings( (LPDIRECTPLAYLOBBY
)This
,
498 0, NULL
, &dwConnSize
);
499 if( hr
!= DPERR_BUFFERTOOSMALL
)
504 lpConn
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, dwConnSize
);
508 return DPERR_NOMEMORY
;
511 /* FIXME: Is it safe/correct to use appID of 0? */
512 hr
= IDirectPlayLobby_GetConnectionSettings( (LPDIRECTPLAYLOBBY
)This
,
513 0, lpConn
, &dwConnSize
);
520 /* - Need to call IDirectPlay::EnumConnections with the service provider to get that good information
521 * - Need to call CreateAddress to create the lpConnection param for IDirectPlay::InitializeConnection
522 * - Call IDirectPlay::InitializeConnection
525 /* Now initialize the Service Provider */
526 hr
= IDirectPlayX_InitializeConnection( (*(LPDIRECTPLAY2
*)lplpDP
),
530 /* Setup flags to pass into DirectPlay::Open */
531 if( dwFlags
& DPCONNECT_RETURNSTATUS
)
533 dwOpenFlags
|= DPOPEN_RETURNSTATUS
;
535 dwOpenFlags
|= lpConn
->dwFlags
;
537 hr
= IDirectPlayX_Open( (*(LPDIRECTPLAY2
*)lplpDP
), lpConn
->lpSessionDesc
,
540 HeapFree( GetProcessHeap(), 0, lpConn
);
545 static HRESULT WINAPI IDirectPlayLobbyAImpl_Connect
546 ( LPDIRECTPLAYLOBBYA iface
,
548 LPDIRECTPLAY2A
* lplpDP
,
551 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
552 return DPL_ConnectEx( This
, dwFlags
, &IID_IDirectPlay2A
,
553 (LPVOID
)lplpDP
, pUnk
);
556 static HRESULT WINAPI IDirectPlayLobbyWImpl_Connect
557 ( LPDIRECTPLAYLOBBY iface
,
559 LPDIRECTPLAY2
* lplpDP
,
562 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
); /* Yes cast to A */
563 return DPL_ConnectEx( This
, dwFlags
, &IID_IDirectPlay2
,
564 (LPVOID
)lplpDP
, pUnk
);
567 /********************************************************************
569 * Creates a DirectPlay Address, given a service provider-specific network
571 * Returns an address contains the globally unique identifier
572 * (GUID) of the service provider and data that the service provider can
573 * interpret as a network address.
575 * NOTE: It appears that this method is supposed to be really really stupid
576 * with no error checking on the contents.
578 static HRESULT WINAPI IDirectPlayLobbyAImpl_CreateAddress
579 ( LPDIRECTPLAYLOBBYA iface
,
581 REFGUID guidDataType
,
585 LPDWORD lpdwAddressSize
)
587 return DPL_CreateAddress( guidSP
, guidDataType
, lpData
, dwDataSize
,
588 lpAddress
, lpdwAddressSize
, TRUE
);
591 static HRESULT WINAPI IDirectPlayLobbyWImpl_CreateAddress
592 ( LPDIRECTPLAYLOBBY iface
,
594 REFGUID guidDataType
,
598 LPDWORD lpdwAddressSize
)
600 return DPL_CreateAddress( guidSP
, guidDataType
, lpData
, dwDataSize
,
601 lpAddress
, lpdwAddressSize
, FALSE
);
604 HRESULT
DPL_CreateAddress(
606 REFGUID guidDataType
,
610 LPDWORD lpdwAddressSize
,
611 BOOL bAnsiInterface
)
613 const DWORD dwNumAddElements
= 2; /* Service Provide & address data type */
614 DPCOMPOUNDADDRESSELEMENT addressElements
[ 2 /* dwNumAddElements */ ];
616 TRACE( "(%p)->(%p,%p,0x%08lx,%p,%p,%d)\n", guidSP
, guidDataType
, lpData
, dwDataSize
,
617 lpAddress
, lpdwAddressSize
, bAnsiInterface
);
619 addressElements
[ 0 ].guidDataType
= DPAID_ServiceProvider
;
620 addressElements
[ 0 ].dwDataSize
= sizeof( GUID
);
621 addressElements
[ 0 ].lpData
= (LPVOID
)guidSP
;
623 addressElements
[ 1 ].guidDataType
= *guidDataType
;
624 addressElements
[ 1 ].dwDataSize
= dwDataSize
;
625 addressElements
[ 1 ].lpData
= (LPVOID
)lpData
;
627 /* Call CreateCompoundAddress to cut down on code.
628 NOTE: We can do this because we don't support DPL 1 interfaces! */
629 return DPL_CreateCompoundAddress( addressElements
, dwNumAddElements
,
630 lpAddress
, lpdwAddressSize
, bAnsiInterface
);
635 /********************************************************************
637 * Parses out chunks from the DirectPlay Address buffer by calling the
638 * given callback function, with lpContext, for each of the chunks.
641 static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddress
642 ( LPDIRECTPLAYLOBBYA iface
,
643 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
,
648 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
650 TRACE("(%p)->(%p,%p,0x%08lx,%p)\n", This
, lpEnumAddressCallback
, lpAddress
,
651 dwAddressSize
, lpContext
);
653 return DPL_EnumAddress( lpEnumAddressCallback
, lpAddress
, dwAddressSize
, lpContext
);
656 static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumAddress
657 ( LPDIRECTPLAYLOBBY iface
,
658 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
,
663 ICOM_THIS(IDirectPlayLobbyWImpl
,iface
);
665 TRACE("(%p)->(%p,%p,0x%08lx,%p)\n", This
, lpEnumAddressCallback
, lpAddress
,
666 dwAddressSize
, lpContext
);
668 return DPL_EnumAddress( lpEnumAddressCallback
, lpAddress
, dwAddressSize
, lpContext
);
671 extern HRESULT
DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
, LPCVOID lpAddress
,
672 DWORD dwAddressSize
, LPVOID lpContext
)
674 DWORD dwTotalSizeEnumerated
= 0;
676 /* FIXME: First chunk is always the total size chunk - Should we report it? */
678 while ( dwTotalSizeEnumerated
< dwAddressSize
)
680 LPDPADDRESS lpElements
= (LPDPADDRESS
)lpAddress
;
681 DWORD dwSizeThisEnumeration
;
683 /* Invoke the enum method. If false is returned, stop enumeration */
684 if ( !lpEnumAddressCallback( &lpElements
->guidDataType
,
685 lpElements
->dwDataSize
,
686 (BYTE
*)lpElements
+ sizeof( DPADDRESS
),
692 dwSizeThisEnumeration
= sizeof( DPADDRESS
) + lpElements
->dwDataSize
;
693 lpAddress
= (BYTE
*) lpAddress
+ dwSizeThisEnumeration
;
694 dwTotalSizeEnumerated
+= dwSizeThisEnumeration
;
700 /********************************************************************
702 * Enumerates all the address types that a given service provider needs to
703 * build the DirectPlay Address.
706 static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddressTypes
707 ( LPDIRECTPLAYLOBBYA iface
,
708 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
,
713 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
716 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
717 DWORD dwIndex
, sizeOfSubKeyName
=50;
721 TRACE(" (%p)->(%p,%p,%p,0x%08lx)\n", This
, lpEnumAddressTypeCallback
, guidSP
, lpContext
, dwFlags
);
725 return DPERR_INVALIDPARAMS
;
728 if( !lpEnumAddressTypeCallback
|| !*lpEnumAddressTypeCallback
)
730 return DPERR_INVALIDPARAMS
;
735 return DPERR_INVALIDOBJECT
;
738 /* Need to loop over the service providers in the registry */
739 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
740 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
742 /* Hmmm. Does this mean that there are no service providers? */
743 ERR(": no service providers?\n");
747 /* Traverse all the service providers we have available */
749 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
,
750 NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
751 ++dwIndex
, sizeOfSubKeyName
=50 )
754 HKEY hkServiceProvider
, hkServiceProviderAt
;
755 GUID serviceProviderGUID
;
756 DWORD returnTypeGUID
, sizeOfReturnBuffer
= 50;
758 char returnBuffer
[51];
761 LPSTR atKey
= "Address Types";
762 LPSTR guidDataSubKey
= "Guid";
766 TRACE(" this time through: %s\n", subKeyName
);
768 /* Get a handle for this particular service provider */
769 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
770 &hkServiceProvider
) != ERROR_SUCCESS
)
772 ERR(": what the heck is going on?\n" );
776 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
777 NULL
, &returnTypeGUID
, returnBuffer
,
778 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
780 ERR(": missing GUID registry data members\n" );
784 /* FIXME: Check return types to ensure we're interpreting data right */
785 MultiByteToWideChar( CP_ACP
, 0, returnBuffer
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
786 CLSIDFromString( (LPCOLESTR
)buff
, &serviceProviderGUID
);
787 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
789 /* Determine if this is the Service Provider that the user asked for */
790 if( !IsEqualGUID( &serviceProviderGUID
, guidSP
) )
795 /* Get a handle for this particular service provider */
796 if( RegOpenKeyExA( hkServiceProvider
, atKey
, 0, KEY_READ
,
797 &hkServiceProviderAt
) != ERROR_SUCCESS
)
799 TRACE(": No Address Types registry data sub key/members\n" );
803 /* Traverse all the address type we have available */
805 RegEnumKeyExA( hkServiceProviderAt
, dwAtIndex
, atSubKey
, &sizeOfSubKeyName
,
806 NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
807 ++dwAtIndex
, sizeOfSubKeyName
=50 )
809 TRACE( "Found Address Type GUID %s\n", atSubKey
);
811 /* FIXME: Check return types to ensure we're interpreting data right */
812 MultiByteToWideChar( CP_ACP
, 0, atSubKey
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
813 CLSIDFromString( (LPCOLESTR
)buff
, &serviceProviderGUID
);
814 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
816 /* The enumeration will return FALSE if we are not to continue */
817 if( !lpEnumAddressTypeCallback( &serviceProviderGUID
, lpContext
, 0 ) )
819 WARN("lpEnumCallback returning FALSE\n" );
820 break; /* FIXME: This most likely has to break from the procedure...*/
825 /* We only enumerate address types for 1 GUID. We've found it, so quit looking */
832 static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumAddressTypes
833 ( LPDIRECTPLAYLOBBY iface
,
834 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
,
840 return DPERR_OUTOFMEMORY
;
843 /********************************************************************
845 * Enumerates what applications are registered with DirectPlay by
846 * invoking the callback function with lpContext.
849 static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumLocalApplications
850 ( LPDIRECTPLAYLOBBY iface
,
851 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback
,
855 ICOM_THIS(IDirectPlayLobbyWImpl
,iface
);
857 FIXME("(%p)->(%p,%p,0x%08lx):stub\n", This
, lpEnumLocalAppCallback
, lpContext
, dwFlags
);
859 return DPERR_OUTOFMEMORY
;
862 static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumLocalApplications
863 ( LPDIRECTPLAYLOBBYA iface
,
864 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback
,
868 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
871 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Applications";
872 LPSTR guidDataSubKey
= "Guid";
873 DWORD dwIndex
, sizeOfSubKeyName
=50;
877 TRACE("(%p)->(%p,%p,0x%08lx)\n", This
, lpEnumLocalAppCallback
, lpContext
, dwFlags
);
881 return DPERR_INVALIDPARAMS
;
884 if( !lpEnumLocalAppCallback
|| !*lpEnumLocalAppCallback
)
886 return DPERR_INVALIDPARAMS
;
889 /* Need to loop over the service providers in the registry */
890 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
891 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
893 /* Hmmm. Does this mean that there are no service providers? */
894 ERR(": no service providers?\n");
898 /* Traverse all registered applications */
900 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
, NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
901 ++dwIndex
, sizeOfSubKeyName
=50 )
904 HKEY hkServiceProvider
;
905 GUID serviceProviderGUID
;
906 DWORD returnTypeGUID
, sizeOfReturnBuffer
= 50;
907 char returnBuffer
[51];
909 DPLAPPINFO dplAppInfo
;
911 TRACE(" this time through: %s\n", subKeyName
);
913 /* Get a handle for this particular service provider */
914 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
915 &hkServiceProvider
) != ERROR_SUCCESS
)
917 ERR(": what the heck is going on?\n" );
921 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
922 NULL
, &returnTypeGUID
, returnBuffer
,
923 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
925 ERR(": missing GUID registry data members\n" );
929 /* FIXME: Check return types to ensure we're interpreting data right */
930 MultiByteToWideChar( CP_ACP
, 0, returnBuffer
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
931 CLSIDFromString( (LPCOLESTR
)buff
, &serviceProviderGUID
);
932 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
934 dplAppInfo
.dwSize
= sizeof( dplAppInfo
);
935 dplAppInfo
.guidApplication
= serviceProviderGUID
;
936 dplAppInfo
.u
.lpszAppNameA
= subKeyName
;
938 EnterCriticalSection( &This
->unk
->DPL_lock
);
940 memcpy( &This
->dpl
->hkCallbackKeyHack
, &hkServiceProvider
, sizeof( hkServiceProvider
) );
942 if( !lpEnumLocalAppCallback( &dplAppInfo
, lpContext
, dwFlags
) )
944 LeaveCriticalSection( &This
->unk
->DPL_lock
);
948 LeaveCriticalSection( &This
->unk
->DPL_lock
);
954 /********************************************************************
956 * Retrieves the DPLCONNECTION structure that contains all the information
957 * needed to start and connect an application. This was generated using
958 * either the RunApplication or SetConnectionSettings methods.
960 * NOTES: If lpData is NULL then just return lpdwDataSize. This allows
961 * the data structure to be allocated by our caller which can then
962 * call this procedure/method again with a valid data pointer.
964 static HRESULT WINAPI IDirectPlayLobbyAImpl_GetConnectionSettings
965 ( LPDIRECTPLAYLOBBYA iface
,
968 LPDWORD lpdwDataSize
)
970 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
973 TRACE("(%p)->(0x%08lx,%p,%p)\n", This
, dwAppID
, lpData
, lpdwDataSize
);
975 EnterCriticalSection( &This
->unk
->DPL_lock
);
977 hr
= DPLAYX_GetConnectionSettingsA( dwAppID
,
982 LeaveCriticalSection( &This
->unk
->DPL_lock
);
987 static HRESULT WINAPI IDirectPlayLobbyWImpl_GetConnectionSettings
988 ( LPDIRECTPLAYLOBBY iface
,
991 LPDWORD lpdwDataSize
)
993 ICOM_THIS(IDirectPlayLobbyWImpl
,iface
);
996 TRACE("(%p)->(0x%08lx,%p,%p)\n", This
, dwAppID
, lpData
, lpdwDataSize
);
998 EnterCriticalSection( &This
->unk
->DPL_lock
);
1000 hr
= DPLAYX_GetConnectionSettingsW( dwAppID
,
1005 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1010 /********************************************************************
1012 * Retrieves the message sent between a lobby client and a DirectPlay
1013 * application. All messages are queued until received.
1016 static HRESULT WINAPI IDirectPlayLobbyAImpl_ReceiveLobbyMessage
1017 ( LPDIRECTPLAYLOBBYA iface
,
1020 LPDWORD lpdwMessageFlags
,
1022 LPDWORD lpdwDataSize
)
1024 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
1025 FIXME(":stub %p %08lx %08lx %p %p %p\n", This
, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
1027 return DPERR_OUTOFMEMORY
;
1030 static HRESULT WINAPI IDirectPlayLobbyWImpl_ReceiveLobbyMessage
1031 ( LPDIRECTPLAYLOBBY iface
,
1034 LPDWORD lpdwMessageFlags
,
1036 LPDWORD lpdwDataSize
)
1038 ICOM_THIS(IDirectPlayLobbyWImpl
,iface
);
1039 FIXME(":stub %p %08lx %08lx %p %p %p\n", This
, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
1041 return DPERR_OUTOFMEMORY
;
1044 typedef struct tagRunApplicationEnumStruct
1046 IDirectPlayLobbyAImpl
* This
;
1051 LPSTR lpszCommandLine
;
1052 LPSTR lpszCurrentDirectory
;
1053 } RunApplicationEnumStruct
, *lpRunApplicationEnumStruct
;
1055 /* To be called by RunApplication to find how to invoke the function */
1056 static BOOL CALLBACK RunApplicationA_EnumLocalApplications
1057 ( LPCDPLAPPINFO lpAppInfo
,
1061 lpRunApplicationEnumStruct lpData
= (lpRunApplicationEnumStruct
)lpContext
;
1063 if( IsEqualGUID( &lpAppInfo
->guidApplication
, &lpData
->appGUID
) )
1065 char returnBuffer
[200];
1066 DWORD returnType
, sizeOfReturnBuffer
;
1067 LPSTR clSubKey
= "CommandLine";
1068 LPSTR cdSubKey
= "CurrentDirectory";
1069 LPSTR fileSubKey
= "File";
1070 LPSTR pathSubKey
= "Path";
1072 /* FIXME: Lazy man hack - dplay struct has the present reg key saved */
1074 sizeOfReturnBuffer
= 200;
1076 /* Get all the appropriate data from the registry */
1077 if( RegQueryValueExA( lpData
->This
->dpl
->hkCallbackKeyHack
, clSubKey
,
1078 NULL
, &returnType
, returnBuffer
,
1079 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1081 ERR( ": missing CommandLine registry data member\n" );
1085 if ((lpData
->lpszCommandLine
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1086 strcpy( lpData
->lpszCommandLine
, returnBuffer
);
1089 sizeOfReturnBuffer
= 200;
1091 if( RegQueryValueExA( lpData
->This
->dpl
->hkCallbackKeyHack
, cdSubKey
,
1092 NULL
, &returnType
, returnBuffer
,
1093 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1095 ERR( ": missing CurrentDirectory registry data member\n" );
1099 if ((lpData
->lpszCurrentDirectory
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1100 strcpy( lpData
->lpszCurrentDirectory
, returnBuffer
);
1103 sizeOfReturnBuffer
= 200;
1105 if( RegQueryValueExA( lpData
->This
->dpl
->hkCallbackKeyHack
, fileSubKey
,
1106 NULL
, &returnType
, returnBuffer
,
1107 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1109 ERR( ": missing File registry data member\n" );
1113 if ((lpData
->lpszFileName
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1114 strcpy( lpData
->lpszFileName
, returnBuffer
);
1117 sizeOfReturnBuffer
= 200;
1119 if( RegQueryValueExA( lpData
->This
->dpl
->hkCallbackKeyHack
, pathSubKey
,
1120 NULL
, &returnType
, returnBuffer
,
1121 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1123 ERR( ": missing Path registry data member\n" );
1127 if ((lpData
->lpszPath
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1128 strcpy( lpData
->lpszPath
, returnBuffer
);
1131 return FALSE
; /* No need to keep going as we found what we wanted */
1134 return TRUE
; /* Keep enumerating, haven't found the application yet */
1137 BOOL
DPL_CreateAndSetLobbyHandles( DWORD dwDestProcessId
, HANDLE hDestProcess
,
1138 LPHANDLE lphStart
, LPHANDLE lphDeath
,
1141 /* These are the handles for the created process */
1142 HANDLE hAppStart
, hAppDeath
, hAppRead
, hTemp
;
1143 SECURITY_ATTRIBUTES s_attrib
;
1145 s_attrib
.nLength
= sizeof( s_attrib
);
1146 s_attrib
.lpSecurityDescriptor
= NULL
;
1147 s_attrib
.bInheritHandle
= TRUE
;
1149 /* FIXME: Is there a handle leak here? */
1150 hTemp
= CreateEventA( &s_attrib
, TRUE
, FALSE
, NULL
);
1151 *lphStart
= ConvertToGlobalHandle( hTemp
);
1153 hTemp
= CreateEventA( &s_attrib
, TRUE
, FALSE
, NULL
);
1154 *lphDeath
= ConvertToGlobalHandle( hTemp
);
1156 hTemp
= CreateEventA( &s_attrib
, TRUE
, FALSE
, NULL
);
1157 *lphRead
= ConvertToGlobalHandle( hTemp
);
1159 if( ( !DuplicateHandle( GetCurrentProcess(), *lphStart
,
1160 hDestProcess
, &hAppStart
,
1161 0, FALSE
, DUPLICATE_SAME_ACCESS
) ) ||
1162 ( !DuplicateHandle( GetCurrentProcess(), *lphDeath
,
1163 hDestProcess
, &hAppDeath
,
1164 0, FALSE
, DUPLICATE_SAME_ACCESS
) ) ||
1165 ( !DuplicateHandle( GetCurrentProcess(), *lphRead
,
1166 hDestProcess
, &hAppRead
,
1167 0, FALSE
, DUPLICATE_SAME_ACCESS
) )
1170 /* FIXME: Handle leak... */
1171 ERR( "Unable to dup handles\n" );
1175 if( !DPLAYX_SetLobbyHandles( dwDestProcessId
,
1176 hAppStart
, hAppDeath
, hAppRead
) )
1185 /********************************************************************
1187 * Starts an application and passes to it all the information to
1188 * connect to a session.
1191 static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication
1192 ( LPDIRECTPLAYLOBBYA iface
,
1195 LPDPLCONNECTION lpConn
,
1196 HANDLE hReceiveEvent
)
1198 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
1200 RunApplicationEnumStruct enumData
;
1202 STARTUPINFOA startupInfo
;
1203 PROCESS_INFORMATION newProcessInfo
;
1205 DWORD dwSuspendCount
;
1206 HANDLE hStart
, hDeath
, hSettingRead
;
1208 TRACE( "(%p)->(0x%08lx,%p,%p,%x)\n",
1209 This
, dwFlags
, lpdwAppID
, lpConn
, hReceiveEvent
);
1213 return DPERR_INVALIDPARAMS
;
1216 if( DPLAYX_AnyLobbiesWaitingForConnSettings() )
1218 FIXME( "Waiting lobby not being handled correctly\n" );
1221 EnterCriticalSection( &This
->unk
->DPL_lock
);
1223 ZeroMemory( &enumData
, sizeof( enumData
) );
1224 enumData
.This
= This
;
1225 enumData
.appGUID
= lpConn
->lpSessionDesc
->guidApplication
;
1227 /* Our callback function will fill up the enumData structure with all the information
1228 required to start a new process */
1229 IDirectPlayLobby_EnumLocalApplications( iface
, RunApplicationA_EnumLocalApplications
,
1230 (LPVOID
)(&enumData
), 0 );
1232 /* First the application name */
1233 strcpy( temp
, enumData
.lpszPath
);
1234 strcat( temp
, "\\" );
1235 strcat( temp
, enumData
.lpszFileName
);
1236 HeapFree( GetProcessHeap(), 0, enumData
.lpszPath
);
1237 HeapFree( GetProcessHeap(), 0, enumData
.lpszFileName
);
1238 if ((appName
= HeapAlloc( GetProcessHeap(), 0, strlen(temp
)+1 ))) strcpy( appName
, temp
);
1240 /* Now the command line */
1241 strcat( temp
, " " );
1242 strcat( temp
, enumData
.lpszCommandLine
);
1243 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1244 if ((enumData
.lpszCommandLine
= HeapAlloc( GetProcessHeap(), 0, strlen(temp
)+1 )))
1245 strcpy( enumData
.lpszCommandLine
, temp
);
1247 ZeroMemory( &startupInfo
, sizeof( startupInfo
) );
1248 startupInfo
.cb
= sizeof( startupInfo
);
1249 /* FIXME: Should any fields be filled in? */
1251 ZeroMemory( &newProcessInfo
, sizeof( newProcessInfo
) );
1253 if( !CreateProcessA( appName
,
1254 enumData
.lpszCommandLine
,
1258 CREATE_DEFAULT_ERROR_MODE
| CREATE_NEW_CONSOLE
| CREATE_SUSPENDED
, /* Creation Flags */
1260 enumData
.lpszCurrentDirectory
,
1266 ERR( "Failed to create process for app %s\n", appName
);
1268 HeapFree( GetProcessHeap(), 0, appName
);
1269 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1270 HeapFree( GetProcessHeap(), 0, enumData
.lpszCurrentDirectory
);
1272 return DPERR_CANTCREATEPROCESS
;
1275 HeapFree( GetProcessHeap(), 0, appName
);
1276 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1277 HeapFree( GetProcessHeap(), 0, enumData
.lpszCurrentDirectory
);
1279 /* Reserve this global application id! */
1280 if( !DPLAYX_CreateLobbyApplication( newProcessInfo
.dwProcessId
) )
1282 ERR( "Unable to create global application data for 0x%08lx\n",
1283 newProcessInfo
.dwProcessId
);
1286 hr
= IDirectPlayLobby_SetConnectionSettings( iface
, 0, newProcessInfo
.dwProcessId
, lpConn
);
1290 ERR( "SetConnectionSettings failure %s\n", DPLAYX_HresultToString( hr
) );
1294 /* Setup the handles for application notification */
1295 DPL_CreateAndSetLobbyHandles( newProcessInfo
.dwProcessId
,
1296 newProcessInfo
.hProcess
,
1297 &hStart
, &hDeath
, &hSettingRead
);
1299 /* Setup the message thread ID */
1300 This
->dpl
->dwMsgThread
=
1301 CreateLobbyMessageReceptionThread( hReceiveEvent
, hStart
, hDeath
, hSettingRead
);
1303 DPLAYX_SetLobbyMsgThreadId( newProcessInfo
.dwProcessId
, This
->dpl
->dwMsgThread
);
1305 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1307 /* Everything seems to have been set correctly, update the dwAppID */
1308 *lpdwAppID
= newProcessInfo
.dwProcessId
;
1310 /* Unsuspend the process - should return the prev suspension count */
1311 if( ( dwSuspendCount
= ResumeThread( newProcessInfo
.hThread
) ) != 1 )
1313 ERR( "ResumeThread failed with 0x%08lx\n", dwSuspendCount
);
1319 static HRESULT WINAPI IDirectPlayLobbyWImpl_RunApplication
1320 ( LPDIRECTPLAYLOBBY iface
,
1323 LPDPLCONNECTION lpConn
,
1324 HANDLE hReceiveEvent
)
1326 ICOM_THIS(IDirectPlayLobbyWImpl
,iface
);
1327 FIXME( "(%p)->(0x%08lx,%p,%p,%p):stub\n", This
, dwFlags
, lpdwAppID
, lpConn
, (void *)hReceiveEvent
);
1328 return DPERR_OUTOFMEMORY
;
1331 /********************************************************************
1333 * Sends a message between the application and the lobby client.
1334 * All messages are queued until received.
1337 static HRESULT WINAPI IDirectPlayLobbyAImpl_SendLobbyMessage
1338 ( LPDIRECTPLAYLOBBYA iface
,
1345 return DPERR_OUTOFMEMORY
;
1348 static HRESULT WINAPI IDirectPlayLobbyWImpl_SendLobbyMessage
1349 ( LPDIRECTPLAYLOBBY iface
,
1356 return DPERR_OUTOFMEMORY
;
1359 /********************************************************************
1361 * Modifies the DPLCONNECTION structure to contain all information
1362 * needed to start and connect an application.
1365 static HRESULT WINAPI IDirectPlayLobbyWImpl_SetConnectionSettings
1366 ( LPDIRECTPLAYLOBBY iface
,
1369 LPDPLCONNECTION lpConn
)
1371 ICOM_THIS(IDirectPlayLobbyWImpl
,iface
);
1374 TRACE("(%p)->(0x%08lx,0x%08lx,%p)\n", This
, dwFlags
, dwAppID
, lpConn
);
1376 EnterCriticalSection( &This
->unk
->DPL_lock
);
1378 hr
= DPLAYX_SetConnectionSettingsW( dwFlags
, dwAppID
, lpConn
);
1380 /* FIXME: Don't think that this is supposed to fail, but the docuementation
1381 is somewhat sketchy. I'll try creating a lobby application
1383 if( hr
== DPERR_NOTLOBBIED
)
1385 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1388 dwAppID
= GetCurrentProcessId();
1390 DPLAYX_CreateLobbyApplication( dwAppID
);
1391 hr
= DPLAYX_SetConnectionSettingsW( dwFlags
, dwAppID
, lpConn
);
1394 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1399 static HRESULT WINAPI IDirectPlayLobbyAImpl_SetConnectionSettings
1400 ( LPDIRECTPLAYLOBBYA iface
,
1403 LPDPLCONNECTION lpConn
)
1405 ICOM_THIS(IDirectPlayLobbyAImpl
,iface
);
1408 TRACE("(%p)->(0x%08lx,0x%08lx,%p)\n", This
, dwFlags
, dwAppID
, lpConn
);
1410 EnterCriticalSection( &This
->unk
->DPL_lock
);
1412 hr
= DPLAYX_SetConnectionSettingsA( dwFlags
, dwAppID
, lpConn
);
1414 /* FIXME: Don't think that this is supposed to fail, but the docuementation
1415 is somewhat sketchy. I'll try creating a lobby application
1417 if( hr
== DPERR_NOTLOBBIED
)
1419 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1420 dwAppID
= GetCurrentProcessId();
1421 DPLAYX_CreateLobbyApplication( dwAppID
);
1422 hr
= DPLAYX_SetConnectionSettingsA( dwFlags
, dwAppID
, lpConn
);
1425 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1430 /********************************************************************
1432 * Registers an event that will be set when a lobby message is received.
1435 static HRESULT WINAPI IDirectPlayLobbyAImpl_SetLobbyMessageEvent
1436 ( LPDIRECTPLAYLOBBYA iface
,
1439 HANDLE hReceiveEvent
)
1442 return DPERR_OUTOFMEMORY
;
1445 static HRESULT WINAPI IDirectPlayLobbyWImpl_SetLobbyMessageEvent
1446 ( LPDIRECTPLAYLOBBY iface
,
1449 HANDLE hReceiveEvent
)
1452 return DPERR_OUTOFMEMORY
;
1457 static HRESULT WINAPI IDirectPlayLobby2WImpl_CreateCompoundAddress
1458 ( LPDIRECTPLAYLOBBY2 iface
,
1459 LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1460 DWORD dwElementCount
,
1462 LPDWORD lpdwAddressSize
)
1464 return DPL_CreateCompoundAddress( lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
, FALSE
);
1467 static HRESULT WINAPI IDirectPlayLobby2AImpl_CreateCompoundAddress
1468 ( LPDIRECTPLAYLOBBY2A iface
,
1469 LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1470 DWORD dwElementCount
,
1472 LPDWORD lpdwAddressSize
)
1474 return DPL_CreateCompoundAddress( lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
, TRUE
);
1477 HRESULT DPL_CreateCompoundAddress
1478 ( LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1479 DWORD dwElementCount
,
1481 LPDWORD lpdwAddressSize
,
1482 BOOL bAnsiInterface
)
1484 DWORD dwSizeRequired
= 0;
1486 LPCDPCOMPOUNDADDRESSELEMENT lpOrigElements
= lpElements
;
1488 TRACE("(%p,0x%08lx,%p,%p)\n", lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
);
1490 /* Parameter check */
1491 if( ( lpElements
== NULL
) ||
1492 ( dwElementCount
== 0 ) /* FIXME: Not sure if this is a failure case */
1495 return DPERR_INVALIDPARAMS
;
1498 /* Add the total size chunk */
1499 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( DWORD
);
1501 /* Calculate the size of the buffer required */
1502 for ( dwElements
= dwElementCount
; dwElements
> 0; --dwElements
, ++lpElements
)
1504 if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ServiceProvider
) ) ||
1505 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_LobbyProvider
) )
1508 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( GUID
);
1510 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Phone
) ) ||
1511 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Modem
) ) ||
1512 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INet
) )
1515 if( !bAnsiInterface
)
1517 ERR( "Ansi GUIDs used for unicode interface\n" );
1518 return DPERR_INVALIDFLAGS
;
1521 dwSizeRequired
+= sizeof( DPADDRESS
) + lpElements
->dwDataSize
;
1523 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_PhoneW
) ) ||
1524 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ModemW
) ) ||
1525 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetW
) )
1528 if( bAnsiInterface
)
1530 ERR( "Unicode GUIDs used for ansi interface\n" );
1531 return DPERR_INVALIDFLAGS
;
1534 FIXME( "Right size for unicode interface?\n" );
1535 dwSizeRequired
+= sizeof( DPADDRESS
) + lpElements
->dwDataSize
* sizeof( WCHAR
);
1537 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetPort
) )
1539 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( WORD
);
1541 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ComPort
) )
1543 FIXME( "Right size for unicode interface?\n" );
1544 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( DPCOMPORTADDRESS
); /* FIXME: Right size? */
1548 ERR( "Unknown GUID %s\n", debugstr_guid(&lpElements
->guidDataType
) );
1549 return DPERR_INVALIDFLAGS
;
1553 /* The user wants to know how big a buffer to allocate for us */
1554 if( ( lpAddress
== NULL
) ||
1555 ( *lpdwAddressSize
< dwSizeRequired
)
1558 *lpdwAddressSize
= dwSizeRequired
;
1559 return DPERR_BUFFERTOOSMALL
;
1562 /* Add the total size chunk */
1564 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1566 CopyMemory( &lpdpAddress
->guidDataType
, &DPAID_TotalSize
, sizeof( GUID
) );
1567 lpdpAddress
->dwDataSize
= sizeof( DWORD
);
1568 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1570 *(LPDWORD
)lpAddress
= dwSizeRequired
;
1571 lpAddress
= (char *) lpAddress
+ sizeof( DWORD
);
1574 /* Calculate the size of the buffer required */
1575 for( dwElements
= dwElementCount
, lpElements
= lpOrigElements
;
1577 --dwElements
, ++lpElements
)
1579 if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ServiceProvider
) ) ||
1580 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_LobbyProvider
) )
1583 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1585 CopyMemory( &lpdpAddress
->guidDataType
, &lpElements
->guidDataType
,
1587 lpdpAddress
->dwDataSize
= sizeof( GUID
);
1588 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1590 CopyMemory( lpAddress
, lpElements
->lpData
, sizeof( GUID
) );
1591 lpAddress
= (char *) lpAddress
+ sizeof( GUID
);
1593 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Phone
) ) ||
1594 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Modem
) ) ||
1595 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INet
) )
1598 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1600 CopyMemory( &lpdpAddress
->guidDataType
, &lpElements
->guidDataType
,
1602 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1603 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1605 lstrcpynA( (LPSTR
)lpAddress
,
1606 (LPCSTR
)lpElements
->lpData
,
1607 lpElements
->dwDataSize
);
1608 lpAddress
= (char *) lpAddress
+ lpElements
->dwDataSize
;
1610 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_PhoneW
) ) ||
1611 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ModemW
) ) ||
1612 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetW
) )
1615 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1617 CopyMemory( &lpdpAddress
->guidDataType
, &lpElements
->guidDataType
,
1619 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1620 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1622 lstrcpynW( (LPWSTR
)lpAddress
,
1623 (LPCWSTR
)lpElements
->lpData
,
1624 lpElements
->dwDataSize
);
1625 lpAddress
= (char *) lpAddress
+ lpElements
->dwDataSize
* sizeof( WCHAR
);
1627 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetPort
) )
1629 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1631 CopyMemory( &lpdpAddress
->guidDataType
, &lpElements
->guidDataType
,
1633 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1634 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1636 *((LPWORD
)lpAddress
) = *((LPWORD
)lpElements
->lpData
);
1637 lpAddress
= (char *) lpAddress
+ sizeof( WORD
);
1639 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ComPort
) )
1641 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1643 CopyMemory( &lpdpAddress
->guidDataType
, &lpElements
->guidDataType
,
1645 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1646 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1648 CopyMemory( lpAddress
, lpElements
->lpData
, sizeof( DPADDRESS
) );
1649 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1658 static HRESULT WINAPI IDirectPlayLobby3WImpl_ConnectEx
1659 ( LPDIRECTPLAYLOBBY3 iface
, DWORD dwFlags
, REFIID riid
,
1660 LPVOID
* lplpDP
, IUnknown
* pUnk
)
1662 ICOM_THIS( IDirectPlayLobbyAImpl
, iface
);
1663 return DPL_ConnectEx( This
, dwFlags
, riid
, lplpDP
, pUnk
);
1666 static HRESULT WINAPI IDirectPlayLobby3AImpl_ConnectEx
1667 ( LPDIRECTPLAYLOBBY3A iface
, DWORD dwFlags
, REFIID riid
,
1668 LPVOID
* lplpDP
, IUnknown
* pUnk
)
1670 ICOM_THIS( IDirectPlayLobbyAImpl
, iface
);
1671 return DPL_ConnectEx( This
, dwFlags
, riid
, lplpDP
, pUnk
);
1674 static HRESULT WINAPI IDirectPlayLobby3WImpl_RegisterApplication
1675 ( LPDIRECTPLAYLOBBY3 iface
, DWORD dwFlags
, LPDPAPPLICATIONDESC lpAppDesc
)
1681 static HRESULT WINAPI IDirectPlayLobby3AImpl_RegisterApplication
1682 ( LPDIRECTPLAYLOBBY3A iface
, DWORD dwFlags
, LPDPAPPLICATIONDESC lpAppDesc
)
1688 static HRESULT WINAPI IDirectPlayLobby3WImpl_UnregisterApplication
1689 ( LPDIRECTPLAYLOBBY3 iface
, DWORD dwFlags
, REFGUID lpAppDesc
)
1695 static HRESULT WINAPI IDirectPlayLobby3AImpl_UnregisterApplication
1696 ( LPDIRECTPLAYLOBBY3A iface
, DWORD dwFlags
, REFGUID lpAppDesc
)
1702 static HRESULT WINAPI IDirectPlayLobby3WImpl_WaitForConnectionSettings
1703 ( LPDIRECTPLAYLOBBY3 iface
, DWORD dwFlags
)
1706 BOOL bStartWait
= (dwFlags
& DPLWAIT_CANCEL
) ? FALSE
: TRUE
;
1708 TRACE( "(%p)->(0x%08lx)\n", iface
, dwFlags
);
1710 if( DPLAYX_WaitForConnectionSettings( bStartWait
) )
1712 /* FIXME: What is the correct error return code? */
1713 hr
= DPERR_NOTLOBBIED
;
1719 static HRESULT WINAPI IDirectPlayLobby3AImpl_WaitForConnectionSettings
1720 ( LPDIRECTPLAYLOBBY3A iface
, DWORD dwFlags
)
1723 BOOL bStartWait
= (dwFlags
& DPLWAIT_CANCEL
) ? FALSE
: TRUE
;
1725 TRACE( "(%p)->(0x%08lx)\n", iface
, dwFlags
);
1727 if( DPLAYX_WaitForConnectionSettings( bStartWait
) )
1729 /* FIXME: What is the correct error return code? */
1730 hr
= DPERR_NOTLOBBIED
;
1737 /* Virtual Table definitions for DPL{1,2,3}{A,W} */
1739 /* Note: Hack so we can reuse the old functions without compiler warnings */
1740 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1741 # define XCAST(fun) (typeof(directPlayLobbyAVT.fun))
1743 # define XCAST(fun) (void*)
1746 /* Direct Play Lobby 1 (ascii) Virtual Table for methods */
1747 /* All lobby 1 methods are exactly the same except QueryInterface */
1748 static struct ICOM_VTABLE(IDirectPlayLobby
) directPlayLobbyAVT
=
1750 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1752 XCAST(QueryInterface
)DPL_QueryInterface
,
1753 XCAST(AddRef
)DPL_AddRef
,
1754 XCAST(Release
)DPL_Release
,
1756 IDirectPlayLobbyAImpl_Connect
,
1757 IDirectPlayLobbyAImpl_CreateAddress
,
1758 IDirectPlayLobbyAImpl_EnumAddress
,
1759 IDirectPlayLobbyAImpl_EnumAddressTypes
,
1760 IDirectPlayLobbyAImpl_EnumLocalApplications
,
1761 IDirectPlayLobbyAImpl_GetConnectionSettings
,
1762 IDirectPlayLobbyAImpl_ReceiveLobbyMessage
,
1763 IDirectPlayLobbyAImpl_RunApplication
,
1764 IDirectPlayLobbyAImpl_SendLobbyMessage
,
1765 IDirectPlayLobbyAImpl_SetConnectionSettings
,
1766 IDirectPlayLobbyAImpl_SetLobbyMessageEvent
1771 /* Note: Hack so we can reuse the old functions without compiler warnings */
1772 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1773 # define XCAST(fun) (typeof(directPlayLobbyWVT.fun))
1775 # define XCAST(fun) (void*)
1778 /* Direct Play Lobby 1 (unicode) Virtual Table for methods */
1779 static ICOM_VTABLE(IDirectPlayLobby
) directPlayLobbyWVT
=
1781 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1783 XCAST(QueryInterface
)DPL_QueryInterface
,
1784 XCAST(AddRef
)DPL_AddRef
,
1785 XCAST(Release
)DPL_Release
,
1787 IDirectPlayLobbyWImpl_Connect
,
1788 IDirectPlayLobbyWImpl_CreateAddress
,
1789 IDirectPlayLobbyWImpl_EnumAddress
,
1790 IDirectPlayLobbyWImpl_EnumAddressTypes
,
1791 IDirectPlayLobbyWImpl_EnumLocalApplications
,
1792 IDirectPlayLobbyWImpl_GetConnectionSettings
,
1793 IDirectPlayLobbyWImpl_ReceiveLobbyMessage
,
1794 IDirectPlayLobbyWImpl_RunApplication
,
1795 IDirectPlayLobbyWImpl_SendLobbyMessage
,
1796 IDirectPlayLobbyWImpl_SetConnectionSettings
,
1797 IDirectPlayLobbyWImpl_SetLobbyMessageEvent
1801 /* Note: Hack so we can reuse the old functions without compiler warnings */
1802 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1803 # define XCAST(fun) (typeof(directPlayLobby2AVT.fun))
1805 # define XCAST(fun) (void*)
1808 /* Direct Play Lobby 2 (ascii) Virtual Table for methods */
1809 static ICOM_VTABLE(IDirectPlayLobby2
) directPlayLobby2AVT
=
1811 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1813 XCAST(QueryInterface
)DPL_QueryInterface
,
1814 XCAST(AddRef
)DPL_AddRef
,
1815 XCAST(Release
)DPL_Release
,
1817 XCAST(Connect
)IDirectPlayLobbyAImpl_Connect
,
1818 XCAST(CreateAddress
)IDirectPlayLobbyAImpl_CreateAddress
,
1819 XCAST(EnumAddress
)IDirectPlayLobbyAImpl_EnumAddress
,
1820 XCAST(EnumAddressTypes
)IDirectPlayLobbyAImpl_EnumAddressTypes
,
1821 XCAST(EnumLocalApplications
)IDirectPlayLobbyAImpl_EnumLocalApplications
,
1822 XCAST(GetConnectionSettings
)IDirectPlayLobbyAImpl_GetConnectionSettings
,
1823 XCAST(ReceiveLobbyMessage
)IDirectPlayLobbyAImpl_ReceiveLobbyMessage
,
1824 XCAST(RunApplication
)IDirectPlayLobbyAImpl_RunApplication
,
1825 XCAST(SendLobbyMessage
)IDirectPlayLobbyAImpl_SendLobbyMessage
,
1826 XCAST(SetConnectionSettings
)IDirectPlayLobbyAImpl_SetConnectionSettings
,
1827 XCAST(SetLobbyMessageEvent
)IDirectPlayLobbyAImpl_SetLobbyMessageEvent
,
1829 IDirectPlayLobby2AImpl_CreateCompoundAddress
1833 /* Note: Hack so we can reuse the old functions without compiler warnings */
1834 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1835 # define XCAST(fun) (typeof(directPlayLobby2AVT.fun))
1837 # define XCAST(fun) (void*)
1840 /* Direct Play Lobby 2 (unicode) Virtual Table for methods */
1841 static ICOM_VTABLE(IDirectPlayLobby2
) directPlayLobby2WVT
=
1843 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1845 XCAST(QueryInterface
)DPL_QueryInterface
,
1846 XCAST(AddRef
)DPL_AddRef
,
1847 XCAST(Release
)DPL_Release
,
1849 XCAST(Connect
)IDirectPlayLobbyWImpl_Connect
,
1850 XCAST(CreateAddress
)IDirectPlayLobbyWImpl_CreateAddress
,
1851 XCAST(EnumAddress
)IDirectPlayLobbyWImpl_EnumAddress
,
1852 XCAST(EnumAddressTypes
)IDirectPlayLobbyWImpl_EnumAddressTypes
,
1853 XCAST(EnumLocalApplications
)IDirectPlayLobbyWImpl_EnumLocalApplications
,
1854 XCAST(GetConnectionSettings
)IDirectPlayLobbyWImpl_GetConnectionSettings
,
1855 XCAST(ReceiveLobbyMessage
)IDirectPlayLobbyWImpl_ReceiveLobbyMessage
,
1856 XCAST(RunApplication
)IDirectPlayLobbyWImpl_RunApplication
,
1857 XCAST(SendLobbyMessage
)IDirectPlayLobbyWImpl_SendLobbyMessage
,
1858 XCAST(SetConnectionSettings
)IDirectPlayLobbyWImpl_SetConnectionSettings
,
1859 XCAST(SetLobbyMessageEvent
)IDirectPlayLobbyWImpl_SetLobbyMessageEvent
,
1861 IDirectPlayLobby2WImpl_CreateCompoundAddress
1865 /* Direct Play Lobby 3 (ascii) Virtual Table for methods */
1867 /* Note: Hack so we can reuse the old functions without compiler warnings */
1868 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1869 # define XCAST(fun) (typeof(directPlayLobby3AVT.fun))
1871 # define XCAST(fun) (void*)
1874 static ICOM_VTABLE(IDirectPlayLobby3
) directPlayLobby3AVT
=
1876 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1877 XCAST(QueryInterface
)DPL_QueryInterface
,
1878 XCAST(AddRef
)DPL_AddRef
,
1879 XCAST(Release
)DPL_Release
,
1881 XCAST(Connect
)IDirectPlayLobbyAImpl_Connect
,
1882 XCAST(CreateAddress
)IDirectPlayLobbyAImpl_CreateAddress
,
1883 XCAST(EnumAddress
)IDirectPlayLobbyAImpl_EnumAddress
,
1884 XCAST(EnumAddressTypes
)IDirectPlayLobbyAImpl_EnumAddressTypes
,
1885 XCAST(EnumLocalApplications
)IDirectPlayLobbyAImpl_EnumLocalApplications
,
1886 XCAST(GetConnectionSettings
)IDirectPlayLobbyAImpl_GetConnectionSettings
,
1887 XCAST(ReceiveLobbyMessage
)IDirectPlayLobbyAImpl_ReceiveLobbyMessage
,
1888 XCAST(RunApplication
)IDirectPlayLobbyAImpl_RunApplication
,
1889 XCAST(SendLobbyMessage
)IDirectPlayLobbyAImpl_SendLobbyMessage
,
1890 XCAST(SetConnectionSettings
)IDirectPlayLobbyAImpl_SetConnectionSettings
,
1891 XCAST(SetLobbyMessageEvent
)IDirectPlayLobbyAImpl_SetLobbyMessageEvent
,
1893 XCAST(CreateCompoundAddress
)IDirectPlayLobby2AImpl_CreateCompoundAddress
,
1895 IDirectPlayLobby3AImpl_ConnectEx
,
1896 IDirectPlayLobby3AImpl_RegisterApplication
,
1897 IDirectPlayLobby3AImpl_UnregisterApplication
,
1898 IDirectPlayLobby3AImpl_WaitForConnectionSettings
1902 /* Direct Play Lobby 3 (unicode) Virtual Table for methods */
1904 /* Note: Hack so we can reuse the old functions without compiler warnings */
1905 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1906 # define XCAST(fun) (typeof(directPlayLobby3WVT.fun))
1908 # define XCAST(fun) (void*)
1911 static ICOM_VTABLE(IDirectPlayLobby3
) directPlayLobby3WVT
=
1913 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1914 XCAST(QueryInterface
)DPL_QueryInterface
,
1915 XCAST(AddRef
)DPL_AddRef
,
1916 XCAST(Release
)DPL_Release
,
1918 XCAST(Connect
)IDirectPlayLobbyWImpl_Connect
,
1919 XCAST(CreateAddress
)IDirectPlayLobbyWImpl_CreateAddress
,
1920 XCAST(EnumAddress
)IDirectPlayLobbyWImpl_EnumAddress
,
1921 XCAST(EnumAddressTypes
)IDirectPlayLobbyWImpl_EnumAddressTypes
,
1922 XCAST(EnumLocalApplications
)IDirectPlayLobbyWImpl_EnumLocalApplications
,
1923 XCAST(GetConnectionSettings
)IDirectPlayLobbyWImpl_GetConnectionSettings
,
1924 XCAST(ReceiveLobbyMessage
)IDirectPlayLobbyWImpl_ReceiveLobbyMessage
,
1925 XCAST(RunApplication
)IDirectPlayLobbyWImpl_RunApplication
,
1926 XCAST(SendLobbyMessage
)IDirectPlayLobbyWImpl_SendLobbyMessage
,
1927 XCAST(SetConnectionSettings
)IDirectPlayLobbyWImpl_SetConnectionSettings
,
1928 XCAST(SetLobbyMessageEvent
)IDirectPlayLobbyWImpl_SetLobbyMessageEvent
,
1930 XCAST(CreateCompoundAddress
)IDirectPlayLobby2WImpl_CreateCompoundAddress
,
1932 IDirectPlayLobby3WImpl_ConnectEx
,
1933 IDirectPlayLobby3WImpl_RegisterApplication
,
1934 IDirectPlayLobby3WImpl_UnregisterApplication
,
1935 IDirectPlayLobby3WImpl_WaitForConnectionSettings
1940 /*********************************************************
1942 * Direct Play Lobby Interface Implementation
1944 *********************************************************/
1946 /***************************************************************************
1947 * DirectPlayLobbyCreateA (DPLAYX.4)
1950 HRESULT WINAPI
DirectPlayLobbyCreateA( LPGUID lpGUIDDSP
,
1951 LPDIRECTPLAYLOBBYA
*lplpDPL
,
1956 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
1957 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
1959 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
1960 * equal 0. These fields are mostly for future expansion.
1962 if ( lpGUIDDSP
|| lpData
|| dwDataSize
)
1965 return DPERR_INVALIDPARAMS
;
1971 ERR("Bad parameters!\n" );
1972 return CLASS_E_NOAGGREGATION
;
1975 return DPL_CreateInterface( &IID_IDirectPlayLobbyA
, (void**)lplpDPL
);
1978 /***************************************************************************
1979 * DirectPlayLobbyCreateW (DPLAYX.5)
1982 HRESULT WINAPI
DirectPlayLobbyCreateW( LPGUID lpGUIDDSP
,
1983 LPDIRECTPLAYLOBBY
*lplpDPL
,
1988 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
1989 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
1991 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
1992 * equal 0. These fields are mostly for future expansion.
1994 if ( lpGUIDDSP
|| lpData
|| dwDataSize
)
1997 ERR("Bad parameters!\n" );
1998 return DPERR_INVALIDPARAMS
;
2004 ERR("Bad parameters!\n" );
2005 return CLASS_E_NOAGGREGATION
;
2008 return DPL_CreateInterface( &IID_IDirectPlayLobby
, (void**)lplpDPL
);