- 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
This commit is contained in:
parent
3f03975f48
commit
3d7cd87698
|
@ -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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* 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,11 +711,36 @@ 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;
|
||||
}
|
||||
|
||||
case DPMSGCMD_FORWARDADDPLAYERNACK:
|
||||
{
|
||||
DP_MSG_ErrorReceived( This, wCommandId, lpcMessageBody, dwMessageBodySize );
|
||||
|
@ -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...
|
||||
despite this method taking slightly more heap space and realtime :) */
|
||||
dpCompoundAddress.dwDataSize = sizeof( GUID );
|
||||
memcpy( &dpCompoundAddress.guidDataType, &DPAID_ServiceProvider,
|
||||
sizeof( GUID ) ) ;
|
||||
dpCompoundAddress.lpData = &serviceProviderGUID;
|
||||
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 :) */
|
||||
|
||||
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 */
|
||||
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 );
|
||||
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;
|
||||
}
|
||||
|
||||
lpSpData->dwReserved1 = GET_DWORD( returnBuffer );
|
||||
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;
|
||||
}
|
||||
|
||||
lpSpData->dwReserved2 = GET_DWORD( returnBuffer );
|
||||
|
||||
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;
|
||||
|
||||
hr = DP_InitializeDPLSP( This, hServiceProvider );
|
||||
}
|
||||
|
||||
if( SPInit == NULL )
|
||||
{
|
||||
ERR( "Service provider doesn't provide %s interface?\n",
|
||||
bIsDpSp ? "SPInit" : "DPLSPInit" );
|
||||
FreeLibrary( hServiceProvider );
|
||||
return DPERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
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,81 +452,49 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
|||
if( lpMsg->dwMagic != DPMSGMAGIC_DPLAYMSG )
|
||||
{
|
||||
ERR( "Unknown magic 0x%08lx!\n", lpMsg->dwMagic );
|
||||
return DPERR_GENERIC;
|
||||
}
|
||||
|
||||
switch( lpMsg->wCommandId )
|
||||
#if 0
|
||||
{
|
||||
/* Name server needs to handle this request */
|
||||
/* FIXME: This should be done in direct play handler */
|
||||
case DPMSGCMD_ENUMSESSIONSREQUEST:
|
||||
const LPDWORD lpcHeader = (LPDWORD)lpMessageHeader;
|
||||
|
||||
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 */
|
||||
data.lpMessage = NULL;
|
||||
data.dwMessageSize = 0;
|
||||
|
||||
/* Pass this message to the dplay interface to handle */
|
||||
hr = DP_HandleMessage( This->sp->dplay, lpMessageBody, dwMessageBodySize,
|
||||
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 )
|
||||
{
|
||||
data.lpSPMessageHeader = lpMessageHeader;
|
||||
data.idNameServer = 0;
|
||||
data.lpISP = iface;
|
||||
|
||||
hr = (This->sp->dplay->dp2->spData.lpCB->Reply)( &data );
|
||||
|
||||
if( FAILED(hr) )
|
||||
{
|
||||
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:
|
||||
{
|
||||
NS_SetRemoteComputerAsNameServer( lpMessageHeader,
|
||||
This->sp->dplay->dp2->spData.dwSPHeaderSize,
|
||||
(LPDPMSG_ENUMSESSIONSREPLY)lpMessageBody,
|
||||
This->sp->dplay->dp2->lpNameServerData );
|
||||
|
||||
/* No reply expected */
|
||||
hr = DP_OK;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Pass everything else to Direct Play */
|
||||
default:
|
||||
{
|
||||
DPSP_REPLYDATA data;
|
||||
|
||||
data.lpMessage = NULL;
|
||||
data.dwMessageSize = 0;
|
||||
|
||||
/* Pass this message to the dplay interface to handle */
|
||||
hr = DP_HandleMessage( This->sp->dplay, lpMessageBody, dwMessageBodySize,
|
||||
lpMessageHeader, wCommandId, wVersion,
|
||||
&data.lpMessage, &data.dwMessageSize );
|
||||
|
||||
/* Do we want a reply? */
|
||||
if( data.lpMessage != NULL )
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
data.lpSPMessageHeader = lpMessageHeader;
|
||||
data.idNameServer = 0;
|
||||
data.lpISP = iface;
|
||||
|
||||
hr = (This->sp->dplay->dp2->spData.lpCB->Reply)( &data );
|
||||
|
||||
if( FAILED(hr) )
|
||||
{
|
||||
ERR( "Reply failed %s\n", DPLAYX_HresultToString(hr) );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
ERR( "Reply failed %s\n", DPLAYX_HresultToString(hr) );
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
|
||||
#if 0
|
||||
HRESULT hr = DP_OK;
|
||||
HANDLE hReceiveEvent = 0;
|
||||
|
@ -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:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* 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;
|
||||
|
|
|
@ -0,0 +1,454 @@
|
|||
/* 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
|
||||
|
||||
};
|
|
@ -0,0 +1,494 @@
|
|||
#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
|
|
@ -1,6 +1,6 @@
|
|||
/* 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,15 +90,11 @@ 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,
|
||||
lpMsg->sd.guidInstance, lpCacheNode );
|
||||
lpMsg->sd.guidInstance, lpCacheNode );
|
||||
|
||||
if( lpCacheNode != NULL )
|
||||
{
|
||||
|
@ -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,25 +346,12 @@ void NS_PruneSessionCache( LPVOID lpNSInfo )
|
|||
break;
|
||||
}
|
||||
|
||||
if( dwPruneTime > dwPresentTime ) /* 0 <= dwPresentTime <= dwPrunePeriod */
|
||||
/* Deal with time in a wrap around safe manner - unsigned arithmatic.
|
||||
* Check the difference in time */
|
||||
if( (dwPresentTime - (DPQ_FIRST(lpCache->first)->dwTime)) < dwPrunePeriod )
|
||||
{
|
||||
if( ( DPQ_FIRST(lpCache->first)->dwTime <= dwPresentTime ) ||
|
||||
( DPQ_FIRST(lpCache->first)->dwTime > dwPruneTime )
|
||||
)
|
||||
{
|
||||
/* Less than dwPrunePeriod old - keep */
|
||||
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;
|
||||
}
|
||||
/* First entry has not expired yet; don't prune */
|
||||
break;
|
||||
}
|
||||
|
||||
lpFirstData = DPQ_FIRST(lpCache->first);
|
||||
|
@ -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 +
|
||||
sizeof( *rmsg ) + dwVariableSize;
|
||||
lpReplyData->lpMessage = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
lpReplyData->dwMessageSize );
|
||||
*lpdwReplySize = lpDP->dp2->spData.dwSPHeaderSize +
|
||||
sizeof( *rmsg ) + dwVariableSize;
|
||||
*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,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#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);
|
||||
|
|
Loading…
Reference in New Issue