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