From 190c76f685f1dcafbcc762082edcdccdb9bb8b0b Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 16 Dec 2015 15:33:42 +0100 Subject: [PATCH] winrt: Use winsock2 API for hostname resolution on WinRT/WinPhone That API has been available for WinRT and Windows Phone for some time now. By using it to get the machine name and for hostname resolution we can get rid of some winrt-only code and use qhostinfo_win.cpp on WinRT and Windows phone as well. Additionally the required capability was added to tst_qhostinfo so that this auto test can be run without any manual editing. Change-Id: I63fa5521bf8cdb0c919bd5a0100ea977c865622a Reviewed-by: Maurice Kalinowski --- mkspecs/common/winrt_winphone/qmake.conf | 4 +- mkspecs/common/winrt_winphone/qplatformdefs.h | 10 -- src/corelib/global/qglobal.cpp | 54 +------ src/corelib/global/qglobal.h | 1 - src/network/kernel/kernel.pri | 4 +- src/network/kernel/qhostinfo_win.cpp | 15 +- src/network/kernel/qhostinfo_winrt.cpp | 150 ------------------ .../network/kernel/qhostinfo/qhostinfo.pro | 2 + 8 files changed, 17 insertions(+), 223 deletions(-) delete mode 100644 src/network/kernel/qhostinfo_winrt.cpp diff --git a/mkspecs/common/winrt_winphone/qmake.conf b/mkspecs/common/winrt_winphone/qmake.conf index bf237882ff..a9450b0c32 100644 --- a/mkspecs/common/winrt_winphone/qmake.conf +++ b/mkspecs/common/winrt_winphone/qmake.conf @@ -78,9 +78,9 @@ QMAKE_PREFIX_STATICLIB = QMAKE_EXTENSION_STATICLIB = lib QMAKE_LIBS += runtimeobject.lib -QMAKE_LIBS_CORE = +QMAKE_LIBS_CORE += ws2_32.lib QMAKE_LIBS_GUI = -QMAKE_LIBS_NETWORK = +QMAKE_LIBS_NETWORK += ws2_32.lib QMAKE_LIBS_OPENGL_ES2 = $${LIBEGL_NAME}.lib $${LIBGLESV2_NAME}.lib QMAKE_LIBS_OPENGL_ES2_DEBUG = $${LIBEGL_NAME}d.lib $${LIBGLESV2_NAME}d.lib diff --git a/mkspecs/common/winrt_winphone/qplatformdefs.h b/mkspecs/common/winrt_winphone/qplatformdefs.h index 6abac1e94d..14f6c58253 100644 --- a/mkspecs/common/winrt_winphone/qplatformdefs.h +++ b/mkspecs/common/winrt_winphone/qplatformdefs.h @@ -130,14 +130,4 @@ typedef int mode_t; -#ifndef INADDR_ANY -# define INADDR_ANY (u_long)0x00000000 -#endif -#ifndef INADDR_LOOPBACK -# define INADDR_LOOPBACK 0x7f000001 -#endif -#ifndef INADDR_BROADCAST -# define INADDR_BROADCAST (u_long)0xffffffff -#endif - #endif // QPLATFORMDEFS_H diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 81925642f8..e8c50dff2b 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -66,18 +66,8 @@ #endif #ifdef Q_OS_WINRT -#include -#include -#include -#include -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; -#endif +#include +#endif // Q_OS_WINRT #if defined(Q_OS_VXWORKS) && defined(_WRS_KERNEL) # include @@ -1880,8 +1870,6 @@ QT_BEGIN_INCLUDE_NAMESPACE #include "qt_windows.h" QT_END_INCLUDE_NAMESPACE -#ifndef Q_OS_WINRT - # ifndef QT_BOOTSTRAPPED class QWindowsSockInit { @@ -1912,8 +1900,6 @@ QWindowsSockInit::~QWindowsSockInit() Q_GLOBAL_STATIC(QWindowsSockInit, winsockInit) # endif // QT_BOOTSTRAPPED -#endif // !Q_OS_WINRT - #ifdef Q_OS_WINRT static inline HMODULE moduleHandleForFunction(LPCVOID address) { @@ -2797,42 +2783,6 @@ QString QSysInfo::machineHostName() struct utsname u; if (uname(&u) == 0) return QString::fromLocal8Bit(u.nodename); -#elif defined(Q_OS_WINRT) - ComPtr statics; - GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &statics); - - ComPtr> hostNames; - statics->GetHostNames(&hostNames); - if (!hostNames) - return QString(); - - unsigned int size; - hostNames->get_Size(&size); - if (size == 0) - return QString(); - - for (unsigned int i = 0; i < size; ++i) { - ComPtr hostName; - hostNames->GetAt(i, &hostName); - HostNameType type; - hostName->get_Type(&type); - if (type != HostNameType_DomainName) - continue; - - HString name; - hostName->get_CanonicalName(name.GetAddressOf()); - UINT32 length; - PCWSTR rawString = name.GetRawBuffer(&length); - return QString::fromWCharArray(rawString, length); - } - ComPtr firstHost; - hostNames->GetAt(0, &firstHost); - - HString name; - firstHost->get_CanonicalName(name.GetAddressOf()); - UINT32 length; - PCWSTR rawString = name.GetRawBuffer(&length); - return QString::fromWCharArray(rawString, length); #else # ifdef Q_OS_WIN // Important: QtNetwork depends on machineHostName() initializing ws2_32.dll diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 07a0b5e27a..2551dcb5d3 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -611,7 +611,6 @@ class QDataStream; #if defined(Q_OS_WINRT) # define QT_NO_FILESYSTEMWATCHER -# define QT_NO_GETADDRINFO # define QT_NO_NETWORKPROXY # define QT_NO_PROCESS # define QT_NO_SOCKETNOTIFIER diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index 435bfd6c27..ddb30b7b6f 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -33,16 +33,16 @@ android { } win32: { + SOURCES += kernel/qhostinfo_win.cpp + !winrt { SOURCES += kernel/qdnslookup_win.cpp \ - kernel/qhostinfo_win.cpp \ kernel/qnetworkinterface_win.cpp LIBS_PRIVATE += -ldnsapi -liphlpapi DEFINES += WINVER=0x0600 _WIN32_WINNT=0x0600 } else { SOURCES += kernel/qdnslookup_winrt.cpp \ - kernel/qhostinfo_winrt.cpp \ kernel/qnetworkinterface_winrt.cpp } } diff --git a/src/network/kernel/qhostinfo_win.cpp b/src/network/kernel/qhostinfo_win.cpp index da28cd48c1..7e45e9f949 100644 --- a/src/network/kernel/qhostinfo_win.cpp +++ b/src/network/kernel/qhostinfo_win.cpp @@ -34,7 +34,6 @@ #include #include "qhostinfo_p.h" -#include "private/qnativesocketengine_p.h" #include #include #include @@ -77,14 +76,18 @@ static void resolveLibrary() { // Attempt to resolve getaddrinfo(); without it we'll have to fall // back to gethostbyname(), which has no IPv6 support. -#if !defined(Q_OS_WINCE) - local_getaddrinfo = (getaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getaddrinfo"); - local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "freeaddrinfo"); - local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getnameinfo"); -#else +#if defined(Q_OS_WINCE) local_getaddrinfo = (getaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2"), "getaddrinfo"); local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2"), "freeaddrinfo"); local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2"), "getnameinfo"); +#elif defined (Q_OS_WINRT) + local_getaddrinfo = (getaddrinfoProto) &getaddrinfo; + local_freeaddrinfo = (freeaddrinfoProto) &freeaddrinfo; + local_getnameinfo = (getnameinfoProto) getnameinfo; +#else + local_getaddrinfo = (getaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getaddrinfo"); + local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "freeaddrinfo"); + local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getnameinfo"); #endif } diff --git a/src/network/kernel/qhostinfo_winrt.cpp b/src/network/kernel/qhostinfo_winrt.cpp deleted file mode 100644 index 1840bebd39..0000000000 --- a/src/network/kernel/qhostinfo_winrt.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtNetwork module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qhostinfo_p.h" - -#include -#include - -#include -#include -#include -#include -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 E_NO_SUCH_HOST 0x80072af9 - -//#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; - } - - ComPtr hostnameFactory; - HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), - IID_PPV_ARGS(&hostnameFactory)); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr host; - HStringReference hostNameRef((const wchar_t*)hostName.utf16()); - hr = hostnameFactory->CreateHostName(hostNameRef.Get(), &host); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr datagramSocketStatics; - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr *>> op; - hr = datagramSocketStatics->GetEndpointPairsAsync(host.Get(), - HString::MakeReference(L"0").Get(), - &op); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr> endpointPairs; - 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; - } - - if (hr == E_NO_SUCH_HOST || !endpointPairs) { - results.setError(QHostInfo::HostNotFound); - results.setErrorString(tr("Host %1 could not be found.").arg(hostName)); - return results; - } - Q_ASSERT_SUCCEEDED(hr); - - unsigned int size; - hr = endpointPairs->get_Size(&size); - Q_ASSERT_SUCCEEDED(hr); - QList addresses; - for (unsigned int i = 0; i < size; ++i) { - ComPtr endpointpair; - hr = endpointPairs->GetAt(i, &endpointpair); - Q_ASSERT_SUCCEEDED(hr); - ComPtr remoteHost; - hr = endpointpair->get_RemoteHostName(&remoteHost); - Q_ASSERT_SUCCEEDED(hr); - if (!remoteHost) - continue; - HostNameType type; - hr = remoteHost->get_Type(&type); - Q_ASSERT_SUCCEEDED(hr); - if (type == HostNameType_DomainName) - continue; - - HString name; - hr = remoteHost->get_CanonicalName(name.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - UINT32 length; - PCWSTR rawString = name.GetRawBuffer(&length); - QHostAddress addr; - addr.setAddress(QString::fromWCharArray(rawString, length)); - if (!addresses.contains(addr)) - addresses.append(addr); - } - results.setAddresses(addresses); - - return results; -} - -// QString QHostInfo::localDomainName() defined in qnetworkinterface_win.cpp - -QT_END_NAMESPACE diff --git a/tests/auto/network/kernel/qhostinfo/qhostinfo.pro b/tests/auto/network/kernel/qhostinfo/qhostinfo.pro index c9b795d098..12858c97ee 100644 --- a/tests/auto/network/kernel/qhostinfo/qhostinfo.pro +++ b/tests/auto/network/kernel/qhostinfo/qhostinfo.pro @@ -14,3 +14,5 @@ wince { # needed for getaddrinfo with official MinGW mingw:DEFINES += _WIN32_WINNT=0x0501 + +winrt: WINRT_MANIFEST.capabilities += internetClientServer