1 /* Direct Play Lobby 2 & 3 Implementation
3 * Copyright 1998,1999,2000 - Peter Hunnisett
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define NONAMELESSUNION
23 #define NONAMELESSSTRUCT
29 #include "wine/debug.h"
31 #include "dplayx_global.h"
32 #include "dplayx_messages.h"
33 #include "dplayx_queue.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(dplay
);
39 /*****************************************************************************
40 * Predeclare the interface implementation structures
42 typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyAImpl
;
43 typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyWImpl
;
44 typedef struct IDirectPlayLobby2Impl IDirectPlayLobby2AImpl
;
45 typedef struct IDirectPlayLobby2Impl IDirectPlayLobby2WImpl
;
46 typedef struct IDirectPlayLobby3Impl IDirectPlayLobby3AImpl
;
47 typedef struct IDirectPlayLobby3Impl IDirectPlayLobby3WImpl
;
49 /* Forward declarations for this module helper methods */
50 HRESULT
DPL_CreateCompoundAddress ( LPCDPCOMPOUNDADDRESSELEMENT lpElements
, DWORD dwElementCount
,
51 LPVOID lpAddress
, LPDWORD lpdwAddressSize
, BOOL bAnsiInterface
);
53 static HRESULT
DPL_CreateAddress( REFGUID guidSP
, REFGUID guidDataType
, LPCVOID lpData
, DWORD dwDataSize
,
54 LPVOID lpAddress
, LPDWORD lpdwAddressSize
, BOOL bAnsiInterface
);
58 extern HRESULT
DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
, LPCVOID lpAddress
,
59 DWORD dwAddressSize
, LPVOID lpContext
);
61 static HRESULT WINAPI
DPL_ConnectEx( IDirectPlayLobbyAImpl
* This
,
62 DWORD dwFlags
, REFIID riid
,
63 LPVOID
* lplpDP
, IUnknown
* pUnk
);
65 static BOOL
DPL_CreateAndSetLobbyHandles( DWORD dwDestProcessId
, HANDLE hDestProcess
,
66 LPHANDLE lphStart
, LPHANDLE lphDeath
,
70 /*****************************************************************************
71 * IDirectPlayLobby {1,2,3} implementation structure
73 * The philosophy behind this extra pointer dereference is that I wanted to
74 * have the same structure for all types of objects without having to do
75 * a lot of casting. I also only wanted to implement an interface in the
76 * object it was "released" with IUnknown interface being implemented in the 1 version.
77 * Of course, with these new interfaces comes the data required to keep the state required
78 * by these interfaces. So, basically, the pointers contain the data associated with
79 * a release. If you use the data associated with release 3 in a release 2 object, you'll
80 * get a run time trap, as that won't have any data.
85 DPQ_ENTRY( DPLMSG
) msgs
; /* Link to next queued message */
87 typedef struct DPLMSG
* LPDPLMSG
;
89 typedef struct tagDirectPlayLobbyIUnknownData
92 CRITICAL_SECTION DPL_lock
;
93 } DirectPlayLobbyIUnknownData
;
95 typedef struct tagDirectPlayLobbyData
97 HKEY hkCallbackKeyHack
;
99 DPQ_HEAD( DPLMSG
) msgs
; /* List of messages received */
100 } DirectPlayLobbyData
;
102 typedef struct tagDirectPlayLobby2Data
105 } DirectPlayLobby2Data
;
107 typedef struct tagDirectPlayLobby3Data
110 } DirectPlayLobby3Data
;
112 #define DPL_IMPL_FIELDS \
113 LONG ulInterfaceRef; \
114 DirectPlayLobbyIUnknownData* unk; \
115 DirectPlayLobbyData* dpl; \
116 DirectPlayLobby2Data* dpl2; \
117 DirectPlayLobby3Data* dpl3;
119 struct IDirectPlayLobbyImpl
121 const IDirectPlayLobbyVtbl
*lpVtbl
;
125 struct IDirectPlayLobby2Impl
127 const IDirectPlayLobby2Vtbl
*lpVtbl
;
131 struct IDirectPlayLobby3Impl
133 const IDirectPlayLobby3Vtbl
*lpVtbl
;
137 /* Forward declarations of virtual tables */
138 static const IDirectPlayLobbyVtbl directPlayLobbyWVT
;
139 static const IDirectPlayLobby2Vtbl directPlayLobby2WVT
;
140 static const IDirectPlayLobby3Vtbl directPlayLobby3WVT
;
142 static const IDirectPlayLobbyVtbl directPlayLobbyAVT
;
143 static const IDirectPlayLobby2Vtbl directPlayLobby2AVT
;
144 static const IDirectPlayLobby3Vtbl directPlayLobby3AVT
;
146 static BOOL
DPL_CreateIUnknown( LPVOID lpDPL
)
148 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)lpDPL
;
150 This
->unk
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *(This
->unk
) ) );
151 if ( This
->unk
== NULL
)
156 InitializeCriticalSection( &This
->unk
->DPL_lock
);
157 This
->unk
->DPL_lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": IDirectPlayLobbyAImpl*->DirectPlayLobbyIUnknownData*->DPL_lock");
162 static BOOL
DPL_DestroyIUnknown( LPVOID lpDPL
)
164 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)lpDPL
;
166 This
->unk
->DPL_lock
.DebugInfo
->Spare
[0] = 0;
167 DeleteCriticalSection( &This
->unk
->DPL_lock
);
168 HeapFree( GetProcessHeap(), 0, This
->unk
);
173 static BOOL
DPL_CreateLobby1( LPVOID lpDPL
)
175 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)lpDPL
;
177 This
->dpl
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *(This
->dpl
) ) );
178 if ( This
->dpl
== NULL
)
183 DPQ_INIT( This
->dpl
->msgs
);
188 static BOOL
DPL_DestroyLobby1( LPVOID lpDPL
)
190 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)lpDPL
;
192 if( This
->dpl
->dwMsgThread
)
194 FIXME( "Should kill the msg thread\n" );
197 DPQ_DELETEQ( This
->dpl
->msgs
, msgs
, LPDPLMSG
, cbDeleteElemFromHeap
);
199 /* Delete the contents */
200 HeapFree( GetProcessHeap(), 0, This
->dpl
);
205 static BOOL
DPL_CreateLobby2( LPVOID lpDPL
)
207 IDirectPlayLobby2AImpl
*This
= (IDirectPlayLobby2AImpl
*)lpDPL
;
209 This
->dpl2
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *(This
->dpl2
) ) );
210 if ( This
->dpl2
== NULL
)
218 static BOOL
DPL_DestroyLobby2( LPVOID lpDPL
)
220 IDirectPlayLobby2AImpl
*This
= (IDirectPlayLobby2AImpl
*)lpDPL
;
222 HeapFree( GetProcessHeap(), 0, This
->dpl2
);
227 static BOOL
DPL_CreateLobby3( LPVOID lpDPL
)
229 IDirectPlayLobby3AImpl
*This
= (IDirectPlayLobby3AImpl
*)lpDPL
;
231 This
->dpl3
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *(This
->dpl3
) ) );
232 if ( This
->dpl3
== NULL
)
240 static BOOL
DPL_DestroyLobby3( LPVOID lpDPL
)
242 IDirectPlayLobby3AImpl
*This
= (IDirectPlayLobby3AImpl
*)lpDPL
;
244 HeapFree( GetProcessHeap(), 0, This
->dpl3
);
250 /* The COM interface for upversioning an interface
251 * We've been given a GUID (riid) and we need to replace the present
252 * interface with that of the requested interface.
254 * Snip from some Microsoft document:
255 * There are four requirements for implementations of QueryInterface (In these
256 * cases, "must succeed" means "must succeed barring catastrophic failure."):
258 * * The set of interfaces accessible on an object through
259 * IUnknown::QueryInterface must be static, not dynamic. This means that
260 * if a call to QueryInterface for a pointer to a specified interface
261 * succeeds the first time, it must succeed again, and if it fails the
262 * first time, it must fail on all subsequent queries.
263 * * It must be symmetric ~W if a client holds a pointer to an interface on
264 * an object, and queries for that interface, the call must succeed.
265 * * It must be reflexive ~W if a client holding a pointer to one interface
266 * queries successfully for another, a query through the obtained pointer
267 * for the first interface must succeed.
268 * * It must be transitive ~W if a client holding a pointer to one interface
269 * queries successfully for a second, and through that pointer queries
270 * successfully for a third interface, a query for the first interface
271 * through the pointer for the third interface must succeed.
274 HRESULT DPL_CreateInterface
275 ( REFIID riid
, LPVOID
* ppvObj
)
277 TRACE( " for %s\n", debugstr_guid( riid
) );
279 *ppvObj
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
280 sizeof( IDirectPlayLobbyWImpl
) );
282 if( *ppvObj
== NULL
)
284 return DPERR_OUTOFMEMORY
;
287 if( IsEqualGUID( &IID_IDirectPlayLobby
, riid
) )
289 IDirectPlayLobbyWImpl
*This
= (IDirectPlayLobbyWImpl
*)*ppvObj
;
290 This
->lpVtbl
= &directPlayLobbyWVT
;
292 else if( IsEqualGUID( &IID_IDirectPlayLobbyA
, riid
) )
294 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)*ppvObj
;
295 This
->lpVtbl
= &directPlayLobbyAVT
;
297 else if( IsEqualGUID( &IID_IDirectPlayLobby2
, riid
) )
299 IDirectPlayLobby2WImpl
*This
= (IDirectPlayLobby2WImpl
*)*ppvObj
;
300 This
->lpVtbl
= &directPlayLobby2WVT
;
302 else if( IsEqualGUID( &IID_IDirectPlayLobby2A
, riid
) )
304 IDirectPlayLobby2AImpl
*This
= (IDirectPlayLobby2AImpl
*)*ppvObj
;
305 This
->lpVtbl
= &directPlayLobby2AVT
;
307 else if( IsEqualGUID( &IID_IDirectPlayLobby3
, riid
) )
309 IDirectPlayLobby3WImpl
*This
= (IDirectPlayLobby3WImpl
*)*ppvObj
;
310 This
->lpVtbl
= &directPlayLobby3WVT
;
312 else if( IsEqualGUID( &IID_IDirectPlayLobby3A
, riid
) )
314 IDirectPlayLobby3AImpl
*This
= (IDirectPlayLobby3AImpl
*)*ppvObj
;
315 This
->lpVtbl
= &directPlayLobby3AVT
;
319 /* Unsupported interface */
320 HeapFree( GetProcessHeap(), 0, *ppvObj
);
323 return E_NOINTERFACE
;
327 if ( DPL_CreateIUnknown( *ppvObj
) &&
328 DPL_CreateLobby1( *ppvObj
) &&
329 DPL_CreateLobby2( *ppvObj
) &&
330 DPL_CreateLobby3( *ppvObj
)
333 IDirectPlayLobby_AddRef( (LPDIRECTPLAYLOBBY
)*ppvObj
);
337 /* Initialize failed, destroy it */
338 DPL_DestroyLobby3( *ppvObj
);
339 DPL_DestroyLobby2( *ppvObj
);
340 DPL_DestroyLobby1( *ppvObj
);
341 DPL_DestroyIUnknown( *ppvObj
);
342 HeapFree( GetProcessHeap(), 0, *ppvObj
);
345 return DPERR_NOMEMORY
;
348 static HRESULT WINAPI DPL_QueryInterface
349 ( LPDIRECTPLAYLOBBYA iface
,
353 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)iface
;
354 TRACE("(%p)->(%s,%p)\n", This
, debugstr_guid( riid
), ppvObj
);
356 *ppvObj
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
359 if( *ppvObj
== NULL
)
361 return DPERR_OUTOFMEMORY
;
364 CopyMemory( *ppvObj
, This
, sizeof( *This
) );
365 (*(IDirectPlayLobbyAImpl
**)ppvObj
)->ulInterfaceRef
= 0;
367 if( IsEqualGUID( &IID_IDirectPlayLobby
, riid
) )
369 IDirectPlayLobbyWImpl
*This
= (IDirectPlayLobbyWImpl
*)*ppvObj
;
370 This
->lpVtbl
= &directPlayLobbyWVT
;
372 else if( IsEqualGUID( &IID_IDirectPlayLobbyA
, riid
) )
374 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)*ppvObj
;
375 This
->lpVtbl
= &directPlayLobbyAVT
;
377 else if( IsEqualGUID( &IID_IDirectPlayLobby2
, riid
) )
379 IDirectPlayLobby2WImpl
*This
= (IDirectPlayLobby2WImpl
*)*ppvObj
;
380 This
->lpVtbl
= &directPlayLobby2WVT
;
382 else if( IsEqualGUID( &IID_IDirectPlayLobby2A
, riid
) )
384 IDirectPlayLobby2AImpl
*This
= (IDirectPlayLobby2AImpl
*)*ppvObj
;
385 This
->lpVtbl
= &directPlayLobby2AVT
;
387 else if( IsEqualGUID( &IID_IDirectPlayLobby3
, riid
) )
389 IDirectPlayLobby3WImpl
*This
= (IDirectPlayLobby3WImpl
*)*ppvObj
;
390 This
->lpVtbl
= &directPlayLobby3WVT
;
392 else if( IsEqualGUID( &IID_IDirectPlayLobby3A
, riid
) )
394 IDirectPlayLobby3AImpl
*This
= (IDirectPlayLobby3AImpl
*)*ppvObj
;
395 This
->lpVtbl
= &directPlayLobby3AVT
;
399 /* Unsupported interface */
400 HeapFree( GetProcessHeap(), 0, *ppvObj
);
403 return E_NOINTERFACE
;
406 IDirectPlayLobby_AddRef( (LPDIRECTPLAYLOBBY
)*ppvObj
);
412 * Simple procedure. Just increment the reference count to this
413 * structure and return the new reference count.
415 static ULONG WINAPI DPL_AddRef
416 ( LPDIRECTPLAYLOBBY iface
)
418 ULONG ulInterfaceRefCount
, ulObjRefCount
;
419 IDirectPlayLobbyWImpl
*This
= (IDirectPlayLobbyWImpl
*)iface
;
421 ulObjRefCount
= InterlockedIncrement( &This
->unk
->ulObjRef
);
422 ulInterfaceRefCount
= InterlockedIncrement( &This
->ulInterfaceRef
);
424 TRACE( "ref count incremented to %u:%u for %p\n",
425 ulInterfaceRefCount
, ulObjRefCount
, This
);
427 return ulObjRefCount
;
431 * Simple COM procedure. Decrease the reference count to this object.
432 * If the object no longer has any reference counts, free up the associated
435 static ULONG WINAPI DPL_Release
436 ( LPDIRECTPLAYLOBBYA iface
)
438 ULONG ulInterfaceRefCount
, ulObjRefCount
;
439 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)iface
;
441 ulObjRefCount
= InterlockedDecrement( &This
->unk
->ulObjRef
);
442 ulInterfaceRefCount
= InterlockedDecrement( &This
->ulInterfaceRef
);
444 TRACE( "ref count decremented to %u:%u for %p\n",
445 ulInterfaceRefCount
, ulObjRefCount
, This
);
447 /* Deallocate if this is the last reference to the object */
448 if( ulObjRefCount
== 0 )
450 DPL_DestroyLobby3( This
);
451 DPL_DestroyLobby2( This
);
452 DPL_DestroyLobby1( This
);
453 DPL_DestroyIUnknown( This
);
456 if( ulInterfaceRefCount
== 0 )
458 HeapFree( GetProcessHeap(), 0, This
);
461 return ulInterfaceRefCount
;
465 /********************************************************************
467 * Connects an application to the session specified by the DPLCONNECTION
468 * structure currently stored with the DirectPlayLobby object.
470 * Returns an IDirectPlay interface.
473 static HRESULT WINAPI DPL_ConnectEx
474 ( IDirectPlayLobbyAImpl
* This
,
481 DWORD dwOpenFlags
= 0;
482 DWORD dwConnSize
= 0;
483 LPDPLCONNECTION lpConn
;
485 FIXME("(%p)->(0x%08x,%p,%p): semi stub\n", This
, dwFlags
, lplpDP
, pUnk
);
489 return DPERR_INVALIDPARAMS
;
492 /* Backwards compatibility */
495 dwFlags
= DPCONNECT_RETURNSTATUS
;
498 /* Create the DirectPlay interface */
499 if( ( hr
= DP_CreateInterface( riid
, lplpDP
) ) != DP_OK
)
501 ERR( "error creating interface for %s:%s.\n",
502 debugstr_guid( riid
), DPLAYX_HresultToString( hr
) );
506 /* FIXME: Is it safe/correct to use appID of 0? */
507 hr
= IDirectPlayLobby_GetConnectionSettings( (LPDIRECTPLAYLOBBY
)This
,
508 0, NULL
, &dwConnSize
);
509 if( hr
!= DPERR_BUFFERTOOSMALL
)
514 lpConn
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, dwConnSize
);
518 return DPERR_NOMEMORY
;
521 /* FIXME: Is it safe/correct to use appID of 0? */
522 hr
= IDirectPlayLobby_GetConnectionSettings( (LPDIRECTPLAYLOBBY
)This
,
523 0, lpConn
, &dwConnSize
);
526 HeapFree( GetProcessHeap(), 0, lpConn
);
531 /* - Need to call IDirectPlay::EnumConnections with the service provider to get that good information
532 * - Need to call CreateAddress to create the lpConnection param for IDirectPlay::InitializeConnection
533 * - Call IDirectPlay::InitializeConnection
536 /* Now initialize the Service Provider */
537 hr
= IDirectPlayX_InitializeConnection( (*(LPDIRECTPLAY2
*)lplpDP
),
541 /* Setup flags to pass into DirectPlay::Open */
542 if( dwFlags
& DPCONNECT_RETURNSTATUS
)
544 dwOpenFlags
|= DPOPEN_RETURNSTATUS
;
546 dwOpenFlags
|= lpConn
->dwFlags
;
548 hr
= IDirectPlayX_Open( (*(LPDIRECTPLAY2
*)lplpDP
), lpConn
->lpSessionDesc
,
551 HeapFree( GetProcessHeap(), 0, lpConn
);
556 static HRESULT WINAPI IDirectPlayLobbyAImpl_Connect
557 ( LPDIRECTPLAYLOBBYA iface
,
559 LPDIRECTPLAY2A
* lplpDP
,
562 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)iface
;
563 return DPL_ConnectEx( This
, dwFlags
, &IID_IDirectPlay2A
,
564 (LPVOID
)lplpDP
, pUnk
);
567 static HRESULT WINAPI IDirectPlayLobbyWImpl_Connect
568 ( LPDIRECTPLAYLOBBY iface
,
570 LPDIRECTPLAY2
* lplpDP
,
573 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)iface
; /* Yes cast to A */
574 return DPL_ConnectEx( This
, dwFlags
, &IID_IDirectPlay2
,
575 (LPVOID
)lplpDP
, pUnk
);
578 /********************************************************************
580 * Creates a DirectPlay Address, given a service provider-specific network
582 * Returns an address contains the globally unique identifier
583 * (GUID) of the service provider and data that the service provider can
584 * interpret as a network address.
586 * NOTE: It appears that this method is supposed to be really really stupid
587 * with no error checking on the contents.
589 static HRESULT WINAPI IDirectPlayLobbyAImpl_CreateAddress
590 ( LPDIRECTPLAYLOBBYA iface
,
592 REFGUID guidDataType
,
596 LPDWORD lpdwAddressSize
)
598 return DPL_CreateAddress( guidSP
, guidDataType
, lpData
, dwDataSize
,
599 lpAddress
, lpdwAddressSize
, TRUE
);
602 static HRESULT WINAPI IDirectPlayLobbyWImpl_CreateAddress
603 ( LPDIRECTPLAYLOBBY iface
,
605 REFGUID guidDataType
,
609 LPDWORD lpdwAddressSize
)
611 return DPL_CreateAddress( guidSP
, guidDataType
, lpData
, dwDataSize
,
612 lpAddress
, lpdwAddressSize
, FALSE
);
615 static HRESULT
DPL_CreateAddress(
617 REFGUID guidDataType
,
621 LPDWORD lpdwAddressSize
,
622 BOOL bAnsiInterface
)
624 const DWORD dwNumAddElements
= 2; /* Service Provide & address data type */
625 DPCOMPOUNDADDRESSELEMENT addressElements
[ 2 /* dwNumAddElements */ ];
627 TRACE( "(%p)->(%p,%p,0x%08x,%p,%p,%d)\n", guidSP
, guidDataType
, lpData
, dwDataSize
,
628 lpAddress
, lpdwAddressSize
, bAnsiInterface
);
630 addressElements
[ 0 ].guidDataType
= DPAID_ServiceProvider
;
631 addressElements
[ 0 ].dwDataSize
= sizeof( GUID
);
632 addressElements
[ 0 ].lpData
= (LPVOID
)guidSP
;
634 addressElements
[ 1 ].guidDataType
= *guidDataType
;
635 addressElements
[ 1 ].dwDataSize
= dwDataSize
;
636 addressElements
[ 1 ].lpData
= (LPVOID
)lpData
;
638 /* Call CreateCompoundAddress to cut down on code.
639 NOTE: We can do this because we don't support DPL 1 interfaces! */
640 return DPL_CreateCompoundAddress( addressElements
, dwNumAddElements
,
641 lpAddress
, lpdwAddressSize
, bAnsiInterface
);
646 /********************************************************************
648 * Parses out chunks from the DirectPlay Address buffer by calling the
649 * given callback function, with lpContext, for each of the chunks.
652 static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddress
653 ( LPDIRECTPLAYLOBBYA iface
,
654 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
,
659 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)iface
;
661 TRACE("(%p)->(%p,%p,0x%08x,%p)\n", This
, lpEnumAddressCallback
, lpAddress
,
662 dwAddressSize
, lpContext
);
664 return DPL_EnumAddress( lpEnumAddressCallback
, lpAddress
, dwAddressSize
, lpContext
);
667 static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumAddress
668 ( LPDIRECTPLAYLOBBY iface
,
669 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
,
674 IDirectPlayLobbyWImpl
*This
= (IDirectPlayLobbyWImpl
*)iface
;
676 TRACE("(%p)->(%p,%p,0x%08x,%p)\n", This
, lpEnumAddressCallback
, lpAddress
,
677 dwAddressSize
, lpContext
);
679 return DPL_EnumAddress( lpEnumAddressCallback
, lpAddress
, dwAddressSize
, lpContext
);
682 extern HRESULT
DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
, LPCVOID lpAddress
,
683 DWORD dwAddressSize
, LPVOID lpContext
)
685 DWORD dwTotalSizeEnumerated
= 0;
687 /* FIXME: First chunk is always the total size chunk - Should we report it? */
689 while ( dwTotalSizeEnumerated
< dwAddressSize
)
691 const DPADDRESS
* lpElements
= (const DPADDRESS
*)lpAddress
;
692 DWORD dwSizeThisEnumeration
;
694 /* Invoke the enum method. If false is returned, stop enumeration */
695 if ( !lpEnumAddressCallback( &lpElements
->guidDataType
,
696 lpElements
->dwDataSize
,
697 (const BYTE
*)lpElements
+ sizeof( DPADDRESS
),
703 dwSizeThisEnumeration
= sizeof( DPADDRESS
) + lpElements
->dwDataSize
;
704 lpAddress
= (const BYTE
*) lpAddress
+ dwSizeThisEnumeration
;
705 dwTotalSizeEnumerated
+= dwSizeThisEnumeration
;
711 /********************************************************************
713 * Enumerates all the address types that a given service provider needs to
714 * build the DirectPlay Address.
717 static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddressTypes
718 ( LPDIRECTPLAYLOBBYA iface
,
719 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
,
724 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)iface
;
727 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
728 DWORD dwIndex
, sizeOfSubKeyName
=50;
732 TRACE(" (%p)->(%p,%p,%p,0x%08x)\n", This
, lpEnumAddressTypeCallback
, guidSP
, lpContext
, dwFlags
);
736 return DPERR_INVALIDPARAMS
;
739 if( !lpEnumAddressTypeCallback
|| !*lpEnumAddressTypeCallback
)
741 return DPERR_INVALIDPARAMS
;
746 return DPERR_INVALIDOBJECT
;
749 /* Need to loop over the service providers in the registry */
750 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
751 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
753 /* Hmmm. Does this mean that there are no service providers? */
754 ERR(": no service providers?\n");
758 /* Traverse all the service providers we have available */
760 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
,
761 NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
762 ++dwIndex
, sizeOfSubKeyName
=50 )
765 HKEY hkServiceProvider
, hkServiceProviderAt
;
766 GUID serviceProviderGUID
;
767 DWORD returnTypeGUID
, sizeOfReturnBuffer
= 50;
769 char returnBuffer
[51];
772 LPCSTR atKey
= "Address Types";
773 LPCSTR guidDataSubKey
= "Guid";
777 TRACE(" this time through: %s\n", subKeyName
);
779 /* Get a handle for this particular service provider */
780 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
781 &hkServiceProvider
) != ERROR_SUCCESS
)
783 ERR(": what the heck is going on?\n" );
787 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
788 NULL
, &returnTypeGUID
, (LPBYTE
)returnBuffer
,
789 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
791 ERR(": missing GUID registry data members\n" );
795 /* FIXME: Check return types to ensure we're interpreting data right */
796 MultiByteToWideChar( CP_ACP
, 0, returnBuffer
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
797 CLSIDFromString( buff
, &serviceProviderGUID
);
798 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
800 /* Determine if this is the Service Provider that the user asked for */
801 if( !IsEqualGUID( &serviceProviderGUID
, guidSP
) )
806 /* Get a handle for this particular service provider */
807 if( RegOpenKeyExA( hkServiceProvider
, atKey
, 0, KEY_READ
,
808 &hkServiceProviderAt
) != ERROR_SUCCESS
)
810 TRACE(": No Address Types registry data sub key/members\n" );
814 /* Traverse all the address type we have available */
816 RegEnumKeyExA( hkServiceProviderAt
, dwAtIndex
, atSubKey
, &sizeOfSubKeyName
,
817 NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
818 ++dwAtIndex
, sizeOfSubKeyName
=50 )
820 TRACE( "Found Address Type GUID %s\n", atSubKey
);
822 /* FIXME: Check return types to ensure we're interpreting data right */
823 MultiByteToWideChar( CP_ACP
, 0, atSubKey
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
824 CLSIDFromString( buff
, &serviceProviderGUID
);
825 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
827 /* The enumeration will return FALSE if we are not to continue */
828 if( !lpEnumAddressTypeCallback( &serviceProviderGUID
, lpContext
, 0 ) )
830 WARN("lpEnumCallback returning FALSE\n" );
831 break; /* FIXME: This most likely has to break from the procedure...*/
836 /* We only enumerate address types for 1 GUID. We've found it, so quit looking */
843 static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumAddressTypes
844 ( LPDIRECTPLAYLOBBY iface
,
845 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
,
851 return DPERR_OUTOFMEMORY
;
854 /********************************************************************
856 * Enumerates what applications are registered with DirectPlay by
857 * invoking the callback function with lpContext.
860 static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumLocalApplications
861 ( LPDIRECTPLAYLOBBY iface
,
862 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback
,
866 IDirectPlayLobbyWImpl
*This
= (IDirectPlayLobbyWImpl
*)iface
;
868 FIXME("(%p)->(%p,%p,0x%08x):stub\n", This
, lpEnumLocalAppCallback
, lpContext
, dwFlags
);
870 return DPERR_OUTOFMEMORY
;
873 static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumLocalApplications
874 ( LPDIRECTPLAYLOBBYA iface
,
875 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback
,
879 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)iface
;
882 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Applications";
883 LPCSTR guidDataSubKey
= "Guid";
884 DWORD dwIndex
, sizeOfSubKeyName
=50;
888 TRACE("(%p)->(%p,%p,0x%08x)\n", This
, lpEnumLocalAppCallback
, lpContext
, dwFlags
);
892 return DPERR_INVALIDPARAMS
;
895 if( !lpEnumLocalAppCallback
|| !*lpEnumLocalAppCallback
)
897 return DPERR_INVALIDPARAMS
;
900 /* Need to loop over the service providers in the registry */
901 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
902 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
904 /* Hmmm. Does this mean that there are no service providers? */
905 ERR(": no service providers?\n");
909 /* Traverse all registered applications */
911 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
, NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
912 ++dwIndex
, sizeOfSubKeyName
=50 )
915 HKEY hkServiceProvider
;
916 GUID serviceProviderGUID
;
917 DWORD returnTypeGUID
, sizeOfReturnBuffer
= 50;
918 char returnBuffer
[51];
920 DPLAPPINFO dplAppInfo
;
922 TRACE(" this time through: %s\n", subKeyName
);
924 /* Get a handle for this particular service provider */
925 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
926 &hkServiceProvider
) != ERROR_SUCCESS
)
928 ERR(": what the heck is going on?\n" );
932 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
933 NULL
, &returnTypeGUID
, (LPBYTE
)returnBuffer
,
934 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
936 ERR(": missing GUID registry data members\n" );
940 /* FIXME: Check return types to ensure we're interpreting data right */
941 MultiByteToWideChar( CP_ACP
, 0, returnBuffer
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
942 CLSIDFromString( buff
, &serviceProviderGUID
);
943 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
945 dplAppInfo
.dwSize
= sizeof( dplAppInfo
);
946 dplAppInfo
.guidApplication
= serviceProviderGUID
;
947 dplAppInfo
.u
.lpszAppNameA
= subKeyName
;
949 EnterCriticalSection( &This
->unk
->DPL_lock
);
951 memcpy( &This
->dpl
->hkCallbackKeyHack
, &hkServiceProvider
, sizeof( hkServiceProvider
) );
953 if( !lpEnumLocalAppCallback( &dplAppInfo
, lpContext
, dwFlags
) )
955 LeaveCriticalSection( &This
->unk
->DPL_lock
);
959 LeaveCriticalSection( &This
->unk
->DPL_lock
);
965 /********************************************************************
967 * Retrieves the DPLCONNECTION structure that contains all the information
968 * needed to start and connect an application. This was generated using
969 * either the RunApplication or SetConnectionSettings methods.
971 * NOTES: If lpData is NULL then just return lpdwDataSize. This allows
972 * the data structure to be allocated by our caller which can then
973 * call this procedure/method again with a valid data pointer.
975 static HRESULT WINAPI IDirectPlayLobbyAImpl_GetConnectionSettings
976 ( LPDIRECTPLAYLOBBYA iface
,
979 LPDWORD lpdwDataSize
)
981 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)iface
;
984 TRACE("(%p)->(0x%08x,%p,%p)\n", This
, dwAppID
, lpData
, lpdwDataSize
);
986 EnterCriticalSection( &This
->unk
->DPL_lock
);
988 hr
= DPLAYX_GetConnectionSettingsA( dwAppID
,
993 LeaveCriticalSection( &This
->unk
->DPL_lock
);
998 static HRESULT WINAPI IDirectPlayLobbyWImpl_GetConnectionSettings
999 ( LPDIRECTPLAYLOBBY iface
,
1002 LPDWORD lpdwDataSize
)
1004 IDirectPlayLobbyWImpl
*This
= (IDirectPlayLobbyWImpl
*)iface
;
1007 TRACE("(%p)->(0x%08x,%p,%p)\n", This
, dwAppID
, lpData
, lpdwDataSize
);
1009 EnterCriticalSection( &This
->unk
->DPL_lock
);
1011 hr
= DPLAYX_GetConnectionSettingsW( dwAppID
,
1016 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1021 /********************************************************************
1023 * Retrieves the message sent between a lobby client and a DirectPlay
1024 * application. All messages are queued until received.
1027 static HRESULT WINAPI IDirectPlayLobbyAImpl_ReceiveLobbyMessage
1028 ( LPDIRECTPLAYLOBBYA iface
,
1031 LPDWORD lpdwMessageFlags
,
1033 LPDWORD lpdwDataSize
)
1035 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)iface
;
1036 FIXME(":stub %p %08x %08x %p %p %p\n", This
, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
1038 return DPERR_OUTOFMEMORY
;
1041 static HRESULT WINAPI IDirectPlayLobbyWImpl_ReceiveLobbyMessage
1042 ( LPDIRECTPLAYLOBBY iface
,
1045 LPDWORD lpdwMessageFlags
,
1047 LPDWORD lpdwDataSize
)
1049 IDirectPlayLobbyWImpl
*This
= (IDirectPlayLobbyWImpl
*)iface
;
1050 FIXME(":stub %p %08x %08x %p %p %p\n", This
, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
1052 return DPERR_OUTOFMEMORY
;
1055 typedef struct tagRunApplicationEnumStruct
1057 IDirectPlayLobbyAImpl
* This
;
1062 LPSTR lpszCommandLine
;
1063 LPSTR lpszCurrentDirectory
;
1064 } RunApplicationEnumStruct
, *lpRunApplicationEnumStruct
;
1066 /* To be called by RunApplication to find how to invoke the function */
1067 static BOOL CALLBACK RunApplicationA_EnumLocalApplications
1068 ( LPCDPLAPPINFO lpAppInfo
,
1072 lpRunApplicationEnumStruct lpData
= (lpRunApplicationEnumStruct
)lpContext
;
1074 if( IsEqualGUID( &lpAppInfo
->guidApplication
, &lpData
->appGUID
) )
1076 char returnBuffer
[200];
1077 DWORD returnType
, sizeOfReturnBuffer
;
1078 LPCSTR clSubKey
= "CommandLine";
1079 LPCSTR cdSubKey
= "CurrentDirectory";
1080 LPCSTR fileSubKey
= "File";
1081 LPCSTR pathSubKey
= "Path";
1083 /* FIXME: Lazy man hack - dplay struct has the present reg key saved */
1085 sizeOfReturnBuffer
= 200;
1087 /* Get all the appropriate data from the registry */
1088 if( RegQueryValueExA( lpData
->This
->dpl
->hkCallbackKeyHack
, clSubKey
,
1089 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1090 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1092 ERR( ": missing CommandLine registry data member\n" );
1096 if ((lpData
->lpszCommandLine
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1097 strcpy( lpData
->lpszCommandLine
, returnBuffer
);
1100 sizeOfReturnBuffer
= 200;
1102 if( RegQueryValueExA( lpData
->This
->dpl
->hkCallbackKeyHack
, cdSubKey
,
1103 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1104 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1106 ERR( ": missing CurrentDirectory registry data member\n" );
1110 if ((lpData
->lpszCurrentDirectory
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1111 strcpy( lpData
->lpszCurrentDirectory
, returnBuffer
);
1114 sizeOfReturnBuffer
= 200;
1116 if( RegQueryValueExA( lpData
->This
->dpl
->hkCallbackKeyHack
, fileSubKey
,
1117 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1118 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1120 ERR( ": missing File registry data member\n" );
1124 if ((lpData
->lpszFileName
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1125 strcpy( lpData
->lpszFileName
, returnBuffer
);
1128 sizeOfReturnBuffer
= 200;
1130 if( RegQueryValueExA( lpData
->This
->dpl
->hkCallbackKeyHack
, pathSubKey
,
1131 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1132 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1134 ERR( ": missing Path registry data member\n" );
1138 if ((lpData
->lpszPath
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1139 strcpy( lpData
->lpszPath
, returnBuffer
);
1142 return FALSE
; /* No need to keep going as we found what we wanted */
1145 return TRUE
; /* Keep enumerating, haven't found the application yet */
1148 static BOOL
DPL_CreateAndSetLobbyHandles( DWORD dwDestProcessId
, HANDLE hDestProcess
,
1149 LPHANDLE lphStart
, LPHANDLE lphDeath
,
1152 /* These are the handles for the created process */
1153 HANDLE hAppStart
= 0, hAppDeath
= 0, hAppRead
= 0;
1154 SECURITY_ATTRIBUTES s_attrib
;
1156 s_attrib
.nLength
= sizeof( s_attrib
);
1157 s_attrib
.lpSecurityDescriptor
= NULL
;
1158 s_attrib
.bInheritHandle
= TRUE
;
1160 *lphStart
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1161 *lphDeath
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1162 *lphRead
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1164 if( ( !DuplicateHandle( GetCurrentProcess(), *lphStart
,
1165 hDestProcess
, &hAppStart
,
1166 0, FALSE
, DUPLICATE_SAME_ACCESS
) ) ||
1167 ( !DuplicateHandle( GetCurrentProcess(), *lphDeath
,
1168 hDestProcess
, &hAppDeath
,
1169 0, FALSE
, DUPLICATE_SAME_ACCESS
) ) ||
1170 ( !DuplicateHandle( GetCurrentProcess(), *lphRead
,
1171 hDestProcess
, &hAppRead
,
1172 0, FALSE
, DUPLICATE_SAME_ACCESS
) )
1175 if (*lphStart
) { CloseHandle(*lphStart
); *lphStart
= 0; }
1176 if (*lphDeath
) { CloseHandle(*lphDeath
); *lphDeath
= 0; }
1177 if (*lphRead
) { CloseHandle(*lphRead
); *lphRead
= 0; }
1178 /* FIXME: Handle leak... */
1179 ERR( "Unable to dup handles\n" );
1183 if( !DPLAYX_SetLobbyHandles( dwDestProcessId
,
1184 hAppStart
, hAppDeath
, hAppRead
) )
1186 /* FIXME: Handle leak... */
1194 /********************************************************************
1196 * Starts an application and passes to it all the information to
1197 * connect to a session.
1200 static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication
1201 ( LPDIRECTPLAYLOBBYA iface
,
1204 LPDPLCONNECTION lpConn
,
1205 HANDLE hReceiveEvent
)
1207 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)iface
;
1209 RunApplicationEnumStruct enumData
;
1211 STARTUPINFOA startupInfo
;
1212 PROCESS_INFORMATION newProcessInfo
;
1214 DWORD dwSuspendCount
;
1215 HANDLE hStart
, hDeath
, hSettingRead
;
1217 TRACE( "(%p)->(0x%08x,%p,%p,%p)\n",
1218 This
, dwFlags
, lpdwAppID
, lpConn
, hReceiveEvent
);
1222 return DPERR_INVALIDPARAMS
;
1225 if( DPLAYX_AnyLobbiesWaitingForConnSettings() )
1227 FIXME( "Waiting lobby not being handled correctly\n" );
1230 EnterCriticalSection( &This
->unk
->DPL_lock
);
1232 ZeroMemory( &enumData
, sizeof( enumData
) );
1233 enumData
.This
= This
;
1234 enumData
.appGUID
= lpConn
->lpSessionDesc
->guidApplication
;
1236 /* Our callback function will fill up the enumData structure with all the information
1237 required to start a new process */
1238 IDirectPlayLobby_EnumLocalApplications( iface
, RunApplicationA_EnumLocalApplications
,
1239 (LPVOID
)(&enumData
), 0 );
1241 /* First the application name */
1242 strcpy( temp
, enumData
.lpszPath
);
1243 strcat( temp
, "\\" );
1244 strcat( temp
, enumData
.lpszFileName
);
1245 HeapFree( GetProcessHeap(), 0, enumData
.lpszPath
);
1246 HeapFree( GetProcessHeap(), 0, enumData
.lpszFileName
);
1247 if ((appName
= HeapAlloc( GetProcessHeap(), 0, strlen(temp
)+1 ))) strcpy( appName
, temp
);
1249 /* Now the command line */
1250 strcat( temp
, " " );
1251 strcat( temp
, enumData
.lpszCommandLine
);
1252 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1253 if ((enumData
.lpszCommandLine
= HeapAlloc( GetProcessHeap(), 0, strlen(temp
)+1 )))
1254 strcpy( enumData
.lpszCommandLine
, temp
);
1256 ZeroMemory( &startupInfo
, sizeof( startupInfo
) );
1257 startupInfo
.cb
= sizeof( startupInfo
);
1258 /* FIXME: Should any fields be filled in? */
1260 ZeroMemory( &newProcessInfo
, sizeof( newProcessInfo
) );
1262 if( !CreateProcessA( appName
,
1263 enumData
.lpszCommandLine
,
1267 CREATE_DEFAULT_ERROR_MODE
| CREATE_NEW_CONSOLE
| CREATE_SUSPENDED
, /* Creation Flags */
1269 enumData
.lpszCurrentDirectory
,
1275 ERR( "Failed to create process for app %s\n", appName
);
1277 HeapFree( GetProcessHeap(), 0, appName
);
1278 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1279 HeapFree( GetProcessHeap(), 0, enumData
.lpszCurrentDirectory
);
1281 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1282 return DPERR_CANTCREATEPROCESS
;
1285 HeapFree( GetProcessHeap(), 0, appName
);
1286 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1287 HeapFree( GetProcessHeap(), 0, enumData
.lpszCurrentDirectory
);
1289 /* Reserve this global application id! */
1290 if( !DPLAYX_CreateLobbyApplication( newProcessInfo
.dwProcessId
) )
1292 ERR( "Unable to create global application data for 0x%08x\n",
1293 newProcessInfo
.dwProcessId
);
1296 hr
= IDirectPlayLobby_SetConnectionSettings( iface
, 0, newProcessInfo
.dwProcessId
, lpConn
);
1300 ERR( "SetConnectionSettings failure %s\n", DPLAYX_HresultToString( hr
) );
1301 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1305 /* Setup the handles for application notification */
1306 DPL_CreateAndSetLobbyHandles( newProcessInfo
.dwProcessId
,
1307 newProcessInfo
.hProcess
,
1308 &hStart
, &hDeath
, &hSettingRead
);
1310 /* Setup the message thread ID */
1311 This
->dpl
->dwMsgThread
=
1312 CreateLobbyMessageReceptionThread( hReceiveEvent
, hStart
, hDeath
, hSettingRead
);
1314 DPLAYX_SetLobbyMsgThreadId( newProcessInfo
.dwProcessId
, This
->dpl
->dwMsgThread
);
1316 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1318 /* Everything seems to have been set correctly, update the dwAppID */
1319 *lpdwAppID
= newProcessInfo
.dwProcessId
;
1321 /* Unsuspend the process - should return the prev suspension count */
1322 if( ( dwSuspendCount
= ResumeThread( newProcessInfo
.hThread
) ) != 1 )
1324 ERR( "ResumeThread failed with 0x%08x\n", dwSuspendCount
);
1330 static HRESULT WINAPI IDirectPlayLobbyWImpl_RunApplication
1331 ( LPDIRECTPLAYLOBBY iface
,
1334 LPDPLCONNECTION lpConn
,
1335 HANDLE hReceiveEvent
)
1337 IDirectPlayLobbyWImpl
*This
= (IDirectPlayLobbyWImpl
*)iface
;
1338 FIXME( "(%p)->(0x%08x,%p,%p,%p):stub\n", This
, dwFlags
, lpdwAppID
, lpConn
, (void *)hReceiveEvent
);
1339 return DPERR_OUTOFMEMORY
;
1342 /********************************************************************
1344 * Sends a message between the application and the lobby client.
1345 * All messages are queued until received.
1348 static HRESULT WINAPI IDirectPlayLobbyAImpl_SendLobbyMessage
1349 ( LPDIRECTPLAYLOBBYA iface
,
1356 return DPERR_OUTOFMEMORY
;
1359 static HRESULT WINAPI IDirectPlayLobbyWImpl_SendLobbyMessage
1360 ( LPDIRECTPLAYLOBBY iface
,
1367 return DPERR_OUTOFMEMORY
;
1370 /********************************************************************
1372 * Modifies the DPLCONNECTION structure to contain all information
1373 * needed to start and connect an application.
1376 static HRESULT WINAPI IDirectPlayLobbyWImpl_SetConnectionSettings
1377 ( LPDIRECTPLAYLOBBY iface
,
1380 LPDPLCONNECTION lpConn
)
1382 IDirectPlayLobbyWImpl
*This
= (IDirectPlayLobbyWImpl
*)iface
;
1385 TRACE("(%p)->(0x%08x,0x%08x,%p)\n", This
, dwFlags
, dwAppID
, lpConn
);
1387 EnterCriticalSection( &This
->unk
->DPL_lock
);
1389 hr
= DPLAYX_SetConnectionSettingsW( dwFlags
, dwAppID
, lpConn
);
1391 /* FIXME: Don't think that this is supposed to fail, but the docuementation
1392 is somewhat sketchy. I'll try creating a lobby application
1394 if( hr
== DPERR_NOTLOBBIED
)
1396 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1399 dwAppID
= GetCurrentProcessId();
1401 DPLAYX_CreateLobbyApplication( dwAppID
);
1402 hr
= DPLAYX_SetConnectionSettingsW( dwFlags
, dwAppID
, lpConn
);
1405 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1410 static HRESULT WINAPI IDirectPlayLobbyAImpl_SetConnectionSettings
1411 ( LPDIRECTPLAYLOBBYA iface
,
1414 LPDPLCONNECTION lpConn
)
1416 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)iface
;
1419 TRACE("(%p)->(0x%08x,0x%08x,%p)\n", This
, dwFlags
, dwAppID
, lpConn
);
1421 EnterCriticalSection( &This
->unk
->DPL_lock
);
1423 hr
= DPLAYX_SetConnectionSettingsA( dwFlags
, dwAppID
, lpConn
);
1425 /* FIXME: Don't think that this is supposed to fail, but the docuementation
1426 is somewhat sketchy. I'll try creating a lobby application
1428 if( hr
== DPERR_NOTLOBBIED
)
1430 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1431 dwAppID
= GetCurrentProcessId();
1432 DPLAYX_CreateLobbyApplication( dwAppID
);
1433 hr
= DPLAYX_SetConnectionSettingsA( dwFlags
, dwAppID
, lpConn
);
1436 LeaveCriticalSection( &This
->unk
->DPL_lock
);
1441 /********************************************************************
1443 * Registers an event that will be set when a lobby message is received.
1446 static HRESULT WINAPI IDirectPlayLobbyAImpl_SetLobbyMessageEvent
1447 ( LPDIRECTPLAYLOBBYA iface
,
1450 HANDLE hReceiveEvent
)
1453 return DPERR_OUTOFMEMORY
;
1456 static HRESULT WINAPI IDirectPlayLobbyWImpl_SetLobbyMessageEvent
1457 ( LPDIRECTPLAYLOBBY iface
,
1460 HANDLE hReceiveEvent
)
1463 return DPERR_OUTOFMEMORY
;
1468 static HRESULT WINAPI IDirectPlayLobby2WImpl_CreateCompoundAddress
1469 ( LPDIRECTPLAYLOBBY2 iface
,
1470 LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1471 DWORD dwElementCount
,
1473 LPDWORD lpdwAddressSize
)
1475 return DPL_CreateCompoundAddress( lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
, FALSE
);
1478 static HRESULT WINAPI IDirectPlayLobby2AImpl_CreateCompoundAddress
1479 ( LPDIRECTPLAYLOBBY2A iface
,
1480 LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1481 DWORD dwElementCount
,
1483 LPDWORD lpdwAddressSize
)
1485 return DPL_CreateCompoundAddress( lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
, TRUE
);
1488 HRESULT DPL_CreateCompoundAddress
1489 ( LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1490 DWORD dwElementCount
,
1492 LPDWORD lpdwAddressSize
,
1493 BOOL bAnsiInterface
)
1495 DWORD dwSizeRequired
= 0;
1497 LPCDPCOMPOUNDADDRESSELEMENT lpOrigElements
= lpElements
;
1499 TRACE("(%p,0x%08x,%p,%p)\n", lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
);
1501 /* Parameter check */
1502 if( ( lpElements
== NULL
) ||
1503 ( dwElementCount
== 0 ) /* FIXME: Not sure if this is a failure case */
1506 return DPERR_INVALIDPARAMS
;
1509 /* Add the total size chunk */
1510 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( DWORD
);
1512 /* Calculate the size of the buffer required */
1513 for ( dwElements
= dwElementCount
; dwElements
> 0; --dwElements
, ++lpElements
)
1515 if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ServiceProvider
) ) ||
1516 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_LobbyProvider
) )
1519 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( GUID
);
1521 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Phone
) ) ||
1522 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Modem
) ) ||
1523 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INet
) )
1526 if( !bAnsiInterface
)
1528 ERR( "Ansi GUIDs used for unicode interface\n" );
1529 return DPERR_INVALIDFLAGS
;
1532 dwSizeRequired
+= sizeof( DPADDRESS
) + lpElements
->dwDataSize
;
1534 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_PhoneW
) ) ||
1535 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ModemW
) ) ||
1536 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetW
) )
1539 if( bAnsiInterface
)
1541 ERR( "Unicode GUIDs used for ansi interface\n" );
1542 return DPERR_INVALIDFLAGS
;
1545 FIXME( "Right size for unicode interface?\n" );
1546 dwSizeRequired
+= sizeof( DPADDRESS
) + lpElements
->dwDataSize
* sizeof( WCHAR
);
1548 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetPort
) )
1550 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( WORD
);
1552 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ComPort
) )
1554 FIXME( "Right size for unicode interface?\n" );
1555 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( DPCOMPORTADDRESS
); /* FIXME: Right size? */
1559 ERR( "Unknown GUID %s\n", debugstr_guid(&lpElements
->guidDataType
) );
1560 return DPERR_INVALIDFLAGS
;
1564 /* The user wants to know how big a buffer to allocate for us */
1565 if( ( lpAddress
== NULL
) ||
1566 ( *lpdwAddressSize
< dwSizeRequired
)
1569 *lpdwAddressSize
= dwSizeRequired
;
1570 return DPERR_BUFFERTOOSMALL
;
1573 /* Add the total size chunk */
1575 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1577 CopyMemory( &lpdpAddress
->guidDataType
, &DPAID_TotalSize
, sizeof( GUID
) );
1578 lpdpAddress
->dwDataSize
= sizeof( DWORD
);
1579 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1581 *(LPDWORD
)lpAddress
= dwSizeRequired
;
1582 lpAddress
= (char *) lpAddress
+ sizeof( DWORD
);
1585 /* Calculate the size of the buffer required */
1586 for( dwElements
= dwElementCount
, lpElements
= lpOrigElements
;
1588 --dwElements
, ++lpElements
)
1590 if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ServiceProvider
) ) ||
1591 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_LobbyProvider
) )
1594 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1596 CopyMemory( &lpdpAddress
->guidDataType
, &lpElements
->guidDataType
,
1598 lpdpAddress
->dwDataSize
= sizeof( GUID
);
1599 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1601 CopyMemory( lpAddress
, lpElements
->lpData
, sizeof( GUID
) );
1602 lpAddress
= (char *) lpAddress
+ sizeof( GUID
);
1604 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Phone
) ) ||
1605 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Modem
) ) ||
1606 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INet
) )
1609 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1611 CopyMemory( &lpdpAddress
->guidDataType
, &lpElements
->guidDataType
,
1613 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1614 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1616 lstrcpynA( (LPSTR
)lpAddress
,
1617 (LPCSTR
)lpElements
->lpData
,
1618 lpElements
->dwDataSize
);
1619 lpAddress
= (char *) lpAddress
+ lpElements
->dwDataSize
;
1621 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_PhoneW
) ) ||
1622 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ModemW
) ) ||
1623 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetW
) )
1626 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1628 CopyMemory( &lpdpAddress
->guidDataType
, &lpElements
->guidDataType
,
1630 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1631 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1633 lstrcpynW( (LPWSTR
)lpAddress
,
1634 (LPCWSTR
)lpElements
->lpData
,
1635 lpElements
->dwDataSize
);
1636 lpAddress
= (char *) lpAddress
+ lpElements
->dwDataSize
* sizeof( WCHAR
);
1638 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetPort
) )
1640 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1642 CopyMemory( &lpdpAddress
->guidDataType
, &lpElements
->guidDataType
,
1644 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1645 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1647 *((LPWORD
)lpAddress
) = *((LPWORD
)lpElements
->lpData
);
1648 lpAddress
= (char *) lpAddress
+ sizeof( WORD
);
1650 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ComPort
) )
1652 LPDPADDRESS lpdpAddress
= (LPDPADDRESS
)lpAddress
;
1654 CopyMemory( &lpdpAddress
->guidDataType
, &lpElements
->guidDataType
,
1656 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1657 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1659 CopyMemory( lpAddress
, lpElements
->lpData
, sizeof( DPADDRESS
) );
1660 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1669 static HRESULT WINAPI IDirectPlayLobby3WImpl_ConnectEx
1670 ( LPDIRECTPLAYLOBBY3 iface
, DWORD dwFlags
, REFIID riid
,
1671 LPVOID
* lplpDP
, IUnknown
* pUnk
)
1673 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)iface
;
1674 return DPL_ConnectEx( This
, dwFlags
, riid
, lplpDP
, pUnk
);
1677 static HRESULT WINAPI IDirectPlayLobby3AImpl_ConnectEx
1678 ( LPDIRECTPLAYLOBBY3A iface
, DWORD dwFlags
, REFIID riid
,
1679 LPVOID
* lplpDP
, IUnknown
* pUnk
)
1681 IDirectPlayLobbyAImpl
*This
= (IDirectPlayLobbyAImpl
*)iface
;
1682 return DPL_ConnectEx( This
, dwFlags
, riid
, lplpDP
, pUnk
);
1685 static HRESULT WINAPI IDirectPlayLobby3WImpl_RegisterApplication
1686 ( LPDIRECTPLAYLOBBY3 iface
, DWORD dwFlags
, LPDPAPPLICATIONDESC lpAppDesc
)
1692 static HRESULT WINAPI IDirectPlayLobby3AImpl_RegisterApplication
1693 ( LPDIRECTPLAYLOBBY3A iface
, DWORD dwFlags
, LPDPAPPLICATIONDESC lpAppDesc
)
1699 static HRESULT WINAPI IDirectPlayLobby3WImpl_UnregisterApplication
1700 ( LPDIRECTPLAYLOBBY3 iface
, DWORD dwFlags
, REFGUID lpAppDesc
)
1706 static HRESULT WINAPI IDirectPlayLobby3AImpl_UnregisterApplication
1707 ( LPDIRECTPLAYLOBBY3A iface
, DWORD dwFlags
, REFGUID lpAppDesc
)
1713 static HRESULT WINAPI IDirectPlayLobby3WImpl_WaitForConnectionSettings
1714 ( LPDIRECTPLAYLOBBY3 iface
, DWORD dwFlags
)
1717 BOOL bStartWait
= (dwFlags
& DPLWAIT_CANCEL
) ? FALSE
: TRUE
;
1719 TRACE( "(%p)->(0x%08x)\n", iface
, dwFlags
);
1721 if( DPLAYX_WaitForConnectionSettings( bStartWait
) )
1723 /* FIXME: What is the correct error return code? */
1724 hr
= DPERR_NOTLOBBIED
;
1730 static HRESULT WINAPI IDirectPlayLobby3AImpl_WaitForConnectionSettings
1731 ( LPDIRECTPLAYLOBBY3A iface
, DWORD dwFlags
)
1734 BOOL bStartWait
= (dwFlags
& DPLWAIT_CANCEL
) ? FALSE
: TRUE
;
1736 TRACE( "(%p)->(0x%08x)\n", iface
, dwFlags
);
1738 if( DPLAYX_WaitForConnectionSettings( bStartWait
) )
1740 /* FIXME: What is the correct error return code? */
1741 hr
= DPERR_NOTLOBBIED
;
1748 /* Virtual Table definitions for DPL{1,2,3}{A,W} */
1750 /* Note: Hack so we can reuse the old functions without compiler warnings */
1751 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1752 # define XCAST(fun) (typeof(directPlayLobbyAVT.fun))
1754 # define XCAST(fun) (void*)
1757 /* Direct Play Lobby 1 (ascii) Virtual Table for methods */
1758 /* All lobby 1 methods are exactly the same except QueryInterface */
1759 static const IDirectPlayLobbyVtbl directPlayLobbyAVT
=
1762 XCAST(QueryInterface
)DPL_QueryInterface
,
1763 XCAST(AddRef
)DPL_AddRef
,
1764 XCAST(Release
)DPL_Release
,
1766 IDirectPlayLobbyAImpl_Connect
,
1767 IDirectPlayLobbyAImpl_CreateAddress
,
1768 IDirectPlayLobbyAImpl_EnumAddress
,
1769 IDirectPlayLobbyAImpl_EnumAddressTypes
,
1770 IDirectPlayLobbyAImpl_EnumLocalApplications
,
1771 IDirectPlayLobbyAImpl_GetConnectionSettings
,
1772 IDirectPlayLobbyAImpl_ReceiveLobbyMessage
,
1773 IDirectPlayLobbyAImpl_RunApplication
,
1774 IDirectPlayLobbyAImpl_SendLobbyMessage
,
1775 IDirectPlayLobbyAImpl_SetConnectionSettings
,
1776 IDirectPlayLobbyAImpl_SetLobbyMessageEvent
1781 /* Note: Hack so we can reuse the old functions without compiler warnings */
1782 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1783 # define XCAST(fun) (typeof(directPlayLobbyWVT.fun))
1785 # define XCAST(fun) (void*)
1788 /* Direct Play Lobby 1 (unicode) Virtual Table for methods */
1789 static const IDirectPlayLobbyVtbl directPlayLobbyWVT
=
1792 XCAST(QueryInterface
)DPL_QueryInterface
,
1793 XCAST(AddRef
)DPL_AddRef
,
1794 XCAST(Release
)DPL_Release
,
1796 IDirectPlayLobbyWImpl_Connect
,
1797 IDirectPlayLobbyWImpl_CreateAddress
,
1798 IDirectPlayLobbyWImpl_EnumAddress
,
1799 IDirectPlayLobbyWImpl_EnumAddressTypes
,
1800 IDirectPlayLobbyWImpl_EnumLocalApplications
,
1801 IDirectPlayLobbyWImpl_GetConnectionSettings
,
1802 IDirectPlayLobbyWImpl_ReceiveLobbyMessage
,
1803 IDirectPlayLobbyWImpl_RunApplication
,
1804 IDirectPlayLobbyWImpl_SendLobbyMessage
,
1805 IDirectPlayLobbyWImpl_SetConnectionSettings
,
1806 IDirectPlayLobbyWImpl_SetLobbyMessageEvent
1810 /* Note: Hack so we can reuse the old functions without compiler warnings */
1811 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1812 # define XCAST(fun) (typeof(directPlayLobby2AVT.fun))
1814 # define XCAST(fun) (void*)
1817 /* Direct Play Lobby 2 (ascii) Virtual Table for methods */
1818 static const IDirectPlayLobby2Vtbl directPlayLobby2AVT
=
1821 XCAST(QueryInterface
)DPL_QueryInterface
,
1822 XCAST(AddRef
)DPL_AddRef
,
1823 XCAST(Release
)DPL_Release
,
1825 XCAST(Connect
)IDirectPlayLobbyAImpl_Connect
,
1826 XCAST(CreateAddress
)IDirectPlayLobbyAImpl_CreateAddress
,
1827 XCAST(EnumAddress
)IDirectPlayLobbyAImpl_EnumAddress
,
1828 XCAST(EnumAddressTypes
)IDirectPlayLobbyAImpl_EnumAddressTypes
,
1829 XCAST(EnumLocalApplications
)IDirectPlayLobbyAImpl_EnumLocalApplications
,
1830 XCAST(GetConnectionSettings
)IDirectPlayLobbyAImpl_GetConnectionSettings
,
1831 XCAST(ReceiveLobbyMessage
)IDirectPlayLobbyAImpl_ReceiveLobbyMessage
,
1832 XCAST(RunApplication
)IDirectPlayLobbyAImpl_RunApplication
,
1833 XCAST(SendLobbyMessage
)IDirectPlayLobbyAImpl_SendLobbyMessage
,
1834 XCAST(SetConnectionSettings
)IDirectPlayLobbyAImpl_SetConnectionSettings
,
1835 XCAST(SetLobbyMessageEvent
)IDirectPlayLobbyAImpl_SetLobbyMessageEvent
,
1837 IDirectPlayLobby2AImpl_CreateCompoundAddress
1841 /* Note: Hack so we can reuse the old functions without compiler warnings */
1842 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1843 # define XCAST(fun) (typeof(directPlayLobby2AVT.fun))
1845 # define XCAST(fun) (void*)
1848 /* Direct Play Lobby 2 (unicode) Virtual Table for methods */
1849 static const IDirectPlayLobby2Vtbl directPlayLobby2WVT
=
1852 XCAST(QueryInterface
)DPL_QueryInterface
,
1853 XCAST(AddRef
)DPL_AddRef
,
1854 XCAST(Release
)DPL_Release
,
1856 XCAST(Connect
)IDirectPlayLobbyWImpl_Connect
,
1857 XCAST(CreateAddress
)IDirectPlayLobbyWImpl_CreateAddress
,
1858 XCAST(EnumAddress
)IDirectPlayLobbyWImpl_EnumAddress
,
1859 XCAST(EnumAddressTypes
)IDirectPlayLobbyWImpl_EnumAddressTypes
,
1860 XCAST(EnumLocalApplications
)IDirectPlayLobbyWImpl_EnumLocalApplications
,
1861 XCAST(GetConnectionSettings
)IDirectPlayLobbyWImpl_GetConnectionSettings
,
1862 XCAST(ReceiveLobbyMessage
)IDirectPlayLobbyWImpl_ReceiveLobbyMessage
,
1863 XCAST(RunApplication
)IDirectPlayLobbyWImpl_RunApplication
,
1864 XCAST(SendLobbyMessage
)IDirectPlayLobbyWImpl_SendLobbyMessage
,
1865 XCAST(SetConnectionSettings
)IDirectPlayLobbyWImpl_SetConnectionSettings
,
1866 XCAST(SetLobbyMessageEvent
)IDirectPlayLobbyWImpl_SetLobbyMessageEvent
,
1868 IDirectPlayLobby2WImpl_CreateCompoundAddress
1872 /* Direct Play Lobby 3 (ascii) Virtual Table for methods */
1874 /* Note: Hack so we can reuse the old functions without compiler warnings */
1875 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1876 # define XCAST(fun) (typeof(directPlayLobby3AVT.fun))
1878 # define XCAST(fun) (void*)
1881 static const IDirectPlayLobby3Vtbl directPlayLobby3AVT
=
1883 XCAST(QueryInterface
)DPL_QueryInterface
,
1884 XCAST(AddRef
)DPL_AddRef
,
1885 XCAST(Release
)DPL_Release
,
1887 XCAST(Connect
)IDirectPlayLobbyAImpl_Connect
,
1888 XCAST(CreateAddress
)IDirectPlayLobbyAImpl_CreateAddress
,
1889 XCAST(EnumAddress
)IDirectPlayLobbyAImpl_EnumAddress
,
1890 XCAST(EnumAddressTypes
)IDirectPlayLobbyAImpl_EnumAddressTypes
,
1891 XCAST(EnumLocalApplications
)IDirectPlayLobbyAImpl_EnumLocalApplications
,
1892 XCAST(GetConnectionSettings
)IDirectPlayLobbyAImpl_GetConnectionSettings
,
1893 XCAST(ReceiveLobbyMessage
)IDirectPlayLobbyAImpl_ReceiveLobbyMessage
,
1894 XCAST(RunApplication
)IDirectPlayLobbyAImpl_RunApplication
,
1895 XCAST(SendLobbyMessage
)IDirectPlayLobbyAImpl_SendLobbyMessage
,
1896 XCAST(SetConnectionSettings
)IDirectPlayLobbyAImpl_SetConnectionSettings
,
1897 XCAST(SetLobbyMessageEvent
)IDirectPlayLobbyAImpl_SetLobbyMessageEvent
,
1899 XCAST(CreateCompoundAddress
)IDirectPlayLobby2AImpl_CreateCompoundAddress
,
1901 IDirectPlayLobby3AImpl_ConnectEx
,
1902 IDirectPlayLobby3AImpl_RegisterApplication
,
1903 IDirectPlayLobby3AImpl_UnregisterApplication
,
1904 IDirectPlayLobby3AImpl_WaitForConnectionSettings
1908 /* Direct Play Lobby 3 (unicode) Virtual Table for methods */
1910 /* Note: Hack so we can reuse the old functions without compiler warnings */
1911 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1912 # define XCAST(fun) (typeof(directPlayLobby3WVT.fun))
1914 # define XCAST(fun) (void*)
1917 static const IDirectPlayLobby3Vtbl directPlayLobby3WVT
=
1919 XCAST(QueryInterface
)DPL_QueryInterface
,
1920 XCAST(AddRef
)DPL_AddRef
,
1921 XCAST(Release
)DPL_Release
,
1923 XCAST(Connect
)IDirectPlayLobbyWImpl_Connect
,
1924 XCAST(CreateAddress
)IDirectPlayLobbyWImpl_CreateAddress
,
1925 XCAST(EnumAddress
)IDirectPlayLobbyWImpl_EnumAddress
,
1926 XCAST(EnumAddressTypes
)IDirectPlayLobbyWImpl_EnumAddressTypes
,
1927 XCAST(EnumLocalApplications
)IDirectPlayLobbyWImpl_EnumLocalApplications
,
1928 XCAST(GetConnectionSettings
)IDirectPlayLobbyWImpl_GetConnectionSettings
,
1929 XCAST(ReceiveLobbyMessage
)IDirectPlayLobbyWImpl_ReceiveLobbyMessage
,
1930 XCAST(RunApplication
)IDirectPlayLobbyWImpl_RunApplication
,
1931 XCAST(SendLobbyMessage
)IDirectPlayLobbyWImpl_SendLobbyMessage
,
1932 XCAST(SetConnectionSettings
)IDirectPlayLobbyWImpl_SetConnectionSettings
,
1933 XCAST(SetLobbyMessageEvent
)IDirectPlayLobbyWImpl_SetLobbyMessageEvent
,
1935 XCAST(CreateCompoundAddress
)IDirectPlayLobby2WImpl_CreateCompoundAddress
,
1937 IDirectPlayLobby3WImpl_ConnectEx
,
1938 IDirectPlayLobby3WImpl_RegisterApplication
,
1939 IDirectPlayLobby3WImpl_UnregisterApplication
,
1940 IDirectPlayLobby3WImpl_WaitForConnectionSettings
1945 /*********************************************************
1947 * Direct Play Lobby Interface Implementation
1949 *********************************************************/
1951 /***************************************************************************
1952 * DirectPlayLobbyCreateA (DPLAYX.4)
1955 HRESULT WINAPI
DirectPlayLobbyCreateA( LPGUID lpGUIDDSP
,
1956 LPDIRECTPLAYLOBBYA
*lplpDPL
,
1961 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08x\n",
1962 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
1964 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
1965 * equal 0. These fields are mostly for future expansion.
1967 if ( lpGUIDDSP
|| lpData
|| dwDataSize
)
1970 return DPERR_INVALIDPARAMS
;
1976 ERR("Bad parameters!\n" );
1977 return CLASS_E_NOAGGREGATION
;
1980 return DPL_CreateInterface( &IID_IDirectPlayLobbyA
, (void**)lplpDPL
);
1983 /***************************************************************************
1984 * DirectPlayLobbyCreateW (DPLAYX.5)
1987 HRESULT WINAPI
DirectPlayLobbyCreateW( LPGUID lpGUIDDSP
,
1988 LPDIRECTPLAYLOBBY
*lplpDPL
,
1993 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08x\n",
1994 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
1996 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
1997 * equal 0. These fields are mostly for future expansion.
1999 if ( lpGUIDDSP
|| lpData
|| dwDataSize
)
2002 ERR("Bad parameters!\n" );
2003 return DPERR_INVALIDPARAMS
;
2009 ERR("Bad parameters!\n" );
2010 return CLASS_E_NOAGGREGATION
;
2013 return DPL_CreateInterface( &IID_IDirectPlayLobby
, (void**)lplpDPL
);