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
24 #define NONAMELESSSTRUCT
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";
768 TRACE(" this time through: %s\n", subKeyName
);
770 /* Get a handle for this particular service provider */
771 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
772 &hkServiceProvider
) != ERROR_SUCCESS
)
774 ERR(": what the heck is going on?\n" );
778 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
779 NULL
, &returnTypeGUID
, (LPBYTE
)returnBuffer
,
780 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
782 ERR(": missing GUID registry data members\n" );
786 /* FIXME: Check return types to ensure we're interpreting data right */
787 MultiByteToWideChar( CP_ACP
, 0, returnBuffer
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
788 CLSIDFromString( buff
, &serviceProviderGUID
);
789 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
791 /* Determine if this is the Service Provider that the user asked for */
792 if( !IsEqualGUID( &serviceProviderGUID
, guidSP
) )
797 /* Get a handle for this particular service provider */
798 if( RegOpenKeyExA( hkServiceProvider
, atKey
, 0, KEY_READ
,
799 &hkServiceProviderAt
) != ERROR_SUCCESS
)
801 TRACE(": No Address Types registry data sub key/members\n" );
805 /* Traverse all the address type we have available */
807 RegEnumKeyExA( hkServiceProviderAt
, dwAtIndex
, atSubKey
, &sizeOfSubKeyName
,
808 NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
809 ++dwAtIndex
, sizeOfSubKeyName
=50 )
811 TRACE( "Found Address Type GUID %s\n", atSubKey
);
813 /* FIXME: Check return types to ensure we're interpreting data right */
814 MultiByteToWideChar( CP_ACP
, 0, atSubKey
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
815 CLSIDFromString( buff
, &serviceProviderGUID
);
816 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
818 /* The enumeration will return FALSE if we are not to continue */
819 if( !lpEnumAddressTypeCallback( &serviceProviderGUID
, lpContext
, 0 ) )
821 WARN("lpEnumCallback returning FALSE\n" );
822 break; /* FIXME: This most likely has to break from the procedure...*/
827 /* We only enumerate address types for 1 GUID. We've found it, so quit looking */
834 static HRESULT WINAPI
IDirectPlayLobby3Impl_EnumAddressTypes( IDirectPlayLobby3
*iface
,
835 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
838 return DPERR_OUTOFMEMORY
;
841 /********************************************************************
843 * Enumerates what applications are registered with DirectPlay by
844 * invoking the callback function with lpContext.
847 static HRESULT WINAPI
IDirectPlayLobby3Impl_EnumLocalApplications( IDirectPlayLobby3
*iface
,
848 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback
, void *lpContext
, DWORD dwFlags
)
850 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
852 FIXME("(%p)->(%p,%p,0x%08x):stub\n", This
, lpEnumLocalAppCallback
, lpContext
, dwFlags
);
854 return DPERR_OUTOFMEMORY
;
857 static HRESULT WINAPI
IDirectPlayLobbyAImpl_EnumLocalApplications( IDirectPlayLobbyA
*iface
,
858 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
860 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
861 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3A_iface
, enumlocalappcb
,
865 static HRESULT WINAPI
IDirectPlayLobbyImpl_EnumLocalApplications( IDirectPlayLobby
*iface
,
866 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
868 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
869 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3_iface
, enumlocalappcb
,
873 static HRESULT WINAPI
IDirectPlayLobby2AImpl_EnumLocalApplications( IDirectPlayLobby2A
*iface
,
874 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
876 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
877 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3A_iface
, enumlocalappcb
,
881 static HRESULT WINAPI
IDirectPlayLobby2Impl_EnumLocalApplications( IDirectPlayLobby2
*iface
,
882 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
884 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
885 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3_iface
, enumlocalappcb
,
889 static HRESULT WINAPI
IDirectPlayLobby3AImpl_EnumLocalApplications( IDirectPlayLobby3A
*iface
,
890 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback
, void *lpContext
, DWORD dwFlags
)
892 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
895 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Applications";
896 LPCSTR guidDataSubKey
= "Guid";
897 DWORD dwIndex
, sizeOfSubKeyName
=50;
901 TRACE("(%p)->(%p,%p,0x%08x)\n", This
, lpEnumLocalAppCallback
, lpContext
, dwFlags
);
905 return DPERR_INVALIDPARAMS
;
908 if( !lpEnumLocalAppCallback
)
910 return DPERR_INVALIDPARAMS
;
913 /* Need to loop over the service providers in the registry */
914 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
915 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
917 /* Hmmm. Does this mean that there are no service providers? */
918 ERR(": no service providers?\n");
922 /* Traverse all registered applications */
924 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
, NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
925 ++dwIndex
, sizeOfSubKeyName
=50 )
928 HKEY hkServiceProvider
;
929 GUID serviceProviderGUID
;
930 DWORD returnTypeGUID
, sizeOfReturnBuffer
= 50;
931 char returnBuffer
[51];
933 DPLAPPINFO dplAppInfo
;
935 TRACE(" this time through: %s\n", subKeyName
);
937 /* Get a handle for this particular service provider */
938 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
939 &hkServiceProvider
) != ERROR_SUCCESS
)
941 ERR(": what the heck is going on?\n" );
945 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
946 NULL
, &returnTypeGUID
, (LPBYTE
)returnBuffer
,
947 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
949 ERR(": missing GUID registry data members\n" );
953 /* FIXME: Check return types to ensure we're interpreting data right */
954 MultiByteToWideChar( CP_ACP
, 0, returnBuffer
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
955 CLSIDFromString( buff
, &serviceProviderGUID
);
956 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
958 dplAppInfo
.dwSize
= sizeof( dplAppInfo
);
959 dplAppInfo
.guidApplication
= serviceProviderGUID
;
960 dplAppInfo
.u
.lpszAppNameA
= subKeyName
;
962 EnterCriticalSection( &This
->lock
);
964 memcpy( &This
->cbkeyhack
, &hkServiceProvider
, sizeof( hkServiceProvider
) );
966 if( !lpEnumLocalAppCallback( &dplAppInfo
, lpContext
, dwFlags
) )
968 LeaveCriticalSection( &This
->lock
);
972 LeaveCriticalSection( &This
->lock
);
978 /********************************************************************
980 * Retrieves the DPLCONNECTION structure that contains all the information
981 * needed to start and connect an application. This was generated using
982 * either the RunApplication or SetConnectionSettings methods.
984 * NOTES: If lpData is NULL then just return lpdwDataSize. This allows
985 * the data structure to be allocated by our caller which can then
986 * call this procedure/method again with a valid data pointer.
988 static HRESULT WINAPI
IDirectPlayLobbyAImpl_GetConnectionSettings( IDirectPlayLobbyA
*iface
,
989 DWORD appid
, void *data
, DWORD
*size
)
991 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
992 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, appid
, data
,
996 static HRESULT WINAPI
IDirectPlayLobbyImpl_GetConnectionSettings( IDirectPlayLobby
*iface
,
997 DWORD appid
, void *data
, DWORD
*size
)
999 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1000 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3_iface
, appid
, data
,
1004 static HRESULT WINAPI
IDirectPlayLobby2AImpl_GetConnectionSettings( IDirectPlayLobby2A
*iface
,
1005 DWORD appid
, void *data
, DWORD
*size
)
1007 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1008 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, appid
, data
,
1012 static HRESULT WINAPI
IDirectPlayLobby2Impl_GetConnectionSettings( IDirectPlayLobby2
*iface
,
1013 DWORD appid
, void *data
, DWORD
*size
)
1015 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1016 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3_iface
, appid
, data
,
1020 static HRESULT WINAPI
IDirectPlayLobby3AImpl_GetConnectionSettings( IDirectPlayLobby3A
*iface
,
1021 DWORD dwAppID
, void *lpData
, DWORD
*lpdwDataSize
)
1023 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1026 TRACE("(%p)->(0x%08x,%p,%p)\n", This
, dwAppID
, lpData
, lpdwDataSize
);
1028 EnterCriticalSection( &This
->lock
);
1030 hr
= DPLAYX_GetConnectionSettingsA( dwAppID
,
1035 LeaveCriticalSection( &This
->lock
);
1040 static HRESULT WINAPI
IDirectPlayLobby3Impl_GetConnectionSettings( IDirectPlayLobby3
*iface
,
1041 DWORD dwAppID
, void *lpData
, DWORD
*lpdwDataSize
)
1043 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1046 TRACE("(%p)->(0x%08x,%p,%p)\n", This
, dwAppID
, lpData
, lpdwDataSize
);
1048 EnterCriticalSection( &This
->lock
);
1050 hr
= DPLAYX_GetConnectionSettingsW( dwAppID
,
1055 LeaveCriticalSection( &This
->lock
);
1060 /********************************************************************
1062 * Retrieves the message sent between a lobby client and a DirectPlay
1063 * application. All messages are queued until received.
1066 static HRESULT WINAPI
IDirectPlayLobbyAImpl_ReceiveLobbyMessage( IDirectPlayLobbyA
*iface
,
1067 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1069 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1070 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1071 msgflags
, data
, size
);
1074 static HRESULT WINAPI
IDirectPlayLobbyImpl_ReceiveLobbyMessage( IDirectPlayLobby
*iface
,
1075 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1077 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1078 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1079 msgflags
, data
, size
);
1082 static HRESULT WINAPI
IDirectPlayLobby2AImpl_ReceiveLobbyMessage( IDirectPlayLobby2A
*iface
,
1083 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1085 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1086 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1087 msgflags
, data
, size
);
1090 static HRESULT WINAPI
IDirectPlayLobby2Impl_ReceiveLobbyMessage( IDirectPlayLobby2
*iface
,
1091 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1093 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1094 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1095 msgflags
, data
, size
);
1098 static HRESULT WINAPI
IDirectPlayLobby3AImpl_ReceiveLobbyMessage( IDirectPlayLobby3A
*iface
,
1099 DWORD dwFlags
, DWORD dwAppID
, DWORD
*lpdwMessageFlags
, void *lpData
,
1100 DWORD
*lpdwDataSize
)
1102 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1103 FIXME(":stub %p %08x %08x %p %p %p\n", This
, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
1105 return DPERR_OUTOFMEMORY
;
1108 static HRESULT WINAPI
IDirectPlayLobby3Impl_ReceiveLobbyMessage( IDirectPlayLobby3
*iface
,
1109 DWORD dwFlags
, DWORD dwAppID
, DWORD
*lpdwMessageFlags
, void *lpData
,
1110 DWORD
*lpdwDataSize
)
1112 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1113 FIXME(":stub %p %08x %08x %p %p %p\n", This
, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
1115 return DPERR_OUTOFMEMORY
;
1118 typedef struct tagRunApplicationEnumStruct
1120 IDirectPlayLobbyImpl
*This
;
1125 LPSTR lpszCommandLine
;
1126 LPSTR lpszCurrentDirectory
;
1127 } RunApplicationEnumStruct
, *lpRunApplicationEnumStruct
;
1129 /* To be called by RunApplication to find how to invoke the function */
1130 static BOOL CALLBACK RunApplicationA_EnumLocalApplications
1131 ( LPCDPLAPPINFO lpAppInfo
,
1135 lpRunApplicationEnumStruct lpData
= (lpRunApplicationEnumStruct
)lpContext
;
1137 if( IsEqualGUID( &lpAppInfo
->guidApplication
, &lpData
->appGUID
) )
1139 char returnBuffer
[200];
1140 DWORD returnType
, sizeOfReturnBuffer
;
1141 LPCSTR clSubKey
= "CommandLine";
1142 LPCSTR cdSubKey
= "CurrentDirectory";
1143 LPCSTR fileSubKey
= "File";
1144 LPCSTR pathSubKey
= "Path";
1146 /* FIXME: Lazy man hack - dplay struct has the present reg key saved */
1148 sizeOfReturnBuffer
= 200;
1150 /* Get all the appropriate data from the registry */
1151 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, clSubKey
,
1152 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1153 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1155 ERR( ": missing CommandLine registry data member\n" );
1159 if ((lpData
->lpszCommandLine
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1160 strcpy( lpData
->lpszCommandLine
, returnBuffer
);
1163 sizeOfReturnBuffer
= 200;
1165 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, cdSubKey
,
1166 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1167 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1169 ERR( ": missing CurrentDirectory registry data member\n" );
1173 if ((lpData
->lpszCurrentDirectory
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1174 strcpy( lpData
->lpszCurrentDirectory
, returnBuffer
);
1177 sizeOfReturnBuffer
= 200;
1179 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, fileSubKey
,
1180 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1181 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1183 ERR( ": missing File registry data member\n" );
1187 if ((lpData
->lpszFileName
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1188 strcpy( lpData
->lpszFileName
, returnBuffer
);
1191 sizeOfReturnBuffer
= 200;
1193 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, pathSubKey
,
1194 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1195 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1197 ERR( ": missing Path registry data member\n" );
1201 if ((lpData
->lpszPath
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1202 strcpy( lpData
->lpszPath
, returnBuffer
);
1205 return FALSE
; /* No need to keep going as we found what we wanted */
1208 return TRUE
; /* Keep enumerating, haven't found the application yet */
1211 static BOOL
DPL_CreateAndSetLobbyHandles( DWORD dwDestProcessId
, HANDLE hDestProcess
,
1212 LPHANDLE lphStart
, LPHANDLE lphDeath
,
1215 /* These are the handles for the created process */
1216 HANDLE hAppStart
= 0, hAppDeath
= 0, hAppRead
= 0;
1217 SECURITY_ATTRIBUTES s_attrib
;
1219 s_attrib
.nLength
= sizeof( s_attrib
);
1220 s_attrib
.lpSecurityDescriptor
= NULL
;
1221 s_attrib
.bInheritHandle
= TRUE
;
1223 *lphStart
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1224 *lphDeath
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1225 *lphRead
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1227 if( ( !DuplicateHandle( GetCurrentProcess(), *lphStart
,
1228 hDestProcess
, &hAppStart
,
1229 0, FALSE
, DUPLICATE_SAME_ACCESS
) ) ||
1230 ( !DuplicateHandle( GetCurrentProcess(), *lphDeath
,
1231 hDestProcess
, &hAppDeath
,
1232 0, FALSE
, DUPLICATE_SAME_ACCESS
) ) ||
1233 ( !DuplicateHandle( GetCurrentProcess(), *lphRead
,
1234 hDestProcess
, &hAppRead
,
1235 0, FALSE
, DUPLICATE_SAME_ACCESS
) )
1238 if (*lphStart
) { CloseHandle(*lphStart
); *lphStart
= 0; }
1239 if (*lphDeath
) { CloseHandle(*lphDeath
); *lphDeath
= 0; }
1240 if (*lphRead
) { CloseHandle(*lphRead
); *lphRead
= 0; }
1241 /* FIXME: Handle leak... */
1242 ERR( "Unable to dup handles\n" );
1246 if( !DPLAYX_SetLobbyHandles( dwDestProcessId
,
1247 hAppStart
, hAppDeath
, hAppRead
) )
1249 /* FIXME: Handle leak... */
1257 /********************************************************************
1259 * Starts an application and passes to it all the information to
1260 * connect to a session.
1263 static HRESULT WINAPI
IDirectPlayLobbyAImpl_RunApplication( IDirectPlayLobbyA
*iface
, DWORD flags
,
1264 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1266 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1267 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, conn
,
1271 static HRESULT WINAPI
IDirectPlayLobbyImpl_RunApplication( IDirectPlayLobby
*iface
, DWORD flags
,
1272 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1274 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1275 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3_iface
, flags
, appid
, conn
,
1279 static HRESULT WINAPI
IDirectPlayLobby2AImpl_RunApplication( IDirectPlayLobby2A
*iface
, DWORD flags
,
1280 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1282 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1283 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, conn
,
1287 static HRESULT WINAPI
IDirectPlayLobby2Impl_RunApplication( IDirectPlayLobby2
*iface
, DWORD flags
,
1288 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1290 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1291 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3_iface
, flags
, appid
, conn
,
1295 static HRESULT WINAPI
IDirectPlayLobby3AImpl_RunApplication( IDirectPlayLobby3A
*iface
,
1296 DWORD dwFlags
, DWORD
*lpdwAppID
, DPLCONNECTION
*lpConn
, HANDLE hReceiveEvent
)
1298 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1300 RunApplicationEnumStruct enumData
;
1302 STARTUPINFOA startupInfo
;
1303 PROCESS_INFORMATION newProcessInfo
;
1305 DWORD dwSuspendCount
;
1306 HANDLE hStart
, hDeath
, hSettingRead
;
1308 TRACE( "(%p)->(0x%08x,%p,%p,%p)\n",
1309 This
, dwFlags
, lpdwAppID
, lpConn
, hReceiveEvent
);
1313 return DPERR_INVALIDPARAMS
;
1316 if( DPLAYX_AnyLobbiesWaitingForConnSettings() )
1318 FIXME( "Waiting lobby not being handled correctly\n" );
1321 EnterCriticalSection( &This
->lock
);
1323 ZeroMemory( &enumData
, sizeof( enumData
) );
1324 enumData
.This
= This
;
1325 enumData
.appGUID
= lpConn
->lpSessionDesc
->guidApplication
;
1327 /* Our callback function will fill up the enumData structure with all the information
1328 required to start a new process */
1329 IDirectPlayLobby_EnumLocalApplications( iface
, RunApplicationA_EnumLocalApplications
,
1332 /* First the application name */
1333 strcpy( temp
, enumData
.lpszPath
);
1334 strcat( temp
, "\\" );
1335 strcat( temp
, enumData
.lpszFileName
);
1336 HeapFree( GetProcessHeap(), 0, enumData
.lpszPath
);
1337 HeapFree( GetProcessHeap(), 0, enumData
.lpszFileName
);
1338 if ((appName
= HeapAlloc( GetProcessHeap(), 0, strlen(temp
)+1 ))) strcpy( appName
, temp
);
1340 /* Now the command line */
1341 strcat( temp
, " " );
1342 strcat( temp
, enumData
.lpszCommandLine
);
1343 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1344 if ((enumData
.lpszCommandLine
= HeapAlloc( GetProcessHeap(), 0, strlen(temp
)+1 )))
1345 strcpy( enumData
.lpszCommandLine
, temp
);
1347 ZeroMemory( &startupInfo
, sizeof( startupInfo
) );
1348 startupInfo
.cb
= sizeof( startupInfo
);
1349 /* FIXME: Should any fields be filled in? */
1351 ZeroMemory( &newProcessInfo
, sizeof( newProcessInfo
) );
1353 if( !CreateProcessA( appName
,
1354 enumData
.lpszCommandLine
,
1358 CREATE_DEFAULT_ERROR_MODE
| CREATE_NEW_CONSOLE
| CREATE_SUSPENDED
, /* Creation Flags */
1360 enumData
.lpszCurrentDirectory
,
1366 ERR( "Failed to create process for app %s\n", appName
);
1368 HeapFree( GetProcessHeap(), 0, appName
);
1369 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1370 HeapFree( GetProcessHeap(), 0, enumData
.lpszCurrentDirectory
);
1372 LeaveCriticalSection( &This
->lock
);
1373 return DPERR_CANTCREATEPROCESS
;
1376 HeapFree( GetProcessHeap(), 0, appName
);
1377 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1378 HeapFree( GetProcessHeap(), 0, enumData
.lpszCurrentDirectory
);
1380 /* Reserve this global application id! */
1381 if( !DPLAYX_CreateLobbyApplication( newProcessInfo
.dwProcessId
) )
1383 ERR( "Unable to create global application data for 0x%08x\n",
1384 newProcessInfo
.dwProcessId
);
1387 hr
= IDirectPlayLobby_SetConnectionSettings( iface
, 0, newProcessInfo
.dwProcessId
, lpConn
);
1391 ERR( "SetConnectionSettings failure %s\n", DPLAYX_HresultToString( hr
) );
1392 LeaveCriticalSection( &This
->lock
);
1396 /* Setup the handles for application notification */
1397 DPL_CreateAndSetLobbyHandles( newProcessInfo
.dwProcessId
,
1398 newProcessInfo
.hProcess
,
1399 &hStart
, &hDeath
, &hSettingRead
);
1401 /* Setup the message thread ID */
1402 This
->msgtid
= CreateLobbyMessageReceptionThread( hReceiveEvent
, hStart
, hDeath
, hSettingRead
);
1404 DPLAYX_SetLobbyMsgThreadId( newProcessInfo
.dwProcessId
, This
->msgtid
);
1406 LeaveCriticalSection( &This
->lock
);
1408 /* Everything seems to have been set correctly, update the dwAppID */
1409 *lpdwAppID
= newProcessInfo
.dwProcessId
;
1411 /* Unsuspend the process - should return the prev suspension count */
1412 if( ( dwSuspendCount
= ResumeThread( newProcessInfo
.hThread
) ) != 1 )
1414 ERR( "ResumeThread failed with 0x%08x\n", dwSuspendCount
);
1420 static HRESULT WINAPI
IDirectPlayLobby3Impl_RunApplication( IDirectPlayLobby3
*iface
, DWORD dwFlags
,
1421 DWORD
*lpdwAppID
, DPLCONNECTION
*lpConn
, HANDLE hReceiveEvent
)
1423 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1424 FIXME( "(%p)->(0x%08x,%p,%p,%p):stub\n", This
, dwFlags
, lpdwAppID
, lpConn
, hReceiveEvent
);
1425 return DPERR_OUTOFMEMORY
;
1428 /********************************************************************
1430 * Sends a message between the application and the lobby client.
1431 * All messages are queued until received.
1434 static HRESULT WINAPI
IDirectPlayLobbyAImpl_SendLobbyMessage( IDirectPlayLobbyA
*iface
, DWORD flags
,
1435 DWORD appid
, void *data
, DWORD size
)
1437 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1438 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, data
,
1442 static HRESULT WINAPI
IDirectPlayLobbyImpl_SendLobbyMessage( IDirectPlayLobby
*iface
, DWORD flags
,
1443 DWORD appid
, void *data
, DWORD size
)
1445 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1446 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
, data
,
1450 static HRESULT WINAPI
IDirectPlayLobby2AImpl_SendLobbyMessage( IDirectPlayLobby2A
*iface
,
1451 DWORD flags
, DWORD appid
, void *data
, DWORD size
)
1453 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1454 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, data
,
1458 static HRESULT WINAPI
IDirectPlayLobby2Impl_SendLobbyMessage( IDirectPlayLobby2
*iface
, DWORD flags
,
1459 DWORD appid
, void *data
, DWORD size
)
1461 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1462 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
, data
,
1466 static HRESULT WINAPI
IDirectPlayLobby3AImpl_SendLobbyMessage( IDirectPlayLobby3A
*iface
,
1467 DWORD flags
, DWORD appid
, void *data
, DWORD size
)
1470 return DPERR_OUTOFMEMORY
;
1473 static HRESULT WINAPI
IDirectPlayLobby3Impl_SendLobbyMessage( IDirectPlayLobby3
*iface
,
1474 DWORD flags
, DWORD appid
, void *data
, DWORD size
)
1477 return DPERR_OUTOFMEMORY
;
1480 /********************************************************************
1482 * Modifies the DPLCONNECTION structure to contain all information
1483 * needed to start and connect an application.
1486 static HRESULT WINAPI
IDirectPlayLobby3Impl_SetConnectionSettings( IDirectPlayLobby3
*iface
,
1487 DWORD dwFlags
, DWORD dwAppID
, DPLCONNECTION
*lpConn
)
1489 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1492 TRACE("(%p)->(0x%08x,0x%08x,%p)\n", This
, dwFlags
, dwAppID
, lpConn
);
1494 EnterCriticalSection( &This
->lock
);
1496 hr
= DPLAYX_SetConnectionSettingsW( dwFlags
, dwAppID
, lpConn
);
1498 /* FIXME: Don't think that this is supposed to fail, but the documentation
1499 is somewhat sketchy. I'll try creating a lobby application
1501 if( hr
== DPERR_NOTLOBBIED
)
1503 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1506 dwAppID
= GetCurrentProcessId();
1508 DPLAYX_CreateLobbyApplication( dwAppID
);
1509 hr
= DPLAYX_SetConnectionSettingsW( dwFlags
, dwAppID
, lpConn
);
1512 LeaveCriticalSection( &This
->lock
);
1517 static HRESULT WINAPI
IDirectPlayLobbyAImpl_SetConnectionSettings( IDirectPlayLobbyA
*iface
,
1518 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1520 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1521 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, flags
,
1525 static HRESULT WINAPI
IDirectPlayLobbyImpl_SetConnectionSettings( IDirectPlayLobby
*iface
,
1526 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1528 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1529 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3_iface
, flags
,
1533 static HRESULT WINAPI
IDirectPlayLobby2AImpl_SetConnectionSettings( IDirectPlayLobby2A
*iface
,
1534 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1536 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1537 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, flags
,
1541 static HRESULT WINAPI
IDirectPlayLobby2Impl_SetConnectionSettings( IDirectPlayLobby2
*iface
,
1542 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1544 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1545 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3_iface
, flags
,
1549 static HRESULT WINAPI
IDirectPlayLobby3AImpl_SetConnectionSettings( IDirectPlayLobby3A
*iface
,
1550 DWORD dwFlags
, DWORD dwAppID
, DPLCONNECTION
*lpConn
)
1552 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1555 TRACE("(%p)->(0x%08x,0x%08x,%p)\n", This
, dwFlags
, dwAppID
, lpConn
);
1557 EnterCriticalSection( &This
->lock
);
1559 hr
= DPLAYX_SetConnectionSettingsA( dwFlags
, dwAppID
, lpConn
);
1561 /* FIXME: Don't think that this is supposed to fail, but the documentation
1562 is somewhat sketchy. I'll try creating a lobby application
1564 if( hr
== DPERR_NOTLOBBIED
)
1566 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1567 dwAppID
= GetCurrentProcessId();
1568 DPLAYX_CreateLobbyApplication( dwAppID
);
1569 hr
= DPLAYX_SetConnectionSettingsA( dwFlags
, dwAppID
, lpConn
);
1572 LeaveCriticalSection( &This
->lock
);
1577 /********************************************************************
1579 * Registers an event that will be set when a lobby message is received.
1582 static HRESULT WINAPI
IDirectPlayLobbyAImpl_SetLobbyMessageEvent( IDirectPlayLobbyA
*iface
,
1583 DWORD flags
, DWORD appid
, HANDLE event
)
1585 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1586 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1590 static HRESULT WINAPI
IDirectPlayLobbyImpl_SetLobbyMessageEvent( IDirectPlayLobby
*iface
,
1591 DWORD flags
, DWORD appid
, HANDLE event
)
1593 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1594 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1598 static HRESULT WINAPI
IDirectPlayLobby2AImpl_SetLobbyMessageEvent( IDirectPlayLobby2A
*iface
,
1599 DWORD flags
, DWORD appid
, HANDLE event
)
1601 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1602 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1606 static HRESULT WINAPI
IDirectPlayLobby2Impl_SetLobbyMessageEvent( IDirectPlayLobby2
*iface
,
1607 DWORD flags
, DWORD appid
, HANDLE event
)
1609 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1610 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1614 static HRESULT WINAPI
IDirectPlayLobby3AImpl_SetLobbyMessageEvent( IDirectPlayLobby3A
*iface
,
1615 DWORD flags
, DWORD appid
, HANDLE event
)
1618 return DPERR_OUTOFMEMORY
;
1621 static HRESULT WINAPI
IDirectPlayLobby3Impl_SetLobbyMessageEvent( IDirectPlayLobby3
*iface
,
1622 DWORD flags
, DWORD appid
, HANDLE event
)
1625 return DPERR_OUTOFMEMORY
;
1630 static HRESULT WINAPI
IDirectPlayLobby2AImpl_CreateCompoundAddress( IDirectPlayLobby2A
*iface
,
1631 const DPCOMPOUNDADDRESSELEMENT
*elements
, DWORD count
, void *address
, DWORD
*size
)
1633 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1634 return IDirectPlayLobby_CreateCompoundAddress( &This
->IDirectPlayLobby3A_iface
, elements
,
1635 count
, address
, size
);
1638 static HRESULT WINAPI
IDirectPlayLobby2Impl_CreateCompoundAddress( IDirectPlayLobby2
*iface
,
1639 const DPCOMPOUNDADDRESSELEMENT
*elements
, DWORD count
, void *address
, DWORD
*size
)
1641 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1642 return IDirectPlayLobby_CreateCompoundAddress( &This
->IDirectPlayLobby3_iface
, elements
,
1643 count
, address
, size
);
1646 static HRESULT WINAPI
IDirectPlayLobby3Impl_CreateCompoundAddress( IDirectPlayLobby3
*iface
,
1647 const DPCOMPOUNDADDRESSELEMENT
*lpElements
, DWORD dwElementCount
, void *lpAddress
,
1648 DWORD
*lpdwAddressSize
)
1650 return DPL_CreateCompoundAddress( lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
, FALSE
);
1653 static HRESULT WINAPI
IDirectPlayLobby3AImpl_CreateCompoundAddress( IDirectPlayLobby3A
*iface
,
1654 const DPCOMPOUNDADDRESSELEMENT
*lpElements
, DWORD dwElementCount
, void *lpAddress
,
1655 DWORD
*lpdwAddressSize
)
1657 return DPL_CreateCompoundAddress( lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
, TRUE
);
1660 HRESULT DPL_CreateCompoundAddress
1661 ( LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1662 DWORD dwElementCount
,
1664 LPDWORD lpdwAddressSize
,
1665 BOOL bAnsiInterface
)
1667 DWORD dwSizeRequired
= 0;
1669 LPCDPCOMPOUNDADDRESSELEMENT lpOrigElements
= lpElements
;
1671 TRACE("(%p,0x%08x,%p,%p)\n", lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
);
1673 /* Parameter check */
1674 if( ( lpElements
== NULL
) ||
1675 ( dwElementCount
== 0 ) /* FIXME: Not sure if this is a failure case */
1678 return DPERR_INVALIDPARAMS
;
1681 /* Add the total size chunk */
1682 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( DWORD
);
1684 /* Calculate the size of the buffer required */
1685 for ( dwElements
= dwElementCount
; dwElements
> 0; --dwElements
, ++lpElements
)
1687 if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ServiceProvider
) ) ||
1688 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_LobbyProvider
) )
1691 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( GUID
);
1693 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Phone
) ) ||
1694 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Modem
) ) ||
1695 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INet
) )
1698 if( !bAnsiInterface
)
1700 ERR( "Ansi GUIDs used for unicode interface\n" );
1701 return DPERR_INVALIDFLAGS
;
1704 dwSizeRequired
+= sizeof( DPADDRESS
) + lpElements
->dwDataSize
;
1706 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_PhoneW
) ) ||
1707 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ModemW
) ) ||
1708 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetW
) )
1711 if( bAnsiInterface
)
1713 ERR( "Unicode GUIDs used for ansi interface\n" );
1714 return DPERR_INVALIDFLAGS
;
1717 FIXME( "Right size for unicode interface?\n" );
1718 dwSizeRequired
+= sizeof( DPADDRESS
) + lpElements
->dwDataSize
* sizeof( WCHAR
);
1720 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetPort
) )
1722 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( WORD
);
1724 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ComPort
) )
1726 FIXME( "Right size for unicode interface?\n" );
1727 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( DPCOMPORTADDRESS
); /* FIXME: Right size? */
1731 ERR( "Unknown GUID %s\n", debugstr_guid(&lpElements
->guidDataType
) );
1732 return DPERR_INVALIDFLAGS
;
1736 /* The user wants to know how big a buffer to allocate for us */
1737 if( ( lpAddress
== NULL
) ||
1738 ( *lpdwAddressSize
< dwSizeRequired
)
1741 *lpdwAddressSize
= dwSizeRequired
;
1742 return DPERR_BUFFERTOOSMALL
;
1745 /* Add the total size chunk */
1747 LPDPADDRESS lpdpAddress
= lpAddress
;
1749 lpdpAddress
->guidDataType
= DPAID_TotalSize
;
1750 lpdpAddress
->dwDataSize
= sizeof( DWORD
);
1751 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1753 *(LPDWORD
)lpAddress
= dwSizeRequired
;
1754 lpAddress
= (char *) lpAddress
+ sizeof( DWORD
);
1757 /* Calculate the size of the buffer required */
1758 for( dwElements
= dwElementCount
, lpElements
= lpOrigElements
;
1760 --dwElements
, ++lpElements
)
1762 if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ServiceProvider
) ) ||
1763 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_LobbyProvider
) )
1766 LPDPADDRESS lpdpAddress
= lpAddress
;
1768 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1769 lpdpAddress
->dwDataSize
= sizeof( GUID
);
1770 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1772 CopyMemory( lpAddress
, lpElements
->lpData
, sizeof( GUID
) );
1773 lpAddress
= (char *) lpAddress
+ sizeof( GUID
);
1775 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Phone
) ) ||
1776 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Modem
) ) ||
1777 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INet
) )
1780 LPDPADDRESS lpdpAddress
= lpAddress
;
1782 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1783 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1784 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1786 lstrcpynA( lpAddress
, lpElements
->lpData
, lpElements
->dwDataSize
);
1787 lpAddress
= (char *) lpAddress
+ lpElements
->dwDataSize
;
1789 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_PhoneW
) ) ||
1790 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ModemW
) ) ||
1791 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetW
) )
1794 LPDPADDRESS lpdpAddress
= lpAddress
;
1796 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1797 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1798 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1800 lstrcpynW( lpAddress
, lpElements
->lpData
, lpElements
->dwDataSize
);
1801 lpAddress
= (char *) lpAddress
+ lpElements
->dwDataSize
* sizeof( WCHAR
);
1803 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetPort
) )
1805 LPDPADDRESS lpdpAddress
= lpAddress
;
1807 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1808 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1809 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1811 *((LPWORD
)lpAddress
) = *((LPWORD
)lpElements
->lpData
);
1812 lpAddress
= (char *) lpAddress
+ sizeof( WORD
);
1814 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ComPort
) )
1816 LPDPADDRESS lpdpAddress
= lpAddress
;
1818 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1819 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1820 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1822 CopyMemory( lpAddress
, lpElements
->lpData
, sizeof( DPADDRESS
) );
1823 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1832 static HRESULT WINAPI
IDirectPlayLobby3Impl_ConnectEx( IDirectPlayLobby3
*iface
, DWORD dwFlags
,
1833 REFIID riid
, LPVOID
* lplpDP
, IUnknown
* pUnk
)
1835 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1836 return DPL_ConnectEx( This
, dwFlags
, riid
, lplpDP
, pUnk
);
1839 static HRESULT WINAPI
IDirectPlayLobby3AImpl_ConnectEx( IDirectPlayLobby3A
*iface
, DWORD dwFlags
,
1840 REFIID riid
, void **lplpDP
, IUnknown
*pUnk
)
1842 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1843 return DPL_ConnectEx( This
, dwFlags
, riid
, lplpDP
, pUnk
);
1846 static HRESULT WINAPI
IDirectPlayLobby3Impl_RegisterApplication( IDirectPlayLobby3
*iface
,
1847 DWORD flags
, DPAPPLICATIONDESC
*appdesc
)
1853 static HRESULT WINAPI
IDirectPlayLobby3AImpl_RegisterApplication( IDirectPlayLobby3A
*iface
,
1854 DWORD flags
, DPAPPLICATIONDESC
*appdesc
)
1860 static HRESULT WINAPI
IDirectPlayLobby3Impl_UnregisterApplication( IDirectPlayLobby3
*iface
,
1861 DWORD flags
, REFGUID appdesc
)
1867 static HRESULT WINAPI
IDirectPlayLobby3AImpl_UnregisterApplication( IDirectPlayLobby3A
*iface
,
1868 DWORD flags
, REFGUID appdesc
)
1874 static HRESULT WINAPI
IDirectPlayLobby3Impl_WaitForConnectionSettings( IDirectPlayLobby3
*iface
,
1878 BOOL bStartWait
= !(dwFlags
& DPLWAIT_CANCEL
);
1880 TRACE( "(%p)->(0x%08x)\n", iface
, dwFlags
);
1882 if( DPLAYX_WaitForConnectionSettings( bStartWait
) )
1884 /* FIXME: What is the correct error return code? */
1885 hr
= DPERR_NOTLOBBIED
;
1891 static HRESULT WINAPI
IDirectPlayLobby3AImpl_WaitForConnectionSettings( IDirectPlayLobby3A
*iface
,
1895 BOOL bStartWait
= !(dwFlags
& DPLWAIT_CANCEL
);
1897 TRACE( "(%p)->(0x%08x)\n", iface
, dwFlags
);
1899 if( DPLAYX_WaitForConnectionSettings( bStartWait
) )
1901 /* FIXME: What is the correct error return code? */
1902 hr
= DPERR_NOTLOBBIED
;
1908 static const IDirectPlayLobbyVtbl dplA_vt
=
1910 IDirectPlayLobbyAImpl_QueryInterface
,
1911 IDirectPlayLobbyAImpl_AddRef
,
1912 IDirectPlayLobbyAImpl_Release
,
1913 IDirectPlayLobbyAImpl_Connect
,
1914 IDirectPlayLobbyAImpl_CreateAddress
,
1915 IDirectPlayLobbyAImpl_EnumAddress
,
1916 IDirectPlayLobbyAImpl_EnumAddressTypes
,
1917 IDirectPlayLobbyAImpl_EnumLocalApplications
,
1918 IDirectPlayLobbyAImpl_GetConnectionSettings
,
1919 IDirectPlayLobbyAImpl_ReceiveLobbyMessage
,
1920 IDirectPlayLobbyAImpl_RunApplication
,
1921 IDirectPlayLobbyAImpl_SendLobbyMessage
,
1922 IDirectPlayLobbyAImpl_SetConnectionSettings
,
1923 IDirectPlayLobbyAImpl_SetLobbyMessageEvent
1926 static const IDirectPlayLobbyVtbl dpl_vt
=
1928 IDirectPlayLobbyImpl_QueryInterface
,
1929 IDirectPlayLobbyImpl_AddRef
,
1930 IDirectPlayLobbyImpl_Release
,
1931 IDirectPlayLobbyImpl_Connect
,
1932 IDirectPlayLobbyImpl_CreateAddress
,
1933 IDirectPlayLobbyImpl_EnumAddress
,
1934 IDirectPlayLobbyImpl_EnumAddressTypes
,
1935 IDirectPlayLobbyImpl_EnumLocalApplications
,
1936 IDirectPlayLobbyImpl_GetConnectionSettings
,
1937 IDirectPlayLobbyImpl_ReceiveLobbyMessage
,
1938 IDirectPlayLobbyImpl_RunApplication
,
1939 IDirectPlayLobbyImpl_SendLobbyMessage
,
1940 IDirectPlayLobbyImpl_SetConnectionSettings
,
1941 IDirectPlayLobbyImpl_SetLobbyMessageEvent
1944 static const IDirectPlayLobby2Vtbl dpl2A_vt
=
1946 IDirectPlayLobby2AImpl_QueryInterface
,
1947 IDirectPlayLobby2AImpl_AddRef
,
1948 IDirectPlayLobby2AImpl_Release
,
1949 IDirectPlayLobby2AImpl_Connect
,
1950 IDirectPlayLobby2AImpl_CreateAddress
,
1951 IDirectPlayLobby2AImpl_EnumAddress
,
1952 IDirectPlayLobby2AImpl_EnumAddressTypes
,
1953 IDirectPlayLobby2AImpl_EnumLocalApplications
,
1954 IDirectPlayLobby2AImpl_GetConnectionSettings
,
1955 IDirectPlayLobby2AImpl_ReceiveLobbyMessage
,
1956 IDirectPlayLobby2AImpl_RunApplication
,
1957 IDirectPlayLobby2AImpl_SendLobbyMessage
,
1958 IDirectPlayLobby2AImpl_SetConnectionSettings
,
1959 IDirectPlayLobby2AImpl_SetLobbyMessageEvent
,
1960 IDirectPlayLobby2AImpl_CreateCompoundAddress
1963 static const IDirectPlayLobby2Vtbl dpl2_vt
=
1965 IDirectPlayLobby2Impl_QueryInterface
,
1966 IDirectPlayLobby2Impl_AddRef
,
1967 IDirectPlayLobby2Impl_Release
,
1968 IDirectPlayLobby2Impl_Connect
,
1969 IDirectPlayLobby2Impl_CreateAddress
,
1970 IDirectPlayLobby2Impl_EnumAddress
,
1971 IDirectPlayLobby2Impl_EnumAddressTypes
,
1972 IDirectPlayLobby2Impl_EnumLocalApplications
,
1973 IDirectPlayLobby2Impl_GetConnectionSettings
,
1974 IDirectPlayLobby2Impl_ReceiveLobbyMessage
,
1975 IDirectPlayLobby2Impl_RunApplication
,
1976 IDirectPlayLobby2Impl_SendLobbyMessage
,
1977 IDirectPlayLobby2Impl_SetConnectionSettings
,
1978 IDirectPlayLobby2Impl_SetLobbyMessageEvent
,
1979 IDirectPlayLobby2Impl_CreateCompoundAddress
1982 static const IDirectPlayLobby3Vtbl dpl3A_vt
=
1984 IDirectPlayLobby3AImpl_QueryInterface
,
1985 IDirectPlayLobby3AImpl_AddRef
,
1986 IDirectPlayLobby3AImpl_Release
,
1987 IDirectPlayLobby3AImpl_Connect
,
1988 IDirectPlayLobby3AImpl_CreateAddress
,
1989 IDirectPlayLobby3AImpl_EnumAddress
,
1990 IDirectPlayLobby3AImpl_EnumAddressTypes
,
1991 IDirectPlayLobby3AImpl_EnumLocalApplications
,
1992 IDirectPlayLobby3AImpl_GetConnectionSettings
,
1993 IDirectPlayLobby3AImpl_ReceiveLobbyMessage
,
1994 IDirectPlayLobby3AImpl_RunApplication
,
1995 IDirectPlayLobby3AImpl_SendLobbyMessage
,
1996 IDirectPlayLobby3AImpl_SetConnectionSettings
,
1997 IDirectPlayLobby3AImpl_SetLobbyMessageEvent
,
1998 IDirectPlayLobby3AImpl_CreateCompoundAddress
,
1999 IDirectPlayLobby3AImpl_ConnectEx
,
2000 IDirectPlayLobby3AImpl_RegisterApplication
,
2001 IDirectPlayLobby3AImpl_UnregisterApplication
,
2002 IDirectPlayLobby3AImpl_WaitForConnectionSettings
2005 static const IDirectPlayLobby3Vtbl dpl3_vt
=
2007 IDirectPlayLobby3Impl_QueryInterface
,
2008 IDirectPlayLobby3Impl_AddRef
,
2009 IDirectPlayLobby3Impl_Release
,
2010 IDirectPlayLobby3Impl_Connect
,
2011 IDirectPlayLobby3Impl_CreateAddress
,
2012 IDirectPlayLobby3Impl_EnumAddress
,
2013 IDirectPlayLobby3Impl_EnumAddressTypes
,
2014 IDirectPlayLobby3Impl_EnumLocalApplications
,
2015 IDirectPlayLobby3Impl_GetConnectionSettings
,
2016 IDirectPlayLobby3Impl_ReceiveLobbyMessage
,
2017 IDirectPlayLobby3Impl_RunApplication
,
2018 IDirectPlayLobby3Impl_SendLobbyMessage
,
2019 IDirectPlayLobby3Impl_SetConnectionSettings
,
2020 IDirectPlayLobby3Impl_SetLobbyMessageEvent
,
2021 IDirectPlayLobby3Impl_CreateCompoundAddress
,
2022 IDirectPlayLobby3Impl_ConnectEx
,
2023 IDirectPlayLobby3Impl_RegisterApplication
,
2024 IDirectPlayLobby3Impl_UnregisterApplication
,
2025 IDirectPlayLobby3Impl_WaitForConnectionSettings
2028 HRESULT
dplobby_create( REFIID riid
, void **ppv
)
2030 IDirectPlayLobbyImpl
*obj
;
2033 TRACE( "(%s, %p)\n", debugstr_guid( riid
), ppv
);
2036 obj
= HeapAlloc( GetProcessHeap(), 0, sizeof( *obj
) );
2038 return DPERR_OUTOFMEMORY
;
2040 obj
->IDirectPlayLobby_iface
.lpVtbl
= &dpl_vt
;
2041 obj
->IDirectPlayLobbyA_iface
.lpVtbl
= &dplA_vt
;
2042 obj
->IDirectPlayLobby2_iface
.lpVtbl
= &dpl2_vt
;
2043 obj
->IDirectPlayLobby2A_iface
.lpVtbl
= &dpl2A_vt
;
2044 obj
->IDirectPlayLobby3_iface
.lpVtbl
= &dpl3_vt
;
2045 obj
->IDirectPlayLobby3A_iface
.lpVtbl
= &dpl3A_vt
;
2055 InitializeCriticalSection( &obj
->lock
);
2056 obj
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": IDirectPlayLobbyImpl.lock");
2057 DPQ_INIT( obj
->msgs
);
2059 hr
= IDirectPlayLobby_QueryInterface( &obj
->IDirectPlayLobby3_iface
, riid
, ppv
);
2060 IDirectPlayLobby_Release( &obj
->IDirectPlayLobby3_iface
);
2067 /***************************************************************************
2068 * DirectPlayLobbyCreateA (DPLAYX.4)
2071 HRESULT WINAPI
DirectPlayLobbyCreateA( GUID
*lpGUIDDSP
, IDirectPlayLobbyA
**lplpDPL
,
2072 IUnknown
*lpUnk
, void *lpData
, DWORD dwDataSize
)
2074 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08x\n",
2075 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
2077 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
2078 * equal 0. These fields are mostly for future expansion.
2080 if ( lpGUIDDSP
|| lpData
|| dwDataSize
)
2083 return DPERR_INVALIDPARAMS
;
2089 ERR("Bad parameters!\n" );
2090 return CLASS_E_NOAGGREGATION
;
2093 return dplobby_create( &IID_IDirectPlayLobbyA
, (void**)lplpDPL
);
2096 /***************************************************************************
2097 * DirectPlayLobbyCreateW (DPLAYX.5)
2100 HRESULT WINAPI
DirectPlayLobbyCreateW( GUID
*lpGUIDDSP
, IDirectPlayLobby
**lplpDPL
,
2101 IUnknown
*lpUnk
, void *lpData
, DWORD dwDataSize
)
2103 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08x\n",
2104 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
2106 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
2107 * equal 0. These fields are mostly for future expansion.
2109 if ( lpGUIDDSP
|| lpData
|| dwDataSize
)
2112 ERR("Bad parameters!\n" );
2113 return DPERR_INVALIDPARAMS
;
2119 ERR("Bad parameters!\n" );
2120 return CLASS_E_NOAGGREGATION
;
2123 return dplobby_create( &IID_IDirectPlayLobby
, (void**)lplpDPL
);