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 <maurice.kalinowski@theqtcompany.com>
This commit is contained in:
parent
2ca20724dd
commit
190c76f685
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -66,18 +66,8 @@
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WINRT
|
||||
#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;
|
||||
#endif
|
||||
#include <Ws2tcpip.h>
|
||||
#endif // Q_OS_WINRT
|
||||
|
||||
#if defined(Q_OS_VXWORKS) && defined(_WRS_KERNEL)
|
||||
# include <envLib.h>
|
||||
@ -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<INetworkInformationStatics> statics;
|
||||
GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &statics);
|
||||
|
||||
ComPtr<IVectorView<HostName *>> 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<IHostName> 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<IHostName> 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include <winsock2.h>
|
||||
|
||||
#include "qhostinfo_p.h"
|
||||
#include "private/qnativesocketengine_p.h"
|
||||
#include <ws2tcpip.h>
|
||||
#include <private/qsystemlibrary_p.h>
|
||||
#include <qmutex.h>
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
@ -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 <qfunctions_winrt.h>
|
||||
#include <qurl.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 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<IHostNameFactory> hostnameFactory;
|
||||
HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(),
|
||||
IID_PPV_ARGS(&hostnameFactory));
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
ComPtr<IHostName> host;
|
||||
HStringReference hostNameRef((const wchar_t*)hostName.utf16());
|
||||
hr = hostnameFactory->CreateHostName(hostNameRef.Get(), &host);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
ComPtr<IDatagramSocketStatics> datagramSocketStatics;
|
||||
hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
ComPtr<IAsyncOperation<IVectorView<EndpointPair *> *>> op;
|
||||
hr = datagramSocketStatics->GetEndpointPairsAsync(host.Get(),
|
||||
HString::MakeReference(L"0").Get(),
|
||||
&op);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
ComPtr<IVectorView<EndpointPair *>> 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<QHostAddress> addresses;
|
||||
for (unsigned int i = 0; i < size; ++i) {
|
||||
ComPtr<IEndpointPair> endpointpair;
|
||||
hr = endpointPairs->GetAt(i, &endpointpair);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
ComPtr<IHostName> 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
|
@ -14,3 +14,5 @@ wince {
|
||||
|
||||
# needed for getaddrinfo with official MinGW
|
||||
mingw:DEFINES += _WIN32_WINNT=0x0501
|
||||
|
||||
winrt: WINRT_MANIFEST.capabilities += internetClientServer
|
||||
|
Loading…
Reference in New Issue
Block a user