/*========================================================================== * * 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; }