|
|
/*++
Copyright (c) 2000, Microsoft Corporation
Module Name:
CollectionAdapters.cpp
Abstract:
Implement a collection of the CPrimaryControlChannel.cpp & CSecondaryControlChannel in a threa safe way.
Author:
JP Duplessis (jpdup) 08-Dec-2000
Revision History:
--*/
#include "PreComp.h"
#include "CollectionAdapters.h"
#include "CollectionAdapterNotifySinks.h"
#include "AlgController.h"
CCollectionAdapters::~CCollectionAdapters() { RemoveAll(); }
//
// Add an already created Adapter
//
HRESULT CCollectionAdapters::Add( IAdapterInfo* pAdapterToAdd ) { try { ENTER_AUTO_CS
if ( !FindUsingInterface(pAdapterToAdd) ) m_ListOfAdapters.push_back(pAdapterToAdd); } catch(...) { return E_FAIL; }
return S_OK; }
//
// Add a NEW Adapter this function insure that the is only 1 adatper with the given INDEX
// returns the newly added adapter or NULL is faild
// if the Adapter index was already present the return pointer is of the one found in the collection
//
IAdapterInfo* CCollectionAdapters::Add( IN ULONG nCookie, IN short nType ) { CComObject<CAdapterInfo>* pIAdapterInfo=NULL;
try { ENTER_AUTO_CS MYTRACE_ENTER("CCollectionAdapters::Add"); MYTRACE("Adapter Cookie %d of type %d", nCookie, nType);
IAdapterInfo* pIFound = FindUsingCookie(nCookie); if ( pIFound ) return pIFound; // Adapter with the given Index is already in the collection
HRESULT hr = CComObject<CAdapterInfo>::CreateInstance(&pIAdapterInfo);
if ( FAILED(hr) ) { MYTRACE_ERROR("CComObject<CAdapterInfo>::CreateInstance(&pIAdapterInfo)",hr); return NULL; //ERROR_NOT_ENOUGH_MEMORY;
}
//
// Initialize the new interface
//
pIAdapterInfo->m_nCookie = nCookie; pIAdapterInfo->m_eType = (ALG_ADAPTER_TYPE)nType;
m_ListOfAdapters.push_back(pIAdapterInfo); pIAdapterInfo->AddRef();
} catch(...) { return NULL; }
return pIAdapterInfo; }
//
// Remove a adapter from the list (Thead safe)
//
HRESULT CCollectionAdapters::Remove( IAdapterInfo* pAdapterToRemove ) { try { ENTER_AUTO_CS MYTRACE_ENTER("CCollectionAdapters::Remove by IAdapterInfo");
LISTOF_ADAPTERS::iterator theIterator = std::find( m_ListOfAdapters.begin(), m_ListOfAdapters.end(), pAdapterToRemove );
if ( *theIterator ) { CAdapterInfo* pAdapterInfo = (CAdapterInfo*)pAdapterToRemove;
g_pAlgController->m_AdapterNotificationSinks.Notify(eNOTIFY_REMOVED, (*theIterator) ); g_pAlgController->m_ControlChannelsPrimary.AdapterRemoved(pAdapterInfo->m_nAdapterIndex);
(*theIterator)->Release(); m_ListOfAdapters.erase(theIterator); } } catch(...) { return E_FAIL; }
return S_OK; }
//
// Remove a adapter from the list (Thead safe)
//
HRESULT CCollectionAdapters::Remove( ULONG nCookieOfAdapterToRemove ) { try { ENTER_AUTO_CS
MYTRACE_ENTER("CCollectionAdapters::Remove by Index");
for ( LISTOF_ADAPTERS::iterator theIterator = m_ListOfAdapters.begin(); theIterator != m_ListOfAdapters.end(); theIterator++ ) {
CAdapterInfo* pAdapterInfo = (CAdapterInfo*)(*theIterator);
if ( pAdapterInfo->m_nCookie == nCookieOfAdapterToRemove ) { g_pAlgController->m_AdapterNotificationSinks.Notify(eNOTIFY_REMOVED, (*theIterator) ); g_pAlgController->m_ControlChannelsPrimary.AdapterRemoved(pAdapterInfo->m_nAdapterIndex);
pAdapterInfo->Release(); m_ListOfAdapters.erase(theIterator);
return S_OK; } } } catch(...) { return E_FAIL; }
return E_INVALIDARG; }
//
// When an adapter form the collection
//
HRESULT CCollectionAdapters::RemoveAll() { try { ENTER_AUTO_CS MYTRACE_ENTER("CCollectionAdapters::RemoveAll");
//
// By deleting all the ControlChannel they will also cancel all their associated Redirection
//
MYTRACE("Collection has %d item", m_ListOfAdapters.size());
LISTOF_ADAPTERS::iterator theIterator;
while ( m_ListOfAdapters.size() > 0 ) { theIterator = m_ListOfAdapters.begin(); CAdapterInfo* pAdapterInfo = (CAdapterInfo*)(*theIterator);
pAdapterInfo->Release(); m_ListOfAdapters.erase(theIterator); } } catch(...) { return E_FAIL; }
return S_OK; }
//
// Return an IAdapterInfo the caller is responsable of releasing the interface
//
HRESULT CCollectionAdapters::GetAdapterInfo( IN ULONG nAdapterIndex, OUT IAdapterInfo** ppAdapterInfo ) { MYTRACE_ENTER("CCollectionAdapters::GetAdapterInfo");
try { ENTER_AUTO_CS
MYTRACE("Adapter index %d requested", nAdapterIndex);
*ppAdapterInfo = FindUsingAdapterIndex(nAdapterIndex);
if ( *ppAdapterInfo == NULL ) { MYTRACE_ERROR("Adapter was not found in the collection", 0); return E_INVALIDARG; }
(*ppAdapterInfo)->AddRef();
} catch(...) { MYTRACE_ERROR("TRY/CATCH",0); return E_FAIL; }
return S_OK; }
//
// Update the addresses member proprety
//
// Now that we have the address we can apply any outstanding ControlChannel (Redirect)
//
HRESULT CCollectionAdapters::SetAddresses( ULONG nCookie, ULONG nAdapterIndex, ULONG nAddressCount, DWORD anAddress[] ) {
try { ENTER_AUTO_CS MYTRACE_ENTER("CCollectionAdapters::SetAddresses"); MYTRACE("Adapter BIND Cookie %d Address Count %d", nCookie, nAddressCount);
CAdapterInfo* pIAdapterFound = (CAdapterInfo*)FindUsingCookie(nCookie);
if ( !pIAdapterFound ) { MYTRACE_ERROR("Adapter was not found in the collection", 0); return E_INVALIDARG; }
//
// Cache the Adapter Index
//
pIAdapterFound->m_nAdapterIndex = nAdapterIndex;
//
// Cache the addresses
//
pIAdapterFound->m_nAddressCount = nAddressCount;
for ( short nA=0; nA < nAddressCount; nA++ ) pIAdapterFound->m_anAddress[nA] = anAddress[nA];
//
// Fire any Sink that may be setup
//
if ( pIAdapterFound->m_bNotified ) { //
// Already notify once the user that this adapter was added
// from now on any CCollectionAdapters::SetAddresses
// will trigger a eNOTIFY_MODIFIED notification
//
g_pAlgController->m_AdapterNotificationSinks.Notify( eNOTIFY_MODIFIED, pIAdapterFound ); } else { //
// Ok this is the first time we received address for this
// adapter we will let the user know that a new adapter got added
//
g_pAlgController->m_AdapterNotificationSinks.Notify( eNOTIFY_ADDED, pIAdapterFound );
pIAdapterFound->m_bNotified = true; }
//
// Create redirect(s) for any ControlChannels in the Collection of PrimaryControlChannel
//
g_pAlgController->m_ControlChannelsPrimary.SetRedirects( pIAdapterFound->m_eType, nAdapterIndex, anAddress[0] ); } catch(...) { return E_FAIL; }
return S_OK; }
//
//
//
HRESULT CCollectionAdapters::ApplyPrimaryChannel( CPrimaryControlChannel* pChannelToActivate ) { MYTRACE_ENTER("CCollectionAdapters::ApplyPrimaryChannel");
if ( !pChannelToActivate ) return E_INVALIDARG;
ENTER_AUTO_CS
for ( LISTOF_ADAPTERS::iterator theIterator = m_ListOfAdapters.begin(); theIterator != m_ListOfAdapters.end(); theIterator++ ) {
CAdapterInfo* pAdapterInfo = (CAdapterInfo*)(*theIterator);
if ( pAdapterInfo && pAdapterInfo->m_nAddressCount >0 ) { pChannelToActivate->SetRedirect( pAdapterInfo->m_eType, pAdapterInfo->m_nAdapterIndex, pAdapterInfo->m_nAddressCount ); } }
return S_OK; }
//
// Will be called when port mapping has changed
//
HRESULT CCollectionAdapters::AdapterUpdatePrimaryChannel( ULONG nCookie, CPrimaryControlChannel *pChannel ) { HRESULT hr = S_OK;
MYTRACE_ENTER("CCollectionAdapters::AdapterUpdatePrimaryChannel");
try { ENTER_AUTO_CS
CAdapterInfo *pAdapter = (CAdapterInfo*) FindUsingCookie(nCookie); if (NULL != pAdapter && ( (eALG_BOUNDARY & pAdapter->m_eType) || (eALG_FIREWALLED & pAdapter->m_eType) ) ) { ULONG ulAddress; USHORT usPort; HANDLE_PTR hRedirect; HRESULT hrPortMappingExists = g_pAlgController->GetNat()->LookupAdapterPortMapping( pAdapter->m_nAdapterIndex, pChannel->m_Properties.eProtocol, 0, pChannel->m_Properties.usCapturePort, &ulAddress, &usPort );
hRedirect = pChannel->m_CollectionRedirects.FindInboundRedirect(pAdapter->m_nAdapterIndex);
if (SUCCEEDED(hrPortMappingExists) && NULL == hRedirect) { MYTRACE("PortMapping Exist and We had no Redirect so create them"); hr = pChannel->CreateInboundRedirect(pAdapter->m_nAdapterIndex); } else if (FAILED(hrPortMappingExists) && NULL != hRedirect) { MYTRACE("PortMapping DOES NOT Exist and We had Redirect set so remove them"); hr = pChannel->m_CollectionRedirects.Remove(hRedirect); } } else { MYTRACE("Adapter is not ICS or ICF"); } } catch (...) { hr = E_FAIL; }
return hr; }
|