windows-nt/Source/XPSP1/NT/multimedia/directx/dplay/dnet/lobby/dplconset.cpp
2020-09-26 16:20:57 +08:00

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;
}