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
23 #define NONAMELESSUNION
30 #include "wine/debug.h"
32 #include "dplayx_global.h"
33 #include "dplayx_messages.h"
34 #include "dplayx_queue.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(dplay
);
39 /* Forward declarations for this module helper methods */
40 HRESULT
DPL_CreateCompoundAddress ( LPCDPCOMPOUNDADDRESSELEMENT lpElements
, DWORD dwElementCount
,
41 LPVOID lpAddress
, LPDWORD lpdwAddressSize
, BOOL bAnsiInterface
)DECLSPEC_HIDDEN
;
43 static HRESULT
DPL_CreateAddress( REFGUID guidSP
, REFGUID guidDataType
, LPCVOID lpData
, DWORD dwDataSize
,
44 LPVOID lpAddress
, LPDWORD lpdwAddressSize
, BOOL bAnsiInterface
);
47 /*****************************************************************************
48 * IDirectPlayLobby {1,2,3} implementation structure
50 * The philosophy behind this extra pointer dereference is that I wanted to
51 * have the same structure for all types of objects without having to do
52 * a lot of casting. I also only wanted to implement an interface in the
53 * object it was "released" with IUnknown interface being implemented in the 1 version.
54 * Of course, with these new interfaces comes the data required to keep the state required
55 * by these interfaces. So, basically, the pointers contain the data associated with
56 * a release. If you use the data associated with release 3 in a release 2 object, you'll
57 * get a run time trap, as that won't have any data.
62 DPQ_ENTRY( DPLMSG
) msgs
; /* Link to next queued message */
64 typedef struct DPLMSG
* LPDPLMSG
;
66 typedef struct IDirectPlayLobbyImpl
68 IDirectPlayLobby IDirectPlayLobby_iface
;
69 IDirectPlayLobbyA IDirectPlayLobbyA_iface
;
70 IDirectPlayLobby2 IDirectPlayLobby2_iface
;
71 IDirectPlayLobby2A IDirectPlayLobby2A_iface
;
72 IDirectPlayLobby3 IDirectPlayLobby3_iface
;
73 IDirectPlayLobby3A IDirectPlayLobby3A_iface
;
74 LONG numIfaces
; /* "in use interfaces" refcount */
75 LONG ref
, refA
, ref2
, ref2A
, ref3
, ref3A
;
76 CRITICAL_SECTION lock
;
79 DPQ_HEAD( DPLMSG
) msgs
; /* List of messages received */
80 } IDirectPlayLobbyImpl
;
82 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobby( IDirectPlayLobby
*iface
)
84 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobby_iface
);
87 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobbyA( IDirectPlayLobbyA
*iface
)
89 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobbyA_iface
);
92 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobby2( IDirectPlayLobby2
*iface
)
94 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobby2_iface
);
97 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobby2A( IDirectPlayLobby2A
*iface
)
99 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobby2A_iface
);
102 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobby3( IDirectPlayLobby3
*iface
)
104 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobby3_iface
);
107 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobby3A( IDirectPlayLobby3A
*iface
)
109 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobby3A_iface
);
112 static void dplobby_destroy(IDirectPlayLobbyImpl
*obj
)
115 FIXME( "Should kill the msg thread\n" );
117 DPQ_DELETEQ( obj
->msgs
, msgs
, LPDPLMSG
, cbDeleteElemFromHeap
);
118 obj
->lock
.DebugInfo
->Spare
[0] = 0;
119 DeleteCriticalSection( &obj
->lock
);
120 HeapFree( GetProcessHeap(), 0, obj
);
123 static HRESULT WINAPI
IDirectPlayLobbyAImpl_QueryInterface( IDirectPlayLobbyA
*iface
, REFIID riid
,
126 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
127 return IDirectPlayLobby_QueryInterface( &This
->IDirectPlayLobby3_iface
, riid
, ppv
);
130 static HRESULT WINAPI
IDirectPlayLobbyImpl_QueryInterface( IDirectPlayLobby
*iface
, REFIID riid
,
133 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
134 return IDirectPlayLobby_QueryInterface( &This
->IDirectPlayLobby3_iface
, riid
, ppv
);
137 static HRESULT WINAPI
IDirectPlayLobby2AImpl_QueryInterface( IDirectPlayLobby2A
*iface
, REFIID riid
,
140 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
141 return IDirectPlayLobby_QueryInterface( &This
->IDirectPlayLobby3_iface
, riid
, ppv
);
144 static HRESULT WINAPI
IDirectPlayLobby2Impl_QueryInterface( IDirectPlayLobby2
*iface
, REFIID riid
,
147 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
148 return IDirectPlayLobby_QueryInterface( &This
->IDirectPlayLobby3_iface
, riid
, ppv
);
151 static HRESULT WINAPI
IDirectPlayLobby3AImpl_QueryInterface( IDirectPlayLobby3A
*iface
, REFIID riid
,
154 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
155 return IDirectPlayLobby_QueryInterface( &This
->IDirectPlayLobby3_iface
, riid
, ppv
);
158 static HRESULT WINAPI
IDirectPlayLobby3Impl_QueryInterface( IDirectPlayLobby3
*iface
, REFIID riid
,
161 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
163 if ( IsEqualGUID( &IID_IUnknown
, riid
) )
165 TRACE( "(%p)->(IID_IUnknown %p)\n", This
, ppv
);
166 *ppv
= &This
->IDirectPlayLobby_iface
;
168 else if ( IsEqualGUID( &IID_IDirectPlayLobby
, riid
) )
170 TRACE( "(%p)->(IID_IDirectPlayLobby %p)\n", This
, ppv
);
171 *ppv
= &This
->IDirectPlayLobby_iface
;
173 else if ( IsEqualGUID( &IID_IDirectPlayLobbyA
, riid
) )
175 TRACE( "(%p)->(IID_IDirectPlayLobbyA %p)\n", This
, ppv
);
176 *ppv
= &This
->IDirectPlayLobbyA_iface
;
178 else if ( IsEqualGUID( &IID_IDirectPlayLobby2
, riid
) )
180 TRACE( "(%p)->(IID_IDirectPlayLobby2 %p)\n", This
, ppv
);
181 *ppv
= &This
->IDirectPlayLobby2_iface
;
183 else if ( IsEqualGUID( &IID_IDirectPlayLobby2A
, riid
) )
185 TRACE( "(%p)->(IID_IDirectPlayLobby2A %p)\n", This
, ppv
);
186 *ppv
= &This
->IDirectPlayLobby2A_iface
;
188 else if ( IsEqualGUID( &IID_IDirectPlayLobby3
, riid
) )
190 TRACE( "(%p)->(IID_IDirectPlay3 %p)\n", This
, ppv
);
191 *ppv
= &This
->IDirectPlayLobby3_iface
;
193 else if ( IsEqualGUID( &IID_IDirectPlayLobby3A
, riid
) )
195 TRACE( "(%p)->(IID_IDirectPlayLobby3A %p)\n", This
, ppv
);
196 *ppv
= &This
->IDirectPlayLobby3A_iface
;
200 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
202 return E_NOINTERFACE
;
205 IUnknown_AddRef((IUnknown
*)*ppv
);
209 static ULONG WINAPI
IDirectPlayLobbyAImpl_AddRef( IDirectPlayLobbyA
*iface
)
211 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
212 ULONG ref
= InterlockedIncrement( &This
->refA
);
214 TRACE( "(%p) refA=%d\n", This
, ref
);
217 InterlockedIncrement( &This
->numIfaces
);
222 static ULONG WINAPI
IDirectPlayLobbyImpl_AddRef( IDirectPlayLobby
*iface
)
224 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
225 ULONG ref
= InterlockedIncrement( &This
->ref
);
227 TRACE( "(%p) ref=%d\n", This
, ref
);
230 InterlockedIncrement( &This
->numIfaces
);
235 static ULONG WINAPI
IDirectPlayLobby2AImpl_AddRef(IDirectPlayLobby2A
*iface
)
237 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
238 ULONG ref
= InterlockedIncrement( &This
->ref2A
);
240 TRACE( "(%p) ref2A=%d\n", This
, ref
);
243 InterlockedIncrement( &This
->numIfaces
);
248 static ULONG WINAPI
IDirectPlayLobby2Impl_AddRef(IDirectPlayLobby2
*iface
)
250 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
251 ULONG ref
= InterlockedIncrement( &This
->ref2
);
253 TRACE( "(%p) ref2=%d\n", This
, ref
);
256 InterlockedIncrement( &This
->numIfaces
);
261 static ULONG WINAPI
IDirectPlayLobby3AImpl_AddRef(IDirectPlayLobby3A
*iface
)
263 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
264 ULONG ref
= InterlockedIncrement( &This
->ref3A
);
266 TRACE( "(%p) ref3A=%d\n", This
, ref
);
269 InterlockedIncrement( &This
->numIfaces
);
274 static ULONG WINAPI
IDirectPlayLobby3Impl_AddRef(IDirectPlayLobby3
*iface
)
276 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
277 ULONG ref
= InterlockedIncrement( &This
->ref3
);
279 TRACE( "(%p) ref3=%d\n", This
, ref
);
282 InterlockedIncrement( &This
->numIfaces
);
287 static ULONG WINAPI
IDirectPlayLobbyAImpl_Release( IDirectPlayLobbyA
*iface
)
289 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
290 ULONG ref
= InterlockedDecrement( &This
->refA
);
292 TRACE( "(%p) refA=%d\n", This
, ref
);
294 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
295 dplobby_destroy( This
);
300 static ULONG WINAPI
IDirectPlayLobbyImpl_Release( IDirectPlayLobby
*iface
)
302 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
303 ULONG ref
= InterlockedDecrement( &This
->ref
);
305 TRACE( "(%p) ref=%d\n", This
, ref
);
307 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
308 dplobby_destroy( This
);
313 static ULONG WINAPI
IDirectPlayLobby2AImpl_Release(IDirectPlayLobby2A
*iface
)
315 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
316 ULONG ref
= InterlockedDecrement( &This
->ref2A
);
318 TRACE( "(%p) ref2A=%d\n", This
, ref
);
320 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
321 dplobby_destroy( This
);
326 static ULONG WINAPI
IDirectPlayLobby2Impl_Release(IDirectPlayLobby2
*iface
)
328 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
329 ULONG ref
= InterlockedDecrement( &This
->ref2
);
331 TRACE( "(%p) ref2=%d\n", This
, ref
);
333 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
334 dplobby_destroy( This
);
339 static ULONG WINAPI
IDirectPlayLobby3AImpl_Release(IDirectPlayLobby3A
*iface
)
341 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
342 ULONG ref
= InterlockedDecrement( &This
->ref3A
);
344 TRACE( "(%p) ref3A=%d\n", This
, ref
);
346 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
347 dplobby_destroy( This
);
352 static ULONG WINAPI
IDirectPlayLobby3Impl_Release(IDirectPlayLobby3
*iface
)
354 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
355 ULONG ref
= InterlockedDecrement( &This
->ref3
);
357 TRACE( "(%p) ref3=%d\n", This
, ref
);
359 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
360 dplobby_destroy( This
);
366 /********************************************************************
368 * Connects an application to the session specified by the DPLCONNECTION
369 * structure currently stored with the DirectPlayLobby object.
371 * Returns an IDirectPlay interface.
374 static HRESULT
DPL_ConnectEx( IDirectPlayLobbyImpl
*This
, DWORD dwFlags
, REFIID riid
, void **lplpDP
,
378 DWORD dwOpenFlags
= 0;
379 DWORD dwConnSize
= 0;
380 LPDPLCONNECTION lpConn
;
382 FIXME("(%p)->(0x%08x,%p,%p): semi stub\n", This
, dwFlags
, lplpDP
, pUnk
);
386 return DPERR_INVALIDPARAMS
;
389 /* Backwards compatibility */
392 dwFlags
= DPCONNECT_RETURNSTATUS
;
395 if ( ( hr
= dplay_create( riid
, lplpDP
) ) != DP_OK
)
397 ERR( "error creating interface for %s:%s.\n",
398 debugstr_guid( riid
), DPLAYX_HresultToString( hr
) );
402 /* FIXME: Is it safe/correct to use appID of 0? */
403 hr
= IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3_iface
,
404 0, NULL
, &dwConnSize
);
405 if( hr
!= DPERR_BUFFERTOOSMALL
)
410 lpConn
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, dwConnSize
);
414 return DPERR_NOMEMORY
;
417 /* FIXME: Is it safe/correct to use appID of 0? */
418 hr
= IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3_iface
,
419 0, lpConn
, &dwConnSize
);
422 HeapFree( GetProcessHeap(), 0, lpConn
);
427 /* - Need to call IDirectPlay::EnumConnections with the service provider to get that good information
428 * - Need to call CreateAddress to create the lpConnection param for IDirectPlay::InitializeConnection
429 * - Call IDirectPlay::InitializeConnection
432 /* Now initialize the Service Provider */
433 hr
= IDirectPlayX_InitializeConnection( (*(LPDIRECTPLAY2
*)lplpDP
),
437 /* Setup flags to pass into DirectPlay::Open */
438 if( dwFlags
& DPCONNECT_RETURNSTATUS
)
440 dwOpenFlags
|= DPOPEN_RETURNSTATUS
;
442 dwOpenFlags
|= lpConn
->dwFlags
;
444 hr
= IDirectPlayX_Open( (*(LPDIRECTPLAY2
*)lplpDP
), lpConn
->lpSessionDesc
,
447 HeapFree( GetProcessHeap(), 0, lpConn
);
452 static HRESULT WINAPI
IDirectPlayLobbyAImpl_Connect( IDirectPlayLobbyA
*iface
, DWORD flags
,
453 IDirectPlay2A
**dp
, IUnknown
*unk
)
455 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
456 return IDirectPlayLobby_Connect( &This
->IDirectPlayLobby3A_iface
, flags
, dp
, unk
);
459 static HRESULT WINAPI
IDirectPlayLobbyImpl_Connect( IDirectPlayLobby
*iface
, DWORD flags
,
460 IDirectPlay2A
**dp
, IUnknown
*unk
)
462 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
463 return IDirectPlayLobby_Connect( &This
->IDirectPlayLobby3_iface
, flags
, dp
, unk
);
466 static HRESULT WINAPI
IDirectPlayLobby2AImpl_Connect( IDirectPlayLobby2A
*iface
, DWORD flags
,
467 IDirectPlay2A
**dp
, IUnknown
*unk
)
469 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
470 return IDirectPlayLobby_Connect( &This
->IDirectPlayLobby3A_iface
, flags
, dp
, unk
);
473 static HRESULT WINAPI
IDirectPlayLobby2Impl_Connect( IDirectPlayLobby2
*iface
, DWORD flags
,
474 IDirectPlay2A
**dp
, IUnknown
*unk
)
476 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
477 return IDirectPlayLobby_Connect( &This
->IDirectPlayLobby3_iface
, flags
, dp
, unk
);
480 static HRESULT WINAPI
IDirectPlayLobby3AImpl_Connect( IDirectPlayLobby3A
*iface
, DWORD flags
,
481 IDirectPlay2A
**dp
, IUnknown
*unk
)
483 return IDirectPlayLobby_ConnectEx( iface
, flags
, &IID_IDirectPlay2A
, (void**)dp
, unk
);
486 static HRESULT WINAPI
IDirectPlayLobby3Impl_Connect( IDirectPlayLobby3
*iface
, DWORD flags
,
487 IDirectPlay2
**dp
, IUnknown
*unk
)
489 return IDirectPlayLobby_ConnectEx( iface
, flags
, &IID_IDirectPlay2A
, (void**)dp
, unk
);
492 /********************************************************************
494 * Creates a DirectPlay Address, given a service provider-specific network
496 * Returns an address contains the globally unique identifier
497 * (GUID) of the service provider and data that the service provider can
498 * interpret as a network address.
500 * NOTE: It appears that this method is supposed to be really really stupid
501 * with no error checking on the contents.
503 static HRESULT WINAPI
IDirectPlayLobbyAImpl_CreateAddress( IDirectPlayLobbyA
*iface
, REFGUID sp
,
504 REFGUID datatype
, const void *data
, DWORD datasize
, void *address
, DWORD
*addrsize
)
506 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
507 return IDirectPlayLobby_CreateAddress( &This
->IDirectPlayLobby3A_iface
, sp
, datatype
, data
,
508 datasize
, address
, addrsize
);
511 static HRESULT WINAPI
IDirectPlayLobbyImpl_CreateAddress( IDirectPlayLobby
*iface
, REFGUID sp
,
512 REFGUID datatype
, const void *data
, DWORD datasize
, void *address
, DWORD
*addrsize
)
514 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
515 return IDirectPlayLobby_CreateAddress( &This
->IDirectPlayLobby3_iface
, sp
, datatype
, data
,
516 datasize
, address
, addrsize
);
519 static HRESULT WINAPI
IDirectPlayLobby2AImpl_CreateAddress( IDirectPlayLobby2A
*iface
, REFGUID sp
,
520 REFGUID datatype
, const void *data
, DWORD datasize
, void *address
, DWORD
*addrsize
)
522 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
523 return IDirectPlayLobby_CreateAddress( &This
->IDirectPlayLobby3A_iface
, sp
, datatype
, data
,
524 datasize
, address
, addrsize
);
527 static HRESULT WINAPI
IDirectPlayLobby2Impl_CreateAddress( IDirectPlayLobby2
*iface
, REFGUID sp
,
528 REFGUID datatype
, const void *data
, DWORD datasize
, void *address
, DWORD
*addrsize
)
530 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
531 return IDirectPlayLobby_CreateAddress( &This
->IDirectPlayLobby3_iface
, sp
, datatype
, data
,
532 datasize
, address
, addrsize
);
535 static HRESULT WINAPI
IDirectPlayLobby3AImpl_CreateAddress( IDirectPlayLobby3A
*iface
,
536 REFGUID guidSP
, REFGUID guidDataType
, const void *lpData
, DWORD dwDataSize
, void *lpAddress
,
537 DWORD
*lpdwAddressSize
)
539 return DPL_CreateAddress( guidSP
, guidDataType
, lpData
, dwDataSize
,
540 lpAddress
, lpdwAddressSize
, TRUE
);
543 static HRESULT WINAPI
IDirectPlayLobby3Impl_CreateAddress( IDirectPlayLobby3
*iface
, REFGUID guidSP
,
544 REFGUID guidDataType
, const void *lpData
, DWORD dwDataSize
, void *lpAddress
,
545 DWORD
*lpdwAddressSize
)
547 return DPL_CreateAddress( guidSP
, guidDataType
, lpData
, dwDataSize
,
548 lpAddress
, lpdwAddressSize
, FALSE
);
551 static HRESULT
DPL_CreateAddress(
553 REFGUID guidDataType
,
557 LPDWORD lpdwAddressSize
,
558 BOOL bAnsiInterface
)
560 const DWORD dwNumAddElements
= 2; /* Service Provide & address data type */
561 DPCOMPOUNDADDRESSELEMENT addressElements
[ 2 /* dwNumAddElements */ ];
563 TRACE( "(%p)->(%p,%p,0x%08x,%p,%p,%d)\n", guidSP
, guidDataType
, lpData
, dwDataSize
,
564 lpAddress
, lpdwAddressSize
, bAnsiInterface
);
566 addressElements
[ 0 ].guidDataType
= DPAID_ServiceProvider
;
567 addressElements
[ 0 ].dwDataSize
= sizeof( GUID
);
568 addressElements
[ 0 ].lpData
= (LPVOID
)guidSP
;
570 addressElements
[ 1 ].guidDataType
= *guidDataType
;
571 addressElements
[ 1 ].dwDataSize
= dwDataSize
;
572 addressElements
[ 1 ].lpData
= (LPVOID
)lpData
;
574 /* Call CreateCompoundAddress to cut down on code.
575 NOTE: We can do this because we don't support DPL 1 interfaces! */
576 return DPL_CreateCompoundAddress( addressElements
, dwNumAddElements
,
577 lpAddress
, lpdwAddressSize
, bAnsiInterface
);
582 /********************************************************************
584 * Parses out chunks from the DirectPlay Address buffer by calling the
585 * given callback function, with lpContext, for each of the chunks.
588 static HRESULT WINAPI
IDirectPlayLobbyAImpl_EnumAddress( IDirectPlayLobbyA
*iface
,
589 LPDPENUMADDRESSCALLBACK enumaddrcb
, const void *address
, DWORD size
, void *context
)
591 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
592 return IDirectPlayLobby_EnumAddress( &This
->IDirectPlayLobby3A_iface
, enumaddrcb
, address
, size
,
596 static HRESULT WINAPI
IDirectPlayLobbyImpl_EnumAddress( IDirectPlayLobby
*iface
,
597 LPDPENUMADDRESSCALLBACK enumaddrcb
, const void *address
, DWORD size
, void *context
)
599 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
600 return IDirectPlayLobby_EnumAddress( &This
->IDirectPlayLobby3_iface
, enumaddrcb
, address
, size
,
604 static HRESULT WINAPI
IDirectPlayLobby2AImpl_EnumAddress( IDirectPlayLobby2A
*iface
,
605 LPDPENUMADDRESSCALLBACK enumaddrcb
, const void *address
, DWORD size
, void *context
)
607 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
608 return IDirectPlayLobby_EnumAddress( &This
->IDirectPlayLobby3A_iface
, enumaddrcb
, address
, size
,
612 static HRESULT WINAPI
IDirectPlayLobby2Impl_EnumAddress( IDirectPlayLobby2
*iface
,
613 LPDPENUMADDRESSCALLBACK enumaddrcb
, const void *address
, DWORD size
, void *context
)
615 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
616 return IDirectPlayLobby_EnumAddress( &This
->IDirectPlayLobby3_iface
, enumaddrcb
, address
, size
,
620 static HRESULT WINAPI
IDirectPlayLobby3AImpl_EnumAddress( IDirectPlayLobby3A
*iface
,
621 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
, const void *lpAddress
, DWORD dwAddressSize
,
624 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
626 TRACE("(%p)->(%p,%p,0x%08x,%p)\n", This
, lpEnumAddressCallback
, lpAddress
,
627 dwAddressSize
, lpContext
);
629 return DPL_EnumAddress( lpEnumAddressCallback
, lpAddress
, dwAddressSize
, lpContext
);
632 static HRESULT WINAPI
IDirectPlayLobby3Impl_EnumAddress( IDirectPlayLobby3
*iface
,
633 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
, const void *lpAddress
, DWORD dwAddressSize
,
636 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
638 TRACE("(%p)->(%p,%p,0x%08x,%p)\n", This
, lpEnumAddressCallback
, lpAddress
,
639 dwAddressSize
, lpContext
);
641 return DPL_EnumAddress( lpEnumAddressCallback
, lpAddress
, dwAddressSize
, lpContext
);
644 HRESULT
DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
, LPCVOID lpAddress
,
645 DWORD dwAddressSize
, LPVOID lpContext
)
647 DWORD dwTotalSizeEnumerated
= 0;
649 /* FIXME: First chunk is always the total size chunk - Should we report it? */
651 while ( dwTotalSizeEnumerated
< dwAddressSize
)
653 const DPADDRESS
* lpElements
= lpAddress
;
654 DWORD dwSizeThisEnumeration
;
656 /* Invoke the enum method. If false is returned, stop enumeration */
657 if ( !lpEnumAddressCallback( &lpElements
->guidDataType
,
658 lpElements
->dwDataSize
,
659 (const BYTE
*)lpElements
+ sizeof( DPADDRESS
),
665 dwSizeThisEnumeration
= sizeof( DPADDRESS
) + lpElements
->dwDataSize
;
666 lpAddress
= (const BYTE
*) lpAddress
+ dwSizeThisEnumeration
;
667 dwTotalSizeEnumerated
+= dwSizeThisEnumeration
;
673 /********************************************************************
675 * Enumerates all the address types that a given service provider needs to
676 * build the DirectPlay Address.
679 static HRESULT WINAPI
IDirectPlayLobbyAImpl_EnumAddressTypes( IDirectPlayLobbyA
*iface
,
680 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
682 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
683 return IDirectPlayLobby_EnumAddressTypes( &This
->IDirectPlayLobby3A_iface
, enumaddrtypecb
, sp
,
687 static HRESULT WINAPI
IDirectPlayLobbyImpl_EnumAddressTypes( IDirectPlayLobby
*iface
,
688 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
690 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
691 return IDirectPlayLobby_EnumAddressTypes( &This
->IDirectPlayLobby3_iface
, enumaddrtypecb
, sp
,
695 static HRESULT WINAPI
IDirectPlayLobby2AImpl_EnumAddressTypes( IDirectPlayLobby2A
*iface
,
696 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
698 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
699 return IDirectPlayLobby_EnumAddressTypes( &This
->IDirectPlayLobby3A_iface
, enumaddrtypecb
, sp
,
703 static HRESULT WINAPI
IDirectPlayLobby2Impl_EnumAddressTypes( IDirectPlayLobby2
*iface
,
704 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
706 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
707 return IDirectPlayLobby_EnumAddressTypes( &This
->IDirectPlayLobby3_iface
, enumaddrtypecb
, sp
,
711 static HRESULT WINAPI
IDirectPlayLobby3AImpl_EnumAddressTypes( IDirectPlayLobby3A
*iface
,
712 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
, REFGUID guidSP
, void *lpContext
,
715 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
718 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
719 DWORD dwIndex
, sizeOfSubKeyName
=50;
723 TRACE(" (%p)->(%p,%p,%p,0x%08x)\n", This
, lpEnumAddressTypeCallback
, guidSP
, lpContext
, dwFlags
);
727 return DPERR_INVALIDPARAMS
;
730 if( !lpEnumAddressTypeCallback
)
732 return DPERR_INVALIDPARAMS
;
737 return DPERR_INVALIDOBJECT
;
740 /* Need to loop over the service providers in the registry */
741 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
742 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
744 /* Hmmm. Does this mean that there are no service providers? */
745 ERR(": no service providers?\n");
749 /* Traverse all the service providers we have available */
751 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
,
752 NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
753 ++dwIndex
, sizeOfSubKeyName
=50 )
756 HKEY hkServiceProvider
, hkServiceProviderAt
;
757 GUID serviceProviderGUID
;
758 DWORD returnTypeGUID
, sizeOfReturnBuffer
= 50;
760 char returnBuffer
[51];
763 LPCSTR atKey
= "Address Types";
764 LPCSTR 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
, (LPBYTE
)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( 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( 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
IDirectPlayLobby3Impl_EnumAddressTypes( IDirectPlayLobby3
*iface
,
833 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
836 return DPERR_OUTOFMEMORY
;
839 /********************************************************************
841 * Enumerates what applications are registered with DirectPlay by
842 * invoking the callback function with lpContext.
845 static HRESULT WINAPI
IDirectPlayLobby3Impl_EnumLocalApplications( IDirectPlayLobby3
*iface
,
846 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback
, void *lpContext
, DWORD dwFlags
)
848 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
850 FIXME("(%p)->(%p,%p,0x%08x):stub\n", This
, lpEnumLocalAppCallback
, lpContext
, dwFlags
);
852 return DPERR_OUTOFMEMORY
;
855 static HRESULT WINAPI
IDirectPlayLobbyAImpl_EnumLocalApplications( IDirectPlayLobbyA
*iface
,
856 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
858 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
859 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3A_iface
, enumlocalappcb
,
863 static HRESULT WINAPI
IDirectPlayLobbyImpl_EnumLocalApplications( IDirectPlayLobby
*iface
,
864 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
866 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
867 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3_iface
, enumlocalappcb
,
871 static HRESULT WINAPI
IDirectPlayLobby2AImpl_EnumLocalApplications( IDirectPlayLobby2A
*iface
,
872 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
874 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
875 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3A_iface
, enumlocalappcb
,
879 static HRESULT WINAPI
IDirectPlayLobby2Impl_EnumLocalApplications( IDirectPlayLobby2
*iface
,
880 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
882 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
883 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3_iface
, enumlocalappcb
,
887 static HRESULT WINAPI
IDirectPlayLobby3AImpl_EnumLocalApplications( IDirectPlayLobby3A
*iface
,
888 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback
, void *lpContext
, DWORD dwFlags
)
890 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
893 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Applications";
894 LPCSTR guidDataSubKey
= "Guid";
895 DWORD dwIndex
, sizeOfSubKeyName
=50;
899 TRACE("(%p)->(%p,%p,0x%08x)\n", This
, lpEnumLocalAppCallback
, lpContext
, dwFlags
);
903 return DPERR_INVALIDPARAMS
;
906 if( !lpEnumLocalAppCallback
)
908 return DPERR_INVALIDPARAMS
;
911 /* Need to loop over the service providers in the registry */
912 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
913 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
915 /* Hmmm. Does this mean that there are no service providers? */
916 ERR(": no service providers?\n");
920 /* Traverse all registered applications */
922 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
, NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
923 ++dwIndex
, sizeOfSubKeyName
=50 )
926 HKEY hkServiceProvider
;
927 GUID serviceProviderGUID
;
928 DWORD returnTypeGUID
, sizeOfReturnBuffer
= 50;
929 char returnBuffer
[51];
931 DPLAPPINFO dplAppInfo
;
933 TRACE(" this time through: %s\n", subKeyName
);
935 /* Get a handle for this particular service provider */
936 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
937 &hkServiceProvider
) != ERROR_SUCCESS
)
939 ERR(": what the heck is going on?\n" );
943 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
944 NULL
, &returnTypeGUID
, (LPBYTE
)returnBuffer
,
945 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
947 ERR(": missing GUID registry data members\n" );
951 /* FIXME: Check return types to ensure we're interpreting data right */
952 MultiByteToWideChar( CP_ACP
, 0, returnBuffer
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
953 CLSIDFromString( buff
, &serviceProviderGUID
);
954 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
956 dplAppInfo
.dwSize
= sizeof( dplAppInfo
);
957 dplAppInfo
.guidApplication
= serviceProviderGUID
;
958 dplAppInfo
.u
.lpszAppNameA
= subKeyName
;
960 EnterCriticalSection( &This
->lock
);
962 memcpy( &This
->cbkeyhack
, &hkServiceProvider
, sizeof( hkServiceProvider
) );
964 if( !lpEnumLocalAppCallback( &dplAppInfo
, lpContext
, dwFlags
) )
966 LeaveCriticalSection( &This
->lock
);
970 LeaveCriticalSection( &This
->lock
);
976 /********************************************************************
978 * Retrieves the DPLCONNECTION structure that contains all the information
979 * needed to start and connect an application. This was generated using
980 * either the RunApplication or SetConnectionSettings methods.
982 * NOTES: If lpData is NULL then just return lpdwDataSize. This allows
983 * the data structure to be allocated by our caller which can then
984 * call this procedure/method again with a valid data pointer.
986 static HRESULT WINAPI
IDirectPlayLobbyAImpl_GetConnectionSettings( IDirectPlayLobbyA
*iface
,
987 DWORD appid
, void *data
, DWORD
*size
)
989 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
990 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, appid
, data
,
994 static HRESULT WINAPI
IDirectPlayLobbyImpl_GetConnectionSettings( IDirectPlayLobby
*iface
,
995 DWORD appid
, void *data
, DWORD
*size
)
997 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
998 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3_iface
, appid
, data
,
1002 static HRESULT WINAPI
IDirectPlayLobby2AImpl_GetConnectionSettings( IDirectPlayLobby2A
*iface
,
1003 DWORD appid
, void *data
, DWORD
*size
)
1005 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1006 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, appid
, data
,
1010 static HRESULT WINAPI
IDirectPlayLobby2Impl_GetConnectionSettings( IDirectPlayLobby2
*iface
,
1011 DWORD appid
, void *data
, DWORD
*size
)
1013 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1014 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3_iface
, appid
, data
,
1018 static HRESULT WINAPI
IDirectPlayLobby3AImpl_GetConnectionSettings( IDirectPlayLobby3A
*iface
,
1019 DWORD dwAppID
, void *lpData
, DWORD
*lpdwDataSize
)
1021 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1024 TRACE("(%p)->(0x%08x,%p,%p)\n", This
, dwAppID
, lpData
, lpdwDataSize
);
1026 EnterCriticalSection( &This
->lock
);
1028 hr
= DPLAYX_GetConnectionSettingsA( dwAppID
,
1033 LeaveCriticalSection( &This
->lock
);
1038 static HRESULT WINAPI
IDirectPlayLobby3Impl_GetConnectionSettings( IDirectPlayLobby3
*iface
,
1039 DWORD dwAppID
, void *lpData
, DWORD
*lpdwDataSize
)
1041 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1044 TRACE("(%p)->(0x%08x,%p,%p)\n", This
, dwAppID
, lpData
, lpdwDataSize
);
1046 EnterCriticalSection( &This
->lock
);
1048 hr
= DPLAYX_GetConnectionSettingsW( dwAppID
,
1053 LeaveCriticalSection( &This
->lock
);
1058 /********************************************************************
1060 * Retrieves the message sent between a lobby client and a DirectPlay
1061 * application. All messages are queued until received.
1064 static HRESULT WINAPI
IDirectPlayLobbyAImpl_ReceiveLobbyMessage( IDirectPlayLobbyA
*iface
,
1065 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1067 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1068 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1069 msgflags
, data
, size
);
1072 static HRESULT WINAPI
IDirectPlayLobbyImpl_ReceiveLobbyMessage( IDirectPlayLobby
*iface
,
1073 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1075 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1076 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1077 msgflags
, data
, size
);
1080 static HRESULT WINAPI
IDirectPlayLobby2AImpl_ReceiveLobbyMessage( IDirectPlayLobby2A
*iface
,
1081 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1083 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1084 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1085 msgflags
, data
, size
);
1088 static HRESULT WINAPI
IDirectPlayLobby2Impl_ReceiveLobbyMessage( IDirectPlayLobby2
*iface
,
1089 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1091 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1092 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1093 msgflags
, data
, size
);
1096 static HRESULT WINAPI
IDirectPlayLobby3AImpl_ReceiveLobbyMessage( IDirectPlayLobby3A
*iface
,
1097 DWORD dwFlags
, DWORD dwAppID
, DWORD
*lpdwMessageFlags
, void *lpData
,
1098 DWORD
*lpdwDataSize
)
1100 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1101 FIXME(":stub %p %08x %08x %p %p %p\n", This
, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
1103 return DPERR_OUTOFMEMORY
;
1106 static HRESULT WINAPI
IDirectPlayLobby3Impl_ReceiveLobbyMessage( IDirectPlayLobby3
*iface
,
1107 DWORD dwFlags
, DWORD dwAppID
, DWORD
*lpdwMessageFlags
, void *lpData
,
1108 DWORD
*lpdwDataSize
)
1110 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1111 FIXME(":stub %p %08x %08x %p %p %p\n", This
, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
1113 return DPERR_OUTOFMEMORY
;
1116 typedef struct tagRunApplicationEnumStruct
1118 IDirectPlayLobbyImpl
*This
;
1123 LPSTR lpszCommandLine
;
1124 LPSTR lpszCurrentDirectory
;
1125 } RunApplicationEnumStruct
, *lpRunApplicationEnumStruct
;
1127 /* To be called by RunApplication to find how to invoke the function */
1128 static BOOL CALLBACK RunApplicationA_EnumLocalApplications
1129 ( LPCDPLAPPINFO lpAppInfo
,
1133 lpRunApplicationEnumStruct lpData
= (lpRunApplicationEnumStruct
)lpContext
;
1135 if( IsEqualGUID( &lpAppInfo
->guidApplication
, &lpData
->appGUID
) )
1137 char returnBuffer
[200];
1138 DWORD returnType
, sizeOfReturnBuffer
;
1139 LPCSTR clSubKey
= "CommandLine";
1140 LPCSTR cdSubKey
= "CurrentDirectory";
1141 LPCSTR fileSubKey
= "File";
1142 LPCSTR pathSubKey
= "Path";
1144 /* FIXME: Lazy man hack - dplay struct has the present reg key saved */
1146 sizeOfReturnBuffer
= 200;
1148 /* Get all the appropriate data from the registry */
1149 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, clSubKey
,
1150 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1151 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1153 ERR( ": missing CommandLine registry data member\n" );
1157 if ((lpData
->lpszCommandLine
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1158 strcpy( lpData
->lpszCommandLine
, returnBuffer
);
1161 sizeOfReturnBuffer
= 200;
1163 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, cdSubKey
,
1164 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1165 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1167 ERR( ": missing CurrentDirectory registry data member\n" );
1171 if ((lpData
->lpszCurrentDirectory
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1172 strcpy( lpData
->lpszCurrentDirectory
, returnBuffer
);
1175 sizeOfReturnBuffer
= 200;
1177 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, fileSubKey
,
1178 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1179 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1181 ERR( ": missing File registry data member\n" );
1185 if ((lpData
->lpszFileName
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1186 strcpy( lpData
->lpszFileName
, returnBuffer
);
1189 sizeOfReturnBuffer
= 200;
1191 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, pathSubKey
,
1192 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1193 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1195 ERR( ": missing Path registry data member\n" );
1199 if ((lpData
->lpszPath
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1200 strcpy( lpData
->lpszPath
, returnBuffer
);
1203 return FALSE
; /* No need to keep going as we found what we wanted */
1206 return TRUE
; /* Keep enumerating, haven't found the application yet */
1209 static BOOL
DPL_CreateAndSetLobbyHandles( DWORD dwDestProcessId
, HANDLE hDestProcess
,
1210 LPHANDLE lphStart
, LPHANDLE lphDeath
,
1213 /* These are the handles for the created process */
1214 HANDLE hAppStart
= 0, hAppDeath
= 0, hAppRead
= 0;
1215 SECURITY_ATTRIBUTES s_attrib
;
1217 s_attrib
.nLength
= sizeof( s_attrib
);
1218 s_attrib
.lpSecurityDescriptor
= NULL
;
1219 s_attrib
.bInheritHandle
= TRUE
;
1221 *lphStart
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1222 *lphDeath
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1223 *lphRead
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1225 if( ( !DuplicateHandle( GetCurrentProcess(), *lphStart
,
1226 hDestProcess
, &hAppStart
,
1227 0, FALSE
, DUPLICATE_SAME_ACCESS
) ) ||
1228 ( !DuplicateHandle( GetCurrentProcess(), *lphDeath
,
1229 hDestProcess
, &hAppDeath
,
1230 0, FALSE
, DUPLICATE_SAME_ACCESS
) ) ||
1231 ( !DuplicateHandle( GetCurrentProcess(), *lphRead
,
1232 hDestProcess
, &hAppRead
,
1233 0, FALSE
, DUPLICATE_SAME_ACCESS
) )
1236 if (*lphStart
) { CloseHandle(*lphStart
); *lphStart
= 0; }
1237 if (*lphDeath
) { CloseHandle(*lphDeath
); *lphDeath
= 0; }
1238 if (*lphRead
) { CloseHandle(*lphRead
); *lphRead
= 0; }
1239 /* FIXME: Handle leak... */
1240 ERR( "Unable to dup handles\n" );
1244 if( !DPLAYX_SetLobbyHandles( dwDestProcessId
,
1245 hAppStart
, hAppDeath
, hAppRead
) )
1247 /* FIXME: Handle leak... */
1255 /********************************************************************
1257 * Starts an application and passes to it all the information to
1258 * connect to a session.
1261 static HRESULT WINAPI
IDirectPlayLobbyAImpl_RunApplication( IDirectPlayLobbyA
*iface
, DWORD flags
,
1262 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1264 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1265 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, conn
,
1269 static HRESULT WINAPI
IDirectPlayLobbyImpl_RunApplication( IDirectPlayLobby
*iface
, DWORD flags
,
1270 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1272 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1273 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3_iface
, flags
, appid
, conn
,
1277 static HRESULT WINAPI
IDirectPlayLobby2AImpl_RunApplication( IDirectPlayLobby2A
*iface
, DWORD flags
,
1278 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1280 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1281 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, conn
,
1285 static HRESULT WINAPI
IDirectPlayLobby2Impl_RunApplication( IDirectPlayLobby2
*iface
, DWORD flags
,
1286 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1288 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1289 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3_iface
, flags
, appid
, conn
,
1293 static HRESULT WINAPI
IDirectPlayLobby3AImpl_RunApplication( IDirectPlayLobby3A
*iface
,
1294 DWORD dwFlags
, DWORD
*lpdwAppID
, DPLCONNECTION
*lpConn
, HANDLE hReceiveEvent
)
1296 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1298 RunApplicationEnumStruct enumData
;
1300 STARTUPINFOA startupInfo
;
1301 PROCESS_INFORMATION newProcessInfo
;
1303 DWORD dwSuspendCount
;
1304 HANDLE hStart
, hDeath
, hSettingRead
;
1306 TRACE( "(%p)->(0x%08x,%p,%p,%p)\n",
1307 This
, dwFlags
, lpdwAppID
, lpConn
, hReceiveEvent
);
1311 return DPERR_INVALIDPARAMS
;
1314 if( DPLAYX_AnyLobbiesWaitingForConnSettings() )
1316 FIXME( "Waiting lobby not being handled correctly\n" );
1319 EnterCriticalSection( &This
->lock
);
1321 ZeroMemory( &enumData
, sizeof( enumData
) );
1322 enumData
.This
= This
;
1323 enumData
.appGUID
= lpConn
->lpSessionDesc
->guidApplication
;
1325 /* Our callback function will fill up the enumData structure with all the information
1326 required to start a new process */
1327 IDirectPlayLobby_EnumLocalApplications( iface
, RunApplicationA_EnumLocalApplications
,
1330 /* First the application name */
1331 strcpy( temp
, enumData
.lpszPath
);
1332 strcat( temp
, "\\" );
1333 strcat( temp
, enumData
.lpszFileName
);
1334 HeapFree( GetProcessHeap(), 0, enumData
.lpszPath
);
1335 HeapFree( GetProcessHeap(), 0, enumData
.lpszFileName
);
1336 if ((appName
= HeapAlloc( GetProcessHeap(), 0, strlen(temp
)+1 ))) strcpy( appName
, temp
);
1338 /* Now the command line */
1339 strcat( temp
, " " );
1340 strcat( temp
, enumData
.lpszCommandLine
);
1341 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1342 if ((enumData
.lpszCommandLine
= HeapAlloc( GetProcessHeap(), 0, strlen(temp
)+1 )))
1343 strcpy( enumData
.lpszCommandLine
, temp
);
1345 ZeroMemory( &startupInfo
, sizeof( startupInfo
) );
1346 startupInfo
.cb
= sizeof( startupInfo
);
1347 /* FIXME: Should any fields be filled in? */
1349 ZeroMemory( &newProcessInfo
, sizeof( newProcessInfo
) );
1351 if( !CreateProcessA( appName
,
1352 enumData
.lpszCommandLine
,
1356 CREATE_DEFAULT_ERROR_MODE
| CREATE_NEW_CONSOLE
| CREATE_SUSPENDED
, /* Creation Flags */
1358 enumData
.lpszCurrentDirectory
,
1364 ERR( "Failed to create process for app %s\n", appName
);
1366 HeapFree( GetProcessHeap(), 0, appName
);
1367 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1368 HeapFree( GetProcessHeap(), 0, enumData
.lpszCurrentDirectory
);
1370 LeaveCriticalSection( &This
->lock
);
1371 return DPERR_CANTCREATEPROCESS
;
1374 HeapFree( GetProcessHeap(), 0, appName
);
1375 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1376 HeapFree( GetProcessHeap(), 0, enumData
.lpszCurrentDirectory
);
1378 /* Reserve this global application id! */
1379 if( !DPLAYX_CreateLobbyApplication( newProcessInfo
.dwProcessId
) )
1381 ERR( "Unable to create global application data for 0x%08x\n",
1382 newProcessInfo
.dwProcessId
);
1385 hr
= IDirectPlayLobby_SetConnectionSettings( iface
, 0, newProcessInfo
.dwProcessId
, lpConn
);
1389 ERR( "SetConnectionSettings failure %s\n", DPLAYX_HresultToString( hr
) );
1390 LeaveCriticalSection( &This
->lock
);
1394 /* Setup the handles for application notification */
1395 DPL_CreateAndSetLobbyHandles( newProcessInfo
.dwProcessId
,
1396 newProcessInfo
.hProcess
,
1397 &hStart
, &hDeath
, &hSettingRead
);
1399 /* Setup the message thread ID */
1400 This
->msgtid
= CreateLobbyMessageReceptionThread( hReceiveEvent
, hStart
, hDeath
, hSettingRead
);
1402 DPLAYX_SetLobbyMsgThreadId( newProcessInfo
.dwProcessId
, This
->msgtid
);
1404 LeaveCriticalSection( &This
->lock
);
1406 /* Everything seems to have been set correctly, update the dwAppID */
1407 *lpdwAppID
= newProcessInfo
.dwProcessId
;
1409 /* Unsuspend the process - should return the prev suspension count */
1410 if( ( dwSuspendCount
= ResumeThread( newProcessInfo
.hThread
) ) != 1 )
1412 ERR( "ResumeThread failed with 0x%08x\n", dwSuspendCount
);
1418 static HRESULT WINAPI
IDirectPlayLobby3Impl_RunApplication( IDirectPlayLobby3
*iface
, DWORD dwFlags
,
1419 DWORD
*lpdwAppID
, DPLCONNECTION
*lpConn
, HANDLE hReceiveEvent
)
1421 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1422 FIXME( "(%p)->(0x%08x,%p,%p,%p):stub\n", This
, dwFlags
, lpdwAppID
, lpConn
, hReceiveEvent
);
1423 return DPERR_OUTOFMEMORY
;
1426 /********************************************************************
1428 * Sends a message between the application and the lobby client.
1429 * All messages are queued until received.
1432 static HRESULT WINAPI
IDirectPlayLobbyAImpl_SendLobbyMessage( IDirectPlayLobbyA
*iface
, DWORD flags
,
1433 DWORD appid
, void *data
, DWORD size
)
1435 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1436 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, data
,
1440 static HRESULT WINAPI
IDirectPlayLobbyImpl_SendLobbyMessage( IDirectPlayLobby
*iface
, DWORD flags
,
1441 DWORD appid
, void *data
, DWORD size
)
1443 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1444 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
, data
,
1448 static HRESULT WINAPI
IDirectPlayLobby2AImpl_SendLobbyMessage( IDirectPlayLobby2A
*iface
,
1449 DWORD flags
, DWORD appid
, void *data
, DWORD size
)
1451 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1452 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, data
,
1456 static HRESULT WINAPI
IDirectPlayLobby2Impl_SendLobbyMessage( IDirectPlayLobby2
*iface
, DWORD flags
,
1457 DWORD appid
, void *data
, DWORD size
)
1459 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1460 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
, data
,
1464 static HRESULT WINAPI
IDirectPlayLobby3AImpl_SendLobbyMessage( IDirectPlayLobby3A
*iface
,
1465 DWORD flags
, DWORD appid
, void *data
, DWORD size
)
1468 return DPERR_OUTOFMEMORY
;
1471 static HRESULT WINAPI
IDirectPlayLobby3Impl_SendLobbyMessage( IDirectPlayLobby3
*iface
,
1472 DWORD flags
, DWORD appid
, void *data
, DWORD size
)
1475 return DPERR_OUTOFMEMORY
;
1478 /********************************************************************
1480 * Modifies the DPLCONNECTION structure to contain all information
1481 * needed to start and connect an application.
1484 static HRESULT WINAPI
IDirectPlayLobby3Impl_SetConnectionSettings( IDirectPlayLobby3
*iface
,
1485 DWORD dwFlags
, DWORD dwAppID
, DPLCONNECTION
*lpConn
)
1487 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1490 TRACE("(%p)->(0x%08x,0x%08x,%p)\n", This
, dwFlags
, dwAppID
, lpConn
);
1492 EnterCriticalSection( &This
->lock
);
1494 hr
= DPLAYX_SetConnectionSettingsW( dwFlags
, dwAppID
, lpConn
);
1496 /* FIXME: Don't think that this is supposed to fail, but the documentation
1497 is somewhat sketchy. I'll try creating a lobby application
1499 if( hr
== DPERR_NOTLOBBIED
)
1501 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1504 dwAppID
= GetCurrentProcessId();
1506 DPLAYX_CreateLobbyApplication( dwAppID
);
1507 hr
= DPLAYX_SetConnectionSettingsW( dwFlags
, dwAppID
, lpConn
);
1510 LeaveCriticalSection( &This
->lock
);
1515 static HRESULT WINAPI
IDirectPlayLobbyAImpl_SetConnectionSettings( IDirectPlayLobbyA
*iface
,
1516 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1518 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1519 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, flags
,
1523 static HRESULT WINAPI
IDirectPlayLobbyImpl_SetConnectionSettings( IDirectPlayLobby
*iface
,
1524 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1526 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1527 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3_iface
, flags
,
1531 static HRESULT WINAPI
IDirectPlayLobby2AImpl_SetConnectionSettings( IDirectPlayLobby2A
*iface
,
1532 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1534 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1535 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, flags
,
1539 static HRESULT WINAPI
IDirectPlayLobby2Impl_SetConnectionSettings( IDirectPlayLobby2
*iface
,
1540 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1542 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1543 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3_iface
, flags
,
1547 static HRESULT WINAPI
IDirectPlayLobby3AImpl_SetConnectionSettings( IDirectPlayLobby3A
*iface
,
1548 DWORD dwFlags
, DWORD dwAppID
, DPLCONNECTION
*lpConn
)
1550 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1553 TRACE("(%p)->(0x%08x,0x%08x,%p)\n", This
, dwFlags
, dwAppID
, lpConn
);
1555 EnterCriticalSection( &This
->lock
);
1557 hr
= DPLAYX_SetConnectionSettingsA( dwFlags
, dwAppID
, lpConn
);
1559 /* FIXME: Don't think that this is supposed to fail, but the documentation
1560 is somewhat sketchy. I'll try creating a lobby application
1562 if( hr
== DPERR_NOTLOBBIED
)
1564 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1565 dwAppID
= GetCurrentProcessId();
1566 DPLAYX_CreateLobbyApplication( dwAppID
);
1567 hr
= DPLAYX_SetConnectionSettingsA( dwFlags
, dwAppID
, lpConn
);
1570 LeaveCriticalSection( &This
->lock
);
1575 /********************************************************************
1577 * Registers an event that will be set when a lobby message is received.
1580 static HRESULT WINAPI
IDirectPlayLobbyAImpl_SetLobbyMessageEvent( IDirectPlayLobbyA
*iface
,
1581 DWORD flags
, DWORD appid
, HANDLE event
)
1583 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1584 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1588 static HRESULT WINAPI
IDirectPlayLobbyImpl_SetLobbyMessageEvent( IDirectPlayLobby
*iface
,
1589 DWORD flags
, DWORD appid
, HANDLE event
)
1591 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1592 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1596 static HRESULT WINAPI
IDirectPlayLobby2AImpl_SetLobbyMessageEvent( IDirectPlayLobby2A
*iface
,
1597 DWORD flags
, DWORD appid
, HANDLE event
)
1599 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1600 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1604 static HRESULT WINAPI
IDirectPlayLobby2Impl_SetLobbyMessageEvent( IDirectPlayLobby2
*iface
,
1605 DWORD flags
, DWORD appid
, HANDLE event
)
1607 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1608 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1612 static HRESULT WINAPI
IDirectPlayLobby3AImpl_SetLobbyMessageEvent( IDirectPlayLobby3A
*iface
,
1613 DWORD flags
, DWORD appid
, HANDLE event
)
1616 return DPERR_OUTOFMEMORY
;
1619 static HRESULT WINAPI
IDirectPlayLobby3Impl_SetLobbyMessageEvent( IDirectPlayLobby3
*iface
,
1620 DWORD flags
, DWORD appid
, HANDLE event
)
1623 return DPERR_OUTOFMEMORY
;
1628 static HRESULT WINAPI
IDirectPlayLobby2AImpl_CreateCompoundAddress( IDirectPlayLobby2A
*iface
,
1629 const DPCOMPOUNDADDRESSELEMENT
*elements
, DWORD count
, void *address
, DWORD
*size
)
1631 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1632 return IDirectPlayLobby_CreateCompoundAddress( &This
->IDirectPlayLobby3A_iface
, elements
,
1633 count
, address
, size
);
1636 static HRESULT WINAPI
IDirectPlayLobby2Impl_CreateCompoundAddress( IDirectPlayLobby2
*iface
,
1637 const DPCOMPOUNDADDRESSELEMENT
*elements
, DWORD count
, void *address
, DWORD
*size
)
1639 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1640 return IDirectPlayLobby_CreateCompoundAddress( &This
->IDirectPlayLobby3_iface
, elements
,
1641 count
, address
, size
);
1644 static HRESULT WINAPI
IDirectPlayLobby3Impl_CreateCompoundAddress( IDirectPlayLobby3
*iface
,
1645 const DPCOMPOUNDADDRESSELEMENT
*lpElements
, DWORD dwElementCount
, void *lpAddress
,
1646 DWORD
*lpdwAddressSize
)
1648 return DPL_CreateCompoundAddress( lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
, FALSE
);
1651 static HRESULT WINAPI
IDirectPlayLobby3AImpl_CreateCompoundAddress( IDirectPlayLobby3A
*iface
,
1652 const DPCOMPOUNDADDRESSELEMENT
*lpElements
, DWORD dwElementCount
, void *lpAddress
,
1653 DWORD
*lpdwAddressSize
)
1655 return DPL_CreateCompoundAddress( lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
, TRUE
);
1658 HRESULT DPL_CreateCompoundAddress
1659 ( LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1660 DWORD dwElementCount
,
1662 LPDWORD lpdwAddressSize
,
1663 BOOL bAnsiInterface
)
1665 DWORD dwSizeRequired
= 0;
1667 LPCDPCOMPOUNDADDRESSELEMENT lpOrigElements
= lpElements
;
1669 TRACE("(%p,0x%08x,%p,%p)\n", lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
);
1671 /* Parameter check */
1672 if( ( lpElements
== NULL
) ||
1673 ( dwElementCount
== 0 ) /* FIXME: Not sure if this is a failure case */
1676 return DPERR_INVALIDPARAMS
;
1679 /* Add the total size chunk */
1680 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( DWORD
);
1682 /* Calculate the size of the buffer required */
1683 for ( dwElements
= dwElementCount
; dwElements
> 0; --dwElements
, ++lpElements
)
1685 if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ServiceProvider
) ) ||
1686 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_LobbyProvider
) )
1689 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( GUID
);
1691 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Phone
) ) ||
1692 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Modem
) ) ||
1693 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INet
) )
1696 if( !bAnsiInterface
)
1698 ERR( "Ansi GUIDs used for unicode interface\n" );
1699 return DPERR_INVALIDFLAGS
;
1702 dwSizeRequired
+= sizeof( DPADDRESS
) + lpElements
->dwDataSize
;
1704 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_PhoneW
) ) ||
1705 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ModemW
) ) ||
1706 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetW
) )
1709 if( bAnsiInterface
)
1711 ERR( "Unicode GUIDs used for ansi interface\n" );
1712 return DPERR_INVALIDFLAGS
;
1715 FIXME( "Right size for unicode interface?\n" );
1716 dwSizeRequired
+= sizeof( DPADDRESS
) + lpElements
->dwDataSize
* sizeof( WCHAR
);
1718 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetPort
) )
1720 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( WORD
);
1722 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ComPort
) )
1724 FIXME( "Right size for unicode interface?\n" );
1725 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( DPCOMPORTADDRESS
); /* FIXME: Right size? */
1729 ERR( "Unknown GUID %s\n", debugstr_guid(&lpElements
->guidDataType
) );
1730 return DPERR_INVALIDFLAGS
;
1734 /* The user wants to know how big a buffer to allocate for us */
1735 if( ( lpAddress
== NULL
) ||
1736 ( *lpdwAddressSize
< dwSizeRequired
)
1739 *lpdwAddressSize
= dwSizeRequired
;
1740 return DPERR_BUFFERTOOSMALL
;
1743 /* Add the total size chunk */
1745 LPDPADDRESS lpdpAddress
= lpAddress
;
1747 lpdpAddress
->guidDataType
= DPAID_TotalSize
;
1748 lpdpAddress
->dwDataSize
= sizeof( DWORD
);
1749 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1751 *(LPDWORD
)lpAddress
= dwSizeRequired
;
1752 lpAddress
= (char *) lpAddress
+ sizeof( DWORD
);
1755 /* Calculate the size of the buffer required */
1756 for( dwElements
= dwElementCount
, lpElements
= lpOrigElements
;
1758 --dwElements
, ++lpElements
)
1760 if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ServiceProvider
) ) ||
1761 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_LobbyProvider
) )
1764 LPDPADDRESS lpdpAddress
= lpAddress
;
1766 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1767 lpdpAddress
->dwDataSize
= sizeof( GUID
);
1768 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1770 CopyMemory( lpAddress
, lpElements
->lpData
, sizeof( GUID
) );
1771 lpAddress
= (char *) lpAddress
+ sizeof( GUID
);
1773 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Phone
) ) ||
1774 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Modem
) ) ||
1775 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INet
) )
1778 LPDPADDRESS lpdpAddress
= lpAddress
;
1780 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1781 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1782 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1784 lstrcpynA( lpAddress
, lpElements
->lpData
, lpElements
->dwDataSize
);
1785 lpAddress
= (char *) lpAddress
+ lpElements
->dwDataSize
;
1787 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_PhoneW
) ) ||
1788 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ModemW
) ) ||
1789 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetW
) )
1792 LPDPADDRESS lpdpAddress
= lpAddress
;
1794 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1795 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1796 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1798 lstrcpynW( lpAddress
, lpElements
->lpData
, lpElements
->dwDataSize
);
1799 lpAddress
= (char *) lpAddress
+ lpElements
->dwDataSize
* sizeof( WCHAR
);
1801 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetPort
) )
1803 LPDPADDRESS lpdpAddress
= lpAddress
;
1805 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1806 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1807 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1809 *((LPWORD
)lpAddress
) = *((LPWORD
)lpElements
->lpData
);
1810 lpAddress
= (char *) lpAddress
+ sizeof( WORD
);
1812 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ComPort
) )
1814 LPDPADDRESS lpdpAddress
= lpAddress
;
1816 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1817 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1818 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1820 CopyMemory( lpAddress
, lpElements
->lpData
, sizeof( DPADDRESS
) );
1821 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1830 static HRESULT WINAPI
IDirectPlayLobby3Impl_ConnectEx( IDirectPlayLobby3
*iface
, DWORD dwFlags
,
1831 REFIID riid
, LPVOID
* lplpDP
, IUnknown
* pUnk
)
1833 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1834 return DPL_ConnectEx( This
, dwFlags
, riid
, lplpDP
, pUnk
);
1837 static HRESULT WINAPI
IDirectPlayLobby3AImpl_ConnectEx( IDirectPlayLobby3A
*iface
, DWORD dwFlags
,
1838 REFIID riid
, void **lplpDP
, IUnknown
*pUnk
)
1840 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1841 return DPL_ConnectEx( This
, dwFlags
, riid
, lplpDP
, pUnk
);
1844 static HRESULT WINAPI
IDirectPlayLobby3Impl_RegisterApplication( IDirectPlayLobby3
*iface
,
1845 DWORD flags
, DPAPPLICATIONDESC
*appdesc
)
1851 static HRESULT WINAPI
IDirectPlayLobby3AImpl_RegisterApplication( IDirectPlayLobby3A
*iface
,
1852 DWORD flags
, DPAPPLICATIONDESC
*appdesc
)
1858 static HRESULT WINAPI
IDirectPlayLobby3Impl_UnregisterApplication( IDirectPlayLobby3
*iface
,
1859 DWORD flags
, REFGUID appdesc
)
1865 static HRESULT WINAPI
IDirectPlayLobby3AImpl_UnregisterApplication( IDirectPlayLobby3A
*iface
,
1866 DWORD flags
, REFGUID appdesc
)
1872 static HRESULT WINAPI
IDirectPlayLobby3Impl_WaitForConnectionSettings( IDirectPlayLobby3
*iface
,
1876 BOOL bStartWait
= !(dwFlags
& DPLWAIT_CANCEL
);
1878 TRACE( "(%p)->(0x%08x)\n", iface
, dwFlags
);
1880 if( DPLAYX_WaitForConnectionSettings( bStartWait
) )
1882 /* FIXME: What is the correct error return code? */
1883 hr
= DPERR_NOTLOBBIED
;
1889 static HRESULT WINAPI
IDirectPlayLobby3AImpl_WaitForConnectionSettings( IDirectPlayLobby3A
*iface
,
1893 BOOL bStartWait
= !(dwFlags
& DPLWAIT_CANCEL
);
1895 TRACE( "(%p)->(0x%08x)\n", iface
, dwFlags
);
1897 if( DPLAYX_WaitForConnectionSettings( bStartWait
) )
1899 /* FIXME: What is the correct error return code? */
1900 hr
= DPERR_NOTLOBBIED
;
1906 static const IDirectPlayLobbyVtbl dplA_vt
=
1908 IDirectPlayLobbyAImpl_QueryInterface
,
1909 IDirectPlayLobbyAImpl_AddRef
,
1910 IDirectPlayLobbyAImpl_Release
,
1911 IDirectPlayLobbyAImpl_Connect
,
1912 IDirectPlayLobbyAImpl_CreateAddress
,
1913 IDirectPlayLobbyAImpl_EnumAddress
,
1914 IDirectPlayLobbyAImpl_EnumAddressTypes
,
1915 IDirectPlayLobbyAImpl_EnumLocalApplications
,
1916 IDirectPlayLobbyAImpl_GetConnectionSettings
,
1917 IDirectPlayLobbyAImpl_ReceiveLobbyMessage
,
1918 IDirectPlayLobbyAImpl_RunApplication
,
1919 IDirectPlayLobbyAImpl_SendLobbyMessage
,
1920 IDirectPlayLobbyAImpl_SetConnectionSettings
,
1921 IDirectPlayLobbyAImpl_SetLobbyMessageEvent
1924 static const IDirectPlayLobbyVtbl dpl_vt
=
1926 IDirectPlayLobbyImpl_QueryInterface
,
1927 IDirectPlayLobbyImpl_AddRef
,
1928 IDirectPlayLobbyImpl_Release
,
1929 IDirectPlayLobbyImpl_Connect
,
1930 IDirectPlayLobbyImpl_CreateAddress
,
1931 IDirectPlayLobbyImpl_EnumAddress
,
1932 IDirectPlayLobbyImpl_EnumAddressTypes
,
1933 IDirectPlayLobbyImpl_EnumLocalApplications
,
1934 IDirectPlayLobbyImpl_GetConnectionSettings
,
1935 IDirectPlayLobbyImpl_ReceiveLobbyMessage
,
1936 IDirectPlayLobbyImpl_RunApplication
,
1937 IDirectPlayLobbyImpl_SendLobbyMessage
,
1938 IDirectPlayLobbyImpl_SetConnectionSettings
,
1939 IDirectPlayLobbyImpl_SetLobbyMessageEvent
1942 static const IDirectPlayLobby2Vtbl dpl2A_vt
=
1944 IDirectPlayLobby2AImpl_QueryInterface
,
1945 IDirectPlayLobby2AImpl_AddRef
,
1946 IDirectPlayLobby2AImpl_Release
,
1947 IDirectPlayLobby2AImpl_Connect
,
1948 IDirectPlayLobby2AImpl_CreateAddress
,
1949 IDirectPlayLobby2AImpl_EnumAddress
,
1950 IDirectPlayLobby2AImpl_EnumAddressTypes
,
1951 IDirectPlayLobby2AImpl_EnumLocalApplications
,
1952 IDirectPlayLobby2AImpl_GetConnectionSettings
,
1953 IDirectPlayLobby2AImpl_ReceiveLobbyMessage
,
1954 IDirectPlayLobby2AImpl_RunApplication
,
1955 IDirectPlayLobby2AImpl_SendLobbyMessage
,
1956 IDirectPlayLobby2AImpl_SetConnectionSettings
,
1957 IDirectPlayLobby2AImpl_SetLobbyMessageEvent
,
1958 IDirectPlayLobby2AImpl_CreateCompoundAddress
1961 static const IDirectPlayLobby2Vtbl dpl2_vt
=
1963 IDirectPlayLobby2Impl_QueryInterface
,
1964 IDirectPlayLobby2Impl_AddRef
,
1965 IDirectPlayLobby2Impl_Release
,
1966 IDirectPlayLobby2Impl_Connect
,
1967 IDirectPlayLobby2Impl_CreateAddress
,
1968 IDirectPlayLobby2Impl_EnumAddress
,
1969 IDirectPlayLobby2Impl_EnumAddressTypes
,
1970 IDirectPlayLobby2Impl_EnumLocalApplications
,
1971 IDirectPlayLobby2Impl_GetConnectionSettings
,
1972 IDirectPlayLobby2Impl_ReceiveLobbyMessage
,
1973 IDirectPlayLobby2Impl_RunApplication
,
1974 IDirectPlayLobby2Impl_SendLobbyMessage
,
1975 IDirectPlayLobby2Impl_SetConnectionSettings
,
1976 IDirectPlayLobby2Impl_SetLobbyMessageEvent
,
1977 IDirectPlayLobby2Impl_CreateCompoundAddress
1980 static const IDirectPlayLobby3Vtbl dpl3A_vt
=
1982 IDirectPlayLobby3AImpl_QueryInterface
,
1983 IDirectPlayLobby3AImpl_AddRef
,
1984 IDirectPlayLobby3AImpl_Release
,
1985 IDirectPlayLobby3AImpl_Connect
,
1986 IDirectPlayLobby3AImpl_CreateAddress
,
1987 IDirectPlayLobby3AImpl_EnumAddress
,
1988 IDirectPlayLobby3AImpl_EnumAddressTypes
,
1989 IDirectPlayLobby3AImpl_EnumLocalApplications
,
1990 IDirectPlayLobby3AImpl_GetConnectionSettings
,
1991 IDirectPlayLobby3AImpl_ReceiveLobbyMessage
,
1992 IDirectPlayLobby3AImpl_RunApplication
,
1993 IDirectPlayLobby3AImpl_SendLobbyMessage
,
1994 IDirectPlayLobby3AImpl_SetConnectionSettings
,
1995 IDirectPlayLobby3AImpl_SetLobbyMessageEvent
,
1996 IDirectPlayLobby3AImpl_CreateCompoundAddress
,
1997 IDirectPlayLobby3AImpl_ConnectEx
,
1998 IDirectPlayLobby3AImpl_RegisterApplication
,
1999 IDirectPlayLobby3AImpl_UnregisterApplication
,
2000 IDirectPlayLobby3AImpl_WaitForConnectionSettings
2003 static const IDirectPlayLobby3Vtbl dpl3_vt
=
2005 IDirectPlayLobby3Impl_QueryInterface
,
2006 IDirectPlayLobby3Impl_AddRef
,
2007 IDirectPlayLobby3Impl_Release
,
2008 IDirectPlayLobby3Impl_Connect
,
2009 IDirectPlayLobby3Impl_CreateAddress
,
2010 IDirectPlayLobby3Impl_EnumAddress
,
2011 IDirectPlayLobby3Impl_EnumAddressTypes
,
2012 IDirectPlayLobby3Impl_EnumLocalApplications
,
2013 IDirectPlayLobby3Impl_GetConnectionSettings
,
2014 IDirectPlayLobby3Impl_ReceiveLobbyMessage
,
2015 IDirectPlayLobby3Impl_RunApplication
,
2016 IDirectPlayLobby3Impl_SendLobbyMessage
,
2017 IDirectPlayLobby3Impl_SetConnectionSettings
,
2018 IDirectPlayLobby3Impl_SetLobbyMessageEvent
,
2019 IDirectPlayLobby3Impl_CreateCompoundAddress
,
2020 IDirectPlayLobby3Impl_ConnectEx
,
2021 IDirectPlayLobby3Impl_RegisterApplication
,
2022 IDirectPlayLobby3Impl_UnregisterApplication
,
2023 IDirectPlayLobby3Impl_WaitForConnectionSettings
2026 HRESULT
dplobby_create( REFIID riid
, void **ppv
)
2028 IDirectPlayLobbyImpl
*obj
;
2031 TRACE( "(%s, %p)\n", debugstr_guid( riid
), ppv
);
2034 obj
= HeapAlloc( GetProcessHeap(), 0, sizeof( *obj
) );
2036 return DPERR_OUTOFMEMORY
;
2038 obj
->IDirectPlayLobby_iface
.lpVtbl
= &dpl_vt
;
2039 obj
->IDirectPlayLobbyA_iface
.lpVtbl
= &dplA_vt
;
2040 obj
->IDirectPlayLobby2_iface
.lpVtbl
= &dpl2_vt
;
2041 obj
->IDirectPlayLobby2A_iface
.lpVtbl
= &dpl2A_vt
;
2042 obj
->IDirectPlayLobby3_iface
.lpVtbl
= &dpl3_vt
;
2043 obj
->IDirectPlayLobby3A_iface
.lpVtbl
= &dpl3A_vt
;
2053 InitializeCriticalSection( &obj
->lock
);
2054 obj
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": IDirectPlayLobbyImpl.lock");
2055 DPQ_INIT( obj
->msgs
);
2057 hr
= IDirectPlayLobby_QueryInterface( &obj
->IDirectPlayLobby3_iface
, riid
, ppv
);
2058 IDirectPlayLobby_Release( &obj
->IDirectPlayLobby3_iface
);
2065 /***************************************************************************
2066 * DirectPlayLobbyCreateA (DPLAYX.4)
2069 HRESULT WINAPI
DirectPlayLobbyCreateA( GUID
*lpGUIDDSP
, IDirectPlayLobbyA
**lplpDPL
,
2070 IUnknown
*lpUnk
, void *lpData
, DWORD dwDataSize
)
2072 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08x\n",
2073 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
2075 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
2076 * equal 0. These fields are mostly for future expansion.
2078 if ( lpGUIDDSP
|| lpData
|| dwDataSize
)
2081 return DPERR_INVALIDPARAMS
;
2087 ERR("Bad parameters!\n" );
2088 return CLASS_E_NOAGGREGATION
;
2091 return dplobby_create( &IID_IDirectPlayLobbyA
, (void**)lplpDPL
);
2094 /***************************************************************************
2095 * DirectPlayLobbyCreateW (DPLAYX.5)
2098 HRESULT WINAPI
DirectPlayLobbyCreateW( GUID
*lpGUIDDSP
, IDirectPlayLobby
**lplpDPL
,
2099 IUnknown
*lpUnk
, void *lpData
, DWORD dwDataSize
)
2101 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08x\n",
2102 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
2104 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
2105 * equal 0. These fields are mostly for future expansion.
2107 if ( lpGUIDDSP
|| lpData
|| dwDataSize
)
2110 ERR("Bad parameters!\n" );
2111 return DPERR_INVALIDPARAMS
;
2117 ERR("Bad parameters!\n" );
2118 return CLASS_E_NOAGGREGATION
;
2121 return dplobby_create( &IID_IDirectPlayLobby
, (void**)lplpDPL
);