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); | |
yzshen1
2015/11/20 20:39:55
Is there any error handling needed if this call fa
jam
2015/11/21 01:26:09
it'll fail because bogus handles are passed in. bu
| |
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 = false; | |
95 DWORD bytes_written = 0; | |
96 BOOL rv = WriteFile(handle_.get().handle, message, message->size, | |
97 &bytes_written, NULL); | |
yzshen1
2015/11/20 20:39:55
Do we need to handle partial read/write as non-err
jam
2015/11/21 01:26:09
per https://msdn.microsoft.com/en-us/library/windo
| |
98 if (!rv || bytes_written != message->size) { | |
99 LOG(ERROR) << "Child token serializer couldn't write message."; | |
100 } else { | |
101 DWORD bytes_read = 0; | |
102 rv = ReadFile(handle_.get().handle, response, response_size, &bytes_read, | |
103 NULL); | |
104 if (!rv || bytes_read != response_size) { | |
105 LOG(ERROR) << "Child token serializer couldn't read result."; | |
106 } else { | |
107 result = true; | |
108 } | |
109 } | |
110 | |
111 lock_.Unlock(); | |
112 | |
113 return result; | |
114 } | |
115 | |
116 } // namespace edk | |
117 } // namespace mojo | |
OLD | NEW |