Index: mojo/edk/system/child_token_serializer_win.cc |
diff --git a/mojo/edk/system/child_token_serializer_win.cc b/mojo/edk/system/child_token_serializer_win.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..bbbbea412c7274510cadc2f371de4b4cf69444df |
--- /dev/null |
+++ b/mojo/edk/system/child_token_serializer_win.cc |
@@ -0,0 +1,124 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "mojo/edk/system/child_token_serializer_win.h" |
+ |
+#include "base/logging.h" |
+#include "mojo/edk/embedder/embedder_internal.h" |
+#include "mojo/edk/system/token_serializer_messages_win.h" |
+ |
+namespace mojo { |
+namespace edk { |
+ |
+ChildTokenSerializer* ChildTokenSerializer::GetInstance() { |
+ return base::Singleton< |
+ ChildTokenSerializer, |
+ base::LeakySingletonTraits<ChildTokenSerializer>>::get(); |
+} |
+ |
+void ChildTokenSerializer::SetParentTokenSerializerHandle( |
+ ScopedPlatformHandle handle) { |
+ handle_ = handle.Pass(); |
+ lock_.Unlock(); |
+} |
+ |
+void ChildTokenSerializer::CreatePlatformChannelPair( |
+ ScopedPlatformHandle* server, ScopedPlatformHandle* client) { |
+ TokenSerializerMessage message; |
+ message.size = kTokenSerializerMessageHeaderSize; |
+ message.id = CREATE_PLATFORM_CHANNEL_PAIR; |
+ |
+ uint32_t response_size = 2 * sizeof(HANDLE); |
+ HANDLE handles[2]; |
+ if (WriteAndReadResponse(&message, handles, response_size)) { |
+ server->reset(PlatformHandle(handles[0])); |
+ client->reset(PlatformHandle(handles[1])); |
+ } |
+} |
+ |
+void ChildTokenSerializer::HandleToToken(const PlatformHandle* platform_handles, |
+ size_t count, |
+ uint64_t* tokens) { |
+ uint32_t size = kTokenSerializerMessageHeaderSize + |
+ static_cast<int>(count) * sizeof(HANDLE); |
+ std::vector<char> message_buffer(size); |
+ TokenSerializerMessage* message = |
+ reinterpret_cast<TokenSerializerMessage*>(&message_buffer[0]); |
+ message->size = size; |
+ message->id = HANDLE_TO_TOKEN; |
+ for (size_t i = 0; i < count; ++i) |
+ message->handles[i] = platform_handles[i].handle; |
+ |
+ uint32_t response_size = static_cast<int>(count) * sizeof(uint64_t); |
+ WriteAndReadResponse(message, tokens, response_size); |
+} |
+ |
+void ChildTokenSerializer::TokenToHandle(const uint64_t* tokens, |
+ size_t count, |
+ PlatformHandle* handles) { |
+ uint32_t size = kTokenSerializerMessageHeaderSize + |
+ static_cast<int>(count) * sizeof(uint64_t); |
+ std::vector<char> message_buffer(size); |
+ TokenSerializerMessage* message = |
+ reinterpret_cast<TokenSerializerMessage*>(&message_buffer[0]); |
+ message->size = size; |
+ message->id = TOKEN_TO_HANDLE; |
+ memcpy(&message->tokens[0], tokens, count * sizeof(uint64_t)); |
+ |
+ std::vector<HANDLE> handles_temp(count); |
+ uint32_t response_size = |
+ static_cast<uint32_t>(handles_temp.size()) * sizeof(HANDLE); |
+ if (WriteAndReadResponse(message, &handles_temp[0], response_size)) { |
+ for (uint32_t i = 0; i < count; ++i) |
+ handles[i].handle = handles_temp[i]; |
+ } |
+} |
+ |
+ChildTokenSerializer::ChildTokenSerializer() { |
+ DCHECK(!internal::g_token_serializer); |
+ internal::g_token_serializer = this; |
+ // Block any threads from calling this until we have a pipe to the parent. |
+ lock_.Lock(); |
+} |
+ |
+ChildTokenSerializer::~ChildTokenSerializer() { |
+} |
+ |
+bool ChildTokenSerializer::WriteAndReadResponse(TokenSerializerMessage* message, |
+ void* response, |
+ uint32_t response_size) { |
+ lock_.Lock(); |
+ CHECK(handle_.is_valid()); |
+ |
+ bool result = true; |
+ DWORD bytes_written = 0; |
+ // This will always write in one chunk per |
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365150.aspx. |
+ BOOL rv = WriteFile(handle_.get().handle, message, message->size, |
+ &bytes_written, NULL); |
+ if (!rv || bytes_written != message->size) { |
+ LOG(ERROR) << "Child token serializer couldn't write message."; |
+ result = false; |
+ } else { |
+ while (response_size) { |
+ DWORD bytes_read = 0; |
+ rv = ReadFile(handle_.get().handle, response, response_size, &bytes_read, |
+ NULL); |
+ if (!rv) { |
+ LOG(ERROR) << "Child token serializer couldn't read result."; |
+ result = false; |
+ break; |
+ } |
+ response_size -= bytes_read; |
+ response = static_cast<char*>(response) + bytes_read; |
+ } |
+ } |
+ |
+ lock_.Unlock(); |
+ |
+ return result; |
+} |
+ |
+} // namespace edk |
+} // namespace mojo |