273 lines
6.7 KiB
C++
273 lines
6.7 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 2000.
|
|
//
|
|
// File: I N T E R F A C E L I S T . C P P
|
|
//
|
|
// Contents: Common code to manage the list of network interfaces
|
|
//
|
|
// Notes:
|
|
//
|
|
// Author: mbend 29 Dec 2000
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
|
|
#include "InterfaceList.h"
|
|
#include <iphlpapi.h>
|
|
#include <winsock2.h>
|
|
|
|
CUPnPInterfaceList CUPnPInterfaceList::s_instance;
|
|
CUPnPInterfaceList::CUPnPInterfaceList() : m_bGlobalEnable(TRUE), m_bICSEnabled(FALSE), m_hInterfaceChangeWait(NULL)
|
|
{
|
|
ZeroMemory(&m_olInterfaceChangeEvent, sizeof(m_olInterfaceChangeEvent));
|
|
}
|
|
|
|
CUPnPInterfaceList::~CUPnPInterfaceList()
|
|
{
|
|
}
|
|
|
|
CUPnPInterfaceList & CUPnPInterfaceList::Instance()
|
|
{
|
|
return s_instance;
|
|
}
|
|
|
|
HRESULT CUPnPInterfaceList::HrInitialize()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
CLock lock(m_critSec);
|
|
|
|
// TODO: Read registry to set global enable state!!!!!
|
|
|
|
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
if(!hEvent)
|
|
{
|
|
hr = HrFromLastWin32Error();
|
|
}
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(!RegisterWaitForSingleObject(&m_hInterfaceChangeWait, hEvent,
|
|
&CUPnPInterfaceList::InterfaceChangeCallback, NULL, INFINITE, 0))
|
|
{
|
|
hr = HrFromLastWin32Error();
|
|
}
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
m_olInterfaceChangeEvent.hEvent = hEvent;
|
|
hr = HrBuildIPAddressList();
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
HANDLE hNotify = NULL;
|
|
if(!NotifyAddrChange(&hNotify, &m_olInterfaceChangeEvent))
|
|
{
|
|
hr = HrFromLastWin32Error();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TraceHr(ttidSsdpNetwork, FAL, hr, FALSE, "CUPnPInterfaceList::HrInitialize");
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CUPnPInterfaceList::HrShutdown()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Kill wait outside of a lock
|
|
UnregisterWaitEx(m_hInterfaceChangeWait, INVALID_HANDLE_VALUE);
|
|
|
|
CLock lock(m_critSec);
|
|
|
|
CloseHandle(m_olInterfaceChangeEvent.hEvent);
|
|
m_olInterfaceChangeEvent.hEvent = NULL;
|
|
|
|
m_ipAddressList.Clear();
|
|
m_indexList.Clear();
|
|
m_interfaceList.Clear();
|
|
|
|
TraceHr(ttidSsdpNetwork, FAL, hr, FALSE, "CUPnPInterfaceList::HrShutdown");
|
|
return hr;
|
|
}
|
|
|
|
BOOL CUPnPInterfaceList::FShouldSendOnInterface(DWORD dwIpAddr)
|
|
{
|
|
CLock lock(m_critSec);
|
|
|
|
if(!m_bICSEnabled)
|
|
{
|
|
return m_bGlobalEnable;
|
|
}
|
|
|
|
long nIndex = -1;
|
|
HRESULT hrTemp = m_ipAddressList.HrFind(dwIpAddr, nIndex);
|
|
#if DBG
|
|
in_addr addr;
|
|
addr.S_un.S_addr = dwIpAddr;
|
|
char * szAddr = inet_ntoa(addr);
|
|
if(S_OK != hrTemp)
|
|
{
|
|
TraceTag(ttidSsdpNetwork, "CUPnPInterfaceList::FShouldSendOnInterface - Blocked sending on IP Address (%s)", szAddr);
|
|
}
|
|
#endif // DBG
|
|
|
|
return S_OK == hrTemp;
|
|
}
|
|
|
|
BOOL CUPnPInterfaceList::FShouldSendOnIndex(DWORD dwIndex)
|
|
{
|
|
CLock lock(m_critSec);
|
|
|
|
if(!m_bICSEnabled)
|
|
{
|
|
return m_bGlobalEnable;
|
|
}
|
|
|
|
long nIndex = -1;
|
|
HRESULT hrTemp = m_indexList.HrFind(dwIndex, nIndex);
|
|
#if DBG
|
|
if(S_OK != hrTemp)
|
|
{
|
|
TraceTag(ttidSsdpNetwork, "CUPnPInterfaceList::FShouldSendOnIndex - Blocked sending on index (%d)", dwIndex);
|
|
}
|
|
#endif // DBG
|
|
|
|
return S_OK == hrTemp;
|
|
}
|
|
|
|
HRESULT CUPnPInterfaceList::HrSetGlobalEnable()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
CLock lock(m_critSec);
|
|
|
|
m_bGlobalEnable = TRUE;
|
|
|
|
TraceHr(ttidSsdpNetwork, FAL, hr, FALSE, "CUPnPInterfaceList::HrSetGlobalEnable");
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CUPnPInterfaceList::HrClearGlobalEnable()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
CLock lock(m_critSec);
|
|
|
|
m_bGlobalEnable = FALSE;
|
|
|
|
TraceHr(ttidSsdpNetwork, FAL, hr, FALSE, "CUPnPInterfaceList::HrClearGlobalEnable");
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CUPnPInterfaceList::HrSetICSInterfaces(long nCount, GUID * arInterfaceGuidsToAllow)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
CLock lock(m_critSec);
|
|
|
|
m_bICSEnabled = TRUE;
|
|
|
|
m_interfaceList.Clear();
|
|
hr = m_interfaceList.HrSetCount(nCount);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
for(long n = 0; n < nCount; ++n)
|
|
{
|
|
m_interfaceList[n] = arInterfaceGuidsToAllow[n];
|
|
}
|
|
hr = HrBuildIPAddressList();
|
|
}
|
|
|
|
TraceHr(ttidSsdpNetwork, FAL, hr, FALSE, "CUPnPInterfaceList::HrSetICSInterfaces");
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CUPnPInterfaceList::HrSetICSOff()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
CLock lock(m_critSec);
|
|
|
|
m_bICSEnabled = FALSE;
|
|
m_interfaceList.Clear();
|
|
hr = HrBuildIPAddressList();
|
|
|
|
TraceHr(ttidSsdpNetwork, FAL, hr, FALSE, "CUPnPInterfaceList::HrSetICSOff");
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CUPnPInterfaceList::HrRegisterInterfaceChange(CUPnPInterfaceChange * pInterfaceChange)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
CLock lock(m_critSec);
|
|
|
|
hr = m_interfaceChangeList.HrPushBack(pInterfaceChange);
|
|
|
|
TraceHr(ttidSsdpNetwork, FAL, hr, FALSE, "CUPnPInterfaceList::HrRegisterInterfaceChange");
|
|
return hr;
|
|
}
|
|
|
|
void CALLBACK CUPnPInterfaceList::InterfaceChangeCallback(void *, BOOLEAN)
|
|
{
|
|
CLock lock(s_instance.m_critSec);
|
|
HRESULT hr = S_OK;
|
|
hr = s_instance.HrBuildIPAddressList();
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
HANDLE hNotify = NULL;
|
|
if(!NotifyAddrChange(&hNotify, &s_instance.m_olInterfaceChangeEvent))
|
|
{
|
|
hr = HrFromLastWin32Error();
|
|
}
|
|
}
|
|
TraceHr(ttidSsdpNetwork, FAL, hr, FALSE, "CUPnPInterfaceList::InterfaceChangeCallback");
|
|
}
|
|
|
|
HRESULT CUPnPInterfaceList::HrBuildIPAddressList()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
CLock lock(m_critSec);
|
|
|
|
CInterfaceManager man;
|
|
if(m_bICSEnabled)
|
|
{
|
|
hr = man.HrInitializeWithIncludedInterfaces(m_interfaceList);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = man.HrGetValidIpAddresses(m_ipAddressList);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = man.HrGetValidIndices(m_indexList);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = man.HrInitializeWithAllInterfaces();
|
|
}
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
InterfaceMappingList interfaceMappingList;
|
|
hr = man.HrGetMappingList(interfaceMappingList);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
long nCount = m_interfaceChangeList.GetCount();
|
|
for(long n = 0; n < nCount; ++n)
|
|
{
|
|
m_interfaceChangeList[n]->OnInterfaceChange(interfaceMappingList);
|
|
}
|
|
}
|
|
}
|
|
|
|
TraceHr(ttidSsdpNetwork, FAL, hr, FALSE, "CUPnPInterfaceList::HrBuildIPAddressList");
|
|
return hr;
|
|
}
|
|
|
|
|