1 /* This contains the implementation of the Lobby Service
2 * Providers interface required to communicate with Direct Play
4 * Copyright 2001 Peter Hunnisett
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "wine/debug.h"
25 #include "dplay_global.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(dplay);
31 static BOOL DPLSP_CreateIUnknown( LPVOID lpSP );
32 static BOOL DPLSP_DestroyIUnknown( LPVOID lpSP );
33 static BOOL DPLSP_CreateDPLobbySP( LPVOID lpSP, IDirectPlay2Impl* dp );
34 static BOOL DPLSP_DestroyDPLobbySP( LPVOID lpSP );
37 /* Predefine the interface */
38 typedef struct IDPLobbySPImpl IDPLobbySPImpl;
40 typedef struct tagDPLobbySPIUnknownData
43 CRITICAL_SECTION DPLSP_lock;
44 } DPLobbySPIUnknownData;
46 typedef struct tagDPLobbySPData
48 IDirectPlay2Impl* dplay;
51 #define DPLSP_IMPL_FIELDS \
52 ULONG ulInterfaceRef; \
53 DPLobbySPIUnknownData* unk; \
58 ICOM_VFIELD(IDPLobbySP);
62 /* Forward declaration of virtual tables */
63 static ICOM_VTABLE(IDPLobbySP) dpLobbySPVT;
66 HRESULT DPLSP_CreateInterface( REFIID riid, LPVOID* ppvObj, IDirectPlay2Impl* dp )
68 TRACE( " for %s\n", debugstr_guid( riid ) );
70 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
71 sizeof( IDPLobbySPImpl ) );
75 return DPERR_OUTOFMEMORY;
78 if( IsEqualGUID( &IID_IDPLobbySP, riid ) )
80 ICOM_THIS(IDPLobbySPImpl,*ppvObj);
81 This->lpVtbl = &dpLobbySPVT;
85 /* Unsupported interface */
86 HeapFree( GetProcessHeap(), 0, *ppvObj );
93 if( DPLSP_CreateIUnknown( *ppvObj ) &&
94 DPLSP_CreateDPLobbySP( *ppvObj, dp )
97 IDPLobbySP_AddRef( (LPDPLOBBYSP)*ppvObj );
101 /* Initialize failed, destroy it */
102 DPLSP_DestroyDPLobbySP( *ppvObj );
103 DPLSP_DestroyIUnknown( *ppvObj );
105 HeapFree( GetProcessHeap(), 0, *ppvObj );
108 return DPERR_NOMEMORY;
111 static BOOL DPLSP_CreateIUnknown( LPVOID lpSP )
113 ICOM_THIS(IDPLobbySPImpl,lpSP);
115 This->unk = (DPLobbySPIUnknownData*)HeapAlloc( GetProcessHeap(),
117 sizeof( *(This->unk) ) );
119 if ( This->unk == NULL )
124 InitializeCriticalSection( &This->unk->DPLSP_lock );
129 static BOOL DPLSP_DestroyIUnknown( LPVOID lpSP )
131 ICOM_THIS(IDPLobbySPImpl,lpSP);
133 DeleteCriticalSection( &This->unk->DPLSP_lock );
134 HeapFree( GetProcessHeap(), 0, This->unk );
139 static BOOL DPLSP_CreateDPLobbySP( LPVOID lpSP, IDirectPlay2Impl* dp )
141 ICOM_THIS(IDPLobbySPImpl,lpSP);
143 This->sp = (DPLobbySPData*)HeapAlloc( GetProcessHeap(),
145 sizeof( *(This->sp) ) );
147 if ( This->sp == NULL )
152 This->sp->dplay = dp;
154 /* Normally we should be keeping a reference, but since only the dplay
155 * interface that created us can destroy us, we do not keep a reference
156 * to it (ie we'd be stuck with always having one reference to the dplay
157 * object, and hence us, around).
158 * NOTE: The dp object does reference count us.
160 * FIXME: This is a kludge to get around a problem where a queryinterface
161 * is used to get a new interface and then is closed. We will then
162 * reference garbage. However, with this we will never deallocate
163 * the interface we store. The correct fix is to require all
164 * DP internal interfaces to use the This->dp2 interface which
165 * should be changed to This->dp
167 IDirectPlayX_AddRef( (LPDIRECTPLAY2)dp );
173 static BOOL DPLSP_DestroyDPLobbySP( LPVOID lpSP )
175 ICOM_THIS(IDPLobbySPImpl,lpSP);
177 HeapFree( GetProcessHeap(), 0, This->sp );
183 HRESULT WINAPI DPLSP_QueryInterface
189 ICOM_THIS(IDPLobbySPImpl,iface);
190 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
192 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
195 if( *ppvObj == NULL )
197 return DPERR_OUTOFMEMORY;
200 CopyMemory( *ppvObj, This, sizeof( *This ) );
201 (*(IDPLobbySPImpl**)ppvObj)->ulInterfaceRef = 0;
203 if( IsEqualGUID( &IID_IDPLobbySP, riid ) )
205 ICOM_THIS(IDPLobbySPImpl,*ppvObj);
206 This->lpVtbl = &dpLobbySPVT;
210 /* Unsupported interface */
211 HeapFree( GetProcessHeap(), 0, *ppvObj );
214 return E_NOINTERFACE;
217 IDPLobbySP_AddRef( (LPDPLOBBYSP)*ppvObj );
223 ULONG WINAPI DPLSP_AddRef
224 ( LPDPLOBBYSP iface )
226 ULONG ulInterfaceRefCount, ulObjRefCount;
227 ICOM_THIS(IDPLobbySPImpl,iface);
229 ulObjRefCount = InterlockedIncrement( &This->unk->ulObjRef );
230 ulInterfaceRefCount = InterlockedIncrement( &This->ulInterfaceRef );
232 TRACE( "ref count incremented to %lu:%lu for %p\n",
233 ulInterfaceRefCount, ulObjRefCount, This );
235 return ulObjRefCount;
239 ULONG WINAPI DPLSP_Release
240 ( LPDPLOBBYSP iface )
242 ULONG ulInterfaceRefCount, ulObjRefCount;
243 ICOM_THIS(IDPLobbySPImpl,iface);
245 ulObjRefCount = InterlockedDecrement( &This->unk->ulObjRef );
246 ulInterfaceRefCount = InterlockedDecrement( &This->ulInterfaceRef );
248 TRACE( "ref count decremented to %lu:%lu for %p\n",
249 ulInterfaceRefCount, ulObjRefCount, This );
251 /* Deallocate if this is the last reference to the object */
252 if( ulObjRefCount == 0 )
254 DPLSP_DestroyDPLobbySP( This );
255 DPLSP_DestroyIUnknown( This );
258 if( ulInterfaceRefCount == 0 )
260 HeapFree( GetProcessHeap(), 0, This );
263 return ulInterfaceRefCount;
267 HRESULT WINAPI IDPLobbySPImpl_AddGroupToGroup
269 LPSPDATA_ADDREMOTEGROUPTOGROUP argtg
272 ICOM_THIS(IDPLobbySPImpl,iface);
273 FIXME( "(%p)->(%p):stub\n", This, argtg );
278 HRESULT WINAPI IDPLobbySPImpl_AddPlayerToGroup
280 LPSPDATA_ADDREMOTEPLAYERTOGROUP arptg
283 ICOM_THIS(IDPLobbySPImpl,iface);
284 FIXME( "(%p)->(%p):stub\n", This, arptg );
289 HRESULT WINAPI IDPLobbySPImpl_CreateGroup
291 LPSPDATA_CREATEREMOTEGROUP crg
294 ICOM_THIS(IDPLobbySPImpl,iface);
295 FIXME( "(%p)->(%p):stub\n", This, crg );
300 HRESULT WINAPI IDPLobbySPImpl_CreateGroupInGroup
302 LPSPDATA_CREATEREMOTEGROUPINGROUP crgig
305 ICOM_THIS(IDPLobbySPImpl,iface);
306 FIXME( "(%p)->(%p):stub\n", This, crgig );
311 HRESULT WINAPI IDPLobbySPImpl_DeleteGroupFromGroup
313 LPSPDATA_DELETEREMOTEGROUPFROMGROUP drgfg
316 ICOM_THIS(IDPLobbySPImpl,iface);
317 FIXME( "(%p)->(%p):stub\n", This, drgfg );
322 HRESULT WINAPI IDPLobbySPImpl_DeletePlayerFromGroup
324 LPSPDATA_DELETEREMOTEPLAYERFROMGROUP drpfg
327 ICOM_THIS(IDPLobbySPImpl,iface);
328 FIXME( "(%p)->(%p):stub\n", This, drpfg );
333 HRESULT WINAPI IDPLobbySPImpl_DestroyGroup
335 LPSPDATA_DESTROYREMOTEGROUP drg
338 ICOM_THIS(IDPLobbySPImpl,iface);
339 FIXME( "(%p)->(%p):stub\n", This, drg );
344 HRESULT WINAPI IDPLobbySPImpl_EnumSessionsResponse
346 LPSPDATA_ENUMSESSIONSRESPONSE er
349 ICOM_THIS(IDPLobbySPImpl,iface);
350 FIXME( "(%p)->(%p):stub\n", This, er );
355 HRESULT WINAPI IDPLobbySPImpl_GetSPDataPointer
360 ICOM_THIS(IDPLobbySPImpl,iface);
361 FIXME( "(%p)->(%p):stub\n", This, lplpData );
366 HRESULT WINAPI IDPLobbySPImpl_HandleMessage
368 LPSPDATA_HANDLEMESSAGE hm
371 ICOM_THIS(IDPLobbySPImpl,iface);
372 FIXME( "(%p)->(%p):stub\n", This, hm );
377 HRESULT WINAPI IDPLobbySPImpl_SendChatMessage
379 LPSPDATA_CHATMESSAGE cm
382 ICOM_THIS(IDPLobbySPImpl,iface);
383 FIXME( "(%p)->(%p):stub\n", This, cm );
388 HRESULT WINAPI IDPLobbySPImpl_SetGroupName
390 LPSPDATA_SETREMOTEGROUPNAME srgn
393 ICOM_THIS(IDPLobbySPImpl,iface);
394 FIXME( "(%p)->(%p):stub\n", This, srgn );
399 HRESULT WINAPI IDPLobbySPImpl_SetPlayerName
401 LPSPDATA_SETREMOTEPLAYERNAME srpn
404 ICOM_THIS(IDPLobbySPImpl,iface);
405 FIXME( "(%p)->(%p):stub\n", This, srpn );
410 HRESULT WINAPI IDPLobbySPImpl_SetSessionDesc
412 LPSPDATA_SETSESSIONDESC ssd
415 ICOM_THIS(IDPLobbySPImpl,iface);
416 FIXME( "(%p)->(%p):stub\n", This, ssd );
421 HRESULT WINAPI IDPLobbySPImpl_SetSPDataPointer
426 ICOM_THIS(IDPLobbySPImpl,iface);
427 FIXME( "(%p)->(%p):stub\n", This, lpData );
432 HRESULT WINAPI IDPLobbySPImpl_StartSession
434 LPSPDATA_STARTSESSIONCOMMAND ssc
437 ICOM_THIS(IDPLobbySPImpl,iface);
438 FIXME( "(%p)->(%p):stub\n", This, ssc );
443 static struct ICOM_VTABLE(IDPLobbySP) dpLobbySPVT =
445 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
447 DPLSP_QueryInterface,
451 IDPLobbySPImpl_AddGroupToGroup,
452 IDPLobbySPImpl_AddPlayerToGroup,
453 IDPLobbySPImpl_CreateGroup,
454 IDPLobbySPImpl_CreateGroupInGroup,
455 IDPLobbySPImpl_DeleteGroupFromGroup,
456 IDPLobbySPImpl_DeletePlayerFromGroup,
457 IDPLobbySPImpl_DestroyGroup,
458 IDPLobbySPImpl_EnumSessionsResponse,
459 IDPLobbySPImpl_GetSPDataPointer,
460 IDPLobbySPImpl_HandleMessage,
461 IDPLobbySPImpl_SendChatMessage,
462 IDPLobbySPImpl_SetGroupName,
463 IDPLobbySPImpl_SetPlayerName,
464 IDPLobbySPImpl_SetSessionDesc,
465 IDPLobbySPImpl_SetSPDataPointer,
466 IDPLobbySPImpl_StartSession