mirror of
https://github.com/Telecominfraproject/wlan-cloud-lib-poco.git
synced 2025-11-02 19:48:00 +00:00
GH #328: NetworkInterface on Windows XP
This commit is contained in:
@@ -64,6 +64,8 @@ Release 1.5.3 (2014-05-xx)
|
|||||||
- fixed GH #321: trivial build fixes (BB QNX build)
|
- fixed GH #321: trivial build fixes (BB QNX build)
|
||||||
- fixed GH #440: MongoDB ObjectId string formatting
|
- fixed GH #440: MongoDB ObjectId string formatting
|
||||||
- added SevenZip library (Guenter Obiltschnig)
|
- added SevenZip library (Guenter Obiltschnig)
|
||||||
|
- fixed GH #442: Use correct prefix length field of Windows IP_ADAPTER_PREFIX structure
|
||||||
|
- improved GH #328: NetworkInterface on Windows XP
|
||||||
|
|
||||||
Release 1.5.2 (2013-09-16)
|
Release 1.5.2 (2013-09-16)
|
||||||
==========================
|
==========================
|
||||||
|
|||||||
@@ -24,31 +24,55 @@
|
|||||||
#include "Poco/UnWindows.h"
|
#include "Poco/UnWindows.h"
|
||||||
|
|
||||||
|
|
||||||
// determine the real version
|
// Determine the real version.
|
||||||
#if defined(_WIN32_WINNT_WIN8)
|
// This setting can be forced from UnWindows.h
|
||||||
|
#if defined (_WIN32_WINNT_WINBLUE)
|
||||||
|
//Windows 8.1 _WIN32_WINNT_WINBLUE (0x0602)
|
||||||
|
#ifdef _WIN32_WINNT
|
||||||
|
#undef _WIN32_WINNT
|
||||||
|
#endif
|
||||||
|
#define _WIN32_WINNT _WIN32_WINNT_WINBLUE
|
||||||
|
#ifdef NTDDI_VERSION
|
||||||
|
#undef NTDDI_VERSION
|
||||||
|
#endif
|
||||||
|
#define NTDDI_VERSION NTDDI_WINBLUE
|
||||||
|
#elif defined (_WIN32_WINNT_WIN8)
|
||||||
//Windows 8 _WIN32_WINNT_WIN8 (0x0602)
|
//Windows 8 _WIN32_WINNT_WIN8 (0x0602)
|
||||||
#ifdef _WIN32_WINNT
|
#ifdef _WIN32_WINNT
|
||||||
#undef _WIN32_WINNT
|
#undef _WIN32_WINNT
|
||||||
#endif
|
#endif
|
||||||
#define _WIN32_WINNT _WIN32_WINNT_WIN8
|
#define _WIN32_WINNT _WIN32_WINNT_WIN8
|
||||||
#elif defined(_WIN32_WINNT_WIN7)
|
#ifdef NTDDI_VERSION
|
||||||
|
#undef NTDDI_VERSION
|
||||||
|
#endif
|
||||||
|
#define NTDDI_VERSION NTDDI_WIN8
|
||||||
|
#elif defined (_WIN32_WINNT_WIN7)
|
||||||
//Windows 7 _WIN32_WINNT_WIN7 (0x0601)
|
//Windows 7 _WIN32_WINNT_WIN7 (0x0601)
|
||||||
#ifdef _WIN32_WINNT
|
#ifdef _WIN32_WINNT
|
||||||
#undef _WIN32_WINNT
|
#undef _WIN32_WINNT
|
||||||
#endif
|
#endif
|
||||||
#define _WIN32_WINNT _WIN32_WINNT_WIN7
|
#define _WIN32_WINNT _WIN32_WINNT_WIN7
|
||||||
|
#ifndef NTDDI_VERSION
|
||||||
|
#define NTDDI_VERSION NTDDI_WIN7
|
||||||
|
#endif
|
||||||
#elif defined (_WIN32_WINNT_WS08)
|
#elif defined (_WIN32_WINNT_WS08)
|
||||||
//Windows Server 2008 _WIN32_WINNT_WS08 (0x0600)
|
//Windows Server 2008 _WIN32_WINNT_WS08 (0x0600)
|
||||||
#ifdef _WIN32_WINNT
|
#ifdef _WIN32_WINNT
|
||||||
#undef _WIN32_WINNT
|
#undef _WIN32_WINNT
|
||||||
#endif
|
#endif
|
||||||
#define _WIN32_WINNT _WIN32_WINNT_WS08
|
#define _WIN32_WINNT _WIN32_WINNT_WS08
|
||||||
|
#ifndef NTDDI_VERSION
|
||||||
|
#define NTDDI_VERSION NTDDI_WS08
|
||||||
|
#endif
|
||||||
#elif defined (_WIN32_WINNT_VISTA)
|
#elif defined (_WIN32_WINNT_VISTA)
|
||||||
//Windows Vista _WIN32_WINNT_VISTA (0x0600)
|
//Windows Vista _WIN32_WINNT_VISTA (0x0600)
|
||||||
#ifdef _WIN32_WINNT
|
#ifdef _WIN32_WINNT
|
||||||
#undef _WIN32_WINNT
|
#undef _WIN32_WINNT
|
||||||
#endif
|
#endif
|
||||||
#define _WIN32_WINNT _WIN32_WINNT_VISTA
|
#define _WIN32_WINNT _WIN32_WINNT_VISTA
|
||||||
|
#ifndef NTDDI_VERSION
|
||||||
|
#define NTDDI_VERSION NTDDI_VISTA
|
||||||
|
#endif
|
||||||
#elif defined (_WIN32_WINNT_LONGHORN)
|
#elif defined (_WIN32_WINNT_LONGHORN)
|
||||||
//Windows Vista and server 2008 Development _WIN32_WINNT_LONGHORN (0x0600)
|
//Windows Vista and server 2008 Development _WIN32_WINNT_LONGHORN (0x0600)
|
||||||
#ifdef _WIN32_WINNT
|
#ifdef _WIN32_WINNT
|
||||||
@@ -62,12 +86,18 @@
|
|||||||
#undef _WIN32_WINNT
|
#undef _WIN32_WINNT
|
||||||
#endif
|
#endif
|
||||||
#define _WIN32_WINNT _WIN32_WINNT_WS03
|
#define _WIN32_WINNT _WIN32_WINNT_WS03
|
||||||
|
#ifndef NTDDI_VERSION
|
||||||
|
#define NTDDI_VERSION NTDDI_WS03
|
||||||
|
#endif
|
||||||
#elif defined (_WIN32_WINNT_WINXP)
|
#elif defined (_WIN32_WINNT_WINXP)
|
||||||
//Windows Server 2003, Windows XP _WIN32_WINNT_WINXP (0x0501)
|
//Windows Server 2003, Windows XP _WIN32_WINNT_WINXP (0x0501)
|
||||||
#ifdef _WIN32_WINNT
|
#ifdef _WIN32_WINNT
|
||||||
#undef _WIN32_WINNT
|
#undef _WIN32_WINNT
|
||||||
#endif
|
#endif
|
||||||
#define _WIN32_WINNT _WIN32_WINNT_WINXP
|
#define _WIN32_WINNT _WIN32_WINNT_WINXP
|
||||||
|
#ifndef NTDDI_VERSION
|
||||||
|
#define NTDDI_VERSION NTDDI_WINXP
|
||||||
|
#endif
|
||||||
#elif defined (_WIN32_WINNT_WIN2K)
|
#elif defined (_WIN32_WINNT_WIN2K)
|
||||||
//Windows 2000 _WIN32_WINNT_WIN2K (0x0500)
|
//Windows 2000 _WIN32_WINNT_WIN2K (0x0500)
|
||||||
#ifdef _WIN32_WINNT
|
#ifdef _WIN32_WINNT
|
||||||
@@ -75,10 +105,18 @@
|
|||||||
#endif
|
#endif
|
||||||
#define _WIN32_WINNT _WIN32_WINNT_WIN2K
|
#define _WIN32_WINNT _WIN32_WINNT_WIN2K
|
||||||
#elif defined (WINVER)
|
#elif defined (WINVER)
|
||||||
|
// fail back on WINVER
|
||||||
#ifdef _WIN32_WINNT
|
#ifdef _WIN32_WINNT
|
||||||
#undef _WIN32_WINNT
|
#undef _WIN32_WINNT
|
||||||
#endif
|
#endif
|
||||||
#define _WIN32_WINNT WINVER
|
#define _WIN32_WINNT WINVER
|
||||||
|
#elif !defined(_WIN32_WINNT)
|
||||||
|
// last resort = Win XP, SP1 is minimum supported
|
||||||
|
#define _WIN32_WINNT 0x0501
|
||||||
|
#ifdef NTDDI_VERSION
|
||||||
|
#undef NTDDI_VERSION
|
||||||
|
#endif
|
||||||
|
#define NTDDI_VERSION 0x05010100
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -47,11 +47,29 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Microsoft Visual C++ includes copies of the Windows header files
|
||||||
|
// that were current at the time Visual C++ was released.
|
||||||
|
// The Windows header files use macros to indicate which versions
|
||||||
|
// of Windows support many programming elements. Therefore, you must
|
||||||
|
// define these macros to use new functionality introduced in each
|
||||||
|
// major operating system release. (Individual header files may use
|
||||||
|
// different macros; therefore, if compilation problems occur, check
|
||||||
|
// the header file that contains the definition for conditional
|
||||||
|
// definitions.) For more information, see SdkDdkVer.h.
|
||||||
|
|
||||||
#if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0501)
|
#if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0501)
|
||||||
#error Unsupported Windows version.
|
#error Unsupported Windows version.
|
||||||
|
#elif defined(NTDDI_VERSION) && (NTDDI_VERSION < 0x05010100)
|
||||||
|
#error Unsupported Windows version.
|
||||||
#elif !defined(_WIN32_WINNT)
|
#elif !defined(_WIN32_WINNT)
|
||||||
// define minimum supported
|
// Define minimum supported version.
|
||||||
|
// This can be changed, if needed.
|
||||||
|
// Otherwise, the Platform_WIN32.h will do
|
||||||
|
// its best to determine the appropriate values
|
||||||
|
// and may redefine these. See Platform_WIN32.h
|
||||||
|
// for details.
|
||||||
#define _WIN32_WINNT 0x0501
|
#define _WIN32_WINNT 0x0501
|
||||||
|
#define NTDDI_VERSION 0x05010100
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,16 @@ class Net_API NetworkInterface
|
|||||||
/// The class also provides static member functions for
|
/// The class also provides static member functions for
|
||||||
/// enumerating or searching network interfaces and their
|
/// enumerating or searching network interfaces and their
|
||||||
/// respective configuration values.
|
/// respective configuration values.
|
||||||
|
///
|
||||||
|
/// On Windows, detection capabilities vary depending on the
|
||||||
|
/// OS version/service pack. Although the best effort is made
|
||||||
|
/// not to attempt access to non-existent features through a
|
||||||
|
/// combination of compile/runtime checks, when running binaries
|
||||||
|
/// compiled on a newer version of the OS on an older one
|
||||||
|
/// problems may occur; if possible, it is best to run
|
||||||
|
/// binaries on the OS version where they were compiled.
|
||||||
|
/// This particularly applies to OS versions older than Vista
|
||||||
|
/// and XP.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::vector<NetworkInterface> List;
|
typedef std::vector<NetworkInterface> List;
|
||||||
|
|||||||
@@ -966,11 +966,66 @@ NetworkInterface::Type fromNative(DWORD type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IPAddress subnetMaskForInterface(const std::string& name, bool isLoopback)
|
||||||
|
{
|
||||||
|
if (isLoopback)
|
||||||
|
{
|
||||||
|
return IPAddress::parse("255.0.0.0");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string subKey("SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces\\");
|
||||||
|
subKey += name;
|
||||||
|
std::string netmask;
|
||||||
|
HKEY hKey;
|
||||||
|
#if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING)
|
||||||
|
std::wstring usubKey;
|
||||||
|
Poco::UnicodeConverter::toUTF16(subKey, usubKey);
|
||||||
|
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, usubKey.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
|
||||||
|
return IPAddress();
|
||||||
|
wchar_t unetmask[16];
|
||||||
|
DWORD size = sizeof(unetmask);
|
||||||
|
if (RegQueryValueExW(hKey, L"DhcpSubnetMask", NULL, NULL, (LPBYTE)&unetmask, &size) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if (RegQueryValueExW(hKey, L"SubnetMask", NULL, NULL, (LPBYTE)&unetmask, &size) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
return IPAddress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Poco::UnicodeConverter::toUTF8(unetmask, netmask);
|
||||||
|
#else
|
||||||
|
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, subKey.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
|
||||||
|
return IPAddress();
|
||||||
|
char unetmask[16];
|
||||||
|
DWORD size = sizeof(unetmask);
|
||||||
|
if (RegQueryValueExA(hKey, "DhcpSubnetMask", NULL, NULL, (LPBYTE)&unetmask, &size) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if (RegQueryValueExA(hKey, "SubnetMask", NULL, NULL, (LPBYTE)&unetmask, &size) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
return IPAddress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
netmask = unetmask;
|
||||||
|
#endif
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
return IPAddress::parse(netmask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} /// namespace
|
} /// namespace
|
||||||
|
|
||||||
|
|
||||||
NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
|
NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
|
||||||
{
|
{
|
||||||
|
OSVERSIONINFO osvi;
|
||||||
|
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
|
||||||
|
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||||
|
GetVersionEx(&osvi);
|
||||||
|
|
||||||
FastMutex::ScopedLock lock(_mutex);
|
FastMutex::ScopedLock lock(_mutex);
|
||||||
Map result;
|
Map result;
|
||||||
ULONG outBufLen = 16384;
|
ULONG outBufLen = 16384;
|
||||||
@@ -1010,15 +1065,32 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
|
|||||||
unsigned ifIndex = 0;
|
unsigned ifIndex = 0;
|
||||||
|
|
||||||
#if defined(POCO_HAVE_IPv6)
|
#if defined(POCO_HAVE_IPv6)
|
||||||
#if (_WIN32_WINNT >= 0x600) && defined (IP_ADAPTER_IPV6_ENABLED)
|
#if (_WIN32_WINNT >= 0x0501) && (NTDDI_VERSION >= 0x05010100) // Win XP SP1
|
||||||
if (pAddress->Flags & IP_ADAPTER_IPV6_ENABLED) ifIndex = pAddress->Ipv6IfIndex;
|
#if defined (IP_ADAPTER_IPV6_ENABLED) // Vista
|
||||||
#else
|
if ((pAddress->Flags & IP_ADAPTER_IPV6_ENABLED) &&
|
||||||
|
(osvi.dwMajorVersion >= 5) &&
|
||||||
|
(osvi.dwMinorVersion >= 1) &&
|
||||||
|
(osvi.dwBuildNumber >=1))
|
||||||
|
{
|
||||||
ifIndex = pAddress->Ipv6IfIndex;
|
ifIndex = pAddress->Ipv6IfIndex;
|
||||||
#endif
|
}
|
||||||
#endif
|
#else // !defined(IP_ADAPTER_IPV6_ENABLED)
|
||||||
#if (_WIN32_WINNT >= 0x600) && defined (IP_ADAPTER_IPV4_ENABLED)
|
if ((osvi.dwMajorVersion >= 5) &&
|
||||||
if (pAddress->Flags & IP_ADAPTER_IPV4_ENABLED) ifIndex = pAddress->IfIndex;
|
(osvi.dwMinorVersion >= 1) &&
|
||||||
#else
|
(osvi.dwBuildNumber >= 0))
|
||||||
|
{
|
||||||
|
ifIndex = pAddress->Ipv6IfIndex;
|
||||||
|
}
|
||||||
|
#endif // defined(IP_ADAPTER_IPV6_ENABLED)
|
||||||
|
#endif // (_WIN32_WINNT >= 0x0501) && (NTDDI_VERSION >= 0x05010100)
|
||||||
|
#endif // POCO_HAVE_IPv6
|
||||||
|
|
||||||
|
#if defined (IP_ADAPTER_IPV4_ENABLED)
|
||||||
|
if (pAddress->Flags & IP_ADAPTER_IPV4_ENABLED)
|
||||||
|
{
|
||||||
|
ifIndex = pAddress->IfIndex;
|
||||||
|
}
|
||||||
|
#else // !IP_ADAPTER_IPV4_ENABLED
|
||||||
ifIndex = pAddress->IfIndex;
|
ifIndex = pAddress->IfIndex;
|
||||||
#endif
|
#endif
|
||||||
if (ifIndex == 0) continue;
|
if (ifIndex == 0) continue;
|
||||||
@@ -1054,7 +1126,12 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
|
|||||||
ifIt->second.impl().setMTU(pAddress->Mtu);
|
ifIt->second.impl().setMTU(pAddress->Mtu);
|
||||||
ifIt->second.impl().setUp(pAddress->OperStatus == IfOperStatusUp);
|
ifIt->second.impl().setUp(pAddress->OperStatus == IfOperStatusUp);
|
||||||
#if (_WIN32_WINNT >= 0x0600) // Vista and newer only
|
#if (_WIN32_WINNT >= 0x0600) // Vista and newer only
|
||||||
|
if ((osvi.dwMajorVersion >= 6) &&
|
||||||
|
(osvi.dwMinorVersion >= 0) &&
|
||||||
|
(osvi.dwBuildNumber >= 0))
|
||||||
|
{
|
||||||
ifIt->second.impl().setRunning(pAddress->ReceiveLinkSpeed > 0 || pAddress->TransmitLinkSpeed > 0);
|
ifIt->second.impl().setRunning(pAddress->ReceiveLinkSpeed > 0 || pAddress->TransmitLinkSpeed > 0);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
ifIt->second.impl().setType(fromNative(pAddress->IfType));
|
ifIt->second.impl().setType(fromNative(pAddress->IfType));
|
||||||
if (pAddress->PhysicalAddressLength)
|
if (pAddress->PhysicalAddressLength)
|
||||||
@@ -1077,10 +1154,11 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
|
|||||||
// On Windows, a valid broadcast address will be all 1's (== address | ~subnetMask); additionaly, on pre-Vista versions of
|
// On Windows, a valid broadcast address will be all 1's (== address | ~subnetMask); additionaly, on pre-Vista versions of
|
||||||
// OS, master address structure does not contain member for prefix length; we go an extra mile here in order to make sure
|
// OS, master address structure does not contain member for prefix length; we go an extra mile here in order to make sure
|
||||||
// we reflect the actual values held by system and protect against misconfiguration (e.g. bad DHCP config entry)
|
// we reflect the actual values held by system and protect against misconfiguration (e.g. bad DHCP config entry)
|
||||||
#if (_WIN32_WINNT >= 0x0600) // Vista and newer
|
#if (_WIN32_WINNT >= 0x0501) && (NTDDI_VERSION >= 0x05010100) // Win XP SP1
|
||||||
|
#if (_WIN32_WINNT >= 0x0600) // Vista and newer
|
||||||
UINT8 prefixLength = pUniAddr->OnLinkPrefixLength;
|
UINT8 prefixLength = pUniAddr->OnLinkPrefixLength;
|
||||||
broadcastAddress = getBroadcastAddress(pAddress->FirstPrefix, address);
|
broadcastAddress = getBroadcastAddress(pAddress->FirstPrefix, address);
|
||||||
#else
|
#else // _WIN32_WINNT < 0x0600
|
||||||
ULONG prefixLength = 0;
|
ULONG prefixLength = 0;
|
||||||
broadcastAddress = getBroadcastAddress(pAddress->FirstPrefix, address, &prefixLength);
|
broadcastAddress = getBroadcastAddress(pAddress->FirstPrefix, address, &prefixLength);
|
||||||
// if previous call did not do it, make last-ditch attempt for prefix and broadcast
|
// if previous call did not do it, make last-ditch attempt for prefix and broadcast
|
||||||
@@ -1093,8 +1171,22 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
|
|||||||
IPAddress host(mask & address);
|
IPAddress host(mask & address);
|
||||||
broadcastAddress = host | ~mask;
|
broadcastAddress = host | ~mask;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // _WIN32_WINNT >= 0x0600
|
||||||
subnetMask = prefixLength ? IPAddress(prefixLength, IPAddress::IPv4) : IPAddress();
|
#endif // (_WIN32_WINNT >= 0x0501) && (NTDDI_VERSION >= 0x05010100)
|
||||||
|
if (prefixLength)
|
||||||
|
{
|
||||||
|
subnetMask = IPAddress(prefixLength, IPAddress::IPv4);
|
||||||
|
}
|
||||||
|
else // if all of the above fails, look up the subnet mask in the registry
|
||||||
|
{
|
||||||
|
address = IPAddress(&reinterpret_cast<struct sockaddr_in*>(pUniAddr->Address.lpSockaddr)->sin_addr, sizeof(in_addr));
|
||||||
|
subnetMask = subnetMaskForInterface(name, address.isLoopback());
|
||||||
|
if (!address.isLoopback())
|
||||||
|
{
|
||||||
|
broadcastAddress = address;
|
||||||
|
broadcastAddress.mask(subnetMask, IPAddress::broadcast());
|
||||||
|
}
|
||||||
|
}
|
||||||
ifIt->second.addAddress(address, subnetMask, broadcastAddress);
|
ifIt->second.addAddress(address, subnetMask, broadcastAddress);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user