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