windows-nt/Source/XPSP1/NT/admin/cys/win32/networkinterface.cpp
2020-09-26 16:20:57 +08:00

403 lines
8.2 KiB
C++

// Copyright (c) 1997-2001 Microsoft Corporation
//
// File: NetworkInterface.h
//
// Synopsis: Defines a NetworkInterface
// This object has the knowledge of an
// IP enabled network connection including
// IP address, DHCP information, etc.
//
// History: 03/01/2001 JeffJon Created
#include "pch.h"
#include "NetworkInterface.h"
#define CYS_WMIPROP_IPADDRESS L"IPAddress"
#define CYS_WMIPROP_DHCPENABLED L"DHCPEnabled"
#define CYS_WMIPROP_DESCRIPTION L"Description"
NetworkInterface::NetworkInterface()
: initialized(false),
ipaddrCount(0),
dhcpEnabled(false)
{
LOG_CTOR(NetworkInterface);
}
NetworkInterface::~NetworkInterface()
{
LOG_DTOR(NetworkInterface);
if (!ipaddresses.empty())
{
ipaddresses.clear();
}
ipaddrCount = 0;
}
NetworkInterface::NetworkInterface(const NetworkInterface &nic)
{
LOG_CTOR2(NetworkInterface, L"Copy constructor");
if (this == &nic)
{
return;
}
initialized = nic.initialized;
ipaddrCount = nic.ipaddrCount;
dhcpEnabled = nic.dhcpEnabled;
wmiAdapterObject = nic.wmiAdapterObject;
ipaddressString = nic.ipaddressString;
// Make a copy of the ipaddress array
ipaddresses = nic.ipaddresses;
}
NetworkInterface&
NetworkInterface::operator=(const NetworkInterface& rhs)
{
LOG_FUNCTION(NetworkInterface::operator=);
if (this == &rhs)
{
return *this;
}
initialized = rhs.initialized;
ipaddrCount = rhs.ipaddrCount;
dhcpEnabled = rhs.dhcpEnabled;
wmiAdapterObject = rhs.wmiAdapterObject;
ipaddressString = rhs.ipaddressString;
// Make a copy of the ipaddress array
ipaddresses = rhs.ipaddresses;
return *this;
}
HRESULT
NetworkInterface::Initialize(SmartInterface<IWbemClassObject>& adapterObject)
{
LOG_FUNCTION(NetworkInterface::Initialize);
HRESULT hr = S_OK;
if (initialized)
{
ASSERT(!initialized);
hr = E_UNEXPECTED;
}
else
{
// Store the adapter interface pointer for later use
wmiAdapterObject = adapterObject;
// Get the needed info from the WMI object
hr = GetIPAddressFromWMI();
if (FAILED(hr))
{
LOG(String::format(
L"Failed to retrieve IP Addresses: hr = 0x%1!x!",
hr));
}
hr = GetDHCPEnabledFromWMI();
if (FAILED(hr))
{
LOG(String::format(
L"Failed to retrieve dhcpEnabled state: hr = 0x%1!x!",
hr));
}
}
// If we succeeded in retrieving the data we need,
// mark the object initialized
if (SUCCEEDED(hr))
{
initialized = true;
}
LOG_HRESULT(hr);
return hr;
}
HRESULT
NetworkInterface::GetIPAddressFromWMI()
{
LOG_FUNCTION(NetworkInterface::GetIPAddressFromWMI);
HRESULT hr = S_OK;
do
{
_variant_t var;
hr = wmiAdapterObject->Get(
CYS_WMIPROP_IPADDRESS,
0, // flags, reserved, must be zero
&var,
0, // CIMTYPE
0); // origin of the property
if (FAILED(hr))
{
LOG(String::format(
L"Unable to retrieve the IPAddress property: hr = 0x%1!x!",
hr));
break;
}
// The IP addresses come as a SAFEARRAY of BSTRs. Convert that to a
// StringList
StringList iplist;
hr = VariantArrayToStringList(&var, iplist);
if (FAILED(hr))
{
LOG(String::format(
L"Unable to convert variant to string list: hr = 0x%1!x!",
hr));
break;
}
hr = SetIPAddresses(iplist);
if (FAILED(hr))
{
LOG(String::format(
L"Failed to convert IP addresses from string: hr = 0x%1!x!",
hr));
break;
}
} while (false);
LOG_HRESULT(hr);
return hr;
}
HRESULT
NetworkInterface::SetIPAddresses(const StringList& ipList)
{
LOG_FUNCTION(NetworkInterface::SetIPAddresses);
HRESULT hr = S_OK;
// if the list already contains some entries, delete them and start over
ipaddressString.erase();
if (!ipaddresses.empty())
{
ipaddresses.erase(ipaddresses.begin());
}
// Loop through the string list converting all string IP addresses
// to DWORD IP addresses and add them to the ipaddresses array
int addressesAdded = 0;
for (
StringList::iterator itr = ipList.begin();
itr != ipList.end();
++itr)
{
String entry = *itr;
// Add the ipaddress to the semicolon delimited string
if (addressesAdded > 0)
{
ipaddressString += L";";
}
ipaddressString += entry;
// Convert the string to ansi so that we can use inet_addr
// to convert to an IP address DWORD
AnsiString ansi;
String::ConvertResult convertResult = entry.convert(ansi);
if (String::CONVERT_SUCCESSFUL == convertResult)
{
// Convert and add the new address to the array
DWORD newAddress = inet_addr(ansi.c_str());
ASSERT(newAddress != INADDR_NONE);
ipaddresses.push_back(newAddress);
++addressesAdded;
}
else
{
LOG(String::format(
L"Failed to convert address: %1: hr = 0x%2!x!",
entry.c_str(),
hr));
continue;
}
}
ipaddrCount = addressesAdded;
ASSERT(ipaddrCount <= ipList.size());
LOG_HRESULT(hr);
return hr;
}
DWORD
NetworkInterface::GetIPAddress(DWORD addressIndex) const
{
LOG_FUNCTION2(
NetworkInterface::GetIPAddress,
String::format(
L"%1!d!",
addressIndex));
ASSERT(initialized);
ASSERT(addressIndex <= ipaddrCount);
return ipaddresses[addressIndex];
}
String
NetworkInterface::GetStringIPAddress() const
{
LOG_FUNCTION(NetworkInterface::GetStringIPAddress);
return ipaddressString;
}
HRESULT
NetworkInterface::GetDHCPEnabledFromWMI()
{
LOG_FUNCTION(NetworkInterface::GetDHCPEnabledFromWMI);
HRESULT hr = S_OK;
do
{
_variant_t var;
hr = wmiAdapterObject->Get(
CYS_WMIPROP_DHCPENABLED,
0, // flags, reserved, must be zero
&var,
0, // CIMTYPE
0); // origin of the property
if (FAILED(hr))
{
LOG(String::format(
L"Unable to retrieve the IPAddress property: hr = 0x%1!x!",
hr));
break;
}
ASSERT(V_VT(&var) == (VT_BOOL));
dhcpEnabled = (V_BOOL(&var) != 0);
} while(false);
LOG_HRESULT(hr);
return hr;
}
bool
NetworkInterface::RenewDHCPLease()
{
LOG_FUNCTION(NetworkInterface::RenewDHCPLease);
bool found = false;
do
{
for(DWORD i = 0; i < ipaddrCount; ++i)
{
found = (IsDHCPAvailableOnInterface(ipaddresses[i]) != 0);
if (found)
{
LOG(String::format(
L"Found DHCP server on: %1!x!",
ipaddresses[i]));
// Then we have to reload the IP addresses because they
// may have been altered by renewing the lease
// return value is ignored
GetIPAddressFromWMI();
break;
}
}
} while(false);
LOG(found ? L"true" : L"false");
return found;
}
String
NetworkInterface::GetDescription() const
{
LOG_FUNCTION(NetworkInterface::GetDescription);
ASSERT(initialized);
String description;
do
{
_variant_t var;
HRESULT hr = wmiAdapterObject->Get(
CYS_WMIPROP_DESCRIPTION,
0, // flags, reserved, must be zero
&var,
0, // CIMTYPE
0); // origin of the property
if (FAILED(hr))
{
LOG(String::format(
L"Unable to retrieve the Description property: hr = 0x%1!x!",
hr));
break;
}
ASSERT(V_VT(&var) == (VT_BSTR));
description = V_BSTR(&var);
} while (false);
LOG(description);
return description;
}