winrt: Also list current profile in QNetworkInterface::allInterfaces

GetConnectionProfiles does not list the current profile, so
"allInterfaces" also has to use GetInternetConnectionProfile.

Task-number: QTBUG-49121
Change-Id: I80a3ea1bfddfe502c84376ca90a7e1fe5d3020c3
Reviewed-by: Samuel Nevala <samuel.nevala@intopalo.com>
Reviewed-by: Andrew Knight <andrew.knight@intopalo.com>
bb10
Oliver Wolff 2015-10-29 10:17:18 +01:00
parent 20208225ee
commit 702a98bfb0
1 changed files with 93 additions and 51 deletions

View File

@ -36,6 +36,8 @@
#ifndef QT_NO_NETWORKINTERFACE
#include <qfunctions_winrt.h>
#include <wrl.h>
#include <windows.foundation.h>
#include <windows.foundation.collections.h>
@ -59,6 +61,54 @@ struct HostNameInfo {
QString address;
};
static QNetworkInterfacePrivate *interfaceFromProfile(IConnectionProfile *profile, QList<HostNameInfo> *hostList)
{
if (!profile)
return 0;
QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate;
NetworkConnectivityLevel connectivityLevel;
HRESULT hr = profile->GetNetworkConnectivityLevel(&connectivityLevel);
Q_ASSERT_SUCCEEDED(hr);
if (connectivityLevel != NetworkConnectivityLevel_None)
iface->flags = QNetworkInterface::IsUp | QNetworkInterface::IsRunning;
ComPtr<INetworkAdapter> adapter;
hr = profile->get_NetworkAdapter(&adapter);
Q_ASSERT_SUCCEEDED(hr);
UINT32 type;
hr = adapter->get_IanaInterfaceType(&type);
Q_ASSERT_SUCCEEDED(hr);
if (type == 23)
iface->flags |= QNetworkInterface::IsPointToPoint;
GUID id;
hr = adapter->get_NetworkAdapterId(&id);
Q_ASSERT_SUCCEEDED(hr);
OLECHAR adapterName[39]={0};
StringFromGUID2(id, adapterName, 39);
iface->name = QString::fromWCharArray(adapterName);
// According to http://stackoverflow.com/questions/12936193/how-unique-is-the-ethernet-network-adapter-id-in-winrt-it-is-derived-from-the-m
// obtaining the MAC address using WinRT API is impossible
// iface->hardwareAddress = ?
for (int i = 0; i < hostList->length(); ++i) {
const HostNameInfo hostInfo = hostList->at(i);
if (id != hostInfo.adapterId)
continue;
QNetworkAddressEntry entry;
entry.setIp(QHostAddress(hostInfo.address));
entry.setPrefixLength(hostInfo.prefixLength);
iface->addressEntries << entry;
hostList->takeAt(i);
--i;
}
return iface;
}
static QList<QNetworkInterfacePrivate *> interfaceListing()
{
QList<QNetworkInterfacePrivate *> interfaces;
@ -66,36 +116,46 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
QList<HostNameInfo> hostList;
ComPtr<INetworkInformationStatics> hostNameStatics;
GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &hostNameStatics);
HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &hostNameStatics);
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IVectorView<HostName *>> hostNames;
hostNameStatics->GetHostNames(&hostNames);
hr = hostNameStatics->GetHostNames(&hostNames);
Q_ASSERT_SUCCEEDED(hr);
if (!hostNames)
return interfaces;
unsigned int hostNameCount;
hostNames->get_Size(&hostNameCount);
hr = hostNames->get_Size(&hostNameCount);
Q_ASSERT_SUCCEEDED(hr);
for (unsigned i = 0; i < hostNameCount; ++i) {
HostNameInfo hostInfo;
ComPtr<IHostName> hostName;
hostNames->GetAt(i, &hostName);
hr = hostNames->GetAt(i, &hostName);
Q_ASSERT_SUCCEEDED(hr);
HostNameType type;
hostName->get_Type(&type);
hr = hostName->get_Type(&type);
Q_ASSERT_SUCCEEDED(hr);
if (type == HostNameType_DomainName)
continue;
ComPtr<IIPInformation> ipInformation;
hostName->get_IPInformation(&ipInformation);
hr = hostName->get_IPInformation(&ipInformation);
Q_ASSERT_SUCCEEDED(hr);
ComPtr<INetworkAdapter> currentAdapter;
ipInformation->get_NetworkAdapter(&currentAdapter);
hr = ipInformation->get_NetworkAdapter(&currentAdapter);
Q_ASSERT_SUCCEEDED(hr);
currentAdapter->get_NetworkAdapterId(&hostInfo.adapterId);
hr = currentAdapter->get_NetworkAdapterId(&hostInfo.adapterId);
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IReference<unsigned char>> prefixLengthReference;
ipInformation->get_PrefixLength(&prefixLengthReference);
hr = ipInformation->get_PrefixLength(&prefixLengthReference);
Q_ASSERT_SUCCEEDED(hr);
prefixLengthReference->get_Value(&hostInfo.prefixLength);
hr = prefixLengthReference->get_Value(&hostInfo.prefixLength);
Q_ASSERT_SUCCEEDED(hr);
// invalid prefixes
if ((type == HostNameType_Ipv4 && hostInfo.prefixLength > 32)
@ -103,7 +163,8 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
continue;
HString name;
hostName->get_CanonicalName(name.GetAddressOf());
hr = hostName->get_CanonicalName(name.GetAddressOf());
Q_ASSERT_SUCCEEDED(hr);
UINT32 length;
PCWSTR rawString = name.GetRawBuffer(&length);
hostInfo.address = QString::fromWCharArray(rawString, length);
@ -112,54 +173,35 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
}
INetworkInformationStatics *networkInfoStatics;
GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &networkInfoStatics);
hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &networkInfoStatics);
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IConnectionProfile> connectionProfile;
hr = networkInfoStatics->GetInternetConnectionProfile(&connectionProfile);
Q_ASSERT_SUCCEEDED(hr);
QNetworkInterfacePrivate *iface = interfaceFromProfile(connectionProfile.Get(), &hostList);
if (iface) {
iface->index = 0;
interfaces << iface;
}
ComPtr<IVectorView<ConnectionProfile *>> connectionProfiles;
networkInfoStatics->GetConnectionProfiles(&connectionProfiles);
hr = networkInfoStatics->GetConnectionProfiles(&connectionProfiles);
Q_ASSERT_SUCCEEDED(hr);
if (!connectionProfiles)
return interfaces;
unsigned int size;
connectionProfiles->get_Size(&size);
hr = connectionProfiles->get_Size(&size);
Q_ASSERT_SUCCEEDED(hr);
for (unsigned int i = 0; i < size; ++i) {
QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate;
interfaces << iface;
ComPtr<IConnectionProfile> profile;
connectionProfiles->GetAt(i, &profile);
hr = connectionProfiles->GetAt(i, &profile);
Q_ASSERT_SUCCEEDED(hr);
NetworkConnectivityLevel connectivityLevel;
profile->GetNetworkConnectivityLevel(&connectivityLevel);
if (connectivityLevel != NetworkConnectivityLevel_None)
iface->flags = QNetworkInterface::IsUp | QNetworkInterface::IsRunning;
ComPtr<INetworkAdapter> adapter;
profile->get_NetworkAdapter(&adapter);
UINT32 type;
adapter->get_IanaInterfaceType(&type);
if (type == 23)
iface->flags |= QNetworkInterface::IsPointToPoint;
GUID id;
adapter->get_NetworkAdapterId(&id);
OLECHAR adapterName[39]={0};
StringFromGUID2(id, adapterName, 39);
iface->name = QString::fromWCharArray(adapterName);
// According to http://stackoverflow.com/questions/12936193/how-unique-is-the-ethernet-network-adapter-id-in-winrt-it-is-derived-from-the-m
// obtaining the MAC address using WinRT API is impossible
// iface->hardwareAddress = ?
for (int i = 0; i < hostList.length(); ++i) {
const HostNameInfo hostInfo = hostList.at(i);
if (id != hostInfo.adapterId)
continue;
QNetworkAddressEntry entry;
entry.setIp(QHostAddress(hostInfo.address));
entry.setPrefixLength(hostInfo.prefixLength);
iface->addressEntries << entry;
hostList.takeAt(i);
--i;
iface = interfaceFromProfile(profile.Get(), &hostList);
if (iface) {
iface->index = i + 1;
interfaces << iface;
}
}
return interfaces;