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";
751 TRACE(" this time through: %s\n", subKeyName
);
753 /* Get a handle for this particular service provider */
754 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
755 &hkServiceProvider
) != ERROR_SUCCESS
)
757 ERR(": what the heck is going on?\n" );
761 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
762 NULL
, &returnTypeGUID
, (LPBYTE
)returnBuffer
,
763 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
765 ERR(": missing GUID registry data members\n" );
769 /* FIXME: Check return types to ensure we're interpreting data right */
770 MultiByteToWideChar( CP_ACP
, 0, returnBuffer
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
771 CLSIDFromString( buff
, &serviceProviderGUID
);
772 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
774 /* Determine if this is the Service Provider that the user asked for */
775 if( !IsEqualGUID( &serviceProviderGUID
, guidSP
) )
780 /* Get a handle for this particular service provider */
781 if( RegOpenKeyExA( hkServiceProvider
, atKey
, 0, KEY_READ
,
782 &hkServiceProviderAt
) != ERROR_SUCCESS
)
784 TRACE(": No Address Types registry data sub key/members\n" );
788 /* Traverse all the address type we have available */
790 RegEnumKeyExA( hkServiceProviderAt
, dwAtIndex
, atSubKey
, &sizeOfSubKeyName
,
791 NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
792 ++dwAtIndex
, sizeOfSubKeyName
=50 )
794 TRACE( "Found Address Type GUID %s\n", atSubKey
);
796 /* FIXME: Check return types to ensure we're interpreting data right */
797 MultiByteToWideChar( CP_ACP
, 0, atSubKey
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
798 CLSIDFromString( buff
, &serviceProviderGUID
);
799 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
801 /* The enumeration will return FALSE if we are not to continue */
802 if( !lpEnumAddressTypeCallback( &serviceProviderGUID
, lpContext
, 0 ) )
804 WARN("lpEnumCallback returning FALSE\n" );
805 break; /* FIXME: This most likely has to break from the procedure...*/
810 /* We only enumerate address types for 1 GUID. We've found it, so quit looking */
817 static HRESULT WINAPI
IDirectPlayLobby3Impl_EnumAddressTypes( IDirectPlayLobby3
*iface
,
818 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb
, REFGUID sp
, void *context
, DWORD flags
)
821 return DPERR_OUTOFMEMORY
;
824 /********************************************************************
826 * Enumerates what applications are registered with DirectPlay by
827 * invoking the callback function with lpContext.
830 static HRESULT WINAPI
IDirectPlayLobby3Impl_EnumLocalApplications( IDirectPlayLobby3
*iface
,
831 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback
, void *lpContext
, DWORD dwFlags
)
833 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
835 FIXME("(%p)->(%p,%p,0x%08x):stub\n", This
, lpEnumLocalAppCallback
, lpContext
, dwFlags
);
837 return DPERR_OUTOFMEMORY
;
840 static HRESULT WINAPI
IDirectPlayLobbyAImpl_EnumLocalApplications( IDirectPlayLobbyA
*iface
,
841 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
843 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
844 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3A_iface
, enumlocalappcb
,
848 static HRESULT WINAPI
IDirectPlayLobbyImpl_EnumLocalApplications( IDirectPlayLobby
*iface
,
849 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
851 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
852 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3_iface
, enumlocalappcb
,
856 static HRESULT WINAPI
IDirectPlayLobby2AImpl_EnumLocalApplications( IDirectPlayLobby2A
*iface
,
857 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
859 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
860 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3A_iface
, enumlocalappcb
,
864 static HRESULT WINAPI
IDirectPlayLobby2Impl_EnumLocalApplications( IDirectPlayLobby2
*iface
,
865 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb
, void *context
, DWORD flags
)
867 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
868 return IDirectPlayLobby_EnumLocalApplications( &This
->IDirectPlayLobby3_iface
, enumlocalappcb
,
872 static HRESULT WINAPI
IDirectPlayLobby3AImpl_EnumLocalApplications( IDirectPlayLobby3A
*iface
,
873 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback
, void *lpContext
, DWORD dwFlags
)
875 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
878 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Applications";
879 LPCSTR guidDataSubKey
= "Guid";
880 DWORD dwIndex
, sizeOfSubKeyName
=50;
884 TRACE("(%p)->(%p,%p,0x%08x)\n", This
, lpEnumLocalAppCallback
, lpContext
, dwFlags
);
888 return DPERR_INVALIDPARAMS
;
891 if( !lpEnumLocalAppCallback
)
893 return DPERR_INVALIDPARAMS
;
896 /* Need to loop over the service providers in the registry */
897 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
898 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
900 /* Hmmm. Does this mean that there are no service providers? */
901 ERR(": no service providers?\n");
905 /* Traverse all registered applications */
907 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
, NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
908 ++dwIndex
, sizeOfSubKeyName
=50 )
911 HKEY hkServiceProvider
;
912 GUID serviceProviderGUID
;
913 DWORD returnTypeGUID
, sizeOfReturnBuffer
= 50;
914 char returnBuffer
[51];
916 DPLAPPINFO dplAppInfo
;
918 TRACE(" this time through: %s\n", subKeyName
);
920 /* Get a handle for this particular service provider */
921 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
922 &hkServiceProvider
) != ERROR_SUCCESS
)
924 ERR(": what the heck is going on?\n" );
928 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
929 NULL
, &returnTypeGUID
, (LPBYTE
)returnBuffer
,
930 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
932 ERR(": missing GUID registry data members\n" );
936 /* FIXME: Check return types to ensure we're interpreting data right */
937 MultiByteToWideChar( CP_ACP
, 0, returnBuffer
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
938 CLSIDFromString( buff
, &serviceProviderGUID
);
939 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
941 dplAppInfo
.dwSize
= sizeof( dplAppInfo
);
942 dplAppInfo
.guidApplication
= serviceProviderGUID
;
943 dplAppInfo
.u
.lpszAppNameA
= subKeyName
;
945 EnterCriticalSection( &This
->lock
);
947 memcpy( &This
->cbkeyhack
, &hkServiceProvider
, sizeof( hkServiceProvider
) );
949 if( !lpEnumLocalAppCallback( &dplAppInfo
, lpContext
, dwFlags
) )
951 LeaveCriticalSection( &This
->lock
);
955 LeaveCriticalSection( &This
->lock
);
961 /********************************************************************
963 * Retrieves the DPLCONNECTION structure that contains all the information
964 * needed to start and connect an application. This was generated using
965 * either the RunApplication or SetConnectionSettings methods.
967 * NOTES: If lpData is NULL then just return lpdwDataSize. This allows
968 * the data structure to be allocated by our caller which can then
969 * call this procedure/method again with a valid data pointer.
971 static HRESULT WINAPI
IDirectPlayLobbyAImpl_GetConnectionSettings( IDirectPlayLobbyA
*iface
,
972 DWORD appid
, void *data
, DWORD
*size
)
974 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
975 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, appid
, data
,
979 static HRESULT WINAPI
IDirectPlayLobbyImpl_GetConnectionSettings( IDirectPlayLobby
*iface
,
980 DWORD appid
, void *data
, DWORD
*size
)
982 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
983 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3_iface
, appid
, data
,
987 static HRESULT WINAPI
IDirectPlayLobby2AImpl_GetConnectionSettings( IDirectPlayLobby2A
*iface
,
988 DWORD appid
, void *data
, DWORD
*size
)
990 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
991 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, appid
, data
,
995 static HRESULT WINAPI
IDirectPlayLobby2Impl_GetConnectionSettings( IDirectPlayLobby2
*iface
,
996 DWORD appid
, void *data
, DWORD
*size
)
998 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
999 return IDirectPlayLobby_GetConnectionSettings( &This
->IDirectPlayLobby3_iface
, appid
, data
,
1003 static HRESULT WINAPI
IDirectPlayLobby3AImpl_GetConnectionSettings( IDirectPlayLobby3A
*iface
,
1004 DWORD dwAppID
, void *lpData
, DWORD
*lpdwDataSize
)
1006 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1009 TRACE("(%p)->(0x%08x,%p,%p)\n", This
, dwAppID
, lpData
, lpdwDataSize
);
1011 EnterCriticalSection( &This
->lock
);
1013 hr
= DPLAYX_GetConnectionSettingsA( dwAppID
,
1018 LeaveCriticalSection( &This
->lock
);
1023 static HRESULT WINAPI
IDirectPlayLobby3Impl_GetConnectionSettings( IDirectPlayLobby3
*iface
,
1024 DWORD dwAppID
, void *lpData
, DWORD
*lpdwDataSize
)
1026 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1029 TRACE("(%p)->(0x%08x,%p,%p)\n", This
, dwAppID
, lpData
, lpdwDataSize
);
1031 EnterCriticalSection( &This
->lock
);
1033 hr
= DPLAYX_GetConnectionSettingsW( dwAppID
,
1038 LeaveCriticalSection( &This
->lock
);
1043 /********************************************************************
1045 * Retrieves the message sent between a lobby client and a DirectPlay
1046 * application. All messages are queued until received.
1049 static HRESULT WINAPI
IDirectPlayLobbyAImpl_ReceiveLobbyMessage( IDirectPlayLobbyA
*iface
,
1050 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1052 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1053 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1054 msgflags
, data
, size
);
1057 static HRESULT WINAPI
IDirectPlayLobbyImpl_ReceiveLobbyMessage( IDirectPlayLobby
*iface
,
1058 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1060 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1061 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1062 msgflags
, data
, size
);
1065 static HRESULT WINAPI
IDirectPlayLobby2AImpl_ReceiveLobbyMessage( IDirectPlayLobby2A
*iface
,
1066 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1068 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1069 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1070 msgflags
, data
, size
);
1073 static HRESULT WINAPI
IDirectPlayLobby2Impl_ReceiveLobbyMessage( IDirectPlayLobby2
*iface
,
1074 DWORD flags
, DWORD appid
, DWORD
*msgflags
, void *data
, DWORD
*size
)
1076 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1077 return IDirectPlayLobby_ReceiveLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1078 msgflags
, data
, size
);
1081 static HRESULT WINAPI
IDirectPlayLobby3AImpl_ReceiveLobbyMessage( IDirectPlayLobby3A
*iface
,
1082 DWORD dwFlags
, DWORD dwAppID
, DWORD
*lpdwMessageFlags
, void *lpData
,
1083 DWORD
*lpdwDataSize
)
1085 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1086 FIXME(":stub %p %08x %08x %p %p %p\n", This
, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
1088 return DPERR_OUTOFMEMORY
;
1091 static HRESULT WINAPI
IDirectPlayLobby3Impl_ReceiveLobbyMessage( IDirectPlayLobby3
*iface
,
1092 DWORD dwFlags
, DWORD dwAppID
, DWORD
*lpdwMessageFlags
, void *lpData
,
1093 DWORD
*lpdwDataSize
)
1095 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1096 FIXME(":stub %p %08x %08x %p %p %p\n", This
, dwFlags
, dwAppID
, lpdwMessageFlags
, lpData
,
1098 return DPERR_OUTOFMEMORY
;
1101 typedef struct tagRunApplicationEnumStruct
1103 IDirectPlayLobbyImpl
*This
;
1108 LPSTR lpszCommandLine
;
1109 LPSTR lpszCurrentDirectory
;
1110 } RunApplicationEnumStruct
, *lpRunApplicationEnumStruct
;
1112 /* To be called by RunApplication to find how to invoke the function */
1113 static BOOL CALLBACK RunApplicationA_EnumLocalApplications
1114 ( LPCDPLAPPINFO lpAppInfo
,
1118 lpRunApplicationEnumStruct lpData
= (lpRunApplicationEnumStruct
)lpContext
;
1120 if( IsEqualGUID( &lpAppInfo
->guidApplication
, &lpData
->appGUID
) )
1122 char returnBuffer
[200];
1123 DWORD returnType
, sizeOfReturnBuffer
;
1124 LPCSTR clSubKey
= "CommandLine";
1125 LPCSTR cdSubKey
= "CurrentDirectory";
1126 LPCSTR fileSubKey
= "File";
1127 LPCSTR pathSubKey
= "Path";
1129 /* FIXME: Lazy man hack - dplay struct has the present reg key saved */
1131 sizeOfReturnBuffer
= 200;
1133 /* Get all the appropriate data from the registry */
1134 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, clSubKey
,
1135 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1136 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1138 ERR( ": missing CommandLine registry data member\n" );
1142 if ((lpData
->lpszCommandLine
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1143 strcpy( lpData
->lpszCommandLine
, returnBuffer
);
1146 sizeOfReturnBuffer
= 200;
1148 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, cdSubKey
,
1149 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1150 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1152 ERR( ": missing CurrentDirectory registry data member\n" );
1156 if ((lpData
->lpszCurrentDirectory
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1157 strcpy( lpData
->lpszCurrentDirectory
, returnBuffer
);
1160 sizeOfReturnBuffer
= 200;
1162 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, fileSubKey
,
1163 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1164 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1166 ERR( ": missing File registry data member\n" );
1170 if ((lpData
->lpszFileName
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1171 strcpy( lpData
->lpszFileName
, returnBuffer
);
1174 sizeOfReturnBuffer
= 200;
1176 if( RegQueryValueExA( lpData
->This
->cbkeyhack
, pathSubKey
,
1177 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
1178 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
1180 ERR( ": missing Path registry data member\n" );
1184 if ((lpData
->lpszPath
= HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer
)+1 )))
1185 strcpy( lpData
->lpszPath
, returnBuffer
);
1188 return FALSE
; /* No need to keep going as we found what we wanted */
1191 return TRUE
; /* Keep enumerating, haven't found the application yet */
1194 static BOOL
DPL_CreateAndSetLobbyHandles( DWORD dwDestProcessId
, HANDLE hDestProcess
,
1195 LPHANDLE lphStart
, LPHANDLE lphDeath
,
1198 /* These are the handles for the created process */
1199 HANDLE hAppStart
= 0, hAppDeath
= 0, hAppRead
= 0;
1200 SECURITY_ATTRIBUTES s_attrib
;
1202 s_attrib
.nLength
= sizeof( s_attrib
);
1203 s_attrib
.lpSecurityDescriptor
= NULL
;
1204 s_attrib
.bInheritHandle
= TRUE
;
1206 *lphStart
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1207 *lphDeath
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1208 *lphRead
= CreateEventW( &s_attrib
, TRUE
, FALSE
, NULL
);
1210 if( ( !DuplicateHandle( GetCurrentProcess(), *lphStart
,
1211 hDestProcess
, &hAppStart
,
1212 0, FALSE
, DUPLICATE_SAME_ACCESS
) ) ||
1213 ( !DuplicateHandle( GetCurrentProcess(), *lphDeath
,
1214 hDestProcess
, &hAppDeath
,
1215 0, FALSE
, DUPLICATE_SAME_ACCESS
) ) ||
1216 ( !DuplicateHandle( GetCurrentProcess(), *lphRead
,
1217 hDestProcess
, &hAppRead
,
1218 0, FALSE
, DUPLICATE_SAME_ACCESS
) )
1221 if (*lphStart
) { CloseHandle(*lphStart
); *lphStart
= 0; }
1222 if (*lphDeath
) { CloseHandle(*lphDeath
); *lphDeath
= 0; }
1223 if (*lphRead
) { CloseHandle(*lphRead
); *lphRead
= 0; }
1224 /* FIXME: Handle leak... */
1225 ERR( "Unable to dup handles\n" );
1229 if( !DPLAYX_SetLobbyHandles( dwDestProcessId
,
1230 hAppStart
, hAppDeath
, hAppRead
) )
1232 /* FIXME: Handle leak... */
1240 /********************************************************************
1242 * Starts an application and passes to it all the information to
1243 * connect to a session.
1246 static HRESULT WINAPI
IDirectPlayLobbyAImpl_RunApplication( IDirectPlayLobbyA
*iface
, DWORD flags
,
1247 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1249 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1250 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, conn
,
1254 static HRESULT WINAPI
IDirectPlayLobbyImpl_RunApplication( IDirectPlayLobby
*iface
, DWORD flags
,
1255 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1257 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1258 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3_iface
, flags
, appid
, conn
,
1262 static HRESULT WINAPI
IDirectPlayLobby2AImpl_RunApplication( IDirectPlayLobby2A
*iface
, DWORD flags
,
1263 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1265 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1266 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, conn
,
1270 static HRESULT WINAPI
IDirectPlayLobby2Impl_RunApplication( IDirectPlayLobby2
*iface
, DWORD flags
,
1271 DWORD
*appid
, DPLCONNECTION
*conn
, HANDLE event
)
1273 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1274 return IDirectPlayLobby_RunApplication( &This
->IDirectPlayLobby3_iface
, flags
, appid
, conn
,
1278 static HRESULT WINAPI
IDirectPlayLobby3AImpl_RunApplication( IDirectPlayLobby3A
*iface
,
1279 DWORD dwFlags
, DWORD
*lpdwAppID
, DPLCONNECTION
*lpConn
, HANDLE hReceiveEvent
)
1281 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1283 RunApplicationEnumStruct enumData
;
1285 STARTUPINFOA startupInfo
;
1286 PROCESS_INFORMATION newProcessInfo
;
1288 DWORD dwSuspendCount
;
1289 HANDLE hStart
, hDeath
, hSettingRead
;
1291 TRACE( "(%p)->(0x%08x,%p,%p,%p)\n",
1292 This
, dwFlags
, lpdwAppID
, lpConn
, hReceiveEvent
);
1296 return DPERR_INVALIDPARAMS
;
1299 if( DPLAYX_AnyLobbiesWaitingForConnSettings() )
1301 FIXME( "Waiting lobby not being handled correctly\n" );
1304 EnterCriticalSection( &This
->lock
);
1306 ZeroMemory( &enumData
, sizeof( enumData
) );
1307 enumData
.This
= This
;
1308 enumData
.appGUID
= lpConn
->lpSessionDesc
->guidApplication
;
1310 /* Our callback function will fill up the enumData structure with all the information
1311 required to start a new process */
1312 IDirectPlayLobby_EnumLocalApplications( iface
, RunApplicationA_EnumLocalApplications
,
1315 /* First the application name */
1316 strcpy( temp
, enumData
.lpszPath
);
1317 strcat( temp
, "\\" );
1318 strcat( temp
, enumData
.lpszFileName
);
1319 HeapFree( GetProcessHeap(), 0, enumData
.lpszPath
);
1320 HeapFree( GetProcessHeap(), 0, enumData
.lpszFileName
);
1321 if ((appName
= HeapAlloc( GetProcessHeap(), 0, strlen(temp
)+1 ))) strcpy( appName
, temp
);
1323 /* Now the command line */
1324 strcat( temp
, " " );
1325 strcat( temp
, enumData
.lpszCommandLine
);
1326 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1327 if ((enumData
.lpszCommandLine
= HeapAlloc( GetProcessHeap(), 0, strlen(temp
)+1 )))
1328 strcpy( enumData
.lpszCommandLine
, temp
);
1330 ZeroMemory( &startupInfo
, sizeof( startupInfo
) );
1331 startupInfo
.cb
= sizeof( startupInfo
);
1332 /* FIXME: Should any fields be filled in? */
1334 ZeroMemory( &newProcessInfo
, sizeof( newProcessInfo
) );
1336 if( !CreateProcessA( appName
,
1337 enumData
.lpszCommandLine
,
1341 CREATE_DEFAULT_ERROR_MODE
| CREATE_NEW_CONSOLE
| CREATE_SUSPENDED
, /* Creation Flags */
1343 enumData
.lpszCurrentDirectory
,
1349 ERR( "Failed to create process for app %s\n", appName
);
1351 HeapFree( GetProcessHeap(), 0, appName
);
1352 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1353 HeapFree( GetProcessHeap(), 0, enumData
.lpszCurrentDirectory
);
1355 LeaveCriticalSection( &This
->lock
);
1356 return DPERR_CANTCREATEPROCESS
;
1359 HeapFree( GetProcessHeap(), 0, appName
);
1360 HeapFree( GetProcessHeap(), 0, enumData
.lpszCommandLine
);
1361 HeapFree( GetProcessHeap(), 0, enumData
.lpszCurrentDirectory
);
1363 /* Reserve this global application id! */
1364 if( !DPLAYX_CreateLobbyApplication( newProcessInfo
.dwProcessId
) )
1366 ERR( "Unable to create global application data for 0x%08x\n",
1367 newProcessInfo
.dwProcessId
);
1370 hr
= IDirectPlayLobby_SetConnectionSettings( iface
, 0, newProcessInfo
.dwProcessId
, lpConn
);
1374 ERR( "SetConnectionSettings failure %s\n", DPLAYX_HresultToString( hr
) );
1375 LeaveCriticalSection( &This
->lock
);
1379 /* Setup the handles for application notification */
1380 DPL_CreateAndSetLobbyHandles( newProcessInfo
.dwProcessId
,
1381 newProcessInfo
.hProcess
,
1382 &hStart
, &hDeath
, &hSettingRead
);
1384 /* Setup the message thread ID */
1385 This
->msgtid
= CreateLobbyMessageReceptionThread( hReceiveEvent
, hStart
, hDeath
, hSettingRead
);
1387 DPLAYX_SetLobbyMsgThreadId( newProcessInfo
.dwProcessId
, This
->msgtid
);
1389 LeaveCriticalSection( &This
->lock
);
1391 /* Everything seems to have been set correctly, update the dwAppID */
1392 *lpdwAppID
= newProcessInfo
.dwProcessId
;
1394 /* Unsuspend the process - should return the prev suspension count */
1395 if( ( dwSuspendCount
= ResumeThread( newProcessInfo
.hThread
) ) != 1 )
1397 ERR( "ResumeThread failed with 0x%08x\n", dwSuspendCount
);
1403 static HRESULT WINAPI
IDirectPlayLobby3Impl_RunApplication( IDirectPlayLobby3
*iface
, DWORD dwFlags
,
1404 DWORD
*lpdwAppID
, DPLCONNECTION
*lpConn
, HANDLE hReceiveEvent
)
1406 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1407 FIXME( "(%p)->(0x%08x,%p,%p,%p):stub\n", This
, dwFlags
, lpdwAppID
, lpConn
, hReceiveEvent
);
1408 return DPERR_OUTOFMEMORY
;
1411 /********************************************************************
1413 * Sends a message between the application and the lobby client.
1414 * All messages are queued until received.
1417 static HRESULT WINAPI
IDirectPlayLobbyAImpl_SendLobbyMessage( IDirectPlayLobbyA
*iface
, DWORD flags
,
1418 DWORD appid
, void *data
, DWORD size
)
1420 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1421 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, data
,
1425 static HRESULT WINAPI
IDirectPlayLobbyImpl_SendLobbyMessage( IDirectPlayLobby
*iface
, DWORD flags
,
1426 DWORD appid
, void *data
, DWORD size
)
1428 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1429 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
, data
,
1433 static HRESULT WINAPI
IDirectPlayLobby2AImpl_SendLobbyMessage( IDirectPlayLobby2A
*iface
,
1434 DWORD flags
, DWORD appid
, void *data
, DWORD size
)
1436 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1437 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3A_iface
, flags
, appid
, data
,
1441 static HRESULT WINAPI
IDirectPlayLobby2Impl_SendLobbyMessage( IDirectPlayLobby2
*iface
, DWORD flags
,
1442 DWORD appid
, void *data
, DWORD size
)
1444 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1445 return IDirectPlayLobby_SendLobbyMessage( &This
->IDirectPlayLobby3_iface
, flags
, appid
, data
,
1449 static HRESULT WINAPI
IDirectPlayLobby3AImpl_SendLobbyMessage( IDirectPlayLobby3A
*iface
,
1450 DWORD flags
, DWORD appid
, void *data
, DWORD size
)
1453 return DPERR_OUTOFMEMORY
;
1456 static HRESULT WINAPI
IDirectPlayLobby3Impl_SendLobbyMessage( IDirectPlayLobby3
*iface
,
1457 DWORD flags
, DWORD appid
, void *data
, DWORD size
)
1460 return DPERR_OUTOFMEMORY
;
1463 /********************************************************************
1465 * Modifies the DPLCONNECTION structure to contain all information
1466 * needed to start and connect an application.
1469 static HRESULT WINAPI
IDirectPlayLobby3Impl_SetConnectionSettings( IDirectPlayLobby3
*iface
,
1470 DWORD dwFlags
, DWORD dwAppID
, DPLCONNECTION
*lpConn
)
1472 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1475 TRACE("(%p)->(0x%08x,0x%08x,%p)\n", This
, dwFlags
, dwAppID
, lpConn
);
1477 EnterCriticalSection( &This
->lock
);
1479 hr
= DPLAYX_SetConnectionSettingsW( dwFlags
, dwAppID
, lpConn
);
1481 /* FIXME: Don't think that this is supposed to fail, but the documentation
1482 is somewhat sketchy. I'll try creating a lobby application
1484 if( hr
== DPERR_NOTLOBBIED
)
1486 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1489 dwAppID
= GetCurrentProcessId();
1491 DPLAYX_CreateLobbyApplication( dwAppID
);
1492 hr
= DPLAYX_SetConnectionSettingsW( dwFlags
, dwAppID
, lpConn
);
1495 LeaveCriticalSection( &This
->lock
);
1500 static HRESULT WINAPI
IDirectPlayLobbyAImpl_SetConnectionSettings( IDirectPlayLobbyA
*iface
,
1501 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1503 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1504 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, flags
,
1508 static HRESULT WINAPI
IDirectPlayLobbyImpl_SetConnectionSettings( IDirectPlayLobby
*iface
,
1509 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1511 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1512 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3_iface
, flags
,
1516 static HRESULT WINAPI
IDirectPlayLobby2AImpl_SetConnectionSettings( IDirectPlayLobby2A
*iface
,
1517 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1519 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1520 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3A_iface
, flags
,
1524 static HRESULT WINAPI
IDirectPlayLobby2Impl_SetConnectionSettings( IDirectPlayLobby2
*iface
,
1525 DWORD flags
, DWORD appid
, DPLCONNECTION
*conn
)
1527 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1528 return IDirectPlayLobby_SetConnectionSettings( &This
->IDirectPlayLobby3_iface
, flags
,
1532 static HRESULT WINAPI
IDirectPlayLobby3AImpl_SetConnectionSettings( IDirectPlayLobby3A
*iface
,
1533 DWORD dwFlags
, DWORD dwAppID
, DPLCONNECTION
*lpConn
)
1535 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1538 TRACE("(%p)->(0x%08x,0x%08x,%p)\n", This
, dwFlags
, dwAppID
, lpConn
);
1540 EnterCriticalSection( &This
->lock
);
1542 hr
= DPLAYX_SetConnectionSettingsA( dwFlags
, dwAppID
, lpConn
);
1544 /* FIXME: Don't think that this is supposed to fail, but the documentation
1545 is somewhat sketchy. I'll try creating a lobby application
1547 if( hr
== DPERR_NOTLOBBIED
)
1549 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1550 dwAppID
= GetCurrentProcessId();
1551 DPLAYX_CreateLobbyApplication( dwAppID
);
1552 hr
= DPLAYX_SetConnectionSettingsA( dwFlags
, dwAppID
, lpConn
);
1555 LeaveCriticalSection( &This
->lock
);
1560 /********************************************************************
1562 * Registers an event that will be set when a lobby message is received.
1565 static HRESULT WINAPI
IDirectPlayLobbyAImpl_SetLobbyMessageEvent( IDirectPlayLobbyA
*iface
,
1566 DWORD flags
, DWORD appid
, HANDLE event
)
1568 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobbyA( iface
);
1569 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1573 static HRESULT WINAPI
IDirectPlayLobbyImpl_SetLobbyMessageEvent( IDirectPlayLobby
*iface
,
1574 DWORD flags
, DWORD appid
, HANDLE event
)
1576 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby( iface
);
1577 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1581 static HRESULT WINAPI
IDirectPlayLobby2AImpl_SetLobbyMessageEvent( IDirectPlayLobby2A
*iface
,
1582 DWORD flags
, DWORD appid
, HANDLE event
)
1584 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1585 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3A_iface
, flags
, appid
,
1589 static HRESULT WINAPI
IDirectPlayLobby2Impl_SetLobbyMessageEvent( IDirectPlayLobby2
*iface
,
1590 DWORD flags
, DWORD appid
, HANDLE event
)
1592 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1593 return IDirectPlayLobby_SetLobbyMessageEvent( &This
->IDirectPlayLobby3_iface
, flags
, appid
,
1597 static HRESULT WINAPI
IDirectPlayLobby3AImpl_SetLobbyMessageEvent( IDirectPlayLobby3A
*iface
,
1598 DWORD flags
, DWORD appid
, HANDLE event
)
1601 return DPERR_OUTOFMEMORY
;
1604 static HRESULT WINAPI
IDirectPlayLobby3Impl_SetLobbyMessageEvent( IDirectPlayLobby3
*iface
,
1605 DWORD flags
, DWORD appid
, HANDLE event
)
1608 return DPERR_OUTOFMEMORY
;
1613 static HRESULT WINAPI
IDirectPlayLobby2AImpl_CreateCompoundAddress( IDirectPlayLobby2A
*iface
,
1614 const DPCOMPOUNDADDRESSELEMENT
*elements
, DWORD count
, void *address
, DWORD
*size
)
1616 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2A( iface
);
1617 return IDirectPlayLobby_CreateCompoundAddress( &This
->IDirectPlayLobby3A_iface
, elements
,
1618 count
, address
, size
);
1621 static HRESULT WINAPI
IDirectPlayLobby2Impl_CreateCompoundAddress( IDirectPlayLobby2
*iface
,
1622 const DPCOMPOUNDADDRESSELEMENT
*elements
, DWORD count
, void *address
, DWORD
*size
)
1624 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby2( iface
);
1625 return IDirectPlayLobby_CreateCompoundAddress( &This
->IDirectPlayLobby3_iface
, elements
,
1626 count
, address
, size
);
1629 static HRESULT WINAPI
IDirectPlayLobby3Impl_CreateCompoundAddress( IDirectPlayLobby3
*iface
,
1630 const DPCOMPOUNDADDRESSELEMENT
*lpElements
, DWORD dwElementCount
, void *lpAddress
,
1631 DWORD
*lpdwAddressSize
)
1633 return DPL_CreateCompoundAddress( lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
, FALSE
);
1636 static HRESULT WINAPI
IDirectPlayLobby3AImpl_CreateCompoundAddress( IDirectPlayLobby3A
*iface
,
1637 const DPCOMPOUNDADDRESSELEMENT
*lpElements
, DWORD dwElementCount
, void *lpAddress
,
1638 DWORD
*lpdwAddressSize
)
1640 return DPL_CreateCompoundAddress( lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
, TRUE
);
1643 HRESULT DPL_CreateCompoundAddress
1644 ( LPCDPCOMPOUNDADDRESSELEMENT lpElements
,
1645 DWORD dwElementCount
,
1647 LPDWORD lpdwAddressSize
,
1648 BOOL bAnsiInterface
)
1650 DWORD dwSizeRequired
= 0;
1652 LPCDPCOMPOUNDADDRESSELEMENT lpOrigElements
= lpElements
;
1654 TRACE("(%p,0x%08x,%p,%p)\n", lpElements
, dwElementCount
, lpAddress
, lpdwAddressSize
);
1656 /* Parameter check */
1657 if( ( lpElements
== NULL
) ||
1658 ( dwElementCount
== 0 ) /* FIXME: Not sure if this is a failure case */
1661 return DPERR_INVALIDPARAMS
;
1664 /* Add the total size chunk */
1665 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( DWORD
);
1667 /* Calculate the size of the buffer required */
1668 for ( dwElements
= dwElementCount
; dwElements
> 0; --dwElements
, ++lpElements
)
1670 if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ServiceProvider
) ) ||
1671 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_LobbyProvider
) )
1674 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( GUID
);
1676 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Phone
) ) ||
1677 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Modem
) ) ||
1678 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INet
) )
1681 if( !bAnsiInterface
)
1683 ERR( "Ansi GUIDs used for unicode interface\n" );
1684 return DPERR_INVALIDFLAGS
;
1687 dwSizeRequired
+= sizeof( DPADDRESS
) + lpElements
->dwDataSize
;
1689 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_PhoneW
) ) ||
1690 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ModemW
) ) ||
1691 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetW
) )
1694 if( bAnsiInterface
)
1696 ERR( "Unicode GUIDs used for ansi interface\n" );
1697 return DPERR_INVALIDFLAGS
;
1700 FIXME( "Right size for unicode interface?\n" );
1701 dwSizeRequired
+= sizeof( DPADDRESS
) + lpElements
->dwDataSize
* sizeof( WCHAR
);
1703 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetPort
) )
1705 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( WORD
);
1707 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ComPort
) )
1709 FIXME( "Right size for unicode interface?\n" );
1710 dwSizeRequired
+= sizeof( DPADDRESS
) + sizeof( DPCOMPORTADDRESS
); /* FIXME: Right size? */
1714 ERR( "Unknown GUID %s\n", debugstr_guid(&lpElements
->guidDataType
) );
1715 return DPERR_INVALIDFLAGS
;
1719 /* The user wants to know how big a buffer to allocate for us */
1720 if( ( lpAddress
== NULL
) ||
1721 ( *lpdwAddressSize
< dwSizeRequired
)
1724 *lpdwAddressSize
= dwSizeRequired
;
1725 return DPERR_BUFFERTOOSMALL
;
1728 /* Add the total size chunk */
1730 LPDPADDRESS lpdpAddress
= lpAddress
;
1732 lpdpAddress
->guidDataType
= DPAID_TotalSize
;
1733 lpdpAddress
->dwDataSize
= sizeof( DWORD
);
1734 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1736 *(LPDWORD
)lpAddress
= dwSizeRequired
;
1737 lpAddress
= (char *) lpAddress
+ sizeof( DWORD
);
1740 /* Calculate the size of the buffer required */
1741 for( dwElements
= dwElementCount
, lpElements
= lpOrigElements
;
1743 --dwElements
, ++lpElements
)
1745 if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ServiceProvider
) ) ||
1746 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_LobbyProvider
) )
1749 LPDPADDRESS lpdpAddress
= lpAddress
;
1751 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1752 lpdpAddress
->dwDataSize
= sizeof( GUID
);
1753 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1755 CopyMemory( lpAddress
, lpElements
->lpData
, sizeof( GUID
) );
1756 lpAddress
= (char *) lpAddress
+ sizeof( GUID
);
1758 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Phone
) ) ||
1759 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_Modem
) ) ||
1760 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INet
) )
1763 LPDPADDRESS lpdpAddress
= lpAddress
;
1765 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1766 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1767 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1769 lstrcpynA( lpAddress
, lpElements
->lpData
, lpElements
->dwDataSize
);
1770 lpAddress
= (char *) lpAddress
+ lpElements
->dwDataSize
;
1772 else if ( ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_PhoneW
) ) ||
1773 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ModemW
) ) ||
1774 ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetW
) )
1777 LPDPADDRESS lpdpAddress
= lpAddress
;
1779 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1780 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1781 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1783 lstrcpynW( lpAddress
, lpElements
->lpData
, lpElements
->dwDataSize
);
1784 lpAddress
= (char *) lpAddress
+ lpElements
->dwDataSize
* sizeof( WCHAR
);
1786 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_INetPort
) )
1788 LPDPADDRESS lpdpAddress
= lpAddress
;
1790 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1791 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1792 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1794 *((LPWORD
)lpAddress
) = *((LPWORD
)lpElements
->lpData
);
1795 lpAddress
= (char *) lpAddress
+ sizeof( WORD
);
1797 else if ( IsEqualGUID( &lpElements
->guidDataType
, &DPAID_ComPort
) )
1799 LPDPADDRESS lpdpAddress
= lpAddress
;
1801 lpdpAddress
->guidDataType
= lpElements
->guidDataType
;
1802 lpdpAddress
->dwDataSize
= lpElements
->dwDataSize
;
1803 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1805 CopyMemory( lpAddress
, lpElements
->lpData
, sizeof( DPADDRESS
) );
1806 lpAddress
= (char *) lpAddress
+ sizeof( DPADDRESS
);
1815 static HRESULT WINAPI
IDirectPlayLobby3Impl_ConnectEx( IDirectPlayLobby3
*iface
, DWORD dwFlags
,
1816 REFIID riid
, LPVOID
* lplpDP
, IUnknown
* pUnk
)
1818 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3( iface
);
1819 return DPL_ConnectEx( This
, dwFlags
, riid
, lplpDP
, pUnk
);
1822 static HRESULT WINAPI
IDirectPlayLobby3AImpl_ConnectEx( IDirectPlayLobby3A
*iface
, DWORD dwFlags
,
1823 REFIID riid
, void **lplpDP
, IUnknown
*pUnk
)
1825 IDirectPlayLobbyImpl
*This
= impl_from_IDirectPlayLobby3A( iface
);
1826 return DPL_ConnectEx( This
, dwFlags
, riid
, lplpDP
, pUnk
);
1829 static HRESULT WINAPI
IDirectPlayLobby3Impl_RegisterApplication( IDirectPlayLobby3
*iface
,
1830 DWORD flags
, DPAPPLICATIONDESC
*appdesc
)
1836 static HRESULT WINAPI
IDirectPlayLobby3AImpl_RegisterApplication( IDirectPlayLobby3A
*iface
,
1837 DWORD flags
, DPAPPLICATIONDESC
*appdesc
)
1843 static HRESULT WINAPI
IDirectPlayLobby3Impl_UnregisterApplication( IDirectPlayLobby3
*iface
,
1844 DWORD flags
, REFGUID appdesc
)
1850 static HRESULT WINAPI
IDirectPlayLobby3AImpl_UnregisterApplication( IDirectPlayLobby3A
*iface
,
1851 DWORD flags
, REFGUID appdesc
)
1857 static HRESULT WINAPI
IDirectPlayLobby3Impl_WaitForConnectionSettings( IDirectPlayLobby3
*iface
,
1861 BOOL bStartWait
= !(dwFlags
& DPLWAIT_CANCEL
);
1863 TRACE( "(%p)->(0x%08x)\n", iface
, dwFlags
);
1865 if( DPLAYX_WaitForConnectionSettings( bStartWait
) )
1867 /* FIXME: What is the correct error return code? */
1868 hr
= DPERR_NOTLOBBIED
;
1874 static HRESULT WINAPI
IDirectPlayLobby3AImpl_WaitForConnectionSettings( IDirectPlayLobby3A
*iface
,
1878 BOOL bStartWait
= !(dwFlags
& DPLWAIT_CANCEL
);
1880 TRACE( "(%p)->(0x%08x)\n", iface
, dwFlags
);
1882 if( DPLAYX_WaitForConnectionSettings( bStartWait
) )
1884 /* FIXME: What is the correct error return code? */
1885 hr
= DPERR_NOTLOBBIED
;
1891 static const IDirectPlayLobbyVtbl dplA_vt
=
1893 IDirectPlayLobbyAImpl_QueryInterface
,
1894 IDirectPlayLobbyAImpl_AddRef
,
1895 IDirectPlayLobbyAImpl_Release
,
1896 IDirectPlayLobbyAImpl_Connect
,
1897 IDirectPlayLobbyAImpl_CreateAddress
,
1898 IDirectPlayLobbyAImpl_EnumAddress
,
1899 IDirectPlayLobbyAImpl_EnumAddressTypes
,
1900 IDirectPlayLobbyAImpl_EnumLocalApplications
,
1901 IDirectPlayLobbyAImpl_GetConnectionSettings
,
1902 IDirectPlayLobbyAImpl_ReceiveLobbyMessage
,
1903 IDirectPlayLobbyAImpl_RunApplication
,
1904 IDirectPlayLobbyAImpl_SendLobbyMessage
,
1905 IDirectPlayLobbyAImpl_SetConnectionSettings
,
1906 IDirectPlayLobbyAImpl_SetLobbyMessageEvent
1909 static const IDirectPlayLobbyVtbl dpl_vt
=
1911 IDirectPlayLobbyImpl_QueryInterface
,
1912 IDirectPlayLobbyImpl_AddRef
,
1913 IDirectPlayLobbyImpl_Release
,
1914 IDirectPlayLobbyImpl_Connect
,
1915 IDirectPlayLobbyImpl_CreateAddress
,
1916 IDirectPlayLobbyImpl_EnumAddress
,
1917 IDirectPlayLobbyImpl_EnumAddressTypes
,
1918 IDirectPlayLobbyImpl_EnumLocalApplications
,
1919 IDirectPlayLobbyImpl_GetConnectionSettings
,
1920 IDirectPlayLobbyImpl_ReceiveLobbyMessage
,
1921 IDirectPlayLobbyImpl_RunApplication
,
1922 IDirectPlayLobbyImpl_SendLobbyMessage
,
1923 IDirectPlayLobbyImpl_SetConnectionSettings
,
1924 IDirectPlayLobbyImpl_SetLobbyMessageEvent
1927 static const IDirectPlayLobby2Vtbl dpl2A_vt
=
1929 IDirectPlayLobby2AImpl_QueryInterface
,
1930 IDirectPlayLobby2AImpl_AddRef
,
1931 IDirectPlayLobby2AImpl_Release
,
1932 IDirectPlayLobby2AImpl_Connect
,
1933 IDirectPlayLobby2AImpl_CreateAddress
,
1934 IDirectPlayLobby2AImpl_EnumAddress
,
1935 IDirectPlayLobby2AImpl_EnumAddressTypes
,
1936 IDirectPlayLobby2AImpl_EnumLocalApplications
,
1937 IDirectPlayLobby2AImpl_GetConnectionSettings
,
1938 IDirectPlayLobby2AImpl_ReceiveLobbyMessage
,
1939 IDirectPlayLobby2AImpl_RunApplication
,
1940 IDirectPlayLobby2AImpl_SendLobbyMessage
,
1941 IDirectPlayLobby2AImpl_SetConnectionSettings
,
1942 IDirectPlayLobby2AImpl_SetLobbyMessageEvent
,
1943 IDirectPlayLobby2AImpl_CreateCompoundAddress
1946 static const IDirectPlayLobby2Vtbl dpl2_vt
=
1948 IDirectPlayLobby2Impl_QueryInterface
,
1949 IDirectPlayLobby2Impl_AddRef
,
1950 IDirectPlayLobby2Impl_Release
,
1951 IDirectPlayLobby2Impl_Connect
,
1952 IDirectPlayLobby2Impl_CreateAddress
,
1953 IDirectPlayLobby2Impl_EnumAddress
,
1954 IDirectPlayLobby2Impl_EnumAddressTypes
,
1955 IDirectPlayLobby2Impl_EnumLocalApplications
,
1956 IDirectPlayLobby2Impl_GetConnectionSettings
,
1957 IDirectPlayLobby2Impl_ReceiveLobbyMessage
,
1958 IDirectPlayLobby2Impl_RunApplication
,
1959 IDirectPlayLobby2Impl_SendLobbyMessage
,
1960 IDirectPlayLobby2Impl_SetConnectionSettings
,
1961 IDirectPlayLobby2Impl_SetLobbyMessageEvent
,
1962 IDirectPlayLobby2Impl_CreateCompoundAddress
1965 static const IDirectPlayLobby3Vtbl dpl3A_vt
=
1967 IDirectPlayLobby3AImpl_QueryInterface
,
1968 IDirectPlayLobby3AImpl_AddRef
,
1969 IDirectPlayLobby3AImpl_Release
,
1970 IDirectPlayLobby3AImpl_Connect
,
1971 IDirectPlayLobby3AImpl_CreateAddress
,
1972 IDirectPlayLobby3AImpl_EnumAddress
,
1973 IDirectPlayLobby3AImpl_EnumAddressTypes
,
1974 IDirectPlayLobby3AImpl_EnumLocalApplications
,
1975 IDirectPlayLobby3AImpl_GetConnectionSettings
,
1976 IDirectPlayLobby3AImpl_ReceiveLobbyMessage
,
1977 IDirectPlayLobby3AImpl_RunApplication
,
1978 IDirectPlayLobby3AImpl_SendLobbyMessage
,
1979 IDirectPlayLobby3AImpl_SetConnectionSettings
,
1980 IDirectPlayLobby3AImpl_SetLobbyMessageEvent
,
1981 IDirectPlayLobby3AImpl_CreateCompoundAddress
,
1982 IDirectPlayLobby3AImpl_ConnectEx
,
1983 IDirectPlayLobby3AImpl_RegisterApplication
,
1984 IDirectPlayLobby3AImpl_UnregisterApplication
,
1985 IDirectPlayLobby3AImpl_WaitForConnectionSettings
1988 static const IDirectPlayLobby3Vtbl dpl3_vt
=
1990 IDirectPlayLobby3Impl_QueryInterface
,
1991 IDirectPlayLobby3Impl_AddRef
,
1992 IDirectPlayLobby3Impl_Release
,
1993 IDirectPlayLobby3Impl_Connect
,
1994 IDirectPlayLobby3Impl_CreateAddress
,
1995 IDirectPlayLobby3Impl_EnumAddress
,
1996 IDirectPlayLobby3Impl_EnumAddressTypes
,
1997 IDirectPlayLobby3Impl_EnumLocalApplications
,
1998 IDirectPlayLobby3Impl_GetConnectionSettings
,
1999 IDirectPlayLobby3Impl_ReceiveLobbyMessage
,
2000 IDirectPlayLobby3Impl_RunApplication
,
2001 IDirectPlayLobby3Impl_SendLobbyMessage
,
2002 IDirectPlayLobby3Impl_SetConnectionSettings
,
2003 IDirectPlayLobby3Impl_SetLobbyMessageEvent
,
2004 IDirectPlayLobby3Impl_CreateCompoundAddress
,
2005 IDirectPlayLobby3Impl_ConnectEx
,
2006 IDirectPlayLobby3Impl_RegisterApplication
,
2007 IDirectPlayLobby3Impl_UnregisterApplication
,
2008 IDirectPlayLobby3Impl_WaitForConnectionSettings
2011 HRESULT
dplobby_create( REFIID riid
, void **ppv
)
2013 IDirectPlayLobbyImpl
*obj
;
2016 TRACE( "(%s, %p)\n", debugstr_guid( riid
), ppv
);
2019 obj
= HeapAlloc( GetProcessHeap(), 0, sizeof( *obj
) );
2021 return DPERR_OUTOFMEMORY
;
2023 obj
->IDirectPlayLobby_iface
.lpVtbl
= &dpl_vt
;
2024 obj
->IDirectPlayLobbyA_iface
.lpVtbl
= &dplA_vt
;
2025 obj
->IDirectPlayLobby2_iface
.lpVtbl
= &dpl2_vt
;
2026 obj
->IDirectPlayLobby2A_iface
.lpVtbl
= &dpl2A_vt
;
2027 obj
->IDirectPlayLobby3_iface
.lpVtbl
= &dpl3_vt
;
2028 obj
->IDirectPlayLobby3A_iface
.lpVtbl
= &dpl3A_vt
;
2038 InitializeCriticalSection( &obj
->lock
);
2039 obj
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": IDirectPlayLobbyImpl.lock");
2040 DPQ_INIT( obj
->msgs
);
2042 hr
= IDirectPlayLobby_QueryInterface( &obj
->IDirectPlayLobby3_iface
, riid
, ppv
);
2043 IDirectPlayLobby_Release( &obj
->IDirectPlayLobby3_iface
);
2050 /***************************************************************************
2051 * DirectPlayLobbyCreateA (DPLAYX.4)
2054 HRESULT WINAPI
DirectPlayLobbyCreateA( GUID
*lpGUIDDSP
, IDirectPlayLobbyA
**lplpDPL
,
2055 IUnknown
*lpUnk
, void *lpData
, DWORD dwDataSize
)
2057 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08x\n",
2058 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
2060 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
2061 * equal 0. These fields are mostly for future expansion.
2063 if ( lpGUIDDSP
|| lpData
|| dwDataSize
)
2066 return DPERR_INVALIDPARAMS
;
2072 ERR("Bad parameters!\n" );
2073 return CLASS_E_NOAGGREGATION
;
2076 return dplobby_create( &IID_IDirectPlayLobbyA
, (void**)lplpDPL
);
2079 /***************************************************************************
2080 * DirectPlayLobbyCreateW (DPLAYX.5)
2083 HRESULT WINAPI
DirectPlayLobbyCreateW( GUID
*lpGUIDDSP
, IDirectPlayLobby
**lplpDPL
,
2084 IUnknown
*lpUnk
, void *lpData
, DWORD dwDataSize
)
2086 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08x\n",
2087 lpGUIDDSP
,lplpDPL
,lpUnk
,lpData
,dwDataSize
);
2089 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
2090 * equal 0. These fields are mostly for future expansion.
2092 if ( lpGUIDDSP
|| lpData
|| dwDataSize
)
2095 ERR("Bad parameters!\n" );
2096 return DPERR_INVALIDPARAMS
;
2102 ERR("Bad parameters!\n" );
2103 return CLASS_E_NOAGGREGATION
;
2106 return dplobby_create( &IID_IDirectPlayLobby
, (void**)lplpDPL
);