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 IDPLobbySPVtbl *lpVtbl;
62 /* Forward declaration of virtual tables */
63 static IDPLobbySPVtbl 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 IDPLobbySPImpl *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 IDPLobbySPImpl *This = (IDPLobbySPImpl *)lpSP;
115 This->unk = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( *(This->unk) ) );
117 if ( This->unk == NULL )
122 InitializeCriticalSection( &This->unk->DPLSP_lock );
127 static BOOL DPLSP_DestroyIUnknown( LPVOID lpSP )
129 IDPLobbySPImpl *This = (IDPLobbySPImpl *)lpSP;
131 DeleteCriticalSection( &This->unk->DPLSP_lock );
132 HeapFree( GetProcessHeap(), 0, This->unk );
137 static BOOL DPLSP_CreateDPLobbySP( LPVOID lpSP, IDirectPlay2Impl* dp )
139 IDPLobbySPImpl *This = (IDPLobbySPImpl *)lpSP;
141 This->sp = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( *(This->sp) ) );
143 if ( This->sp == NULL )
148 This->sp->dplay = dp;
150 /* Normally we should be keeping a reference, but since only the dplay
151 * interface that created us can destroy us, we do not keep a reference
152 * to it (ie we'd be stuck with always having one reference to the dplay
153 * object, and hence us, around).
154 * NOTE: The dp object does reference count us.
156 * FIXME: This is a kludge to get around a problem where a queryinterface
157 * is used to get a new interface and then is closed. We will then
158 * reference garbage. However, with this we will never deallocate
159 * the interface we store. The correct fix is to require all
160 * DP internal interfaces to use the This->dp2 interface which
161 * should be changed to This->dp
163 IDirectPlayX_AddRef( (LPDIRECTPLAY2)dp );
169 static BOOL DPLSP_DestroyDPLobbySP( LPVOID lpSP )
171 IDPLobbySPImpl *This = (IDPLobbySPImpl *)lpSP;
173 HeapFree( GetProcessHeap(), 0, This->sp );
179 HRESULT WINAPI DPLSP_QueryInterface
185 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
186 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
188 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
191 if( *ppvObj == NULL )
193 return DPERR_OUTOFMEMORY;
196 CopyMemory( *ppvObj, This, sizeof( *This ) );
197 (*(IDPLobbySPImpl**)ppvObj)->ulInterfaceRef = 0;
199 if( IsEqualGUID( &IID_IDPLobbySP, riid ) )
201 IDPLobbySPImpl *This = (IDPLobbySPImpl *)*ppvObj;
202 This->lpVtbl = &dpLobbySPVT;
206 /* Unsupported interface */
207 HeapFree( GetProcessHeap(), 0, *ppvObj );
210 return E_NOINTERFACE;
213 IDPLobbySP_AddRef( (LPDPLOBBYSP)*ppvObj );
219 ULONG WINAPI DPLSP_AddRef
220 ( LPDPLOBBYSP iface )
222 ULONG ulInterfaceRefCount, ulObjRefCount;
223 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
225 ulObjRefCount = InterlockedIncrement( &This->unk->ulObjRef );
226 ulInterfaceRefCount = InterlockedIncrement( &This->ulInterfaceRef );
228 TRACE( "ref count incremented to %lu:%lu for %p\n",
229 ulInterfaceRefCount, ulObjRefCount, This );
231 return ulObjRefCount;
235 ULONG WINAPI DPLSP_Release
236 ( LPDPLOBBYSP iface )
238 ULONG ulInterfaceRefCount, ulObjRefCount;
239 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
241 ulObjRefCount = InterlockedDecrement( &This->unk->ulObjRef );
242 ulInterfaceRefCount = InterlockedDecrement( &This->ulInterfaceRef );
244 TRACE( "ref count decremented to %lu:%lu for %p\n",
245 ulInterfaceRefCount, ulObjRefCount, This );
247 /* Deallocate if this is the last reference to the object */
248 if( ulObjRefCount == 0 )
250 DPLSP_DestroyDPLobbySP( This );
251 DPLSP_DestroyIUnknown( This );
254 if( ulInterfaceRefCount == 0 )
256 HeapFree( GetProcessHeap(), 0, This );
259 return ulInterfaceRefCount;
263 HRESULT WINAPI IDPLobbySPImpl_AddGroupToGroup
265 LPSPDATA_ADDREMOTEGROUPTOGROUP argtg
268 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
269 FIXME( "(%p)->(%p):stub\n", This, argtg );
274 HRESULT WINAPI IDPLobbySPImpl_AddPlayerToGroup
276 LPSPDATA_ADDREMOTEPLAYERTOGROUP arptg
279 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
280 FIXME( "(%p)->(%p):stub\n", This, arptg );
285 HRESULT WINAPI IDPLobbySPImpl_CreateGroup
287 LPSPDATA_CREATEREMOTEGROUP crg
290 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
291 FIXME( "(%p)->(%p):stub\n", This, crg );
296 HRESULT WINAPI IDPLobbySPImpl_CreateGroupInGroup
298 LPSPDATA_CREATEREMOTEGROUPINGROUP crgig
301 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
302 FIXME( "(%p)->(%p):stub\n", This, crgig );
307 HRESULT WINAPI IDPLobbySPImpl_DeleteGroupFromGroup
309 LPSPDATA_DELETEREMOTEGROUPFROMGROUP drgfg
312 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
313 FIXME( "(%p)->(%p):stub\n", This, drgfg );
318 HRESULT WINAPI IDPLobbySPImpl_DeletePlayerFromGroup
320 LPSPDATA_DELETEREMOTEPLAYERFROMGROUP drpfg
323 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
324 FIXME( "(%p)->(%p):stub\n", This, drpfg );
329 HRESULT WINAPI IDPLobbySPImpl_DestroyGroup
331 LPSPDATA_DESTROYREMOTEGROUP drg
334 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
335 FIXME( "(%p)->(%p):stub\n", This, drg );
340 HRESULT WINAPI IDPLobbySPImpl_EnumSessionsResponse
342 LPSPDATA_ENUMSESSIONSRESPONSE er
345 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
346 FIXME( "(%p)->(%p):stub\n", This, er );
351 HRESULT WINAPI IDPLobbySPImpl_GetSPDataPointer
356 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
357 FIXME( "(%p)->(%p):stub\n", This, lplpData );
362 HRESULT WINAPI IDPLobbySPImpl_HandleMessage
364 LPSPDATA_HANDLEMESSAGE hm
367 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
368 FIXME( "(%p)->(%p):stub\n", This, hm );
373 HRESULT WINAPI IDPLobbySPImpl_SendChatMessage
375 LPSPDATA_CHATMESSAGE cm
378 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
379 FIXME( "(%p)->(%p):stub\n", This, cm );
384 HRESULT WINAPI IDPLobbySPImpl_SetGroupName
386 LPSPDATA_SETREMOTEGROUPNAME srgn
389 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
390 FIXME( "(%p)->(%p):stub\n", This, srgn );
395 HRESULT WINAPI IDPLobbySPImpl_SetPlayerName
397 LPSPDATA_SETREMOTEPLAYERNAME srpn
400 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
401 FIXME( "(%p)->(%p):stub\n", This, srpn );
406 HRESULT WINAPI IDPLobbySPImpl_SetSessionDesc
408 LPSPDATA_SETSESSIONDESC ssd
411 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
412 FIXME( "(%p)->(%p):stub\n", This, ssd );
417 HRESULT WINAPI IDPLobbySPImpl_SetSPDataPointer
422 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
423 FIXME( "(%p)->(%p):stub\n", This, lpData );
428 HRESULT WINAPI IDPLobbySPImpl_StartSession
430 LPSPDATA_STARTSESSIONCOMMAND ssc
433 IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
434 FIXME( "(%p)->(%p):stub\n", This, ssc );
439 static struct IDPLobbySPVtbl dpLobbySPVT =
442 DPLSP_QueryInterface,
446 IDPLobbySPImpl_AddGroupToGroup,
447 IDPLobbySPImpl_AddPlayerToGroup,
448 IDPLobbySPImpl_CreateGroup,
449 IDPLobbySPImpl_CreateGroupInGroup,
450 IDPLobbySPImpl_DeleteGroupFromGroup,
451 IDPLobbySPImpl_DeletePlayerFromGroup,
452 IDPLobbySPImpl_DestroyGroup,
453 IDPLobbySPImpl_EnumSessionsResponse,
454 IDPLobbySPImpl_GetSPDataPointer,
455 IDPLobbySPImpl_HandleMessage,
456 IDPLobbySPImpl_SendChatMessage,
457 IDPLobbySPImpl_SetGroupName,
458 IDPLobbySPImpl_SetPlayerName,
459 IDPLobbySPImpl_SetSessionDesc,
460 IDPLobbySPImpl_SetSPDataPointer,
461 IDPLobbySPImpl_StartSession