Changes to the mechanics of obtaining data about network adapters

This commit is contained in:
Fedotov Anton 2021-11-24 03:00:27 +03:00
parent 90a92bea1b
commit 3424068993
2 changed files with 177 additions and 369 deletions

View file

@ -1,84 +1,102 @@
#pragma once #pragma once
#include <list>
#include <vector> #include <vector>
#include <string> #include <string>
#include <tuple> #include <tuple>
//#include <thread> #include <memory>
namespace adpinfo{ namespace adpinfo{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static bool is_string_equal(const std::string &lhs, const std::string &rhs){ //static bool is_string_equal(const std::string &lhs, const std::string &rhs){
if (lhs.find(rhs) != std::string::npos) // if (lhs.find(rhs) != std::string::npos)
return true; // return true;
return false; // return false;
} //}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// {false,""} - no error
// {true,"descr"} - error with description
using RET_TYPE = std::tuple<bool, std::string>; using RET_TYPE = std::tuple<bool, std::string>;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typedef struct adapter{ //class Adapter{
std::string name{}; //private:
std::string mac{}; // std::string name{};
std::list<std::string> dns_address{}; // std::string descr{};
std::list<std::tuple<std::string,std::string>> ip_mask_V4{}; // std::string current_ip_address_v4{};
std::list<std::string> gateWay{}; // std::string maskv4{};
std::string dhcp_server_adress{}; // std::vector<std::string> dns_address{};
std::string system_gateway{}; // default system gatewasy for ip 0.0.0.0 //public:
// explicit Adapter() = default;
// ~Adapter() = default;
bool operator==(const adapter& rhs) { // void set_name(std::string_view);
if (!is_string_equal(name, rhs.name)) // std::string_view get_name()const;
return false;
if (!is_string_equal(mac, rhs.mac))
return false;
if (dns_address != rhs.dns_address)
return false;
if (ip_mask_V4 != rhs.ip_mask_V4)
return false;
if (gateWay != rhs.gateWay)
return false;
if (!is_string_equal(dhcp_server_adress, rhs.dhcp_server_adress))
return false;
if (!is_string_equal(system_gateway, rhs.system_gateway))
return false;
return true; // void set_description(std::string_view);
} // std::string_view get_description()const;
}adapter;
// void set_mac(std::string_view);
// std::string_view get_mac()const;
//// bool operator==(const adapter& rhs) {
//// if (!is_string_equal(name, rhs.name))
//// return false;
//// if (!is_string_equal(mac, rhs.mac))
//// return false;
//// if (dns_address != rhs.dns_address)
//// return false;
//// return true;
//// }
//}adapter;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* /*
* The object uses for collect the information about active network adapters/interfaces * The object uses for collect the information about active network adapters/interfaces
* NetAdpInfo adi; * QString m_routeGateway;
* //Each call to the collect function fills QString m_vpnLocalAddress;
* //the _adapters array with information about active network connections (network address, gateways, ip addresses, etc.). QString m_vpnGateway;
* adi.collect();
*
* //We get the adapter that appeared after the penultimate call to the collect function
* adi.get_differents()
*
* //We get the adapter that appeared after the penultimate call to the collect function and
* //have a concrete system name
*get_adapter_info_by_name
*/ */
class NetAdpInfo final{ class NetAdpInfo final{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class Adapter{
std::string name{};
std::string descr{};
std::string route{};
std::string address{};
std::string gateway{};
public:
explicit Adapter() = default;
~Adapter() = default;
bool init_error{false}; void set_name(std::string_view);
std::vector<adapter>_adapters{}; std::string_view get_name()const;
adapter _adapter_in_use{}; void set_description(std::string_view);
std::string_view get_description()const;
void set_route_gateway(std::string_view);
std::string_view get_route_gateway()const;
void set_local_address(std::string_view);
std::string_view get_local_address()const;
void set_local_gateway(std::string_view);
std::string_view get_local_gateway()const;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int16_t _index_of_adapter{};
std::vector<std::shared_ptr<Adapter>>_adapters{};
RET_TYPE collect_adapters_data();
public: public:
explicit NetAdpInfo(); explicit NetAdpInfo() = default;
~NetAdpInfo(); ~NetAdpInfo() = default;
RET_TYPE get_adapter_infor(std::string_view );
std::string_view get_adapter_route_gateway()const;
std::string_view get_adapter_local_address()const;
std::string_view get_adapter_local_gateway()const;
//collect all adapter data //static std::string get_system_route();
RET_TYPE collect();
//return all adapter data
std::list<adapter> get_adapters()const;
//get the diferent between the first call collect and the next call collect
adapter get_differents()const;
//get the adapter by name
adapter get_adapter_info_by_name(const std::string &)const;
}; };
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} } //end namespace

View file

@ -7,14 +7,14 @@
#include <cassert> #include <cassert>
#include <windows.h> #include <windows.h>
#include <atlbase.h> //#include <atlbase.h>
#include <wbemcli.h> //#include <wbemcli.h>
#include <comutil.h> //#include <comutil.h>
#include <iphlpapi.h> #include <iphlpapi.h>
#pragma comment(lib, "iphlpapi.lib") #pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "wbemuuid.lib") //#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "comsuppw.lib") //#pragma comment(lib, "comsuppw.lib")
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static std::string convert_wide_to_ansi(const std::wstring& widestring) { static std::string convert_wide_to_ansi(const std::wstring& widestring) {
@ -65,8 +65,8 @@ static std::string get_route_gateway()
free(pIpForwardTable); free(pIpForwardTable);
return {"getIpForwardTable failed"}; return {"getIpForwardTable failed"};
} }
const auto end = pIpForwardTable->dwNumEntries; const DWORD end = pIpForwardTable->dwNumEntries;
for (auto i = 0; i < end; i++) { for (DWORD i = 0; i < end; i++) {
if (pIpForwardTable->table[i].dwForwardDest == 0) { if (pIpForwardTable->table[i].dwForwardDest == 0) {
// We have found the default gateway. // We have found the default gateway.
IpAddr.S_un.S_addr = IpAddr.S_un.S_addr =
@ -82,321 +82,111 @@ static std::string get_route_gateway()
return route_gateway; return route_gateway;
} }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
namespace amnezia_wmi { namespace adpinfo {
// prepare WMI object void NetAdpInfo::Adapter::set_name(std::string_view value){
static adpinfo::RET_TYPE prepare_WMI(CComPtr<IWbemLocator>&pLoc, name = value;
CComPtr<IWbemServices> &pSvc, }
CComPtr<IEnumWbemClassObject>&pEnumerator){ std::string_view NetAdpInfo::Adapter::get_name()const{
HRESULT result;
{
result = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *)&pLoc);
if (FAILED(result))
{
// TODO: add GetLastError description
return std::make_tuple(true, "CoCreateInstance failed");
}
}
{ return name;
result = pLoc->ConnectServer( }
_bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace void NetAdpInfo::Adapter::set_description(std::string_view value){
NULL, // User name. NULL = current user descr = value;
NULL, // User password. NULL = current }
0, // Locale. NULL indicates current std::string_view NetAdpInfo::Adapter::get_description()const{
NULL, // Security flags. return descr;
0, // Authority (for example, Kerberos) }
0, // Context object void NetAdpInfo::Adapter::set_route_gateway(std::string_view value){
&pSvc // pointer to IWbemServices proxy route = value;
); }
if (FAILED(result)) std::string_view NetAdpInfo::Adapter::get_route_gateway()const{
{ return route;
// TODO: add GetLastError description
return std::make_tuple(true, "ConnectServer failed");
}
}
{
result = CoSetProxyBlanket(
pSvc, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(result)) }
{ void NetAdpInfo::Adapter::set_local_address(std::string_view value){
// TODO: add GetLastError description address = value;
return std::make_tuple(true, "CoSetProxyBlanket failed"); }
} std::string_view NetAdpInfo::Adapter::get_local_address()const{
} return address;
{ }
result = pSvc->ExecQuery( void NetAdpInfo::Adapter::set_local_gateway(std::string_view value){
bstr_t("WQL"), gateway = value;
bstr_t("Select * from Win32_NetworkAdapterConfiguration WHERE IPEnabled = true"), }
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, std::string_view NetAdpInfo::Adapter::get_local_gateway()const{
NULL, return gateway;
&pEnumerator);
if (FAILED(result))
{
// TODO: add GetLastError description
return std::make_tuple(true, "ExecQuery failed");
}
}
return std::make_tuple(false,"");
} }
// get one WMI parametr from object RET_TYPE NetAdpInfo::collect_adapters_data(){
static std::string getValue(IWbemClassObject* pclsObj, const std::wstring& ParamName) {
VARIANT vtProp;
auto result = pclsObj->Get(ParamName.c_str(), 0, &vtProp, 0, 0);
if (FAILED(result)) {
VariantClear(&vtProp);
return {};
}
if (vtProp.vt == VT_EMPTY || vtProp.vt == VT_NULL) {
VariantClear(&vtProp);
return {};
}
const std::string &retValue = convert_wide_to_ansi(vtProp.bstrVal) ;
VariantClear(&vtProp);
return retValue;
}
// get the array of WMI parametrs from object
static std::vector<std::string>getValues(IWbemClassObject* pclsObj, const std::wstring& ParamName) {
VARIANT vtProp;
std::vector<std::string>_values{};
auto result = pclsObj->Get(ParamName.c_str(), 0, &vtProp, 0, 0);
if (FAILED(result)) {
VariantClear(&vtProp);
return std::vector<std::string>();
}
if (vtProp.vt == (VT_ARRAY | VT_BSTR)) {
SAFEARRAY* pSafeArray{ V_ARRAY(&vtProp) };
BSTR elm;
long size = pSafeArray->rgsabound[0].cElements;
long i = 0;
for (i = 0; i < size; ++i) {
SafeArrayGetElement(pSafeArray, &i, (void*)&elm);
const std::wstring& widestring = elm;
const std::string& string_str = convert_wide_to_ansi(widestring);
_values.emplace_back(string_str);
}
VariantClear(&vtProp);
return _values;
}
else {
VariantClear(&vtProp);
return std::vector<std::string>();
}
}
}
namespace adpinfo{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NetAdpInfo::NetAdpInfo()
{
_adapters.clear(); _adapters.clear();
SetLastError(0); std::vector<BYTE> buffer{};
HRESULT result = CoInitializeEx(0, COINIT_MULTITHREADED); IP_ADAPTER_INFO *adapter_info{nullptr};
if (FAILED(result)) DWORD result{ERROR_BUFFER_OVERFLOW};
{ ULONG buffer_len = sizeof(IP_ADAPTER_INFO) * 3;
init_error = true; while (result == ERROR_BUFFER_OVERFLOW){
return; buffer.resize(buffer_len);
adapter_info = reinterpret_cast<IP_ADAPTER_INFO*>(&buffer[0]);
result = GetAdaptersInfo(adapter_info, &buffer_len);
if (result == ERROR_NO_DATA){
return {true, "GetAdaptersInfo return ERROR_NO_DATA"};
}
}//end while
if (result != NO_ERROR){
const std::string &error = "GetAdaptersInfo failed :" + std::to_string(result);
return {true, error};
} }
IP_ADAPTER_INFO *adapter_iterator = adapter_info;
CoInitializeSecurity( while(adapter_iterator){
NULL, std::shared_ptr<Adapter>_tmp{std::make_shared<Adapter>()};
-1, // COM authentication _tmp->set_name(adapter_iterator->AdapterName);
NULL, // Authentication services _tmp->set_description(adapter_iterator->Description);
NULL, // Reserved _tmp->set_local_address(adapter_iterator->IpAddressList.IpAddress.String);
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication _tmp->set_local_gateway(adapter_iterator->GatewayList.IpAddress.String);
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation _tmp->set_route_gateway(get_route_gateway());
NULL, // Authentication info _adapters.emplace_back(_tmp);
EOAC_NONE, // Additional capabilities adapter_iterator = adapter_iterator->Next;
NULL // Reserved }
); return {false, ""};
// if (result != S_OK || result != RPC_E_TOO_LATE)
// {
// // TODO: add GetLastError description
// //_current_error = std::make_tuple(true, "CoInitializeSecurity failed");
// //printf("%d\r\n", __LINE__);
// qDebug()<<GetLastError()<<"result= "<<result;
// init_error = true;
// return;
// }
collect();
} }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NetAdpInfo::~NetAdpInfo()
{
CoUninitialize();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RET_TYPE NetAdpInfo::collect()
{
if (init_error){
return std::make_tuple(true,"Initial error");
}
std::vector<adapter>_adapters_next;
_adapters_next.clear();
if (_adapters.size()>0){
std::copy(_adapters.begin(), _adapters.end(), std::back_inserter(_adapters_next));
_adapters.clear();
}
CComPtr<IWbemLocator> pLoc{nullptr}; RET_TYPE NetAdpInfo::get_adapter_infor(std::string_view _adapter_name){
CComPtr<IWbemServices> pSvc{nullptr};
CComPtr<IEnumWbemClassObject> pEnumerator{nullptr}; _index_of_adapter = -1;
auto wmi_init {amnezia_wmi::prepare_WMI(pLoc, pSvc, pEnumerator)}; const auto result{collect_adapters_data()};
if (std::get<0>(wmi_init)){ if (std::get<0>(result) == true){
return wmi_init; _index_of_adapter = -1;
return result;
} }
CComPtr<IWbemClassObject> pclsObj{nullptr}; const int16_t &len = static_cast<int16_t>(_adapters.size());
ULONG uReturn = 0; for (auto i = 0; i< len; ++i){
{ auto adap_name = _adapters[i]->get_name();
// get data from query auto adap_desc = _adapters[i]->get_description();
while (pEnumerator) if (adap_name.find(_adapter_name) != std::string::npos || adap_desc.find(_adapter_name) != std::string::npos){
{ _index_of_adapter = i;
HRESULT result; return {false, ""};
result = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (FAILED(result)){
break;
}
if (uReturn == 0) {
break;
}
auto adap_name = amnezia_wmi::getValue(pclsObj, L"Description");
auto adap_mac = amnezia_wmi::getValue(pclsObj, L"MACAddress");
auto adap_dns = amnezia_wmi::getValues(pclsObj, L"DNSServerSearchOrder");
auto adap_ips_address = amnezia_wmi::getValues(pclsObj, L"IPAddress");
auto adap_ips_mask = amnezia_wmi::getValues(pclsObj, L"IPSubnet");
auto adap_gateway = amnezia_wmi::getValues(pclsObj, L"DefaultIPGateway");
auto adap_gate = amnezia_wmi::getValue(pclsObj, L"DHCPServer");
{
adapter ainfo;
ainfo.name = adap_name;
ainfo.mac = adap_mac;
ainfo.dns_address = std::list<std::string>(adap_dns.begin(), adap_dns.end());
ainfo.gateWay = std::list<std::string>(adap_gateway.begin(), adap_gateway.end());
ainfo.dhcp_server_adress = adap_gate;
if (ainfo.gateWay.size() == 0)
ainfo.gateWay.push_back(get_route_gateway());
const auto ipv4_address_size = adap_ips_address.size();
const auto ipv4_mask_size = adap_ips_mask.size();
assert(ipv4_address_size == ipv4_mask_size);
for (auto i = 0; i < ipv4_address_size; ++i) {
ainfo.ip_mask_V4.emplace_back(std::make_tuple(adap_ips_address.at(i), adap_ips_mask.at(i)));
}
_adapters.emplace_back(ainfo);
}
pclsObj.Release();
pclsObj = nullptr;
} }
} }
if (_adapters_next.size()>0){ return {true, "adapters no founded"};
const auto newsize = _adapters.size(); }
const auto oldsize = _adapters_next.size();
if (newsize>oldsize){ std::string_view NetAdpInfo::get_adapter_route_gateway()const{
auto fv = _adapters; if (_index_of_adapter < 0)
for (int i = 0; i< newsize ;++i){ return "error adapter index";
if (i < oldsize){ return _adapters.at(_index_of_adapter)->get_route_gateway();
if (_adapters[i] == _adapters_next[i]){ }
fv.erase(fv.begin()+i); std::string_view NetAdpInfo::get_adapter_local_address()const{
continue; if (_index_of_adapter < 0)
} return "error adapter index";
} return _adapters.at(_index_of_adapter)->get_local_address();
} }
_adapter_in_use = *fv.begin(); std::string_view NetAdpInfo::get_adapter_local_gateway()const{
} if (_index_of_adapter < 0)
} return "error adapter index";
return std::make_tuple(false, ""); return _adapters.at(_index_of_adapter)->get_local_gateway();
} }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
std::list<adapter> NetAdpInfo::get_adapters()const { //std::string NetAdpInfo::get_system_route(){
return std::list<adapter>(_adapters.begin(), _adapters.end()); // return get_route_gateway();
} //}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
adapter NetAdpInfo::get_differents()const{ }// end namespace
return _adapter_in_use;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
adapter NetAdpInfo::get_adapter_info_by_name(const std::string &_adap_name)const{
adapter ainfo;
if (init_error){
return ainfo;
}
CComPtr<IWbemLocator> pLoc{nullptr};
CComPtr<IWbemServices> pSvc{nullptr};
CComPtr<IEnumWbemClassObject> pEnumerator{nullptr};
auto wmi_init = amnezia_wmi::prepare_WMI(pLoc, pSvc, pEnumerator);
if (std::get<0>(wmi_init)){
return ainfo;
}
CComPtr<IWbemClassObject> pclsObj{nullptr};
ULONG uReturn = 0;
{
// get data from query
while (pEnumerator)
{
HRESULT result;
result = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (FAILED(result)){
break;
}
if (uReturn == 0) {
break;
}
auto adap_name = amnezia_wmi::getValue(pclsObj, L"Description"); // can take Caption
auto adap_mac = amnezia_wmi::getValue(pclsObj, L"MACAddress");
auto adap_dns = amnezia_wmi::getValues(pclsObj, L"DNSServerSearchOrder");
auto adap_ips_address = amnezia_wmi::getValues(pclsObj, L"IPAddress");
auto adap_ips_mask = amnezia_wmi::getValues(pclsObj, L"IPSubnet");
auto adap_gateway = amnezia_wmi::getValues(pclsObj, L"DefaultIPGateway");
auto adap_gate = amnezia_wmi::getValue(pclsObj, L"DHCPServer");
{
adapter ainfoc;
ainfoc.system_gateway = get_route_gateway();
ainfoc.name = adap_name;
ainfoc.mac = adap_mac;
ainfoc.dns_address = std::list<std::string>(adap_dns.begin(), adap_dns.end());
ainfoc.gateWay = std::list<std::string>(adap_gateway.begin(), adap_gateway.end());
ainfoc.dhcp_server_adress = adap_gate;
if (ainfoc.gateWay.size() == 0)
ainfoc.gateWay.push_back(get_route_gateway());
const auto ipv4_address_size = adap_ips_address.size();
const auto ipv4_mask_size = adap_ips_mask.size();
assert(ipv4_address_size == ipv4_mask_size);
for (auto i = 0; i < ipv4_address_size; ++i) {
ainfoc.ip_mask_V4.emplace_back(std::make_tuple(adap_ips_address.at(i), adap_ips_mask.at(i)));
}
qDebug()<<"Current adapter name is ["<<ainfoc.name.data()<<"] but we search for ["<<_adap_name.data()<<"]";
if ( ainfoc.name.find(_adap_name) != std::string::npos ){
qDebug()<<"Find adapter with name = "<<_adap_name.data();
pclsObj.Release();
pclsObj = nullptr;
return ainfoc;
}
}
pclsObj.Release();
pclsObj = nullptr;
}
}
return ainfo;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}