1 // Copyright (c) 2012 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 "ppapi/proxy/resource_message_params.h"
6
7 #include "base/logging.h"
8 #include "base/memory/read_only_shared_memory_region.h"
9 #include "ppapi/c/pp_errors.h"
10 #include "ppapi/proxy/ppapi_messages.h"
11
12 namespace ppapi {
13 namespace proxy {
14
SerializedHandles()15 ResourceMessageParams::SerializedHandles::SerializedHandles()
16 : should_close_(false) {
17 }
18
~SerializedHandles()19 ResourceMessageParams::SerializedHandles::~SerializedHandles() {
20 if (should_close_) {
21 for (std::vector<SerializedHandle>::iterator iter = data_.begin();
22 iter != data_.end(); ++iter) {
23 iter->Close();
24 }
25 }
26 }
27
ResourceMessageParams()28 ResourceMessageParams::ResourceMessageParams()
29 : pp_resource_(0),
30 sequence_(0),
31 handles_(new SerializedHandles()) {
32 }
33
ResourceMessageParams(PP_Resource resource,int32_t sequence)34 ResourceMessageParams::ResourceMessageParams(PP_Resource resource,
35 int32_t sequence)
36 : pp_resource_(resource),
37 sequence_(sequence),
38 handles_(new SerializedHandles()) {
39 }
40
~ResourceMessageParams()41 ResourceMessageParams::~ResourceMessageParams() {
42 }
43
Serialize(base::Pickle * msg) const44 void ResourceMessageParams::Serialize(base::Pickle* msg) const {
45 WriteHeader(msg);
46 WriteHandles(msg);
47 }
48
Deserialize(const base::Pickle * msg,base::PickleIterator * iter)49 bool ResourceMessageParams::Deserialize(const base::Pickle* msg,
50 base::PickleIterator* iter) {
51 return ReadHeader(msg, iter) && ReadHandles(msg, iter);
52 }
53
WriteHeader(base::Pickle * msg) const54 void ResourceMessageParams::WriteHeader(base::Pickle* msg) const {
55 IPC::WriteParam(msg, pp_resource_);
56 IPC::WriteParam(msg, sequence_);
57 }
58
WriteHandles(base::Pickle * msg) const59 void ResourceMessageParams::WriteHandles(base::Pickle* msg) const {
60 IPC::WriteParam(msg, handles_->data());
61 }
62
ReadHeader(const base::Pickle * msg,base::PickleIterator * iter)63 bool ResourceMessageParams::ReadHeader(const base::Pickle* msg,
64 base::PickleIterator* iter) {
65 DCHECK(handles_->data().empty());
66 handles_->set_should_close(true);
67 return IPC::ReadParam(msg, iter, &pp_resource_) &&
68 IPC::ReadParam(msg, iter, &sequence_);
69 }
70
ReadHandles(const base::Pickle * msg,base::PickleIterator * iter)71 bool ResourceMessageParams::ReadHandles(const base::Pickle* msg,
72 base::PickleIterator* iter) {
73 return IPC::ReadParam(msg, iter, &handles_->data());
74 }
75
ConsumeHandles() const76 void ResourceMessageParams::ConsumeHandles() const {
77 // Note: we must not invalidate the handles. This is used for converting
78 // handles from the host OS to NaCl, and that conversion will not work if we
79 // invalidate the handles (see HandleConverter).
80 handles_->set_should_close(false);
81 }
82
TakeHandleOfTypeAtIndex(size_t index,SerializedHandle::Type type) const83 SerializedHandle ResourceMessageParams::TakeHandleOfTypeAtIndex(
84 size_t index,
85 SerializedHandle::Type type) const {
86 SerializedHandle handle;
87 std::vector<SerializedHandle>& data = handles_->data();
88 if (index < data.size() && data[index].type() == type)
89 handle = std::move(data[index]);
90 return handle;
91 }
92
TakeReadOnlySharedMemoryRegionAtIndex(size_t index,base::ReadOnlySharedMemoryRegion * region) const93 bool ResourceMessageParams::TakeReadOnlySharedMemoryRegionAtIndex(
94 size_t index,
95 base::ReadOnlySharedMemoryRegion* region) const {
96 SerializedHandle serialized =
97 TakeHandleOfTypeAtIndex(index, SerializedHandle::SHARED_MEMORY_REGION);
98 if (!serialized.is_shmem_region())
99 return false;
100 *region = base::ReadOnlySharedMemoryRegion::Deserialize(
101 serialized.TakeSharedMemoryRegion());
102 return true;
103 }
104
TakeUnsafeSharedMemoryRegionAtIndex(size_t index,base::UnsafeSharedMemoryRegion * region) const105 bool ResourceMessageParams::TakeUnsafeSharedMemoryRegionAtIndex(
106 size_t index,
107 base::UnsafeSharedMemoryRegion* region) const {
108 SerializedHandle serialized =
109 TakeHandleOfTypeAtIndex(index, SerializedHandle::SHARED_MEMORY_REGION);
110 if (!serialized.is_shmem_region())
111 return false;
112 *region = base::UnsafeSharedMemoryRegion::Deserialize(
113 serialized.TakeSharedMemoryRegion());
114 return true;
115 }
116
TakeSocketHandleAtIndex(size_t index,IPC::PlatformFileForTransit * handle) const117 bool ResourceMessageParams::TakeSocketHandleAtIndex(
118 size_t index,
119 IPC::PlatformFileForTransit* handle) const {
120 SerializedHandle serialized = TakeHandleOfTypeAtIndex(
121 index, SerializedHandle::SOCKET);
122 if (!serialized.is_socket())
123 return false;
124 *handle = serialized.descriptor();
125 return true;
126 }
127
TakeFileHandleAtIndex(size_t index,IPC::PlatformFileForTransit * handle) const128 bool ResourceMessageParams::TakeFileHandleAtIndex(
129 size_t index,
130 IPC::PlatformFileForTransit* handle) const {
131 SerializedHandle serialized = TakeHandleOfTypeAtIndex(
132 index, SerializedHandle::FILE);
133 if (!serialized.is_file())
134 return false;
135 *handle = serialized.descriptor();
136 return true;
137 }
138
TakeAllHandles(std::vector<SerializedHandle> * handles) const139 void ResourceMessageParams::TakeAllHandles(
140 std::vector<SerializedHandle>* handles) const {
141 std::vector<SerializedHandle>& data = handles_->data();
142 for (size_t i = 0; i < data.size(); ++i)
143 handles->push_back(std::move(data[i]));
144 }
145
AppendHandle(SerializedHandle handle) const146 void ResourceMessageParams::AppendHandle(SerializedHandle handle) const {
147 handles_->data().push_back(std::move(handle));
148 }
149
ResourceMessageCallParams()150 ResourceMessageCallParams::ResourceMessageCallParams()
151 : ResourceMessageParams(),
152 has_callback_(0) {
153 }
154
ResourceMessageCallParams(PP_Resource resource,int32_t sequence)155 ResourceMessageCallParams::ResourceMessageCallParams(PP_Resource resource,
156 int32_t sequence)
157 : ResourceMessageParams(resource, sequence),
158 has_callback_(0) {
159 }
160
~ResourceMessageCallParams()161 ResourceMessageCallParams::~ResourceMessageCallParams() {
162 }
163
Serialize(base::Pickle * msg) const164 void ResourceMessageCallParams::Serialize(base::Pickle* msg) const {
165 ResourceMessageParams::Serialize(msg);
166 IPC::WriteParam(msg, has_callback_);
167 }
168
Deserialize(const base::Pickle * msg,base::PickleIterator * iter)169 bool ResourceMessageCallParams::Deserialize(const base::Pickle* msg,
170 base::PickleIterator* iter) {
171 if (!ResourceMessageParams::Deserialize(msg, iter))
172 return false;
173 return IPC::ReadParam(msg, iter, &has_callback_);
174 }
175
ResourceMessageReplyParams()176 ResourceMessageReplyParams::ResourceMessageReplyParams()
177 : ResourceMessageParams(),
178 result_(PP_OK) {
179 }
180
ResourceMessageReplyParams(PP_Resource resource,int32_t sequence)181 ResourceMessageReplyParams::ResourceMessageReplyParams(PP_Resource resource,
182 int32_t sequence)
183 : ResourceMessageParams(resource, sequence),
184 result_(PP_OK) {
185 }
186
~ResourceMessageReplyParams()187 ResourceMessageReplyParams::~ResourceMessageReplyParams() {
188 }
189
Serialize(base::Pickle * msg) const190 void ResourceMessageReplyParams::Serialize(base::Pickle* msg) const {
191 // Rather than serialize all of ResourceMessageParams first, we serialize all
192 // non-handle data first, then the handles. When transferring to NaCl on
193 // Windows, we need to be able to translate Windows-style handles to POSIX-
194 // style handles, and it's easier to put all the regular stuff at the front.
195 WriteReplyHeader(msg);
196 WriteHandles(msg);
197 }
198
Deserialize(const base::Pickle * msg,base::PickleIterator * iter)199 bool ResourceMessageReplyParams::Deserialize(const base::Pickle* msg,
200 base::PickleIterator* iter) {
201 return (ReadHeader(msg, iter) && IPC::ReadParam(msg, iter, &result_) &&
202 ReadHandles(msg, iter));
203 }
204
WriteReplyHeader(base::Pickle * msg) const205 void ResourceMessageReplyParams::WriteReplyHeader(base::Pickle* msg) const {
206 WriteHeader(msg);
207 IPC::WriteParam(msg, result_);
208 }
209
210 } // namespace proxy
211 } // namespace ppapi
212