Commit 3d7cd876 authored by Peter Hunnisett's avatar Peter Hunnisett Committed by Alexandre Julliard

- Provide lobby provider COM object header file and stub implementation

- Break out dpl and dp service provider intialization - Add missing definition of E_PENDING - Resolve a few fixmes - Fix includes for dplay.h
parent 3f03975f
......@@ -16,6 +16,7 @@ C_SRCS = \
dplayx_main.c \
dplayx_messages.c \
dplobby.c \
lobbysp.c \
name_server.c
@MAKE_DLL_RULES@
......
......@@ -9,5 +9,8 @@ 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
/* Direct Play 2,3,4 Implementation
*
* Copyright 1998,1999,2000 - Peter Hunnisett
* Copyright 1998,1999,2000,2001 - Peter Hunnisett
*
* <presently under construction - contact hunnise@nortelnetworks.com>
*
......@@ -169,6 +169,8 @@ static HRESULT WINAPI DP_IF_InitializeConnection
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 );
......@@ -181,6 +183,9 @@ static void DP_CopySessionDesc( LPDPSESSIONDESC2 destSessionDesc,
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 );
......@@ -283,6 +288,20 @@ static BOOL DP_CreateDirectPlay2( LPVOID lpDP )
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;
}
......@@ -347,12 +366,17 @@ static BOOL DP_DestroyDirectPlay2( LPVOID lpDP )
(*This->dp2->spData.lpCB->Shutdown)();
}
/* Unload the SP */
/* 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 );
......@@ -631,6 +655,26 @@ HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpcMessageBody,
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 =
......@@ -667,8 +711,33 @@ HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpcMessageBody,
case DPMSGCMD_NEWPLAYERIDREPLY:
{
#if 0
if( wCommandId == DPMSGCMD_NEWPLAYERIDREPLY )
DebugBreak();
#endif
DP_MSG_ReplyReceived( This, wCommandId, lpcMessageBody, dwMessageBodySize );
break;
}
#if 1
case DPMSGCMD_JUSTENVELOPE:
{
TRACE( "GOT THE SELF MESSAGE: %p -> 0x%08lx\n", lpcMessageHeader, ((LPDWORD)lpcMessageHeader)[1] );
NS_SetLocalAddr( This->dp2->lpNameServerData, lpcMessageHeader, 20 );
DP_MSG_ReplyReceived( This, wCommandId, lpcMessageBody, dwMessageBodySize );
}
#endif
case DPMSGCMD_FORWARDADDPLAYER:
{
#if 0
DebugBreak();
#endif
#if 1
TRACE( "Sending message to self to get my addr\n" );
DP_MSG_ToSelf( This, 1 ); /* This is a hack right now */
#endif
break;
}
......@@ -686,6 +755,8 @@ HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpcMessageBody,
}
}
/* FIXME: There is code in dplaysp.c to handle dplay commands. Move to here. */
return DP_OK;
}
......@@ -1475,6 +1546,11 @@ static HRESULT WINAPI DP_IF_CreatePlayer
* is this used for regular players? If only for server players, move
* this call to DP_SecureOpen(...);
*/
#if 0
TRACE( "Sending message to self to get my addr\n" );
DP_MSG_ToSelf( This, *lpidPlayer ); /* This is a hack right now */
#endif
hr = DP_MSG_ForwardPlayerCreation( This, *lpidPlayer);
}
#else
......@@ -2107,6 +2183,47 @@ static HRESULT WINAPI DP_IF_EnumSessions
return DPERR_GENERIC;
}
#if 1
/* The loading of a lobby provider _seems_ to require a backdoor loading
* of the service provider to also associate with this DP object. This is
* because the app doesn't seem to have to call EnumConnections and
* InitializeConnection for the SP before calling this method. As such
* we'll do their dirty work for them with a quick hack so as to always
* load the TCP/IP service provider.
*
* The correct solution would seem to involve creating a dialog box which
* contains the possible SPs. These dialog boxes most likely follow SDK
* examples.
*/
if( This->dp2->bDPLSPInitialized && !This->dp2->bSPInitialized )
{
LPVOID lpConnection;
DWORD dwSize;
WARN( "Hack providing TCP/IP SP for lobby provider activated\n" );
if( !DP_BuildSPCompoundAddr( (LPGUID)&DPSPGUID_TCPIP, &lpConnection, &dwSize ) )
{
ERR( "Can't build compound addr\n" );
return DPERR_GENERIC;
}
hr = DP_IF_InitializeConnection( (IDirectPlay3Impl*)This, lpConnection,
0, bAnsi );
if( FAILED(hr) )
{
return hr;
}
/* Free up the address buffer */
HeapFree( GetProcessHeap(), 0, lpConnection );
/* The SP is now initialized */
This->dp2->bSPInitialized = TRUE;
}
#endif
/* Use the service provider default? */
if( dwTimeout == 0 )
{
......@@ -2158,6 +2275,7 @@ static HRESULT WINAPI DP_IF_EnumSessions
sizeof( *lpData ) );
/* FIXME: need to kill the thread on object deletion */
lpData->lpSpData = &This->dp2->spData;
CopyMemory( &lpData->requestGuid, &lpsd->guidApplication, sizeof(GUID) );
lpData->dwEnumSessionFlags = dwFlags;
lpData->dwTimeout = dwTimeout;
......@@ -2693,7 +2811,7 @@ static HRESULT WINAPI DP_SecureOpen
{
/* Rightoo - this computer is the host and the local computer needs to be
the name server so that others can join this session */
NS_SetLocalComputerAsNameServer( lpsd );
NS_SetLocalComputerAsNameServer( lpsd, This->dp2->lpNameServerData );
This->dp2->bHostInterface = TRUE;
......@@ -3458,6 +3576,45 @@ static HRESULT WINAPI DirectPlay3WImpl_DeleteGroupFromGroup
return DP_IF_DeleteGroupFromGroup( This, idParentGroup, idGroup );
}
static
BOOL WINAPI DP_BuildSPCompoundAddr( LPGUID lpcSpGuid, LPVOID* lplpAddrBuf,
LPDWORD lpdwBufSize )
{
DPCOMPOUNDADDRESSELEMENT dpCompoundAddress;
HRESULT hr;
dpCompoundAddress.dwDataSize = sizeof( GUID );
memcpy( &dpCompoundAddress.guidDataType, &DPAID_ServiceProvider,
sizeof( GUID ) ) ;
dpCompoundAddress.lpData = lpcSpGuid;
*lplpAddrBuf = NULL;
*lpdwBufSize = 0;
hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, *lplpAddrBuf,
lpdwBufSize, TRUE );
if( hr != DPERR_BUFFERTOOSMALL )
{
ERR( "can't get buffer size: %s\n", DPLAYX_HresultToString( hr ) );
return FALSE;
}
/* Now allocate the buffer */
*lplpAddrBuf = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
*lpdwBufSize );
hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, *lplpAddrBuf,
lpdwBufSize, TRUE );
if( FAILED(hr) )
{
ERR( "can't create address: %s\n", DPLAYX_HresultToString( hr ) );
return FALSE;
}
return TRUE;
}
static HRESULT WINAPI DirectPlay3AImpl_EnumConnections
( LPDIRECTPLAY3A iface, LPCGUID lpguidApplication, LPDPENUMCONNECTIONSCALLBACK lpEnumCallback, LPVOID lpContext, DWORD dwFlags )
{
......@@ -3515,9 +3672,8 @@ static HRESULT WINAPI DirectPlay3AImpl_EnumConnections
char returnBuffer[51];
WCHAR buff[51];
DPNAME dpName;
HRESULT hr;
BOOL bBuildPass;
DPCOMPOUNDADDRESSELEMENT dpCompoundAddress;
LPVOID lpAddressBuffer = NULL;
DWORD dwAddressBufferSize = 0;
......@@ -3551,31 +3707,19 @@ static HRESULT WINAPI DirectPlay3AImpl_EnumConnections
dpName.u2.lpszLongNameA = NULL;
/* Create the compound address for the service provider.
NOTE: This is a gruesome architectural scar right now. DP uses DPL and DPL uses DP,
nasty stuff. This may be why the native dll just gets around this little bit by
allocating an 80 byte buffer which isn't even filled with a valid compound
address. Oh well. Creating a proper compound address is the way to go anyway...
NOTE: This is a gruesome architectural scar right now. DP uses DPL and DPL uses DP
nast stuff. This may be why the native dll just gets around this little bit by
allocating an 80 byte buffer which isn't even a filled with a valid compound
address. Oh well. Creating a proper compound address is the way to go anyways
despite this method taking slightly more heap space and realtime :) */
dpCompoundAddress.dwDataSize = sizeof( GUID );
memcpy( &dpCompoundAddress.guidDataType, &DPAID_ServiceProvider,
sizeof( GUID ) ) ;
dpCompoundAddress.lpData = &serviceProviderGUID;
if( ( hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, lpAddressBuffer,
&dwAddressBufferSize, TRUE ) ) != DPERR_BUFFERTOOSMALL )
bBuildPass = DP_BuildSPCompoundAddr( &serviceProviderGUID,
&lpAddressBuffer,
&dwAddressBufferSize );
if( !bBuildPass )
{
ERR( "can't get buffer size: %s\n", DPLAYX_HresultToString( hr ) );
return hr;
}
/* Now allocate the buffer */
lpAddressBuffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAddressBufferSize );
if( ( hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, lpAddressBuffer,
&dwAddressBufferSize, TRUE ) ) != DP_OK )
{
ERR( "can't create address: %s\n", DPLAYX_HresultToString( hr ) );
return hr;
ERR( "Can't build compound addr\n" );
return DPERR_GENERIC;
}
/* The enumeration will return FALSE if we are not to continue */
......@@ -3656,11 +3800,12 @@ static HRESULT WINAPI DirectPlay3AImpl_EnumConnections
dpName.u2.lpszLongNameA = NULL;
/* Create the compound address for the service provider.
NOTE: This is a gruesome architectural scar right now. DP uses DPL and DPL uses DP,
nasty stuff. This may be why the native dll just gets around this little bit by
allocating an 80 byte buffer which isn't even filled with a valid compound
address. Oh well. Creating a proper compound address is the way to go anyway...
NOTE: This is a gruesome architectural scar right now. DP uses DPL and DPL uses DP
nast stuff. This may be why the native dll just gets around this little bit by
allocating an 80 byte buffer which isn't even a filled with a valid compound
address. Oh well. Creating a proper compound address is the way to go anyways
despite this method taking slightly more heap space and realtime :) */
dpCompoundAddress.guidDataType = DPAID_LobbyProvider;
dpCompoundAddress.dwDataSize = sizeof( GUID );
dpCompoundAddress.lpData = &serviceProviderGUID;
......@@ -3895,10 +4040,12 @@ static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData, LPBOOL lpbIsDp
continue;
}
/* Save the name of the SP or LP */
if( i == 0 ) /* DP SP */
{
len = MultiByteToWideChar( CP_ACP, 0, subKeyName, -1, NULL, 0 );
lpSpData->lpszName = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, subKeyName, -1, lpSpData->lpszName, len );
}
sizeOfReturnBuffer = 255;
......@@ -3911,7 +4058,10 @@ static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData, LPBOOL lpbIsDp
continue;
}
if( i == 0 )
{
lpSpData->dwReserved1 = GET_DWORD( returnBuffer );
}
sizeOfReturnBuffer = 255;
......@@ -3924,8 +4074,10 @@ static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData, LPBOOL lpbIsDp
continue;
}
if( i == 0 )
{
lpSpData->dwReserved2 = GET_DWORD( returnBuffer );
}
sizeOfReturnBuffer = 255;
......@@ -3946,12 +4098,92 @@ static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData, LPBOOL lpbIsDp
return 0;
}
static
HRESULT DP_InitializeDPSP( IDirectPlay3Impl* This, HMODULE hServiceProvider )
{
HRESULT hr;
LPDPSP_SPINIT SPInit;
/* Initialize the service provider by calling SPInit */
SPInit = (LPDPSP_SPINIT)GetProcAddress( hServiceProvider, "SPInit" );
if( SPInit == NULL )
{
ERR( "Service provider doesn't provide SPInit interface?\n" );
FreeLibrary( hServiceProvider );
return DPERR_UNAVAILABLE;
}
TRACE( "Calling SPInit (DP SP entry point)\n" );
hr = (*SPInit)( &This->dp2->spData );
if( FAILED(hr) )
{
ERR( "DP SP Initialization failed: %s\n", DPLAYX_HresultToString(hr) );
FreeLibrary( hServiceProvider );
return hr;
}
/* FIXME: Need to verify the sanity of the returned callback table
* using IsBadCodePtr */
This->dp2->bSPInitialized = TRUE;
/* This interface is now initialized as a DP object */
This->dp2->connectionInitialized = DP_SERVICE_PROVIDER;
/* Store the handle of the module so that we can unload it later */
This->dp2->hServiceProvider = hServiceProvider;
return hr;
}
static
HRESULT DP_InitializeDPLSP( IDirectPlay3Impl* This, HMODULE hLobbyProvider )
{
HRESULT hr;
LPSP_INIT DPLSPInit;
/* Initialize the service provider by calling SPInit */
DPLSPInit = (LPSP_INIT)GetProcAddress( hLobbyProvider, "DPLSPInit" );
if( DPLSPInit == NULL )
{
ERR( "Service provider doesn't provide DPLSPInit interface?\n" );
FreeLibrary( hLobbyProvider );
return DPERR_UNAVAILABLE;
}
TRACE( "Calling DPLSPInit (DPL SP entry point)\n" );
hr = (*DPLSPInit)( &This->dp2->dplspData );
if( FAILED(hr) )
{
ERR( "DPL SP Initialization failed: %s\n", DPLAYX_HresultToString(hr) );
FreeLibrary( hLobbyProvider );
return hr;
}
/* FIXME: Need to verify the sanity of the returned callback table
* using IsBadCodePtr */
This->dp2->bDPLSPInitialized = TRUE;
/* This interface is now initialized as a lobby object */
This->dp2->connectionInitialized = DP_LOBBY_PROVIDER;
/* Store the handle of the module so that we can unload it later */
This->dp2->hDPLobbyProvider = hLobbyProvider;
return hr;
}
static HRESULT WINAPI DP_IF_InitializeConnection
( IDirectPlay3Impl* This, LPVOID lpConnection, DWORD dwFlags, BOOL bAnsi )
{
HMODULE hServiceProvider;
HRESULT hr;
LPDPSP_SPINIT SPInit;
GUID guidSP;
const DWORD dwAddrSize = 80; /* FIXME: Need to calculate it correctly */
BOOL bIsDpSp; /* TRUE if Direct Play SP, FALSE if Direct Play Lobby SP */
......@@ -3963,11 +4195,6 @@ static HRESULT WINAPI DP_IF_InitializeConnection
return DPERR_INVALIDFLAGS;
}
if( This->dp2->bConnectionInitialized == TRUE )
{
return DPERR_ALREADYINITIALIZED;
}
/* Find out what the requested SP is and how large this buffer is */
hr = DPL_EnumAddress( DP_GetSpLpGuidFromCompoundAddress, lpConnection,
dwAddrSize, &guidSP );
......@@ -3978,13 +4205,6 @@ static HRESULT WINAPI DP_IF_InitializeConnection
return DPERR_UNAVAILABLE;
}
/* Initialize what we can of the Service Provider required information.
* The rest will be done in DP_LoadSP
*/
This->dp2->spData.lpAddress = lpConnection;
This->dp2->spData.dwAddressSize = dwAddrSize;
This->dp2->spData.lpGuid = &guidSP;
/* Load the service provider */
hServiceProvider = DP_LoadSP( &guidSP, &This->dp2->spData, &bIsDpSp );
......@@ -3996,43 +4216,27 @@ static HRESULT WINAPI DP_IF_InitializeConnection
if( bIsDpSp )
{
/* Initialize the service provider by calling SPInit */
SPInit = (LPDPSP_SPINIT)GetProcAddress( hServiceProvider, "SPInit" );
/* Fill in what we can of the Service Provider required information.
* The rest was be done in DP_LoadSP
*/
This->dp2->spData.lpAddress = lpConnection;
This->dp2->spData.dwAddressSize = dwAddrSize;
This->dp2->spData.lpGuid = &guidSP;
hr = DP_InitializeDPSP( This, hServiceProvider );
}
else
{
/* Initialize the service provider by calling SPInit */
SPInit = (LPDPSP_SPINIT)GetProcAddress( hServiceProvider, "DPLSPInit" );
}
This->dp2->dplspData.lpAddress = lpConnection;
if( SPInit == NULL )
{
ERR( "Service provider doesn't provide %s interface?\n",
bIsDpSp ? "SPInit" : "DPLSPInit" );
FreeLibrary( hServiceProvider );
return DPERR_UNAVAILABLE;
hr = DP_InitializeDPLSP( This, hServiceProvider );
}
TRACE( "Calling %s (SP entry point)\n", bIsDpSp ? "SPInit" : "DPLSPInit" );
/* FIXME: Need to break this out into a separate routine for DP SP and
* DPL SP as they actually use different stuff...
*/
hr = (*SPInit)( &This->dp2->spData );
if( FAILED(hr) )
{
ERR( "DP/DPL SP Initialization failed: %s\n", DPLAYX_HresultToString(hr) );
FreeLibrary( hServiceProvider );
return hr;
}
/* This interface is now initialized */
This->dp2->bConnectionInitialized = TRUE;
/* Store the handle of the module so that we can unload it later */
This->dp2->hServiceProvider = hServiceProvider;
return DP_OK;
}
......@@ -4040,6 +4244,13 @@ static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
( LPDIRECTPLAY3A iface, LPVOID lpConnection, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay3Impl,iface);
/* This may not be externally invoked once either an SP or LP is initialized */
if( This->dp2->connectionInitialized != NO_PROVIDER )
{
return DPERR_ALREADYINITIALIZED;
}
return DP_IF_InitializeConnection( This, lpConnection, dwFlags, TRUE );
}
......@@ -4047,6 +4258,13 @@ static HRESULT WINAPI DirectPlay3WImpl_InitializeConnection
( LPDIRECTPLAY3 iface, LPVOID lpConnection, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay3Impl,iface);
/* This may not be externally invoked once either an SP or LP is initialized */
if( This->dp2->connectionInitialized != NO_PROVIDER )
{
return DPERR_ALREADYINITIALIZED;
}
return DP_IF_InitializeConnection( This, lpConnection, dwFlags, FALSE );
}
......
......@@ -2,6 +2,7 @@
#define __WINE_DPLAY_GLOBAL_INCLUDED
#include "dplaysp.h"
#include "lobbysp.h"
#include "dplayx_queue.h"
extern HRESULT DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
......@@ -126,7 +127,14 @@ struct DPMSG
};
typedef struct DPMSG* LPDPMSG;
/* Contains all dp1 and dp2 data members */
enum SPSTATE
{
NO_PROVIDER = 0,
DP_SERVICE_PROVIDER = 1,
DP_LOBBY_PROVIDER = 2
};
/* Contains all data members. FIXME: Rename me */
typedef struct tagDirectPlay2Data
{
BOOL bConnectionOpen;
......@@ -149,11 +157,19 @@ typedef struct tagDirectPlay2Data
/* Information about the service provider active on this connection */
SPINITDATA spData;
BOOL bSPInitialized;
/* Information about the lobby server that's attached to this DP object */
SPDATA_INIT dplspData;
BOOL bDPLSPInitialized;
/* Our service provider */
HMODULE hServiceProvider;
BOOL bConnectionInitialized;
/* Our DP lobby provider */
HMODULE hDPLobbyProvider;
enum SPSTATE connectionInitialized;
/* Expected messages queue */
DPQ_HEAD( tagDP_MSG_REPLY_STRUCT_LIST ) replysExpected;
......
......@@ -168,10 +168,8 @@ static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp )
* to it (ie we'd be stuck with always having one reference to the dplay
* object, and hence us, around).
* NOTE: The dp object does reference count us.
*/
/* IDirectPlayX_AddRef( (LPDIRECTPLAY2)dp ); */
/* FIXME: This is a kludge to get around a problem where a queryinterface
*
* FIXME: This is a kludge to get around a problem where a queryinterface
* is used to get a new interface and then is closed. We will then
* reference garbage. However, with this we will never deallocate
* the interface we store. The correct fix is to require all
......@@ -297,6 +295,8 @@ static HRESULT WINAPI IDirectPlaySPImpl_AddMRUEntry
{
ICOM_THIS(IDirectPlaySPImpl,iface);
/* Should be able to call the comctl32 undocumented MRU routines.
I suspect that the interface works appropriately */
FIXME( "(%p)->(%p,%p%p,0x%08lx,0x%08lx): stub\n",
This, lpSection, lpKey, lpData, dwDataSize, dwMaxEntries );
......@@ -350,6 +350,8 @@ static HRESULT WINAPI IDirectPlaySPImpl_EnumMRUEntries
{
ICOM_THIS(IDirectPlaySPImpl,iface);
/* Should be able to call the comctl32 undocumented MRU routines.
I suspect that the interface works appropriately */
FIXME( "(%p)->(%p,%p,%p,%p,): stub\n",
This, lpSection, lpKey, lpEnumMRUCallback, lpContext );
......@@ -382,7 +384,6 @@ static HRESULT WINAPI IDirectPlaySPImpl_GetSPPlayerData
LPDP_SPPLAYERDATA lpPlayerData;
ICOM_THIS(IDirectPlaySPImpl,iface);
/* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
TRACE( "(%p)->(0x%08lx,%p,%p,0x%08lx)\n",
This, idPlayer, lplpData, lpdwDataSize, dwFlags );
......@@ -435,10 +436,10 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
HRESULT hr = DPERR_GENERIC;
WORD wCommandId;
WORD wVersion;
DPSP_REPLYDATA data;
ICOM_THIS(IDirectPlaySPImpl,iface);
/* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
FIXME( "(%p)->(%p,0x%08lx,%p): mostly stub\n",
This, lpMessageBody, dwMessageBodySize, lpMessageHeader );
......@@ -451,52 +452,19 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
if( lpMsg->dwMagic != DPMSGMAGIC_DPLAYMSG )
{
ERR( "Unknown magic 0x%08lx!\n", lpMsg->dwMagic );
return DPERR_GENERIC;
}
switch( lpMsg->wCommandId )
{
/* Name server needs to handle this request */
/* FIXME: This should be done in direct play handler */
case DPMSGCMD_ENUMSESSIONSREQUEST:
{
DPSP_REPLYDATA data;
data.lpSPMessageHeader = lpMessageHeader;
data.idNameServer = 0;
data.lpISP = iface;
NS_ReplyToEnumSessionsRequest( lpMessageBody, &data, This->sp->dplay );
hr = (This->sp->dplay->dp2->spData.lpCB->Reply)( &data );
if( FAILED(hr) )
{
ERR( "Reply failed 0x%08lx\n", hr );
}
break;
}
/* Name server needs to handle this request */
/* FIXME: This should be done in direct play handler */
case DPMSGCMD_ENUMSESSIONSREPLY:
#if 0
{
NS_SetRemoteComputerAsNameServer( lpMessageHeader,
This->sp->dplay->dp2->spData.dwSPHeaderSize,
(LPDPMSG_ENUMSESSIONSREPLY)lpMessageBody,
This->sp->dplay->dp2->lpNameServerData );
const LPDWORD lpcHeader = (LPDWORD)lpMessageHeader;
/* No reply expected */
hr = DP_OK;
break;
TRACE( "lpMessageHeader = [0x%08lx] [0x%08lx] [0x%08lx] [0x%08lx] [0x%08lx]\n",
lpcHeader[0], lpcHeader[1], lpcHeader[2], lpcHeader[3], lpcHeader[4] );
}
#endif
/* Pass everything else to Direct Play */
default:
{
DPSP_REPLYDATA data;
data.lpMessage = NULL;
data.dwMessageSize = 0;
......@@ -505,11 +473,14 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
lpMessageHeader, wCommandId, wVersion,
&data.lpMessage, &data.dwMessageSize );
if( FAILED(hr) )
{
ERR( "Command processing failed %s\n", DPLAYX_HresultToString(hr) );
}
/* Do we want a reply? */
if( data.lpMessage != NULL )
{
HRESULT hr;
data.lpSPMessageHeader = lpMessageHeader;
data.idNameServer = 0;
data.lpISP = iface;
......@@ -522,9 +493,7 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
}
}
break;
}
}
return hr;
#if 0
HRESULT hr = DP_OK;
......@@ -768,8 +737,6 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
SetEvent( hReceiveEvent );
}
#endif
return hr;
}
static HRESULT WINAPI IDirectPlaySPImpl_SetSPPlayerData
......@@ -859,7 +826,7 @@ static HRESULT WINAPI IDirectPlaySPImpl_GetSPData
*/
if( dwFlags != DPSET_REMOTE )
{
FIXME( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
TRACE( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
}
#endif
......@@ -918,7 +885,7 @@ static HRESULT WINAPI IDirectPlaySPImpl_SetSPData
*/
if( dwFlags != DPSET_REMOTE )
{
FIXME( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
TRACE( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
}
#endif
......
......@@ -1240,10 +1240,8 @@ LPCSTR DPLAYX_HresultToString(HRESULT hr)
return "DPERR_NOPLAYERS";
case DPERR_NOSESSIONS:
return "DPERR_NOSESSIONS";
/* This one isn't defined yet in WINE sources. I don't know the value
case DPERR_PENDING:
return "DPERR_PENDING";
*/
case DPERR_SENDTOOBIG:
return "DPERR_SENDTOOBIG";
case DPERR_TIMEOUT:
......
/* DirectPlay & DirectPlayLobby messaging implementation
*
* Copyright 2000 - Peter Hunnisett
* Copyright 2000,2001 - Peter Hunnisett
*
* <presently under construction - contact hunnise@nortelnetworks.com>
*
......@@ -17,6 +17,7 @@
#include "dplayx_messages.h"
#include "dplay_global.h"
#include "dplayx_global.h"
#include "name_server.h"
DEFAULT_DEBUG_CHANNEL(dplay);
......@@ -212,7 +213,6 @@ HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
TRACE( "Asking for player id w/ dwFlags 0x%08lx\n",
lpMsgBody->dwFlags );
DP_MSG_ExpectReply( This, &data, DPMSG_DEFAULT_WAIT_TIME, DPMSGCMD_NEWPLAYERIDREPLY,
&lpMsg, &dwMsgSize );
}
......@@ -267,7 +267,7 @@ HRESULT DP_MSG_ForwardPlayerCreation( IDirectPlay2AImpl* This, DPID dpidServer )
DWORD dwDataSize;
/* SP Player remote data needs to be propagated at some point - is this the point? */
IDirectPlaySP_GetSPPlayerData( This->dp2->spData.lpISP, dpidServer, (LPVOID*)&lpPData, &dwDataSize, DPSET_REMOTE );
IDirectPlaySP_GetSPPlayerData( This->dp2->spData.lpISP, 0, (LPVOID*)&lpPData, &dwDataSize, DPSET_REMOTE );
ERR( "Player Data size is 0x%08lx\n"
"[%02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x]\n"
......@@ -305,11 +305,22 @@ HRESULT DP_MSG_ForwardPlayerCreation( IDirectPlay2AImpl* This, DPID dpidServer )
lpMsgBody->unknown4[0] = 0x30;
lpMsgBody->unknown4[1] = 0xb;
lpMsgBody->unknown4[2] = 0x0;
lpMsgBody->unknown4[3] = 0x1e090002;
lpMsgBody->unknown4[3] = NS_GetNsMagic( This->dp2->lpNameServerData ) -
0x02000000;
TRACE( "Setting first magic to 0x%08lx\n", lpMsgBody->unknown4[3] );
lpMsgBody->unknown4[4] = 0x0;
lpMsgBody->unknown4[5] = 0x0;
lpMsgBody->unknown4[6] = 0x0;
lpMsgBody->unknown4[7] = 0x32090002;
#if 0
lpMsgBody->unknown4[7] = NS_GetOtherMagic( This->dp2->lpNameServerData )
#else
lpMsgBody->unknown4[7] = NS_GetNsMagic( This->dp2->lpNameServerData );
#endif
TRACE( "Setting second magic to 0x%08lx\n", lpMsgBody->unknown4[7] );
lpMsgBody->unknown4[8] = 0x0;
lpMsgBody->unknown4[9] = 0x0;
lpMsgBody->unknown4[10] = 0x0;
......@@ -331,6 +342,8 @@ HRESULT DP_MSG_ForwardPlayerCreation( IDirectPlay2AImpl* This, DPID dpidServer )
data.bSystemMessage = TRUE; /* Allow reply to be sent */
data.lpISP = This->dp2->spData.lpISP;
TRACE( "Sending forward player request with 0x%08lx\n", dpidServer );
lpMsg = DP_MSG_ExpectReply( This, &data,
DPMSG_WAIT_60_SECS,
DPMSGCMD_GETNAMETABLEREPLY,
......@@ -372,11 +385,13 @@ LPVOID DP_MSG_ExpectReply( IDirectPlay2AImpl* This, LPDPSP_SENDDATA lpData,
if( FAILED(hr) )
{
ERR( "Request for new playerID send failed: %s\n",
DPLAYX_HresultToString( hr ) );
ERR( "Send failed: %s\n", DPLAYX_HresultToString( hr ) );
return NULL;
}
/* The reply message will trigger the hMsgReceipt event effectively switching
* control back to this thread. See DP_MSG_ReplyReceived.
*/
dwWaitReturn = WaitForSingleObject( hMsgReceipt, dwWaitTime );
if( dwWaitReturn != WAIT_OBJECT_0 )
{
......@@ -429,7 +444,43 @@ void DP_MSG_ReplyReceived( IDirectPlay2AImpl* This, WORD wCommandId,
ERR( "No receipt event set - only expecting in reply mode\n" );
DebugBreak();
}
}
void DP_MSG_ToSelf( IDirectPlay2AImpl* This, DPID dpidSelf )
{
LPVOID lpMsg;
LPDPMSG_SENDENVELOPE lpMsgBody;
DWORD dwMsgSize;
dwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpMsgBody );
lpMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwMsgSize );
lpMsgBody = (LPDPMSG_SENDENVELOPE)( (BYTE*)lpMsg +
This->dp2->spData.dwSPHeaderSize );
/* Compose dplay message envelope */
lpMsgBody->dwMagic = DPMSGMAGIC_DPLAYMSG;
lpMsgBody->wCommandId = DPMSGCMD_JUSTENVELOPE;
lpMsgBody->wVersion = DPMSGVER_DP6;
/* Send the message to ourselves */
{
DPSP_SENDDATA data;
data.dwFlags = 0;
data.idPlayerTo = dpidSelf; /* Sending to session server */
data.idPlayerFrom = 0; /* Sending from session server */
data.lpMessage = lpMsg;
data.dwMessageSize = dwMsgSize;
data.bSystemMessage = TRUE; /* Allow reply to be sent */
data.lpISP = This->dp2->spData.lpISP;
lpMsg = DP_MSG_ExpectReply( This, &data,
DPMSG_WAIT_5_SECS,
DPMSGCMD_JUSTENVELOPE,
&lpMsg, &dwMsgSize );
}
}
void DP_MSG_ErrorReceived( IDirectPlay2AImpl* This, WORD wCommandId,
......
......@@ -19,6 +19,7 @@ void DP_MSG_ReplyReceived( IDirectPlay2AImpl* This, WORD wCommandId,
LPCVOID lpMsgBody, DWORD dwMsgBodySize );
void DP_MSG_ErrorReceived( IDirectPlay2AImpl* This, WORD wCommandId,
LPCVOID lpMsgBody, DWORD dwMsgBodySize );
void DP_MSG_ToSelf( IDirectPlay2AImpl* This, DPID dpidSelf );
/* Timings -> 1000 ticks/sec */
#define DPMSG_WAIT_5_SECS 5000
......@@ -47,8 +48,13 @@ void DP_MSG_ErrorReceived( IDirectPlay2AImpl* This, WORD wCommandId,
#define DPMSGCMD_FORWARDADDPLAYER 19
#define DPMSGCMD_PLAYERCHAT 22
#define DPMSGCMD_FORWARDADDPLAYERNACK 36
#define DPMSGCMD_JUSTENVELOPE 1000
#define DPMSGCMD_JUSTENVELOPEREPLY 1001
/* This is what DP 6 defines it as. Don't know what it means. All messages
* defined below are DPMSGVER_DP6.
*/
......@@ -163,21 +169,21 @@ typedef struct tagDPMSG_FORWARDADDPLAYER
DWORD unknown; /* 0 */
DPID dpidAppServer; /* Remote application server id */
DWORD unknown2[5]; /* ??? */
#define FORWARDADDPLAYER_UNKNOWN2_INIT { 0x0, 0x1c, 0x6c, 0x50, 0x9 }
DWORD unknown2[5]; /* 0x0, 0x1c, 0x6c, 0x50, 0x9 */
DPID dpidAppServer2; /* Remote application server id again !? */
DWORD unknown3[5]; /* ??? */
#define FORWARDADDPLAYER_UNKNOWN3_INIT { 0x0, 0x0, 0x20, 0x0, 0x0 }
DWORD unknown3[5]; /* 0x0, 0x0, 0x20, 0x0, 0x0 */
DPID dpidAppServer3; /* Remote application server id again !? */
DWORD unknown4[12]; /* ??? - Is this a clump of 5 and then 8? */
/* NOTE: 1 byte infront of the two 0x??090002 entries changes! */
/* NOTE: 1 byte infront of the two 0x??090002 entries changes!
* Is it a timestamp of some sort? 1st always smaller than
* other...
*/
#define FORWARDADDPLAYER_UNKNOWN4_INIT { 0x30, 0xb, 0x0, 0x1e090002, 0x0, 0x0, 0x0, 0x32090002, 0x0, 0x0, 0x0, 0x0 }
BYTE unknown5[2]; /* 2 bytes at the end. This may be a part of something! */
#define FORWARDADDPLAYER_UNKNOWN5_INIT { 0x0 }
BYTE unknown5[2]; /* 2 bytes at the end. This may be a part of something! ( 0x0, 0x0) */
} DPMSG_FORWARDADDPLAYER, *LPDPMSG_FORWARDADDPLAYER;
typedef const DPMSG_FORWARDADDPLAYER* LPCDPMSG_FORWARDADDPLAYER;
......
/* This contains the implementation of the Lobby Service
* Providers interface required to communicate with Direct Play
*
* Copyright 2001 Peter Hunnisett <hunnise@nortelnetworks.com>
*/
#include "winerror.h"
#include "debugtools.h"
#include "lobbysp.h"
#include "dplay_global.h"
#include "dpinit.h"
DEFAULT_DEBUG_CHANNEL(dplay);
/* Prototypes */
static BOOL DPLSP_CreateIUnknown( LPVOID lpSP );
static BOOL DPLSP_DestroyIUnknown( LPVOID lpSP );
static BOOL DPLSP_CreateDPLobbySP( LPVOID lpSP, IDirectPlay2Impl* dp );
static BOOL DPLSP_DestroyDPLobbySP( LPVOID lpSP );
/* Predefine the interface */
typedef struct IDPLobbySPImpl IDPLobbySPImpl;
typedef struct tagDPLobbySPIUnknownData
{
ULONG ulObjRef;
CRITICAL_SECTION DPLSP_lock;
} DPLobbySPIUnknownData;
typedef struct tagDPLobbySPData
{
IDirectPlay2Impl* dplay;
} DPLobbySPData;
#define DPLSP_IMPL_FIELDS \
ULONG ulInterfaceRef; \
DPLobbySPIUnknownData* unk; \
DPLobbySPData* sp;
struct IDPLobbySPImpl
{
ICOM_VFIELD(IDPLobbySP);
DPLSP_IMPL_FIELDS
};
/* Forward declaration of virtual tables */
static ICOM_VTABLE(IDPLobbySP) dpLobbySPVT;
extern
HRESULT DPLSP_CreateInterface( REFIID riid, LPVOID* ppvObj, IDirectPlay2Impl* dp )
{
TRACE( " for %s\n", debugstr_guid( riid ) );
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( IDPLobbySPImpl ) );
if( *ppvObj == NULL )
{
return DPERR_OUTOFMEMORY;
}
if( IsEqualGUID( &IID_IDPLobbySP, riid ) )
{
ICOM_THIS(IDPLobbySPImpl,*ppvObj);
ICOM_VTBL(This) = &dpLobbySPVT;
}
else
{
/* Unsupported interface */
HeapFree( GetProcessHeap(), 0, *ppvObj );
*ppvObj = NULL;
return E_NOINTERFACE;
}
/* Initialize it */
if( DPLSP_CreateIUnknown( *ppvObj ) &&
DPLSP_CreateDPLobbySP( *ppvObj, dp )
)
{
IDPLobbySP_AddRef( (LPDPLOBBYSP)*ppvObj );
return S_OK;
}
/* Initialize failed, destroy it */
DPLSP_DestroyDPLobbySP( *ppvObj );
DPLSP_DestroyIUnknown( *ppvObj );
HeapFree( GetProcessHeap(), 0, *ppvObj );
*ppvObj = NULL;
return DPERR_NOMEMORY;
}
static BOOL DPLSP_CreateIUnknown( LPVOID lpSP )
{
ICOM_THIS(IDPLobbySPImpl,lpSP);
This->unk = (DPLobbySPIUnknownData*)HeapAlloc( GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof( *(This->unk) ) );
if ( This->unk == NULL )
{
return FALSE;
}
InitializeCriticalSection( &This->unk->DPLSP_lock );
return TRUE;
}
static BOOL DPLSP_DestroyIUnknown( LPVOID lpSP )
{
ICOM_THIS(IDPLobbySPImpl,lpSP);
DeleteCriticalSection( &This->unk->DPLSP_lock );
HeapFree( GetProcessHeap(), 0, This->unk );
return TRUE;
}
static BOOL DPLSP_CreateDPLobbySP( LPVOID lpSP, IDirectPlay2Impl* dp )
{
ICOM_THIS(IDPLobbySPImpl,lpSP);
This->sp = (DPLobbySPData*)HeapAlloc( GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof( *(This->sp) ) );
if ( This->sp == NULL )
{
return FALSE;
}
This->sp->dplay = dp;
/* Normally we should be keeping a reference, but since only the dplay
* interface that created us can destroy us, we do not keep a reference
* to it (ie we'd be stuck with always having one reference to the dplay
* object, and hence us, around).
* NOTE: The dp object does reference count us.
*
* FIXME: This is a kludge to get around a problem where a queryinterface
* is used to get a new interface and then is closed. We will then
* reference garbage. However, with this we will never deallocate
* the interface we store. The correct fix is to require all
* DP internal interfaces to use the This->dp2 interface which
* should be changed to This->dp
*/
IDirectPlayX_AddRef( (LPDIRECTPLAY2)dp );
return TRUE;
}
static BOOL DPLSP_DestroyDPLobbySP( LPVOID lpSP )
{
ICOM_THIS(IDPLobbySPImpl,lpSP);
HeapFree( GetProcessHeap(), 0, This->sp );
return TRUE;
}
static
HRESULT WINAPI DPLSP_QueryInterface
( LPDPLOBBYSP iface,
REFIID riid,
LPVOID* ppvObj
)
{
ICOM_THIS(IDPLobbySPImpl,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 ) );
(*(IDPLobbySPImpl**)ppvObj)->ulInterfaceRef = 0;
if( IsEqualGUID( &IID_IDPLobbySP, riid ) )
{
ICOM_THIS(IDPLobbySPImpl,*ppvObj);
ICOM_VTBL(This) = &dpLobbySPVT;
}
else
{
/* Unsupported interface */
HeapFree( GetProcessHeap(), 0, *ppvObj );
*ppvObj = NULL;
return E_NOINTERFACE;
}
IDPLobbySP_AddRef( (LPDPLOBBYSP)*ppvObj );
return S_OK;
}
static
ULONG WINAPI DPLSP_AddRef
( LPDPLOBBYSP iface )
{
ULONG ulInterfaceRefCount, ulObjRefCount;
ICOM_THIS(IDPLobbySPImpl,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 DPLSP_Release
( LPDPLOBBYSP iface )
{
ULONG ulInterfaceRefCount, ulObjRefCount;
ICOM_THIS(IDPLobbySPImpl,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 )
{
DPLSP_DestroyDPLobbySP( This );
DPLSP_DestroyIUnknown( This );
}
if( ulInterfaceRefCount == 0 )
{
HeapFree( GetProcessHeap(), 0, This );
}
return ulInterfaceRefCount;
}
static
HRESULT WINAPI IDPLobbySPImpl_AddGroupToGroup
( LPDPLOBBYSP iface,
LPSPDATA_ADDREMOTEGROUPTOGROUP argtg
)
{
ICOM_THIS(IDPLobbySPImpl,iface);
FIXME( "(%p)->(%p):stub\n", This, argtg );
return DP_OK;
}
static
HRESULT WINAPI IDPLobbySPImpl_AddPlayerToGroup
( LPDPLOBBYSP iface,
LPSPDATA_ADDREMOTEPLAYERTOGROUP arptg
)
{
ICOM_THIS(IDPLobbySPImpl,iface);
FIXME( "(%p)->(%p):stub\n", This, arptg );
return DP_OK;
}
static
HRESULT WINAPI IDPLobbySPImpl_CreateGroup
( LPDPLOBBYSP iface,
LPSPDATA_CREATEREMOTEGROUP crg
)
{
ICOM_THIS(IDPLobbySPImpl,iface);
FIXME( "(%p)->(%p):stub\n", This, crg );
return DP_OK;
}
static
HRESULT WINAPI IDPLobbySPImpl_CreateGroupInGroup
( LPDPLOBBYSP iface,
LPSPDATA_CREATEREMOTEGROUPINGROUP crgig
)
{
ICOM_THIS(IDPLobbySPImpl,iface);
FIXME( "(%p)->(%p):stub\n", This, crgig );
return DP_OK;
}
static
HRESULT WINAPI IDPLobbySPImpl_DeleteGroupFromGroup
( LPDPLOBBYSP iface,
LPSPDATA_DELETEREMOTEGROUPFROMGROUP drgfg
)
{
ICOM_THIS(IDPLobbySPImpl,iface);
FIXME( "(%p)->(%p):stub\n", This, drgfg );
return DP_OK;
}
static
HRESULT WINAPI IDPLobbySPImpl_DeletePlayerFromGroup
( LPDPLOBBYSP iface,
LPSPDATA_DELETEREMOTEPLAYERFROMGROUP drpfg
)
{
ICOM_THIS(IDPLobbySPImpl,iface);
FIXME( "(%p)->(%p):stub\n", This, drpfg );
return DP_OK;
}
static
HRESULT WINAPI IDPLobbySPImpl_DestroyGroup
( LPDPLOBBYSP iface,
LPSPDATA_DESTROYREMOTEGROUP drg
)
{
ICOM_THIS(IDPLobbySPImpl,iface);
FIXME( "(%p)->(%p):stub\n", This, drg );
return DP_OK;
}
static
HRESULT WINAPI IDPLobbySPImpl_EnumSessionsResponse
( LPDPLOBBYSP iface,
LPSPDATA_ENUMSESSIONSRESPONSE er
)
{
ICOM_THIS(IDPLobbySPImpl,iface);
FIXME( "(%p)->(%p):stub\n", This, er );
return DP_OK;
}
static
HRESULT WINAPI IDPLobbySPImpl_GetSPDataPointer
( LPDPLOBBYSP iface,
LPVOID* lplpData
)
{
ICOM_THIS(IDPLobbySPImpl,iface);
FIXME( "(%p)->(%p):stub\n", This, lplpData );
return DP_OK;
}
static
HRESULT WINAPI IDPLobbySPImpl_HandleMessage
( LPDPLOBBYSP iface,
LPSPDATA_HANDLEMESSAGE hm
)
{
ICOM_THIS(IDPLobbySPImpl,iface);
FIXME( "(%p)->(%p):stub\n", This, hm );
return DP_OK;
}
static
HRESULT WINAPI IDPLobbySPImpl_SendChatMessage
( LPDPLOBBYSP iface,
LPSPDATA_CHATMESSAGE cm
)
{
ICOM_THIS(IDPLobbySPImpl,iface);
FIXME( "(%p)->(%p):stub\n", This, cm );
return DP_OK;
}
static
HRESULT WINAPI IDPLobbySPImpl_SetGroupName
( LPDPLOBBYSP iface,
LPSPDATA_SETREMOTEGROUPNAME srgn
)
{
ICOM_THIS(IDPLobbySPImpl,iface);
FIXME( "(%p)->(%p):stub\n", This, srgn );
return DP_OK;
}
static
HRESULT WINAPI IDPLobbySPImpl_SetPlayerName
( LPDPLOBBYSP iface,
LPSPDATA_SETREMOTEPLAYERNAME srpn
)
{
ICOM_THIS(IDPLobbySPImpl,iface);
FIXME( "(%p)->(%p):stub\n", This, srpn );
return DP_OK;
}
static
HRESULT WINAPI IDPLobbySPImpl_SetSessionDesc
( LPDPLOBBYSP iface,
LPSPDATA_SETSESSIONDESC ssd
)
{
ICOM_THIS(IDPLobbySPImpl,iface);
FIXME( "(%p)->(%p):stub\n", This, ssd );
return DP_OK;
}
static
HRESULT WINAPI IDPLobbySPImpl_SetSPDataPointer
( LPDPLOBBYSP iface,
LPVOID lpData
)
{
ICOM_THIS(IDPLobbySPImpl,iface);
FIXME( "(%p)->(%p):stub\n", This, lpData );
return DP_OK;
}
static
HRESULT WINAPI IDPLobbySPImpl_StartSession
( LPDPLOBBYSP iface,
LPSPDATA_STARTSESSIONCOMMAND ssc
)
{
ICOM_THIS(IDPLobbySPImpl,iface);
FIXME( "(%p)->(%p):stub\n", This, ssc );
return DP_OK;
}
static struct ICOM_VTABLE(IDPLobbySP) dpLobbySPVT =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
DPLSP_QueryInterface,
DPLSP_AddRef,
DPLSP_Release,
IDPLobbySPImpl_AddGroupToGroup,
IDPLobbySPImpl_AddPlayerToGroup,
IDPLobbySPImpl_CreateGroup,
IDPLobbySPImpl_CreateGroupInGroup,
IDPLobbySPImpl_DeleteGroupFromGroup,
IDPLobbySPImpl_DeletePlayerFromGroup,
IDPLobbySPImpl_DestroyGroup,
IDPLobbySPImpl_EnumSessionsResponse,
IDPLobbySPImpl_GetSPDataPointer,
IDPLobbySPImpl_HandleMessage,
IDPLobbySPImpl_SendChatMessage,
IDPLobbySPImpl_SetGroupName,
IDPLobbySPImpl_SetPlayerName,
IDPLobbySPImpl_SetSessionDesc,
IDPLobbySPImpl_SetSPDataPointer,
IDPLobbySPImpl_StartSession
};
#ifndef __WINE_LOBBY_SP_H
#define __WINE_LOBBY_SP_H
#include "dplobby.h"
/* GUID for IDPLobbySP {5A4E5A20-2CED-11d0-A889-00A0C905433C} */
DEFINE_GUID(IID_IDPLobbySP, 0x5a4e5a20, 0x2ced, 0x11d0, 0xa8, 0x89, 0x0, 0xa0, 0xc9, 0x5, 0x43, 0x3c);
typedef struct IDPLobbySP IDPLobbySP, *LPDPLOBBYSP;
/* For SP. Top 16 bits is dplay, bottom 16 is SP */
#define DPLSP_MAJORVERSION 0x00050000
typedef struct SPDATA_ADDGROUPTOGROUP
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwParentID;
DWORD dwGroupID;
} SPDATA_ADDGROUPTOGROUP, *LPSPDATA_ADDGROUPTOGROUP;
typedef struct SPDATA_ADDPLAYERTOGROUP
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwGroupID;
DWORD dwPlayerID;
} SPDATA_ADDPLAYERTOGROUP, *LPSPDATA_ADDPLAYERTOGROUP;
typedef struct SPDATA_ADDREMOTEGROUPTOGROUP
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwAnchorID;
DWORD dwGroupID;
DWORD dwParentID;
LPDPNAME lpName;
DWORD dwGroupFlags;
} SPDATA_ADDREMOTEGROUPTOGROUP, *LPSPDATA_ADDREMOTEGROUPTOGROUP;
typedef struct SPDATA_ADDREMOTEPLAYERTOGROUP
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwGroupID;
DWORD dwPlayerID;
DWORD dwPlayerFlags;
LPDPNAME lpName;
} SPDATA_ADDREMOTEPLAYERTOGROUP, *LPSPDATA_ADDREMOTEPLAYERTOGROUP;
typedef struct SPDATA_BUILDPARENTALHEIRARCHY
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwGroupID;
DWORD dwMessage;
DWORD dwParentID;
} SPDATA_BUILDPARENTALHEIRARCHY, *LPSPDATA_BUILDPARENTALHEIRARCHY;
typedef struct SPDATA_CLOSE
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
} SPDATA_CLOSE, *LPSPDATA_CLOSE;
typedef struct SPDATA_CREATEGROUP
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwGroupID;
LPDPNAME lpName;
LPVOID lpData;
DWORD dwDataSize;
DWORD dwFlags;
} SPDATA_CREATEGROUP, *LPSPDATA_CREATEGROUP;
typedef struct SPDATA_CREATEGROUPINGROUP
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwParentID;
DWORD dwGroupID;
LPDPNAME lpName;
LPVOID lpData;
DWORD dwDataSize;
DWORD dwFlags;
} SPDATA_CREATEGROUPINGROUP, *LPSPDATA_CREATEGROUPINGROUP;
typedef struct SPDATA_CREATEREMOTEGROUP
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwGroupID;
LPDPNAME lpName;
LPVOID lpData;
DWORD dwDataSize;
DWORD dwFlags;
} SPDATA_CREATEREMOTEGROUP, *LPSPDATA_CREATEREMOTEGROUP;
typedef struct SPDATA_CREATEREMOTEGROUPINGROUP
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwParentID;
DWORD dwGroupID;
LPDPNAME lpName;
DWORD dwFlags;
} SPDATA_CREATEREMOTEGROUPINGROUP, *LPSPDATA_CREATEREMOTEGROUPINGROUP;
typedef struct SPDATA_CREATEPLAYER
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwPlayerID;
LPDPNAME lpName;
LPVOID lpData;
DWORD dwDataSize;
DWORD dwFlags;
} SPDATA_CREATEPLAYER, *LPSPDATA_CREATEPLAYER;
typedef struct SPDATA_DELETEGROUPFROMGROUP
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwParentID;
DWORD dwGroupID;
} SPDATA_DELETEGROUPFROMGROUP, *LPSPDATA_DELETEGROUPFROMGROUP;
typedef struct SPDATA_DELETEPLAYERFROMGROUP
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwGroupID;
DWORD dwPlayerID;
} SPDATA_DELETEPLAYERFROMGROUP, *LPSPDATA_DELETEPLAYERFROMGROUP;
typedef struct SPDATA_DELETEREMOTEGROUPFROMGROUP
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwParentID;
DWORD dwGroupID;
} SPDATA_DELETEREMOTEGROUPFROMGROUP, *LPSPDATA_DELETEREMOTEGROUPFROMGROUP;
typedef struct SPDATA_DELETEREMOTEPLAYERFROMGROUP
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwGroupID;
DWORD dwPlayerID;
} SPDATA_DELETEREMOTEPLAYERFROMGROUP, *LPSPDATA_DELETEREMOTEPLAYERFROMGROUP;
typedef struct SPDATA_DESTROYGROUP
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwGroupID;
} SPDATA_DESTROYGROUP, *LPSPDATA_DESTROYGROUP;
typedef struct SPDATA_DESTROYREMOTEGROUP
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwGroupID;
} SPDATA_DESTROYREMOTEGROUP, *LPSPDATA_DESTROYREMOTEGROUP;
typedef struct SPDATA_DESTROYPLAYER
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwPlayerID;
} SPDATA_DESTROYPLAYER, *LPSPDATA_DESTROYPLAYER;
typedef struct SPDATA_ENUMSESSIONS
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
LPDPSESSIONDESC2 lpsd;
DWORD dwTimeout;
DWORD dwFlags;
} SPDATA_ENUMSESSIONS, *LPSPDATA_ENUMSESSIONS;
typedef struct SPDATA_ENUMSESSIONSRESPONSE
{
DWORD dwSize;
LPDPSESSIONDESC2 lpsd;
} SPDATA_ENUMSESSIONSRESPONSE, *LPSPDATA_ENUMSESSIONSRESPONSE;
typedef struct SPDATA_GETCAPS
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwFlags;
LPDPCAPS lpcaps;
} SPDATA_GETCAPS, *LPSPDATA_GETCAPS;
typedef struct SPDATA_GETGROUPCONNECTIONSETTINGS
{
DWORD dwSize;
DWORD dwFlags;
LPDPLOBBYSP lpISP;
DWORD dwGroupID;
LPDWORD lpdwBufferSize;
LPVOID lpBuffer;
} SPDATA_GETGROUPCONNECTIONSETTINGS, *LPSPDATA_GETGROUPCONNECTIONSETTINGS;
typedef struct SPDATA_GETGROUPDATA
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwGroupID;
LPDWORD lpdwDataSize;
LPVOID lpData;
} SPDATA_GETGROUPDATA, *LPSPDATA_GETGROUPDATA;
typedef struct SPDATA_GETPLAYERCAPS
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwFlags;
DWORD dwPlayerID;
LPDPCAPS lpcaps;
} SPDATA_GETPLAYERCAPS, *LPSPDATA_GETPLAYERCAPS;
typedef struct SPDATA_GETPLAYERDATA
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwPlayerID;
LPDWORD lpdwDataSize;
LPVOID lpData;
} SPDATA_GETPLAYERDATA, *LPSPDATA_GETPLAYERDATA;
typedef struct SPDATA_HANDLEMESSAGE
{
DWORD dwSize;
DWORD dwFromID;
DWORD dwToID;
LPVOID lpBuffer;
DWORD dwBufSize;
} SPDATA_HANDLEMESSAGE, *LPSPDATA_HANDLEMESSAGE;
typedef struct SPDATA_OPEN
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
LPDPSESSIONDESC2 lpsd;
DWORD dwFlags;
LPCDPCREDENTIALS lpCredentials;
} SPDATA_OPEN, *LPSPDATA_OPEN;
typedef struct SPDATA_SEND
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwFromID;
DWORD dwToID;
DWORD dwFlags;
LPVOID lpBuffer;
DWORD dwBufSize;
} SPDATA_SEND, *LPSPDATA_SEND;
typedef struct SPDATA_CHATMESSAGE
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwFromID;
DWORD dwToID;
DWORD dwFlags;
LPDPCHAT lpChat;
} SPDATA_CHATMESSAGE, *LPSPDATA_CHATMESSAGE;
typedef struct SPDATA_SETGROUPCONNECTIONSETTINGS
{
DWORD dwSize;
DWORD dwFlags;
LPDPLOBBYSP lpISP;
DWORD dwGroupID;
LPDPLCONNECTION lpConn;
} SPDATA_SETGROUPCONNECTIONSETTINGS, *LPSPDATA_SETGROUPCONNECTIONSETTINGS;
typedef struct SPDATA_SETGROUPDATA
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwGroupID;
LPVOID lpData;
DWORD dwDataSize;
DWORD dwFlags;
} SPDATA_SETGROUPDATA, *LPSPDATA_SETGROUPDATA;
typedef struct SPDATA_SETGROUPNAME
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwGroupID;
LPDPNAME lpName;
DWORD dwFlags;
} SPDATA_SETGROUPNAME, *LPSPDATA_SETGROUPNAME;
typedef struct SPDATA_SETREMOTEGROUPNAME
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwGroupID;
LPDPNAME lpName;
DWORD dwFlags;
} SPDATA_SETREMOTEGROUPNAME, *LPSPDATA_SETREMOTEGROUPNAME;
typedef struct SPDATA_SETPLAYERDATA
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwPlayerID;
LPVOID lpData;
DWORD dwDataSize;
DWORD dwFlags;
} SPDATA_SETPLAYERDATA, *LPSPDATA_SETPLAYERDATA;
typedef struct SPDATA_SETPLAYERNAME
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwPlayerID;
LPDPNAME lpName;
DWORD dwFlags;
} SPDATA_SETPLAYERNAME, *LPSPDATA_SETPLAYERNAME;
typedef struct SPDATA_SETREMOTEPLAYERNAME
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwPlayerID;
LPDPNAME lpName;
DWORD dwFlags;
} SPDATA_SETREMOTEPLAYERNAME, *LPSPDATA_SETREMOTEPLAYERNAME;
typedef struct SPDATA_SETSESSIONDESC
{
DWORD dwSize;
LPDPSESSIONDESC2 lpsd;
} SPDATA_SETSESSIONDESC, *LPSPDATA_SETSESSIONDESC;
typedef struct SPDATA_SHUTDOWN
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
} SPDATA_SHUTDOWN, *LPSPDATA_SHUTDOWN;
typedef struct SPDATA_STARTSESSION
{
DWORD dwSize;
LPDPLOBBYSP lpISP;
DWORD dwFlags;
DWORD dwGroupID;
} SPDATA_STARTSESSION, *LPSPDATA_STARTSESSION;
typedef struct SPDATA_STARTSESSIONCOMMAND
{
DWORD dwFlags;
DWORD dwGroupID;
DWORD dwHostID;
LPDPLCONNECTION lpConn;
} SPDATA_STARTSESSIONCOMMAND, *LPSPDATA_STARTSESSIONCOMMAND;
/* Prototypes for callbacks returned by DPLSPInit */
typedef HRESULT (WINAPI *LPSP_ADDGROUPTOGROUP)(LPSPDATA_ADDGROUPTOGROUP);
typedef HRESULT (WINAPI *LPSP_ADDPLAYERTOGROUP)(LPSPDATA_ADDPLAYERTOGROUP);
typedef HRESULT (WINAPI *LPSP_BUILDPARENTALHEIRARCHY)(LPSPDATA_BUILDPARENTALHEIRARCHY);
typedef HRESULT (WINAPI *LPSP_CLOSE)(LPSPDATA_CLOSE);
typedef HRESULT (WINAPI *LPSP_CREATEGROUP)(LPSPDATA_CREATEGROUP);
typedef HRESULT (WINAPI *LPSP_CREATEGROUPINGROUP)(LPSPDATA_CREATEGROUPINGROUP);
typedef HRESULT (WINAPI *LPSP_CREATEPLAYER)(LPSPDATA_CREATEPLAYER);
typedef HRESULT (WINAPI *LPSP_DELETEGROUPFROMGROUP)(LPSPDATA_DELETEGROUPFROMGROUP);
typedef HRESULT (WINAPI *LPSP_DELETEPLAYERFROMGROUP)(LPSPDATA_DELETEPLAYERFROMGROUP);
typedef HRESULT (WINAPI *LPSP_DESTROYGROUP)(LPSPDATA_DESTROYGROUP);
typedef HRESULT (WINAPI *LPSP_DESTROYPLAYER)(LPSPDATA_DESTROYPLAYER);
typedef HRESULT (WINAPI *LPSP_ENUMSESSIONS)(LPSPDATA_ENUMSESSIONS);
typedef HRESULT (WINAPI *LPSP_GETCAPS)(LPSPDATA_GETCAPS);
typedef HRESULT (WINAPI *LPSP_GETGROUPCONNECTIONSETTINGS)(LPSPDATA_GETGROUPCONNECTIONSETTINGS);
typedef HRESULT (WINAPI *LPSP_GETGROUPDATA)(LPSPDATA_GETGROUPDATA);
typedef HRESULT (WINAPI *LPSP_GETPLAYERCAPS)(LPSPDATA_GETPLAYERCAPS);
typedef HRESULT (WINAPI *LPSP_GETPLAYERDATA)(LPSPDATA_GETPLAYERDATA);
typedef HRESULT (WINAPI *LPSP_HANDLEMESSAGE)(LPSPDATA_HANDLEMESSAGE);
typedef HRESULT (WINAPI *LPSP_OPEN)(LPSPDATA_OPEN);
typedef HRESULT (WINAPI *LPSP_SEND)(LPSPDATA_SEND);
typedef HRESULT (WINAPI *LPSP_SENDCHATMESSAGE)(LPSPDATA_CHATMESSAGE);
typedef HRESULT (WINAPI *LPSP_SETGROUPCONNECTIONSETTINGS)(LPSPDATA_SETGROUPCONNECTIONSETTINGS);
typedef HRESULT (WINAPI *LPSP_SETGROUPDATA)(LPSPDATA_SETGROUPDATA);
typedef HRESULT (WINAPI *LPSP_SETGROUPNAME)(LPSPDATA_SETGROUPNAME);
typedef HRESULT (WINAPI *LPSP_SETPLAYERDATA)(LPSPDATA_SETPLAYERDATA);
typedef HRESULT (WINAPI *LPSP_SETPLAYERNAME)(LPSPDATA_SETPLAYERNAME);
typedef HRESULT (WINAPI *LPSP_SHUTDOWN)(LPSPDATA_SHUTDOWN);
typedef HRESULT (WINAPI *LPSP_STARTSESSION)(LPSPDATA_STARTSESSION);
/* Callback table for dplay to call into service provider */
typedef struct SP_CALLBACKS
{
DWORD dwSize;
DWORD dwFlags;
LPSP_ADDGROUPTOGROUP AddGroupToGroup;
LPSP_ADDPLAYERTOGROUP AddPlayerToGroup;
LPSP_BUILDPARENTALHEIRARCHY BuildParentalHeirarchy;
LPSP_CLOSE Close;
LPSP_CREATEGROUP CreateGroup;
LPSP_CREATEGROUPINGROUP CreateGroupInGroup;
LPSP_CREATEPLAYER CreatePlayer;
LPSP_DELETEGROUPFROMGROUP DeleteGroupFromGroup;
LPSP_DELETEPLAYERFROMGROUP DeletePlayerFromGroup;
LPSP_DESTROYGROUP DestroyGroup;
LPSP_DESTROYPLAYER DestroyPlayer;
LPSP_ENUMSESSIONS EnumSessions;
LPSP_GETCAPS GetCaps;
LPSP_GETGROUPCONNECTIONSETTINGS GetGroupConnectionSettings;
LPSP_GETGROUPDATA GetGroupData;
LPSP_GETPLAYERCAPS GetPlayerCaps;
LPSP_GETPLAYERDATA GetPlayerData;
LPSP_OPEN Open;
LPSP_SEND Send;
LPSP_SENDCHATMESSAGE SendChatMessage;
LPSP_SETGROUPCONNECTIONSETTINGS SetGroupConnectionSettings;
LPSP_SETGROUPDATA SetGroupData;
LPSP_SETGROUPNAME SetGroupName;
LPSP_SETPLAYERDATA SetPlayerData;
LPSP_SETPLAYERNAME SetPlayerName;
LPSP_SHUTDOWN Shutdown;
LPSP_STARTSESSION StartSession;
} SP_CALLBACKS, *LPSP_CALLBACKS;
typedef struct SPDATA_INIT
{
LPSP_CALLBACKS lpCB;
DWORD dwSPVersion;
LPDPLOBBYSP lpISP;
LPDPADDRESS lpAddress;
} SPDATA_INIT, *LPSPDATA_INIT;
typedef HRESULT (WINAPI *LPSP_INIT)(LPSPDATA_INIT);
HRESULT WINAPI DPLSPInit(LPSPDATA_INIT);
/* Define the COM interface */
#define ICOM_INTERFACE IDPLobbySP
#define IDPLobbySP_METHODS \
ICOM_METHOD1(HRESULT, AddGroupToGroup, LPSPDATA_ADDREMOTEGROUPTOGROUP, argtg ) \
ICOM_METHOD1(HRESULT, AddPlayerToGroup, LPSPDATA_ADDREMOTEPLAYERTOGROUP, arptg ) \
ICOM_METHOD1(HRESULT, CreateGroup, LPSPDATA_CREATEREMOTEGROUP, crg ) \
ICOM_METHOD1(HRESULT, CreateGroupInGroup, LPSPDATA_CREATEREMOTEGROUPINGROUP, crgig ) \
ICOM_METHOD1(HRESULT, DeleteGroupFromGroup, LPSPDATA_DELETEREMOTEGROUPFROMGROUP, drgfg ) \
ICOM_METHOD1(HRESULT, DeletePlayerFromGroup, LPSPDATA_DELETEREMOTEPLAYERFROMGROUP, drpfg ) \
ICOM_METHOD1(HRESULT, DestroyGroup, LPSPDATA_DESTROYREMOTEGROUP, drg ) \
ICOM_METHOD1(HRESULT, EnumSessionsResponse, LPSPDATA_ENUMSESSIONSRESPONSE, er ) \
ICOM_METHOD1(HRESULT, GetSPDataPointer, LPVOID*, lplpData ) \
ICOM_METHOD1(HRESULT, HandleMessage, LPSPDATA_HANDLEMESSAGE, hm ) \
ICOM_METHOD1(HRESULT, SendChatMessage, LPSPDATA_CHATMESSAGE, cm ) \
ICOM_METHOD1(HRESULT, SetGroupName, LPSPDATA_SETREMOTEGROUPNAME, srgn ) \
ICOM_METHOD1(HRESULT, SetPlayerName, LPSPDATA_SETREMOTEPLAYERNAME, srpn ) \
ICOM_METHOD1(HRESULT, SetSessionDesc, LPSPDATA_SETSESSIONDESC, ssd ) \
ICOM_METHOD1(HRESULT, SetSPDataPointer, LPVOID, lpData ) \
ICOM_METHOD1(HRESULT, StartSession, LPSPDATA_STARTSESSIONCOMMAND, ssc )
#define IDPLobbySP_IMETHODS \
IUnknown_IMETHODS \
IDPLobbySP_METHODS
ICOM_DEFINE(IDPLobbySP,IUnknown)
#undef ICOM_INTERFACE
/*** IUnknown methods ***/
#define IDPLobbySP_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
#define IDPLobbySP_AddRef(p) ICOM_CALL (AddRef,p)
#define IDPLobbySP_Release(p) ICOM_CALL (Release,p)
/*** IDPLobbySP methods ***/
#define IDPLobbySP_AddGroupToGroup(p,a) ICOM_CALL1(AddGroupToGroup,p,a)
#define IDPLobbySP_AddPlayerToGroup(p,a) ICOM_CALL1(AddPlayerToGroup,p,a)
#define IDPLobbySP_CreateGroup(p,a) ICOM_CALL1(CreateGroup,p,a)
#define IDPLobbySP_CreateGroupInGroup(p,a) ICOM_CALL1(CreateGroupInGroup,p,a)
#define IDPLobbySP_DeleteGroupFromGroup(p,a) ICOM_CALL1(DeleteGroupFromGroup,p,a)
#define IDPLobbySP_DeletePlayerFromGroup(p,a) ICOM_CALL1(DeletePlayerFromGroup,p,a)
#define IDPLobbySP_DestroyGroup(p,a) ICOM_CALL1(DestroyGroup,p,a)
#define IDPLobbySP_EnumSessionsResponse(p,a) ICOM_CALL1(EnumSessionsResponse,p,a)
#define IDPLobbySP_GetSPDataPointer(p,a) ICOM_CALL1(GetSPDataPointer,p,a)
#define IDPLobbySP_HandleMessage(p,a) ICOM_CALL1(HandleMessage,p,a)
#define IDPLobbySP_SetGroupName(p,a) ICOM_CALL1(SetGroupName,p,a)
#define IDPLobbySP_SetPlayerName(p,a) ICOM_CALL1(SetPlayerName,p,a)
#define IDPLobbySP_SetSessionDesc(p,a) ICOM_CALL1(SetSessionDesc,p,a)
#define IDPLobbySP_StartSession(p,a) ICOM_CALL1(StartSession,p,a)
#define IDPLobbySP_SetSPDataPointer(p,a) ICOM_CALL1(SetSPDataPointer,p,a)
/* This variable is exported from the DLL at ordinal 6 to be accessed by the
* SP directly. This is the same variable that the DP SP will use.
*/
extern DWORD gdwDPlaySPRefCount;
#endif
/* DPLAYX.DLL name server implementation
*
* Copyright 2000 - Peter Hunnisett
* Copyright 2000-2001 - Peter Hunnisett
*
* <presently under construction - contact hunnise@nortelnetworks.com>
*
......@@ -43,6 +43,10 @@ struct NSCache
lpNSCacheData present; /* keep track of what is to be looked at when walking */
DPQ_HEAD(NSCacheData) first;
BOOL bNsIsLocal;
LPVOID lpLocalAddrHdr; /* FIXME: Not yet used */
LPVOID lpRemoteAddrHdr; /* FIXME: Not yet used */
};
typedef struct NSCache NSCache, *lpNSCache;
......@@ -52,12 +56,22 @@ DPQ_DECL_DELETECB( cbDeleteNSNodeFromHeap, lpNSCacheData );
/* Name Server functions
* ---------------------
*/
void NS_SetLocalComputerAsNameServer( LPCDPSESSIONDESC2 lpsd )
void NS_SetLocalComputerAsNameServer( LPCDPSESSIONDESC2 lpsd, LPVOID lpNSInfo )
{
#if 0
/* FIXME: Remove this method? */
DPLAYX_SetLocalSession( lpsd );
#endif
lpNSCache lpCache = (lpNSCache)lpNSInfo;
lpCache->bNsIsLocal = TRUE;
}
void NS_SetRemoteComputerAsNameServer( LPCDPSESSIONDESC2 lpsd, LPVOID lpNSInfo )
{
lpNSCache lpCache = (lpNSCache)lpNSInfo;
lpCache->bNsIsLocal = FALSE;
}
DPQ_DECL_COMPARECB( cbUglyPig, GUID )
......@@ -66,7 +80,8 @@ DPQ_DECL_COMPARECB( cbUglyPig, GUID )
}
/* Store the given NS remote address for future reference */
void NS_SetRemoteComputerAsNameServer( LPVOID lpNSAddrHdr,
/* FIXME: LPDPMSG_ENUMSESSIONSREPLY should be const */
void NS_AddRemoteComputerAsNameServer( LPCVOID lpcNSAddrHdr,
DWORD dwHdrSize,
LPDPMSG_ENUMSESSIONSREPLY lpMsg,
LPVOID lpNSInfo )
......@@ -75,11 +90,7 @@ void NS_SetRemoteComputerAsNameServer( LPVOID lpNSAddrHdr,
lpNSCache lpCache = (lpNSCache)lpNSInfo;
lpNSCacheData lpCacheNode;
TRACE( "%p, %p, %p\n", lpNSAddrHdr, lpMsg, lpNSInfo );
/* FIXME: Should check to see if the reply is for an existing session. If
* so we remove the old and add the new so oldest is at front.
*/
TRACE( "%p, %p, %p\n", lpcNSAddrHdr, lpMsg, lpNSInfo );
/* See if we can find this session. If we can, remove it as it's a dup */
DPQ_REMOVE_ENTRY_CB( lpCache->first, next, data->guidInstance, cbUglyPig,
......@@ -104,12 +115,12 @@ void NS_SetRemoteComputerAsNameServer( LPVOID lpNSAddrHdr,
lpCacheNode->lpNSAddrHdr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
dwHdrSize );
CopyMemory( lpCacheNode->lpNSAddrHdr, lpNSAddrHdr, dwHdrSize );
CopyMemory( lpCacheNode->lpNSAddrHdr, lpcNSAddrHdr, dwHdrSize );
lpCacheNode->data = (LPDPSESSIONDESC2)HeapAlloc( GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof( *lpCacheNode->data ) );
sizeof( *(lpCacheNode->data) ) );
if( lpCacheNode->data == NULL )
{
......@@ -120,8 +131,10 @@ void NS_SetRemoteComputerAsNameServer( LPVOID lpNSAddrHdr,
CopyMemory( lpCacheNode->data, &lpMsg->sd, sizeof( *lpCacheNode->data ) );
len = WideCharToMultiByte( CP_ACP, 0, (LPWSTR)(lpMsg+1), -1, NULL, 0, NULL, NULL );
if ((lpCacheNode->data->u1.lpszSessionNameA = HeapAlloc( GetProcessHeap(), 0, len )))
{
WideCharToMultiByte( CP_ACP, 0, (LPWSTR)(lpMsg+1), -1,
lpCacheNode->data->u1.lpszSessionNameA, len, NULL, NULL );
}
lpCacheNode->dwTime = timeGetTime();
......@@ -148,8 +161,38 @@ LPVOID NS_GetNSAddr( LPVOID lpNSInfo )
* must be it. That would make this method obsolete once that's
* in place.
*/
#if 1
return lpCache->first.lpQHFirst->lpNSAddrHdr;
#else
/* FIXME: Should convert over to this */
return lpCache->bNsIsLocal ? lpCache->lpLocalAddrHdr
: lpCache->lpRemoteAddrHdr;
#endif
}
/* Get the magic number associated with the Name Server */
DWORD NS_GetNsMagic( LPVOID lpNSInfo )
{
LPDWORD lpHdrInfo = (LPDWORD)NS_GetNSAddr( lpNSInfo );
return lpHdrInfo[1];
}
/* Get the magic number associated with the non NS end */
DWORD NS_GetOtherMagic( LPVOID lpNSInfo )
{
lpNSCache lpCache = (lpNSCache)lpNSInfo;
return ((LPDWORD)lpCache->lpLocalAddrHdr)[1];
}
void NS_SetLocalAddr( LPVOID lpNSInfo, LPCVOID lpHdr, DWORD dwHdrSize )
{
lpNSCache lpCache = (lpNSCache)lpNSInfo;
lpCache->lpLocalAddrHdr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwHdrSize );
CopyMemory( lpCache->lpLocalAddrHdr, lpHdr, dwHdrSize );
}
/* This function is responsible for sending a request for all other known
......@@ -216,6 +259,9 @@ void NS_InvalidateSessionCache( LPVOID lpNSInfo )
/* NULL out the walking pointer */
lpCache->present = NULL;
lpCache->bNsIsLocal = FALSE;
}
/* Create and initialize a session cache */
......@@ -235,6 +281,8 @@ BOOL NS_InitializeSessionCache( LPVOID* lplpNSInfo )
DPQ_INIT(lpCache->first);
lpCache->present = NULL;
lpCache->bNsIsLocal = FALSE;
return TRUE;
}
......@@ -280,8 +328,7 @@ void NS_PruneSessionCache( LPVOID lpNSInfo )
lpNSCache lpCache = lpNSInfo;
const DWORD dwPresentTime = timeGetTime();
const DWORD dwPrunePeriod = 60000; /* is 60 secs enough? */
const DWORD dwPruneTime = dwPresentTime - dwPrunePeriod;
const DWORD dwPrunePeriod = DPMSG_WAIT_60_SECS; /* is 60 secs enough? */
/* This silly little algorithm is based on the fact we keep entries in
* the queue in a time based order. It also assumes that it is not possible
......@@ -299,26 +346,13 @@ void NS_PruneSessionCache( LPVOID lpNSInfo )
break;
}
if( dwPruneTime > dwPresentTime ) /* 0 <= dwPresentTime <= dwPrunePeriod */
{
if( ( DPQ_FIRST(lpCache->first)->dwTime <= dwPresentTime ) ||
( DPQ_FIRST(lpCache->first)->dwTime > dwPruneTime )
)
/* Deal with time in a wrap around safe manner - unsigned arithmatic.
* Check the difference in time */
if( (dwPresentTime - (DPQ_FIRST(lpCache->first)->dwTime)) < dwPrunePeriod )
{
/* Less than dwPrunePeriod old - keep */
/* First entry has not expired yet; don't prune */
break;
}
}
else /* dwPrunePeriod <= dwPresentTime <= max dword */
{
if( ( DPQ_FIRST(lpCache->first)->dwTime <= dwPresentTime ) &&
( DPQ_FIRST(lpCache->first)->dwTime > dwPruneTime )
)
{
/* Less than dwPrunePeriod old - keep */
break;
}
}
lpFirstData = DPQ_FIRST(lpCache->first);
DPQ_REMOVE( lpCache->first, DPQ_FIRST(lpCache->first), next );
......@@ -328,33 +362,38 @@ void NS_PruneSessionCache( LPVOID lpNSInfo )
}
/* NAME SERVER Message stuff */
void NS_ReplyToEnumSessionsRequest( LPVOID lpMsg,
LPDPSP_REPLYDATA lpReplyData,
void NS_ReplyToEnumSessionsRequest( LPCVOID lpcMsg,
LPVOID* lplpReplyData,
LPDWORD lpdwReplySize,
IDirectPlay2Impl* lpDP )
{
LPDPMSG_ENUMSESSIONSREPLY rmsg;
DWORD dwVariableSize;
DWORD dwVariableLen;
/* LPDPMSG_ENUMSESSIONSREQUEST msg = (LPDPMSG_ENUMSESSIONSREQUEST)lpMsg; */
/* LPCDPMSG_ENUMSESSIONSREQUEST msg = (LPDPMSG_ENUMSESSIONSREQUEST)lpcMsg; */
BOOL bAnsi = TRUE; /* FIXME: This needs to be in the DPLAY interface */
FIXME( ": few fixed + need to check request for response\n" );
if (bAnsi)
{
dwVariableLen = MultiByteToWideChar( CP_ACP, 0,
lpDP->dp2->lpSessionDesc->u1.lpszSessionNameA,
-1, NULL, 0 );
}
else
{
dwVariableLen = strlenW( lpDP->dp2->lpSessionDesc->u1.lpszSessionName ) + 1;
}
dwVariableSize = dwVariableLen * sizeof( WCHAR );
lpReplyData->dwMessageSize = lpDP->dp2->spData.dwSPHeaderSize +
*lpdwReplySize = lpDP->dp2->spData.dwSPHeaderSize +
sizeof( *rmsg ) + dwVariableSize;
lpReplyData->lpMessage = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
lpReplyData->dwMessageSize );
*lplpReplyData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
*lpdwReplySize );
rmsg = (LPDPMSG_ENUMSESSIONSREPLY)( (BYTE*)lpReplyData->lpMessage +
rmsg = (LPDPMSG_ENUMSESSIONSREPLY)( (BYTE*)*lplpReplyData +
lpDP->dp2->spData.dwSPHeaderSize);
rmsg->envelope.dwMagic = DPMSGMAGIC_DPLAYMSG;
......@@ -365,8 +404,12 @@ void NS_ReplyToEnumSessionsRequest( LPVOID lpMsg,
sizeof( lpDP->dp2->lpSessionDesc->dwSize ) );
rmsg->dwUnknown = 0x0000005c;
if( bAnsi )
{
MultiByteToWideChar( CP_ACP, 0, lpDP->dp2->lpSessionDesc->u1.lpszSessionNameA, -1,
(LPWSTR)(rmsg+1), dwVariableLen );
}
else
{
strcpyW( (LPWSTR)(rmsg+1), lpDP->dp2->lpSessionDesc->u1.lpszSessionName );
}
}
......@@ -7,15 +7,20 @@
#include "dplayx_messages.h"
#include "dplay_global.h"
void NS_SetLocalComputerAsNameServer( LPCDPSESSIONDESC2 lpsd );
void NS_SetRemoteComputerAsNameServer( LPVOID lpNSAddrHdr,
void NS_SetLocalComputerAsNameServer( LPCDPSESSIONDESC2 lpsd, LPVOID lpNSInfo );
void NS_SetRemoteComputerAsNameServer( LPCDPSESSIONDESC2 lpsd, LPVOID lpNSInfo );
void NS_AddRemoteComputerAsNameServer( LPCVOID lpNSAddrHdr,
DWORD dwHdrSize,
LPDPMSG_ENUMSESSIONSREPLY lpMsg,
LPVOID lpNSInfo );
LPVOID NS_GetNSAddr( LPVOID lpNSInfo );
DWORD NS_GetNsMagic( LPVOID lpNSInfo );
DWORD NS_GetOtherMagic( LPVOID lpNSInfo );
void NS_SetLocalAddr( LPVOID lpNSInfo, LPCVOID lpHdr, DWORD dwHdrSize );
void NS_ReplyToEnumSessionsRequest( LPVOID lpMsg,
LPDPSP_REPLYDATA lpReplyData,
void NS_ReplyToEnumSessionsRequest( LPCVOID lpcMsg,
LPVOID* lplpReplyData,
LPDWORD lpdwReplySize,
IDirectPlay2Impl* lpDP );
HRESULT NS_SendSessionRequestBroadcast( LPCGUID lpcGuid,
......
#ifndef __WINE_DPLAY_H
#define __WINE_DPLAY_H
#include "ole2.h"
#include "wine/obj_base.h"
#ifdef __cplusplus
......
......@@ -26,7 +26,9 @@
#include <stdlib.h>
#endif
#ifndef INITGUID
#include "cguid.h"
#endif
#ifdef __cplusplus
extern "C" {
......
......@@ -1464,6 +1464,8 @@ extern int WIN32_LastError;
#define S_OK ((HRESULT)0L)
#define S_FALSE ((HRESULT)1L)
#define E_PENDING 0x8000000AL
#define E_NOTIMPL 0x80004001L
#define E_NOINTERFACE 0x80004002L
......
......@@ -49,3 +49,4 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
/* GUIDs not declared in an exported header file */
DEFINE_GUID(IID_IDirectPlaySP,0xc9f6360,0xcc61,0x11cf,0xac,0xec,0x00,0xaa,0x00,0x68,0x86,0xe3);
DEFINE_GUID(IID_ISFHelper,0x1fe68efb,0x1874,0x9812,0x56,0xdc,0x00,0x00,0x00,0x00,0x00,0x00);
DEFINE_GUID(IID_IDPLobbySP,0x5a4e5a20,0x2ced,0x11d0,0xa8,0x89,0x00,0xa0,0xc9,0x05,0x43,0x3c);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment