927 lines
30 KiB
C++
927 lines
30 KiB
C++
/*==========================================================================
|
|
*
|
|
* Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: DPLConset.cpp
|
|
* Content: DirectPlay Lobby Connection Settings Utility Functions
|
|
*@@BEGIN_MSINTERNAL
|
|
* History:
|
|
* Date By Reason
|
|
* ==== == ======
|
|
* 06/13/00 rmt Created
|
|
* 07/07/00 rmt Bug #38755 - No way to specify player name in connection settings
|
|
* 07/08/2000 rmt Bug #38725 - Need to provide method to detect if app was lobby launched
|
|
* rmt Bug #38757 - Callback messages for connections may return AFTER WaitForConnection returns
|
|
* rmt Bug #38755 - No way to specify player name in Connection Settings
|
|
* rmt Bug #38758 - DPLOBBY8.H has incorrect comments
|
|
* rmt Bug #38783 - pvUserApplicationContext is only partially implemented
|
|
* rmt Added DPLHANDLE_ALLCONNECTIONS and dwFlags (reserved field to couple of funcs).
|
|
* 07/12/2000 rmt Removed improper assert
|
|
* 02/06/2001 rodtoll WINBUG #293871: DPLOBBY8: [IA64] Lobby launching a 64-bit
|
|
* app from 64-bit lobby launcher crashes with unaligned memory error.
|
|
*@@END_MSINTERNAL
|
|
*
|
|
***************************************************************************/
|
|
|
|
#include "dnlobbyi.h"
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CConnectionSettings::CConnectionSettings"
|
|
CConnectionSettings::CConnectionSettings(): m_dwSignature(DPLSIGNATURE_LOBBYCONSET), m_fManaged(FALSE), m_pdplConnectionSettings(NULL), m_fCritSecInited(FALSE)
|
|
{
|
|
}
|
|
|
|
CConnectionSettings::~CConnectionSettings()
|
|
{
|
|
if( !m_fManaged && m_pdplConnectionSettings )
|
|
{
|
|
FreeConnectionSettings( m_pdplConnectionSettings );
|
|
m_pdplConnectionSettings = NULL;
|
|
}
|
|
|
|
if (m_fCritSecInited)
|
|
{
|
|
DNDeleteCriticalSection( &m_csLock );
|
|
}
|
|
m_dwSignature = DPLSIGNATURE_LOBBYCONSET_FREE;
|
|
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CConnectionSettings::FreeConnectionSettings"
|
|
// CConnectionSettings::FreeConnectionSettings
|
|
//
|
|
// This function frees the memory associated with the specified connection
|
|
void CConnectionSettings::FreeConnectionSettings( DPL_CONNECTION_SETTINGS *pConnectionSettings )
|
|
{
|
|
if( pConnectionSettings )
|
|
{
|
|
if( pConnectionSettings->pwszPlayerName )
|
|
{
|
|
delete [] pConnectionSettings->pwszPlayerName;
|
|
pConnectionSettings->pwszPlayerName = NULL;
|
|
}
|
|
|
|
if( pConnectionSettings->dpnAppDesc.pwszSessionName )
|
|
{
|
|
delete [] pConnectionSettings->dpnAppDesc.pwszSessionName;
|
|
pConnectionSettings->dpnAppDesc.pwszSessionName = NULL;
|
|
}
|
|
|
|
if( pConnectionSettings->dpnAppDesc.pwszPassword )
|
|
{
|
|
delete [] pConnectionSettings->dpnAppDesc.pwszPassword;
|
|
pConnectionSettings->dpnAppDesc.pwszPassword = NULL;
|
|
}
|
|
|
|
if( pConnectionSettings->dpnAppDesc.pvReservedData )
|
|
{
|
|
delete [] pConnectionSettings->dpnAppDesc.pvReservedData;
|
|
pConnectionSettings->dpnAppDesc.pvReservedData = NULL;
|
|
}
|
|
|
|
if( pConnectionSettings->dpnAppDesc.pvApplicationReservedData )
|
|
{
|
|
delete [] pConnectionSettings->dpnAppDesc.pvApplicationReservedData;
|
|
pConnectionSettings->dpnAppDesc.pvApplicationReservedData = NULL;
|
|
}
|
|
|
|
if( pConnectionSettings->pdp8HostAddress )
|
|
{
|
|
pConnectionSettings->pdp8HostAddress->lpVtbl->Release( pConnectionSettings->pdp8HostAddress );
|
|
pConnectionSettings->pdp8HostAddress = NULL;
|
|
}
|
|
|
|
if( pConnectionSettings->ppdp8DeviceAddresses )
|
|
{
|
|
for( DWORD dwIndex = 0; dwIndex < pConnectionSettings->cNumDeviceAddresses; dwIndex++ )
|
|
{
|
|
pConnectionSettings->ppdp8DeviceAddresses[dwIndex]->lpVtbl->Release( pConnectionSettings->ppdp8DeviceAddresses[dwIndex] );
|
|
}
|
|
|
|
delete [] pConnectionSettings->ppdp8DeviceAddresses;
|
|
pConnectionSettings->ppdp8DeviceAddresses = NULL;
|
|
|
|
}
|
|
|
|
delete pConnectionSettings;
|
|
}
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CConnectionSettings::Initialize"
|
|
// Initialize (DPL_CONNECTION_SETTINGS version)
|
|
//
|
|
// This function tells this class to take the specified connection settings and
|
|
// work with it.
|
|
//
|
|
HRESULT CConnectionSettings::Initialize( DPL_CONNECTION_SETTINGS * pdplSettings )
|
|
{
|
|
if (!DNInitializeCriticalSection( &m_csLock ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed to create critical section");
|
|
return DPNERR_OUTOFMEMORY;
|
|
}
|
|
m_fCritSecInited = TRUE;
|
|
|
|
m_pdplConnectionSettings = pdplSettings;
|
|
m_fManaged = FALSE;
|
|
|
|
return DPN_OK;
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CConnectionSettings::Initialize"
|
|
// Initialize (Wire Version)
|
|
//
|
|
// THis function initializes this object to contain a connection settings structure
|
|
// that mirrors the values of the wire message.
|
|
HRESULT CConnectionSettings::Initialize( UNALIGNED DPL_INTERNAL_CONNECTION_SETTINGS *pdplSettingsMsg, UNALIGNED BYTE * pbBufferStart )
|
|
{
|
|
DNASSERT( pdplSettingsMsg );
|
|
|
|
HRESULT hr = DPN_OK;
|
|
DPL_CONNECTION_SETTINGS *pdplConnectionSettings = NULL;
|
|
UNALIGNED BYTE *pBasePointer = pbBufferStart;
|
|
PDIRECTPLAY8ADDRESS pdp8Address = NULL;
|
|
WCHAR *wszTmpAlignedBuffer = NULL;
|
|
DWORD dwTmpOffset = 0;
|
|
DWORD dwTmpLength = 0;
|
|
UNALIGNED DWORD *pdwOffsets = NULL;
|
|
UNALIGNED DWORD *pdwLengths = NULL;
|
|
|
|
if (!DNInitializeCriticalSection( &m_csLock ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed to create critical section");
|
|
return DPNERR_OUTOFMEMORY;
|
|
}
|
|
m_fCritSecInited = TRUE;
|
|
|
|
pdplConnectionSettings = new DPL_CONNECTION_SETTINGS;
|
|
|
|
if( !pdplConnectionSettings )
|
|
{
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
// Zero out the memory
|
|
ZeroMemory( pdplConnectionSettings, sizeof( DPL_CONNECTION_SETTINGS ) );
|
|
|
|
pdplConnectionSettings->dwSize = sizeof( DPL_CONNECTION_SETTINGS );
|
|
pdplConnectionSettings->dwFlags = pdplSettingsMsg->dwFlags;
|
|
|
|
//
|
|
// PLAYER NAME COPY
|
|
//
|
|
if( pdplSettingsMsg->dwPlayerNameLength )
|
|
{
|
|
pdplConnectionSettings->pwszPlayerName = new WCHAR[pdplSettingsMsg->dwPlayerNameLength >> 1];
|
|
|
|
if( !pdplConnectionSettings->pwszPlayerName )
|
|
{
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
memcpy( pdplConnectionSettings->pwszPlayerName, pBasePointer + pdplSettingsMsg->dwPlayerNameOffset,
|
|
pdplSettingsMsg->dwPlayerNameLength );
|
|
}
|
|
|
|
//
|
|
// HOST ADDRESS COPY
|
|
//
|
|
if( pdplSettingsMsg->dwHostAddressLength )
|
|
{
|
|
// We need to create a buffer for string that we know is aligned. - Ick -
|
|
wszTmpAlignedBuffer = new WCHAR[pdplSettingsMsg->dwHostAddressLength >> 1];
|
|
|
|
if( !wszTmpAlignedBuffer )
|
|
{
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
// Copy the potentially unaligned data to the aligned data string.
|
|
memcpy( wszTmpAlignedBuffer, pBasePointer + pdplSettingsMsg->dwHostAddressOffset,pdplSettingsMsg->dwHostAddressLength );
|
|
|
|
hr = COM_CoCreateInstance( CLSID_DirectPlay8Address, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlay8Address, (void **) &pdp8Address );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Error creating address hr=0x%x", hr );
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
// Convert the host address (if there is one)
|
|
hr = pdp8Address->lpVtbl->BuildFromURLW( pdp8Address, wszTmpAlignedBuffer );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Error building URL from address hr=0x%x", hr );
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
pdplConnectionSettings->pdp8HostAddress = pdp8Address;
|
|
|
|
pdp8Address = NULL;
|
|
|
|
if( wszTmpAlignedBuffer )
|
|
{
|
|
delete [] wszTmpAlignedBuffer;
|
|
wszTmpAlignedBuffer = NULL;
|
|
}
|
|
}
|
|
|
|
if( pdplSettingsMsg->dwNumDeviceAddresses )
|
|
{
|
|
pdplConnectionSettings->cNumDeviceAddresses = pdplSettingsMsg->dwNumDeviceAddresses;
|
|
//
|
|
// DEVICE ADDRESS COPY
|
|
//
|
|
|
|
pdplConnectionSettings->ppdp8DeviceAddresses = new PDIRECTPLAY8ADDRESS[pdplSettingsMsg->dwNumDeviceAddresses];
|
|
|
|
if( !pdplConnectionSettings->ppdp8DeviceAddresses )
|
|
{
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
// Give us an unaligned dword pointer to the device addresses offset
|
|
pdwOffsets = (UNALIGNED DWORD *) (pBasePointer + pdplSettingsMsg->dwDeviceAddressOffset);
|
|
pdwLengths = (UNALIGNED DWORD *) (pBasePointer + pdplSettingsMsg->dwDeviceAddressLengthOffset);
|
|
|
|
for( DWORD dwIndex = 0; dwIndex < pdplSettingsMsg->dwNumDeviceAddresses; dwIndex++ )
|
|
{
|
|
dwTmpOffset = pdwOffsets[dwIndex];
|
|
dwTmpLength = pdwLengths[dwIndex];
|
|
|
|
// We need to create a buffer for string that we know is aligned. - Ick -
|
|
wszTmpAlignedBuffer = new WCHAR[dwTmpLength >> 1];
|
|
|
|
if( !wszTmpAlignedBuffer )
|
|
{
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
memcpy( wszTmpAlignedBuffer, pBasePointer + dwTmpOffset, dwTmpLength );
|
|
|
|
hr = COM_CoCreateInstance( CLSID_DirectPlay8Address, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlay8Address, (void **) &pdp8Address );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Error creating address hr=0x%x", hr );
|
|
return hr;
|
|
}
|
|
|
|
// Convert the host address (if there is one)
|
|
hr = pdp8Address->lpVtbl->BuildFromURLW( pdp8Address, wszTmpAlignedBuffer );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Error building URL from address hr=0x%x", hr );
|
|
DNASSERT( FALSE );
|
|
return hr;
|
|
}
|
|
|
|
pdplConnectionSettings->ppdp8DeviceAddresses[dwIndex] = pdp8Address;
|
|
|
|
pdp8Address = NULL;
|
|
|
|
if( wszTmpAlignedBuffer )
|
|
{
|
|
delete [] wszTmpAlignedBuffer;
|
|
wszTmpAlignedBuffer = NULL;
|
|
}
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pdplConnectionSettings->ppdp8DeviceAddresses = NULL;
|
|
}
|
|
|
|
//
|
|
// APPLICATION DESCRIPTION COPY
|
|
//
|
|
|
|
pdplConnectionSettings->dpnAppDesc.dwSize = sizeof( DPN_APPLICATION_DESC );
|
|
pdplConnectionSettings->dpnAppDesc.dwFlags = pdplSettingsMsg->dpnApplicationDesc.dwFlags;
|
|
pdplConnectionSettings->dpnAppDesc.guidInstance = pdplSettingsMsg->dpnApplicationDesc.guidInstance;
|
|
pdplConnectionSettings->dpnAppDesc.guidApplication = pdplSettingsMsg->dpnApplicationDesc.guidApplication;
|
|
pdplConnectionSettings->dpnAppDesc.dwMaxPlayers = pdplSettingsMsg->dpnApplicationDesc.dwMaxPlayers;
|
|
pdplConnectionSettings->dpnAppDesc.dwCurrentPlayers = pdplSettingsMsg->dpnApplicationDesc.dwCurrentPlayers;
|
|
|
|
if( pdplSettingsMsg->dpnApplicationDesc.dwSessionNameSize )
|
|
{
|
|
pdplConnectionSettings->dpnAppDesc.pwszSessionName = new WCHAR[pdplSettingsMsg->dpnApplicationDesc.dwSessionNameSize >> 1];
|
|
|
|
if( !pdplConnectionSettings->dpnAppDesc.pwszSessionName )
|
|
{
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
memcpy( pdplConnectionSettings->dpnAppDesc.pwszSessionName,
|
|
pBasePointer + pdplSettingsMsg->dpnApplicationDesc.dwSessionNameOffset,
|
|
pdplSettingsMsg->dpnApplicationDesc.dwSessionNameSize );
|
|
}
|
|
|
|
if( pdplSettingsMsg->dpnApplicationDesc.dwPasswordSize )
|
|
{
|
|
pdplConnectionSettings->dpnAppDesc.pwszPassword = new WCHAR[pdplSettingsMsg->dpnApplicationDesc.dwPasswordSize >> 1];
|
|
|
|
if( !pdplConnectionSettings->dpnAppDesc.pwszPassword )
|
|
{
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
memcpy( pdplConnectionSettings->dpnAppDesc.pwszPassword,
|
|
pBasePointer + pdplSettingsMsg->dpnApplicationDesc.dwPasswordOffset,
|
|
pdplSettingsMsg->dpnApplicationDesc.dwPasswordSize );
|
|
}
|
|
|
|
if( pdplSettingsMsg->dpnApplicationDesc.dwReservedDataSize )
|
|
{
|
|
pdplConnectionSettings->dpnAppDesc.pvReservedData = new BYTE[pdplSettingsMsg->dpnApplicationDesc.dwReservedDataSize];
|
|
|
|
if( !pdplConnectionSettings->dpnAppDesc.pvReservedData )
|
|
{
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
memcpy( pdplConnectionSettings->dpnAppDesc.pvReservedData,
|
|
pBasePointer + pdplSettingsMsg->dpnApplicationDesc.dwReservedDataOffset,
|
|
pdplSettingsMsg->dpnApplicationDesc.dwReservedDataSize );
|
|
|
|
pdplConnectionSettings->dpnAppDesc.dwReservedDataSize = pdplSettingsMsg->dpnApplicationDesc.dwReservedDataSize;
|
|
}
|
|
|
|
if( pdplSettingsMsg->dpnApplicationDesc.dwApplicationReservedDataSize )
|
|
{
|
|
pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData = new BYTE[pdplSettingsMsg->dpnApplicationDesc.dwApplicationReservedDataSize];
|
|
|
|
if( !pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData )
|
|
{
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
memcpy( pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData,
|
|
pBasePointer + pdplSettingsMsg->dpnApplicationDesc.dwApplicationReservedDataOffset,
|
|
pdplSettingsMsg->dpnApplicationDesc.dwApplicationReservedDataSize );
|
|
|
|
pdplConnectionSettings->dpnAppDesc.dwApplicationReservedDataSize = pdplSettingsMsg->dpnApplicationDesc.dwApplicationReservedDataSize;
|
|
}
|
|
|
|
|
|
// Free the old structure if one exists.
|
|
if( m_fManaged )
|
|
{
|
|
m_fManaged = FALSE;
|
|
}
|
|
else if( m_pdplConnectionSettings )
|
|
{
|
|
FreeConnectionSettings( m_pdplConnectionSettings );
|
|
}
|
|
|
|
m_pdplConnectionSettings = pdplConnectionSettings;
|
|
|
|
if( wszTmpAlignedBuffer )
|
|
delete [] wszTmpAlignedBuffer;
|
|
|
|
return DPN_OK;
|
|
|
|
INITIALIZE_FAILED:
|
|
|
|
FreeConnectionSettings( pdplConnectionSettings );
|
|
|
|
if( wszTmpAlignedBuffer )
|
|
delete [] wszTmpAlignedBuffer;
|
|
|
|
if( pdp8Address )
|
|
pdp8Address->lpVtbl->Release( pdp8Address );
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CConnectionSettings::InitializeAndCopy"
|
|
// InitializeAndCopy
|
|
//
|
|
// This function initializes this class to contain a copy of the specified
|
|
// connection settings structure.
|
|
//
|
|
HRESULT CConnectionSettings::InitializeAndCopy( const DPL_CONNECTION_SETTINGS * const pdplSettings )
|
|
{
|
|
DNASSERT( pdplSettings );
|
|
|
|
HRESULT hr = DPN_OK;
|
|
DPL_CONNECTION_SETTINGS *pdplConnectionSettings = NULL;
|
|
|
|
if (!DNInitializeCriticalSection( &m_csLock ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed to create critical section");
|
|
return DPNERR_OUTOFMEMORY;
|
|
}
|
|
m_fCritSecInited = TRUE;
|
|
|
|
pdplConnectionSettings = new DPL_CONNECTION_SETTINGS;
|
|
|
|
if( !pdplConnectionSettings )
|
|
{
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
// Copy over. This is a little dangerous as we copy pointer values. Pointers
|
|
// should be set in our local structure to NULL so that proper cleanup can occur
|
|
// on error. (Otherwise we'll free other structure's memory!!)
|
|
memcpy( pdplConnectionSettings, pdplSettings, sizeof( DPL_CONNECTION_SETTINGS ) );
|
|
|
|
// Reset pointers as mentioned above.
|
|
pdplConnectionSettings->pdp8HostAddress = NULL;
|
|
pdplConnectionSettings->ppdp8DeviceAddresses = NULL;
|
|
pdplConnectionSettings->pwszPlayerName = NULL;
|
|
pdplConnectionSettings->dpnAppDesc.pwszSessionName = NULL;
|
|
pdplConnectionSettings->dpnAppDesc.pwszPassword = NULL;
|
|
pdplConnectionSettings->dpnAppDesc.pvReservedData = NULL;
|
|
pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData = NULL;
|
|
|
|
if( pdplSettings->pdp8HostAddress )
|
|
{
|
|
hr = pdplSettings->pdp8HostAddress->lpVtbl->Duplicate( pdplSettings->pdp8HostAddress, &pdplConnectionSettings->pdp8HostAddress );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Error duplicating host address hr [0x%x]", hr );
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
}
|
|
|
|
if( pdplSettings->ppdp8DeviceAddresses )
|
|
{
|
|
pdplConnectionSettings->ppdp8DeviceAddresses = new PDIRECTPLAY8ADDRESS[pdplSettings->cNumDeviceAddresses];
|
|
|
|
if( !pdplConnectionSettings->ppdp8DeviceAddresses )
|
|
{
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
DPFX(DPFPREP, 0, "Failed allocating memory" );
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
for( DWORD dwIndex = 0; dwIndex < pdplSettings->cNumDeviceAddresses; dwIndex++ )
|
|
{
|
|
hr = pdplSettings->ppdp8DeviceAddresses[dwIndex]->lpVtbl->Duplicate( pdplSettings->ppdp8DeviceAddresses[dwIndex], &pdplConnectionSettings->ppdp8DeviceAddresses[dwIndex] );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Error duplicating host address hr [0x%x]", hr );
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( pdplSettings->pwszPlayerName )
|
|
{
|
|
pdplConnectionSettings->pwszPlayerName = new WCHAR[wcslen(pdplSettings->pwszPlayerName)+1];
|
|
|
|
if( !pdplConnectionSettings->pwszPlayerName )
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed allocating memory" );
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
wcscpy( pdplConnectionSettings->pwszPlayerName, pdplSettings->pwszPlayerName );
|
|
}
|
|
|
|
if( pdplSettings->dpnAppDesc.pwszSessionName )
|
|
{
|
|
pdplConnectionSettings->dpnAppDesc.pwszSessionName = new WCHAR[wcslen(pdplSettings->dpnAppDesc.pwszSessionName)+1];
|
|
|
|
if( !pdplConnectionSettings->dpnAppDesc.pwszSessionName )
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed allocating memory" );
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
wcscpy( pdplConnectionSettings->dpnAppDesc.pwszSessionName, pdplSettings->dpnAppDesc.pwszSessionName );
|
|
}
|
|
|
|
if( pdplSettings->dpnAppDesc.pwszPassword )
|
|
{
|
|
pdplConnectionSettings->dpnAppDesc.pwszPassword = new WCHAR[wcslen(pdplSettings->dpnAppDesc.pwszPassword)+1];
|
|
|
|
if( !pdplConnectionSettings->dpnAppDesc.pwszPassword )
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed allocating memory" );
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
wcscpy( pdplConnectionSettings->dpnAppDesc.pwszPassword, pdplSettings->dpnAppDesc.pwszPassword );
|
|
}
|
|
|
|
if( pdplSettings->dpnAppDesc.pvReservedData )
|
|
{
|
|
pdplConnectionSettings->dpnAppDesc.pvReservedData = new BYTE[pdplSettings->dpnAppDesc.dwReservedDataSize];
|
|
|
|
if( !pdplConnectionSettings->dpnAppDesc.pvReservedData )
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed allocating memory" );
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
memcpy( pdplConnectionSettings->dpnAppDesc.pvReservedData,
|
|
pdplSettings->dpnAppDesc.pvReservedData,
|
|
pdplSettings->dpnAppDesc.dwReservedDataSize );
|
|
}
|
|
|
|
if( pdplSettings->dpnAppDesc.pvApplicationReservedData )
|
|
{
|
|
pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData = new BYTE[pdplSettings->dpnAppDesc.dwApplicationReservedDataSize];
|
|
|
|
if( !pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData )
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed allocating memory" );
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto INITIALIZE_FAILED;
|
|
}
|
|
|
|
memcpy( pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData,
|
|
pdplSettings->dpnAppDesc.pvApplicationReservedData,
|
|
pdplSettings->dpnAppDesc.dwApplicationReservedDataSize );
|
|
}
|
|
|
|
// Free the old structure if one exists.
|
|
if( m_fManaged )
|
|
{
|
|
m_fManaged = FALSE;
|
|
}
|
|
else if( m_pdplConnectionSettings )
|
|
{
|
|
FreeConnectionSettings( m_pdplConnectionSettings );
|
|
}
|
|
|
|
m_pdplConnectionSettings = pdplConnectionSettings;
|
|
|
|
return DPN_OK;
|
|
|
|
INITIALIZE_FAILED:
|
|
|
|
FreeConnectionSettings( pdplConnectionSettings );
|
|
|
|
return hr;
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CConnectionSettings::BuildWireStruct"
|
|
// BuildWireStruct
|
|
//
|
|
// This function fills the packed buffer with the wire representation of the
|
|
// connection settings structure.
|
|
HRESULT CConnectionSettings::BuildWireStruct( CPackedBuffer *const pPackedBuffer )
|
|
{
|
|
HRESULT hr = DPN_OK;
|
|
DPL_INTERNAL_CONNECTION_SETTINGS *pdplConnectSettings = NULL;
|
|
WCHAR *wszTmpAddress = NULL;
|
|
DWORD dwTmpStringSize = 0;
|
|
UNALIGNED DWORD *pdwTmpOffsets = NULL;
|
|
UNALIGNED DWORD *pdwTmpLengths = NULL;
|
|
|
|
pdplConnectSettings = (DPL_INTERNAL_CONNECTION_SETTINGS *) pPackedBuffer->GetHeadAddress();
|
|
|
|
hr = pPackedBuffer->AddToFront( NULL, sizeof( DPL_INTERNAL_CONNECTION_SETTINGS ) );
|
|
|
|
if( hr == DPN_OK )
|
|
{
|
|
ZeroMemory( pdplConnectSettings, sizeof( DPL_INTERNAL_CONNECTION_SETTINGS ) );
|
|
|
|
//
|
|
// COPY CORE FIXED VALUES
|
|
//
|
|
pdplConnectSettings->dwFlags = m_pdplConnectionSettings->dwFlags;
|
|
pdplConnectSettings->dwNumDeviceAddresses = m_pdplConnectionSettings->cNumDeviceAddresses;
|
|
|
|
//
|
|
// COPY APPDESC FIXED VALUES
|
|
//
|
|
pdplConnectSettings->dpnApplicationDesc.dwSize = sizeof( DPN_APPLICATION_DESC_INFO );
|
|
pdplConnectSettings->dpnApplicationDesc.dwFlags = m_pdplConnectionSettings->dpnAppDesc.dwFlags;
|
|
pdplConnectSettings->dpnApplicationDesc.dwMaxPlayers = m_pdplConnectionSettings->dpnAppDesc.dwMaxPlayers;
|
|
pdplConnectSettings->dpnApplicationDesc.dwCurrentPlayers = m_pdplConnectionSettings->dpnAppDesc.dwCurrentPlayers;
|
|
pdplConnectSettings->dpnApplicationDesc.guidInstance = m_pdplConnectionSettings->dpnAppDesc.guidInstance;
|
|
pdplConnectSettings->dpnApplicationDesc.guidApplication = m_pdplConnectionSettings->dpnAppDesc.guidApplication;
|
|
}
|
|
|
|
//
|
|
// COPY VARIABLE CORE VALUES
|
|
//
|
|
|
|
if( m_pdplConnectionSettings->pwszPlayerName )
|
|
{
|
|
hr = pPackedBuffer->AddWCHARStringToBack( m_pdplConnectionSettings->pwszPlayerName );
|
|
|
|
if( hr == DPN_OK && pdplConnectSettings )
|
|
{
|
|
pdplConnectSettings->dwPlayerNameOffset = pPackedBuffer->GetTailOffset();
|
|
pdplConnectSettings->dwPlayerNameLength =
|
|
(wcslen( m_pdplConnectionSettings->pwszPlayerName )+1) * sizeof( WCHAR );
|
|
}
|
|
}
|
|
|
|
if( m_pdplConnectionSettings->pdp8HostAddress )
|
|
{
|
|
hr = m_pdplConnectionSettings->pdp8HostAddress->lpVtbl->GetURLW( m_pdplConnectionSettings->pdp8HostAddress, NULL, &dwTmpStringSize );
|
|
|
|
if( hr != DPNERR_BUFFERTOOSMALL )
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed converting address hr [0x%x]", hr );
|
|
goto BUILDWIRESTRUCT_FAILURE;
|
|
}
|
|
|
|
wszTmpAddress = new WCHAR[dwTmpStringSize];
|
|
|
|
if( !wszTmpAddress )
|
|
{
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
DPFX(DPFPREP, 0, "Failed allocating memory" );
|
|
goto BUILDWIRESTRUCT_FAILURE;
|
|
}
|
|
|
|
hr = m_pdplConnectionSettings->pdp8HostAddress->lpVtbl->GetURLW( m_pdplConnectionSettings->pdp8HostAddress, wszTmpAddress, &dwTmpStringSize );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed converting address hr [0x%x]", hr );
|
|
goto BUILDWIRESTRUCT_FAILURE;
|
|
}
|
|
|
|
hr = pPackedBuffer->AddWCHARStringToBack( wszTmpAddress );
|
|
|
|
if( hr == DPN_OK && pdplConnectSettings )
|
|
{
|
|
pdplConnectSettings->dwHostAddressOffset = pPackedBuffer->GetTailOffset();
|
|
pdplConnectSettings->dwHostAddressLength =
|
|
(wcslen( wszTmpAddress )+1) * sizeof( WCHAR );
|
|
}
|
|
|
|
delete [] wszTmpAddress;
|
|
wszTmpAddress = NULL;
|
|
|
|
}
|
|
|
|
hr = pPackedBuffer->AddToBack( NULL, sizeof( DWORD ) * m_pdplConnectionSettings->cNumDeviceAddresses );
|
|
|
|
if( hr == DPN_OK && pdplConnectSettings )
|
|
{
|
|
pdwTmpOffsets = (DWORD *) pPackedBuffer->GetTailAddress();
|
|
pdplConnectSettings->dwDeviceAddressOffset = pPackedBuffer->GetTailOffset();
|
|
}
|
|
|
|
hr = pPackedBuffer->AddToBack( NULL, sizeof( DWORD ) * m_pdplConnectionSettings->cNumDeviceAddresses );
|
|
|
|
if( hr == DPN_OK && pdplConnectSettings )
|
|
{
|
|
pdwTmpLengths = (DWORD *) pPackedBuffer->GetTailAddress();
|
|
pdplConnectSettings->dwDeviceAddressLengthOffset = pPackedBuffer->GetTailOffset();
|
|
}
|
|
|
|
for( DWORD dwIndex = 0; dwIndex < m_pdplConnectionSettings->cNumDeviceAddresses; dwIndex++ )
|
|
{
|
|
dwTmpStringSize = 0;
|
|
|
|
hr = m_pdplConnectionSettings->ppdp8DeviceAddresses[dwIndex]->lpVtbl->GetURLW(
|
|
m_pdplConnectionSettings->ppdp8DeviceAddresses[dwIndex],
|
|
NULL, &dwTmpStringSize );
|
|
|
|
if( hr != DPNERR_BUFFERTOOSMALL )
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed converting address hr [0x%x]", hr );
|
|
goto BUILDWIRESTRUCT_FAILURE;
|
|
}
|
|
|
|
wszTmpAddress = new WCHAR[dwTmpStringSize];
|
|
|
|
if( !wszTmpAddress )
|
|
{
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
DPFX(DPFPREP, 0, "Failed allocating memory" );
|
|
goto BUILDWIRESTRUCT_FAILURE;
|
|
}
|
|
|
|
hr = m_pdplConnectionSettings->ppdp8DeviceAddresses[dwIndex]->lpVtbl->GetURLW(
|
|
m_pdplConnectionSettings->ppdp8DeviceAddresses[dwIndex],
|
|
wszTmpAddress, &dwTmpStringSize );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed converting address hr [0x%x]", hr );
|
|
goto BUILDWIRESTRUCT_FAILURE;
|
|
}
|
|
|
|
hr = pPackedBuffer->AddWCHARStringToBack( wszTmpAddress );
|
|
|
|
if( hr == DPN_OK && pdplConnectSettings && pdwTmpLengths )
|
|
{
|
|
pdwTmpOffsets[dwIndex] = pPackedBuffer->GetTailOffset();
|
|
pdwTmpLengths[dwIndex] = (wcslen( wszTmpAddress )+1) * sizeof( WCHAR );
|
|
}
|
|
|
|
delete [] wszTmpAddress;
|
|
wszTmpAddress = NULL;
|
|
}
|
|
|
|
//
|
|
// COPY APP DESC VARIABLE MEMBERS
|
|
//
|
|
|
|
if( m_pdplConnectionSettings->dpnAppDesc.pwszPassword )
|
|
{
|
|
hr = pPackedBuffer->AddWCHARStringToBack( m_pdplConnectionSettings->dpnAppDesc.pwszPassword );
|
|
|
|
if( hr == DPN_OK && pdplConnectSettings )
|
|
{
|
|
pdplConnectSettings->dpnApplicationDesc.dwPasswordOffset = pPackedBuffer->GetTailOffset();
|
|
pdplConnectSettings->dpnApplicationDesc.dwPasswordSize =
|
|
(wcslen( m_pdplConnectionSettings->dpnAppDesc.pwszPassword )+1) * sizeof( WCHAR );
|
|
}
|
|
}
|
|
|
|
if( m_pdplConnectionSettings->dpnAppDesc.pwszSessionName)
|
|
{
|
|
hr = pPackedBuffer->AddWCHARStringToBack( m_pdplConnectionSettings->dpnAppDesc.pwszSessionName );
|
|
|
|
if( hr == DPN_OK && pdplConnectSettings )
|
|
{
|
|
pdplConnectSettings->dpnApplicationDesc.dwSessionNameOffset = pPackedBuffer->GetTailOffset();
|
|
pdplConnectSettings->dpnApplicationDesc.dwSessionNameSize =
|
|
(wcslen( m_pdplConnectionSettings->dpnAppDesc.pwszSessionName )+1) * sizeof( WCHAR );
|
|
}
|
|
}
|
|
|
|
if( m_pdplConnectionSettings->dpnAppDesc.pvReservedData )
|
|
{
|
|
hr = pPackedBuffer->AddToBack( m_pdplConnectionSettings->dpnAppDesc.pvReservedData,
|
|
m_pdplConnectionSettings->dpnAppDesc.dwReservedDataSize );
|
|
|
|
if( hr == DPN_OK && pdplConnectSettings )
|
|
{
|
|
pdplConnectSettings->dpnApplicationDesc.dwReservedDataOffset = pPackedBuffer->GetTailOffset();
|
|
pdplConnectSettings->dpnApplicationDesc.dwReservedDataSize = m_pdplConnectionSettings->dpnAppDesc.dwReservedDataSize;
|
|
}
|
|
}
|
|
|
|
if( m_pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData)
|
|
{
|
|
hr = pPackedBuffer->AddToBack( m_pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData,
|
|
m_pdplConnectionSettings->dpnAppDesc.dwApplicationReservedDataSize);
|
|
|
|
if( hr == DPN_OK && pdplConnectSettings )
|
|
{
|
|
pdplConnectSettings->dpnApplicationDesc.dwApplicationReservedDataOffset = pPackedBuffer->GetTailOffset();
|
|
pdplConnectSettings->dpnApplicationDesc.dwApplicationReservedDataSize = m_pdplConnectionSettings->dpnAppDesc.dwApplicationReservedDataSize;
|
|
}
|
|
}
|
|
|
|
BUILDWIRESTRUCT_FAILURE:
|
|
|
|
if( wszTmpAddress )
|
|
delete [] wszTmpAddress;
|
|
|
|
return hr;
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CConnectionSettings::SetEqual"
|
|
// SetEqual
|
|
//
|
|
// This function provides a deep copy of the specified class into this object
|
|
HRESULT CConnectionSettings::SetEqual( CConnectionSettings * pdplSettings )
|
|
{
|
|
PDPL_CONNECTION_SETTINGS pConnectSettings = pdplSettings->GetConnectionSettings();
|
|
|
|
if( pConnectSettings == NULL )
|
|
{
|
|
DPFX(DPFPREP, 0, "Error getting settings -- no settings available!" );
|
|
return DPNERR_DOESNOTEXIST;
|
|
}
|
|
|
|
return Initialize( pConnectSettings );
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CConnectionSettings::CopyToBuffer( BYTE *pbBuffer, DWORD *pdwBufferSize )"
|
|
HRESULT CConnectionSettings::CopyToBuffer( BYTE *pbBuffer, DWORD *pdwBufferSize )
|
|
{
|
|
if( m_pdplConnectionSettings == NULL )
|
|
{
|
|
*pdwBufferSize = 0;
|
|
return DPNERR_DOESNOTEXIST;
|
|
}
|
|
|
|
CPackedBuffer packBuff;
|
|
HRESULT hr = DPN_OK;
|
|
DPL_CONNECTION_SETTINGS *pConnectionSettings = NULL;
|
|
|
|
packBuff.Initialize( pbBuffer, *pdwBufferSize, TRUE );
|
|
|
|
pConnectionSettings = (DPL_CONNECTION_SETTINGS *) packBuff.GetHeadAddress();
|
|
|
|
hr = packBuff.AddToFront( m_pdplConnectionSettings, sizeof( DPL_CONNECTION_SETTINGS ), TRUE );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
pConnectionSettings = NULL;
|
|
}
|
|
|
|
// Add app desc's session name if there is one
|
|
if( m_pdplConnectionSettings->dpnAppDesc.pwszSessionName != NULL )
|
|
{
|
|
hr = packBuff.AddWCHARStringToBack( m_pdplConnectionSettings->dpnAppDesc.pwszSessionName, TRUE );
|
|
|
|
if( pConnectionSettings )
|
|
pConnectionSettings->dpnAppDesc.pwszSessionName = (WCHAR *) packBuff.GetTailAddress();
|
|
}
|
|
|
|
// Copy player name
|
|
if( m_pdplConnectionSettings->pwszPlayerName != NULL )
|
|
{
|
|
hr = packBuff.AddWCHARStringToBack( m_pdplConnectionSettings->pwszPlayerName, TRUE );
|
|
|
|
if( pConnectionSettings )
|
|
pConnectionSettings->pwszPlayerName = (WCHAR *) packBuff.GetTailAddress();
|
|
}
|
|
|
|
// Copy password
|
|
if( m_pdplConnectionSettings->dpnAppDesc.pwszPassword )
|
|
{
|
|
hr = packBuff.AddWCHARStringToBack( m_pdplConnectionSettings->dpnAppDesc.pwszPassword, TRUE );
|
|
|
|
if( pConnectionSettings )
|
|
pConnectionSettings->dpnAppDesc.pwszPassword = (WCHAR *) packBuff.GetTailAddress();
|
|
}
|
|
|
|
if( m_pdplConnectionSettings->dpnAppDesc.dwReservedDataSize )
|
|
{
|
|
hr = packBuff.AddToBack( m_pdplConnectionSettings->dpnAppDesc.pvReservedData, m_pdplConnectionSettings->dpnAppDesc.dwReservedDataSize, TRUE );
|
|
if( pConnectionSettings )
|
|
pConnectionSettings->dpnAppDesc.pvReservedData = (WCHAR *) packBuff.GetTailAddress();
|
|
}
|
|
|
|
if( m_pdplConnectionSettings->dpnAppDesc.dwApplicationReservedDataSize )
|
|
{
|
|
hr = packBuff.AddToBack( m_pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData, m_pdplConnectionSettings->dpnAppDesc.dwApplicationReservedDataSize, TRUE );
|
|
|
|
if( pConnectionSettings )
|
|
pConnectionSettings->dpnAppDesc.pvApplicationReservedData = (WCHAR *) packBuff.GetTailAddress();
|
|
}
|
|
|
|
hr = packBuff.AddToBack( m_pdplConnectionSettings->ppdp8DeviceAddresses, sizeof( IDirectPlay8Address * )*m_pdplConnectionSettings->cNumDeviceAddresses, TRUE );
|
|
|
|
if( pConnectionSettings )
|
|
pConnectionSettings->ppdp8DeviceAddresses = (IDirectPlay8Address **) packBuff.GetTailAddress();
|
|
|
|
if( pConnectionSettings )
|
|
{
|
|
if( m_pdplConnectionSettings->pdp8HostAddress != NULL )
|
|
{
|
|
hr = m_pdplConnectionSettings->pdp8HostAddress->lpVtbl->Duplicate( m_pdplConnectionSettings->pdp8HostAddress, &pConnectionSettings->pdp8HostAddress );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Error duplicating host address hr [0x%x]", hr );
|
|
goto INITIALIZE_COMPLETE;
|
|
}
|
|
}
|
|
|
|
for( DWORD dwIndex = 0; dwIndex < m_pdplConnectionSettings->cNumDeviceAddresses; dwIndex++ )
|
|
{
|
|
hr = m_pdplConnectionSettings->ppdp8DeviceAddresses[dwIndex]->lpVtbl->Duplicate( m_pdplConnectionSettings->ppdp8DeviceAddresses[dwIndex], &pConnectionSettings->ppdp8DeviceAddresses[dwIndex] );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Error duplicating device address hr [0x%x]", hr );
|
|
goto INITIALIZE_COMPLETE;
|
|
}
|
|
}
|
|
}
|
|
|
|
INITIALIZE_COMPLETE:
|
|
|
|
*pdwBufferSize = packBuff.GetSizeRequired();
|
|
|
|
return hr;
|
|
|
|
}
|
|
|