No longer directly accessing debuggee memory.
[wine] / dlls / dplayx / dplay.c
1 /* Direct Play 2,3,4 Implementation
2  *
3  * Copyright 1998,1999 - Peter Hunnisett
4  *
5  * <presently under construction - contact hunnise@nortelnetworks.com>
6  *
7  */
8 #include <string.h>
9
10 #include "winerror.h"
11 #include "winnt.h"
12 #include "winreg.h"
13 #include "dplay.h"
14 #include "heap.h"
15 #include "debugtools.h"
16
17 #include "dpinit.h"
18 #include "dplayx_global.h"
19
20 /* FIXME: This stuff shouldn't really be here. It indicates a poor architectural coupling */
21 #include "dplobby.h"
22 extern HRESULT DPL_CreateCompoundAddress ( LPCDPCOMPOUNDADDRESSELEMENT lpElements, DWORD dwElementCount,
23                                            LPVOID lpAddress, LPDWORD lpdwAddressSize, BOOL bAnsiInterface );
24
25 DEFAULT_DEBUG_CHANNEL(dplay)
26
27
28 /*****************************************************************************
29  * Predeclare the interface implementation structures
30  */
31 typedef struct IDirectPlay2Impl IDirectPlay2AImpl;
32 typedef struct IDirectPlay2Impl IDirectPlay2Impl;
33 typedef struct IDirectPlay3Impl IDirectPlay3AImpl;
34 typedef struct IDirectPlay3Impl IDirectPlay3Impl;
35 typedef struct IDirectPlay4Impl IDirectPlay4AImpl;
36 typedef struct IDirectPlay4Impl IDirectPlay4Impl;
37
38 /*****************************************************************************
39  * IDirectPlay implementation structure
40  *
41  * The philosophy behind this extra pointer derefernce is that I wanted to
42  * have the same structure for all types of objects without having to do
43  * alot of casting. I also only wanted to implement an interface in the
44  * object it was "released" with IUnknown interface being implemented in the 1 version.
45  * Of course, with these new interfaces comes the data required to keep the state required
46  * by these interfaces. So, basically, the pointers contain the data associated with
47  * a release. If you use the data associated with release 3 in a release 2 object, you'll
48  * get a run time trap, as that won't have any data.
49  * 
50  */
51 typedef struct tagDirectPlayIUnknownData
52 {
53   DWORD             ref;
54   CRITICAL_SECTION  DP_lock;
55 } DirectPlayIUnknownData;
56
57 /* Contains all dp1 and dp2 data members */
58 typedef struct tagDirectPlay2Data
59 {
60   BOOL dummy;
61 } DirectPlay2Data;
62
63 typedef struct tagDirectPlay3Data
64 {
65   BOOL connectionInitialized;
66 } DirectPlay3Data;
67
68 typedef struct tagDirectPlay4Data
69 {
70   BOOL dummy;
71 } DirectPlay4Data;
72
73 #define DP_IMPL_FIELDS \
74   DirectPlayIUnknownData*  unk; \
75   DirectPlay2Data*         dp2; \
76   DirectPlay3Data*         dp3; \
77   DirectPlay4Data*         dp4;
78
79 struct IDirectPlay2Impl
80 {
81   ICOM_VFIELD(IDirectPlay2); 
82   DP_IMPL_FIELDS
83 };
84
85 struct IDirectPlay3Impl
86 {
87   ICOM_VFIELD(IDirectPlay3);
88   DP_IMPL_FIELDS
89 };
90
91 struct IDirectPlay4Impl
92 {
93   ICOM_VFIELD(IDirectPlay4);
94   DP_IMPL_FIELDS
95 };
96
97 /* Forward declarations of virtual tables */
98 static ICOM_VTABLE(IDirectPlay2) directPlay2AVT;
99 static ICOM_VTABLE(IDirectPlay3) directPlay3AVT;
100 static ICOM_VTABLE(IDirectPlay4) directPlay4AVT;
101
102 static ICOM_VTABLE(IDirectPlay2) directPlay2WVT;
103 static ICOM_VTABLE(IDirectPlay3) directPlay3WVT;
104 static ICOM_VTABLE(IDirectPlay4) directPlay4WVT;
105
106 BOOL DP_CreateIUnknown( LPVOID lpDP )
107 {
108   ICOM_THIS(IDirectPlay2AImpl,lpDP);
109
110   This->unk = (DirectPlayIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
111                                                   sizeof( *(This->unk) ) );
112   if ( This->unk == NULL )
113   {
114     return FALSE;
115   }
116
117   InitializeCriticalSection( &This->unk->DP_lock );
118
119   IDirectPlay_AddRef( (LPDIRECTPLAY2A)lpDP );
120
121   return TRUE;
122 }
123
124 BOOL DP_DestroyIUnknown( LPVOID lpDP )
125 {
126   ICOM_THIS(IDirectPlay2AImpl,lpDP);
127
128   DeleteCriticalSection( &This->unk->DP_lock );
129   HeapFree( GetProcessHeap(), 0, This->unk );
130
131   return TRUE;
132 }
133
134 BOOL DP_CreateDirectPlay2( LPVOID lpDP )
135 {
136   ICOM_THIS(IDirectPlay2AImpl,lpDP);
137
138   This->dp2 = (DirectPlay2Data*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
139                                            sizeof( *(This->dp2) ) );
140   if ( This->dp2 == NULL )
141   {
142     return FALSE;
143   }
144
145   return TRUE;
146 }
147
148 BOOL DP_DestroyDirectPlay2( LPVOID lpDP )
149 {
150   ICOM_THIS(IDirectPlay2AImpl,lpDP);
151
152   /* Delete the contents */
153   HeapFree( GetProcessHeap(), 0, This->dp2 );
154
155   return TRUE;
156 }
157
158 BOOL DP_CreateDirectPlay3( LPVOID lpDP )
159 {
160   ICOM_THIS(IDirectPlay3AImpl,lpDP);
161
162   This->dp3 = (DirectPlay3Data*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
163                                            sizeof( *(This->dp3) ) );
164   if ( This->dp3 == NULL )
165   {
166     return FALSE;
167   }
168
169   This->dp3->connectionInitialized = FALSE;
170
171   return TRUE;
172 }
173
174 BOOL DP_DestroyDirectPlay3( LPVOID lpDP )
175 {
176   ICOM_THIS(IDirectPlay3AImpl,lpDP);
177
178   /* Delete the contents */
179   HeapFree( GetProcessHeap(), 0, This->dp3 );
180
181   return TRUE;
182 }
183
184 BOOL DP_CreateDirectPlay4( LPVOID lpDP )
185 {
186   ICOM_THIS(IDirectPlay4AImpl,lpDP);
187
188   This->dp4 = (DirectPlay4Data*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
189                                            sizeof( *(This->dp4) ) );
190   if ( This->dp4 == NULL )
191   {
192     return FALSE;
193   }
194
195   return TRUE;
196 }
197
198 BOOL DP_DestroyDirectPlay4( LPVOID lpDP )
199 {
200   ICOM_THIS(IDirectPlay3AImpl,lpDP);
201
202   /* Delete the contents */
203   HeapFree( GetProcessHeap(), 0, This->dp4 );
204
205   return TRUE;
206 }
207
208
209 /* Get a new interface. To be used by QueryInterface. */ 
210 extern 
211 HRESULT directPlay_QueryInterface 
212          ( REFIID riid, LPVOID* ppvObj )
213 {
214
215   if( IsEqualGUID( &IID_IDirectPlay2, riid ) )
216   {
217     *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
218                          sizeof( IDirectPlay2Impl ) );
219
220     if( *ppvObj == NULL )
221     {
222        return DPERR_OUTOFMEMORY;
223     }
224
225     /* new scope for variable declaration */
226     {
227       ICOM_THIS(IDirectPlay2Impl,*ppvObj);
228
229       ICOM_VTBL(This) = &directPlay2WVT;
230
231       if ( DP_CreateIUnknown( (LPVOID)This ) &&
232            DP_CreateDirectPlay2( (LPVOID)This )
233          )
234       {
235         return S_OK;
236       }
237
238     }
239
240     goto error; 
241   } 
242   else if( IsEqualGUID( &IID_IDirectPlay2A, riid ) )
243   {
244     *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
245                          sizeof( IDirectPlay2AImpl ) );
246
247     if( *ppvObj == NULL )
248     {
249        return DPERR_OUTOFMEMORY;
250     }
251
252     /* new scope for variable declaration */
253     {
254       ICOM_THIS(IDirectPlay2AImpl,*ppvObj);
255
256       ICOM_VTBL(This) = &directPlay2AVT;
257
258       if ( DP_CreateIUnknown( (LPVOID)This ) &&
259            DP_CreateDirectPlay2( (LPVOID)This )
260          )
261       {
262         return S_OK;
263       }
264
265     }
266
267     goto error;
268   }
269   else if( IsEqualGUID( &IID_IDirectPlay3, riid ) )
270   {
271     *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
272                          sizeof( IDirectPlay3Impl ) );
273
274     if( *ppvObj == NULL )
275     {
276        return DPERR_OUTOFMEMORY;
277     }
278
279     /* new scope for variable declaration */
280     {
281       ICOM_THIS(IDirectPlay3Impl,*ppvObj);
282
283       ICOM_VTBL(This) = &directPlay3WVT;
284
285       if ( DP_CreateIUnknown( (LPVOID)This ) &&
286            DP_CreateDirectPlay2( (LPVOID)This ) &&
287            DP_CreateDirectPlay3( (LPVOID)This )
288          )
289       {
290         return S_OK;
291       }
292
293     }
294
295     goto error;
296   }
297   else if( IsEqualGUID( &IID_IDirectPlay3A, riid ) )
298   {
299     *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
300                          sizeof( IDirectPlay3AImpl ) );
301
302     if( *ppvObj == NULL )
303     {
304        return DPERR_OUTOFMEMORY;
305     }
306
307     /* new scope for variable declaration */
308     {
309       ICOM_THIS(IDirectPlay3AImpl,*ppvObj);
310
311       ICOM_VTBL(This) = &directPlay3AVT;
312
313       if ( DP_CreateIUnknown( (LPVOID)This ) &&
314            DP_CreateDirectPlay2( (LPVOID)This ) &&
315            DP_CreateDirectPlay3( (LPVOID)This )
316          )
317       {
318         return S_OK;
319       }
320
321     }
322
323     goto error;
324   }
325   else if( IsEqualGUID( &IID_IDirectPlay4, riid ) )
326   {
327     *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
328                          sizeof( IDirectPlay4Impl ) );
329
330     if( *ppvObj == NULL )
331     {
332        return DPERR_OUTOFMEMORY;
333     }
334
335     /* new scope for variable declaration */
336     {
337       ICOM_THIS(IDirectPlay4Impl,*ppvObj);
338
339       ICOM_VTBL(This) = &directPlay4WVT;
340
341       if ( DP_CreateIUnknown( (LPVOID)This ) &&
342            DP_CreateDirectPlay2( (LPVOID)This ) &&
343            DP_CreateDirectPlay3( (LPVOID)This ) &&
344            DP_CreateDirectPlay4( (LPVOID)This )
345          )
346       {
347         return S_OK;
348       }
349
350     }
351
352     goto error;
353   }
354   else if( IsEqualGUID( &IID_IDirectPlay4A, riid ) )
355   {
356     *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
357                          sizeof( IDirectPlay4AImpl ) );
358
359     if( *ppvObj == NULL )
360     {
361        return DPERR_OUTOFMEMORY;
362     }
363
364     /* new scope for variable declaration */
365     {
366       ICOM_THIS(IDirectPlay4AImpl,*ppvObj);
367
368       ICOM_VTBL(This) = &directPlay4AVT;
369
370       if ( DP_CreateIUnknown( (LPVOID)This ) &&
371            DP_CreateDirectPlay2( (LPVOID)This ) &&
372            DP_CreateDirectPlay3( (LPVOID)This ) &&
373            DP_CreateDirectPlay4( (LPVOID)This )
374          )
375       {
376         return S_OK;
377       }
378
379     }
380
381     goto error;
382   }
383
384   /* Unsupported interface */
385   *ppvObj = NULL;
386   return E_NOINTERFACE;
387
388 error:
389
390     DP_DestroyDirectPlay4( *ppvObj );
391     DP_DestroyDirectPlay3( *ppvObj );
392     DP_DestroyDirectPlay2( *ppvObj );
393     DP_DestroyIUnknown( *ppvObj );
394     HeapFree( GetProcessHeap(), 0, *ppvObj );
395
396     *ppvObj = NULL;
397     return DPERR_NOMEMORY;
398
399 }
400
401
402 /* Direct Play methods */
403 static HRESULT WINAPI DirectPlay2W_QueryInterface
404          ( LPDIRECTPLAY2 iface, REFIID riid, LPVOID* ppvObj )
405 {
406   ICOM_THIS(IDirectPlay2Impl,iface);
407   TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
408
409   if( IsEqualGUID( &IID_IUnknown, riid ) ||
410       IsEqualGUID( &IID_IDirectPlay2, riid )
411     )
412   {
413     IDirectPlayX_AddRef( iface );
414     *ppvObj = This;
415     return S_OK;
416   }
417   return directPlay_QueryInterface( riid, ppvObj );
418 }
419
420 static HRESULT WINAPI DirectPlay2A_QueryInterface
421          ( LPDIRECTPLAY2A iface, REFIID riid, LPVOID* ppvObj )
422 {
423   ICOM_THIS(IDirectPlay2Impl,iface);
424   TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
425
426   if( IsEqualGUID( &IID_IUnknown, riid ) ||
427       IsEqualGUID( &IID_IDirectPlay2A, riid )
428     )
429   {
430     IDirectPlayX_AddRef( iface );
431     *ppvObj = This;
432     return S_OK;
433   }
434
435   return directPlay_QueryInterface( riid, ppvObj );
436 }
437
438 static HRESULT WINAPI DirectPlay3WImpl_QueryInterface
439          ( LPDIRECTPLAY3 iface, REFIID riid, LPVOID* ppvObj )
440 {
441   ICOM_THIS(IDirectPlay3Impl,iface);
442   TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
443
444   if( IsEqualGUID( &IID_IUnknown, riid ) ||
445       IsEqualGUID( &IID_IDirectPlay3, riid )
446     )
447   {
448     IDirectPlayX_AddRef( iface );
449     *ppvObj = This;
450     return S_OK;
451   }
452
453   return directPlay_QueryInterface( riid, ppvObj );
454 }
455
456 static HRESULT WINAPI DirectPlay3AImpl_QueryInterface
457          ( LPDIRECTPLAY3A iface, REFIID riid, LPVOID* ppvObj )
458 {
459   ICOM_THIS(IDirectPlay3Impl,iface);
460   TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
461
462   if( IsEqualGUID( &IID_IUnknown, riid ) ||
463       IsEqualGUID( &IID_IDirectPlay3A, riid )
464     )
465   {
466     IDirectPlayX_AddRef( iface );
467     *ppvObj = This;
468     return S_OK;
469   }
470
471   return directPlay_QueryInterface( riid, ppvObj );
472 }
473
474 static HRESULT WINAPI DirectPlay4WImpl_QueryInterface
475          ( LPDIRECTPLAY4 iface, REFIID riid, LPVOID* ppvObj )
476 {
477   ICOM_THIS(IDirectPlay4Impl,iface);
478   TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
479
480   if( IsEqualGUID( &IID_IUnknown, riid ) ||
481       IsEqualGUID( &IID_IDirectPlay4, riid )
482     )
483   {
484     IDirectPlayX_AddRef( iface );
485     *ppvObj = This;
486     return S_OK;
487   }
488
489   return directPlay_QueryInterface( riid, ppvObj );
490 }
491
492
493 static HRESULT WINAPI DirectPlay4AImpl_QueryInterface
494          ( LPDIRECTPLAY4A iface, REFIID riid, LPVOID* ppvObj )
495 {
496   ICOM_THIS(IDirectPlay4Impl,iface);
497   TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
498
499   if( IsEqualGUID( &IID_IUnknown, riid ) ||
500       IsEqualGUID( &IID_IDirectPlay4A, riid )
501     )
502   {
503     IDirectPlayX_AddRef( iface );
504     *ppvObj = This;
505     return S_OK;
506   }
507
508   return directPlay_QueryInterface( riid, ppvObj );
509 }
510
511
512 /* Shared between all dplay types */
513 static ULONG WINAPI DirectPlay2AImpl_AddRef
514          ( LPDIRECTPLAY3 iface )
515 {
516   ULONG refCount;
517   ICOM_THIS(IDirectPlay3Impl,iface);
518
519   EnterCriticalSection( &This->unk->DP_lock ); 
520   {
521     refCount = ++(This->unk->ref);
522   }  
523   LeaveCriticalSection( &This->unk->DP_lock );
524
525   TRACE("ref count incremented to %lu for %p\n", refCount, This );
526
527   return refCount;
528 }
529
530 static ULONG WINAPI DirectPlay2AImpl_Release
531 ( LPDIRECTPLAY3 iface )
532 {
533   ULONG refCount;
534
535   ICOM_THIS(IDirectPlay3Impl,iface);
536
537   EnterCriticalSection( &This->unk->DP_lock );
538   {
539     refCount = --(This->unk->ref);
540   }
541   LeaveCriticalSection( &This->unk->DP_lock );
542
543   TRACE("ref count decremented to %lu for %p\n", refCount, This );
544
545   /* Deallocate if this is the last reference to the object */
546   if( refCount == 0 )
547   {
548      DP_DestroyDirectPlay4( This );
549      DP_DestroyDirectPlay3( This );
550      DP_DestroyDirectPlay2( This );
551      DP_DestroyIUnknown( This );
552      HeapFree( GetProcessHeap(), 0, This );
553   }
554
555   return refCount;
556 }
557
558 static HRESULT WINAPI DirectPlay2AImpl_AddPlayerToGroup
559           ( LPDIRECTPLAY2A iface, DPID idGroup, DPID idPlayer )
560 {
561   ICOM_THIS(IDirectPlay2Impl,iface);
562   FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idPlayer );
563   return DP_OK;
564 }
565
566 static HRESULT WINAPI DirectPlay2WImpl_AddPlayerToGroup
567           ( LPDIRECTPLAY2 iface, DPID idGroup, DPID idPlayer )
568 {
569   ICOM_THIS(IDirectPlay2Impl,iface);
570   FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idPlayer );
571   return DP_OK;
572 }
573
574
575 static HRESULT WINAPI DirectPlay2AImpl_Close
576           ( LPDIRECTPLAY2A iface )
577 {
578   ICOM_THIS(IDirectPlay2Impl,iface);
579   FIXME("(%p)->(): stub\n", This );
580   return DP_OK;
581 }
582
583 static HRESULT WINAPI DirectPlay2WImpl_Close
584           ( LPDIRECTPLAY2 iface )
585 {
586   ICOM_THIS(IDirectPlay2Impl,iface);
587   FIXME("(%p)->(): stub\n", This );
588   return DP_OK;
589 }
590
591 static HRESULT WINAPI DirectPlay2AImpl_CreateGroup
592           ( LPDIRECTPLAY2A iface, LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
593 {
594   ICOM_THIS(IDirectPlay2Impl,iface);
595   FIXME("(%p)->(%p,%p,%p,0x%08lx,0x%08lx): stub\n", This, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags );
596   return DP_OK;
597 }
598
599 static HRESULT WINAPI DirectPlay2WImpl_CreateGroup
600           ( LPDIRECTPLAY2 iface, LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
601 {
602   ICOM_THIS(IDirectPlay2Impl,iface);
603   FIXME("(%p)->(%p,%p,%p,0x%08lx,0x%08lx): stub\n", This, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags );
604   return DP_OK;
605 }
606
607 static HRESULT WINAPI DirectPlay2AImpl_CreatePlayer
608           ( LPDIRECTPLAY2A iface, LPDPID lpidPlayer, LPDPNAME lpPlayerName, HANDLE hEvent, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
609 {
610   ICOM_THIS(IDirectPlay2Impl,iface);
611   FIXME("(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx): stub\n", This, lpidPlayer, lpPlayerName, hEvent, lpData, dwDataSize, dwFlags );
612   return DP_OK;
613 }
614
615 static HRESULT WINAPI DirectPlay2WImpl_CreatePlayer
616           ( LPDIRECTPLAY2 iface, LPDPID lpidPlayer, LPDPNAME lpPlayerName, HANDLE hEvent, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
617 {
618   ICOM_THIS(IDirectPlay2Impl,iface);
619   FIXME("(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx): stub\n", This, lpidPlayer, lpPlayerName, hEvent, lpData, dwDataSize, dwFlags );
620   return DP_OK;
621 }
622
623 static HRESULT WINAPI DirectPlay2AImpl_DeletePlayerFromGroup
624           ( LPDIRECTPLAY2A iface, DPID idGroup, DPID idPlayer )
625 {
626   ICOM_THIS(IDirectPlay2Impl,iface);
627   FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idPlayer );
628   return DP_OK;
629 }
630
631 static HRESULT WINAPI DirectPlay2WImpl_DeletePlayerFromGroup
632           ( LPDIRECTPLAY2 iface, DPID idGroup, DPID idPlayer )
633 {
634   ICOM_THIS(IDirectPlay2Impl,iface);
635   FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idPlayer );
636   return DP_OK;
637 }
638
639 static HRESULT WINAPI DirectPlay2AImpl_DestroyGroup
640           ( LPDIRECTPLAY2A iface, DPID idGroup )
641 {
642   ICOM_THIS(IDirectPlay2Impl,iface);
643   FIXME("(%p)->(0x%08lx): stub\n", This, idGroup );
644   return DP_OK;
645 }
646
647 static HRESULT WINAPI DirectPlay2WImpl_DestroyGroup
648           ( LPDIRECTPLAY2 iface, DPID idGroup )
649 {
650   ICOM_THIS(IDirectPlay2Impl,iface);
651   FIXME("(%p)->(0x%08lx): stub\n", This, idGroup );
652   return DP_OK;
653 }
654
655 static HRESULT WINAPI DirectPlay2AImpl_DestroyPlayer
656           ( LPDIRECTPLAY2A iface, DPID idPlayer )
657 {
658   ICOM_THIS(IDirectPlay2Impl,iface);
659   FIXME("(%p)->(0x%08lx): stub\n", This, idPlayer );
660   return DP_OK;
661 }
662
663 static HRESULT WINAPI DirectPlay2WImpl_DestroyPlayer
664           ( LPDIRECTPLAY2 iface, DPID idPlayer )
665 {
666   ICOM_THIS(IDirectPlay2Impl,iface);
667   FIXME("(%p)->(0x%08lx): stub\n", This, idPlayer );
668   return DP_OK;
669 }
670
671 static HRESULT WINAPI DirectPlay2AImpl_EnumGroupPlayers
672           ( LPDIRECTPLAY2A iface, DPID idGroup, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
673             LPVOID lpContext, DWORD dwFlags )
674 {
675   ICOM_THIS(IDirectPlay2Impl,iface);
676   FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub\n", This, idGroup, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
677   return DP_OK;
678 }
679
680 static HRESULT WINAPI DirectPlay2WImpl_EnumGroupPlayers
681           ( LPDIRECTPLAY2 iface, DPID idGroup, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
682             LPVOID lpContext, DWORD dwFlags )
683 {
684   ICOM_THIS(IDirectPlay2Impl,iface);
685   FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub\n", This, idGroup, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
686   return DP_OK;
687 }
688
689 static HRESULT WINAPI DirectPlay2AImpl_EnumGroups
690           ( LPDIRECTPLAY2A iface, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
691 {
692   ICOM_THIS(IDirectPlay2Impl,iface);
693   FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
694   return DP_OK;
695 }
696
697 static HRESULT WINAPI DirectPlay2WImpl_EnumGroups
698           ( LPDIRECTPLAY2 iface, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
699 {
700   ICOM_THIS(IDirectPlay2Impl,iface);
701   FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
702   return DP_OK;
703 }
704
705 static HRESULT WINAPI DirectPlay2AImpl_EnumPlayers
706           ( LPDIRECTPLAY2A iface, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
707 {
708   ICOM_THIS(IDirectPlay2Impl,iface);
709   FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
710   return DP_OK;
711 }
712
713 static HRESULT WINAPI DirectPlay2WImpl_EnumPlayers
714           ( LPDIRECTPLAY2 iface, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
715 {
716   ICOM_THIS(IDirectPlay2Impl,iface);
717   FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
718   return DP_OK;
719 }
720
721 static HRESULT WINAPI DirectPlay2AImpl_EnumSessions
722           ( LPDIRECTPLAY2A iface, LPDPSESSIONDESC2 lpsd, DWORD dwTimeout, LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
723             LPVOID lpContext, DWORD dwFlags )
724 {
725   ICOM_THIS(IDirectPlay2Impl,iface);
726   FIXME("(%p)->(%p,0x%08lx,%p,%p,0x%08lx): stub\n", This, lpsd, dwTimeout, lpEnumSessionsCallback2, lpContext, dwFlags );
727   return DP_OK;
728 }
729
730 static HRESULT WINAPI DirectPlay2WImpl_EnumSessions
731           ( LPDIRECTPLAY2 iface, LPDPSESSIONDESC2 lpsd, DWORD dwTimeout, LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
732             LPVOID lpContext, DWORD dwFlags )
733 {
734   ICOM_THIS(IDirectPlay2Impl,iface);
735   FIXME("(%p)->(%p,0x%08lx,%p,%p,0x%08lx): stub\n", This, lpsd, dwTimeout, lpEnumSessionsCallback2, lpContext, dwFlags );
736   return DP_OK;
737 }
738
739 static HRESULT WINAPI DirectPlay2AImpl_GetCaps
740           ( LPDIRECTPLAY2A iface, LPDPCAPS lpDPCaps, DWORD dwFlags )
741 {
742   ICOM_THIS(IDirectPlay2Impl,iface);
743   FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpDPCaps, dwFlags );
744   return DP_OK;
745 }
746
747 static HRESULT WINAPI DirectPlay2WImpl_GetCaps
748           ( LPDIRECTPLAY2 iface, LPDPCAPS lpDPCaps, DWORD dwFlags )
749 {
750   ICOM_THIS(IDirectPlay2Impl,iface);
751   FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpDPCaps, dwFlags );
752   return DP_OK;
753 }
754
755 static HRESULT WINAPI DirectPlay2AImpl_GetGroupData
756           ( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize, DWORD dwFlags )
757 {
758   ICOM_THIS(IDirectPlay2Impl,iface);
759   FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, idGroup, lpData, lpdwDataSize, dwFlags );
760   return DP_OK;
761 }
762
763 static HRESULT WINAPI DirectPlay2WImpl_GetGroupData
764           ( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize, DWORD dwFlags )
765 {
766   ICOM_THIS(IDirectPlay2Impl,iface);
767   FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, idGroup, lpData, lpdwDataSize, dwFlags );
768   return DP_OK;
769 }
770
771 static HRESULT WINAPI DirectPlay2AImpl_GetGroupName
772           ( LPDIRECTPLAY2A iface, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize )
773 {
774   ICOM_THIS(IDirectPlay2Impl,iface);
775   FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idGroup, lpData, lpdwDataSize );
776   return DP_OK;
777 }
778
779 static HRESULT WINAPI DirectPlay2WImpl_GetGroupName
780           ( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize )
781 {
782   ICOM_THIS(IDirectPlay2Impl,iface);
783   FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idGroup, lpData, lpdwDataSize );
784   return DP_OK;
785 }
786
787 static HRESULT WINAPI DirectPlay2AImpl_GetMessageCount
788           ( LPDIRECTPLAY2A iface, DPID idPlayer, LPDWORD lpdwCount )
789 {
790   ICOM_THIS(IDirectPlay2Impl,iface);
791   FIXME("(%p)->(0x%08lx,%p): stub\n", This, idPlayer, lpdwCount );
792   return DP_OK;
793 }
794
795 static HRESULT WINAPI DirectPlay2WImpl_GetMessageCount
796           ( LPDIRECTPLAY2 iface, DPID idPlayer, LPDWORD lpdwCount )
797 {
798   ICOM_THIS(IDirectPlay2Impl,iface);
799   FIXME("(%p)->(0x%08lx,%p): stub\n", This, idPlayer, lpdwCount );
800   return DP_OK;
801 }
802
803 static HRESULT WINAPI DirectPlay2AImpl_GetPlayerAddress
804           ( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize )
805 {
806   ICOM_THIS(IDirectPlay2Impl,iface);
807   FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idPlayer, lpData, lpdwDataSize );
808   return DP_OK;
809 }
810
811 static HRESULT WINAPI DirectPlay2WImpl_GetPlayerAddress
812           ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize )
813 {
814   ICOM_THIS(IDirectPlay2Impl,iface);
815   FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idPlayer, lpData, lpdwDataSize );
816   return DP_OK;
817 }
818
819 static HRESULT WINAPI DirectPlay2AImpl_GetPlayerCaps
820           ( LPDIRECTPLAY2A iface, DPID idPlayer, LPDPCAPS lpPlayerCaps, DWORD dwFlags )
821 {
822   ICOM_THIS(IDirectPlay2Impl,iface);
823   FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idPlayer, lpPlayerCaps, dwFlags );
824   return DP_OK;
825 }
826
827 static HRESULT WINAPI DirectPlay2WImpl_GetPlayerCaps
828           ( LPDIRECTPLAY2 iface, DPID idPlayer, LPDPCAPS lpPlayerCaps, DWORD dwFlags )
829 {
830   ICOM_THIS(IDirectPlay2Impl,iface);
831   FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idPlayer, lpPlayerCaps, dwFlags );
832   return DP_OK;
833 }
834
835 static HRESULT WINAPI DirectPlay2AImpl_GetPlayerData
836           ( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize, DWORD dwFlags )
837 {
838   ICOM_THIS(IDirectPlay2Impl,iface);
839   FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, idPlayer, lpData, lpdwDataSize, dwFlags );
840   return DP_OK;
841 }
842
843 static HRESULT WINAPI DirectPlay2WImpl_GetPlayerData
844           ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize, DWORD dwFlags )
845 {
846   ICOM_THIS(IDirectPlay2Impl,iface);
847   FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, idPlayer, lpData, lpdwDataSize, dwFlags );
848   return DP_OK;
849 }
850
851 static HRESULT WINAPI DirectPlay2AImpl_GetPlayerName
852           ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize )
853 {
854   ICOM_THIS(IDirectPlay2Impl,iface);
855   FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idPlayer, lpData, lpdwDataSize );
856   return DP_OK;
857 }
858
859 static HRESULT WINAPI DirectPlay2WImpl_GetPlayerName
860           ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize )
861 {
862   ICOM_THIS(IDirectPlay2Impl,iface);
863   FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idPlayer, lpData, lpdwDataSize );
864   return DP_OK;
865 }
866
867 static HRESULT WINAPI DirectPlay2AImpl_GetSessionDesc
868           ( LPDIRECTPLAY2A iface, LPVOID lpData, LPDWORD lpdwDataSize )
869 {
870   ICOM_THIS(IDirectPlay2Impl,iface);
871   FIXME("(%p)->(%p,%p): stub\n", This, lpData, lpdwDataSize );
872   return DP_OK;
873 }
874
875 static HRESULT WINAPI DirectPlay2WImpl_GetSessionDesc
876           ( LPDIRECTPLAY2 iface, LPVOID lpData, LPDWORD lpdwDataSize )
877 {
878   ICOM_THIS(IDirectPlay2Impl,iface);
879   FIXME("(%p)->(%p,%p): stub\n", This, lpData, lpdwDataSize );
880   return DP_OK;
881 }
882
883 /* Intended only for COM compatibility. Always returns an error. */
884 static HRESULT WINAPI DirectPlay2AImpl_Initialize
885           ( LPDIRECTPLAY2A iface, LPGUID lpGUID )
886 {
887   ICOM_THIS(IDirectPlay2Impl,iface);
888   TRACE("(%p)->(%p): stub\n", This, lpGUID );
889   return DPERR_ALREADYINITIALIZED;
890 }
891
892 /* Intended only for COM compatibility. Always returns an error. */
893 static HRESULT WINAPI DirectPlay2WImpl_Initialize
894           ( LPDIRECTPLAY2 iface, LPGUID lpGUID )
895 {
896   ICOM_THIS(IDirectPlay2Impl,iface);
897   TRACE("(%p)->(%p): stub\n", This, lpGUID );
898   return DPERR_ALREADYINITIALIZED;
899 }
900
901
902 static HRESULT WINAPI DirectPlay2AImpl_Open
903           ( LPDIRECTPLAY2A iface, LPDPSESSIONDESC2 lpsd, DWORD dwFlags )
904 {
905   ICOM_THIS(IDirectPlay2Impl,iface);
906   FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpsd, dwFlags );
907   return DP_OK;
908 }
909
910 static HRESULT WINAPI DirectPlay2WImpl_Open
911           ( LPDIRECTPLAY2 iface, LPDPSESSIONDESC2 lpsd, DWORD dwFlags )
912 {
913   ICOM_THIS(IDirectPlay2Impl,iface);
914   FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpsd, dwFlags );
915   return DP_OK;
916 }
917
918 static HRESULT WINAPI DirectPlay2AImpl_Receive
919           ( LPDIRECTPLAY2A iface, LPDPID lpidFrom, LPDPID lpidTo, DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize )
920 {
921   ICOM_THIS(IDirectPlay2Impl,iface);
922   FIXME("(%p)->(%p,%p,0x%08lx,%p,%p): stub\n", This, lpidFrom, lpidTo, dwFlags, lpData, lpdwDataSize );
923   return DP_OK;
924 }
925
926 static HRESULT WINAPI DirectPlay2WImpl_Receive
927           ( LPDIRECTPLAY2 iface, LPDPID lpidFrom, LPDPID lpidTo, DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize )
928 {
929   ICOM_THIS(IDirectPlay2Impl,iface);
930   FIXME("(%p)->(%p,%p,0x%08lx,%p,%p): stub\n", This, lpidFrom, lpidTo, dwFlags, lpData, lpdwDataSize );
931   return DP_OK;
932 }
933
934 static HRESULT WINAPI DirectPlay2AImpl_Send
935           ( LPDIRECTPLAY2A iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize )
936 {
937   ICOM_THIS(IDirectPlay2Impl,iface);
938   FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx): stub\n", This, idFrom, idTo, dwFlags, lpData, dwDataSize );
939   return DP_OK;
940 }
941
942 static HRESULT WINAPI DirectPlay2WImpl_Send
943           ( LPDIRECTPLAY2 iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize )
944 {
945   ICOM_THIS(IDirectPlay2Impl,iface);
946   FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx): stub\n", This, idFrom, idTo, dwFlags, lpData, dwDataSize );
947   return DP_OK;
948 }
949
950 static HRESULT WINAPI DirectPlay2AImpl_SetGroupData
951           ( LPDIRECTPLAY2A iface, DPID idGroup, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
952 {
953   ICOM_THIS(IDirectPlay2Impl,iface);
954   FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub\n", This, idGroup, lpData, dwDataSize, dwFlags );
955   return DP_OK;
956 }
957
958 static HRESULT WINAPI DirectPlay2WImpl_SetGroupData
959           ( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
960 {   
961   ICOM_THIS(IDirectPlay2Impl,iface);
962   FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub\n", This, idGroup, lpData, dwDataSize, dwFlags );
963   return DP_OK;
964 }
965
966 static HRESULT WINAPI DirectPlay2AImpl_SetGroupName
967           ( LPDIRECTPLAY2A iface, DPID idGroup, LPDPNAME lpGroupName, DWORD dwFlags )
968 {
969   ICOM_THIS(IDirectPlay2Impl,iface);
970   FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idGroup, lpGroupName, dwFlags );
971   return DP_OK;
972 }
973
974 static HRESULT WINAPI DirectPlay2WImpl_SetGroupName
975           ( LPDIRECTPLAY2 iface, DPID idGroup, LPDPNAME lpGroupName, DWORD dwFlags )
976 {
977   ICOM_THIS(IDirectPlay2Impl,iface);
978   FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idGroup, lpGroupName, dwFlags );
979   return DP_OK;
980 }
981
982 static HRESULT WINAPI DirectPlay2AImpl_SetPlayerData
983           ( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
984 {
985   ICOM_THIS(IDirectPlay2Impl,iface);
986   FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub\n", This, idPlayer, lpData, dwDataSize, dwFlags );
987   return DP_OK;
988 }
989
990 static HRESULT WINAPI DirectPlay2WImpl_SetPlayerData
991           ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
992 {
993   ICOM_THIS(IDirectPlay2Impl,iface);
994   FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub\n", This, idPlayer, lpData, dwDataSize, dwFlags );
995   return DP_OK;
996 }
997
998 static HRESULT WINAPI DirectPlay2AImpl_SetPlayerName
999           ( LPDIRECTPLAY2A iface, DPID idPlayer, LPDPNAME lpPlayerName, DWORD dwFlags )
1000 {
1001   ICOM_THIS(IDirectPlay2Impl,iface);
1002   FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idPlayer, lpPlayerName, dwFlags );
1003   return DP_OK;
1004 }
1005
1006 static HRESULT WINAPI DirectPlay2WImpl_SetPlayerName
1007           ( LPDIRECTPLAY2 iface, DPID idPlayer, LPDPNAME lpPlayerName, DWORD dwFlags )
1008 {
1009   ICOM_THIS(IDirectPlay2Impl,iface);
1010   FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idPlayer, lpPlayerName, dwFlags );
1011   return DP_OK;
1012 }
1013
1014 static HRESULT WINAPI DirectPlay2AImpl_SetSessionDesc
1015           ( LPDIRECTPLAY2A iface, LPDPSESSIONDESC2 lpSessDesc, DWORD dwFlags )
1016 {
1017   ICOM_THIS(IDirectPlay2Impl,iface);
1018   FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpSessDesc, dwFlags );
1019   return DP_OK;
1020 }
1021
1022 static HRESULT WINAPI DirectPlay2WImpl_SetSessionDesc
1023           ( LPDIRECTPLAY2 iface, LPDPSESSIONDESC2 lpSessDesc, DWORD dwFlags )
1024 {
1025   ICOM_THIS(IDirectPlay2Impl,iface);
1026   FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpSessDesc, dwFlags );
1027   return DP_OK;
1028 }
1029
1030 static HRESULT WINAPI DirectPlay3AImpl_AddGroupToGroup
1031           ( LPDIRECTPLAY3A iface, DPID idParentGroup, DPID idGroup )
1032 {
1033   ICOM_THIS(IDirectPlay3Impl,iface);
1034   FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idParentGroup, idGroup );
1035   return DP_OK;
1036 }
1037
1038 static HRESULT WINAPI DirectPlay3WImpl_AddGroupToGroup
1039           ( LPDIRECTPLAY3 iface, DPID idParentGroup, DPID idGroup )
1040 {
1041   ICOM_THIS(IDirectPlay3Impl,iface);
1042   FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idParentGroup, idGroup );
1043   return DP_OK;
1044 }
1045
1046 static HRESULT WINAPI DirectPlay3AImpl_CreateGroupInGroup
1047           ( LPDIRECTPLAY3A iface, DPID idParentGroup, LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
1048 {
1049   ICOM_THIS(IDirectPlay3Impl,iface);
1050   FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx): stub\n", This, idParentGroup, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags );
1051   return DP_OK;
1052 }
1053
1054 static HRESULT WINAPI DirectPlay3WImpl_CreateGroupInGroup
1055           ( LPDIRECTPLAY3 iface, DPID idParentGroup, LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
1056 {
1057   ICOM_THIS(IDirectPlay3Impl,iface);
1058   FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx): stub\n", This, idParentGroup, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags );
1059   return DP_OK;
1060 }
1061
1062 static HRESULT WINAPI DirectPlay3AImpl_DeleteGroupFromGroup
1063           ( LPDIRECTPLAY3A iface, DPID idParentGroup, DPID idGroup )
1064 {
1065   ICOM_THIS(IDirectPlay3Impl,iface);
1066   FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idParentGroup, idGroup );
1067   return DP_OK;
1068 }
1069
1070 static HRESULT WINAPI DirectPlay3WImpl_DeleteGroupFromGroup
1071           ( LPDIRECTPLAY3 iface, DPID idParentGroup, DPID idGroup )
1072 {
1073   ICOM_THIS(IDirectPlay3Impl,iface);
1074   FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idParentGroup, idGroup );
1075   return DP_OK;
1076 }
1077
1078 static HRESULT WINAPI DirectPlay3AImpl_EnumConnections
1079           ( LPDIRECTPLAY3A iface, LPCGUID lpguidApplication, LPDPENUMCONNECTIONSCALLBACK lpEnumCallback, LPVOID lpContext, DWORD dwFlags )
1080 {
1081   ICOM_THIS(IDirectPlay3Impl,iface);
1082   TRACE("(%p)->(%p,%p,%p,0x%08lx)\n", This, lpguidApplication, lpEnumCallback, lpContext, dwFlags );
1083
1084   /* A default dwFlags (0) is backwards compatible -- DPCONNECTION_DIRECTPLAY */
1085   if( dwFlags == 0 )
1086   {
1087     dwFlags = DPCONNECTION_DIRECTPLAY;
1088   }
1089
1090   if( ! ( ( dwFlags & DPCONNECTION_DIRECTPLAY ) ||
1091           ( dwFlags & DPCONNECTION_DIRECTPLAYLOBBY ) )
1092     ) 
1093   {
1094     return DPERR_INVALIDFLAGS;
1095   }
1096
1097   if( !lpEnumCallback || !*lpEnumCallback )
1098   {
1099      return DPERR_INVALIDPARAMS;
1100   }
1101
1102   /* Enumerate DirectPlay service providers */
1103   if( dwFlags & DPCONNECTION_DIRECTPLAY )
1104   {
1105     HKEY hkResult;
1106     LPCSTR searchSubKey    = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
1107     LPSTR guidDataSubKey   = "Guid";
1108     DWORD dwIndex, sizeOfSubKeyName=50;
1109     char subKeyName[51]; 
1110
1111     /* Need to loop over the service providers in the registry */
1112     if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
1113                          0, KEY_ENUMERATE_SUB_KEYS, &hkResult ) != ERROR_SUCCESS )
1114     {
1115       /* Hmmm. Does this mean that there are no service providers? */
1116       ERR(": no service providers?\n");
1117       return DP_OK;
1118     }
1119
1120
1121     /* Traverse all the service providers we have available */
1122     for( dwIndex=0;
1123          RegEnumKeyA( hkResult, dwIndex, subKeyName, sizeOfSubKeyName ) != ERROR_NO_MORE_ITEMS;
1124          ++dwIndex )
1125     {
1126
1127       HKEY     hkServiceProvider;
1128       GUID     serviceProviderGUID;
1129       DWORD    returnTypeGUID, sizeOfReturnBuffer = 50;
1130       char     returnBuffer[51];
1131       LPWSTR   lpWGUIDString;
1132       DPNAME   dpName;
1133       HRESULT  hr;
1134
1135       DPCOMPOUNDADDRESSELEMENT dpCompoundAddress;
1136       LPVOID                   lpAddressBuffer = NULL;
1137       DWORD                    dwAddressBufferSize = 0;
1138
1139       TRACE(" this time through: %s\n", subKeyName );
1140
1141       /* Get a handle for this particular service provider */
1142       if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_QUERY_VALUE,
1143                          &hkServiceProvider ) != ERROR_SUCCESS )
1144       {
1145          ERR(": what the heck is going on?\n" );
1146          continue;
1147       }
1148
1149       if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
1150                             NULL, &returnTypeGUID, returnBuffer,
1151                             &sizeOfReturnBuffer ) != ERROR_SUCCESS )
1152       {
1153         ERR(": missing GUID registry data members\n" );
1154         continue;
1155       }
1156
1157       /* FIXME: Check return types to ensure we're interpreting data right */
1158       lpWGUIDString = HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer );
1159       CLSIDFromString( (LPCOLESTR)lpWGUIDString, &serviceProviderGUID );
1160       HeapFree( GetProcessHeap(), 0, lpWGUIDString );
1161       /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
1162
1163       /* Fill in the DPNAME struct for the service provider */
1164       dpName.dwSize             = sizeof( dpName );
1165       dpName.dwFlags            = 0;
1166       dpName.psn.lpszShortNameA = subKeyName;
1167       dpName.pln.lpszLongNameA  = NULL;
1168
1169       /* Create the compound address for the service provider. 
1170          NOTE: This is a gruesome architectural scar right now. DP uses DPL and DPL uses DP
1171                nast stuff. This may be why the native dll just gets around this little bit by
1172                allocating an 80 byte buffer which isn't even a filled with a valid compound 
1173                address. Oh well. Creating a proper compound address is the way to go anyways 
1174                despite this method taking slightly more heap space and realtime :) */
1175       dpCompoundAddress.guidDataType = DPAID_ServiceProvider;
1176       dpCompoundAddress.dwDataSize   = sizeof( GUID );
1177       dpCompoundAddress.lpData       = &serviceProviderGUID; 
1178
1179       if( ( hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, lpAddressBuffer, 
1180                                      &dwAddressBufferSize, TRUE ) ) != DPERR_BUFFERTOOSMALL )
1181       {
1182         ERR( "can't get buffer size: %s\n", DPLAYX_HresultToString( hr ) );
1183         return hr;
1184       }
1185
1186       /* Now allocate the buffer */
1187       lpAddressBuffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAddressBufferSize );
1188
1189       if( ( hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, lpAddressBuffer,
1190                                      &dwAddressBufferSize, TRUE ) ) != DP_OK )
1191       {
1192         ERR( "can't create address: %s\n", DPLAYX_HresultToString( hr ) );
1193         return hr;
1194       }
1195
1196       /* The enumeration will return FALSE if we are not to continue */
1197       if( !lpEnumCallback( &serviceProviderGUID, lpAddressBuffer, dwAddressBufferSize, 
1198                            &dpName, DPCONNECTION_DIRECTPLAY, lpContext ) )
1199       {
1200          WARN("lpEnumCallback returning FALSE\n" );
1201
1202          return DP_OK;
1203       }
1204     }
1205   }
1206
1207   /* Enumerate DirectPlayLobby service providers */
1208   if( dwFlags & DPCONNECTION_DIRECTPLAYLOBBY )
1209   {
1210     FIXME( "DPCONNECTION_DIRECTPLAYLOBBY flag not handled\n" );
1211   }
1212
1213   return DP_OK;
1214 }
1215
1216 static HRESULT WINAPI DirectPlay3WImpl_EnumConnections
1217           ( LPDIRECTPLAY3 iface, LPCGUID lpguidApplication, LPDPENUMCONNECTIONSCALLBACK lpEnumCallback, LPVOID lpContext, DWORD dwFlags )
1218
1219   ICOM_THIS(IDirectPlay3Impl,iface);
1220   FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidApplication, lpEnumCallback, lpContext, dwFlags );
1221   return DP_OK;
1222 }
1223
1224 static HRESULT WINAPI DirectPlay3AImpl_EnumGroupsInGroup
1225           ( LPDIRECTPLAY3A iface, DPID idGroup, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumCallback, LPVOID lpContext, DWORD dwFlags )
1226 {
1227   ICOM_THIS(IDirectPlay3Impl,iface);
1228   FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub\n", This, idGroup, lpguidInstance, lpEnumCallback, lpContext, dwFlags );
1229   return DP_OK;
1230 }
1231
1232 static HRESULT WINAPI DirectPlay3WImpl_EnumGroupsInGroup
1233           ( LPDIRECTPLAY3 iface, DPID idGroup, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumCallback, LPVOID lpContext, DWORD dwFlags )
1234 {
1235   ICOM_THIS(IDirectPlay3Impl,iface);
1236   FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub\n", This, idGroup, lpguidInstance, lpEnumCallback, lpContext, dwFlags );
1237   return DP_OK;
1238 }
1239
1240 static HRESULT WINAPI DirectPlay3AImpl_GetGroupConnectionSettings
1241           ( LPDIRECTPLAY3A iface, DWORD dwFlags, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize )
1242 {
1243   ICOM_THIS(IDirectPlay3Impl,iface);
1244   FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, dwFlags, idGroup, lpData, lpdwDataSize );
1245   return DP_OK;
1246 }
1247
1248 static HRESULT WINAPI DirectPlay3WImpl_GetGroupConnectionSettings
1249           ( LPDIRECTPLAY3 iface, DWORD dwFlags, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize )
1250 {
1251   ICOM_THIS(IDirectPlay3Impl,iface);
1252   FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, dwFlags, idGroup, lpData, lpdwDataSize );
1253   return DP_OK;
1254 }
1255
1256 static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
1257           ( LPDIRECTPLAY3A iface, LPVOID lpConnection, DWORD dwFlags )
1258 {
1259   HMODULE hServiceProvider;
1260   typedef DWORD (WINAPI *SP_SPInit)(LPVOID lpCompoundAddress, ...); /* FIXME: How many arguments? */
1261   SP_SPInit SPInit;
1262
1263   ICOM_THIS(IDirectPlay3Impl,iface);
1264
1265   FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpConnection, dwFlags );
1266
1267   if( dwFlags != 0 )
1268   {
1269     return DPERR_INVALIDFLAGS;
1270   }
1271
1272   if( This->dp3->connectionInitialized == TRUE )
1273   {
1274     return DPERR_ALREADYINITIALIZED;
1275   }
1276
1277   /* Parse lpConnection as a compound address for the service provider */
1278   /* Take service provider GUID and find the path to it */
1279
1280   /* FIXME: Hard coded to only load the tcp/ip service provider for now... */
1281   hServiceProvider = LoadLibraryA( "dpwsockx.dll" );
1282
1283   if( hServiceProvider == 0 )
1284   {
1285     ERR( "Unable to load service provider\n" );
1286     return DPERR_UNAVAILABLE; 
1287   }
1288   
1289   /* Initialize the service provider by calling SPInit */
1290   SPInit = (SP_SPInit)GetProcAddress( hServiceProvider, "SPInit" );
1291
1292   if( SPInit == NULL )
1293   {
1294     ERR( "Service provider doesn't provide SPInit interface?\n" );
1295   }  
1296
1297 #if 0
1298   /* NOTE: This will crash until I know what parameters/interface this has */
1299   /* FIXME: Take a guess that we just pass the compound address to the SP */
1300   /* Hmmm...how to say which parameters need to be gotten from the SP. They must
1301      come from the compound address, but how do we communicate what's required? */
1302   dwReturnValue = (*SPInit)( lpConnection );
1303 #endif
1304
1305   /* This interface is now initialized */
1306   This->dp3->connectionInitialized = TRUE;
1307
1308   return DP_OK;
1309 }
1310
1311 static HRESULT WINAPI DirectPlay3WImpl_InitializeConnection
1312           ( LPDIRECTPLAY3 iface, LPVOID lpConnection, DWORD dwFlags )
1313 {
1314   ICOM_THIS(IDirectPlay3Impl,iface);
1315   FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpConnection, dwFlags );
1316   return DP_OK;
1317 }
1318
1319 static HRESULT WINAPI DirectPlay3AImpl_SecureOpen
1320           ( LPDIRECTPLAY3A iface, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags, LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials )
1321 {
1322   ICOM_THIS(IDirectPlay3Impl,iface);
1323   FIXME("(%p)->(%p,0x%08lx,%p,%p): stub\n", This, lpsd, dwFlags, lpSecurity, lpCredentials );
1324   return DP_OK;
1325 }
1326
1327 static HRESULT WINAPI DirectPlay3WImpl_SecureOpen
1328           ( LPDIRECTPLAY3 iface, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags, LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials )
1329 {   
1330   ICOM_THIS(IDirectPlay3Impl,iface);
1331   FIXME("(%p)->(%p,0x%08lx,%p,%p): stub\n", This, lpsd, dwFlags, lpSecurity, lpCredentials );
1332   return DP_OK;
1333 }
1334
1335 static HRESULT WINAPI DirectPlay3AImpl_SendChatMessage
1336           ( LPDIRECTPLAY3A iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPDPCHAT lpChatMessage )
1337 {
1338   ICOM_THIS(IDirectPlay3Impl,iface);
1339   FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p): stub\n", This, idFrom, idTo, dwFlags, lpChatMessage );
1340   return DP_OK;
1341 }
1342
1343 static HRESULT WINAPI DirectPlay3WImpl_SendChatMessage
1344           ( LPDIRECTPLAY3 iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPDPCHAT lpChatMessage )
1345 {
1346   ICOM_THIS(IDirectPlay3Impl,iface);
1347   FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p): stub\n", This, idFrom, idTo, dwFlags, lpChatMessage );
1348   return DP_OK;
1349 }
1350
1351 static HRESULT WINAPI DirectPlay3AImpl_SetGroupConnectionSettings
1352           ( LPDIRECTPLAY3A iface, DWORD dwFlags, DPID idGroup, LPDPLCONNECTION lpConnection )
1353 {
1354   ICOM_THIS(IDirectPlay3Impl,iface);
1355   FIXME("(%p)->(0x%08lx,0x%08lx,%p): stub\n", This, dwFlags, idGroup, lpConnection );
1356   return DP_OK;
1357 }
1358
1359 static HRESULT WINAPI DirectPlay3WImpl_SetGroupConnectionSettings
1360           ( LPDIRECTPLAY3 iface, DWORD dwFlags, DPID idGroup, LPDPLCONNECTION lpConnection )
1361 {
1362   ICOM_THIS(IDirectPlay3Impl,iface);
1363   FIXME("(%p)->(0x%08lx,0x%08lx,%p): stub\n", This, dwFlags, idGroup, lpConnection );
1364   return DP_OK;
1365 }
1366
1367 static HRESULT WINAPI DirectPlay3AImpl_StartSession
1368           ( LPDIRECTPLAY3A iface, DWORD dwFlags, DPID idGroup )
1369 {
1370   ICOM_THIS(IDirectPlay3Impl,iface);
1371   FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, dwFlags, idGroup );
1372   return DP_OK;
1373 }
1374
1375 static HRESULT WINAPI DirectPlay3WImpl_StartSession
1376           ( LPDIRECTPLAY3 iface, DWORD dwFlags, DPID idGroup )
1377 {
1378   ICOM_THIS(IDirectPlay3Impl,iface);
1379   FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, dwFlags, idGroup );
1380   return DP_OK;
1381 }
1382  
1383 static HRESULT WINAPI DirectPlay3AImpl_GetGroupFlags
1384           ( LPDIRECTPLAY3A iface, DPID idGroup, LPDWORD lpdwFlags )
1385 {
1386   ICOM_THIS(IDirectPlay3Impl,iface);
1387   FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpdwFlags );
1388   return DP_OK;
1389 }
1390
1391 static HRESULT WINAPI DirectPlay3WImpl_GetGroupFlags
1392           ( LPDIRECTPLAY3 iface, DPID idGroup, LPDWORD lpdwFlags )
1393 {
1394   ICOM_THIS(IDirectPlay3Impl,iface);
1395   FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpdwFlags );
1396   return DP_OK;
1397 }
1398
1399 static HRESULT WINAPI DirectPlay3AImpl_GetGroupParent
1400           ( LPDIRECTPLAY3A iface, DPID idGroup, LPDPID lpidGroup )
1401 {
1402   ICOM_THIS(IDirectPlay3Impl,iface);
1403   FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpidGroup );
1404   return DP_OK;
1405 }
1406
1407 static HRESULT WINAPI DirectPlay3WImpl_GetGroupParent
1408           ( LPDIRECTPLAY3 iface, DPID idGroup, LPDPID lpidGroup )
1409 {
1410   ICOM_THIS(IDirectPlay3Impl,iface);
1411   FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpidGroup );
1412   return DP_OK;
1413 }
1414
1415 static HRESULT WINAPI DirectPlay3AImpl_GetPlayerAccount
1416           ( LPDIRECTPLAY3A iface, DPID idPlayer, DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize )
1417 {
1418   ICOM_THIS(IDirectPlay3Impl,iface);
1419   FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, idPlayer, dwFlags, lpData, lpdwDataSize );
1420   return DP_OK;
1421 }
1422
1423 static HRESULT WINAPI DirectPlay3WImpl_GetPlayerAccount
1424           ( LPDIRECTPLAY3 iface, DPID idPlayer, DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize )
1425 {
1426   ICOM_THIS(IDirectPlay3Impl,iface);
1427   FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, idPlayer, dwFlags, lpData, lpdwDataSize );
1428   return DP_OK;
1429 }
1430
1431 static HRESULT WINAPI DirectPlay3AImpl_GetPlayerFlags
1432           ( LPDIRECTPLAY3A iface, DPID idPlayer, LPDWORD lpdwFlags )
1433 {
1434   ICOM_THIS(IDirectPlay3Impl,iface);
1435   FIXME("(%p)->(0x%08lx,%p): stub\n", This, idPlayer, lpdwFlags );
1436   return DP_OK;
1437 }
1438
1439 static HRESULT WINAPI DirectPlay3WImpl_GetPlayerFlags
1440           ( LPDIRECTPLAY3 iface, DPID idPlayer, LPDWORD lpdwFlags )
1441 {
1442   ICOM_THIS(IDirectPlay3Impl,iface);
1443   FIXME("(%p)->(0x%08lx,%p): stub\n", This, idPlayer, lpdwFlags );
1444   return DP_OK;
1445 }
1446
1447 static HRESULT WINAPI DirectPlay4AImpl_GetGroupOwner
1448           ( LPDIRECTPLAY4A iface, DPID idGroup, LPDPID lpidGroupOwner )
1449 {
1450   ICOM_THIS(IDirectPlay4Impl,iface);
1451   FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpidGroupOwner );
1452   return DP_OK;
1453 }
1454
1455 static HRESULT WINAPI DirectPlay4WImpl_GetGroupOwner
1456           ( LPDIRECTPLAY4 iface, DPID idGroup, LPDPID lpidGroupOwner )
1457 {
1458   ICOM_THIS(IDirectPlay4Impl,iface);
1459   FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpidGroupOwner );
1460   return DP_OK;
1461 }
1462
1463 static HRESULT WINAPI DirectPlay4AImpl_SetGroupOwner
1464           ( LPDIRECTPLAY4A iface, DPID idGroup , DPID idGroupOwner )
1465 {
1466   ICOM_THIS(IDirectPlay4Impl,iface);
1467   FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idGroupOwner );
1468   return DP_OK;
1469 }
1470
1471 static HRESULT WINAPI DirectPlay4WImpl_SetGroupOwner
1472           ( LPDIRECTPLAY4 iface, DPID idGroup , DPID idGroupOwner )
1473 {
1474   ICOM_THIS(IDirectPlay4Impl,iface);
1475   FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idGroupOwner );
1476   return DP_OK;
1477 }
1478
1479 static HRESULT WINAPI DirectPlay4AImpl_SendEx
1480           ( LPDIRECTPLAY4A iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize, DWORD dwPriority, DWORD dwTimeout, LPVOID lpContext, LPDWORD lpdwMsgID )
1481 {
1482   ICOM_THIS(IDirectPlay4Impl,iface);
1483   FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx,0x%08lx,0x%08lx,%p,%p): stub\n", This, idFrom, idTo, dwFlags, lpData, dwDataSize, dwPriority, dwTimeout, lpContext, lpdwMsgID );
1484   return DP_OK;
1485 }
1486
1487 static HRESULT WINAPI DirectPlay4WImpl_SendEx
1488           ( LPDIRECTPLAY4 iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize, DWORD dwPriority, DWORD dwTimeout, LPVOID lpContext, LPDWORD lpdwMsgID )
1489 {
1490   ICOM_THIS(IDirectPlay4Impl,iface);
1491   FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx,0x%08lx,0x%08lx,%p,%p): stub\n", This, idFrom, idTo, dwFlags, lpData, dwDataSize, dwPriority, dwTimeout, lpContext, lpdwMsgID );
1492   return DP_OK;
1493 }
1494
1495 static HRESULT WINAPI DirectPlay4AImpl_GetMessageQueue
1496           ( LPDIRECTPLAY4A iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPDWORD lpdwNumMsgs, LPDWORD lpdwNumBytes )
1497 {
1498   ICOM_THIS(IDirectPlay4Impl,iface);
1499   FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,%p): stub\n", This, idFrom, idTo, dwFlags, lpdwNumMsgs, lpdwNumBytes );
1500   return DP_OK;
1501 }
1502
1503 static HRESULT WINAPI DirectPlay4WImpl_GetMessageQueue
1504           ( LPDIRECTPLAY4 iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPDWORD lpdwNumMsgs, LPDWORD lpdwNumBytes )
1505 {
1506   ICOM_THIS(IDirectPlay4Impl,iface);
1507   FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,%p): stub\n", This, idFrom, idTo, dwFlags, lpdwNumMsgs, lpdwNumBytes );
1508   return DP_OK;
1509 }
1510
1511 static HRESULT WINAPI DirectPlay4AImpl_CancelMessage
1512           ( LPDIRECTPLAY4A iface, DWORD dwMsgID, DWORD dwFlags )
1513 {
1514   ICOM_THIS(IDirectPlay4Impl,iface);
1515   FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, dwMsgID, dwFlags );
1516   return DP_OK;
1517 }
1518
1519 static HRESULT WINAPI DirectPlay4WImpl_CancelMessage
1520           ( LPDIRECTPLAY4 iface, DWORD dwMsgID, DWORD dwFlags )
1521 {
1522   ICOM_THIS(IDirectPlay4Impl,iface);
1523   FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, dwMsgID, dwFlags );
1524   return DP_OK;
1525 }
1526
1527 static HRESULT WINAPI DirectPlay4AImpl_CancelPriority
1528           ( LPDIRECTPLAY4A iface, DWORD dwMinPriority, DWORD dwMaxPriority, DWORD dwFlags )
1529 {
1530   ICOM_THIS(IDirectPlay4Impl,iface);
1531   FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx): stub\n", This, dwMinPriority, dwMaxPriority, dwFlags );
1532   return DP_OK;
1533 }
1534
1535 static HRESULT WINAPI DirectPlay4WImpl_CancelPriority
1536           ( LPDIRECTPLAY4 iface, DWORD dwMinPriority, DWORD dwMaxPriority, DWORD dwFlags )
1537 {
1538   ICOM_THIS(IDirectPlay4Impl,iface);
1539   FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx): stub\n", This, dwMinPriority, dwMaxPriority, dwFlags );
1540   return DP_OK;
1541 }
1542
1543 /* Note: Hack so we can reuse the old functions without compiler warnings */
1544 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1545 # define XCAST(fun)     (typeof(directPlay2WVT.fn##fun))
1546 #else
1547 # define XCAST(fun)     (void*)
1548 #endif
1549
1550 static ICOM_VTABLE(IDirectPlay2) directPlay2WVT = 
1551 {
1552   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1553   DirectPlay2W_QueryInterface,
1554   XCAST(AddRef)DirectPlay2AImpl_AddRef,
1555   XCAST(Release)DirectPlay2AImpl_Release,
1556
1557   DirectPlay2WImpl_AddPlayerToGroup,
1558   DirectPlay2WImpl_Close,
1559   DirectPlay2WImpl_CreateGroup,
1560   DirectPlay2WImpl_CreatePlayer,
1561   DirectPlay2WImpl_DeletePlayerFromGroup,
1562   DirectPlay2WImpl_DestroyGroup,
1563   DirectPlay2WImpl_DestroyPlayer,
1564   DirectPlay2WImpl_EnumGroupPlayers,
1565   DirectPlay2WImpl_EnumGroups,
1566   DirectPlay2WImpl_EnumPlayers,
1567   DirectPlay2WImpl_EnumSessions,
1568   DirectPlay2WImpl_GetCaps,
1569   DirectPlay2WImpl_GetGroupData,
1570   DirectPlay2WImpl_GetGroupName,
1571   DirectPlay2WImpl_GetMessageCount,
1572   DirectPlay2WImpl_GetPlayerAddress,
1573   DirectPlay2WImpl_GetPlayerCaps,
1574   DirectPlay2WImpl_GetPlayerData,
1575   DirectPlay2WImpl_GetPlayerName,
1576   DirectPlay2WImpl_GetSessionDesc,
1577   DirectPlay2WImpl_Initialize,
1578   DirectPlay2WImpl_Open,
1579   DirectPlay2WImpl_Receive,
1580   DirectPlay2WImpl_Send,
1581   DirectPlay2WImpl_SetGroupData,
1582   DirectPlay2WImpl_SetGroupName,
1583   DirectPlay2WImpl_SetPlayerData,
1584   DirectPlay2WImpl_SetPlayerName,
1585   DirectPlay2WImpl_SetSessionDesc
1586 };
1587 #undef XCAST
1588
1589 /* Note: Hack so we can reuse the old functions without compiler warnings */
1590 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1591 # define XCAST(fun)     (typeof(directPlay2AVT.fn##fun))
1592 #else
1593 # define XCAST(fun)     (void*)
1594 #endif
1595
1596 static ICOM_VTABLE(IDirectPlay2) directPlay2AVT = 
1597 {
1598   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1599   DirectPlay2A_QueryInterface,
1600   XCAST(AddRef)DirectPlay2AImpl_AddRef,
1601   XCAST(Release)DirectPlay2AImpl_Release,
1602
1603   DirectPlay2AImpl_AddPlayerToGroup,
1604   DirectPlay2AImpl_Close,
1605   DirectPlay2AImpl_CreateGroup,
1606   DirectPlay2AImpl_CreatePlayer,
1607   DirectPlay2AImpl_DeletePlayerFromGroup,
1608   DirectPlay2AImpl_DestroyGroup,
1609   DirectPlay2AImpl_DestroyPlayer,
1610   DirectPlay2AImpl_EnumGroupPlayers,
1611   DirectPlay2AImpl_EnumGroups,
1612   DirectPlay2AImpl_EnumPlayers,
1613   DirectPlay2AImpl_EnumSessions,
1614   DirectPlay2AImpl_GetCaps,
1615   DirectPlay2AImpl_GetGroupData,
1616   DirectPlay2AImpl_GetGroupName,
1617   DirectPlay2AImpl_GetMessageCount,
1618   DirectPlay2AImpl_GetPlayerAddress,
1619   DirectPlay2AImpl_GetPlayerCaps,
1620   DirectPlay2AImpl_GetPlayerData,
1621   DirectPlay2AImpl_GetPlayerName,
1622   DirectPlay2AImpl_GetSessionDesc,
1623   DirectPlay2AImpl_Initialize,
1624   DirectPlay2AImpl_Open,
1625   DirectPlay2AImpl_Receive,
1626   DirectPlay2AImpl_Send,
1627   DirectPlay2AImpl_SetGroupData,
1628   DirectPlay2AImpl_SetGroupName,
1629   DirectPlay2AImpl_SetPlayerData,
1630   DirectPlay2AImpl_SetPlayerName,
1631   DirectPlay2AImpl_SetSessionDesc
1632 };
1633 #undef XCAST
1634
1635
1636 /* Note: Hack so we can reuse the old functions without compiler warnings */
1637 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1638 # define XCAST(fun)     (typeof(directPlay3AVT.fn##fun))
1639 #else
1640 # define XCAST(fun)     (void*)
1641 #endif
1642
1643 static ICOM_VTABLE(IDirectPlay3) directPlay3AVT = 
1644 {
1645   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1646   DirectPlay3AImpl_QueryInterface,
1647   XCAST(AddRef)DirectPlay2AImpl_AddRef,
1648   XCAST(Release)DirectPlay2AImpl_Release,
1649
1650   XCAST(AddPlayerToGroup)DirectPlay2AImpl_AddPlayerToGroup,
1651   XCAST(Close)DirectPlay2AImpl_Close,
1652   XCAST(CreateGroup)DirectPlay2AImpl_CreateGroup,
1653   XCAST(CreatePlayer)DirectPlay2AImpl_CreatePlayer,
1654   XCAST(DeletePlayerFromGroup)DirectPlay2AImpl_DeletePlayerFromGroup,
1655   XCAST(DestroyGroup)DirectPlay2AImpl_DestroyGroup,
1656   XCAST(DestroyPlayer)DirectPlay2AImpl_DestroyPlayer,
1657   XCAST(EnumGroupPlayers)DirectPlay2AImpl_EnumGroupPlayers,
1658   XCAST(EnumGroups)DirectPlay2AImpl_EnumGroups,
1659   XCAST(EnumPlayers)DirectPlay2AImpl_EnumPlayers,
1660   XCAST(EnumSessions)DirectPlay2AImpl_EnumSessions,
1661   XCAST(GetCaps)DirectPlay2AImpl_GetCaps,
1662   XCAST(GetGroupData)DirectPlay2AImpl_GetGroupData,
1663   XCAST(GetGroupName)DirectPlay2AImpl_GetGroupName,
1664   XCAST(GetMessageCount)DirectPlay2AImpl_GetMessageCount,
1665   XCAST(GetPlayerAddress)DirectPlay2AImpl_GetPlayerAddress,
1666   XCAST(GetPlayerCaps)DirectPlay2AImpl_GetPlayerCaps,
1667   XCAST(GetPlayerData)DirectPlay2AImpl_GetPlayerData,
1668   XCAST(GetPlayerName)DirectPlay2AImpl_GetPlayerName,
1669   XCAST(GetSessionDesc)DirectPlay2AImpl_GetSessionDesc,
1670   XCAST(Initialize)DirectPlay2AImpl_Initialize,
1671   XCAST(Open)DirectPlay2AImpl_Open,
1672   XCAST(Receive)DirectPlay2AImpl_Receive,
1673   XCAST(Send)DirectPlay2AImpl_Send,
1674   XCAST(SetGroupData)DirectPlay2AImpl_SetGroupData,
1675   XCAST(SetGroupName)DirectPlay2AImpl_SetGroupName,
1676   XCAST(SetPlayerData)DirectPlay2AImpl_SetPlayerData,
1677   XCAST(SetPlayerName)DirectPlay2AImpl_SetPlayerName,
1678   XCAST(SetSessionDesc)DirectPlay2AImpl_SetSessionDesc,
1679
1680   DirectPlay3AImpl_AddGroupToGroup,
1681   DirectPlay3AImpl_CreateGroupInGroup,
1682   DirectPlay3AImpl_DeleteGroupFromGroup,
1683   DirectPlay3AImpl_EnumConnections,
1684   DirectPlay3AImpl_EnumGroupsInGroup,
1685   DirectPlay3AImpl_GetGroupConnectionSettings,
1686   DirectPlay3AImpl_InitializeConnection,
1687   DirectPlay3AImpl_SecureOpen,
1688   DirectPlay3AImpl_SendChatMessage,
1689   DirectPlay3AImpl_SetGroupConnectionSettings,
1690   DirectPlay3AImpl_StartSession,
1691   DirectPlay3AImpl_GetGroupFlags,
1692   DirectPlay3AImpl_GetGroupParent,
1693   DirectPlay3AImpl_GetPlayerAccount,
1694   DirectPlay3AImpl_GetPlayerFlags
1695 };
1696 #undef XCAST
1697
1698 /* Note: Hack so we can reuse the old functions without compiler warnings */
1699 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1700 # define XCAST(fun)     (typeof(directPlay3WVT.fn##fun))
1701 #else
1702 # define XCAST(fun)     (void*)
1703 #endif
1704 static ICOM_VTABLE(IDirectPlay3) directPlay3WVT = 
1705 {
1706   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1707   DirectPlay3WImpl_QueryInterface,
1708   XCAST(AddRef)DirectPlay2AImpl_AddRef,
1709   XCAST(Release)DirectPlay2AImpl_Release,
1710
1711   XCAST(AddPlayerToGroup)DirectPlay2WImpl_AddPlayerToGroup,
1712   XCAST(Close)DirectPlay2WImpl_Close,
1713   XCAST(CreateGroup)DirectPlay2WImpl_CreateGroup,
1714   XCAST(CreatePlayer)DirectPlay2WImpl_CreatePlayer,
1715   XCAST(DeletePlayerFromGroup)DirectPlay2WImpl_DeletePlayerFromGroup,
1716   XCAST(DestroyGroup)DirectPlay2WImpl_DestroyGroup,
1717   XCAST(DestroyPlayer)DirectPlay2WImpl_DestroyPlayer,
1718   XCAST(EnumGroupPlayers)DirectPlay2WImpl_EnumGroupPlayers,
1719   XCAST(EnumGroups)DirectPlay2WImpl_EnumGroups,
1720   XCAST(EnumPlayers)DirectPlay2WImpl_EnumPlayers,
1721   XCAST(EnumSessions)DirectPlay2WImpl_EnumSessions,
1722   XCAST(GetCaps)DirectPlay2WImpl_GetCaps,
1723   XCAST(GetGroupData)DirectPlay2WImpl_GetGroupData,
1724   XCAST(GetGroupName)DirectPlay2WImpl_GetGroupName,
1725   XCAST(GetMessageCount)DirectPlay2WImpl_GetMessageCount,
1726   XCAST(GetPlayerAddress)DirectPlay2WImpl_GetPlayerAddress,
1727   XCAST(GetPlayerCaps)DirectPlay2WImpl_GetPlayerCaps,
1728   XCAST(GetPlayerData)DirectPlay2WImpl_GetPlayerData,
1729   XCAST(GetPlayerName)DirectPlay2WImpl_GetPlayerName,
1730   XCAST(GetSessionDesc)DirectPlay2WImpl_GetSessionDesc,
1731   XCAST(Initialize)DirectPlay2WImpl_Initialize,
1732   XCAST(Open)DirectPlay2WImpl_Open,
1733   XCAST(Receive)DirectPlay2WImpl_Receive,
1734   XCAST(Send)DirectPlay2WImpl_Send,
1735   XCAST(SetGroupData)DirectPlay2WImpl_SetGroupData,
1736   XCAST(SetGroupName)DirectPlay2WImpl_SetGroupName,
1737   XCAST(SetPlayerData)DirectPlay2WImpl_SetPlayerData,
1738   XCAST(SetPlayerName)DirectPlay2WImpl_SetPlayerName,
1739   XCAST(SetSessionDesc)DirectPlay2WImpl_SetSessionDesc,
1740
1741   DirectPlay3WImpl_AddGroupToGroup,
1742   DirectPlay3WImpl_CreateGroupInGroup,
1743   DirectPlay3WImpl_DeleteGroupFromGroup,
1744   DirectPlay3WImpl_EnumConnections,
1745   DirectPlay3WImpl_EnumGroupsInGroup,
1746   DirectPlay3WImpl_GetGroupConnectionSettings,
1747   DirectPlay3WImpl_InitializeConnection,
1748   DirectPlay3WImpl_SecureOpen,
1749   DirectPlay3WImpl_SendChatMessage,
1750   DirectPlay3WImpl_SetGroupConnectionSettings,
1751   DirectPlay3WImpl_StartSession,
1752   DirectPlay3WImpl_GetGroupFlags,
1753   DirectPlay3WImpl_GetGroupParent,
1754   DirectPlay3WImpl_GetPlayerAccount,
1755   DirectPlay3WImpl_GetPlayerFlags
1756 };
1757 #undef XCAST
1758
1759 /* Note: Hack so we can reuse the old functions without compiler warnings */
1760 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1761 # define XCAST(fun)     (typeof(directPlay4WVT.fn##fun))
1762 #else
1763 # define XCAST(fun)     (void*)
1764 #endif
1765 static ICOM_VTABLE(IDirectPlay4) directPlay4WVT =
1766 {
1767   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1768   DirectPlay4WImpl_QueryInterface,
1769   XCAST(AddRef)DirectPlay2AImpl_AddRef,
1770   XCAST(Release)DirectPlay2AImpl_Release,
1771
1772   XCAST(AddPlayerToGroup)DirectPlay2WImpl_AddPlayerToGroup,
1773   XCAST(Close)DirectPlay2WImpl_Close,
1774   XCAST(CreateGroup)DirectPlay2WImpl_CreateGroup,
1775   XCAST(CreatePlayer)DirectPlay2WImpl_CreatePlayer,
1776   XCAST(DeletePlayerFromGroup)DirectPlay2WImpl_DeletePlayerFromGroup,
1777   XCAST(DestroyGroup)DirectPlay2WImpl_DestroyGroup,
1778   XCAST(DestroyPlayer)DirectPlay2WImpl_DestroyPlayer,
1779   XCAST(EnumGroupPlayers)DirectPlay2WImpl_EnumGroupPlayers,
1780   XCAST(EnumGroups)DirectPlay2WImpl_EnumGroups,
1781   XCAST(EnumPlayers)DirectPlay2WImpl_EnumPlayers,
1782   XCAST(EnumSessions)DirectPlay2WImpl_EnumSessions,
1783   XCAST(GetCaps)DirectPlay2WImpl_GetCaps,
1784   XCAST(GetGroupData)DirectPlay2WImpl_GetGroupData,
1785   XCAST(GetGroupName)DirectPlay2WImpl_GetGroupName,
1786   XCAST(GetMessageCount)DirectPlay2WImpl_GetMessageCount,
1787   XCAST(GetPlayerAddress)DirectPlay2WImpl_GetPlayerAddress,
1788   XCAST(GetPlayerCaps)DirectPlay2WImpl_GetPlayerCaps,
1789   XCAST(GetPlayerData)DirectPlay2WImpl_GetPlayerData,
1790   XCAST(GetPlayerName)DirectPlay2WImpl_GetPlayerName,
1791   XCAST(GetSessionDesc)DirectPlay2WImpl_GetSessionDesc,
1792   XCAST(Initialize)DirectPlay2WImpl_Initialize,
1793   XCAST(Open)DirectPlay2WImpl_Open,
1794   XCAST(Receive)DirectPlay2WImpl_Receive,
1795   XCAST(Send)DirectPlay2WImpl_Send,
1796   XCAST(SetGroupData)DirectPlay2WImpl_SetGroupData,
1797   XCAST(SetGroupName)DirectPlay2WImpl_SetGroupName,
1798   XCAST(SetPlayerData)DirectPlay2WImpl_SetPlayerData,
1799   XCAST(SetPlayerName)DirectPlay2WImpl_SetPlayerName,
1800   XCAST(SetSessionDesc)DirectPlay2WImpl_SetSessionDesc,
1801
1802   XCAST(AddGroupToGroup)DirectPlay3WImpl_AddGroupToGroup,
1803   XCAST(CreateGroupInGroup)DirectPlay3WImpl_CreateGroupInGroup,
1804   XCAST(DeleteGroupFromGroup)DirectPlay3WImpl_DeleteGroupFromGroup,
1805   XCAST(EnumConnections)DirectPlay3WImpl_EnumConnections,
1806   XCAST(EnumGroupsInGroup)DirectPlay3WImpl_EnumGroupsInGroup,
1807   XCAST(GetGroupConnectionSettings)DirectPlay3WImpl_GetGroupConnectionSettings,
1808   XCAST(InitializeConnection)DirectPlay3WImpl_InitializeConnection,
1809   XCAST(SecureOpen)DirectPlay3WImpl_SecureOpen,
1810   XCAST(SendChatMessage)DirectPlay3WImpl_SendChatMessage,
1811   XCAST(SetGroupConnectionSettings)DirectPlay3WImpl_SetGroupConnectionSettings,
1812   XCAST(StartSession)DirectPlay3WImpl_StartSession,
1813   XCAST(GetGroupFlags)DirectPlay3WImpl_GetGroupFlags,
1814   XCAST(GetGroupParent)DirectPlay3WImpl_GetGroupParent,
1815   XCAST(GetPlayerAccount)DirectPlay3WImpl_GetPlayerAccount,
1816   XCAST(GetPlayerFlags)DirectPlay3WImpl_GetPlayerFlags,
1817
1818   DirectPlay4WImpl_GetGroupOwner,
1819   DirectPlay4WImpl_SetGroupOwner,
1820   DirectPlay4WImpl_SendEx,
1821   DirectPlay4WImpl_GetMessageQueue,
1822   DirectPlay4WImpl_CancelMessage,
1823   DirectPlay4WImpl_CancelPriority
1824 };
1825 #undef XCAST
1826
1827
1828 /* Note: Hack so we can reuse the old functions without compiler warnings */
1829 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1830 # define XCAST(fun)     (typeof(directPlay4AVT.fn##fun))
1831 #else
1832 # define XCAST(fun)     (void*)
1833 #endif
1834 static ICOM_VTABLE(IDirectPlay4) directPlay4AVT =
1835 {
1836   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1837   DirectPlay4AImpl_QueryInterface,
1838   XCAST(AddRef)DirectPlay2AImpl_AddRef,
1839   XCAST(Release)DirectPlay2AImpl_Release,
1840
1841   XCAST(AddPlayerToGroup)DirectPlay2AImpl_AddPlayerToGroup,
1842   XCAST(Close)DirectPlay2AImpl_Close,
1843   XCAST(CreateGroup)DirectPlay2AImpl_CreateGroup,
1844   XCAST(CreatePlayer)DirectPlay2AImpl_CreatePlayer,
1845   XCAST(DeletePlayerFromGroup)DirectPlay2AImpl_DeletePlayerFromGroup,
1846   XCAST(DestroyGroup)DirectPlay2AImpl_DestroyGroup,
1847   XCAST(DestroyPlayer)DirectPlay2AImpl_DestroyPlayer,
1848   XCAST(EnumGroupPlayers)DirectPlay2AImpl_EnumGroupPlayers,
1849   XCAST(EnumGroups)DirectPlay2AImpl_EnumGroups,
1850   XCAST(EnumPlayers)DirectPlay2AImpl_EnumPlayers,
1851   XCAST(EnumSessions)DirectPlay2AImpl_EnumSessions,
1852   XCAST(GetCaps)DirectPlay2AImpl_GetCaps,
1853   XCAST(GetGroupData)DirectPlay2AImpl_GetGroupData,
1854   XCAST(GetGroupName)DirectPlay2AImpl_GetGroupName,
1855   XCAST(GetMessageCount)DirectPlay2AImpl_GetMessageCount,
1856   XCAST(GetPlayerAddress)DirectPlay2AImpl_GetPlayerAddress,
1857   XCAST(GetPlayerCaps)DirectPlay2AImpl_GetPlayerCaps,
1858   XCAST(GetPlayerData)DirectPlay2AImpl_GetPlayerData,
1859   XCAST(GetPlayerName)DirectPlay2AImpl_GetPlayerName,
1860   XCAST(GetSessionDesc)DirectPlay2AImpl_GetSessionDesc,
1861   XCAST(Initialize)DirectPlay2AImpl_Initialize,
1862   XCAST(Open)DirectPlay2AImpl_Open,
1863   XCAST(Receive)DirectPlay2AImpl_Receive,
1864   XCAST(Send)DirectPlay2AImpl_Send,
1865   XCAST(SetGroupData)DirectPlay2AImpl_SetGroupData,
1866   XCAST(SetGroupName)DirectPlay2AImpl_SetGroupName,
1867   XCAST(SetPlayerData)DirectPlay2AImpl_SetPlayerData,
1868   XCAST(SetPlayerName)DirectPlay2AImpl_SetPlayerName,
1869   XCAST(SetSessionDesc)DirectPlay2AImpl_SetSessionDesc,
1870
1871   XCAST(AddGroupToGroup)DirectPlay3AImpl_AddGroupToGroup,
1872   XCAST(CreateGroupInGroup)DirectPlay3AImpl_CreateGroupInGroup,
1873   XCAST(DeleteGroupFromGroup)DirectPlay3AImpl_DeleteGroupFromGroup,
1874   XCAST(EnumConnections)DirectPlay3AImpl_EnumConnections,
1875   XCAST(EnumGroupsInGroup)DirectPlay3AImpl_EnumGroupsInGroup,
1876   XCAST(GetGroupConnectionSettings)DirectPlay3AImpl_GetGroupConnectionSettings,
1877   XCAST(InitializeConnection)DirectPlay3AImpl_InitializeConnection,
1878   XCAST(SecureOpen)DirectPlay3AImpl_SecureOpen,
1879   XCAST(SendChatMessage)DirectPlay3AImpl_SendChatMessage,
1880   XCAST(SetGroupConnectionSettings)DirectPlay3AImpl_SetGroupConnectionSettings,
1881   XCAST(StartSession)DirectPlay3AImpl_StartSession,
1882   XCAST(GetGroupFlags)DirectPlay3AImpl_GetGroupFlags,
1883   XCAST(GetGroupParent)DirectPlay3AImpl_GetGroupParent,
1884   XCAST(GetPlayerAccount)DirectPlay3AImpl_GetPlayerAccount,
1885   XCAST(GetPlayerFlags)DirectPlay3AImpl_GetPlayerFlags,
1886
1887   DirectPlay4AImpl_GetGroupOwner,
1888   DirectPlay4AImpl_SetGroupOwner,
1889   DirectPlay4AImpl_SendEx,
1890   DirectPlay4AImpl_GetMessageQueue,
1891   DirectPlay4AImpl_CancelMessage,
1892   DirectPlay4AImpl_CancelPriority
1893 };
1894 #undef XCAST
1895
1896
1897 /***************************************************************************
1898  *  DirectPlayEnumerateA (DPLAYX.2) 
1899  *
1900  *  The pointer to the structure lpContext will be filled with the 
1901  *  appropriate data for each service offered by the OS. These services are
1902  *  not necessarily available on this particular machine but are defined
1903  *  as simple service providers under the "Service Providers" registry key.
1904  *  This structure is then passed to lpEnumCallback for each of the different 
1905  *  services. 
1906  *
1907  *  This API is useful only for applications written using DirectX3 or
1908  *  worse. It is superceeded by IDirectPlay3::EnumConnections which also
1909  *  gives information on the actual connections.
1910  *
1911  * defn of a service provider:
1912  * A dynamic-link library used by DirectPlay to communicate over a network. 
1913  * The service provider contains all the network-specific code required
1914  * to send and receive messages. Online services and network operators can
1915  * supply service providers to use specialized hardware, protocols, communications
1916  * media, and network resources. 
1917  *
1918  * TODO: Allocate string buffer space from the heap (length from reg)
1919  *       Pass real device driver numbers...
1920  *       Get the GUID properly...
1921  */
1922 HRESULT WINAPI DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback,
1923                                      LPVOID lpContext )
1924 {
1925
1926   HKEY   hkResult; 
1927   LPCSTR searchSubKey    = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
1928   DWORD  dwIndex;
1929   DWORD  sizeOfSubKeyName=50;
1930   char   subKeyName[51]; 
1931
1932   TRACE(": lpEnumCallback=%p lpContext=%p\n", lpEnumCallback, lpContext );
1933
1934   if( !lpEnumCallback || !*lpEnumCallback )
1935   {
1936      return DPERR_INVALIDPARAMS;
1937   }
1938
1939   /* Need to loop over the service providers in the registry */
1940   if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
1941                        0, KEY_ENUMERATE_SUB_KEYS, &hkResult ) != ERROR_SUCCESS )
1942   {
1943     /* Hmmm. Does this mean that there are no service providers? */ 
1944     ERR(": no service providers?\n");
1945     return DP_OK; 
1946   }
1947
1948   /* Traverse all the service providers we have available */
1949   for( dwIndex=0;
1950        RegEnumKeyA( hkResult, dwIndex, subKeyName, sizeOfSubKeyName ) != ERROR_NO_MORE_ITEMS;
1951        ++dwIndex )
1952   {
1953     LPSTR    majVerDataSubKey = "dwReserved1";  
1954     LPSTR    minVerDataSubKey = "dwReserved2";  
1955     LPSTR    guidDataSubKey   = "Guid";
1956     HKEY     hkServiceProvider;
1957     GUID     serviceProviderGUID;
1958     DWORD    returnTypeGUID, returnTypeReserved, sizeOfReturnBuffer = 50;
1959     char     returnBuffer[51];
1960     DWORD    majVersionNum , minVersionNum = 0;
1961     LPWSTR   lpWGUIDString; 
1962
1963     TRACE(" this time through: %s\n", subKeyName );
1964
1965     /* Get a handle for this particular service provider */
1966     if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_QUERY_VALUE,
1967                          &hkServiceProvider ) != ERROR_SUCCESS )
1968     {
1969       ERR(": what the heck is going on?\n" );
1970       continue;
1971     }
1972
1973     /* Get the GUID, Device major number and device minor number 
1974      * from the registry. 
1975      */
1976     if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
1977                             NULL, &returnTypeGUID, returnBuffer,
1978                             &sizeOfReturnBuffer ) != ERROR_SUCCESS )
1979     {
1980       ERR(": missing GUID registry data members\n" );
1981       continue; 
1982     }
1983
1984     /* FIXME: Check return types to ensure we're interpreting data right */
1985     lpWGUIDString = HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer );
1986     CLSIDFromString( (LPCOLESTR)lpWGUIDString, &serviceProviderGUID ); 
1987     HeapFree( GetProcessHeap(), 0, lpWGUIDString );
1988
1989     /* FIXME: Need to know which of dwReserved1 and dwReserved2 are maj and min */
1990
1991     sizeOfReturnBuffer = 50;
1992     if( RegQueryValueExA( hkServiceProvider, majVerDataSubKey,
1993                             NULL, &returnTypeReserved, returnBuffer,
1994                             &sizeOfReturnBuffer ) != ERROR_SUCCESS )
1995     {
1996       ERR(": missing dwReserved1 registry data members\n") ;
1997       continue; 
1998     }
1999
2000     majVersionNum = GET_DWORD( returnBuffer );
2001
2002     sizeOfReturnBuffer = 50;
2003     if( RegQueryValueExA( hkServiceProvider, minVerDataSubKey,
2004                             NULL, &returnTypeReserved, returnBuffer,
2005                             &sizeOfReturnBuffer ) != ERROR_SUCCESS )
2006     {
2007       ERR(": missing dwReserved2 registry data members\n") ;
2008       continue;
2009     }
2010
2011     minVersionNum = GET_DWORD( returnBuffer );
2012
2013
2014     /* The enumeration will return FALSE if we are not to continue */
2015     if( !lpEnumCallback( &serviceProviderGUID , subKeyName,
2016                          majVersionNum, minVersionNum, lpContext ) )
2017     {
2018       WARN("lpEnumCallback returning FALSE\n" );
2019       break;
2020     }
2021   }
2022
2023   return DP_OK;
2024
2025 }
2026
2027 /***************************************************************************
2028  *  DirectPlayEnumerateW (DPLAYX.3)
2029  *
2030  */
2031 HRESULT WINAPI DirectPlayEnumerateW( LPDPENUMDPCALLBACKW lpEnumCallback, LPVOID lpContext )
2032 {
2033
2034   FIXME(":stub\n");
2035
2036   return DPERR_OUTOFMEMORY; 
2037
2038 }
2039
2040 /***************************************************************************
2041  *  DirectPlayCreate (DPLAYX.1) (DPLAY.1)
2042  *
2043  */
2044 HRESULT WINAPI DirectPlayCreate
2045 ( LPGUID lpGUID, LPDIRECTPLAY2 *lplpDP, IUnknown *pUnk)
2046 {
2047   TRACE( "lpGUID=%s lplpDP=%p pUnk=%p\n", debugstr_guid(lpGUID), lplpDP, pUnk );
2048
2049   if( pUnk != NULL )
2050   {
2051     return CLASS_E_NOAGGREGATION;
2052   }
2053
2054
2055   /* Create an IDirectPlay object. We don't support that so we'll cheat and
2056      give them an IDirectPlay2A object and hope that doesn't cause problems */
2057   if( directPlay_QueryInterface( &IID_IDirectPlay2A, (LPVOID*)lplpDP ) != DP_OK )
2058   {
2059     return DPERR_UNAVAILABLE;
2060   } 
2061
2062   if( IsEqualGUID( &GUID_NULL, lpGUID ) )
2063   {
2064     /* The GUID_NULL means don't bind a service provider. Just return the
2065        interface */ 
2066     return DP_OK;
2067   }
2068
2069
2070   /* Bind the desired service provider */
2071   if( ( IsEqualGUID( lpGUID, &DPSPGUID_MODEM ) ) ||
2072       ( IsEqualGUID( lpGUID, &DPSPGUID_SERIAL ) ) ||
2073       ( IsEqualGUID( lpGUID, &DPSPGUID_TCPIP ) ) ||
2074       ( IsEqualGUID( lpGUID, &DPSPGUID_IPX ) ) 
2075     )
2076   {
2077      FIXME( "Service provider binding not supported yet\n" );
2078      IDirectPlayX_Release( *lplpDP );
2079      *lplpDP = NULL;
2080      return DPERR_INVALIDPARAMS; 
2081   }
2082
2083   ERR( "unknown Service Provider %s\n", debugstr_guid(lpGUID) );
2084
2085   IDirectPlayX_Release( *lplpDP );
2086   *lplpDP = NULL;
2087
2088   return DPERR_INVALIDPARAMS;
2089 }