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
= (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 IDPLobbySPImpl
*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 IDPLobbySPImpl
*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 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)lpSP
;
177 HeapFree( GetProcessHeap(), 0, This
->sp
);
183 HRESULT WINAPI DPLSP_QueryInterface
189 IDPLobbySPImpl
*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 IDPLobbySPImpl
*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 IDPLobbySPImpl
*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 IDPLobbySPImpl
*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 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)iface
;
273 FIXME( "(%p)->(%p):stub\n", This
, argtg
);
278 HRESULT WINAPI IDPLobbySPImpl_AddPlayerToGroup
280 LPSPDATA_ADDREMOTEPLAYERTOGROUP arptg
283 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)iface
;
284 FIXME( "(%p)->(%p):stub\n", This
, arptg
);
289 HRESULT WINAPI IDPLobbySPImpl_CreateGroup
291 LPSPDATA_CREATEREMOTEGROUP crg
294 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)iface
;
295 FIXME( "(%p)->(%p):stub\n", This
, crg
);
300 HRESULT WINAPI IDPLobbySPImpl_CreateGroupInGroup
302 LPSPDATA_CREATEREMOTEGROUPINGROUP crgig
305 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)iface
;
306 FIXME( "(%p)->(%p):stub\n", This
, crgig
);
311 HRESULT WINAPI IDPLobbySPImpl_DeleteGroupFromGroup
313 LPSPDATA_DELETEREMOTEGROUPFROMGROUP drgfg
316 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)iface
;
317 FIXME( "(%p)->(%p):stub\n", This
, drgfg
);
322 HRESULT WINAPI IDPLobbySPImpl_DeletePlayerFromGroup
324 LPSPDATA_DELETEREMOTEPLAYERFROMGROUP drpfg
327 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)iface
;
328 FIXME( "(%p)->(%p):stub\n", This
, drpfg
);
333 HRESULT WINAPI IDPLobbySPImpl_DestroyGroup
335 LPSPDATA_DESTROYREMOTEGROUP drg
338 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)iface
;
339 FIXME( "(%p)->(%p):stub\n", This
, drg
);
344 HRESULT WINAPI IDPLobbySPImpl_EnumSessionsResponse
346 LPSPDATA_ENUMSESSIONSRESPONSE er
349 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)iface
;
350 FIXME( "(%p)->(%p):stub\n", This
, er
);
355 HRESULT WINAPI IDPLobbySPImpl_GetSPDataPointer
360 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)iface
;
361 FIXME( "(%p)->(%p):stub\n", This
, lplpData
);
366 HRESULT WINAPI IDPLobbySPImpl_HandleMessage
368 LPSPDATA_HANDLEMESSAGE hm
371 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)iface
;
372 FIXME( "(%p)->(%p):stub\n", This
, hm
);
377 HRESULT WINAPI IDPLobbySPImpl_SendChatMessage
379 LPSPDATA_CHATMESSAGE cm
382 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)iface
;
383 FIXME( "(%p)->(%p):stub\n", This
, cm
);
388 HRESULT WINAPI IDPLobbySPImpl_SetGroupName
390 LPSPDATA_SETREMOTEGROUPNAME srgn
393 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)iface
;
394 FIXME( "(%p)->(%p):stub\n", This
, srgn
);
399 HRESULT WINAPI IDPLobbySPImpl_SetPlayerName
401 LPSPDATA_SETREMOTEPLAYERNAME srpn
404 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)iface
;
405 FIXME( "(%p)->(%p):stub\n", This
, srpn
);
410 HRESULT WINAPI IDPLobbySPImpl_SetSessionDesc
412 LPSPDATA_SETSESSIONDESC ssd
415 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)iface
;
416 FIXME( "(%p)->(%p):stub\n", This
, ssd
);
421 HRESULT WINAPI IDPLobbySPImpl_SetSPDataPointer
426 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)iface
;
427 FIXME( "(%p)->(%p):stub\n", This
, lpData
);
432 HRESULT WINAPI IDPLobbySPImpl_StartSession
434 LPSPDATA_STARTSESSIONCOMMAND ssc
437 IDPLobbySPImpl
*This
= (IDPLobbySPImpl
*)iface
;
438 FIXME( "(%p)->(%p):stub\n", This
, ssc
);
443 static struct IDPLobbySPVtbl dpLobbySPVT
=
446 DPLSP_QueryInterface
,
450 IDPLobbySPImpl_AddGroupToGroup
,
451 IDPLobbySPImpl_AddPlayerToGroup
,
452 IDPLobbySPImpl_CreateGroup
,
453 IDPLobbySPImpl_CreateGroupInGroup
,
454 IDPLobbySPImpl_DeleteGroupFromGroup
,
455 IDPLobbySPImpl_DeletePlayerFromGroup
,
456 IDPLobbySPImpl_DestroyGroup
,
457 IDPLobbySPImpl_EnumSessionsResponse
,
458 IDPLobbySPImpl_GetSPDataPointer
,
459 IDPLobbySPImpl_HandleMessage
,
460 IDPLobbySPImpl_SendChatMessage
,
461 IDPLobbySPImpl_SetGroupName
,
462 IDPLobbySPImpl_SetPlayerName
,
463 IDPLobbySPImpl_SetSessionDesc
,
464 IDPLobbySPImpl_SetSPDataPointer
,
465 IDPLobbySPImpl_StartSession