Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(663)

Side by Side Diff: base/memory/shared_memory_win.cc

Issue 1647803004: Move base to DEPS (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/memory/shared_memory_unittest.cc ('k') | base/memory/singleton.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "base/memory/shared_memory.h"
6
7 #include <aclapi.h>
8
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/rand_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/strings/utf_string_conversions.h"
14
15 namespace {
16
17 // Returns the length of the memory section starting at the supplied address.
18 size_t GetMemorySectionSize(void* address) {
19 MEMORY_BASIC_INFORMATION memory_info;
20 if (!::VirtualQuery(address, &memory_info, sizeof(memory_info)))
21 return 0;
22 return memory_info.RegionSize - (static_cast<char*>(address) -
23 static_cast<char*>(memory_info.AllocationBase));
24 }
25
26 } // namespace.
27
28 namespace base {
29
30 SharedMemory::SharedMemory()
31 : mapped_file_(NULL),
32 mapped_size_(0),
33 memory_(NULL),
34 read_only_(false),
35 requested_size_(0) {}
36
37 SharedMemory::SharedMemory(const std::wstring& name)
38 : name_(name),
39 mapped_file_(NULL),
40 mapped_size_(0),
41 memory_(NULL),
42 read_only_(false),
43 requested_size_(0) {}
44
45 SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only)
46 : mapped_file_(handle),
47 mapped_size_(0),
48 memory_(NULL),
49 read_only_(read_only),
50 requested_size_(0) {}
51
52 SharedMemory::SharedMemory(const SharedMemoryHandle& handle,
53 bool read_only,
54 ProcessHandle process)
55 : mapped_file_(NULL),
56 mapped_size_(0),
57 memory_(NULL),
58 read_only_(read_only),
59 requested_size_(0) {
60 ::DuplicateHandle(process, handle,
61 GetCurrentProcess(), &mapped_file_,
62 read_only_ ? FILE_MAP_READ : FILE_MAP_READ |
63 FILE_MAP_WRITE,
64 FALSE, 0);
65 }
66
67 SharedMemory::~SharedMemory() {
68 Unmap();
69 Close();
70 }
71
72 // static
73 bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) {
74 return handle != NULL;
75 }
76
77 // static
78 SharedMemoryHandle SharedMemory::NULLHandle() {
79 return NULL;
80 }
81
82 // static
83 void SharedMemory::CloseHandle(const SharedMemoryHandle& handle) {
84 DCHECK(handle != NULL);
85 ::CloseHandle(handle);
86 }
87
88 // static
89 size_t SharedMemory::GetHandleLimit() {
90 // Rounded down from value reported here:
91 // http://blogs.technet.com/b/markrussinovich/archive/2009/09/29/3283844.aspx
92 return static_cast<size_t>(1 << 23);
93 }
94
95 // static
96 SharedMemoryHandle SharedMemory::DuplicateHandle(
97 const SharedMemoryHandle& handle) {
98 ProcessHandle process = GetCurrentProcess();
99 SharedMemoryHandle duped_handle;
100 BOOL success = ::DuplicateHandle(process, handle, process, &duped_handle, 0,
101 FALSE, DUPLICATE_SAME_ACCESS);
102 if (success)
103 return duped_handle;
104 return NULLHandle();
105 }
106
107 bool SharedMemory::CreateAndMapAnonymous(size_t size) {
108 return CreateAnonymous(size) && Map(size);
109 }
110
111 bool SharedMemory::Create(const SharedMemoryCreateOptions& options) {
112 // TODO(bsy,sehr): crbug.com/210609 NaCl forces us to round up 64k here,
113 // wasting 32k per mapping on average.
114 static const size_t kSectionMask = 65536 - 1;
115 DCHECK(!options.executable);
116 DCHECK(!mapped_file_);
117 if (options.size == 0)
118 return false;
119
120 // Check maximum accounting for overflow.
121 if (options.size >
122 static_cast<size_t>(std::numeric_limits<int>::max()) - kSectionMask)
123 return false;
124
125 size_t rounded_size = (options.size + kSectionMask) & ~kSectionMask;
126 name_ = options.name_deprecated ?
127 ASCIIToUTF16(*options.name_deprecated) : L"";
128 SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, FALSE };
129 SECURITY_DESCRIPTOR sd;
130 ACL dacl;
131
132 if (options.share_read_only && name_.empty()) {
133 // Add an empty DACL to enforce anonymous read-only sections.
134 sa.lpSecurityDescriptor = &sd;
135 if (!InitializeAcl(&dacl, sizeof(dacl), ACL_REVISION))
136 return false;
137 if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
138 return false;
139 if (!SetSecurityDescriptorDacl(&sd, TRUE, &dacl, FALSE))
140 return false;
141
142 // Windows ignores DACLs on certain unnamed objects (like shared sections).
143 // So, we generate a random name when we need to enforce read-only.
144 uint64_t rand_values[4];
145 RandBytes(&rand_values, sizeof(rand_values));
146 name_ = StringPrintf(L"CrSharedMem_%016x%016x%016x%016x",
147 rand_values[0], rand_values[1],
148 rand_values[2], rand_values[3]);
149 }
150 mapped_file_ = CreateFileMapping(INVALID_HANDLE_VALUE, &sa,
151 PAGE_READWRITE, 0, static_cast<DWORD>(rounded_size),
152 name_.empty() ? nullptr : name_.c_str());
153 if (!mapped_file_)
154 return false;
155
156 requested_size_ = options.size;
157
158 // Check if the shared memory pre-exists.
159 if (GetLastError() == ERROR_ALREADY_EXISTS) {
160 // If the file already existed, set requested_size_ to 0 to show that
161 // we don't know the size.
162 requested_size_ = 0;
163 if (!options.open_existing_deprecated) {
164 Close();
165 return false;
166 }
167 }
168
169 return true;
170 }
171
172 bool SharedMemory::Delete(const std::string& name) {
173 // intentionally empty -- there is nothing for us to do on Windows.
174 return true;
175 }
176
177 bool SharedMemory::Open(const std::string& name, bool read_only) {
178 DCHECK(!mapped_file_);
179
180 name_ = ASCIIToUTF16(name);
181 read_only_ = read_only;
182 mapped_file_ = OpenFileMapping(
183 read_only_ ? FILE_MAP_READ : FILE_MAP_READ | FILE_MAP_WRITE,
184 false, name_.empty() ? NULL : name_.c_str());
185 if (mapped_file_ != NULL) {
186 // Note: size_ is not set in this case.
187 return true;
188 }
189 return false;
190 }
191
192 bool SharedMemory::MapAt(off_t offset, size_t bytes) {
193 if (mapped_file_ == NULL)
194 return false;
195
196 if (bytes > static_cast<size_t>(std::numeric_limits<int>::max()))
197 return false;
198
199 if (memory_)
200 return false;
201
202 memory_ = MapViewOfFile(mapped_file_,
203 read_only_ ? FILE_MAP_READ : FILE_MAP_READ |
204 FILE_MAP_WRITE,
205 static_cast<uint64>(offset) >> 32,
206 static_cast<DWORD>(offset),
207 bytes);
208 if (memory_ != NULL) {
209 DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(memory_) &
210 (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1));
211 mapped_size_ = GetMemorySectionSize(memory_);
212 return true;
213 }
214 return false;
215 }
216
217 bool SharedMemory::Unmap() {
218 if (memory_ == NULL)
219 return false;
220
221 UnmapViewOfFile(memory_);
222 memory_ = NULL;
223 return true;
224 }
225
226 bool SharedMemory::ShareToProcessCommon(ProcessHandle process,
227 SharedMemoryHandle* new_handle,
228 bool close_self,
229 ShareMode share_mode) {
230 *new_handle = 0;
231 DWORD access = FILE_MAP_READ;
232 DWORD options = 0;
233 HANDLE mapped_file = mapped_file_;
234 HANDLE result;
235 if (share_mode == SHARE_CURRENT_MODE && !read_only_)
236 access |= FILE_MAP_WRITE;
237 if (close_self) {
238 // DUPLICATE_CLOSE_SOURCE causes DuplicateHandle to close mapped_file.
239 options = DUPLICATE_CLOSE_SOURCE;
240 mapped_file_ = NULL;
241 Unmap();
242 }
243
244 if (process == GetCurrentProcess() && close_self) {
245 *new_handle = mapped_file;
246 return true;
247 }
248
249 if (!::DuplicateHandle(GetCurrentProcess(), mapped_file, process, &result,
250 access, FALSE, options)) {
251 return false;
252 }
253 *new_handle = result;
254 return true;
255 }
256
257
258 void SharedMemory::Close() {
259 if (mapped_file_ != NULL) {
260 CloseHandle(mapped_file_);
261 mapped_file_ = NULL;
262 }
263 }
264
265 SharedMemoryHandle SharedMemory::handle() const {
266 return mapped_file_;
267 }
268
269 } // namespace base
OLDNEW
« no previous file with comments | « base/memory/shared_memory_unittest.cc ('k') | base/memory/singleton.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698