summaryrefslogtreecommitdiffstats
path: root/src/network/socket/qnativesocketengine_winrt.cpp
diff options
context:
space:
mode:
authorMaurice Kalinowski <maurice.kalinowski@qt.io>2016-11-04 13:46:36 +0100
committerMaurice Kalinowski <maurice.kalinowski@qt.io>2016-11-23 09:27:45 +0000
commite9fa435652ef064515bd5c04c0b5e5c4a30ebca4 (patch)
tree3658f0fadfce68732bca17b69cbff4dd3ea512f4 /src/network/socket/qnativesocketengine_winrt.cpp
parent20017d0b1bde34190d96bebe34b4e641efdde779 (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.cpp68
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>(