- Moved dplay and dplayx to a proper home in the dlls directory.
- Implemented new DirectPlay4 and DirectPlayLobby3 interfaces.
- Implemented a class factory for dplay and dplobby. COM interfaces
  now work for dp and dpl.
- Added a few more entries to dplayx.spec files. How do you find the
  ordinals? I just guessed :(
- Seperated DirectPlay and DirectPlayLobby implementation into separate files.
- Included some missing header file definitions.
- Implemented the dplay dll in terms of the dplayx dll. I haven't
  tested it so it may not work...
- A few bug fixes and a little new implementatioe.n
- Updated document with a more detailed implementation plan.

diff --git a/Makefile.in b/Makefile.in
index 3ddf0e8..bba46b1 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -36,6 +36,7 @@
 	dlls/commdlg \
 	dlls/crtdll \
 	dlls/dciman32 \
+	dlls/dplayx \
 	dlls/imagehlp \
 	dlls/imm32 \
 	dlls/lzexpand \
@@ -135,6 +136,7 @@
 	dlls/commdlg/commdlg.o \
 	dlls/crtdll/crtdll.o \
 	dlls/dciman32/dciman32.o \
+	dlls/dplayx/dplayx.o \
 	dlls/imagehlp/imagehlp.o \
 	dlls/imm32/imm32.o \
 	dlls/lzexpand/lzexpand.o \
diff --git a/configure b/configure
index 7d009d6..968a40d 100755
--- a/configure
+++ b/configure
@@ -5624,6 +5624,7 @@
 dlls/commdlg/Makefile
 dlls/crtdll/Makefile
 dlls/dciman32/Makefile
+dlls/dplayx/Makefile
 dlls/imagehlp/Makefile
 dlls/imm32/Makefile
 dlls/lzexpand/Makefile
@@ -5819,6 +5820,7 @@
 dlls/commdlg/Makefile
 dlls/crtdll/Makefile
 dlls/dciman32/Makefile
+dlls/dplayx/Makefile
 dlls/imagehlp/Makefile
 dlls/imm32/Makefile
 dlls/lzexpand/Makefile
diff --git a/configure.in b/configure.in
index 6007c52..ba9f6b3 100644
--- a/configure.in
+++ b/configure.in
@@ -831,6 +831,7 @@
 dlls/commdlg/Makefile
 dlls/crtdll/Makefile
 dlls/dciman32/Makefile
+dlls/dplayx/Makefile
 dlls/imagehlp/Makefile
 dlls/imm32/Makefile
 dlls/lzexpand/Makefile
diff --git a/dlls/Makefile.in b/dlls/Makefile.in
index f3e7733..1df8185 100644
--- a/dlls/Makefile.in
+++ b/dlls/Makefile.in
@@ -5,6 +5,7 @@
 	commdlg \
 	crtdll \
 	dciman32 \
+	dplayx \
 	imagehlp \
 	imm32 \
 	lzexpand \
diff --git a/dlls/dplayx/.cvsignore b/dlls/dplayx/.cvsignore
new file mode 100644
index 0000000..96f8530
--- /dev/null
+++ b/dlls/dplayx/.cvsignore
@@ -0,0 +1,3 @@
+Makefile
+dplay.spec.c
+dplayx.spec.c
diff --git a/dlls/dplayx/Makefile.in b/dlls/dplayx/Makefile.in
new file mode 100644
index 0000000..9819b79
--- /dev/null
+++ b/dlls/dplayx/Makefile.in
@@ -0,0 +1,19 @@
+DEFS      = @DLLFLAGS@ -D__WINE__
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = dplayx
+
+SPEC_SRCS = dplay.spec dplayx.spec 
+
+C_SRCS = dplay.c \
+         dplobby.c \
+         dpclassfactory.c
+
+all: $(MODULE).o
+
+@MAKE_RULES@
+
+### Dependencies:
+
diff --git a/dlls/dplayx/dpclassfactory.c b/dlls/dplayx/dpclassfactory.c
new file mode 100644
index 0000000..b418efa
--- /dev/null
+++ b/dlls/dplayx/dpclassfactory.c
@@ -0,0 +1,134 @@
+
+#include "wine/obj_base.h"
+#include "winerror.h"
+#include "debugtools.h"
+#include "dpinit.h"
+
+DEFAULT_DEBUG_CHANNEL(dplay)
+
+
+/*******************************************************************************
+ * DirectPlayLobby ClassFactory
+ */
+
+typedef struct
+{
+    /* IUnknown fields */
+    ICOM_VTABLE(IClassFactory)* lpvtbl;
+    DWORD                       ref;
+} IClassFactoryImpl;
+
+static HRESULT WINAPI
+DP_and_DPL_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
+        ICOM_THIS(IClassFactoryImpl,iface);
+        char buf[80];
+
+        if (HIWORD(riid))
+            WINE_StringFromCLSID(riid,buf);
+        else
+            sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
+
+        FIXME("(%p)->(%s,%p),stub!\n",This,buf,ppobj);
+
+        return E_NOINTERFACE;
+}
+
+static ULONG WINAPI
+DP_and_DPL_AddRef(LPCLASSFACTORY iface) {
+        ICOM_THIS(IClassFactoryImpl,iface);
+        return ++(This->ref);
+}
+
+static ULONG WINAPI DP_and_DPL_Release(LPCLASSFACTORY iface) {
+        ICOM_THIS(IClassFactoryImpl,iface);
+        /* static class (reference starts @ 1), won't ever be freed */
+        return --(This->ref);
+}
+
+/* Not the most efficient implementation, but it's simple */
+static HRESULT WINAPI DP_and_DPL_CreateInstance(
+        LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
+) {
+        ICOM_THIS(IClassFactoryImpl,iface);
+        char buf[80];
+
+        WINE_StringFromCLSID(riid,buf);
+        TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
+
+        /* FIXME: reuse already created DP/DPL object if present? */
+        if ( directPlayLobby_QueryInterface( riid, ppobj ) == S_OK )
+        {
+           return S_OK;
+        }
+        else if ( directPlay_QueryInterface( riid, ppobj ) == S_OK )
+        {
+           return S_OK;
+        }
+
+        return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI DP_and_DPL_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
+        ICOM_THIS(IClassFactoryImpl,iface);
+        FIXME("(%p)->(%d),stub!\n",This,dolock);
+        return S_OK;
+}
+
+static ICOM_VTABLE(IClassFactory) DP_and_DPL_Vtbl = {
+        DP_and_DPL_QueryInterface,
+        DP_and_DPL_AddRef,
+        DP_and_DPL_Release,
+        DP_and_DPL_CreateInstance,
+        DP_and_DPL_LockServer
+};
+
+static IClassFactoryImpl DP_and_DPL_CF = {&DP_and_DPL_Vtbl, 1 };
+
+
+/*******************************************************************************
+ * DllGetClassObject [DPLAYX.?]
+ * Retrieves DP or DPL class object from a DLL object
+ *
+ * NOTES
+ *    Docs say returns STDAPI
+ *
+ * PARAMS
+ *    rclsid [I] CLSID for the class object
+ *    riid   [I] Reference to identifier of interface for class object
+ *    ppv    [O] Address of variable to receive interface pointer for riid
+ *
+ * RETURNS
+ *    Success: S_OK
+ *    Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
+ *             E_UNEXPECTED
+ */
+DWORD WINAPI DP_and_DPL_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
+{
+    char buf[80],xbuf[80];
+
+    if (HIWORD(rclsid))
+        WINE_StringFromCLSID(rclsid,xbuf);
+    else
+        sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
+
+    if (HIWORD(riid))
+        WINE_StringFromCLSID(riid,buf);
+    else
+        sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
+
+    WINE_StringFromCLSID(riid,xbuf);
+
+    TRACE("(%p,%p,%p)\n", xbuf, buf, ppv);
+
+    if ( IsEqualCLSID( riid, &IID_IClassFactory ) )
+    {
+        *ppv = (LPVOID)&DP_and_DPL_CF;
+        IClassFactory_AddRef( (IClassFactory*)*ppv );
+
+        return S_OK;
+    }
+
+    ERR("(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
+    return CLASS_E_CLASSNOTAVAILABLE;
+}
+
diff --git a/dlls/dplayx/dpinit.h b/dlls/dplayx/dpinit.h
new file mode 100644
index 0000000..8408765
--- /dev/null
+++ b/dlls/dplayx/dpinit.h
@@ -0,0 +1,8 @@
+
+#ifndef __WINE_DPINIT_H
+#define __WINE_DPINIT_H
+
+extern HRESULT directPlay_QueryInterface( REFIID riid, LPVOID* ppvObj );
+extern HRESULT directPlayLobby_QueryInterface( REFIID riid, LPVOID* ppvObj );
+
+#endif
diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c
new file mode 100644
index 0000000..14ccc9a
--- /dev/null
+++ b/dlls/dplayx/dplay.c
@@ -0,0 +1,1726 @@
+/* Direct Play 2,3,4 Implementation
+ *
+ * Copyright 1998,1999 - Peter Hunnisett
+ *
+ * <presently under construction - contact hunnise@nortelnetworks.com>
+ *
+ */
+#include <string.h>
+#include "winerror.h"
+#include "winnt.h"
+#include "winreg.h"
+#include "dplay.h"
+#include "heap.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(dplay)
+
+
+/*****************************************************************************
+ * Predeclare the interface implementation structures
+ */
+typedef struct IDirectPlayImpl IDirectPlay2AImpl;
+typedef struct IDirectPlayImpl IDirectPlay2Impl;
+typedef struct IDirectPlayImpl IDirectPlay3AImpl;
+typedef struct IDirectPlayImpl IDirectPlay3Impl;
+typedef struct IDirectPlayImpl IDirectPlay4AImpl;
+typedef struct IDirectPlayImpl IDirectPlay4Impl;
+
+/* Forward declarations of virtual tables */
+static ICOM_VTABLE(IDirectPlay2) directPlay2WVT;
+static ICOM_VTABLE(IDirectPlay2) directPlay2AVT;
+static ICOM_VTABLE(IDirectPlay3) directPlay3WVT;
+static ICOM_VTABLE(IDirectPlay3) directPlay3AVT;
+static ICOM_VTABLE(IDirectPlay4) directPlay4WVT;
+static ICOM_VTABLE(IDirectPlay4) directPlay4AVT;
+
+/*****************************************************************************
+ * IDirectPlay implementation structure
+ */
+struct IDirectPlayImpl
+{
+    /* IUnknown fields */
+    ICOM_VTABLE(IDirectPlay4)* lpvtbl;
+    DWORD                      ref;
+    CRITICAL_SECTION           DP_lock;
+    /* IDirectPlay3Impl fields */
+    /* none so far */
+    /* IDirectPlay4Impl fields */
+    /* none so far */
+};
+
+
+
+/* Get a new interface. To be used by QueryInterface. */ 
+extern 
+HRESULT directPlay_QueryInterface 
+         ( REFIID riid, LPVOID* ppvObj )
+{
+
+  if( IsEqualGUID( &IID_IDirectPlay2, riid ) )
+  {
+    IDirectPlay2Impl* lpDP;
+
+    lpDP = (IDirectPlay2Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                         sizeof( *lpDP ) );
+
+    if( !lpDP ) 
+    {
+       return DPERR_OUTOFMEMORY;
+    }
+
+    lpDP->lpvtbl = &directPlay2WVT;
+
+    InitializeCriticalSection( &lpDP->DP_lock );
+    IDirectPlayX_AddRef( lpDP );
+
+    *ppvObj = lpDP;
+
+    return S_OK;
+  } 
+  else if( IsEqualGUID( &IID_IDirectPlay2A, riid ) )
+  {
+    IDirectPlay2AImpl* lpDP;
+
+    lpDP = (IDirectPlay2AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                          sizeof( *lpDP ) );
+
+    if( !lpDP )
+    {
+       return DPERR_OUTOFMEMORY;
+    }
+
+    lpDP->lpvtbl = &directPlay2AVT;
+    InitializeCriticalSection( &lpDP->DP_lock );
+    IDirectPlayX_AddRef( lpDP );
+
+    *ppvObj = lpDP;
+
+    return S_OK;
+  }
+  else if( IsEqualGUID( &IID_IDirectPlay3, riid ) )
+  {
+    IDirectPlay3Impl* lpDP;
+
+    lpDP = (IDirectPlay3Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                         sizeof( *lpDP ) );
+
+    if( !lpDP )
+    {
+       return DPERR_OUTOFMEMORY;
+    }
+
+    lpDP->lpvtbl = &directPlay3WVT;
+    InitializeCriticalSection( &lpDP->DP_lock );
+    IDirectPlayX_AddRef( lpDP );
+
+    *ppvObj = lpDP;
+
+    return S_OK;
+  }
+  else if( IsEqualGUID( &IID_IDirectPlay3A, riid ) )
+  {
+    IDirectPlay3AImpl* lpDP;
+
+    lpDP = (IDirectPlay3AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                          sizeof( *lpDP ) );
+
+    if( !lpDP )
+    {
+       return DPERR_OUTOFMEMORY;
+    }
+
+    lpDP->lpvtbl = &directPlay3AVT;
+    InitializeCriticalSection( &lpDP->DP_lock );
+    IDirectPlayX_AddRef( lpDP );
+
+    *ppvObj = lpDP;
+
+    return S_OK;
+  }
+  else if( IsEqualGUID( &IID_IDirectPlay4, riid ) )
+  {
+    IDirectPlay4Impl* lpDP;
+
+    lpDP = (IDirectPlay4Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                         sizeof( *lpDP ) );
+
+    if( !lpDP )
+    {
+       return DPERR_OUTOFMEMORY;
+    }
+
+    lpDP->lpvtbl = &directPlay4WVT;
+    InitializeCriticalSection( &lpDP->DP_lock );
+    IDirectPlayX_AddRef( lpDP );
+
+    *ppvObj = lpDP;
+
+    return S_OK;
+  }
+  else if( IsEqualGUID( &IID_IDirectPlay4A, riid ) )
+  {
+    IDirectPlay4AImpl* lpDP;
+
+    lpDP = (IDirectPlay4AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                          sizeof( *lpDP ) );
+
+    if( !lpDP )
+    {
+       return DPERR_OUTOFMEMORY;
+    }
+
+    lpDP->lpvtbl = &directPlay4AVT;
+    InitializeCriticalSection( &lpDP->DP_lock );
+    IDirectPlayX_AddRef( lpDP );
+
+    *ppvObj = lpDP;
+
+    return S_OK;
+  }
+
+  /* Unsupported interface */
+  *ppvObj = NULL;
+  return E_NOINTERFACE;
+}
+
+
+/* Direct Play methods */
+static HRESULT WINAPI DirectPlay2W_QueryInterface
+         ( LPDIRECTPLAY2 iface, REFIID riid, LPVOID* ppvObj )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
+
+  if( IsEqualGUID( &IID_IUnknown, riid ) ||
+      IsEqualGUID( &IID_IDirectPlay2, riid )
+    )
+  {
+    IDirectPlayX_AddRef( iface );
+    *ppvObj = This;
+    return S_OK;
+  }
+  return directPlay_QueryInterface( riid, ppvObj );
+}
+
+static HRESULT WINAPI DirectPlay2A_QueryInterface
+         ( LPDIRECTPLAY2A iface, REFIID riid, LPVOID* ppvObj )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
+
+  if( IsEqualGUID( &IID_IUnknown, riid ) ||
+      IsEqualGUID( &IID_IDirectPlay2A, riid )
+    )
+  {
+    IDirectPlayX_AddRef( iface );
+    *ppvObj = This;
+    return S_OK;
+  }
+
+  return directPlay_QueryInterface( riid, ppvObj );
+}
+
+static HRESULT WINAPI DirectPlay3WImpl_QueryInterface
+         ( LPDIRECTPLAY3 iface, REFIID riid, LPVOID* ppvObj )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
+
+  if( IsEqualGUID( &IID_IUnknown, riid ) ||
+      IsEqualGUID( &IID_IDirectPlay3, riid )
+    )
+  {
+    IDirectPlayX_AddRef( iface );
+    *ppvObj = This;
+    return S_OK;
+  }
+
+  return directPlay_QueryInterface( riid, ppvObj );
+}
+
+static HRESULT WINAPI DirectPlay3AImpl_QueryInterface
+         ( LPDIRECTPLAY3A iface, REFIID riid, LPVOID* ppvObj )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
+
+  if( IsEqualGUID( &IID_IUnknown, riid ) ||
+      IsEqualGUID( &IID_IDirectPlay3A, riid )
+    )
+  {
+    IDirectPlayX_AddRef( iface );
+    *ppvObj = This;
+    return S_OK;
+  }
+
+  return directPlay_QueryInterface( riid, ppvObj );
+}
+
+static HRESULT WINAPI DirectPlay4WImpl_QueryInterface
+         ( LPDIRECTPLAY4 iface, REFIID riid, LPVOID* ppvObj )
+{
+  ICOM_THIS(IDirectPlay4Impl,iface);
+  TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
+
+  if( IsEqualGUID( &IID_IUnknown, riid ) ||
+      IsEqualGUID( &IID_IDirectPlay4, riid )
+    )
+  {
+    IDirectPlayX_AddRef( iface );
+    *ppvObj = This;
+    return S_OK;
+  }
+
+  return directPlay_QueryInterface( riid, ppvObj );
+}
+
+
+static HRESULT WINAPI DirectPlay4AImpl_QueryInterface
+         ( LPDIRECTPLAY4A iface, REFIID riid, LPVOID* ppvObj )
+{
+  ICOM_THIS(IDirectPlay4Impl,iface);
+  TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
+
+  if( IsEqualGUID( &IID_IUnknown, riid ) ||
+      IsEqualGUID( &IID_IDirectPlay4A, riid )
+    )
+  {
+    IDirectPlayX_AddRef( iface );
+    *ppvObj = This;
+    return S_OK;
+  }
+
+  return directPlay_QueryInterface( riid, ppvObj );
+}
+
+
+/* Shared between all dplay types */
+static ULONG WINAPI DirectPlay2AImpl_AddRef
+         ( LPDIRECTPLAY3 iface )
+{
+  ULONG refCount;
+  ICOM_THIS(IDirectPlay3Impl,iface);
+
+  EnterCriticalSection( &This->DP_lock ); 
+  {
+    refCount = ++(This->ref);
+  }  
+  LeaveCriticalSection( &This->DP_lock );
+
+  TRACE("ref count incremented to %lu for %p\n", refCount, This );
+
+  return (This->ref);
+}
+
+static ULONG WINAPI DirectPlay2AImpl_Release
+( LPDIRECTPLAY3 iface )
+{
+  ULONG refCount;
+
+  ICOM_THIS(IDirectPlay3Impl,iface);
+
+  EnterCriticalSection( &This->DP_lock );
+  {
+    refCount = --(This->ref);
+  }
+  LeaveCriticalSection( &This->DP_lock );
+
+  TRACE("ref count decremeneted to %lu for %p\n", refCount, This );
+
+  /* Deallocate if this is the last reference to the object */
+  if( refCount == 0 )
+  {
+    FIXME("memory leak\n" );
+    /* Implement memory deallocation */
+
+    HeapFree( GetProcessHeap(), 0, This );
+  }
+
+  return refCount;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_AddPlayerToGroup
+          ( LPDIRECTPLAY2A iface, DPID idGroup, DPID idPlayer )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idPlayer );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_AddPlayerToGroup
+          ( LPDIRECTPLAY2 iface, DPID idGroup, DPID idPlayer )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idPlayer );
+  return DP_OK;
+}
+
+
+static HRESULT WINAPI DirectPlay2AImpl_Close
+          ( LPDIRECTPLAY2A iface )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(): stub\n", This );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_Close
+          ( LPDIRECTPLAY2 iface )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(): stub\n", This );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_CreateGroup
+          ( LPDIRECTPLAY2A iface, LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,%p,%p,0x%08lx,0x%08lx): stub\n", This, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_CreateGroup
+          ( LPDIRECTPLAY2 iface, LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,%p,%p,0x%08lx,0x%08lx): stub\n", This, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_CreatePlayer
+          ( LPDIRECTPLAY2A iface, LPDPID lpidPlayer, LPDPNAME lpPlayerName, HANDLE hEvent, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx): stub\n", This, lpidPlayer, lpPlayerName, hEvent, lpData, dwDataSize, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_CreatePlayer
+          ( LPDIRECTPLAY2 iface, LPDPID lpidPlayer, LPDPNAME lpPlayerName, HANDLE hEvent, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx): stub\n", This, lpidPlayer, lpPlayerName, hEvent, lpData, dwDataSize, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_DeletePlayerFromGroup
+          ( LPDIRECTPLAY2A iface, DPID idGroup, DPID idPlayer )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idPlayer );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_DeletePlayerFromGroup
+          ( LPDIRECTPLAY2 iface, DPID idGroup, DPID idPlayer )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idPlayer );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_DestroyGroup
+          ( LPDIRECTPLAY2A iface, DPID idGroup )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx): stub\n", This, idGroup );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_DestroyGroup
+          ( LPDIRECTPLAY2 iface, DPID idGroup )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx): stub\n", This, idGroup );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_DestroyPlayer
+          ( LPDIRECTPLAY2A iface, DPID idPlayer )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx): stub\n", This, idPlayer );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_DestroyPlayer
+          ( LPDIRECTPLAY2 iface, DPID idPlayer )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx): stub\n", This, idPlayer );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_EnumGroupPlayers
+          ( LPDIRECTPLAY2A iface, DPID idGroup, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
+            LPVOID lpContext, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub\n", This, idGroup, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_EnumGroupPlayers
+          ( LPDIRECTPLAY2 iface, DPID idGroup, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
+            LPVOID lpContext, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub\n", This, idGroup, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_EnumGroups
+          ( LPDIRECTPLAY2A iface, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_EnumGroups
+          ( LPDIRECTPLAY2 iface, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_EnumPlayers
+          ( LPDIRECTPLAY2A iface, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_EnumPlayers
+          ( LPDIRECTPLAY2 iface, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_EnumSessions
+          ( LPDIRECTPLAY2A iface, LPDPSESSIONDESC2 lpsd, DWORD dwTimeout, LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
+            LPVOID lpContext, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,0x%08lx,%p,%p,0x%08lx): stub\n", This, lpsd, dwTimeout, lpEnumSessionsCallback2, lpContext, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_EnumSessions
+          ( LPDIRECTPLAY2 iface, LPDPSESSIONDESC2 lpsd, DWORD dwTimeout, LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
+            LPVOID lpContext, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,0x%08lx,%p,%p,0x%08lx): stub\n", This, lpsd, dwTimeout, lpEnumSessionsCallback2, lpContext, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_GetCaps
+          ( LPDIRECTPLAY2A iface, LPDPCAPS lpDPCaps, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpDPCaps, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_GetCaps
+          ( LPDIRECTPLAY2 iface, LPDPCAPS lpDPCaps, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpDPCaps, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_GetGroupData
+          ( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, idGroup, lpData, lpdwDataSize, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_GetGroupData
+          ( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, idGroup, lpData, lpdwDataSize, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_GetGroupName
+          ( LPDIRECTPLAY2A iface, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idGroup, lpData, lpdwDataSize );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_GetGroupName
+          ( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idGroup, lpData, lpdwDataSize );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_GetMessageCount
+          ( LPDIRECTPLAY2A iface, DPID idPlayer, LPDWORD lpdwCount )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p): stub\n", This, idPlayer, lpdwCount );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_GetMessageCount
+          ( LPDIRECTPLAY2 iface, DPID idPlayer, LPDWORD lpdwCount )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p): stub\n", This, idPlayer, lpdwCount );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_GetPlayerAddress
+          ( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idPlayer, lpData, lpdwDataSize );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_GetPlayerAddress
+          ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idPlayer, lpData, lpdwDataSize );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_GetPlayerCaps
+          ( LPDIRECTPLAY2A iface, DPID idPlayer, LPDPCAPS lpPlayerCaps, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idPlayer, lpPlayerCaps, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_GetPlayerCaps
+          ( LPDIRECTPLAY2 iface, DPID idPlayer, LPDPCAPS lpPlayerCaps, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idPlayer, lpPlayerCaps, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_GetPlayerData
+          ( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, idPlayer, lpData, lpdwDataSize, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_GetPlayerData
+          ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, idPlayer, lpData, lpdwDataSize, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_GetPlayerName
+          ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idPlayer, lpData, lpdwDataSize );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_GetPlayerName
+          ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idPlayer, lpData, lpdwDataSize );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_GetSessionDesc
+          ( LPDIRECTPLAY2A iface, LPVOID lpData, LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,%p): stub\n", This, lpData, lpdwDataSize );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_GetSessionDesc
+          ( LPDIRECTPLAY2 iface, LPVOID lpData, LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,%p): stub\n", This, lpData, lpdwDataSize );
+  return DP_OK;
+}
+
+/* Intended only for COM compatibility. Always returns an error. */
+static HRESULT WINAPI DirectPlay2AImpl_Initialize
+          ( LPDIRECTPLAY2A iface, LPGUID lpGUID )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  TRACE("(%p)->(%p): stub\n", This, lpGUID );
+  return DPERR_ALREADYINITIALIZED;
+}
+
+/* Intended only for COM compatibility. Always returns an error. */
+static HRESULT WINAPI DirectPlay2WImpl_Initialize
+          ( LPDIRECTPLAY2 iface, LPGUID lpGUID )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  TRACE("(%p)->(%p): stub\n", This, lpGUID );
+  return DPERR_ALREADYINITIALIZED;
+}
+
+
+static HRESULT WINAPI DirectPlay2AImpl_Open
+          ( LPDIRECTPLAY2A iface, LPDPSESSIONDESC2 lpsd, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpsd, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_Open
+          ( LPDIRECTPLAY2 iface, LPDPSESSIONDESC2 lpsd, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpsd, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_Receive
+          ( LPDIRECTPLAY2A iface, LPDPID lpidFrom, LPDPID lpidTo, DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,%p,0x%08lx,%p,%p): stub\n", This, lpidFrom, lpidTo, dwFlags, lpData, lpdwDataSize );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_Receive
+          ( LPDIRECTPLAY2 iface, LPDPID lpidFrom, LPDPID lpidTo, DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,%p,0x%08lx,%p,%p): stub\n", This, lpidFrom, lpidTo, dwFlags, lpData, lpdwDataSize );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_Send
+          ( LPDIRECTPLAY2A iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx): stub\n", This, idFrom, idTo, dwFlags, lpData, dwDataSize );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_Send
+          ( LPDIRECTPLAY2 iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx): stub\n", This, idFrom, idTo, dwFlags, lpData, dwDataSize );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_SetGroupData
+          ( LPDIRECTPLAY2A iface, DPID idGroup, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub\n", This, idGroup, lpData, dwDataSize, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_SetGroupData
+          ( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
+{   
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub\n", This, idGroup, lpData, dwDataSize, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_SetGroupName
+          ( LPDIRECTPLAY2A iface, DPID idGroup, LPDPNAME lpGroupName, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idGroup, lpGroupName, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_SetGroupName
+          ( LPDIRECTPLAY2 iface, DPID idGroup, LPDPNAME lpGroupName, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idGroup, lpGroupName, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_SetPlayerData
+          ( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub\n", This, idPlayer, lpData, dwDataSize, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_SetPlayerData
+          ( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub\n", This, idPlayer, lpData, dwDataSize, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_SetPlayerName
+          ( LPDIRECTPLAY2A iface, DPID idPlayer, LPDPNAME lpPlayerName, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idPlayer, lpPlayerName, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_SetPlayerName
+          ( LPDIRECTPLAY2 iface, DPID idPlayer, LPDPNAME lpPlayerName, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idPlayer, lpPlayerName, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2AImpl_SetSessionDesc
+          ( LPDIRECTPLAY2A iface, LPDPSESSIONDESC2 lpSessDesc, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpSessDesc, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay2WImpl_SetSessionDesc
+          ( LPDIRECTPLAY2 iface, LPDPSESSIONDESC2 lpSessDesc, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay2Impl,iface);
+  FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpSessDesc, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3AImpl_AddGroupToGroup
+          ( LPDIRECTPLAY3A iface, DPID idParentGroup, DPID idGroup )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idParentGroup, idGroup );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3WImpl_AddGroupToGroup
+          ( LPDIRECTPLAY3 iface, DPID idParentGroup, DPID idGroup )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idParentGroup, idGroup );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3AImpl_CreateGroupInGroup
+          ( LPDIRECTPLAY3A iface, DPID idParentGroup, LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx): stub\n", This, idParentGroup, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3WImpl_CreateGroupInGroup
+          ( LPDIRECTPLAY3 iface, DPID idParentGroup, LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx): stub\n", This, idParentGroup, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3AImpl_DeleteGroupFromGroup
+          ( LPDIRECTPLAY3A iface, DPID idParentGroup, DPID idGroup )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idParentGroup, idGroup );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3WImpl_DeleteGroupFromGroup
+          ( LPDIRECTPLAY3 iface, DPID idParentGroup, DPID idGroup )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idParentGroup, idGroup );
+  return DP_OK;
+}
+
+#if 0
+typedef BOOL (CALLBACK* LPDPENUMDPCALLBACKA)(
+    LPGUID      lpguidSP,
+    LPSTR       lpSPName,       /* ptr to str w/ driver description */
+    DWORD       dwMajorVersion, /* Major # of driver spec in lpguidSP */
+    DWORD       dwMinorVersion, /* Minor # of driver spec in lpguidSP */
+    LPVOID      lpContext);     /* User given */
+
+typedef BOOL (CALLBACK* LPDPENUMCONNECTIONSCALLBACK)(
+    LPCGUID     lpguidSP,
+    LPVOID      lpConnection,
+    DWORD       dwConnectionSize,
+    LPCDPNAME   lpName,
+    DWORD       dwFlags,
+    LPVOID      lpContext);
+
+#endif
+
+static HRESULT WINAPI DirectPlay3AImpl_EnumConnections
+          ( LPDIRECTPLAY3A iface, LPCGUID lpguidApplication, LPDPENUMCONNECTIONSCALLBACK lpEnumCallback, LPVOID lpContext, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidApplication, lpEnumCallback, lpContext, dwFlags );
+
+  /* A default dwFlags (0) is backwards compatible -- DPCONNECTION_DIRECTPLAY */
+  if( dwFlags == 0 )
+  {
+    dwFlags = DPCONNECTION_DIRECTPLAY;
+  }
+
+  if( ! ( ( dwFlags & DPCONNECTION_DIRECTPLAY ) ||
+          ( dwFlags & DPCONNECTION_DIRECTPLAYLOBBY ) )
+    ) 
+  {
+    return DPERR_INVALIDFLAGS;
+  }
+
+  if( lpguidApplication != NULL )
+  {
+    FIXME( ": don't know how to deal with a non NULL lpguidApplication yet\n" );
+  }
+
+  /* Enumerate DirectPlay service providers */
+  if( dwFlags & DPCONNECTION_DIRECTPLAY )
+  {
+
+  }
+
+  /* Enumerate DirectPlayLobby service providers */
+  if( dwFlags & DPCONNECTION_DIRECTPLAYLOBBY )
+  {
+
+  }
+
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3WImpl_EnumConnections
+          ( LPDIRECTPLAY3 iface, LPCGUID lpguidApplication, LPDPENUMCONNECTIONSCALLBACK lpEnumCallback, LPVOID lpContext, DWORD dwFlags )
+{ 
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidApplication, lpEnumCallback, lpContext, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3AImpl_EnumGroupsInGroup
+          ( LPDIRECTPLAY3A iface, DPID idGroup, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumCallback, LPVOID lpContext, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub\n", This, idGroup, lpguidInstance, lpEnumCallback, lpContext, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3WImpl_EnumGroupsInGroup
+          ( LPDIRECTPLAY3 iface, DPID idGroup, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumCallback, LPVOID lpContext, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub\n", This, idGroup, lpguidInstance, lpEnumCallback, lpContext, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3AImpl_GetGroupConnectionSettings
+          ( LPDIRECTPLAY3A iface, DWORD dwFlags, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, dwFlags, idGroup, lpData, lpdwDataSize );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3WImpl_GetGroupConnectionSettings
+          ( LPDIRECTPLAY3 iface, DWORD dwFlags, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, dwFlags, idGroup, lpData, lpdwDataSize );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
+          ( LPDIRECTPLAY3A iface, LPVOID lpConnection, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpConnection, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3WImpl_InitializeConnection
+          ( LPDIRECTPLAY3 iface, LPVOID lpConnection, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpConnection, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3AImpl_SecureOpen
+          ( LPDIRECTPLAY3A iface, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags, LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(%p,0x%08lx,%p,%p): stub\n", This, lpsd, dwFlags, lpSecurity, lpCredentials );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3WImpl_SecureOpen
+          ( LPDIRECTPLAY3 iface, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags, LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials )
+{   
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(%p,0x%08lx,%p,%p): stub\n", This, lpsd, dwFlags, lpSecurity, lpCredentials );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3AImpl_SendChatMessage
+          ( LPDIRECTPLAY3A iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPDPCHAT lpChatMessage )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p): stub\n", This, idFrom, idTo, dwFlags, lpChatMessage );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3WImpl_SendChatMessage
+          ( LPDIRECTPLAY3 iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPDPCHAT lpChatMessage )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p): stub\n", This, idFrom, idTo, dwFlags, lpChatMessage );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3AImpl_SetGroupConnectionSettings
+          ( LPDIRECTPLAY3A iface, DWORD dwFlags, DPID idGroup, LPDPLCONNECTION lpConnection )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx,%p): stub\n", This, dwFlags, idGroup, lpConnection );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3WImpl_SetGroupConnectionSettings
+          ( LPDIRECTPLAY3 iface, DWORD dwFlags, DPID idGroup, LPDPLCONNECTION lpConnection )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx,%p): stub\n", This, dwFlags, idGroup, lpConnection );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3AImpl_StartSession
+          ( LPDIRECTPLAY3A iface, DWORD dwFlags, DPID idGroup )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, dwFlags, idGroup );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3WImpl_StartSession
+          ( LPDIRECTPLAY3 iface, DWORD dwFlags, DPID idGroup )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, dwFlags, idGroup );
+  return DP_OK;
+}
+ 
+static HRESULT WINAPI DirectPlay3AImpl_GetGroupFlags
+          ( LPDIRECTPLAY3A iface, DPID idGroup, LPDWORD lpdwFlags )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpdwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3WImpl_GetGroupFlags
+          ( LPDIRECTPLAY3 iface, DPID idGroup, LPDWORD lpdwFlags )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpdwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3AImpl_GetGroupParent
+          ( LPDIRECTPLAY3A iface, DPID idGroup, LPDPID lpidGroup )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpidGroup );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3WImpl_GetGroupParent
+          ( LPDIRECTPLAY3 iface, DPID idGroup, LPDPID lpidGroup )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpidGroup );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3AImpl_GetPlayerAccount
+          ( LPDIRECTPLAY3A iface, DPID idPlayer, DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, idPlayer, dwFlags, lpData, lpdwDataSize );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3WImpl_GetPlayerAccount
+          ( LPDIRECTPLAY3 iface, DPID idPlayer, DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, idPlayer, dwFlags, lpData, lpdwDataSize );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3AImpl_GetPlayerFlags
+          ( LPDIRECTPLAY3A iface, DPID idPlayer, LPDWORD lpdwFlags )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p): stub\n", This, idPlayer, lpdwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay3WImpl_GetPlayerFlags
+          ( LPDIRECTPLAY3 iface, DPID idPlayer, LPDWORD lpdwFlags )
+{
+  ICOM_THIS(IDirectPlay3Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p): stub\n", This, idPlayer, lpdwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay4AImpl_GetGroupOwner
+          ( LPDIRECTPLAY4A iface, DPID idGroup, LPDPID lpidGroupOwner )
+{
+  ICOM_THIS(IDirectPlay4Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpidGroupOwner );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay4WImpl_GetGroupOwner
+          ( LPDIRECTPLAY4 iface, DPID idGroup, LPDPID lpidGroupOwner )
+{
+  ICOM_THIS(IDirectPlay4Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p): stub\n", This, idGroup, lpidGroupOwner );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay4AImpl_SetGroupOwner
+          ( LPDIRECTPLAY4A iface, DPID idGroup , DPID idGroupOwner )
+{
+  ICOM_THIS(IDirectPlay4Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idGroupOwner );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay4WImpl_SetGroupOwner
+          ( LPDIRECTPLAY4 iface, DPID idGroup , DPID idGroupOwner )
+{
+  ICOM_THIS(IDirectPlay4Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idGroupOwner );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay4AImpl_SendEx
+          ( LPDIRECTPLAY4A iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize, DWORD dwPriority, DWORD dwTimeout, LPVOID lpContext, LPDWORD lpdwMsgID )
+{
+  ICOM_THIS(IDirectPlay4Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx,0x%08lx,0x%08lx,%p,%p): stub\n", This, idFrom, idTo, dwFlags, lpData, dwDataSize, dwPriority, dwTimeout, lpContext, lpdwMsgID );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay4WImpl_SendEx
+          ( LPDIRECTPLAY4 iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize, DWORD dwPriority, DWORD dwTimeout, LPVOID lpContext, LPDWORD lpdwMsgID )
+{
+  ICOM_THIS(IDirectPlay4Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx,0x%08lx,0x%08lx,%p,%p): stub\n", This, idFrom, idTo, dwFlags, lpData, dwDataSize, dwPriority, dwTimeout, lpContext, lpdwMsgID );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay4AImpl_GetMessageQueue
+          ( LPDIRECTPLAY4A iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPDWORD lpdwNumMsgs, LPDWORD lpdwNumBytes )
+{
+  ICOM_THIS(IDirectPlay4Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,%p): stub\n", This, idFrom, idTo, dwFlags, lpdwNumMsgs, lpdwNumBytes );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay4WImpl_GetMessageQueue
+          ( LPDIRECTPLAY4 iface, DPID idFrom, DPID idTo, DWORD dwFlags, LPDWORD lpdwNumMsgs, LPDWORD lpdwNumBytes )
+{
+  ICOM_THIS(IDirectPlay4Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,%p): stub\n", This, idFrom, idTo, dwFlags, lpdwNumMsgs, lpdwNumBytes );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay4AImpl_CancelMessage
+          ( LPDIRECTPLAY4A iface, DWORD dwMsgID, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay4Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, dwMsgID, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay4WImpl_CancelMessage
+          ( LPDIRECTPLAY4 iface, DWORD dwMsgID, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay4Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, dwMsgID, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay4AImpl_CancelPriority
+          ( LPDIRECTPLAY4A iface, DWORD dwMinPriority, DWORD dwMaxPriority, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay4Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx): stub\n", This, dwMinPriority, dwMaxPriority, dwFlags );
+  return DP_OK;
+}
+
+static HRESULT WINAPI DirectPlay4WImpl_CancelPriority
+          ( LPDIRECTPLAY4 iface, DWORD dwMinPriority, DWORD dwMaxPriority, DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlay4Impl,iface);
+  FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx): stub\n", This, dwMinPriority, dwMaxPriority, dwFlags );
+  return DP_OK;
+}
+
+/* Note: Hack so we can reuse the old functions without compiler warnings */
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(directPlay2WVT.fn##fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+static ICOM_VTABLE(IDirectPlay2) directPlay2WVT = 
+{
+  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+  DirectPlay2W_QueryInterface,
+  XCAST(AddRef)DirectPlay2AImpl_AddRef,
+  XCAST(Release)DirectPlay2AImpl_Release,
+
+  DirectPlay2WImpl_AddPlayerToGroup,
+  DirectPlay2WImpl_Close,
+  DirectPlay2WImpl_CreateGroup,
+  DirectPlay2WImpl_CreatePlayer,
+  DirectPlay2WImpl_DeletePlayerFromGroup,
+  DirectPlay2WImpl_DestroyGroup,
+  DirectPlay2WImpl_DestroyPlayer,
+  DirectPlay2WImpl_EnumGroupPlayers,
+  DirectPlay2WImpl_EnumGroups,
+  DirectPlay2WImpl_EnumPlayers,
+  DirectPlay2WImpl_EnumSessions,
+  DirectPlay2WImpl_GetCaps,
+  DirectPlay2WImpl_GetGroupData,
+  DirectPlay2WImpl_GetGroupName,
+  DirectPlay2WImpl_GetMessageCount,
+  DirectPlay2WImpl_GetPlayerAddress,
+  DirectPlay2WImpl_GetPlayerCaps,
+  DirectPlay2WImpl_GetPlayerData,
+  DirectPlay2WImpl_GetPlayerName,
+  DirectPlay2WImpl_GetSessionDesc,
+  DirectPlay2WImpl_Initialize,
+  DirectPlay2WImpl_Open,
+  DirectPlay2WImpl_Receive,
+  DirectPlay2WImpl_Send,
+  DirectPlay2WImpl_SetGroupData,
+  DirectPlay2WImpl_SetGroupName,
+  DirectPlay2WImpl_SetPlayerData,
+  DirectPlay2WImpl_SetPlayerName,
+  DirectPlay2WImpl_SetSessionDesc
+};
+#undef XCAST
+
+/* Note: Hack so we can reuse the old functions without compiler warnings */
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(directPlay2AVT.fn##fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+static ICOM_VTABLE(IDirectPlay2) directPlay2AVT = 
+{
+  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+  DirectPlay2A_QueryInterface,
+  XCAST(AddRef)DirectPlay2AImpl_AddRef,
+  XCAST(Release)DirectPlay2AImpl_Release,
+
+  DirectPlay2AImpl_AddPlayerToGroup,
+  DirectPlay2AImpl_Close,
+  DirectPlay2AImpl_CreateGroup,
+  DirectPlay2AImpl_CreatePlayer,
+  DirectPlay2AImpl_DeletePlayerFromGroup,
+  DirectPlay2AImpl_DestroyGroup,
+  DirectPlay2AImpl_DestroyPlayer,
+  DirectPlay2AImpl_EnumGroupPlayers,
+  DirectPlay2AImpl_EnumGroups,
+  DirectPlay2AImpl_EnumPlayers,
+  DirectPlay2AImpl_EnumSessions,
+  DirectPlay2AImpl_GetCaps,
+  DirectPlay2AImpl_GetGroupData,
+  DirectPlay2AImpl_GetGroupName,
+  DirectPlay2AImpl_GetMessageCount,
+  DirectPlay2AImpl_GetPlayerAddress,
+  DirectPlay2AImpl_GetPlayerCaps,
+  DirectPlay2AImpl_GetPlayerData,
+  DirectPlay2AImpl_GetPlayerName,
+  DirectPlay2AImpl_GetSessionDesc,
+  DirectPlay2AImpl_Initialize,
+  DirectPlay2AImpl_Open,
+  DirectPlay2AImpl_Receive,
+  DirectPlay2AImpl_Send,
+  DirectPlay2AImpl_SetGroupData,
+  DirectPlay2AImpl_SetGroupName,
+  DirectPlay2AImpl_SetPlayerData,
+  DirectPlay2AImpl_SetPlayerName,
+  DirectPlay2AImpl_SetSessionDesc
+};
+#undef XCAST
+
+
+/* Note: Hack so we can reuse the old functions without compiler warnings */
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(directPlay3AVT.fn##fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+static ICOM_VTABLE(IDirectPlay3) directPlay3AVT = 
+{
+  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+  DirectPlay3AImpl_QueryInterface,
+  XCAST(AddRef)DirectPlay2AImpl_AddRef,
+  XCAST(Release)DirectPlay2AImpl_Release,
+
+  XCAST(AddPlayerToGroup)DirectPlay2AImpl_AddPlayerToGroup,
+  XCAST(Close)DirectPlay2AImpl_Close,
+  XCAST(CreateGroup)DirectPlay2AImpl_CreateGroup,
+  XCAST(CreatePlayer)DirectPlay2AImpl_CreatePlayer,
+  XCAST(DeletePlayerFromGroup)DirectPlay2AImpl_DeletePlayerFromGroup,
+  XCAST(DestroyGroup)DirectPlay2AImpl_DestroyGroup,
+  XCAST(DestroyPlayer)DirectPlay2AImpl_DestroyPlayer,
+  XCAST(EnumGroupPlayers)DirectPlay2AImpl_EnumGroupPlayers,
+  XCAST(EnumGroups)DirectPlay2AImpl_EnumGroups,
+  XCAST(EnumPlayers)DirectPlay2AImpl_EnumPlayers,
+  XCAST(EnumSessions)DirectPlay2AImpl_EnumSessions,
+  XCAST(GetCaps)DirectPlay2AImpl_GetCaps,
+  XCAST(GetGroupData)DirectPlay2AImpl_GetGroupData,
+  XCAST(GetGroupName)DirectPlay2AImpl_GetGroupName,
+  XCAST(GetMessageCount)DirectPlay2AImpl_GetMessageCount,
+  XCAST(GetPlayerAddress)DirectPlay2AImpl_GetPlayerAddress,
+  XCAST(GetPlayerCaps)DirectPlay2AImpl_GetPlayerCaps,
+  XCAST(GetPlayerData)DirectPlay2AImpl_GetPlayerData,
+  XCAST(GetPlayerName)DirectPlay2AImpl_GetPlayerName,
+  XCAST(GetSessionDesc)DirectPlay2AImpl_GetSessionDesc,
+  XCAST(Initialize)DirectPlay2AImpl_Initialize,
+  XCAST(Open)DirectPlay2AImpl_Open,
+  XCAST(Receive)DirectPlay2AImpl_Receive,
+  XCAST(Send)DirectPlay2AImpl_Send,
+  XCAST(SetGroupData)DirectPlay2AImpl_SetGroupData,
+  XCAST(SetGroupName)DirectPlay2AImpl_SetGroupName,
+  XCAST(SetPlayerData)DirectPlay2AImpl_SetPlayerData,
+  XCAST(SetPlayerName)DirectPlay2AImpl_SetPlayerName,
+  XCAST(SetSessionDesc)DirectPlay2AImpl_SetSessionDesc,
+
+  DirectPlay3AImpl_AddGroupToGroup,
+  DirectPlay3AImpl_CreateGroupInGroup,
+  DirectPlay3AImpl_DeleteGroupFromGroup,
+  DirectPlay3AImpl_EnumConnections,
+  DirectPlay3AImpl_EnumGroupsInGroup,
+  DirectPlay3AImpl_GetGroupConnectionSettings,
+  DirectPlay3AImpl_InitializeConnection,
+  DirectPlay3AImpl_SecureOpen,
+  DirectPlay3AImpl_SendChatMessage,
+  DirectPlay3AImpl_SetGroupConnectionSettings,
+  DirectPlay3AImpl_StartSession,
+  DirectPlay3AImpl_GetGroupFlags,
+  DirectPlay3AImpl_GetGroupParent,
+  DirectPlay3AImpl_GetPlayerAccount,
+  DirectPlay3AImpl_GetPlayerFlags
+};
+#undef XCAST
+
+/* Note: Hack so we can reuse the old functions without compiler warnings */
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(directPlay3WVT.fn##fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+static ICOM_VTABLE(IDirectPlay3) directPlay3WVT = 
+{
+  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+  DirectPlay3WImpl_QueryInterface,
+  XCAST(AddRef)DirectPlay2AImpl_AddRef,
+  XCAST(Release)DirectPlay2AImpl_Release,
+
+  XCAST(AddPlayerToGroup)DirectPlay2WImpl_AddPlayerToGroup,
+  XCAST(Close)DirectPlay2WImpl_Close,
+  XCAST(CreateGroup)DirectPlay2WImpl_CreateGroup,
+  XCAST(CreatePlayer)DirectPlay2WImpl_CreatePlayer,
+  XCAST(DeletePlayerFromGroup)DirectPlay2WImpl_DeletePlayerFromGroup,
+  XCAST(DestroyGroup)DirectPlay2WImpl_DestroyGroup,
+  XCAST(DestroyPlayer)DirectPlay2WImpl_DestroyPlayer,
+  XCAST(EnumGroupPlayers)DirectPlay2WImpl_EnumGroupPlayers,
+  XCAST(EnumGroups)DirectPlay2WImpl_EnumGroups,
+  XCAST(EnumPlayers)DirectPlay2WImpl_EnumPlayers,
+  XCAST(EnumSessions)DirectPlay2WImpl_EnumSessions,
+  XCAST(GetCaps)DirectPlay2WImpl_GetCaps,
+  XCAST(GetGroupData)DirectPlay2WImpl_GetGroupData,
+  XCAST(GetGroupName)DirectPlay2WImpl_GetGroupName,
+  XCAST(GetMessageCount)DirectPlay2WImpl_GetMessageCount,
+  XCAST(GetPlayerAddress)DirectPlay2WImpl_GetPlayerAddress,
+  XCAST(GetPlayerCaps)DirectPlay2WImpl_GetPlayerCaps,
+  XCAST(GetPlayerData)DirectPlay2WImpl_GetPlayerData,
+  XCAST(GetPlayerName)DirectPlay2WImpl_GetPlayerName,
+  XCAST(GetSessionDesc)DirectPlay2WImpl_GetSessionDesc,
+  XCAST(Initialize)DirectPlay2WImpl_Initialize,
+  XCAST(Open)DirectPlay2WImpl_Open,
+  XCAST(Receive)DirectPlay2WImpl_Receive,
+  XCAST(Send)DirectPlay2WImpl_Send,
+  XCAST(SetGroupData)DirectPlay2WImpl_SetGroupData,
+  XCAST(SetGroupName)DirectPlay2WImpl_SetGroupName,
+  XCAST(SetPlayerData)DirectPlay2WImpl_SetPlayerData,
+  XCAST(SetPlayerName)DirectPlay2WImpl_SetPlayerName,
+  XCAST(SetSessionDesc)DirectPlay2WImpl_SetSessionDesc,
+
+  DirectPlay3WImpl_AddGroupToGroup,
+  DirectPlay3WImpl_CreateGroupInGroup,
+  DirectPlay3WImpl_DeleteGroupFromGroup,
+  DirectPlay3WImpl_EnumConnections,
+  DirectPlay3WImpl_EnumGroupsInGroup,
+  DirectPlay3WImpl_GetGroupConnectionSettings,
+  DirectPlay3WImpl_InitializeConnection,
+  DirectPlay3WImpl_SecureOpen,
+  DirectPlay3WImpl_SendChatMessage,
+  DirectPlay3WImpl_SetGroupConnectionSettings,
+  DirectPlay3WImpl_StartSession,
+  DirectPlay3WImpl_GetGroupFlags,
+  DirectPlay3WImpl_GetGroupParent,
+  DirectPlay3WImpl_GetPlayerAccount,
+  DirectPlay3WImpl_GetPlayerFlags
+};
+#undef XCAST
+
+/* Note: Hack so we can reuse the old functions without compiler warnings */
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(directPlay4WVT.fn##fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+static ICOM_VTABLE(IDirectPlay4) directPlay4WVT =
+{
+  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+  DirectPlay4WImpl_QueryInterface,
+  XCAST(AddRef)DirectPlay2AImpl_AddRef,
+  XCAST(Release)DirectPlay2AImpl_Release,
+
+  XCAST(AddPlayerToGroup)DirectPlay2WImpl_AddPlayerToGroup,
+  XCAST(Close)DirectPlay2WImpl_Close,
+  XCAST(CreateGroup)DirectPlay2WImpl_CreateGroup,
+  XCAST(CreatePlayer)DirectPlay2WImpl_CreatePlayer,
+  XCAST(DeletePlayerFromGroup)DirectPlay2WImpl_DeletePlayerFromGroup,
+  XCAST(DestroyGroup)DirectPlay2WImpl_DestroyGroup,
+  XCAST(DestroyPlayer)DirectPlay2WImpl_DestroyPlayer,
+  XCAST(EnumGroupPlayers)DirectPlay2WImpl_EnumGroupPlayers,
+  XCAST(EnumGroups)DirectPlay2WImpl_EnumGroups,
+  XCAST(EnumPlayers)DirectPlay2WImpl_EnumPlayers,
+  XCAST(EnumSessions)DirectPlay2WImpl_EnumSessions,
+  XCAST(GetCaps)DirectPlay2WImpl_GetCaps,
+  XCAST(GetGroupData)DirectPlay2WImpl_GetGroupData,
+  XCAST(GetGroupName)DirectPlay2WImpl_GetGroupName,
+  XCAST(GetMessageCount)DirectPlay2WImpl_GetMessageCount,
+  XCAST(GetPlayerAddress)DirectPlay2WImpl_GetPlayerAddress,
+  XCAST(GetPlayerCaps)DirectPlay2WImpl_GetPlayerCaps,
+  XCAST(GetPlayerData)DirectPlay2WImpl_GetPlayerData,
+  XCAST(GetPlayerName)DirectPlay2WImpl_GetPlayerName,
+  XCAST(GetSessionDesc)DirectPlay2WImpl_GetSessionDesc,
+  XCAST(Initialize)DirectPlay2WImpl_Initialize,
+  XCAST(Open)DirectPlay2WImpl_Open,
+  XCAST(Receive)DirectPlay2WImpl_Receive,
+  XCAST(Send)DirectPlay2WImpl_Send,
+  XCAST(SetGroupData)DirectPlay2WImpl_SetGroupData,
+  XCAST(SetGroupName)DirectPlay2WImpl_SetGroupName,
+  XCAST(SetPlayerData)DirectPlay2WImpl_SetPlayerData,
+  XCAST(SetPlayerName)DirectPlay2WImpl_SetPlayerName,
+  XCAST(SetSessionDesc)DirectPlay2WImpl_SetSessionDesc,
+
+  XCAST(AddGroupToGroup)DirectPlay3WImpl_AddGroupToGroup,
+  XCAST(CreateGroupInGroup)DirectPlay3WImpl_CreateGroupInGroup,
+  XCAST(DeleteGroupFromGroup)DirectPlay3WImpl_DeleteGroupFromGroup,
+  XCAST(EnumConnections)DirectPlay3WImpl_EnumConnections,
+  XCAST(EnumGroupsInGroup)DirectPlay3WImpl_EnumGroupsInGroup,
+  XCAST(GetGroupConnectionSettings)DirectPlay3WImpl_GetGroupConnectionSettings,
+  XCAST(InitializeConnection)DirectPlay3WImpl_InitializeConnection,
+  XCAST(SecureOpen)DirectPlay3WImpl_SecureOpen,
+  XCAST(SendChatMessage)DirectPlay3WImpl_SendChatMessage,
+  XCAST(SetGroupConnectionSettings)DirectPlay3WImpl_SetGroupConnectionSettings,
+  XCAST(StartSession)DirectPlay3WImpl_StartSession,
+  XCAST(GetGroupFlags)DirectPlay3WImpl_GetGroupFlags,
+  XCAST(GetGroupParent)DirectPlay3WImpl_GetGroupParent,
+  XCAST(GetPlayerAccount)DirectPlay3WImpl_GetPlayerAccount,
+  XCAST(GetPlayerFlags)DirectPlay3WImpl_GetPlayerFlags,
+
+  DirectPlay4WImpl_GetGroupOwner,
+  DirectPlay4WImpl_SetGroupOwner,
+  DirectPlay4WImpl_SendEx,
+  DirectPlay4WImpl_GetMessageQueue,
+  DirectPlay4WImpl_CancelMessage,
+  DirectPlay4WImpl_CancelPriority
+};
+#undef XCAST
+
+
+/* Note: Hack so we can reuse the old functions without compiler warnings */
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(directPlay4AVT.fn##fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+static ICOM_VTABLE(IDirectPlay4) directPlay4AVT =
+{
+  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+  DirectPlay4AImpl_QueryInterface,
+  XCAST(AddRef)DirectPlay2AImpl_AddRef,
+  XCAST(Release)DirectPlay2AImpl_Release,
+
+  XCAST(AddPlayerToGroup)DirectPlay2AImpl_AddPlayerToGroup,
+  XCAST(Close)DirectPlay2AImpl_Close,
+  XCAST(CreateGroup)DirectPlay2AImpl_CreateGroup,
+  XCAST(CreatePlayer)DirectPlay2AImpl_CreatePlayer,
+  XCAST(DeletePlayerFromGroup)DirectPlay2AImpl_DeletePlayerFromGroup,
+  XCAST(DestroyGroup)DirectPlay2AImpl_DestroyGroup,
+  XCAST(DestroyPlayer)DirectPlay2AImpl_DestroyPlayer,
+  XCAST(EnumGroupPlayers)DirectPlay2AImpl_EnumGroupPlayers,
+  XCAST(EnumGroups)DirectPlay2AImpl_EnumGroups,
+  XCAST(EnumPlayers)DirectPlay2AImpl_EnumPlayers,
+  XCAST(EnumSessions)DirectPlay2AImpl_EnumSessions,
+  XCAST(GetCaps)DirectPlay2AImpl_GetCaps,
+  XCAST(GetGroupData)DirectPlay2AImpl_GetGroupData,
+  XCAST(GetGroupName)DirectPlay2AImpl_GetGroupName,
+  XCAST(GetMessageCount)DirectPlay2AImpl_GetMessageCount,
+  XCAST(GetPlayerAddress)DirectPlay2AImpl_GetPlayerAddress,
+  XCAST(GetPlayerCaps)DirectPlay2AImpl_GetPlayerCaps,
+  XCAST(GetPlayerData)DirectPlay2AImpl_GetPlayerData,
+  XCAST(GetPlayerName)DirectPlay2AImpl_GetPlayerName,
+  XCAST(GetSessionDesc)DirectPlay2AImpl_GetSessionDesc,
+  XCAST(Initialize)DirectPlay2AImpl_Initialize,
+  XCAST(Open)DirectPlay2AImpl_Open,
+  XCAST(Receive)DirectPlay2AImpl_Receive,
+  XCAST(Send)DirectPlay2AImpl_Send,
+  XCAST(SetGroupData)DirectPlay2AImpl_SetGroupData,
+  XCAST(SetGroupName)DirectPlay2AImpl_SetGroupName,
+  XCAST(SetPlayerData)DirectPlay2AImpl_SetPlayerData,
+  XCAST(SetPlayerName)DirectPlay2AImpl_SetPlayerName,
+  XCAST(SetSessionDesc)DirectPlay2AImpl_SetSessionDesc,
+
+  XCAST(AddGroupToGroup)DirectPlay3AImpl_AddGroupToGroup,
+  XCAST(CreateGroupInGroup)DirectPlay3AImpl_CreateGroupInGroup,
+  XCAST(DeleteGroupFromGroup)DirectPlay3AImpl_DeleteGroupFromGroup,
+  XCAST(EnumConnections)DirectPlay3AImpl_EnumConnections,
+  XCAST(EnumGroupsInGroup)DirectPlay3AImpl_EnumGroupsInGroup,
+  XCAST(GetGroupConnectionSettings)DirectPlay3AImpl_GetGroupConnectionSettings,
+  XCAST(InitializeConnection)DirectPlay3AImpl_InitializeConnection,
+  XCAST(SecureOpen)DirectPlay3AImpl_SecureOpen,
+  XCAST(SendChatMessage)DirectPlay3AImpl_SendChatMessage,
+  XCAST(SetGroupConnectionSettings)DirectPlay3AImpl_SetGroupConnectionSettings,
+  XCAST(StartSession)DirectPlay3AImpl_StartSession,
+  XCAST(GetGroupFlags)DirectPlay3AImpl_GetGroupFlags,
+  XCAST(GetGroupParent)DirectPlay3AImpl_GetGroupParent,
+  XCAST(GetPlayerAccount)DirectPlay3AImpl_GetPlayerAccount,
+  XCAST(GetPlayerFlags)DirectPlay3AImpl_GetPlayerFlags,
+
+  DirectPlay4AImpl_GetGroupOwner,
+  DirectPlay4AImpl_SetGroupOwner,
+  DirectPlay4AImpl_SendEx,
+  DirectPlay4AImpl_GetMessageQueue,
+  DirectPlay4AImpl_CancelMessage,
+  DirectPlay4AImpl_CancelPriority
+};
+#undef XCAST
+
+
+/***************************************************************************
+ *  DirectPlayEnumerateA (DPLAYX.2) 
+ *
+ *  The pointer to the structure lpContext will be filled with the 
+ *  appropriate data for each service offered by the OS. These services are
+ *  not necessarily available on this particular machine but are defined
+ *  as simple service providers under the "Service Providers" registry key.
+ *  This structure is then passed to lpEnumCallback for each of the different 
+ *  services. 
+ *
+ *  This API is useful only for applications written using DirectX3 or
+ *  worse. It is superceeded by IDirectPlay3::EnumConnections which also
+ *  gives information on the actual connections.
+ *
+ * defn of a service provider:
+ * A dynamic-link library used by DirectPlay to communicate over a network. 
+ * The service provider contains all the network-specific code required
+ * to send and receive messages. Online services and network operators can
+ * supply service providers to use specialized hardware, protocols, communications
+ * media, and network resources. 
+ *
+ * TODO: Allocate string buffer space from the heap (length from reg)
+ *       Pass real device driver numbers...
+ *       Get the GUID properly...
+ */
+HRESULT WINAPI DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback,
+                                     LPVOID lpContext )
+{
+
+  HKEY hkResult; 
+  LPCSTR searchSubKey    = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
+  LPSTR guidDataSubKey   = "Guid";
+  LPSTR majVerDataSubKey = "dwReserved1";  
+  LPSTR minVerDataSubKey = "dwReserved0";  
+  DWORD dwIndex, sizeOfSubKeyName=50;
+  char subKeyName[51]; 
+
+  TRACE(": lpEnumCallback=%p lpContext=%p\n", lpEnumCallback, lpContext );
+
+  if( !lpEnumCallback || !*lpEnumCallback )
+  {
+     return DPERR_INVALIDPARAMS;
+  }
+
+  /* Need to loop over the service providers in the registry */
+  if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
+                       0, KEY_ENUMERATE_SUB_KEYS, &hkResult ) != ERROR_SUCCESS )
+  {
+    /* Hmmm. Does this mean that there are no service providers? */ 
+    ERR(": no service providers?\n");
+    return DP_OK; 
+  }
+
+  /* Traverse all the service providers we have available */
+  for( dwIndex=0;
+       RegEnumKeyA( hkResult, dwIndex, subKeyName, sizeOfSubKeyName ) != ERROR_NO_MORE_ITEMS;
+       ++dwIndex )
+  {
+    HKEY     hkServiceProvider;
+    GUID     serviceProviderGUID;
+    DWORD    returnTypeGUID, returnTypeReserved, sizeOfReturnBuffer = 50;
+    char     returnBuffer[51];
+    DWORD    majVersionNum , minVersionNum = 0;
+    LPWSTR   lpWGUIDString; 
+
+    TRACE(" this time through: %s\n", subKeyName );
+
+    /* Get a handle for this particular service provider */
+    if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_QUERY_VALUE,
+                         &hkServiceProvider ) != ERROR_SUCCESS )
+    {
+      ERR(": what the heck is going on?\n" );
+      continue;
+    }
+
+    /* Get the GUID, Device major number and device minor number 
+     * from the registry. 
+     */
+    if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
+                            NULL, &returnTypeGUID, returnBuffer,
+                            &sizeOfReturnBuffer ) != ERROR_SUCCESS )
+    {
+      ERR(": missing GUID registry data members\n" );
+      continue; 
+    }
+
+    /* FIXME: Check return types to ensure we're interpreting data right */
+    lpWGUIDString = HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer );
+    CLSIDFromString( (LPCOLESTR)lpWGUIDString, &serviceProviderGUID ); 
+    HeapFree( GetProcessHeap(), 0, lpWGUIDString );
+
+    sizeOfReturnBuffer = 50;
+ 
+    if( RegQueryValueExA( hkServiceProvider, majVerDataSubKey,
+                            NULL, &returnTypeReserved, returnBuffer,
+                            &sizeOfReturnBuffer ) != ERROR_SUCCESS )
+    {
+      ERR(": missing dwReserved1 registry data members\n") ;
+      continue; 
+    }
+
+    /* FIXME: This couldn't possibly be right...*/
+    majVersionNum = GET_DWORD( returnBuffer );
+
+
+    sizeOfReturnBuffer = 50;
+
+    if( RegQueryValueExA( hkServiceProvider, minVerDataSubKey,
+                            NULL, &returnTypeReserved, returnBuffer,
+                            &sizeOfReturnBuffer ) != ERROR_SUCCESS )
+    {
+      ERR(": missing dwReserved0 registry data members\n") ;
+      continue;
+    }
+
+    minVersionNum = GET_DWORD( returnBuffer );
+
+
+    /* The enumeration will return FALSE if we are not to continue */
+    if( !lpEnumCallback( &serviceProviderGUID , subKeyName,
+                         majVersionNum, minVersionNum, lpContext ) )
+    {
+      WARN("lpEnumCallback returning FALSE\n" );
+      break;
+    }
+  }
+
+  return DP_OK;
+
+}
+
+/***************************************************************************
+ *  DirectPlayEnumerateW (DPLAYX.3)
+ *
+ */
+HRESULT WINAPI DirectPlayEnumerateW( LPDPENUMDPCALLBACKW lpEnumCallback, LPVOID lpContext )
+{
+
+  FIXME(":stub\n");
+
+  return DPERR_OUTOFMEMORY; 
+
+}
+
+/***************************************************************************
+ *  DirectPlayCreate (DPLAYX.1) (DPLAY.1)
+ *
+ */
+HRESULT WINAPI DirectPlayCreate
+( LPGUID lpGUID, LPDIRECTPLAY2 *lplpDP, IUnknown *pUnk)
+{
+
+  TRACE("lpGUID=%p lplpDP=%p pUnk=%p\n", lpGUID,lplpDP,pUnk);
+
+  if( pUnk != NULL )
+  {
+    /* Hmmm...wonder what this means! */
+    ERR("What does a NULL here mean?\n" ); 
+    return DPERR_OUTOFMEMORY;
+  }
+
+  if( IsEqualGUID( &IID_IDirectPlay2A, lpGUID ) )
+  {
+    return directPlay_QueryInterface( lpGUID, lplpDP );
+  }
+  else if( IsEqualGUID( &IID_IDirectPlay2, lpGUID ) )
+  {
+    return directPlay_QueryInterface( lpGUID, lplpDP );
+  }
+
+  /* Unknown interface type */
+  return DPERR_NOINTERFACE;
+}
diff --git a/dlls/dplayx/dplay.spec b/dlls/dplayx/dplay.spec
new file mode 100644
index 0000000..80ffd67
--- /dev/null
+++ b/dlls/dplayx/dplay.spec
@@ -0,0 +1,8 @@
+# First DirectPlay dll. Replaced by dplayx.dll.
+name dplay
+type win32
+
+import  dplayx.dll
+
+1 forward DirectPlayCreate DPLAYX.DirectPlayCreate
+2 forward DirectPlayEnumerate DPLAYX.DirectPlayEnumerate
diff --git a/relay32/dplayx.spec b/dlls/dplayx/dplayx.spec
similarity index 69%
rename from relay32/dplayx.spec
rename to dlls/dplayx/dplayx.spec
index 49c51b7..002f6c4 100644
--- a/relay32/dplayx.spec
+++ b/dlls/dplayx/dplayx.spec
@@ -6,4 +6,6 @@
   3 stdcall DirectPlayEnumerateW(ptr ptr) DirectPlayEnumerateW
   4 stdcall DirectPlayLobbyCreateA(ptr ptr ptr ptr long) DirectPlayLobbyCreateA
   5 stdcall DirectPlayLobbyCreateW(ptr ptr ptr ptr long) DirectPlayLobbyCreateW
-  9 stub DirectPlayEnumerate
+  6 stub DllCanUnloadNow
+  7 stdcall DllGetClassObject(ptr ptr ptr) DP_and_DPL_DllGetClassObject
+  9 stdcall DirectPlayEnumerate(ptr ptr) DirectPlayEnumerateA
diff --git a/dlls/dplayx/dplobby.c b/dlls/dplayx/dplobby.c
new file mode 100644
index 0000000..d7c1a77
--- /dev/null
+++ b/dlls/dplayx/dplobby.c
@@ -0,0 +1,1578 @@
+/* Direct Play Lobby 2 & 3 Implementation
+ *
+ * Copyright 1998,1999 - Peter Hunnisett
+ *
+ * <presently under construction - contact hunnise@nortelnetworks.com>
+ *
+ */
+#include <string.h>
+#include "winerror.h"
+#include "winnt.h"
+#include "winreg.h"
+#include "dplobby.h"
+#include "heap.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(dplay)
+
+/*****************************************************************************
+ * Predeclare the interface implementation structures
+ */
+typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyImpl;
+typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyAImpl;
+typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyWImpl;
+typedef struct IDirectPlayLobbyImpl IDirectPlayLobby2Impl;
+typedef struct IDirectPlayLobbyImpl IDirectPlayLobby2AImpl;
+typedef struct IDirectPlayLobbyImpl IDirectPlayLobby3Impl;
+typedef struct IDirectPlayLobbyImpl IDirectPlayLobby3AImpl;
+
+/*****************************************************************************
+ * IDirectPlayLobby {1,2,3} implementation structure
+ * 
+ * The philosophy behind this extra pointer derefernce is that I wanted to 
+ * have the same structure for all types of objects without having to do
+ * alot of casting. I also only wanted to implement an interface in the 
+ * object it was "released" with IUnknown interface being implemented in the 1 version.
+ * Of course, with these new interfaces comes the data required to keep the state required
+ * by these interfaces. So, basically, the pointers contain the data associated with
+ * a release. If you use the data associated with release 3 in a release 2 object, you'll
+ * get a run time trap, as that won't have any data.
+ *
+ */
+
+typedef struct tagDirectPlayLobbyIUnknownData
+{
+  DWORD             ref;
+  CRITICAL_SECTION  DPL_lock;
+} DirectPlayLobbyIUnknownData;
+
+/* FIXME: I don't think that everything belongs here...*/
+typedef struct tagDirectPlayLobbyData
+{
+  DWORD                     dwConnFlags;
+  DPSESSIONDESC2            sessionDesc;
+  DPNAME                    playerName;
+  GUID                      guidSP;
+  LPVOID                    lpAddress;
+  DWORD                     dwAddressSize;
+} DirectPlayLobbyData;
+
+typedef struct tagDirectPlayLobby2Data
+{
+  BOOL dummy;
+} DirectPlayLobby2Data;
+
+typedef struct tagDirectPlayLobby3Data
+{
+  BOOL dummy;
+} DirectPlayLobby3Data;
+
+struct IDirectPlayLobbyImpl
+{
+    ICOM_VTABLE(IDirectPlayLobby)* lpvtbl;
+ 
+    /* IUnknown fields */
+    DirectPlayLobbyIUnknownData*  unk;
+
+    /* IDirectPlayLobby 1 fields */
+    DirectPlayLobbyData*          dpl;
+
+    /* IDirectPlayLobby 2 fields */
+    DirectPlayLobby2Data*         dpl2;
+
+    /* IDirectPlayLobby 3 fields */
+    DirectPlayLobby3Data*         dpl3;
+};
+
+/* Forward declarations of virtual tables */
+static ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyAVT;
+static ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyWVT;
+static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2AVT;
+static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2WVT;
+static ICOM_VTABLE(IDirectPlayLobby3) directPlayLobby3AVT;
+static ICOM_VTABLE(IDirectPlayLobby3) directPlayLobby3WVT;
+
+
+
+
+/* The COM interface for upversioning an interface
+ * We've been given a GUID (riid) and we need to replace the present
+ * interface with that of the requested interface.
+ *
+ * Snip from some Microsoft document:
+ * There are four requirements for implementations of QueryInterface (In these
+ * cases, "must succeed" means "must succeed barring catastrophic failure."):
+ *
+ *  * The set of interfaces accessible on an object through
+ *    IUnknown::QueryInterface must be static, not dynamic. This means that
+ *    if a call to QueryInterface for a pointer to a specified interface
+ *    succeeds the first time, it must succeed again, and if it fails the
+ *    first time, it must fail on all subsequent queries.
+ *  * It must be symmetric ~W if a client holds a pointer to an interface on
+ *    an object, and queries for that interface, the call must succeed.
+ *  * It must be reflexive ~W if a client holding a pointer to one interface
+ *    queries successfully for another, a query through the obtained pointer
+ *    for the first interface must succeed.
+ *  * It must be transitive ~W if a client holding a pointer to one interface
+ *    queries successfully for a second, and through that pointer queries
+ *    successfully for a third interface, a query for the first interface
+ *    through the pointer for the third interface must succeed.
+ *
+ *  As you can see, this interface doesn't qualify but will most likely
+ *  be good enough for the time being.
+ */
+
+
+BOOL DPL_CreateIUnknown( IDirectPlayLobbyImpl* lpDPL ) 
+{
+  lpDPL->unk = (DirectPlayLobbyIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 
+                                                        sizeof( *(lpDPL->unk) ) ); 
+  if ( lpDPL->unk != NULL )
+  {
+    InitializeCriticalSection( &lpDPL->unk->DPL_lock );
+
+    IDirectPlayLobby_AddRef( lpDPL );
+
+    return TRUE; 
+  }
+
+  return FALSE;
+}
+
+BOOL DPL_DestroyIUnknown( IDirectPlayLobbyImpl* lpDPL )
+{
+  DeleteCriticalSection( &lpDPL->unk->DPL_lock );
+  HeapFree( GetProcessHeap(), 0, lpDPL->unk );
+
+  return TRUE;
+}
+
+BOOL DPL_CreateLobby1( IDirectPlayLobbyImpl* lpDPL )
+{
+  lpDPL->dpl = (DirectPlayLobbyIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                                        sizeof( *(lpDPL->dpl) ) );
+  if ( lpDPL->dpl == NULL )
+  {
+    return FALSE;
+  }
+
+  /* Initialize the dwSize fields for internal structures */
+
+  lpDPL->dpl->sessionDesc.dwSize = sizeof( lpDPL->dpl->sessionDesc ); 
+  lpDPL->dpl->playerName.dwSize = sizeof( lpDPL->dpl->playerName );
+  /* lpDPL->dpl->dwAddressSize = 0; Done in HeapAlloc */
+  
+  return TRUE;  
+}
+
+BOOL DPL_DestroyLobby1( IDirectPlayLobbyImpl* lpDPL )
+{
+  /* Delete the contents */
+  HeapFree( GetProcessHeap(), 0, lpDPL->dpl->sessionDesc.sess.lpszSessionNameA );
+  HeapFree( GetProcessHeap(), 0, lpDPL->dpl->sessionDesc.pass.lpszPasswordA );
+
+  HeapFree( GetProcessHeap(), 0, lpDPL->dpl->playerName.psn.lpszShortNameA );
+  HeapFree( GetProcessHeap(), 0, lpDPL->dpl->playerName.pln.lpszLongNameA );
+
+  HeapFree( GetProcessHeap(), 0, lpDPL->dpl->lpAddress );
+
+  HeapFree( GetProcessHeap(), 0, lpDPL->dpl );
+
+  return TRUE;
+}
+
+BOOL DPL_CreateLobby2( IDirectPlayLobbyImpl* lpDPL )
+{
+  lpDPL->dpl2 = (DirectPlayLobbyIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                                         sizeof( *(lpDPL->dpl2) ) );
+  if ( lpDPL->dpl2 == NULL )
+  {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+BOOL DPL_DestroyLobby2( IDirectPlayLobbyImpl* lpDPL )
+{
+  HeapFree( GetProcessHeap(), 0, lpDPL->dpl2 );
+
+  return TRUE;
+}
+
+BOOL DPL_CreateLobby3( IDirectPlayLobbyImpl* lpDPL )
+{
+  lpDPL->dpl3 = (DirectPlayLobbyIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                                         sizeof( *(lpDPL->dpl3) ) );
+  if ( lpDPL->dpl3 == NULL )
+  {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+BOOL DPL_DestroyLobby3( IDirectPlayLobbyImpl* lpDPL )
+{
+  HeapFree( GetProcessHeap(), 0, lpDPL->dpl3 );
+
+  return TRUE;
+}
+
+
+/* Helper function for DirectPlayLobby  QueryInterface */ 
+extern 
+HRESULT directPlayLobby_QueryInterface
+         ( REFIID riid, LPVOID* ppvObj )
+{
+  IDirectPlayLobby3AImpl* lpDPL = NULL;
+
+  if( IsEqualGUID( &IID_IDirectPlayLobby, riid ) )
+  {
+    lpDPL = (IDirectPlayLobbyImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                              sizeof( *lpDPL ) );
+
+    if( !lpDPL )
+    {
+      return E_OUTOFMEMORY;
+    }
+
+    lpDPL->lpvtbl = &directPlayLobbyWVT;
+
+    if ( DPL_CreateIUnknown( lpDPL ) &&
+         DPL_CreateLobby1( lpDPL ) 
+       )
+    { 
+      *ppvObj = lpDPL;
+      return S_OK;
+    }
+  }
+  else if( IsEqualGUID( &IID_IDirectPlayLobbyA, riid ) )
+  {
+    lpDPL = (IDirectPlayLobbyAImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                               sizeof( *lpDPL ) );
+
+    if( !lpDPL )
+    {
+      return E_OUTOFMEMORY;
+    }
+
+    lpDPL->lpvtbl = &directPlayLobbyAVT;
+
+    if ( DPL_CreateIUnknown( lpDPL ) &&
+         DPL_CreateLobby1( lpDPL ) 
+       )
+    { 
+      *ppvObj = lpDPL;
+      return S_OK;
+    }
+  }
+  else if( IsEqualGUID( &IID_IDirectPlayLobby2, riid ) )
+  {
+    lpDPL = (IDirectPlayLobby2Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                               sizeof( *lpDPL ) );
+
+    if( !lpDPL )
+    {
+      return E_OUTOFMEMORY;
+    }
+
+    lpDPL->lpvtbl = &directPlayLobby2WVT;
+
+    if ( DPL_CreateIUnknown( lpDPL ) &&
+         DPL_CreateLobby1( lpDPL ) &&
+         DPL_CreateLobby2( lpDPL )
+       )
+    {
+      *ppvObj = lpDPL;
+      return S_OK;
+    }
+  }
+  else if( IsEqualGUID( &IID_IDirectPlayLobby2A, riid ) )
+  {
+    lpDPL = (IDirectPlayLobby2AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                                sizeof( *lpDPL ) );
+
+    if( !lpDPL )
+    {
+      return E_OUTOFMEMORY;
+    }
+
+    lpDPL->lpvtbl = &directPlayLobby2AVT;
+
+    if ( DPL_CreateIUnknown( lpDPL ) &&
+         DPL_CreateLobby1( lpDPL )  &&
+         DPL_CreateLobby2( lpDPL )
+       )
+    {
+      *ppvObj = lpDPL;
+      return S_OK;
+    }
+  }
+  else if( IsEqualGUID( &IID_IDirectPlayLobby3, riid ) )
+  {
+    lpDPL = (IDirectPlayLobby3Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                               sizeof( *lpDPL ) );
+
+    if( !lpDPL )
+    {
+      return E_OUTOFMEMORY;
+    }
+
+    lpDPL->lpvtbl = &directPlayLobby3WVT;
+
+    if ( DPL_CreateIUnknown( lpDPL ) &&
+         DPL_CreateLobby1( lpDPL ) &&
+         DPL_CreateLobby2( lpDPL ) &&
+         DPL_CreateLobby3( lpDPL )
+       )
+    {
+      *ppvObj = lpDPL;
+      return S_OK;
+    }
+  }
+  else if( IsEqualGUID( &IID_IDirectPlayLobby3A, riid ) )
+  {
+     lpDPL = (IDirectPlayLobby3AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                             sizeof( *lpDPL ) );
+
+    if( !lpDPL )
+    {
+      return E_OUTOFMEMORY;
+    }
+
+    lpDPL->lpvtbl = &directPlayLobby3AVT;
+
+    if ( DPL_CreateIUnknown( lpDPL ) &&
+         DPL_CreateLobby1( lpDPL ) &&
+         DPL_CreateLobby2( lpDPL ) &&
+         DPL_CreateLobby3( lpDPL )
+       )
+    {
+      *ppvObj = lpDPL;
+      return S_OK;
+    }
+  }
+
+  /* Check if we had problems creating an interface */
+  if ( lpDPL != NULL )
+  {
+    DPL_DestroyLobby3( lpDPL );
+    DPL_DestroyLobby2( lpDPL );
+    DPL_DestroyLobby1( lpDPL );
+    DPL_DestroyIUnknown( lpDPL );
+    HeapFree( GetProcessHeap(), 0, lpDPL );
+
+    *ppvObj = NULL;
+
+    return DPERR_NOMEMORY;
+  }
+  else /* Unsupported interface */
+  {
+    *ppvObj = NULL;
+    return E_NOINTERFACE;
+  }
+}
+
+static HRESULT WINAPI IDirectPlayLobbyAImpl_QueryInterface
+( LPDIRECTPLAYLOBBYA iface,
+  REFIID riid,
+  LPVOID* ppvObj )
+{
+  ICOM_THIS(IDirectPlayLobby2Impl,iface);
+  TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
+
+  if( IsEqualGUID( &IID_IUnknown, riid )  ||
+      IsEqualGUID( &IID_IDirectPlayLobbyA, riid )
+    )
+  {
+    IDirectPlayLobby_AddRef( iface );
+    *ppvObj = This;
+    return S_OK;
+  }
+
+  return directPlayLobby_QueryInterface( riid, ppvObj );
+
+}
+
+static HRESULT WINAPI IDirectPlayLobbyW_QueryInterface
+( LPDIRECTPLAYLOBBY iface,
+  REFIID riid,
+  LPVOID* ppvObj )
+{
+  ICOM_THIS(IDirectPlayLobbyImpl,iface);
+  TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
+
+  if( IsEqualGUID( &IID_IUnknown, riid )  ||
+      IsEqualGUID( &IID_IDirectPlayLobby, riid )
+    )
+  {
+    IDirectPlayLobby_AddRef( iface );
+    *ppvObj = This;
+    return S_OK;
+  }
+
+  return directPlayLobby_QueryInterface( riid, ppvObj );
+}
+
+
+static HRESULT WINAPI IDirectPlayLobby2AImpl_QueryInterface
+( LPDIRECTPLAYLOBBY2A iface,
+  REFIID riid,
+  LPVOID* ppvObj )
+{
+  ICOM_THIS(IDirectPlayLobby2Impl,iface);
+  TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
+
+  /* Compare riids. We know this object is a direct play lobby 2A object.
+     If we are asking about the same type of interface we're fine.
+   */
+  if( IsEqualGUID( &IID_IUnknown, riid )  ||
+      IsEqualGUID( &IID_IDirectPlayLobby2A, riid )
+    )
+  {
+    IDirectPlayLobby_AddRef( iface );
+    *ppvObj = This;
+    return S_OK;
+  }
+  return directPlayLobby_QueryInterface( riid, ppvObj ); 
+}
+
+static HRESULT WINAPI IDirectPlayLobby2WImpl_QueryInterface
+( LPDIRECTPLAYLOBBY2 iface,
+  REFIID riid,
+  LPVOID* ppvObj )
+{
+  ICOM_THIS(IDirectPlayLobby2Impl,iface);
+
+  /* Compare riids. We know this object is a direct play lobby 2 object.
+     If we are asking about the same type of interface we're fine.
+   */
+  if( IsEqualGUID( &IID_IUnknown, riid ) ||
+      IsEqualGUID( &IID_IDirectPlayLobby2, riid ) 
+    )
+  {
+    IDirectPlayLobby_AddRef( iface );
+    *ppvObj = This;
+    return S_OK;
+  }
+
+  return directPlayLobby_QueryInterface( riid, ppvObj ); 
+
+}
+
+static HRESULT WINAPI IDirectPlayLobby3AImpl_QueryInterface
+( LPDIRECTPLAYLOBBY3A iface,
+  REFIID riid,
+  LPVOID* ppvObj )
+{
+  ICOM_THIS(IDirectPlayLobby3Impl,iface);
+
+  /* Compare riids. We know this object is a direct play lobby 3 object.
+     If we are asking about the same type of interface we're fine.
+   */
+  if( IsEqualGUID( &IID_IUnknown, riid ) ||
+      IsEqualGUID( &IID_IDirectPlayLobby3A, riid )
+    )
+  {
+    IDirectPlayLobby_AddRef( This );
+    *ppvObj = This;
+    return S_OK;
+  }
+
+  return directPlayLobby_QueryInterface( riid, ppvObj );
+
+}
+
+static HRESULT WINAPI IDirectPlayLobby3WImpl_QueryInterface
+( LPDIRECTPLAYLOBBY3 iface,
+  REFIID riid,
+  LPVOID* ppvObj )
+{
+  ICOM_THIS(IDirectPlayLobby3Impl,iface);
+
+  /* Compare riids. We know this object is a direct play lobby 3 object.
+     If we are asking about the same type of interface we're fine.
+   */
+  if( IsEqualGUID( &IID_IUnknown, riid ) ||
+      IsEqualGUID( &IID_IDirectPlayLobby3, riid )
+    )
+  {
+    IDirectPlayLobby_AddRef( This );
+    *ppvObj = This;
+    return S_OK;
+  }
+
+  return directPlayLobby_QueryInterface( riid, ppvObj );
+
+}
+
+/* 
+ * Simple procedure. Just increment the reference count to this
+ * structure and return the new reference count.
+ */
+static ULONG WINAPI IDirectPlayLobbyAImpl_AddRef
+( LPDIRECTPLAYLOBBYA iface )
+{
+  ULONG refCount;
+  ICOM_THIS(IDirectPlayLobby2Impl,iface);
+
+  EnterCriticalSection( &This->unk->DPL_lock );
+  {
+    refCount = ++(This->unk->ref);
+  }
+  LeaveCriticalSection( &This->unk->DPL_lock );
+
+  TRACE("ref count incremented to %lu for %p\n", refCount, This );
+
+  return refCount;
+}
+
+/*
+ * Simple COM procedure. Decrease the reference count to this object.
+ * If the object no longer has any reference counts, free up the associated
+ * memory.
+ */
+static ULONG WINAPI IDirectPlayLobbyAImpl_Release
+( LPDIRECTPLAYLOBBYA iface )
+{
+  ULONG refCount;
+
+  ICOM_THIS(IDirectPlayLobby2Impl,iface);
+
+  EnterCriticalSection( &This->unk->DPL_lock );
+  {
+    refCount = --(This->unk->ref);
+  }
+  LeaveCriticalSection( &This->unk->DPL_lock );
+
+  TRACE("ref count decremeneted to %lu for %p\n", refCount, This );
+
+  /* Deallocate if this is the last reference to the object */
+  if( refCount )
+  {
+     DPL_DestroyLobby3( This );
+     DPL_DestroyLobby2( This );
+     DPL_DestroyLobby1( This );
+     DPL_DestroyIUnknown( This );
+     HeapFree( GetProcessHeap(), 0, This );
+  }
+
+  return refCount;
+}
+
+
+/********************************************************************
+ * 
+ * Connects an application to the session specified by the DPLCONNECTION
+ * structure currently stored with the DirectPlayLobby object.
+ *
+ * Returns a IDirectPlay interface.
+ *
+ */
+static HRESULT WINAPI IDirectPlayLobbyAImpl_Connect
+( LPDIRECTPLAYLOBBYA iface,
+  DWORD dwFlags,
+  LPDIRECTPLAY2A* lplpDP,
+  IUnknown* pUnk)
+{
+  ICOM_THIS(IDirectPlayLobbyImpl,iface);
+
+  LPDIRECTPLAY2A      lpDirectPlay2A;
+  LPDIRECTPLAY3A      lpDirectPlay3A;
+  LPDIRECTPLAYLOBBY2A lpDirectPlayLobby2A;
+  HRESULT             rc;
+
+  FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, dwFlags, lplpDP, pUnk );
+
+  if( dwFlags || pUnk )
+  {
+     return DPERR_INVALIDPARAMS;
+  }
+
+  if( ( rc = DirectPlayCreate( (LPGUID)&IID_IDirectPlay2A, lplpDP, pUnk ) ) != DP_OK )
+  {
+     ERR("error creating Direct Play 2W interface. Return Code = 0x%lx.\n", rc );
+     return rc;
+  }
+
+  lpDirectPlay2A = *lplpDP;
+
+  /* This should invoke IDirectPlay3::InitializeConnection IDirectPlay3::Open */
+  /* - Use This object to get a DPL2 object using QueryInterface
+   * - Need to call CreateCompoundAddress to create the lpConnection param for IDirectPlay::InitializeConnection
+   * - Call IDirectPlay::InitializeConnection
+   * - Call IDirectPlay::Open 
+   */
+#if 0
+  create_address:
+  {
+    DPCOMPOUNDADDRESSELEMENT compoundAddress;
+
+    /* Get lobby version capable of supporting CreateCompoundAddress */ 
+    if( ( rc = IDirectPlayLobby_QueryInterface( This, &IID_IDirectPlayLobby2A, &lpDirectPlayLobby2A ) ) != DP_OK )
+    {
+      return rc;
+    }
+
+    EnterCriticalSection( &This->unk->DPL_lock );
+
+    /* Actually create the compound address */
+    memcpy( compoundAddress.guidDataType, This->dpl->guidSP, sizeof( compoundAddress.guidDataType ) );
+
+    LeaveCriticalSection( &This->unk->DPL_lock );
+
+    rc = IDirectPlayLobby_CreateCompoundAddress( lpDirectPlayLobby2A, lpElements, dwElementCount, lpAddress, lpdwAddressSize ) 
+
+    /* Free the lobby object since we're done with it */
+    IDirectPlayLobby_Release( lpDirectPlayLobby2A );
+
+    if( rc != DP_OK )
+    {
+      return rc; 
+    }
+  }
+
+  if( ( rc = IDirectPlayX_QueryInterface( directPlay2A, &IID_IDirectPlay3A, &lpDirectPlay3A ) ) != DP_OK )
+  {
+    return rc;
+  }
+#endif
+
+  return DP_OK;
+
+}
+
+static HRESULT WINAPI IDirectPlayLobbyWImpl_Connect
+( LPDIRECTPLAYLOBBY iface,
+  DWORD dwFlags,
+  LPDIRECTPLAY2* lplpDP,
+  IUnknown* pUnk)
+{
+  ICOM_THIS(IDirectPlayLobbyImpl,iface);
+  LPDIRECTPLAY2* directPlay2W;
+  HRESULT        createRC;
+
+  FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, dwFlags, lplpDP, pUnk );
+
+  if( dwFlags || pUnk )
+  {
+     return DPERR_INVALIDPARAMS;
+  }
+
+  if( ( createRC = DirectPlayCreate( (LPGUID)&IID_IDirectPlay2, lplpDP, pUnk ) ) != DP_OK )
+  {
+     ERR("error creating Direct Play 2W interface. Return Code = 0x%lx.\n", createRC );
+     return createRC;
+  } 
+
+  /* This should invoke IDirectPlay3::InitializeConnection IDirectPlay3::Open */  
+  directPlay2W = lplpDP; 
+ 
+  return DP_OK;
+
+}
+
+/********************************************************************
+ *
+ * Creates a DirectPlay Address, given a service provider-specific network
+ * address. 
+ * Returns an address contains the globally unique identifier
+ * (GUID) of the service provider and data that the service provider can
+ * interpret as a network address.
+ *
+ */
+static HRESULT WINAPI IDirectPlayLobbyAImpl_CreateAddress
+( LPDIRECTPLAYLOBBYA iface,
+  REFGUID guidSP,
+  REFGUID guidDataType,
+  LPCVOID lpData, 
+  DWORD dwDataSize,
+  LPVOID lpAddress, 
+  LPDWORD lpdwAddressSize )
+{
+  FIXME(":stub\n");
+  return DPERR_OUTOFMEMORY;
+}
+
+static HRESULT WINAPI IDirectPlayLobbyWImpl_CreateAddress
+( LPDIRECTPLAYLOBBY iface,
+  REFGUID guidSP,
+  REFGUID guidDataType,
+  LPCVOID lpData,
+  DWORD dwDataSize,
+  LPVOID lpAddress,
+  LPDWORD lpdwAddressSize )
+{
+  FIXME(":stub\n");
+  return DPERR_OUTOFMEMORY;
+}
+
+
+/********************************************************************
+ *
+ * Parses out chunks from the DirectPlay Address buffer by calling the
+ * given callback function, with lpContext, for each of the chunks.
+ *
+ */
+static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddress
+( LPDIRECTPLAYLOBBYA iface,
+  LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
+  LPCVOID lpAddress,
+  DWORD dwAddressSize,
+  LPVOID lpContext )
+{
+  FIXME(":stub\n");
+  return DPERR_OUTOFMEMORY;
+}
+
+static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumAddress
+( LPDIRECTPLAYLOBBY iface,
+  LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
+  LPCVOID lpAddress,
+  DWORD dwAddressSize,
+  LPVOID lpContext )
+{
+  FIXME(":stub\n");
+  return DPERR_OUTOFMEMORY;
+}
+
+/********************************************************************
+ *
+ * Enumerates all the address types that a given service provider needs to
+ * build the DirectPlay Address.
+ *
+ */
+static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddressTypes
+( LPDIRECTPLAYLOBBYA iface,
+  LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
+  REFGUID guidSP,
+  LPVOID lpContext,
+  DWORD dwFlags )
+{
+  FIXME(":stub\n");
+  return DPERR_OUTOFMEMORY;
+}
+
+static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumAddressTypes
+( LPDIRECTPLAYLOBBY iface,
+  LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
+  REFGUID guidSP,
+  LPVOID lpContext,
+  DWORD dwFlags )
+{
+  FIXME(":stub\n");
+  return DPERR_OUTOFMEMORY;
+}
+
+/********************************************************************
+ *
+ * Enumerates what applications are registered with DirectPlay by
+ * invoking the callback function with lpContext.
+ *
+ */
+static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumLocalApplications
+( LPDIRECTPLAYLOBBY iface,
+  LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback,
+  LPVOID lpContext,
+  DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlayLobbyImpl,iface);
+
+  FIXME("(%p)->(%p,%p,0x%08lx):stub\n", This, lpEnumLocalAppCallback, lpContext, dwFlags );
+
+  return DPERR_OUTOFMEMORY;
+}
+
+static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumLocalApplications
+( LPDIRECTPLAYLOBBYA iface,
+  LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback,
+  LPVOID lpContext,
+  DWORD dwFlags )
+{
+  ICOM_THIS(IDirectPlayLobbyImpl,iface);
+
+  FIXME("(%p)->(%p,%p,0x%08lx):stub\n", This, lpEnumLocalAppCallback, lpContext, dwFlags );
+
+  return DPERR_OUTOFMEMORY;
+}
+
+/********************************************************************
+ *
+ * Retrieves the DPLCONNECTION structure that contains all the information
+ * needed to start and connect an application. This was generated using
+ * either the RunApplication or SetConnectionSettings methods.
+ *
+ * NOTES: If lpData is NULL then just return lpdwDataSize. This allows
+ *        the data structure to be allocated by our caller which can then
+ *        call this procedure/method again with a valid data pointer.
+ */
+static HRESULT WINAPI IDirectPlayLobbyAImpl_GetConnectionSettings
+( LPDIRECTPLAYLOBBYA iface,
+  DWORD dwAppID,
+  LPVOID lpData,
+  LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlayLobbyImpl,iface);
+  LPDPLCONNECTION lpDplConnection;
+
+  FIXME(": semi stub (%p)->(0x%08lx,%p,%p)\n", This, dwAppID, lpData, lpdwDataSize );
+ 
+  /* Application is requesting us to give the required size */
+  if ( lpData == NULL )
+  {
+    *lpdwDataSize = sizeof( DPLCONNECTION );
+    return DPERR_BUFFERTOOSMALL;
+  }
+
+  /* Let's check the size of the buffer that the application has allocated */
+  if ( *lpdwDataSize < sizeof( DPLCONNECTION ) )
+  {
+    *lpdwDataSize = sizeof( DPLCONNECTION );
+    return DPERR_BUFFERTOOSMALL;
+  }
+
+  /* FIXME: Who's supposed to own the data */
+
+  /* Fill in the fields - let them just use the ptrs */
+  lpDplConnection = (LPDPLCONNECTION)lpData;
+
+  /* Copy everything we've got into here */
+  /* Need to actually store the stuff here. Check if we've already allocated each field first. */
+  lpDplConnection->dwFlags = This->dpl->dwConnFlags;
+
+  /* Copy LPDPSESSIONDESC2 struct */
+  lpDplConnection->lpSessionDesc = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( This->dpl->sessionDesc ) );
+  memcpy( lpDplConnection->lpSessionDesc, &This->dpl->sessionDesc, sizeof( This->dpl->sessionDesc ) );
+
+  if( This->dpl->sessionDesc.sess.lpszSessionName )
+  {
+    lpDplConnection->lpSessionDesc->sess.lpszSessionName = 
+      HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, This->dpl->sessionDesc.sess.lpszSessionNameA );
+  }
+
+  if( This->dpl->sessionDesc.pass.lpszPassword )
+  {
+    lpDplConnection->lpSessionDesc->pass.lpszPassword = 
+      HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, This->dpl->sessionDesc.pass.lpszPasswordA );
+  }
+     
+  lpDplConnection->lpSessionDesc->dwReserved1 = This->dpl->sessionDesc.dwReserved1;
+  lpDplConnection->lpSessionDesc->dwReserved2 = This->dpl->sessionDesc.dwReserved2;
+
+  /* Copy DPNAME struct - seems to be optional - check for existance first */
+  lpDplConnection->lpPlayerName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( This->dpl->playerName ) );
+  memcpy( lpDplConnection->lpPlayerName, &(This->dpl->playerName), sizeof( This->dpl->playerName ) );
+
+  if( This->dpl->playerName.psn.lpszShortName )
+  {
+    lpDplConnection->lpPlayerName->psn.lpszShortName =
+      HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, This->dpl->playerName.psn.lpszShortNameA );  
+  }
+
+  if( This->dpl->playerName.pln.lpszLongName )
+  {
+    lpDplConnection->lpPlayerName->pln.lpszLongName =
+      HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, This->dpl->playerName.pln.lpszLongNameA );
+  }
+
+  memcpy( &lpDplConnection->guidSP, &This->dpl->guidSP, sizeof( This->dpl->guidSP ) );
+
+  lpDplConnection->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, This->dpl->dwAddressSize );
+  memcpy( lpDplConnection->lpAddress, This->dpl->lpAddress, This->dpl->dwAddressSize );
+
+  lpDplConnection->dwAddressSize = This->dpl->dwAddressSize;
+
+  return DP_OK;
+}
+
+static HRESULT WINAPI IDirectPlayLobbyWImpl_GetConnectionSettings
+( LPDIRECTPLAYLOBBY iface,
+  DWORD dwAppID,
+  LPVOID lpData,
+  LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlayLobbyImpl,iface);
+  FIXME(":semi stub %p %08lx %p %p \n", This, dwAppID, lpData, lpdwDataSize );
+
+  /* Application is requesting us to give the required size */ 
+  if ( !lpData )
+  {
+    /* Let's check the size of the buffer that the application has allocated */
+    if( *lpdwDataSize >= sizeof( DPLCONNECTION ) )
+    {
+      return DP_OK;  
+    }
+    else
+    {
+      *lpdwDataSize = sizeof( DPLCONNECTION );
+      return DPERR_BUFFERTOOSMALL;
+    }
+  }
+
+  /* Fill in the fields - see above */
+  FIXME("stub\n" );
+
+  return DP_OK;
+}
+
+/********************************************************************
+ *
+ * Retrieves the message sent between a lobby client and a DirectPlay 
+ * application. All messages are queued until received.
+ *
+ */
+static HRESULT WINAPI IDirectPlayLobbyAImpl_ReceiveLobbyMessage
+( LPDIRECTPLAYLOBBYA iface,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  LPDWORD lpdwMessageFlags,
+  LPVOID lpData,
+  LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlayLobbyImpl,iface);
+  FIXME(":stub %p %08lx %08lx %p %p %p\n", This, dwFlags, dwAppID, lpdwMessageFlags, lpData,
+         lpdwDataSize );
+  return DPERR_OUTOFMEMORY;
+}
+
+static HRESULT WINAPI IDirectPlayLobbyWImpl_ReceiveLobbyMessage
+( LPDIRECTPLAYLOBBY iface,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  LPDWORD lpdwMessageFlags,
+  LPVOID lpData,
+  LPDWORD lpdwDataSize )
+{
+  ICOM_THIS(IDirectPlayLobbyImpl,iface);
+  FIXME(":stub %p %08lx %08lx %p %p %p\n", This, dwFlags, dwAppID, lpdwMessageFlags, lpData,
+         lpdwDataSize );
+  return DPERR_OUTOFMEMORY;
+}
+
+/********************************************************************
+ *
+ * Starts an application and passes to it all the information to
+ * connect to a session.
+ *
+ */
+static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication
+( LPDIRECTPLAYLOBBYA iface,
+  DWORD dwFlags,
+  LPDWORD lpdwAppID,
+  LPDPLCONNECTION lpConn,
+  HANDLE hReceiveEvent )
+{
+  FIXME(":stub\n");
+  return DPERR_OUTOFMEMORY;
+}
+
+static HRESULT WINAPI IDirectPlayLobbyWImpl_RunApplication
+( LPDIRECTPLAYLOBBY iface,
+  DWORD dwFlags,
+  LPDWORD lpdwAppID,
+  LPDPLCONNECTION lpConn,
+  HANDLE hReceiveEvent )
+{
+  FIXME(":stub\n");
+  return DPERR_OUTOFMEMORY;
+}
+
+/********************************************************************
+ *
+ * Sends a message between the application and the lobby client.
+ * All messages are queued until received.
+ *
+ */
+static HRESULT WINAPI IDirectPlayLobbyAImpl_SendLobbyMessage
+( LPDIRECTPLAYLOBBYA iface,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  LPVOID lpData,
+  DWORD dwDataSize )
+{
+  FIXME(":stub\n");
+  return DPERR_OUTOFMEMORY;
+}
+
+static HRESULT WINAPI IDirectPlayLobbyWImpl_SendLobbyMessage
+( LPDIRECTPLAYLOBBY iface,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  LPVOID lpData,
+  DWORD dwDataSize )
+{
+  FIXME(":stub\n");
+  return DPERR_OUTOFMEMORY;
+}
+
+/********************************************************************
+ *
+ * Modifies the DPLCONNECTION structure to contain all information
+ * needed to start and connect an application.
+ *
+ */
+static HRESULT WINAPI IDirectPlayLobbyWImpl_SetConnectionSettings
+( LPDIRECTPLAYLOBBY iface,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  LPDPLCONNECTION lpConn )
+{
+  ICOM_THIS(IDirectPlayLobbyImpl,iface);
+  TRACE(": This=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p\n",
+         This, dwFlags, dwAppID, lpConn );
+
+  /* Paramater check */
+  if( dwFlags || !This || !lpConn )
+  {
+    ERR("invalid parameters.\n");
+    return DPERR_INVALIDPARAMS;
+  }
+
+  /* See if there is a connection associated with this request.
+   * dwAppID == 0 indicates that this request isn't associated with a connection.
+   */
+  if( dwAppID )
+  {
+     FIXME(": Connection dwAppID=%08lx given. Not implemented yet.\n",
+            dwAppID );
+
+     /* Need to add a check for this application Id...*/
+     return DPERR_NOTLOBBIED;
+  }
+
+  if(  lpConn->dwSize != sizeof(DPLCONNECTION) )
+  {
+    ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n", 
+         lpConn->dwSize, sizeof( DPLCONNECTION ) );
+    return DPERR_INVALIDPARAMS;
+  }
+
+  /* Need to investigate the lpConn->lpSessionDesc to figure out
+   * what type of session we need to join/create.
+   */
+  if(  (!lpConn->lpSessionDesc ) || 
+       ( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
+    )
+  {
+    ERR("DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
+         lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
+    return DPERR_INVALIDPARAMS;
+  }
+
+  EnterCriticalSection( &This->unk->DPL_lock );
+
+  /* Need to actually store the stuff here. Check if we've already allocated each field first. */
+  This->dpl->dwConnFlags = lpConn->dwFlags;
+
+  /* Copy LPDPSESSIONDESC2 struct - this is required */
+  memcpy( &This->dpl->sessionDesc, lpConn->lpSessionDesc, sizeof( *(lpConn->lpSessionDesc) ) );
+
+  /* FIXME: Can this just be shorted? Does it handle the NULL case correctly? */
+  if( lpConn->lpSessionDesc->sess.lpszSessionName )
+    This->dpl->sessionDesc.sess.lpszSessionName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->sess.lpszSessionName );
+  else
+    This->dpl->sessionDesc.sess.lpszSessionName = NULL;
+ 
+  if( lpConn->lpSessionDesc->pass.lpszPassword )
+    This->dpl->sessionDesc.pass.lpszPassword = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->pass.lpszPassword );
+  else
+    This->dpl->sessionDesc.pass.lpszPassword = NULL;
+
+  This->dpl->sessionDesc.dwReserved1 = lpConn->lpSessionDesc->dwReserved1;
+  This->dpl->sessionDesc.dwReserved2 = lpConn->lpSessionDesc->dwReserved2;
+
+  /* Copy DPNAME struct - seems to be optional - check for existance first */
+  if( lpConn->lpPlayerName )
+  {
+     memcpy( &This->dpl->playerName, lpConn->lpPlayerName, sizeof( *lpConn->lpPlayerName ) ); 
+
+     if( lpConn->lpPlayerName->psn.lpszShortName )
+       This->dpl->playerName.psn.lpszShortName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->psn.lpszShortName );
+
+     if( lpConn->lpPlayerName->pln.lpszLongName )
+       This->dpl->playerName.pln.lpszLongName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->pln.lpszLongName );
+
+  }
+
+  memcpy( &This->dpl->guidSP, &lpConn->guidSP, sizeof( lpConn->guidSP ) );  
+  
+  This->dpl->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->dwAddressSize ); 
+  memcpy( This->dpl->lpAddress, lpConn->lpAddress, lpConn->dwAddressSize );
+
+  This->dpl->dwAddressSize = lpConn->dwAddressSize;
+
+  LeaveCriticalSection( &This->unk->DPL_lock );
+
+  return DP_OK;
+}
+
+static HRESULT WINAPI IDirectPlayLobbyAImpl_SetConnectionSettings
+( LPDIRECTPLAYLOBBYA iface,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  LPDPLCONNECTION lpConn )
+{
+  ICOM_THIS(IDirectPlayLobbyImpl,iface);
+  TRACE(": This=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p\n",
+         This, dwFlags, dwAppID, lpConn );
+
+  /* Paramater check */
+  if( dwFlags || !This || !lpConn )
+  {
+    ERR("invalid parameters.\n");
+    return DPERR_INVALIDPARAMS;
+  }
+
+  /* See if there is a connection associated with this request.
+   * dwAppID == 0 indicates that this request isn't associated with a connection.
+   */
+  if( dwAppID )
+  {
+     FIXME(": Connection dwAppID=%08lx given. Not implemented yet.\n",
+            dwAppID );
+
+     /* Need to add a check for this application Id...*/
+     return DPERR_NOTLOBBIED;
+  }
+
+  if(  lpConn->dwSize != sizeof(DPLCONNECTION) )
+  {
+    ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
+         lpConn->dwSize, sizeof( DPLCONNECTION ) );
+    return DPERR_INVALIDPARAMS;
+  }
+
+  /* Need to investigate the lpConn->lpSessionDesc to figure out
+   * what type of session we need to join/create.
+   */
+  if(  (!lpConn->lpSessionDesc ) ||
+       ( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
+    )
+  {
+    ERR("DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
+         lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
+    return DPERR_INVALIDPARAMS;
+  }
+
+  EnterCriticalSection( &This->unk->DPL_lock );
+
+  /* Need to actually store the stuff here. Check if we've already allocated each field first. */
+  This->dpl->dwConnFlags = lpConn->dwFlags;
+
+  /* Copy LPDPSESSIONDESC2 struct - this is required */
+  memcpy( &This->dpl->sessionDesc, lpConn->lpSessionDesc, sizeof( *(lpConn->lpSessionDesc) ) );
+
+  /* FIXME: Can this just be shorted? Does it handle the NULL case correctly? */
+  if( lpConn->lpSessionDesc->sess.lpszSessionNameA )
+    This->dpl->sessionDesc.sess.lpszSessionNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->sess.lpszSessionNameA );
+  else
+    This->dpl->sessionDesc.sess.lpszSessionNameA = NULL;
+
+  if( lpConn->lpSessionDesc->pass.lpszPasswordA )
+    This->dpl->sessionDesc.pass.lpszPasswordA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->pass.lpszPasswordA );
+  else
+    This->dpl->sessionDesc.pass.lpszPasswordA = NULL;
+
+  This->dpl->sessionDesc.dwReserved1 = lpConn->lpSessionDesc->dwReserved1;
+  This->dpl->sessionDesc.dwReserved2 = lpConn->lpSessionDesc->dwReserved2;
+
+  /* Copy DPNAME struct - seems to be optional - check for existance first */
+  if( lpConn->lpPlayerName )
+  {
+     memcpy( &This->dpl->playerName, lpConn->lpPlayerName, sizeof( *lpConn->lpPlayerName ) );
+
+     if( lpConn->lpPlayerName->psn.lpszShortNameA )
+       This->dpl->playerName.psn.lpszShortNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->psn.lpszShortNameA );
+
+     if( lpConn->lpPlayerName->pln.lpszLongNameA )
+       This->dpl->playerName.pln.lpszLongNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->pln.lpszLongNameA );
+
+  }
+
+  memcpy( &This->dpl->guidSP, &lpConn->guidSP, sizeof( lpConn->guidSP ) );
+
+  This->dpl->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->dwAddressSize );
+  memcpy( This->dpl->lpAddress, lpConn->lpAddress, lpConn->dwAddressSize );
+
+  This->dpl->dwAddressSize = lpConn->dwAddressSize;
+
+  LeaveCriticalSection( &This->unk->DPL_lock );
+
+  return DP_OK;
+}
+
+/********************************************************************
+ *
+ * Registers an event that will be set when a lobby message is received.
+ *
+ */
+static HRESULT WINAPI IDirectPlayLobbyAImpl_SetLobbyMessageEvent
+( LPDIRECTPLAYLOBBYA iface,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  HANDLE hReceiveEvent )
+{
+  FIXME(":stub\n");
+  return DPERR_OUTOFMEMORY;
+}
+
+static HRESULT WINAPI IDirectPlayLobbyWImpl_SetLobbyMessageEvent
+( LPDIRECTPLAYLOBBY iface,
+  DWORD dwFlags,
+  DWORD dwAppID,
+  HANDLE hReceiveEvent )
+{
+  FIXME(":stub\n");
+  return DPERR_OUTOFMEMORY;
+}
+
+
+/* DPL 2 methods - well actuall only one */
+
+/********************************************************************
+ *
+ * Registers an event that will be set when a lobby message is received.
+ *
+ */
+static HRESULT WINAPI IDirectPlayLobby2WImpl_CreateCompoundAddress
+( LPDIRECTPLAYLOBBY2 iface,
+  LPCDPCOMPOUNDADDRESSELEMENT lpElements,
+  DWORD dwElementCount,
+  LPVOID lpAddress,
+  LPDWORD lpdwAddressSize )
+{
+  FIXME(":stub\n");
+  return DPERR_OUTOFMEMORY;
+}
+
+static HRESULT WINAPI IDirectPlayLobby2AImpl_CreateCompoundAddress
+( LPDIRECTPLAYLOBBY2A iface,
+  LPCDPCOMPOUNDADDRESSELEMENT lpElements,
+  DWORD dwElementCount,
+  LPVOID lpAddress,
+  LPDWORD lpdwAddressSize )
+{
+  FIXME(":stub\n");
+  return DPERR_OUTOFMEMORY;
+}
+
+/* DPL 3 methods */
+
+static HRESULT WINAPI IDirectPlayLobby3WImpl_ConnectEx
+( LPDIRECTPLAYLOBBY3 iface, DWORD dwFlags, REFIID riid, LPVOID* lplpDP, IUnknown* pUnk )
+{
+  FIXME(":stub\n");
+  return DP_OK;
+}
+
+static HRESULT WINAPI IDirectPlayLobby3AImpl_ConnectEx
+( LPDIRECTPLAYLOBBY3A iface, DWORD dwFlags, REFIID riid, LPVOID* lplpDP, IUnknown* pUnk )
+{
+  FIXME(":stub\n");
+  return DP_OK;
+}
+
+static HRESULT WINAPI IDirectPlayLobby3WImpl_RegisterApplication
+( LPDIRECTPLAYLOBBY3 iface, DWORD dwFlags, LPDPAPPLICATIONDESC lpAppDesc )
+{
+  FIXME(":stub\n");
+  return DP_OK;
+}
+
+static HRESULT WINAPI IDirectPlayLobby3AImpl_RegisterApplication
+( LPDIRECTPLAYLOBBY3A iface, DWORD dwFlags, LPDPAPPLICATIONDESC lpAppDesc )
+{
+  FIXME(":stub\n");
+  return DP_OK;
+}
+
+static HRESULT WINAPI IDirectPlayLobby3WImpl_UnregisterApplication
+( LPDIRECTPLAYLOBBY3 iface, DWORD dwFlags, REFGUID lpAppDesc )
+{
+  FIXME(":stub\n");
+  return DP_OK;
+}
+
+static HRESULT WINAPI IDirectPlayLobby3AImpl_UnregisterApplication
+( LPDIRECTPLAYLOBBY3A iface, DWORD dwFlags, REFGUID lpAppDesc )
+{
+  FIXME(":stub\n");
+  return DP_OK;
+}
+
+static HRESULT WINAPI IDirectPlayLobby3WImpl_WaitForConnectionSettings
+( LPDIRECTPLAYLOBBY3 iface, DWORD dwFlags )
+{
+  FIXME(":stub\n");
+  return DP_OK;
+}
+
+static HRESULT WINAPI IDirectPlayLobby3AImpl_WaitForConnectionSettings
+( LPDIRECTPLAYLOBBY3A iface, DWORD dwFlags )
+{
+  FIXME(":stub\n");
+  return DP_OK;
+}
+
+
+/* Virtual Table definitions for DPL{1,2,3}{A,W} */
+
+/* Note: Hack so we can reuse the old functions without compiler warnings */
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(directPlayLobbyAVT.fn##fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+/* Direct Play Lobby 1 (ascii) Virtual Table for methods */
+/* All lobby 1 methods are exactly the same except QueryInterface */
+static struct ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyAVT = 
+{
+  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+
+  IDirectPlayLobbyAImpl_QueryInterface,
+  XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
+  XCAST(Release)IDirectPlayLobbyAImpl_Release,
+
+  IDirectPlayLobbyAImpl_Connect,
+  IDirectPlayLobbyAImpl_CreateAddress,
+  IDirectPlayLobbyAImpl_EnumAddress,
+  IDirectPlayLobbyAImpl_EnumAddressTypes,
+  IDirectPlayLobbyAImpl_EnumLocalApplications,
+  IDirectPlayLobbyAImpl_GetConnectionSettings,
+  IDirectPlayLobbyAImpl_ReceiveLobbyMessage,
+  IDirectPlayLobbyAImpl_RunApplication,
+  IDirectPlayLobbyAImpl_SendLobbyMessage,
+  IDirectPlayLobbyAImpl_SetConnectionSettings,
+  IDirectPlayLobbyAImpl_SetLobbyMessageEvent
+};
+#undef XCAST
+
+
+/* Note: Hack so we can reuse the old functions without compiler warnings */
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(directPlayLobbyWVT.fn##fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+/* Direct Play Lobby 1 (unicode) Virtual Table for methods */
+static ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyWVT = 
+{
+  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+
+  IDirectPlayLobbyW_QueryInterface,
+  XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
+  XCAST(Release)IDirectPlayLobbyAImpl_Release,
+
+  IDirectPlayLobbyWImpl_Connect,
+  IDirectPlayLobbyWImpl_CreateAddress, 
+  IDirectPlayLobbyWImpl_EnumAddress,
+  IDirectPlayLobbyWImpl_EnumAddressTypes,
+  IDirectPlayLobbyWImpl_EnumLocalApplications,
+  IDirectPlayLobbyWImpl_GetConnectionSettings,
+  IDirectPlayLobbyWImpl_ReceiveLobbyMessage,
+  IDirectPlayLobbyWImpl_RunApplication,
+  IDirectPlayLobbyWImpl_SendLobbyMessage,
+  IDirectPlayLobbyWImpl_SetConnectionSettings,
+  IDirectPlayLobbyWImpl_SetLobbyMessageEvent
+};
+#undef XCAST
+
+/* Note: Hack so we can reuse the old functions without compiler warnings */
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(directPlayLobby2AVT.fn##fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+/* Direct Play Lobby 2 (ascii) Virtual Table for methods */
+static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2AVT = 
+{
+  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+
+  IDirectPlayLobby2AImpl_QueryInterface,
+  XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
+  XCAST(Release)IDirectPlayLobbyAImpl_Release,
+
+  XCAST(Connect)IDirectPlayLobbyAImpl_Connect,
+  XCAST(CreateAddress)IDirectPlayLobbyAImpl_CreateAddress,
+  XCAST(EnumAddress)IDirectPlayLobbyAImpl_EnumAddress,
+  XCAST(EnumAddressTypes)IDirectPlayLobbyAImpl_EnumAddressTypes,
+  XCAST(EnumLocalApplications)IDirectPlayLobbyAImpl_EnumLocalApplications,
+  XCAST(GetConnectionSettings)IDirectPlayLobbyAImpl_GetConnectionSettings,
+  XCAST(ReceiveLobbyMessage)IDirectPlayLobbyAImpl_ReceiveLobbyMessage,
+  XCAST(RunApplication)IDirectPlayLobbyAImpl_RunApplication,
+  XCAST(SendLobbyMessage)IDirectPlayLobbyAImpl_SendLobbyMessage,
+  XCAST(SetConnectionSettings)IDirectPlayLobbyAImpl_SetConnectionSettings,
+  XCAST(SetLobbyMessageEvent)IDirectPlayLobbyAImpl_SetLobbyMessageEvent,
+
+  IDirectPlayLobby2AImpl_CreateCompoundAddress 
+};
+#undef XCAST
+
+/* Note: Hack so we can reuse the old functions without compiler warnings */
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(directPlayLobby2AVT.fn##fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+/* Direct Play Lobby 2 (unicode) Virtual Table for methods */
+static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2WVT = 
+{
+  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+
+  IDirectPlayLobby2WImpl_QueryInterface,
+  XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef, 
+  XCAST(Release)IDirectPlayLobbyAImpl_Release,
+
+  XCAST(Connect)IDirectPlayLobbyWImpl_Connect,
+  XCAST(CreateAddress)IDirectPlayLobbyWImpl_CreateAddress,
+  XCAST(EnumAddress)IDirectPlayLobbyWImpl_EnumAddress,
+  XCAST(EnumAddressTypes)IDirectPlayLobbyWImpl_EnumAddressTypes,
+  XCAST(EnumLocalApplications)IDirectPlayLobbyWImpl_EnumLocalApplications,
+  XCAST(GetConnectionSettings)IDirectPlayLobbyWImpl_GetConnectionSettings,
+  XCAST(ReceiveLobbyMessage)IDirectPlayLobbyWImpl_ReceiveLobbyMessage,
+  XCAST(RunApplication)IDirectPlayLobbyWImpl_RunApplication,
+  XCAST(SendLobbyMessage)IDirectPlayLobbyWImpl_SendLobbyMessage,
+  XCAST(SetConnectionSettings)IDirectPlayLobbyWImpl_SetConnectionSettings,
+  XCAST(SetLobbyMessageEvent)IDirectPlayLobbyWImpl_SetLobbyMessageEvent,
+
+  IDirectPlayLobby2WImpl_CreateCompoundAddress
+};
+#undef XCAST
+
+/* Direct Play Lobby 3 (ascii) Virtual Table for methods */
+
+/* Note: Hack so we can reuse the old functions without compiler warnings */
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(directPlayLobby3AVT.fn##fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+static ICOM_VTABLE(IDirectPlayLobby3) directPlayLobby3AVT =
+{
+  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+  IDirectPlayLobby3AImpl_QueryInterface,
+  XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
+  XCAST(Release)IDirectPlayLobbyAImpl_Release,
+
+  XCAST(Connect)IDirectPlayLobbyAImpl_Connect,
+  XCAST(CreateAddress)IDirectPlayLobbyAImpl_CreateAddress,
+  XCAST(EnumAddress)IDirectPlayLobbyAImpl_EnumAddress,
+  XCAST(EnumAddressTypes)IDirectPlayLobbyAImpl_EnumAddressTypes,
+  XCAST(EnumLocalApplications)IDirectPlayLobbyAImpl_EnumLocalApplications,
+  XCAST(GetConnectionSettings)IDirectPlayLobbyAImpl_GetConnectionSettings,
+  XCAST(ReceiveLobbyMessage)IDirectPlayLobbyAImpl_ReceiveLobbyMessage,
+  XCAST(RunApplication)IDirectPlayLobbyAImpl_RunApplication,
+  XCAST(SendLobbyMessage)IDirectPlayLobbyAImpl_SendLobbyMessage,
+  XCAST(SetConnectionSettings)IDirectPlayLobbyAImpl_SetConnectionSettings,
+  XCAST(SetLobbyMessageEvent)IDirectPlayLobbyAImpl_SetLobbyMessageEvent,
+
+  XCAST(CreateCompoundAddress)IDirectPlayLobby2AImpl_CreateCompoundAddress,
+
+  IDirectPlayLobby3AImpl_ConnectEx,
+  IDirectPlayLobby3AImpl_RegisterApplication,
+  IDirectPlayLobby3AImpl_UnregisterApplication,
+  IDirectPlayLobby3AImpl_WaitForConnectionSettings
+};
+#undef XCAST
+
+/* Direct Play Lobby 3 (unicode) Virtual Table for methods */
+
+/* Note: Hack so we can reuse the old functions without compiler warnings */
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(directPlayLobby3WVT.fn##fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+static ICOM_VTABLE(IDirectPlayLobby3) directPlayLobby3WVT =
+{
+  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+  IDirectPlayLobby3WImpl_QueryInterface,
+  XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
+  XCAST(Release)IDirectPlayLobbyAImpl_Release,
+
+  XCAST(Connect)IDirectPlayLobbyWImpl_Connect,
+  XCAST(CreateAddress)IDirectPlayLobbyWImpl_CreateAddress,
+  XCAST(EnumAddress)IDirectPlayLobbyWImpl_EnumAddress,
+  XCAST(EnumAddressTypes)IDirectPlayLobbyWImpl_EnumAddressTypes,
+  XCAST(EnumLocalApplications)IDirectPlayLobbyWImpl_EnumLocalApplications,
+  XCAST(GetConnectionSettings)IDirectPlayLobbyWImpl_GetConnectionSettings,
+  XCAST(ReceiveLobbyMessage)IDirectPlayLobbyWImpl_ReceiveLobbyMessage,
+  XCAST(RunApplication)IDirectPlayLobbyWImpl_RunApplication,
+  XCAST(SendLobbyMessage)IDirectPlayLobbyWImpl_SendLobbyMessage,
+  XCAST(SetConnectionSettings)IDirectPlayLobbyWImpl_SetConnectionSettings,
+  XCAST(SetLobbyMessageEvent)IDirectPlayLobbyWImpl_SetLobbyMessageEvent,
+
+  XCAST(CreateCompoundAddress)IDirectPlayLobby2WImpl_CreateCompoundAddress,
+
+  IDirectPlayLobby3WImpl_ConnectEx,
+  IDirectPlayLobby3WImpl_RegisterApplication,
+  IDirectPlayLobby3WImpl_UnregisterApplication,
+  IDirectPlayLobby3WImpl_WaitForConnectionSettings
+};
+#undef XCAST
+
+
+/*********************************************************
+ *
+ * Direct Play and Direct Play Lobby Interface Implementation 
+ * 
+ *********************************************************/ 
+
+/***************************************************************************
+ *  DirectPlayLobbyCreateA   (DPLAYX.4)
+ *
+ */
+HRESULT WINAPI DirectPlayLobbyCreateA( LPGUID lpGUIDDSP,
+                                       LPDIRECTPLAYLOBBYA *lplpDPL,
+                                       IUnknown *lpUnk, 
+                                       LPVOID lpData,
+                                       DWORD dwDataSize )
+{
+  TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
+        lpGUIDDSP,lplpDPL,lpUnk,lpData,dwDataSize);
+
+  /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
+   * equal 0. These fields are mostly for future expansion.
+   */
+  if ( lpGUIDDSP || lpUnk || lpData || dwDataSize )
+  {
+     *lplpDPL = NULL;
+     return DPERR_INVALIDPARAMS;
+  }
+
+  return directPlayLobby_QueryInterface( &IID_IDirectPlayLobbyA, (void**)lplpDPL ); 
+}
+
+/***************************************************************************
+ *  DirectPlayLobbyCreateW   (DPLAYX.5)
+ *
+ */
+HRESULT WINAPI DirectPlayLobbyCreateW( LPGUID lpGUIDDSP, 
+                                       LPDIRECTPLAYLOBBY *lplpDPL,
+                                       IUnknown *lpUnk,
+                                       LPVOID lpData, 
+                                       DWORD dwDataSize )
+{
+  TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
+        lpGUIDDSP,lplpDPL,lpUnk,lpData,dwDataSize);
+
+  /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must 
+   * equal 0. These fields are mostly for future expansion.
+   */
+  if ( lpGUIDDSP || lpUnk || lpData || dwDataSize )
+  {
+     *lplpDPL = NULL;
+     ERR("Bad parameters!\n" );
+     return DPERR_INVALIDPARAMS;
+  }
+
+  return directPlayLobby_QueryInterface( &IID_IDirectPlayLobby, (void**)lplpDPL );  
+
+}
diff --git a/documentation/status/directplay b/documentation/status/directplay
index 6e7f1e9..cbad076 100644
--- a/documentation/status/directplay
+++ b/documentation/status/directplay
@@ -5,18 +5,74 @@
 to see what has been implemented.  Stay tuned for some information here once
 there is more implementation (and I figure out what the heck I'm doing).
 
-The files are include/dplay.h and multimedia/dplay.c. They're getting a 
-little cumbersome at present perhaps they will be broken out in a later
-version.
+The files are include/dplay.h, include/dplobby.h, multimedia/dplobby.c and multimedia/dplay.c. 
+The .c files will be moved to appropriate dll directories at some later time.
 
 I think I can safely say that any application which requires direct play
 or direct play lobby will not work at this point. Priority will be to get
-lserver.exe from the sdk running.
+examples from the sdk running. Once they're at least partially working, I can
+get down to trying to get some of the games working.
 
+A small issue will be the fact that DirectX 6.1(ie. DirectPlay4) introduces a layer of functionality
+inside the DP objects which provide guaranteed protocol delivery. This is
+even if the native protocol, IPX or modem for instance, doesn't guarantee it. I'm going to leave
+this kind of implementation to as close to the end as possible. However, I
+will implement an abstraction layer, where possible, for this functionality. 
+It will do nothing to start, but will require only the implementation of the 
+guaranteness to give final implementation.
 
 
 TODO:
-  - Just about everything
+  - (done) Header files for DP4 and DPL3 
+  - (done) Add stub functions for all DP4 and DPL3 interfaces
+  - (done) Correct naming of the parameters for DP3 and DPL2
+  - (done) Seperate out DP and DPL into multiple .c files
+  - (done) Allow CoCreateInstance to create the new interfaces
+  - (started)Implement mutual exclusion on object data for existing functions
+  - (done) Create and move to correct dll directories (dplay and dplayx)
+  - (done) Implement dplay in terms of dplayx
+  - (started) Need a better internal implementation for the objects which scales and 
+    preferably doesn't involve casting structures
+  - (started) More generic initialization and destruction helper methods based off
+    the chosen internal implementation
+  - How to deal with all the incorrect interfaces for IUnknown methods. The standard
+    wine macros are incorrect in that they always give IUnknown* rather than DirectPlayLobby2A
+    for instance. Are we forced to cast?
+  - Implement a lib main for the dplayx dll
+  - Ensure that all dll stubs are present and the ordinals are correct
+  - Implementation of functionality
+  - bug fixes ;)
 
+Programs to make work:
+  - lserver.exe (from sdk)
+  - override.exe (from sdk)
+  - dpchat.exe (from sdk)
+  - duel.exe (from sdk)
 
-Peter Hunnisett  -  hunnise@nortel.ca
+Next API to implement on a per program basis:
+  override.exe
+  - IDirectPlay3AImp_EnumConnections
+  - ?
+
+  dplaunch.exe
+  - IDirectPlayLobbyAImpl_EnumLocalApplications
+  - ?
+
+  lserver.exe
+  - IDirectPlayLobby2WImpl_Connect 
+  - IDirectPlay3WImpl_CreatePlayer 
+  - IDirectPlay3WImpl_CreateGroup
+  - IDirectPlay3WImpl_SetGroupData
+  - IDirectPlay3WImpl_Send
+  - ?
+ 
+  bellhop.exe
+  - DirectPlay3AImpl_EnumConnections
+  - ?
+
+  dpslots.exe
+  - IDirectPlayLobbyAImpl_SetConnectionSettings
+  - IDirectPlayAImpl_EnumConnections 
+  - ?
+   
+Peter Hunnisett  -  hunnise@nortelnetworks.com
diff --git a/include/dplay.h b/include/dplay.h
index 54d359b..272a50c 100644
--- a/include/dplay.h
+++ b/include/dplay.h
@@ -1,6 +1,10 @@
 #ifndef __WINE_DPLAY_H
 #define __WINE_DPLAY_H
 
+/* FIXME: GCC doesn't yet support annon structures so some of the structures defined here don't match the sdk exactly.
+ * I've tried to come up with suitably terse names, but this file won't cut it for inclusion into a WineLib app.
+ */
+
 #include "wine/obj_base.h"
 
 #ifdef __cplusplus
@@ -29,6 +33,13 @@
 DEFINE_GUID(IID_IDirectPlay3A,0x133efe41, 0x32dc, 0x11d0, 0x9c, 0xfb, 0x0, 0xa0, 0xc9, 0xa, 0x43, 0xcb);
 typedef struct IDirectPlay3 IDirectPlay3A,*LPDIRECTPLAY3A;
 
+DEFINE_GUID(IID_IDirectPlay4, 0xab1c530, 0x4745, 0x11d1, 0xa7, 0xa1, 0x0, 0x0, 0xf8, 0x3, 0xab, 0xfc);
+typedef struct IDirectPlay4 IDirectPlay4,*LPDIRECTPLAY4;
+
+DEFINE_GUID(IID_IDirectPlay4A,0xab1c531, 0x4745, 0x11d1, 0xa7, 0xa1, 0x0, 0x0, 0xf8, 0x3, 0xab, 0xfc);
+typedef struct IDirectPlay4 IDirectPlay4A,*LPDIRECTPLAY4A;
+
+
 /*
  * GUIDS used by Service Providers shipped with DirectPlay
  * Use these to identify Service Provider returned by EnumConnections
@@ -37,7 +48,7 @@
 /* GUID for IPX service provider {685BC400-9D2C-11cf-A9CD-00AA006886E3} */
 DEFINE_GUID(DPSPGUID_IPX, 0x685bc400, 0x9d2c, 0x11cf, 0xa9, 0xcd, 0x0, 0xaa, 0x0, 0x68, 0x86, 0xe3);
 
-/* GUID for TCP/IP service provider 36E95EE0-8577-11cf-960C-0080C7534E82 */
+/* GUID for TCP/IP service provider {36E95EE0-8577-11cf-960C-0080C7534E82} */
 DEFINE_GUID(DPSPGUID_TCPIP, 0x36E95EE0, 0x8577, 0x11cf, 0x96, 0xc, 0x0, 0x80, 0xc7, 0x53, 0x4e, 0x82);
 
 /* GUID for Serial service provider {0F1D6860-88D9-11cf-9C4E-00A0C905425E} */
@@ -96,6 +107,13 @@
 #define DPERR_NONEWPLAYERS              MAKE_DPHRESULT( 330 )
 #define DPERR_INVALIDPASSWORD           MAKE_DPHRESULT( 340 )
 #define DPERR_CONNECTING                MAKE_DPHRESULT( 350 )
+#define DPERR_CONNECTIONLOST            MAKE_DPHRESULT( 360 )
+#define DPERR_UNKNOWNMESSAGE            MAKE_DPHRESULT( 370 )
+#define DPERR_CANCELFAILED              MAKE_DPHRESULT( 380 )
+#define DPERR_INVALIDPRIORITY           MAKE_DPHRESULT( 390 )
+#define DPERR_NOTHANDLED                MAKE_DPHRESULT( 400 )
+#define DPERR_CANCELLED                 MAKE_DPHRESULT( 410 )
+#define DPERR_ABORTED                   MAKE_DPHRESULT( 420 )
 #define DPERR_BUFFERTOOLARGE            MAKE_DPHRESULT( 1000 )
 #define DPERR_CANTCREATEPROCESS         MAKE_DPHRESULT( 1010 )
 #define DPERR_APPNOTSTARTED             MAKE_DPHRESULT( 1020 )
@@ -106,15 +124,15 @@
 #define DPERR_SERVICEPROVIDERLOADED     MAKE_DPHRESULT( 1080 )
 #define DPERR_ALREADYREGISTERED         MAKE_DPHRESULT( 1090 )
 #define DPERR_NOTREGISTERED             MAKE_DPHRESULT( 1100 )
-#define DPERR_AUTHENTICATIONFAILED      MAKE_DPHRESULT(  2000 )
-#define DPERR_CANTLOADSSPI              MAKE_DPHRESULT(  2010 )
-#define DPERR_ENCRYPTIONFAILED          MAKE_DPHRESULT(  2020 )
-#define DPERR_SIGNFAILED                MAKE_DPHRESULT(  2030 )
-#define DPERR_CANTLOADSECURITYPACKAGE   MAKE_DPHRESULT(  2040 )
-#define DPERR_ENCRYPTIONNOTSUPPORTED    MAKE_DPHRESULT(  2050 )
-#define DPERR_CANTLOADCAPI              MAKE_DPHRESULT(  2060 )
-#define DPERR_NOTLOGGEDIN               MAKE_DPHRESULT(  2070 )
-#define DPERR_LOGONDENIED               MAKE_DPHRESULT(  2080 )
+#define DPERR_AUTHENTICATIONFAILED      MAKE_DPHRESULT( 2000 )
+#define DPERR_CANTLOADSSPI              MAKE_DPHRESULT( 2010 )
+#define DPERR_ENCRYPTIONFAILED          MAKE_DPHRESULT( 2020 )
+#define DPERR_SIGNFAILED                MAKE_DPHRESULT( 2030 )
+#define DPERR_CANTLOADSECURITYPACKAGE   MAKE_DPHRESULT( 2040 )
+#define DPERR_ENCRYPTIONNOTSUPPORTED    MAKE_DPHRESULT( 2050 )
+#define DPERR_CANTLOADCAPI              MAKE_DPHRESULT( 2060 )
+#define DPERR_NOTLOGGEDIN               MAKE_DPHRESULT( 2070 )
+#define DPERR_LOGONDENIED               MAKE_DPHRESULT( 2080 )
 
 
 /* DPID - DirectPlay player and group ID */
@@ -589,6 +607,364 @@
 #define IDirectPlay3_GetPlayerFlags(p,a,b)                 ICOM_CALL2(GetPlayerFlags,p,a,b)
 #endif
 
+/*****************************************************************************
+ * IDirectPlay4 interface - this is also known as IDirectPlayX. Apparently people
+ * are realizing that declaring all the darn interfaces as IDirectPlay{2,3,...} is
+ * just plain dumb. It's now going to be just IDirectPlayX since they're just macros
+ * anyways. That's good because I'm tired of typing these entries :)
+ * The compiler should catch any problems with invocation of invalid method :)
+ */
+#define ICOM_INTERFACE IDirectPlay4
+#define IDirectPlay4_METHODS \
+    ICOM_METHOD2( HRESULT, GetGroupOwner,        DPID,, LPDPID, ) \
+    ICOM_METHOD2( HRESULT, SetGroupOwner,        DPID,, DPID, ) \
+    ICOM_METHOD9( HRESULT, SendEx,               DPID,, DPID,, DWORD,, LPVOID,, DWORD,, DWORD,, DWORD,, LPVOID,, LPDWORD, ) \
+    ICOM_METHOD5( HRESULT, GetMessageQueue,      DPID,, DPID,, DWORD,, LPDWORD,, LPDWORD, ) \
+    ICOM_METHOD2( HRESULT, CancelMessage,        DWORD,, DWORD, ) \
+    ICOM_METHOD3( HRESULT, CancelPriority,       DWORD,, DWORD,, DWORD, )
+
+#define IDirectPlay4_IMETHODS
+    IDirectPlay3_IMETHODS \
+    IDirectPlay4_METHODS 
+ICOM_DEFINE(IDirectPlay4,IDirectPlay3)
+
+#undef ICOM_INTERFACE
+
+#ifdef ICOM_CINTERFACE
+/*** IUnknown methods ***/
+#define IDirectPlayX_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
+#define IDirectPlayX_AddRef(p)             ICOM_CALL (AddRef,p)
+#define IDirectPlayX_Release(p)            ICOM_CALL (Release,p)
+/*** IDirectPlay2 methods ***/
+#define IDirectPlayX_AddPlayerToGroup(p,a,b)       ICOM_CALL2(AddPlayerToGroup,p,a,b)
+#define IDirectPlayX_Close(p)                      ICOM_CALL (Close,p)
+#define IDirectPlayX_CreateGroup(p,a,b,c,d,e)      ICOM_CALL5(CreateGroup,p,a,b,c,d,e)
+#define IDirectPlayX_CreatePlayer(p,a,b,c,d,e,f)   ICOM_CALL6(CreatePlayer,p,a,b,c,d,e,f)
+#define IDirectPlayX_DeletePlayerFromGroup(p,a,b)  ICOM_CALL2(DeletePlayerFromGroup,p,a,b)
+#define IDirectPlayX_DestroyGroup(p,a)             ICOM_CALL1(DestroyGroup,p,a)
+#define IDirectPlayX_DestroyPlayer(p,a)            ICOM_CALL1(DestroyPlayer,p,a)
+#define IDirectPlayX_EnumGroupPlayers(p,a,b,c,d,e) ICOM_CALL5(EnumGroupPlayers,p,a,b,c,d,e)
+#define IDirectPlayX_EnumGroups(p,a,b,c,d)         ICOM_CALL4(EnumGroups,p,a,b,c,d)
+#define IDirectPlayX_EnumPlayers(p,a,b,c,d)        ICOM_CALL4(EnumPlayers,p,a,b,c,d)
+#define IDirectPlayX_EnumSessions(p,a,b,c,d,e)     ICOM_CALL5(EnumSessions,p,a,b,c,d,e)
+#define IDirectPlayX_GetCaps(p,a,b)                ICOM_CALL2(GetCaps,p,a,b)
+#define IDirectPlayX_GetGroupData(p,a,b,c,d)       ICOM_CALL4(GetGroupData,p,a,b,c,d)
+#define IDirectPlayX_GetGroupName(p,a,b,c)         ICOM_CALL3(GetGroupName,p,a,b,c)
+#define IDirectPlayX_GetMessageCount(p,a,b)        ICOM_CALL2(GetMessageCount,p,a,b)
+#define IDirectPlayX_GetPlayerAddress(p,a,b,c)     ICOM_CALL3(GetPlayerAddress,p,a,b,c)
+#define IDirectPlayX_GetPlayerCaps(p,a,b,c)        ICOM_CALL3(GetPlayerCaps,p,a,b,c)
+#define IDirectPlayX_GetPlayerData(p,a,b,c,d)      ICOM_CALL4(GetPlayerData,p,a,b,c,d)
+#define IDirectPlayX_GetPlayerName(p,a,b,c)        ICOM_CALL3(GetPlayerName,p,a,b,c)
+#define IDirectPlayX_GetSessionDesc(p,a,b)         ICOM_CALL2(GetSessionDesc,p,a,b)
+#define IDirectPlayX_Initialize(p,a)               ICOM_CALL1(Initialize,p,a)
+#define IDirectPlayX_Open(p,a,b)                   ICOM_CALL2(Open,p,a,b)
+#define IDirectPlayX_Receive(p,a,b,c,d,e)          ICOM_CALL5(Receive,p,a,b,c,d,e)
+#define IDirectPlayX_Send(p,a,b,c,d,e)             ICOM_CALL5(Send,p,a,b,c,d,e)
+#define IDirectPlayX_SetGroupData(p,a,b,c,d)       ICOM_CALL4(SetGroupData,p,a,b,c,d)
+#define IDirectPlayX_SetGroupName(p,a,b,c)         ICOM_CALL3(SetGroupName,p,a,b,c)
+#define IDirectPlayX_SetPlayerData(p,a,b,c,d)      ICOM_CALL4(SetPlayerData,p,a,b,c,d)
+#define IDirectPlayX_SetPlayerName(p,a,b,c)        ICOM_CALL3(SetPlayerName,p,a,b,c)
+#define IDirectPlayX_SetSessionDesc(p,a,b)         ICOM_CALL2(SetSessionDesc,p,a,b)
+/*** IDirectPlay3 methods ***/
+#define IDirectPlayX_AddGroupToGroup(p,a,b)                ICOM_CALL2(AddGroupToGroup,p,a,b)
+#define IDirectPlayX_CreateGroupInGroup(p,a,b,c,d,e,f)     ICOM_CALL6(CreateGroupInGroup,p,a,b,c,d,e,f)
+#define IDirectPlayX_DeleteGroupFromGroup(p,a,b)           ICOM_CALL2(DeleteGroupFromGroup,p,a,b)
+#define IDirectPlayX_EnumConnections(p,a,b,c,d)            ICOM_CALL4(EnumConnections,p,a,b,c,d)
+#define IDirectPlayX_EnumGroupsInGroup(p,a,b,c,d,e)        ICOM_CALL5(EnumGroupsInGroup,p,a,b,c,d,e)
+#define IDirectPlayX_GetGroupConnectionSettings(p,a,b,c,d) ICOM_CALL4(GetGroupConnectionSettings,p,a,b,c,d)
+#define IDirectPlayX_InitializeConnection(p,a,b)           ICOM_CALL2(InitializeConnection,p,a,b)
+#define IDirectPlayX_SecureOpen(p,a,b,c,d)                 ICOM_CALL4(SecureOpen,p,a,b,c,d)
+#define IDirectPlayX_SendChatMessage(p,a,b,c,d)            ICOM_CALL4(SendChatMessage,p,a,b,c,d)
+#define IDirectPlayX_SetGroupConnectionSettings(p,a,b,c)   ICOM_CALL3(SetGroupConnectionSettings,p,a,b,c)
+#define IDirectPlayX_StartSession(p,a,b)                   ICOM_CALL2(StartSession,p,a,b)
+#define IDirectPlayX_GetGroupFlags(p,a,b)                  ICOM_CALL2(GetGroupFlags,p,a,b)
+#define IDirectPlayX_GetGroupParent(p,a,b)                 ICOM_CALL2(GetGroupParent,p,a,b)
+#define IDirectPlayX_GetPlayerAccount(p,a,b,c,d)           ICOM_CALL4(GetPlayerAccount,p,a,b,c,d)
+#define IDirectPlayX_GetPlayerFlags(p,a,b)                 ICOM_CALL2(GetPlayerFlags,p,a,b)
+/*** IDirectPlay4 methods ***/
+#define IDirectPlayX_GetGroupOwner(p,a,b)                  ICOM_CALL2(GetGroupOwner,p,a,b)
+#define IDirectPlayX_SetGroupOwner(p,a,b)                  ICOM_CALL2(SetGroupOwner,p,a,b)
+#define IDirectPlayX_SendEx(p,a,b,c,d,e,f,g,h,i)           ICOM_CALL9(SendEx,a,b,c,d,e,f,g,h,i)
+#define IDirectPlayX_GetMessageQueue(p,a,b,c,d,e)          ICOM_CALL5(GetMessageQueue,a,b,c,d,e)
+#define IDirectPlayX_CancelMessage(p,a,b)                  ICOM_CALL2(CancelMessage,a,b)
+#define IDirectPlayX_CancelPriority(p,a,b,c)               ICOM_CALL3(CancelPriority,a,b,c)
+
+#endif
+
+/* For DirectPlay::EnumConnections */
+#define DPCONNECTION_DIRECTPLAY      0x00000001
+#define DPCONNECTION_DIRECTPLAYLOBBY 0x00000002
+
+/* For DirectPlay::EnumPlayers and DirectPlay::EnumGroups */
+#define DPENUMPLAYERS_ALL           0x00000000
+#define DPENUMPLAYERS_LOCAL         0x00000008
+#define DPENUMPLAYERS_REMOTE        0x00000010
+#define DPENUMPLAYERS_GROUP         0x00000020
+#define DPENUMPLAYERS_SESSION       0x00000080
+#define DPENUMPLAYERS_SERVERPLAYER  0x00000100
+#define DPENUMPLAYERS_SPECTATOR     0x00000200
+#define DPENUMPLAYERS_OWNER         0x00002000
+
+#define DPENUMGROUPS_ALL            DPENUMPLAYERS_ALL
+#define DPENUMGROUPS_LOCAL          DPENUMPLAYERS_LOCAL
+#define DPENUMGROUPS_REMOTE         DPENUMPLAYERS_REMOTE
+#define DPENUMGROUPS_SESSION        DPENUMPLAYERS_SESSION
+#define DPENUMGROUPS_SHORTCUT       0x00000400
+#define DPENUMGROUPS_STAGINGAREA    0x00000800
+#define DPENUMGROUPS_HIDDEN         0x00001000
+
+
+/* For DirectPlay::CreatePlayer */ 
+#define DPPLAYER_SERVERPLAYER  DPENUMPLAYERS_SERVERPLAYER
+#define DPPLAYER_SPECTATOR     DPENUMPLAYERS_SPECTATOR
+#define DPPLAYER_LOCAL         DPENUMPLAYERS_LOCAL
+#define DPPLAYER_OWNER         DPENUMPLAYERS_OWNER
+
+/* For DirectPlay::CreateGroup */
+#define DPGROUP_STAGINGAREA  DPENUMGROUPS_STAGINGAREA
+#define DPGROUP_LOCAL        DPENUMGROUPS_LOCAL
+#define DPGROUP_HIDDEN       DPENUMGROUPS_HIDDEN
+
+/* For DirectPlay::EnumSessions */
+#define DPENUMSESSIONS_AVAILABLE         0x00000001
+#define DPENUMSESSIONS_ALL               0x00000002
+#define DPENUMSESSIONS_ASYNC             0x00000010
+#define DPENUMSESSIONS_STOPASYNC         0x00000020
+#define DPENUMSESSIONS_PASSWORDREQUIRED  0x00000040
+#define DPENUMSESSIONS_RETURNSTATUS      0x00000080
+
+/* For DirectPlay::GetCaps and DirectPlay::GetPlayerCaps */
+#define DPGETCAPS_GUARANTEED  0x00000001
+
+/* For DirectPlay::GetGroupData and DirectPlay::GetPlayerData */
+#define DPGET_REMOTE  0x00000000
+#define DPGET_LOCAL   0x00000001
+
+/* For DirectPlay::Receive */
+#define DPRECEIVE_ALL         0x00000001
+#define DPRECEIVE_TOPLAYER    0x00000002
+#define DPRECEIVE_FROMPLAYER  0x00000004
+#define DPRECEIVE_PEEK        0x00000008
+
+/* For DirectPlay::Send */
+#define DPSEND_NONGUARANTEED       0x00000000
+#define DPSEND_GUARANTEED          0x00000001
+#define DPSEND_HIGHPRIORITY        0x00000002
+#define DPSEND_OPENSTREAM          0x00000008
+#define DPSEND_CLOSESTREAM         0x00000010
+#define DPSEND_SIGNED              0x00000020
+#define DPSEND_ENCRYPTED           0x00000040
+#define DPSEND_LOBBYSYSTEMMESSAGE  0x00000080
+#define DPSEND_ASYNC               0x00000200
+#define DPSEND_NOSENDCOMPLETEMSG   0x00000400
+
+#define DPSEND_MAX_PRI       0x0000FFFF
+#define DPSEND_MAX_PRIORITY  DPSEND_MAX_PRI
+
+
+/* For  DirectPlay::SetGroupData, DirectPlay::SetGroupName, 
+ * DirectPlay::SetPlayerData, DirectPlay::SetPlayerName and 
+ * DirectPlay::SetSessionDesc.
+ */
+#define DPSET_REMOTE      0x00000000
+#define DPSET_LOCAL       0x00000001
+#define DPSET_GUARANTEED  0x00000002
+
+/* For DirectPlay::GetMessageQueue */
+#define DPMESSAGEQUEUE_SEND    0x00000001
+#define DPMESSAGEQUEUE_RECEIVE 0x00000002
+
+/* DirectPlay::Connect */
+#define DPCONNECT_RETURNSTATUS  (DPENUMSESSIONS_RETURNSTATUS)
+
+
+/** DirectPlay system messages **/
+
+/* A new player or group has been created in the session */
+#define DPSYS_CREATEPLAYERORGROUP   0x0003
+
+/* A player or group has been deleted from the session */
+#define DPSYS_DESTROYPLAYERORGROUP  0x0005
+
+/* A player has been added to a group */
+#define DPSYS_ADDPLAYERTOGROUP      0x0007
+
+/* A player has been deleted from a group */
+#define DPSYS_DELETEPLAYERFROMGROUP 0x0021
+
+/* Session lost for this object - ie lost contact with all players */
+#define DPSYS_SESSIONLOST           0x0031
+
+/* The current host has left the session */
+#define DPSYS_HOST                  0x0101
+
+/* Player or group data has changed */
+#define DPSYS_SETPLAYERORGROUPDATA  0x0102
+
+/* The name of a player or group has changed */
+#define DPSYS_SETPLAYERORGROUPNAME  0x0103
+
+/* The session description has changed */
+#define DPSYS_SETSESSIONDESC        0x0104
+
+/* A group has been added to a group */
+#define DPSYS_ADDGROUPTOGROUP           0x0105
+
+/* A group has been deleted from a group */
+#define DPSYS_DELETEGROUPFROMGROUP      0x0106
+
+/* A secure player to player message has arrived */
+#define DPSYS_SECUREMESSAGE         0x0107
+
+/* Start a new session */
+#define DPSYS_STARTSESSION          0x0108
+
+/* A chat message has arrived */
+#define DPSYS_CHAT                  0x0109
+
+/* The owner of a group has changed */
+#define DPSYS_SETGROUPOWNER         0x010A
+
+/* An async send is done (finished normally, failed or cancelled) */
+#define DPSYS_SENDCOMPLETE          0x010d
+
+/** DirectPlay System Messages **/ 
+
+#define DPPLAYERTYPE_GROUP   0x00000000
+#define DPPLAYERTYPE_PLAYER  0x00000001
+
+
+/* NOTE: DPMSG_HOST and DPMSG_GENERIC share the same format */
+typedef struct tagDPMSG_GENERIC
+{
+   DWORD       dwType; /* Use message type as described above */
+} DPMSG_GENERIC,     *LPDPMSG_GENERIC, 
+  DPMSG_HOST,        *LPDPMSG_HOST,
+  DPMSG_SESSIONLOST, *LPDPMSG_SESSIONLOST;
+
+typedef struct tagDPMSG_CREATEPLAYERORGROUP
+{
+   DWORD   dwType;           /* Use message type as described above */
+   DWORD   dwPlayerType;     /* Use DPPLAYERTYPE_GROUP or DPPLAYERTYPE_PLAYER */
+   DPID    dpId;             /* ID of the player/group */
+   DWORD   dwCurrentPlayers; /* Current number of players/groups in session */
+   LPVOID  lpData;           /* Pointer to data */
+   DWORD   dwDataSize;       /* Size of data */
+   DPNAME  dpnName;          /* Name info */
+
+   /* dpIdParent and dwFlags are only valid in DirectPlay3 and later. What
+    * does that mean about the message size before? -PH */ 
+   DPID   dpIdParent;  /* id of parent group */
+   DWORD  dwFlags;     /* Flags for the player/group */ 
+} DPMSG_CREATEPLAYERORGROUP, *LPDPMSG_CREATEPLAYERORGROUP;
+
+typedef struct tagDPMSG_DESTROYPLAYERORGROUP
+{
+   DWORD   dwType;           /* Use message type as described above */
+   DWORD   dwPlayerType;     /* Use DPPLAYERTYPE_GROUP or DPPLAYERTYPE_PLAYER */
+   DPID    dpId;             /* ID of player/group to be deleted */
+   LPVOID  lpLocalData;      /* Pointer to local data */
+   DWORD   dwLocalDataSize;  /* Sizeof local data */
+   LPVOID  lpRemoteData;     /* Pointer to remote data */
+   DWORD   dwRemoteDataSize; /* Sizeof remote data */
+
+   /* dpnName, dpIdParent and dwFlags are only valid in DirectPlay3 and later. What
+    * does that mean about the message size before? -PH */
+   DPNAME  dpnName;     /* Name info */
+   DPID    dpIdParent;  /* id of parent group */
+   DWORD   dwFlags;     /* Flags for the player/group */
+} DPMSG_DESTROYPLAYERORGROUP, *LPDPMSG_DESTROYPLAYERORGROUP;
+
+/* NOTE: DPMSG_ADDPLAYERTOGROUP and DPMSG_DELETEPLAYERFROMGROUP are the same */
+typedef struct tagDPMSG_ADDPLAYERTOGROUP
+{
+   DWORD  dwType;      /* Use message type as described above */
+   DPID   dpIdGroup;   /* Group ID to add player into */
+   DPID   dpIdPlayer;  /* ID of player to add */
+} DPMSG_ADDPLAYERTOGROUP,      *LPDPMSG_ADDPLAYERTOGROUP, 
+  DPMSG_DELETEPLAYERFROMGROUP, *LPDPMSG_DELETEPLAYERFROMGROUP; 
+
+/* NOTE: DPMSG_ADDGROUPTOGROUP and DPMSG_DELETEGROUPFROMGROUP are the same */
+typedef struct tagDPMSG_ADDGROUPTOGROUP
+{
+   DWORD  dwType;          /* Use message type as described above */
+   DPID   dpIdParentGroup; /* Group ID to add group into */
+   DPID   dpIdGroup;       /* ID of group to add */
+} DPMSG_ADDGROUPTOGROUP,      *LPDPMSG_ADDGROUPTOGROUP,
+  DPMSG_DELETEGROUPFROMGROUP, *LPDPMSG_DELETEGROUPFROMGROUP;
+
+typedef struct tagDPMSG_SETPLAYERORGROUPDATA
+{
+   DWORD   dwType;       /* Use message type as described above */
+   DWORD   dwPlayerType; /* Use DPPLAYERTYPE_GROUP or DPPLAYERTYPE_PLAYER */ 
+   DPID    dpId;         /* ID of player/group */
+   LPVOID  lpData;       /* Pointer to data */
+   DWORD   dwDataSize;   /* Size of data */
+} DPMSG_SETPLAYERORGROUPDATA, *LPDPMSG_SETPLAYERORGROUPDATA;
+
+typedef struct tagDPMSG_SETPLAYERORGROUPNAME
+{
+   DWORD  dwType;       /* Use message type as described above */
+   DWORD  dwPlayerType; /* Use DPPLAYERTYPE_GROUP or DPPLAYERTYPE_PLAYER */
+   DPID   dpId;         /* ID of player/group */
+   DPNAME dpnName;      /* New name */
+} DPMSG_SETPLAYERORGROUPNAME, *LPDPMSG_SETPLAYERORGROUPNAME;
+
+typedef struct tagDPMSG_SETSESSIONDESC
+{
+   DWORD           dwType; /* Use message type as described above */
+   DPSESSIONDESC2  dpDesc; /* New session desc */
+} DPMSG_SETSESSIONDESC, *LPDPMSG_SETSESSIONDESC;
+
+typedef struct tagDPMSG_SECUREMESSAGE
+{
+   DWORD   dwType;     /* Use message type as described above */
+   DWORD   dwFlags;    /* Signed/Encrypted */
+   DPID    dpIdFrom;   /* ID of from player */
+   LPVOID  lpData;     /* Message sent */
+   DWORD   dwDataSize; /* Size of message */
+} DPMSG_SECUREMESSAGE, *LPDPMSG_SECUREMESSAGE;
+
+typedef struct tagDPMSG_STARTSESSION
+{
+   DWORD            dwType; /* Use message type as described above */
+   LPDPLCONNECTION  lpConn; /* DPLCONNECTION structure */
+} DPMSG_STARTSESSION, *LPDPMSG_STARTSESSION;
+
+typedef struct tagDPMSG_CHAT
+{
+   DWORD     dwType;       /* Use message type as described above */
+   DWORD     dwFlags;      /* Message flags */
+   DPID      idFromPlayer; /* ID of sender */
+   DPID      idToPlayer;   /* ID of who msg is for */
+   DPID      idToGroup;    /* ID of what group msg is for */
+   LPDPCHAT  lpChat;       /* Chat message */
+} DPMSG_CHAT, *LPDPMSG_CHAT;
+
+typedef struct tagDPMSG_SETGROUPOWNER
+{
+   DWORD  dwType;     /* Use message type as described above */
+   DPID   idGroup;    /* Group ID */
+   DPID   idNewOwner; /* ID of player who now owns group */
+   DPID   idOldOwner; /* ID of player who used to own group */
+} DPMSG_SETGROUPOWNER, *LPDPMSG_SETGROUPOWNER;
+
+typedef struct
+{
+   DWORD    dwType;      /* Use message type as described above */
+   DPID     idFrom;      /* ID from */
+   DPID     idTo;        /* ID to */ 
+   DWORD    dwFlags;    
+   DWORD    dwPriority;
+   DWORD    dwTimeout;
+   LPVOID   lpvContext;
+   DWORD    dwMsgID;
+   HRESULT  hr;
+   DWORD    dwSendTime;  /* When sent ? */ 
+} DPMSG_SENDCOMPLETE, *LPDPMSG_SENDCOMPLETE;
+
+
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif /* defined(__cplusplus) */
diff --git a/include/dplobby.h b/include/dplobby.h
index 41944b7..1ce2d18 100644
--- a/include/dplobby.h
+++ b/include/dplobby.h
@@ -1,6 +1,10 @@
 #ifndef __WINE_DPLOBBY_H
 #define __WINE_DPLOBBY_H
 
+/* FIXME: GCC doesn't yet support annon structures so some of the structures defined here don't match the sdk exactly. 
+ * I've tried to come up with suitably terse names, but this file won't cut it for inclusion into a WineLib app.
+ */
+
 #include "dplay.h"
 
 #ifdef __cplusplus
@@ -26,8 +30,238 @@
 DEFINE_GUID(IID_IDirectPlayLobby2A, 0x1bb4af80, 0xa303, 0x11d0, 0x9c, 0x4f, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
 typedef struct IDirectPlayLobby2 IDirectPlayLobby2A, *LPDIRECTPLAYLOBBY2A;
 
+DEFINE_GUID(IID_IDirectPlayLobby3, 0x2db72490, 0x652c, 0x11d1, 0xa7, 0xa8, 0x0, 0x0, 0xf8, 0x3, 0xab, 0xfc);
+typedef struct IDirectPlayLobby3 IDirectPlayLobby3, *LPDIRECTPLAYLOBBY3;
+
+DEFINE_GUID(IID_IDirectPlayLobby3A, 0x2db72491, 0x652c, 0x11d1, 0xa7, 0xa8, 0x0, 0x0, 0xf8, 0x3, 0xab, 0xfc);
+typedef struct IDirectPlayLobby3A IDirectPlayLobby3A, *LPDIRECTPLAYLOBBY3A;
+
 
 /*****************************************************************************
+ * DirectPlayLobby Property GUIDs used in lobby messages
+ */
+
+/* DPLPROPERTY_MessagesSupported {762CCDA1-D916-11d0-BA39-00C04FD7ED67}. 
+ * Purpose: Request if the lobby supports standard (?).
+ * Response: Answer is a BOOL. TRUE if supports the standard (?) and FALSE otherwise. Of course, it might not respond at all.
+ */
+DEFINE_GUID(DPLPROPERTY_MessagesSupported, 0x762ccda1, 0xd916, 0x11d0, 0xba, 0x39, 0x0, 0xc0, 0x4f, 0xd7, 0xed, 0x67);
+
+/* DPLPROPERTY_LobbyGuid {F56920A0-D218-11d0-BA39-00C04FD7ED67}.
+ * Purpose: Request the GUID that identifies the lobby version that the application is communicating with.
+ * Response: The GUID which identifies the lobby version 
+ */
+DEFINE_GUID(DPLPROPERTY_LobbyGuid, 0xf56920a0, 0xd218, 0x11d0, 0xba, 0x39, 0x0, 0xc0, 0x4f, 0xd7, 0xed, 0x67);
+
+/* DPLPROPERTY_PlayerGuid {B4319322-D20D-11d0-BA39-00C04FD7ED67}
+ * Purpose: Request the GUID that identifies the player for this particular machine.
+ * Response: DPLDATA_PLAYERDATA structure.
+ */
+DEFINE_GUID(DPLPROPERTY_PlayerGuid, 0xb4319322, 0xd20d, 0x11d0, 0xba, 0x39, 0x0, 0xc0, 0x4f, 0xd7, 0xed, 0x67);
+
+/* DPLPROPERTY_PlayerScore {48784000-D219-11d0-BA39-00C04FD7ED67}
+ * Purpose: Used to send a score of a player to the lobby. The format is an array of long integers.
+ * Response: I don't think there is one.
+ */
+DEFINE_GUID(DPLPROPERTY_PlayerScore, 0x48784000, 0xd219, 0x11d0, 0xba, 0x39, 0x0, 0xc0, 0x4f, 0xd7, 0xed, 0x67);
+
+
+
+/*****************************************************************************
+ * LOBBY structures associated with GUID messages
+ */
+
+typedef struct tagDPLDATA_PLAYERGUID
+{
+        GUID    guidPlayer;
+        DWORD   dwPlayerFlags;
+} DPLDATA_PLAYERGUID, *LPDPLDATA_PLAYERGUID;
+
+typedef struct tagDPLDATA_PLAYERSCORE
+{
+        DWORD   dwScoreCount;
+        LONG    Score[1];
+} DPLDATA_PLAYERSCORE, *LPDPLDATA_PLAYERSCORE;
+
+
+/*****************************************************************************
+ * LOBBY messages and message data structures.
+ *
+ * System messages can be identified by dwMessageFlags having a value of DPLMSG_SYSTEM
+ * after a call to ReceiveLobbyMessage.
+ *
+ * Standard messages can be indentified by dwMessageFlags having a value of DPLMSG_STANDARD
+ * after a call to ReceiveLobbyMessage.
+ */
+
+/* DPLobby1 definition required for backwards compatibility */
+#define DPLMSG_SYSTEM                                   0x00000001
+#define DPLMSG_STANDARD                                 0x00000002
+#define DPLAD_SYSTEM          DPLMSG_SYSTEM
+
+
+/* System messages  - dwType field for messages */
+#define DPLSYS_CONNECTIONSETTINGSREAD   0x00000001
+#define DPLSYS_DPLAYCONNECTFAILED       0x00000002
+#define DPLSYS_DPLAYCONNECTSUCCEEDED    0x00000003
+#define DPLSYS_APPTERMINATED            0x00000004
+#define DPLSYS_SETPROPERTY              0x00000005
+#define DPLSYS_SETPROPERTYRESPONSE      0x00000006
+#define DPLSYS_GETPROPERTY              0x00000007
+#define DPLSYS_GETPROPERTYRESPONSE      0x00000008
+#define DPLSYS_NEWSESSIONHOST           0x00000009
+#define DPLSYS_NEWCONNECTIONSETTINGS    0x0000000A
+
+
+
+/* Used to indentify the message type */
+typedef struct tagDPLMSG_GENERIC
+{
+    DWORD       dwType;         /* Message type */
+} DPLMSG_GENERIC, *LPDPLMSG_GENERIC;
+
+/* Generic format for system messages - see above */
+typedef struct tagDPLMSG_SYSTEMMESSAGE
+{
+    DWORD       dwType;         /* Message type */
+    GUID        guidInstance;   /* Instance GUID of the dplay session the message corresponds to */
+} DPLMSG_SYSTEMMESSAGE, *LPDPLMSG_SYSTEMMESSAGE;
+
+/* Generic message to set a property - see property GUIDs above */
+typedef struct tagDPLMSG_SETPROPERTY
+{
+        DWORD   dwType;              /* Message type */
+        DWORD   dwRequestID;         /* Request ID (DPL_NOCONFIRMATION if no confirmation desired) */
+        GUID    guidPlayer;          /* Player GUID */
+        GUID    guidPropertyTag;     /* Property GUID */
+        DWORD   dwDataSize;          /* Size of data */
+        DWORD   dwPropertyData[1];   /* Buffer containing data */
+} DPLMSG_SETPROPERTY, *LPDPLMSG_SETPROPERTY;
+
+#define DPL_NOCONFIRMATION                      0L
+
+/* Reply to DPLMSG_SETPROPERTY */
+typedef struct tagDPLMSG_SETPROPERTYRESPONSE
+{
+        DWORD   dwType;              /* Message type */
+        DWORD   dwRequestID;         /* Request ID */
+        GUID    guidPlayer;          /* Player GUID */
+        GUID    guidPropertyTag;     /* Property GUID */
+        HRESULT hr;                  /* Return Code */
+} DPLMSG_SETPROPERTYRESPONSE, *LPDPLMSG_SETPROPERTYRESPONSE;
+
+/* Request to get the present value of a property */
+typedef struct tagDPLMSG_GETPROPERTY
+{
+        DWORD   dwType;           /* Message type */
+        DWORD   dwRequestID;      /* Request ID */
+        GUID    guidPlayer;       /* Player GUID */
+        GUID    guidPropertyTag;  /* Property GUID */
+} DPLMSG_GETPROPERTY, *LPDPLMSG_GETPROPERTY;
+
+/* Response to a request to get the present value of a property */
+typedef struct tagDPLMSG_GETPROPERTYRESPONSE
+{
+        DWORD   dwType;              /* Message type */
+        DWORD   dwRequestID;         /* Request ID */
+        GUID    guidPlayer;          /* Player GUID */
+        GUID    guidPropertyTag;     /* Property GUID */
+        HRESULT hr;                  /* Return Code */
+        DWORD   dwDataSize;          /* Size of data */
+        DWORD   dwPropertyData[1];   /* Buffer containing data */
+} DPLMSG_GETPROPERTYRESPONSE, *LPDPLMSG_GETPROPERTYRESPONSE;
+
+/* Standard message in response to a session host migration to a new client */
+typedef struct tagDPLMSG_NEWSESSIONHOST
+{
+    DWORD   dwType;        /* Message type */
+    GUID    guidInstance;  /* GUID Instance of the session */
+} DPLMSG_NEWSESSIONHOST, *LPDPLMSG_NEWSESSIONHOST;
+
+/*****************************************************************************
+ * DirectPlay Address ID's
+ * A DirectPlay address is composed of multiple data chunks, each assocated with
+ * a GUID to give significance to the type of data. All chunks have an associated
+ * size so that unknown chunks can be ignored for backwards compatibility!
+ * EnumAddresses function is used to parse the address data chunks.
+ */
+
+/* DPAID_TotalSize {1318F560-912C-11d0-9DAA-00A0C90A43CB} 
+ * Chunk purpose: Chunk is a DWORD containing the size of the entire DPADDRESS struct 
+ */
+DEFINE_GUID(DPAID_TotalSize, 0x1318f560, 0x912c, 0x11d0, 0x9d, 0xaa, 0x0, 0xa0, 0xc9, 0xa, 0x43, 0xcb);
+
+/* DPAID_ServiceProvider {07D916C0-E0AF-11cf-9C4E-00A0C905425E}
+ * Chunk purpose: Chunk is a GUID indicated what service provider created the chunk.
+ */
+DEFINE_GUID(DPAID_ServiceProvider, 0x7d916c0, 0xe0af, 0x11cf, 0x9c, 0x4e, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
+
+/* DPAID_LobbyProvider {59B95640-9667-11d0-A77D-0000F803ABFC}
+ * Chunk purpose: Chunk is a GUID indicating what lobby provider created the chunk.
+ */
+DEFINE_GUID(DPAID_LobbyProvider, 0x59b95640, 0x9667, 0x11d0, 0xa7, 0x7d, 0x0, 0x0, 0xf8, 0x3, 0xab, 0xfc);
+
+/* DPAID_Phone  {78EC89A0-E0AF-11cf-9C4E-00A0C905425E} -- ANSI
+ * DPAID_PhoneW {BA5A7A70-9DBF-11d0-9CC1-00A0C905425E} -- UNICODE
+ * Chunk purpose: Chunk is a phone number in ANSI or UNICODE format 
+ */
+DEFINE_GUID(DPAID_Phone, 0x78ec89a0, 0xe0af, 0x11cf, 0x9c, 0x4e, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
+DEFINE_GUID(DPAID_PhoneW, 0xba5a7a70, 0x9dbf, 0x11d0, 0x9c, 0xc1, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
+
+/* DPAID_Modem  {F6DCC200-A2FE-11d0-9C4F-00A0C905425E} -- ANSI
+ * DPAID_ModemW {01FD92E0-A2FF-11d0-9C4F-00A0C905425E} -- UNICODE
+ * Chunk purpose: Chunk is a modem name registered with TAPI
+ */
+DEFINE_GUID(DPAID_Modem, 0xf6dcc200, 0xa2fe, 0x11d0, 0x9c, 0x4f, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
+DEFINE_GUID(DPAID_ModemW, 0x1fd92e0, 0xa2ff, 0x11d0, 0x9c, 0x4f, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
+
+/* DPAID_INet  {C4A54DA0-E0AF-11cf-9C4E-00A0C905425E} -- ANSI
+ * DPAID_INetW {E63232A0-9DBF-11d0-9CC1-00A0C905425E} -- UNICODE
+ * Chunk purpose: Chunk is a string containing a TCP/IP host name or IP address
+ */
+DEFINE_GUID(DPAID_INet, 0xc4a54da0, 0xe0af, 0x11cf, 0x9c, 0x4e, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
+DEFINE_GUID(DPAID_INetW, 0xe63232a0, 0x9dbf, 0x11d0, 0x9c, 0xc1, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
+
+/* DPAID_INetPort {E4524541-8EA5-11d1-8A96-006097B01411}
+ * Chunk purpose: Chunk is a port number used for creating TCP and UDP sockets.
+ */
+DEFINE_GUID(DPAID_INetPort, 0xe4524541, 0x8ea5, 0x11d1, 0x8a, 0x96, 0x0, 0x60, 0x97, 0xb0, 0x14, 0x11);
+
+/* DPAID_ComPort {F2F0CE00-E0AF-11cf-9C4E-00A0C905425E}
+ * Chunk purpose: Chunk contains the description of a serial port.
+ */
+DEFINE_GUID(DPAID_ComPort, 0xf2f0ce00, 0xe0af, 0x11cf, 0x9c, 0x4e, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
+
+
+/* Header block for address data elements */
+typedef struct tagDPADDRESS
+{
+    GUID                guidDataType;
+    DWORD               dwDataSize;
+} DPADDRESS, *LPDPADDRESS;
+
+
+/* Used for specification of a communication port. Baud rate, stop bits and
+ * parity bits can be found in winbase.h. These are flow control constants only. 
+ */
+#define DPCPA_NOFLOW        0           // no flow control
+#define DPCPA_XONXOFFFLOW   1           // software flow control
+#define DPCPA_RTSFLOW       2           // hardware flow control with RTS
+#define DPCPA_DTRFLOW       3           // hardware flow control with DTR
+#define DPCPA_RTSDTRFLOW    4           // hardware flow control with RTS and DTR
+
+typedef struct tagDPCOMPORTADDRESS
+{
+    DWORD   dwComPort;                  // COM port to use (1-4)
+    DWORD   dwBaudRate;                 // baud rate (100-256k)
+    DWORD   dwStopBits;                 // no. stop bits (1-2)
+    DWORD   dwParity;                   // parity (none, odd, even, mark)
+    DWORD   dwFlowControl;              // flow control (none, xon/xoff, rts, dtr)
+} DPCOMPORTADDRESS, *LPDPCOMPORTADDRESS;
+
+
+
+/**************************************************************************** 
  * Miscellaneous
  */
 
@@ -36,11 +270,11 @@
     DWORD       dwSize;            
     GUID        guidApplication;   
 
-    union appName
+    union 
     {
         LPSTR   lpszAppNameA;      
         LPWSTR  lpszAppName;
-    };
+    } appName;
 
 } DPLAPPINFO, *LPDPLAPPINFO;
 typedef const DPLAPPINFO *LPCDPLAPPINFO;
@@ -53,6 +287,49 @@
 } DPCOMPOUNDADDRESSELEMENT, *LPDPCOMPOUNDADDRESSELEMENT;
 typedef const DPCOMPOUNDADDRESSELEMENT *LPCDPCOMPOUNDADDRESSELEMENT;
 
+typedef struct tagDPAPPLICATIONDESC
+{
+    DWORD       dwSize;
+    DWORD       dwFlags;
+
+    union
+    {
+        LPSTR       lpszApplicationNameA;
+        LPWSTR      lpszApplicationName;
+    } appName;
+
+    GUID        guidApplication;
+
+    union
+    {
+        LPSTR       lpszFilenameA;
+        LPWSTR      lpszFilename;
+    } fileName;
+
+    union
+    {
+        LPSTR       lpszCommandLineA;
+        LPWSTR      lpszCommandLine;
+    } cmdLine;
+
+    union
+    {
+        LPSTR       lpszPathA;
+        LPWSTR      lpszPath;
+    } path;
+
+    union
+    {
+        LPSTR       lpszCurrentDirectoryA;
+        LPWSTR      lpszCurrentDirectory;
+    } curDir;
+
+    LPSTR       lpszDescriptionA;
+    LPWSTR      lpszDescriptionW;
+
+} DPAPPLICATIONDESC, *LPDPAPPLICATIONDESC;
+
+
 
 extern HRESULT WINAPI DirectPlayLobbyCreateW(LPGUID, LPDIRECTPLAYLOBBY *, IUnknown *, LPVOID, DWORD );
 extern HRESULT WINAPI DirectPlayLobbyCreateA(LPGUID, LPDIRECTPLAYLOBBYA *, IUnknown *, LPVOID, DWORD );
@@ -99,26 +376,6 @@
 ICOM_DEFINE(IDirectPlayLobby,IUnknown)
 #undef ICOM_INTERFACE
 
-#ifdef ICOM_CINTERFACE
-/*** IUnknown methods ***/
-#define IDirectPlayLobby_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
-#define IDirectPlayLobby_AddRef(p)             ICOM_CALL (AddRef,p)
-#define IDirectPlayLobby_Release(p)            ICOM_CALL (Release,p)
-/*** IDirectPlayLobby methods ***/
-#define IDirectPlayLobby_Connect(p,a,b,c)                 ICOM_CALL3(Connect,p,a,b,c)
-#define IDirectPlayLobby_CreateAddress(p,a,b,c,d,e,f)     ICOM_CALL6(CreateAddress,p,a,b,c,d,e,f)
-#define IDirectPlayLobby_EnumAddress(p,a,b,c,d)           ICOM_CALL4(EnumAddress,p,a,b,c,d)
-#define IDirectPlayLobby_EnumAddressTypes(p,a,b,c,d)      ICOM_CALL4(EnumAddressTypes,p,a,b,c,d)
-#define IDirectPlayLobby_EnumLocalApplications(p,a,b,c)   ICOM_CALL3(EnumLocalApplications,p,a,b,c)
-#define IDirectPlayLobby_GetConnectionSettings(p,a,b,c)   ICOM_CALL3(GetConnectionSettings,p,a,b,c)
-#define IDirectPlayLobby_ReceiveLobbyMessage(p,a,b,c,d,e) ICOM_CALL5(ReceiveLobbyMessage,p,a,b,c,d,e)
-#define IDirectPlayLobby_RunApplication(p,a,b,c,d)        ICOM_CALL4(RunApplication,p,a,b,c,d)
-#define IDirectPlayLobby_SendLobbyMessage(p,a,b,c,d)      ICOM_CALL4(SendLobbyMessage,p,a,b,c,d)
-#define IDirectPlayLobby_SetConnectionSettings(p,a,b,c)   ICOM_CALL3(SetConnectionSettings,p,a,b,c)
-#define IDirectPlayLobby_SetLobbyMessageEvent(p,a,b,c)    ICOM_CALL3(SetLobbyMessageEvent,p,a,b,c)
-#endif
-
-
 /*****************************************************************************
  * IDirectPlayLobby2 interface
  */
@@ -131,25 +388,45 @@
 ICOM_DEFINE(IDirectPlayLobby2,IDirectPlayLobby)
 #undef ICOM_INTERFACE
 
+/*****************************************************************************
+ * IDirectPlayLobby3 interface
+ */
+
+#define ICOM_INTERFACE IDirectPlayLobby3
+#define IDirectPlayLobby3_METHODS \
+    ICOM_METHOD4( HRESULT, ConnectEx,                 DWORD,, REFIID,, LPVOID *,, IUnknown *,) \
+    ICOM_METHOD2( HRESULT, RegisterApplication,       DWORD,, LPDPAPPLICATIONDESC, ) \
+    ICOM_METHOD2( HRESULT, UnregisterApplication,     DWORD,, REFGUID, ) \
+    ICOM_METHOD1( HRESULT, WaitForConnectionSettings, DWORD, )
+
+#define IDirectPlayLobby3_IMETHODS \
+    IDirectPlayLobby2_IMETHODS \
+    IDirectPlayLobby3_METHODS
+ICOM_DEFINE(IDirectPlayLobby3,IDirectPlayLobby2)
+#undef ICOM_INTERFACE
+
 #ifdef ICOM_CINTERFACE
-/*** IUnknown methods ***/
-#define IDirectPlayLobby2_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
-#define IDirectPlayLobby2_AddRef(p)             ICOM_CALL (AddRef,p)
-#define IDirectPlayLobby2_Release(p)            ICOM_CALL (Release,p)
-/*** IDirectPlayLobby methods ***/
-#define IDirectPlayLobby2_Connect(p,a,b,c)                 ICOM_CALL3(Connect,p,a,b,c)
-#define IDirectPlayLobby2_CreateAddress(p,a,b,c,d,e,f)     ICOM_CALL6(CreateAddress,p,a,b,c,d,e,f)
-#define IDirectPlayLobby2_EnumAddress(p,a,b,c,d)           ICOM_CALL4(EnumAddress,p,a,b,c,d)
-#define IDirectPlayLobby2_EnumAddressTypes(p,a,b,c,d)      ICOM_CALL4(EnumAddressTypes,p,a,b,c,d)
-#define IDirectPlayLobby2_EnumLocalApplications(p,a,b,c)   ICOM_CALL3(EnumLocalApplications,p,a,b,c)
-#define IDirectPlayLobby2_GetConnectionSettings(p,a,b,c)   ICOM_CALL3(GetConnectionSettings,p,a,b,c)
-#define IDirectPlayLobby2_ReceiveLobbyMessage(p,a,b,c,d,e) ICOM_CALL5(ReceiveLobbyMessage,p,a,b,c,d,e)
-#define IDirectPlayLobby2_RunApplication(p,a,b,c,d)        ICOM_CALL4(RunApplication,p,a,b,c,d)
-#define IDirectPlayLobby2_SendLobbyMessage(p,a,b,c,d)      ICOM_CALL4(SendLobbyMessage,p,a,b,c,d)
-#define IDirectPlayLobby2_SetConnectionSettings(p,a,b,c)   ICOM_CALL3(SetConnectionSettings,p,a,b,c)
-#define IDirectPlayLobby2_SetLobbyMessageEvent(p,a,b,c)    ICOM_CALL3(SetLobbyMessageEvent,p,a,b,c)
-/*** IDirectPlayLobby2 methods ***/
-#define IDirectPlayLobby2_CreateCompoundAddress(p,a,b,c,d) ICOM_CALL4(CreateCompoundAddress,p,a,b,c,d)
+
+#define IDirectPlayLobby_QueryInterface(p,a,b)              ICOM_CALL2(QueryInterface,p,a,b)
+#define IDirectPlayLobby_AddRef(p)                          ICOM_CALL (AddRef,p)
+#define IDirectPlayLobby_Release(p)                         ICOM_CALL (Release,p)
+#define IDirectPlayLobby_Connect(p,a,b,c)                   ICOM_CALL3(Connect,p,a,b,c)
+#define IDirectPlayLobby_ConnectEx(p,a,b,c,d)               ICOM_CALL4(ConnectEx,p,a,b,c,d)
+#define IDirectPlayLobby_CreateAddress(p,a,b,c,d,e,f)       ICOM_CALL6(CreateAddress,p,a,b,c,d,e,f)
+#define IDirectPlayLobby_CreateCompoundAddress(p,a,b,c,d)   ICOM_CALL4(CreateCompoundAddress,p,a,b,c,d)
+#define IDirectPlayLobby_EnumAddress(p,a,b,c,d)             ICOM_CALL4(EnumAddress,p,a,b,c,d)
+#define IDirectPlayLobby_EnumAddressTypes(p,a,b,c,d)        ICOM_CALL4(EnumAddressTypes,p,a,b,c,d)
+#define IDirectPlayLobby_EnumLocalApplications(p,a,b,c)     ICOM_CALL3(EnumLocalApplications,p,a,b,c)
+#define IDirectPlayLobby_GetConnectionSettings(p,a,b,c)     ICOM_CALL3(GetConnectionSettings,p,a,b,c)
+#define IDirectPlayLobby_ReceiveLobbyMessage(p,a,b,c,d,e)   ICOM_CALL5(ReceiveLobbyMessage,p,a,b,c,d,e)
+#define IDirectPlayLobby_RegisterApplication(p,a,b)         ICOM_CALL2(RegisterApplication,p,a,b)
+#define IDirectPlayLobby_RunApplication(p,a,b,c,d)          ICOM_CALL4(RunApplication,p,a,b,c,d)
+#define IDirectPlayLobby_SendLobbyMessage(p,a,b,c,d)        ICOM_CALL4(SendLobbyMessage,p,a,b,c,d)
+#define IDirectPlayLobby_SetConnectionSettings(p,a,b,c)     ICOM_CALL3(SetConnectionSettings,p,a,b,c)
+#define IDirectPlayLobby_SetLobbyMessageEvent(p,a,b,c)      ICOM_CALL3(SetLobbyMessageEvent,p,a,b,c)
+#define IDirectPlayLobby_UnregisterApplication(p,a,b)       ICOM_CALL2(UnregisterApplication,p,a,b)
+#define IDirectPlayLobby_WaitForConnectionSettings(p,a)     ICOM_CALL1(WaitForConnectionSettings,p,a)
+
 #endif
 
 #ifdef __cplusplus
diff --git a/multimedia/Makefile.in b/multimedia/Makefile.in
index 2a6a49f..f937e2e 100644
--- a/multimedia/Makefile.in
+++ b/multimedia/Makefile.in
@@ -8,7 +8,6 @@
 
 C_SRCS = \
 	audio.c \
-	dplay.c \
 	dsound.c \
 	joystick.c \
 	lolvldrv.c \
diff --git a/multimedia/dplay.c b/multimedia/dplay.c
deleted file mode 100644
index d86ec08..0000000
--- a/multimedia/dplay.c
+++ /dev/null
@@ -1,2673 +0,0 @@
-/* Direct Play 3 and Direct Play Lobby 2 Implementation
- *
- * Copyright 1998,1999 - Peter Hunnisett
- *
- * <presently under construction - contact hunnise@nortelnetworks.com>
- *
- */
-#include <string.h>
-#include "winerror.h"
-#include "winnt.h"
-#include "winreg.h"
-#include "dplay.h"
-#include "dplobby.h"
-#include "heap.h"
-#include "debugtools.h"
-
-DEFAULT_DEBUG_CHANNEL(dplay)
-
-/*****************************************************************************
- * Predeclare the interface implementation structures
- */
-typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyImpl;
-typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyAImpl;
-typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyWImpl;
-typedef struct IDirectPlayLobby2Impl IDirectPlayLobby2Impl;
-typedef struct IDirectPlayLobby2Impl IDirectPlayLobby2AImpl;
-typedef struct IDirectPlay2Impl IDirectPlay2Impl;
-typedef struct IDirectPlay2Impl IDirectPlay2AImpl;
-typedef struct IDirectPlay3Impl IDirectPlay3Impl;
-typedef struct IDirectPlay3Impl IDirectPlay3AImpl;
-
-/*****************************************************************************
- * IDirectPlayLobby implementation structure
- */
-struct IDirectPlayLobbyImpl
-{
-    /* IUnknown fields */
-    ICOM_VTABLE(IDirectPlayLobby)* lpvtbl;
-    DWORD                          ref;
-    /* IDirectPlayLobbyImpl fields */
-    DWORD                    dwConnFlags;
-    DPSESSIONDESC2           sessionDesc;
-    DPNAME                   playerName;
-    GUID                     guidSP;
-    LPVOID                   lpAddress;
-    DWORD                    dwAddressSize;
-};
-
-/*****************************************************************************
- * IDirectPlayLobby2 implementation structure
- */
-struct IDirectPlayLobby2Impl
-{
-    /* IUnknown fields */
-    ICOM_VTABLE(IDirectPlayLobby2)* lpvtbl;
-    DWORD                           ref;
-    /* IDirectPlayLobby2Impl fields */
-    DWORD                     dwConnFlags;
-    DPSESSIONDESC2            lpSessionDesc;
-    DPNAME                    lpPlayerName;
-    GUID                      guidSP;
-    LPVOID                    lpAddress;
-    DWORD                     dwAddressSize;
-};
-
-/*****************************************************************************
- * IDirectPlay2 implementation structure
- */
-struct IDirectPlay2Impl
-{
-    /* IUnknown fields */
-    ICOM_VTABLE(IDirectPlay2)* lpvtbl;
-    DWORD                      ref;
-    /* IDirectPlay2Impl fields */
-    /* none */
-};
-
-/*****************************************************************************
- * IDirectPlay3 implementation structure
- */
-struct IDirectPlay3Impl
-{
-    /* IUnknown fields */
-    ICOM_VTABLE(IDirectPlay3)* lpvtbl;
-    DWORD                      ref;
-    /* IDirectPlay3Impl fields */
-    /* none */
-};
-
-/* Forward declarations of virtual tables */
-static ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyAVT;
-static ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyWVT;
-static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2AVT;
-static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2WVT;
-static ICOM_VTABLE(IDirectPlay2) directPlay2WVT;
-static ICOM_VTABLE(IDirectPlay2) directPlay2AVT;
-static ICOM_VTABLE(IDirectPlay3) directPlay3WVT;
-static ICOM_VTABLE(IDirectPlay3) directPlay3AVT;
-
-
-
-
-/* Routine called when starting up the server thread */
-DWORD DPLobby_Spawn_Server( LPVOID startData )
-{
-  DPSESSIONDESC2* lpSession = (DPSESSIONDESC2*) startData;
-  DWORD sessionDwFlags = lpSession->dwFlags;
- 
-  TRACE("spawing thread for lpConn=%p dwFlags=%08lx\n", lpSession, sessionDwFlags );
-  FIXME("thread needs something to do\n" ); 
-
-/*for(;;)*/
-  {
-     
-    /* Check out the connection flags to determine what to do. Ensure we have 
-       no leftover bits in this structure */
-    if( sessionDwFlags & DPSESSION_CLIENTSERVER )
-    {
-       /* This indicates that the application which is requesting the creation
-        * of this session is going to be the server (application/player)
-        */ 
-       if( sessionDwFlags & DPSESSION_SECURESERVER )
-       {
-         sessionDwFlags &= ~DPSESSION_SECURESERVER; 
-       }
-       sessionDwFlags &= ~DPSESSION_CLIENTSERVER;  
-    }
-
-    if( sessionDwFlags & DPSESSION_JOINDISABLED )
-    {
-       sessionDwFlags &= ~DPSESSION_JOINDISABLED; 
-    } 
-
-    if( sessionDwFlags & DPSESSION_KEEPALIVE )
-    {
-       sessionDwFlags &= ~DPSESSION_KEEPALIVE;
-    }
-
-    if( sessionDwFlags & DPSESSION_MIGRATEHOST )
-    {
-       sessionDwFlags &= ~DPSESSION_MIGRATEHOST;
-    }
-
-    if( sessionDwFlags & DPSESSION_MULTICASTSERVER )
-    {
-       sessionDwFlags &= ~DPSESSION_MULTICASTSERVER;
-    }
-
-    if( sessionDwFlags & DPSESSION_NEWPLAYERSDISABLED )
-    {
-       sessionDwFlags &= ~DPSESSION_NEWPLAYERSDISABLED; 
-    }
-
-    if( sessionDwFlags & DPSESSION_NODATAMESSAGES )
-    {
-       sessionDwFlags &= ~DPSESSION_NODATAMESSAGES; 
-    } 
-
-    if( sessionDwFlags & DPSESSION_NOMESSAGEID )
-    {
-       sessionDwFlags &= ~DPSESSION_NOMESSAGEID;
-    }
-
-    if( sessionDwFlags & DPSESSION_PASSWORDREQUIRED )
-    {
-       sessionDwFlags &= ~DPSESSION_PASSWORDREQUIRED;
-    }
-
-  }
-
-  ExitThread(0);
-  return 0; 
-}
-
-
-/*********************************************************
- *
- * Direct Play and Direct Play Lobby Interface Implementation 
- * 
- *********************************************************/ 
-
-/* The COM interface for upversioning an interface
- * We've been given a GUID (riid) and we need to replace the present
- * interface with that of the requested interface.
- *
- * Snip from some Microsoft document:
- * There are four requirements for implementations of QueryInterface (In these
- * cases, "must succeed" means "must succeed barring catastrophic failure."):
- *
- *  * The set of interfaces accessible on an object through
- *    IUnknown::QueryInterface must be static, not dynamic. This means that
- *    if a call to QueryInterface for a pointer to a specified interface
- *    succeeds the first time, it must succeed again, and if it fails the
- *    first time, it must fail on all subsequent queries.
- *  * It must be symmetric ~W if a client holds a pointer to an interface on
- *    an object, and queries for that interface, the call must succeed.
- *  * It must be reflexive ~W if a client holding a pointer to one interface
- *    queries successfully for another, a query through the obtained pointer
- *    for the first interface must succeed.
- *  * It must be transitive ~W if a client holding a pointer to one interface
- *    queries successfully for a second, and through that pointer queries
- *    successfully for a third interface, a query for the first interface
- *    through the pointer for the third interface must succeed.
- *
- *  As you can see, this interface doesn't qualify but will most likely
- *  be good enough for the time being.
- */
-
-/* Helper function for DirectPlayLobby  QueryInterface */ 
-static HRESULT directPlayLobby_QueryInterface
-         ( REFIID riid, LPVOID* ppvObj )
-{
-
-  if( IsEqualGUID( &IID_IDirectPlayLobby, riid ) )
-  {
-     IDirectPlayLobbyImpl* lpDpL = (IDirectPlayLobbyImpl*)(*ppvObj);
-
-     lpDpL = (IDirectPlayLobbyImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                           sizeof( *lpDpL ) );
-
-    if( !lpDpL )
-    {
-      return E_NOINTERFACE;
-    }
-
-    lpDpL->lpvtbl = &directPlayLobbyWVT;
-    lpDpL->ref    = 1;
-
-    return S_OK;
-  }
-  else if( IsEqualGUID( &IID_IDirectPlayLobbyA, riid ) )
-  {
-     IDirectPlayLobbyAImpl* lpDpL = (IDirectPlayLobbyAImpl*)(*ppvObj);
-
-     lpDpL = (IDirectPlayLobbyAImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                            sizeof( *lpDpL ) );
-
-    if( !lpDpL )
-    {
-      return E_NOINTERFACE;
-    }
-
-    lpDpL->lpvtbl = &directPlayLobbyAVT;
-    lpDpL->ref    = 1;
-
-    return S_OK;
-  }
-  else if( IsEqualGUID( &IID_IDirectPlayLobby2, riid ) )
-  {
-     IDirectPlayLobby2Impl* lpDpL = (IDirectPlayLobby2Impl*)(*ppvObj);
-
-     lpDpL = (IDirectPlayLobby2Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                             sizeof( *lpDpL ) );
-
-    if( !lpDpL )
-    {
-      return E_NOINTERFACE;
-    }
-
-    lpDpL->lpvtbl = &directPlayLobby2WVT;
-    lpDpL->ref    = 1;
-
-    return S_OK;
-  }
-  else if( IsEqualGUID( &IID_IDirectPlayLobby2A, riid ) )
-  {
-     IDirectPlayLobby2AImpl* lpDpL = (IDirectPlayLobby2AImpl*)(*ppvObj);
-
-     lpDpL = (IDirectPlayLobby2AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                             sizeof( *lpDpL ) );
-
-    if( !lpDpL )
-    {
-      return E_NOINTERFACE;
-    }
-
-    lpDpL->lpvtbl = &directPlayLobby2AVT;
-    lpDpL->ref    = 1;
-
-    return S_OK;
-  }
-
-  /* Unknown interface */
-  *ppvObj = NULL;
-  return E_NOINTERFACE;
-}
-static HRESULT WINAPI IDirectPlayLobbyAImpl_QueryInterface
-( LPDIRECTPLAYLOBBYA iface,
-  REFIID riid,
-  LPVOID* ppvObj )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
-
-  if( IsEqualGUID( &IID_IUnknown, riid )  ||
-      IsEqualGUID( &IID_IDirectPlayLobbyA, riid )
-    )
-  {
-    IDirectPlayLobby_AddRef( iface );
-    *ppvObj = This;
-    return S_OK;
-  }
-
-  return directPlayLobby_QueryInterface( riid, ppvObj );
-
-}
-
-static HRESULT WINAPI IDirectPlayLobbyW_QueryInterface
-( LPDIRECTPLAYLOBBY iface,
-  REFIID riid,
-  LPVOID* ppvObj )
-{
-  ICOM_THIS(IDirectPlayLobbyImpl,iface);
-  TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
-
-  if( IsEqualGUID( &IID_IUnknown, riid )  ||
-      IsEqualGUID( &IID_IDirectPlayLobby, riid )
-    )
-  {
-    IDirectPlayLobby_AddRef( iface );
-    *ppvObj = This;
-    return S_OK;
-  }
-
-  return directPlayLobby_QueryInterface( riid, ppvObj );
-}
-
-
-static HRESULT WINAPI IDirectPlayLobby2AImpl_QueryInterface
-( LPDIRECTPLAYLOBBY2A iface,
-  REFIID riid,
-  LPVOID* ppvObj )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
-
-  /* Compare riids. We know this object is a direct play lobby 2A object.
-     If we are asking about the same type of interface we're fine.
-   */
-  if( IsEqualGUID( &IID_IUnknown, riid )  ||
-      IsEqualGUID( &IID_IDirectPlayLobby2A, riid )
-    )
-  {
-    IDirectPlayLobby2_AddRef( iface );
-    *ppvObj = This;
-    return S_OK;
-  }
-  return directPlayLobby_QueryInterface( riid, ppvObj ); 
-}
-
-static HRESULT WINAPI IDirectPlayLobby2WImpl_QueryInterface
-( LPDIRECTPLAYLOBBY2 iface,
-  REFIID riid,
-  LPVOID* ppvObj )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-
-  /* Compare riids. We know this object is a direct play lobby 2 object.
-     If we are asking about the same type of interface we're fine.
-   */
-  if( IsEqualGUID( &IID_IUnknown, riid ) ||
-      IsEqualGUID( &IID_IDirectPlayLobby2, riid ) 
-    )
-  {
-    IDirectPlayLobby2_AddRef( iface );
-    *ppvObj = This;
-    return S_OK;
-  }
-
-  return directPlayLobby_QueryInterface( riid, ppvObj ); 
-
-}
-
-/* 
- * Simple procedure. Just increment the reference count to this
- * structure and return the new reference count.
- */
-static ULONG WINAPI IDirectPlayLobby2AImpl_AddRef
-( LPDIRECTPLAYLOBBY2A iface )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  ++(This->ref);
-  TRACE("ref count now %lu\n", This->ref );
-  return (This->ref);
-}
-
-static ULONG WINAPI IDirectPlayLobby2WImpl_AddRef
-( LPDIRECTPLAYLOBBY2 iface )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobby2AImpl_AddRef( (LPDIRECTPLAYLOBBY2) This );
-}
-
-
-/*
- * Simple COM procedure. Decrease the reference count to this object.
- * If the object no longer has any reference counts, free up the associated
- * memory.
- */
-static ULONG WINAPI IDirectPlayLobby2AImpl_Release
-( LPDIRECTPLAYLOBBY2A iface )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  TRACE("ref count decremeneted from %lu\n", This->ref );
-
-  This->ref--;
-
-  /* Deallocate if this is the last reference to the object */
-  if( !(This->ref) )
-  {
-    FIXME("memory leak\n" );
-    /* Implement memory deallocation */
-
-    HeapFree( GetProcessHeap(), 0, This );
-
-    return 0;
-  }
-
-  return This->ref;
-}
-
-static ULONG WINAPI IDirectPlayLobby2WImpl_Release
-( LPDIRECTPLAYLOBBY2 iface )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobby2AImpl_Release( (LPDIRECTPLAYLOBBY2A) This );
-}
-
-
-/********************************************************************
- * 
- * Connects an application to the session specified by the DPLCONNECTION
- * structure currently stored with the DirectPlayLobby object.
- *
- * Returns a IDirectPlay interface.
- *
- */
-static HRESULT WINAPI IDirectPlayLobby2AImpl_Connect
-( LPDIRECTPLAYLOBBY2A iface,
-  DWORD dwFlags,
-  LPDIRECTPLAY2* lplpDP,
-  IUnknown* pUnk)
-{
-  FIXME(": dwFlags=%08lx %p %p stub\n", dwFlags, lplpDP, pUnk );
-  return DPERR_OUTOFMEMORY;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2WImpl_Connect
-( LPDIRECTPLAYLOBBY2 iface,
-  DWORD dwFlags,
-  LPDIRECTPLAY2* lplpDP,
-  IUnknown* pUnk)
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  LPDIRECTPLAY2* directPlay2W;
-  HRESULT        createRC;
-
-  FIXME("(%p)->(%08lx,%p,%p): stub\n", This, dwFlags, lplpDP, pUnk );
-
-  if( dwFlags )
-  {
-     return DPERR_INVALIDPARAMS;
-  }
-
-  if( ( createRC = DirectPlayCreate( (LPGUID)&IID_IDirectPlayLobby2, lplpDP, pUnk ) ) != DP_OK )
-  {
-     ERR("error creating Direct Play 2W interface. Return Code = %ld.\n", createRC );
-     return createRC;
-  } 
-
-  /* This should invoke IDirectPlay3::InitializeConnection IDirectPlay3::Open */  
-  directPlay2W = lplpDP; 
- 
-    
-
-
-#if 0
-  /* All the stuff below this is WRONG! */
-  if( This->lpSession->dwFlags == DPLCONNECTION_CREATESESSION )
-  {
-    DWORD threadIdSink;
-
-    /* Spawn a thread to deal with all of this and to handle the incomming requests */
-    threadIdSink = CreateThread( NULL, 0, &DPLobby_Spawn_Server,
-                                (LPVOID)This->lpSession->lpConn->lpSessionDesc, 0, &threadIdSink );  
-
-  }
-  else if ( This->lpSession->dwFlags == DPLCONNECTION_JOINSESSION ) 
-  {
-    /* Let's search for a matching session */
-    FIXME("joining session not yet supported.\n");
-    return DPERR_OUTOFMEMORY;
-  }
-  else /* Unknown type of connection request */
-  {
-     ERR(": Unknown connection request lpConn->dwFlags=%08lx\n",
-          lpConn->dwFlags ); 
-
-     return DPERR_OUTOFMEMORY;
-  }
-
-  /* This does the work of the following methods...
-     IDirectPlay3::InitializeConnection,
-     IDirectPlay3::EnumSessions,
-     IDirectPlay3::Open
-   */
-  
-
-#endif
-
-  return DP_OK;
-
-}
-
-/********************************************************************
- *
- * Creates a DirectPlay Address, given a service provider-specific network
- * address. 
- * Returns an address contains the globally unique identifier
- * (GUID) of the service provider and data that the service provider can
- * interpret as a network address.
- *
- */
-static HRESULT WINAPI IDirectPlayLobby2AImpl_CreateAddress
-( LPDIRECTPLAYLOBBY2A iface,
-  REFGUID guidSP,
-  REFGUID guidDataType,
-  LPCVOID lpData, 
-  DWORD dwDataSize,
-  LPVOID lpAddress, 
-  LPDWORD lpdwAddressSize )
-{
-  FIXME(":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2WImpl_CreateAddress
-( LPDIRECTPLAYLOBBY2 iface,
-  REFGUID guidSP,
-  REFGUID guidDataType,
-  LPCVOID lpData,
-  DWORD dwDataSize,
-  LPVOID lpAddress,
-  LPDWORD lpdwAddressSize )
-{
-  FIXME(":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
-
-
-/********************************************************************
- *
- * Parses out chunks from the DirectPlay Address buffer by calling the
- * given callback function, with lpContext, for each of the chunks.
- *
- */
-static HRESULT WINAPI IDirectPlayLobby2AImpl_EnumAddress
-( LPDIRECTPLAYLOBBY2A iface,
-  LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
-  LPCVOID lpAddress,
-  DWORD dwAddressSize,
-  LPVOID lpContext )
-{
-  FIXME(":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2WImpl_EnumAddress
-( LPDIRECTPLAYLOBBY2 iface,
-  LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
-  LPCVOID lpAddress,
-  DWORD dwAddressSize,
-  LPVOID lpContext )
-{
-  FIXME(":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
-
-/********************************************************************
- *
- * Enumerates all the address types that a given service provider needs to
- * build the DirectPlay Address.
- *
- */
-static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddressTypes
-( LPDIRECTPLAYLOBBYA iface,
-  LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
-  REFGUID guidSP,
-  LPVOID lpContext,
-  DWORD dwFlags )
-{
-  FIXME(":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2AImpl_EnumAddressTypes
-( LPDIRECTPLAYLOBBY2A iface,
-  LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
-  REFGUID guidSP, 
-  LPVOID lpContext,
-  DWORD dwFlags )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobbyAImpl_EnumAddressTypes( (LPDIRECTPLAYLOBBYA)This, lpEnumAddressTypeCallback,
-                                             guidSP, lpContext, dwFlags );
-}
-
-static HRESULT WINAPI IDirectPlayLobby2WImpl_EnumAddressTypes
-( LPDIRECTPLAYLOBBY2 iface,
-  LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
-  REFGUID guidSP,
-  LPVOID lpContext,
-  DWORD dwFlags )
-{
-  FIXME(":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
-
-/********************************************************************
- *
- * Enumerates what applications are registered with DirectPlay by
- * invoking the callback function with lpContext.
- *
- */
-static HRESULT WINAPI IDirectPlayLobbyW_EnumLocalApplications
-( LPDIRECTPLAYLOBBY iface,
-  LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
-  LPVOID lpContext,
-  DWORD dwFlags )
-{
-  FIXME(":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2WImpl_EnumLocalApplications
-( LPDIRECTPLAYLOBBY2 iface,
-  LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
-  LPVOID lpContext,
-  DWORD dwFlags )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobbyW_EnumLocalApplications( (LPDIRECTPLAYLOBBY)This, a,
-                                                  lpContext, dwFlags ); 
-}
-
-static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumLocalApplications
-( LPDIRECTPLAYLOBBYA iface,
-  LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
-  LPVOID lpContext,
-  DWORD dwFlags )
-{
-  FIXME(":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2AImpl_EnumLocalApplications
-( LPDIRECTPLAYLOBBY2A iface,
-  LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
-  LPVOID lpContext,
-  DWORD dwFlags )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobbyAImpl_EnumLocalApplications( (LPDIRECTPLAYLOBBYA)This, a,
-                                                  lpContext, dwFlags ); 
-}
-
-
-/********************************************************************
- *
- * Retrieves the DPLCONNECTION structure that contains all the information
- * needed to start and connect an application. This was generated using
- * either the RunApplication or SetConnectionSettings methods.
- *
- * NOTES: If lpData is NULL then just return lpdwDataSize. This allows
- *        the data structure to be allocated by our caller which can then
- *        call this procedure/method again with a valid data pointer.
- */
-static HRESULT WINAPI IDirectPlayLobbyAImpl_GetConnectionSettings
-( LPDIRECTPLAYLOBBYA iface,
-  DWORD dwAppID,
-  LPVOID lpData,
-  LPDWORD lpdwDataSize )
-{
-  ICOM_THIS(IDirectPlayLobbyImpl,iface);
-  LPDPLCONNECTION lpDplConnection;
-
-  FIXME(": semi stub (%p)->(0x%08lx,%p,%p)\n", This, dwAppID, lpData, lpdwDataSize );
- 
-  /* Application is requesting us to give the required size */
-  if ( !lpData )
-  {
-    /* Let's check the size of the buffer that the application has allocated */
-    if( *lpdwDataSize >= sizeof( DPLCONNECTION ) )
-    {
-      return DP_OK;
-    }
-    else
-    {
-      *lpdwDataSize = sizeof( DPLCONNECTION );
-      return DPERR_BUFFERTOOSMALL;
-    }
-  }
-
-  /* Fill in the fields - let them just use the ptrs */
-  lpDplConnection = (LPDPLCONNECTION)lpData;
-
-  /* Make sure we were given the right size */
-  if( lpDplConnection->dwSize < sizeof( DPLCONNECTION ) )
-  {
-     ERR("bad passed size 0x%08lx.\n", lpDplConnection->dwSize );
-     return DPERR_INVALIDPARAMS;
-  }
-
-  /* Copy everything we've got into here */
-  /* Need to actually store the stuff here. Check if we've already allocated each field first. */
-  lpDplConnection->dwFlags = This->dwConnFlags;
-
-  /* Copy LPDPSESSIONDESC2 struct */
-  lpDplConnection->lpSessionDesc = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( This->sessionDesc ) );
-  memcpy( lpDplConnection->lpSessionDesc, &(This->sessionDesc), sizeof( This->sessionDesc ) );
-
-  if( This->sessionDesc.sess.lpszSessionName )
-  {
-    lpDplConnection->lpSessionDesc->sess.lpszSessionName = 
-      HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, This->sessionDesc.sess.lpszSessionName );
-  }
-
-  if( This->sessionDesc.pass.lpszPassword )
-  {
-    lpDplConnection->lpSessionDesc->pass.lpszPassword = 
-      HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, This->sessionDesc.pass.lpszPassword );
-  }
-     
-  /* I don't know what to use the reserved for. We'll set it to 0 just for fun */
-  This->sessionDesc.dwReserved1 = This->sessionDesc.dwReserved2 = 0;
-
-  /* Copy DPNAME struct - seems to be optional - check for existance first */
-  lpDplConnection->lpPlayerName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( This->playerName ) );
-  memcpy( lpDplConnection->lpPlayerName, &(This->playerName), sizeof( This->playerName ) );
-
-  if( This->playerName.psn.lpszShortName )
-  {
-    lpDplConnection->lpPlayerName->psn.lpszShortName =
-      HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, This->playerName.psn.lpszShortName );  
-  }
-
-  if( This->playerName.pln.lpszLongName )
-  {
-    lpDplConnection->lpPlayerName->pln.lpszLongName =
-      HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, This->playerName.pln.lpszLongName );
-  }
-
-
-
-  memcpy( &(lpDplConnection->guidSP), &(This->guidSP), sizeof( This->guidSP ) );
-
-  lpDplConnection->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, This->dwAddressSize );
-  memcpy( lpDplConnection->lpAddress, This->lpAddress, This->dwAddressSize );
-
-  lpDplConnection->dwAddressSize = This->dwAddressSize;
-
-  return DP_OK;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2AImpl_GetConnectionSettings
-( LPDIRECTPLAYLOBBY2A iface,
-  DWORD dwAppID,
-  LPVOID lpData,
-  LPDWORD lpdwDataSize )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobbyAImpl_GetConnectionSettings( (LPDIRECTPLAYLOBBYA)This,
-                                                  dwAppID, lpData, lpdwDataSize ); 
-}
-
-static HRESULT WINAPI IDirectPlayLobbyWImpl_GetConnectionSettings
-( LPDIRECTPLAYLOBBY iface,
-  DWORD dwAppID,
-  LPVOID lpData,
-  LPDWORD lpdwDataSize )
-{
-  ICOM_THIS(IDirectPlayLobbyImpl,iface);
-  FIXME(":semi stub %p %08lx %p %p \n", This, dwAppID, lpData, lpdwDataSize );
-
-  /* Application is requesting us to give the required size */ 
-  if ( !lpData )
-  {
-    /* Let's check the size of the buffer that the application has allocated */
-    if( *lpdwDataSize >= sizeof( DPLCONNECTION ) )
-    {
-      return DP_OK;  
-    }
-    else
-    {
-      *lpdwDataSize = sizeof( DPLCONNECTION );
-      return DPERR_BUFFERTOOSMALL;
-    }
-  }
-
-  /* Fill in the fields - let them just use the ptrs */
-  FIXME("stub\n" );
-
-  return DP_OK;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2WImpl_GetConnectionSettings
-( LPDIRECTPLAYLOBBY2 iface,
-  DWORD dwAppID,
-  LPVOID lpData,
-  LPDWORD lpdwDataSize )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobbyWImpl_GetConnectionSettings( (LPDIRECTPLAYLOBBY)This,
-                                                  dwAppID, lpData, lpdwDataSize );
-}
-
-/********************************************************************
- *
- * Retrieves the message sent between a lobby client and a DirectPlay 
- * application. All messages are queued until received.
- *
- */
-static HRESULT WINAPI IDirectPlayLobbyAImpl_ReceiveLobbyMessage
-( LPDIRECTPLAYLOBBYA iface,
-  DWORD dwFlags,
-  DWORD dwAppID,
-  LPDWORD lpdwMessageFlags,
-  LPVOID lpData,
-  LPDWORD lpdwDataSize )
-{
-  ICOM_THIS(IDirectPlayLobbyImpl,iface);
-  FIXME(":stub %p %08lx %08lx %p %p %p\n", This, dwFlags, dwAppID, lpdwMessageFlags, lpData,
-         lpdwDataSize );
-  return DPERR_OUTOFMEMORY;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2AImpl_ReceiveLobbyMessage
-( LPDIRECTPLAYLOBBY2A iface,
-  DWORD dwFlags,
-  DWORD dwAppID,
-  LPDWORD lpdwMessageFlags,
-  LPVOID lpData,
-  LPDWORD lpdwDataSize )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobbyAImpl_ReceiveLobbyMessage( (LPDIRECTPLAYLOBBYA)This, dwFlags, dwAppID,
-                                                 lpdwMessageFlags, lpData, lpdwDataSize );
-}
-
-
-static HRESULT WINAPI IDirectPlayLobbyW_ReceiveLobbyMessage
-( LPDIRECTPLAYLOBBY iface,
-  DWORD dwFlags,
-  DWORD dwAppID,
-  LPDWORD lpdwMessageFlags,
-  LPVOID lpData,
-  LPDWORD lpdwDataSize )
-{
-  ICOM_THIS(IDirectPlayLobbyImpl,iface);
-  FIXME(":stub %p %08lx %08lx %p %p %p\n", This, dwFlags, dwAppID, lpdwMessageFlags, lpData,
-         lpdwDataSize );
-  return DPERR_OUTOFMEMORY;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2WImpl_ReceiveLobbyMessage
-( LPDIRECTPLAYLOBBY2 iface,
-  DWORD dwFlags,
-  DWORD dwAppID,
-  LPDWORD lpdwMessageFlags,
-  LPVOID lpData,
-  LPDWORD lpdwDataSize )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobbyW_ReceiveLobbyMessage( (LPDIRECTPLAYLOBBY)This, dwFlags, dwAppID,
-                                                 lpdwMessageFlags, lpData, lpdwDataSize );
-}
-
-/********************************************************************
- *
- * Starts an application and passes to it all the information to
- * connect to a session.
- *
- */
-static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication
-( LPDIRECTPLAYLOBBYA iface,
-  DWORD dwFlags,
-  LPDWORD lpdwAppID,
-  LPDPLCONNECTION lpConn,
-  HANDLE hReceiveEvent )
-{
-  FIXME(":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2AImpl_RunApplication
-( LPDIRECTPLAYLOBBY2A iface,
-  DWORD dwFlags,
-  LPDWORD lpdwAppID,
-  LPDPLCONNECTION lpConn,
-  HANDLE hReceiveEvent )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobbyAImpl_RunApplication( (LPDIRECTPLAYLOBBYA)This, dwFlags,
-                                           lpdwAppID, lpConn, hReceiveEvent );
-}
-
-static HRESULT WINAPI IDirectPlayLobbyW_RunApplication
-( LPDIRECTPLAYLOBBY iface,
-  DWORD dwFlags,
-  LPDWORD lpdwAppID,
-  LPDPLCONNECTION lpConn,
-  HANDLE hReceiveEvent )
-{
-  FIXME(":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2WImpl_RunApplication
-( LPDIRECTPLAYLOBBY2 iface,
-  DWORD dwFlags,
-  LPDWORD lpdwAppID,
-  LPDPLCONNECTION lpConn,
-  HANDLE hReceiveEvent )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobbyW_RunApplication( (LPDIRECTPLAYLOBBY)This, dwFlags,
-                                           lpdwAppID, lpConn, hReceiveEvent );
-}
-
-
-/********************************************************************
- *
- * Sends a message between the application and the lobby client.
- * All messages are queued until received.
- *
- */
-static HRESULT WINAPI IDirectPlayLobbyAImpl_SendLobbyMessage
-( LPDIRECTPLAYLOBBYA iface,
-  DWORD dwFlags,
-  DWORD dwAppID,
-  LPVOID lpData,
-  DWORD dwDataSize )
-{
-  FIXME(":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2AImpl_SendLobbyMessage
-( LPDIRECTPLAYLOBBY2A iface,
-  DWORD dwFlags,
-  DWORD dwAppID,
-  LPVOID lpData,
-  DWORD dwDataSize )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobbyAImpl_SendLobbyMessage( (LPDIRECTPLAYLOBBYA)This, dwFlags, 
-                                             dwAppID, lpData, dwDataSize ); 
-}
-
-
-static HRESULT WINAPI IDirectPlayLobbyW_SendLobbyMessage
-( LPDIRECTPLAYLOBBY iface,
-  DWORD dwFlags,
-  DWORD dwAppID,
-  LPVOID lpData,
-  DWORD dwDataSize )
-{
-  FIXME(":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2WImpl_SendLobbyMessage
-( LPDIRECTPLAYLOBBY2 iface,
-  DWORD dwFlags,
-  DWORD dwAppID,
-  LPVOID lpData,
-  DWORD dwDataSize )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobbyW_SendLobbyMessage( (LPDIRECTPLAYLOBBY)This, dwFlags,
-                                              dwAppID, lpData, dwDataSize );
-}
-
-/********************************************************************
- *
- * Modifies the DPLCONNECTION structure to contain all information
- * needed to start and connect an application.
- *
- */
-static HRESULT WINAPI IDirectPlayLobbyW_SetConnectionSettings
-( LPDIRECTPLAYLOBBY iface,
-  DWORD dwFlags,
-  DWORD dwAppID,
-  LPDPLCONNECTION lpConn )
-{
-  ICOM_THIS(IDirectPlayLobbyImpl,iface);
-  TRACE(": This=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p\n",
-         This, dwFlags, dwAppID, lpConn );
-
-  /* Paramater check */
-  if( dwFlags || !This || !lpConn )
-  {
-    ERR("invalid parameters.\n");
-    return DPERR_INVALIDPARAMS;
-  }
-
-  /* See if there is a connection associated with this request.
-   * dwAppID == 0 indicates that this request isn't associated with a connection.
-   */
-  if( dwAppID )
-  {
-     FIXME(": Connection dwAppID=%08lx given. Not implemented yet.\n",
-            dwAppID );
-
-     /* Need to add a check for this application Id...*/
-     return DPERR_NOTLOBBIED;
-  }
-
-  if(  lpConn->dwSize != sizeof(DPLCONNECTION) )
-  {
-    ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n", 
-         lpConn->dwSize, sizeof( DPLCONNECTION ) );
-    return DPERR_INVALIDPARAMS;
-  }
-
-  /* Need to investigate the lpConn->lpSessionDesc to figure out
-   * what type of session we need to join/create.
-   */
-  if(  (!lpConn->lpSessionDesc ) || 
-       ( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
-    )
-  {
-    ERR("DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
-         lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
-    return DPERR_INVALIDPARAMS;
-  }
-
-  /* Need to actually store the stuff here. Check if we've already allocated each field first. */
-  This->dwConnFlags = lpConn->dwFlags;
-
-  /* Copy LPDPSESSIONDESC2 struct - this is required */
-  memcpy( &(This->sessionDesc), lpConn->lpSessionDesc, sizeof( *(lpConn->lpSessionDesc) ) );
-
-  if( lpConn->lpSessionDesc->sess.lpszSessionName )
-    This->sessionDesc.sess.lpszSessionName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->sess.lpszSessionName );
-  else
-    This->sessionDesc.sess.lpszSessionName = NULL;
- 
-  if( lpConn->lpSessionDesc->pass.lpszPassword )
-    This->sessionDesc.pass.lpszPassword = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->pass.lpszPassword );
-  else
-    This->sessionDesc.pass.lpszPassword = NULL;
-
-  /* I don't know what to use the reserved for ... */
-  This->sessionDesc.dwReserved1 = This->sessionDesc.dwReserved2 = 0;
-
-  /* Copy DPNAME struct - seems to be optional - check for existance first */
-  if( lpConn->lpPlayerName )
-  {
-     memcpy( &(This->playerName), lpConn->lpPlayerName, sizeof( *lpConn->lpPlayerName ) ); 
-
-     if( lpConn->lpPlayerName->psn.lpszShortName )
-       This->playerName.psn.lpszShortName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->psn.lpszShortName ); 
-
-     if( lpConn->lpPlayerName->pln.lpszLongName )
-       This->playerName.pln.lpszLongName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->pln.lpszLongName );
-
-  }
-
-  memcpy( &(This->guidSP), &(lpConn->guidSP), sizeof( lpConn->guidSP ) );  
-  
-  This->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->dwAddressSize ); 
-  memcpy( This->lpAddress, lpConn->lpAddress, lpConn->dwAddressSize );
-
-  This->dwAddressSize = lpConn->dwAddressSize;
-
-  return DP_OK;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2WImpl_SetConnectionSettings
-( LPDIRECTPLAYLOBBY2 iface,
-  DWORD dwFlags,
-  DWORD dwAppID,
-  LPDPLCONNECTION lpConn )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobbyW_SetConnectionSettings( (LPDIRECTPLAYLOBBY)This, 
-                                                  dwFlags, dwAppID, lpConn );
-}
-
-static HRESULT WINAPI IDirectPlayLobbyAImpl_SetConnectionSettings
-( LPDIRECTPLAYLOBBYA iface,
-  DWORD dwFlags,
-  DWORD dwAppID,
-  LPDPLCONNECTION lpConn )
-{
-  ICOM_THIS(IDirectPlayLobbyImpl,iface);
-  FIXME(": This=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p: stub\n",
-         This, dwFlags, dwAppID, lpConn );
-  return DPERR_OUTOFMEMORY;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2AImpl_SetConnectionSettings
-( LPDIRECTPLAYLOBBY2A iface,
-  DWORD dwFlags,
-  DWORD dwAppID,
-  LPDPLCONNECTION lpConn )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobbyAImpl_SetConnectionSettings( (LPDIRECTPLAYLOBBYA)This,
-                                                  dwFlags, dwAppID, lpConn );
-}
-
-/********************************************************************
- *
- * Registers an event that will be set when a lobby message is received.
- *
- */
-static HRESULT WINAPI IDirectPlayLobbyAImpl_SetLobbyMessageEvent
-( LPDIRECTPLAYLOBBYA iface,
-  DWORD dwFlags,
-  DWORD dwAppID,
-  HANDLE hReceiveEvent )
-{
-  FIXME(":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2AImpl_SetLobbyMessageEvent
-( LPDIRECTPLAYLOBBY2A iface,
-  DWORD dwFlags,
-  DWORD dwAppID,
-  HANDLE hReceiveEvent )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobbyAImpl_SetLobbyMessageEvent( (LPDIRECTPLAYLOBBYA)This, dwFlags,
-                                                 dwAppID, hReceiveEvent ); 
-}
-
-static HRESULT WINAPI IDirectPlayLobbyW_SetLobbyMessageEvent
-( LPDIRECTPLAYLOBBY iface,
-  DWORD dwFlags,
-  DWORD dwAppID,
-  HANDLE hReceiveEvent )
-{
-  FIXME(":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2WImpl_SetLobbyMessageEvent
-( LPDIRECTPLAYLOBBY2 iface,
-  DWORD dwFlags,
-  DWORD dwAppID,
-  HANDLE hReceiveEvent )
-{
-  ICOM_THIS(IDirectPlayLobby2Impl,iface);
-  return IDirectPlayLobbyW_SetLobbyMessageEvent( (LPDIRECTPLAYLOBBY)This, dwFlags,
-                                                 dwAppID, hReceiveEvent ); 
-}
-
-
-/********************************************************************
- *
- * Registers an event that will be set when a lobby message is received.
- *
- */
-static HRESULT WINAPI IDirectPlayLobby2WImpl_CreateCompoundAddress
-( LPDIRECTPLAYLOBBY2 iface,
-  LPCDPCOMPOUNDADDRESSELEMENT lpElements,
-  DWORD dwElementCount,
-  LPVOID lpAddress,
-  LPDWORD lpdwAddressSize )
-{
-  FIXME(":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
-
-static HRESULT WINAPI IDirectPlayLobby2AImpl_CreateCompoundAddress
-( LPDIRECTPLAYLOBBY2A iface,
-  LPCDPCOMPOUNDADDRESSELEMENT lpElements,
-  DWORD dwElementCount,
-  LPVOID lpAddress,
-  LPDWORD lpdwAddressSize )
-{
-  FIXME(":stub\n");
-  return DPERR_OUTOFMEMORY;
-}
-
-
-/* Note: Hack so we can reuse the old functions without compiler warnings */
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(directPlayLobbyAVT.fn##fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-/* Direct Play Lobby 1 (ascii) Virtual Table for methods */
-/* All lobby 1 methods are exactly the same except QueryInterface */
-static struct ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyAVT = 
-{
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  IDirectPlayLobbyAImpl_QueryInterface,
-  XCAST(AddRef)IDirectPlayLobby2AImpl_AddRef,
-  XCAST(Release)IDirectPlayLobby2AImpl_Release,
-  XCAST(Connect)IDirectPlayLobby2AImpl_Connect,
-  XCAST(CreateAddress)IDirectPlayLobby2AImpl_CreateAddress,
-  XCAST(EnumAddress)IDirectPlayLobby2AImpl_EnumAddress,
-  XCAST(EnumAddressTypes)IDirectPlayLobby2AImpl_EnumAddressTypes,
-  XCAST(EnumLocalApplications)IDirectPlayLobby2AImpl_EnumLocalApplications,
-  XCAST(GetConnectionSettings)IDirectPlayLobby2AImpl_GetConnectionSettings,
-  XCAST(ReceiveLobbyMessage)IDirectPlayLobby2AImpl_ReceiveLobbyMessage,
-  XCAST(RunApplication)IDirectPlayLobby2AImpl_RunApplication,
-  XCAST(SendLobbyMessage)IDirectPlayLobby2AImpl_SendLobbyMessage,
-  XCAST(SetConnectionSettings)IDirectPlayLobby2AImpl_SetConnectionSettings,
-  XCAST(SetLobbyMessageEvent)IDirectPlayLobby2AImpl_SetLobbyMessageEvent
-};
-#undef XCAST
-
-
-/* Note: Hack so we can reuse the old functions without compiler warnings */
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(directPlayLobbyWVT.fn##fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-/* Direct Play Lobby 1 (unicode) Virtual Table for methods */
-static ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyWVT = 
-{
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  IDirectPlayLobbyW_QueryInterface,
-  XCAST(AddRef)IDirectPlayLobby2WImpl_AddRef,
-  XCAST(Release)IDirectPlayLobby2WImpl_Release,
-  XCAST(Connect)IDirectPlayLobby2WImpl_Connect,
-  XCAST(CreateAddress)IDirectPlayLobby2WImpl_CreateAddress, 
-  XCAST(EnumAddress)IDirectPlayLobby2WImpl_EnumAddress,
-  XCAST(EnumAddressTypes)IDirectPlayLobby2WImpl_EnumAddressTypes,
-  XCAST(EnumLocalApplications)IDirectPlayLobby2WImpl_EnumLocalApplications,
-  XCAST(GetConnectionSettings)IDirectPlayLobby2WImpl_GetConnectionSettings,
-  XCAST(ReceiveLobbyMessage)IDirectPlayLobby2WImpl_ReceiveLobbyMessage,
-  XCAST(RunApplication)IDirectPlayLobby2WImpl_RunApplication,
-  XCAST(SendLobbyMessage)IDirectPlayLobby2WImpl_SendLobbyMessage,
-  XCAST(SetConnectionSettings)IDirectPlayLobby2WImpl_SetConnectionSettings,
-  XCAST(SetLobbyMessageEvent)IDirectPlayLobby2WImpl_SetLobbyMessageEvent
-};
-#undef XCAST
-
-
-/* Direct Play Lobby 2 (ascii) Virtual Table for methods */
-static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2AVT = 
-{
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  IDirectPlayLobby2AImpl_QueryInterface,
-  IDirectPlayLobby2AImpl_AddRef,
-  IDirectPlayLobby2AImpl_Release,
-  IDirectPlayLobby2AImpl_Connect,
-  IDirectPlayLobby2AImpl_CreateAddress,
-  IDirectPlayLobby2AImpl_EnumAddress,
-  IDirectPlayLobby2AImpl_EnumAddressTypes,
-  IDirectPlayLobby2AImpl_EnumLocalApplications,
-  IDirectPlayLobby2AImpl_GetConnectionSettings,
-  IDirectPlayLobby2AImpl_ReceiveLobbyMessage,
-  IDirectPlayLobby2AImpl_RunApplication,
-  IDirectPlayLobby2AImpl_SendLobbyMessage,
-  IDirectPlayLobby2AImpl_SetConnectionSettings,
-  IDirectPlayLobby2AImpl_SetLobbyMessageEvent,
-  IDirectPlayLobby2AImpl_CreateCompoundAddress 
-};
-
-/* Direct Play Lobby 2 (unicode) Virtual Table for methods */
-static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2WVT = 
-{
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  IDirectPlayLobby2WImpl_QueryInterface,
-  IDirectPlayLobby2WImpl_AddRef, 
-  IDirectPlayLobby2WImpl_Release,
-  IDirectPlayLobby2WImpl_Connect,
-  IDirectPlayLobby2WImpl_CreateAddress,
-  IDirectPlayLobby2WImpl_EnumAddress,
-  IDirectPlayLobby2WImpl_EnumAddressTypes,
-  IDirectPlayLobby2WImpl_EnumLocalApplications,
-  IDirectPlayLobby2WImpl_GetConnectionSettings,
-  IDirectPlayLobby2WImpl_ReceiveLobbyMessage,
-  IDirectPlayLobby2WImpl_RunApplication,
-  IDirectPlayLobby2WImpl_SendLobbyMessage,
-  IDirectPlayLobby2WImpl_SetConnectionSettings,
-  IDirectPlayLobby2WImpl_SetLobbyMessageEvent,
-  IDirectPlayLobby2WImpl_CreateCompoundAddress
-};
-
-/***************************************************************************
- *  DirectPlayLobbyCreateA   (DPLAYX.4)
- *
- */
-HRESULT WINAPI DirectPlayLobbyCreateA( LPGUID lpGUIDDSP,
-                                       LPDIRECTPLAYLOBBYA *lplpDPL,
-                                       IUnknown *lpUnk, 
-                                       LPVOID lpData,
-                                       DWORD dwDataSize )
-{
-  IDirectPlayLobbyAImpl** ilplpDPL=(IDirectPlayLobbyAImpl**)lplpDPL;
-  TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
-        lpGUIDDSP,ilplpDPL,lpUnk,lpData,dwDataSize);
-
-  /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
-   * equal 0. These fields are mostly for future expansion.
-   */
-  if ( lpGUIDDSP || lpUnk || lpData || dwDataSize )
-  {
-     *ilplpDPL = NULL;
-     return DPERR_INVALIDPARAMS;
-  }
-
-  /* Yes...really we should be returning a lobby 1 object */
-  *ilplpDPL = (IDirectPlayLobbyAImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                            sizeof( IDirectPlayLobbyAImpl ) );
-
-  if( ! (*ilplpDPL) )
-  {
-     return DPERR_OUTOFMEMORY;
-  }
-
-  (*ilplpDPL)->lpvtbl = &directPlayLobbyAVT;
-  (*ilplpDPL)->ref    = 1;
-
-  /* All fields were nulled out by the allocation */
-
-  return DP_OK;
-}
-
-/***************************************************************************
- *  DirectPlayLobbyCreateW   (DPLAYX.5)
- *
- */
-HRESULT WINAPI DirectPlayLobbyCreateW( LPGUID lpGUIDDSP, 
-                                       LPDIRECTPLAYLOBBY *lplpDPL,
-                                       IUnknown *lpUnk,
-                                       LPVOID lpData, 
-                                       DWORD dwDataSize )
-{
-  IDirectPlayLobbyImpl** ilplpDPL=(IDirectPlayLobbyImpl**)lplpDPL;
-  TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
-        lpGUIDDSP,ilplpDPL,lpUnk,lpData,dwDataSize);
-
-  /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must 
-   * equal 0. These fields are mostly for future expansion.
-   */
-  if ( lpGUIDDSP || lpUnk || lpData || dwDataSize )
-  {
-     *ilplpDPL = NULL;
-     ERR("Bad parameters!\n" );
-     return DPERR_INVALIDPARAMS;
-  }
-
-  /* Yes...really we should bre returning a lobby 1 object */
-  *ilplpDPL = (IDirectPlayLobbyImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                           sizeof( IDirectPlayLobbyImpl ) );
-
-  if( !*ilplpDPL)
-  {
-     return DPERR_OUTOFMEMORY;
-  }
-
-  (*ilplpDPL)->lpvtbl = &directPlayLobbyWVT;
-  (*ilplpDPL)->ref    = 1;
-
-  /* All fields were nulled out by the allocation */
-
-  return DP_OK;
-
-}
-
-/***************************************************************************
- *  DirectPlayEnumerateA (DPLAYX.2) 
- *
- *  The pointer to the structure lpContext will be filled with the 
- *  appropriate data for each service offered by the OS. These services are
- *  not necessarily available on this particular machine but are defined
- *  as simple service providers under the "Service Providers" registry key.
- *  This structure is then passed to lpEnumCallback for each of the different 
- *  services. 
- *
- *  This API is useful only for applications written using DirectX3 or
- *  worse. It is superceeded by IDirectPlay3::EnumConnections which also
- *  gives information on the actual connections.
- *
- * defn of a service provider:
- * A dynamic-link library used by DirectPlay to communicate over a network. 
- * The service provider contains all the network-specific code required
- * to send and receive messages. Online services and network operators can
- * supply service providers to use specialized hardware, protocols, communications
- * media, and network resources. 
- *
- * TODO: Allocate string buffer space from the heap (length from reg)
- *       Pass real device driver numbers...
- *       Get the GUID properly...
- */
-HRESULT WINAPI DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback,
-                                     LPVOID lpContext )
-{
-
-  HKEY hkResult; 
-  LPCSTR searchSubKey    = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
-  LPSTR guidDataSubKey   = "Guid";
-  LPSTR majVerDataSubKey = "dwReserved1";
-  DWORD dwIndex, sizeOfSubKeyName=50;
-  char subKeyName[51]; 
-
-  TRACE(": lpEnumCallback=%p lpContext=%p\n", lpEnumCallback, lpContext );
-
-  if( !lpEnumCallback || !*lpEnumCallback )
-  {
-     return DPERR_INVALIDPARAMS;
-  }
-
-  /* Need to loop over the service providers in the registry */
-  if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
-                       0, KEY_ENUMERATE_SUB_KEYS, &hkResult ) != ERROR_SUCCESS )
-  {
-    /* Hmmm. Does this mean that there are no service providers? */ 
-    ERR(": no service providers?\n");
-    return DP_OK; 
-  }
-
-  /* Traverse all the service providers we have available */
-  for( dwIndex=0;
-       RegEnumKeyA( hkResult, dwIndex, subKeyName, sizeOfSubKeyName ) !=
-         ERROR_NO_MORE_ITEMS;
-       ++dwIndex )
-  {
-    HKEY     hkServiceProvider;
-    GUID     serviceProviderGUID;
-    DWORD    returnTypeGUID, returnTypeReserved1, sizeOfReturnBuffer=50;
-    char     returnBuffer[51];
-    DWORD    majVersionNum /*, minVersionNum */;
-    LPWSTR   lpWGUIDString; 
-
-    TRACE(" this time through: %s\n", subKeyName );
-
-    /* Get a handle for this particular service provider */
-    if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_QUERY_VALUE,
-                         &hkServiceProvider ) != ERROR_SUCCESS )
-    {
-      ERR(": what the heck is going on?\n" );
-      continue;
-    }
-
-    /* Get the GUID, Device major number and device minor number 
-     * from the registry. 
-     */
-    if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
-                            NULL, &returnTypeGUID, returnBuffer,
-                            &sizeOfReturnBuffer ) != ERROR_SUCCESS )
-    {
-      ERR(": missing GUID registry data members\n" );
-      continue; 
-    }
-
-    /* FIXME: Check return types to ensure we're interpreting data right */
-    lpWGUIDString = HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer );
-    CLSIDFromString( (LPCOLESTR)lpWGUIDString, &serviceProviderGUID ); 
-    HeapFree( GetProcessHeap(), 0, lpWGUIDString );
-
-    sizeOfReturnBuffer = 50;
- 
-    if( RegQueryValueExA( hkServiceProvider, majVerDataSubKey,
-                            NULL, &returnTypeReserved1, returnBuffer,
-                            &sizeOfReturnBuffer ) != ERROR_SUCCESS )
-    {
-      ERR(": missing dwReserved1 registry data members\n") ;
-      continue; 
-    }
-    /* FIXME: This couldn't possibly be right...*/
-    majVersionNum = GET_DWORD( returnBuffer );
-
-    /* The enumeration will return FALSE if we are not to continue */
-    if( !lpEnumCallback( &serviceProviderGUID , subKeyName,
-                         majVersionNum, (DWORD)0, lpContext ) )
-    {
-      WARN("lpEnumCallback returning FALSE\n" );
-      break;
-    }
-  }
-
-  return DP_OK;
-
-}
-
-/***************************************************************************
- *  DirectPlayEnumerateW (DPLAYX.3)
- *
- */
-HRESULT WINAPI DirectPlayEnumerateW( LPDPENUMDPCALLBACKW lpEnumCallback, LPVOID lpContext )
-{
-
-  FIXME(":stub\n");
-
-  return DPERR_OUTOFMEMORY; 
-
-}
-
-/***************************************************************************
- *  DirectPlayCreate (DPLAYX.1) (DPLAY.1)
- *
- */
-HRESULT WINAPI DirectPlayCreate
-( LPGUID lpGUID, LPDIRECTPLAY2 *lplpDP, IUnknown *pUnk)
-{
-
-  TRACE("lpGUID=%p lplpDP=%p pUnk=%p\n", lpGUID,lplpDP,pUnk);
-
-  if( pUnk != NULL )
-  {
-    /* Hmmm...wonder what this means! */
-    ERR("What does a NULL here mean?\n" ); 
-    return DPERR_OUTOFMEMORY;
-  }
-
-  if( IsEqualGUID( &IID_IDirectPlay2A, lpGUID ) )
-  {
-    IDirectPlay2AImpl** ilplpDP=(IDirectPlay2AImpl**)lplpDP;
-    *ilplpDP = (IDirectPlay2AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                         sizeof( **ilplpDP ) );
-
-    if( !*ilplpDP )
-    {
-       return DPERR_OUTOFMEMORY;
-    }
-
-    (*ilplpDP)->lpvtbl = &directPlay2AVT;
-    (*ilplpDP)->ref    = 1;
-  
-    return DP_OK;
-  }
-  else if( IsEqualGUID( &IID_IDirectPlay2, lpGUID ) )
-  {
-    IDirectPlay2Impl** ilplpDP=(IDirectPlay2Impl**)lplpDP;
-    *ilplpDP = (IDirectPlay2Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                        sizeof( **ilplpDP ) );
-
-    if( !*ilplpDP )
-    {
-       return DPERR_OUTOFMEMORY;
-    }
-
-    (*ilplpDP)->lpvtbl = &directPlay2WVT;
-    (*ilplpDP)->ref    = 1;
-
-    return DP_OK;
-  }
-
-  /* Unknown interface type */
-  return DPERR_NOINTERFACE;
-
-}
-
-/* Direct Play helper methods */
-
-/* Get a new interface. To be used by QueryInterface. */ 
-static HRESULT directPlay_QueryInterface 
-         ( REFIID riid, LPVOID* ppvObj )
-{
-
-  if( IsEqualGUID( &IID_IDirectPlay2, riid ) )
-  {
-    IDirectPlay2Impl* lpDP = (IDirectPlay2Impl*)*ppvObj;
-
-    lpDP = (IDirectPlay2Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                      sizeof( *lpDP ) );
-
-    if( !lpDP ) 
-    {
-       return DPERR_OUTOFMEMORY;
-    }
-
-    lpDP->lpvtbl = &directPlay2WVT;
-    lpDP->ref    = 1;
-
-    return S_OK;
-  } 
-  else if( IsEqualGUID( &IID_IDirectPlay2A, riid ) )
-  {
-    IDirectPlay2AImpl* lpDP = (IDirectPlay2AImpl*)*ppvObj;
-
-    lpDP = (IDirectPlay2AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                      sizeof( *lpDP ) );
-
-    if( !lpDP )
-    {
-       return DPERR_OUTOFMEMORY;
-    }
-
-    lpDP->lpvtbl = &directPlay2AVT;
-    lpDP->ref    = 1;
-
-    return S_OK;
-  }
-  else if( IsEqualGUID( &IID_IDirectPlay3, riid ) )
-  {
-    IDirectPlay3Impl* lpDP = (IDirectPlay3Impl*)*ppvObj;
-
-    lpDP = (IDirectPlay3Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                      sizeof( *lpDP ) );
-
-    if( !lpDP )
-    {
-       return DPERR_OUTOFMEMORY;
-    }
-
-    lpDP->lpvtbl = &directPlay3WVT;
-    lpDP->ref    = 1;
-
-    return S_OK;
-  }
-  else if( IsEqualGUID( &IID_IDirectPlay3A, riid ) )
-  {
-    IDirectPlay3AImpl* lpDP = (IDirectPlay3AImpl*)*ppvObj;
-
-    lpDP = (IDirectPlay3AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                      sizeof( *lpDP ) );
-
-    if( !lpDP )
-    {
-       return DPERR_OUTOFMEMORY;
-    }
-
-    lpDP->lpvtbl = &directPlay3AVT;
-    lpDP->ref    = 1;
-
-    return S_OK;
-
-  }
-
-  *ppvObj = NULL;
-  return E_NOINTERFACE;
-}
-
-
-/* Direct Play methods */
-static HRESULT WINAPI DirectPlay2W_QueryInterface
-         ( LPDIRECTPLAY2 iface, REFIID riid, LPVOID* ppvObj )
-{
-  ICOM_THIS(IDirectPlay2Impl,iface);
-  TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
-
-  if( IsEqualGUID( &IID_IUnknown, riid ) ||
-      IsEqualGUID( &IID_IDirectPlay2, riid )
-    )
-  {
-    IDirectPlay2_AddRef( iface );
-    *ppvObj = This;
-    return S_OK;
-  }
-  return directPlay_QueryInterface( riid, ppvObj );
-}
-
-static HRESULT WINAPI DirectPlay2A_QueryInterface
-         ( LPDIRECTPLAY2A iface, REFIID riid, LPVOID* ppvObj )
-{
-  ICOM_THIS(IDirectPlay2Impl,iface);
-  TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
-
-  if( IsEqualGUID( &IID_IUnknown, riid ) ||
-      IsEqualGUID( &IID_IDirectPlay2A, riid )
-    )
-  {
-    IDirectPlay2_AddRef( iface );
-    *ppvObj = This;
-    return S_OK;
-  }
-
-  return directPlay_QueryInterface( riid, ppvObj );
-}
-
-static HRESULT WINAPI DirectPlay3WImpl_QueryInterface
-         ( LPDIRECTPLAY3 iface, REFIID riid, LPVOID* ppvObj )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
-
-  if( IsEqualGUID( &IID_IUnknown, riid ) ||
-      IsEqualGUID( &IID_IDirectPlay3, riid )
-    )
-  {
-    IDirectPlay3_AddRef( iface );
-    *ppvObj = This;
-    return S_OK;
-  }
-
-  return directPlay_QueryInterface( riid, ppvObj );
-}
-
-static HRESULT WINAPI DirectPlay3A_QueryInterface
-         ( LPDIRECTPLAY3A iface, REFIID riid, LPVOID* ppvObj )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
-
-  if( IsEqualGUID( &IID_IUnknown, riid ) ||
-      IsEqualGUID( &IID_IDirectPlay3A, riid )
-    )
-  {
-    IDirectPlay3_AddRef( iface );
-    *ppvObj = This;
-    return S_OK;
-  }
-
-  return directPlay_QueryInterface( riid, ppvObj );
-}
-
-
-/* Shared between all dplay types */
-static ULONG WINAPI DirectPlay3WImpl_AddRef
-         ( LPDIRECTPLAY3 iface )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  ++(This->ref);
-  TRACE("ref count now %lu\n", This->ref );
-  return (This->ref);
-}
-
-static ULONG WINAPI DirectPlay3WImpl_Release
-( LPDIRECTPLAY3 iface )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  TRACE("ref count decremeneted from %lu\n", This->ref );
-
-  This->ref--;
-
-  /* Deallocate if this is the last reference to the object */
-  if( !(This->ref) )
-  {
-    FIXME("memory leak\n" );
-    /* Implement memory deallocation */
-
-    HeapFree( GetProcessHeap(), 0, This );
-
-    return 0;
-  }
-
-  return This->ref;
-}
-
-static ULONG WINAPI DirectPlay3A_Release
-( LPDIRECTPLAY3A iface )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  TRACE("ref count decremeneted from %lu\n", This->ref );
-
-  This->ref--;
-
-  /* Deallocate if this is the last reference to the object */
-  if( !(This->ref) )
-  {
-    FIXME("memory leak\n" );
-    /* Implement memory deallocation */
-
-    HeapFree( GetProcessHeap(), 0, This );
-
-    return 0;
-  }
-
-  return This->ref;
-}
-
-HRESULT WINAPI DirectPlay3A_AddPlayerToGroup
-          ( LPDIRECTPLAY3A iface, DPID a, DPID b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_AddPlayerToGroup
-          ( LPDIRECTPLAY3 iface, DPID a, DPID b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-
-HRESULT WINAPI DirectPlay3A_Close
-          ( LPDIRECTPLAY3A iface )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(): stub", This );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_Close
-          ( LPDIRECTPLAY3 iface )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(): stub", This );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_CreateGroup
-          ( LPDIRECTPLAY3A iface, LPDPID a, LPDPNAME b, LPVOID c, DWORD d, DWORD e )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,%p,%p,0x%08lx,0x%08lx): stub", This, a, b, c, d, e );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_CreateGroup
-          ( LPDIRECTPLAY3 iface, LPDPID a, LPDPNAME b, LPVOID c, DWORD d, DWORD e )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,%p,%p,0x%08lx,0x%08lx): stub", This, a, b, c, d, e );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_CreatePlayer
-          ( LPDIRECTPLAY3A iface, LPDPID a, LPDPNAME b, HANDLE c, LPVOID d, DWORD e, DWORD f )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx): stub", This, a, b, c, d, e, f );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_CreatePlayer
-          ( LPDIRECTPLAY3 iface, LPDPID a, LPDPNAME b, HANDLE c, LPVOID d, DWORD e, DWORD f )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx): stub", This, a, b, c, d, e, f );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_DeletePlayerFromGroup
-          ( LPDIRECTPLAY3A iface, DPID a, DPID b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_DeletePlayerFromGroup
-          ( LPDIRECTPLAY3 iface, DPID a, DPID b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_DestroyGroup
-          ( LPDIRECTPLAY3A iface, DPID a )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx): stub", This, a );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_DestroyGroup
-          ( LPDIRECTPLAY3 iface, DPID a )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx): stub", This, a );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_DestroyPlayer
-          ( LPDIRECTPLAY3A iface, DPID a )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx): stub", This, a );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_DestroyPlayer
-          ( LPDIRECTPLAY3 iface, DPID a )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx): stub", This, a );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_EnumGroupPlayers
-          ( LPDIRECTPLAY3A iface, DPID a, LPGUID b, LPDPENUMPLAYERSCALLBACK2 c,
-            LPVOID d, DWORD e )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub", This, a, b, c, d, e );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_EnumGroupPlayers
-          ( LPDIRECTPLAY3 iface, DPID a, LPGUID b, LPDPENUMPLAYERSCALLBACK2 c,
-            LPVOID d, DWORD e )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub", This, a, b, c, d, e );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_EnumGroups
-          ( LPDIRECTPLAY3A iface, LPGUID a, LPDPENUMPLAYERSCALLBACK2 b, LPVOID c, DWORD d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,%p,%p,0x%08lx): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_EnumGroups
-          ( LPDIRECTPLAY3 iface, LPGUID a, LPDPENUMPLAYERSCALLBACK2 b, LPVOID c, DWORD d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,%p,%p,0x%08lx): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_EnumPlayers
-          ( LPDIRECTPLAY3A iface, LPGUID a, LPDPENUMPLAYERSCALLBACK2 b, LPVOID c, DWORD d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,%p,%p,0x%08lx): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_EnumPlayers
-          ( LPDIRECTPLAY3 iface, LPGUID a, LPDPENUMPLAYERSCALLBACK2 b, LPVOID c, DWORD d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,%p,%p,0x%08lx): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_EnumSessions
-          ( LPDIRECTPLAY3A iface, LPDPSESSIONDESC2 a, DWORD b, LPDPENUMSESSIONSCALLBACK2 c,
-            LPVOID d, DWORD e )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,0x%08lx,%p,%p,0x%08lx): stub", This, a, b, c, d, e );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_EnumSessions
-          ( LPDIRECTPLAY3 iface, LPDPSESSIONDESC2 a, DWORD b, LPDPENUMSESSIONSCALLBACK2 c,
-            LPVOID d, DWORD e )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,0x%08lx,%p,%p,0x%08lx): stub", This, a, b, c, d, e );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_GetCaps
-          ( LPDIRECTPLAY3A iface, LPDPCAPS a, DWORD b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_GetCaps
-          ( LPDIRECTPLAY3 iface, LPDPCAPS a, DWORD b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_GetGroupData
-          ( LPDIRECTPLAY3 iface, DPID a, LPVOID b, LPDWORD c, DWORD d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_GetGroupData
-          ( LPDIRECTPLAY3 iface, DPID a, LPVOID b, LPDWORD c, DWORD d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_GetGroupName
-          ( LPDIRECTPLAY3A iface, DPID a, LPVOID b, LPDWORD c )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p): stub", This, a, b, c );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_GetGroupName
-          ( LPDIRECTPLAY3 iface, DPID a, LPVOID b, LPDWORD c )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p): stub", This, a, b, c );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_GetMessageCount
-          ( LPDIRECTPLAY3A iface, DPID a, LPDWORD b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_GetMessageCount
-          ( LPDIRECTPLAY3 iface, DPID a, LPDWORD b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_GetPlayerAddress
-          ( LPDIRECTPLAY3A iface, DPID a, LPVOID b, LPDWORD c )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p): stub", This, a, b, c );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_GetPlayerAddress
-          ( LPDIRECTPLAY3 iface, DPID a, LPVOID b, LPDWORD c )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p): stub", This, a, b, c );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_GetPlayerCaps
-          ( LPDIRECTPLAY3A iface, DPID a, LPDPCAPS b, DWORD c )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub", This, a, b, c );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_GetPlayerCaps
-          ( LPDIRECTPLAY3 iface, DPID a, LPDPCAPS b, DWORD c )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub", This, a, b, c );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_GetPlayerData
-          ( LPDIRECTPLAY3A iface, DPID a, LPVOID b, LPDWORD c, DWORD d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_GetPlayerData
-          ( LPDIRECTPLAY3 iface, DPID a, LPVOID b, LPDWORD c, DWORD d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_GetPlayerName
-          ( LPDIRECTPLAY3 iface, DPID a, LPVOID b, LPDWORD c )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p): stub", This, a, b, c );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_GetPlayerName
-          ( LPDIRECTPLAY3 iface, DPID a, LPVOID b, LPDWORD c )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p): stub", This, a, b, c );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_GetSessionDesc
-          ( LPDIRECTPLAY3A iface, LPVOID a, LPDWORD b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,%p): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_GetSessionDesc
-          ( LPDIRECTPLAY3 iface, LPVOID a, LPDWORD b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,%p): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_Initialize
-          ( LPDIRECTPLAY3A iface, LPGUID a )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p): stub", This, a );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_Initialize
-          ( LPDIRECTPLAY3 iface, LPGUID a )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p): stub", This, a );
-  return DP_OK;
-}
-
-
-HRESULT WINAPI DirectPlay3A_Open
-          ( LPDIRECTPLAY3A iface, LPDPSESSIONDESC2 a, DWORD b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_Open
-          ( LPDIRECTPLAY3 iface, LPDPSESSIONDESC2 a, DWORD b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_Receive
-          ( LPDIRECTPLAY3A iface, LPDPID a, LPDPID b, DWORD c, LPVOID d, LPDWORD e )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,%p,0x%08lx,%p,%p): stub", This, a, b, c, d, e );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_Receive
-          ( LPDIRECTPLAY3 iface, LPDPID a, LPDPID b, DWORD c, LPVOID d, LPDWORD e )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,%p,0x%08lx,%p,%p): stub", This, a, b, c, d, e );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_Send
-          ( LPDIRECTPLAY3A iface, DPID a, DPID b, DWORD c, LPVOID d, DWORD e )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx): stub", This, a, b, c, d, e );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_Send
-          ( LPDIRECTPLAY3 iface, DPID a, DPID b, DWORD c, LPVOID d, DWORD e )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx): stub", This, a, b, c, d, e );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_SetGroupData
-          ( LPDIRECTPLAY3A iface, DPID a, LPVOID b, DWORD c, DWORD d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_SetGroupData
-          ( LPDIRECTPLAY3 iface, DPID a, LPVOID b, DWORD c, DWORD d )
-{   
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_SetGroupName
-          ( LPDIRECTPLAY3A iface, DPID a, LPDPNAME b, DWORD c )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub", This, a, b, c );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_SetGroupName
-          ( LPDIRECTPLAY3 iface, DPID a, LPDPNAME b, DWORD c )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub", This, a, b, c );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_SetPlayerData
-          ( LPDIRECTPLAY3A iface, DPID a, LPVOID b, DWORD c, DWORD d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_SetPlayerData
-          ( LPDIRECTPLAY3 iface, DPID a, LPVOID b, DWORD c, DWORD d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_SetPlayerName
-          ( LPDIRECTPLAY3A iface, DPID a, LPDPNAME b, DWORD c )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub", This, a, b, c );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_SetPlayerName
-          ( LPDIRECTPLAY3 iface, DPID a, LPDPNAME b, DWORD c )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub", This, a, b, c );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_SetSessionDesc
-          ( LPDIRECTPLAY3A iface, LPDPSESSIONDESC2 a, DWORD b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_SetSessionDesc
-          ( LPDIRECTPLAY3 iface, LPDPSESSIONDESC2 a, DWORD b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_AddGroupToGroup
-          ( LPDIRECTPLAY3A iface, DPID a, DPID b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_AddGroupToGroup
-          ( LPDIRECTPLAY3 iface, DPID a, DPID b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_CreateGroupInGroup
-          ( LPDIRECTPLAY3A iface, DPID a, LPDPID b, LPDPNAME c, LPVOID d, DWORD e, DWORD f )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx): stub", This, a, b, c, d, e, f );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_CreateGroupInGroup
-          ( LPDIRECTPLAY3 iface, DPID a, LPDPID b, LPDPNAME c, LPVOID d, DWORD e, DWORD f )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx): stub", This, a, b, c, d, e, f );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_DeleteGroupFromGroup
-          ( LPDIRECTPLAY3A iface, DPID a, DPID b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_DeleteGroupFromGroup
-          ( LPDIRECTPLAY3 iface, DPID a, DPID b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_EnumConnections
-          ( LPDIRECTPLAY3A iface, LPCGUID a, LPDPENUMCONNECTIONSCALLBACK b, LPVOID c, DWORD d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,%p,%p,0x%08lx): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_EnumConnections
-          ( LPDIRECTPLAY3 iface, LPCGUID a, LPDPENUMCONNECTIONSCALLBACK b, LPVOID c, DWORD d )
-{ 
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,%p,%p,0x%08lx): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_EnumGroupsInGroup
-          ( LPDIRECTPLAY3A iface, DPID a, LPGUID b, LPDPENUMPLAYERSCALLBACK2 c, LPVOID d, DWORD e )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub", This, a, b, c, d, e );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_EnumGroupsInGroup
-          ( LPDIRECTPLAY3 iface, DPID a, LPGUID b, LPDPENUMPLAYERSCALLBACK2 c, LPVOID d, DWORD e )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub", This, a, b, c, d, e );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_GetGroupConnectionSettings
-          ( LPDIRECTPLAY3A iface, DWORD a, DPID b, LPVOID c, LPDWORD d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_GetGroupConnectionSettings
-          ( LPDIRECTPLAY3 iface, DWORD a, DPID b, LPVOID c, LPDWORD d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_InitializeConnection
-          ( LPDIRECTPLAY3A iface, LPVOID a, DWORD b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_InitializeConnection
-          ( LPDIRECTPLAY3 iface, LPVOID a, DWORD b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_SecureOpen
-          ( LPDIRECTPLAY3A iface, LPCDPSESSIONDESC2 a, DWORD b, LPCDPSECURITYDESC c, LPCDPCREDENTIALS d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,0x%08lx,%p,%p): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_SecureOpen
-          ( LPDIRECTPLAY3 iface, LPCDPSESSIONDESC2 a, DWORD b, LPCDPSECURITYDESC c, LPCDPCREDENTIALS d )
-{   
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(%p,0x%08lx,%p,%p): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_SendChatMessage
-          ( LPDIRECTPLAY3A iface, DPID a, DPID b, DWORD c, LPDPCHAT d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_SendChatMessage
-          ( LPDIRECTPLAY3 iface, DPID a, DPID b, DWORD c, LPDPCHAT d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_SetGroupConnectionSettings
-          ( LPDIRECTPLAY3A iface, DWORD a, DPID b, LPDPLCONNECTION c )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx,%p): stub", This, a, b, c );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_SetGroupConnectionSettings
-          ( LPDIRECTPLAY3 iface, DWORD a, DPID b, LPDPLCONNECTION c )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx,%p): stub", This, a, b, c );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_StartSession
-          ( LPDIRECTPLAY3A iface, DWORD a, DPID b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_StartSession
-          ( LPDIRECTPLAY3 iface, DWORD a, DPID b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx): stub", This, a, b );
-  return DP_OK;
-}
- 
-HRESULT WINAPI DirectPlay3A_GetGroupFlags
-          ( LPDIRECTPLAY3A iface, DPID a, LPDWORD b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_GetGroupFlags
-          ( LPDIRECTPLAY3 iface, DPID a, LPDWORD b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_GetGroupParent
-          ( LPDIRECTPLAY3A iface, DPID a, LPDPID b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_GetGroupParent
-          ( LPDIRECTPLAY3 iface, DPID a, LPDPID b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_GetPlayerAccount
-          ( LPDIRECTPLAY3A iface, DPID a, DWORD b, LPVOID c, LPDWORD d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_GetPlayerAccount
-          ( LPDIRECTPLAY3 iface, DPID a, DWORD b, LPVOID c, LPDWORD d )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub", This, a, b, c, d );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3A_GetPlayerFlags
-          ( LPDIRECTPLAY3A iface, DPID a, LPDWORD b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p): stub", This, a, b );
-  return DP_OK;
-}
-
-HRESULT WINAPI DirectPlay3WImpl_GetPlayerFlags
-          ( LPDIRECTPLAY3 iface, DPID a, LPDWORD b )
-{
-  ICOM_THIS(IDirectPlay3Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p): stub", This, a, b );
-  return DP_OK;
-}
-
-
-/* Note: Hack so we can reuse the old functions without compiler warnings */
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(directPlay2WVT.fn##fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static ICOM_VTABLE(IDirectPlay2) directPlay2WVT = 
-{
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  DirectPlay2W_QueryInterface,
-  XCAST(AddRef)DirectPlay3WImpl_AddRef,
-  XCAST(Release)DirectPlay3WImpl_Release,
-  XCAST(AddPlayerToGroup)DirectPlay3WImpl_AddPlayerToGroup,
-  XCAST(Close)DirectPlay3WImpl_Close,
-  XCAST(CreateGroup)DirectPlay3WImpl_CreateGroup,
-  XCAST(CreatePlayer)DirectPlay3WImpl_CreatePlayer,
-  XCAST(DeletePlayerFromGroup)DirectPlay3WImpl_DeletePlayerFromGroup,
-  XCAST(DestroyGroup)DirectPlay3WImpl_DestroyGroup,
-  XCAST(DestroyPlayer)DirectPlay3WImpl_DestroyPlayer,
-  XCAST(EnumGroupPlayers)DirectPlay3WImpl_EnumGroupPlayers,
-  XCAST(EnumGroups)DirectPlay3WImpl_EnumGroups,
-  XCAST(EnumPlayers)DirectPlay3WImpl_EnumPlayers,
-  XCAST(EnumSessions)DirectPlay3WImpl_EnumSessions,
-  XCAST(GetCaps)DirectPlay3WImpl_GetCaps,
-  XCAST(GetGroupData)DirectPlay3WImpl_GetGroupData,
-  XCAST(GetGroupName)DirectPlay3WImpl_GetGroupName,
-  XCAST(GetMessageCount)DirectPlay3WImpl_GetMessageCount,
-  XCAST(GetPlayerAddress)DirectPlay3WImpl_GetPlayerAddress,
-  XCAST(GetPlayerCaps)DirectPlay3WImpl_GetPlayerCaps,
-  XCAST(GetPlayerData)DirectPlay3WImpl_GetPlayerData,
-  XCAST(GetPlayerName)DirectPlay3WImpl_GetPlayerName,
-  XCAST(GetSessionDesc)DirectPlay3WImpl_GetSessionDesc,
-  XCAST(Initialize)DirectPlay3WImpl_Initialize,
-  XCAST(Open)DirectPlay3WImpl_Open,
-  XCAST(Receive)DirectPlay3WImpl_Receive,
-  XCAST(Send)DirectPlay3WImpl_Send,
-  XCAST(SetGroupData)DirectPlay3WImpl_SetGroupData,
-  XCAST(SetGroupName)DirectPlay3WImpl_SetGroupName,
-  XCAST(SetPlayerData)DirectPlay3WImpl_SetPlayerData,
-  XCAST(SetPlayerName)DirectPlay3WImpl_SetPlayerName,
-  XCAST(SetSessionDesc)DirectPlay3WImpl_SetSessionDesc
-};
-#undef XCAST
-
-
-/* Note: Hack so we can reuse the old functions without compiler warnings */
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)     (typeof(directPlay2AVT.fn##fun))
-#else
-# define XCAST(fun)     (void*)
-#endif
-
-static ICOM_VTABLE(IDirectPlay2) directPlay2AVT = 
-{
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  DirectPlay2A_QueryInterface,
-  XCAST(AddRef)DirectPlay3WImpl_AddRef,
-  XCAST(Release)DirectPlay3A_Release,
-  XCAST(AddPlayerToGroup)DirectPlay3A_AddPlayerToGroup,
-  XCAST(Close)DirectPlay3A_Close,
-  XCAST(CreateGroup)DirectPlay3A_CreateGroup,
-  XCAST(CreatePlayer)DirectPlay3A_CreatePlayer,
-  XCAST(DeletePlayerFromGroup)DirectPlay3A_DeletePlayerFromGroup,
-  XCAST(DestroyGroup)DirectPlay3A_DestroyGroup,
-  XCAST(DestroyPlayer)DirectPlay3A_DestroyPlayer,
-  XCAST(EnumGroupPlayers)DirectPlay3A_EnumGroupPlayers,
-  XCAST(EnumGroups)DirectPlay3A_EnumGroups,
-  XCAST(EnumPlayers)DirectPlay3A_EnumPlayers,
-  XCAST(EnumSessions)DirectPlay3A_EnumSessions,
-  XCAST(GetCaps)DirectPlay3A_GetCaps,
-  XCAST(GetGroupData)DirectPlay3A_GetGroupData,
-  XCAST(GetGroupName)DirectPlay3A_GetGroupName,
-  XCAST(GetMessageCount)DirectPlay3A_GetMessageCount,
-  XCAST(GetPlayerAddress)DirectPlay3A_GetPlayerAddress,
-  XCAST(GetPlayerCaps)DirectPlay3A_GetPlayerCaps,
-  XCAST(GetPlayerData)DirectPlay3A_GetPlayerData,
-  XCAST(GetPlayerName)DirectPlay3A_GetPlayerName,
-  XCAST(GetSessionDesc)DirectPlay3A_GetSessionDesc,
-  XCAST(Initialize)DirectPlay3A_Initialize,
-  XCAST(Open)DirectPlay3A_Open,
-  XCAST(Receive)DirectPlay3A_Receive,
-  XCAST(Send)DirectPlay3A_Send,
-  XCAST(SetGroupData)DirectPlay3A_SetGroupData,
-  XCAST(SetGroupName)DirectPlay3A_SetGroupName,
-  XCAST(SetPlayerData)DirectPlay3A_SetPlayerData,
-  XCAST(SetPlayerName)DirectPlay3A_SetPlayerName,
-  XCAST(SetSessionDesc)DirectPlay3A_SetSessionDesc
-};
-#undef XCAST
-
-
-static ICOM_VTABLE(IDirectPlay3) directPlay3AVT = 
-{
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  DirectPlay3A_QueryInterface,
-  DirectPlay3WImpl_AddRef,
-  DirectPlay3A_Release,
-  DirectPlay3A_AddPlayerToGroup,
-  DirectPlay3A_Close,
-  DirectPlay3A_CreateGroup,
-  DirectPlay3A_CreatePlayer,
-  DirectPlay3A_DeletePlayerFromGroup,
-  DirectPlay3A_DestroyGroup,
-  DirectPlay3A_DestroyPlayer,
-  DirectPlay3A_EnumGroupPlayers,
-  DirectPlay3A_EnumGroups,
-  DirectPlay3A_EnumPlayers,
-  DirectPlay3A_EnumSessions,
-  DirectPlay3A_GetCaps,
-  DirectPlay3A_GetGroupData,
-  DirectPlay3A_GetGroupName,
-  DirectPlay3A_GetMessageCount,
-  DirectPlay3A_GetPlayerAddress,
-  DirectPlay3A_GetPlayerCaps,
-  DirectPlay3A_GetPlayerData,
-  DirectPlay3A_GetPlayerName,
-  DirectPlay3A_GetSessionDesc,
-  DirectPlay3A_Initialize,
-  DirectPlay3A_Open,
-  DirectPlay3A_Receive,
-  DirectPlay3A_Send,
-  DirectPlay3A_SetGroupData,
-  DirectPlay3A_SetGroupName,
-  DirectPlay3A_SetPlayerData,
-  DirectPlay3A_SetPlayerName,
-  DirectPlay3A_SetSessionDesc,
-
-  DirectPlay3A_AddGroupToGroup,
-  DirectPlay3A_CreateGroupInGroup,
-  DirectPlay3A_DeleteGroupFromGroup,
-  DirectPlay3A_EnumConnections,
-  DirectPlay3A_EnumGroupsInGroup,
-  DirectPlay3A_GetGroupConnectionSettings,
-  DirectPlay3A_InitializeConnection,
-  DirectPlay3A_SecureOpen,
-  DirectPlay3A_SendChatMessage,
-  DirectPlay3A_SetGroupConnectionSettings,
-  DirectPlay3A_StartSession,
-  DirectPlay3A_GetGroupFlags,
-  DirectPlay3A_GetGroupParent,
-  DirectPlay3A_GetPlayerAccount,
-  DirectPlay3A_GetPlayerFlags
-};
-
-static ICOM_VTABLE(IDirectPlay3) directPlay3WVT = 
-{
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  DirectPlay3WImpl_QueryInterface,
-  DirectPlay3WImpl_AddRef,
-  DirectPlay3WImpl_Release,
-  DirectPlay3WImpl_AddPlayerToGroup,
-  DirectPlay3WImpl_Close,
-  DirectPlay3WImpl_CreateGroup,
-  DirectPlay3WImpl_CreatePlayer,
-  DirectPlay3WImpl_DeletePlayerFromGroup,
-  DirectPlay3WImpl_DestroyGroup,
-  DirectPlay3WImpl_DestroyPlayer,
-  DirectPlay3WImpl_EnumGroupPlayers,
-  DirectPlay3WImpl_EnumGroups,
-  DirectPlay3WImpl_EnumPlayers,
-  DirectPlay3WImpl_EnumSessions,
-  DirectPlay3WImpl_GetCaps,
-  DirectPlay3WImpl_GetGroupData,
-  DirectPlay3WImpl_GetGroupName,
-  DirectPlay3WImpl_GetMessageCount,
-  DirectPlay3WImpl_GetPlayerAddress,
-  DirectPlay3WImpl_GetPlayerCaps,
-  DirectPlay3WImpl_GetPlayerData,
-  DirectPlay3WImpl_GetPlayerName,
-  DirectPlay3WImpl_GetSessionDesc,
-  DirectPlay3WImpl_Initialize,
-  DirectPlay3WImpl_Open,
-  DirectPlay3WImpl_Receive,
-  DirectPlay3WImpl_Send,
-  DirectPlay3WImpl_SetGroupData,
-  DirectPlay3WImpl_SetGroupName,
-  DirectPlay3WImpl_SetPlayerData,
-  DirectPlay3WImpl_SetPlayerName,
-  DirectPlay3WImpl_SetSessionDesc,
-
-  DirectPlay3WImpl_AddGroupToGroup,
-  DirectPlay3WImpl_CreateGroupInGroup,
-  DirectPlay3WImpl_DeleteGroupFromGroup,
-  DirectPlay3WImpl_EnumConnections,
-  DirectPlay3WImpl_EnumGroupsInGroup,
-  DirectPlay3WImpl_GetGroupConnectionSettings,
-  DirectPlay3WImpl_InitializeConnection,
-  DirectPlay3WImpl_SecureOpen,
-  DirectPlay3WImpl_SendChatMessage,
-  DirectPlay3WImpl_SetGroupConnectionSettings,
-  DirectPlay3WImpl_StartSession,
-  DirectPlay3WImpl_GetGroupFlags,
-  DirectPlay3WImpl_GetGroupParent,
-  DirectPlay3WImpl_GetPlayerAccount,
-  DirectPlay3WImpl_GetPlayerFlags
-};
diff --git a/relay32/.cvsignore b/relay32/.cvsignore
index 63c0ec2..0375e53 100644
--- a/relay32/.cvsignore
+++ b/relay32/.cvsignore
@@ -2,8 +2,6 @@
 call32.s
 ddraw.spec.c
 dinput.spec.c
-dplay.spec.c
-dplayx.spec.c
 dsound.spec.c
 gdi32.spec.c
 kernel32.spec.c
diff --git a/relay32/Makefile.in b/relay32/Makefile.in
index 2005ff4..bdd7bb6 100644
--- a/relay32/Makefile.in
+++ b/relay32/Makefile.in
@@ -8,8 +8,6 @@
 SPEC_SRCS = \
 	ddraw.spec \
 	dinput.spec \
-	dplay.spec \
-	dplayx.spec \
 	dsound.spec \
 	gdi32.spec \
 	kernel32.spec \
diff --git a/relay32/dplay.spec b/relay32/dplay.spec
deleted file mode 100644
index 6722363..0000000
--- a/relay32/dplay.spec
+++ /dev/null
@@ -1,5 +0,0 @@
-name dplay
-type win32
-
-  1 stdcall DirectPlayCreate(ptr ptr ptr ptr) DirectPlayCreate
-  2 stdcall DirectPlayEnumerate(ptr ptr) DirectPlayEnumerateA