summaryrefslogtreecommitdiffstats
path: root/src/network/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/kernel')
-rw-r--r--src/network/kernel/kernel.pri14
-rw-r--r--src/network/kernel/qauthenticator.cpp21
-rw-r--r--src/network/kernel/qdnslookup.cpp19
-rw-r--r--src/network/kernel/qdnslookup.h6
-rw-r--r--src/network/kernel/qdnslookup_p.h1
-rw-r--r--src/network/kernel/qdnslookup_winrt.cpp144
-rw-r--r--src/network/kernel/qhostaddress.cpp6
-rw-r--r--src/network/kernel/qhostinfo_winrt.cpp194
-rw-r--r--src/network/kernel/qnetworkinterface_winrt.cpp198
9 files changed, 588 insertions, 15 deletions
diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri
index 97f52fdb6e..9b584be206 100644
--- a/src/network/kernel/kernel.pri
+++ b/src/network/kernel/kernel.pri
@@ -33,9 +33,17 @@ android {
}
win32: {
- HEADERS += kernel/qnetworkinterface_win_p.h
- SOURCES += kernel/qdnslookup_win.cpp kernel/qhostinfo_win.cpp kernel/qnetworkinterface_win.cpp
- LIBS_PRIVATE += -ldnsapi
+ !winrt {
+ HEADERS += kernel/qnetworkinterface_win_p.h
+ SOURCES += kernel/qdnslookup_win.cpp \
+ kernel/qhostinfo_win.cpp \
+ kernel/qnetworkinterface_win.cpp
+ LIBS_PRIVATE += -ldnsapi
+ } else {
+ SOURCES += kernel/qdnslookup_winrt.cpp \
+ kernel/qhostinfo_winrt.cpp \
+ kernel/qnetworkinterface_winrt.cpp
+ }
}
integrity:SOURCES += kernel/qdnslookup_unix.cpp kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index 8c16486878..edbbbf5a75 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -55,9 +55,11 @@
#include <qmutex.h>
#include <private/qmutexpool_p.h>
#include <rpc.h>
+#ifndef Q_OS_WINRT
#define SECURITY_WIN32 1
#include <security.h>
#endif
+#endif
//#define NTLMV1_CLIENT
@@ -69,7 +71,7 @@ QT_BEGIN_NAMESPACE
static QByteArray qNtlmPhase1();
static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phase2data);
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
static QByteArray qNtlmPhase1_SSPI(QAuthenticatorPrivate *ctx);
static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray& phase2data);
#endif
@@ -328,7 +330,7 @@ bool QAuthenticator::isNull() const
return !d;
}
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
class QNtlmWindowsHandles
{
public:
@@ -340,7 +342,7 @@ public:
QAuthenticatorPrivate::QAuthenticatorPrivate()
: method(None)
- #ifdef Q_OS_WIN
+ #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
, ntlmWindowsHandles(0)
#endif
, hasFailed(false)
@@ -354,7 +356,7 @@ QAuthenticatorPrivate::QAuthenticatorPrivate()
QAuthenticatorPrivate::~QAuthenticatorPrivate()
{
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
if (ntlmWindowsHandles)
delete ntlmWindowsHandles;
#endif
@@ -485,7 +487,7 @@ QByteArray QAuthenticatorPrivate::calculateResponse(const QByteArray &requestMet
case QAuthenticatorPrivate::Ntlm:
methodString = "NTLM ";
if (challenge.isEmpty()) {
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
QByteArray phase1Token;
if (user.isEmpty()) // Only pull from system if no user was specified in authenticator
phase1Token = qNtlmPhase1_SSPI(this);
@@ -502,7 +504,7 @@ QByteArray QAuthenticatorPrivate::calculateResponse(const QByteArray &requestMet
phase = Phase2;
}
} else {
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
QByteArray phase3Token;
if (ntlmWindowsHandles)
phase3Token = qNtlmPhase3_SSPI(this, QByteArray::fromBase64(challenge));
@@ -1475,7 +1477,7 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas
return rc;
}
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
// See http://davenport.sourceforge.net/ntlm.html
// and libcurl http_ntlm.c
@@ -1513,7 +1515,6 @@ static bool q_NTLM_SSPI_library_load()
return true;
}
-#ifdef Q_OS_WIN
// Phase 1:
static QByteArray qNtlmPhase1_SSPI(QAuthenticatorPrivate *ctx)
{
@@ -1631,8 +1632,6 @@ static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray&
return result;
}
-#endif // Q_OS_WIN
-
-#endif
+#endif // Q_OS_WIN && !Q_OS_WINRT
QT_END_NAMESPACE
diff --git a/src/network/kernel/qdnslookup.cpp b/src/network/kernel/qdnslookup.cpp
index 53675d083b..e776a8eb76 100644
--- a/src/network/kernel/qdnslookup.cpp
+++ b/src/network/kernel/qdnslookup.cpp
@@ -363,6 +363,25 @@ void QDnsLookup::setType(Type type)
}
/*!
+ \property QDnsLookup::nameserver
+ \brief the nameserver to use for DNS lookup.
+*/
+
+QHostAddress QDnsLookup::nameserver() const
+{
+ return d_func()->nameserver;
+}
+
+void QDnsLookup::setNameserver(const QHostAddress &nameserver)
+{
+ Q_D(QDnsLookup);
+ if (nameserver != d->nameserver) {
+ d->nameserver = nameserver;
+ emit nameserverChanged(nameserver);
+ }
+}
+
+/*!
Returns the list of canonical name records associated with this lookup.
*/
diff --git a/src/network/kernel/qdnslookup.h b/src/network/kernel/qdnslookup.h
index 1df21d866e..ffbef61f92 100644
--- a/src/network/kernel/qdnslookup.h
+++ b/src/network/kernel/qdnslookup.h
@@ -180,6 +180,7 @@ class Q_NETWORK_EXPORT QDnsLookup : public QObject
Q_PROPERTY(QString errorString READ errorString NOTIFY finished)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(Type type READ type WRITE setType NOTIFY typeChanged)
+ Q_PROPERTY(QHostAddress nameserver READ nameserver WRITE setNameserver NOTIFY nameserverChanged)
public:
enum Error
@@ -209,6 +210,7 @@ public:
explicit QDnsLookup(QObject *parent = 0);
QDnsLookup(Type type, const QString &name, QObject *parent = 0);
+ QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent = 0);
~QDnsLookup();
Error error() const;
@@ -221,6 +223,9 @@ public:
Type type() const;
void setType(QDnsLookup::Type);
+ QHostAddress nameserver() const;
+ void setNameserver(const QHostAddress &nameserver);
+
QList<QDnsDomainNameRecord> canonicalNameRecords() const;
QList<QDnsHostAddressRecord> hostAddressRecords() const;
QList<QDnsMailExchangeRecord> mailExchangeRecords() const;
@@ -238,6 +243,7 @@ Q_SIGNALS:
void finished();
void nameChanged(const QString &name);
void typeChanged(Type type);
+ void nameserverChanged(const QHostAddress &nameserver);
private:
Q_DECLARE_PRIVATE(QDnsLookup)
diff --git a/src/network/kernel/qdnslookup_p.h b/src/network/kernel/qdnslookup_p.h
index 692b9088fe..4bd3bd7603 100644
--- a/src/network/kernel/qdnslookup_p.h
+++ b/src/network/kernel/qdnslookup_p.h
@@ -100,6 +100,7 @@ public:
bool isFinished;
QString name;
QDnsLookup::Type type;
+ QHostAddress nameserver;
QDnsLookupReply reply;
QDnsLookupRunnable *runnable;
diff --git a/src/network/kernel/qdnslookup_winrt.cpp b/src/network/kernel/qdnslookup_winrt.cpp
new file mode 100644
index 0000000000..a5d16e4b63
--- /dev/null
+++ b/src/network/kernel/qdnslookup_winrt.cpp
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdnslookup_p.h"
+
+#include <qurl.h>
+
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.foundation.collections.h>
+#include <windows.networking.h>
+#include <windows.networking.sockets.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::Networking;
+using namespace ABI::Windows::Networking::Connectivity;
+using namespace ABI::Windows::Networking::Sockets;
+
+QT_BEGIN_NAMESPACE
+
+void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, QDnsLookupReply *reply)
+{
+ // TODO: is there any way to do "proper" dns lookup?
+ if (requestType != QDnsLookup::A && requestType != QDnsLookup::AAAA
+ && requestType != QDnsLookup::ANY) {
+ reply->error = QDnsLookup::InvalidRequestError;
+ reply->errorString = QLatin1String("WinRT only supports IPv4 and IPv6 requests");
+ return;
+ }
+
+ QString aceHostname = QUrl::fromAce(requestName);
+ if (aceHostname.isEmpty()) {
+ reply->error = QDnsLookup::InvalidRequestError;
+ reply->errorString = requestName.isEmpty() ? tr("No hostname given") : tr("Invalid hostname");
+ return;
+ }
+
+ IHostNameFactory *hostnameFactory;
+
+ HStringReference classId(RuntimeClass_Windows_Networking_HostName);
+ if (FAILED(GetActivationFactory(classId.Get(), &hostnameFactory))) {
+ reply->error = QDnsLookup::ResolverError;
+ reply->errorString = QLatin1String("Could not obtain hostname factory");
+ return;
+ }
+ IHostName *host;
+ HStringReference hostNameRef((const wchar_t*)aceHostname.utf16());
+ hostnameFactory->CreateHostName(hostNameRef.Get(), &host);
+ hostnameFactory->Release();
+
+ IDatagramSocketStatics *datagramSocketStatics;
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics);
+
+ IAsyncOperation<IVectorView<EndpointPair*> *> *op;
+ HSTRING proto;
+ WindowsCreateString(L"0", 1, &proto);
+ datagramSocketStatics->GetEndpointPairsAsync(host, proto, &op);
+ datagramSocketStatics->Release();
+ host->Release();
+
+ IVectorView<EndpointPair*> *endpointPairs = 0;
+ HRESULT hr = op->GetResults(&endpointPairs);
+ int waitCount = 0;
+ while (hr == E_ILLEGAL_METHOD_CALL) {
+ WaitForSingleObjectEx(GetCurrentThread(), 50, FALSE);
+ hr = op->GetResults(&endpointPairs);
+ if (++waitCount > 1200) // Wait for 1 minute max
+ return;
+ }
+ op->Release();
+
+ if (!endpointPairs)
+ return;
+
+ unsigned int size;
+ endpointPairs->get_Size(&size);
+ for (unsigned int i = 0; i < size; ++i) {
+ IEndpointPair *endpointpair;
+ endpointPairs->GetAt(i, &endpointpair);
+ IHostName *remoteHost;
+ endpointpair->get_RemoteHostName(&remoteHost);
+ endpointpair->Release();
+ HostNameType type;
+ remoteHost->get_Type(&type);
+ if (type == HostNameType_Bluetooth || type == HostNameType_DomainName
+ || (requestType != QDnsLookup::ANY
+ && ((type == HostNameType_Ipv4 && requestType == QDnsLookup::AAAA)
+ || (type == HostNameType_Ipv6 && requestType == QDnsLookup::A))))
+ continue;
+
+ HSTRING name;
+ remoteHost->get_CanonicalName(&name);
+ remoteHost->Release();
+ UINT32 length;
+ PCWSTR rawString = WindowsGetStringRawBuffer(name, &length);
+ QDnsHostAddressRecord record;
+ record.d->name = aceHostname;
+ record.d->value = QHostAddress(QString::fromWCharArray(rawString, length));
+ reply->hostAddressRecords.append(record);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp
index 18fd6dee58..0ab72191dc 100644
--- a/src/network/kernel/qhostaddress.cpp
+++ b/src/network/kernel/qhostaddress.cpp
@@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE
// sockaddr_in6 size changed between old and new SDK
// Only the new version is the correct one, so always
// use this structure.
-#if defined(Q_OS_WINCE)
+#if defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
# if !defined(u_char)
# define u_char unsigned char
# endif
@@ -448,10 +448,12 @@ QHostAddress::QHostAddress(const QString &address)
QHostAddress::QHostAddress(const struct sockaddr *sockaddr)
: d(new QHostAddressPrivate)
{
+#ifndef Q_OS_WINRT
if (sockaddr->sa_family == AF_INET)
setAddress(htonl(((sockaddr_in *)sockaddr)->sin_addr.s_addr));
else if (sockaddr->sa_family == AF_INET6)
setAddress(((qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr);
+#endif
}
/*!
@@ -604,11 +606,13 @@ bool QHostAddress::setAddress(const QString &address)
*/
void QHostAddress::setAddress(const struct sockaddr *sockaddr)
{
+#ifndef Q_OS_WINRT
clear();
if (sockaddr->sa_family == AF_INET)
setAddress(htonl(((sockaddr_in *)sockaddr)->sin_addr.s_addr));
else if (sockaddr->sa_family == AF_INET6)
setAddress(((qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr);
+#endif
}
/*!
diff --git a/src/network/kernel/qhostinfo_winrt.cpp b/src/network/kernel/qhostinfo_winrt.cpp
new file mode 100644
index 0000000000..928c9e4628
--- /dev/null
+++ b/src/network/kernel/qhostinfo_winrt.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhostinfo_p.h"
+
+#include <qurl.h>
+
+#include <ppltasks.h>
+#include <wrl.h>
+#include <windows.networking.h>
+#include <windows.networking.sockets.h>
+#include <windows.networking.connectivity.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::Networking;
+using namespace ABI::Windows::Networking::Connectivity;
+using namespace ABI::Windows::Networking::Sockets;
+
+QT_BEGIN_NAMESPACE
+
+//#define QHOSTINFO_DEBUG
+
+QHostInfo QHostInfoAgent::fromName(const QString &hostName)
+{
+ QHostInfo results;
+
+ QHostAddress address;
+ if (address.setAddress(hostName)) {
+ // Reverse lookup
+ // TODO: is there a replacement for getnameinfo for winrt?
+ Q_UNIMPLEMENTED();
+ return results;
+ }
+
+ QByteArray aceHostname = QUrl::toAce(hostName);
+ results.setHostName(hostName);
+ if (aceHostname.isEmpty()) {
+ results.setError(QHostInfo::HostNotFound);
+ results.setErrorString(hostName.isEmpty() ? tr("No host name given") : tr("Invalid hostname"));
+ return results;
+ }
+
+ IHostNameFactory *hostnameFactory;
+
+ HStringReference classId(RuntimeClass_Windows_Networking_HostName);
+ if (FAILED(GetActivationFactory(classId.Get(), &hostnameFactory)))
+ Q_ASSERT(false, "Could not obtain hostname factory.");
+
+ IHostName *host;
+ HStringReference hostNameRef((const wchar_t*)hostName.utf16());
+ hostnameFactory->CreateHostName(hostNameRef.Get(), &host);
+ hostnameFactory->Release();
+
+ IDatagramSocketStatics *datagramSocketStatics;
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics);
+
+ IAsyncOperation<IVectorView<EndpointPair*> *> *op;
+ HSTRING proto;
+ WindowsCreateString(L"0", 1, &proto);
+ datagramSocketStatics->GetEndpointPairsAsync(host, proto, &op);
+ datagramSocketStatics->Release();
+ host->Release();
+
+ IVectorView<EndpointPair*> *endpointPairs = 0;
+ HRESULT hr = op->GetResults(&endpointPairs);
+ int waitCount = 0;
+ while (hr == E_ILLEGAL_METHOD_CALL) {
+ WaitForSingleObjectEx(GetCurrentThread(), 50, FALSE);
+ hr = op->GetResults(&endpointPairs);
+ if (++waitCount > 1200) // Wait for 1 minute max
+ return results;
+ }
+ op->Release();
+
+ if (!endpointPairs)
+ return results;
+
+ unsigned int size;
+ endpointPairs->get_Size(&size);
+ QList<QHostAddress> addresses;
+ for (unsigned int i = 0; i < size; ++i) {
+ IEndpointPair *endpointpair;
+ endpointPairs->GetAt(i, &endpointpair);
+ IHostName *remoteHost;
+ endpointpair->get_RemoteHostName(&remoteHost);
+ endpointpair->Release();
+ if (!remoteHost)
+ continue;
+ HostNameType type;
+ remoteHost->get_Type(&type);
+ if (type == HostNameType_DomainName)
+ continue;
+
+ HSTRING name;
+ remoteHost->get_CanonicalName(&name);
+ remoteHost->Release();
+ UINT32 length;
+ PCWSTR rawString = WindowsGetStringRawBuffer(name, &length);
+ QHostAddress addr;
+ addr.setAddress(QString::fromWCharArray(rawString, length));
+ if (!addresses.contains(addr))
+ addresses.append(addr);
+ }
+ results.setAddresses(addresses);
+
+ return results;
+}
+
+QString QHostInfo::localHostName()
+{
+ INetworkInformationStatics *statics;
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &statics);
+
+ IVectorView<HostName*> *hostNames = 0;
+ statics->GetHostNames(&hostNames);
+ statics->Release();
+ if (!hostNames)
+ return QString();
+
+ unsigned int size;
+ hostNames->get_Size(&size);
+ if (size == 0)
+ return QString();
+
+ for (unsigned int i = 0; i < size; ++i) {
+ IHostName *hostName;
+ hostNames->GetAt(i, &hostName);
+ HostNameType type;
+ hostName->get_Type(&type);
+ if (type != HostNameType_DomainName)
+ continue;
+
+ HSTRING name;
+ hostName->get_CanonicalName(&name);
+ hostName->Release();
+ UINT32 length;
+ PCWSTR rawString = WindowsGetStringRawBuffer(name, &length);
+ return QString::fromWCharArray(rawString, length);
+ }
+ IHostName *firstHost;
+ hostNames->GetAt(0, &firstHost);
+ hostNames->Release();
+
+ HSTRING name;
+ firstHost->get_CanonicalName(&name);
+ firstHost->Release();
+ UINT32 length;
+ PCWSTR rawString = WindowsGetStringRawBuffer(name, &length);
+ return QString::fromWCharArray(rawString, length);
+}
+
+// QString QHostInfo::localDomainName() defined in qnetworkinterface_win.cpp
+
+QT_END_NAMESPACE
diff --git a/src/network/kernel/qnetworkinterface_winrt.cpp b/src/network/kernel/qnetworkinterface_winrt.cpp
new file mode 100644
index 0000000000..6a814c85d4
--- /dev/null
+++ b/src/network/kernel/qnetworkinterface_winrt.cpp
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnetworkinterface.h"
+#include "qnetworkinterface_p.h"
+
+#ifndef QT_NO_NETWORKINTERFACE
+
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.foundation.collections.h>
+#include <windows.networking.h>
+#include <windows.networking.connectivity.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::Networking;
+using namespace ABI::Windows::Networking::Connectivity;
+
+#include <qhostinfo.h>
+
+QT_BEGIN_NAMESPACE
+
+struct HostNameInfo {
+ GUID adapterId;
+ unsigned char prefixLength;
+ QString address;
+};
+
+static QList<QNetworkInterfacePrivate *> interfaceListing()
+{
+ QList<QNetworkInterfacePrivate *> interfaces;
+
+ QList<HostNameInfo> hostList;
+
+ INetworkInformationStatics *hostNameStatics;
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &hostNameStatics);
+
+ IVectorView<HostName*> *hostNames = 0;
+ hostNameStatics->GetHostNames(&hostNames);
+ hostNameStatics->Release();
+ if (!hostNames)
+ return interfaces;
+
+ unsigned int hostNameCount;
+ hostNames->get_Size(&hostNameCount);
+ for (unsigned i = 0; i < hostNameCount; ++i) {
+ HostNameInfo hostInfo;
+ IHostName *hostName;
+ hostNames->GetAt(i, &hostName);
+
+ HostNameType type;
+ hostName->get_Type(&type);
+ if (type == HostNameType_DomainName)
+ continue;
+
+ IIPInformation *ipInformation;
+ hostName->get_IPInformation(&ipInformation);
+ INetworkAdapter *currentAdapter;
+ ipInformation->get_NetworkAdapter(&currentAdapter);
+
+ currentAdapter->get_NetworkAdapterId(&hostInfo.adapterId);
+ currentAdapter->Release();
+
+ IReference<unsigned char> *prefixLengthReference;
+ ipInformation->get_PrefixLength(&prefixLengthReference);
+ ipInformation->Release();
+
+ prefixLengthReference->get_Value(&hostInfo.prefixLength);
+ prefixLengthReference->Release();
+
+ // invalid prefixes
+ if ((type == HostNameType_Ipv4 && hostInfo.prefixLength > 32)
+ || (type == HostNameType_Ipv6 && hostInfo.prefixLength > 128))
+ continue;
+
+ HSTRING name;
+ hostName->get_CanonicalName(&name);
+ hostName->Release();
+ UINT32 length;
+ PCWSTR rawString = WindowsGetStringRawBuffer(name, &length);
+ hostInfo.address = QString::fromWCharArray(rawString, length);
+
+ hostList << hostInfo;
+ }
+ hostNames->Release();
+
+ INetworkInformationStatics *networkInfoStatics;
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &networkInfoStatics);
+ IVectorView<ConnectionProfile *> *connectionProfiles = 0;
+ networkInfoStatics->GetConnectionProfiles(&connectionProfiles);
+ networkInfoStatics->Release();
+ if (!connectionProfiles)
+ return interfaces;
+
+ unsigned int size;
+ connectionProfiles->get_Size(&size);
+ for (unsigned int i = 0; i < size; ++i) {
+ QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate;
+ interfaces << iface;
+
+ IConnectionProfile *profile;
+ connectionProfiles->GetAt(i, &profile);
+
+ NetworkConnectivityLevel connectivityLevel;
+ profile->GetNetworkConnectivityLevel(&connectivityLevel);
+ if (connectivityLevel != NetworkConnectivityLevel_None)
+ iface->flags = QNetworkInterface::IsUp | QNetworkInterface::IsRunning;
+
+ INetworkAdapter *adapter;
+ profile->get_NetworkAdapter(&adapter);
+ profile->Release();
+ UINT32 type;
+ adapter->get_IanaInterfaceType(&type);
+ if (type == 23)
+ iface->flags |= QNetworkInterface::IsPointToPoint;
+ GUID id;
+ adapter->get_NetworkAdapterId(&id);
+ adapter->Release();
+ 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;
+ }
+ }
+ connectionProfiles->Release();
+ return interfaces;
+}
+
+QList<QNetworkInterfacePrivate *> QNetworkInterfaceManager::scan()
+{
+ return interfaceListing();
+}
+
+QString QHostInfo::localDomainName()
+{
+ return QString();
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_NETWORKINTERFACE