diff options
author | Maurice Kalinowski <maurice.kalinowski@qt.io> | 2016-11-04 13:46:36 +0100 |
---|---|---|
committer | Maurice Kalinowski <maurice.kalinowski@qt.io> | 2016-11-23 09:27:45 +0000 |
commit | e9fa435652ef064515bd5c04c0b5e5c4a30ebca4 (patch) | |
tree | 3658f0fadfce68732bca17b69cbff4dd3ea512f4 /src/network/socket/qnativesocketengine_winrt.cpp | |
parent | 20017d0b1bde34190d96bebe34b4e641efdde779 (diff) |
winrt: Add support for Windows Information Protection
Windows Information Protection is used for splitting corporate and
personal data, requiring connections to be established in a different
way instantiating ThreadNetworkContext.
Usage is enabled via the QT_WINRT_USE_THREAD_NETWORK_CONTEXT environment
variable.
Change-Id: I3aaa097b66fc616d42cd05a1e20bbcb004f6e467
Reviewed-by: James Tong
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Diffstat (limited to 'src/network/socket/qnativesocketengine_winrt.cpp')
-rw-r--r-- | src/network/socket/qnativesocketengine_winrt.cpp | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 3daca38959..d0b8bff7f9 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -75,6 +75,9 @@ 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; @@ -84,6 +87,45 @@ typedef IAsyncOperationWithProgress<IBuffer *, UINT32> IAsyncBufferOperation; QT_BEGIN_NAMESPACE +#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 + static inline QString qt_QStringFromHString(const HString &string) { UINT32 length; @@ -367,9 +409,23 @@ bool QNativeSocketEngine::connectToHost(const QHostAddress &address, quint16 por bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port) { Q_D(QNativeSocketEngine); + HRESULT hr; + +#if _MSC_VER >= 1900 + ComPtr<IThreadNetworkContext> networkContext; + if (!qEnvironmentVariableIsEmpty("QT_WINRT_USE_THREAD_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; - HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), + hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), &hostNameFactory); Q_ASSERT_SUCCEEDED(hr); ComPtr<IHostName> remoteHost; @@ -390,6 +446,16 @@ bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port) } Q_ASSERT_SUCCEEDED(hr); +#if _MSC_VER >= 1900 + if (networkContext != nullptr) { + 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->connectOp->put_Completed(Callback<IAsyncActionCompletedHandler>( |