diff options
Diffstat (limited to 'src/network')
32 files changed, 47 insertions, 3726 deletions
diff --git a/src/network/.prev_CMakeLists.txt b/src/network/.prev_CMakeLists.txt index 1af21c806b..bc088516a3 100644 --- a/src/network/.prev_CMakeLists.txt +++ b/src/network/.prev_CMakeLists.txt @@ -35,6 +35,7 @@ qt_add_module(Network kernel/qtnetworkglobal.h kernel/qtnetworkglobal_p.h socket/qabstractsocket.cpp socket/qabstractsocket.h socket/qabstractsocket_p.h socket/qabstractsocketengine.cpp socket/qabstractsocketengine_p.h + socket/qnativesocketengine.cpp socket/qnativesocketengine_p.h socket/qtcpserver.cpp socket/qtcpserver.h socket/qtcpserver_p.h socket/qtcpsocket.cpp socket/qtcpsocket.h socket/qtcpsocket_p.h socket/qudpsocket.cpp socket/qudpsocket.h @@ -59,7 +60,6 @@ qt_add_module(Network ) #### Keys ignored in scope 1:.:.:network.pro:<TRUE>: -# MODULE_WINRT_CAPABILITIES = "internetClient" "internetClientServer" "privateNetworkClientServer" # QMAKE_LIBS = "$$QMAKE_LIBS_NETWORK" ## Scopes: @@ -178,10 +178,6 @@ qt_extend_target(Network CONDITION ANDROID AND QT_FEATURE_dnslookup qt_extend_target(Network CONDITION WIN32 SOURCES kernel/qhostinfo_win.cpp -) - -qt_extend_target(Network CONDITION WIN32 AND NOT WINRT - SOURCES kernel/qnetworkinterface_win.cpp kernel/qnetworkproxy_win.cpp socket/qnativesocketengine_win.cpp @@ -191,22 +187,11 @@ qt_extend_target(Network CONDITION WIN32 AND NOT WINRT iphlpapi ) -qt_extend_target(Network CONDITION QT_FEATURE_dnslookup AND WIN32 AND NOT WINRT +qt_extend_target(Network CONDITION QT_FEATURE_dnslookup AND WIN32 SOURCES kernel/qdnslookup_win.cpp ) -qt_extend_target(Network CONDITION WINRT - SOURCES - kernel/qnetworkinterface_winrt.cpp - socket/qnativesocketengine_winrt.cpp socket/qnativesocketengine_winrt_p.h -) - -qt_extend_target(Network CONDITION QT_FEATURE_dnslookup AND WINRT - SOURCES - kernel/qdnslookup_winrt.cpp -) - qt_extend_target(Network CONDITION APPLE AND NOT UIKIT LIBRARIES ${FWCoreServices} @@ -245,7 +230,7 @@ qt_extend_target(Network CONDITION MACOS kernel/qnetworkproxy_mac.cpp ) -qt_extend_target(Network CONDITION QT_FEATURE_libproxy AND NOT MACOS AND (UNIX OR WINRT) +qt_extend_target(Network CONDITION QT_FEATURE_libproxy AND UNIX AND NOT MACOS SOURCES kernel/qnetworkproxy_libproxy.cpp LIBRARIES @@ -253,7 +238,7 @@ qt_extend_target(Network CONDITION QT_FEATURE_libproxy AND NOT MACOS AND (UNIX O PkgConfig::Libproxy ) -qt_extend_target(Network CONDITION NOT MACOS AND NOT QT_FEATURE_libproxy AND (UNIX OR WINRT) +qt_extend_target(Network CONDITION UNIX AND NOT MACOS AND NOT QT_FEATURE_libproxy SOURCES kernel/qnetworkproxy_generic.cpp ) @@ -269,11 +254,6 @@ qt_extend_target(Network CONDITION QT_FEATURE_sctp socket/qsctpsocket.cpp socket/qsctpsocket.h socket/qsctpsocket_p.h ) -qt_extend_target(Network CONDITION NOT WINRT - SOURCES - socket/qnativesocketengine.cpp socket/qnativesocketengine_p.h -) - qt_extend_target(Network CONDITION MSVC MOC_OPTIONS "-D_WINSOCK_DEPRECATED_NO_WARNINGS" @@ -285,7 +265,7 @@ qt_extend_target(Network CONDITION QT_FEATURE_localserver socket/qlocalsocket.cpp socket/qlocalsocket.h socket/qlocalsocket_p.h ) -qt_extend_target(Network CONDITION QT_FEATURE_localserver AND (INTEGRITY OR WINRT) +qt_extend_target(Network CONDITION INTEGRITY AND QT_FEATURE_localserver SOURCES socket/qlocalserver_tcp.cpp socket/qlocalsocket_tcp.cpp @@ -293,13 +273,13 @@ qt_extend_target(Network CONDITION QT_FEATURE_localserver AND (INTEGRITY OR WINR QT_LOCALSOCKET_TCP ) -qt_extend_target(Network CONDITION QT_FEATURE_localserver AND UNIX AND NOT INTEGRITY AND NOT WINRT +qt_extend_target(Network CONDITION QT_FEATURE_localserver AND UNIX AND NOT INTEGRITY SOURCES socket/qlocalserver_unix.cpp socket/qlocalsocket_unix.cpp ) -qt_extend_target(Network CONDITION QT_FEATURE_localserver AND WIN32 AND NOT WINRT +qt_extend_target(Network CONDITION QT_FEATURE_localserver AND WIN32 SOURCES socket/qlocalserver_win.cpp socket/qlocalsocket_win.cpp @@ -328,16 +308,6 @@ qt_extend_target(Network CONDITION QT_FEATURE_ssl ssl/qsslsocket.cpp ssl/qsslsocket.h ssl/qsslsocket_p.h ) -qt_extend_target(Network CONDITION QT_FEATURE_ssl AND WINRT - SOURCES - ssl/qsslcertificate_winrt.cpp - ssl/qssldiffiehellmanparameters_dummy.cpp - ssl/qsslellipticcurve_dummy.cpp - ssl/qsslkey_qt.cpp - ssl/qsslkey_winrt.cpp - ssl/qsslsocket_winrt.cpp ssl/qsslsocket_winrt_p.h -) - qt_extend_target(Network CONDITION QT_FEATURE_schannel AND QT_FEATURE_ssl SOURCES ssl/qsslcertificate_schannel.cpp diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 6ff806fef9..0aff359750 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -35,6 +35,7 @@ qt_add_module(Network kernel/qtnetworkglobal.h kernel/qtnetworkglobal_p.h socket/qabstractsocket.cpp socket/qabstractsocket.h socket/qabstractsocket_p.h socket/qabstractsocketengine.cpp socket/qabstractsocketengine_p.h + socket/qnativesocketengine.cpp socket/qnativesocketengine_p.h socket/qtcpserver.cpp socket/qtcpserver.h socket/qtcpserver_p.h socket/qtcpsocket.cpp socket/qtcpsocket.h socket/qtcpsocket_p.h socket/qudpsocket.cpp socket/qudpsocket.h @@ -59,7 +60,6 @@ qt_add_module(Network ) #### Keys ignored in scope 1:.:.:network.pro:<TRUE>: -# MODULE_WINRT_CAPABILITIES = "internetClient" "internetClientServer" "privateNetworkClientServer" # QMAKE_LIBS = "$$QMAKE_LIBS_NETWORK" ## Scopes: @@ -178,10 +178,6 @@ qt_extend_target(Network CONDITION ANDROID AND QT_FEATURE_dnslookup qt_extend_target(Network CONDITION WIN32 SOURCES kernel/qhostinfo_win.cpp -) - -qt_extend_target(Network CONDITION WIN32 AND NOT WINRT - SOURCES kernel/qnetworkinterface_win.cpp kernel/qnetworkproxy_win.cpp socket/qnativesocketengine_win.cpp @@ -191,22 +187,11 @@ qt_extend_target(Network CONDITION WIN32 AND NOT WINRT iphlpapi ) -qt_extend_target(Network CONDITION QT_FEATURE_dnslookup AND WIN32 AND NOT WINRT +qt_extend_target(Network CONDITION QT_FEATURE_dnslookup AND WIN32 SOURCES kernel/qdnslookup_win.cpp ) -qt_extend_target(Network CONDITION WINRT - SOURCES - kernel/qnetworkinterface_winrt.cpp - socket/qnativesocketengine_winrt.cpp socket/qnativesocketengine_winrt_p.h -) - -qt_extend_target(Network CONDITION QT_FEATURE_dnslookup AND WINRT - SOURCES - kernel/qdnslookup_winrt.cpp -) - qt_extend_target(Network CONDITION APPLE AND NOT UIKIT LIBRARIES ${FWCoreServices} @@ -245,7 +230,7 @@ qt_extend_target(Network CONDITION MACOS kernel/qnetworkproxy_mac.cpp ) -qt_extend_target(Network CONDITION QT_FEATURE_libproxy AND NOT MACOS AND (UNIX OR WINRT) +qt_extend_target(Network CONDITION QT_FEATURE_libproxy AND UNIX AND NOT MACOS SOURCES kernel/qnetworkproxy_libproxy.cpp LIBRARIES @@ -253,7 +238,7 @@ qt_extend_target(Network CONDITION QT_FEATURE_libproxy AND NOT MACOS AND (UNIX O PkgConfig::Libproxy ) -qt_extend_target(Network CONDITION NOT MACOS AND NOT QT_FEATURE_libproxy AND (UNIX OR WINRT) +qt_extend_target(Network CONDITION UNIX AND NOT MACOS AND NOT QT_FEATURE_libproxy SOURCES kernel/qnetworkproxy_generic.cpp ) @@ -269,11 +254,6 @@ qt_extend_target(Network CONDITION QT_FEATURE_sctp socket/qsctpsocket.cpp socket/qsctpsocket.h socket/qsctpsocket_p.h ) -qt_extend_target(Network CONDITION NOT WINRT - SOURCES - socket/qnativesocketengine.cpp socket/qnativesocketengine_p.h -) - qt_extend_target(Network CONDITION MSVC MOC_OPTIONS "-D_WINSOCK_DEPRECATED_NO_WARNINGS" @@ -285,7 +265,7 @@ qt_extend_target(Network CONDITION QT_FEATURE_localserver socket/qlocalsocket.cpp socket/qlocalsocket.h socket/qlocalsocket_p.h ) -qt_extend_target(Network CONDITION QT_FEATURE_localserver AND (INTEGRITY OR WINRT) +qt_extend_target(Network CONDITION INTEGRITY AND QT_FEATURE_localserver SOURCES socket/qlocalserver_tcp.cpp socket/qlocalsocket_tcp.cpp @@ -293,13 +273,13 @@ qt_extend_target(Network CONDITION QT_FEATURE_localserver AND (INTEGRITY OR WINR QT_LOCALSOCKET_TCP ) -qt_extend_target(Network CONDITION QT_FEATURE_localserver AND UNIX AND NOT INTEGRITY AND NOT WINRT +qt_extend_target(Network CONDITION QT_FEATURE_localserver AND UNIX AND NOT INTEGRITY SOURCES socket/qlocalserver_unix.cpp socket/qlocalsocket_unix.cpp ) -qt_extend_target(Network CONDITION QT_FEATURE_localserver AND WIN32 AND NOT WINRT +qt_extend_target(Network CONDITION QT_FEATURE_localserver AND WIN32 SOURCES socket/qlocalserver_win.cpp socket/qlocalsocket_win.cpp @@ -328,16 +308,6 @@ qt_extend_target(Network CONDITION QT_FEATURE_ssl ssl/qsslsocket.cpp ssl/qsslsocket.h ssl/qsslsocket_p.h ) -qt_extend_target(Network CONDITION QT_FEATURE_ssl AND WINRT - SOURCES - ssl/qsslcertificate_winrt.cpp - ssl/qssldiffiehellmanparameters_dummy.cpp - ssl/qsslellipticcurve_dummy.cpp - ssl/qsslkey_qt.cpp - ssl/qsslkey_winrt.cpp - ssl/qsslsocket_winrt.cpp ssl/qsslsocket_winrt_p.h -) - qt_extend_target(Network CONDITION QT_FEATURE_schannel AND QT_FEATURE_ssl SOURCES ssl/qsslcertificate_schannel.cpp diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index f916ee2981..468a530e7b 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -640,7 +640,6 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor channels[0].h2RequestsToSend.insert(request.priority(), pair); } -#ifndef Q_OS_WINRT // For Happy Eyeballs the networkLayerState is set to Unknown // until we have started the first connection attempt. So no // request will be started until we know if IPv4 or IPv6 @@ -648,13 +647,6 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor if (networkLayerState == Unknown || networkLayerState == HostLookupPending) { startHostInfoLookup(); } else if ( networkLayerState == IPv4 || networkLayerState == IPv6 ) { -#else // !Q_OS_WINRT - { - // Skip the host lookup part for winrt. Host lookup and proxy handling are done by Windows - // internally and networkLayerPreference is ignored on this platform. Instead of refactoring - // the whole approach we just pretend that everything important is known here. - networkLayerState = IPv4; -#endif // this used to be called via invokeMethod and a QueuedConnection // It is the only place _q_startNextRequest is called directly without going // through the event loop using a QueuedConnection. diff --git a/src/network/configure.cmake b/src/network/configure.cmake index 1dccd67f78..1bfa978612 100644 --- a/src/network/configure.cmake +++ b/src/network/configure.cmake @@ -264,7 +264,7 @@ qt_feature("openssl" PRIVATE qt_feature_definition("openssl" "QT_NO_OPENSSL" NEGATE) qt_feature_config("openssl" QMAKE_PUBLIC_QT_CONFIG) qt_feature("openssl-runtime" - AUTODETECT NOT WINRT AND NOT WASM + AUTODETECT NOT WASM CONDITION NOT QT_FEATURE_securetransport AND NOT QT_FEATURE_schannel AND TEST_openssl_headers ENABLE INPUT_openssl STREQUAL 'yes' OR INPUT_openssl STREQUAL 'runtime' DISABLE INPUT_openssl STREQUAL 'no' OR INPUT_openssl STREQUAL 'linked' OR INPUT_ssl STREQUAL 'no' @@ -284,13 +284,13 @@ qt_feature("securetransport" PUBLIC qt_feature_definition("securetransport" "QT_SECURETRANSPORT") qt_feature("schannel" PUBLIC LABEL "Schannel" - CONDITION INPUT_schannel STREQUAL 'yes' AND WIN32 AND NOT WINRT AND ( INPUT_openssl STREQUAL '' OR INPUT_openssl STREQUAL 'no' ) + CONDITION INPUT_schannel STREQUAL 'yes' AND WIN32 AND ( INPUT_openssl STREQUAL '' OR INPUT_openssl STREQUAL 'no' ) DISABLE INPUT_schannel STREQUAL 'no' OR INPUT_ssl STREQUAL 'no' ) qt_feature_definition("schannel" "QT_SCHANNEL") qt_feature("ssl" PUBLIC LABEL "SSL" - CONDITION WINRT OR QT_FEATURE_securetransport OR QT_FEATURE_openssl OR QT_FEATURE_schannel + CONDITION QT_FEATURE_securetransport OR QT_FEATURE_openssl OR QT_FEATURE_schannel ) qt_feature_definition("ssl" "QT_NO_SSL" NEGATE VALUE "1") qt_feature("dtls" PUBLIC @@ -389,7 +389,7 @@ qt_feature("sspi" PUBLIC SECTION "Networking" LABEL "SSPI" PURPOSE "Enable NTLM/SPNEGO authentication through SSPI" - CONDITION WIN32 AND NOT WINRT + CONDITION WIN32 ) qt_feature_definition("sspi" "QT_NO_SSPI" NEGATE VALUE "1") qt_feature("netlistmgr" PRIVATE @@ -421,7 +421,7 @@ qt_configure_add_summary_entry( ) qt_configure_add_summary_entry( ARGS "schannel" - CONDITION WIN32 AND NOT WINRT + CONDITION WIN32 ) qt_configure_add_summary_entry(ARGS "openssl") qt_configure_add_summary_entry(ARGS "openssl-linked") diff --git a/src/network/configure.json b/src/network/configure.json index 254a36d725..5f26f83c54 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -272,7 +272,7 @@ ] }, "openssl-runtime": { - "autoDetect": "!config.winrt && !config.wasm", + "autoDetect": "!config.wasm", "enable": "input.openssl == 'yes' || input.openssl == 'runtime'", "disable": "input.openssl == 'no' || input.openssl == 'linked' || input.ssl == 'no'", "condition": "!features.securetransport && !features.schannel && libs.openssl_headers" @@ -299,7 +299,7 @@ "schannel": { "label": "Schannel", "disable": "input.schannel == 'no' || input.ssl == 'no'", - "condition": "input.schannel == 'yes' && config.win32 && !config.winrt && (input.openssl == '' || input.openssl == 'no')", + "condition": "input.schannel == 'yes' && config.win32 && (input.openssl == '' || input.openssl == 'no')", "output": [ "publicFeature", { "type": "define", "name": "QT_SCHANNEL" } @@ -307,7 +307,7 @@ }, "ssl": { "label": "SSL", - "condition": "config.winrt || features.securetransport || features.openssl || features.schannel", + "condition": "features.securetransport || features.openssl || features.schannel", "output": [ "publicFeature", "feature" ] }, "dtls": { @@ -411,7 +411,7 @@ "label": "SSPI", "purpose": "Enable NTLM/SPNEGO authentication through SSPI", "section": "Networking", - "condition": "config.win32 && !config.winrt", + "condition": "config.win32", "output": [ "publicFeature", "feature" ] }, "netlistmgr": { @@ -469,7 +469,7 @@ For example: { "type": "feature", "args": "schannel", - "condition": "config.win32 && !config.winrt" + "condition": "config.win32" }, "openssl", "openssl-linked", diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index 7dd5b1d97e..d7d0dd522c 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -62,16 +62,10 @@ android:qtConfig(dnslookup) { } win32: { - SOURCES += kernel/qhostinfo_win.cpp - - !winrt { - SOURCES += kernel/qnetworkinterface_win.cpp - qtConfig(dnslookup): SOURCES += kernel/qdnslookup_win.cpp - LIBS_PRIVATE += -ldnsapi -liphlpapi - } else { - SOURCES += kernel/qnetworkinterface_winrt.cpp - qtConfig(dnslookup): SOURCES += kernel/qdnslookup_winrt.cpp - } + SOURCES += kernel/qhostinfo_win.cpp \ + kernel/qnetworkinterface_win.cpp + qtConfig(dnslookup): SOURCES += kernel/qdnslookup_win.cpp + LIBS_PRIVATE += -ldnsapi -liphlpapi } mac { @@ -94,7 +88,7 @@ qtConfig(gssapi): QMAKE_USE_PRIVATE += gssapi uikit:HEADERS += kernel/qnetworkinterface_uikit_p.h osx:SOURCES += kernel/qnetworkproxy_mac.cpp -else:win32:!winrt: SOURCES += kernel/qnetworkproxy_win.cpp +else:win32: SOURCES += kernel/qnetworkproxy_win.cpp else: qtConfig(libproxy) { SOURCES += kernel/qnetworkproxy_libproxy.cpp QMAKE_USE_PRIVATE += libproxy libdl diff --git a/src/network/kernel/qdnslookup_winrt.cpp b/src/network/kernel/qdnslookup_winrt.cpp deleted file mode 100644 index 30510d89fc..0000000000 --- a/src/network/kernel/qdnslookup_winrt.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdnslookup_p.h" - -#include <qfunctions_winrt.h> -#include <qurl.h> -#include <qdebug.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; - -#define E_NO_SUCH_HOST 0x80072af9 - -QT_BEGIN_NAMESPACE - -void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply) -{ - // TODO: Add nameserver support for winRT - if (!nameserver.isNull()) - qWarning("Ignoring nameserver as its currently not supported on WinRT"); - - // 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; - } - - ComPtr<IHostNameFactory> hostnameFactory; - HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), - IID_PPV_ARGS(&hostnameFactory)); - if (FAILED(hr)) { - reply->error = QDnsLookup::ResolverError; - reply->errorString = QLatin1String("Could not obtain hostname factory"); - return; - } - ComPtr<IHostName> host; - HStringReference hostNameRef((const wchar_t*)aceHostname.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 = QWinRTFunctions::await(op, endpointPairs.GetAddressOf(), QWinRTFunctions::YieldThread, 60 * 1000); - if (hr == E_NO_SUCH_HOST || !endpointPairs) { - reply->error = QDnsLookup::NotFoundError; - reply->errorString = tr("Host %1 could not be found.").arg(aceHostname); - return; - } - if (FAILED(hr)) { - reply->error = QDnsLookup::ServerFailureError; - reply->errorString = tr("Unknown error"); - return; - } - - unsigned int size; - hr = endpointPairs->get_Size(&size); - Q_ASSERT_SUCCEEDED(hr); - // endpoint pairs might contain duplicates so we temporarily store addresses in a QSet - QSet<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); - HostNameType type; - hr = remoteHost->get_Type(&type); - Q_ASSERT_SUCCEEDED(hr); - 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; - hr = remoteHost->get_CanonicalName(name.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - UINT32 length; - PCWSTR rawString = name.GetRawBuffer(&length); - addresses.insert(QHostAddress(QString::fromWCharArray(rawString, length))); - } - for (const QHostAddress &address : qAsConst(addresses)) { - QDnsHostAddressRecord record; - record.d->name = aceHostname; - record.d->value = address; - reply->hostAddressRecords.append(record); - } -} - -QT_END_NAMESPACE diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index b9fc129685..0783c0751f 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -479,14 +479,10 @@ 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(((const sockaddr_in *)sockaddr)->sin_addr.s_addr)); else if (sockaddr->sa_family == AF_INET6) setAddress(((const sockaddr_in6 *)sockaddr)->sin6_addr.s6_addr); -#else - Q_UNUSED(sockaddr) -#endif } /*! @@ -659,15 +655,11 @@ bool QHostAddress::setAddress(const QString &address) void QHostAddress::setAddress(const struct sockaddr *sockaddr) { d.detach(); -#ifndef Q_OS_WINRT clear(); if (sockaddr->sa_family == AF_INET) setAddress(htonl(((const sockaddr_in *)sockaddr)->sin_addr.s_addr)); else if (sockaddr->sa_family == AF_INET6) setAddress(((const sockaddr_in6 *)sockaddr)->sin6_addr.s6_addr); -#else - Q_UNUSED(sockaddr) -#endif } /*! diff --git a/src/network/kernel/qnetworkinterface_winrt.cpp b/src/network/kernel/qnetworkinterface_winrt.cpp deleted file mode 100644 index 24ac3df52f..0000000000 --- a/src/network/kernel/qnetworkinterface_winrt.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qnetworkinterface.h" -#include "qnetworkinterface_p.h" - -#ifndef QT_NO_NETWORKINTERFACE - -#include <qfunctions_winrt.h> - -#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; -}; - -uint QNetworkInterfaceManager::interfaceIndexFromName(const QString &name) -{ - // TBD - may not be possible - Q_UNUSED(name); - return 0; -} - -QString QNetworkInterfaceManager::interfaceNameFromIndex(uint index) -{ - // TBD - may not be possible - return QString::number(index); -} - -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; - iface->flags |= QNetworkInterface::CanBroadcast; - - ComPtr<INetworkAdapter> adapter; - hr = profile->get_NetworkAdapter(&adapter); - // Indicates that no internet connection is available/the device is in airplane mode - if (hr == E_INVALIDARG) - return 0; - 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; - - QList<HostNameInfo> hostList; - - ComPtr<INetworkInformationStatics> hostNameStatics; - HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &hostNameStatics); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr<IVectorView<HostName *>> hostNames; - hr = hostNameStatics->GetHostNames(&hostNames); - Q_ASSERT_SUCCEEDED(hr); - if (!hostNames) - return interfaces; - - unsigned int hostNameCount; - hr = hostNames->get_Size(&hostNameCount); - Q_ASSERT_SUCCEEDED(hr); - for (unsigned i = 0; i < hostNameCount; ++i) { - HostNameInfo hostInfo; - ComPtr<IHostName> hostName; - hr = hostNames->GetAt(i, &hostName); - Q_ASSERT_SUCCEEDED(hr); - - HostNameType type; - hr = hostName->get_Type(&type); - Q_ASSERT_SUCCEEDED(hr); - if (type == HostNameType_DomainName) - continue; - - ComPtr<IIPInformation> ipInformation; - hr = hostName->get_IPInformation(&ipInformation); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<INetworkAdapter> currentAdapter; - hr = ipInformation->get_NetworkAdapter(¤tAdapter); - Q_ASSERT_SUCCEEDED(hr); - - hr = currentAdapter->get_NetworkAdapterId(&hostInfo.adapterId); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr<IReference<unsigned char>> prefixLengthReference; - hr = ipInformation->get_PrefixLength(&prefixLengthReference); - Q_ASSERT_SUCCEEDED(hr); - - hr = prefixLengthReference->get_Value(&hostInfo.prefixLength); - Q_ASSERT_SUCCEEDED(hr); - - // invalid prefixes - if ((type == HostNameType_Ipv4 && hostInfo.prefixLength > 32) - || (type == HostNameType_Ipv6 && hostInfo.prefixLength > 128)) - continue; - - HString name; - hr = hostName->get_CanonicalName(name.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - UINT32 length; - PCWSTR rawString = name.GetRawBuffer(&length); - hostInfo.address = QString::fromWCharArray(rawString, length); - - hostList << hostInfo; - } - - INetworkInformationStatics *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; - hr = networkInfoStatics->GetConnectionProfiles(&connectionProfiles); - Q_ASSERT_SUCCEEDED(hr); - if (!connectionProfiles) - return interfaces; - - unsigned int size; - hr = connectionProfiles->get_Size(&size); - Q_ASSERT_SUCCEEDED(hr); - for (unsigned int i = 0; i < size; ++i) { - ComPtr<IConnectionProfile> profile; - hr = connectionProfiles->GetAt(i, &profile); - Q_ASSERT_SUCCEEDED(hr); - - iface = interfaceFromProfile(profile.Get(), &hostList); - if (iface) { - iface->index = i + 1; - interfaces << iface; - } - } - return interfaces; -} - -QList<QNetworkInterfacePrivate *> QNetworkInterfaceManager::scan() -{ - return interfaceListing(); -} - -QString QHostInfo::localDomainName() -{ - return QString(); -} - -QT_END_NAMESPACE - -#endif // QT_NO_NETWORKINTERFACE diff --git a/src/network/kernel/qnetworkproxy_win.cpp b/src/network/kernel/qnetworkproxy_win.cpp index 9dfe32d5f7..c4dc33f66f 100644 --- a/src/network/kernel/qnetworkproxy_win.cpp +++ b/src/network/kernel/qnetworkproxy_win.cpp @@ -367,7 +367,6 @@ static QList<QNetworkProxy> parseServerList(const QNetworkProxyQuery &query, con return removeDuplicateProxies(result); } -#if !defined(Q_OS_WINRT) namespace { class QRegistryWatcher { Q_DISABLE_COPY_MOVE(QRegistryWatcher) @@ -421,7 +420,6 @@ private: QVector<HKEY> m_registryHandles; }; } // namespace -#endif // !defined(Q_OS_WINRT) class QWindowsSystemProxy { @@ -441,9 +439,7 @@ public: QStringList proxyServerList; QStringList proxyBypass; QList<QNetworkProxy> defaultResult; -#if !defined(Q_OS_WINRT) QRegistryWatcher proxySettingsWatcher; -#endif bool initialized; bool functional; bool isAutoConfig; @@ -477,9 +473,7 @@ void QWindowsSystemProxy::reset() void QWindowsSystemProxy::init() { bool proxySettingsChanged = false; -#if !defined(Q_OS_WINRT) proxySettingsChanged = proxySettingsWatcher.hasChanged(); -#endif if (initialized && !proxySettingsChanged) return; @@ -487,12 +481,10 @@ void QWindowsSystemProxy::init() reset(); -#if !defined(Q_OS_WINRT) proxySettingsWatcher.clear(); // needs reset to trigger a new detection proxySettingsWatcher.addLocation(HKEY_CURRENT_USER, QStringLiteral("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings")); proxySettingsWatcher.addLocation(HKEY_LOCAL_MACHINE, QStringLiteral("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings")); proxySettingsWatcher.addLocation(HKEY_LOCAL_MACHINE, QStringLiteral("Software\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings")); -#endif // load the winhttp.dll library QSystemLibrary lib(L"winhttp"); diff --git a/src/network/network.pro b/src/network/network.pro index 7bd54fd12e..b1bfc51f90 100644 --- a/src/network/network.pro +++ b/src/network/network.pro @@ -21,9 +21,4 @@ include(ssl/ssl.pri) QMAKE_LIBS += $$QMAKE_LIBS_NETWORK -MODULE_WINRT_CAPABILITIES = \ - internetClient \ - internetClientServer \ - privateNetworkClientServer - load(qt_module) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 03d69d6204..0f9e22d131 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -948,7 +948,7 @@ void QAbstractSocketPrivate::resolveProxy(const QString &hostname, quint16 port) } #endif // !QT_NO_NETWORKPROXY -#if !defined(QT_NO_NETWORKPROXY) || defined(Q_OS_WINRT) +#if !defined(QT_NO_NETWORKPROXY) /*! \internal @@ -990,7 +990,7 @@ void QAbstractSocketPrivate::startConnectingByName(const QString &host) emit q->stateChanged(state); } -#endif // !QT_NO_NETWORKPROXY || Q_OS_WINRT +#endif // !QT_NO_NETWORKPROXY /*! \internal @@ -1713,7 +1713,6 @@ void QAbstractSocket::connectToHost(const QString &hostName, quint16 port, QIODevice::open(openMode); d->readChannelCount = d->writeChannelCount = 0; -#ifndef Q_OS_WINRT d->state = HostLookupState; emit stateChanged(d->state); @@ -1751,10 +1750,6 @@ void QAbstractSocket::connectToHost(const QString &hostName, quint16 port, (d->state == ConnectingState || d->state == HostLookupState) ? " (connection in progress)" : ""); #endif -#else // !Q_OS_WINRT - // On WinRT we should always connect by name. Lookup and proxy handling are done by the API. - d->startConnectingByName(hostName); -#endif } /*! \overload diff --git a/src/network/socket/qabstractsocketengine.cpp b/src/network/socket/qabstractsocketengine.cpp index 44139ff81d..50462fb11f 100644 --- a/src/network/socket/qabstractsocketengine.cpp +++ b/src/network/socket/qabstractsocketengine.cpp @@ -39,11 +39,7 @@ #include "qabstractsocketengine_p.h" -#ifndef Q_OS_WINRT #include "qnativesocketengine_p.h" -#else -#include "qnativesocketengine_winrt_p.h" -#endif #include "qmutex.h" #include "qnetworkproxy.h" diff --git a/src/network/socket/qlocalserver.cpp b/src/network/socket/qlocalserver.cpp index 5ca2db70b9..251b785dfd 100644 --- a/src/network/socket/qlocalserver.cpp +++ b/src/network/socket/qlocalserver.cpp @@ -195,7 +195,7 @@ QLocalServer::SocketOptions QLocalServer::socketOptions() const \l{https://msdn.microsoft.com/en-us/library/windows/desktop/ms740522(v=vs.85).aspx} {Winsock 2 Socket Handle}. - \li With WinRT and on INTEGRITY, the returned value is the + \li On INTEGRITY, the returned value is the QTcpServer socket descriptor and the type is defined by \l{QTcpServer::socketDescriptor}{socketDescriptor}. diff --git a/src/network/socket/qlocalsocket.cpp b/src/network/socket/qlocalsocket.cpp index 60e753e2e2..ab3fcecf66 100644 --- a/src/network/socket/qlocalsocket.cpp +++ b/src/network/socket/qlocalsocket.cpp @@ -135,7 +135,7 @@ QT_BEGIN_NAMESPACE \l{https://msdn.microsoft.com/en-us/library/windows/desktop/ms740522(v=vs.85).aspx} {Winsock 2 Socket Handle}. - \li With WinRT and on INTEGRITY, the returned value is the + \li On INTEGRITY, the returned value is the QTcpSocket socket descriptor and the type is defined by \l{QTcpSocket::socketDescriptor}{socketDescriptor}. diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp index ad625b758e..6667a6b097 100644 --- a/src/network/socket/qnativesocketengine.cpp +++ b/src/network/socket/qnativesocketengine.cpp @@ -195,7 +195,7 @@ QNativeSocketEnginePrivate::QNativeSocketEnginePrivate() : writeNotifier(nullptr), exceptNotifier(nullptr) { -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) +#if defined(Q_OS_WIN) QSysInfo::machineHostName(); // this initializes ws2_32.dll #endif } diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp deleted file mode 100644 index 2eb2141fee..0000000000 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ /dev/null @@ -1,1815 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qt_windows.h> - -#include "qnativesocketengine_winrt_p.h" - -#include <qcoreapplication.h> -#include <qabstracteventdispatcher.h> -#include <qsocketnotifier.h> -#include <qdatetime.h> -#include <qnetworkinterface.h> -#include <qelapsedtimer.h> -#include <qthread.h> -#include <qabstracteventdispatcher.h> -#include <qfunctions_winrt.h> - -#include <private/qthread_p.h> -#include <private/qabstractsocket_p.h> -#include <private/qeventdispatcher_winrt_p.h> - -#ifndef QT_NO_SSL -#include <QSslSocket> -#endif - -#include <functional> -#include <wrl.h> -#include <windows.foundation.collections.h> -#include <windows.storage.streams.h> -#include <windows.networking.h> -#include <windows.networking.sockets.h> -#include <robuffer.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::Storage::Streams; -using namespace ABI::Windows::Networking; -using namespace ABI::Windows::Networking::Connectivity; -using namespace ABI::Windows::Networking::Sockets; -#if _MSC_VER >= 1900 -using namespace ABI::Windows::Security::EnterpriseData; -#endif - -typedef ITypedEventHandler<StreamSocketListener *, StreamSocketListenerConnectionReceivedEventArgs *> ClientConnectedHandler; -typedef ITypedEventHandler<DatagramSocket *, DatagramSocketMessageReceivedEventArgs *> DatagramReceivedHandler; -typedef IAsyncOperationWithProgressCompletedHandler<IBuffer *, UINT32> SocketReadCompletedHandler; -typedef IAsyncOperationWithProgressCompletedHandler<UINT32, UINT32> SocketWriteCompletedHandler; -typedef IAsyncOperationWithProgress<IBuffer *, UINT32> IAsyncBufferOperation; - -QT_BEGIN_NAMESPACE - -Q_LOGGING_CATEGORY(lcNetworkSocket, "qt.network.socket"); -Q_LOGGING_CATEGORY(lcNetworkSocketVerbose, "qt.network.socket.verbose"); - -#if _MSC_VER >= 1900 -static HRESULT qt_winrt_try_create_thread_network_context(QString host, ComPtr<IThreadNetworkContext> &context) -{ - HRESULT hr; - ComPtr<IProtectionPolicyManagerStatics> protectionPolicyManager; - - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Security_EnterpriseData_ProtectionPolicyManager).Get(), - &protectionPolicyManager); - RETURN_HR_IF_FAILED("Could not access ProtectionPolicyManager statics."); - - ComPtr<IHostNameFactory> hostNameFactory; - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), - &hostNameFactory); - RETURN_HR_IF_FAILED("Could not access HostName factory."); - - ComPtr<IHostName> hostName; - HStringReference hostRef(reinterpret_cast<LPCWSTR>(host.utf16()), host.length()); - hr = hostNameFactory->CreateHostName(hostRef.Get(), &hostName); - RETURN_HR_IF_FAILED("Could not create hostname."); - - ComPtr<IAsyncOperation<HSTRING>> op; - hr = protectionPolicyManager->GetPrimaryManagedIdentityForNetworkEndpointAsync(hostName.Get(), &op); - RETURN_HR_IF_FAILED("Could not get identity operation."); - - HSTRING hIdentity; - hr = QWinRTFunctions::await(op, &hIdentity); - RETURN_HR_IF_FAILED("Could not wait for identity operation."); - - // Implies there is no need for a network context for this address - if (hIdentity == nullptr) - return S_OK; - - hr = protectionPolicyManager->CreateCurrentThreadNetworkContext(hIdentity, &context); - RETURN_HR_IF_FAILED("Could not create thread network context"); - - return S_OK; -} -#endif // _MSC_VER >= 1900 - -typedef QHash<qintptr, IStreamSocket *> TcpSocketHash; - -struct SocketHandler -{ - SocketHandler() : socketCount(0) {} - qintptr socketCount; - TcpSocketHash pendingTcpSockets; -}; - -Q_GLOBAL_STATIC(SocketHandler, gSocketHandler) - -struct SocketGlobal -{ - SocketGlobal() - { - HRESULT hr; - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(), - &bufferFactory); - Q_ASSERT_SUCCEEDED(hr); - } - - ComPtr<IBufferFactory> bufferFactory; -}; -Q_GLOBAL_STATIC(SocketGlobal, g) - -#define READ_BUFFER_SIZE 65536 - -static inline QString qt_QStringFromHString(const HString &string) -{ - UINT32 length; - PCWSTR rawString = string.GetRawBuffer(&length); - return QString::fromWCharArray(rawString, length); -} - -class SocketEngineWorker : public QObject -{ - Q_OBJECT -public: - SocketEngineWorker(QNativeSocketEnginePrivate *engine) - : enginePrivate(engine) - { - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << engine; - } - - ~SocketEngineWorker() - { - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO; - if (Q_UNLIKELY(initialReadOp)) { - qCDebug(lcNetworkSocket) << Q_FUNC_INFO << "Closing initial read operation"; - ComPtr<IAsyncInfo> info; - HRESULT hr = initialReadOp.As(&info); - Q_ASSERT_SUCCEEDED(hr); - if (info) { - hr = info->Cancel(); - Q_ASSERT_SUCCEEDED(hr); - hr = info->Close(); - Q_ASSERT_SUCCEEDED(hr); - } - } - - if (readOp) { - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << "Closing read operation"; - ComPtr<IAsyncInfo> info; - HRESULT hr = readOp.As(&info); - Q_ASSERT_SUCCEEDED(hr); - if (info) { - hr = info->Cancel(); - Q_ASSERT_SUCCEEDED(hr); - hr = info->Close(); - Q_ASSERT_SUCCEEDED(hr); - } - } - - if (connectOp) { - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << "Closing connect operation"; - ComPtr<IAsyncInfo> info; - HRESULT hr = connectOp.As(&info); - Q_ASSERT_SUCCEEDED(hr); - if (info) { - hr = info->Cancel(); - Q_ASSERT_SUCCEEDED(hr); - hr = info->Close(); - Q_ASSERT_SUCCEEDED(hr); - } - } - } - -signals: - void connectOpFinished(bool success, QAbstractSocket::SocketError error, WinRTSocketEngine::ErrorString errorString); - void newDataReceived(); - void socketErrorOccured(QAbstractSocket::SocketError error); - -public: - void startReading() - { - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO; - ComPtr<IBuffer> buffer; - HRESULT hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<IInputStream> stream; - hr = tcpSocket->get_InputStream(&stream); - Q_ASSERT_SUCCEEDED(hr); - hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, initialReadOp.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - enginePrivate->socketState = QAbstractSocket::ConnectedState; - hr = initialReadOp->put_Completed(Callback<SocketReadCompletedHandler>(this, &SocketEngineWorker::onReadyRead).Get()); - Q_ASSERT_SUCCEEDED(hr); - } - - HRESULT onConnectOpFinished(IAsyncAction *action, AsyncStatus) - { - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO; - HRESULT hr = action->GetResults(); - if (FAILED(hr)) { - if (hr == HRESULT_FROM_WIN32(WSAETIMEDOUT)) { - emit connectOpFinished(false, QAbstractSocket::NetworkError, WinRTSocketEngine::ConnectionTimeOutErrorString); - return S_OK; - } else if (hr == HRESULT_FROM_WIN32(WSAEHOSTUNREACH)) { - emit connectOpFinished(false, QAbstractSocket::HostNotFoundError, WinRTSocketEngine::HostUnreachableErrorString); - return S_OK; - } else if (hr == HRESULT_FROM_WIN32(WSAECONNREFUSED)) { - emit connectOpFinished(false, QAbstractSocket::ConnectionRefusedError, WinRTSocketEngine::ConnectionRefusedErrorString); - return S_OK; - } else { - emit connectOpFinished(false, QAbstractSocket::UnknownSocketError, WinRTSocketEngine::UnknownSocketErrorString); - return S_OK; - } - } - - // The callback might be triggered several times if we do not cancel/reset it here - if (connectOp) { - ComPtr<IAsyncInfo> info; - hr = connectOp.As(&info); - Q_ASSERT_SUCCEEDED(hr); - if (info) { - hr = info->Cancel(); - Q_ASSERT_SUCCEEDED(hr); - hr = info->Close(); - Q_ASSERT_SUCCEEDED(hr); - } - hr = connectOp.Reset(); - Q_ASSERT_SUCCEEDED(hr); - } - - emit connectOpFinished(true, QAbstractSocket::UnknownSocketError, WinRTSocketEngine::UnknownSocketErrorString); - return S_OK; - } - - HRESULT OnNewDatagramReceived(IDatagramSocket *, IDatagramSocketMessageReceivedEventArgs *args) - { - qCDebug(lcNetworkSocketVerbose) << this << Q_FUNC_INFO; - WinRtDatagram datagram; - QHostAddress returnAddress; - ComPtr<IHostName> remoteHost; - HRESULT hr = args->get_RemoteAddress(&remoteHost); - RETURN_OK_IF_FAILED("Could not obtain remote host"); - HString remoteHostString; - hr = remoteHost->get_CanonicalName(remoteHostString.GetAddressOf()); - RETURN_OK_IF_FAILED("Could not obtain remote host's canonical name"); - returnAddress.setAddress(qt_QStringFromHString(remoteHostString)); - datagram.header.senderAddress = returnAddress; - HString remotePort; - hr = args->get_RemotePort(remotePort.GetAddressOf()); - RETURN_OK_IF_FAILED("Could not obtain remote port"); - datagram.header.senderPort = qt_QStringFromHString(remotePort).toInt(); - - ComPtr<IDataReader> reader; - hr = args->GetDataReader(&reader); - RETURN_OK_IF_FAILED("Could not obtain data reader"); - quint32 length; - hr = reader->get_UnconsumedBufferLength(&length); - RETURN_OK_IF_FAILED("Could not obtain unconsumed buffer length"); - datagram.data.resize(length); - hr = reader->ReadBytes(length, reinterpret_cast<BYTE *>(datagram.data.data())); - RETURN_OK_IF_FAILED("Could not read datagram"); - - QMutexLocker locker(&mutex); - // Notify the engine about new datagrams being present at the next event loop iteration - if (emitDataReceived) - emit newDataReceived(); - pendingDatagrams << datagram; - - return S_OK; - } - - HRESULT onReadyRead(IAsyncBufferOperation *asyncInfo, AsyncStatus status) - { - qCDebug(lcNetworkSocketVerbose) << this << Q_FUNC_INFO; - if (asyncInfo == initialReadOp.Get()) { - initialReadOp.Reset(); - } else if (asyncInfo == readOp.Get()) { - readOp.Reset(); - } else { - Q_ASSERT(false); - } - - // A read in UnconnectedState will close the socket and return -1 and thus tell the caller, - // that the connection was closed. The socket cannot be closed here, as the subsequent read - // might fail then. - if (status == Error || status == Canceled) { - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << "Remote host closed"; - emit socketErrorOccured(QAbstractSocket::RemoteHostClosedError); - return S_OK; - } - - ComPtr<IBuffer> buffer; - HRESULT hr = asyncInfo->GetResults(&buffer); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to get read results buffer"); - emit socketErrorOccured(QAbstractSocket::UnknownSocketError); - return S_OK; - } - - UINT32 bufferLength; - hr = buffer->get_Length(&bufferLength); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to get buffer length"); - emit socketErrorOccured(QAbstractSocket::UnknownSocketError); - return S_OK; - } - // A zero sized buffer length signals, that the remote host closed the connection. The socket - // cannot be closed though, as the following read might have socket descriptor -1 and thus and - // the closing of the socket won't be communicated to the caller. So only the error is set. The - // actual socket close happens inside of read. - if (!bufferLength) { - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << "Remote host closed"; - emit socketErrorOccured(QAbstractSocket::RemoteHostClosedError); - return S_OK; - } - - ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess; - hr = buffer.As(&byteArrayAccess); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to get cast buffer"); - emit socketErrorOccured(QAbstractSocket::UnknownSocketError); - return S_OK; - } - byte *data; - hr = byteArrayAccess->Buffer(&data); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to access buffer data"); - emit socketErrorOccured(QAbstractSocket::UnknownSocketError); - return S_OK; - } - - QByteArray newData(reinterpret_cast<const char*>(data), qint64(bufferLength)); - - QMutexLocker readLocker(&mutex); - emit newDataReceived(); - pendingData.append(newData); - readLocker.unlock(); - - hr = QEventDispatcherWinRT::runOnXamlThread([buffer, this]() { - UINT32 readBufferLength; - ComPtr<IInputStream> stream; - HRESULT hr = tcpSocket->get_InputStream(&stream); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to obtain input stream"); - emit socketErrorOccured(QAbstractSocket::UnknownSocketError); - return S_OK; - } - - // Reuse the stream buffer - hr = buffer->get_Capacity(&readBufferLength); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to get buffer capacity"); - emit socketErrorOccured(QAbstractSocket::UnknownSocketError); - return S_OK; - } - hr = buffer->put_Length(0); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to set buffer length"); - emit socketErrorOccured(QAbstractSocket::UnknownSocketError); - return S_OK; - } - - hr = stream->ReadAsync(buffer.Get(), readBufferLength, InputStreamOptions_Partial, &readOp); - if (FAILED(hr)) { - qErrnoWarning(hr, "onReadyRead(): Could not read into socket stream buffer."); - emit socketErrorOccured(QAbstractSocket::UnknownSocketError); - return S_OK; - } - hr = readOp->put_Completed(Callback<SocketReadCompletedHandler>(this, &SocketEngineWorker::onReadyRead).Get()); - if (FAILED(hr)) { - qErrnoWarning(hr, "onReadyRead(): Failed to set socket read callback."); - emit socketErrorOccured(QAbstractSocket::UnknownSocketError); - return S_OK; - } - return S_OK; - }); - Q_ASSERT_SUCCEEDED(hr); - return S_OK; - } - - void setTcpSocket(ComPtr<IStreamSocket> socket) { tcpSocket = socket; } - -private: - friend class QNativeSocketEngine; - ComPtr<IStreamSocket> tcpSocket; - - QList<WinRtDatagram> pendingDatagrams; - bool emitDataReceived = true; - QByteArray pendingData; - - // Protects pendingData/pendingDatagrams which are accessed from native callbacks - QMutex mutex; - - ComPtr<IAsyncAction> connectOp; - ComPtr<IAsyncOperationWithProgress<IBuffer *, UINT32>> initialReadOp; - ComPtr<IAsyncOperationWithProgress<IBuffer *, UINT32>> readOp; - - QNativeSocketEnginePrivate *enginePrivate; -}; - -static QByteArray socketDescription(const QAbstractSocketEngine *s) -{ - QByteArray result; - if (const QObject *o = s->parent()) { - const QString name = o->objectName(); - if (!name.isEmpty()) { - result += '"'; - result += name.toLocal8Bit(); - result += "\"/"; - } - result += o->metaObject()->className(); - } - return result; -} - -// Common constructs -#define Q_CHECK_VALID_SOCKETLAYER(function, returnValue) do { \ - if (!isValid()) { \ - qWarning(""#function" was called on an uninitialized socket device"); \ - return returnValue; \ - } } while (0) -#define Q_CHECK_INVALID_SOCKETLAYER(function, returnValue) do { \ - if (isValid()) { \ - qWarning(""#function" was called on an already initialized socket device"); \ - return returnValue; \ - } } while (0) -#define Q_CHECK_STATE(function, checkState, returnValue) do { \ - if (d->socketState != (checkState)) { \ - qWarning(""#function" was not called in "#checkState); \ - return (returnValue); \ - } } while (0) -#define Q_CHECK_NOT_STATE(function, checkState, returnValue) do { \ - if (d->socketState == (checkState)) { \ - qWarning(""#function" was called in "#checkState); \ - return (returnValue); \ - } } while (0) -#define Q_CHECK_STATES(function, state1, state2, returnValue) do { \ - if (d->socketState != (state1) && d->socketState != (state2)) { \ - qWarning(""#function" was called" \ - " not in "#state1" or "#state2); \ - return (returnValue); \ - } } while (0) -#define Q_CHECK_STATES3(function, state1, state2, state3, returnValue) do { \ - if (d->socketState != (state1) && d->socketState != (state2) && d->socketState != (state3)) { \ - qWarning(""#function" was called" \ - " not in "#state1", "#state2" or "#state3); \ - return (returnValue); \ - } } while (0) -#define Q_CHECK_TYPE(function, type, returnValue) do { \ - if (d->socketType != (type)) { \ - qWarning(#function" was called by a" \ - " socket other than "#type""); \ - return (returnValue); \ - } } while (0) -#define Q_TR(a) QT_TRANSLATE_NOOP(QNativeSocketEngine, a) - -template <typename T> -static AsyncStatus opStatus(const ComPtr<T> &op) -{ - ComPtr<IAsyncInfo> info; - HRESULT hr = op.As(&info); - Q_ASSERT_SUCCEEDED(hr); - AsyncStatus status; - hr = info->get_Status(&status); - Q_ASSERT_SUCCEEDED(hr); - return status; -} - -static qint64 writeIOStream(ComPtr<IOutputStream> stream, const char *data, qint64 len) -{ - qCDebug(lcNetworkSocket) << Q_FUNC_INFO << data << len; - ComPtr<IBuffer> buffer; - HRESULT hr = g->bufferFactory->Create(len, &buffer); - Q_ASSERT_SUCCEEDED(hr); - hr = buffer->put_Length(len); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess; - hr = buffer.As(&byteArrayAccess); - Q_ASSERT_SUCCEEDED(hr); - byte *bytes; - hr = byteArrayAccess->Buffer(&bytes); - Q_ASSERT_SUCCEEDED(hr); - memcpy(bytes, data, len); - ComPtr<IAsyncOperationWithProgress<UINT32, UINT32>> op; - hr = stream->WriteAsync(buffer.Get(), &op); - RETURN_IF_FAILED("Failed to write to stream", return -1); - UINT32 bytesWritten; - hr = QWinRTFunctions::await(op, &bytesWritten); - RETURN_IF_FAILED("Failed to write to stream", return -1); - return bytesWritten; -} - -QNativeSocketEngine::QNativeSocketEngine(QObject *parent) - : QAbstractSocketEngine(*new QNativeSocketEnginePrivate(), parent) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << parent; - qRegisterMetaType<WinRtDatagram>(); - qRegisterMetaType<WinRTSocketEngine::ErrorString>(); - Q_D(QNativeSocketEngine); -#ifndef QT_NO_SSL - if (parent) - d->sslSocket = qobject_cast<QSslSocket *>(parent->parent()); -#endif - - connect(this, &QNativeSocketEngine::connectionReady, - this, &QNativeSocketEngine::connectionNotification, Qt::QueuedConnection); - connect(this, &QNativeSocketEngine::readReady, - this, &QNativeSocketEngine::processReadReady, Qt::QueuedConnection); - connect(this, &QNativeSocketEngine::writeReady, - this, &QNativeSocketEngine::writeNotification, Qt::QueuedConnection); - connect(d->worker, &SocketEngineWorker::connectOpFinished, - this, &QNativeSocketEngine::handleConnectOpFinished, Qt::QueuedConnection); - connect(d->worker, &SocketEngineWorker::newDataReceived, this, &QNativeSocketEngine::handleNewData, Qt::QueuedConnection); - connect(d->worker, &SocketEngineWorker::socketErrorOccured, - this, &QNativeSocketEngine::handleTcpError, Qt::QueuedConnection); -} - -QNativeSocketEngine::~QNativeSocketEngine() -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO; - close(); -} - -bool QNativeSocketEngine::initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << type << protocol; - Q_D(QNativeSocketEngine); - if (isValid()) - close(); - - // Create the socket - if (!d->createNewSocket(type, protocol)) - return false; - - if (type == QAbstractSocket::UdpSocket) { - // Set the broadcasting flag if it's a UDP socket. - if (!setOption(BroadcastSocketOption, 1)) { - d->setError(QAbstractSocket::UnsupportedSocketOperationError, - WinRTSocketEngine::BroadcastingInitFailedErrorString); - close(); - return false; - } - - // Set some extra flags that are interesting to us, but accept failure - setOption(ReceivePacketInformation, 1); - setOption(ReceiveHopLimit, 1); - } - - - // Make sure we receive out-of-band data - if (type == QAbstractSocket::TcpSocket - && !setOption(ReceiveOutOfBandData, 1)) { - qWarning("QNativeSocketEngine::initialize unable to inline out-of-band data"); - } - - - d->socketType = type; - d->socketProtocol = protocol; - return true; -} - -bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << socketDescriptor << socketState; - Q_D(QNativeSocketEngine); - - if (isValid()) - close(); - - // Currently, only TCP sockets are initialized this way. - IStreamSocket *socket = gSocketHandler->pendingTcpSockets.take(socketDescriptor); - d->socketDescriptor = qintptr(socket); - d->socketType = QAbstractSocket::TcpSocket; - - if (!d->socketDescriptor || !d->fetchConnectionParameters()) { - d->setError(QAbstractSocket::UnsupportedSocketOperationError, - WinRTSocketEngine::InvalidSocketErrorString); - d->socketDescriptor = -1; - return false; - } - - // Start processing incoming data - if (d->socketType == QAbstractSocket::TcpSocket) { - HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([d, socket, this]() { - d->worker->setTcpSocket(socket); - d->worker->startReading(); - return S_OK; - }); - if (FAILED(hr)) - return false; - } else { - d->socketState = socketState; - } - - return true; -} - -qintptr QNativeSocketEngine::socketDescriptor() const -{ - Q_D(const QNativeSocketEngine); - return d->socketDescriptor; -} - -bool QNativeSocketEngine::isValid() const -{ - Q_D(const QNativeSocketEngine); - return d->socketDescriptor != -1; -} - -bool QNativeSocketEngine::connectToHost(const QHostAddress &address, quint16 port) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << address << port; - Q_D(QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::connectToHost(), false); - Q_CHECK_STATES3(QNativeSocketEngine::connectToHost(), QAbstractSocket::BoundState, - QAbstractSocket::UnconnectedState, QAbstractSocket::ConnectingState, false); - const QString addressString = address.toString(); - return connectToHostByName(addressString, port); -} - -bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << name << port; - Q_D(QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::connectToHostByName(), false); - Q_CHECK_STATES3(QNativeSocketEngine::connectToHostByName(), QAbstractSocket::BoundState, - QAbstractSocket::UnconnectedState, QAbstractSocket::ConnectingState, false); - HRESULT hr; - -#if _MSC_VER >= 1900 - ComPtr<IThreadNetworkContext> networkContext; - if (!qEnvironmentVariableIsEmpty("QT_WINRT_USE_THREAD_NETWORK_CONTEXT")) { - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << "Creating network context"; - hr = qt_winrt_try_create_thread_network_context(name, networkContext); - if (FAILED(hr)) { - setError(QAbstractSocket::ConnectionRefusedError, QLatin1String("Could not create thread network context.")); - d->socketState = QAbstractSocket::ConnectedState; - return true; - } - } -#endif // _MSC_VER >= 1900 - - HStringReference hostNameRef(reinterpret_cast<LPCWSTR>(name.utf16())); - ComPtr<IHostNameFactory> hostNameFactory; - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), - &hostNameFactory); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<IHostName> remoteHost; - hr = hostNameFactory->CreateHostName(hostNameRef.Get(), &remoteHost); - RETURN_FALSE_IF_FAILED("QNativeSocketEngine::connectToHostByName: Could not create hostname."); - - const QString portString = QString::number(port); - HStringReference portReference(reinterpret_cast<LPCWSTR>(portString.utf16())); - if (d->socketType == QAbstractSocket::TcpSocket) - hr = d->tcpSocket()->ConnectAsync(remoteHost.Get(), portReference.Get(), &d->worker->connectOp); - else if (d->socketType == QAbstractSocket::UdpSocket) - hr = d->udpSocket()->ConnectAsync(remoteHost.Get(), portReference.Get(), &d->worker->connectOp); - if (hr == E_ACCESSDENIED) { - qErrnoWarning(hr, "QNativeSocketEngine::connectToHostByName: Unable to connect to host (%s:%hu/%s). " - "Please check your manifest capabilities.", - qPrintable(name), port, socketDescription(this).constData()); - return false; - } - Q_ASSERT_SUCCEEDED(hr); - -#if _MSC_VER >= 1900 - if (networkContext != nullptr) { - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << "Closing network context"; - ComPtr<IClosable> networkContextCloser; - hr = networkContext.As(&networkContextCloser); - Q_ASSERT_SUCCEEDED(hr); - hr = networkContextCloser->Close(); - Q_ASSERT_SUCCEEDED(hr); - } -#endif // _MSC_VER >= 1900 - - d->socketState = QAbstractSocket::ConnectingState; - QEventDispatcherWinRT::runOnXamlThread([d, &hr]() { - hr = d->worker->connectOp->put_Completed(Callback<IAsyncActionCompletedHandler>( - d->worker, &SocketEngineWorker::onConnectOpFinished).Get()); - RETURN_OK_IF_FAILED("connectToHostByName: Could not register \"connectOp\" callback"); - return S_OK; - }); - if (FAILED(hr)) - return false; - - return d->socketState == QAbstractSocket::ConnectedState; -} - -bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << address << port; - Q_D(QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::bind(), false); - Q_CHECK_STATE(QNativeSocketEngine::bind(), QAbstractSocket::UnconnectedState, false); - - HRESULT hr; - // runOnXamlThread may only return S_OK (will assert otherwise) so no need to check its result. - // hr is set inside the lambda though. If an error occurred hr will point that out. - bool specificErrorSet = false; - QEventDispatcherWinRT::runOnXamlThread([address, d, &hr, port, &specificErrorSet, this]() { - ComPtr<IHostName> hostAddress; - - if (address != QHostAddress::Any && address != QHostAddress::AnyIPv4 && address != QHostAddress::AnyIPv6) { - ComPtr<IHostNameFactory> hostNameFactory; - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), - &hostNameFactory); - RETURN_OK_IF_FAILED("QNativeSocketEngine::bind: Could not obtain hostname factory"); - const QString addressString = address.toString(); - HStringReference addressRef(reinterpret_cast<LPCWSTR>(addressString.utf16())); - hr = hostNameFactory->CreateHostName(addressRef.Get(), &hostAddress); - RETURN_OK_IF_FAILED("QNativeSocketEngine::bind: Could not create hostname."); - } - - QString portQString = port ? QString::number(port) : QString(); - HStringReference portString(reinterpret_cast<LPCWSTR>(portQString.utf16())); - - ComPtr<IAsyncAction> op; - if (d->socketType == QAbstractSocket::TcpSocket) { - if (!d->tcpListener) { - hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocketListener).Get(), - &d->tcpListener); - RETURN_OK_IF_FAILED("QNativeSocketEngine::bind: Could not create tcp listener"); - } - - hr = d->tcpListener->add_ConnectionReceived( - Callback<ClientConnectedHandler>(d, &QNativeSocketEnginePrivate::handleClientConnection).Get(), - &d->connectionToken); - RETURN_OK_IF_FAILED("QNativeSocketEngine::bind: Could not register client connection callback"); - hr = d->tcpListener->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); - } else if (d->socketType == QAbstractSocket::UdpSocket) { - hr = d->udpSocket()->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); - } - if (hr == E_ACCESSDENIED) { - qErrnoWarning(hr, "Unable to bind socket (%s:%hu/%s). Please check your manifest capabilities.", - qPrintable(address.toString()), port, socketDescription(this).constData()); - d->setError(QAbstractSocket::SocketAccessError, - WinRTSocketEngine::AccessErrorString); - d->socketState = QAbstractSocket::UnconnectedState; - specificErrorSet = true; - return S_OK; - } - RETURN_OK_IF_FAILED("QNativeSocketEngine::bind: Unable to bind socket"); - - hr = QWinRTFunctions::await(op); - if (hr == 0x80072741) { // The requested address is not valid in its context - d->setError(QAbstractSocket::SocketAddressNotAvailableError, - WinRTSocketEngine::AddressNotAvailableErrorString); - d->socketState = QAbstractSocket::UnconnectedState; - specificErrorSet = true; - return S_OK; - // Only one usage of each socket address (protocol/network address/port) is normally permitted - } else if (hr == 0x80072740) { - d->setError(QAbstractSocket::AddressInUseError, - WinRTSocketEngine::AddressInuseErrorString); - d->socketState = QAbstractSocket::UnconnectedState; - specificErrorSet = true; - return S_OK; - } - RETURN_OK_IF_FAILED("QNativeSocketEngine::bind: Could not wait for bind to finish"); - return S_OK; - }); - if (FAILED(hr)) { - if (!specificErrorSet) { - d->setError(QAbstractSocket::UnknownSocketError, - WinRTSocketEngine::UnknownSocketErrorString); - d->socketState = QAbstractSocket::UnconnectedState; - } - return false; - } - - d->socketState = QAbstractSocket::BoundState; - return d->fetchConnectionParameters(); -} - -bool QNativeSocketEngine::listen() -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO; - Q_D(QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::listen(), false); - Q_CHECK_STATE(QNativeSocketEngine::listen(), QAbstractSocket::BoundState, false); -#if QT_CONFIG(sctp) - Q_CHECK_TYPES(QNativeSocketEngine::listen(), QAbstractSocket::TcpSocket, - QAbstractSocket::SctpSocket, false); -#else - Q_CHECK_TYPE(QNativeSocketEngine::listen(), QAbstractSocket::TcpSocket, false); -#endif - - if (d->tcpListener && d->socketDescriptor != -1) { - d->socketState = QAbstractSocket::ListeningState; - return true; - } - return false; -} - -int QNativeSocketEngine::accept() -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO; - Q_D(QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::accept(), -1); - Q_CHECK_STATE(QNativeSocketEngine::accept(), QAbstractSocket::ListeningState, -1); -#if QT_CONFIG(sctp) - Q_CHECK_TYPES(QNativeSocketEngine::accept(), QAbstractSocket::TcpSocket, - QAbstractSocket::SctpSocket, -1); -#else - Q_CHECK_TYPE(QNativeSocketEngine::accept(), QAbstractSocket::TcpSocket, -1); -#endif - - if (d->socketDescriptor == -1 || d->pendingConnections.isEmpty()) { - d->setError(QAbstractSocket::TemporaryError, WinRTSocketEngine::TemporaryErrorString); - return -1; - } - - if (d->socketType == QAbstractSocket::TcpSocket) { - IStreamSocket *socket = d->pendingConnections.takeFirst(); - - SocketHandler *handler = gSocketHandler(); - handler->pendingTcpSockets.insert(++handler->socketCount, socket); - return handler->socketCount; - } - - return -1; -} - -void QNativeSocketEngine::close() -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO; - Q_D(QNativeSocketEngine); - - if (d->closingDown) - return; - - if (d->pendingReadNotification) { - // We use QPointer here to see if this QNativeSocketEngine was deleted as a result of - // finishing and cleaning up a network request when calling "processReadReady". - QPointer<QNativeSocketEngine> alive(this); - processReadReady(); - if (alive.isNull()) - return; - } - - d->closingDown = true; - - d->notifyOnRead = false; - d->notifyOnWrite = false; - d->notifyOnException = false; - d->emitReadReady = false; - - HRESULT hr; - if (d->socketType == QAbstractSocket::TcpSocket) { - hr = QEventDispatcherWinRT::runOnXamlThread([d]() { - HRESULT hr; - // To close the connection properly (not with a hard reset) all pending read operation have to - // be finished or cancelled. The API isn't available on Windows 8.1 though. - ComPtr<IStreamSocket3> socket3; - hr = d->tcpSocket()->QueryInterface(IID_PPV_ARGS(&socket3)); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr<IAsyncAction> action; - hr = socket3->CancelIOAsync(&action); - Q_ASSERT_SUCCEEDED(hr); - hr = QWinRTFunctions::await(action, QWinRTFunctions::YieldThread, 5000); - // If there is no pending IO (no read established before) the function will fail with - // "function was called at an unexpected time" which is fine. - // Timeout is fine as well. The result will be the socket being hard reset instead of - // being closed gracefully - if (hr != E_ILLEGAL_METHOD_CALL && hr != ERROR_TIMEOUT) - Q_ASSERT_SUCCEEDED(hr); - return S_OK; - }); - Q_ASSERT_SUCCEEDED(hr); - } - - if (d->socketDescriptor != -1) { - ComPtr<IClosable> socket; - if (d->socketType == QAbstractSocket::TcpSocket) { - hr = d->tcpSocket()->QueryInterface(IID_PPV_ARGS(&socket)); - Q_ASSERT_SUCCEEDED(hr); - hr = d->tcpSocket()->Release(); - Q_ASSERT_SUCCEEDED(hr); - } else if (d->socketType == QAbstractSocket::UdpSocket) { - hr = d->udpSocket()->QueryInterface(IID_PPV_ARGS(&socket)); - Q_ASSERT_SUCCEEDED(hr); - hr = d->udpSocket()->Release(); - Q_ASSERT_SUCCEEDED(hr); - } - - if (socket) { - hr = socket->Close(); - Q_ASSERT_SUCCEEDED(hr); - } - d->socketDescriptor = -1; - } - d->socketState = QAbstractSocket::UnconnectedState; - d->hasSetSocketError = false; - d->localPort = 0; - d->localAddress.clear(); - d->peerPort = 0; - d->peerAddress.clear(); - d->inboundStreamCount = d->outboundStreamCount = 0; -} - -bool QNativeSocketEngine::joinMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface) -{ - Q_D(QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::joinMulticastGroup(), false); - Q_CHECK_STATE(QNativeSocketEngine::joinMulticastGroup(), QAbstractSocket::BoundState, false); - Q_CHECK_TYPE(QNativeSocketEngine::joinMulticastGroup(), QAbstractSocket::UdpSocket, false); - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << groupAddress << iface; - Q_UNIMPLEMENTED(); - return false; -} - -bool QNativeSocketEngine::leaveMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface) -{ - Q_D(QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::leaveMulticastGroup(), false); - Q_CHECK_STATE(QNativeSocketEngine::leaveMulticastGroup(), QAbstractSocket::BoundState, false); - Q_CHECK_TYPE(QNativeSocketEngine::leaveMulticastGroup(), QAbstractSocket::UdpSocket, false); - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << groupAddress << iface; - Q_UNIMPLEMENTED(); - return false; -} - -QNetworkInterface QNativeSocketEngine::multicastInterface() const -{ - Q_D(const QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::multicastInterface(), QNetworkInterface()); - Q_CHECK_TYPE(QNativeSocketEngine::multicastInterface(), QAbstractSocket::UdpSocket, QNetworkInterface()); - Q_UNIMPLEMENTED(); - return QNetworkInterface(); -} - -bool QNativeSocketEngine::setMulticastInterface(const QNetworkInterface &iface) -{ - Q_D(QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::setMulticastInterface(), false); - Q_CHECK_TYPE(QNativeSocketEngine::setMulticastInterface(), QAbstractSocket::UdpSocket, false); - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << iface; - Q_UNIMPLEMENTED(); - return false; -} - -qint64 QNativeSocketEngine::bytesAvailable() const -{ - Q_D(const QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::bytesAvailable(), -1); - Q_CHECK_NOT_STATE(QNativeSocketEngine::bytesAvailable(), QAbstractSocket::UnconnectedState, -1); - if (d->socketType != QAbstractSocket::TcpSocket) - return -1; - - QMutexLocker locker(&d->worker->mutex); - const qint64 bytesAvailable = d->worker->pendingData.length(); - - qCDebug(lcNetworkSocketVerbose) << this << Q_FUNC_INFO << bytesAvailable; - return bytesAvailable; -} - -qint64 QNativeSocketEngine::read(char *data, qint64 maxlen) -{ - qCDebug(lcNetworkSocketVerbose) << this << Q_FUNC_INFO << maxlen; - Q_D(QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::read(), -1); - Q_CHECK_STATES(QNativeSocketEngine::read(), QAbstractSocket::ConnectedState, QAbstractSocket::BoundState, -1); - if (d->socketType != QAbstractSocket::TcpSocket) - return -1; - - // There will be a read notification when the socket was closed by the remote host. If that - // happens and there isn't anything left in the buffer, we have to return -1 in order to signal - // the closing of the socket. - QMutexLocker mutexLocker(&d->worker->mutex); - if (d->worker->pendingData.isEmpty() && d->socketState != QAbstractSocket::ConnectedState) { - close(); - return -1; - } - - QByteArray readData; - const int copyLength = qMin(maxlen, qint64(d->worker->pendingData.length())); - if (maxlen >= d->worker->pendingData.length()) { - qCDebug(lcNetworkSocketVerbose) << this << Q_FUNC_INFO << "Reading full buffer"; - readData = d->worker->pendingData; - d->worker->pendingData.clear(); - d->emitReadReady = true; - } else { - qCDebug(lcNetworkSocketVerbose) << this << Q_FUNC_INFO << "Reading part of the buffer (" - << copyLength << "of" << d->worker->pendingData.length() << "bytes"; - readData = d->worker->pendingData.left(maxlen); - d->worker->pendingData.remove(0, maxlen); - if (d->notifyOnRead) { - d->pendingReadNotification = true; - emit readReady(); - } - } - mutexLocker.unlock(); - - memcpy(data, readData, copyLength); - qCDebug(lcNetworkSocketVerbose) << this << Q_FUNC_INFO << "Read" << copyLength << "bytes"; - return copyLength; -} - -qint64 QNativeSocketEngine::write(const char *data, qint64 len) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << data << len; - Q_D(QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::write(), -1); - Q_CHECK_STATE(QNativeSocketEngine::write(), QAbstractSocket::ConnectedState, -1); - - HRESULT hr = E_FAIL; - ComPtr<IOutputStream> stream; - if (d->socketType == QAbstractSocket::TcpSocket) - hr = d->tcpSocket()->get_OutputStream(&stream); - else if (d->socketType == QAbstractSocket::UdpSocket) - hr = d->udpSocket()->get_OutputStream(&stream); - Q_ASSERT_SUCCEEDED(hr); - - qint64 bytesWritten = writeIOStream(stream, data, len); - if (bytesWritten < 0) - d->setError(QAbstractSocket::SocketAccessError, WinRTSocketEngine::AccessErrorString); - else if (bytesWritten > 0 && d->notifyOnWrite) - emit writeReady(); - - return bytesWritten; -} - -qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QIpPacketHeader *header, - PacketHeaderOptions) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << maxlen; -#ifndef QT_NO_UDPSOCKET - Q_D(QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::readDatagram(), -1); - Q_CHECK_STATES(QNativeSocketEngine::readDatagram(), QAbstractSocket::BoundState, - QAbstractSocket::ConnectedState, -1); - - QMutexLocker locker(&d->worker->mutex); - if (d->socketType != QAbstractSocket::UdpSocket || d->worker->pendingDatagrams.isEmpty()) { - if (header) - header->clear(); - return -1; - } - - WinRtDatagram datagram = d->worker->pendingDatagrams.takeFirst(); - if (header) - *header = datagram.header; - - QByteArray readOrigin; - if (maxlen < datagram.data.length()) - readOrigin = datagram.data.left(maxlen); - else - readOrigin = datagram.data; - if (d->worker->pendingDatagrams.isEmpty()) { - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << "That's all folks"; - d->worker->emitDataReceived = true; - d->emitReadReady = true; - } - - locker.unlock(); - memcpy(data, readOrigin, qMin(maxlen, qint64(datagram.data.length()))); - return readOrigin.length(); -#else - Q_UNUSED(data) - Q_UNUSED(maxlen) - Q_UNUSED(header) - return -1; -#endif // QT_NO_UDPSOCKET -} - -qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 len, const QIpPacketHeader &header) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << data << len; -#ifndef QT_NO_UDPSOCKET - Q_D(QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::writeDatagram(), -1); - Q_CHECK_STATES(QNativeSocketEngine::writeDatagram(), QAbstractSocket::BoundState, - QAbstractSocket::ConnectedState, -1); - - if (d->socketType != QAbstractSocket::UdpSocket) - return -1; - - ComPtr<IHostName> remoteHost; - ComPtr<IHostNameFactory> hostNameFactory; - - HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), - &hostNameFactory); - Q_ASSERT_SUCCEEDED(hr); - const QString addressString = header.destinationAddress.toString(); - HStringReference hostNameRef(reinterpret_cast<LPCWSTR>(addressString.utf16())); - hr = hostNameFactory->CreateHostName(hostNameRef.Get(), &remoteHost); - RETURN_IF_FAILED("QNativeSocketEngine::writeDatagram: Could not create hostname.", return -1); - - ComPtr<IAsyncOperation<IOutputStream *>> streamOperation; - ComPtr<IOutputStream> stream; - const QString portString = QString::number(header.destinationPort); - HStringReference portRef(reinterpret_cast<LPCWSTR>(portString.utf16())); - hr = d->udpSocket()->GetOutputStreamAsync(remoteHost.Get(), portRef.Get(), &streamOperation); - Q_ASSERT_SUCCEEDED(hr); - - hr = QWinRTFunctions::await(streamOperation, stream.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - - return writeIOStream(stream, data, len); -#else - Q_UNUSED(data) - Q_UNUSED(len) - Q_UNUSED(header) - return -1; -#endif // QT_NO_UDPSOCKET -} - -bool QNativeSocketEngine::hasPendingDatagrams() const -{ - Q_D(const QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::hasPendingDatagrams(), false); - Q_CHECK_NOT_STATE(QNativeSocketEngine::hasPendingDatagrams(), QAbstractSocket::UnconnectedState, false); - Q_CHECK_TYPE(QNativeSocketEngine::hasPendingDatagrams(), QAbstractSocket::UdpSocket, false); - - QMutexLocker locker(&d->worker->mutex); - return d->worker->pendingDatagrams.length() > 0; -} - -qint64 QNativeSocketEngine::pendingDatagramSize() const -{ - Q_D(const QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::pendingDatagramSize(), -1); - Q_CHECK_TYPE(QNativeSocketEngine::pendingDatagramSize(), QAbstractSocket::UdpSocket, -1); - - QMutexLocker locker(&d->worker->mutex); - if (d->worker->pendingDatagrams.isEmpty()) - return -1; - - return d->worker->pendingDatagrams.at(0).data.length(); -} - -qint64 QNativeSocketEngine::bytesToWrite() const -{ - return 0; -} - -qint64 QNativeSocketEngine::receiveBufferSize() const -{ - Q_D(const QNativeSocketEngine); - return d->option(QAbstractSocketEngine::ReceiveBufferSocketOption); -} - -void QNativeSocketEngine::setReceiveBufferSize(qint64 bufferSize) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << bufferSize; - Q_D(QNativeSocketEngine); - d->setOption(QAbstractSocketEngine::ReceiveBufferSocketOption, bufferSize); -} - -qint64 QNativeSocketEngine::sendBufferSize() const -{ - Q_D(const QNativeSocketEngine); - return d->option(QAbstractSocketEngine::SendBufferSocketOption); -} - -void QNativeSocketEngine::setSendBufferSize(qint64 bufferSize) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << bufferSize; - Q_D(QNativeSocketEngine); - d->setOption(QAbstractSocketEngine::SendBufferSocketOption, bufferSize); -} - -int QNativeSocketEngine::option(QAbstractSocketEngine::SocketOption option) const -{ - Q_D(const QNativeSocketEngine); - return d->option(option); -} - -bool QNativeSocketEngine::setOption(QAbstractSocketEngine::SocketOption option, int value) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << option << value; - Q_D(QNativeSocketEngine); - return d->setOption(option, value); -} - -bool QNativeSocketEngine::waitForRead(int msecs, bool *timedOut) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << msecs; - Q_D(QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForRead(), false); - Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForRead(), - QAbstractSocket::UnconnectedState, false); - - if (timedOut) - *timedOut = false; - - QElapsedTimer timer; - timer.start(); - while (msecs > timer.elapsed()) { - // Servers with active connections are ready for reading - if (!d->currentConnections.isEmpty()) - return true; - - // If we are a client, we are ready to read if our buffer has data - QMutexLocker locker(&d->worker->mutex); - if (!d->worker->pendingData.isEmpty()) - return true; - - // Nothing to do, wait for more events - d->eventLoop.processEvents(); - } - - d->setError(QAbstractSocket::SocketTimeoutError, - WinRTSocketEngine::TimeOutErrorString); - - if (timedOut) - *timedOut = true; - return false; -} - -bool QNativeSocketEngine::waitForWrite(int msecs, bool *timedOut) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << msecs; - Q_UNUSED(timedOut); - Q_D(QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForWrite(), false); - Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForWrite(), - QAbstractSocket::UnconnectedState, false); - - if (d->socketState == QAbstractSocket::ConnectingState) { - HRESULT hr = QWinRTFunctions::await(d->worker->connectOp, QWinRTFunctions::ProcessMainThreadEvents); - if (SUCCEEDED(hr)) { - handleConnectOpFinished(true, QAbstractSocket::UnknownSocketError, WinRTSocketEngine::UnknownSocketErrorString); - return true; - } - } - return false; -} - -bool QNativeSocketEngine::waitForReadOrWrite(bool *readyToRead, bool *readyToWrite, bool checkRead, bool checkWrite, int msecs, bool *timedOut) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << checkRead << checkWrite << msecs; - Q_D(QNativeSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForReadOrWrite(), false); - Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForReadOrWrite(), - QAbstractSocket::UnconnectedState, false); - - Q_UNUSED(readyToRead); - Q_UNUSED(readyToWrite); - Q_UNUSED(timedOut); - return false; -} - -bool QNativeSocketEngine::isReadNotificationEnabled() const -{ - Q_D(const QNativeSocketEngine); - return d->notifyOnRead; -} - -void QNativeSocketEngine::setReadNotificationEnabled(bool enable) -{ - qCDebug(lcNetworkSocketVerbose) << this << Q_FUNC_INFO << enable; - Q_D(QNativeSocketEngine); - d->notifyOnRead = enable; -} - -bool QNativeSocketEngine::isWriteNotificationEnabled() const -{ - Q_D(const QNativeSocketEngine); - return d->notifyOnWrite; -} - -void QNativeSocketEngine::setWriteNotificationEnabled(bool enable) -{ - qCDebug(lcNetworkSocketVerbose) << this << Q_FUNC_INFO << enable; - Q_D(QNativeSocketEngine); - d->notifyOnWrite = enable; - if (enable && d->socketState == QAbstractSocket::ConnectedState) { - if (bytesToWrite()) - return; // will be emitted as a result of bytes written - writeNotification(); - } -} - -bool QNativeSocketEngine::isExceptionNotificationEnabled() const -{ - Q_D(const QNativeSocketEngine); - return d->notifyOnException; -} - -void QNativeSocketEngine::setExceptionNotificationEnabled(bool enable) -{ - qCDebug(lcNetworkSocketVerbose) << this << Q_FUNC_INFO << enable; - Q_D(QNativeSocketEngine); - d->notifyOnException = enable; -} - -void QNativeSocketEngine::establishRead() -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO; - Q_D(QNativeSocketEngine); - - HRESULT hr; - hr = QEventDispatcherWinRT::runOnXamlThread([d]() { - d->worker->setTcpSocket(d->tcpSocket()); - d->worker->startReading(); - return S_OK; - }); - Q_ASSERT_SUCCEEDED(hr); -} - -void QNativeSocketEngine::handleConnectOpFinished(bool success, QAbstractSocket::SocketError error, WinRTSocketEngine::ErrorString errorString) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << success << error << errorString; - Q_D(QNativeSocketEngine); - disconnect(d->worker, &SocketEngineWorker::connectOpFinished, - this, &QNativeSocketEngine::handleConnectOpFinished); - if (!success) { - d->setError(error, errorString); - d->socketState = QAbstractSocket::UnconnectedState; - close(); - return; - } - - d->socketState = QAbstractSocket::ConnectedState; - d->fetchConnectionParameters(); - emit connectionReady(); - - if (d->socketType != QAbstractSocket::TcpSocket) - return; - -#ifndef QT_NO_SSL - // Delay the reader so that the SSL socket can upgrade - if (d->sslSocket) - QObject::connect(qobject_cast<QSslSocket *>(d->sslSocket), &QSslSocket::encrypted, this, &QNativeSocketEngine::establishRead); - else -#endif - establishRead(); -} - -void QNativeSocketEngine::handleNewData() -{ - qCDebug(lcNetworkSocketVerbose) << this << Q_FUNC_INFO; - Q_D(QNativeSocketEngine); - - if (d->notifyOnRead && d->emitReadReady) { - if (d->socketType == QAbstractSocket::UdpSocket && !d->worker->emitDataReceived) - return; - qCDebug(lcNetworkSocketVerbose) << this << Q_FUNC_INFO << "Emitting readReady"; - d->pendingReadNotification = true; - emit readReady(); - d->worker->emitDataReceived = false; - d->emitReadReady = false; - } -} - -void QNativeSocketEngine::handleTcpError(QAbstractSocket::SocketError error) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << error; - Q_D(QNativeSocketEngine); - WinRTSocketEngine::ErrorString errorString; - switch (error) { - case QAbstractSocket::RemoteHostClosedError: - errorString = WinRTSocketEngine::RemoteHostClosedErrorString; - break; - default: - errorString = WinRTSocketEngine::UnknownSocketErrorString; - } - - d->setError(error, errorString); - close(); -} - -void QNativeSocketEngine::processReadReady() -{ - Q_D(QNativeSocketEngine); - if (d->closingDown) - return; - - d->pendingReadNotification = false; - readNotification(); -} - -bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol &socketProtocol) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << socketType << socketProtocol; - Q_UNUSED(socketProtocol); - HRESULT hr; - - switch (socketType) { - case QAbstractSocket::TcpSocket: { - ComPtr<IStreamSocket> socket; - hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocket).Get(), &socket); - RETURN_FALSE_IF_FAILED("createNewSocket: Could not create socket instance"); - socketDescriptor = qintptr(socket.Detach()); - break; - } - case QAbstractSocket::UdpSocket: { - ComPtr<IDatagramSocket> socket; - hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &socket); - RETURN_FALSE_IF_FAILED("createNewSocket: Could not create socket instance"); - socketDescriptor = qintptr(socket.Detach()); - QEventDispatcherWinRT::runOnXamlThread([&hr, this]() { - hr = udpSocket()->add_MessageReceived(Callback<DatagramReceivedHandler>(worker, &SocketEngineWorker::OnNewDatagramReceived).Get(), &connectionToken); - if (FAILED(hr)) { - qErrnoWarning(hr, "createNewSocket: Could not add \"message received\" callback"); - return hr; - } - return S_OK; - }); - if (FAILED(hr)) - return false; - break; - } - default: - qWarning("Invalid socket type"); - return false; - } - - this->socketType = socketType; - - // Make the socket nonblocking. - if (!setOption(QAbstractSocketEngine::NonBlockingSocketOption, 1)) { - setError(QAbstractSocket::UnsupportedSocketOperationError, WinRTSocketEngine::NonBlockingInitFailedErrorString); - q_func()->close(); - return false; - } - - return true; -} - -QNativeSocketEnginePrivate::QNativeSocketEnginePrivate() - : QAbstractSocketEnginePrivate() - , notifyOnRead(true) - , notifyOnWrite(true) - , notifyOnException(false) - , closingDown(false) - , socketDescriptor(-1) - , worker(new SocketEngineWorker(this)) - , sslSocket(nullptr) - , connectionToken( { -1 } ) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO; -} - -QNativeSocketEnginePrivate::~QNativeSocketEnginePrivate() -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO; - if (socketDescriptor == -1 || connectionToken.value == -1) - return; - - HRESULT hr; - if (socketType == QAbstractSocket::UdpSocket) - hr = udpSocket()->remove_MessageReceived(connectionToken); - else if (socketType == QAbstractSocket::TcpSocket) - hr = tcpListener->remove_ConnectionReceived(connectionToken); - Q_ASSERT_SUCCEEDED(hr); - - worker->deleteLater(); -} - -void QNativeSocketEnginePrivate::setError(QAbstractSocket::SocketError error, WinRTSocketEngine::ErrorString errorString) const -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << error << errorString; - if (hasSetSocketError) { - // Only set socket errors once for one engine; expect the - // socket to recreate its engine after an error. Note: There's - // one exception: SocketError(11) bypasses this as it's purely - // a temporary internal error condition. - // Another exception is the way the waitFor*() functions set - // an error when a timeout occurs. After the call to setError() - // they reset the hasSetSocketError to false - return; - } - if (error != QAbstractSocket::SocketError(11)) - hasSetSocketError = true; - - socketError = error; - - switch (errorString) { - case WinRTSocketEngine::NonBlockingInitFailedErrorString: - socketErrorString = QNativeSocketEngine::tr("Unable to initialize non-blocking socket"); - break; - case WinRTSocketEngine::BroadcastingInitFailedErrorString: - socketErrorString = QNativeSocketEngine::tr("Unable to initialize broadcast socket"); - break; - // should not happen anymore - case WinRTSocketEngine::NoIpV6ErrorString: - socketErrorString = QNativeSocketEngine::tr("Attempt to use IPv6 socket on a platform with no IPv6 support"); - break; - case WinRTSocketEngine::RemoteHostClosedErrorString: - socketErrorString = QNativeSocketEngine::tr("The remote host closed the connection"); - break; - case WinRTSocketEngine::TimeOutErrorString: - socketErrorString = QNativeSocketEngine::tr("Network operation timed out"); - break; - case WinRTSocketEngine::ResourceErrorString: - socketErrorString = QNativeSocketEngine::tr("Out of resources"); - break; - case WinRTSocketEngine::OperationUnsupportedErrorString: - socketErrorString = QNativeSocketEngine::tr("Unsupported socket operation"); - break; - case WinRTSocketEngine::ProtocolUnsupportedErrorString: - socketErrorString = QNativeSocketEngine::tr("Protocol type not supported"); - break; - case WinRTSocketEngine::InvalidSocketErrorString: - socketErrorString = QNativeSocketEngine::tr("Invalid socket descriptor"); - break; - case WinRTSocketEngine::HostUnreachableErrorString: - socketErrorString = QNativeSocketEngine::tr("Host unreachable"); - break; - case WinRTSocketEngine::NetworkUnreachableErrorString: - socketErrorString = QNativeSocketEngine::tr("Network unreachable"); - break; - case WinRTSocketEngine::AccessErrorString: - socketErrorString = QNativeSocketEngine::tr("Permission denied"); - break; - case WinRTSocketEngine::ConnectionTimeOutErrorString: - socketErrorString = QNativeSocketEngine::tr("Connection timed out"); - break; - case WinRTSocketEngine::ConnectionRefusedErrorString: - socketErrorString = QNativeSocketEngine::tr("Connection refused"); - break; - case WinRTSocketEngine::AddressInuseErrorString: - socketErrorString = QNativeSocketEngine::tr("The bound address is already in use"); - break; - case WinRTSocketEngine::AddressNotAvailableErrorString: - socketErrorString = QNativeSocketEngine::tr("The address is not available"); - break; - case WinRTSocketEngine::AddressProtectedErrorString: - socketErrorString = QNativeSocketEngine::tr("The address is protected"); - break; - case WinRTSocketEngine::DatagramTooLargeErrorString: - socketErrorString = QNativeSocketEngine::tr("Datagram was too large to send"); - break; - case WinRTSocketEngine::SendDatagramErrorString: - socketErrorString = QNativeSocketEngine::tr("Unable to send a message"); - break; - case WinRTSocketEngine::ReceiveDatagramErrorString: - socketErrorString = QNativeSocketEngine::tr("Unable to receive a message"); - break; - case WinRTSocketEngine::WriteErrorString: - socketErrorString = QNativeSocketEngine::tr("Unable to write"); - break; - case WinRTSocketEngine::ReadErrorString: - socketErrorString = QNativeSocketEngine::tr("Network error"); - break; - case WinRTSocketEngine::PortInuseErrorString: - socketErrorString = QNativeSocketEngine::tr("Another socket is already listening on the same port"); - break; - case WinRTSocketEngine::NotSocketErrorString: - socketErrorString = QNativeSocketEngine::tr("Operation on non-socket"); - break; - case WinRTSocketEngine::InvalidProxyTypeString: - socketErrorString = QNativeSocketEngine::tr("The proxy type is invalid for this operation"); - break; - case WinRTSocketEngine::TemporaryErrorString: - socketErrorString = QNativeSocketEngine::tr("Temporary error"); - break; - case WinRTSocketEngine::UnknownSocketErrorString: - socketErrorString = QNativeSocketEngine::tr("Unknown error"); - break; - } -} - -int QNativeSocketEnginePrivate::option(QAbstractSocketEngine::SocketOption opt) const -{ - ComPtr<IStreamSocketControl> control; - if (socketType == QAbstractSocket::TcpSocket) { - if (FAILED(tcpSocket()->get_Control(&control))) { - qWarning("QNativeSocketEnginePrivate::option: Could not obtain socket control"); - return -1; - } - } - switch (opt) { - case QAbstractSocketEngine::NonBlockingSocketOption: - case QAbstractSocketEngine::BroadcastSocketOption: - case QAbstractSocketEngine::ReceiveOutOfBandData: - return 1; - case QAbstractSocketEngine::SendBufferSocketOption: - if (socketType == QAbstractSocket::UdpSocket) - return -1; - - UINT32 bufferSize; - if (FAILED(control->get_OutboundBufferSizeInBytes(&bufferSize))) { - qWarning("Could not obtain OutboundBufferSizeInBytes information vom socket control"); - return -1; - } - return bufferSize; - case QAbstractSocketEngine::LowDelayOption: - if (socketType == QAbstractSocket::UdpSocket) - return -1; - - boolean noDelay; - if (FAILED(control->get_NoDelay(&noDelay))) { - qWarning("Could not obtain NoDelay information from socket control"); - return -1; - } - return noDelay; - case QAbstractSocketEngine::KeepAliveOption: - if (socketType == QAbstractSocket::UdpSocket) - return -1; - - boolean keepAlive; - if (FAILED(control->get_KeepAlive(&keepAlive))) { - qWarning("Could not obtain KeepAlive information from socket control"); - return -1; - } - return keepAlive; - case QAbstractSocketEngine::ReceiveBufferSocketOption: - case QAbstractSocketEngine::AddressReusable: - case QAbstractSocketEngine::BindExclusively: - case QAbstractSocketEngine::MulticastTtlOption: - case QAbstractSocketEngine::MulticastLoopbackOption: - case QAbstractSocketEngine::TypeOfServiceOption: - case QAbstractSocketEngine::MaxStreamsSocketOption: - case QAbstractSocketEngine::PathMtuInformation: - default: - return -1; - } - return -1; -} - -bool QNativeSocketEnginePrivate::setOption(QAbstractSocketEngine::SocketOption opt, int v) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO << opt << v; - ComPtr<IStreamSocketControl> control; - if (socketType == QAbstractSocket::TcpSocket) { - if (FAILED(tcpSocket()->get_Control(&control))) { - qWarning("QNativeSocketEnginePrivate::setOption: Could not obtain socket control"); - return false; - } - } - switch (opt) { - case QAbstractSocketEngine::NonBlockingSocketOption: - case QAbstractSocketEngine::BroadcastSocketOption: - case QAbstractSocketEngine::ReceiveOutOfBandData: - return v != 0; - case QAbstractSocketEngine::SendBufferSocketOption: - if (socketType == QAbstractSocket::UdpSocket) - return false; - - if (FAILED(control->put_OutboundBufferSizeInBytes(v))) { - qWarning("Could not set OutboundBufferSizeInBytes"); - return false; - } - return true; - case QAbstractSocketEngine::LowDelayOption: { - if (socketType == QAbstractSocket::UdpSocket) - return false; - - boolean noDelay = v; - if (FAILED(control->put_NoDelay(noDelay))) { - qWarning("Could not obtain NoDelay information from socket control"); - return false; - } - return true; - } - case QAbstractSocketEngine::KeepAliveOption: { - if (socketType == QAbstractSocket::UdpSocket - || socketState != QAbstractSocket::UnconnectedState) - return false; - - boolean keepAlive = v; - if (FAILED(control->put_KeepAlive(keepAlive))) { - qWarning("Could not set KeepAlive value"); - return false; - } - return true; - } - case QAbstractSocketEngine::ReceiveBufferSocketOption: - case QAbstractSocketEngine::AddressReusable: - case QAbstractSocketEngine::BindExclusively: - case QAbstractSocketEngine::MulticastTtlOption: - case QAbstractSocketEngine::MulticastLoopbackOption: - case QAbstractSocketEngine::TypeOfServiceOption: - case QAbstractSocketEngine::MaxStreamsSocketOption: - case QAbstractSocketEngine::PathMtuInformation: - default: - return false; - } - return false; -} - -bool QNativeSocketEnginePrivate::fetchConnectionParameters() -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO; - localPort = 0; - localAddress.clear(); - peerPort = 0; - peerAddress.clear(); - inboundStreamCount = outboundStreamCount = 0; - - HRESULT hr; - if (socketType == QAbstractSocket::TcpSocket) { - ComPtr<IHostName> hostName; - HString tmpHString; - ComPtr<IStreamSocketInformation> info; - hr = tcpSocket()->get_Information(&info); - Q_ASSERT_SUCCEEDED(hr); - hr = info->get_LocalAddress(&hostName); - Q_ASSERT_SUCCEEDED(hr); - if (hostName) { - hr = hostName->get_CanonicalName(tmpHString.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - localAddress.setAddress(qt_QStringFromHString(tmpHString)); - hr = info->get_LocalPort(tmpHString.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - localPort = qt_QStringFromHString(tmpHString).toInt(); - } - if (!localPort && tcpListener) { - ComPtr<IStreamSocketListenerInformation> listenerInfo = 0; - hr = tcpListener->get_Information(&listenerInfo); - Q_ASSERT_SUCCEEDED(hr); - hr = listenerInfo->get_LocalPort(tmpHString.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - localPort = qt_QStringFromHString(tmpHString).toInt(); - localAddress = QHostAddress::Any; - } - info->get_RemoteAddress(&hostName); - if (hostName) { - hr = hostName->get_CanonicalName(tmpHString.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - peerAddress.setAddress(qt_QStringFromHString(tmpHString)); - hr = info->get_RemotePort(tmpHString.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - peerPort = qt_QStringFromHString(tmpHString).toInt(); - inboundStreamCount = outboundStreamCount = 1; - } - } else if (socketType == QAbstractSocket::UdpSocket) { - ComPtr<IHostName> hostName; - HString tmpHString; - ComPtr<IDatagramSocketInformation> info; - hr = udpSocket()->get_Information(&info); - Q_ASSERT_SUCCEEDED(hr); - hr = info->get_LocalAddress(&hostName); - Q_ASSERT_SUCCEEDED(hr); - if (hostName) { - hr = hostName->get_CanonicalName(tmpHString.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - localAddress.setAddress(qt_QStringFromHString(tmpHString)); - hr = info->get_LocalPort(tmpHString.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - localPort = qt_QStringFromHString(tmpHString).toInt(); - } - - hr = info->get_RemoteAddress(&hostName); - Q_ASSERT_SUCCEEDED(hr); - if (hostName) { - hr = hostName->get_CanonicalName(tmpHString.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - peerAddress.setAddress(qt_QStringFromHString(tmpHString)); - hr = info->get_RemotePort(tmpHString.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - peerPort = qt_QStringFromHString(tmpHString).toInt(); - inboundStreamCount = outboundStreamCount = 1; - } - } - return true; -} - -HRESULT QNativeSocketEnginePrivate::handleClientConnection(IStreamSocketListener *listener, IStreamSocketListenerConnectionReceivedEventArgs *args) -{ - qCDebug(lcNetworkSocket) << this << Q_FUNC_INFO; - Q_Q(QNativeSocketEngine); - Q_UNUSED(listener) - IStreamSocket *socket; - args->get_Socket(&socket); - pendingConnections.append(socket); - emit q->connectionReady(); - if (notifyOnRead) - emit q->readReady(); - return S_OK; -} - -QT_END_NAMESPACE - -#include "qnativesocketengine_winrt.moc" diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h deleted file mode 100644 index e1fe58bb97..0000000000 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ /dev/null @@ -1,243 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QNATIVESOCKETENGINE_WINRT_P_H -#define QNATIVESOCKETENGINE_WINRT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of the QLibrary class. This header file may change from -// version to version without notice, or even be removed. -// -// We mean it. -// - -#include <QtNetwork/private/qtnetworkglobal_p.h> -#include <QtCore/QEventLoop> -#include <QtCore/QBuffer> -#include <QtCore/QLoggingCategory> -#include <QtCore/QMutex> -#include <QtCore/QAtomicInteger> -#include "QtNetwork/qhostaddress.h" -#include "private/qabstractsocketengine_p.h" -#include <wrl.h> -#include <windows.networking.sockets.h> - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(lcNetworkSocket) -Q_DECLARE_LOGGING_CATEGORY(lcNetworkSocketVerbose) - -namespace WinRTSocketEngine { - enum ErrorString { - NonBlockingInitFailedErrorString, - BroadcastingInitFailedErrorString, - NoIpV6ErrorString, - RemoteHostClosedErrorString, - TimeOutErrorString, - ResourceErrorString, - OperationUnsupportedErrorString, - ProtocolUnsupportedErrorString, - InvalidSocketErrorString, - HostUnreachableErrorString, - NetworkUnreachableErrorString, - AccessErrorString, - ConnectionTimeOutErrorString, - ConnectionRefusedErrorString, - AddressInuseErrorString, - AddressNotAvailableErrorString, - AddressProtectedErrorString, - DatagramTooLargeErrorString, - SendDatagramErrorString, - ReceiveDatagramErrorString, - WriteErrorString, - ReadErrorString, - PortInuseErrorString, - NotSocketErrorString, - InvalidProxyTypeString, - TemporaryErrorString, - - UnknownSocketErrorString = -1 - }; -} - -class QNativeSocketEnginePrivate; -class SocketEngineWorker; - -struct WinRtDatagram { - QByteArray data; - QIpPacketHeader header; -}; - -class Q_AUTOTEST_EXPORT QNativeSocketEngine : public QAbstractSocketEngine -{ - Q_OBJECT -public: - QNativeSocketEngine(QObject *parent = 0); - ~QNativeSocketEngine(); - - bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol); - bool initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState); - - qintptr socketDescriptor() const; - - bool isValid() const; - - bool connectToHost(const QHostAddress &address, quint16 port); - bool connectToHostByName(const QString &name, quint16 port); - bool bind(const QHostAddress &address, quint16 port); - bool listen(); - int accept(); - void close(); - -#ifndef QT_NO_NETWORKINTERFACE - bool joinMulticastGroup(const QHostAddress &groupAddress, - const QNetworkInterface &iface); - bool leaveMulticastGroup(const QHostAddress &groupAddress, - const QNetworkInterface &iface); - QNetworkInterface multicastInterface() const; - bool setMulticastInterface(const QNetworkInterface &iface); -#endif - - qint64 bytesAvailable() const; - - qint64 read(char *data, qint64 maxlen); - qint64 write(const char *data, qint64 len); - - qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader * = 0, PacketHeaderOptions = WantNone); - qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &header); - bool hasPendingDatagrams() const; - qint64 pendingDatagramSize() const; - - qint64 bytesToWrite() const; - - qint64 receiveBufferSize() const; - void setReceiveBufferSize(qint64 bufferSize); - - qint64 sendBufferSize() const; - void setSendBufferSize(qint64 bufferSize); - - int option(SocketOption option) const; - bool setOption(SocketOption option, int value); - - bool waitForRead(int msecs = 30000, bool *timedOut = 0); - bool waitForWrite(int msecs = 30000, bool *timedOut = 0); - bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite, - bool checkRead, bool checkWrite, - int msecs = 30000, bool *timedOut = 0); - - bool isReadNotificationEnabled() const; - void setReadNotificationEnabled(bool enable); - bool isWriteNotificationEnabled() const; - void setWriteNotificationEnabled(bool enable); - bool isExceptionNotificationEnabled() const; - void setExceptionNotificationEnabled(bool enable); - -signals: - void connectionReady(); - void readReady(); - void writeReady(); - void newDatagramReceived(const WinRtDatagram &datagram); - -private slots: - void establishRead(); - void handleConnectOpFinished(bool success, QAbstractSocket::SocketError error, - WinRTSocketEngine::ErrorString errorString); - void handleNewData(); - void handleTcpError(QAbstractSocket::SocketError error); - void processReadReady(); - -private: - Q_DECLARE_PRIVATE(QNativeSocketEngine) - Q_DISABLE_COPY_MOVE(QNativeSocketEngine) -}; - -class QNativeSocketEnginePrivate : public QAbstractSocketEnginePrivate -{ - Q_DECLARE_PUBLIC(QNativeSocketEngine) -public: - QNativeSocketEnginePrivate(); - ~QNativeSocketEnginePrivate(); - - qintptr socketDescriptor; - SocketEngineWorker *worker; - - bool notifyOnRead, notifyOnWrite, notifyOnException; - QAtomicInt closingDown; - - void setError(QAbstractSocket::SocketError error, WinRTSocketEngine::ErrorString errorString) const; - - // native functions - int option(QNativeSocketEngine::SocketOption option) const; - bool setOption(QNativeSocketEngine::SocketOption option, int value); - - bool createNewSocket(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol &protocol); - - bool checkProxy(const QHostAddress &address); - bool fetchConnectionParameters(); - -private: - inline ABI::Windows::Networking::Sockets::IStreamSocket *tcpSocket() const - { return reinterpret_cast<ABI::Windows::Networking::Sockets::IStreamSocket *>(socketDescriptor); } - inline ABI::Windows::Networking::Sockets::IDatagramSocket *udpSocket() const - { return reinterpret_cast<ABI::Windows::Networking::Sockets::IDatagramSocket *>(socketDescriptor); } - Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocketListener> tcpListener; - - QList<ABI::Windows::Networking::Sockets::IStreamSocket *> pendingConnections; - QList<ABI::Windows::Networking::Sockets::IStreamSocket *> currentConnections; - QEventLoop eventLoop; - QAbstractSocket *sslSocket; - EventRegistrationToken connectionToken; - - bool emitReadReady = true; - bool pendingReadNotification = false; - - HRESULT handleClientConnection(ABI::Windows::Networking::Sockets::IStreamSocketListener *tcpListener, - ABI::Windows::Networking::Sockets::IStreamSocketListenerConnectionReceivedEventArgs *args); -}; - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(WinRtDatagram) -Q_DECLARE_METATYPE(WinRTSocketEngine::ErrorString) - -#endif // QNATIVESOCKETENGINE_WINRT_P_H diff --git a/src/network/socket/socket.pri b/src/network/socket/socket.pri index c3a98ea31a..67325ac70f 100644 --- a/src/network/socket/socket.pri +++ b/src/network/socket/socket.pri @@ -43,10 +43,8 @@ qtConfig(sctp) { socket/qsctpsocket.cpp } -!winrt { - SOURCES += socket/qnativesocketengine.cpp - HEADERS += socket/qnativesocketengine_p.h -} +SOURCES += socket/qnativesocketengine.cpp +HEADERS += socket/qnativesocketengine_p.h unix { SOURCES += socket/qnativesocketengine_unix.cpp @@ -57,13 +55,8 @@ unix { # invalid C/C++ code otherwise. msvc: QMAKE_MOC_OPTIONS += -D_WINSOCK_DEPRECATED_NO_WARNINGS -win32:!winrt:SOURCES += socket/qnativesocketengine_win.cpp -win32:!winrt: QMAKE_USE_PRIVATE += advapi32 - -winrt { - SOURCES += socket/qnativesocketengine_winrt.cpp - HEADERS += socket/qnativesocketengine_winrt_p.h -} +win32: SOURCES += socket/qnativesocketengine_win.cpp +win32: QMAKE_USE_PRIVATE += advapi32 qtConfig(localserver) { HEADERS += socket/qlocalserver.h \ @@ -73,7 +66,7 @@ qtConfig(localserver) { SOURCES += socket/qlocalsocket.cpp \ socket/qlocalserver.cpp - integrity|winrt { + integrity { SOURCES += socket/qlocalsocket_tcp.cpp \ socket/qlocalserver_tcp.cpp DEFINES += QT_LOCALSOCKET_TCP diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp index 87b9a1b038..4482e8862b 100644 --- a/src/network/ssl/qssl.cpp +++ b/src/network/ssl/qssl.cpp @@ -111,11 +111,11 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl"); Describes the protocol of the cipher. \value TlsV1_0 TLSv1.0 - \value TlsV1_0OrLater TLSv1.0 and later versions. This option is not available when using the WinRT backend due to platform limitations. - \value TlsV1_1 TLSv1.1. When using the WinRT backend this option will also enable TLSv1.0. - \value TlsV1_1OrLater TLSv1.1 and later versions. This option is not available when using the WinRT backend due to platform limitations. - \value TlsV1_2 TLSv1.2. When using the WinRT backend this option will also enable TLSv1.0 and TLSv1.1. - \value TlsV1_2OrLater TLSv1.2 and later versions. This option is not available when using the WinRT backend due to platform limitations. + \value TlsV1_0OrLater TLSv1.0 and later versions. + \value TlsV1_1 TLSv1.1. + \value TlsV1_1OrLater TLSv1.1 and later versions. + \value TlsV1_2 TLSv1.2. + \value TlsV1_2OrLater TLSv1.2 and later versions. \value DtlsV1_0 DTLSv1.0 \value DtlsV1_0OrLater DTLSv1.0 and later versions. \value DtlsV1_2 DTLSv1.2 diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 7539c26ecb..6daf5c362e 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -115,9 +115,6 @@ #ifndef QT_NO_OPENSSL #include "qsslsocket_openssl_symbols_p.h" #endif -#ifdef Q_OS_WINRT -#include "qsslsocket_winrt_p.h" -#endif #ifdef QT_SECURETRANSPORT #include "qsslsocket_mac_p.h" #endif diff --git a/src/network/ssl/qsslcertificate_p.h b/src/network/ssl/qsslcertificate_p.h index 234cd45ceb..4588aa7d6f 100644 --- a/src/network/ssl/qsslcertificate_p.h +++ b/src/network/ssl/qsslcertificate_p.h @@ -70,11 +70,6 @@ struct X509_EXTENSION; struct ASN1_OBJECT; #endif -#ifdef Q_OS_WINRT -#include <wrl.h> -#include <windows.security.cryptography.certificates.h> -#endif - #if QT_CONFIG(schannel) #include <wincrypt.h> #endif @@ -146,12 +141,6 @@ public: QAtomicInt ref; -#ifdef Q_OS_WINRT - Microsoft::WRL::ComPtr<ABI::Windows::Security::Cryptography::Certificates::ICertificate> certificate; - - static QSslCertificate QSslCertificate_from_Certificate(ABI::Windows::Security::Cryptography::Certificates::ICertificate *iCertificate); -#endif - #if QT_CONFIG(schannel) const CERT_CONTEXT *certificateContext = nullptr; diff --git a/src/network/ssl/qsslcertificate_qt.cpp b/src/network/ssl/qsslcertificate_qt.cpp index 7cf96a4a88..d75e620ff7 100644 --- a/src/network/ssl/qsslcertificate_qt.cpp +++ b/src/network/ssl/qsslcertificate_qt.cpp @@ -141,7 +141,7 @@ QDateTime QSslCertificate::expiryDate() const return d->notValidAfter; } -#if !defined(Q_OS_WINRT) && !QT_CONFIG(schannel) // implemented in qsslcertificate_{winrt,schannel}.cpp +#if !QT_CONFIG(schannel) // implemented in qsslcertificate_schannel.cpp Qt::HANDLE QSslCertificate::handle() const { Q_UNIMPLEMENTED(); diff --git a/src/network/ssl/qsslcertificate_winrt.cpp b/src/network/ssl/qsslcertificate_winrt.cpp deleted file mode 100644 index e601307c17..0000000000 --- a/src/network/ssl/qsslcertificate_winrt.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsslcertificate_p.h" - -#include <QtCore/qfunctions_winrt.h> - -#include <wrl.h> -#include <windows.storage.streams.h> -#include <windows.security.cryptography.h> -#include <robuffer.h> - -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; -using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::Security::Cryptography; -using namespace ABI::Windows::Security::Cryptography::Certificates; -using namespace ABI::Windows::Storage::Streams; - -QT_USE_NAMESPACE - -struct SslCertificateGlobal -{ - SslCertificateGlobal() { - HRESULT hr; - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Security_Cryptography_Certificates_Certificate).Get(), - &certificateFactory); - Q_ASSERT_SUCCEEDED(hr); - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Security_Cryptography_CryptographicBuffer).Get(), - &bufferFactory); - Q_ASSERT_SUCCEEDED(hr); - } - - ComPtr<ICertificateFactory> certificateFactory; - ComPtr<ICryptographicBufferStatics> bufferFactory; -}; -Q_GLOBAL_STATIC(SslCertificateGlobal, g) - -QSslCertificate QSslCertificatePrivate::QSslCertificate_from_Certificate(ICertificate *iCertificate) -{ - Q_ASSERT(iCertificate); - ComPtr<IBuffer> buffer; - HRESULT hr = iCertificate->GetCertificateBlob(&buffer); - RETURN_IF_FAILED("Could not obtain certification blob", return QSslCertificate()); - ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteAccess; - hr = buffer.As(&byteAccess); - RETURN_IF_FAILED("Could not obtain byte access to buffer", return QSslCertificate()); - char *data; - hr = byteAccess->Buffer(reinterpret_cast<byte **>(&data)); - RETURN_IF_FAILED("Could not obtain buffer data", return QSslCertificate()); - UINT32 size; - hr = buffer->get_Length(&size); - RETURN_IF_FAILED("Could not obtain buffer length ", return QSslCertificate()); - QByteArray der(data, size); - - QSslCertificate certificate; - certificate.d->null = false; - certificate.d->certificate = iCertificate; - - return certificatesFromDer(der, 1).at(0); -} - -Qt::HANDLE QSslCertificate::handle() const -{ - if (!d->certificate) { - HRESULT hr; - ComPtr<IBuffer> buffer; - hr = g->bufferFactory->CreateFromByteArray(d->derData.length(), (BYTE *)d->derData.data(), &buffer); - RETURN_IF_FAILED("Failed to create the certificate data buffer", return nullptr); - - hr = g->certificateFactory->CreateCertificate(buffer.Get(), &d->certificate); - RETURN_IF_FAILED("Failed to create the certificate handle from the data buffer", - return nullptr); - } - - return d->certificate.Get(); -} diff --git a/src/network/ssl/qsslkey_qt.cpp b/src/network/ssl/qsslkey_qt.cpp index 43969c3d28..f3bd75dfa6 100644 --- a/src/network/ssl/qsslkey_qt.cpp +++ b/src/network/ssl/qsslkey_qt.cpp @@ -715,11 +715,6 @@ static EncryptionData readPbes1(const QVector<QAsn1Element> &element, const QByt key.truncate(8); // first 8 bytes are used for the key QSslKeyPrivate::Cipher cipher = oidCipherMap[encryptionScheme]; -#ifdef Q_OS_WINRT - // @todo: document this instead? find some other solution? - if (cipher == QSslKeyPrivate::Cipher::Rc2Cbc) - qWarning("PBES1 with RC2_CBC doesn't work properly on WinRT."); -#endif // Steps 4-6 are done after returning return {cipher, key, iv}; } diff --git a/src/network/ssl/qsslkey_winrt.cpp b/src/network/ssl/qsslkey_winrt.cpp deleted file mode 100644 index 69eaaa387f..0000000000 --- a/src/network/ssl/qsslkey_winrt.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qssl_p.h" -#include "qsslkey.h" -#include "qsslkey_p.h" -#include "qsslcertificate_p.h" - -#include <QtCore/qfunctions_winrt.h> - -#include <wrl.h> -#include <windows.security.cryptography.h> -#include <windows.security.cryptography.core.h> -#include <windows.security.cryptography.certificates.h> -#include <windows.storage.streams.h> -#include <robuffer.h> - -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; -using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::Security::Cryptography; -using namespace ABI::Windows::Security::Cryptography::Certificates; -using namespace ABI::Windows::Security::Cryptography::Core; -using namespace ABI::Windows::Storage::Streams; - -QT_USE_NAMESPACE - -struct SslKeyGlobal -{ - SslKeyGlobal() - { - HRESULT hr; - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Security_Cryptography_Core_CryptographicEngine).Get(), - &engine); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr<ISymmetricKeyAlgorithmProviderStatics> keyProviderFactory; - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Security_Cryptography_Core_SymmetricKeyAlgorithmProvider).Get(), - &keyProviderFactory); - Q_ASSERT_SUCCEEDED(hr); - hr = keyProviderFactory->OpenAlgorithm(HString::MakeReference(L"DES_CBC").Get(), - &keyProviders[QSslKeyPrivate::DesCbc]); - Q_ASSERT_SUCCEEDED(hr); - hr = keyProviderFactory->OpenAlgorithm(HString::MakeReference(L"3DES_CBC").Get(), - &keyProviders[QSslKeyPrivate::DesEde3Cbc]); - Q_ASSERT_SUCCEEDED(hr); - hr = keyProviderFactory->OpenAlgorithm(HString::MakeReference(L"RC2_CBC").Get(), - &keyProviders[QSslKeyPrivate::Rc2Cbc]); - Q_ASSERT_SUCCEEDED(hr); - hr = keyProviderFactory->OpenAlgorithm(HString::MakeReference(L"AES_CBC").Get(), - &keyProviders[QSslKeyPrivate::Aes128Cbc]); - Q_ASSERT_SUCCEEDED(hr); - hr = keyProviderFactory->OpenAlgorithm(HString::MakeReference(L"AES_CBC").Get(), - &keyProviders[QSslKeyPrivate::Aes192Cbc]); - Q_ASSERT_SUCCEEDED(hr); - hr = keyProviderFactory->OpenAlgorithm(HString::MakeReference(L"AES_CBC").Get(), - &keyProviders[QSslKeyPrivate::Aes256Cbc]); - Q_ASSERT_SUCCEEDED(hr); - - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Security_Cryptography_CryptographicBuffer).Get(), - &bufferFactory); - Q_ASSERT_SUCCEEDED(hr); - } - - ComPtr<ICryptographicEngineStatics> engine; - QHash<QSslKeyPrivate::Cipher, ComPtr<ISymmetricKeyAlgorithmProvider>> keyProviders; - ComPtr<ICryptographicBufferStatics> bufferFactory; -}; -Q_GLOBAL_STATIC(SslKeyGlobal, g) - -static QByteArray doCrypt(QSslKeyPrivate::Cipher cipher, QByteArray data, const QByteArray &key, const QByteArray &iv, bool encrypt) -{ - HRESULT hr; - - ISymmetricKeyAlgorithmProvider *keyProvider = g->keyProviders[cipher].Get(); - Q_ASSERT(keyProvider); - - ComPtr<IBuffer> keyBuffer; - hr = g->bufferFactory->CreateFromByteArray(key.length(), (BYTE *)key.data(), &keyBuffer); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<ICryptographicKey> cryptographicKey; - hr = keyProvider->CreateSymmetricKey(keyBuffer.Get(), &cryptographicKey); - Q_ASSERT_SUCCEEDED(hr); - - UINT32 blockLength; - hr = keyProvider->get_BlockLength(&blockLength); - Q_ASSERT_SUCCEEDED(hr); - if (encrypt) { // Add padding - const char padding = blockLength - data.length() % blockLength; - data += QByteArray(padding, padding); - } - - ComPtr<IBuffer> dataBuffer; - hr = g->bufferFactory->CreateFromByteArray(data.length(), (BYTE *)data.data(), &dataBuffer); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<IBuffer> ivBuffer; - hr = g->bufferFactory->CreateFromByteArray(iv.length(), (BYTE *)iv.data(), &ivBuffer); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<IBuffer> resultBuffer; - hr = encrypt ? g->engine->Encrypt(cryptographicKey.Get(), dataBuffer.Get(), ivBuffer.Get(), &resultBuffer) - : g->engine->Decrypt(cryptographicKey.Get(), dataBuffer.Get(), ivBuffer.Get(), &resultBuffer); - Q_ASSERT_SUCCEEDED(hr); - - UINT32 resultLength; - hr = resultBuffer->get_Length(&resultLength); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<Windows::Storage::Streams::IBufferByteAccess> bufferAccess; - hr = resultBuffer.As(&bufferAccess); - Q_ASSERT_SUCCEEDED(hr); - byte *resultData; - hr = bufferAccess->Buffer(&resultData); - Q_ASSERT_SUCCEEDED(hr); - - if (!encrypt) { // Remove padding - const uchar padding = resultData[resultLength - 1]; - if (padding > 0 && padding <= blockLength) - resultLength -= padding; - else - qCWarning(lcSsl, "Invalid padding length of %u; decryption likely failed.", padding); - } - - return QByteArray(reinterpret_cast<const char *>(resultData), resultLength); -} - -QByteArray QSslKeyPrivate::decrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv) -{ - return doCrypt(cipher, data, key, iv, false); -} - -QByteArray QSslKeyPrivate::encrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv) -{ - return doCrypt(cipher, data, key, iv, true); -} diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 47dc7a9f71..64e556ac3c 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -456,9 +456,6 @@ #ifndef QT_NO_OPENSSL #include "qsslsocket_openssl_p.h" #endif -#ifdef Q_OS_WINRT -#include "qsslsocket_winrt_p.h" -#endif #ifdef QT_SECURETRANSPORT #include "qsslsocket_mac_p.h" #endif diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h index d21e8900d8..e7e24ef246 100644 --- a/src/network/ssl/qsslsocket.h +++ b/src/network/ssl/qsslsocket.h @@ -279,7 +279,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_flushWriteBuffer()) Q_PRIVATE_SLOT(d_func(), void _q_flushReadBuffer()) Q_PRIVATE_SLOT(d_func(), void _q_resumeImplementation()) -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !QT_CONFIG(schannel) +#if defined(Q_OS_WIN) && !QT_CONFIG(schannel) Q_PRIVATE_SLOT(d_func(), void _q_caRootLoaded(QSslCertificate,QSslCertificate)) #endif friend class QSslSocketBackendPrivate; diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index 971650a71c..c5e604cf5e 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -75,9 +75,7 @@ class QSslContext; #elif defined(Q_OS_WIN) #include <QtCore/qt_windows.h> #include <memory> -#ifndef Q_OS_WINRT #include <wincrypt.h> -#endif // !Q_OS_WINRT #ifndef HCRYPTPROV_LEGACY #define HCRYPTPROV_LEGACY HCRYPTPROV #endif // !HCRYPTPROV_LEGACY @@ -184,7 +182,7 @@ public: void _q_flushWriteBuffer(); void _q_flushReadBuffer(); void _q_resumeImplementation(); -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !QT_CONFIG(schannel) +#if defined(Q_OS_WIN) && !QT_CONFIG(schannel) virtual void _q_caRootLoaded(QSslCertificate,QSslCertificate) = 0; #endif diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp deleted file mode 100644 index 5f5201fc82..0000000000 --- a/src/network/ssl/qsslsocket_winrt.cpp +++ /dev/null @@ -1,682 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qssl_p.h" -#include "qsslsocket_winrt_p.h" -#include "qsslsocket.h" -#include "qsslcertificate_p.h" -#include "qsslcipher_p.h" - -#include <QtCore/QCoreApplication> -#include <QtCore/QSysInfo> -#include <QtCore/qfunctions_winrt.h> -#include <private/qnativesocketengine_winrt_p.h> -#include <private/qeventdispatcher_winrt_p.h> - -#include <windows.networking.h> -#include <windows.networking.sockets.h> -#include <windows.security.cryptography.certificates.h> -#include <robuffer.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::Sockets; -using namespace ABI::Windows::Security::Cryptography::Certificates; -using namespace ABI::Windows::Storage::Streams; - -QT_BEGIN_NAMESPACE - -bool QSslSocketPrivate::s_libraryLoaded = true; -bool QSslSocketPrivate::s_loadRootCertsOnDemand = true; -bool QSslSocketPrivate::s_loadedCiphersAndCerts = false; - -struct SslSocketGlobal -{ - SslSocketGlobal() - { - HRESULT hr; - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), - &hostNameFactory); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr<ICertificateStoresStatics> certificateStores; - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Security_Cryptography_Certificates_CertificateStores).Get(), - &certificateStores); - Q_ASSERT_SUCCEEDED(hr); - - hr = certificateStores->get_TrustedRootCertificationAuthorities(&rootStore); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr<IAsyncOperation<IVectorView<Certificate *> *>> op; - hr = certificateStores->FindAllAsync(&op); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<IVectorView<Certificate *>> certificates; - hr = QWinRTFunctions::await(op, certificates.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - quint32 size; - hr = certificates->get_Size(&size); - Q_ASSERT_SUCCEEDED(hr); - for (quint32 i = 0; i < size; ++i) { - ComPtr<ICertificate> certificate; - hr = certificates->GetAt(i, &certificate); - Q_ASSERT_SUCCEEDED(hr); - systemCaCertificates.append(QSslCertificatePrivate::QSslCertificate_from_Certificate(certificate.Get())); - } - } - - void syncCaCertificates(const QSet<QSslCertificate> &add, const QSet<QSslCertificate> &remove) - { - QMutexLocker locker(&certificateMutex); - for (const QSslCertificate &certificate : add) { - QHash<QSslCertificate, QAtomicInt>::iterator it = additionalCertificates.find(certificate); - if (it != additionalCertificates.end()) { - it.value().ref(); // Add a reference - } else { - // install certificate - HRESULT hr; - hr = rootStore->Add(static_cast<ICertificate *>(certificate.handle())); - Q_ASSERT_SUCCEEDED(hr); - additionalCertificates.insert(certificate, 1); - } - } - for (const QSslCertificate &certificate : remove) { - QHash<QSslCertificate, QAtomicInt>::iterator it = additionalCertificates.find(certificate); - if (it != additionalCertificates.end() && !it.value().deref()) { - // no more references, remove certificate - HRESULT hr; - hr = rootStore->Delete(static_cast<ICertificate *>(certificate.handle())); - Q_ASSERT_SUCCEEDED(hr); - additionalCertificates.erase(it); - } - } - } - - ComPtr<IHostNameFactory> hostNameFactory; - QList<QSslCertificate> systemCaCertificates; - -private: - QMutex certificateMutex; - ComPtr<ICertificateStore> rootStore; - QHash<QSslCertificate, QAtomicInt> additionalCertificates; -}; -Q_GLOBAL_STATIC(SslSocketGlobal, g) - -// Called on the socket's thread to avoid cross-thread deletion -void QSslSocketConnectionHelper::disconnectSocketFromHost() -{ - if (d->plainSocket) - d->plainSocket->disconnectFromHost(); -} - -QSslSocketBackendPrivate::QSslSocketBackendPrivate() - : connectionHelper(new QSslSocketConnectionHelper(this)) -{ -} - -QSslSocketBackendPrivate::~QSslSocketBackendPrivate() -{ - g->syncCaCertificates(QSet<QSslCertificate>(), previousCaCertificates); -} - -bool QSslSocketPrivate::supportsSsl() -{ - return true; -} - -void QSslSocketPrivate::ensureInitialized() -{ - if (s_loadedCiphersAndCerts) - return; - s_loadedCiphersAndCerts = true; - resetDefaultCiphers(); -} - -long QSslSocketPrivate::sslLibraryVersionNumber() -{ - // ### Qt 6: Find a proper replacement for the deprecated method below. - return QSysInfo::windowsVersion(); -} - -QString QSslSocketPrivate::sslLibraryVersionString() -{ - return QStringLiteral("Windows Runtime, ") + QSysInfo::prettyProductName(); -} - -long QSslSocketPrivate::sslLibraryBuildVersionNumber() -{ - Q_UNIMPLEMENTED(); - return 0; -} - -QString QSslSocketPrivate::sslLibraryBuildVersionString() -{ - Q_UNIMPLEMENTED(); - return QString::number(sslLibraryBuildVersionNumber()); -} - -void QSslSocketPrivate::resetDefaultCiphers() -{ - setDefaultSupportedCiphers(QSslSocketBackendPrivate::defaultCiphers()); - setDefaultCiphers(QSslSocketBackendPrivate::defaultCiphers()); -} - - -QList<QSslCipher> QSslSocketBackendPrivate::defaultCiphers() -{ - QList<QSslCipher> ciphers; - const QString protocolStrings[] = { QStringLiteral("TLSv1"), - QStringLiteral("TLSv1.1"), QStringLiteral("TLSv1.2") }; - const QSsl::SslProtocol protocols[] = { QSsl::TlsV1_0, QSsl::TlsV1_1, QSsl::TlsV1_2 }; - const int size = static_cast<int>(ARRAYSIZE(protocols)); - ciphers.reserve(size); - for (int i = 0; i < size; ++i) { - QSslCipher cipher; - cipher.d->isNull = false; - cipher.d->name = QStringLiteral("WINRT"); - cipher.d->protocol = protocols[i]; - cipher.d->protocolString = protocolStrings[i]; - ciphers.append(cipher); - } - return ciphers; -} - -QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates() -{ - return g->systemCaCertificates; -} - -void QSslSocketBackendPrivate::startClientEncryption() -{ - Q_Q(QSslSocket); - - QSsl::SslProtocol protocol = q->protocol(); - switch (q->protocol()) { - case QSsl::AnyProtocol: - protectionLevel = SocketProtectionLevel_Tls10; - break; - case QSsl::TlsV1_0: - protectionLevel = SocketProtectionLevel_Tls10; - break; - case QSsl::TlsV1_1: - protectionLevel = SocketProtectionLevel_Tls11; - break; - case QSsl::TlsV1_2: - protectionLevel = SocketProtectionLevel_Tls12; - break; - case QSsl::TlsV1_0OrLater: - case QSsl::TlsV1_1OrLater: - case QSsl::TlsV1_2OrLater: - case QSsl::TlsV1_3: - case QSsl::TlsV1_3OrLater: - // TlsV1_0OrLater, TlsV1_1OrLater and TlsV1_2OrLater are disabled on WinRT - // because there is no good way to map them to the native API. - setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError, - QStringLiteral("unsupported protocol")); - return; - case QSsl::SecureProtocols: - // SocketProtectionLevel_Tls12 actually means "use TLS1.0, 1.1 or 1.2" - // https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.socketprotectionlevel - protectionLevel = SocketProtectionLevel_Tls12; - break; - default: - protectionLevel = SocketProtectionLevel_Tls12; // default to highest - protocol = QSsl::TlsV1_2; - break; - } - - // Sync custom certificates - const QSet<QSslCertificate> caCertificates(configuration.caCertificates.constBegin(), configuration.caCertificates.constEnd()); - const QSet<QSslCertificate> newCertificates = caCertificates - previousCaCertificates; - const QSet<QSslCertificate> oldCertificates = previousCaCertificates - caCertificates; - g->syncCaCertificates(newCertificates, oldCertificates); - previousCaCertificates = caCertificates; - - continueHandshake(); -} - -void QSslSocketBackendPrivate::startServerEncryption() -{ - Q_UNIMPLEMENTED(); -} - -void QSslSocketBackendPrivate::transmit() -{ - Q_Q(QSslSocket); - - if (connectionEncrypted && !writeBuffer.isEmpty()) { - qint64 totalBytesWritten = 0; - int nextDataBlockSize; - while ((nextDataBlockSize = writeBuffer.nextDataBlockSize()) > 0) { - int writtenBytes = plainSocket->write(writeBuffer.readPointer(), nextDataBlockSize); - writtenBytes = nextDataBlockSize; - - writeBuffer.free(writtenBytes); - totalBytesWritten += writtenBytes; - - if (writtenBytes < nextDataBlockSize) - break; - } - - if (totalBytesWritten > 0) { - // Don't emit bytesWritten() recursively. - if (!emittedBytesWritten) { - emittedBytesWritten = true; - emit q->bytesWritten(totalBytesWritten); - emittedBytesWritten = false; - } - emit q->channelBytesWritten(0, totalBytesWritten); - } - } - - // Check if we've got any data to be read from the socket. - int pendingBytes; - bool bytesRead = false; - while ((pendingBytes = plainSocket->bytesAvailable()) > 0) { - char *ptr = buffer.reserve(pendingBytes); - int readBytes = plainSocket->read(ptr, pendingBytes); - buffer.chop(pendingBytes - readBytes); - bytesRead = true; - } - - if (bytesRead) { - if (readyReadEmittedPointer) - *readyReadEmittedPointer = true; - emit q->readyRead(); - emit q->channelReadyRead(0); - } - - if (pendingClose) { - pendingClose = false; - q->disconnectFromHost(); - } -} - -void QSslSocketBackendPrivate::disconnectFromHost() -{ - QMetaObject::invokeMethod(connectionHelper.data(), "disconnectSocketFromHost", Qt::QueuedConnection); -} - -void QSslSocketBackendPrivate::disconnected() -{ -} - -QSslCipher QSslSocketBackendPrivate::sessionCipher() const -{ - return configuration.sessionCipher; -} - -QSsl::SslProtocol QSslSocketBackendPrivate::sessionProtocol() const -{ - return configuration.sessionCipher.protocol(); -} - -void QSslSocketBackendPrivate::continueHandshake() -{ - IStreamSocket *socket = reinterpret_cast<IStreamSocket *>(plainSocket->socketDescriptor()); - if (qintptr(socket) == -1) { - setErrorAndEmit(QAbstractSocket::SslInternalError, - QStringLiteral("At attempt was made to continue the handshake on an invalid socket.")); - return; - } - - HRESULT hr; - ComPtr<IHostName> hostName; - const QString host = verificationPeerName.isEmpty() ? plainSocket->peerName() - : verificationPeerName; - if (host.isEmpty()) { - ComPtr<IStreamSocketInformation> info; - hr = socket->get_Information(&info); - Q_ASSERT_SUCCEEDED(hr); - hr = info->get_RemoteAddress(&hostName); - } else { - HStringReference hostRef(reinterpret_cast<LPCWSTR>(host.utf16()), host.length()); - hr = g->hostNameFactory->CreateHostName(hostRef.Get(), &hostName); - Q_ASSERT_SUCCEEDED(hr); - } - if (FAILED(hr)) { - setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError, qt_error_string(hr)); - return; - } - - ComPtr<IStreamSocketControl> control; - hr = socket->get_Control(&control); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr<IStreamSocketControl2> control2; - hr = control.As(&control2); - ComPtr<IVector<ChainValidationResult>> ignoreList; - hr = control2->get_IgnorableServerCertificateErrors(&ignoreList); - Q_ASSERT_SUCCEEDED(hr); - - QSet<QSslError> ignoreErrors(ignoreErrorsList.constBegin(), ignoreErrorsList.constEnd()); - for (int i = ChainValidationResult_Untrusted; i < ChainValidationResult_OtherErrors + 1; ++i) { - // Populate the native ignore list - break to add, continue to skip - switch (i) { - case ChainValidationResult_Revoked: - case ChainValidationResult_InvalidSignature: - case ChainValidationResult_BasicConstraintsError: - case ChainValidationResult_InvalidCertificateAuthorityPolicy: - case ChainValidationResult_UnknownCriticalExtension: - case ChainValidationResult_OtherErrors: - continue; // The above errors can't be ignored in the handshake - case ChainValidationResult_Untrusted: - if (ignoreAllSslErrors || ignoreErrors.contains(QSslError::CertificateUntrusted)) - break; - continue; - case ChainValidationResult_Expired: - if (ignoreAllSslErrors || ignoreErrors.contains(QSslError::CertificateExpired)) - break; - continue; - case ChainValidationResult_IncompleteChain: - if (ignoreAllSslErrors - || ignoreErrors.contains(QSslError::InvalidCaCertificate) - || ignoreErrors.contains(QSslError::UnableToVerifyFirstCertificate) - || ignoreErrors.contains(QSslError::UnableToGetIssuerCertificate)) { - break; - } - continue; - case ChainValidationResult_WrongUsage: - if (ignoreAllSslErrors || ignoreErrors.contains(QSslError::InvalidPurpose)) - break; - continue; - case ChainValidationResult_InvalidName: - if (ignoreAllSslErrors - || ignoreErrors.contains(QSslError::HostNameMismatch) - || ignoreErrors.contains(QSslError::SubjectIssuerMismatch)) { - break; - } - continue; - case ChainValidationResult_RevocationInformationMissing: - case ChainValidationResult_RevocationFailure: - default: - if (ignoreAllSslErrors) - break; - continue; - } - hr = ignoreList->Append(static_cast<ChainValidationResult>(i)); - Q_ASSERT_SUCCEEDED(hr); - } - - ComPtr<IAsyncAction> op; - hr = socket->UpgradeToSslAsync(protectionLevel, hostName.Get(), &op); - if (FAILED(hr)) { - setErrorAndEmit(QAbstractSocket::SslInternalError, - QSslSocket::tr("Error creating SSL session: %1").arg(qt_error_string(hr))); - return; - } - - hr = QEventDispatcherWinRT::runOnXamlThread([this, op]() { - HRESULT hr = op->put_Completed(Callback<IAsyncActionCompletedHandler>( - this, &QSslSocketBackendPrivate::onSslUpgrade).Get()); - return hr; - }); - Q_ASSERT_SUCCEEDED(hr); -} - -HRESULT QSslSocketBackendPrivate::onSslUpgrade(IAsyncAction *action, AsyncStatus) -{ - Q_Q(QSslSocket); - - if (wasDeleted) { - qCWarning(lcSsl, - "SSL upgrade callback received after the delegate was deleted. " - "This may be indicative of an internal bug in the WinRT SSL implementation."); - return S_OK; - } - - HRESULT hr = action->GetResults(); - QSet<QSslError> errors; - switch (hr) { - case SEC_E_INVALID_TOKEN: // Occurs when the server doesn't support the requested protocol - setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, qt_error_string(hr)); - q->disconnectFromHost(); - return S_OK; - default: - if (FAILED(hr)) - qErrnoWarning(hr, "error"); // Unhandled error; let sslErrors take care of it - break; - } - - IStreamSocket *socket = reinterpret_cast<IStreamSocket *>(plainSocket->socketDescriptor()); - if (qintptr(socket) == -1) { - qCWarning(lcSsl, - "The underlying TCP socket used by the SSL socket is invalid. " - "This may be indicative of an internal bug in the WinRT SSL implementation."); - return S_OK; - } - - ComPtr<IStreamSocketInformation> info; - hr = socket->get_Information(&info); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<IStreamSocketInformation2> info2; - hr = info.As(&info2); - Q_ASSERT_SUCCEEDED(hr); - - // Cipher - QSsl::SslProtocol protocol; - SocketProtectionLevel protectionLevel; - hr = info->get_ProtectionLevel(&protectionLevel); - switch (protectionLevel) { - default: - protocol = QSsl::UnknownProtocol; - break; - case SocketProtectionLevel_Ssl: - protocol = QSsl::SslV3; - break; - case SocketProtectionLevel_Tls10: - protocol = QSsl::TlsV1_0; - break; - case SocketProtectionLevel_Tls11: - protocol = QSsl::TlsV1_1; - break; - case SocketProtectionLevel_Tls12: - protocol = QSsl::TlsV1_2; - break; - } - configuration.sessionCipher = QSslCipher(QStringLiteral("WINRT"), protocol); // The actual cipher name is not accessible - - // Certificate & chain - ComPtr<ICertificate> certificate; - hr = info2->get_ServerCertificate(&certificate); - Q_ASSERT_SUCCEEDED(hr); - - QList<QSslCertificate> peerCertificateChain; - if (certificate) { - ComPtr<IAsyncOperation<CertificateChain *>> op; - hr = certificate->BuildChainAsync(nullptr, &op); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<ICertificateChain> certificateChain; - hr = QWinRTFunctions::await(op, certificateChain.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr<IVectorView<Certificate *>> certificates; - hr = certificateChain->GetCertificates(true, &certificates); - Q_ASSERT_SUCCEEDED(hr); - quint32 certificatesLength; - hr = certificates->get_Size(&certificatesLength); - Q_ASSERT_SUCCEEDED(hr); - for (quint32 i = 0; i < certificatesLength; ++i) { - ComPtr<ICertificate> chainCertificate; - hr = certificates->GetAt(i, &chainCertificate); - Q_ASSERT_SUCCEEDED(hr); - peerCertificateChain.append(QSslCertificatePrivate::QSslCertificate_from_Certificate(chainCertificate.Get())); - } - } - - configuration.peerCertificate = certificate ? QSslCertificatePrivate::QSslCertificate_from_Certificate(certificate.Get()) - : QSslCertificate(); - configuration.peerCertificateChain = peerCertificateChain; - - // Errors - ComPtr<IVectorView<ChainValidationResult>> chainValidationResults; - hr = info2->get_ServerCertificateErrors(&chainValidationResults); - Q_ASSERT_SUCCEEDED(hr); - quint32 size; - hr = chainValidationResults->get_Size(&size); - Q_ASSERT_SUCCEEDED(hr); - for (quint32 i = 0; i < size; ++i) { - ChainValidationResult result; - hr = chainValidationResults->GetAt(i, &result); - Q_ASSERT_SUCCEEDED(hr); - switch (result) { - case ChainValidationResult_Success: - break; - case ChainValidationResult_Untrusted: - errors.insert(QSslError::CertificateUntrusted); - break; - case ChainValidationResult_Revoked: - errors.insert(QSslError::CertificateRevoked); - break; - case ChainValidationResult_Expired: - errors.insert(QSslError::CertificateExpired); - break; - case ChainValidationResult_IncompleteChain: - errors.insert(QSslError::UnableToGetIssuerCertificate); - break; - case ChainValidationResult_InvalidSignature: - errors.insert(QSslError::CertificateSignatureFailed); - break; - case ChainValidationResult_WrongUsage: - errors.insert(QSslError::InvalidPurpose); - break; - case ChainValidationResult_InvalidName: - errors.insert(QSslError::HostNameMismatch); - break; - case ChainValidationResult_InvalidCertificateAuthorityPolicy: - errors.insert(QSslError::InvalidCaCertificate); - break; - default: - errors.insert(QSslError::UnspecifiedError); - break; - } - } - - sslErrors = QList<QSslError>(errors.constBegin(), errors.constEnd()); - - // Peer validation - if (!configuration.peerCertificate.isNull()) { - const QString peerName = verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName; - if (!isMatchingHostname(configuration.peerCertificate, peerName)) { - // No matches in common names or alternate names. - const QSslError error(QSslError::HostNameMismatch, configuration.peerCertificate); - const int index = sslErrors.indexOf(QSslError::HostNameMismatch); - if (index >= 0) // Replace the existing error - sslErrors[index] = error; - else - sslErrors.append(error); - emit q->peerVerifyError(error); - } - - // Peer validation required, but no certificate is present - } else if (configuration.peerVerifyMode == QSslSocket::VerifyPeer - || configuration.peerVerifyMode == QSslSocket::AutoVerifyPeer) { - QSslError error(QSslError::NoPeerCertificate); - sslErrors.append(error); - emit q->peerVerifyError(error); - } - - // Peer chain validation - for (const QSslCertificate &certificate : qAsConst(peerCertificateChain)) { - if (!QSslCertificatePrivate::isBlacklisted(certificate)) - continue; - - QSslError error(QSslError::CertificateBlacklisted, certificate); - sslErrors.append(error); - emit q->peerVerifyError(error); - } - - if (!sslErrors.isEmpty()) { - emit q->sslErrors(sslErrors); - setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, sslErrors.constFirst().errorString()); - - // Disconnect if there are any non-ignorable errors - for (const QSslError &error : qAsConst(sslErrors)) { - if (ignoreErrorsList.contains(error)) - continue; - q->disconnectFromHost(); - return S_OK; - } - } - - if (readBufferMaxSize) - plainSocket->setReadBufferSize(readBufferMaxSize); - - connectionEncrypted = true; - emit q->encrypted(); - - // The write buffer may already have data written to it, so we need to call transmit. - // This has to be done in 'q's thread, and not in the current thread (the XAML thread). - QMetaObject::invokeMethod(q, [this](){ transmit(); }); - - if (pendingClose) { - pendingClose = false; - q->disconnectFromHost(); - } - - return S_OK; -} - -QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &certificateChain, const QString &hostName) -{ - Q_UNIMPLEMENTED(); - Q_UNUSED(certificateChain) - Q_UNUSED(hostName) - QList<QSslError> errors; - - return errors; -} - -bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device, - QSslKey *key, QSslCertificate *cert, - QList<QSslCertificate> *caCertificates, - const QByteArray &passPhrase) -{ - Q_UNIMPLEMENTED(); - Q_UNUSED(device) - Q_UNUSED(key) - Q_UNUSED(cert) - Q_UNUSED(caCertificates) - Q_UNUSED(passPhrase) - return false; -} - -QT_END_NAMESPACE diff --git a/src/network/ssl/qsslsocket_winrt_p.h b/src/network/ssl/qsslsocket_winrt_p.h deleted file mode 100644 index 030db6d4fa..0000000000 --- a/src/network/ssl/qsslsocket_winrt_p.h +++ /dev/null @@ -1,110 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSSLSOCKET_WINRT_P_H -#define QSSLSOCKET_WINRT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of the QtNetwork library. This header file may change from -// version to version without notice, or even be removed. -// -// We mean it. -// - -#include <QtNetwork/private/qtnetworkglobal_p.h> -#include "qsslsocket_p.h" - -#include <wrl.h> -#include <windows.networking.sockets.h> - -QT_BEGIN_NAMESPACE - -class QSslSocketConnectionHelper : public QObject -{ - Q_OBJECT -public: - QSslSocketConnectionHelper(QSslSocketBackendPrivate *d) - : d(d) { } - - Q_INVOKABLE void disconnectSocketFromHost(); - -private: - QSslSocketBackendPrivate *d; -}; - -class QSslSocketBackendPrivate : public QSslSocketPrivate -{ - Q_DECLARE_PUBLIC(QSslSocket) -public: - QSslSocketBackendPrivate(); - ~QSslSocketBackendPrivate(); - - // Platform specific functions - void startClientEncryption() override; - void startServerEncryption() override; - void transmit() override; - void disconnectFromHost() override; - void disconnected() override; - QSslCipher sessionCipher() const override; - QSsl::SslProtocol sessionProtocol() const override; - void continueHandshake() override; - - static QList<QSslCipher> defaultCiphers(); - static QList<QSslError> verify(const QList<QSslCertificate> &certificateChain, const QString &hostName); - static bool importPkcs12(QIODevice *device, - QSslKey *key, QSslCertificate *cert, - QList<QSslCertificate> *caCertificates, - const QByteArray &passPhrase); - -private: - HRESULT onSslUpgrade(ABI::Windows::Foundation::IAsyncAction *, - ABI::Windows::Foundation::AsyncStatus); - - QScopedPointer<QSslSocketConnectionHelper> connectionHelper; - ABI::Windows::Networking::Sockets::SocketProtectionLevel protectionLevel; - QSet<QSslCertificate> previousCaCertificates; -}; - -QT_END_NAMESPACE - -#endif // QSSLSOCKET_WINRT_P_H diff --git a/src/network/ssl/ssl.pri b/src/network/ssl/ssl.pri index dfbf539303..1310435eb9 100644 --- a/src/network/ssl/ssl.pri +++ b/src/network/ssl/ssl.pri @@ -42,16 +42,6 @@ qtConfig(ssl) { ssl/qsslpresharedkeyauthenticator.cpp \ ssl/qocspresponse.cpp - winrt { - HEADERS += ssl/qsslsocket_winrt_p.h - SOURCES += ssl/qsslcertificate_winrt.cpp \ - ssl/qssldiffiehellmanparameters_dummy.cpp \ - ssl/qsslkey_qt.cpp \ - ssl/qsslkey_winrt.cpp \ - ssl/qsslsocket_winrt.cpp \ - ssl/qsslellipticcurve_dummy.cpp - } - qtConfig(schannel) { HEADERS += ssl/qsslsocket_schannel_p.h SOURCES += ssl/qsslsocket_schannel.cpp \ |