Changed the first parameter from LPGUID (Windows headers) to REFGUID.
[wine] / multimedia / dplay.c
1 /* Direct Play 3 and Direct Play Lobby 2 Implementation
2  *
3  * Copyright 1998,1999 - Peter Hunnisett
4  *
5  * <presently under construction - contact hunnise@nortelnetworks.com>
6  *
7  */
8 #include "heap.h"
9 #include "winerror.h"
10 #include "debug.h"
11 #include "winnt.h"
12 #include "winreg.h"
13 #include "dplay.h"
14
15 #include "thread.h"
16
17 struct IDirectPlayLobby {
18     LPDIRECTPLAYLOBBY_VTABLE lpVtbl;
19     ULONG                    ref;
20     DWORD                    dwConnFlags;
21     DPSESSIONDESC2           sessionDesc;
22     DPNAME                   playerName;
23     GUID                     guidSP;
24     LPVOID                   lpAddress;
25     DWORD                    dwAddressSize;
26 };
27
28 struct IDirectPlayLobby2 {
29     LPDIRECTPLAYLOBBY2_VTABLE lpVtbl;
30     ULONG                     ref;
31     DWORD                     dwConnFlags;
32     DPSESSIONDESC2            lpSessionDesc;
33     DPNAME                    lpPlayerName;
34     GUID                      guidSP;
35     LPVOID                    lpAddress;
36     DWORD                     dwAddressSize;
37 };
38
39
40 /* Forward declarations of virtual tables */
41 static DIRECTPLAYLOBBY_VTABLE  directPlayLobbyAVT;
42 static DIRECTPLAYLOBBY_VTABLE  directPlayLobbyWVT;
43 static DIRECTPLAYLOBBY2_VTABLE directPlayLobby2AVT;
44 static DIRECTPLAYLOBBY2_VTABLE directPlayLobby2WVT;
45
46
47 static DIRECTPLAY2_VTABLE directPlay2WVT;
48 static DIRECTPLAY2_VTABLE directPlay2AVT;
49 static DIRECTPLAY3_VTABLE directPlay3WVT;
50 static DIRECTPLAY3_VTABLE directPlay3AVT;
51
52
53
54
55 struct IDirectPlay2 {
56   LPDIRECTPLAY2_VTABLE lpVtbl;
57   ULONG                ref;
58 };
59
60 struct IDirectPlay3 {
61   LPDIRECTPLAY3_VTABLE lpVtbl;
62   ULONG                ref;
63 };
64
65 /* Routine called when starting up the server thread */
66 DWORD DPLobby_Spawn_Server( LPVOID startData )
67 {
68   DPSESSIONDESC2* lpSession = (DPSESSIONDESC2*) startData;
69   DWORD sessionDwFlags = lpSession->dwFlags;
70  
71   TRACE( dplay, "spawing thread for lpConn=%p dwFlags=%08lx\n", lpSession, sessionDwFlags );
72   FIXME( dplay, "thread needs something to do\n" ); 
73
74 /*for(;;)*/
75   {
76      
77     /* Check out the connection flags to determine what to do. Ensure we have 
78        no leftover bits in this structure */
79     if( sessionDwFlags & DPSESSION_CLIENTSERVER )
80     {
81        /* This indicates that the application which is requesting the creation
82         * of this session is going to be the server (application/player)
83         */ 
84        if( sessionDwFlags & DPSESSION_SECURESERVER )
85        {
86          sessionDwFlags &= ~DPSESSION_SECURESERVER; 
87        }
88        sessionDwFlags &= ~DPSESSION_CLIENTSERVER;  
89     }
90
91     if( sessionDwFlags & DPSESSION_JOINDISABLED )
92     {
93        sessionDwFlags &= ~DPSESSION_JOINDISABLED; 
94     } 
95
96     if( sessionDwFlags & DPSESSION_KEEPALIVE )
97     {
98        sessionDwFlags &= ~DPSESSION_KEEPALIVE;
99     }
100
101     if( sessionDwFlags & DPSESSION_MIGRATEHOST )
102     {
103        sessionDwFlags &= ~DPSESSION_MIGRATEHOST;
104     }
105
106     if( sessionDwFlags & DPSESSION_MULTICASTSERVER )
107     {
108        sessionDwFlags &= ~DPSESSION_MULTICASTSERVER;
109     }
110
111     if( sessionDwFlags & DPSESSION_NEWPLAYERSDISABLED )
112     {
113        sessionDwFlags &= ~DPSESSION_NEWPLAYERSDISABLED; 
114     }
115
116     if( sessionDwFlags & DPSESSION_NODATAMESSAGES )
117     {
118        sessionDwFlags &= ~DPSESSION_NODATAMESSAGES; 
119     } 
120
121     if( sessionDwFlags & DPSESSION_NOMESSAGEID )
122     {
123        sessionDwFlags &= ~DPSESSION_NOMESSAGEID;
124     }
125
126     if( sessionDwFlags & DPSESSION_PASSWORDREQUIRED )
127     {
128        sessionDwFlags &= ~DPSESSION_PASSWORDREQUIRED;
129     }
130
131   }
132
133   ExitThread(0);
134   return 0; 
135 }
136
137
138 /*********************************************************
139  *
140  * Direct Play and Direct Play Lobby Interface Implementation 
141  * 
142  *********************************************************/ 
143
144 /* The COM interface for upversioning an interface
145  * We've been given a GUID (riid) and we need to replace the present
146  * interface with that of the requested interface.
147  *
148  * Snip from some Microsoft document:
149  * There are four requirements for implementations of QueryInterface (In these
150  * cases, "must succeed" means "must succeed barring catastrophic failure."):
151  *
152  *  * The set of interfaces accessible on an object through
153  *    IUnknown::QueryInterface must be static, not dynamic. This means that
154  *    if a call to QueryInterface for a pointer to a specified interface
155  *    succeeds the first time, it must succeed again, and if it fails the
156  *    first time, it must fail on all subsequent queries.
157  *  * It must be symmetric ~W if a client holds a pointer to an interface on
158  *    an object, and queries for that interface, the call must succeed.
159  *  * It must be reflexive ~W if a client holding a pointer to one interface
160  *    queries successfully for another, a query through the obtained pointer
161  *    for the first interface must succeed.
162  *  * It must be transitive ~W if a client holding a pointer to one interface
163  *    queries successfully for a second, and through that pointer queries
164  *    successfully for a third interface, a query for the first interface
165  *    through the pointer for the third interface must succeed.
166  *
167  *  As you can see, this interface doesn't qualify but will most likely
168  *  be good enough for the time being.
169  */
170
171 /* Helper function for DirectPlayLobby  QueryInterface */ 
172 static HRESULT directPlayLobby_QueryInterface
173          ( REFIID riid, LPVOID* ppvObj )
174 {
175
176   if( IsEqualGUID( &IID_IDirectPlayLobby, riid ) )
177   {
178      LPDIRECTPLAYLOBBY lpDpL = (LPDIRECTPLAYLOBBY)(*ppvObj);
179
180      lpDpL = (LPDIRECTPLAYLOBBY)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
181                                            sizeof( *lpDpL ) );
182
183     if( !lpDpL )
184     {
185       return E_NOINTERFACE;
186     }
187
188     lpDpL->lpVtbl = &directPlayLobbyWVT;
189     lpDpL->ref    = 1;
190
191     return S_OK;
192   }
193   else if( IsEqualGUID( &IID_IDirectPlayLobbyA, riid ) )
194   {
195      LPDIRECTPLAYLOBBYA lpDpL = (LPDIRECTPLAYLOBBYA)(*ppvObj);
196
197      lpDpL = (LPDIRECTPLAYLOBBYA)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
198                                             sizeof( *lpDpL ) );
199
200     if( !lpDpL )
201     {
202       return E_NOINTERFACE;
203     }
204
205     lpDpL->lpVtbl = &directPlayLobbyAVT;
206     lpDpL->ref    = 1;
207
208     return S_OK;
209   }
210   else if( IsEqualGUID( &IID_IDirectPlayLobby2, riid ) )
211   {
212      LPDIRECTPLAYLOBBY2 lpDpL = (LPDIRECTPLAYLOBBY2)(*ppvObj);
213
214      lpDpL = (LPDIRECTPLAYLOBBY2)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
215                                              sizeof( *lpDpL ) );
216
217     if( !lpDpL )
218     {
219       return E_NOINTERFACE;
220     }
221
222     lpDpL->lpVtbl = &directPlayLobby2WVT;
223     lpDpL->ref    = 1;
224
225     return S_OK;
226   }
227   else if( IsEqualGUID( &IID_IDirectPlayLobby2A, riid ) )
228   {
229      LPDIRECTPLAYLOBBY2A lpDpL = (LPDIRECTPLAYLOBBY2A)(*ppvObj);
230
231      lpDpL = (LPDIRECTPLAYLOBBY2)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
232                                              sizeof( *lpDpL ) );
233
234     if( !lpDpL )
235     {
236       return E_NOINTERFACE;
237     }
238
239     lpDpL->lpVtbl = &directPlayLobby2AVT;
240     lpDpL->ref    = 1;
241
242     return S_OK;
243   }
244
245   /* Unknown interface */
246   *ppvObj = NULL;
247   return E_NOINTERFACE;
248 }
249 static HRESULT WINAPI IDirectPlayLobbyA_QueryInterface
250 ( LPDIRECTPLAYLOBBYA this,
251   REFIID riid,
252   LPVOID* ppvObj )
253 {
254   TRACE( dplay, "(%p)->(%p,%p)\n", this, riid, ppvObj );
255
256   if( IsEqualGUID( &IID_IUnknown, riid )  ||
257       IsEqualGUID( &IID_IDirectPlayLobbyA, riid )
258     )
259   {
260     this->lpVtbl->fnAddRef( this );
261     *ppvObj = this;
262     return S_OK;
263   }
264
265   return directPlayLobby_QueryInterface( riid, ppvObj );
266
267 }
268
269 static HRESULT WINAPI IDirectPlayLobbyW_QueryInterface
270 ( LPDIRECTPLAYLOBBY this,
271   REFIID riid,
272   LPVOID* ppvObj )
273 {
274   TRACE( dplay, "(%p)->(%p,%p)\n", this, riid, ppvObj );
275
276   if( IsEqualGUID( &IID_IUnknown, riid )  ||
277       IsEqualGUID( &IID_IDirectPlayLobby, riid )
278     )
279   {
280     this->lpVtbl->fnAddRef( this );
281     *ppvObj = this;
282     return S_OK;
283   }
284
285   return directPlayLobby_QueryInterface( riid, ppvObj );
286 }
287
288
289 static HRESULT WINAPI IDirectPlayLobby2A_QueryInterface
290 ( LPDIRECTPLAYLOBBY2A this,
291   REFIID riid,
292   LPVOID* ppvObj )
293 {
294   TRACE( dplay, "(%p)->(%p,%p)\n", this, riid, ppvObj );
295
296   /* Compare riids. We know this object is a direct play lobby 2A object.
297      If we are asking about the same type of interface we're fine.
298    */
299   if( IsEqualGUID( &IID_IUnknown, riid )  ||
300       IsEqualGUID( &IID_IDirectPlayLobby2A, riid )
301     )
302   {
303     this->lpVtbl->fnAddRef( this );
304     *ppvObj = this;
305     return S_OK;
306   }
307   return directPlayLobby_QueryInterface( riid, ppvObj ); 
308 };
309
310 static HRESULT WINAPI IDirectPlayLobby2W_QueryInterface
311 ( LPDIRECTPLAYLOBBY2 this,
312   REFIID riid,
313   LPVOID* ppvObj )
314 {
315
316   /* Compare riids. We know this object is a direct play lobby 2 object.
317      If we are asking about the same type of interface we're fine.
318    */
319   if( IsEqualGUID( &IID_IUnknown, riid ) ||
320       IsEqualGUID( &IID_IDirectPlayLobby2, riid ) 
321     )
322   {
323     this->lpVtbl->fnAddRef( this );
324     *ppvObj = this;
325     return S_OK;
326   }
327
328   return directPlayLobby_QueryInterface( riid, ppvObj ); 
329
330 };
331
332 /* 
333  * Simple procedure. Just increment the reference count to this
334  * structure and return the new reference count.
335  */
336 static ULONG WINAPI IDirectPlayLobby2A_AddRef
337 ( LPDIRECTPLAYLOBBY2A this )
338 {
339   ++(this->ref);
340   TRACE( dplay,"ref count now %lu\n", this->ref );
341   return (this->ref);
342 };
343
344 static ULONG WINAPI IDirectPlayLobby2W_AddRef
345 ( LPDIRECTPLAYLOBBY2 this )
346 {
347   return IDirectPlayLobby2A_AddRef( (LPDIRECTPLAYLOBBY2) this );
348 };
349
350
351 /*
352  * Simple COM procedure. Decrease the reference count to this object.
353  * If the object no longer has any reference counts, free up the associated
354  * memory.
355  */
356 static ULONG WINAPI IDirectPlayLobby2A_Release
357 ( LPDIRECTPLAYLOBBY2A this )
358 {
359   TRACE( dplay, "ref count decremeneted from %lu\n", this->ref );
360
361   this->ref--;
362
363   /* Deallocate if this is the last reference to the object */
364   if( !(this->ref) )
365   {
366     FIXME( dplay, "memory leak\n" );
367     /* Implement memory deallocation */
368
369     HeapFree( GetProcessHeap(), 0, this );
370
371     return 0;
372   }
373
374   return this->ref;
375 };
376
377 static ULONG WINAPI IDirectPlayLobby2W_Release
378 ( LPDIRECTPLAYLOBBY2 this )
379 {
380   return IDirectPlayLobby2A_Release( (LPDIRECTPLAYLOBBY2A) this );
381 };
382
383
384 /********************************************************************
385  * 
386  * Connects an application to the session specified by the DPLCONNECTION
387  * structure currently stored with the DirectPlayLobby object.
388  *
389  * Returns a IDirectPlay interface.
390  *
391  */
392 static HRESULT WINAPI IDirectPlayLobby2A_Connect
393 ( LPDIRECTPLAYLOBBY2A this,
394   DWORD dwFlags,
395   LPDIRECTPLAY2* lplpDP,
396   IUnknown* pUnk)
397 {
398   FIXME( dplay, ": dwFlags=%08lx %p %p stub\n", dwFlags, lplpDP, pUnk );
399   return DPERR_OUTOFMEMORY;
400 };
401
402 static HRESULT WINAPI IDirectPlayLobby2W_Connect
403 ( LPDIRECTPLAYLOBBY2 this,
404   DWORD dwFlags,
405   LPDIRECTPLAY2* lplpDP,
406   IUnknown* pUnk)
407 {
408   LPDIRECTPLAY2* directPlay2W;
409   HRESULT        createRC;
410
411   FIXME( dplay, "(%p)->(%08lx,%p,%p): stub\n", this, dwFlags, lplpDP, pUnk );
412
413   if( dwFlags )
414   {
415      return DPERR_INVALIDPARAMS;
416   }
417
418   if( ( createRC = DirectPlayCreate( (LPGUID)&IID_IDirectPlayLobby2, lplpDP, pUnk ) ) != DP_OK )
419   {
420      ERR( dplay, "error creating Direct Play 2W interface. Return Code = %ld.\n", createRC );
421      return createRC;
422   } 
423
424   /* This should invoke IDirectPlay3::InitializeConnection IDirectPlay3::Open */  
425   directPlay2W = lplpDP; 
426  
427     
428
429
430 #if 0
431   /* All the stuff below this is WRONG! */
432   if( this->lpSession->dwFlags == DPLCONNECTION_CREATESESSION )
433   {
434     DWORD threadIdSink;
435
436     /* Spawn a thread to deal with all of this and to handle the incomming requests */
437     threadIdSink = CreateThread( NULL, 0, &DPLobby_Spawn_Server,
438                                 (LPVOID)this->lpSession->lpConn->lpSessionDesc, 0, &threadIdSink );  
439
440   }
441   else if ( this->lpSession->dwFlags == DPLCONNECTION_JOINSESSION ) 
442   {
443     /* Let's search for a matching session */
444     FIXME( dplay, "joining session not yet supported.\n");
445     return DPERR_OUTOFMEMORY;
446   }
447   else /* Unknown type of connection request */
448   {
449      ERR( dplay, ": Unknown connection request lpConn->dwFlags=%08lx\n",
450           lpConn->dwFlags ); 
451
452      return DPERR_OUTOFMEMORY;
453   }
454
455   /* This does the work of the following methods...
456      IDirectPlay3::InitializeConnection,
457      IDirectPlay3::EnumSessions,
458      IDirectPlay3::Open
459    */
460   
461
462 #endif
463
464   return DP_OK;
465
466 };
467
468 /********************************************************************
469  *
470  * Creates a DirectPlay Address, given a service provider-specific network
471  * address. 
472  * Returns an address contains the globally unique identifier
473  * (GUID) of the service provider and data that the service provider can
474  * interpret as a network address.
475  *
476  */
477 static HRESULT WINAPI IDirectPlayLobby2A_CreateAddress
478 ( LPDIRECTPLAYLOBBY2A this,
479   REFGUID guidSP,
480   REFGUID guidDataType,
481   LPCVOID lpData, 
482   DWORD dwDataSize,
483   LPVOID lpAddress, 
484   LPDWORD lpdwAddressSize )
485 {
486   FIXME( dplay, ":stub\n");
487   return DPERR_OUTOFMEMORY;
488 };
489
490 static HRESULT WINAPI IDirectPlayLobby2W_CreateAddress
491 ( LPDIRECTPLAYLOBBY2 this,
492   REFGUID guidSP,
493   REFGUID guidDataType,
494   LPCVOID lpData,
495   DWORD dwDataSize,
496   LPVOID lpAddress,
497   LPDWORD lpdwAddressSize )
498 {
499   FIXME( dplay, ":stub\n");
500   return DPERR_OUTOFMEMORY;
501 };
502
503
504 /********************************************************************
505  *
506  * Parses out chunks from the DirectPlay Address buffer by calling the
507  * given callback function, with lpContext, for each of the chunks.
508  *
509  */
510 static HRESULT WINAPI IDirectPlayLobby2A_EnumAddress
511 ( LPDIRECTPLAYLOBBY2A this,
512   LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
513   LPCVOID lpAddress,
514   DWORD dwAddressSize,
515   LPVOID lpContext )
516 {
517   FIXME( dplay, ":stub\n");
518   return DPERR_OUTOFMEMORY;
519 };
520
521 static HRESULT WINAPI IDirectPlayLobby2W_EnumAddress
522 ( LPDIRECTPLAYLOBBY2 this,
523   LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
524   LPCVOID lpAddress,
525   DWORD dwAddressSize,
526   LPVOID lpContext )
527 {
528   FIXME( dplay, ":stub\n");
529   return DPERR_OUTOFMEMORY;
530 };
531
532 /********************************************************************
533  *
534  * Enumerates all the address types that a given service provider needs to
535  * build the DirectPlay Address.
536  *
537  */
538 static HRESULT WINAPI IDirectPlayLobbyA_EnumAddressTypes
539 ( LPDIRECTPLAYLOBBYA this,
540   LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
541   REFGUID guidSP,
542   LPVOID lpContext,
543   DWORD dwFlags )
544 {
545   FIXME( dplay, ":stub\n");
546   return DPERR_OUTOFMEMORY;
547 };
548
549 static HRESULT WINAPI IDirectPlayLobby2A_EnumAddressTypes
550 ( LPDIRECTPLAYLOBBY2A this,
551   LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
552   REFGUID guidSP, 
553   LPVOID lpContext,
554   DWORD dwFlags )
555 {
556   return IDirectPlayLobbyA_EnumAddressTypes( (LPDIRECTPLAYLOBBYA)this, lpEnumAddressTypeCallback,
557                                              guidSP, lpContext, dwFlags );
558 };
559
560 static HRESULT WINAPI IDirectPlayLobby2W_EnumAddressTypes
561 ( LPDIRECTPLAYLOBBY2 this,
562   LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
563   REFGUID guidSP,
564   LPVOID lpContext,
565   DWORD dwFlags )
566 {
567   FIXME( dplay, ":stub\n");
568   return DPERR_OUTOFMEMORY;
569 };
570
571 /********************************************************************
572  *
573  * Enumerates what applications are registered with DirectPlay by
574  * invoking the callback function with lpContext.
575  *
576  */
577 static HRESULT WINAPI IDirectPlayLobbyW_EnumLocalApplications
578 ( LPDIRECTPLAYLOBBY this,
579   LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
580   LPVOID lpContext,
581   DWORD dwFlags )
582 {
583   FIXME( dplay, ":stub\n");
584   return DPERR_OUTOFMEMORY;
585 };
586
587 static HRESULT WINAPI IDirectPlayLobby2W_EnumLocalApplications
588 ( LPDIRECTPLAYLOBBY2 this,
589   LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
590   LPVOID lpContext,
591   DWORD dwFlags )
592 {
593   return IDirectPlayLobbyW_EnumLocalApplications( (LPDIRECTPLAYLOBBY)this, a,
594                                                   lpContext, dwFlags ); 
595 };
596
597 static HRESULT WINAPI IDirectPlayLobbyA_EnumLocalApplications
598 ( LPDIRECTPLAYLOBBYA this,
599   LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
600   LPVOID lpContext,
601   DWORD dwFlags )
602 {
603   FIXME( dplay, ":stub\n");
604   return DPERR_OUTOFMEMORY;
605 };
606
607 static HRESULT WINAPI IDirectPlayLobby2A_EnumLocalApplications
608 ( LPDIRECTPLAYLOBBY2A this,
609   LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
610   LPVOID lpContext,
611   DWORD dwFlags )
612 {
613   return IDirectPlayLobbyA_EnumLocalApplications( (LPDIRECTPLAYLOBBYA)this, a,
614                                                   lpContext, dwFlags ); 
615 };
616
617
618 /********************************************************************
619  *
620  * Retrieves the DPLCONNECTION structure that contains all the information
621  * needed to start and connect an application. This was generated using
622  * either the RunApplication or SetConnectionSettings methods.
623  *
624  * NOTES: If lpData is NULL then just return lpdwDataSize. This allows
625  *        the data structure to be allocated by our caller which can then
626  *        call this procedure/method again with a valid data pointer.
627  */
628 static HRESULT WINAPI IDirectPlayLobbyA_GetConnectionSettings
629 ( LPDIRECTPLAYLOBBYA this,
630   DWORD dwAppID,
631   LPVOID lpData,
632   LPDWORD lpdwDataSize )
633 {
634   LPDPLCONNECTION lpDplConnection;
635
636   FIXME( dplay, ": semi stub (%p)->(0x%08lx,%p,%p)\n", this, dwAppID, lpData, lpdwDataSize );
637  
638   /* Application is requesting us to give the required size */
639   if ( !lpData )
640   {
641     /* Let's check the size of the buffer that the application has allocated */
642     if( *lpdwDataSize >= sizeof( DPLCONNECTION ) )
643     {
644       return DP_OK;
645     }
646     else
647     {
648       *lpdwDataSize = sizeof( DPLCONNECTION );
649       return DPERR_BUFFERTOOSMALL;
650     }
651   }
652
653   /* Fill in the fields - let them just use the ptrs */
654   lpDplConnection = (LPDPLCONNECTION)lpData;
655
656   /* Make sure we were given the right size */
657   if( lpDplConnection->dwSize < sizeof( DPLCONNECTION ) )
658   {
659      ERR( dplay, "bad passed size 0x%08lx.\n", lpDplConnection->dwSize );
660      return DPERR_INVALIDPARAMS;
661   }
662
663   /* Copy everything we've got into here */
664   /* Need to actually store the stuff here. Check if we've already allocated each field first. */
665   lpDplConnection->dwFlags = this->dwConnFlags;
666
667   /* Copy LPDPSESSIONDESC2 struct */
668   lpDplConnection->lpSessionDesc = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( this->sessionDesc ) );
669   memcpy( lpDplConnection->lpSessionDesc, &(this->sessionDesc), sizeof( this->sessionDesc ) );
670
671   if( this->sessionDesc.sess.lpszSessionName )
672   {
673     lpDplConnection->lpSessionDesc->sess.lpszSessionName = 
674       HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, this->sessionDesc.sess.lpszSessionName );
675   }
676
677   if( this->sessionDesc.pass.lpszPassword )
678   {
679     lpDplConnection->lpSessionDesc->pass.lpszPassword = 
680       HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, this->sessionDesc.pass.lpszPassword );
681   }
682      
683   /* I don't know what to use the reserved for. We'll set it to 0 just for fun */
684   this->sessionDesc.dwReserved1 = this->sessionDesc.dwReserved2 = 0;
685
686   /* Copy DPNAME struct - seems to be optional - check for existance first */
687   lpDplConnection->lpPlayerName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( this->playerName ) );
688   memcpy( lpDplConnection->lpPlayerName, &(this->playerName), sizeof( this->playerName ) );
689
690   if( this->playerName.psn.lpszShortName )
691   {
692     lpDplConnection->lpPlayerName->psn.lpszShortName =
693       HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, this->playerName.psn.lpszShortName );  
694   }
695
696   if( this->playerName.pln.lpszLongName )
697   {
698     lpDplConnection->lpPlayerName->pln.lpszLongName =
699       HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, this->playerName.pln.lpszLongName );
700   }
701
702
703
704   memcpy( &(lpDplConnection->guidSP), &(this->guidSP), sizeof( this->guidSP ) );
705
706   lpDplConnection->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, this->dwAddressSize );
707   memcpy( lpDplConnection->lpAddress, this->lpAddress, this->dwAddressSize );
708
709   lpDplConnection->dwAddressSize = this->dwAddressSize;
710
711   return DP_OK;
712 }
713
714 static HRESULT WINAPI IDirectPlayLobby2A_GetConnectionSettings
715 ( LPDIRECTPLAYLOBBY2A this,
716   DWORD dwAppID,
717   LPVOID lpData,
718   LPDWORD lpdwDataSize )
719 {
720   return IDirectPlayLobbyA_GetConnectionSettings( (LPDIRECTPLAYLOBBYA)this,
721                                                   dwAppID, lpData, lpdwDataSize ); 
722 }
723
724 static HRESULT WINAPI IDirectPlayLobbyW_GetConnectionSettings
725 ( LPDIRECTPLAYLOBBY this,
726   DWORD dwAppID,
727   LPVOID lpData,
728   LPDWORD lpdwDataSize )
729 {
730   FIXME( dplay, ":semi stub %p %08lx %p %p \n", this, dwAppID, lpData, lpdwDataSize );
731
732   /* Application is requesting us to give the required size */ 
733   if ( !lpData )
734   {
735     /* Let's check the size of the buffer that the application has allocated */
736     if( *lpdwDataSize >= sizeof( DPLCONNECTION ) )
737     {
738       return DP_OK;  
739     }
740     else
741     {
742       *lpdwDataSize = sizeof( DPLCONNECTION );
743       return DPERR_BUFFERTOOSMALL;
744     }
745   }
746
747   /* Fill in the fields - let them just use the ptrs */
748   FIXME( dplay, "stub\n" );
749
750   return DP_OK;
751 };
752
753 static HRESULT WINAPI IDirectPlayLobby2W_GetConnectionSettings
754 ( LPDIRECTPLAYLOBBY2 this,
755   DWORD dwAppID,
756   LPVOID lpData,
757   LPDWORD lpdwDataSize )
758 {
759   return IDirectPlayLobbyW_GetConnectionSettings( (LPDIRECTPLAYLOBBY)this,
760                                                   dwAppID, lpData, lpdwDataSize );
761 }
762
763 /********************************************************************
764  *
765  * Retrieves the message sent between a lobby client and a DirectPlay 
766  * application. All messages are queued until received.
767  *
768  */
769 static HRESULT WINAPI IDirectPlayLobbyA_ReceiveLobbyMessage
770 ( LPDIRECTPLAYLOBBYA this,
771   DWORD dwFlags,
772   DWORD dwAppID,
773   LPDWORD lpdwMessageFlags,
774   LPVOID lpData,
775   LPDWORD lpdwDataSize )
776 {
777   FIXME( dplay, ":stub %p %08lx %08lx %p %p %p\n", this, dwFlags, dwAppID, lpdwMessageFlags, lpData,
778          lpdwDataSize );
779   return DPERR_OUTOFMEMORY;
780 };
781
782 static HRESULT WINAPI IDirectPlayLobby2A_ReceiveLobbyMessage
783 ( LPDIRECTPLAYLOBBY2A this,
784   DWORD dwFlags,
785   DWORD dwAppID,
786   LPDWORD lpdwMessageFlags,
787   LPVOID lpData,
788   LPDWORD lpdwDataSize )
789 {
790   return IDirectPlayLobbyA_ReceiveLobbyMessage( (LPDIRECTPLAYLOBBYA)this, dwFlags, dwAppID,
791                                                  lpdwMessageFlags, lpData, lpdwDataSize );
792 };
793
794
795 static HRESULT WINAPI IDirectPlayLobbyW_ReceiveLobbyMessage
796 ( LPDIRECTPLAYLOBBY this,
797   DWORD dwFlags,
798   DWORD dwAppID,
799   LPDWORD lpdwMessageFlags,
800   LPVOID lpData,
801   LPDWORD lpdwDataSize )
802 {
803   FIXME( dplay, ":stub %p %08lx %08lx %p %p %p\n", this, dwFlags, dwAppID, lpdwMessageFlags, lpData,
804          lpdwDataSize );
805   return DPERR_OUTOFMEMORY;
806 };
807
808 static HRESULT WINAPI IDirectPlayLobby2W_ReceiveLobbyMessage
809 ( LPDIRECTPLAYLOBBY2 this,
810   DWORD dwFlags,
811   DWORD dwAppID,
812   LPDWORD lpdwMessageFlags,
813   LPVOID lpData,
814   LPDWORD lpdwDataSize )
815 {
816   return IDirectPlayLobbyW_ReceiveLobbyMessage( (LPDIRECTPLAYLOBBY)this, dwFlags, dwAppID,
817                                                  lpdwMessageFlags, lpData, lpdwDataSize );
818 };
819
820 /********************************************************************
821  *
822  * Starts an application and passes to it all the information to
823  * connect to a session.
824  *
825  */
826 static HRESULT WINAPI IDirectPlayLobbyA_RunApplication
827 ( LPDIRECTPLAYLOBBYA this,
828   DWORD dwFlags,
829   LPDWORD lpdwAppID,
830   LPDPLCONNECTION lpConn,
831   HANDLE32 hReceiveEvent )
832 {
833   FIXME( dplay, ":stub\n");
834   return DPERR_OUTOFMEMORY;
835 };
836
837 static HRESULT WINAPI IDirectPlayLobby2A_RunApplication
838 ( LPDIRECTPLAYLOBBY2A this,
839   DWORD dwFlags,
840   LPDWORD lpdwAppID,
841   LPDPLCONNECTION lpConn,
842   HANDLE32 hReceiveEvent )
843 {
844   return IDirectPlayLobbyA_RunApplication( (LPDIRECTPLAYLOBBYA)this, dwFlags,
845                                            lpdwAppID, lpConn, hReceiveEvent );
846 };
847
848 static HRESULT WINAPI IDirectPlayLobbyW_RunApplication
849 ( LPDIRECTPLAYLOBBY this,
850   DWORD dwFlags,
851   LPDWORD lpdwAppID,
852   LPDPLCONNECTION lpConn,
853   HANDLE32 hReceiveEvent )
854 {
855   FIXME( dplay, ":stub\n");
856   return DPERR_OUTOFMEMORY;
857 };
858
859 static HRESULT WINAPI IDirectPlayLobby2W_RunApplication
860 ( LPDIRECTPLAYLOBBY2 this,
861   DWORD dwFlags,
862   LPDWORD lpdwAppID,
863   LPDPLCONNECTION lpConn,
864   HANDLE32 hReceiveEvent )
865 {
866   return IDirectPlayLobbyW_RunApplication( (LPDIRECTPLAYLOBBY)this, dwFlags,
867                                            lpdwAppID, lpConn, hReceiveEvent );
868 };
869
870
871 /********************************************************************
872  *
873  * Sends a message between the application and the lobby client.
874  * All messages are queued until received.
875  *
876  */
877 static HRESULT WINAPI IDirectPlayLobbyA_SendLobbyMessage
878 ( LPDIRECTPLAYLOBBYA this,
879   DWORD dwFlags,
880   DWORD dwAppID,
881   LPVOID lpData,
882   DWORD dwDataSize )
883 {
884   FIXME( dplay, ":stub\n");
885   return DPERR_OUTOFMEMORY;
886 };
887
888 static HRESULT WINAPI IDirectPlayLobby2A_SendLobbyMessage
889 ( LPDIRECTPLAYLOBBY2A this,
890   DWORD dwFlags,
891   DWORD dwAppID,
892   LPVOID lpData,
893   DWORD dwDataSize )
894 {
895   return IDirectPlayLobbyA_SendLobbyMessage( (LPDIRECTPLAYLOBBYA)this, dwFlags, 
896                                              dwAppID, lpData, dwDataSize ); 
897 };
898
899
900 static HRESULT WINAPI IDirectPlayLobbyW_SendLobbyMessage
901 ( LPDIRECTPLAYLOBBY this,
902   DWORD dwFlags,
903   DWORD dwAppID,
904   LPVOID lpData,
905   DWORD dwDataSize )
906 {
907   FIXME( dplay, ":stub\n");
908   return DPERR_OUTOFMEMORY;
909 };
910
911 static HRESULT WINAPI IDirectPlayLobby2W_SendLobbyMessage
912 ( LPDIRECTPLAYLOBBY2 this,
913   DWORD dwFlags,
914   DWORD dwAppID,
915   LPVOID lpData,
916   DWORD dwDataSize )
917 {
918   return IDirectPlayLobbyW_SendLobbyMessage( (LPDIRECTPLAYLOBBY)this, dwFlags,
919                                               dwAppID, lpData, dwDataSize );
920 };
921
922 /********************************************************************
923  *
924  * Modifies the DPLCONNECTION structure to contain all information
925  * needed to start and connect an application.
926  *
927  */
928 static HRESULT WINAPI IDirectPlayLobbyW_SetConnectionSettings
929 ( LPDIRECTPLAYLOBBY this,
930   DWORD dwFlags,
931   DWORD dwAppID,
932   LPDPLCONNECTION lpConn )
933 {
934   TRACE( dplay, ": this=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p\n",
935          this, dwFlags, dwAppID, lpConn );
936
937   /* Paramater check */
938   if( dwFlags || !this || !lpConn )
939   {
940     ERR( dplay, "invalid parameters.\n");
941     return DPERR_INVALIDPARAMS;
942   }
943
944   /* See if there is a connection associated with this request.
945    * dwAppID == 0 indicates that this request isn't associated with a connection.
946    */
947   if( dwAppID )
948   {
949      FIXME( dplay, ": Connection dwAppID=%08lx given. Not implemented yet.\n",
950             dwAppID );
951
952      /* Need to add a check for this application Id...*/
953      return DPERR_NOTLOBBIED;
954   }
955
956   if(  lpConn->dwSize != sizeof(DPLCONNECTION) )
957   {
958     ERR( dplay, ": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n", 
959          lpConn->dwSize, sizeof( DPLCONNECTION ) );
960     return DPERR_INVALIDPARAMS;
961   }
962
963   /* Need to investigate the lpConn->lpSessionDesc to figure out
964    * what type of session we need to join/create.
965    */
966   if(  (!lpConn->lpSessionDesc ) || 
967        ( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
968     )
969   {
970     ERR( dplay, "DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
971          lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
972     return DPERR_INVALIDPARAMS;
973   }
974
975   /* Need to actually store the stuff here. Check if we've already allocated each field first. */
976   this->dwConnFlags = lpConn->dwFlags;
977
978   /* Copy LPDPSESSIONDESC2 struct - this is required */
979   memcpy( &(this->sessionDesc), lpConn->lpSessionDesc, sizeof( *(lpConn->lpSessionDesc) ) );
980
981   if( lpConn->lpSessionDesc->sess.lpszSessionName )
982     this->sessionDesc.sess.lpszSessionName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->sess.lpszSessionName );
983   else
984     this->sessionDesc.sess.lpszSessionName = NULL;
985  
986   if( lpConn->lpSessionDesc->pass.lpszPassword )
987     this->sessionDesc.pass.lpszPassword = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->pass.lpszPassword );
988   else
989     this->sessionDesc.pass.lpszPassword = NULL;
990
991   /* I don't know what to use the reserved for ... */
992   this->sessionDesc.dwReserved1 = this->sessionDesc.dwReserved2 = 0;
993
994   /* Copy DPNAME struct - seems to be optional - check for existance first */
995   if( lpConn->lpPlayerName )
996   {
997      memcpy( &(this->playerName), lpConn->lpPlayerName, sizeof( *lpConn->lpPlayerName ) ); 
998
999      if( lpConn->lpPlayerName->psn.lpszShortName )
1000        this->playerName.psn.lpszShortName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->psn.lpszShortName ); 
1001
1002      if( lpConn->lpPlayerName->pln.lpszLongName )
1003        this->playerName.pln.lpszLongName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->pln.lpszLongName );
1004
1005   }
1006
1007   memcpy( &(this->guidSP), &(lpConn->guidSP), sizeof( lpConn->guidSP ) );  
1008   
1009   this->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->dwAddressSize ); 
1010   memcpy( this->lpAddress, lpConn->lpAddress, lpConn->dwAddressSize );
1011
1012   this->dwAddressSize = lpConn->dwAddressSize;
1013
1014   return DP_OK;
1015 };
1016
1017 static HRESULT WINAPI IDirectPlayLobby2W_SetConnectionSettings
1018 ( LPDIRECTPLAYLOBBY2 this,
1019   DWORD dwFlags,
1020   DWORD dwAppID,
1021   LPDPLCONNECTION lpConn )
1022 {
1023   return IDirectPlayLobbyW_SetConnectionSettings( (LPDIRECTPLAYLOBBY)this, 
1024                                                   dwFlags, dwAppID, lpConn );
1025 }
1026
1027 static HRESULT WINAPI IDirectPlayLobbyA_SetConnectionSettings
1028 ( LPDIRECTPLAYLOBBYA this,
1029   DWORD dwFlags,
1030   DWORD dwAppID,
1031   LPDPLCONNECTION lpConn )
1032 {
1033   FIXME( dplay, ": this=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p: stub\n",
1034          this, dwFlags, dwAppID, lpConn );
1035   return DPERR_OUTOFMEMORY;
1036 }
1037
1038 static HRESULT WINAPI IDirectPlayLobby2A_SetConnectionSettings
1039 ( LPDIRECTPLAYLOBBY2A this,
1040   DWORD dwFlags,
1041   DWORD dwAppID,
1042   LPDPLCONNECTION lpConn )
1043 {
1044   return IDirectPlayLobbyA_SetConnectionSettings( (LPDIRECTPLAYLOBBYA)this,
1045                                                   dwFlags, dwAppID, lpConn );
1046 };
1047
1048 /********************************************************************
1049  *
1050  * Registers an event that will be set when a lobby message is received.
1051  *
1052  */
1053 static HRESULT WINAPI IDirectPlayLobbyA_SetLobbyMessageEvent
1054 ( LPDIRECTPLAYLOBBYA this,
1055   DWORD dwFlags,
1056   DWORD dwAppID,
1057   HANDLE32 hReceiveEvent )
1058 {
1059   FIXME( dplay, ":stub\n");
1060   return DPERR_OUTOFMEMORY;
1061 };
1062
1063 static HRESULT WINAPI IDirectPlayLobby2A_SetLobbyMessageEvent
1064 ( LPDIRECTPLAYLOBBY2A this,
1065   DWORD dwFlags,
1066   DWORD dwAppID,
1067   HANDLE32 hReceiveEvent )
1068 {
1069   return IDirectPlayLobbyA_SetLobbyMessageEvent( (LPDIRECTPLAYLOBBYA)this, dwFlags,
1070                                                  dwAppID, hReceiveEvent ); 
1071 };
1072
1073 static HRESULT WINAPI IDirectPlayLobbyW_SetLobbyMessageEvent
1074 ( LPDIRECTPLAYLOBBY this,
1075   DWORD dwFlags,
1076   DWORD dwAppID,
1077   HANDLE32 hReceiveEvent )
1078 {
1079   FIXME( dplay, ":stub\n");
1080   return DPERR_OUTOFMEMORY;
1081 };
1082
1083 static HRESULT WINAPI IDirectPlayLobby2W_SetLobbyMessageEvent
1084 ( LPDIRECTPLAYLOBBY2 this,
1085   DWORD dwFlags,
1086   DWORD dwAppID,
1087   HANDLE32 hReceiveEvent )
1088 {
1089   return IDirectPlayLobbyW_SetLobbyMessageEvent( (LPDIRECTPLAYLOBBY)this, dwFlags,
1090                                                  dwAppID, hReceiveEvent ); 
1091 };
1092
1093
1094 /********************************************************************
1095  *
1096  * Registers an event that will be set when a lobby message is received.
1097  *
1098  */
1099 static HRESULT WINAPI IDirectPlayLobby2W_CreateCompoundAddress
1100 ( LPDIRECTPLAYLOBBY2 this,
1101   LPCDPCOMPOUNDADDRESSELEMENT lpElements,
1102   DWORD dwElementCount,
1103   LPVOID lpAddress,
1104   LPDWORD lpdwAddressSize )
1105 {
1106   FIXME( dplay, ":stub\n");
1107   return DPERR_OUTOFMEMORY;
1108 };
1109
1110 static HRESULT WINAPI IDirectPlayLobby2A_CreateCompoundAddress
1111 ( LPDIRECTPLAYLOBBY2A this,
1112   LPCDPCOMPOUNDADDRESSELEMENT lpElements,
1113   DWORD dwElementCount,
1114   LPVOID lpAddress,
1115   LPDWORD lpdwAddressSize )
1116 {
1117   FIXME( dplay, ":stub\n");
1118   return DPERR_OUTOFMEMORY;
1119 };
1120
1121
1122 /* Direct Play Lobby 1 (ascii) Virtual Table for methods */
1123 /* All lobby 1 methods are exactly the same except QueryInterface */
1124 static struct tagLPDIRECTPLAYLOBBY_VTABLE directPlayLobbyAVT = {
1125   IDirectPlayLobbyA_QueryInterface,
1126   (void*)IDirectPlayLobby2A_AddRef,
1127   (void*)IDirectPlayLobby2A_Release,
1128   (void*)IDirectPlayLobby2A_Connect,
1129   (void*)IDirectPlayLobby2A_CreateAddress,
1130   (void*)IDirectPlayLobby2A_EnumAddress,
1131   (void*)IDirectPlayLobby2A_EnumAddressTypes,
1132   (void*)IDirectPlayLobby2A_EnumLocalApplications,
1133   (void*)IDirectPlayLobby2A_GetConnectionSettings,
1134   (void*)IDirectPlayLobby2A_ReceiveLobbyMessage,
1135   (void*)IDirectPlayLobby2A_RunApplication,
1136   (void*)IDirectPlayLobby2A_SendLobbyMessage,
1137   (void*)IDirectPlayLobby2A_SetConnectionSettings,
1138   (void*)IDirectPlayLobby2A_SetLobbyMessageEvent
1139 };
1140
1141 /* Direct Play Lobby 1 (unicode) Virtual Table for methods */
1142 static struct tagLPDIRECTPLAYLOBBY_VTABLE directPlayLobbyWVT = {
1143   IDirectPlayLobbyW_QueryInterface,
1144   (void*)IDirectPlayLobby2W_AddRef,
1145   (void*)IDirectPlayLobby2W_Release,
1146   (void*)IDirectPlayLobby2W_Connect,
1147   (void*)IDirectPlayLobby2W_CreateAddress, 
1148   (void*)IDirectPlayLobby2W_EnumAddress,
1149   (void*)IDirectPlayLobby2W_EnumAddressTypes,
1150   (void*)IDirectPlayLobby2W_EnumLocalApplications,
1151   (void*)IDirectPlayLobby2W_GetConnectionSettings,
1152   (void*)IDirectPlayLobby2W_ReceiveLobbyMessage,
1153   (void*)IDirectPlayLobby2W_RunApplication,
1154   (void*)IDirectPlayLobby2W_SendLobbyMessage,
1155   (void*)IDirectPlayLobby2W_SetConnectionSettings,
1156   (void*)IDirectPlayLobby2W_SetLobbyMessageEvent
1157 };
1158
1159
1160 /* Direct Play Lobby 2 (ascii) Virtual Table for methods */
1161 static struct tagLPDIRECTPLAYLOBBY2_VTABLE directPlayLobby2AVT = {
1162   IDirectPlayLobby2A_QueryInterface,
1163   IDirectPlayLobby2A_AddRef,
1164   IDirectPlayLobby2A_Release,
1165   IDirectPlayLobby2A_Connect,
1166   IDirectPlayLobby2A_CreateAddress,
1167   IDirectPlayLobby2A_EnumAddress,
1168   IDirectPlayLobby2A_EnumAddressTypes,
1169   IDirectPlayLobby2A_EnumLocalApplications,
1170   IDirectPlayLobby2A_GetConnectionSettings,
1171   IDirectPlayLobby2A_ReceiveLobbyMessage,
1172   IDirectPlayLobby2A_RunApplication,
1173   IDirectPlayLobby2A_SendLobbyMessage,
1174   IDirectPlayLobby2A_SetConnectionSettings,
1175   IDirectPlayLobby2A_SetLobbyMessageEvent,
1176   IDirectPlayLobby2A_CreateCompoundAddress 
1177 };
1178
1179 /* Direct Play Lobby 2 (unicode) Virtual Table for methods */
1180 static struct tagLPDIRECTPLAYLOBBY2_VTABLE directPlayLobby2WVT = {
1181   IDirectPlayLobby2W_QueryInterface,
1182   IDirectPlayLobby2W_AddRef, 
1183   IDirectPlayLobby2W_Release,
1184   IDirectPlayLobby2W_Connect,
1185   IDirectPlayLobby2W_CreateAddress,
1186   IDirectPlayLobby2W_EnumAddress,
1187   IDirectPlayLobby2W_EnumAddressTypes,
1188   IDirectPlayLobby2W_EnumLocalApplications,
1189   IDirectPlayLobby2W_GetConnectionSettings,
1190   IDirectPlayLobby2W_ReceiveLobbyMessage,
1191   IDirectPlayLobby2W_RunApplication,
1192   IDirectPlayLobby2W_SendLobbyMessage,
1193   IDirectPlayLobby2W_SetConnectionSettings,
1194   IDirectPlayLobby2W_SetLobbyMessageEvent,
1195   IDirectPlayLobby2W_CreateCompoundAddress
1196 };
1197
1198 /***************************************************************************
1199  *  DirectPlayLobbyCreateA   (DPLAYX.4)
1200  *
1201  */
1202 HRESULT WINAPI DirectPlayLobbyCreateA( LPGUID lpGUIDDSP,
1203                                        LPDIRECTPLAYLOBBYA *lplpDPL,
1204                                        IUnknown *lpUnk, 
1205                                        LPVOID lpData,
1206                                        DWORD dwDataSize )
1207 {
1208   TRACE(dplay,"lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
1209         lpGUIDDSP,lplpDPL,lpUnk,lpData,dwDataSize);
1210
1211   /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
1212    * equal 0. These fields are mostly for future expansion.
1213    */
1214   if ( lpGUIDDSP || lpUnk || lpData || dwDataSize )
1215   {
1216      *lplpDPL = NULL;
1217      return DPERR_INVALIDPARAMS;
1218   }
1219
1220   /* Yes...really we should be returning a lobby 1 object */
1221   *lplpDPL = (LPDIRECTPLAYLOBBYA)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
1222                                             sizeof( IDirectPlayLobbyA ) );
1223
1224   if( ! (*lplpDPL) )
1225   {
1226      return DPERR_OUTOFMEMORY;
1227   }
1228
1229   (*lplpDPL)->lpVtbl = &directPlayLobbyAVT;
1230   (*lplpDPL)->ref    = 1;
1231
1232   /* All fields were nulled out by the allocation */
1233
1234   return DP_OK;
1235 }
1236
1237 /***************************************************************************
1238  *  DirectPlayLobbyCreateW   (DPLAYX.5)
1239  *
1240  */
1241 HRESULT WINAPI DirectPlayLobbyCreateW( LPGUID lpGUIDDSP, 
1242                                        LPDIRECTPLAYLOBBY *lplpDPL,
1243                                        IUnknown *lpUnk,
1244                                        LPVOID lpData, 
1245                                        DWORD dwDataSize )
1246 {
1247   TRACE(dplay,"lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
1248         lpGUIDDSP,lplpDPL,lpUnk,lpData,dwDataSize);
1249
1250   /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must 
1251    * equal 0. These fields are mostly for future expansion.
1252    */
1253   if ( lpGUIDDSP || lpUnk || lpData || dwDataSize )
1254   {
1255      *lplpDPL = NULL;
1256      ERR( dplay, "Bad parameters!\n" );
1257      return DPERR_INVALIDPARAMS;
1258   }
1259
1260   /* Yes...really we should bre returning a lobby 1 object */
1261   *lplpDPL = (LPDIRECTPLAYLOBBY)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
1262                                            sizeof( IDirectPlayLobby ) );
1263
1264   if( !*lplpDPL)
1265   {
1266      return DPERR_OUTOFMEMORY;
1267   }
1268
1269   (*lplpDPL)->lpVtbl = &directPlayLobbyWVT;
1270   (*lplpDPL)->ref    = 1;
1271
1272   /* All fields were nulled out by the allocation */
1273
1274   return DP_OK;
1275
1276 }
1277
1278 /***************************************************************************
1279  *  DirectPlayEnumerateA (DPLAYX.2) 
1280  *
1281  *  The pointer to the structure lpContext will be filled with the 
1282  *  appropriate data for each service offered by the OS. These services are
1283  *  not necessarily available on this particular machine but are defined
1284  *  as simple service providers under the "Service Providers" registry key.
1285  *  This structure is then passed to lpEnumCallback for each of the different 
1286  *  services. 
1287  *
1288  *  This API is useful only for applications written using DirectX3 or
1289  *  worse. It is superceeded by IDirectPlay3::EnumConnections which also
1290  *  gives information on the actual connections.
1291  *
1292  * defn of a service provider:
1293  * A dynamic-link library used by DirectPlay to communicate over a network. 
1294  * The service provider contains all the network-specific code required
1295  * to send and receive messages. Online services and network operators can
1296  * supply service providers to use specialized hardware, protocols, communications
1297  * media, and network resources. 
1298  *
1299  * TODO: Allocate string buffer space from the heap (length from reg)
1300  *       Pass real device driver numbers...
1301  *       Get the GUID properly...
1302  */
1303 HRESULT WINAPI DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback,
1304                                      LPVOID lpContext )
1305 {
1306
1307   HKEY hkResult; 
1308   LPCSTR searchSubKey    = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
1309   LPSTR guidDataSubKey   = "Guid";
1310   LPSTR majVerDataSubKey = "dwReserved1";
1311   DWORD dwIndex, sizeOfSubKeyName=50;
1312   char subKeyName[51]; 
1313
1314   TRACE( dplay, ": lpEnumCallback=%p lpContext=%p\n", lpEnumCallback, lpContext );
1315
1316   if( !lpEnumCallback || !*lpEnumCallback )
1317   {
1318      return DPERR_INVALIDPARAMS;
1319   }
1320
1321   /* Need to loop over the service providers in the registry */
1322   if( RegOpenKeyEx32A( HKEY_LOCAL_MACHINE, searchSubKey,
1323                        0, KEY_ENUMERATE_SUB_KEYS, &hkResult ) != ERROR_SUCCESS )
1324   {
1325     /* Hmmm. Does this mean that there are no service providers? */ 
1326     ERR(dplay, ": no service providers?\n");
1327     return DP_OK; 
1328   }
1329
1330   /* Traverse all the service providers we have available */
1331   for( dwIndex=0;
1332        RegEnumKey32A( hkResult, dwIndex, subKeyName, sizeOfSubKeyName ) !=
1333          ERROR_NO_MORE_ITEMS;
1334        ++dwIndex )
1335   {
1336     HKEY     hkServiceProvider;
1337     GUID     serviceProviderGUID;
1338     DWORD    returnTypeGUID, returnTypeReserved1, sizeOfReturnBuffer=50;
1339     char     returnBuffer[51];
1340     DWORD    majVersionNum /*, minVersionNum */;
1341     LPWSTR   lpWGUIDString; 
1342
1343     TRACE( dplay, " this time through: %s\n", subKeyName );
1344
1345     /* Get a handle for this particular service provider */
1346     if( RegOpenKeyEx32A( hkResult, subKeyName, 0, KEY_QUERY_VALUE,
1347                          &hkServiceProvider ) != ERROR_SUCCESS )
1348     {
1349       ERR( dplay, ": what the heck is going on?\n" );
1350       continue;
1351     }
1352
1353     /* Get the GUID, Device major number and device minor number 
1354      * from the registry. 
1355      */
1356     if( RegQueryValueEx32A( hkServiceProvider, guidDataSubKey,
1357                             NULL, &returnTypeGUID, returnBuffer,
1358                             &sizeOfReturnBuffer ) != ERROR_SUCCESS )
1359     {
1360       ERR( dplay, ": missing GUID registry data members\n" );
1361       continue; 
1362     }
1363
1364     /* FIXME: Check return types to ensure we're interpreting data right */
1365     lpWGUIDString = HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer );
1366     CLSIDFromString32( (LPCOLESTR32)lpWGUIDString, &serviceProviderGUID ); 
1367     HeapFree( GetProcessHeap(), 0, lpWGUIDString );
1368
1369     sizeOfReturnBuffer = 50;
1370  
1371     if( RegQueryValueEx32A( hkServiceProvider, majVerDataSubKey,
1372                             NULL, &returnTypeReserved1, returnBuffer,
1373                             &sizeOfReturnBuffer ) != ERROR_SUCCESS )
1374     {
1375       ERR( dplay, ": missing dwReserved1 registry data members\n") ;
1376       continue; 
1377     }
1378     /* FIXME: This couldn't possibly be right...*/
1379     majVersionNum = GET_DWORD( returnBuffer );
1380
1381     /* The enumeration will return FALSE if we are not to continue */
1382     if( !lpEnumCallback( &serviceProviderGUID , subKeyName,
1383                          majVersionNum, (DWORD)0, lpContext ) )
1384     {
1385       WARN( dplay, "lpEnumCallback returning FALSE\n" );
1386       break;
1387     }
1388   }
1389
1390   return DP_OK;
1391
1392 };
1393
1394 /***************************************************************************
1395  *  DirectPlayEnumerateW (DPLAYX.3)
1396  *
1397  */
1398 HRESULT WINAPI DirectPlayEnumerateW( LPDPENUMDPCALLBACKW lpEnumCallback, LPVOID lpContext )
1399 {
1400
1401   FIXME( dplay, ":stub\n");
1402
1403   return DPERR_OUTOFMEMORY; 
1404
1405 };
1406
1407 /***************************************************************************
1408  *  DirectPlayCreate (DPLAYX.1) (DPLAY.1)
1409  *
1410  */
1411 HRESULT WINAPI DirectPlayCreate
1412 ( LPGUID lpGUID, LPDIRECTPLAY2 *lplpDP, IUnknown *pUnk)
1413 {
1414
1415   TRACE(dplay,"lpGUID=%p lplpDP=%p pUnk=%p\n", lpGUID,lplpDP,pUnk);
1416
1417   if( pUnk != NULL )
1418   {
1419     /* Hmmm...wonder what this means! */
1420     ERR(dplay, "What does a NULL here mean?\n" ); 
1421     return DPERR_OUTOFMEMORY;
1422   }
1423
1424   if( IsEqualGUID( &IID_IDirectPlay2A, lpGUID ) )
1425   {
1426     *lplpDP = (LPDIRECTPLAY2A)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
1427                                          sizeof( **lplpDP ) );
1428
1429     if( !*lplpDP )
1430     {
1431        return DPERR_OUTOFMEMORY;
1432     }
1433
1434     (*lplpDP)->lpVtbl = &directPlay2AVT;
1435     (*lplpDP)->ref    = 1;
1436   
1437     return DP_OK;
1438   }
1439   else if( IsEqualGUID( &IID_IDirectPlay2, lpGUID ) )
1440   {
1441     *lplpDP = (LPDIRECTPLAY2)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
1442                                         sizeof( **lplpDP ) );
1443
1444     if( !*lplpDP )
1445     {
1446        return DPERR_OUTOFMEMORY;
1447     }
1448
1449     (*lplpDP)->lpVtbl = &directPlay2WVT;
1450     (*lplpDP)->ref    = 1;
1451
1452     return DP_OK;
1453   }
1454
1455   /* Unknown interface type */
1456   return DPERR_NOINTERFACE;
1457
1458 };
1459
1460 /* Direct Play helper methods */
1461
1462 /* Get a new interface. To be used by QueryInterface. */ 
1463 static HRESULT directPlay_QueryInterface 
1464          ( REFIID riid, LPVOID* ppvObj )
1465 {
1466
1467   if( IsEqualGUID( &IID_IDirectPlay2, riid ) )
1468   {
1469     LPDIRECTPLAY2 lpDP = (LPDIRECTPLAY2)*ppvObj;
1470
1471     lpDP = (LPDIRECTPLAY2)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
1472                                       sizeof( *lpDP ) );
1473
1474     if( !lpDP ) 
1475     {
1476        return DPERR_OUTOFMEMORY;
1477     }
1478
1479     lpDP->lpVtbl = &directPlay2WVT;
1480     lpDP->ref    = 1;
1481
1482     return S_OK;
1483   } 
1484   else if( IsEqualGUID( &IID_IDirectPlay2A, riid ) )
1485   {
1486     LPDIRECTPLAY2A lpDP = (LPDIRECTPLAY2A)*ppvObj;
1487
1488     lpDP = (LPDIRECTPLAY2A)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
1489                                       sizeof( *lpDP ) );
1490
1491     if( !lpDP )
1492     {
1493        return DPERR_OUTOFMEMORY;
1494     }
1495
1496     lpDP->lpVtbl = &directPlay2AVT;
1497     lpDP->ref    = 1;
1498
1499     return S_OK;
1500   }
1501   else if( IsEqualGUID( &IID_IDirectPlay3, riid ) )
1502   {
1503     LPDIRECTPLAY3 lpDP = (LPDIRECTPLAY3)*ppvObj;
1504
1505     lpDP = (LPDIRECTPLAY3)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
1506                                       sizeof( *lpDP ) );
1507
1508     if( !lpDP )
1509     {
1510        return DPERR_OUTOFMEMORY;
1511     }
1512
1513     lpDP->lpVtbl = &directPlay3WVT;
1514     lpDP->ref    = 1;
1515
1516     return S_OK;
1517   }
1518   else if( IsEqualGUID( &IID_IDirectPlay3A, riid ) )
1519   {
1520     LPDIRECTPLAY3A lpDP = (LPDIRECTPLAY3A)*ppvObj;
1521
1522     lpDP = (LPDIRECTPLAY3A)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
1523                                       sizeof( *lpDP ) );
1524
1525     if( !lpDP )
1526     {
1527        return DPERR_OUTOFMEMORY;
1528     }
1529
1530     lpDP->lpVtbl = &directPlay3AVT;
1531     lpDP->ref    = 1;
1532
1533     return S_OK;
1534
1535   }
1536
1537   *ppvObj = NULL;
1538   return E_NOINTERFACE;
1539 }
1540
1541
1542 /* Direct Play methods */
1543 static HRESULT WINAPI DirectPlay2W_QueryInterface
1544          ( LPDIRECTPLAY2 this, REFIID riid, LPVOID* ppvObj )
1545 {
1546   TRACE( dplay, "(%p)->(%p,%p)\n", this, riid, ppvObj );
1547
1548   if( IsEqualGUID( &IID_IUnknown, riid ) ||
1549       IsEqualGUID( &IID_IDirectPlay2, riid )
1550     )
1551   {
1552     this->lpVtbl->fnAddRef( this );
1553     *ppvObj = this;
1554     return S_OK;
1555   }
1556   return directPlay_QueryInterface( riid, ppvObj );
1557 }
1558
1559 static HRESULT WINAPI DirectPlay2A_QueryInterface
1560          ( LPDIRECTPLAY2A this, REFIID riid, LPVOID* ppvObj )
1561 {
1562   TRACE( dplay, "(%p)->(%p,%p)\n", this, riid, ppvObj );
1563
1564   if( IsEqualGUID( &IID_IUnknown, riid ) ||
1565       IsEqualGUID( &IID_IDirectPlay2A, riid )
1566     )
1567   {
1568     this->lpVtbl->fnAddRef( this );
1569     *ppvObj = this;
1570     return S_OK;
1571   }
1572
1573   return directPlay_QueryInterface( riid, ppvObj );
1574 }
1575
1576 static HRESULT WINAPI DirectPlay3W_QueryInterface
1577          ( LPDIRECTPLAY3 this, REFIID riid, LPVOID* ppvObj )
1578 {
1579   TRACE( dplay, "(%p)->(%p,%p)\n", this, riid, ppvObj );
1580
1581   if( IsEqualGUID( &IID_IUnknown, riid ) ||
1582       IsEqualGUID( &IID_IDirectPlay3, riid )
1583     )
1584   {
1585     this->lpVtbl->fnAddRef( this );
1586     *ppvObj = this;
1587     return S_OK;
1588   }
1589
1590   return directPlay_QueryInterface( riid, ppvObj );
1591 }
1592
1593 static HRESULT WINAPI DirectPlay3A_QueryInterface
1594          ( LPDIRECTPLAY3A this, REFIID riid, LPVOID* ppvObj )
1595 {
1596   TRACE( dplay, "(%p)->(%p,%p)\n", this, riid, ppvObj );
1597
1598   if( IsEqualGUID( &IID_IUnknown, riid ) ||
1599       IsEqualGUID( &IID_IDirectPlay3A, riid )
1600     )
1601   {
1602     this->lpVtbl->fnAddRef( this );
1603     *ppvObj = this;
1604     return S_OK;
1605   }
1606
1607   return directPlay_QueryInterface( riid, ppvObj );
1608 }
1609
1610
1611 /* Shared between all dplay types */
1612 static ULONG WINAPI DirectPlay3W_AddRef
1613          ( LPDIRECTPLAY3 this )
1614 {
1615   ++(this->ref);
1616   TRACE( dplay,"ref count now %lu\n", this->ref );
1617   return (this->ref);
1618 }
1619
1620 static ULONG WINAPI DirectPlay3W_Release
1621 ( LPDIRECTPLAY3 this )
1622 {
1623   TRACE( dplay, "ref count decremeneted from %lu\n", this->ref );
1624
1625   this->ref--;
1626
1627   /* Deallocate if this is the last reference to the object */
1628   if( !(this->ref) )
1629   {
1630     FIXME( dplay, "memory leak\n" );
1631     /* Implement memory deallocation */
1632
1633     HeapFree( GetProcessHeap(), 0, this );
1634
1635     return 0;
1636   }
1637
1638   return this->ref;
1639 };
1640
1641 static ULONG WINAPI DirectPlay3A_Release
1642 ( LPDIRECTPLAY3A this )
1643 {
1644   TRACE( dplay, "ref count decremeneted from %lu\n", this->ref );
1645
1646   this->ref--;
1647
1648   /* Deallocate if this is the last reference to the object */
1649   if( !(this->ref) )
1650   {
1651     FIXME( dplay, "memory leak\n" );
1652     /* Implement memory deallocation */
1653
1654     HeapFree( GetProcessHeap(), 0, this );
1655
1656     return 0;
1657   }
1658
1659   return this->ref;
1660 };
1661
1662 HRESULT WINAPI DirectPlay3A_AddPlayerToGroup
1663           ( LPDIRECTPLAY3A this, DPID a, DPID b )
1664 {
1665   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx): stub", this, a, b );
1666   return DP_OK;
1667 }
1668
1669 HRESULT WINAPI DirectPlay3W_AddPlayerToGroup
1670           ( LPDIRECTPLAY3 this, DPID a, DPID b )
1671 {
1672   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx): stub", this, a, b );
1673   return DP_OK;
1674 }
1675
1676
1677 HRESULT WINAPI DirectPlay3A_Close
1678           ( LPDIRECTPLAY3A this )
1679 {
1680   FIXME( dplay,"(%p)->(): stub", this );
1681   return DP_OK;
1682 }
1683
1684 HRESULT WINAPI DirectPlay3W_Close
1685           ( LPDIRECTPLAY3 this )
1686 {
1687   FIXME( dplay,"(%p)->(): stub", this );
1688   return DP_OK;
1689 }
1690
1691 HRESULT WINAPI DirectPlay3A_CreateGroup
1692           ( LPDIRECTPLAY3A this, LPDPID a, LPDPNAME b, LPVOID c, DWORD d, DWORD e )
1693 {
1694   FIXME( dplay,"(%p)->(%p,%p,%p,0x%08lx,0x%08lx): stub", this, a, b, c, d, e );
1695   return DP_OK;
1696 }
1697
1698 HRESULT WINAPI DirectPlay3W_CreateGroup
1699           ( LPDIRECTPLAY3 this, LPDPID a, LPDPNAME b, LPVOID c, DWORD d, DWORD e )
1700 {
1701   FIXME( dplay,"(%p)->(%p,%p,%p,0x%08lx,0x%08lx): stub", this, a, b, c, d, e );
1702   return DP_OK;
1703 }
1704
1705 HRESULT WINAPI DirectPlay3A_CreatePlayer
1706           ( LPDIRECTPLAY3A this, LPDPID a, LPDPNAME b, HANDLE32 c, LPVOID d, DWORD e, DWORD f )
1707 {
1708   FIXME( dplay,"(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx): stub", this, a, b, c, d, e, f );
1709   return DP_OK;
1710 }
1711
1712 HRESULT WINAPI DirectPlay3W_CreatePlayer
1713           ( LPDIRECTPLAY3 this, LPDPID a, LPDPNAME b, HANDLE32 c, LPVOID d, DWORD e, DWORD f )
1714 {
1715   FIXME( dplay,"(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx): stub", this, a, b, c, d, e, f );
1716   return DP_OK;
1717 }
1718
1719 HRESULT WINAPI DirectPlay3A_DeletePlayerFromGroup
1720           ( LPDIRECTPLAY3A this, DPID a, DPID b )
1721 {
1722   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx): stub", this, a, b );
1723   return DP_OK;
1724 }
1725
1726 HRESULT WINAPI DirectPlay3W_DeletePlayerFromGroup
1727           ( LPDIRECTPLAY3 this, DPID a, DPID b )
1728 {
1729   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx): stub", this, a, b );
1730   return DP_OK;
1731 }
1732
1733 HRESULT WINAPI DirectPlay3A_DestroyGroup
1734           ( LPDIRECTPLAY3A this, DPID a )
1735 {
1736   FIXME( dplay,"(%p)->(0x%08lx): stub", this, a );
1737   return DP_OK;
1738 }
1739
1740 HRESULT WINAPI DirectPlay3W_DestroyGroup
1741           ( LPDIRECTPLAY3 this, DPID a )
1742 {
1743   FIXME( dplay,"(%p)->(0x%08lx): stub", this, a );
1744   return DP_OK;
1745 }
1746
1747 HRESULT WINAPI DirectPlay3A_DestroyPlayer
1748           ( LPDIRECTPLAY3A this, DPID a )
1749 {
1750   FIXME( dplay,"(%p)->(0x%08lx): stub", this, a );
1751   return DP_OK;
1752 }
1753
1754 HRESULT WINAPI DirectPlay3W_DestroyPlayer
1755           ( LPDIRECTPLAY3 this, DPID a )
1756 {
1757   FIXME( dplay,"(%p)->(0x%08lx): stub", this, a );
1758   return DP_OK;
1759 }
1760
1761 HRESULT WINAPI DirectPlay3A_EnumGroupPlayers
1762           ( LPDIRECTPLAY3A this, DPID a, LPGUID b, LPDPENUMPLAYERSCALLBACK2 c,
1763             LPVOID d, DWORD e )
1764 {
1765   FIXME( dplay,"(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub", this, a, b, c, d, e );
1766   return DP_OK;
1767 }
1768
1769 HRESULT WINAPI DirectPlay3W_EnumGroupPlayers
1770           ( LPDIRECTPLAY3 this, DPID a, LPGUID b, LPDPENUMPLAYERSCALLBACK2 c,
1771             LPVOID d, DWORD e )
1772 {
1773   FIXME( dplay,"(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub", this, a, b, c, d, e );
1774   return DP_OK;
1775 }
1776
1777 HRESULT WINAPI DirectPlay3A_EnumGroups
1778           ( LPDIRECTPLAY3A this, LPGUID a, LPDPENUMPLAYERSCALLBACK2 b, LPVOID c, DWORD d )
1779 {
1780   FIXME( dplay,"(%p)->(%p,%p,%p,0x%08lx): stub", this, a, b, c, d );
1781   return DP_OK;
1782 }
1783
1784 HRESULT WINAPI DirectPlay3W_EnumGroups
1785           ( LPDIRECTPLAY3 this, LPGUID a, LPDPENUMPLAYERSCALLBACK2 b, LPVOID c, DWORD d )
1786 {
1787   FIXME( dplay,"(%p)->(%p,%p,%p,0x%08lx): stub", this, a, b, c, d );
1788   return DP_OK;
1789 }
1790
1791 HRESULT WINAPI DirectPlay3A_EnumPlayers
1792           ( LPDIRECTPLAY3A this, LPGUID a, LPDPENUMPLAYERSCALLBACK2 b, LPVOID c, DWORD d )
1793 {
1794   FIXME( dplay,"(%p)->(%p,%p,%p,0x%08lx): stub", this, a, b, c, d );
1795   return DP_OK;
1796 }
1797
1798 HRESULT WINAPI DirectPlay3W_EnumPlayers
1799           ( LPDIRECTPLAY3 this, LPGUID a, LPDPENUMPLAYERSCALLBACK2 b, LPVOID c, DWORD d )
1800 {
1801   FIXME( dplay,"(%p)->(%p,%p,%p,0x%08lx): stub", this, a, b, c, d );
1802   return DP_OK;
1803 }
1804
1805 HRESULT WINAPI DirectPlay3A_EnumSessions
1806           ( LPDIRECTPLAY3A this, LPDPSESSIONDESC2 a, DWORD b, LPDPENUMSESSIONSCALLBACK2 c,
1807             LPVOID d, DWORD e )
1808 {
1809   FIXME( dplay,"(%p)->(%p,0x%08lx,%p,%p,0x%08lx): stub", this, a, b, c, d, e );
1810   return DP_OK;
1811 }
1812
1813 HRESULT WINAPI DirectPlay3W_EnumSessions
1814           ( LPDIRECTPLAY3 this, LPDPSESSIONDESC2 a, DWORD b, LPDPENUMSESSIONSCALLBACK2 c,
1815             LPVOID d, DWORD e )
1816 {
1817   FIXME( dplay,"(%p)->(%p,0x%08lx,%p,%p,0x%08lx): stub", this, a, b, c, d, e );
1818   return DP_OK;
1819 }
1820
1821 HRESULT WINAPI DirectPlay3A_GetCaps
1822           ( LPDIRECTPLAY3A this, LPDPCAPS a, DWORD b )
1823 {
1824   FIXME( dplay,"(%p)->(%p,0x%08lx): stub", this, a, b );
1825   return DP_OK;
1826 }
1827
1828 HRESULT WINAPI DirectPlay3W_GetCaps
1829           ( LPDIRECTPLAY3 this, LPDPCAPS a, DWORD b )
1830 {
1831   FIXME( dplay,"(%p)->(%p,0x%08lx): stub", this, a, b );
1832   return DP_OK;
1833 }
1834
1835 HRESULT WINAPI DirectPlay3A_GetGroupData
1836           ( LPDIRECTPLAY3 this, DPID a, LPVOID b, LPDWORD c, DWORD d )
1837 {
1838   FIXME( dplay,"(%p)->(0x%08lx,%p,%p,0x%08lx): stub", this, a, b, c, d );
1839   return DP_OK;
1840 }
1841
1842 HRESULT WINAPI DirectPlay3W_GetGroupData
1843           ( LPDIRECTPLAY3 this, DPID a, LPVOID b, LPDWORD c, DWORD d )
1844 {
1845   FIXME( dplay,"(%p)->(0x%08lx,%p,%p,0x%08lx): stub", this, a, b, c, d );
1846   return DP_OK;
1847 }
1848
1849 HRESULT WINAPI DirectPlay3A_GetGroupName
1850           ( LPDIRECTPLAY3A this, DPID a, LPVOID b, LPDWORD c )
1851 {
1852   FIXME( dplay,"(%p)->(0x%08lx,%p,%p): stub", this, a, b, c );
1853   return DP_OK;
1854 }
1855
1856 HRESULT WINAPI DirectPlay3W_GetGroupName
1857           ( LPDIRECTPLAY3 this, DPID a, LPVOID b, LPDWORD c )
1858 {
1859   FIXME( dplay,"(%p)->(0x%08lx,%p,%p): stub", this, a, b, c );
1860   return DP_OK;
1861 }
1862
1863 HRESULT WINAPI DirectPlay3A_GetMessageCount
1864           ( LPDIRECTPLAY3A this, DPID a, LPDWORD b )
1865 {
1866   FIXME( dplay,"(%p)->(0x%08lx,%p): stub", this, a, b );
1867   return DP_OK;
1868 }
1869
1870 HRESULT WINAPI DirectPlay3W_GetMessageCount
1871           ( LPDIRECTPLAY3 this, DPID a, LPDWORD b )
1872 {
1873   FIXME( dplay,"(%p)->(0x%08lx,%p): stub", this, a, b );
1874   return DP_OK;
1875 }
1876
1877 HRESULT WINAPI DirectPlay3A_GetPlayerAddress
1878           ( LPDIRECTPLAY3A this, DPID a, LPVOID b, LPDWORD c )
1879 {
1880   FIXME( dplay,"(%p)->(0x%08lx,%p,%p): stub", this, a, b, c );
1881   return DP_OK;
1882 }
1883
1884 HRESULT WINAPI DirectPlay3W_GetPlayerAddress
1885           ( LPDIRECTPLAY3 this, DPID a, LPVOID b, LPDWORD c )
1886 {
1887   FIXME( dplay,"(%p)->(0x%08lx,%p,%p): stub", this, a, b, c );
1888   return DP_OK;
1889 }
1890
1891 HRESULT WINAPI DirectPlay3A_GetPlayerCaps
1892           ( LPDIRECTPLAY3A this, DPID a, LPDPCAPS b, DWORD c )
1893 {
1894   FIXME( dplay,"(%p)->(0x%08lx,%p,0x%08lx): stub", this, a, b, c );
1895   return DP_OK;
1896 }
1897
1898 HRESULT WINAPI DirectPlay3W_GetPlayerCaps
1899           ( LPDIRECTPLAY3 this, DPID a, LPDPCAPS b, DWORD c )
1900 {
1901   FIXME( dplay,"(%p)->(0x%08lx,%p,0x%08lx): stub", this, a, b, c );
1902   return DP_OK;
1903 }
1904
1905 HRESULT WINAPI DirectPlay3A_GetPlayerData
1906           ( LPDIRECTPLAY3A this, DPID a, LPVOID b, LPDWORD c, DWORD d )
1907 {
1908   FIXME( dplay,"(%p)->(0x%08lx,%p,%p,0x%08lx): stub", this, a, b, c, d );
1909   return DP_OK;
1910 }
1911
1912 HRESULT WINAPI DirectPlay3W_GetPlayerData
1913           ( LPDIRECTPLAY3 this, DPID a, LPVOID b, LPDWORD c, DWORD d )
1914 {
1915   FIXME( dplay,"(%p)->(0x%08lx,%p,%p,0x%08lx): stub", this, a, b, c, d );
1916   return DP_OK;
1917 }
1918
1919 HRESULT WINAPI DirectPlay3A_GetPlayerName
1920           ( LPDIRECTPLAY3 this, DPID a, LPVOID b, LPDWORD c )
1921 {
1922   FIXME( dplay,"(%p)->(0x%08lx,%p,%p): stub", this, a, b, c );
1923   return DP_OK;
1924 }
1925
1926 HRESULT WINAPI DirectPlay3W_GetPlayerName
1927           ( LPDIRECTPLAY3 this, DPID a, LPVOID b, LPDWORD c )
1928 {
1929   FIXME( dplay,"(%p)->(0x%08lx,%p,%p): stub", this, a, b, c );
1930   return DP_OK;
1931 }
1932
1933 HRESULT WINAPI DirectPlay3A_GetSessionDesc
1934           ( LPDIRECTPLAY3A this, LPVOID a, LPDWORD b )
1935 {
1936   FIXME( dplay,"(%p)->(%p,%p): stub", this, a, b );
1937   return DP_OK;
1938 }
1939
1940 HRESULT WINAPI DirectPlay3W_GetSessionDesc
1941           ( LPDIRECTPLAY3 this, LPVOID a, LPDWORD b )
1942 {
1943   FIXME( dplay,"(%p)->(%p,%p): stub", this, a, b );
1944   return DP_OK;
1945 }
1946
1947 HRESULT WINAPI DirectPlay3A_Initialize
1948           ( LPDIRECTPLAY3A this, LPGUID a )
1949 {
1950   FIXME( dplay,"(%p)->(%p): stub", this, a );
1951   return DP_OK;
1952 }
1953
1954 HRESULT WINAPI DirectPlay3W_Initialize
1955           ( LPDIRECTPLAY3 this, LPGUID a )
1956 {
1957   FIXME( dplay,"(%p)->(%p): stub", this, a );
1958   return DP_OK;
1959 }
1960
1961
1962 HRESULT WINAPI DirectPlay3A_Open
1963           ( LPDIRECTPLAY3A this, LPDPSESSIONDESC2 a, DWORD b )
1964 {
1965   FIXME( dplay,"(%p)->(%p,0x%08lx): stub", this, a, b );
1966   return DP_OK;
1967 }
1968
1969 HRESULT WINAPI DirectPlay3W_Open
1970           ( LPDIRECTPLAY3 this, LPDPSESSIONDESC2 a, DWORD b )
1971 {
1972   FIXME( dplay,"(%p)->(%p,0x%08lx): stub", this, a, b );
1973   return DP_OK;
1974 }
1975
1976 HRESULT WINAPI DirectPlay3A_Receive
1977           ( LPDIRECTPLAY3A this, LPDPID a, LPDPID b, DWORD c, LPVOID d, LPDWORD e )
1978 {
1979   FIXME( dplay,"(%p)->(%p,%p,0x%08lx,%p,%p): stub", this, a, b, c, d, e );
1980   return DP_OK;
1981 }
1982
1983 HRESULT WINAPI DirectPlay3W_Receive
1984           ( LPDIRECTPLAY3 this, LPDPID a, LPDPID b, DWORD c, LPVOID d, LPDWORD e )
1985 {
1986   FIXME( dplay,"(%p)->(%p,%p,0x%08lx,%p,%p): stub", this, a, b, c, d, e );
1987   return DP_OK;
1988 }
1989
1990 HRESULT WINAPI DirectPlay3A_Send
1991           ( LPDIRECTPLAY3A this, DPID a, DPID b, DWORD c, LPVOID d, DWORD e )
1992 {
1993   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx): stub", this, a, b, c, d, e );
1994   return DP_OK;
1995 }
1996
1997 HRESULT WINAPI DirectPlay3W_Send
1998           ( LPDIRECTPLAY3 this, DPID a, DPID b, DWORD c, LPVOID d, DWORD e )
1999 {
2000   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx): stub", this, a, b, c, d, e );
2001   return DP_OK;
2002 }
2003
2004 HRESULT WINAPI DirectPlay3A_SetGroupData
2005           ( LPDIRECTPLAY3A this, DPID a, LPVOID b, DWORD c, DWORD d )
2006 {
2007   FIXME( dplay,"(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub", this, a, b, c, d );
2008   return DP_OK;
2009 }
2010
2011 HRESULT WINAPI DirectPlay3W_SetGroupData
2012           ( LPDIRECTPLAY3 this, DPID a, LPVOID b, DWORD c, DWORD d )
2013 {   
2014   FIXME( dplay,"(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub", this, a, b, c, d );
2015   return DP_OK;
2016 }
2017
2018 HRESULT WINAPI DirectPlay3A_SetGroupName
2019           ( LPDIRECTPLAY3A this, DPID a, LPDPNAME b, DWORD c )
2020 {
2021   FIXME( dplay,"(%p)->(0x%08lx,%p,0x%08lx): stub", this, a, b, c );
2022   return DP_OK;
2023 }
2024
2025 HRESULT WINAPI DirectPlay3W_SetGroupName
2026           ( LPDIRECTPLAY3 this, DPID a, LPDPNAME b, DWORD c )
2027 {
2028   FIXME( dplay,"(%p)->(0x%08lx,%p,0x%08lx): stub", this, a, b, c );
2029   return DP_OK;
2030 }
2031
2032 HRESULT WINAPI DirectPlay3A_SetPlayerData
2033           ( LPDIRECTPLAY3A this, DPID a, LPVOID b, DWORD c, DWORD d )
2034 {
2035   FIXME( dplay,"(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub", this, a, b, c, d );
2036   return DP_OK;
2037 }
2038
2039 HRESULT WINAPI DirectPlay3W_SetPlayerData
2040           ( LPDIRECTPLAY3 this, DPID a, LPVOID b, DWORD c, DWORD d )
2041 {
2042   FIXME( dplay,"(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub", this, a, b, c, d );
2043   return DP_OK;
2044 }
2045
2046 HRESULT WINAPI DirectPlay3A_SetPlayerName
2047           ( LPDIRECTPLAY3A this, DPID a, LPDPNAME b, DWORD c )
2048 {
2049   FIXME( dplay,"(%p)->(0x%08lx,%p,0x%08lx): stub", this, a, b, c );
2050   return DP_OK;
2051 }
2052
2053 HRESULT WINAPI DirectPlay3W_SetPlayerName
2054           ( LPDIRECTPLAY3 this, DPID a, LPDPNAME b, DWORD c )
2055 {
2056   FIXME( dplay,"(%p)->(0x%08lx,%p,0x%08lx): stub", this, a, b, c );
2057   return DP_OK;
2058 }
2059
2060 HRESULT WINAPI DirectPlay3A_SetSessionDesc
2061           ( LPDIRECTPLAY3A this, LPDPSESSIONDESC2 a, DWORD b )
2062 {
2063   FIXME( dplay,"(%p)->(%p,0x%08lx): stub", this, a, b );
2064   return DP_OK;
2065 }
2066
2067 HRESULT WINAPI DirectPlay3W_SetSessionDesc
2068           ( LPDIRECTPLAY3 this, LPDPSESSIONDESC2 a, DWORD b )
2069 {
2070   FIXME( dplay,"(%p)->(%p,0x%08lx): stub", this, a, b );
2071   return DP_OK;
2072 }
2073
2074 HRESULT WINAPI DirectPlay3A_AddGroupToGroup
2075           ( LPDIRECTPLAY3A this, DPID a, DPID b )
2076 {
2077   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx): stub", this, a, b );
2078   return DP_OK;
2079 }
2080
2081 HRESULT WINAPI DirectPlay3W_AddGroupToGroup
2082           ( LPDIRECTPLAY3 this, DPID a, DPID b )
2083 {
2084   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx): stub", this, a, b );
2085   return DP_OK;
2086 }
2087
2088 HRESULT WINAPI DirectPlay3A_CreateGroupInGroup
2089           ( LPDIRECTPLAY3A this, DPID a, LPDPID b, LPDPNAME c, LPVOID d, DWORD e, DWORD f )
2090 {
2091   FIXME( dplay,"(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx): stub", this, a, b, c, d, e, f );
2092   return DP_OK;
2093 }
2094
2095 HRESULT WINAPI DirectPlay3W_CreateGroupInGroup
2096           ( LPDIRECTPLAY3 this, DPID a, LPDPID b, LPDPNAME c, LPVOID d, DWORD e, DWORD f )
2097 {
2098   FIXME( dplay,"(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx): stub", this, a, b, c, d, e, f );
2099   return DP_OK;
2100 }
2101
2102 HRESULT WINAPI DirectPlay3A_DeleteGroupFromGroup
2103           ( LPDIRECTPLAY3A this, DPID a, DPID b )
2104 {
2105   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx): stub", this, a, b );
2106   return DP_OK;
2107 }
2108
2109 HRESULT WINAPI DirectPlay3W_DeleteGroupFromGroup
2110           ( LPDIRECTPLAY3 this, DPID a, DPID b )
2111 {
2112   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx): stub", this, a, b );
2113   return DP_OK;
2114 }
2115
2116 HRESULT WINAPI DirectPlay3A_EnumConnections
2117           ( LPDIRECTPLAY3A this, LPCGUID a, LPDPENUMCONNECTIONSCALLBACK b, LPVOID c, DWORD d )
2118 {
2119   FIXME( dplay,"(%p)->(%p,%p,%p,0x%08lx): stub", this, a, b, c, d );
2120   return DP_OK;
2121 }
2122
2123 HRESULT WINAPI DirectPlay3W_EnumConnections
2124           ( LPDIRECTPLAY3 this, LPCGUID a, LPDPENUMCONNECTIONSCALLBACK b, LPVOID c, DWORD d )
2125
2126   FIXME( dplay,"(%p)->(%p,%p,%p,0x%08lx): stub", this, a, b, c, d );
2127   return DP_OK;
2128 }
2129
2130 HRESULT WINAPI DirectPlay3A_EnumGroupsInGroup
2131           ( LPDIRECTPLAY3A this, DPID a, LPGUID b, LPDPENUMPLAYERSCALLBACK2 c, LPVOID d, DWORD e )
2132 {
2133   FIXME( dplay,"(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub", this, a, b, c, d, e );
2134   return DP_OK;
2135 }
2136
2137 HRESULT WINAPI DirectPlay3W_EnumGroupsInGroup
2138           ( LPDIRECTPLAY3 this, DPID a, LPGUID b, LPDPENUMPLAYERSCALLBACK2 c, LPVOID d, DWORD e )
2139 {
2140   FIXME( dplay,"(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub", this, a, b, c, d, e );
2141   return DP_OK;
2142 }
2143
2144 HRESULT WINAPI DirectPlay3A_GetGroupConnectionSettings
2145           ( LPDIRECTPLAY3A this, DWORD a, DPID b, LPVOID c, LPDWORD d )
2146 {
2147   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx,%p,%p): stub", this, a, b, c, d );
2148   return DP_OK;
2149 }
2150
2151 HRESULT WINAPI DirectPlay3W_GetGroupConnectionSettings
2152           ( LPDIRECTPLAY3 this, DWORD a, DPID b, LPVOID c, LPDWORD d )
2153 {
2154   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx,%p,%p): stub", this, a, b, c, d );
2155   return DP_OK;
2156 }
2157
2158 HRESULT WINAPI DirectPlay3A_InitializeConnection
2159           ( LPDIRECTPLAY3A this, LPVOID a, DWORD b )
2160 {
2161   FIXME( dplay,"(%p)->(%p,0x%08lx): stub", this, a, b );
2162   return DP_OK;
2163 }
2164
2165 HRESULT WINAPI DirectPlay3W_InitializeConnection
2166           ( LPDIRECTPLAY3 this, LPVOID a, DWORD b )
2167 {
2168   FIXME( dplay,"(%p)->(%p,0x%08lx): stub", this, a, b );
2169   return DP_OK;
2170 }
2171
2172 HRESULT WINAPI DirectPlay3A_SecureOpen
2173           ( LPDIRECTPLAY3A this, LPCDPSESSIONDESC2 a, DWORD b, LPCDPSECURITYDESC c, LPCDPCREDENTIALS d )
2174 {
2175   FIXME( dplay,"(%p)->(%p,0x%08lx,%p,%p): stub", this, a, b, c, d );
2176   return DP_OK;
2177 }
2178
2179 HRESULT WINAPI DirectPlay3W_SecureOpen
2180           ( LPDIRECTPLAY3 this, LPCDPSESSIONDESC2 a, DWORD b, LPCDPSECURITYDESC c, LPCDPCREDENTIALS d )
2181 {   
2182   FIXME( dplay,"(%p)->(%p,0x%08lx,%p,%p): stub", this, a, b, c, d );
2183   return DP_OK;
2184 }
2185
2186 HRESULT WINAPI DirectPlay3A_SendChatMessage
2187           ( LPDIRECTPLAY3A this, DPID a, DPID b, DWORD c, LPDPCHAT d )
2188 {
2189   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx,0x%08lx,%p): stub", this, a, b, c, d );
2190   return DP_OK;
2191 }
2192
2193 HRESULT WINAPI DirectPlay3W_SendChatMessage
2194           ( LPDIRECTPLAY3 this, DPID a, DPID b, DWORD c, LPDPCHAT d )
2195 {
2196   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx,0x%08lx,%p): stub", this, a, b, c, d );
2197   return DP_OK;
2198 }
2199
2200 HRESULT WINAPI DirectPlay3A_SetGroupConnectionSettings
2201           ( LPDIRECTPLAY3A this, DWORD a, DPID b, LPDPLCONNECTION c )
2202 {
2203   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx,%p): stub", this, a, b, c );
2204   return DP_OK;
2205 }
2206
2207 HRESULT WINAPI DirectPlay3W_SetGroupConnectionSettings
2208           ( LPDIRECTPLAY3 this, DWORD a, DPID b, LPDPLCONNECTION c )
2209 {
2210   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx,%p): stub", this, a, b, c );
2211   return DP_OK;
2212 }
2213
2214 HRESULT WINAPI DirectPlay3A_StartSession
2215           ( LPDIRECTPLAY3A this, DWORD a, DPID b )
2216 {
2217   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx): stub", this, a, b );
2218   return DP_OK;
2219 }
2220
2221 HRESULT WINAPI DirectPlay3W_StartSession
2222           ( LPDIRECTPLAY3 this, DWORD a, DPID b )
2223 {
2224   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx): stub", this, a, b );
2225   return DP_OK;
2226 }
2227  
2228 HRESULT WINAPI DirectPlay3A_GetGroupFlags
2229           ( LPDIRECTPLAY3A this, DPID a, LPDWORD b )
2230 {
2231   FIXME( dplay,"(%p)->(0x%08lx,%p): stub", this, a, b );
2232   return DP_OK;
2233 }
2234
2235 HRESULT WINAPI DirectPlay3W_GetGroupFlags
2236           ( LPDIRECTPLAY3 this, DPID a, LPDWORD b )
2237 {
2238   FIXME( dplay,"(%p)->(0x%08lx,%p): stub", this, a, b );
2239   return DP_OK;
2240 }
2241
2242 HRESULT WINAPI DirectPlay3A_GetGroupParent
2243           ( LPDIRECTPLAY3A this, DPID a, LPDPID b )
2244 {
2245   FIXME( dplay,"(%p)->(0x%08lx,%p): stub", this, a, b );
2246   return DP_OK;
2247 }
2248
2249 HRESULT WINAPI DirectPlay3W_GetGroupParent
2250           ( LPDIRECTPLAY3 this, DPID a, LPDPID b )
2251 {
2252   FIXME( dplay,"(%p)->(0x%08lx,%p): stub", this, a, b );
2253   return DP_OK;
2254 }
2255
2256 HRESULT WINAPI DirectPlay3A_GetPlayerAccount
2257           ( LPDIRECTPLAY3A this, DPID a, DWORD b, LPVOID c, LPDWORD d )
2258 {
2259   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx,%p,%p): stub", this, a, b, c, d );
2260   return DP_OK;
2261 }
2262
2263 HRESULT WINAPI DirectPlay3W_GetPlayerAccount
2264           ( LPDIRECTPLAY3 this, DPID a, DWORD b, LPVOID c, LPDWORD d )
2265 {
2266   FIXME( dplay,"(%p)->(0x%08lx,0x%08lx,%p,%p): stub", this, a, b, c, d );
2267   return DP_OK;
2268 }
2269
2270 HRESULT WINAPI DirectPlay3A_GetPlayerFlags
2271           ( LPDIRECTPLAY3A this, DPID a, LPDWORD b )
2272 {
2273   FIXME( dplay,"(%p)->(0x%08lx,%p): stub", this, a, b );
2274   return DP_OK;
2275 }
2276
2277 HRESULT WINAPI DirectPlay3W_GetPlayerFlags
2278           ( LPDIRECTPLAY3 this, DPID a, LPDWORD b )
2279 {
2280   FIXME( dplay,"(%p)->(0x%08lx,%p): stub", this, a, b );
2281   return DP_OK;
2282 }
2283
2284 static struct tagLPDIRECTPLAY2_VTABLE directPlay2WVT = {
2285   DirectPlay2W_QueryInterface,
2286   (void*)DirectPlay3W_AddRef,
2287   (void*)DirectPlay3W_Release,
2288   (void*)DirectPlay3W_AddPlayerToGroup,
2289   (void*)DirectPlay3W_Close,
2290   (void*)DirectPlay3W_CreateGroup,
2291   (void*)DirectPlay3W_CreatePlayer,
2292   (void*)DirectPlay3W_DeletePlayerFromGroup,
2293   (void*)DirectPlay3W_DestroyGroup,
2294   (void*)DirectPlay3W_DestroyPlayer,
2295   (void*)DirectPlay3W_EnumGroupPlayers,
2296   (void*)DirectPlay3W_EnumGroups,
2297   (void*)DirectPlay3W_EnumPlayers,
2298   (void*)DirectPlay3W_EnumSessions,
2299   (void*)DirectPlay3W_GetCaps,
2300   (void*)DirectPlay3W_GetGroupData,
2301   (void*)DirectPlay3W_GetGroupName,
2302   (void*)DirectPlay3W_GetMessageCount,
2303   (void*)DirectPlay3W_GetPlayerAddress,
2304   (void*)DirectPlay3W_GetPlayerCaps,
2305   (void*)DirectPlay3W_GetPlayerData,
2306   (void*)DirectPlay3W_GetPlayerName,
2307   (void*)DirectPlay3W_GetSessionDesc,
2308   (void*)DirectPlay3W_Initialize,
2309   (void*)DirectPlay3W_Open,
2310   (void*)DirectPlay3W_Receive,
2311   (void*)DirectPlay3W_Send,
2312   (void*)DirectPlay3W_SetGroupData,
2313   (void*)DirectPlay3W_SetGroupName,
2314   (void*)DirectPlay3W_SetPlayerData,
2315   (void*)DirectPlay3W_SetPlayerName,
2316   (void*)DirectPlay3W_SetSessionDesc
2317 };
2318
2319 static struct tagLPDIRECTPLAY2_VTABLE directPlay2AVT = {
2320   DirectPlay2A_QueryInterface,
2321   (void*)DirectPlay3W_AddRef,
2322   (void*)DirectPlay3A_Release,
2323   (void*)DirectPlay3A_AddPlayerToGroup,
2324   (void*)DirectPlay3A_Close,
2325   (void*)DirectPlay3A_CreateGroup,
2326   (void*)DirectPlay3A_CreatePlayer,
2327   (void*)DirectPlay3A_DeletePlayerFromGroup,
2328   (void*)DirectPlay3A_DestroyGroup,
2329   (void*)DirectPlay3A_DestroyPlayer,
2330   (void*)DirectPlay3A_EnumGroupPlayers,
2331   (void*)DirectPlay3A_EnumGroups,
2332   (void*)DirectPlay3A_EnumPlayers,
2333   (void*)DirectPlay3A_EnumSessions,
2334   (void*)DirectPlay3A_GetCaps,
2335   (void*)DirectPlay3A_GetGroupData,
2336   (void*)DirectPlay3A_GetGroupName,
2337   (void*)DirectPlay3A_GetMessageCount,
2338   (void*)DirectPlay3A_GetPlayerAddress,
2339   (void*)DirectPlay3A_GetPlayerCaps,
2340   (void*)DirectPlay3A_GetPlayerData,
2341   (void*)DirectPlay3A_GetPlayerName,
2342   (void*)DirectPlay3A_GetSessionDesc,
2343   (void*)DirectPlay3A_Initialize,
2344   (void*)DirectPlay3A_Open,
2345   (void*)DirectPlay3A_Receive,
2346   (void*)DirectPlay3A_Send,
2347   (void*)DirectPlay3A_SetGroupData,
2348   (void*)DirectPlay3A_SetGroupName,
2349   (void*)DirectPlay3A_SetPlayerData,
2350   (void*)DirectPlay3A_SetPlayerName,
2351   (void*)DirectPlay3A_SetSessionDesc
2352 };
2353
2354 static struct tagLPDIRECTPLAY3_VTABLE directPlay3AVT = {
2355   DirectPlay3A_QueryInterface,
2356   (void*)DirectPlay3W_AddRef,
2357   DirectPlay3A_Release,
2358   DirectPlay3A_AddPlayerToGroup,
2359   DirectPlay3A_Close,
2360   DirectPlay3A_CreateGroup,
2361   DirectPlay3A_CreatePlayer,
2362   DirectPlay3A_DeletePlayerFromGroup,
2363   DirectPlay3A_DestroyGroup,
2364   DirectPlay3A_DestroyPlayer,
2365   DirectPlay3A_EnumGroupPlayers,
2366   DirectPlay3A_EnumGroups,
2367   DirectPlay3A_EnumPlayers,
2368   DirectPlay3A_EnumSessions,
2369   DirectPlay3A_GetCaps,
2370   DirectPlay3A_GetGroupData,
2371   DirectPlay3A_GetGroupName,
2372   DirectPlay3A_GetMessageCount,
2373   DirectPlay3A_GetPlayerAddress,
2374   DirectPlay3A_GetPlayerCaps,
2375   DirectPlay3A_GetPlayerData,
2376   DirectPlay3A_GetPlayerName,
2377   DirectPlay3A_GetSessionDesc,
2378   DirectPlay3A_Initialize,
2379   DirectPlay3A_Open,
2380   DirectPlay3A_Receive,
2381   DirectPlay3A_Send,
2382   DirectPlay3A_SetGroupData,
2383   DirectPlay3A_SetGroupName,
2384   DirectPlay3A_SetPlayerData,
2385   DirectPlay3A_SetPlayerName,
2386   DirectPlay3A_SetSessionDesc,
2387
2388   DirectPlay3A_AddGroupToGroup,
2389   DirectPlay3A_CreateGroupInGroup,
2390   DirectPlay3A_DeleteGroupFromGroup,
2391   DirectPlay3A_EnumConnections,
2392   DirectPlay3A_EnumGroupsInGroup,
2393   DirectPlay3A_GetGroupConnectionSettings,
2394   DirectPlay3A_InitializeConnection,
2395   DirectPlay3A_SecureOpen,
2396   DirectPlay3A_SendChatMessage,
2397   DirectPlay3A_SetGroupConnectionSettings,
2398   DirectPlay3A_StartSession,
2399   DirectPlay3A_GetGroupFlags,
2400   DirectPlay3A_GetGroupParent,
2401   DirectPlay3A_GetPlayerAccount,
2402   DirectPlay3A_GetPlayerFlags
2403 };
2404
2405 static struct tagLPDIRECTPLAY3_VTABLE directPlay3WVT = {
2406   DirectPlay3W_QueryInterface,
2407   DirectPlay3W_AddRef,
2408   DirectPlay3W_Release,
2409   DirectPlay3W_AddPlayerToGroup,
2410   DirectPlay3W_Close,
2411   DirectPlay3W_CreateGroup,
2412   DirectPlay3W_CreatePlayer,
2413   DirectPlay3W_DeletePlayerFromGroup,
2414   DirectPlay3W_DestroyGroup,
2415   DirectPlay3W_DestroyPlayer,
2416   DirectPlay3W_EnumGroupPlayers,
2417   DirectPlay3W_EnumGroups,
2418   DirectPlay3W_EnumPlayers,
2419   DirectPlay3W_EnumSessions,
2420   DirectPlay3W_GetCaps,
2421   DirectPlay3W_GetGroupData,
2422   DirectPlay3W_GetGroupName,
2423   DirectPlay3W_GetMessageCount,
2424   DirectPlay3W_GetPlayerAddress,
2425   DirectPlay3W_GetPlayerCaps,
2426   DirectPlay3W_GetPlayerData,
2427   DirectPlay3W_GetPlayerName,
2428   DirectPlay3W_GetSessionDesc,
2429   DirectPlay3W_Initialize,
2430   DirectPlay3W_Open,
2431   DirectPlay3W_Receive,
2432   DirectPlay3W_Send,
2433   DirectPlay3W_SetGroupData,
2434   DirectPlay3W_SetGroupName,
2435   DirectPlay3W_SetPlayerData,
2436   DirectPlay3W_SetPlayerName,
2437   DirectPlay3W_SetSessionDesc,
2438
2439   DirectPlay3W_AddGroupToGroup,
2440   DirectPlay3W_CreateGroupInGroup,
2441   DirectPlay3W_DeleteGroupFromGroup,
2442   DirectPlay3W_EnumConnections,
2443   DirectPlay3W_EnumGroupsInGroup,
2444   DirectPlay3W_GetGroupConnectionSettings,
2445   DirectPlay3W_InitializeConnection,
2446   DirectPlay3W_SecureOpen,
2447   DirectPlay3W_SendChatMessage,
2448   DirectPlay3W_SetGroupConnectionSettings,
2449   DirectPlay3W_StartSession,
2450   DirectPlay3W_GetGroupFlags,
2451   DirectPlay3W_GetGroupParent,
2452   DirectPlay3W_GetPlayerAccount,
2453   DirectPlay3W_GetPlayerFlags
2454 };
2455