mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-09 19:17:38 +01:00
Implement GetAdaptersAddresses API (#4419)
* Upgrade from GetAdaptersInfo to GetAdaptersAddresses API. The code has been swapped back to a buffer of bytes because the data structure built by GetAdaptersAddresses is a linked list and the returned size is not a multiple of the IP_ADAPTERS_ADDRESSES struct. * Adding back Poco/UnWindows.h * Undoing indents.
This commit is contained in:
parent
c2ee0ebd0d
commit
727db08000
@ -16,15 +16,14 @@
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/UnicodeConverter.h"
|
||||
#include "Poco/Buffer.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include "Poco/UnWindows.h"
|
||||
#include <winsock2.h>
|
||||
#include <wincrypt.h>
|
||||
#include <ws2ipdef.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable:4996) // deprecation warnings
|
||||
@ -95,7 +94,7 @@ std::string EnvironmentImpl::osDisplayNameImpl()
|
||||
{
|
||||
OSVERSIONINFOEX vi; // OSVERSIONINFOEX is supported starting at Windows 2000
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
if (GetVersionEx((OSVERSIONINFO*) &vi) == 0) throw SystemException("Cannot get OS version information");
|
||||
if (GetVersionEx((OSVERSIONINFO*)&vi) == 0) throw SystemException("Cannot get OS version information");
|
||||
switch (vi.dwMajorVersion)
|
||||
{
|
||||
case 10:
|
||||
@ -203,56 +202,56 @@ void EnvironmentImpl::nodeIdImpl(NodeId& id)
|
||||
{
|
||||
std::memset(&id, 0, sizeof(id));
|
||||
|
||||
auto pAdapterInfo = std::make_unique<IP_ADAPTER_INFO[]>(1);
|
||||
ULONG len = sizeof(IP_ADAPTER_INFO);
|
||||
// Preallocate buffer for some adapters to avoid calling
|
||||
// GetAdaptersAddresses multiple times.
|
||||
static constexpr int STARTING_BUFFER_SIZE = 20000;
|
||||
|
||||
// Make an initial call to GetAdaptersInfo to get
|
||||
// the necessary size into len
|
||||
const DWORD rc = GetAdaptersInfo(pAdapterInfo.get(), &len);
|
||||
auto buffer = std::make_unique<unsigned char[]>(STARTING_BUFFER_SIZE);
|
||||
ULONG len = STARTING_BUFFER_SIZE;
|
||||
|
||||
// use GAA_FLAG_SKIP_DNS_SERVER because we're only interested in the physical addresses of the interfaces
|
||||
const DWORD rc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_DNS_SERVER, nullptr, reinterpret_cast<IP_ADAPTER_ADDRESSES*>(buffer.get()), &len);
|
||||
|
||||
if (rc == ERROR_BUFFER_OVERFLOW)
|
||||
{
|
||||
pAdapterInfo = std::make_unique<IP_ADAPTER_INFO[]>(len / sizeof(IP_ADAPTER_INFO));
|
||||
// Buffer is not large enough: reallocate and retry.
|
||||
buffer = std::make_unique<unsigned char[]>(len);
|
||||
|
||||
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_DNS_SERVER, nullptr, reinterpret_cast<IP_ADAPTER_ADDRESSES*>(buffer.get()), &len) != ERROR_SUCCESS)
|
||||
{
|
||||
throw SystemException("cannot get network adapter list");
|
||||
}
|
||||
}
|
||||
else if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
throw SystemException("cannot get network adapter list");
|
||||
}
|
||||
|
||||
if (GetAdaptersInfo(pAdapterInfo.get(), &len) == NO_ERROR)
|
||||
IP_ADAPTER_ADDRESSES* pAdapter = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(buffer.get());
|
||||
while (pAdapter)
|
||||
{
|
||||
IP_ADAPTER_INFO* pAdapter = pAdapterInfo.get();
|
||||
|
||||
while (pAdapter)
|
||||
if (pAdapter->IfType == IF_TYPE_ETHERNET_CSMACD && pAdapter->PhysicalAddressLength == sizeof(id))
|
||||
{
|
||||
if (pAdapter->Type == MIB_IF_TYPE_ETHERNET && pAdapter->AddressLength == sizeof(id))
|
||||
{
|
||||
std::memcpy(&id, pAdapter->Address, pAdapter->AddressLength);
|
||||
std::memcpy(&id, pAdapter->PhysicalAddress, pAdapter->PhysicalAddressLength);
|
||||
|
||||
// found an ethernet adapter, we can return now
|
||||
return;
|
||||
}
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
|
||||
// if an ethernet adapter was not found, search for a wifi adapter
|
||||
pAdapter = pAdapterInfo.get();
|
||||
|
||||
while (pAdapter)
|
||||
{
|
||||
if (pAdapter->Type == IF_TYPE_IEEE80211 && pAdapter->AddressLength == sizeof(id))
|
||||
{
|
||||
std::memcpy(&id, pAdapter->Address, pAdapter->AddressLength);
|
||||
|
||||
// found a wifi adapter, we can return now
|
||||
return;
|
||||
}
|
||||
pAdapter = pAdapter->Next;
|
||||
// found an ethernet adapter, we can return now
|
||||
return;
|
||||
}
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
else
|
||||
|
||||
// if an ethernet adapter was not found, search for a wifi adapter
|
||||
pAdapter = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(buffer.get());
|
||||
while (pAdapter)
|
||||
{
|
||||
throw SystemException("cannot get network adapter list");
|
||||
if (pAdapter->IfType == IF_TYPE_IEEE80211 && pAdapter->PhysicalAddressLength == sizeof(id))
|
||||
{
|
||||
std::memcpy(&id, pAdapter->PhysicalAddress, pAdapter->PhysicalAddressLength);
|
||||
|
||||
// found a wifi adapter, we can return now
|
||||
return;
|
||||
}
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
|
||||
// ethernet and wifi adapters not found, fail the search
|
||||
|
Loading…
Reference in New Issue
Block a user