Addin wine 0.9 dplay and dplayx it is directx core for network and tested in windows and not in reactos. 
it is working in windows.
Modified: trunk/reactos/lib/directory.xml
Added: trunk/reactos/lib/dplay/
Added: trunk/reactos/lib/dplay/dplay.spec
Added: trunk/reactos/lib/dplay/dplay.xml
Added: trunk/reactos/lib/dplay/dplay_main.c
Added: trunk/reactos/lib/dplay/version.rc
Added: trunk/reactos/lib/dplayx/
Added: trunk/reactos/lib/dplayx/dpclassfactory.c
Added: trunk/reactos/lib/dplayx/dpinit.h
Added: trunk/reactos/lib/dplayx/dplay.c
Added: trunk/reactos/lib/dplayx/dplay_global.h
Added: trunk/reactos/lib/dplayx/dplaysp.c
Added: trunk/reactos/lib/dplayx/dplaysp.h
Added: trunk/reactos/lib/dplayx/dplayx.spec
Added: trunk/reactos/lib/dplayx/dplayx.xml
Added: trunk/reactos/lib/dplayx/dplayx_global.c
Added: trunk/reactos/lib/dplayx/dplayx_global.h
Added: trunk/reactos/lib/dplayx/dplayx_main.c
Added: trunk/reactos/lib/dplayx/dplayx_messages.c
Added: trunk/reactos/lib/dplayx/dplayx_messages.h
Added: trunk/reactos/lib/dplayx/dplayx_queue.h
Added: trunk/reactos/lib/dplayx/dplobby.c
Added: trunk/reactos/lib/dplayx/lobbysp.c
Added: trunk/reactos/lib/dplayx/lobbysp.h
Added: trunk/reactos/lib/dplayx/name_server.c
Added: trunk/reactos/lib/dplayx/name_server.h
Added: trunk/reactos/lib/dplayx/regsvr.c
Added: trunk/reactos/lib/dplayx/version.rc

Modified: trunk/reactos/lib/directory.xml
--- trunk/reactos/lib/directory.xml	2005-10-27 22:05:46 UTC (rev 18810)
+++ trunk/reactos/lib/directory.xml	2005-10-27 22:10:33 UTC (rev 18811)
@@ -62,6 +62,12 @@
 <directory name="dnsapi">
 	<xi:include href="dnsapi/dnsapi.xml" />
 </directory>
+<directory name="dplay">
+	<xi:include href="dplay/dplay.xml" />
+</directory>
+<directory name="dplayx">
+	<xi:include href="dplayx/dplayx.xml" />
+</directory>
 <directory name="dsound">
 	<xi:include href="dsound/dsound.xml" />
 </directory>

Added: trunk/reactos/lib/dplay/dplay.spec
--- trunk/reactos/lib/dplay/dplay.spec	2005-10-27 22:05:46 UTC (rev 18810)
+++ trunk/reactos/lib/dplay/dplay.spec	2005-10-27 22:10:33 UTC (rev 18811)
@@ -0,0 +1,4 @@
+# First DirectPlay dll. Replaced by dplayx.dll.
+
+@ stdcall DirectPlayCreate(ptr ptr ptr) dplayx.DirectPlayCreate
+@ stdcall DirectPlayEnumerate(ptr ptr) dplayx.DirectPlayEnumerate

Added: trunk/reactos/lib/dplay/dplay.xml
--- trunk/reactos/lib/dplay/dplay.xml	2005-10-27 22:05:46 UTC (rev 18810)
+++ trunk/reactos/lib/dplay/dplay.xml	2005-10-27 22:10:33 UTC (rev 18811)
@@ -0,0 +1,25 @@
+<module name="dplay" type="win32dll" baseaddress="${BASEADDRESS_DPLAY}" installbase="system32" installname="dplay.dll">
+	<importlibrary definition="dplay.spec.def" />
+	<include base="dinput8">.</include>
+	<include base="ReactOS">include/wine</include>
+	<define name="UNICODE" />
+	<define name="_UNICODE" />
+	<define name="__REACTOS__" />
+	<define name="__USE_W32API" />
+	<define name="_WIN32_IE">0x600</define>
+	<define name="_WIN32_WINNT">0x501</define>
+	<define name="WINVER">0x501</define>
+	<library>wine</library>
+	<library>uuid</library>
+	<library>ntdll</library>
+	<library>kernel32</library>
+	<library>user32</library>
+	<library>advapi32</library>
+	<library>ole32</library>
+	<library>winmm</library>
+	<library>dxguid</library>
+	<library>dinput</library>
+      <file>version.rc</file>
+	<file>dplay_main.c</file>
+	<file>dplay.spec</file>
+</module>

Added: trunk/reactos/lib/dplay/dplay_main.c
--- trunk/reactos/lib/dplay/dplay_main.c	2005-10-27 22:05:46 UTC (rev 18810)
+++ trunk/reactos/lib/dplay/dplay_main.c	2005-10-27 22:10:33 UTC (rev 18811)
@@ -0,0 +1 @@
+/* nothing here yet */

Added: trunk/reactos/lib/dplay/version.rc
--- trunk/reactos/lib/dplay/version.rc	2005-10-27 22:05:46 UTC (rev 18810)
+++ trunk/reactos/lib/dplay/version.rc	2005-10-27 22:10:33 UTC (rev 18811)
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2004 Tom Wickline
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define WINE_OLESELFREGISTER
+#define WINE_FILEDESCRIPTION_STR "Wine DirectPlay"
+#define WINE_FILENAME_STR "dplay.dll"
+#define WINE_FILEVERSION 5,3,0,900
+#define WINE_FILEVERSION_STR "5.3.0.900"
+#define WINE_PRODUCTVERSION 5,3,0,900
+#define WINE_PRODUCTVERSION_STR "5.3"
+
+#include "wine/wine_common_ver.rc"

Added: trunk/reactos/lib/dplayx/dpclassfactory.c
--- trunk/reactos/lib/dplayx/dpclassfactory.c	2005-10-27 22:05:46 UTC (rev 18810)
+++ trunk/reactos/lib/dplayx/dpclassfactory.c	2005-10-27 22:10:33 UTC (rev 18811)
@@ -0,0 +1,134 @@
+/* COM class factory for direct play lobby interfaces.
+ *
+ * Copyright 1999, 2000 Peter Hunnisett
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdarg.h>
+#include <string.h>
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "objbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "dpinit.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dplay);
+
+
+/*******************************************************************************
+ * DirectPlayLobby ClassFactory
+ */
+
+typedef struct
+{
+    /* IUnknown fields */
+    const IClassFactoryVtbl    *lpVtbl;
+    LONG                        ref;
+} IClassFactoryImpl;
+
+static HRESULT WINAPI
+DP_and_DPL_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
+        IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+
+        FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
+
+        return E_NOINTERFACE;
+}
+
+static ULONG WINAPI
+DP_and_DPL_AddRef(LPCLASSFACTORY iface) {
+        IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+        return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI DP_and_DPL_Release(LPCLASSFACTORY iface) {
+        IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+        /* static class (reference starts @ 1), won't ever be freed */
+        return InterlockedDecrement(&This->ref);
+}
+
+static HRESULT WINAPI DP_and_DPL_CreateInstance(
+        LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
+) {
+        IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+
+        TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
+
+        if ( DPL_CreateInterface( riid, ppobj ) == S_OK )
+        {
+           return S_OK;
+        }
+        else if ( DP_CreateInterface( riid, ppobj ) == S_OK )
+        {
+           return S_OK;
+        }
+
+        return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI DP_and_DPL_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
+        IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+        FIXME("(%p)->(%d),stub!\n",This,dolock);
+        return S_OK;
+}
+
+static const IClassFactoryVtbl 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
+ */
+HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+{
+    TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), 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", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+    return CLASS_E_CLASSNOTAVAILABLE;
+}

Added: trunk/reactos/lib/dplayx/dpinit.h
--- trunk/reactos/lib/dplayx/dpinit.h	2005-10-27 22:05:46 UTC (rev 18810)
+++ trunk/reactos/lib/dplayx/dpinit.h	2005-10-27 22:10:33 UTC (rev 18811)
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1999, 2000 Peter Hunnisett
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __WINE_DPINIT_H
+#define __WINE_DPINIT_H
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wtypes.h"
+#include "dplay_global.h"
+
+extern HRESULT DP_CreateInterface( REFIID riid, LPVOID* ppvObj );
+extern HRESULT DPL_CreateInterface( REFIID riid, LPVOID* ppvObj );
+extern HRESULT DPSP_CreateInterface( REFIID riid, LPVOID* ppvObj,
+                                     IDirectPlay2Impl* dp );
+extern HRESULT DPLSP_CreateInterface( REFIID riid, LPVOID* ppvObj,
+                                      IDirectPlay2Impl* dp );
+
+
+#endif

Added: trunk/reactos/lib/dplayx/dplay.c
--- trunk/reactos/lib/dplayx/dplay.c	2005-10-27 22:05:46 UTC (rev 18810)
+++ trunk/reactos/lib/dplayx/dplay.c	2005-10-27 22:10:33 UTC (rev 18811)
@@ -0,0 +1,5451 @@
+/* Direct Play 2,3,4 Implementation
+ *
+ * Copyright 1998,1999,2000,2001 - Peter Hunnisett
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdarg.h>
+#include <string.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "windef.h"
+#include "winerror.h"
+#include "winbase.h"
+#include "winnt.h"
+#include "winreg.h"
+#include "winnls.h"
+#include "wine/unicode.h"
+#include "wine/debug.h"
+
+#include "dpinit.h"
+#include "dplayx_global.h"
+#include "name_server.h"
+#include "dplayx_queue.h"
+#include "dplaysp.h"
+#include "dplay_global.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dplay);
+
+/* FIXME: Should this be externed? */
+extern HRESULT DPL_CreateCompoundAddress
+( LPCDPCOMPOUNDADDRESSELEMENT lpElements, DWORD dwElementCount,
+  LPVOID lpAddress, LPDWORD lpdwAddressSize, BOOL bAnsiInterface );
+
+
+/* Local function prototypes */
+static lpPlayerList DP_FindPlayer( IDirectPlay2AImpl* This, DPID dpid );
+static lpPlayerData DP_CreatePlayer( IDirectPlay2Impl* iface, LPDPID lpid,
+                                     LPDPNAME lpName, DWORD dwFlags,
+                                     HANDLE hEvent, BOOL bAnsi );
+static BOOL DP_CopyDPNAMEStruct( LPDPNAME lpDst, LPDPNAME lpSrc, BOOL bAnsi );
+static void DP_SetPlayerData( lpPlayerData lpPData, DWORD dwFlags,
+                              LPVOID lpData, DWORD dwDataSize );
+
+static lpGroupData DP_CreateGroup( IDirectPlay2AImpl* iface, LPDPID lpid,
+                                   LPDPNAME lpName, DWORD dwFlags,
+                                   DPID idParent, BOOL bAnsi );
+static void DP_SetGroupData( lpGroupData lpGData, DWORD dwFlags,
+                             LPVOID lpData, DWORD dwDataSize );
+static void DP_DeleteDPNameStruct( LPDPNAME lpDPName );
+static void DP_DeletePlayer( IDirectPlay2Impl* This, DPID dpid );
+static BOOL CALLBACK cbDeletePlayerFromAllGroups( DPID dpId,
+                                                  DWORD dwPlayerType,
+                                                  LPCDPNAME lpName,
+                                                  DWORD dwFlags,
+                                                  LPVOID lpContext );
+static lpGroupData DP_FindAnyGroup( IDirectPlay2AImpl* This, DPID dpid );
+static BOOL CALLBACK cbRemoveGroupOrPlayer( DPID dpId, DWORD dwPlayerType,
+                                            LPCDPNAME lpName, DWORD dwFlags,
+                                            LPVOID lpContext );
+static void DP_DeleteGroup( IDirectPlay2Impl* This, DPID dpid );
+
+/* Forward declarations of virtual tables */
+static const IDirectPlay2Vtbl directPlay2AVT;
+static const IDirectPlay3Vtbl directPlay3AVT;
+static const IDirectPlay4Vtbl directPlay4AVT;
+
+static const IDirectPlay2Vtbl directPlay2WVT;
+static const IDirectPlay3Vtbl directPlay3WVT;
+static const IDirectPlay4Vtbl directPlay4WVT;
+
+/* Helper methods for player/group interfaces */
+static HRESULT WINAPI DP_IF_DeletePlayerFromGroup
+          ( IDirectPlay2Impl* This, LPVOID lpMsgHdr, DPID idGroup,
+            DPID idPlayer, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_CreatePlayer
+          ( IDirectPlay2Impl* This, LPVOID lpMsgHdr, LPDPID lpidPlayer,
+            LPDPNAME lpPlayerName, HANDLE hEvent, LPVOID lpData,
+            DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_DestroyGroup
+          ( IDirectPlay2Impl* This, LPVOID lpMsgHdr, DPID idGroup, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_DestroyPlayer
+          ( IDirectPlay2Impl* This, LPVOID lpMsgHdr, DPID idPlayer, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_EnumGroupPlayers
+          ( IDirectPlay2Impl* This, DPID idGroup, LPGUID lpguidInstance,
+            LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
+            LPVOID lpContext, DWORD dwFlags, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_EnumGroups
+          ( IDirectPlay2Impl* This, LPGUID lpguidInstance,
+            LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
+            LPVOID lpContext, DWORD dwFlags, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_EnumPlayers
+          ( IDirectPlay2Impl* This, LPGUID lpguidInstance,
+            LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
+            LPVOID lpContext, DWORD dwFlags, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_GetGroupData
+          ( IDirectPlay2Impl* This, DPID idGroup, LPVOID lpData,
+            LPDWORD lpdwDataSize, DWORD dwFlags, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_GetGroupName
+          ( IDirectPlay2Impl* This, DPID idGroup, LPVOID lpData,
+            LPDWORD lpdwDataSize, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_GetPlayerData
+          ( IDirectPlay2Impl* This, DPID idPlayer, LPVOID lpData,
+            LPDWORD lpdwDataSize, DWORD dwFlags, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_GetPlayerName
+          ( IDirectPlay2Impl* This, DPID idPlayer, LPVOID lpData,
+            LPDWORD lpdwDataSize, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_SetGroupName
+          ( IDirectPlay2Impl* This, DPID idGroup, LPDPNAME lpGroupName,
+            DWORD dwFlags, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_SetPlayerData
+          ( IDirectPlay2Impl* This, DPID idPlayer, LPVOID lpData,
+            DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_SetPlayerName
+          ( IDirectPlay2Impl* This, DPID idPlayer, LPDPNAME lpPlayerName,
+            DWORD dwFlags, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_AddGroupToGroup
+          ( IDirectPlay3Impl* This, DPID idParentGroup, DPID idGroup );
+static HRESULT WINAPI DP_IF_CreateGroup
+          ( IDirectPlay2AImpl* This, LPVOID lpMsgHdr, LPDPID lpidGroup,
+            LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize,
+            DWORD dwFlags, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_CreateGroupInGroup
+          ( IDirectPlay3Impl* This, LPVOID lpMsgHdr, DPID idParentGroup,
+            LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData,
+            DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_AddPlayerToGroup
+          ( IDirectPlay2Impl* This, LPVOID lpMsgHdr, DPID idGroup,
+            DPID idPlayer, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_DeleteGroupFromGroup
+          ( IDirectPlay3Impl* This, DPID idParentGroup, DPID idGroup );
+static HRESULT WINAPI DP_SetSessionDesc
+          ( IDirectPlay2Impl* This, LPCDPSESSIONDESC2 lpSessDesc,
+            DWORD dwFlags, BOOL bInitial, BOOL bAnsi  );
+static HRESULT WINAPI DP_SecureOpen
+          ( IDirectPlay2Impl* This, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags,
+            LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials,
+            BOOL bAnsi );
+static HRESULT WINAPI DP_SendEx
+          ( IDirectPlay2Impl* This, DPID idFrom, DPID idTo, DWORD dwFlags,
+            LPVOID lpData, DWORD dwDataSize, DWORD dwPriority, DWORD dwTimeout,
+            LPVOID lpContext, LPDWORD lpdwMsgID, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_Receive
+          ( IDirectPlay2Impl* This, LPDPID lpidFrom, LPDPID lpidTo,
+            DWORD dwFlags, LPVOID lpData, LPDWORD lpdwDataSize, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_GetMessageQueue
+          ( IDirectPlay4Impl* This, DPID idFrom, DPID idTo, DWORD dwFlags,
+            LPDWORD lpdwNumMsgs, LPDWORD lpdwNumBytes, BOOL bAnsi );
+static HRESULT WINAPI DP_SP_SendEx
+          ( IDirectPlay2Impl* This, DWORD dwFlags,
+            LPVOID lpData, DWORD dwDataSize, DWORD dwPriority, DWORD dwTimeout,
+            LPVOID lpContext, LPDWORD lpdwMsgID );
+static HRESULT WINAPI DP_IF_SetGroupData
+          ( IDirectPlay2Impl* This, DPID idGroup, LPVOID lpData,
+            DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_GetPlayerCaps
+          ( IDirectPlay2Impl* This, DPID idPlayer, LPDPCAPS lpDPCaps,
+            DWORD dwFlags );
+static HRESULT WINAPI DP_IF_Close( IDirectPlay2Impl* This, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_CancelMessage
+          ( IDirectPlay4Impl* This, DWORD dwMsgID, DWORD dwFlags,
+            DWORD dwMinPriority, DWORD dwMaxPriority, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_EnumGroupsInGroup
+          ( IDirectPlay3AImpl* This, DPID idGroup, LPGUID lpguidInstance,
+            LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
+            LPVOID lpContext, DWORD dwFlags, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_GetGroupParent
+          ( IDirectPlay3AImpl* This, DPID idGroup, LPDPID lpidGroup,
+            BOOL bAnsi );
+static HRESULT WINAPI DP_IF_GetCaps
+          ( IDirectPlay2Impl* This, LPDPCAPS lpDPCaps, DWORD dwFlags );
+static HRESULT WINAPI DP_IF_EnumSessions
+          ( IDirectPlay2Impl* This, LPDPSESSIONDESC2 lpsd, DWORD dwTimeout,
+            LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
+            LPVOID lpContext, DWORD dwFlags, BOOL bAnsi );
+static HRESULT WINAPI DP_IF_InitializeConnection
+          ( IDirectPlay3Impl* This, LPVOID lpConnection, DWORD dwFlags, BOOL bAnsi );
+static BOOL CALLBACK cbDPCreateEnumConnections( LPCGUID lpguidSP,
+    LPVOID lpConnection, DWORD dwConnectionSize, LPCDPNAME lpName,
+    DWORD dwFlags, LPVOID lpContext );
+static BOOL WINAPI DP_BuildSPCompoundAddr( LPGUID lpcSpGuid, LPVOID* lplpAddrBuf,
+                                           LPDWORD lpdwBufSize );
+
+
+
+static inline DPID DP_NextObjectId(void);
+static DPID DP_GetRemoteNextObjectId(void);
+
+
+static void DP_CopySessionDesc( LPDPSESSIONDESC2 destSessionDesc,
+                                LPCDPSESSIONDESC2 srcSessDesc, BOOL bAnsi );
+
+
+static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData, LPBOOL lpbIsDpSp );
+static HRESULT DP_InitializeDPSP( IDirectPlay3Impl* This, HMODULE hServiceProvider );
+static HRESULT DP_InitializeDPLSP( IDirectPlay3Impl* This, HMODULE hServiceProvider );
+
+
+
+
+
+
+#define DPID_NOPARENT_GROUP 0 /* Magic number to indicate no parent of group */
+#define DPID_SYSTEM_GROUP DPID_NOPARENT_GROUP /* If system group is supported
+                                                 we don't have to change much */
+#define DPID_NAME_SERVER 0x19a9d65b  /* Don't ask me why */
+
+/* Strip out dwFlag values which cannot be sent in the CREATEGROUP msg */
+#define DPMSG_CREATEGROUP_DWFLAGS(x) ( (x) & DPGROUP_HIDDEN )
+
+/* Strip out all dwFlags values for CREATEPLAYER msg */
+#define DPMSG_CREATEPLAYER_DWFLAGS(x) 0
+
+static LONG kludgePlayerGroupId = 1000;
+
+/* ------------------------------------------------------------------ */
+
+
+static BOOL DP_CreateIUnknown( LPVOID lpDP )
+{
+  IDirectPlay2AImpl *This = (IDirectPlay2AImpl *)lpDP;
+
+  This->unk = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( *(This->unk) ) );
+  if ( This->unk == NULL )
+  {
+    return FALSE;
+  }
+
+  InitializeCriticalSection( &This->unk->DP_lock );
+
+  return TRUE;
+}
+
+static BOOL DP_DestroyIUnknown( LPVOID lpDP )
+{
+  IDirectPlay2AImpl *This = (IDirectPlay2AImpl *)lpDP;
+
+  DeleteCriticalSection( &This->unk->DP_lock );
+  HeapFree( GetProcessHeap(), 0, This->unk );
+
+  return TRUE;
+}
+
+static BOOL DP_CreateDirectPlay2( LPVOID lpDP )
+{
+  IDirectPlay2AImpl *This = (IDirectPlay2AImpl *)lpDP;
+
+  This->dp2 = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( *(This->dp2) ) );
+  if ( This->dp2 == NULL )
+  {
+    return FALSE;
+  }
+
+  This->dp2->bConnectionOpen = FALSE;
+
+  This->dp2->hEnumSessionThread = INVALID_HANDLE_VALUE;
+
+  This->dp2->bHostInterface = FALSE;
+
+  DPQ_INIT(This->dp2->receiveMsgs);
+  DPQ_INIT(This->dp2->sendMsgs);
+  DPQ_INIT(This->dp2->replysExpected);
+
+  if( !NS_InitializeSessionCache( &This->dp2->lpNameServerData ) )
+  {
+    /* FIXME: Memory leak */
+    return FALSE;
+  }
+
+  /* Provide an initial session desc with nothing in it */
+  This->dp2->lpSessionDesc = HeapAlloc( GetProcessHeap(),
+                                        HEAP_ZERO_MEMORY,
+                                        sizeof( *This->dp2->lpSessionDesc ) );
+  if( This->dp2->lpSessionDesc == NULL )
+  {
+    /* FIXME: Memory leak */
+    return FALSE;
+  }
+  This->dp2->lpSessionDesc->dwSize = sizeof( *This->dp2->lpSessionDesc );
+
+  /* We are emulating a dp 6 implementation */
+  This->dp2->spData.dwSPVersion = DPSP_MAJORVERSION;
+
+  This->dp2->spData.lpCB = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                      sizeof( *This->dp2->spData.lpCB ) );
+  This->dp2->spData.lpCB->dwSize = sizeof( *This->dp2->spData.lpCB );
+  This->dp2->spData.lpCB->dwVersion = DPSP_MAJORVERSION;
+
+  /* This is the pointer to the service provider */
+  if( FAILED( DPSP_CreateInterface( &IID_IDirectPlaySP,
+                                    (LPVOID*)&This->dp2->spData.lpISP, This ) )
+    )
+  {
+    /* FIXME: Memory leak */
+    return FALSE;
+  }
+
+  /* Setup lobby provider information */
+  This->dp2->dplspData.dwSPVersion = DPSP_MAJORVERSION;
+  This->dp2->dplspData.lpCB = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                         sizeof( *This->dp2->dplspData.lpCB ) );
+  This->dp2->dplspData.lpCB->dwSize = sizeof(  *This->dp2->dplspData.lpCB );
+
+  if( FAILED( DPLSP_CreateInterface( &IID_IDPLobbySP,
+                                     (LPVOID*)&This->dp2->dplspData.lpISP, This ) )
+    )
+  {
+    /* FIXME: Memory leak */
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/* Definition of the global function in dplayx_queue.h. #
+ * FIXME: Would it be better to have a dplayx_queue.c for this function? */
+DPQ_DECL_DELETECB( cbDeleteElemFromHeap, LPVOID )
+{
+  HeapFree( GetProcessHeap(), 0, elem );
+}
+
+/* Function to delete the list of groups with this interface. Needs to
+ * delete the group and player lists associated with this group as well
+ * as the group data associated with this group. It should not delete
+ * player data as that is shared with the top player list and will be
+ * deleted with that.
+ */
+DPQ_DECL_DELETECB( cbDeleteGroupsElem, lpGroupList );
+DPQ_DECL_DELETECB( cbDeleteGroupsElem, lpGroupList )
+{
+  DPQ_DELETEQ( elem->lpGData->groups, groups,
+               lpGroupList, cbDeleteElemFromHeap );
+  DPQ_DELETEQ( elem->lpGData->players, players,
+               lpPlayerList, cbDeleteElemFromHeap );
+  HeapFree( GetProcessHeap(), 0, elem->lpGData );
+  HeapFree( GetProcessHeap(), 0, elem );
+}
+
+/* Function to delete the list of players with this interface. Needs to
+ * delete the player data for all players as well.
+ */
+DPQ_DECL_DELETECB( cbDeletePlayerElem, lpPlayerList );
+DPQ_DECL_DELETECB( cbDeletePlayerElem, lpPlayerList )
+{
+  HeapFree( GetProcessHeap(), 0, elem->lpPData );
+  HeapFree( GetProcessHeap(), 0, elem );
+}
+
+static BOOL DP_DestroyDirectPlay2( LPVOID lpDP )
+{
+  IDirectPlay2AImpl *This = (IDirectPlay2AImpl *)lpDP;
+
+  if( This->dp2->hEnumSessionThread != INVALID_HANDLE_VALUE )
+  {
+    TerminateThread( This->dp2->hEnumSessionThread, 0 );
+    CloseHandle( This->dp2->hEnumSessionThread );
+  }
+
+  /* Finish with the SP - have it shutdown */
+  if( This->dp2->spData.lpCB->ShutdownEx )
+  {
+    DPSP_SHUTDOWNDATA data;
+
+    TRACE( "Calling SP ShutdownEx\n" );
+
+    data.lpISP = This->dp2->spData.lpISP;
+
+    (*This->dp2->spData.lpCB->ShutdownEx)( &data );
+  }
+  else if (This->dp2->spData.lpCB->Shutdown ) /* obsolete interface */
+  {
+    TRACE( "Calling obsolete SP Shutdown\n" );
+    (*This->dp2->spData.lpCB->Shutdown)();
+  }
+
+  /* Unload the SP (if it exists) */
+  if( This->dp2->hServiceProvider != 0 )
+  {
+    FreeLibrary( This->dp2->hServiceProvider );
+  }
+
+  /* Unload the Lobby Provider (if it exists) */
+  if( This->dp2->hDPLobbyProvider != 0 )
+  {
+    FreeLibrary( This->dp2->hDPLobbyProvider );
+  }
+
+#if 0
+  DPQ_DELETEQ( This->dp2->players, players, lpPlayerList, cbDeletePlayerElem );
+  DPQ_DELETEQ( This->dp2->groups, groups, lpGroupList, cbDeleteGroupsElem );
+#endif
+
+  /* FIXME: Need to delete receive and send msgs queue contents */
+
+  NS_DeleteSessionCache( This->dp2->lpNameServerData );
+
+  HeapFree( GetProcessHeap(), 0, This->dp2->lpSessionDesc );
+
+  IDirectPlaySP_Release( This->dp2->spData.lpISP );
+
+  /* Delete the contents */
+  HeapFree( GetProcessHeap(), 0, This->dp2 );
+
+  return TRUE;
+}
+
+static BOOL DP_CreateDirectPlay3( LPVOID lpDP )
+{
+  IDirectPlay3AImpl *This = (IDirectPlay3AImpl *)lpDP;
+
+  This->dp3 = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( *(This->dp3) ) );
+  if ( This->dp3 == NULL )
+  {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+static BOOL DP_DestroyDirectPlay3( LPVOID lpDP )
+{
+  IDirectPlay3AImpl *This = (IDirectPlay3AImpl *)lpDP;
+
+  /* Delete the contents */
+  HeapFree( GetProcessHeap(), 0, This->dp3 );
+
+  return TRUE;
+}
+
+static BOOL DP_CreateDirectPlay4( LPVOID lpDP )
+{
+  IDirectPlay4AImpl *This = (IDirectPlay4AImpl *)lpDP;
+
+  This->dp4 = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( *(This->dp4) ) );
+  if ( This->dp4 == NULL )
+  {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+static BOOL DP_DestroyDirectPlay4( LPVOID lpDP )
+{
+  IDirectPlay3AImpl *This = (IDirectPlay3AImpl *)lpDP;
+
+  /* Delete the contents */
+  HeapFree( GetProcessHeap(), 0, This->dp4 );
+
+  return TRUE;
+}
+
+
+/* Create a new interface */
+extern
+HRESULT DP_CreateInterface
+         ( REFIID riid, LPVOID* ppvObj )
+{
+  TRACE( " for %s\n", debugstr_guid( riid ) );
+
+  *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                       sizeof( IDirectPlay2Impl ) );
+
+  if( *ppvObj == NULL )
+  {
+    return DPERR_OUTOFMEMORY;
+  }
+
+  if( IsEqualGUID( &IID_IDirectPlay2, riid ) )
+  {
+    IDirectPlay2Impl *This = (IDirectPlay2Impl *)*ppvObj;
+    This->lpVtbl = &directPlay2WVT;
+  }
+  else if( IsEqualGUID( &IID_IDirectPlay2A, riid ) )
+  {
+    IDirectPlay2AImpl *This = (IDirectPlay2AImpl *)*ppvObj;
+    This->lpVtbl = &directPlay2AVT;
+  }
+  else if( IsEqualGUID( &IID_IDirectPlay3, riid ) )
+  {
+    IDirectPlay3Impl *This = (IDirectPlay3Impl *)*ppvObj;
+    This->lpVtbl = &directPlay3WVT;
+  }
+  else if( IsEqualGUID( &IID_IDirectPlay3A, riid ) )
+  {
+    IDirectPlay3AImpl *This = (IDirectPlay3AImpl *)*ppvObj;
+    This->lpVtbl = &directPlay3AVT;
+  }
+  else if( IsEqualGUID( &IID_IDirectPlay4, riid ) )
+  {
+    IDirectPlay4Impl *This = (IDirectPlay4Impl *)*ppvObj;
+    This->lpVtbl = &directPlay4WVT;
+  }
+  else if( IsEqualGUID( &IID_IDirectPlay4A, riid ) )
+  {
+    IDirectPlay4AImpl *This = (IDirectPlay4AImpl *)*ppvObj;
+    This->lpVtbl = &directPlay4AVT;
+  }
+  else
+  {
+    /* Unsupported interface */
+    HeapFree( GetProcessHeap(), 0, *ppvObj );
+    *ppvObj = NULL;
+
+    return E_NOINTERFACE;
+  }
+
+  /* Initialize it */
+  if ( DP_CreateIUnknown( *ppvObj ) &&
+       DP_CreateDirectPlay2( *ppvObj ) &&
+       DP_CreateDirectPlay3( *ppvObj ) &&
+       DP_CreateDirectPlay4( *ppvObj )
+     )
+  {
+    IDirectPlayX_AddRef( (LPDIRECTPLAY2A)*ppvObj );
+
+    return S_OK;
+  }
+
+  /* Initialize failed, destroy it */
+  DP_DestroyDirectPlay4( *ppvObj );
+  DP_DestroyDirectPlay3( *ppvObj );
+  DP_DestroyDirectPlay2( *ppvObj );
+  DP_DestroyIUnknown( *ppvObj );
+
+  HeapFree( GetProcessHeap(), 0, *ppvObj );
+
+  *ppvObj = NULL;
+  return DPERR_NOMEMORY;
+}
+
+
+/* Direct Play methods */
+
+/* Shared between all dplay types */
+static HRESULT WINAPI DP_QueryInterface
+         ( LPDIRECTPLAY2 iface, REFIID riid, LPVOID* ppvObj )
+{
+  IDirectPlay2Impl *This = (IDirectPlay2Impl *)iface;
+  TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
+
+  *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                       sizeof( *This ) );
+
+  if( *ppvObj == NULL )
+  {
+    return DPERR_OUTOFMEMORY;
+  }
+
+  CopyMemory( *ppvObj, This, sizeof( *This )  );
+  (*(IDirectPlay2Impl**)ppvObj)->ulInterfaceRef = 0;
+
+  if( IsEqualGUID( &IID_IDirectPlay2, riid ) )
+  {
+    IDirectPlay2Impl *This = (IDirectPlay2Impl *)*ppvObj;
+    This->lpVtbl = &directPlay2WVT;
+  }
+  else if( IsEqualGUID( &IID_IDirectPlay2A, riid ) )
+  {
+    IDirectPlay2AImpl *This = (IDirectPlay2AImpl *)*ppvObj;
+    This->lpVtbl = &directPlay2AVT;
+  }
+  else if( IsEqualGUID( &IID_IDirectPlay3, riid ) )
+  {
+    IDirectPlay3Impl *This = (IDirectPlay3Impl *)*ppvObj;
+    This->lpVtbl = &directPlay3WVT;
+  }
+  else if( IsEqualGUID( &IID_IDirectPlay3A, riid ) )
+  {
+    IDirectPlay3AImpl *This = (IDirectPlay3AImpl *)*ppvObj;
+    This->lpVtbl = &directPlay3AVT;
+  }
+  else if( IsEqualGUID( &IID_IDirectPlay4, riid ) )
+  {
+    IDirectPlay4Impl *This = (IDirectPlay4Impl *)*ppvObj;
+    This->lpVtbl = &directPlay4WVT;
+  }
+  else if( IsEqualGUID( &IID_IDirectPlay4A, riid ) )
+  {
+    IDirectPlay4AImpl *This = (IDirectPlay4AImpl *)*ppvObj;
+    This->lpVtbl = &directPlay4AVT;
+  }
+  else
+  {
+    /* Unsupported interface */
+    HeapFree( GetProcessHeap(), 0, *ppvObj );
+    *ppvObj = NULL;
+
+    return E_NOINTERFACE;
+  }
+
+  IDirectPlayX_AddRef( (LPDIRECTPLAY2)*ppvObj );
+
+  return S_OK;
+}
+
+/* Shared between all dplay types */
+static ULONG WINAPI DP_AddRef
+         ( LPDIRECTPLAY3 iface )
+{
+  ULONG ulInterfaceRefCount, ulObjRefCount;
+  IDirectPlay3Impl *This = (IDirectPlay3Impl *)iface;
+
+  ulObjRefCount       = InterlockedIncrement( &This->unk->ulObjRef );
+  ulInterfaceRefCount = InterlockedIncrement( &This->ulInterfaceRef );
+
+  TRACE( "ref count incremented to %lu:%lu for %p\n",
+         ulInterfaceRefCount, ulObjRefCount, This );
+
+  return ulObjRefCount;
+}
+
+static ULONG WINAPI DP_Release
+( LPDIRECTPLAY3 iface )
+{
+  ULONG ulInterfaceRefCount, ulObjRefCount;
+
+  IDirectPlay3Impl *This = (IDirectPlay3Impl *)iface;
+
+  ulObjRefCount       = InterlockedDecrement( &This->unk->ulObjRef );
+  ulInterfaceRefCount = InterlockedDecrement( &This->ulInterfaceRef );
+
+  TRACE( "ref count decremented to %lu:%lu for %p\n",
+         ulInterfaceRefCount, ulObjRefCount, This );
+
+  /* Deallocate if this is the last reference to the object */
+  if( ulObjRefCount == 0 )
+  {
+     /* If we're destroying the object, this must be the last ref
+        of the last interface */
+     DP_DestroyDirectPlay4( This );
+     DP_DestroyDirectPlay3( This );
+     DP_DestroyDirectPlay2( This );
+     DP_DestroyIUnknown( This );
+  }
+
+  /* Deallocate the interface */
+  if( ulInterfaceRefCount == 0 )
+  {
+    HeapFree( GetProcessHeap(), 0, This );
+  }
+
+  return ulObjRefCount;
+}
+
+static inline DPID DP_NextObjectId(void)
+{
+  return (DPID)InterlockedIncrement( &kludgePlayerGroupId );
+}
+
+/* *lplpReply will be non NULL iff there is something to reply */
+HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpcMessageBody,
+                          DWORD  dwMessageBodySize, LPCVOID lpcMessageHeader,
+                          WORD wCommandId, WORD wVersion,
+                          LPVOID* lplpReply, LPDWORD lpdwMsgSize )
+{
+  TRACE( "(%p)->(%p,0x%08lx,%p,%u,%u)\n",
+         This, lpcMessageBody, dwMessageBodySize, lpcMessageHeader, wCommandId,
+         wVersion );
+
+  switch( wCommandId )
+  {
+    /* Name server needs to handle this request */
+    case DPMSGCMD_ENUMSESSIONSREQUEST:
+    {
+      /* Reply expected */
+      NS_ReplyToEnumSessionsRequest( lpcMessageBody, lplpReply, lpdwMsgSize, This );
+
+      break;
+    }
+
+    /* Name server needs to handle this request */
+    case DPMSGCMD_ENUMSESSIONSREPLY:
+    {
+      /* No reply expected */
+      NS_AddRemoteComputerAsNameServer( lpcMessageHeader,
+                                        This->dp2->spData.dwSPHeaderSize,
+                                        (LPDPMSG_ENUMSESSIONSREPLY)lpcMessageBody,
+                                        This->dp2->lpNameServerData );
+      break;
+    }
+
+    case DPMSGCMD_REQUESTNEWPLAYERID:
+    {
+      LPCDPMSG_REQUESTNEWPLAYERID lpcMsg =
+        (LPCDPMSG_REQUESTNEWPLAYERID)lpcMessageBody;
+
+      LPDPMSG_NEWPLAYERIDREPLY lpReply;
+
+      *lpdwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpReply );
+
+      *lplpReply = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, *lpdwMsgSize );
+
+      FIXME( "Ignoring dwFlags 0x%08lx in request msg\n",
+             lpcMsg->dwFlags );
+
+      /* Setup the reply */
+      lpReply = (LPDPMSG_NEWPLAYERIDREPLY)( (BYTE*)(*lplpReply) +
+                                            This->dp2->spData.dwSPHeaderSize );
+
+      lpReply->envelope.dwMagic    = DPMSGMAGIC_DPLAYMSG;
+      lpReply->envelope.wCommandId = DPMSGCMD_NEWPLAYERIDREPLY;
+      lpReply->envelope.wVersion   = DPMSGVER_DP6;
+
[truncated at 1000 lines; 12987 more skipped]