ieframe: Added GoForward implementation.
[wine] / dlls / dplayx / lobbysp.c
1 /* This contains the implementation of the Lobby Service
2  * Providers interface required to communicate with Direct Play
3  *
4  * Copyright 2001 Peter Hunnisett
5  *
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.
10  *
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.
15  *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "winerror.h"
22 #include "wine/debug.h"
23
24 #include "lobbysp.h"
25 #include "dplay_global.h"
26 #include "dpinit.h"
27
28 WINE_DEFAULT_DEBUG_CHANNEL(dplay);
29
30 /* Prototypes */
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 );
35
36
37 /* Predefine the interface */
38 typedef struct IDPLobbySPImpl IDPLobbySPImpl;
39
40 typedef struct tagDPLobbySPIUnknownData
41 {
42   LONG              ulObjRef;
43   CRITICAL_SECTION  DPLSP_lock;
44 } DPLobbySPIUnknownData;
45
46 typedef struct tagDPLobbySPData
47 {
48   IDirectPlay2Impl* dplay;
49 } DPLobbySPData;
50
51 #define DPLSP_IMPL_FIELDS \
52    LONG ulInterfaceRef; \
53    DPLobbySPIUnknownData* unk; \
54    DPLobbySPData* sp;
55
56 struct IDPLobbySPImpl
57 {
58   const IDPLobbySPVtbl *lpVtbl;
59   DPLSP_IMPL_FIELDS
60 };
61
62 /* Forward declaration of virtual tables */
63 static const IDPLobbySPVtbl dpLobbySPVT;
64
65 HRESULT DPLSP_CreateInterface( REFIID riid, LPVOID* ppvObj, IDirectPlay2Impl* dp )
66 {
67   TRACE( " for %s\n", debugstr_guid( riid ) );
68
69   *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
70                        sizeof( IDPLobbySPImpl ) );
71
72   if( *ppvObj == NULL )
73   {
74     return DPERR_OUTOFMEMORY;
75   }
76
77   if( IsEqualGUID( &IID_IDPLobbySP, riid ) )
78   {
79     IDPLobbySPImpl *This = *ppvObj;
80     This->lpVtbl = &dpLobbySPVT;
81   }
82   else
83   {
84     /* Unsupported interface */
85     HeapFree( GetProcessHeap(), 0, *ppvObj );
86     *ppvObj = NULL;
87
88     return E_NOINTERFACE;
89   }
90
91   /* Initialize it */
92   if( DPLSP_CreateIUnknown( *ppvObj ) &&
93       DPLSP_CreateDPLobbySP( *ppvObj, dp )
94     )
95   {
96     IDPLobbySP_AddRef( (LPDPLOBBYSP)*ppvObj );
97     return S_OK;
98   }
99
100   /* Initialize failed, destroy it */
101   DPLSP_DestroyDPLobbySP( *ppvObj );
102   DPLSP_DestroyIUnknown( *ppvObj );
103
104   HeapFree( GetProcessHeap(), 0, *ppvObj );
105   *ppvObj = NULL;
106
107   return DPERR_NOMEMORY;
108 }
109
110 static BOOL DPLSP_CreateIUnknown( LPVOID lpSP )
111 {
112   IDPLobbySPImpl *This = lpSP;
113
114   This->unk = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( *(This->unk) ) );
115
116   if ( This->unk == NULL )
117   {
118     return FALSE;
119   }
120
121   InitializeCriticalSection( &This->unk->DPLSP_lock );
122   This->unk->DPLSP_lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDPLobbySPImpl*->DPLobbySPIUnknownData*->DPLSP_lock");
123
124   return TRUE;
125 }
126
127 static BOOL DPLSP_DestroyIUnknown( LPVOID lpSP )
128 {
129   IDPLobbySPImpl *This = lpSP;
130
131   This->unk->DPLSP_lock.DebugInfo->Spare[0] = 0;
132   DeleteCriticalSection( &This->unk->DPLSP_lock );
133   HeapFree( GetProcessHeap(), 0, This->unk );
134
135   return TRUE;
136 }
137
138 static BOOL DPLSP_CreateDPLobbySP( LPVOID lpSP, IDirectPlay2Impl* dp )
139 {
140   IDPLobbySPImpl *This = lpSP;
141
142   This->sp = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( *(This->sp) ) );
143
144   if ( This->sp == NULL )
145   {
146     return FALSE;
147   }
148
149   This->sp->dplay = dp;
150
151   return TRUE;
152 }
153
154 static BOOL DPLSP_DestroyDPLobbySP( LPVOID lpSP )
155 {
156   IDPLobbySPImpl *This = lpSP;
157
158   HeapFree( GetProcessHeap(), 0, This->sp );
159
160   return TRUE;
161 }
162
163 static
164 HRESULT WINAPI DPLSP_QueryInterface
165 ( LPDPLOBBYSP iface,
166   REFIID riid,
167   LPVOID* ppvObj
168 )
169 {
170   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
171   TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
172
173   *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
174                        sizeof( *This ) );
175
176   if( *ppvObj == NULL )
177   {
178     return DPERR_OUTOFMEMORY;
179   }
180
181   CopyMemory( *ppvObj, This, sizeof( *This )  );
182   (*(IDPLobbySPImpl**)ppvObj)->ulInterfaceRef = 0;
183
184   if( IsEqualGUID( &IID_IDPLobbySP, riid ) )
185   {
186     IDPLobbySPImpl *This = *ppvObj;
187     This->lpVtbl = &dpLobbySPVT;
188   }
189   else
190   {
191     /* Unsupported interface */
192     HeapFree( GetProcessHeap(), 0, *ppvObj );
193     *ppvObj = NULL;
194
195     return E_NOINTERFACE;
196   }
197
198   IDPLobbySP_AddRef( (LPDPLOBBYSP)*ppvObj );
199
200   return S_OK;
201 }
202
203 static
204 ULONG WINAPI DPLSP_AddRef
205 ( LPDPLOBBYSP iface )
206 {
207   ULONG ulInterfaceRefCount, ulObjRefCount;
208   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
209
210   ulObjRefCount       = InterlockedIncrement( &This->unk->ulObjRef );
211   ulInterfaceRefCount = InterlockedIncrement( &This->ulInterfaceRef );
212
213   TRACE( "ref count incremented to %u:%u for %p\n",
214          ulInterfaceRefCount, ulObjRefCount, This );
215
216   return ulObjRefCount;
217 }
218
219 static
220 ULONG WINAPI DPLSP_Release
221 ( LPDPLOBBYSP iface )
222 {
223   ULONG ulInterfaceRefCount, ulObjRefCount;
224   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
225
226   ulObjRefCount       = InterlockedDecrement( &This->unk->ulObjRef );
227   ulInterfaceRefCount = InterlockedDecrement( &This->ulInterfaceRef );
228
229   TRACE( "ref count decremented to %u:%u for %p\n",
230          ulInterfaceRefCount, ulObjRefCount, This );
231
232   /* Deallocate if this is the last reference to the object */
233   if( ulObjRefCount == 0 )
234   {
235      DPLSP_DestroyDPLobbySP( This );
236      DPLSP_DestroyIUnknown( This );
237   }
238
239   if( ulInterfaceRefCount == 0 )
240   {
241     HeapFree( GetProcessHeap(), 0, This );
242   }
243
244   return ulInterfaceRefCount;
245 }
246
247 static
248 HRESULT WINAPI IDPLobbySPImpl_AddGroupToGroup
249 ( LPDPLOBBYSP iface,
250   LPSPDATA_ADDREMOTEGROUPTOGROUP argtg
251 )
252 {
253   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
254   FIXME( "(%p)->(%p):stub\n", This, argtg );
255   return DP_OK;
256 }
257
258 static
259 HRESULT WINAPI IDPLobbySPImpl_AddPlayerToGroup
260 ( LPDPLOBBYSP iface,
261   LPSPDATA_ADDREMOTEPLAYERTOGROUP arptg
262 )
263 {
264   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
265   FIXME( "(%p)->(%p):stub\n", This, arptg );
266   return DP_OK;
267 }
268
269 static
270 HRESULT WINAPI IDPLobbySPImpl_CreateGroup
271 ( LPDPLOBBYSP iface,
272   LPSPDATA_CREATEREMOTEGROUP crg
273 )
274 {
275   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
276   FIXME( "(%p)->(%p):stub\n", This, crg );
277   return DP_OK;
278 }
279
280 static
281 HRESULT WINAPI IDPLobbySPImpl_CreateGroupInGroup
282 ( LPDPLOBBYSP iface,
283   LPSPDATA_CREATEREMOTEGROUPINGROUP crgig
284 )
285 {
286   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
287   FIXME( "(%p)->(%p):stub\n", This, crgig );
288   return DP_OK;
289 }
290
291 static
292 HRESULT WINAPI IDPLobbySPImpl_DeleteGroupFromGroup
293 ( LPDPLOBBYSP iface,
294   LPSPDATA_DELETEREMOTEGROUPFROMGROUP drgfg
295 )
296 {
297   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
298   FIXME( "(%p)->(%p):stub\n", This, drgfg );
299   return DP_OK;
300 }
301
302 static
303 HRESULT WINAPI IDPLobbySPImpl_DeletePlayerFromGroup
304 ( LPDPLOBBYSP iface,
305   LPSPDATA_DELETEREMOTEPLAYERFROMGROUP drpfg
306 )
307 {
308   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
309   FIXME( "(%p)->(%p):stub\n", This, drpfg );
310   return DP_OK;
311 }
312
313 static
314 HRESULT WINAPI IDPLobbySPImpl_DestroyGroup
315 ( LPDPLOBBYSP iface,
316   LPSPDATA_DESTROYREMOTEGROUP drg
317 )
318 {
319   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
320   FIXME( "(%p)->(%p):stub\n", This, drg );
321   return DP_OK;
322 }
323
324 static
325 HRESULT WINAPI IDPLobbySPImpl_EnumSessionsResponse
326 ( LPDPLOBBYSP iface,
327   LPSPDATA_ENUMSESSIONSRESPONSE er
328 )
329 {
330   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
331   FIXME( "(%p)->(%p):stub\n", This, er );
332   return DP_OK;
333 }
334
335 static
336 HRESULT WINAPI IDPLobbySPImpl_GetSPDataPointer
337 ( LPDPLOBBYSP iface,
338   LPVOID* lplpData
339 )
340 {
341   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
342   FIXME( "(%p)->(%p):stub\n", This, lplpData );
343   return DP_OK;
344 }
345
346 static
347 HRESULT WINAPI IDPLobbySPImpl_HandleMessage
348 ( LPDPLOBBYSP iface,
349   LPSPDATA_HANDLEMESSAGE hm
350 )
351 {
352   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
353   FIXME( "(%p)->(%p):stub\n", This, hm );
354   return DP_OK;
355 }
356
357 static
358 HRESULT WINAPI IDPLobbySPImpl_SendChatMessage
359 ( LPDPLOBBYSP iface,
360   LPSPDATA_CHATMESSAGE cm
361 )
362 {
363   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
364   FIXME( "(%p)->(%p):stub\n", This, cm );
365   return DP_OK;
366 }
367
368 static
369 HRESULT WINAPI IDPLobbySPImpl_SetGroupName
370 ( LPDPLOBBYSP iface,
371   LPSPDATA_SETREMOTEGROUPNAME srgn
372 )
373 {
374   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
375   FIXME( "(%p)->(%p):stub\n", This, srgn );
376   return DP_OK;
377 }
378
379 static
380 HRESULT WINAPI IDPLobbySPImpl_SetPlayerName
381 ( LPDPLOBBYSP iface,
382   LPSPDATA_SETREMOTEPLAYERNAME srpn
383 )
384 {
385   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
386   FIXME( "(%p)->(%p):stub\n", This, srpn );
387   return DP_OK;
388 }
389
390 static
391 HRESULT WINAPI IDPLobbySPImpl_SetSessionDesc
392 ( LPDPLOBBYSP iface,
393   LPSPDATA_SETSESSIONDESC ssd
394 )
395 {
396   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
397   FIXME( "(%p)->(%p):stub\n", This, ssd );
398   return DP_OK;
399 }
400
401 static
402 HRESULT WINAPI IDPLobbySPImpl_SetSPDataPointer
403 ( LPDPLOBBYSP iface,
404   LPVOID lpData
405 )
406 {
407   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
408   FIXME( "(%p)->(%p):stub\n", This, lpData );
409   return DP_OK;
410 }
411
412 static
413 HRESULT WINAPI IDPLobbySPImpl_StartSession
414 ( LPDPLOBBYSP iface,
415   LPSPDATA_STARTSESSIONCOMMAND ssc
416 )
417 {
418   IDPLobbySPImpl *This = (IDPLobbySPImpl *)iface;
419   FIXME( "(%p)->(%p):stub\n", This, ssc );
420   return DP_OK;
421 }
422
423
424 static const IDPLobbySPVtbl dpLobbySPVT =
425 {
426
427   DPLSP_QueryInterface,
428   DPLSP_AddRef,
429   DPLSP_Release,
430
431   IDPLobbySPImpl_AddGroupToGroup,
432   IDPLobbySPImpl_AddPlayerToGroup,
433   IDPLobbySPImpl_CreateGroup,
434   IDPLobbySPImpl_CreateGroupInGroup,
435   IDPLobbySPImpl_DeleteGroupFromGroup,
436   IDPLobbySPImpl_DeletePlayerFromGroup,
437   IDPLobbySPImpl_DestroyGroup,
438   IDPLobbySPImpl_EnumSessionsResponse,
439   IDPLobbySPImpl_GetSPDataPointer,
440   IDPLobbySPImpl_HandleMessage,
441   IDPLobbySPImpl_SendChatMessage,
442   IDPLobbySPImpl_SetGroupName,
443   IDPLobbySPImpl_SetPlayerName,
444   IDPLobbySPImpl_SetSessionDesc,
445   IDPLobbySPImpl_SetSPDataPointer,
446   IDPLobbySPImpl_StartSession
447
448 };