xinput1_3: Move HID data into struct xinput_controller.
[wine.git] / dlls / dplayx / dplobby.c
blob30d76aa16d13f1a01cbfd97bf2ae2366299287e0
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
19 #include <stdarg.h>
20 #include <string.h>
22 #define COBJMACROS
23 #define NONAMELESSUNION
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winerror.h"
28 #include "winreg.h"
29 #include "winnls.h"
30 #include "wine/debug.h"
32 #include "dplayx_global.h"
33 #include "dplayx_messages.h"
34 #include "dplayx_queue.h"
35 #include "dplobby.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(dplay);
39 /* Forward declarations for this module helper methods */
40 HRESULT DPL_CreateCompoundAddress ( LPCDPCOMPOUNDADDRESSELEMENT lpElements, DWORD dwElementCount,
41 LPVOID lpAddress, LPDWORD lpdwAddressSize, BOOL bAnsiInterface )DECLSPEC_HIDDEN;
43 static HRESULT DPL_CreateAddress( REFGUID guidSP, REFGUID guidDataType, LPCVOID lpData, DWORD dwDataSize,
44 LPVOID lpAddress, LPDWORD lpdwAddressSize, BOOL bAnsiInterface );
47 /*****************************************************************************
48 * IDirectPlayLobby {1,2,3} implementation structure
50 * The philosophy behind this extra pointer dereference is that I wanted to
51 * have the same structure for all types of objects without having to do
52 * a lot of casting. I also only wanted to implement an interface in the
53 * object it was "released" with IUnknown interface being implemented in the 1 version.
54 * Of course, with these new interfaces comes the data required to keep the state required
55 * by these interfaces. So, basically, the pointers contain the data associated with
56 * a release. If you use the data associated with release 3 in a release 2 object, you'll
57 * get a run time trap, as that won't have any data.
60 struct DPLMSG
62 DPQ_ENTRY( DPLMSG ) msgs; /* Link to next queued message */
64 typedef struct DPLMSG* LPDPLMSG;
66 typedef struct IDirectPlayLobbyImpl
68 IDirectPlayLobby IDirectPlayLobby_iface;
69 IDirectPlayLobbyA IDirectPlayLobbyA_iface;
70 IDirectPlayLobby2 IDirectPlayLobby2_iface;
71 IDirectPlayLobby2A IDirectPlayLobby2A_iface;
72 IDirectPlayLobby3 IDirectPlayLobby3_iface;
73 IDirectPlayLobby3A IDirectPlayLobby3A_iface;
74 LONG numIfaces; /* "in use interfaces" refcount */
75 LONG ref, refA, ref2, ref2A, ref3, ref3A;
76 CRITICAL_SECTION lock;
77 HKEY cbkeyhack;
78 DWORD msgtid;
79 DPQ_HEAD( DPLMSG ) msgs; /* List of messages received */
80 } IDirectPlayLobbyImpl;
82 static inline IDirectPlayLobbyImpl *impl_from_IDirectPlayLobby( IDirectPlayLobby *iface )
84 return CONTAINING_RECORD( iface, IDirectPlayLobbyImpl, IDirectPlayLobby_iface );
87 static inline IDirectPlayLobbyImpl *impl_from_IDirectPlayLobbyA( IDirectPlayLobbyA *iface )
89 return CONTAINING_RECORD( iface, IDirectPlayLobbyImpl, IDirectPlayLobbyA_iface );
92 static inline IDirectPlayLobbyImpl *impl_from_IDirectPlayLobby2( IDirectPlayLobby2 *iface )
94 return CONTAINING_RECORD( iface, IDirectPlayLobbyImpl, IDirectPlayLobby2_iface );
97 static inline IDirectPlayLobbyImpl *impl_from_IDirectPlayLobby2A( IDirectPlayLobby2A *iface )
99 return CONTAINING_RECORD( iface, IDirectPlayLobbyImpl, IDirectPlayLobby2A_iface );
102 static inline IDirectPlayLobbyImpl *impl_from_IDirectPlayLobby3( IDirectPlayLobby3 *iface )
104 return CONTAINING_RECORD( iface, IDirectPlayLobbyImpl, IDirectPlayLobby3_iface );
107 static inline IDirectPlayLobbyImpl *impl_from_IDirectPlayLobby3A( IDirectPlayLobby3A *iface )
109 return CONTAINING_RECORD( iface, IDirectPlayLobbyImpl, IDirectPlayLobby3A_iface );
112 static void dplobby_destroy(IDirectPlayLobbyImpl *obj)
114 if ( obj->msgtid )
115 FIXME( "Should kill the msg thread\n" );
117 DPQ_DELETEQ( obj->msgs, msgs, LPDPLMSG, cbDeleteElemFromHeap );
118 obj->lock.DebugInfo->Spare[0] = 0;
119 DeleteCriticalSection( &obj->lock );
120 HeapFree( GetProcessHeap(), 0, obj );
123 static HRESULT WINAPI IDirectPlayLobbyAImpl_QueryInterface( IDirectPlayLobbyA *iface, REFIID riid,
124 void **ppv )
126 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface );
127 return IDirectPlayLobby_QueryInterface( &This->IDirectPlayLobby3_iface, riid, ppv );
130 static HRESULT WINAPI IDirectPlayLobbyImpl_QueryInterface( IDirectPlayLobby *iface, REFIID riid,
131 void **ppv )
133 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface );
134 return IDirectPlayLobby_QueryInterface( &This->IDirectPlayLobby3_iface, riid, ppv );
137 static HRESULT WINAPI IDirectPlayLobby2AImpl_QueryInterface( IDirectPlayLobby2A *iface, REFIID riid,
138 void **ppv )
140 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface );
141 return IDirectPlayLobby_QueryInterface( &This->IDirectPlayLobby3_iface, riid, ppv );
144 static HRESULT WINAPI IDirectPlayLobby2Impl_QueryInterface( IDirectPlayLobby2 *iface, REFIID riid,
145 void **ppv )
147 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface );
148 return IDirectPlayLobby_QueryInterface( &This->IDirectPlayLobby3_iface, riid, ppv );
151 static HRESULT WINAPI IDirectPlayLobby3AImpl_QueryInterface( IDirectPlayLobby3A *iface, REFIID riid,
152 void **ppv )
154 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface );
155 return IDirectPlayLobby_QueryInterface( &This->IDirectPlayLobby3_iface, riid, ppv );
158 static HRESULT WINAPI IDirectPlayLobby3Impl_QueryInterface( IDirectPlayLobby3 *iface, REFIID riid,
159 void **ppv )
161 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface );
163 if ( IsEqualGUID( &IID_IUnknown, riid ) )
165 TRACE( "(%p)->(IID_IUnknown %p)\n", This, ppv );
166 *ppv = &This->IDirectPlayLobby_iface;
168 else if ( IsEqualGUID( &IID_IDirectPlayLobby, riid ) )
170 TRACE( "(%p)->(IID_IDirectPlayLobby %p)\n", This, ppv );
171 *ppv = &This->IDirectPlayLobby_iface;
173 else if ( IsEqualGUID( &IID_IDirectPlayLobbyA, riid ) )
175 TRACE( "(%p)->(IID_IDirectPlayLobbyA %p)\n", This, ppv );
176 *ppv = &This->IDirectPlayLobbyA_iface;
178 else if ( IsEqualGUID( &IID_IDirectPlayLobby2, riid ) )
180 TRACE( "(%p)->(IID_IDirectPlayLobby2 %p)\n", This, ppv );
181 *ppv = &This->IDirectPlayLobby2_iface;
183 else if ( IsEqualGUID( &IID_IDirectPlayLobby2A, riid ) )
185 TRACE( "(%p)->(IID_IDirectPlayLobby2A %p)\n", This, ppv );
186 *ppv = &This->IDirectPlayLobby2A_iface;
188 else if ( IsEqualGUID( &IID_IDirectPlayLobby3, riid ) )
190 TRACE( "(%p)->(IID_IDirectPlay3 %p)\n", This, ppv );
191 *ppv = &This->IDirectPlayLobby3_iface;
193 else if ( IsEqualGUID( &IID_IDirectPlayLobby3A, riid ) )
195 TRACE( "(%p)->(IID_IDirectPlayLobby3A %p)\n", This, ppv );
196 *ppv = &This->IDirectPlayLobby3A_iface;
198 else
200 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
201 *ppv = NULL;
202 return E_NOINTERFACE;
205 IUnknown_AddRef((IUnknown*)*ppv);
206 return S_OK;
209 static ULONG WINAPI IDirectPlayLobbyAImpl_AddRef( IDirectPlayLobbyA *iface )
211 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface );
212 ULONG ref = InterlockedIncrement( &This->refA );
214 TRACE( "(%p) refA=%d\n", This, ref );
216 if ( ref == 1 )
217 InterlockedIncrement( &This->numIfaces );
219 return ref;
222 static ULONG WINAPI IDirectPlayLobbyImpl_AddRef( IDirectPlayLobby *iface )
224 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface );
225 ULONG ref = InterlockedIncrement( &This->ref );
227 TRACE( "(%p) ref=%d\n", This, ref );
229 if ( ref == 1 )
230 InterlockedIncrement( &This->numIfaces );
232 return ref;
235 static ULONG WINAPI IDirectPlayLobby2AImpl_AddRef(IDirectPlayLobby2A *iface)
237 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface );
238 ULONG ref = InterlockedIncrement( &This->ref2A );
240 TRACE( "(%p) ref2A=%d\n", This, ref );
242 if ( ref == 1 )
243 InterlockedIncrement( &This->numIfaces );
245 return ref;
248 static ULONG WINAPI IDirectPlayLobby2Impl_AddRef(IDirectPlayLobby2 *iface)
250 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface );
251 ULONG ref = InterlockedIncrement( &This->ref2 );
253 TRACE( "(%p) ref2=%d\n", This, ref );
255 if ( ref == 1 )
256 InterlockedIncrement( &This->numIfaces );
258 return ref;
261 static ULONG WINAPI IDirectPlayLobby3AImpl_AddRef(IDirectPlayLobby3A *iface)
263 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface );
264 ULONG ref = InterlockedIncrement( &This->ref3A );
266 TRACE( "(%p) ref3A=%d\n", This, ref );
268 if ( ref == 1 )
269 InterlockedIncrement( &This->numIfaces );
271 return ref;
274 static ULONG WINAPI IDirectPlayLobby3Impl_AddRef(IDirectPlayLobby3 *iface)
276 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface );
277 ULONG ref = InterlockedIncrement( &This->ref3 );
279 TRACE( "(%p) ref3=%d\n", This, ref );
281 if ( ref == 1 )
282 InterlockedIncrement( &This->numIfaces );
284 return ref;
287 static ULONG WINAPI IDirectPlayLobbyAImpl_Release( IDirectPlayLobbyA *iface )
289 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface );
290 ULONG ref = InterlockedDecrement( &This->refA );
292 TRACE( "(%p) refA=%d\n", This, ref );
294 if ( !ref && !InterlockedDecrement( &This->numIfaces ) )
295 dplobby_destroy( This );
297 return ref;
300 static ULONG WINAPI IDirectPlayLobbyImpl_Release( IDirectPlayLobby *iface )
302 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface );
303 ULONG ref = InterlockedDecrement( &This->ref );
305 TRACE( "(%p) ref=%d\n", This, ref );
307 if ( !ref && !InterlockedDecrement( &This->numIfaces ) )
308 dplobby_destroy( This );
310 return ref;
313 static ULONG WINAPI IDirectPlayLobby2AImpl_Release(IDirectPlayLobby2A *iface)
315 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface );
316 ULONG ref = InterlockedDecrement( &This->ref2A );
318 TRACE( "(%p) ref2A=%d\n", This, ref );
320 if ( !ref && !InterlockedDecrement( &This->numIfaces ) )
321 dplobby_destroy( This );
323 return ref;
326 static ULONG WINAPI IDirectPlayLobby2Impl_Release(IDirectPlayLobby2 *iface)
328 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface );
329 ULONG ref = InterlockedDecrement( &This->ref2 );
331 TRACE( "(%p) ref2=%d\n", This, ref );
333 if ( !ref && !InterlockedDecrement( &This->numIfaces ) )
334 dplobby_destroy( This );
336 return ref;
339 static ULONG WINAPI IDirectPlayLobby3AImpl_Release(IDirectPlayLobby3A *iface)
341 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface );
342 ULONG ref = InterlockedDecrement( &This->ref3A );
344 TRACE( "(%p) ref3A=%d\n", This, ref );
346 if ( !ref && !InterlockedDecrement( &This->numIfaces ) )
347 dplobby_destroy( This );
349 return ref;
352 static ULONG WINAPI IDirectPlayLobby3Impl_Release(IDirectPlayLobby3 *iface)
354 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface );
355 ULONG ref = InterlockedDecrement( &This->ref3 );
357 TRACE( "(%p) ref3=%d\n", This, ref );
359 if ( !ref && !InterlockedDecrement( &This->numIfaces ) )
360 dplobby_destroy( This );
362 return ref;
366 /********************************************************************
368 * Connects an application to the session specified by the DPLCONNECTION
369 * structure currently stored with the DirectPlayLobby object.
371 * Returns an IDirectPlay interface.
374 static HRESULT DPL_ConnectEx( IDirectPlayLobbyImpl *This, DWORD dwFlags, REFIID riid, void **lplpDP,
375 IUnknown* pUnk)
377 HRESULT hr;
378 DWORD dwOpenFlags = 0;
379 DWORD dwConnSize = 0;
380 LPDPLCONNECTION lpConn;
382 FIXME("(%p)->(0x%08x,%p,%p): semi stub\n", This, dwFlags, lplpDP, pUnk );
384 if( pUnk )
386 return DPERR_INVALIDPARAMS;
389 /* Backwards compatibility */
390 if( dwFlags == 0 )
392 dwFlags = DPCONNECT_RETURNSTATUS;
395 if ( ( hr = dplay_create( riid, lplpDP ) ) != DP_OK )
397 ERR( "error creating interface for %s:%s.\n",
398 debugstr_guid( riid ), DPLAYX_HresultToString( hr ) );
399 return hr;
402 /* FIXME: Is it safe/correct to use appID of 0? */
403 hr = IDirectPlayLobby_GetConnectionSettings( &This->IDirectPlayLobby3_iface,
404 0, NULL, &dwConnSize );
405 if( hr != DPERR_BUFFERTOOSMALL )
407 return hr;
410 lpConn = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwConnSize );
412 if( lpConn == NULL )
414 return DPERR_NOMEMORY;
417 /* FIXME: Is it safe/correct to use appID of 0? */
418 hr = IDirectPlayLobby_GetConnectionSettings( &This->IDirectPlayLobby3_iface,
419 0, lpConn, &dwConnSize );
420 if( FAILED( hr ) )
422 HeapFree( GetProcessHeap(), 0, lpConn );
423 return hr;
426 #if 0
427 /* - Need to call IDirectPlay::EnumConnections with the service provider to get that good information
428 * - Need to call CreateAddress to create the lpConnection param for IDirectPlay::InitializeConnection
429 * - Call IDirectPlay::InitializeConnection
432 /* Now initialize the Service Provider */
433 hr = IDirectPlayX_InitializeConnection( (*(LPDIRECTPLAY2*)lplpDP),
434 #endif
437 /* Setup flags to pass into DirectPlay::Open */
438 if( dwFlags & DPCONNECT_RETURNSTATUS )
440 dwOpenFlags |= DPOPEN_RETURNSTATUS;
442 dwOpenFlags |= lpConn->dwFlags;
444 hr = IDirectPlayX_Open( (*(LPDIRECTPLAY2*)lplpDP), lpConn->lpSessionDesc,
445 dwOpenFlags );
447 HeapFree( GetProcessHeap(), 0, lpConn );
449 return hr;
452 static HRESULT WINAPI IDirectPlayLobbyAImpl_Connect( IDirectPlayLobbyA *iface, DWORD flags,
453 IDirectPlay2A **dp, IUnknown *unk )
455 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface );
456 return IDirectPlayLobby_Connect( &This->IDirectPlayLobby3A_iface, flags, dp, unk );
459 static HRESULT WINAPI IDirectPlayLobbyImpl_Connect( IDirectPlayLobby *iface, DWORD flags,
460 IDirectPlay2A **dp, IUnknown *unk )
462 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface );
463 return IDirectPlayLobby_Connect( &This->IDirectPlayLobby3_iface, flags, dp, unk );
466 static HRESULT WINAPI IDirectPlayLobby2AImpl_Connect( IDirectPlayLobby2A *iface, DWORD flags,
467 IDirectPlay2A **dp, IUnknown *unk )
469 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface );
470 return IDirectPlayLobby_Connect( &This->IDirectPlayLobby3A_iface, flags, dp, unk );
473 static HRESULT WINAPI IDirectPlayLobby2Impl_Connect( IDirectPlayLobby2 *iface, DWORD flags,
474 IDirectPlay2A **dp, IUnknown *unk )
476 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface );
477 return IDirectPlayLobby_Connect( &This->IDirectPlayLobby3_iface, flags, dp, unk );
480 static HRESULT WINAPI IDirectPlayLobby3AImpl_Connect( IDirectPlayLobby3A *iface, DWORD flags,
481 IDirectPlay2A **dp, IUnknown *unk)
483 return IDirectPlayLobby_ConnectEx( iface, flags, &IID_IDirectPlay2A, (void**)dp, unk );
486 static HRESULT WINAPI IDirectPlayLobby3Impl_Connect( IDirectPlayLobby3 *iface, DWORD flags,
487 IDirectPlay2 **dp, IUnknown *unk)
489 return IDirectPlayLobby_ConnectEx( iface, flags, &IID_IDirectPlay2A, (void**)dp, unk );
492 /********************************************************************
494 * Creates a DirectPlay Address, given a service provider-specific network
495 * address.
496 * Returns an address contains the globally unique identifier
497 * (GUID) of the service provider and data that the service provider can
498 * interpret as a network address.
500 * NOTE: It appears that this method is supposed to be really really stupid
501 * with no error checking on the contents.
503 static HRESULT WINAPI IDirectPlayLobbyAImpl_CreateAddress( IDirectPlayLobbyA *iface, REFGUID sp,
504 REFGUID datatype, const void *data, DWORD datasize, void *address, DWORD *addrsize )
506 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface );
507 return IDirectPlayLobby_CreateAddress( &This->IDirectPlayLobby3A_iface, sp, datatype, data,
508 datasize, address, addrsize );
511 static HRESULT WINAPI IDirectPlayLobbyImpl_CreateAddress( IDirectPlayLobby *iface, REFGUID sp,
512 REFGUID datatype, const void *data, DWORD datasize, void *address, DWORD *addrsize )
514 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface );
515 return IDirectPlayLobby_CreateAddress( &This->IDirectPlayLobby3_iface, sp, datatype, data,
516 datasize, address, addrsize );
519 static HRESULT WINAPI IDirectPlayLobby2AImpl_CreateAddress( IDirectPlayLobby2A *iface, REFGUID sp,
520 REFGUID datatype, const void *data, DWORD datasize, void *address, DWORD *addrsize )
522 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface );
523 return IDirectPlayLobby_CreateAddress( &This->IDirectPlayLobby3A_iface, sp, datatype, data,
524 datasize, address, addrsize );
527 static HRESULT WINAPI IDirectPlayLobby2Impl_CreateAddress( IDirectPlayLobby2 *iface, REFGUID sp,
528 REFGUID datatype, const void *data, DWORD datasize, void *address, DWORD *addrsize )
530 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface );
531 return IDirectPlayLobby_CreateAddress( &This->IDirectPlayLobby3_iface, sp, datatype, data,
532 datasize, address, addrsize );
535 static HRESULT WINAPI IDirectPlayLobby3AImpl_CreateAddress( IDirectPlayLobby3A *iface,
536 REFGUID guidSP, REFGUID guidDataType, const void *lpData, DWORD dwDataSize, void *lpAddress,
537 DWORD *lpdwAddressSize )
539 return DPL_CreateAddress( guidSP, guidDataType, lpData, dwDataSize,
540 lpAddress, lpdwAddressSize, TRUE );
543 static HRESULT WINAPI IDirectPlayLobby3Impl_CreateAddress( IDirectPlayLobby3 *iface, REFGUID guidSP,
544 REFGUID guidDataType, const void *lpData, DWORD dwDataSize, void *lpAddress,
545 DWORD *lpdwAddressSize )
547 return DPL_CreateAddress( guidSP, guidDataType, lpData, dwDataSize,
548 lpAddress, lpdwAddressSize, FALSE );
551 static HRESULT DPL_CreateAddress(
552 REFGUID guidSP,
553 REFGUID guidDataType,
554 LPCVOID lpData,
555 DWORD dwDataSize,
556 LPVOID lpAddress,
557 LPDWORD lpdwAddressSize,
558 BOOL bAnsiInterface )
560 const DWORD dwNumAddElements = 2; /* Service Provide & address data type */
561 DPCOMPOUNDADDRESSELEMENT addressElements[ 2 /* dwNumAddElements */ ];
563 TRACE( "(%p)->(%p,%p,0x%08x,%p,%p,%d)\n", guidSP, guidDataType, lpData, dwDataSize,
564 lpAddress, lpdwAddressSize, bAnsiInterface );
566 addressElements[ 0 ].guidDataType = DPAID_ServiceProvider;
567 addressElements[ 0 ].dwDataSize = sizeof( GUID );
568 addressElements[ 0 ].lpData = (LPVOID)guidSP;
570 addressElements[ 1 ].guidDataType = *guidDataType;
571 addressElements[ 1 ].dwDataSize = dwDataSize;
572 addressElements[ 1 ].lpData = (LPVOID)lpData;
574 /* Call CreateCompoundAddress to cut down on code.
575 NOTE: We can do this because we don't support DPL 1 interfaces! */
576 return DPL_CreateCompoundAddress( addressElements, dwNumAddElements,
577 lpAddress, lpdwAddressSize, bAnsiInterface );
582 /********************************************************************
584 * Parses out chunks from the DirectPlay Address buffer by calling the
585 * given callback function, with lpContext, for each of the chunks.
588 static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddress( IDirectPlayLobbyA *iface,
589 LPDPENUMADDRESSCALLBACK enumaddrcb, const void *address, DWORD size, void *context )
591 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface );
592 return IDirectPlayLobby_EnumAddress( &This->IDirectPlayLobby3A_iface, enumaddrcb, address, size,
593 context );
596 static HRESULT WINAPI IDirectPlayLobbyImpl_EnumAddress( IDirectPlayLobby *iface,
597 LPDPENUMADDRESSCALLBACK enumaddrcb, const void *address, DWORD size, void *context )
599 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface );
600 return IDirectPlayLobby_EnumAddress( &This->IDirectPlayLobby3_iface, enumaddrcb, address, size,
601 context );
604 static HRESULT WINAPI IDirectPlayLobby2AImpl_EnumAddress( IDirectPlayLobby2A *iface,
605 LPDPENUMADDRESSCALLBACK enumaddrcb, const void *address, DWORD size, void *context )
607 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface );
608 return IDirectPlayLobby_EnumAddress( &This->IDirectPlayLobby3A_iface, enumaddrcb, address, size,
609 context );
612 static HRESULT WINAPI IDirectPlayLobby2Impl_EnumAddress( IDirectPlayLobby2 *iface,
613 LPDPENUMADDRESSCALLBACK enumaddrcb, const void *address, DWORD size, void *context )
615 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface );
616 return IDirectPlayLobby_EnumAddress( &This->IDirectPlayLobby3_iface, enumaddrcb, address, size,
617 context );
620 static HRESULT WINAPI IDirectPlayLobby3AImpl_EnumAddress( IDirectPlayLobby3A *iface,
621 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback, const void *lpAddress, DWORD dwAddressSize,
622 void *lpContext )
624 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface );
626 TRACE("(%p)->(%p,%p,0x%08x,%p)\n", This, lpEnumAddressCallback, lpAddress,
627 dwAddressSize, lpContext );
629 return DPL_EnumAddress( lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext );
632 static HRESULT WINAPI IDirectPlayLobby3Impl_EnumAddress( IDirectPlayLobby3 *iface,
633 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback, const void *lpAddress, DWORD dwAddressSize,
634 void *lpContext )
636 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface );
638 TRACE("(%p)->(%p,%p,0x%08x,%p)\n", This, lpEnumAddressCallback, lpAddress,
639 dwAddressSize, lpContext );
641 return DPL_EnumAddress( lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext );
644 HRESULT DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback, LPCVOID lpAddress,
645 DWORD dwAddressSize, LPVOID lpContext )
647 DWORD dwTotalSizeEnumerated = 0;
649 /* FIXME: First chunk is always the total size chunk - Should we report it? */
651 while ( dwTotalSizeEnumerated < dwAddressSize )
653 const DPADDRESS* lpElements = lpAddress;
654 DWORD dwSizeThisEnumeration;
656 /* Invoke the enum method. If false is returned, stop enumeration */
657 if ( !lpEnumAddressCallback( &lpElements->guidDataType,
658 lpElements->dwDataSize,
659 (const BYTE *)lpElements + sizeof( DPADDRESS ),
660 lpContext ) )
662 break;
665 dwSizeThisEnumeration = sizeof( DPADDRESS ) + lpElements->dwDataSize;
666 lpAddress = (const BYTE*) lpAddress + dwSizeThisEnumeration;
667 dwTotalSizeEnumerated += dwSizeThisEnumeration;
670 return DP_OK;
673 /********************************************************************
675 * Enumerates all the address types that a given service provider needs to
676 * build the DirectPlay Address.
679 static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddressTypes( IDirectPlayLobbyA *iface,
680 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb, REFGUID sp, void *context, DWORD flags )
682 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface );
683 return IDirectPlayLobby_EnumAddressTypes( &This->IDirectPlayLobby3A_iface, enumaddrtypecb, sp,
684 context, flags );
687 static HRESULT WINAPI IDirectPlayLobbyImpl_EnumAddressTypes( IDirectPlayLobby *iface,
688 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb, REFGUID sp, void *context, DWORD flags )
690 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface );
691 return IDirectPlayLobby_EnumAddressTypes( &This->IDirectPlayLobby3_iface, enumaddrtypecb, sp,
692 context, flags );
695 static HRESULT WINAPI IDirectPlayLobby2AImpl_EnumAddressTypes( IDirectPlayLobby2A *iface,
696 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb, REFGUID sp, void *context, DWORD flags )
698 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface );
699 return IDirectPlayLobby_EnumAddressTypes( &This->IDirectPlayLobby3A_iface, enumaddrtypecb, sp,
700 context, flags );
703 static HRESULT WINAPI IDirectPlayLobby2Impl_EnumAddressTypes( IDirectPlayLobby2 *iface,
704 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb, REFGUID sp, void *context, DWORD flags )
706 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface );
707 return IDirectPlayLobby_EnumAddressTypes( &This->IDirectPlayLobby3_iface, enumaddrtypecb, sp,
708 context, flags );
711 static HRESULT WINAPI IDirectPlayLobby3AImpl_EnumAddressTypes( IDirectPlayLobby3A *iface,
712 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback, REFGUID guidSP, void *lpContext,
713 DWORD dwFlags )
715 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface );
717 HKEY hkResult;
718 LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
719 DWORD dwIndex, sizeOfSubKeyName=50;
720 char subKeyName[51];
721 FILETIME filetime;
723 TRACE(" (%p)->(%p,%p,%p,0x%08x)\n", This, lpEnumAddressTypeCallback, guidSP, lpContext, dwFlags );
725 if( dwFlags != 0 )
727 return DPERR_INVALIDPARAMS;
730 if( !lpEnumAddressTypeCallback )
732 return DPERR_INVALIDPARAMS;
735 if( guidSP == NULL )
737 return DPERR_INVALIDOBJECT;
740 /* Need to loop over the service providers in the registry */
741 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
742 0, KEY_READ, &hkResult ) != ERROR_SUCCESS )
744 /* Hmmm. Does this mean that there are no service providers? */
745 ERR(": no service providers?\n");
746 return DP_OK;
749 /* Traverse all the service providers we have available */
750 for( dwIndex=0;
751 RegEnumKeyExA( hkResult, dwIndex, subKeyName, &sizeOfSubKeyName,
752 NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS;
753 ++dwIndex, sizeOfSubKeyName=50 )
756 HKEY hkServiceProvider, hkServiceProviderAt;
757 GUID serviceProviderGUID;
758 DWORD returnTypeGUID, sizeOfReturnBuffer = 50;
759 char atSubKey[51];
760 char returnBuffer[51];
761 WCHAR buff[51];
762 DWORD dwAtIndex;
763 LPCSTR atKey = "Address Types";
764 LPCSTR guidDataSubKey = "Guid";
766 TRACE(" this time through: %s\n", subKeyName );
768 /* Get a handle for this particular service provider */
769 if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_READ,
770 &hkServiceProvider ) != ERROR_SUCCESS )
772 ERR(": what the heck is going on?\n" );
773 continue;
776 if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
777 NULL, &returnTypeGUID, (LPBYTE)returnBuffer,
778 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
780 ERR(": missing GUID registry data members\n" );
781 continue;
784 /* FIXME: Check return types to ensure we're interpreting data right */
785 MultiByteToWideChar( CP_ACP, 0, returnBuffer, -1, buff, ARRAY_SIZE( buff ));
786 CLSIDFromString( buff, &serviceProviderGUID );
787 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
789 /* Determine if this is the Service Provider that the user asked for */
790 if( !IsEqualGUID( &serviceProviderGUID, guidSP ) )
792 continue;
795 /* Get a handle for this particular service provider */
796 if( RegOpenKeyExA( hkServiceProvider, atKey, 0, KEY_READ,
797 &hkServiceProviderAt ) != ERROR_SUCCESS )
799 TRACE(": No Address Types registry data sub key/members\n" );
800 break;
803 /* Traverse all the address type we have available */
804 for( dwAtIndex=0;
805 RegEnumKeyExA( hkServiceProviderAt, dwAtIndex, atSubKey, &sizeOfSubKeyName,
806 NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS;
807 ++dwAtIndex, sizeOfSubKeyName=50 )
809 TRACE( "Found Address Type GUID %s\n", atSubKey );
811 /* FIXME: Check return types to ensure we're interpreting data right */
812 MultiByteToWideChar( CP_ACP, 0, atSubKey, -1, buff, ARRAY_SIZE( buff ));
813 CLSIDFromString( buff, &serviceProviderGUID );
814 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
816 /* The enumeration will return FALSE if we are not to continue */
817 if( !lpEnumAddressTypeCallback( &serviceProviderGUID, lpContext, 0 ) )
819 WARN("lpEnumCallback returning FALSE\n" );
820 break; /* FIXME: This most likely has to break from the procedure...*/
825 /* We only enumerate address types for 1 GUID. We've found it, so quit looking */
826 break;
829 return DP_OK;
832 static HRESULT WINAPI IDirectPlayLobby3Impl_EnumAddressTypes( IDirectPlayLobby3 *iface,
833 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb, REFGUID sp, void *context, DWORD flags )
835 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface );
836 return IDirectPlayLobby_EnumAddressTypes( &This->IDirectPlayLobby3A_iface, enumaddrtypecb, sp,
837 context, flags );
840 /********************************************************************
842 * Enumerates what applications are registered with DirectPlay by
843 * invoking the callback function with lpContext.
846 static HRESULT WINAPI IDirectPlayLobby3Impl_EnumLocalApplications( IDirectPlayLobby3 *iface,
847 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback, void *lpContext, DWORD dwFlags )
849 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface );
851 FIXME("(%p)->(%p,%p,0x%08x):stub\n", This, lpEnumLocalAppCallback, lpContext, dwFlags );
853 return DPERR_OUTOFMEMORY;
856 static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumLocalApplications( IDirectPlayLobbyA *iface,
857 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb, void *context, DWORD flags )
859 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface );
860 return IDirectPlayLobby_EnumLocalApplications( &This->IDirectPlayLobby3A_iface, enumlocalappcb,
861 context, flags );
864 static HRESULT WINAPI IDirectPlayLobbyImpl_EnumLocalApplications( IDirectPlayLobby *iface,
865 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb, void *context, DWORD flags )
867 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface );
868 return IDirectPlayLobby_EnumLocalApplications( &This->IDirectPlayLobby3_iface, enumlocalappcb,
869 context, flags );
872 static HRESULT WINAPI IDirectPlayLobby2AImpl_EnumLocalApplications( IDirectPlayLobby2A *iface,
873 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb, void *context, DWORD flags )
875 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface );
876 return IDirectPlayLobby_EnumLocalApplications( &This->IDirectPlayLobby3A_iface, enumlocalappcb,
877 context, flags );
880 static HRESULT WINAPI IDirectPlayLobby2Impl_EnumLocalApplications( IDirectPlayLobby2 *iface,
881 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb, void *context, DWORD flags )
883 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface );
884 return IDirectPlayLobby_EnumLocalApplications( &This->IDirectPlayLobby3_iface, enumlocalappcb,
885 context, flags );
888 static HRESULT WINAPI IDirectPlayLobby3AImpl_EnumLocalApplications( IDirectPlayLobby3A *iface,
889 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback, void *lpContext, DWORD dwFlags )
891 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface );
893 HKEY hkResult;
894 LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Applications";
895 LPCSTR guidDataSubKey = "Guid";
896 DWORD dwIndex, sizeOfSubKeyName=50;
897 char subKeyName[51];
898 FILETIME filetime;
900 TRACE("(%p)->(%p,%p,0x%08x)\n", This, lpEnumLocalAppCallback, lpContext, dwFlags );
902 if( dwFlags != 0 )
904 return DPERR_INVALIDPARAMS;
907 if( !lpEnumLocalAppCallback )
909 return DPERR_INVALIDPARAMS;
912 /* Need to loop over the service providers in the registry */
913 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
914 0, KEY_READ, &hkResult ) != ERROR_SUCCESS )
916 /* Hmmm. Does this mean that there are no service providers? */
917 ERR(": no service providers?\n");
918 return DP_OK;
921 /* Traverse all registered applications */
922 for( dwIndex=0;
923 RegEnumKeyExA( hkResult, dwIndex, subKeyName, &sizeOfSubKeyName, NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS;
924 ++dwIndex, sizeOfSubKeyName=50 )
927 HKEY hkServiceProvider;
928 GUID serviceProviderGUID;
929 DWORD returnTypeGUID, sizeOfReturnBuffer = 50;
930 char returnBuffer[51];
931 WCHAR buff[51];
932 DPLAPPINFO dplAppInfo;
934 TRACE(" this time through: %s\n", subKeyName );
936 /* Get a handle for this particular service provider */
937 if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_READ,
938 &hkServiceProvider ) != ERROR_SUCCESS )
940 ERR(": what the heck is going on?\n" );
941 continue;
944 if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
945 NULL, &returnTypeGUID, (LPBYTE)returnBuffer,
946 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
948 ERR(": missing GUID registry data members\n" );
949 continue;
952 /* FIXME: Check return types to ensure we're interpreting data right */
953 MultiByteToWideChar( CP_ACP, 0, returnBuffer, -1, buff, ARRAY_SIZE( buff ));
954 CLSIDFromString( buff, &serviceProviderGUID );
955 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
957 dplAppInfo.dwSize = sizeof( dplAppInfo );
958 dplAppInfo.guidApplication = serviceProviderGUID;
959 dplAppInfo.u.lpszAppNameA = subKeyName;
961 EnterCriticalSection( &This->lock );
963 memcpy( &This->cbkeyhack, &hkServiceProvider, sizeof( hkServiceProvider ) );
965 if( !lpEnumLocalAppCallback( &dplAppInfo, lpContext, dwFlags ) )
967 LeaveCriticalSection( &This->lock );
968 break;
971 LeaveCriticalSection( &This->lock );
974 return DP_OK;
977 /********************************************************************
979 * Retrieves the DPLCONNECTION structure that contains all the information
980 * needed to start and connect an application. This was generated using
981 * either the RunApplication or SetConnectionSettings methods.
983 * NOTES: If lpData is NULL then just return lpdwDataSize. This allows
984 * the data structure to be allocated by our caller which can then
985 * call this procedure/method again with a valid data pointer.
987 static HRESULT WINAPI IDirectPlayLobbyAImpl_GetConnectionSettings( IDirectPlayLobbyA *iface,
988 DWORD appid, void *data, DWORD *size )
990 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface );
991 return IDirectPlayLobby_GetConnectionSettings( &This->IDirectPlayLobby3A_iface, appid, data,
992 size );
995 static HRESULT WINAPI IDirectPlayLobbyImpl_GetConnectionSettings( IDirectPlayLobby *iface,
996 DWORD appid, void *data, DWORD *size )
998 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface );
999 return IDirectPlayLobby_GetConnectionSettings( &This->IDirectPlayLobby3_iface, appid, data,
1000 size );
1003 static HRESULT WINAPI IDirectPlayLobby2AImpl_GetConnectionSettings( IDirectPlayLobby2A *iface,
1004 DWORD appid, void *data, DWORD *size )
1006 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface );
1007 return IDirectPlayLobby_GetConnectionSettings( &This->IDirectPlayLobby3A_iface, appid, data,
1008 size );
1011 static HRESULT WINAPI IDirectPlayLobby2Impl_GetConnectionSettings( IDirectPlayLobby2 *iface,
1012 DWORD appid, void *data, DWORD *size )
1014 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface );
1015 return IDirectPlayLobby_GetConnectionSettings( &This->IDirectPlayLobby3_iface, appid, data,
1016 size );
1019 static HRESULT WINAPI IDirectPlayLobby3AImpl_GetConnectionSettings( IDirectPlayLobby3A *iface,
1020 DWORD dwAppID, void *lpData, DWORD *lpdwDataSize )
1022 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface );
1023 HRESULT hr;
1025 TRACE("(%p)->(0x%08x,%p,%p)\n", This, dwAppID, lpData, lpdwDataSize );
1027 EnterCriticalSection( &This->lock );
1029 hr = DPLAYX_GetConnectionSettingsA( dwAppID,
1030 lpData,
1031 lpdwDataSize
1034 LeaveCriticalSection( &This->lock );
1036 return hr;
1039 static HRESULT WINAPI IDirectPlayLobby3Impl_GetConnectionSettings( IDirectPlayLobby3 *iface,
1040 DWORD dwAppID, void *lpData, DWORD *lpdwDataSize )
1042 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface );
1043 HRESULT hr;
1045 TRACE("(%p)->(0x%08x,%p,%p)\n", This, dwAppID, lpData, lpdwDataSize );
1047 EnterCriticalSection( &This->lock );
1049 hr = DPLAYX_GetConnectionSettingsW( dwAppID,
1050 lpData,
1051 lpdwDataSize
1054 LeaveCriticalSection( &This->lock );
1056 return hr;
1059 /********************************************************************
1061 * Retrieves the message sent between a lobby client and a DirectPlay
1062 * application. All messages are queued until received.
1065 static HRESULT WINAPI IDirectPlayLobbyAImpl_ReceiveLobbyMessage( IDirectPlayLobbyA *iface,
1066 DWORD flags, DWORD appid, DWORD *msgflags, void *data, DWORD *size )
1068 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface );
1069 return IDirectPlayLobby_ReceiveLobbyMessage( &This->IDirectPlayLobby3A_iface, flags, appid,
1070 msgflags, data, size );
1073 static HRESULT WINAPI IDirectPlayLobbyImpl_ReceiveLobbyMessage( IDirectPlayLobby *iface,
1074 DWORD flags, DWORD appid, DWORD *msgflags, void *data, DWORD *size )
1076 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface );
1077 return IDirectPlayLobby_ReceiveLobbyMessage( &This->IDirectPlayLobby3_iface, flags, appid,
1078 msgflags, data, size );
1081 static HRESULT WINAPI IDirectPlayLobby2AImpl_ReceiveLobbyMessage( IDirectPlayLobby2A *iface,
1082 DWORD flags, DWORD appid, DWORD *msgflags, void *data, DWORD *size )
1084 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface );
1085 return IDirectPlayLobby_ReceiveLobbyMessage( &This->IDirectPlayLobby3A_iface, flags, appid,
1086 msgflags, data, size );
1089 static HRESULT WINAPI IDirectPlayLobby2Impl_ReceiveLobbyMessage( IDirectPlayLobby2 *iface,
1090 DWORD flags, DWORD appid, DWORD *msgflags, void *data, DWORD *size )
1092 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface );
1093 return IDirectPlayLobby_ReceiveLobbyMessage( &This->IDirectPlayLobby3_iface, flags, appid,
1094 msgflags, data, size );
1097 static HRESULT WINAPI IDirectPlayLobby3AImpl_ReceiveLobbyMessage( IDirectPlayLobby3A *iface,
1098 DWORD dwFlags, DWORD dwAppID, DWORD *lpdwMessageFlags, void *lpData,
1099 DWORD *lpdwDataSize )
1101 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface );
1102 FIXME(":stub %p %08x %08x %p %p %p\n", This, dwFlags, dwAppID, lpdwMessageFlags, lpData,
1103 lpdwDataSize );
1104 return DPERR_OUTOFMEMORY;
1107 static HRESULT WINAPI IDirectPlayLobby3Impl_ReceiveLobbyMessage( IDirectPlayLobby3 *iface,
1108 DWORD dwFlags, DWORD dwAppID, DWORD *lpdwMessageFlags, void *lpData,
1109 DWORD *lpdwDataSize )
1111 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface );
1112 FIXME(":stub %p %08x %08x %p %p %p\n", This, dwFlags, dwAppID, lpdwMessageFlags, lpData,
1113 lpdwDataSize );
1114 return DPERR_OUTOFMEMORY;
1117 typedef struct tagRunApplicationEnumStruct
1119 IDirectPlayLobbyImpl *This;
1121 GUID appGUID;
1122 LPSTR lpszPath;
1123 LPSTR lpszFileName;
1124 LPSTR lpszCommandLine;
1125 LPSTR lpszCurrentDirectory;
1126 } RunApplicationEnumStruct, *lpRunApplicationEnumStruct;
1128 /* To be called by RunApplication to find how to invoke the function */
1129 static BOOL CALLBACK RunApplicationA_EnumLocalApplications
1130 ( LPCDPLAPPINFO lpAppInfo,
1131 LPVOID lpContext,
1132 DWORD dwFlags )
1134 lpRunApplicationEnumStruct lpData = (lpRunApplicationEnumStruct)lpContext;
1136 if( IsEqualGUID( &lpAppInfo->guidApplication, &lpData->appGUID ) )
1138 char returnBuffer[200];
1139 DWORD returnType, sizeOfReturnBuffer;
1140 LPCSTR clSubKey = "CommandLine";
1141 LPCSTR cdSubKey = "CurrentDirectory";
1142 LPCSTR fileSubKey = "File";
1143 LPCSTR pathSubKey = "Path";
1145 /* FIXME: Lazy man hack - dplay struct has the present reg key saved */
1147 sizeOfReturnBuffer = 200;
1149 /* Get all the appropriate data from the registry */
1150 if( RegQueryValueExA( lpData->This->cbkeyhack, clSubKey,
1151 NULL, &returnType, (LPBYTE)returnBuffer,
1152 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
1154 ERR( ": missing CommandLine registry data member\n" );
1156 else
1158 if ((lpData->lpszCommandLine = HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer)+1 )))
1159 strcpy( lpData->lpszCommandLine, returnBuffer );
1162 sizeOfReturnBuffer = 200;
1164 if( RegQueryValueExA( lpData->This->cbkeyhack, cdSubKey,
1165 NULL, &returnType, (LPBYTE)returnBuffer,
1166 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
1168 ERR( ": missing CurrentDirectory registry data member\n" );
1170 else
1172 if ((lpData->lpszCurrentDirectory = HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer)+1 )))
1173 strcpy( lpData->lpszCurrentDirectory, returnBuffer );
1176 sizeOfReturnBuffer = 200;
1178 if( RegQueryValueExA( lpData->This->cbkeyhack, fileSubKey,
1179 NULL, &returnType, (LPBYTE)returnBuffer,
1180 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
1182 ERR( ": missing File registry data member\n" );
1184 else
1186 if ((lpData->lpszFileName = HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer)+1 )))
1187 strcpy( lpData->lpszFileName, returnBuffer );
1190 sizeOfReturnBuffer = 200;
1192 if( RegQueryValueExA( lpData->This->cbkeyhack, pathSubKey,
1193 NULL, &returnType, (LPBYTE)returnBuffer,
1194 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
1196 ERR( ": missing Path registry data member\n" );
1198 else
1200 if ((lpData->lpszPath = HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer)+1 )))
1201 strcpy( lpData->lpszPath, returnBuffer );
1204 return FALSE; /* No need to keep going as we found what we wanted */
1207 return TRUE; /* Keep enumerating, haven't found the application yet */
1210 static BOOL DPL_CreateAndSetLobbyHandles( DWORD dwDestProcessId, HANDLE hDestProcess,
1211 LPHANDLE lphStart, LPHANDLE lphDeath,
1212 LPHANDLE lphRead )
1214 /* These are the handles for the created process */
1215 HANDLE hAppStart = 0, hAppDeath = 0, hAppRead = 0;
1216 SECURITY_ATTRIBUTES s_attrib;
1218 s_attrib.nLength = sizeof( s_attrib );
1219 s_attrib.lpSecurityDescriptor = NULL;
1220 s_attrib.bInheritHandle = TRUE;
1222 *lphStart = CreateEventW( &s_attrib, TRUE, FALSE, NULL );
1223 *lphDeath = CreateEventW( &s_attrib, TRUE, FALSE, NULL );
1224 *lphRead = CreateEventW( &s_attrib, TRUE, FALSE, NULL );
1226 if( ( !DuplicateHandle( GetCurrentProcess(), *lphStart,
1227 hDestProcess, &hAppStart,
1228 0, FALSE, DUPLICATE_SAME_ACCESS ) ) ||
1229 ( !DuplicateHandle( GetCurrentProcess(), *lphDeath,
1230 hDestProcess, &hAppDeath,
1231 0, FALSE, DUPLICATE_SAME_ACCESS ) ) ||
1232 ( !DuplicateHandle( GetCurrentProcess(), *lphRead,
1233 hDestProcess, &hAppRead,
1234 0, FALSE, DUPLICATE_SAME_ACCESS ) )
1237 if (*lphStart) { CloseHandle(*lphStart); *lphStart = 0; }
1238 if (*lphDeath) { CloseHandle(*lphDeath); *lphDeath = 0; }
1239 if (*lphRead) { CloseHandle(*lphRead); *lphRead = 0; }
1240 /* FIXME: Handle leak... */
1241 ERR( "Unable to dup handles\n" );
1242 return FALSE;
1245 if( !DPLAYX_SetLobbyHandles( dwDestProcessId,
1246 hAppStart, hAppDeath, hAppRead ) )
1248 /* FIXME: Handle leak... */
1249 return FALSE;
1252 return TRUE;
1256 /********************************************************************
1258 * Starts an application and passes to it all the information to
1259 * connect to a session.
1262 static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication( IDirectPlayLobbyA *iface, DWORD flags,
1263 DWORD *appid, DPLCONNECTION *conn, HANDLE event )
1265 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface );
1266 return IDirectPlayLobby_RunApplication( &This->IDirectPlayLobby3A_iface, flags, appid, conn,
1267 event );
1270 static HRESULT WINAPI IDirectPlayLobbyImpl_RunApplication( IDirectPlayLobby *iface, DWORD flags,
1271 DWORD *appid, DPLCONNECTION *conn, HANDLE event )
1273 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface );
1274 return IDirectPlayLobby_RunApplication( &This->IDirectPlayLobby3_iface, flags, appid, conn,
1275 event );
1278 static HRESULT WINAPI IDirectPlayLobby2AImpl_RunApplication( IDirectPlayLobby2A *iface, DWORD flags,
1279 DWORD *appid, DPLCONNECTION *conn, HANDLE event )
1281 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface );
1282 return IDirectPlayLobby_RunApplication( &This->IDirectPlayLobby3A_iface, flags, appid, conn,
1283 event );
1286 static HRESULT WINAPI IDirectPlayLobby2Impl_RunApplication( IDirectPlayLobby2 *iface, DWORD flags,
1287 DWORD *appid, DPLCONNECTION *conn, HANDLE event )
1289 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface );
1290 return IDirectPlayLobby_RunApplication( &This->IDirectPlayLobby3_iface, flags, appid, conn,
1291 event );
1294 static HRESULT WINAPI IDirectPlayLobby3AImpl_RunApplication( IDirectPlayLobby3A *iface,
1295 DWORD dwFlags, DWORD *lpdwAppID, DPLCONNECTION *lpConn, HANDLE hReceiveEvent )
1297 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface );
1298 HRESULT hr;
1299 RunApplicationEnumStruct enumData;
1300 char temp[200];
1301 STARTUPINFOA startupInfo;
1302 PROCESS_INFORMATION newProcessInfo;
1303 LPSTR appName;
1304 DWORD dwSuspendCount;
1305 HANDLE hStart, hDeath, hSettingRead;
1307 TRACE( "(%p)->(0x%08x,%p,%p,%p)\n",
1308 This, dwFlags, lpdwAppID, lpConn, hReceiveEvent );
1310 if( dwFlags != 0 )
1312 return DPERR_INVALIDPARAMS;
1315 if( DPLAYX_AnyLobbiesWaitingForConnSettings() )
1317 FIXME( "Waiting lobby not being handled correctly\n" );
1320 EnterCriticalSection( &This->lock );
1322 ZeroMemory( &enumData, sizeof( enumData ) );
1323 enumData.This = This;
1324 enumData.appGUID = lpConn->lpSessionDesc->guidApplication;
1326 /* Our callback function will fill up the enumData structure with all the information
1327 required to start a new process */
1328 IDirectPlayLobby_EnumLocalApplications( iface, RunApplicationA_EnumLocalApplications,
1329 (&enumData), 0 );
1331 /* First the application name */
1332 strcpy( temp, enumData.lpszPath );
1333 strcat( temp, "\\" );
1334 strcat( temp, enumData.lpszFileName );
1335 HeapFree( GetProcessHeap(), 0, enumData.lpszPath );
1336 HeapFree( GetProcessHeap(), 0, enumData.lpszFileName );
1337 if ((appName = HeapAlloc( GetProcessHeap(), 0, strlen(temp)+1 ))) strcpy( appName, temp );
1339 /* Now the command line */
1340 strcat( temp, " " );
1341 strcat( temp, enumData.lpszCommandLine );
1342 HeapFree( GetProcessHeap(), 0, enumData.lpszCommandLine );
1343 if ((enumData.lpszCommandLine = HeapAlloc( GetProcessHeap(), 0, strlen(temp)+1 )))
1344 strcpy( enumData.lpszCommandLine, temp );
1346 ZeroMemory( &startupInfo, sizeof( startupInfo ) );
1347 startupInfo.cb = sizeof( startupInfo );
1348 /* FIXME: Should any fields be filled in? */
1350 ZeroMemory( &newProcessInfo, sizeof( newProcessInfo ) );
1352 if( !CreateProcessA( appName,
1353 enumData.lpszCommandLine,
1354 NULL,
1355 NULL,
1356 FALSE,
1357 CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE | CREATE_SUSPENDED, /* Creation Flags */
1358 NULL,
1359 enumData.lpszCurrentDirectory,
1360 &startupInfo,
1361 &newProcessInfo
1365 ERR( "Failed to create process for app %s\n", appName );
1367 HeapFree( GetProcessHeap(), 0, appName );
1368 HeapFree( GetProcessHeap(), 0, enumData.lpszCommandLine );
1369 HeapFree( GetProcessHeap(), 0, enumData.lpszCurrentDirectory );
1371 LeaveCriticalSection( &This->lock );
1372 return DPERR_CANTCREATEPROCESS;
1375 HeapFree( GetProcessHeap(), 0, appName );
1376 HeapFree( GetProcessHeap(), 0, enumData.lpszCommandLine );
1377 HeapFree( GetProcessHeap(), 0, enumData.lpszCurrentDirectory );
1379 /* Reserve this global application id! */
1380 if( !DPLAYX_CreateLobbyApplication( newProcessInfo.dwProcessId ) )
1382 ERR( "Unable to create global application data for 0x%08x\n",
1383 newProcessInfo.dwProcessId );
1386 hr = IDirectPlayLobby_SetConnectionSettings( iface, 0, newProcessInfo.dwProcessId, lpConn );
1388 if( hr != DP_OK )
1390 ERR( "SetConnectionSettings failure %s\n", DPLAYX_HresultToString( hr ) );
1391 LeaveCriticalSection( &This->lock );
1392 return hr;
1395 /* Setup the handles for application notification */
1396 DPL_CreateAndSetLobbyHandles( newProcessInfo.dwProcessId,
1397 newProcessInfo.hProcess,
1398 &hStart, &hDeath, &hSettingRead );
1400 /* Setup the message thread ID */
1401 This->msgtid = CreateLobbyMessageReceptionThread( hReceiveEvent, hStart, hDeath, hSettingRead );
1403 DPLAYX_SetLobbyMsgThreadId( newProcessInfo.dwProcessId, This->msgtid );
1405 LeaveCriticalSection( &This->lock );
1407 /* Everything seems to have been set correctly, update the dwAppID */
1408 *lpdwAppID = newProcessInfo.dwProcessId;
1410 /* Unsuspend the process - should return the prev suspension count */
1411 if( ( dwSuspendCount = ResumeThread( newProcessInfo.hThread ) ) != 1 )
1413 ERR( "ResumeThread failed with 0x%08x\n", dwSuspendCount );
1416 return DP_OK;
1419 static HRESULT WINAPI IDirectPlayLobby3Impl_RunApplication( IDirectPlayLobby3 *iface, DWORD dwFlags,
1420 DWORD *lpdwAppID, DPLCONNECTION *lpConn, HANDLE hReceiveEvent )
1422 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface );
1423 FIXME( "(%p)->(0x%08x,%p,%p,%p):stub\n", This, dwFlags, lpdwAppID, lpConn, hReceiveEvent );
1424 return DPERR_OUTOFMEMORY;
1427 /********************************************************************
1429 * Sends a message between the application and the lobby client.
1430 * All messages are queued until received.
1433 static HRESULT WINAPI IDirectPlayLobbyAImpl_SendLobbyMessage( IDirectPlayLobbyA *iface, DWORD flags,
1434 DWORD appid, void *data, DWORD size )
1436 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface );
1437 return IDirectPlayLobby_SendLobbyMessage( &This->IDirectPlayLobby3A_iface, flags, appid, data,
1438 size );
1441 static HRESULT WINAPI IDirectPlayLobbyImpl_SendLobbyMessage( IDirectPlayLobby *iface, DWORD flags,
1442 DWORD appid, void *data, DWORD size )
1444 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface );
1445 return IDirectPlayLobby_SendLobbyMessage( &This->IDirectPlayLobby3_iface, flags, appid, data,
1446 size );
1449 static HRESULT WINAPI IDirectPlayLobby2AImpl_SendLobbyMessage( IDirectPlayLobby2A *iface,
1450 DWORD flags, DWORD appid, void *data, DWORD size )
1452 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface );
1453 return IDirectPlayLobby_SendLobbyMessage( &This->IDirectPlayLobby3A_iface, flags, appid, data,
1454 size );
1457 static HRESULT WINAPI IDirectPlayLobby2Impl_SendLobbyMessage( IDirectPlayLobby2 *iface, DWORD flags,
1458 DWORD appid, void *data, DWORD size )
1460 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface );
1461 return IDirectPlayLobby_SendLobbyMessage( &This->IDirectPlayLobby3_iface, flags, appid, data,
1462 size );
1465 static HRESULT WINAPI IDirectPlayLobby3AImpl_SendLobbyMessage( IDirectPlayLobby3A *iface,
1466 DWORD flags, DWORD appid, void *data, DWORD size )
1468 FIXME(":stub\n");
1469 return DPERR_OUTOFMEMORY;
1472 static HRESULT WINAPI IDirectPlayLobby3Impl_SendLobbyMessage( IDirectPlayLobby3 *iface,
1473 DWORD flags, DWORD appid, void *data, DWORD size )
1475 FIXME(":stub\n");
1476 return DPERR_OUTOFMEMORY;
1479 /********************************************************************
1481 * Modifies the DPLCONNECTION structure to contain all information
1482 * needed to start and connect an application.
1485 static HRESULT WINAPI IDirectPlayLobby3Impl_SetConnectionSettings( IDirectPlayLobby3 *iface,
1486 DWORD dwFlags, DWORD dwAppID, DPLCONNECTION *lpConn )
1488 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface );
1489 HRESULT hr;
1491 TRACE("(%p)->(0x%08x,0x%08x,%p)\n", This, dwFlags, dwAppID, lpConn );
1493 EnterCriticalSection( &This->lock );
1495 hr = DPLAYX_SetConnectionSettingsW( dwFlags, dwAppID, lpConn );
1497 /* FIXME: Don't think that this is supposed to fail, but the documentation
1498 is somewhat sketchy. I'll try creating a lobby application
1499 for this... */
1500 if( hr == DPERR_NOTLOBBIED )
1502 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1503 if( dwAppID == 0 )
1505 dwAppID = GetCurrentProcessId();
1507 DPLAYX_CreateLobbyApplication( dwAppID );
1508 hr = DPLAYX_SetConnectionSettingsW( dwFlags, dwAppID, lpConn );
1511 LeaveCriticalSection( &This->lock );
1513 return hr;
1516 static HRESULT WINAPI IDirectPlayLobbyAImpl_SetConnectionSettings( IDirectPlayLobbyA *iface,
1517 DWORD flags, DWORD appid, DPLCONNECTION *conn )
1519 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface );
1520 return IDirectPlayLobby_SetConnectionSettings( &This->IDirectPlayLobby3A_iface, flags,
1521 appid, conn );
1524 static HRESULT WINAPI IDirectPlayLobbyImpl_SetConnectionSettings( IDirectPlayLobby *iface,
1525 DWORD flags, DWORD appid, DPLCONNECTION *conn )
1527 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface );
1528 return IDirectPlayLobby_SetConnectionSettings( &This->IDirectPlayLobby3_iface, flags,
1529 appid, conn );
1532 static HRESULT WINAPI IDirectPlayLobby2AImpl_SetConnectionSettings( IDirectPlayLobby2A *iface,
1533 DWORD flags, DWORD appid, DPLCONNECTION *conn )
1535 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface );
1536 return IDirectPlayLobby_SetConnectionSettings( &This->IDirectPlayLobby3A_iface, flags,
1537 appid, conn );
1540 static HRESULT WINAPI IDirectPlayLobby2Impl_SetConnectionSettings( IDirectPlayLobby2 *iface,
1541 DWORD flags, DWORD appid, DPLCONNECTION *conn )
1543 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface );
1544 return IDirectPlayLobby_SetConnectionSettings( &This->IDirectPlayLobby3_iface, flags,
1545 appid, conn );
1548 static HRESULT WINAPI IDirectPlayLobby3AImpl_SetConnectionSettings( IDirectPlayLobby3A *iface,
1549 DWORD dwFlags, DWORD dwAppID, DPLCONNECTION *lpConn )
1551 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface );
1552 HRESULT hr;
1554 TRACE("(%p)->(0x%08x,0x%08x,%p)\n", This, dwFlags, dwAppID, lpConn );
1556 EnterCriticalSection( &This->lock );
1558 hr = DPLAYX_SetConnectionSettingsA( dwFlags, dwAppID, lpConn );
1560 /* FIXME: Don't think that this is supposed to fail, but the documentation
1561 is somewhat sketchy. I'll try creating a lobby application
1562 for this... */
1563 if( hr == DPERR_NOTLOBBIED )
1565 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
1566 dwAppID = GetCurrentProcessId();
1567 DPLAYX_CreateLobbyApplication( dwAppID );
1568 hr = DPLAYX_SetConnectionSettingsA( dwFlags, dwAppID, lpConn );
1571 LeaveCriticalSection( &This->lock );
1573 return hr;
1576 /********************************************************************
1578 * Registers an event that will be set when a lobby message is received.
1581 static HRESULT WINAPI IDirectPlayLobbyAImpl_SetLobbyMessageEvent( IDirectPlayLobbyA *iface,
1582 DWORD flags, DWORD appid, HANDLE event )
1584 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface );
1585 return IDirectPlayLobby_SetLobbyMessageEvent( &This->IDirectPlayLobby3A_iface, flags, appid,
1586 event );
1589 static HRESULT WINAPI IDirectPlayLobbyImpl_SetLobbyMessageEvent( IDirectPlayLobby *iface,
1590 DWORD flags, DWORD appid, HANDLE event )
1592 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface );
1593 return IDirectPlayLobby_SetLobbyMessageEvent( &This->IDirectPlayLobby3_iface, flags, appid,
1594 event );
1597 static HRESULT WINAPI IDirectPlayLobby2AImpl_SetLobbyMessageEvent( IDirectPlayLobby2A *iface,
1598 DWORD flags, DWORD appid, HANDLE event )
1600 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface );
1601 return IDirectPlayLobby_SetLobbyMessageEvent( &This->IDirectPlayLobby3A_iface, flags, appid,
1602 event );
1605 static HRESULT WINAPI IDirectPlayLobby2Impl_SetLobbyMessageEvent( IDirectPlayLobby2 *iface,
1606 DWORD flags, DWORD appid, HANDLE event )
1608 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface );
1609 return IDirectPlayLobby_SetLobbyMessageEvent( &This->IDirectPlayLobby3_iface, flags, appid,
1610 event );
1613 static HRESULT WINAPI IDirectPlayLobby3AImpl_SetLobbyMessageEvent( IDirectPlayLobby3A *iface,
1614 DWORD flags, DWORD appid, HANDLE event )
1616 FIXME(":stub\n");
1617 return DPERR_OUTOFMEMORY;
1620 static HRESULT WINAPI IDirectPlayLobby3Impl_SetLobbyMessageEvent( IDirectPlayLobby3 *iface,
1621 DWORD flags, DWORD appid, HANDLE event )
1623 FIXME(":stub\n");
1624 return DPERR_OUTOFMEMORY;
1628 /* DPL 2 methods */
1629 static HRESULT WINAPI IDirectPlayLobby2AImpl_CreateCompoundAddress( IDirectPlayLobby2A *iface,
1630 const DPCOMPOUNDADDRESSELEMENT *elements, DWORD count, void *address, DWORD *size )
1632 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface );
1633 return IDirectPlayLobby_CreateCompoundAddress( &This->IDirectPlayLobby3A_iface, elements,
1634 count, address, size );
1637 static HRESULT WINAPI IDirectPlayLobby2Impl_CreateCompoundAddress( IDirectPlayLobby2 *iface,
1638 const DPCOMPOUNDADDRESSELEMENT *elements, DWORD count, void *address, DWORD *size )
1640 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface );
1641 return IDirectPlayLobby_CreateCompoundAddress( &This->IDirectPlayLobby3_iface, elements,
1642 count, address, size );
1645 static HRESULT WINAPI IDirectPlayLobby3Impl_CreateCompoundAddress( IDirectPlayLobby3 *iface,
1646 const DPCOMPOUNDADDRESSELEMENT *lpElements, DWORD dwElementCount, void *lpAddress,
1647 DWORD *lpdwAddressSize )
1649 return DPL_CreateCompoundAddress( lpElements, dwElementCount, lpAddress, lpdwAddressSize, FALSE );
1652 static HRESULT WINAPI IDirectPlayLobby3AImpl_CreateCompoundAddress( IDirectPlayLobby3A *iface,
1653 const DPCOMPOUNDADDRESSELEMENT *lpElements, DWORD dwElementCount, void *lpAddress,
1654 DWORD *lpdwAddressSize )
1656 return DPL_CreateCompoundAddress( lpElements, dwElementCount, lpAddress, lpdwAddressSize, TRUE );
1659 HRESULT DPL_CreateCompoundAddress
1660 ( LPCDPCOMPOUNDADDRESSELEMENT lpElements,
1661 DWORD dwElementCount,
1662 LPVOID lpAddress,
1663 LPDWORD lpdwAddressSize,
1664 BOOL bAnsiInterface )
1666 DWORD dwSizeRequired = 0;
1667 DWORD dwElements;
1668 LPCDPCOMPOUNDADDRESSELEMENT lpOrigElements = lpElements;
1670 TRACE("(%p,0x%08x,%p,%p)\n", lpElements, dwElementCount, lpAddress, lpdwAddressSize );
1672 /* Parameter check */
1673 if( ( lpElements == NULL ) ||
1674 ( dwElementCount == 0 ) /* FIXME: Not sure if this is a failure case */
1677 return DPERR_INVALIDPARAMS;
1680 /* Add the total size chunk */
1681 dwSizeRequired += sizeof( DPADDRESS ) + sizeof( DWORD );
1683 /* Calculate the size of the buffer required */
1684 for ( dwElements = dwElementCount; dwElements > 0; --dwElements, ++lpElements )
1686 if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_ServiceProvider ) ) ||
1687 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_LobbyProvider ) )
1690 dwSizeRequired += sizeof( DPADDRESS ) + sizeof( GUID );
1692 else if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_Phone ) ) ||
1693 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_Modem ) ) ||
1694 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_INet ) )
1697 if( !bAnsiInterface )
1699 ERR( "Ansi GUIDs used for unicode interface\n" );
1700 return DPERR_INVALIDFLAGS;
1703 dwSizeRequired += sizeof( DPADDRESS ) + lpElements->dwDataSize;
1705 else if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_PhoneW ) ) ||
1706 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_ModemW ) ) ||
1707 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_INetW ) )
1710 if( bAnsiInterface )
1712 ERR( "Unicode GUIDs used for ansi interface\n" );
1713 return DPERR_INVALIDFLAGS;
1716 FIXME( "Right size for unicode interface?\n" );
1717 dwSizeRequired += sizeof( DPADDRESS ) + lpElements->dwDataSize * sizeof( WCHAR );
1719 else if ( IsEqualGUID( &lpElements->guidDataType, &DPAID_INetPort ) )
1721 dwSizeRequired += sizeof( DPADDRESS ) + sizeof( WORD );
1723 else if ( IsEqualGUID( &lpElements->guidDataType, &DPAID_ComPort ) )
1725 FIXME( "Right size for unicode interface?\n" );
1726 dwSizeRequired += sizeof( DPADDRESS ) + sizeof( DPCOMPORTADDRESS ); /* FIXME: Right size? */
1728 else
1730 WARN( "Skipping Unknown GUID %s\n", debugstr_guid(&lpElements->guidDataType) );
1734 /* The user wants to know how big a buffer to allocate for us */
1735 if( ( lpAddress == NULL ) ||
1736 ( *lpdwAddressSize < dwSizeRequired )
1739 *lpdwAddressSize = dwSizeRequired;
1740 return DPERR_BUFFERTOOSMALL;
1743 /* Add the total size chunk */
1745 LPDPADDRESS lpdpAddress = lpAddress;
1747 lpdpAddress->guidDataType = DPAID_TotalSize;
1748 lpdpAddress->dwDataSize = sizeof( DWORD );
1749 lpAddress = (char *) lpAddress + sizeof( DPADDRESS );
1751 *(LPDWORD)lpAddress = dwSizeRequired;
1752 lpAddress = (char *) lpAddress + sizeof( DWORD );
1755 /* Calculate the size of the buffer required */
1756 for( dwElements = dwElementCount, lpElements = lpOrigElements;
1757 dwElements > 0;
1758 --dwElements, ++lpElements )
1760 if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_ServiceProvider ) ) ||
1761 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_LobbyProvider ) )
1764 LPDPADDRESS lpdpAddress = lpAddress;
1766 lpdpAddress->guidDataType = lpElements->guidDataType;
1767 lpdpAddress->dwDataSize = sizeof( GUID );
1768 lpAddress = (char *) lpAddress + sizeof( DPADDRESS );
1770 CopyMemory( lpAddress, lpElements->lpData, sizeof( GUID ) );
1771 lpAddress = (char *) lpAddress + sizeof( GUID );
1773 else if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_Phone ) ) ||
1774 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_Modem ) ) ||
1775 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_INet ) )
1778 LPDPADDRESS lpdpAddress = lpAddress;
1780 lpdpAddress->guidDataType = lpElements->guidDataType;
1781 lpdpAddress->dwDataSize = lpElements->dwDataSize;
1782 lpAddress = (char *) lpAddress + sizeof( DPADDRESS );
1784 lstrcpynA( lpAddress, lpElements->lpData, lpElements->dwDataSize );
1785 lpAddress = (char *) lpAddress + lpElements->dwDataSize;
1787 else if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_PhoneW ) ) ||
1788 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_ModemW ) ) ||
1789 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_INetW ) )
1792 LPDPADDRESS lpdpAddress = lpAddress;
1794 lpdpAddress->guidDataType = lpElements->guidDataType;
1795 lpdpAddress->dwDataSize = lpElements->dwDataSize;
1796 lpAddress = (char *) lpAddress + sizeof( DPADDRESS );
1798 lstrcpynW( lpAddress, lpElements->lpData, lpElements->dwDataSize );
1799 lpAddress = (char *) lpAddress + lpElements->dwDataSize * sizeof( WCHAR );
1801 else if ( IsEqualGUID( &lpElements->guidDataType, &DPAID_INetPort ) )
1803 LPDPADDRESS lpdpAddress = lpAddress;
1805 lpdpAddress->guidDataType = lpElements->guidDataType;
1806 lpdpAddress->dwDataSize = lpElements->dwDataSize;
1807 lpAddress = (char *) lpAddress + sizeof( DPADDRESS );
1809 *((LPWORD)lpAddress) = *((LPWORD)lpElements->lpData);
1810 lpAddress = (char *) lpAddress + sizeof( WORD );
1812 else if ( IsEqualGUID( &lpElements->guidDataType, &DPAID_ComPort ) )
1814 LPDPADDRESS lpdpAddress = lpAddress;
1816 lpdpAddress->guidDataType = lpElements->guidDataType;
1817 lpdpAddress->dwDataSize = lpElements->dwDataSize;
1818 lpAddress = (char *) lpAddress + sizeof( DPADDRESS );
1820 CopyMemory( lpAddress, lpElements->lpData, sizeof( DPADDRESS ) );
1821 lpAddress = (char *) lpAddress + sizeof( DPADDRESS );
1825 return DP_OK;
1828 /* DPL 3 methods */
1830 static HRESULT WINAPI IDirectPlayLobby3Impl_ConnectEx( IDirectPlayLobby3 *iface, DWORD dwFlags,
1831 REFIID riid, LPVOID* lplpDP, IUnknown* pUnk )
1833 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface );
1834 return DPL_ConnectEx( This, dwFlags, riid, lplpDP, pUnk );
1837 static HRESULT WINAPI IDirectPlayLobby3AImpl_ConnectEx( IDirectPlayLobby3A *iface, DWORD dwFlags,
1838 REFIID riid, void **lplpDP, IUnknown *pUnk )
1840 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface );
1841 return DPL_ConnectEx( This, dwFlags, riid, lplpDP, pUnk );
1844 static HRESULT WINAPI IDirectPlayLobby3Impl_RegisterApplication( IDirectPlayLobby3 *iface,
1845 DWORD flags, DPAPPLICATIONDESC *appdesc )
1847 FIXME(":stub\n");
1848 return DP_OK;
1851 static HRESULT WINAPI IDirectPlayLobby3AImpl_RegisterApplication( IDirectPlayLobby3A *iface,
1852 DWORD flags, DPAPPLICATIONDESC *appdesc )
1854 FIXME(":stub\n");
1855 return DP_OK;
1858 static HRESULT WINAPI IDirectPlayLobby3Impl_UnregisterApplication( IDirectPlayLobby3 *iface,
1859 DWORD flags, REFGUID appdesc )
1861 FIXME(":stub\n");
1862 return DP_OK;
1865 static HRESULT WINAPI IDirectPlayLobby3AImpl_UnregisterApplication( IDirectPlayLobby3A *iface,
1866 DWORD flags, REFGUID appdesc )
1868 FIXME(":stub\n");
1869 return DP_OK;
1872 static HRESULT WINAPI IDirectPlayLobby3Impl_WaitForConnectionSettings( IDirectPlayLobby3 *iface,
1873 DWORD dwFlags )
1875 HRESULT hr = DP_OK;
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;
1886 return hr;
1889 static HRESULT WINAPI IDirectPlayLobby3AImpl_WaitForConnectionSettings( IDirectPlayLobby3A *iface,
1890 DWORD dwFlags )
1892 HRESULT hr = DP_OK;
1893 BOOL bStartWait = !(dwFlags & DPLWAIT_CANCEL);
1895 TRACE( "(%p)->(0x%08x)\n", iface, dwFlags );
1897 if( DPLAYX_WaitForConnectionSettings( bStartWait ) )
1899 /* FIXME: What is the correct error return code? */
1900 hr = DPERR_NOTLOBBIED;
1903 return hr;
1906 static const IDirectPlayLobbyVtbl dplA_vt =
1908 IDirectPlayLobbyAImpl_QueryInterface,
1909 IDirectPlayLobbyAImpl_AddRef,
1910 IDirectPlayLobbyAImpl_Release,
1911 IDirectPlayLobbyAImpl_Connect,
1912 IDirectPlayLobbyAImpl_CreateAddress,
1913 IDirectPlayLobbyAImpl_EnumAddress,
1914 IDirectPlayLobbyAImpl_EnumAddressTypes,
1915 IDirectPlayLobbyAImpl_EnumLocalApplications,
1916 IDirectPlayLobbyAImpl_GetConnectionSettings,
1917 IDirectPlayLobbyAImpl_ReceiveLobbyMessage,
1918 IDirectPlayLobbyAImpl_RunApplication,
1919 IDirectPlayLobbyAImpl_SendLobbyMessage,
1920 IDirectPlayLobbyAImpl_SetConnectionSettings,
1921 IDirectPlayLobbyAImpl_SetLobbyMessageEvent
1924 static const IDirectPlayLobbyVtbl dpl_vt =
1926 IDirectPlayLobbyImpl_QueryInterface,
1927 IDirectPlayLobbyImpl_AddRef,
1928 IDirectPlayLobbyImpl_Release,
1929 IDirectPlayLobbyImpl_Connect,
1930 IDirectPlayLobbyImpl_CreateAddress,
1931 IDirectPlayLobbyImpl_EnumAddress,
1932 IDirectPlayLobbyImpl_EnumAddressTypes,
1933 IDirectPlayLobbyImpl_EnumLocalApplications,
1934 IDirectPlayLobbyImpl_GetConnectionSettings,
1935 IDirectPlayLobbyImpl_ReceiveLobbyMessage,
1936 IDirectPlayLobbyImpl_RunApplication,
1937 IDirectPlayLobbyImpl_SendLobbyMessage,
1938 IDirectPlayLobbyImpl_SetConnectionSettings,
1939 IDirectPlayLobbyImpl_SetLobbyMessageEvent
1942 static const IDirectPlayLobby2Vtbl dpl2A_vt =
1944 IDirectPlayLobby2AImpl_QueryInterface,
1945 IDirectPlayLobby2AImpl_AddRef,
1946 IDirectPlayLobby2AImpl_Release,
1947 IDirectPlayLobby2AImpl_Connect,
1948 IDirectPlayLobby2AImpl_CreateAddress,
1949 IDirectPlayLobby2AImpl_EnumAddress,
1950 IDirectPlayLobby2AImpl_EnumAddressTypes,
1951 IDirectPlayLobby2AImpl_EnumLocalApplications,
1952 IDirectPlayLobby2AImpl_GetConnectionSettings,
1953 IDirectPlayLobby2AImpl_ReceiveLobbyMessage,
1954 IDirectPlayLobby2AImpl_RunApplication,
1955 IDirectPlayLobby2AImpl_SendLobbyMessage,
1956 IDirectPlayLobby2AImpl_SetConnectionSettings,
1957 IDirectPlayLobby2AImpl_SetLobbyMessageEvent,
1958 IDirectPlayLobby2AImpl_CreateCompoundAddress
1961 static const IDirectPlayLobby2Vtbl dpl2_vt =
1963 IDirectPlayLobby2Impl_QueryInterface,
1964 IDirectPlayLobby2Impl_AddRef,
1965 IDirectPlayLobby2Impl_Release,
1966 IDirectPlayLobby2Impl_Connect,
1967 IDirectPlayLobby2Impl_CreateAddress,
1968 IDirectPlayLobby2Impl_EnumAddress,
1969 IDirectPlayLobby2Impl_EnumAddressTypes,
1970 IDirectPlayLobby2Impl_EnumLocalApplications,
1971 IDirectPlayLobby2Impl_GetConnectionSettings,
1972 IDirectPlayLobby2Impl_ReceiveLobbyMessage,
1973 IDirectPlayLobby2Impl_RunApplication,
1974 IDirectPlayLobby2Impl_SendLobbyMessage,
1975 IDirectPlayLobby2Impl_SetConnectionSettings,
1976 IDirectPlayLobby2Impl_SetLobbyMessageEvent,
1977 IDirectPlayLobby2Impl_CreateCompoundAddress
1980 static const IDirectPlayLobby3Vtbl dpl3A_vt =
1982 IDirectPlayLobby3AImpl_QueryInterface,
1983 IDirectPlayLobby3AImpl_AddRef,
1984 IDirectPlayLobby3AImpl_Release,
1985 IDirectPlayLobby3AImpl_Connect,
1986 IDirectPlayLobby3AImpl_CreateAddress,
1987 IDirectPlayLobby3AImpl_EnumAddress,
1988 IDirectPlayLobby3AImpl_EnumAddressTypes,
1989 IDirectPlayLobby3AImpl_EnumLocalApplications,
1990 IDirectPlayLobby3AImpl_GetConnectionSettings,
1991 IDirectPlayLobby3AImpl_ReceiveLobbyMessage,
1992 IDirectPlayLobby3AImpl_RunApplication,
1993 IDirectPlayLobby3AImpl_SendLobbyMessage,
1994 IDirectPlayLobby3AImpl_SetConnectionSettings,
1995 IDirectPlayLobby3AImpl_SetLobbyMessageEvent,
1996 IDirectPlayLobby3AImpl_CreateCompoundAddress,
1997 IDirectPlayLobby3AImpl_ConnectEx,
1998 IDirectPlayLobby3AImpl_RegisterApplication,
1999 IDirectPlayLobby3AImpl_UnregisterApplication,
2000 IDirectPlayLobby3AImpl_WaitForConnectionSettings
2003 static const IDirectPlayLobby3Vtbl dpl3_vt =
2005 IDirectPlayLobby3Impl_QueryInterface,
2006 IDirectPlayLobby3Impl_AddRef,
2007 IDirectPlayLobby3Impl_Release,
2008 IDirectPlayLobby3Impl_Connect,
2009 IDirectPlayLobby3Impl_CreateAddress,
2010 IDirectPlayLobby3Impl_EnumAddress,
2011 IDirectPlayLobby3Impl_EnumAddressTypes,
2012 IDirectPlayLobby3Impl_EnumLocalApplications,
2013 IDirectPlayLobby3Impl_GetConnectionSettings,
2014 IDirectPlayLobby3Impl_ReceiveLobbyMessage,
2015 IDirectPlayLobby3Impl_RunApplication,
2016 IDirectPlayLobby3Impl_SendLobbyMessage,
2017 IDirectPlayLobby3Impl_SetConnectionSettings,
2018 IDirectPlayLobby3Impl_SetLobbyMessageEvent,
2019 IDirectPlayLobby3Impl_CreateCompoundAddress,
2020 IDirectPlayLobby3Impl_ConnectEx,
2021 IDirectPlayLobby3Impl_RegisterApplication,
2022 IDirectPlayLobby3Impl_UnregisterApplication,
2023 IDirectPlayLobby3Impl_WaitForConnectionSettings
2026 HRESULT dplobby_create( REFIID riid, void **ppv )
2028 IDirectPlayLobbyImpl *obj;
2029 HRESULT hr;
2031 TRACE( "(%s, %p)\n", debugstr_guid( riid ), ppv );
2033 *ppv = NULL;
2034 obj = HeapAlloc( GetProcessHeap(), 0, sizeof( *obj ) );
2035 if ( !obj )
2036 return DPERR_OUTOFMEMORY;
2038 obj->IDirectPlayLobby_iface.lpVtbl = &dpl_vt;
2039 obj->IDirectPlayLobbyA_iface.lpVtbl = &dplA_vt;
2040 obj->IDirectPlayLobby2_iface.lpVtbl = &dpl2_vt;
2041 obj->IDirectPlayLobby2A_iface.lpVtbl = &dpl2A_vt;
2042 obj->IDirectPlayLobby3_iface.lpVtbl = &dpl3_vt;
2043 obj->IDirectPlayLobby3A_iface.lpVtbl = &dpl3A_vt;
2044 obj->numIfaces = 1;
2045 obj->msgtid = 0;
2046 obj->ref = 0;
2047 obj->refA = 0;
2048 obj->ref2 = 0;
2049 obj->ref2A = 0;
2050 obj->ref3 = 1;
2051 obj->ref3A = 0;
2053 InitializeCriticalSection( &obj->lock );
2054 obj->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectPlayLobbyImpl.lock");
2055 DPQ_INIT( obj->msgs );
2057 hr = IDirectPlayLobby_QueryInterface( &obj->IDirectPlayLobby3_iface, riid, ppv );
2058 IDirectPlayLobby_Release( &obj->IDirectPlayLobby3_iface );
2060 return hr;
2065 /***************************************************************************
2066 * DirectPlayLobbyCreateA (DPLAYX.4)
2069 HRESULT WINAPI DirectPlayLobbyCreateA( GUID *lpGUIDDSP, IDirectPlayLobbyA **lplpDPL,
2070 IUnknown *lpUnk, void *lpData, DWORD dwDataSize )
2072 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08x\n",
2073 lpGUIDDSP,lplpDPL,lpUnk,lpData,dwDataSize);
2075 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
2076 * equal 0. These fields are mostly for future expansion.
2078 if ( lpGUIDDSP || lpData || dwDataSize )
2080 *lplpDPL = NULL;
2081 return DPERR_INVALIDPARAMS;
2084 if( lpUnk )
2086 *lplpDPL = NULL;
2087 ERR("Bad parameters!\n" );
2088 return CLASS_E_NOAGGREGATION;
2091 return dplobby_create( &IID_IDirectPlayLobbyA, (void**)lplpDPL );
2094 /***************************************************************************
2095 * DirectPlayLobbyCreateW (DPLAYX.5)
2098 HRESULT WINAPI DirectPlayLobbyCreateW( GUID *lpGUIDDSP, IDirectPlayLobby **lplpDPL,
2099 IUnknown *lpUnk, void *lpData, DWORD dwDataSize )
2101 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08x\n",
2102 lpGUIDDSP,lplpDPL,lpUnk,lpData,dwDataSize);
2104 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
2105 * equal 0. These fields are mostly for future expansion.
2107 if ( lpGUIDDSP || lpData || dwDataSize )
2109 *lplpDPL = NULL;
2110 ERR("Bad parameters!\n" );
2111 return DPERR_INVALIDPARAMS;
2114 if( lpUnk )
2116 *lplpDPL = NULL;
2117 ERR("Bad parameters!\n" );
2118 return CLASS_E_NOAGGREGATION;
2121 return dplobby_create( &IID_IDirectPlayLobby, (void**)lplpDPL );