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