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
20 #include "dplayx_global.h"
22 /* Forward declarations for this module helper methods */
23 HRESULT
DPL_CreateCompoundAddress ( LPCDPCOMPOUNDADDRESSELEMENT lpElements
, DWORD dwElementCount
,
24 LPVOID lpAddress
, LPDWORD lpdwAddressSize
, BOOL bAnsiInterface
)DECLSPEC_HIDDEN
;
26 static HRESULT
DPL_CreateAddress( REFGUID guidSP
, REFGUID guidDataType
, LPCVOID lpData
, DWORD dwDataSize
,
27 LPVOID lpAddress
, LPDWORD lpdwAddressSize
, BOOL bAnsiInterface
);
30 /*****************************************************************************
31 * IDirectPlayLobby {1,2,3} implementation structure
33 * The philosophy behind this extra pointer dereference is that I wanted to
34 * have the same structure for all types of objects without having to do
35 * a lot of casting. I also only wanted to implement an interface in the
36 * object it was "released" with IUnknown interface being implemented in the 1 version.
37 * Of course, with these new interfaces comes the data required to keep the state required
38 * by these interfaces. So, basically, the pointers contain the data associated with
39 * a release. If you use the data associated with release 3 in a release 2 object, you'll
40 * get a run time trap, as that won't have any data.
45 DPQ_ENTRY( DPLMSG
) msgs
; /* Link to next queued message */
47 typedef struct DPLMSG
* LPDPLMSG
;
49 typedef struct IDirectPlayLobbyImpl
51 IDirectPlayLobby IDirectPlayLobby_iface
;
52 IDirectPlayLobbyA IDirectPlayLobbyA_iface
;
53 IDirectPlayLobby2 IDirectPlayLobby2_iface
;
54 IDirectPlayLobby2A IDirectPlayLobby2A_iface
;
55 IDirectPlayLobby3 IDirectPlayLobby3_iface
;
56 IDirectPlayLobby3A IDirectPlayLobby3A_iface
;
57 LONG numIfaces
; /* "in use interfaces" refcount */
58 LONG ref
, refA
, ref2
, ref2A
, ref3
, ref3A
;
59 CRITICAL_SECTION lock
;
62 DPQ_HEAD( DPLMSG
) msgs
; /* List of messages received */
63 } IDirectPlayLobbyImpl
;
65 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobby( IDirectPlayLobby
*iface
)
67 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobby_iface
);
70 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobbyA( IDirectPlayLobbyA
*iface
)
72 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobbyA_iface
);
75 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobby2( IDirectPlayLobby2
*iface
)
77 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobby2_iface
);
80 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobby2A( IDirectPlayLobby2A
*iface
)
82 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobby2A_iface
);
85 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobby3( IDirectPlayLobby3
*iface
)
87 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobby3_iface
);
90 static inline IDirectPlayLobbyImpl
*impl_from_IDirectPlayLobby3A( IDirectPlayLobby3A
*iface
)
92 return CONTAINING_RECORD( iface
, IDirectPlayLobbyImpl
, IDirectPlayLobby3A_iface
);
95 static void dplobby_destroy(IDirectPlayLobbyImpl
*obj
)
98 FIXME( "Should kill the msg thread\n" );
100 DPQ_DELETEQ( obj
->msgs
, msgs
, LPDPLMSG
, cbDeleteElemFromHeap
);
101 obj
->lock
.DebugInfo
->Spare
[0] = 0;
102 DeleteCriticalSection( &obj
->lock
);
103 HeapFree( GetProcessHeap(), 0, obj
);
106 static HRESULT WINAPI
IDirectPlayLobbyAImpl_QueryInterface( IDirectPlayLobbyA
*iface
, REFIID riid
,
109 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
110 return IDirectPlayLobby_QueryInterface( &This
->IDirectPlayLobby3_iface
, riid
, ppv
);
113 static HRESULT WINAPI
IDirectPlayLobbyImpl_QueryInterface( IDirectPlayLobby
*iface
, REFIID riid
,
116 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
117 return IDirectPlayLobby_QueryInterface( &This
->IDirectPlayLobby3_iface
, riid
, ppv
);
120 static HRESULT WINAPI
IDirectPlayLobby2AImpl_QueryInterface( IDirectPlayLobby2A
*iface
, REFIID riid
,
123 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
124 return IDirectPlayLobby_QueryInterface( &This
->IDirectPlayLobby3_iface
, riid
, ppv
);
127 static HRESULT WINAPI
IDirectPlayLobby2Impl_QueryInterface( IDirectPlayLobby2
*iface
, REFIID riid
,
130 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
131 return IDirectPlayLobby_QueryInterface( &This
->IDirectPlayLobby3_iface
, riid
, ppv
);
134 static HRESULT WINAPI
IDirectPlayLobby3AImpl_QueryInterface( IDirectPlayLobby3A
*iface
, REFIID riid
,
137 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
138 return IDirectPlayLobby_QueryInterface( &This
->IDirectPlayLobby3_iface
, riid
, ppv
);
141 static HRESULT WINAPI
IDirectPlayLobby3Impl_QueryInterface( IDirectPlayLobby3
*iface
, REFIID riid
,
144 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
146 if ( IsEqualGUID( &IID_IUnknown
, riid
) )
148 TRACE( "(%p)->(IID_IUnknown %p)\n", This
, ppv
);
149 *ppv
= &This
->IDirectPlayLobby_iface
;
151 else if ( IsEqualGUID( &IID_IDirectPlayLobby
, riid
) )
153 TRACE( "(%p)->(IID_IDirectPlayLobby %p)\n", This
, ppv
);
154 *ppv
= &This
->IDirectPlayLobby_iface
;
156 else if ( IsEqualGUID( &IID_IDirectPlayLobbyA
, riid
) )
158 TRACE( "(%p)->(IID_IDirectPlayLobbyA %p)\n", This
, ppv
);
159 *ppv
= &This
->IDirectPlayLobbyA_iface
;
161 else if ( IsEqualGUID( &IID_IDirectPlayLobby2
, riid
) )
163 TRACE( "(%p)->(IID_IDirectPlayLobby2 %p)\n", This
, ppv
);
164 *ppv
= &This
->IDirectPlayLobby2_iface
;
166 else if ( IsEqualGUID( &IID_IDirectPlayLobby2A
, riid
) )
168 TRACE( "(%p)->(IID_IDirectPlayLobby2A %p)\n", This
, ppv
);
169 *ppv
= &This
->IDirectPlayLobby2A_iface
;
171 else if ( IsEqualGUID( &IID_IDirectPlayLobby3
, riid
) )
173 TRACE( "(%p)->(IID_IDirectPlay3 %p)\n", This
, ppv
);
174 *ppv
= &This
->IDirectPlayLobby3_iface
;
176 else if ( IsEqualGUID( &IID_IDirectPlayLobby3A
, riid
) )
178 TRACE( "(%p)->(IID_IDirectPlayLobby3A %p)\n", This
, ppv
);
179 *ppv
= &This
->IDirectPlayLobby3A_iface
;
183 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
185 return E_NOINTERFACE
;
188 IUnknown_AddRef((IUnknown
*)*ppv
);
192 static ULONG WINAPI
IDirectPlayLobbyAImpl_AddRef( IDirectPlayLobbyA
*iface
)
194 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
195 ULONG ref
= InterlockedIncrement( &This
->refA
);
197 TRACE( "(%p) refA=%d\n", This
, ref
);
200 InterlockedIncrement( &This
->numIfaces
);
205 static ULONG WINAPI
IDirectPlayLobbyImpl_AddRef( IDirectPlayLobby
*iface
)
207 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
208 ULONG ref
= InterlockedIncrement( &This
->ref
);
210 TRACE( "(%p) ref=%d\n", This
, ref
);
213 InterlockedIncrement( &This
->numIfaces
);
218 static ULONG WINAPI
IDirectPlayLobby2AImpl_AddRef(IDirectPlayLobby2A
*iface
)
220 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
221 ULONG ref
= InterlockedIncrement( &This
->ref2A
);
223 TRACE( "(%p) ref2A=%d\n", This
, ref
);
226 InterlockedIncrement( &This
->numIfaces
);
231 static ULONG WINAPI
IDirectPlayLobby2Impl_AddRef(IDirectPlayLobby2
*iface
)
233 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
234 ULONG ref
= InterlockedIncrement( &This
->ref2
);
236 TRACE( "(%p) ref2=%d\n", This
, ref
);
239 InterlockedIncrement( &This
->numIfaces
);
244 static ULONG WINAPI
IDirectPlayLobby3AImpl_AddRef(IDirectPlayLobby3A
*iface
)
246 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
247 ULONG ref
= InterlockedIncrement( &This
->ref3A
);
249 TRACE( "(%p) ref3A=%d\n", This
, ref
);
252 InterlockedIncrement( &This
->numIfaces
);
257 static ULONG WINAPI
IDirectPlayLobby3Impl_AddRef(IDirectPlayLobby3
*iface
)
259 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
260 ULONG ref
= InterlockedIncrement( &This
->ref3
);
262 TRACE( "(%p) ref3=%d\n", This
, ref
);
265 InterlockedIncrement( &This
->numIfaces
);
270 static ULONG WINAPI
IDirectPlayLobbyAImpl_Release( IDirectPlayLobbyA
*iface
)
272 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
273 ULONG ref
= InterlockedDecrement( &This
->refA
);
275 TRACE( "(%p) refA=%d\n", This
, ref
);
277 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
278 dplobby_destroy( This
);
283 static ULONG WINAPI
IDirectPlayLobbyImpl_Release( IDirectPlayLobby
*iface
)
285 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
286 ULONG ref
= InterlockedDecrement( &This
->ref
);
288 TRACE( "(%p) ref=%d\n", This
, ref
);
290 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
291 dplobby_destroy( This
);
296 static ULONG WINAPI
IDirectPlayLobby2AImpl_Release(IDirectPlayLobby2A
*iface
)
298 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
299 ULONG ref
= InterlockedDecrement( &This
->ref2A
);
301 TRACE( "(%p) ref2A=%d\n", This
, ref
);
303 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
304 dplobby_destroy( This
);
309 static ULONG WINAPI
IDirectPlayLobby2Impl_Release(IDirectPlayLobby2
*iface
)
311 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
312 ULONG ref
= InterlockedDecrement( &This
->ref2
);
314 TRACE( "(%p) ref2=%d\n", This
, ref
);
316 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
317 dplobby_destroy( This
);
322 static ULONG WINAPI
IDirectPlayLobby3AImpl_Release(IDirectPlayLobby3A
*iface
)
324 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
325 ULONG ref
= InterlockedDecrement( &This
->ref3A
);
327 TRACE( "(%p) ref3A=%d\n", This
, ref
);
329 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
330 dplobby_destroy( This
);
335 static ULONG WINAPI
IDirectPlayLobby3Impl_Release(IDirectPlayLobby3
*iface
)
337 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
338 ULONG ref
= InterlockedDecrement( &This
->ref3
);
340 TRACE( "(%p) ref3=%d\n", This
, ref
);
342 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
343 dplobby_destroy( This
);
349 /********************************************************************
351 * Connects an application to the session specified by the DPLCONNECTION
352 * structure currently stored with the DirectPlayLobby object.
354 * Returns an IDirectPlay interface.
357 static HRESULT
DPL_ConnectEx( IDirectPlayLobbyImpl
*This
, DWORD dwFlags
, REFIID riid
, void **lplpDP
,
361 DWORD dwOpenFlags
= 0;
362 DWORD dwConnSize
= 0;
363 LPDPLCONNECTION lpConn
;
365 FIXME("(%p)->(0x%08x,%p,%p): semi stub\n", This
, dwFlags
, lplpDP
, pUnk
);
369 return DPERR_INVALIDPARAMS
;
372 /* Backwards compatibility */
375 dwFlags
= DPCONNECT_RETURNSTATUS
;
378 if ( ( hr
= dplay_create( riid
, lplpDP
) ) != DP_OK
)
380 ERR( "error creating interface for %s:%s.\n",
381 debugstr_guid( riid
), DPLAYX_HresultToString( hr
) );
385 /* FIXME: Is it safe/correct to use appID of 0? */
386 hr
= IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3_iface
,
387 0, NULL
, &dwConnSize
);
388 if( hr
!= DPERR_BUFFERTOOSMALL
)
393 lpConn
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, dwConnSize
);
397 return DPERR_NOMEMORY
;
400 /* FIXME: Is it safe/correct to use appID of 0? */
401 hr
= IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3_iface
,
402 0, lpConn
, &dwConnSize
);
405 HeapFree( GetProcessHeap(), 0, lpConn
);
410 /* - Need to call IDirectPlay::EnumConnections with the service provider to get that good information
411 * - Need to call CreateAddress to create the lpConnection param for IDirectPlay::InitializeConnection
412 * - Call IDirectPlay::InitializeConnection
415 /* Now initialize the Service Provider */
416 hr
= IDirectPlayX_InitializeConnection( (*(LPDIRECTPLAY2
*)lplpDP
),
420 /* Setup flags to pass into DirectPlay::Open */
421 if( dwFlags
& DPCONNECT_RETURNSTATUS
)
423 dwOpenFlags
|= DPOPEN_RETURNSTATUS
;
425 dwOpenFlags
|= lpConn
->dwFlags
;
427 hr
= IDirectPlayX_Open( (*(LPDIRECTPLAY2
*)lplpDP
), lpConn
->lpSessionDesc
,
430 HeapFree( GetProcessHeap(), 0, lpConn
);
435 static HRESULT WINAPI
IDirectPlayLobbyAImpl_Connect( IDirectPlayLobbyA
*iface
, DWORD flags
,
436 IDirectPlay2A
**dp
, IUnknown
*unk
)
438 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
439 return IDirectPlayLobby_Connect( &This
->IDirectPlayLobby3A_iface
, flags
, dp
, unk
);
442 static HRESULT WINAPI
IDirectPlayLobbyImpl_Connect( IDirectPlayLobby
*iface
, DWORD flags
,
443 IDirectPlay2A
**dp
, IUnknown
*unk
)
445 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
446 return IDirectPlayLobby_Connect( &This
->IDirectPlayLobby3_iface
, flags
, dp
, unk
);
449 static HRESULT WINAPI
IDirectPlayLobby2AImpl_Connect( IDirectPlayLobby2A
*iface
, DWORD flags
,
450 IDirectPlay2A
**dp
, IUnknown
*unk
)
452 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
453 return IDirectPlayLobby_Connect( &This
->IDirectPlayLobby3A_iface
, flags
, dp
, unk
);
456 static HRESULT WINAPI
IDirectPlayLobby2Impl_Connect( IDirectPlayLobby2
*iface
, DWORD flags
,
457 IDirectPlay2A
**dp
, IUnknown
*unk
)
459 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
460 return IDirectPlayLobby_Connect( &This
->IDirectPlayLobby3_iface
, flags
, dp
, unk
);
463 static HRESULT WINAPI
IDirectPlayLobby3AImpl_Connect( IDirectPlayLobby3A
*iface
, DWORD flags
,
464 IDirectPlay2A
**dp
, IUnknown
*unk
)
466 return IDirectPlayLobby_ConnectEx( iface
, flags
, &IID_IDirectPlay2A
, (void**)dp
, unk
);
469 static HRESULT WINAPI
IDirectPlayLobby3Impl_Connect( IDirectPlayLobby3
*iface
, DWORD flags
,
470 IDirectPlay2
**dp
, IUnknown
*unk
)
472 return IDirectPlayLobby_ConnectEx( iface
, flags
, &IID_IDirectPlay2A
, (void**)dp
, unk
);
475 /********************************************************************
477 * Creates a DirectPlay Address, given a service provider-specific network
479 * Returns an address contains the globally unique identifier
480 * (GUID) of the service provider and data that the service provider can
481 * interpret as a network address.
483 * NOTE: It appears that this method is supposed to be really really stupid
484 * with no error checking on the contents.
486 static HRESULT WINAPI
IDirectPlayLobbyAImpl_CreateAddress( IDirectPlayLobbyA
*iface
, REFGUID sp
,
487 REFGUID datatype
, const void *data
, DWORD datasize
, void *address
, DWORD
*addrsize
)
489 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
490 return IDirectPlayLobby_CreateAddress( &This
->IDirectPlayLobby3A_iface
, sp
, datatype
, data
,
491 datasize
, address
, addrsize
);
494 static HRESULT WINAPI
IDirectPlayLobbyImpl_CreateAddress( IDirectPlayLobby
*iface
, REFGUID sp
,
495 REFGUID datatype
, const void *data
, DWORD datasize
, void *address
, DWORD
*addrsize
)
497 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
498 return IDirectPlayLobby_CreateAddress( &This
->IDirectPlayLobby3_iface
, sp
, datatype
, data
,
499 datasize
, address
, addrsize
);
502 static HRESULT WINAPI
IDirectPlayLobby2AImpl_CreateAddress( IDirectPlayLobby2A
*iface
, REFGUID sp
,
503 REFGUID datatype
, const void *data
, DWORD datasize
, void *address
, DWORD
*addrsize
)
505 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
506 return IDirectPlayLobby_CreateAddress( &This
->IDirectPlayLobby3A_iface
, sp
, datatype
, data
,
507 datasize
, address
, addrsize
);
510 static HRESULT WINAPI
IDirectPlayLobby2Impl_CreateAddress( IDirectPlayLobby2
*iface
, REFGUID sp
,
511 REFGUID datatype
, const void *data
, DWORD datasize
, void *address
, DWORD
*addrsize
)
513 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
514 return IDirectPlayLobby_CreateAddress( &This
->IDirectPlayLobby3_iface
, sp
, datatype
, data
,
515 datasize
, address
, addrsize
);
518 static HRESULT WINAPI
IDirectPlayLobby3AImpl_CreateAddress( IDirectPlayLobby3A
*iface
,
519 REFGUID guidSP
, REFGUID guidDataType
, const void *lpData
, DWORD dwDataSize
, void *lpAddress
,
520 DWORD
*lpdwAddressSize
)
522 return DPL_CreateAddress( guidSP
, guidDataType
, lpData
, dwDataSize
,
523 lpAddress
, lpdwAddressSize
, TRUE
);
526 static HRESULT WINAPI
IDirectPlayLobby3Impl_CreateAddress( IDirectPlayLobby3
*iface
, REFGUID guidSP
,
527 REFGUID guidDataType
, const void *lpData
, DWORD dwDataSize
, void *lpAddress
,
528 DWORD
*lpdwAddressSize
)
530 return DPL_CreateAddress( guidSP
, guidDataType
, lpData
, dwDataSize
,
531 lpAddress
, lpdwAddressSize
, FALSE
);
534 static HRESULT
DPL_CreateAddress(
536 REFGUID guidDataType
,
540 LPDWORD lpdwAddressSize
,
541 BOOL bAnsiInterface
)
543 const DWORD dwNumAddElements
= 2; /* Service Provide & address data type */
544 DPCOMPOUNDADDRESSELEMENT addressElements
[ 2 /* dwNumAddElements */ ];
546 TRACE( "(%p)->(%p,%p,0x%08x,%p,%p,%d)\n", guidSP
, guidDataType
, lpData
, dwDataSize
,
547 lpAddress
, lpdwAddressSize
, bAnsiInterface
);
549 addressElements
[ 0 ].guidDataType
= DPAID_ServiceProvider
;
550 addressElements
[ 0 ].dwDataSize
= sizeof( GUID
);
551 addressElements
[ 0 ].lpData
= (LPVOID
)guidSP
;
553 addressElements
[ 1 ].guidDataType
= *guidDataType
;
554 addressElements
[ 1 ].dwDataSize
= dwDataSize
;
555 addressElements
[ 1 ].lpData
= (LPVOID
)lpData
;
557 /* Call CreateCompoundAddress to cut down on code.
558 NOTE: We can do this because we don't support DPL 1 interfaces! */
559 return DPL_CreateCompoundAddress( addressElements
, dwNumAddElements
,
560 lpAddress
, lpdwAddressSize
, bAnsiInterface
);
565 /********************************************************************
567 * Parses out chunks from the DirectPlay Address buffer by calling the
568 * given callback function, with lpContext, for each of the chunks.
571 static HRESULT WINAPI
IDirectPlayLobbyAImpl_EnumAddress( IDirectPlayLobbyA
*iface
,
572 LPDPENUMADDRESSCALLBACK enumaddrcb
, const void *address
, DWORD size
, void *context
)
574 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
575 return IDirectPlayLobby_EnumAddress( &This
->IDirectPlayLobby3A_iface
, enumaddrcb
, address
, size
,
579 static HRESULT WINAPI
IDirectPlayLobbyImpl_EnumAddress( IDirectPlayLobby
*iface
,
580 LPDPENUMADDRESSCALLBACK enumaddrcb
, const void *address
, DWORD size
, void *context
)
582 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
583 return IDirectPlayLobby_EnumAddress( &This
->IDirectPlayLobby3_iface
, enumaddrcb
, address
, size
,
587 static HRESULT WINAPI
IDirectPlayLobby2AImpl_EnumAddress( IDirectPlayLobby2A
*iface
,
588 LPDPENUMADDRESSCALLBACK enumaddrcb
, const void *address
, DWORD size
, void *context
)
590 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
591 return IDirectPlayLobby_EnumAddress( &This
->IDirectPlayLobby3A_iface
, enumaddrcb
, address
, size
,
595 static HRESULT WINAPI
IDirectPlayLobby2Impl_EnumAddress( IDirectPlayLobby2
*iface
,
596 LPDPENUMADDRESSCALLBACK enumaddrcb
, const void *address
, DWORD size
, void *context
)
598 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
599 return IDirectPlayLobby_EnumAddress( &This
->IDirectPlayLobby3_iface
, enumaddrcb
, address
, size
,
603 static HRESULT WINAPI
IDirectPlayLobby3AImpl_EnumAddress( IDirectPlayLobby3A
*iface
,
604 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
, const void *lpAddress
, DWORD dwAddressSize
,
607 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
609 TRACE("(%p)->(%p,%p,0x%08x,%p)\n", This
, lpEnumAddressCallback
, lpAddress
,
610 dwAddressSize
, lpContext
);
612 return DPL_EnumAddress( lpEnumAddressCallback
, lpAddress
, dwAddressSize
, lpContext
);
615 static HRESULT WINAPI
IDirectPlayLobby3Impl_EnumAddress( IDirectPlayLobby3
*iface
,
616 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
, const void *lpAddress
, DWORD dwAddressSize
,
619 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
621 TRACE("(%p)->(%p,%p,0x%08x,%p)\n", This
, lpEnumAddressCallback
, lpAddress
,
622 dwAddressSize
, lpContext
);
624 return DPL_EnumAddress( lpEnumAddressCallback
, lpAddress
, dwAddressSize
, lpContext
);
627 HRESULT
DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback
, LPCVOID lpAddress
,
628 DWORD dwAddressSize
, LPVOID lpContext
)
630 DWORD dwTotalSizeEnumerated
= 0;
632 /* FIXME: First chunk is always the total size chunk - Should we report it? */
634 while ( dwTotalSizeEnumerated
< dwAddressSize
)
636 const DPADDRESS
* lpElements
= lpAddress
;
637 DWORD dwSizeThisEnumeration
;
639 /* Invoke the enum method. If false is returned, stop enumeration */
640 if ( !lpEnumAddressCallback( &lpElements
->guidDataType
,
641 lpElements
->dwDataSize
,
642 (const BYTE
*)lpElements
+ sizeof( DPADDRESS
),
648 dwSizeThisEnumeration
= sizeof( DPADDRESS
) + lpElements
->dwDataSize
;
649 lpAddress
= (const BYTE
*) lpAddress
+ dwSizeThisEnumeration
;
650 dwTotalSizeEnumerated
+= dwSizeThisEnumeration
;
656 /********************************************************************
658 * Enumerates all the address types that a given service provider needs to
659 * build the DirectPlay Address.
662 static HRESULT WINAPI
IDirectPlayLobbyAImpl_EnumAddressTypes( IDirectPlayLobbyA
*iface
,
663 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
665 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
666 return IDirectPlayLobby_EnumAddressTypes( &This
->IDirectPlayLobby3A_iface
, enumaddrtypecb
, sp
,
670 static HRESULT WINAPI
IDirectPlayLobbyImpl_EnumAddressTypes( IDirectPlayLobby
*iface
,
671 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
673 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
674 return IDirectPlayLobby_EnumAddressTypes( &This
->IDirectPlayLobby3_iface
, enumaddrtypecb
, sp
,
678 static HRESULT WINAPI
IDirectPlayLobby2AImpl_EnumAddressTypes( IDirectPlayLobby2A
*iface
,
679 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
681 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
682 return IDirectPlayLobby_EnumAddressTypes( &This
->IDirectPlayLobby3A_iface
, enumaddrtypecb
, sp
,
686 static HRESULT WINAPI
IDirectPlayLobby2Impl_EnumAddressTypes( IDirectPlayLobby2
*iface
,
687 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
689 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
690 return IDirectPlayLobby_EnumAddressTypes( &This
->IDirectPlayLobby3_iface
, enumaddrtypecb
, sp
,
694 static HRESULT WINAPI
IDirectPlayLobby3AImpl_EnumAddressTypes( IDirectPlayLobby3A
*iface
,
695 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback
, REFGUID guidSP
, void *lpContext
,
698 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
701 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
702 DWORD dwIndex
, sizeOfSubKeyName
=50;
706 TRACE(" (%p)->(%p,%p,%p,0x%08x)\n", This
, lpEnumAddressTypeCallback
, guidSP
, lpContext
, dwFlags
);
710 return DPERR_INVALIDPARAMS
;
713 if( !lpEnumAddressTypeCallback
)
715 return DPERR_INVALIDPARAMS
;
720 return DPERR_INVALIDOBJECT
;
723 /* Need to loop over the service providers in the registry */
724 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
725 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
727 /* Hmmm. Does this mean that there are no service providers? */
728 ERR(": no service providers?\n");
732 /* Traverse all the service providers we have available */
734 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
,
735 NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
736 ++dwIndex
, sizeOfSubKeyName
=50 )
739 HKEY hkServiceProvider
, hkServiceProviderAt
;
740 GUID serviceProviderGUID
;
741 DWORD returnTypeGUID
, sizeOfReturnBuffer
= 50;
743 char returnBuffer
[51];
746 LPCSTR atKey
= "Address Types";
747 LPCSTR guidDataSubKey
= "Guid";
749 TRACE(" this time through: %s\n", subKeyName
);
751 /* Get a handle for this particular service provider */
752 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
753 &hkServiceProvider
) != ERROR_SUCCESS
)
755 ERR(": what the heck is going on?\n" );
759 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
760 NULL
, &returnTypeGUID
, (LPBYTE
)returnBuffer
,
761 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
763 ERR(": missing GUID registry data members\n" );
767 /* FIXME: Check return types to ensure we're interpreting data right */
768 MultiByteToWideChar( CP_ACP
, 0, returnBuffer
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
769 CLSIDFromString( buff
, &serviceProviderGUID
);
770 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
772 /* Determine if this is the Service Provider that the user asked for */
773 if( !IsEqualGUID( &serviceProviderGUID
, guidSP
) )
778 /* Get a handle for this particular service provider */
779 if( RegOpenKeyExA( hkServiceProvider
, atKey
, 0, KEY_READ
,
780 &hkServiceProviderAt
) != ERROR_SUCCESS
)
782 TRACE(": No Address Types registry data sub key/members\n" );
786 /* Traverse all the address type we have available */
788 RegEnumKeyExA( hkServiceProviderAt
, dwAtIndex
, atSubKey
, &sizeOfSubKeyName
,
789 NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
790 ++dwAtIndex
, sizeOfSubKeyName
=50 )
792 TRACE( "Found Address Type GUID %s\n", atSubKey
);
794 /* FIXME: Check return types to ensure we're interpreting data right */
795 MultiByteToWideChar( CP_ACP
, 0, atSubKey
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
796 CLSIDFromString( buff
, &serviceProviderGUID
);
797 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
799 /* The enumeration will return FALSE if we are not to continue */
800 if( !lpEnumAddressTypeCallback( &serviceProviderGUID
, lpContext
, 0 ) )
802 WARN("lpEnumCallback returning FALSE\n" );
803 break; /* FIXME: This most likely has to break from the procedure...*/
808 /* We only enumerate address types for 1 GUID. We've found it, so quit looking */
815 static HRESULT WINAPI
IDirectPlayLobby3Impl_EnumAddressTypes( IDirectPlayLobby3
*iface
,
816 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
818 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
819 return IDirectPlayLobby_EnumAddressTypes( &This
->IDirectPlayLobby3A_iface
, enumaddrtypecb
, sp
,
823 /********************************************************************
825 * Enumerates what applications are registered with DirectPlay by
826 * invoking the callback function with lpContext.
829 static HRESULT WINAPI
IDirectPlayLobby3Impl_EnumLocalApplications( IDirectPlayLobby3
*iface
,
830 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback
, void *lpContext
, DWORD dwFlags
)
832 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
834 FIXME("(%p)->(%p,%p,0x%08x):stub\n", This
, lpEnumLocalAppCallback
, lpContext
, dwFlags
);
836 return DPERR_OUTOFMEMORY
;
839 static HRESULT WINAPI
IDirectPlayLobbyAImpl_EnumLocalApplications( IDirectPlayLobbyA
*iface
,
840 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
842 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
843 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3A_iface
, enumlocalappcb
,
847 static HRESULT WINAPI
IDirectPlayLobbyImpl_EnumLocalApplications( IDirectPlayLobby
*iface
,
848 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
850 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
851 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3_iface
, enumlocalappcb
,
855 static HRESULT WINAPI
IDirectPlayLobby2AImpl_EnumLocalApplications( IDirectPlayLobby2A
*iface
,
856 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
858 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
859 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3A_iface
, enumlocalappcb
,
863 static HRESULT WINAPI
IDirectPlayLobby2Impl_EnumLocalApplications( IDirectPlayLobby2
*iface
,
864 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
866 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
867 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3_iface
, enumlocalappcb
,
871 static HRESULT WINAPI
IDirectPlayLobby3AImpl_EnumLocalApplications( IDirectPlayLobby3A
*iface
,
872 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback
, void *lpContext
, DWORD dwFlags
)
874 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
877 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Applications";
878 LPCSTR guidDataSubKey
= "Guid";
879 DWORD dwIndex
, sizeOfSubKeyName
=50;
883 TRACE("(%p)->(%p,%p,0x%08x)\n", This
, lpEnumLocalAppCallback
, lpContext
, dwFlags
);
887 return DPERR_INVALIDPARAMS
;
890 if( !lpEnumLocalAppCallback
)
892 return DPERR_INVALIDPARAMS
;
895 /* Need to loop over the service providers in the registry */
896 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
897 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
899 /* Hmmm. Does this mean that there are no service providers? */
900 ERR(": no service providers?\n");
904 /* Traverse all registered applications */
906 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
, NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
907 ++dwIndex
, sizeOfSubKeyName
=50 )
910 HKEY hkServiceProvider
;
911 GUID serviceProviderGUID
;
912 DWORD returnTypeGUID
, sizeOfReturnBuffer
= 50;
913 char returnBuffer
[51];
915 DPLAPPINFO dplAppInfo
;
917 TRACE(" this time through: %s\n", subKeyName
);
919 /* Get a handle for this particular service provider */
920 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
921 &hkServiceProvider
) != ERROR_SUCCESS
)
923 ERR(": what the heck is going on?\n" );
927 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
928 NULL
, &returnTypeGUID
, (LPBYTE
)returnBuffer
,
929 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
931 ERR(": missing GUID registry data members\n" );
935 /* FIXME: Check return types to ensure we're interpreting data right */
936 MultiByteToWideChar( CP_ACP
, 0, returnBuffer
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
937 CLSIDFromString( buff
, &serviceProviderGUID
);
938 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
940 dplAppInfo
.dwSize
= sizeof( dplAppInfo
);
941 dplAppInfo
.guidApplication
= serviceProviderGUID
;
942 dplAppInfo
.u
.lpszAppNameA
= subKeyName
;
944 EnterCriticalSection( &This
->lock
);
946 memcpy( &This
->cbkeyhack
, &hkServiceProvider
, sizeof( hkServiceProvider
) );
948 if( !lpEnumLocalAppCallback( &dplAppInfo
, lpContext
, dwFlags
) )
950 LeaveCriticalSection( &This
->lock
);
954 LeaveCriticalSection( &This
->lock
);
960 /********************************************************************
962 * Retrieves the DPLCONNECTION structure that contains all the information
963 * needed to start and connect an application. This was generated using
964 * either the RunApplication or SetConnectionSettings methods.
966 * NOTES: If lpData is NULL then just return lpdwDataSize. This allows
967 * the data structure to be allocated by our caller which can then
968 * call this procedure/method again with a valid data pointer.
970 static HRESULT WINAPI
IDirectPlayLobbyAImpl_GetConnectionSettings( IDirectPlayLobbyA
*iface
,
971 DWORD appid
, void *data
, DWORD
*size
)
973 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
974 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, appid
, data
,
978 static HRESULT WINAPI
IDirectPlayLobbyImpl_GetConnectionSettings( IDirectPlayLobby
*iface
,
979 DWORD appid
, void *data
, DWORD
*size
)
981 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
982 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3_iface
, appid
, data
,
986 static HRESULT WINAPI
IDirectPlayLobby2AImpl_GetConnectionSettings( IDirectPlayLobby2A
*iface
,
987 DWORD appid
, void *data
, DWORD
*size
)
989 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
990 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, appid
, data
,
994 static HRESULT WINAPI
IDirectPlayLobby2Impl_GetConnectionSettings( IDirectPlayLobby2
*iface
,
995 DWORD appid
, void *data
, DWORD
*size
)
997 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
998 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3_iface
, appid
, data
,
1002 static HRESULT WINAPI
IDirectPlayLobby3AImpl_GetConnectionSettings( IDirectPlayLobby3A
*iface
,
1003 DWORD dwAppID
, void *lpData
, DWORD
*lpdwDataSize
)
1005 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1008 TRACE("(%p)->(0x%08x,%p,%p)\n", This
, dwAppID
, lpData
, lpdwDataSize
);
1010 EnterCriticalSection( &This
->lock
);
1012 hr
= DPLAYX_GetConnectionSettingsA( dwAppID
,
1017 LeaveCriticalSection( &This
->lock
);
1022 static HRESULT WINAPI
IDirectPlayLobby3Impl_GetConnectionSettings( IDirectPlayLobby3
*iface
,
1023 DWORD dwAppID
, void *lpData
, DWORD
*lpdwDataSize
)
1025 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1028 TRACE("(%p)->(0x%08x,%p,%p)\n", This
, dwAppID
, lpData
, lpdwDataSize
);
1030 EnterCriticalSection( &This
->lock
);
1032 hr
= DPLAYX_GetConnectionSettingsW( dwAppID
,
1037 LeaveCriticalSection( &This
->lock
);
1042 /********************************************************************
1044 * Retrieves the message sent between a lobby client and a DirectPlay
1045 * application. All messages are queued until received.
1048 static HRESULT WINAPI
IDirectPlayLobbyAImpl_ReceiveLobbyMessage( IDirectPlayLobbyA
*iface
,
1049 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1051 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1052 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1053 msgflags
, data
, size
);
1056 static HRESULT WINAPI
IDirectPlayLobbyImpl_ReceiveLobbyMessage( IDirectPlayLobby
*iface
,
1057 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1059 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1060 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1061 msgflags
, data
, size
);
1064 static HRESULT WINAPI
IDirectPlayLobby2AImpl_ReceiveLobbyMessage( IDirectPlayLobby2A
*iface
,
1065 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1067 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1068 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1069 msgflags
, data
, size
);
1072 static HRESULT WINAPI
IDirectPlayLobby2Impl_ReceiveLobbyMessage( IDirectPlayLobby2
*iface
,
1073 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1075 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1076 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1077 msgflags
, data
, size
);
1080 static HRESULT WINAPI
IDirectPlayLobby3AImpl_ReceiveLobbyMessage( IDirectPlayLobby3A
*iface
,
1081 DWORD dwFlags
, DWORD dwAppID
, DWORD
*lpdwMessageFlags
, void *lpData
,
1082 DWORD
*lpdwDataSize
)
1084 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1085 FIXME(":stub %p %08x %08x %p %p %p\n", This
, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
1087 return DPERR_OUTOFMEMORY
;
1090 static HRESULT WINAPI
IDirectPlayLobby3Impl_ReceiveLobbyMessage( IDirectPlayLobby3
*iface
,
1091 DWORD dwFlags
, DWORD dwAppID
, DWORD
*lpdwMessageFlags
, void *lpData
,
1092 DWORD
*lpdwDataSize
)
1094 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1095 FIXME(":stub %p %08x %08x %p %p %p\n", This
, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
1097 return DPERR_OUTOFMEMORY
;
1100 typedef struct tagRunApplicationEnumStruct
1102 IDirectPlayLobbyImpl
*This
;
1107 LPSTR lpszCommandLine
;
1108 LPSTR lpszCurrentDirectory
;
1109 } RunApplicationEnumStruct
, *lpRunApplicationEnumStruct
;
1111 /* To be called by RunApplication to find how to invoke the function */
1112 static BOOL CALLBACK RunApplicationA_EnumLocalApplications
1113 ( LPCDPLAPPINFO lpAppInfo
,
1117 lpRunApplicationEnumStruct lpData
= (lpRunApplicationEnumStruct
)lpContext
;
1119 if( IsEqualGUID( &lpAppInfo
->guidApplication
, &lpData
->appGUID
) )
1121 char returnBuffer
[200];
1122 DWORD returnType
, sizeOfReturnBuffer
;
1123 LPCSTR clSubKey
= "CommandLine";
1124 LPCSTR cdSubKey
= "CurrentDirectory";
1125 LPCSTR fileSubKey
= "File";
1126 LPCSTR pathSubKey
= "Path";
1128 /* FIXME: Lazy man hack - dplay struct has the present reg key saved */
1130 sizeOfReturnBuffer
= 200;
1132 /* Get all the appropriate data from the registry */
1133 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, clSubKey
,
1134 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1135 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1137 ERR( ": missing CommandLine registry data member\n" );
1141 if ((lpData
->lpszCommandLine
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1142 strcpy( lpData
->lpszCommandLine
, returnBuffer
);
1145 sizeOfReturnBuffer
= 200;
1147 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, cdSubKey
,
1148 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1149 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1151 ERR( ": missing CurrentDirectory registry data member\n" );
1155 if ((lpData
->lpszCurrentDirectory
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1156 strcpy( lpData
->lpszCurrentDirectory
, returnBuffer
);
1159 sizeOfReturnBuffer
= 200;
1161 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, fileSubKey
,
1162 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1163 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1165 ERR( ": missing File registry data member\n" );
1169 if ((lpData
->lpszFileName
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1170 strcpy( lpData
->lpszFileName
, returnBuffer
);
1173 sizeOfReturnBuffer
= 200;
1175 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, pathSubKey
,
1176 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1177 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1179 ERR( ": missing Path registry data member\n" );
1183 if ((lpData
->lpszPath
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1184 strcpy( lpData
->lpszPath
, returnBuffer
);
1187 return FALSE
; /* No need to keep going as we found what we wanted */
1190 return TRUE
; /* Keep enumerating, haven't found the application yet */
1193 static BOOL
DPL_CreateAndSetLobbyHandles( DWORD dwDestProcessId
, HANDLE hDestProcess
,
1194 LPHANDLE lphStart
, LPHANDLE lphDeath
,
1197 /* These are the handles for the created process */
1198 HANDLE hAppStart
= 0, hAppDeath
= 0, hAppRead
= 0;
1199 SECURITY_ATTRIBUTES s_attrib
;
1201 s_attrib
.nLength
= sizeof( s_attrib
);
1202 s_attrib
.lpSecurityDescriptor
= NULL
;
1203 s_attrib
.bInheritHandle
= TRUE
;
1205 *lphStart
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1206 *lphDeath
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1207 *lphRead
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1209 if( ( !DuplicateHandle( GetCurrentProcess(), *lphStart
,
1210 hDestProcess
, &hAppStart
,
1211 0, FALSE
, DUPLICATE_SAME_ACCESS
) ) ||
1212 ( !DuplicateHandle( GetCurrentProcess(), *lphDeath
,
1213 hDestProcess
, &hAppDeath
,
1214 0, FALSE
, DUPLICATE_SAME_ACCESS
) ) ||
1215 ( !DuplicateHandle( GetCurrentProcess(), *lphRead
,
1216 hDestProcess
, &hAppRead
,
1217 0, FALSE
, DUPLICATE_SAME_ACCESS
) )
1220 if (*lphStart
) { CloseHandle(*lphStart
); *lphStart
= 0; }
1221 if (*lphDeath
) { CloseHandle(*lphDeath
); *lphDeath
= 0; }
1222 if (*lphRead
) { CloseHandle(*lphRead
); *lphRead
= 0; }
1223 /* FIXME: Handle leak... */
1224 ERR( "Unable to dup handles\n" );
1228 if( !DPLAYX_SetLobbyHandles( dwDestProcessId
,
1229 hAppStart
, hAppDeath
, hAppRead
) )
1231 /* FIXME: Handle leak... */
1239 /********************************************************************
1241 * Starts an application and passes to it all the information to
1242 * connect to a session.
1245 static HRESULT WINAPI
IDirectPlayLobbyAImpl_RunApplication( IDirectPlayLobbyA
*iface
, DWORD flags
,
1246 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1248 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1249 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, conn
,
1253 static HRESULT WINAPI
IDirectPlayLobbyImpl_RunApplication( IDirectPlayLobby
*iface
, DWORD flags
,
1254 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1256 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1257 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3_iface
, flags
, appid
, conn
,
1261 static HRESULT WINAPI
IDirectPlayLobby2AImpl_RunApplication( IDirectPlayLobby2A
*iface
, DWORD flags
,
1262 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1264 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1265 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, conn
,
1269 static HRESULT WINAPI
IDirectPlayLobby2Impl_RunApplication( IDirectPlayLobby2
*iface
, DWORD flags
,
1270 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1272 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1273 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3_iface
, flags
, appid
, conn
,
1277 static HRESULT WINAPI
IDirectPlayLobby3AImpl_RunApplication( IDirectPlayLobby3A
*iface
,
1278 DWORD dwFlags
, DWORD
*lpdwAppID
, DPLCONNECTION
*lpConn
, HANDLE hReceiveEvent
)
1280 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1282 RunApplicationEnumStruct enumData
;
1284 STARTUPINFOA startupInfo
;
1285 PROCESS_INFORMATION newProcessInfo
;
1287 DWORD dwSuspendCount
;
1288 HANDLE hStart
, hDeath
, hSettingRead
;
1290 TRACE( "(%p)->(0x%08x,%p,%p,%p)\n",
1291 This
, dwFlags
, lpdwAppID
, lpConn
, hReceiveEvent
);
1295 return DPERR_INVALIDPARAMS
;
1298 if( DPLAYX_AnyLobbiesWaitingForConnSettings() )
1300 FIXME( "Waiting lobby not being handled correctly\n" );
1303 EnterCriticalSection( &This
->lock
);
1305 ZeroMemory( &enumData
, sizeof( enumData
) );
1306 enumData
.This
= This
;
1307 enumData
.appGUID
= lpConn
->lpSessionDesc
->guidApplication
;
1309 /* Our callback function will fill up the enumData structure with all the information
1310 required to start a new process */
1311 IDirectPlayLobby_EnumLocalApplications( iface
, RunApplicationA_EnumLocalApplications
,
1314 /* First the application name */
1315 strcpy( temp
, enumData
.lpszPath
);
1316 strcat( temp
, "\\" );
1317 strcat( temp
, enumData
.lpszFileName
);
1318 HeapFree( GetProcessHeap(), 0, enumData
.lpszPath
);
1319 HeapFree( GetProcessHeap(), 0, enumData
.lpszFileName
);
1320 if ((appName
= HeapAlloc( GetProcessHeap(), 0, strlen(temp
)+1 ))) strcpy( appName
, temp
);
1322 /* Now the command line */
1323 strcat( temp
, " " );
1324 strcat( temp
, enumData
.lpszCommandLine
);
1325 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1326 if ((enumData
.lpszCommandLine
= HeapAlloc( GetProcessHeap(), 0, strlen(temp
)+1 )))
1327 strcpy( enumData
.lpszCommandLine
, temp
);
1329 ZeroMemory( &startupInfo
, sizeof( startupInfo
) );
1330 startupInfo
.cb
= sizeof( startupInfo
);
1331 /* FIXME: Should any fields be filled in? */
1333 ZeroMemory( &newProcessInfo
, sizeof( newProcessInfo
) );
1335 if( !CreateProcessA( appName
,
1336 enumData
.lpszCommandLine
,
1340 CREATE_DEFAULT_ERROR_MODE
| CREATE_NEW_CONSOLE
| CREATE_SUSPENDED
, /* Creation Flags */
1342 enumData
.lpszCurrentDirectory
,
1348 ERR( "Failed to create process for app %s\n", appName
);
1350 HeapFree( GetProcessHeap(), 0, appName
);
1351 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1352 HeapFree( GetProcessHeap(), 0, enumData
.lpszCurrentDirectory
);
1354 LeaveCriticalSection( &This
->lock
);
1355 return DPERR_CANTCREATEPROCESS
;
1358 HeapFree( GetProcessHeap(), 0, appName
);
1359 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1360 HeapFree( GetProcessHeap(), 0, enumData
.lpszCurrentDirectory
);
1362 /* Reserve this global application id! */
1363 if( !DPLAYX_CreateLobbyApplication( newProcessInfo
.dwProcessId
) )
1365 ERR( "Unable to create global application data for 0x%08x\n",
1366 newProcessInfo
.dwProcessId
);
1369 hr
= IDirectPlayLobby_SetConnectionSettings( iface
, 0, newProcessInfo
.dwProcessId
, lpConn
);
1373 ERR( "SetConnectionSettings failure %s\n", DPLAYX_HresultToString( hr
) );
1374 LeaveCriticalSection( &This
->lock
);
1378 /* Setup the handles for application notification */
1379 DPL_CreateAndSetLobbyHandles( newProcessInfo
.dwProcessId
,
1380 newProcessInfo
.hProcess
,
1381 &hStart
, &hDeath
, &hSettingRead
);
1383 /* Setup the message thread ID */
1384 This
->msgtid
= CreateLobbyMessageReceptionThread( hReceiveEvent
, hStart
, hDeath
, hSettingRead
);
1386 DPLAYX_SetLobbyMsgThreadId( newProcessInfo
.dwProcessId
, This
->msgtid
);
1388 LeaveCriticalSection( &This
->lock
);
1390 /* Everything seems to have been set correctly, update the dwAppID */
1391 *lpdwAppID
= newProcessInfo
.dwProcessId
;
1393 /* Unsuspend the process - should return the prev suspension count */
1394 if( ( dwSuspendCount
= ResumeThread( newProcessInfo
.hThread
) ) != 1 )
1396 ERR( "ResumeThread failed with 0x%08x\n", dwSuspendCount
);
1402 static HRESULT WINAPI
IDirectPlayLobby3Impl_RunApplication( IDirectPlayLobby3
*iface
, DWORD dwFlags
,
1403 DWORD
*lpdwAppID
, DPLCONNECTION
*lpConn
, HANDLE hReceiveEvent
)
1405 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1406 FIXME( "(%p)->(0x%08x,%p,%p,%p):stub\n", This
, dwFlags
, lpdwAppID
, lpConn
, hReceiveEvent
);
1407 return DPERR_OUTOFMEMORY
;
1410 /********************************************************************
1412 * Sends a message between the application and the lobby client.
1413 * All messages are queued until received.
1416 static HRESULT WINAPI
IDirectPlayLobbyAImpl_SendLobbyMessage( IDirectPlayLobbyA
*iface
, DWORD flags
,
1417 DWORD appid
, void *data
, DWORD size
)
1419 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1420 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, data
,
1424 static HRESULT WINAPI
IDirectPlayLobbyImpl_SendLobbyMessage( IDirectPlayLobby
*iface
, DWORD flags
,
1425 DWORD appid
, void *data
, DWORD size
)
1427 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1428 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
, data
,
1432 static HRESULT WINAPI
IDirectPlayLobby2AImpl_SendLobbyMessage( IDirectPlayLobby2A
*iface
,
1433 DWORD flags
, DWORD appid
, void *data
, DWORD size
)
1435 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1436 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, data
,
1440 static HRESULT WINAPI
IDirectPlayLobby2Impl_SendLobbyMessage( IDirectPlayLobby2
*iface
, DWORD flags
,
1441 DWORD appid
, void *data
, DWORD size
)
1443 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1444 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
, data
,
1448 static HRESULT WINAPI
IDirectPlayLobby3AImpl_SendLobbyMessage( IDirectPlayLobby3A
*iface
,
1449 DWORD flags
, DWORD appid
, void *data
, DWORD size
)
1452 return DPERR_OUTOFMEMORY
;
1455 static HRESULT WINAPI
IDirectPlayLobby3Impl_SendLobbyMessage( IDirectPlayLobby3
*iface
,
1456 DWORD flags
, DWORD appid
, void *data
, DWORD size
)
1459 return DPERR_OUTOFMEMORY
;
1462 /********************************************************************
1464 * Modifies the DPLCONNECTION structure to contain all information
1465 * needed to start and connect an application.
1468 static HRESULT WINAPI
IDirectPlayLobby3Impl_SetConnectionSettings( IDirectPlayLobby3
*iface
,
1469 DWORD dwFlags
, DWORD dwAppID
, DPLCONNECTION
*lpConn
)
1471 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1474 TRACE("(%p)->(0x%08x,0x%08x,%p)\n", This
, dwFlags
, dwAppID
, lpConn
);
1476 EnterCriticalSection( &This
->lock
);
1478 hr
= DPLAYX_SetConnectionSettingsW( dwFlags
, dwAppID
, lpConn
);
1480 /* FIXME: Don't think that this is supposed to fail, but the documentation
1481 is somewhat sketchy. I'll try creating a lobby application
1483 if( hr
== DPERR_NOTLOBBIED
)
1485 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1488 dwAppID
= GetCurrentProcessId();
1490 DPLAYX_CreateLobbyApplication( dwAppID
);
1491 hr
= DPLAYX_SetConnectionSettingsW( dwFlags
, dwAppID
, lpConn
);
1494 LeaveCriticalSection( &This
->lock
);
1499 static HRESULT WINAPI
IDirectPlayLobbyAImpl_SetConnectionSettings( IDirectPlayLobbyA
*iface
,
1500 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1502 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1503 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, flags
,
1507 static HRESULT WINAPI
IDirectPlayLobbyImpl_SetConnectionSettings( IDirectPlayLobby
*iface
,
1508 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1510 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1511 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3_iface
, flags
,
1515 static HRESULT WINAPI
IDirectPlayLobby2AImpl_SetConnectionSettings( IDirectPlayLobby2A
*iface
,
1516 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1518 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1519 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, flags
,
1523 static HRESULT WINAPI
IDirectPlayLobby2Impl_SetConnectionSettings( IDirectPlayLobby2
*iface
,
1524 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1526 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1527 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3_iface
, flags
,
1531 static HRESULT WINAPI
IDirectPlayLobby3AImpl_SetConnectionSettings( IDirectPlayLobby3A
*iface
,
1532 DWORD dwFlags
, DWORD dwAppID
, DPLCONNECTION
*lpConn
)
1534 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1537 TRACE("(%p)->(0x%08x,0x%08x,%p)\n", This
, dwFlags
, dwAppID
, lpConn
);
1539 EnterCriticalSection( &This
->lock
);
1541 hr
= DPLAYX_SetConnectionSettingsA( dwFlags
, dwAppID
, lpConn
);
1543 /* FIXME: Don't think that this is supposed to fail, but the documentation
1544 is somewhat sketchy. I'll try creating a lobby application
1546 if( hr
== DPERR_NOTLOBBIED
)
1548 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1549 dwAppID
= GetCurrentProcessId();
1550 DPLAYX_CreateLobbyApplication( dwAppID
);
1551 hr
= DPLAYX_SetConnectionSettingsA( dwFlags
, dwAppID
, lpConn
);
1554 LeaveCriticalSection( &This
->lock
);
1559 /********************************************************************
1561 * Registers an event that will be set when a lobby message is received.
1564 static HRESULT WINAPI
IDirectPlayLobbyAImpl_SetLobbyMessageEvent( IDirectPlayLobbyA
*iface
,
1565 DWORD flags
, DWORD appid
, HANDLE event
)
1567 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1568 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1572 static HRESULT WINAPI
IDirectPlayLobbyImpl_SetLobbyMessageEvent( IDirectPlayLobby
*iface
,
1573 DWORD flags
, DWORD appid
, HANDLE event
)
1575 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1576 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1580 static HRESULT WINAPI
IDirectPlayLobby2AImpl_SetLobbyMessageEvent( IDirectPlayLobby2A
*iface
,
1581 DWORD flags
, DWORD appid
, HANDLE event
)
1583 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1584 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1588 static HRESULT WINAPI
IDirectPlayLobby2Impl_SetLobbyMessageEvent( IDirectPlayLobby2
*iface
,
1589 DWORD flags
, DWORD appid
, HANDLE event
)
1591 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1592 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1596 static HRESULT WINAPI
IDirectPlayLobby3AImpl_SetLobbyMessageEvent( IDirectPlayLobby3A
*iface
,
1597 DWORD flags
, DWORD appid
, HANDLE event
)
1600 return DPERR_OUTOFMEMORY
;
1603 static HRESULT WINAPI
IDirectPlayLobby3Impl_SetLobbyMessageEvent( IDirectPlayLobby3
*iface
,
1604 DWORD flags
, DWORD appid
, HANDLE event
)
1607 return DPERR_OUTOFMEMORY
;
1612 static HRESULT WINAPI
IDirectPlayLobby2AImpl_CreateCompoundAddress( IDirectPlayLobby2A
*iface
,
1613 const DPCOMPOUNDADDRESSELEMENT
*elements
, DWORD count
, void *address
, DWORD
*size
)
1615 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1616 return IDirectPlayLobby_CreateCompoundAddress( &This
->IDirectPlayLobby3A_iface
, elements
,
1617 count
, address
, size
);
1620 static HRESULT WINAPI
IDirectPlayLobby2Impl_CreateCompoundAddress( IDirectPlayLobby2
*iface
,
1621 const DPCOMPOUNDADDRESSELEMENT
*elements
, DWORD count
, void *address
, DWORD
*size
)
1623 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1624 return IDirectPlayLobby_CreateCompoundAddress( &This
->IDirectPlayLobby3_iface
, elements
,
1625 count
, address
, size
);
1628 static HRESULT WINAPI
IDirectPlayLobby3Impl_CreateCompoundAddress( IDirectPlayLobby3
*iface
,
1629 const DPCOMPOUNDADDRESSELEMENT
*lpElements
, DWORD dwElementCount
, void *lpAddress
,
1630 DWORD
*lpdwAddressSize
)
1632 return DPL_CreateCompoundAddress( lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
, FALSE
);
1635 static HRESULT WINAPI
IDirectPlayLobby3AImpl_CreateCompoundAddress( IDirectPlayLobby3A
*iface
,
1636 const DPCOMPOUNDADDRESSELEMENT
*lpElements
, DWORD dwElementCount
, void *lpAddress
,
1637 DWORD
*lpdwAddressSize
)
1639 return DPL_CreateCompoundAddress( lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
, TRUE
);
1642 HRESULT DPL_CreateCompoundAddress
1643 ( LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1644 DWORD dwElementCount
,
1646 LPDWORD lpdwAddressSize
,
1647 BOOL bAnsiInterface
)
1649 DWORD dwSizeRequired
= 0;
1651 LPCDPCOMPOUNDADDRESSELEMENT lpOrigElements
= lpElements
;
1653 TRACE("(%p,0x%08x,%p,%p)\n", lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
);
1655 /* Parameter check */
1656 if( ( lpElements
== NULL
) ||
1657 ( dwElementCount
== 0 ) /* FIXME: Not sure if this is a failure case */
1660 return DPERR_INVALIDPARAMS
;
1663 /* Add the total size chunk */
1664 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( DWORD
);
1666 /* Calculate the size of the buffer required */
1667 for ( dwElements
= dwElementCount
; dwElements
> 0; --dwElements
, ++lpElements
)
1669 if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ServiceProvider
) ) ||
1670 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_LobbyProvider
) )
1673 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( GUID
);
1675 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Phone
) ) ||
1676 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Modem
) ) ||
1677 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INet
) )
1680 if( !bAnsiInterface
)
1682 ERR( "Ansi GUIDs used for unicode interface\n" );
1683 return DPERR_INVALIDFLAGS
;
1686 dwSizeRequired
+= sizeof( DPADDRESS
) + lpElements
->dwDataSize
;
1688 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_PhoneW
) ) ||
1689 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ModemW
) ) ||
1690 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetW
) )
1693 if( bAnsiInterface
)
1695 ERR( "Unicode GUIDs used for ansi interface\n" );
1696 return DPERR_INVALIDFLAGS
;
1699 FIXME( "Right size for unicode interface?\n" );
1700 dwSizeRequired
+= sizeof( DPADDRESS
) + lpElements
->dwDataSize
* sizeof( WCHAR
);
1702 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetPort
) )
1704 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( WORD
);
1706 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ComPort
) )
1708 FIXME( "Right size for unicode interface?\n" );
1709 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( DPCOMPORTADDRESS
); /* FIXME: Right size? */
1713 WARN( "Skipping Unknown GUID %s\n", debugstr_guid(&lpElements
->guidDataType
) );
1717 /* The user wants to know how big a buffer to allocate for us */
1718 if( ( lpAddress
== NULL
) ||
1719 ( *lpdwAddressSize
< dwSizeRequired
)
1722 *lpdwAddressSize
= dwSizeRequired
;
1723 return DPERR_BUFFERTOOSMALL
;
1726 /* Add the total size chunk */
1728 LPDPADDRESS lpdpAddress
= lpAddress
;
1730 lpdpAddress
->guidDataType
= DPAID_TotalSize
;
1731 lpdpAddress
->dwDataSize
= sizeof( DWORD
);
1732 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1734 *(LPDWORD
)lpAddress
= dwSizeRequired
;
1735 lpAddress
= (char *) lpAddress
+ sizeof( DWORD
);
1738 /* Calculate the size of the buffer required */
1739 for( dwElements
= dwElementCount
, lpElements
= lpOrigElements
;
1741 --dwElements
, ++lpElements
)
1743 if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ServiceProvider
) ) ||
1744 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_LobbyProvider
) )
1747 LPDPADDRESS lpdpAddress
= lpAddress
;
1749 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1750 lpdpAddress
->dwDataSize
= sizeof( GUID
);
1751 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1753 CopyMemory( lpAddress
, lpElements
->lpData
, sizeof( GUID
) );
1754 lpAddress
= (char *) lpAddress
+ sizeof( GUID
);
1756 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Phone
) ) ||
1757 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Modem
) ) ||
1758 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INet
) )
1761 LPDPADDRESS lpdpAddress
= lpAddress
;
1763 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1764 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1765 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1767 lstrcpynA( lpAddress
, lpElements
->lpData
, lpElements
->dwDataSize
);
1768 lpAddress
= (char *) lpAddress
+ lpElements
->dwDataSize
;
1770 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_PhoneW
) ) ||
1771 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ModemW
) ) ||
1772 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetW
) )
1775 LPDPADDRESS lpdpAddress
= lpAddress
;
1777 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1778 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1779 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1781 lstrcpynW( lpAddress
, lpElements
->lpData
, lpElements
->dwDataSize
);
1782 lpAddress
= (char *) lpAddress
+ lpElements
->dwDataSize
* sizeof( WCHAR
);
1784 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetPort
) )
1786 LPDPADDRESS lpdpAddress
= lpAddress
;
1788 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1789 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1790 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1792 *((LPWORD
)lpAddress
) = *((LPWORD
)lpElements
->lpData
);
1793 lpAddress
= (char *) lpAddress
+ sizeof( WORD
);
1795 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ComPort
) )
1797 LPDPADDRESS lpdpAddress
= lpAddress
;
1799 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1800 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1801 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1803 CopyMemory( lpAddress
, lpElements
->lpData
, sizeof( DPADDRESS
) );
1804 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1813 static HRESULT WINAPI
IDirectPlayLobby3Impl_ConnectEx( IDirectPlayLobby3
*iface
, DWORD dwFlags
,
1814 REFIID riid
, LPVOID
* lplpDP
, IUnknown
* pUnk
)
1816 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1817 return DPL_ConnectEx( This
, dwFlags
, riid
, lplpDP
, pUnk
);
1820 static HRESULT WINAPI
IDirectPlayLobby3AImpl_ConnectEx( IDirectPlayLobby3A
*iface
, DWORD dwFlags
,
1821 REFIID riid
, void **lplpDP
, IUnknown
*pUnk
)
1823 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1824 return DPL_ConnectEx( This
, dwFlags
, riid
, lplpDP
, pUnk
);
1827 static HRESULT WINAPI
IDirectPlayLobby3Impl_RegisterApplication( IDirectPlayLobby3
*iface
,
1828 DWORD flags
, DPAPPLICATIONDESC
*appdesc
)
1834 static HRESULT WINAPI
IDirectPlayLobby3AImpl_RegisterApplication( IDirectPlayLobby3A
*iface
,
1835 DWORD flags
, DPAPPLICATIONDESC
*appdesc
)
1841 static HRESULT WINAPI
IDirectPlayLobby3Impl_UnregisterApplication( IDirectPlayLobby3
*iface
,
1842 DWORD flags
, REFGUID appdesc
)
1848 static HRESULT WINAPI
IDirectPlayLobby3AImpl_UnregisterApplication( IDirectPlayLobby3A
*iface
,
1849 DWORD flags
, REFGUID appdesc
)
1855 static HRESULT WINAPI
IDirectPlayLobby3Impl_WaitForConnectionSettings( IDirectPlayLobby3
*iface
,
1859 BOOL bStartWait
= !(dwFlags
& DPLWAIT_CANCEL
);
1861 TRACE( "(%p)->(0x%08x)\n", iface
, dwFlags
);
1863 if( DPLAYX_WaitForConnectionSettings( bStartWait
) )
1865 /* FIXME: What is the correct error return code? */
1866 hr
= DPERR_NOTLOBBIED
;
1872 static HRESULT WINAPI
IDirectPlayLobby3AImpl_WaitForConnectionSettings( IDirectPlayLobby3A
*iface
,
1876 BOOL bStartWait
= !(dwFlags
& DPLWAIT_CANCEL
);
1878 TRACE( "(%p)->(0x%08x)\n", iface
, dwFlags
);
1880 if( DPLAYX_WaitForConnectionSettings( bStartWait
) )
1882 /* FIXME: What is the correct error return code? */
1883 hr
= DPERR_NOTLOBBIED
;
1889 static const IDirectPlayLobbyVtbl dplA_vt
=
1891 IDirectPlayLobbyAImpl_QueryInterface
,
1892 IDirectPlayLobbyAImpl_AddRef
,
1893 IDirectPlayLobbyAImpl_Release
,
1894 IDirectPlayLobbyAImpl_Connect
,
1895 IDirectPlayLobbyAImpl_CreateAddress
,
1896 IDirectPlayLobbyAImpl_EnumAddress
,
1897 IDirectPlayLobbyAImpl_EnumAddressTypes
,
1898 IDirectPlayLobbyAImpl_EnumLocalApplications
,
1899 IDirectPlayLobbyAImpl_GetConnectionSettings
,
1900 IDirectPlayLobbyAImpl_ReceiveLobbyMessage
,
1901 IDirectPlayLobbyAImpl_RunApplication
,
1902 IDirectPlayLobbyAImpl_SendLobbyMessage
,
1903 IDirectPlayLobbyAImpl_SetConnectionSettings
,
1904 IDirectPlayLobbyAImpl_SetLobbyMessageEvent
1907 static const IDirectPlayLobbyVtbl dpl_vt
=
1909 IDirectPlayLobbyImpl_QueryInterface
,
1910 IDirectPlayLobbyImpl_AddRef
,
1911 IDirectPlayLobbyImpl_Release
,
1912 IDirectPlayLobbyImpl_Connect
,
1913 IDirectPlayLobbyImpl_CreateAddress
,
1914 IDirectPlayLobbyImpl_EnumAddress
,
1915 IDirectPlayLobbyImpl_EnumAddressTypes
,
1916 IDirectPlayLobbyImpl_EnumLocalApplications
,
1917 IDirectPlayLobbyImpl_GetConnectionSettings
,
1918 IDirectPlayLobbyImpl_ReceiveLobbyMessage
,
1919 IDirectPlayLobbyImpl_RunApplication
,
1920 IDirectPlayLobbyImpl_SendLobbyMessage
,
1921 IDirectPlayLobbyImpl_SetConnectionSettings
,
1922 IDirectPlayLobbyImpl_SetLobbyMessageEvent
1925 static const IDirectPlayLobby2Vtbl dpl2A_vt
=
1927 IDirectPlayLobby2AImpl_QueryInterface
,
1928 IDirectPlayLobby2AImpl_AddRef
,
1929 IDirectPlayLobby2AImpl_Release
,
1930 IDirectPlayLobby2AImpl_Connect
,
1931 IDirectPlayLobby2AImpl_CreateAddress
,
1932 IDirectPlayLobby2AImpl_EnumAddress
,
1933 IDirectPlayLobby2AImpl_EnumAddressTypes
,
1934 IDirectPlayLobby2AImpl_EnumLocalApplications
,
1935 IDirectPlayLobby2AImpl_GetConnectionSettings
,
1936 IDirectPlayLobby2AImpl_ReceiveLobbyMessage
,
1937 IDirectPlayLobby2AImpl_RunApplication
,
1938 IDirectPlayLobby2AImpl_SendLobbyMessage
,
1939 IDirectPlayLobby2AImpl_SetConnectionSettings
,
1940 IDirectPlayLobby2AImpl_SetLobbyMessageEvent
,
1941 IDirectPlayLobby2AImpl_CreateCompoundAddress
1944 static const IDirectPlayLobby2Vtbl dpl2_vt
=
1946 IDirectPlayLobby2Impl_QueryInterface
,
1947 IDirectPlayLobby2Impl_AddRef
,
1948 IDirectPlayLobby2Impl_Release
,
1949 IDirectPlayLobby2Impl_Connect
,
1950 IDirectPlayLobby2Impl_CreateAddress
,
1951 IDirectPlayLobby2Impl_EnumAddress
,
1952 IDirectPlayLobby2Impl_EnumAddressTypes
,
1953 IDirectPlayLobby2Impl_EnumLocalApplications
,
1954 IDirectPlayLobby2Impl_GetConnectionSettings
,
1955 IDirectPlayLobby2Impl_ReceiveLobbyMessage
,
1956 IDirectPlayLobby2Impl_RunApplication
,
1957 IDirectPlayLobby2Impl_SendLobbyMessage
,
1958 IDirectPlayLobby2Impl_SetConnectionSettings
,
1959 IDirectPlayLobby2Impl_SetLobbyMessageEvent
,
1960 IDirectPlayLobby2Impl_CreateCompoundAddress
1963 static const IDirectPlayLobby3Vtbl dpl3A_vt
=
1965 IDirectPlayLobby3AImpl_QueryInterface
,
1966 IDirectPlayLobby3AImpl_AddRef
,
1967 IDirectPlayLobby3AImpl_Release
,
1968 IDirectPlayLobby3AImpl_Connect
,
1969 IDirectPlayLobby3AImpl_CreateAddress
,
1970 IDirectPlayLobby3AImpl_EnumAddress
,
1971 IDirectPlayLobby3AImpl_EnumAddressTypes
,
1972 IDirectPlayLobby3AImpl_EnumLocalApplications
,
1973 IDirectPlayLobby3AImpl_GetConnectionSettings
,
1974 IDirectPlayLobby3AImpl_ReceiveLobbyMessage
,
1975 IDirectPlayLobby3AImpl_RunApplication
,
1976 IDirectPlayLobby3AImpl_SendLobbyMessage
,
1977 IDirectPlayLobby3AImpl_SetConnectionSettings
,
1978 IDirectPlayLobby3AImpl_SetLobbyMessageEvent
,
1979 IDirectPlayLobby3AImpl_CreateCompoundAddress
,
1980 IDirectPlayLobby3AImpl_ConnectEx
,
1981 IDirectPlayLobby3AImpl_RegisterApplication
,
1982 IDirectPlayLobby3AImpl_UnregisterApplication
,
1983 IDirectPlayLobby3AImpl_WaitForConnectionSettings
1986 static const IDirectPlayLobby3Vtbl dpl3_vt
=
1988 IDirectPlayLobby3Impl_QueryInterface
,
1989 IDirectPlayLobby3Impl_AddRef
,
1990 IDirectPlayLobby3Impl_Release
,
1991 IDirectPlayLobby3Impl_Connect
,
1992 IDirectPlayLobby3Impl_CreateAddress
,
1993 IDirectPlayLobby3Impl_EnumAddress
,
1994 IDirectPlayLobby3Impl_EnumAddressTypes
,
1995 IDirectPlayLobby3Impl_EnumLocalApplications
,
1996 IDirectPlayLobby3Impl_GetConnectionSettings
,
1997 IDirectPlayLobby3Impl_ReceiveLobbyMessage
,
1998 IDirectPlayLobby3Impl_RunApplication
,
1999 IDirectPlayLobby3Impl_SendLobbyMessage
,
2000 IDirectPlayLobby3Impl_SetConnectionSettings
,
2001 IDirectPlayLobby3Impl_SetLobbyMessageEvent
,
2002 IDirectPlayLobby3Impl_CreateCompoundAddress
,
2003 IDirectPlayLobby3Impl_ConnectEx
,
2004 IDirectPlayLobby3Impl_RegisterApplication
,
2005 IDirectPlayLobby3Impl_UnregisterApplication
,
2006 IDirectPlayLobby3Impl_WaitForConnectionSettings
2009 HRESULT
dplobby_create( REFIID riid
, void **ppv
)
2011 IDirectPlayLobbyImpl
*obj
;
2014 TRACE( "(%s, %p)\n", debugstr_guid( riid
), ppv
);
2017 obj
= HeapAlloc( GetProcessHeap(), 0, sizeof( *obj
) );
2019 return DPERR_OUTOFMEMORY
;
2021 obj
->IDirectPlayLobby_iface
.lpVtbl
= &dpl_vt
;
2022 obj
->IDirectPlayLobbyA_iface
.lpVtbl
= &dplA_vt
;
2023 obj
->IDirectPlayLobby2_iface
.lpVtbl
= &dpl2_vt
;
2024 obj
->IDirectPlayLobby2A_iface
.lpVtbl
= &dpl2A_vt
;
2025 obj
->IDirectPlayLobby3_iface
.lpVtbl
= &dpl3_vt
;
2026 obj
->IDirectPlayLobby3A_iface
.lpVtbl
= &dpl3A_vt
;
2036 InitializeCriticalSection( &obj
->lock
);
2037 obj
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": IDirectPlayLobbyImpl.lock");
2038 DPQ_INIT( obj
->msgs
);
2040 hr
= IDirectPlayLobby_QueryInterface( &obj
->IDirectPlayLobby3_iface
, riid
, ppv
);
2041 IDirectPlayLobby_Release( &obj
->IDirectPlayLobby3_iface
);
2048 /***************************************************************************
2049 * DirectPlayLobbyCreateA (DPLAYX.4)
2052 HRESULT WINAPI
DirectPlayLobbyCreateA( GUID
*lpGUIDDSP
, IDirectPlayLobbyA
**lplpDPL
,
2053 IUnknown
*lpUnk
, void *lpData
, DWORD dwDataSize
)
2055 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08x\n",
2056 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
2058 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
2059 * equal 0. These fields are mostly for future expansion.
2061 if ( lpGUIDDSP
|| lpData
|| dwDataSize
)
2064 return DPERR_INVALIDPARAMS
;
2070 ERR("Bad parameters!\n" );
2071 return CLASS_E_NOAGGREGATION
;
2074 return dplobby_create( &IID_IDirectPlayLobbyA
, (void**)lplpDPL
);
2077 /***************************************************************************
2078 * DirectPlayLobbyCreateW (DPLAYX.5)
2081 HRESULT WINAPI
DirectPlayLobbyCreateW( GUID
*lpGUIDDSP
, IDirectPlayLobby
**lplpDPL
,
2082 IUnknown
*lpUnk
, void *lpData
, DWORD dwDataSize
)
2084 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08x\n",
2085 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
2087 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
2088 * equal 0. These fields are mostly for future expansion.
2090 if ( lpGUIDDSP
|| lpData
|| dwDataSize
)
2093 ERR("Bad parameters!\n" );
2094 return DPERR_INVALIDPARAMS
;
2100 ERR("Bad parameters!\n" );
2101 return CLASS_E_NOAGGREGATION
;
2104 return dplobby_create( &IID_IDirectPlayLobby
, (void**)lplpDPL
);