OLD | NEW |
| (Empty) |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "mojo/edk/system/child_token_serializer_win.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "mojo/edk/embedder/embedder_internal.h" | |
9 #include "mojo/edk/system/token_serializer_messages_win.h" | |
10 | |
11 namespace mojo { | |
12 namespace edk { | |
13 | |
14 ChildTokenSerializer* ChildTokenSerializer::GetInstance() { | |
15 return base::Singleton< | |
16 ChildTokenSerializer, | |
17 base::LeakySingletonTraits<ChildTokenSerializer>>::get(); | |
18 } | |
19 | |
20 void ChildTokenSerializer::SetParentTokenSerializerHandle( | |
21 ScopedPlatformHandle handle) { | |
22 handle_ = handle.Pass(); | |
23 lock_.Unlock(); | |
24 } | |
25 | |
26 void ChildTokenSerializer::CreatePlatformChannelPair( | |
27 ScopedPlatformHandle* server, ScopedPlatformHandle* client) { | |
28 TokenSerializerMessage message; | |
29 message.size = kTokenSerializerMessageHeaderSize; | |
30 message.id = CREATE_PLATFORM_CHANNEL_PAIR; | |
31 | |
32 uint32_t response_size = 2 * sizeof(HANDLE); | |
33 HANDLE handles[2]; | |
34 if (WriteAndReadResponse(&message, handles, response_size)) { | |
35 server->reset(PlatformHandle(handles[0])); | |
36 client->reset(PlatformHandle(handles[1])); | |
37 } | |
38 } | |
39 | |
40 void ChildTokenSerializer::HandleToToken(const PlatformHandle* platform_handles, | |
41 size_t count, | |
42 uint64_t* tokens) { | |
43 uint32_t size = kTokenSerializerMessageHeaderSize + | |
44 static_cast<int>(count) * sizeof(HANDLE); | |
45 std::vector<char> message_buffer(size); | |
46 TokenSerializerMessage* message = | |
47 reinterpret_cast<TokenSerializerMessage*>(&message_buffer[0]); | |
48 message->size = size; | |
49 message->id = HANDLE_TO_TOKEN; | |
50 for (size_t i = 0; i < count; ++i) | |
51 message->handles[i] = platform_handles[i].handle; | |
52 | |
53 uint32_t response_size = static_cast<int>(count) * sizeof(uint64_t); | |
54 WriteAndReadResponse(message, tokens, response_size); | |
55 } | |
56 | |
57 void ChildTokenSerializer::TokenToHandle(const uint64_t* tokens, | |
58 size_t count, | |
59 PlatformHandle* handles) { | |
60 uint32_t size = kTokenSerializerMessageHeaderSize + | |
61 static_cast<int>(count) * sizeof(uint64_t); | |
62 std::vector<char> message_buffer(size); | |
63 TokenSerializerMessage* message = | |
64 reinterpret_cast<TokenSerializerMessage*>(&message_buffer[0]); | |
65 message->size = size; | |
66 message->id = TOKEN_TO_HANDLE; | |
67 memcpy(&message->tokens[0], tokens, count * sizeof(uint64_t)); | |
68 | |
69 std::vector<HANDLE> handles_temp(count); | |
70 uint32_t response_size = | |
71 static_cast<uint32_t>(handles_temp.size()) * sizeof(HANDLE); | |
72 if (WriteAndReadResponse(message, &handles_temp[0], response_size)) { | |
73 for (uint32_t i = 0; i < count; ++i) | |
74 handles[i].handle = handles_temp[i]; | |
75 } | |
76 } | |
77 | |
78 ChildTokenSerializer::ChildTokenSerializer() { | |
79 DCHECK(!internal::g_token_serializer); | |
80 internal::g_token_serializer = this; | |
81 // Block any threads from calling this until we have a pipe to the parent. | |
82 lock_.Lock(); | |
83 } | |
84 | |
85 ChildTokenSerializer::~ChildTokenSerializer() { | |
86 } | |
87 | |
88 bool ChildTokenSerializer::WriteAndReadResponse(TokenSerializerMessage* message, | |
89 void* response, | |
90 uint32_t response_size) { | |
91 lock_.Lock(); | |
92 CHECK(handle_.is_valid()); | |
93 | |
94 bool result = true; | |
95 DWORD bytes_written = 0; | |
96 // This will always write in one chunk per | |
97 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365150.aspx. | |
98 BOOL rv = WriteFile(handle_.get().handle, message, message->size, | |
99 &bytes_written, NULL); | |
100 if (!rv || bytes_written != message->size) { | |
101 LOG(ERROR) << "Child token serializer couldn't write message."; | |
102 result = false; | |
103 } else { | |
104 while (response_size) { | |
105 DWORD bytes_read = 0; | |
106 rv = ReadFile(handle_.get().handle, response, response_size, &bytes_read, | |
107 NULL); | |
108 if (!rv) { | |
109 LOG(ERROR) << "Child token serializer couldn't read result."; | |
110 result = false; | |
111 break; | |
112 } | |
113 response_size -= bytes_read; | |
114 response = static_cast<char*>(response) + bytes_read; | |
115 } | |
116 } | |
117 | |
118 lock_.Unlock(); | |
119 | |
120 return result; | |
121 } | |
122 | |
123 } // namespace edk | |
124 } // namespace mojo | |
OLD | NEW |