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
28 #include "wine/debug.h"
30 #include "dplayx_global.h"
31 #include "dplayx_messages.h"
32 #include "dplayx_queue.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(dplay
);
37 /* Forward declarations for this module helper methods */
38 HRESULT
DPL_CreateCompoundAddress ( LPCDPCOMPOUNDADDRESSELEMENT lpElements
, DWORD dwElementCount
,
39 LPVOID lpAddress
, LPDWORD lpdwAddressSize
, BOOL bAnsiInterface
);
41 static HRESULT
DPL_CreateAddress( REFGUID guidSP
, REFGUID guidDataType
, LPCVOID lpData
, DWORD dwDataSize
,
42 LPVOID lpAddress
, LPDWORD lpdwAddressSize
, BOOL bAnsiInterface
);
45 /*****************************************************************************
46 * IDirectPlayLobby {1,2,3} implementation structure
48 * The philosophy behind this extra pointer dereference is that I wanted to
49 * have the same structure for all types of objects without having to do
50 * a lot of casting. I also only wanted to implement an interface in the
51 * object it was "released" with IUnknown interface being implemented in the 1 version.
52 * Of course, with these new interfaces comes the data required to keep the state required
53 * by these interfaces. So, basically, the pointers contain the data associated with
54 * a release. If you use the data associated with release 3 in a release 2 object, you'll
55 * get a run time trap, as that won't have any data.
60 DPQ_ENTRY( DPLMSG
) msgs
; /* Link to next queued message */
62 typedef struct DPLMSG
* LPDPLMSG
;
64 typedef struct IDirectPlayLobbyImpl
66 IDirectPlayLobby IDirectPlayLobby_iface
;
67 IDirectPlayLobbyA IDirectPlayLobbyA_iface
;
68 IDirectPlayLobby2 IDirectPlayLobby2_iface
;
69 IDirectPlayLobby2A IDirectPlayLobby2A_iface
;
70 IDirectPlayLobby3 IDirectPlayLobby3_iface
;
71 IDirectPlayLobby3A IDirectPlayLobby3A_iface
;
72 LONG numIfaces
; /* "in use interfaces" refcount */
73 LONG ref
, refA
, ref2
, ref2A
, ref3
, ref3A
;
74 CRITICAL_SECTION lock
;
77 DPQ_HEAD( DPLMSG
) msgs
; /* List of messages received */
78 } IDirectPlayLobbyImpl
;
80 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobby( IDirectPlayLobby
*iface
)
82 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobby_iface
);
85 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobbyA( IDirectPlayLobbyA
*iface
)
87 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobbyA_iface
);
90 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobby2( IDirectPlayLobby2
*iface
)
92 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobby2_iface
);
95 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobby2A( IDirectPlayLobby2A
*iface
)
97 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobby2A_iface
);
100 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobby3( IDirectPlayLobby3
*iface
)
102 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobby3_iface
);
105 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobby3A( IDirectPlayLobby3A
*iface
)
107 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobby3A_iface
);
110 static void dplobby_destroy(IDirectPlayLobbyImpl
*obj
)
113 FIXME( "Should kill the msg thread\n" );
115 DPQ_DELETEQ( obj
->msgs
, msgs
, LPDPLMSG
, cbDeleteElemFromHeap
);
116 obj
->lock
.DebugInfo
->Spare
[0] = 0;
117 DeleteCriticalSection( &obj
->lock
);
121 static HRESULT WINAPI
IDirectPlayLobbyAImpl_QueryInterface( IDirectPlayLobbyA
*iface
, REFIID riid
,
124 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
125 return IDirectPlayLobby_QueryInterface( &This
->IDirectPlayLobby3_iface
, riid
, ppv
);
128 static HRESULT WINAPI
IDirectPlayLobbyImpl_QueryInterface( IDirectPlayLobby
*iface
, REFIID riid
,
131 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
132 return IDirectPlayLobby_QueryInterface( &This
->IDirectPlayLobby3_iface
, riid
, ppv
);
135 static HRESULT WINAPI
IDirectPlayLobby2AImpl_QueryInterface( IDirectPlayLobby2A
*iface
, REFIID riid
,
138 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
139 return IDirectPlayLobby_QueryInterface( &This
->IDirectPlayLobby3_iface
, riid
, ppv
);
142 static HRESULT WINAPI
IDirectPlayLobby2Impl_QueryInterface( IDirectPlayLobby2
*iface
, REFIID riid
,
145 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
146 return IDirectPlayLobby_QueryInterface( &This
->IDirectPlayLobby3_iface
, riid
, ppv
);
149 static HRESULT WINAPI
IDirectPlayLobby3AImpl_QueryInterface( IDirectPlayLobby3A
*iface
, REFIID riid
,
152 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
153 return IDirectPlayLobby_QueryInterface( &This
->IDirectPlayLobby3_iface
, riid
, ppv
);
156 static HRESULT WINAPI
IDirectPlayLobby3Impl_QueryInterface( IDirectPlayLobby3
*iface
, REFIID riid
,
159 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
161 if ( IsEqualGUID( &IID_IUnknown
, riid
) )
163 TRACE( "(%p)->(IID_IUnknown %p)\n", This
, ppv
);
164 *ppv
= &This
->IDirectPlayLobby_iface
;
166 else if ( IsEqualGUID( &IID_IDirectPlayLobby
, riid
) )
168 TRACE( "(%p)->(IID_IDirectPlayLobby %p)\n", This
, ppv
);
169 *ppv
= &This
->IDirectPlayLobby_iface
;
171 else if ( IsEqualGUID( &IID_IDirectPlayLobbyA
, riid
) )
173 TRACE( "(%p)->(IID_IDirectPlayLobbyA %p)\n", This
, ppv
);
174 *ppv
= &This
->IDirectPlayLobbyA_iface
;
176 else if ( IsEqualGUID( &IID_IDirectPlayLobby2
, riid
) )
178 TRACE( "(%p)->(IID_IDirectPlayLobby2 %p)\n", This
, ppv
);
179 *ppv
= &This
->IDirectPlayLobby2_iface
;
181 else if ( IsEqualGUID( &IID_IDirectPlayLobby2A
, riid
) )
183 TRACE( "(%p)->(IID_IDirectPlayLobby2A %p)\n", This
, ppv
);
184 *ppv
= &This
->IDirectPlayLobby2A_iface
;
186 else if ( IsEqualGUID( &IID_IDirectPlayLobby3
, riid
) )
188 TRACE( "(%p)->(IID_IDirectPlay3 %p)\n", This
, ppv
);
189 *ppv
= &This
->IDirectPlayLobby3_iface
;
191 else if ( IsEqualGUID( &IID_IDirectPlayLobby3A
, riid
) )
193 TRACE( "(%p)->(IID_IDirectPlayLobby3A %p)\n", This
, ppv
);
194 *ppv
= &This
->IDirectPlayLobby3A_iface
;
198 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
200 return E_NOINTERFACE
;
203 IUnknown_AddRef((IUnknown
*)*ppv
);
207 static ULONG WINAPI
IDirectPlayLobbyAImpl_AddRef( IDirectPlayLobbyA
*iface
)
209 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
210 ULONG ref
= InterlockedIncrement( &This
->refA
);
212 TRACE( "(%p) refA=%ld\n", This
, ref
);
215 InterlockedIncrement( &This
->numIfaces
);
220 static ULONG WINAPI
IDirectPlayLobbyImpl_AddRef( IDirectPlayLobby
*iface
)
222 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
223 ULONG ref
= InterlockedIncrement( &This
->ref
);
225 TRACE( "(%p) ref=%ld\n", This
, ref
);
228 InterlockedIncrement( &This
->numIfaces
);
233 static ULONG WINAPI
IDirectPlayLobby2AImpl_AddRef(IDirectPlayLobby2A
*iface
)
235 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
236 ULONG ref
= InterlockedIncrement( &This
->ref2A
);
238 TRACE( "(%p) ref2A=%ld\n", This
, ref
);
241 InterlockedIncrement( &This
->numIfaces
);
246 static ULONG WINAPI
IDirectPlayLobby2Impl_AddRef(IDirectPlayLobby2
*iface
)
248 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
249 ULONG ref
= InterlockedIncrement( &This
->ref2
);
251 TRACE( "(%p) ref2=%ld\n", This
, ref
);
254 InterlockedIncrement( &This
->numIfaces
);
259 static ULONG WINAPI
IDirectPlayLobby3AImpl_AddRef(IDirectPlayLobby3A
*iface
)
261 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
262 ULONG ref
= InterlockedIncrement( &This
->ref3A
);
264 TRACE( "(%p) ref3A=%ld\n", This
, ref
);
267 InterlockedIncrement( &This
->numIfaces
);
272 static ULONG WINAPI
IDirectPlayLobby3Impl_AddRef(IDirectPlayLobby3
*iface
)
274 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
275 ULONG ref
= InterlockedIncrement( &This
->ref3
);
277 TRACE( "(%p) ref3=%ld\n", This
, ref
);
280 InterlockedIncrement( &This
->numIfaces
);
285 static ULONG WINAPI
IDirectPlayLobbyAImpl_Release( IDirectPlayLobbyA
*iface
)
287 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
288 ULONG ref
= InterlockedDecrement( &This
->refA
);
290 TRACE( "(%p) refA=%ld\n", This
, ref
);
292 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
293 dplobby_destroy( This
);
298 static ULONG WINAPI
IDirectPlayLobbyImpl_Release( IDirectPlayLobby
*iface
)
300 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
301 ULONG ref
= InterlockedDecrement( &This
->ref
);
303 TRACE( "(%p) ref=%ld\n", This
, ref
);
305 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
306 dplobby_destroy( This
);
311 static ULONG WINAPI
IDirectPlayLobby2AImpl_Release(IDirectPlayLobby2A
*iface
)
313 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
314 ULONG ref
= InterlockedDecrement( &This
->ref2A
);
316 TRACE( "(%p) ref2A=%ld\n", This
, ref
);
318 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
319 dplobby_destroy( This
);
324 static ULONG WINAPI
IDirectPlayLobby2Impl_Release(IDirectPlayLobby2
*iface
)
326 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
327 ULONG ref
= InterlockedDecrement( &This
->ref2
);
329 TRACE( "(%p) ref2=%ld\n", This
, ref
);
331 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
332 dplobby_destroy( This
);
337 static ULONG WINAPI
IDirectPlayLobby3AImpl_Release(IDirectPlayLobby3A
*iface
)
339 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
340 ULONG ref
= InterlockedDecrement( &This
->ref3A
);
342 TRACE( "(%p) ref3A=%ld\n", This
, ref
);
344 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
345 dplobby_destroy( This
);
350 static ULONG WINAPI
IDirectPlayLobby3Impl_Release(IDirectPlayLobby3
*iface
)
352 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
353 ULONG ref
= InterlockedDecrement( &This
->ref3
);
355 TRACE( "(%p) ref3=%ld\n", This
, ref
);
357 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
358 dplobby_destroy( This
);
364 /********************************************************************
366 * Connects an application to the session specified by the DPLCONNECTION
367 * structure currently stored with the DirectPlayLobby object.
369 * Returns an IDirectPlay interface.
372 static HRESULT
DPL_ConnectEx( IDirectPlayLobbyImpl
*This
, DWORD dwFlags
, REFIID riid
, void **lplpDP
,
376 DWORD dwOpenFlags
= 0;
377 DWORD dwConnSize
= 0;
378 LPDPLCONNECTION lpConn
;
380 FIXME("(%p)->(0x%08lx,%p,%p): semi stub\n", This
, dwFlags
, lplpDP
, pUnk
);
384 return DPERR_INVALIDPARAMS
;
387 /* Backwards compatibility */
390 dwFlags
= DPCONNECT_RETURNSTATUS
;
393 if ( ( hr
= dplay_create( riid
, lplpDP
) ) != DP_OK
)
395 ERR( "error creating interface for %s:%s.\n",
396 debugstr_guid( riid
), DPLAYX_HresultToString( hr
) );
400 /* FIXME: Is it safe/correct to use appID of 0? */
401 hr
= IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3_iface
,
402 0, NULL
, &dwConnSize
);
403 if( hr
!= DPERR_BUFFERTOOSMALL
)
408 lpConn
= calloc( 1, dwConnSize
);
412 return DPERR_NOMEMORY
;
415 /* FIXME: Is it safe/correct to use appID of 0? */
416 hr
= IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3_iface
,
417 0, lpConn
, &dwConnSize
);
425 /* - Need to call IDirectPlay::EnumConnections with the service provider to get that good information
426 * - Need to call CreateAddress to create the lpConnection param for IDirectPlay::InitializeConnection
427 * - Call IDirectPlay::InitializeConnection
430 /* Now initialize the Service Provider */
431 hr
= IDirectPlayX_InitializeConnection( (*(LPDIRECTPLAY2
*)lplpDP
),
435 /* Setup flags to pass into DirectPlay::Open */
436 if( dwFlags
& DPCONNECT_RETURNSTATUS
)
438 dwOpenFlags
|= DPOPEN_RETURNSTATUS
;
440 dwOpenFlags
|= lpConn
->dwFlags
;
442 hr
= IDirectPlayX_Open( (*(LPDIRECTPLAY2
*)lplpDP
), lpConn
->lpSessionDesc
,
450 static HRESULT WINAPI
IDirectPlayLobbyAImpl_Connect( IDirectPlayLobbyA
*iface
, DWORD flags
,
451 IDirectPlay2A
**dp
, IUnknown
*unk
)
453 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
454 return IDirectPlayLobby_Connect( &This
->IDirectPlayLobby3A_iface
, flags
, dp
, unk
);
457 static HRESULT WINAPI
IDirectPlayLobbyImpl_Connect( IDirectPlayLobby
*iface
, DWORD flags
,
458 IDirectPlay2A
**dp
, IUnknown
*unk
)
460 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
461 return IDirectPlayLobby_Connect( &This
->IDirectPlayLobby3_iface
, flags
, dp
, unk
);
464 static HRESULT WINAPI
IDirectPlayLobby2AImpl_Connect( IDirectPlayLobby2A
*iface
, DWORD flags
,
465 IDirectPlay2A
**dp
, IUnknown
*unk
)
467 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
468 return IDirectPlayLobby_Connect( &This
->IDirectPlayLobby3A_iface
, flags
, dp
, unk
);
471 static HRESULT WINAPI
IDirectPlayLobby2Impl_Connect( IDirectPlayLobby2
*iface
, DWORD flags
,
472 IDirectPlay2A
**dp
, IUnknown
*unk
)
474 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
475 return IDirectPlayLobby_Connect( &This
->IDirectPlayLobby3_iface
, flags
, dp
, unk
);
478 static HRESULT WINAPI
IDirectPlayLobby3AImpl_Connect( IDirectPlayLobby3A
*iface
, DWORD flags
,
479 IDirectPlay2A
**dp
, IUnknown
*unk
)
481 return IDirectPlayLobby_ConnectEx( iface
, flags
, &IID_IDirectPlay2A
, (void**)dp
, unk
);
484 static HRESULT WINAPI
IDirectPlayLobby3Impl_Connect( IDirectPlayLobby3
*iface
, DWORD flags
,
485 IDirectPlay2
**dp
, IUnknown
*unk
)
487 return IDirectPlayLobby_ConnectEx( iface
, flags
, &IID_IDirectPlay2A
, (void**)dp
, unk
);
490 /********************************************************************
492 * Creates a DirectPlay Address, given a service provider-specific network
494 * Returns an address contains the globally unique identifier
495 * (GUID) of the service provider and data that the service provider can
496 * interpret as a network address.
498 * NOTE: It appears that this method is supposed to be really really stupid
499 * with no error checking on the contents.
501 static HRESULT WINAPI
IDirectPlayLobbyAImpl_CreateAddress( IDirectPlayLobbyA
*iface
, REFGUID sp
,
502 REFGUID datatype
, const void *data
, DWORD datasize
, void *address
, DWORD
*addrsize
)
504 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
505 return IDirectPlayLobby_CreateAddress( &This
->IDirectPlayLobby3A_iface
, sp
, datatype
, data
,
506 datasize
, address
, addrsize
);
509 static HRESULT WINAPI
IDirectPlayLobbyImpl_CreateAddress( IDirectPlayLobby
*iface
, REFGUID sp
,
510 REFGUID datatype
, const void *data
, DWORD datasize
, void *address
, DWORD
*addrsize
)
512 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
513 return IDirectPlayLobby_CreateAddress( &This
->IDirectPlayLobby3_iface
, sp
, datatype
, data
,
514 datasize
, address
, addrsize
);
517 static HRESULT WINAPI
IDirectPlayLobby2AImpl_CreateAddress( IDirectPlayLobby2A
*iface
, REFGUID sp
,
518 REFGUID datatype
, const void *data
, DWORD datasize
, void *address
, DWORD
*addrsize
)
520 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
521 return IDirectPlayLobby_CreateAddress( &This
->IDirectPlayLobby3A_iface
, sp
, datatype
, data
,
522 datasize
, address
, addrsize
);
525 static HRESULT WINAPI
IDirectPlayLobby2Impl_CreateAddress( IDirectPlayLobby2
*iface
, REFGUID sp
,
526 REFGUID datatype
, const void *data
, DWORD datasize
, void *address
, DWORD
*addrsize
)
528 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
529 return IDirectPlayLobby_CreateAddress( &This
->IDirectPlayLobby3_iface
, sp
, datatype
, data
,
530 datasize
, address
, addrsize
);
533 static HRESULT WINAPI
IDirectPlayLobby3AImpl_CreateAddress( IDirectPlayLobby3A
*iface
,
534 REFGUID guidSP
, REFGUID guidDataType
, const void *lpData
, DWORD dwDataSize
, void *lpAddress
,
535 DWORD
*lpdwAddressSize
)
537 return DPL_CreateAddress( guidSP
, guidDataType
, lpData
, dwDataSize
,
538 lpAddress
, lpdwAddressSize
, TRUE
);
541 static HRESULT WINAPI
IDirectPlayLobby3Impl_CreateAddress( IDirectPlayLobby3
*iface
, REFGUID guidSP
,
542 REFGUID guidDataType
, const void *lpData
, DWORD dwDataSize
, void *lpAddress
,
543 DWORD
*lpdwAddressSize
)
545 return DPL_CreateAddress( guidSP
, guidDataType
, lpData
, dwDataSize
,
546 lpAddress
, lpdwAddressSize
, FALSE
);
549 static HRESULT
DPL_CreateAddress(
551 REFGUID guidDataType
,
555 LPDWORD lpdwAddressSize
,
556 BOOL bAnsiInterface
)
558 const DWORD dwNumAddElements
= 2; /* Service Provide & address data type */
559 DPCOMPOUNDADDRESSELEMENT addressElements
[ 2 /* dwNumAddElements */ ];
561 TRACE( "(%p)->(%p,%p,0x%08lx,%p,%p,%d)\n", guidSP
, guidDataType
, lpData
, dwDataSize
,
562 lpAddress
, lpdwAddressSize
, bAnsiInterface
);
564 addressElements
[ 0 ].guidDataType
= DPAID_ServiceProvider
;
565 addressElements
[ 0 ].dwDataSize
= sizeof( GUID
);
566 addressElements
[ 0 ].lpData
= (LPVOID
)guidSP
;
568 addressElements
[ 1 ].guidDataType
= *guidDataType
;
569 addressElements
[ 1 ].dwDataSize
= dwDataSize
;
570 addressElements
[ 1 ].lpData
= (LPVOID
)lpData
;
572 /* Call CreateCompoundAddress to cut down on code.
573 NOTE: We can do this because we don't support DPL 1 interfaces! */
574 return DPL_CreateCompoundAddress( addressElements
, dwNumAddElements
,
575 lpAddress
, lpdwAddressSize
, bAnsiInterface
);
580 /********************************************************************
582 * Parses out chunks from the DirectPlay Address buffer by calling the
583 * given callback function, with lpContext, for each of the chunks.
586 static HRESULT WINAPI
IDirectPlayLobbyAImpl_EnumAddress( IDirectPlayLobbyA
*iface
,
587 LPDPENUMADDRESSCALLBACK enumaddrcb
, const void *address
, DWORD size
, void *context
)
589 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
590 return IDirectPlayLobby_EnumAddress( &This
->IDirectPlayLobby3A_iface
, enumaddrcb
, address
, size
,
594 static HRESULT WINAPI
IDirectPlayLobbyImpl_EnumAddress( IDirectPlayLobby
*iface
,
595 LPDPENUMADDRESSCALLBACK enumaddrcb
, const void *address
, DWORD size
, void *context
)
597 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
598 return IDirectPlayLobby_EnumAddress( &This
->IDirectPlayLobby3_iface
, enumaddrcb
, address
, size
,
602 static HRESULT WINAPI
IDirectPlayLobby2AImpl_EnumAddress( IDirectPlayLobby2A
*iface
,
603 LPDPENUMADDRESSCALLBACK enumaddrcb
, const void *address
, DWORD size
, void *context
)
605 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
606 return IDirectPlayLobby_EnumAddress( &This
->IDirectPlayLobby3A_iface
, enumaddrcb
, address
, size
,
610 static HRESULT WINAPI
IDirectPlayLobby2Impl_EnumAddress( IDirectPlayLobby2
*iface
,
611 LPDPENUMADDRESSCALLBACK enumaddrcb
, const void *address
, DWORD size
, void *context
)
613 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
614 return IDirectPlayLobby_EnumAddress( &This
->IDirectPlayLobby3_iface
, enumaddrcb
, address
, size
,
618 static HRESULT WINAPI
IDirectPlayLobby3AImpl_EnumAddress( IDirectPlayLobby3A
*iface
,
619 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
, const void *lpAddress
, DWORD dwAddressSize
,
622 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
624 TRACE("(%p)->(%p,%p,0x%08lx,%p)\n", This
, lpEnumAddressCallback
, lpAddress
,
625 dwAddressSize
, lpContext
);
627 return DPL_EnumAddress( lpEnumAddressCallback
, lpAddress
, dwAddressSize
, lpContext
);
630 static HRESULT WINAPI
IDirectPlayLobby3Impl_EnumAddress( IDirectPlayLobby3
*iface
,
631 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
, const void *lpAddress
, DWORD dwAddressSize
,
634 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
636 TRACE("(%p)->(%p,%p,0x%08lx,%p)\n", This
, lpEnumAddressCallback
, lpAddress
,
637 dwAddressSize
, lpContext
);
639 return DPL_EnumAddress( lpEnumAddressCallback
, lpAddress
, dwAddressSize
, lpContext
);
642 HRESULT
DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
, LPCVOID lpAddress
,
643 DWORD dwAddressSize
, LPVOID lpContext
)
645 DWORD dwTotalSizeEnumerated
= 0;
647 /* FIXME: First chunk is always the total size chunk - Should we report it? */
649 while ( dwTotalSizeEnumerated
< dwAddressSize
)
651 const DPADDRESS
* lpElements
= lpAddress
;
652 DWORD dwSizeThisEnumeration
;
654 /* Invoke the enum method. If false is returned, stop enumeration */
655 if ( !lpEnumAddressCallback( &lpElements
->guidDataType
,
656 lpElements
->dwDataSize
,
657 (const BYTE
*)lpElements
+ sizeof( DPADDRESS
),
663 dwSizeThisEnumeration
= sizeof( DPADDRESS
) + lpElements
->dwDataSize
;
664 lpAddress
= (const BYTE
*) lpAddress
+ dwSizeThisEnumeration
;
665 dwTotalSizeEnumerated
+= dwSizeThisEnumeration
;
671 /********************************************************************
673 * Enumerates all the address types that a given service provider needs to
674 * build the DirectPlay Address.
677 static HRESULT WINAPI
IDirectPlayLobbyAImpl_EnumAddressTypes( IDirectPlayLobbyA
*iface
,
678 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
680 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
681 return IDirectPlayLobby_EnumAddressTypes( &This
->IDirectPlayLobby3A_iface
, enumaddrtypecb
, sp
,
685 static HRESULT WINAPI
IDirectPlayLobbyImpl_EnumAddressTypes( IDirectPlayLobby
*iface
,
686 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
688 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
689 return IDirectPlayLobby_EnumAddressTypes( &This
->IDirectPlayLobby3_iface
, enumaddrtypecb
, sp
,
693 static HRESULT WINAPI
IDirectPlayLobby2AImpl_EnumAddressTypes( IDirectPlayLobby2A
*iface
,
694 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
696 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
697 return IDirectPlayLobby_EnumAddressTypes( &This
->IDirectPlayLobby3A_iface
, enumaddrtypecb
, sp
,
701 static HRESULT WINAPI
IDirectPlayLobby2Impl_EnumAddressTypes( IDirectPlayLobby2
*iface
,
702 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
704 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
705 return IDirectPlayLobby_EnumAddressTypes( &This
->IDirectPlayLobby3_iface
, enumaddrtypecb
, sp
,
709 static HRESULT WINAPI
IDirectPlayLobby3AImpl_EnumAddressTypes( IDirectPlayLobby3A
*iface
,
710 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
, REFGUID guidSP
, void *lpContext
,
713 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
716 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
717 DWORD dwIndex
, sizeOfSubKeyName
=50;
721 TRACE(" (%p)->(%p,%p,%p,0x%08lx)\n", This
, lpEnumAddressTypeCallback
, guidSP
, lpContext
, dwFlags
);
725 return DPERR_INVALIDPARAMS
;
728 if( !lpEnumAddressTypeCallback
)
730 return DPERR_INVALIDPARAMS
;
735 return DPERR_INVALIDOBJECT
;
738 /* Need to loop over the service providers in the registry */
739 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
740 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
742 /* Hmmm. Does this mean that there are no service providers? */
743 ERR(": no service providers?\n");
747 /* Traverse all the service providers we have available */
749 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
,
750 NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
751 ++dwIndex
, sizeOfSubKeyName
=50 )
754 HKEY hkServiceProvider
, hkServiceProviderAt
;
755 GUID serviceProviderGUID
;
756 DWORD returnTypeGUID
, sizeOfReturnBuffer
= 50;
758 char returnBuffer
[51];
761 LPCSTR atKey
= "Address Types";
762 LPCSTR guidDataSubKey
= "Guid";
764 TRACE(" this time through: %s\n", subKeyName
);
766 /* Get a handle for this particular service provider */
767 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
768 &hkServiceProvider
) != ERROR_SUCCESS
)
770 ERR(": what the heck is going on?\n" );
774 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
775 NULL
, &returnTypeGUID
, (LPBYTE
)returnBuffer
,
776 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
778 ERR(": missing GUID registry data members\n" );
782 /* FIXME: Check return types to ensure we're interpreting data right */
783 MultiByteToWideChar( CP_ACP
, 0, returnBuffer
, -1, buff
, ARRAY_SIZE( buff
));
784 CLSIDFromString( buff
, &serviceProviderGUID
);
785 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
787 /* Determine if this is the Service Provider that the user asked for */
788 if( !IsEqualGUID( &serviceProviderGUID
, guidSP
) )
793 /* Get a handle for this particular service provider */
794 if( RegOpenKeyExA( hkServiceProvider
, atKey
, 0, KEY_READ
,
795 &hkServiceProviderAt
) != ERROR_SUCCESS
)
797 TRACE(": No Address Types registry data sub key/members\n" );
801 /* Traverse all the address type we have available */
803 RegEnumKeyExA( hkServiceProviderAt
, dwAtIndex
, atSubKey
, &sizeOfSubKeyName
,
804 NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
805 ++dwAtIndex
, sizeOfSubKeyName
=50 )
807 TRACE( "Found Address Type GUID %s\n", atSubKey
);
809 /* FIXME: Check return types to ensure we're interpreting data right */
810 MultiByteToWideChar( CP_ACP
, 0, atSubKey
, -1, buff
, ARRAY_SIZE( buff
));
811 CLSIDFromString( buff
, &serviceProviderGUID
);
812 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
814 /* The enumeration will return FALSE if we are not to continue */
815 if( !lpEnumAddressTypeCallback( &serviceProviderGUID
, lpContext
, 0 ) )
817 WARN("lpEnumCallback returning FALSE\n" );
818 break; /* FIXME: This most likely has to break from the procedure...*/
823 /* We only enumerate address types for 1 GUID. We've found it, so quit looking */
830 static HRESULT WINAPI
IDirectPlayLobby3Impl_EnumAddressTypes( IDirectPlayLobby3
*iface
,
831 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
833 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
834 return IDirectPlayLobby_EnumAddressTypes( &This
->IDirectPlayLobby3A_iface
, enumaddrtypecb
, sp
,
838 /********************************************************************
840 * Enumerates what applications are registered with DirectPlay by
841 * invoking the callback function with lpContext.
844 static HRESULT WINAPI
IDirectPlayLobby3Impl_EnumLocalApplications( IDirectPlayLobby3
*iface
,
845 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback
, void *lpContext
, DWORD dwFlags
)
847 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
849 FIXME("(%p)->(%p,%p,0x%08lx):stub\n", This
, lpEnumLocalAppCallback
, lpContext
, dwFlags
);
851 return DPERR_OUTOFMEMORY
;
854 static HRESULT WINAPI
IDirectPlayLobbyAImpl_EnumLocalApplications( IDirectPlayLobbyA
*iface
,
855 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
857 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
858 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3A_iface
, enumlocalappcb
,
862 static HRESULT WINAPI
IDirectPlayLobbyImpl_EnumLocalApplications( IDirectPlayLobby
*iface
,
863 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
865 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
866 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3_iface
, enumlocalappcb
,
870 static HRESULT WINAPI
IDirectPlayLobby2AImpl_EnumLocalApplications( IDirectPlayLobby2A
*iface
,
871 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
873 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
874 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3A_iface
, enumlocalappcb
,
878 static HRESULT WINAPI
IDirectPlayLobby2Impl_EnumLocalApplications( IDirectPlayLobby2
*iface
,
879 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
881 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
882 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3_iface
, enumlocalappcb
,
886 static HRESULT WINAPI
IDirectPlayLobby3AImpl_EnumLocalApplications( IDirectPlayLobby3A
*iface
,
887 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback
, void *lpContext
, DWORD dwFlags
)
889 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
892 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Applications";
893 LPCSTR guidDataSubKey
= "Guid";
894 DWORD dwIndex
, sizeOfSubKeyName
=50;
898 TRACE("(%p)->(%p,%p,0x%08lx)\n", This
, lpEnumLocalAppCallback
, lpContext
, dwFlags
);
902 return DPERR_INVALIDPARAMS
;
905 if( !lpEnumLocalAppCallback
)
907 return DPERR_INVALIDPARAMS
;
910 /* Need to loop over the service providers in the registry */
911 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
912 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
914 /* Hmmm. Does this mean that there are no service providers? */
915 ERR(": no service providers?\n");
919 /* Traverse all registered applications */
921 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
, NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
922 ++dwIndex
, sizeOfSubKeyName
=50 )
925 HKEY hkServiceProvider
;
926 GUID serviceProviderGUID
;
927 DWORD returnTypeGUID
, sizeOfReturnBuffer
= 50;
928 char returnBuffer
[51];
930 DPLAPPINFO dplAppInfo
;
932 TRACE(" this time through: %s\n", subKeyName
);
934 /* Get a handle for this particular service provider */
935 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
936 &hkServiceProvider
) != ERROR_SUCCESS
)
938 ERR(": what the heck is going on?\n" );
942 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
943 NULL
, &returnTypeGUID
, (LPBYTE
)returnBuffer
,
944 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
946 ERR(": missing GUID registry data members\n" );
950 /* FIXME: Check return types to ensure we're interpreting data right */
951 MultiByteToWideChar( CP_ACP
, 0, returnBuffer
, -1, buff
, ARRAY_SIZE( buff
));
952 CLSIDFromString( buff
, &serviceProviderGUID
);
953 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
955 dplAppInfo
.dwSize
= sizeof( dplAppInfo
);
956 dplAppInfo
.guidApplication
= serviceProviderGUID
;
957 dplAppInfo
.lpszAppNameA
= subKeyName
;
959 EnterCriticalSection( &This
->lock
);
961 memcpy( &This
->cbkeyhack
, &hkServiceProvider
, sizeof( hkServiceProvider
) );
963 if( !lpEnumLocalAppCallback( &dplAppInfo
, lpContext
, dwFlags
) )
965 LeaveCriticalSection( &This
->lock
);
969 LeaveCriticalSection( &This
->lock
);
975 /********************************************************************
977 * Retrieves the DPLCONNECTION structure that contains all the information
978 * needed to start and connect an application. This was generated using
979 * either the RunApplication or SetConnectionSettings methods.
981 * NOTES: If lpData is NULL then just return lpdwDataSize. This allows
982 * the data structure to be allocated by our caller which can then
983 * call this procedure/method again with a valid data pointer.
985 static HRESULT WINAPI
IDirectPlayLobbyAImpl_GetConnectionSettings( IDirectPlayLobbyA
*iface
,
986 DWORD appid
, void *data
, DWORD
*size
)
988 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
989 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, appid
, data
,
993 static HRESULT WINAPI
IDirectPlayLobbyImpl_GetConnectionSettings( IDirectPlayLobby
*iface
,
994 DWORD appid
, void *data
, DWORD
*size
)
996 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
997 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3_iface
, appid
, data
,
1001 static HRESULT WINAPI
IDirectPlayLobby2AImpl_GetConnectionSettings( IDirectPlayLobby2A
*iface
,
1002 DWORD appid
, void *data
, DWORD
*size
)
1004 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1005 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, appid
, data
,
1009 static HRESULT WINAPI
IDirectPlayLobby2Impl_GetConnectionSettings( IDirectPlayLobby2
*iface
,
1010 DWORD appid
, void *data
, DWORD
*size
)
1012 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1013 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3_iface
, appid
, data
,
1017 static HRESULT WINAPI
IDirectPlayLobby3AImpl_GetConnectionSettings( IDirectPlayLobby3A
*iface
,
1018 DWORD dwAppID
, void *lpData
, DWORD
*lpdwDataSize
)
1020 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1023 TRACE("(%p)->(0x%08lx,%p,%p)\n", This
, dwAppID
, lpData
, lpdwDataSize
);
1025 EnterCriticalSection( &This
->lock
);
1027 hr
= DPLAYX_GetConnectionSettingsA( dwAppID
,
1032 LeaveCriticalSection( &This
->lock
);
1037 static HRESULT WINAPI
IDirectPlayLobby3Impl_GetConnectionSettings( IDirectPlayLobby3
*iface
,
1038 DWORD dwAppID
, void *lpData
, DWORD
*lpdwDataSize
)
1040 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1043 TRACE("(%p)->(0x%08lx,%p,%p)\n", This
, dwAppID
, lpData
, lpdwDataSize
);
1045 EnterCriticalSection( &This
->lock
);
1047 hr
= DPLAYX_GetConnectionSettingsW( dwAppID
,
1052 LeaveCriticalSection( &This
->lock
);
1057 /********************************************************************
1059 * Retrieves the message sent between a lobby client and a DirectPlay
1060 * application. All messages are queued until received.
1063 static HRESULT WINAPI
IDirectPlayLobbyAImpl_ReceiveLobbyMessage( IDirectPlayLobbyA
*iface
,
1064 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1066 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1067 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1068 msgflags
, data
, size
);
1071 static HRESULT WINAPI
IDirectPlayLobbyImpl_ReceiveLobbyMessage( IDirectPlayLobby
*iface
,
1072 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1074 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1075 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1076 msgflags
, data
, size
);
1079 static HRESULT WINAPI
IDirectPlayLobby2AImpl_ReceiveLobbyMessage( IDirectPlayLobby2A
*iface
,
1080 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1082 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1083 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1084 msgflags
, data
, size
);
1087 static HRESULT WINAPI
IDirectPlayLobby2Impl_ReceiveLobbyMessage( IDirectPlayLobby2
*iface
,
1088 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1090 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1091 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1092 msgflags
, data
, size
);
1095 static HRESULT WINAPI
IDirectPlayLobby3AImpl_ReceiveLobbyMessage( IDirectPlayLobby3A
*iface
,
1096 DWORD dwFlags
, DWORD dwAppID
, DWORD
*lpdwMessageFlags
, void *lpData
,
1097 DWORD
*lpdwDataSize
)
1099 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1100 FIXME(":stub %p %08lx %08lx %p %p %p\n", This
, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
1102 return DPERR_OUTOFMEMORY
;
1105 static HRESULT WINAPI
IDirectPlayLobby3Impl_ReceiveLobbyMessage( IDirectPlayLobby3
*iface
,
1106 DWORD dwFlags
, DWORD dwAppID
, DWORD
*lpdwMessageFlags
, void *lpData
,
1107 DWORD
*lpdwDataSize
)
1109 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1110 FIXME(":stub %p %08lx %08lx %p %p %p\n", This
, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
1112 return DPERR_OUTOFMEMORY
;
1115 typedef struct tagRunApplicationEnumStruct
1117 IDirectPlayLobbyImpl
*This
;
1122 LPSTR lpszCommandLine
;
1123 LPSTR lpszCurrentDirectory
;
1124 } RunApplicationEnumStruct
, *lpRunApplicationEnumStruct
;
1126 /* To be called by RunApplication to find how to invoke the function */
1127 static BOOL CALLBACK RunApplicationA_EnumLocalApplications
1128 ( LPCDPLAPPINFO lpAppInfo
,
1132 lpRunApplicationEnumStruct lpData
= (lpRunApplicationEnumStruct
)lpContext
;
1134 if( IsEqualGUID( &lpAppInfo
->guidApplication
, &lpData
->appGUID
) )
1136 char returnBuffer
[200];
1137 DWORD returnType
, sizeOfReturnBuffer
;
1138 LPCSTR clSubKey
= "CommandLine";
1139 LPCSTR cdSubKey
= "CurrentDirectory";
1140 LPCSTR fileSubKey
= "File";
1141 LPCSTR pathSubKey
= "Path";
1143 /* FIXME: Lazy man hack - dplay struct has the present reg key saved */
1145 sizeOfReturnBuffer
= 200;
1147 /* Get all the appropriate data from the registry */
1148 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, clSubKey
,
1149 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1150 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1152 ERR( ": missing CommandLine registry data member\n" );
1156 lpData
->lpszCommandLine
= strdup( returnBuffer
);
1159 sizeOfReturnBuffer
= 200;
1161 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, cdSubKey
,
1162 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1163 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1165 ERR( ": missing CurrentDirectory registry data member\n" );
1169 lpData
->lpszCurrentDirectory
= strdup( returnBuffer
);
1172 sizeOfReturnBuffer
= 200;
1174 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, fileSubKey
,
1175 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1176 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1178 ERR( ": missing File registry data member\n" );
1182 lpData
->lpszFileName
= strdup( returnBuffer
);
1185 sizeOfReturnBuffer
= 200;
1187 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, pathSubKey
,
1188 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1189 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1191 ERR( ": missing Path registry data member\n" );
1195 lpData
->lpszPath
= strdup( returnBuffer
);
1198 return FALSE
; /* No need to keep going as we found what we wanted */
1201 return TRUE
; /* Keep enumerating, haven't found the application yet */
1204 static BOOL
DPL_CreateAndSetLobbyHandles( DWORD dwDestProcessId
, HANDLE hDestProcess
,
1205 LPHANDLE lphStart
, LPHANDLE lphDeath
,
1208 /* These are the handles for the created process */
1209 HANDLE hAppStart
= 0, hAppDeath
= 0, hAppRead
= 0;
1210 SECURITY_ATTRIBUTES s_attrib
;
1212 s_attrib
.nLength
= sizeof( s_attrib
);
1213 s_attrib
.lpSecurityDescriptor
= NULL
;
1214 s_attrib
.bInheritHandle
= TRUE
;
1216 *lphStart
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1217 *lphDeath
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1218 *lphRead
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1220 if( ( !DuplicateHandle( GetCurrentProcess(), *lphStart
,
1221 hDestProcess
, &hAppStart
,
1222 0, FALSE
, DUPLICATE_SAME_ACCESS
) ) ||
1223 ( !DuplicateHandle( GetCurrentProcess(), *lphDeath
,
1224 hDestProcess
, &hAppDeath
,
1225 0, FALSE
, DUPLICATE_SAME_ACCESS
) ) ||
1226 ( !DuplicateHandle( GetCurrentProcess(), *lphRead
,
1227 hDestProcess
, &hAppRead
,
1228 0, FALSE
, DUPLICATE_SAME_ACCESS
) )
1231 if (*lphStart
) { CloseHandle(*lphStart
); *lphStart
= 0; }
1232 if (*lphDeath
) { CloseHandle(*lphDeath
); *lphDeath
= 0; }
1233 if (*lphRead
) { CloseHandle(*lphRead
); *lphRead
= 0; }
1234 /* FIXME: Handle leak... */
1235 ERR( "Unable to dup handles\n" );
1239 if( !DPLAYX_SetLobbyHandles( dwDestProcessId
,
1240 hAppStart
, hAppDeath
, hAppRead
) )
1242 /* FIXME: Handle leak... */
1250 /********************************************************************
1252 * Starts an application and passes to it all the information to
1253 * connect to a session.
1256 static HRESULT WINAPI
IDirectPlayLobbyAImpl_RunApplication( IDirectPlayLobbyA
*iface
, DWORD flags
,
1257 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1259 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1260 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, conn
,
1264 static HRESULT WINAPI
IDirectPlayLobbyImpl_RunApplication( IDirectPlayLobby
*iface
, DWORD flags
,
1265 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1267 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1268 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3_iface
, flags
, appid
, conn
,
1272 static HRESULT WINAPI
IDirectPlayLobby2AImpl_RunApplication( IDirectPlayLobby2A
*iface
, DWORD flags
,
1273 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1275 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1276 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, conn
,
1280 static HRESULT WINAPI
IDirectPlayLobby2Impl_RunApplication( IDirectPlayLobby2
*iface
, DWORD flags
,
1281 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1283 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1284 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3_iface
, flags
, appid
, conn
,
1288 static HRESULT WINAPI
IDirectPlayLobby3AImpl_RunApplication( IDirectPlayLobby3A
*iface
,
1289 DWORD dwFlags
, DWORD
*lpdwAppID
, DPLCONNECTION
*lpConn
, HANDLE hReceiveEvent
)
1291 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1293 RunApplicationEnumStruct enumData
;
1295 STARTUPINFOA startupInfo
;
1296 PROCESS_INFORMATION newProcessInfo
;
1298 DWORD dwSuspendCount
;
1299 HANDLE hStart
, hDeath
, hSettingRead
;
1301 TRACE( "(%p)->(0x%08lx,%p,%p,%p)\n",
1302 This
, dwFlags
, lpdwAppID
, lpConn
, hReceiveEvent
);
1306 return DPERR_INVALIDPARAMS
;
1309 if( DPLAYX_AnyLobbiesWaitingForConnSettings() )
1311 FIXME( "Waiting lobby not being handled correctly\n" );
1314 EnterCriticalSection( &This
->lock
);
1316 ZeroMemory( &enumData
, sizeof( enumData
) );
1317 enumData
.This
= This
;
1318 enumData
.appGUID
= lpConn
->lpSessionDesc
->guidApplication
;
1320 /* Our callback function will fill up the enumData structure with all the information
1321 required to start a new process */
1322 IDirectPlayLobby_EnumLocalApplications( iface
, RunApplicationA_EnumLocalApplications
,
1325 /* First the application name */
1326 strcpy( temp
, enumData
.lpszPath
);
1327 strcat( temp
, "\\" );
1328 strcat( temp
, enumData
.lpszFileName
);
1329 free( enumData
.lpszPath
);
1330 free( enumData
.lpszFileName
);
1331 appName
= strdup( temp
);
1333 /* Now the command line */
1334 strcat( temp
, " " );
1335 strcat( temp
, enumData
.lpszCommandLine
);
1336 free( enumData
.lpszCommandLine
);
1337 enumData
.lpszCommandLine
= strdup( temp
);
1339 ZeroMemory( &startupInfo
, sizeof( startupInfo
) );
1340 startupInfo
.cb
= sizeof( startupInfo
);
1341 /* FIXME: Should any fields be filled in? */
1343 ZeroMemory( &newProcessInfo
, sizeof( newProcessInfo
) );
1345 if( !CreateProcessA( appName
,
1346 enumData
.lpszCommandLine
,
1350 CREATE_DEFAULT_ERROR_MODE
| CREATE_NEW_CONSOLE
| CREATE_SUSPENDED
, /* Creation Flags */
1352 enumData
.lpszCurrentDirectory
,
1358 ERR( "Failed to create process for app %s\n", appName
);
1361 free( enumData
.lpszCommandLine
);
1362 free( enumData
.lpszCurrentDirectory
);
1364 LeaveCriticalSection( &This
->lock
);
1365 return DPERR_CANTCREATEPROCESS
;
1369 free( enumData
.lpszCommandLine
);
1370 free( enumData
.lpszCurrentDirectory
);
1372 /* Reserve this global application id! */
1373 if( !DPLAYX_CreateLobbyApplication( newProcessInfo
.dwProcessId
) )
1375 ERR( "Unable to create global application data for 0x%08lx\n",
1376 newProcessInfo
.dwProcessId
);
1379 hr
= IDirectPlayLobby_SetConnectionSettings( iface
, 0, newProcessInfo
.dwProcessId
, lpConn
);
1383 ERR( "SetConnectionSettings failure %s\n", DPLAYX_HresultToString( hr
) );
1384 LeaveCriticalSection( &This
->lock
);
1388 /* Setup the handles for application notification */
1389 DPL_CreateAndSetLobbyHandles( newProcessInfo
.dwProcessId
,
1390 newProcessInfo
.hProcess
,
1391 &hStart
, &hDeath
, &hSettingRead
);
1393 /* Setup the message thread ID */
1394 This
->msgtid
= CreateLobbyMessageReceptionThread( hReceiveEvent
, hStart
, hDeath
, hSettingRead
);
1396 DPLAYX_SetLobbyMsgThreadId( newProcessInfo
.dwProcessId
, This
->msgtid
);
1398 LeaveCriticalSection( &This
->lock
);
1400 /* Everything seems to have been set correctly, update the dwAppID */
1401 *lpdwAppID
= newProcessInfo
.dwProcessId
;
1403 /* Unsuspend the process - should return the prev suspension count */
1404 if( ( dwSuspendCount
= ResumeThread( newProcessInfo
.hThread
) ) != 1 )
1406 ERR( "ResumeThread failed with 0x%08lx\n", dwSuspendCount
);
1412 static HRESULT WINAPI
IDirectPlayLobby3Impl_RunApplication( IDirectPlayLobby3
*iface
, DWORD dwFlags
,
1413 DWORD
*lpdwAppID
, DPLCONNECTION
*lpConn
, HANDLE hReceiveEvent
)
1415 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1416 FIXME( "(%p)->(0x%08lx,%p,%p,%p):stub\n", This
, dwFlags
, lpdwAppID
, lpConn
, hReceiveEvent
);
1417 return DPERR_OUTOFMEMORY
;
1420 /********************************************************************
1422 * Sends a message between the application and the lobby client.
1423 * All messages are queued until received.
1426 static HRESULT WINAPI
IDirectPlayLobbyAImpl_SendLobbyMessage( IDirectPlayLobbyA
*iface
, DWORD flags
,
1427 DWORD appid
, void *data
, DWORD size
)
1429 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1430 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, data
,
1434 static HRESULT WINAPI
IDirectPlayLobbyImpl_SendLobbyMessage( IDirectPlayLobby
*iface
, DWORD flags
,
1435 DWORD appid
, void *data
, DWORD size
)
1437 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1438 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
, data
,
1442 static HRESULT WINAPI
IDirectPlayLobby2AImpl_SendLobbyMessage( IDirectPlayLobby2A
*iface
,
1443 DWORD flags
, DWORD appid
, void *data
, DWORD size
)
1445 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1446 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, data
,
1450 static HRESULT WINAPI
IDirectPlayLobby2Impl_SendLobbyMessage( IDirectPlayLobby2
*iface
, DWORD flags
,
1451 DWORD appid
, void *data
, DWORD size
)
1453 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1454 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
, data
,
1458 static HRESULT WINAPI
IDirectPlayLobby3AImpl_SendLobbyMessage( IDirectPlayLobby3A
*iface
,
1459 DWORD flags
, DWORD appid
, void *data
, DWORD size
)
1462 return DPERR_OUTOFMEMORY
;
1465 static HRESULT WINAPI
IDirectPlayLobby3Impl_SendLobbyMessage( IDirectPlayLobby3
*iface
,
1466 DWORD flags
, DWORD appid
, void *data
, DWORD size
)
1469 return DPERR_OUTOFMEMORY
;
1472 /********************************************************************
1474 * Modifies the DPLCONNECTION structure to contain all information
1475 * needed to start and connect an application.
1478 static HRESULT WINAPI
IDirectPlayLobby3Impl_SetConnectionSettings( IDirectPlayLobby3
*iface
,
1479 DWORD dwFlags
, DWORD dwAppID
, DPLCONNECTION
*lpConn
)
1481 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1484 TRACE("(%p)->(0x%08lx,0x%08lx,%p)\n", This
, dwFlags
, dwAppID
, lpConn
);
1486 EnterCriticalSection( &This
->lock
);
1488 hr
= DPLAYX_SetConnectionSettingsW( dwFlags
, dwAppID
, lpConn
);
1490 /* FIXME: Don't think that this is supposed to fail, but the documentation
1491 is somewhat sketchy. I'll try creating a lobby application
1493 if( hr
== DPERR_NOTLOBBIED
)
1495 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1498 dwAppID
= GetCurrentProcessId();
1500 DPLAYX_CreateLobbyApplication( dwAppID
);
1501 hr
= DPLAYX_SetConnectionSettingsW( dwFlags
, dwAppID
, lpConn
);
1504 LeaveCriticalSection( &This
->lock
);
1509 static HRESULT WINAPI
IDirectPlayLobbyAImpl_SetConnectionSettings( IDirectPlayLobbyA
*iface
,
1510 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1512 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1513 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, flags
,
1517 static HRESULT WINAPI
IDirectPlayLobbyImpl_SetConnectionSettings( IDirectPlayLobby
*iface
,
1518 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1520 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1521 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3_iface
, flags
,
1525 static HRESULT WINAPI
IDirectPlayLobby2AImpl_SetConnectionSettings( IDirectPlayLobby2A
*iface
,
1526 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1528 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1529 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, flags
,
1533 static HRESULT WINAPI
IDirectPlayLobby2Impl_SetConnectionSettings( IDirectPlayLobby2
*iface
,
1534 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1536 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1537 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3_iface
, flags
,
1541 static HRESULT WINAPI
IDirectPlayLobby3AImpl_SetConnectionSettings( IDirectPlayLobby3A
*iface
,
1542 DWORD dwFlags
, DWORD dwAppID
, DPLCONNECTION
*lpConn
)
1544 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1547 TRACE("(%p)->(0x%08lx,0x%08lx,%p)\n", This
, dwFlags
, dwAppID
, lpConn
);
1549 EnterCriticalSection( &This
->lock
);
1551 hr
= DPLAYX_SetConnectionSettingsA( dwFlags
, dwAppID
, lpConn
);
1553 /* FIXME: Don't think that this is supposed to fail, but the documentation
1554 is somewhat sketchy. I'll try creating a lobby application
1556 if( hr
== DPERR_NOTLOBBIED
)
1558 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1559 dwAppID
= GetCurrentProcessId();
1560 DPLAYX_CreateLobbyApplication( dwAppID
);
1561 hr
= DPLAYX_SetConnectionSettingsA( dwFlags
, dwAppID
, lpConn
);
1564 LeaveCriticalSection( &This
->lock
);
1569 /********************************************************************
1571 * Registers an event that will be set when a lobby message is received.
1574 static HRESULT WINAPI
IDirectPlayLobbyAImpl_SetLobbyMessageEvent( IDirectPlayLobbyA
*iface
,
1575 DWORD flags
, DWORD appid
, HANDLE event
)
1577 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1578 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1582 static HRESULT WINAPI
IDirectPlayLobbyImpl_SetLobbyMessageEvent( IDirectPlayLobby
*iface
,
1583 DWORD flags
, DWORD appid
, HANDLE event
)
1585 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1586 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1590 static HRESULT WINAPI
IDirectPlayLobby2AImpl_SetLobbyMessageEvent( IDirectPlayLobby2A
*iface
,
1591 DWORD flags
, DWORD appid
, HANDLE event
)
1593 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1594 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1598 static HRESULT WINAPI
IDirectPlayLobby2Impl_SetLobbyMessageEvent( IDirectPlayLobby2
*iface
,
1599 DWORD flags
, DWORD appid
, HANDLE event
)
1601 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1602 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1606 static HRESULT WINAPI
IDirectPlayLobby3AImpl_SetLobbyMessageEvent( IDirectPlayLobby3A
*iface
,
1607 DWORD flags
, DWORD appid
, HANDLE event
)
1610 return DPERR_OUTOFMEMORY
;
1613 static HRESULT WINAPI
IDirectPlayLobby3Impl_SetLobbyMessageEvent( IDirectPlayLobby3
*iface
,
1614 DWORD flags
, DWORD appid
, HANDLE event
)
1617 return DPERR_OUTOFMEMORY
;
1622 static HRESULT WINAPI
IDirectPlayLobby2AImpl_CreateCompoundAddress( IDirectPlayLobby2A
*iface
,
1623 const DPCOMPOUNDADDRESSELEMENT
*elements
, DWORD count
, void *address
, DWORD
*size
)
1625 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1626 return IDirectPlayLobby_CreateCompoundAddress( &This
->IDirectPlayLobby3A_iface
, elements
,
1627 count
, address
, size
);
1630 static HRESULT WINAPI
IDirectPlayLobby2Impl_CreateCompoundAddress( IDirectPlayLobby2
*iface
,
1631 const DPCOMPOUNDADDRESSELEMENT
*elements
, DWORD count
, void *address
, DWORD
*size
)
1633 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1634 return IDirectPlayLobby_CreateCompoundAddress( &This
->IDirectPlayLobby3_iface
, elements
,
1635 count
, address
, size
);
1638 static HRESULT WINAPI
IDirectPlayLobby3Impl_CreateCompoundAddress( IDirectPlayLobby3
*iface
,
1639 const DPCOMPOUNDADDRESSELEMENT
*lpElements
, DWORD dwElementCount
, void *lpAddress
,
1640 DWORD
*lpdwAddressSize
)
1642 return DPL_CreateCompoundAddress( lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
, FALSE
);
1645 static HRESULT WINAPI
IDirectPlayLobby3AImpl_CreateCompoundAddress( IDirectPlayLobby3A
*iface
,
1646 const DPCOMPOUNDADDRESSELEMENT
*lpElements
, DWORD dwElementCount
, void *lpAddress
,
1647 DWORD
*lpdwAddressSize
)
1649 return DPL_CreateCompoundAddress( lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
, TRUE
);
1652 HRESULT DPL_CreateCompoundAddress
1653 ( LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1654 DWORD dwElementCount
,
1656 LPDWORD lpdwAddressSize
,
1657 BOOL bAnsiInterface
)
1659 DWORD dwSizeRequired
= 0;
1661 LPCDPCOMPOUNDADDRESSELEMENT lpOrigElements
= lpElements
;
1663 TRACE("(%p,0x%08lx,%p,%p)\n", lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
);
1665 /* Parameter check */
1666 if( ( lpElements
== NULL
) ||
1667 ( dwElementCount
== 0 ) /* FIXME: Not sure if this is a failure case */
1670 return DPERR_INVALIDPARAMS
;
1673 /* Add the total size chunk */
1674 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( DWORD
);
1676 /* Calculate the size of the buffer required */
1677 for ( dwElements
= dwElementCount
; dwElements
> 0; --dwElements
, ++lpElements
)
1679 if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ServiceProvider
) ) ||
1680 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_LobbyProvider
) )
1683 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( GUID
);
1685 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Phone
) ) ||
1686 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Modem
) ) ||
1687 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INet
) )
1690 if( !bAnsiInterface
)
1692 ERR( "Ansi GUIDs used for unicode interface\n" );
1693 return DPERR_INVALIDFLAGS
;
1696 dwSizeRequired
+= sizeof( DPADDRESS
) + lpElements
->dwDataSize
;
1698 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_PhoneW
) ) ||
1699 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ModemW
) ) ||
1700 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetW
) )
1703 if( bAnsiInterface
)
1705 ERR( "Unicode GUIDs used for ansi interface\n" );
1706 return DPERR_INVALIDFLAGS
;
1709 FIXME( "Right size for unicode interface?\n" );
1710 dwSizeRequired
+= sizeof( DPADDRESS
) + lpElements
->dwDataSize
* sizeof( WCHAR
);
1712 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetPort
) )
1714 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( WORD
);
1716 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ComPort
) )
1718 FIXME( "Right size for unicode interface?\n" );
1719 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( DPCOMPORTADDRESS
); /* FIXME: Right size? */
1723 WARN( "Skipping Unknown GUID %s\n", debugstr_guid(&lpElements
->guidDataType
) );
1727 /* The user wants to know how big a buffer to allocate for us */
1728 if( ( lpAddress
== NULL
) ||
1729 ( *lpdwAddressSize
< dwSizeRequired
)
1732 *lpdwAddressSize
= dwSizeRequired
;
1733 return DPERR_BUFFERTOOSMALL
;
1736 /* Add the total size chunk */
1738 LPDPADDRESS lpdpAddress
= lpAddress
;
1740 lpdpAddress
->guidDataType
= DPAID_TotalSize
;
1741 lpdpAddress
->dwDataSize
= sizeof( DWORD
);
1742 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1744 *(LPDWORD
)lpAddress
= dwSizeRequired
;
1745 lpAddress
= (char *) lpAddress
+ sizeof( DWORD
);
1748 /* Calculate the size of the buffer required */
1749 for( dwElements
= dwElementCount
, lpElements
= lpOrigElements
;
1751 --dwElements
, ++lpElements
)
1753 if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ServiceProvider
) ) ||
1754 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_LobbyProvider
) )
1757 LPDPADDRESS lpdpAddress
= lpAddress
;
1759 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1760 lpdpAddress
->dwDataSize
= sizeof( GUID
);
1761 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1763 CopyMemory( lpAddress
, lpElements
->lpData
, sizeof( GUID
) );
1764 lpAddress
= (char *) lpAddress
+ sizeof( GUID
);
1766 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Phone
) ) ||
1767 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Modem
) ) ||
1768 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INet
) )
1771 LPDPADDRESS lpdpAddress
= lpAddress
;
1773 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1774 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1775 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1777 lstrcpynA( lpAddress
, lpElements
->lpData
, lpElements
->dwDataSize
);
1778 lpAddress
= (char *) lpAddress
+ lpElements
->dwDataSize
;
1780 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_PhoneW
) ) ||
1781 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ModemW
) ) ||
1782 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetW
) )
1785 LPDPADDRESS lpdpAddress
= lpAddress
;
1787 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1788 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1789 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1791 lstrcpynW( lpAddress
, lpElements
->lpData
, lpElements
->dwDataSize
);
1792 lpAddress
= (char *) lpAddress
+ lpElements
->dwDataSize
* sizeof( WCHAR
);
1794 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetPort
) )
1796 LPDPADDRESS lpdpAddress
= lpAddress
;
1798 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1799 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1800 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1802 *((LPWORD
)lpAddress
) = *((LPWORD
)lpElements
->lpData
);
1803 lpAddress
= (char *) lpAddress
+ sizeof( WORD
);
1805 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ComPort
) )
1807 LPDPADDRESS lpdpAddress
= lpAddress
;
1809 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1810 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1811 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1813 CopyMemory( lpAddress
, lpElements
->lpData
, sizeof( DPADDRESS
) );
1814 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1823 static HRESULT WINAPI
IDirectPlayLobby3Impl_ConnectEx( IDirectPlayLobby3
*iface
, DWORD dwFlags
,
1824 REFIID riid
, LPVOID
* lplpDP
, IUnknown
* pUnk
)
1826 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1827 return DPL_ConnectEx( This
, dwFlags
, riid
, lplpDP
, pUnk
);
1830 static HRESULT WINAPI
IDirectPlayLobby3AImpl_ConnectEx( IDirectPlayLobby3A
*iface
, DWORD dwFlags
,
1831 REFIID riid
, void **lplpDP
, IUnknown
*pUnk
)
1833 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1834 return DPL_ConnectEx( This
, dwFlags
, riid
, lplpDP
, pUnk
);
1837 static HRESULT WINAPI
IDirectPlayLobby3Impl_RegisterApplication( IDirectPlayLobby3
*iface
,
1838 DWORD flags
, DPAPPLICATIONDESC
*appdesc
)
1844 static HRESULT WINAPI
IDirectPlayLobby3AImpl_RegisterApplication( IDirectPlayLobby3A
*iface
,
1845 DWORD flags
, DPAPPLICATIONDESC
*appdesc
)
1851 static HRESULT WINAPI
IDirectPlayLobby3Impl_UnregisterApplication( IDirectPlayLobby3
*iface
,
1852 DWORD flags
, REFGUID appdesc
)
1858 static HRESULT WINAPI
IDirectPlayLobby3AImpl_UnregisterApplication( IDirectPlayLobby3A
*iface
,
1859 DWORD flags
, REFGUID appdesc
)
1865 static HRESULT WINAPI
IDirectPlayLobby3Impl_WaitForConnectionSettings( IDirectPlayLobby3
*iface
,
1869 BOOL bStartWait
= !(dwFlags
& DPLWAIT_CANCEL
);
1871 TRACE( "(%p)->(0x%08lx)\n", iface
, dwFlags
);
1873 if( DPLAYX_WaitForConnectionSettings( bStartWait
) )
1875 /* FIXME: What is the correct error return code? */
1876 hr
= DPERR_NOTLOBBIED
;
1882 static HRESULT WINAPI
IDirectPlayLobby3AImpl_WaitForConnectionSettings( IDirectPlayLobby3A
*iface
,
1886 BOOL bStartWait
= !(dwFlags
& DPLWAIT_CANCEL
);
1888 TRACE( "(%p)->(0x%08lx)\n", iface
, dwFlags
);
1890 if( DPLAYX_WaitForConnectionSettings( bStartWait
) )
1892 /* FIXME: What is the correct error return code? */
1893 hr
= DPERR_NOTLOBBIED
;
1899 static const IDirectPlayLobbyVtbl dplA_vt
=
1901 IDirectPlayLobbyAImpl_QueryInterface
,
1902 IDirectPlayLobbyAImpl_AddRef
,
1903 IDirectPlayLobbyAImpl_Release
,
1904 IDirectPlayLobbyAImpl_Connect
,
1905 IDirectPlayLobbyAImpl_CreateAddress
,
1906 IDirectPlayLobbyAImpl_EnumAddress
,
1907 IDirectPlayLobbyAImpl_EnumAddressTypes
,
1908 IDirectPlayLobbyAImpl_EnumLocalApplications
,
1909 IDirectPlayLobbyAImpl_GetConnectionSettings
,
1910 IDirectPlayLobbyAImpl_ReceiveLobbyMessage
,
1911 IDirectPlayLobbyAImpl_RunApplication
,
1912 IDirectPlayLobbyAImpl_SendLobbyMessage
,
1913 IDirectPlayLobbyAImpl_SetConnectionSettings
,
1914 IDirectPlayLobbyAImpl_SetLobbyMessageEvent
1917 static const IDirectPlayLobbyVtbl dpl_vt
=
1919 IDirectPlayLobbyImpl_QueryInterface
,
1920 IDirectPlayLobbyImpl_AddRef
,
1921 IDirectPlayLobbyImpl_Release
,
1922 IDirectPlayLobbyImpl_Connect
,
1923 IDirectPlayLobbyImpl_CreateAddress
,
1924 IDirectPlayLobbyImpl_EnumAddress
,
1925 IDirectPlayLobbyImpl_EnumAddressTypes
,
1926 IDirectPlayLobbyImpl_EnumLocalApplications
,
1927 IDirectPlayLobbyImpl_GetConnectionSettings
,
1928 IDirectPlayLobbyImpl_ReceiveLobbyMessage
,
1929 IDirectPlayLobbyImpl_RunApplication
,
1930 IDirectPlayLobbyImpl_SendLobbyMessage
,
1931 IDirectPlayLobbyImpl_SetConnectionSettings
,
1932 IDirectPlayLobbyImpl_SetLobbyMessageEvent
1935 static const IDirectPlayLobby2Vtbl dpl2A_vt
=
1937 IDirectPlayLobby2AImpl_QueryInterface
,
1938 IDirectPlayLobby2AImpl_AddRef
,
1939 IDirectPlayLobby2AImpl_Release
,
1940 IDirectPlayLobby2AImpl_Connect
,
1941 IDirectPlayLobby2AImpl_CreateAddress
,
1942 IDirectPlayLobby2AImpl_EnumAddress
,
1943 IDirectPlayLobby2AImpl_EnumAddressTypes
,
1944 IDirectPlayLobby2AImpl_EnumLocalApplications
,
1945 IDirectPlayLobby2AImpl_GetConnectionSettings
,
1946 IDirectPlayLobby2AImpl_ReceiveLobbyMessage
,
1947 IDirectPlayLobby2AImpl_RunApplication
,
1948 IDirectPlayLobby2AImpl_SendLobbyMessage
,
1949 IDirectPlayLobby2AImpl_SetConnectionSettings
,
1950 IDirectPlayLobby2AImpl_SetLobbyMessageEvent
,
1951 IDirectPlayLobby2AImpl_CreateCompoundAddress
1954 static const IDirectPlayLobby2Vtbl dpl2_vt
=
1956 IDirectPlayLobby2Impl_QueryInterface
,
1957 IDirectPlayLobby2Impl_AddRef
,
1958 IDirectPlayLobby2Impl_Release
,
1959 IDirectPlayLobby2Impl_Connect
,
1960 IDirectPlayLobby2Impl_CreateAddress
,
1961 IDirectPlayLobby2Impl_EnumAddress
,
1962 IDirectPlayLobby2Impl_EnumAddressTypes
,
1963 IDirectPlayLobby2Impl_EnumLocalApplications
,
1964 IDirectPlayLobby2Impl_GetConnectionSettings
,
1965 IDirectPlayLobby2Impl_ReceiveLobbyMessage
,
1966 IDirectPlayLobby2Impl_RunApplication
,
1967 IDirectPlayLobby2Impl_SendLobbyMessage
,
1968 IDirectPlayLobby2Impl_SetConnectionSettings
,
1969 IDirectPlayLobby2Impl_SetLobbyMessageEvent
,
1970 IDirectPlayLobby2Impl_CreateCompoundAddress
1973 static const IDirectPlayLobby3Vtbl dpl3A_vt
=
1975 IDirectPlayLobby3AImpl_QueryInterface
,
1976 IDirectPlayLobby3AImpl_AddRef
,
1977 IDirectPlayLobby3AImpl_Release
,
1978 IDirectPlayLobby3AImpl_Connect
,
1979 IDirectPlayLobby3AImpl_CreateAddress
,
1980 IDirectPlayLobby3AImpl_EnumAddress
,
1981 IDirectPlayLobby3AImpl_EnumAddressTypes
,
1982 IDirectPlayLobby3AImpl_EnumLocalApplications
,
1983 IDirectPlayLobby3AImpl_GetConnectionSettings
,
1984 IDirectPlayLobby3AImpl_ReceiveLobbyMessage
,
1985 IDirectPlayLobby3AImpl_RunApplication
,
1986 IDirectPlayLobby3AImpl_SendLobbyMessage
,
1987 IDirectPlayLobby3AImpl_SetConnectionSettings
,
1988 IDirectPlayLobby3AImpl_SetLobbyMessageEvent
,
1989 IDirectPlayLobby3AImpl_CreateCompoundAddress
,
1990 IDirectPlayLobby3AImpl_ConnectEx
,
1991 IDirectPlayLobby3AImpl_RegisterApplication
,
1992 IDirectPlayLobby3AImpl_UnregisterApplication
,
1993 IDirectPlayLobby3AImpl_WaitForConnectionSettings
1996 static const IDirectPlayLobby3Vtbl dpl3_vt
=
1998 IDirectPlayLobby3Impl_QueryInterface
,
1999 IDirectPlayLobby3Impl_AddRef
,
2000 IDirectPlayLobby3Impl_Release
,
2001 IDirectPlayLobby3Impl_Connect
,
2002 IDirectPlayLobby3Impl_CreateAddress
,
2003 IDirectPlayLobby3Impl_EnumAddress
,
2004 IDirectPlayLobby3Impl_EnumAddressTypes
,
2005 IDirectPlayLobby3Impl_EnumLocalApplications
,
2006 IDirectPlayLobby3Impl_GetConnectionSettings
,
2007 IDirectPlayLobby3Impl_ReceiveLobbyMessage
,
2008 IDirectPlayLobby3Impl_RunApplication
,
2009 IDirectPlayLobby3Impl_SendLobbyMessage
,
2010 IDirectPlayLobby3Impl_SetConnectionSettings
,
2011 IDirectPlayLobby3Impl_SetLobbyMessageEvent
,
2012 IDirectPlayLobby3Impl_CreateCompoundAddress
,
2013 IDirectPlayLobby3Impl_ConnectEx
,
2014 IDirectPlayLobby3Impl_RegisterApplication
,
2015 IDirectPlayLobby3Impl_UnregisterApplication
,
2016 IDirectPlayLobby3Impl_WaitForConnectionSettings
2019 HRESULT
dplobby_create( REFIID riid
, void **ppv
)
2021 IDirectPlayLobbyImpl
*obj
;
2024 TRACE( "(%s, %p)\n", debugstr_guid( riid
), ppv
);
2027 obj
= malloc( sizeof( *obj
) );
2029 return DPERR_OUTOFMEMORY
;
2031 obj
->IDirectPlayLobby_iface
.lpVtbl
= &dpl_vt
;
2032 obj
->IDirectPlayLobbyA_iface
.lpVtbl
= &dplA_vt
;
2033 obj
->IDirectPlayLobby2_iface
.lpVtbl
= &dpl2_vt
;
2034 obj
->IDirectPlayLobby2A_iface
.lpVtbl
= &dpl2A_vt
;
2035 obj
->IDirectPlayLobby3_iface
.lpVtbl
= &dpl3_vt
;
2036 obj
->IDirectPlayLobby3A_iface
.lpVtbl
= &dpl3A_vt
;
2046 InitializeCriticalSectionEx( &obj
->lock
, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
);
2047 obj
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": IDirectPlayLobbyImpl.lock");
2048 DPQ_INIT( obj
->msgs
);
2050 hr
= IDirectPlayLobby_QueryInterface( &obj
->IDirectPlayLobby3_iface
, riid
, ppv
);
2051 IDirectPlayLobby_Release( &obj
->IDirectPlayLobby3_iface
);
2058 /***************************************************************************
2059 * DirectPlayLobbyCreateA (DPLAYX.4)
2062 HRESULT WINAPI
DirectPlayLobbyCreateA( GUID
*lpGUIDDSP
, IDirectPlayLobbyA
**lplpDPL
,
2063 IUnknown
*lpUnk
, void *lpData
, DWORD dwDataSize
)
2065 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
2066 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
2068 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
2069 * equal 0. These fields are mostly for future expansion.
2071 if ( lpGUIDDSP
|| lpData
|| dwDataSize
)
2074 return DPERR_INVALIDPARAMS
;
2080 ERR("Bad parameters!\n" );
2081 return CLASS_E_NOAGGREGATION
;
2084 return dplobby_create( &IID_IDirectPlayLobbyA
, (void**)lplpDPL
);
2087 /***************************************************************************
2088 * DirectPlayLobbyCreateW (DPLAYX.5)
2091 HRESULT WINAPI
DirectPlayLobbyCreateW( GUID
*lpGUIDDSP
, IDirectPlayLobby
**lplpDPL
,
2092 IUnknown
*lpUnk
, void *lpData
, DWORD dwDataSize
)
2094 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
2095 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
2097 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
2098 * equal 0. These fields are mostly for future expansion.
2100 if ( lpGUIDDSP
|| lpData
|| dwDataSize
)
2103 ERR("Bad parameters!\n" );
2104 return DPERR_INVALIDPARAMS
;
2110 ERR("Bad parameters!\n" );
2111 return CLASS_E_NOAGGREGATION
;
2114 return dplobby_create( &IID_IDirectPlayLobby
, (void**)lplpDPL
);