windows-nt/Source/XPSP1/NT/net/homenet/alg/exe/collectionadapters.cpp
2020-09-26 16:20:57 +08:00

470 lines
10 KiB
C++

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