OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 <windows.h> | |
6 | |
7 #include <limits> | |
8 #include <utility> | |
9 | |
10 #include "mojo/edk/embedder/platform_handle.h" | |
11 #include "mojo/edk/embedder/platform_handle_vector.h" | |
12 #include "mojo/edk/embedder/platform_shared_buffer.h" | |
13 #include "mojo/edk/system/broker.h" | |
14 #include "mojo/edk/system/broker_messages.h" | |
15 #include "mojo/edk/system/channel.h" | |
16 | |
17 namespace mojo { | |
18 namespace edk { | |
19 | |
20 namespace { | |
21 | |
22 // 256 bytes should be enough for anyone! | |
23 const size_t kMaxBrokerMessageSize = 256; | |
24 | |
25 bool WaitForBrokerMessage(PlatformHandle platform_handle, | |
26 BrokerMessageType expected_type, | |
27 size_t expected_num_handles, | |
28 ScopedPlatformHandle* out_handles) { | |
29 char buffer[kMaxBrokerMessageSize]; | |
30 DWORD bytes_read = 0; | |
31 BOOL result = ::ReadFile(platform_handle.handle, buffer, | |
32 kMaxBrokerMessageSize, &bytes_read, nullptr); | |
33 if (!result) { | |
34 PLOG(ERROR) << "Error reading broker pipe"; | |
35 return false; | |
36 } | |
37 | |
38 Channel::MessagePtr message = | |
39 Channel::Message::Deserialize(buffer, static_cast<size_t>(bytes_read)); | |
40 if (!message || message->payload_size() < sizeof(BrokerMessageHeader)) { | |
41 LOG(ERROR) << "Invalid broker message"; | |
42 return false; | |
43 } | |
44 | |
45 if (message->num_handles() != expected_num_handles) { | |
46 LOG(ERROR) << "Received unexpected number of handles in broker message"; | |
47 return false; | |
48 } | |
49 | |
50 const BrokerMessageHeader* header = | |
51 reinterpret_cast<const BrokerMessageHeader*>(message->payload()); | |
52 if (header->type != expected_type) { | |
53 LOG(ERROR) << "Unknown broker message type"; | |
54 return false; | |
55 } | |
56 | |
57 ScopedPlatformHandleVectorPtr handles = message->TakeHandles(); | |
58 DCHECK(handles); | |
59 DCHECK_EQ(handles->size(), expected_num_handles); | |
60 DCHECK(out_handles); | |
61 | |
62 for (size_t i = 0; i < expected_num_handles; ++i) | |
63 out_handles[i] = ScopedPlatformHandle(handles->at(i)); | |
64 handles->clear(); | |
65 return true; | |
66 } | |
67 | |
68 } // namespace | |
69 | |
70 Broker::Broker(ScopedPlatformHandle handle) : sync_channel_(std::move(handle)) { | |
71 CHECK(sync_channel_.is_valid()); | |
72 bool result = WaitForBrokerMessage( | |
73 sync_channel_.get(), BrokerMessageType::INIT, 1, &parent_channel_); | |
74 DCHECK(result); | |
75 } | |
76 | |
77 Broker::~Broker() {} | |
78 | |
79 ScopedPlatformHandle Broker::GetParentPlatformHandle() { | |
80 return std::move(parent_channel_); | |
81 } | |
82 | |
83 scoped_refptr<PlatformSharedBuffer> Broker::GetSharedBuffer(size_t num_bytes) { | |
84 base::AutoLock lock(lock_); | |
85 | |
86 BufferRequestData* buffer_request; | |
87 Channel::MessagePtr out_message = CreateBrokerMessage( | |
88 BrokerMessageType::BUFFER_REQUEST, 0, &buffer_request); | |
89 DCHECK_LE(num_bytes, std::numeric_limits<uint32_t>::max()); | |
Will Harris
2016/09/13 23:54:43
why not use safe_numerics here? also I feel this s
Ken Rockot(use gerrit already)
2016/09/14 19:57:05
Switched to using base::checked_cast below and kil
| |
90 buffer_request->size = static_cast<uint32_t>(num_bytes); | |
Will Harris
2016/09/13 23:54:43
BufferRequestData's size member is a size_t - why
Ken Rockot(use gerrit already)
2016/09/14 19:57:05
It's not a size_t, it's a uint32_t. https://cs.chr
| |
91 DWORD bytes_written = 0; | |
92 BOOL result = ::WriteFile(sync_channel_.get().handle, out_message->data(), | |
93 static_cast<DWORD>(out_message->data_num_bytes()), | |
94 &bytes_written, nullptr); | |
95 if (!result || | |
96 static_cast<size_t>(bytes_written) != out_message->data_num_bytes()) { | |
97 LOG(ERROR) << "Error sending sync broker message"; | |
98 return nullptr; | |
99 } | |
100 | |
101 ScopedPlatformHandle handles[2]; | |
102 if (WaitForBrokerMessage(sync_channel_.get(), | |
103 BrokerMessageType::BUFFER_RESPONSE, 2, | |
104 &handles[0])) { | |
105 return PlatformSharedBuffer::CreateFromPlatformHandlePair( | |
106 num_bytes, std::move(handles[0]), std::move(handles[1])); | |
107 } | |
108 | |
109 return nullptr; | |
110 } | |
111 | |
112 } // namespace edk | |
113 } // namespace mojo | |
OLD | NEW |