summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorJose <jose@zeroc.com>2017-01-10 14:34:05 +0100
committerJose <jose@zeroc.com>2017-01-10 14:34:05 +0100
commit82f314a870b145e81553987100067558498a1be0 (patch)
tree2b94ca3464ee643c53237021bc7035394fecb4fd /cpp/src
parentFix for static initialization issue with VS 2013 (diff)
downloadice-82f314a870b145e81553987100067558498a1be0.tar.bz2
ice-82f314a870b145e81553987100067558498a1be0.tar.xz
ice-82f314a870b145e81553987100067558498a1be0.zip
UWP code simplifications
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Ice/EndpointFactoryManager.cpp4
-rwxr-xr-xcpp/src/Ice/Network.cpp123
-rwxr-xr-xcpp/src/Ice/Network.h32
-rw-r--r--cpp/src/Ice/ReferenceFactory.cpp2
-rwxr-xr-xcpp/src/IceSSL/Certificate.cpp47
-rw-r--r--cpp/src/IceSSL/UWPTransceiverI.cpp33
-rwxr-xr-xcpp/src/IceSSL/Util.cpp255
7 files changed, 212 insertions, 284 deletions
diff --git a/cpp/src/Ice/EndpointFactoryManager.cpp b/cpp/src/Ice/EndpointFactoryManager.cpp
index d69f5e2ff82..72fa5002aaa 100644
--- a/cpp/src/Ice/EndpointFactoryManager.cpp
+++ b/cpp/src/Ice/EndpointFactoryManager.cpp
@@ -62,7 +62,7 @@ IceInternal::EndpointFactoryManager::get(Short type) const
return _factories[i];
}
}
- return 0;
+ return ICE_NULLPTR;
}
EndpointIPtr
@@ -170,7 +170,7 @@ IceInternal::EndpointFactoryManager::create(const string& str, bool oaEndpoint)
return ue; // Endpoint is opaque, but we don't have a factory for its type.
}
- return 0;
+ return ICE_NULLPTR;
}
EndpointIPtr
diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp
index e53532c48d9..95e9a49249d 100755
--- a/cpp/src/Ice/Network.cpp
+++ b/cpp/src/Ice/Network.cpp
@@ -32,7 +32,6 @@
#if defined(ICE_OS_UWP)
# include <IceUtil/InputUtil.h>
-# include <IceUtil/CountDownLatch.h>
#elif defined(_WIN32)
# include <winsock2.h>
# include <ws2tcpip.h>
@@ -2057,46 +2056,24 @@ IceInternal::setMcastGroup(SOCKET fd, const Address& group, const string&)
// message. We send a valiate connection message that the peers will ignore to workaround
// the issue.
//
- promise<void> p;
- create_task(safe_cast<DatagramSocket^>(fd)->GetOutputStreamAsync(group.host, group.port))
+ auto out = IceInternal::runSync(safe_cast<DatagramSocket^>(fd)->GetOutputStreamAsync(group.host, group.port));
+ auto writer = ref new DataWriter(out);
- .then([](IOutputStream^ out)
- {
+ OutputStream os;
+ os.write(magic[0]);
+ os.write(magic[1]);
+ os.write(magic[2]);
+ os.write(magic[3]);
+ os.write(currentProtocol);
+ os.write(currentProtocolEncoding);
+ os.write(validateConnectionMsg);
+ os.write(static_cast<Byte>(0)); // Compression status (always zero for validate connection).
+ os.write(headerSize); // Message size.
+ os.i = os.b.begin();
- OutputStream os;
- os.write(magic[0]);
- os.write(magic[1]);
- os.write(magic[2]);
- os.write(magic[3]);
- os.write(currentProtocol);
- os.write(currentProtocolEncoding);
- os.write(validateConnectionMsg);
- os.write(static_cast<Byte>(0)); // Compression status (always zero for validate connection).
- os.write(headerSize); // Message size.
- os.i = os.b.begin();
-
- auto writer = ref new DataWriter(out);
- writer->WriteBytes(ref new Array<unsigned char>(&*os.i, static_cast<unsigned int>(headerSize)));
-
- return writer->StoreAsync();
- },
- task_continuation_context::use_arbitrary())
-
- .then([&p](task<unsigned int> t)
- {
- try
- {
- t.get();
- p.set_value();
- }
- catch(...)
- {
- p.set_exception(current_exception());
- }
- },
- task_continuation_context::use_arbitrary());
+ writer->WriteBytes(ref new Array<unsigned char>(&*os.i, static_cast<unsigned int>(headerSize)));
- p.get_future().get();
+ IceInternal::runSync(writer->StoreAsync());
}
catch(Platform::Exception^ pex)
{
@@ -2191,28 +2168,34 @@ namespace
void
checkResultAndWait(IAsyncAction^ action)
{
- if(action->Status == Windows::Foundation::AsyncStatus::Started)
+ auto status = action->Status;
+ switch(status)
{
- IceUtilInternal::CountDownLatch count(1);
- HRESULT result = 0;
- action->Completed = ref new AsyncActionCompletedHandler(
- [&count, &result] (IAsyncAction^ action, Windows::Foundation::AsyncStatus status)
- {
- if(status != Windows::Foundation::AsyncStatus::Completed)
+ case Windows::Foundation::AsyncStatus::Started:
+ {
+ promise<HRESULT> p;
+ action->Completed = ref new AsyncActionCompletedHandler(
+ [&p] (IAsyncAction^ action, Windows::Foundation::AsyncStatus status)
{
- result = action->ErrorCode.Value;
- }
- count.countDown();
- });
- count.await();
- if(result)
+ p.set_value(status != Windows::Foundation::AsyncStatus::Completed ? action->ErrorCode.Value : 0);
+ });
+
+ HRESULT result = p.get_future().get();
+ if(result)
+ {
+ checkErrorCode(__FILE__, __LINE__, result);
+ }
+ break;
+ }
+ case Windows::Foundation::AsyncStatus::Error:
{
- checkErrorCode(__FILE__, __LINE__, result);
+ checkErrorCode(__FILE__, __LINE__, action->ErrorCode.Value);
+ break;
+ }
+ default:
+ {
+ break;
}
- }
- else if(action->Status == Windows::Foundation::AsyncStatus::Error)
- {
- checkErrorCode(__FILE__, __LINE__, action->ErrorCode.Value);
}
}
@@ -2856,6 +2839,34 @@ IceInternal::checkErrorCode(const char* file, int line, HRESULT herr)
}
}
+//
+// UWP impose some restriction on operations that block when run from
+// STA thread and throws concurrency::invalid_operation. We cannot
+// directly call task::get or task::way, this helper method is used to
+// workaround this limitation.
+//
+void
+IceInternal::runSync(Windows::Foundation::IAsyncAction^ action)
+{
+ std::promise<void> p;
+
+ concurrency::create_task(action).then(
+ [&p](concurrency::task<void> t)
+ {
+ try
+ {
+ t.get();
+ p.set_value();
+ }
+ catch(...)
+ {
+ p.set_exception(std::current_exception());
+ }
+ },
+ concurrency::task_continuation_context::use_arbitrary());
+
+ return p.get_future().get();
+}
#endif
diff --git a/cpp/src/Ice/Network.h b/cpp/src/Ice/Network.h
index f558cff3e13..3f0c8cf2da7 100755
--- a/cpp/src/Ice/Network.h
+++ b/cpp/src/Ice/Network.h
@@ -25,7 +25,7 @@
#include <Ice/EndpointTypes.h>
#if defined(ICE_OS_UWP)
-// Nothing to include
+# include <ppltasks.h>
#elif defined(_WIN32)
# include <winsock2.h>
# include <ws2tcpip.h>
@@ -331,6 +331,36 @@ ICE_API Address getNumericAddress(const std::string&);
#else
ICE_API void checkConnectErrorCode(const char*, int, HRESULT);
ICE_API void checkErrorCode(const char*, int, HRESULT);
+
+//
+// UWP impose some restriction on operations that block when run from
+// STA thread and throws concurrency::invalid_operation. We cannot
+// directly call task::get or task::way, this helper method is used to
+// workaround this limitation.
+//
+template<typename T>
+T runSync(Windows::Foundation::IAsyncOperation<T>^ operation)
+{
+ std::promise<T> p;
+ concurrency::create_task(operation).then(
+ [&p](concurrency::task<T> t)
+ {
+ try
+ {
+ p.set_value(t.get());
+ }
+ catch(...)
+ {
+ p.set_exception(std::current_exception());
+ }
+ },
+ concurrency::task_continuation_context::use_arbitrary());
+
+ return p.get_future().get();
+}
+
+ICE_API void runSync(Windows::Foundation::IAsyncAction^ action);
+
#endif
#if defined(ICE_USE_IOCP)
diff --git a/cpp/src/Ice/ReferenceFactory.cpp b/cpp/src/Ice/ReferenceFactory.cpp
index 099cb147b4f..d4198699609 100644
--- a/cpp/src/Ice/ReferenceFactory.cpp
+++ b/cpp/src/Ice/ReferenceFactory.cpp
@@ -479,7 +479,7 @@ IceInternal::ReferenceFactory::create(const string& str, const string& propertyP
string es = s.substr(beg, end - beg);
EndpointIPtr endp = _instance->endpointFactoryManager()->create(es, false);
- if(endp != 0)
+ if(endp != ICE_NULLPTR)
{
endpoints.push_back(endp);
}
diff --git a/cpp/src/IceSSL/Certificate.cpp b/cpp/src/IceSSL/Certificate.cpp
index 97f2bd63365..fe0e85aef94 100755
--- a/cpp/src/IceSSL/Certificate.cpp
+++ b/cpp/src/IceSSL/Certificate.cpp
@@ -1138,39 +1138,24 @@ Certificate::load(const string& file)
BIO_free(cert);
return ICE_MAKE_SHARED(Certificate, x);
#elif defined(ICE_OS_UWP)
- promise<shared_ptr<Certificate>> result;
- create_task(StorageFile::GetFileFromApplicationUriAsync(
- ref new Uri(ref new String(stringToWstring(file).c_str())))).then([](StorageFile^ file)
+ try
+ {
+ auto uri = ref new Uri(ref new String(stringToWstring(file).c_str()));
+ auto file = create_task(StorageFile::GetFileFromApplicationUriAsync(uri)).get();
+ auto buffer = create_task(FileIO::ReadTextAsync(file)).get();
+ return Certificate::decode(wstringToString(buffer->Data()));
+ }
+ catch(Platform::Exception^ ex)
+ {
+ if(HRESULT_CODE(ex->HResult) == ERROR_FILE_NOT_FOUND)
{
- return FileIO::ReadTextAsync(file);
- },
- task_continuation_context::use_arbitrary()).then([&result, &file](task<String^> previous)
+ throw CertificateReadException(__FILE__, __LINE__, "certificate file not found:\n" + file);
+ }
+ else
{
- try
- {
- result.set_value(Certificate::decode(wstringToString(previous.get()->Data())));
- }
- catch(Platform::Exception^ ex)
- {
- try
- {
- if(HRESULT_CODE(ex->HResult) == ERROR_FILE_NOT_FOUND)
- {
- throw CertificateReadException(__FILE__, __LINE__, "certificate file not found:\n" + file);
- }
- else
- {
- throw Ice::SyscallException(__FILE__, __LINE__, ex->HResult);
- }
- }
- catch(...)
- {
- result.set_exception(current_exception());
- }
- }
- },
- task_continuation_context::use_arbitrary());
- return result.get_future().get();
+ throw Ice::SyscallException(__FILE__, __LINE__, ex->HResult);
+ }
+ }
#else
# error "Unknown platform"
#endif
diff --git a/cpp/src/IceSSL/UWPTransceiverI.cpp b/cpp/src/IceSSL/UWPTransceiverI.cpp
index bef7d0769b5..50f82800897 100644
--- a/cpp/src/IceSSL/UWPTransceiverI.cpp
+++ b/cpp/src/IceSSL/UWPTransceiverI.cpp
@@ -152,30 +152,15 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B
//{
// params->ExclusiveTrustRoots->Append(_engine->ca()->getCert());
//}
-
- promise<CertificateChain^> p;
- create_task(fd->Information->ServerCertificate->BuildChainAsync(
- fd->Information->ServerIntermediateCertificates, params)).then(
- [&](task<CertificateChain^> previous)
- {
- try
- {
- p.set_value(previous.get());
- }
- catch(Platform::Exception^ ex)
- {
- try
- {
- throw SyscallException(__FILE__, __LINE__, ex->HResult);
- }
- catch(...)
- {
- p.set_exception(current_exception());
- }
- }
- });
-
- _chain = p.get_future().get();
+ try
+ {
+ _chain = create_task(fd->Information->ServerCertificate->BuildChainAsync(
+ fd->Information->ServerIntermediateCertificates, params)).get();
+ }
+ catch(Platform::Exception^ ex)
+ {
+ throw SyscallException(__FILE__, __LINE__, ex->HResult);
+ }
ChainValidationResult result = _chain->Validate();
//
diff --git a/cpp/src/IceSSL/Util.cpp b/cpp/src/IceSSL/Util.cpp
index f262d09979f..5a0f815b12d 100755
--- a/cpp/src/IceSSL/Util.cpp
+++ b/cpp/src/IceSSL/Util.cpp
@@ -23,10 +23,6 @@
#include <Ice/StringConverter.h>
#include <fstream>
-#ifdef ICE_OS_UWP
-# include <ppltasks.h>
-#endif
-
#ifdef ICE_USE_OPENSSL
# include <openssl/err.h>
//
@@ -1705,45 +1701,22 @@ namespace
Certificates::Certificate^
findPersonalCertificate(String^ friendlyName)
{
- std::promise<Certificates::Certificate^> p;
-
CertificateQuery^ query = ref new CertificateQuery();
query->IncludeDuplicates = true;
query->IncludeExpiredCertificates = true;
query->FriendlyName = friendlyName;
query->StoreName = StandardCertificateStoreNames::Personal;
- create_task(CertificateStores::FindAllAsync(query))
-
- .then([&p](IVectorView<Certificates::Certificate^>^ certificates)
- {
- if(certificates->Size > 0)
- {
- p.set_value(certificates->GetAt(0));
- }
- else
- {
- p.set_value(nullptr);
- }
- },
- task_continuation_context::use_arbitrary())
-
- .then([&](task<void> t)
- {
- try
- {
- t.get();
- }
- catch(Platform::Exception^ ex)
- {
- p.set_exception(make_exception_ptr(
- PluginInitializationException(__FILE__, __LINE__, "IceSSL: certificate error:\n" +
- wstringToString(ex->Message->Data()))));
- }
- },
- task_continuation_context::use_arbitrary());
-
- return p.get_future().get();
+ try
+ {
+ auto certificates = IceInternal::runSync(CertificateStores::FindAllAsync(query));
+ return certificates->Size > 0 ? certificates->GetAt(0) : nullptr;
+ }
+ catch(Platform::Exception^ ex)
+ {
+ throw PluginInitializationException(__FILE__, __LINE__,
+ "IceSSL: certificate error:\n" + wstringToString(ex->Message->Data()));
+ }
}
//
@@ -1755,45 +1728,29 @@ findPersonalCertificate(String^ friendlyName)
bool
importPfxData(String^ friendlyName, String^ data, String^ password)
{
- promise<bool> p;
-
- create_task(CertificateEnrollmentManager::ImportPfxDataAsync(
- data,
- password,
- ExportOption::NotExportable,
- KeyProtectionLevel::NoConsent,
- InstallOptions::None,
- friendlyName))
-
- .then([&p]()
+ try
+ {
+ IceInternal::runSync(CertificateEnrollmentManager::ImportPfxDataAsync(
+ data,
+ password,
+ ExportOption::NotExportable,
+ KeyProtectionLevel::NoConsent,
+ InstallOptions::None,
+ friendlyName));
+ return false; // The import succcess
+ }
+ catch(Platform::Exception^ ex)
+ {
+ if(HRESULT_CODE(ex->HResult) == ERROR_DECRYPTION_FAILED)
{
- p.set_value(false); // The import succcess
- },
- task_continuation_context::use_arbitrary())
-
- .then([&p](task<void> t)
+ return true; // Password error
+ }
+ else
{
- try
- {
- t.get();
- }
- catch(Platform::Exception^ ex)
- {
- if(HRESULT_CODE(ex->HResult) == ERROR_DECRYPTION_FAILED)
- {
- p.set_value(true); // Password error
- }
- else
- {
- p.set_exception(make_exception_ptr(
- PluginInitializationException(__FILE__, __LINE__, "IceSSL: certificate error:\n" +
- wstringToString(ex->Message->Data()))));
- }
- }
- },
- task_continuation_context::use_arbitrary());
-
- return p.get_future().get();
+ throw PluginInitializationException(__FILE__, __LINE__,
+ "IceSSL: certificate error:\n" + wstringToString(ex->Message->Data()));
+ }
+ }
}
}
@@ -1802,84 +1759,60 @@ Certificates::Certificate^
IceSSL::importPersonalCertificate(const string& file, function<string ()> password, bool passwordPrompt,
int passwordRetryMax)
{
- std::promise<Certificates::Certificate^> p;
auto uri = ref new Uri(ref new String(stringToWstring(file).c_str()));
- create_task(StorageFile::GetFileFromApplicationUriAsync(uri))
-
- .then([](StorageFile^ file)
- {
- return FileIO::ReadBufferAsync(file);
- },
- task_continuation_context::use_arbitrary())
+ try
+ {
+ auto file = IceInternal::runSync(StorageFile::GetFileFromApplicationUriAsync(uri));
+ auto buffer = IceInternal::runSync(FileIO::ReadBufferAsync(file));
- .then([&file, &password, &p, passwordPrompt, passwordRetryMax](IBuffer^ buffer)
+ //
+ // Create a hash of the certificate to use as a friendly name, this will allow us
+ // to uniquely identify the certificate in the store.
+ //
+ auto hasher = HashAlgorithmProvider::OpenAlgorithm(HashAlgorithmNames::Sha1);
+ auto hash = hasher->CreateHash();
+
+ hash->Append(buffer);
+ String^ friendlyName = CryptographicBuffer::EncodeToBase64String(hash->GetValueAndReset());
+
+ //
+ // If the certificate is already in the store we avoid importing it.
+ //
+ Certificates::Certificate^ cert = findPersonalCertificate(friendlyName);
+ if(cert)
{
- //
- // Create a hash of the certificate to use as a friendly name, this will allow us
- // to uniquely identify the certificate in the store.
- //
- auto hasher = HashAlgorithmProvider::OpenAlgorithm(HashAlgorithmNames::Sha1);
- auto hash = hasher->CreateHash();
-
- hash->Append(buffer);
- String^ friendlyName = CryptographicBuffer::EncodeToBase64String(hash->GetValueAndReset());
-
- //
- // If the certificate is already in the store we avoid importing it.
- //
- Certificates::Certificate^ cert = findPersonalCertificate(friendlyName);
- if(cert)
- {
- p.set_value(cert);
- }
- else
- {
- String^ data = CryptographicBuffer::EncodeToBase64String(buffer);
- int count = 0;
- bool passwordErr = false;
- do
- {
- passwordErr = importPfxData(friendlyName, data,
- ref new String(stringToWstring(password()).c_str()));
- }
- while(passwordPrompt && passwordErr && ++count < passwordRetryMax);
- if(passwordErr)
- {
- throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: error decoding certificate");
- }
- p.set_value(findPersonalCertificate(friendlyName));
- }
- },
- task_continuation_context::use_arbitrary())
-
- .then([&p, &file](task<void> t)
+ return cert;
+ }
+ else
{
- try
+ String^ data = CryptographicBuffer::EncodeToBase64String(buffer);
+ int count = 0;
+ bool passwordErr = false;
+ do
{
- t.get();
- }
- catch(Platform::Exception^ ex)
- {
- if(HRESULT_CODE(ex->HResult) == ERROR_FILE_NOT_FOUND)
- {
- p.set_exception(make_exception_ptr(
- PluginInitializationException(__FILE__, __LINE__, "certificate file not found:\n" + file)));
- }
- else
- {
- p.set_exception(make_exception_ptr(
- PluginInitializationException(__FILE__, __LINE__, "IceSSL: certificate error:\n" +
- wstringToString(ex->Message->Data()))));
- }
+ passwordErr = importPfxData(friendlyName, data,
+ ref new String(stringToWstring(password()).c_str()));
}
- catch(...)
+ while(passwordPrompt && passwordErr && ++count < passwordRetryMax);
+ if(passwordErr)
{
- p.set_exception(current_exception());
+ throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: error decoding certificate");
}
- },
- task_continuation_context::use_arbitrary());
-
- return p.get_future().get();
+ return findPersonalCertificate(friendlyName);
+ }
+ }
+ catch(Platform::Exception^ ex)
+ {
+ if(HRESULT_CODE(ex->HResult) == ERROR_FILE_NOT_FOUND)
+ {
+ throw PluginInitializationException(__FILE__, __LINE__, "certificate file not found:\n" + file);
+ }
+ else
+ {
+ throw PluginInitializationException(__FILE__, __LINE__,
+ "IceSSL: certificate error:\n" + wstringToString(ex->Message->Data()));
+ }
+ }
}
IVectorView<Certificates::Certificate^>^
@@ -1974,31 +1907,15 @@ IceSSL::findCertificates(const string& name, const string& value)
}
}
- std::promise<IVectorView<Certificates::Certificate^>^> p;
- create_task(CertificateStores::FindAllAsync(query))
-
- .then([&p](IVectorView<Certificates::Certificate^>^ certificates)
- {
- p.set_value(certificates);
- },
- task_continuation_context::use_arbitrary())
-
- .then([&p](task<void> t)
- {
- try
- {
- t.get();
- }
- catch(Platform::Exception^ ex)
- {
- p.set_exception(
- make_exception_ptr(PluginInitializationException(__FILE__, __LINE__, "IceSSL: certificate error:\n" +
- wstringToString(ex->Message->Data()))));
- }
- },
- task_continuation_context::use_arbitrary());
-
- return p.get_future().get();
+ try
+ {
+ return IceInternal::runSync(CertificateStores::FindAllAsync(query));
+ }
+ catch(Platform::Exception^ ex)
+ {
+ throw PluginInitializationException(__FILE__, __LINE__,
+ "IceSSL: certificate error:\n" + wstringToString(ex->Message->Data()));
+ }
}
#endif