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

412 lines
7.6 KiB
C++

/*++
Copyright (c) 2000, Microsoft Corporation
Module Name:
CollectionChannels.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 "AlgController.h"
#define NAT_PROTOCOL_TCP 0x06
#define NAT_PROTOCOL_UDP 0x11
CCollectionControlChannelsPrimary::~CCollectionControlChannelsPrimary()
{
RemoveAll();
}
//
// Add a new control channel (Thread safe)
//
HRESULT
CCollectionControlChannelsPrimary::Add(
CPrimaryControlChannel* pChannelToAdd
)
{
try
{
ENTER_AUTO_CS
m_ListOfChannels.push_back(pChannelToAdd);
g_pAlgController->m_CollectionOfAdapters.ApplyPrimaryChannel(pChannelToAdd);
pChannelToAdd->AddRef();
}
catch(...)
{
return E_FAIL;
}
return S_OK;
}
//
// Remove a channel from the list (Thead safe)
//
HRESULT
CCollectionControlChannelsPrimary::Remove(
CPrimaryControlChannel* pChannelToRemove
)
{
HRESULT hr = S_OK;
try
{
ENTER_AUTO_CS
LISTOF_CHANNELS_PRIMARY::iterator theIterator = std::find(
m_ListOfChannels.begin(),
m_ListOfChannels.end(),
pChannelToRemove
);
if ( *theIterator )
{
m_ListOfChannels.erase(theIterator); // Remove from list
pChannelToRemove->CancelRedirects();
pChannelToRemove->Release();
}
}
catch(...)
{
return E_FAIL;
}
return hr;
}
//
// Empty the list and free the PrimaryControlChannels
//
HRESULT
CCollectionControlChannelsPrimary::RemoveAll()
{
try
{
ENTER_AUTO_CS
MYTRACE_ENTER("CCollectionControlChannelsPrimary::RemoveAll()");
//
// By deleting all the ControlChannel they will also cancel all associated Redirects
//
MYTRACE("Collection has %d item", m_ListOfChannels.size());
LISTOF_CHANNELS_PRIMARY::iterator theIterator;
while ( m_ListOfChannels.size() > 0 )
{
theIterator = m_ListOfChannels.begin();
m_ListOfChannels.erase(theIterator); // Remove from list
(*theIterator)->CancelRedirects();
(*theIterator)->Release();
}
}
catch(...)
{
return E_FAIL;
}
return S_OK;
}
//
// Set a dynamic redirection and all collected Primary ControlChannel
//
HRESULT
CCollectionControlChannelsPrimary::SetRedirects(
ALG_ADAPTER_TYPE eAdapterType,
ULONG nAdapterIndex,
ULONG nAdapterAddress
)
{
HRESULT hr=S_OK;
try
{
ENTER_AUTO_CS
MYTRACE_ENTER("CCollectionControlChannelsPrimary::SetRedirects");
MYTRACE("AdapterType %d, RealAdapterIndex %d, Currently %d ControlChannel in the collection", eAdapterType, nAdapterIndex, m_ListOfChannels.size());
//
// Set redirect for all Channel
//
for ( LISTOF_CHANNELS_PRIMARY::iterator theIterator = m_ListOfChannels.begin();
theIterator != m_ListOfChannels.end();
theIterator++
)
{
(*theIterator)->SetRedirect(
eAdapterType,
nAdapterIndex,
nAdapterAddress
);
}
}
catch(...)
{
hr = E_FAIL;
}
return hr;
}
//
// Check to see if the any PrimaryChannel need to be apply or his redirect should be removed
//
HRESULT
CCollectionControlChannelsPrimary::AdapterPortMappingChanged(
ULONG nCookie,
UCHAR ucProtocol,
USHORT usPort
)
{
HRESULT hr = S_OK;
ALG_PROTOCOL algProtocol;
MYTRACE_ENTER("CCollectionControlChannelsPrimary::AdapterPortMappingChanged");
MYTRACE("AdapterCookie %d, Protocol %d, Port %d", nCookie, ucProtocol, usPort);
if (NAT_PROTOCOL_TCP == ucProtocol)
{
algProtocol = eALG_TCP;
}
else if (NAT_PROTOCOL_UDP == ucProtocol)
{
algProtocol = eALG_UDP;
}
else
{
hr = E_INVALIDARG;
}
if (SUCCEEDED(hr))
{
try
{
ENTER_AUTO_CS
CPrimaryControlChannel *pControlChannel = FindControlChannel(algProtocol, usPort);
if (NULL != pControlChannel
&& pControlChannel->m_Properties.fCaptureInbound)
{
hr = g_pAlgController->m_CollectionOfAdapters.AdapterUpdatePrimaryChannel(
nCookie,
pControlChannel
);
}
}
catch (...)
{
hr = E_FAIL;
}
}
return hr;
}
//
// Called when an adapter got removed
// function will cancel any redirect that was done on this adapter index
//
HRESULT
CCollectionControlChannelsPrimary::AdapterRemoved(
ULONG nAdapterIndex
)
{
HRESULT hr = S_OK;
MYTRACE_ENTER("CCollectionControlChannelsPrimary::AdapterRemoved");
MYTRACE("AdapterIndex %d", nAdapterIndex);
try
{
ENTER_AUTO_CS
//
// Set redirect for all Channel
//
for ( LISTOF_CHANNELS_PRIMARY::iterator theIterator = m_ListOfChannels.begin();
theIterator != m_ListOfChannels.end();
theIterator++
)
{
(*theIterator)->CancelRedirectsForAdapter(
nAdapterIndex
);
}
}
catch (...)
{
hr = E_FAIL;
}
return hr;
}
//
//
// Collection of Secondary control channels
//
//
//
//
//
CCollectionControlChannelsSecondary::~CCollectionControlChannelsSecondary()
{
RemoveAll();
}
//
// Add a new control channel (Thread safe)
//
HRESULT
CCollectionControlChannelsSecondary::Add(
CSecondaryControlChannel* pChannelToAdd
)
{
try
{
ENTER_AUTO_CS
m_ListOfChannels.push_back(pChannelToAdd);
pChannelToAdd->AddRef();
}
catch(...)
{
return E_FAIL;
}
return S_OK;
}
//
// Remove a channel from the list (Thead safe)
//
HRESULT
CCollectionControlChannelsSecondary::Remove(
CSecondaryControlChannel* pChannelToRemove
)
{
try
{
ENTER_AUTO_CS
LISTOF_CHANNELS_SECONDARY::iterator theIterator = std::find(
m_ListOfChannels.begin(),
m_ListOfChannels.end(),
pChannelToRemove
);
if ( *theIterator )
{
m_ListOfChannels.erase(theIterator); // Remove from list
pChannelToRemove->CancelRedirects();
pChannelToRemove->Release();
}
}
catch(...)
{
return E_FAIL;
}
return S_OK;
}
//
// When a Control is cancel it need to Cancel all it's redirect previousely created
//
HRESULT
CCollectionControlChannelsSecondary::RemoveAll()
{
try
{
ENTER_AUTO_CS
MYTRACE_ENTER("CCollectionControlChannelsSecondary::RemoveAll()");
//
// By deleting all the SecondaryControlChannel they will also cancel all associated Redirects
//
MYTRACE("Collection has %d item", m_ListOfChannels.size());
LISTOF_CHANNELS_SECONDARY::iterator theIterator;
while ( m_ListOfChannels.size() > 0 )
{
theIterator = m_ListOfChannels.begin();
m_ListOfChannels.erase(theIterator); // Remove from list
(*theIterator)->CancelRedirects();
(*theIterator)->Release();
}
}
catch(...)
{
return E_FAIL;
}
return S_OK;
}