[email protected] | b05df6b | 2011-12-01 23:19:31 | [diff] [blame] | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 4 | |
[email protected] | 99873aa | 2013-03-29 17:46:23 | [diff] [blame] | 5 | #include "base/memory/shared_memory.h" |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 6 | |
[email protected] | 6d6797eb | 2014-08-07 22:07:43 | [diff] [blame] | 7 | #include <aclapi.h> |
avi | 9beac25 | 2015-12-24 08:44:47 | [diff] [blame] | 8 | #include <stddef.h> |
| 9 | #include <stdint.h> |
[email protected] | 6d6797eb | 2014-08-07 22:07:43 | [diff] [blame] | 10 | |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 11 | #include "base/logging.h" |
[email protected] | 6d6797eb | 2014-08-07 22:07:43 | [diff] [blame] | 12 | #include "base/memory/scoped_ptr.h" |
[email protected] | dc84fcc | 2014-07-24 11:42:59 | [diff] [blame] | 13 | #include "base/rand_util.h" |
| 14 | #include "base/strings/stringprintf.h" |
[email protected] | a4ea1f1 | 2013-06-07 18:37:07 | [diff] [blame] | 15 | #include "base/strings/utf_string_conversions.h" |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 16 | |
[email protected] | 67ea507 | 2013-03-28 02:02:18 | [diff] [blame] | 17 | namespace { |
| 18 | |
forshaw | 0474abe | 2015-12-18 02:16:59 | [diff] [blame] | 19 | typedef enum _SECTION_INFORMATION_CLASS { |
| 20 | SectionBasicInformation, |
| 21 | } SECTION_INFORMATION_CLASS; |
| 22 | |
| 23 | typedef struct _SECTION_BASIC_INFORMATION { |
| 24 | PVOID BaseAddress; |
| 25 | ULONG Attributes; |
| 26 | LARGE_INTEGER Size; |
| 27 | } SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION; |
| 28 | |
| 29 | typedef ULONG(__stdcall* NtQuerySectionType)( |
| 30 | HANDLE SectionHandle, |
| 31 | SECTION_INFORMATION_CLASS SectionInformationClass, |
| 32 | PVOID SectionInformation, |
| 33 | ULONG SectionInformationLength, |
| 34 | PULONG ResultLength); |
| 35 | |
[email protected] | 67ea507 | 2013-03-28 02:02:18 | [diff] [blame] | 36 | // Returns the length of the memory section starting at the supplied address. |
| 37 | size_t GetMemorySectionSize(void* address) { |
| 38 | MEMORY_BASIC_INFORMATION memory_info; |
| 39 | if (!::VirtualQuery(address, &memory_info, sizeof(memory_info))) |
| 40 | return 0; |
| 41 | return memory_info.RegionSize - (static_cast<char*>(address) - |
| 42 | static_cast<char*>(memory_info.AllocationBase)); |
| 43 | } |
| 44 | |
forshaw | 0474abe | 2015-12-18 02:16:59 | [diff] [blame] | 45 | // Checks if the section object is safe to map. At the moment this just means |
| 46 | // it's not an image section. |
| 47 | bool IsSectionSafeToMap(HANDLE handle) { |
| 48 | static NtQuerySectionType nt_query_section_func; |
| 49 | if (!nt_query_section_func) { |
| 50 | nt_query_section_func = reinterpret_cast<NtQuerySectionType>( |
| 51 | ::GetProcAddress(::GetModuleHandle(L"ntdll.dll"), "NtQuerySection")); |
| 52 | DCHECK(nt_query_section_func); |
| 53 | } |
| 54 | |
| 55 | // The handle must have SECTION_QUERY access for this to succeed. |
| 56 | SECTION_BASIC_INFORMATION basic_information = {}; |
| 57 | ULONG status = |
| 58 | nt_query_section_func(handle, SectionBasicInformation, &basic_information, |
| 59 | sizeof(basic_information), nullptr); |
| 60 | if (status) |
| 61 | return false; |
| 62 | return (basic_information.Attributes & SEC_IMAGE) != SEC_IMAGE; |
| 63 | } |
| 64 | |
[email protected] | 67ea507 | 2013-03-28 02:02:18 | [diff] [blame] | 65 | } // namespace. |
| 66 | |
[email protected] | 176aa48 | 2008-11-14 03:25:15 | [diff] [blame] | 67 | namespace base { |
| 68 | |
erikchen | baac911 | 2015-10-23 20:20:34 | [diff] [blame] | 69 | SharedMemoryCreateOptions::SharedMemoryCreateOptions() |
| 70 | : name_deprecated(nullptr), |
| 71 | open_existing_deprecated(false), |
| 72 | size(0), |
| 73 | executable(false), |
| 74 | share_read_only(false) {} |
| 75 | |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 76 | SharedMemory::SharedMemory() |
forshaw | 0474abe | 2015-12-18 02:16:59 | [diff] [blame] | 77 | : external_section_(false), |
sammc | 5648c85 | 2015-07-02 01:25:00 | [diff] [blame] | 78 | mapped_file_(NULL), |
| 79 | mapped_size_(0), |
[email protected] | 8cc4194 | 2010-11-05 19:16:07 | [diff] [blame] | 80 | memory_(NULL), |
| 81 | read_only_(false), |
forshaw | 0474abe | 2015-12-18 02:16:59 | [diff] [blame] | 82 | requested_size_(0) {} |
| 83 | |
| 84 | SharedMemory::SharedMemory(const std::wstring& name) |
| 85 | : external_section_(false), |
| 86 | name_(name), |
| 87 | mapped_file_(NULL), |
| 88 | mapped_size_(0), |
| 89 | memory_(NULL), |
| 90 | read_only_(false), |
| 91 | requested_size_(0) {} |
[email protected] | 8cc4194 | 2010-11-05 19:16:07 | [diff] [blame] | 92 | |
scottmg | d19b4f7 | 2015-06-19 22:51:00 | [diff] [blame] | 93 | SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only) |
forshaw | 0474abe | 2015-12-18 02:16:59 | [diff] [blame] | 94 | : external_section_(true), |
| 95 | mapped_file_(handle.GetHandle()), |
sammc | 5648c85 | 2015-07-02 01:25:00 | [diff] [blame] | 96 | mapped_size_(0), |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 97 | memory_(NULL), |
| 98 | read_only_(read_only), |
sammc | 5648c85 | 2015-07-02 01:25:00 | [diff] [blame] | 99 | requested_size_(0) { |
erikchen | 5ea2ab7 | 2015-09-25 22:34:31 | [diff] [blame] | 100 | DCHECK(!handle.IsValid() || handle.BelongsToCurrentProcess()); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 101 | } |
| 102 | |
erikchen | 9d688915 | 2016-01-30 00:06:24 | [diff] [blame] | 103 | SharedMemory::SharedMemory(const SharedMemoryHandle& handle, |
| 104 | bool read_only, |
| 105 | ProcessHandle process) |
| 106 | : external_section_(true), |
| 107 | mapped_file_(NULL), |
| 108 | mapped_size_(0), |
| 109 | memory_(NULL), |
| 110 | read_only_(read_only), |
| 111 | requested_size_(0) { |
| 112 | DWORD access = FILE_MAP_READ | SECTION_QUERY; |
| 113 | ::DuplicateHandle(process, handle.GetHandle(), GetCurrentProcess(), |
| 114 | &mapped_file_, |
| 115 | read_only_ ? access : access | FILE_MAP_WRITE, FALSE, 0); |
| 116 | } |
| 117 | |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 118 | SharedMemory::~SharedMemory() { |
jbauman | 569918b | 2014-12-10 22:07:20 | [diff] [blame] | 119 | Unmap(); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 120 | Close(); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 121 | } |
| 122 | |
[email protected] | 5fe733de | 2009-02-11 18:59:20 | [diff] [blame] | 123 | // static |
| 124 | bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) { |
erikchen | 5ea2ab7 | 2015-09-25 22:34:31 | [diff] [blame] | 125 | return handle.IsValid(); |
[email protected] | 5fe733de | 2009-02-11 18:59:20 | [diff] [blame] | 126 | } |
| 127 | |
[email protected] | 76aac1e | 2009-03-16 16:45:36 | [diff] [blame] | 128 | // static |
| 129 | SharedMemoryHandle SharedMemory::NULLHandle() { |
erikchen | 5ea2ab7 | 2015-09-25 22:34:31 | [diff] [blame] | 130 | return SharedMemoryHandle(); |
[email protected] | 76aac1e | 2009-03-16 16:45:36 | [diff] [blame] | 131 | } |
| 132 | |
[email protected] | b0af04c | 2009-05-18 17:46:31 | [diff] [blame] | 133 | // static |
| 134 | void SharedMemory::CloseHandle(const SharedMemoryHandle& handle) { |
erikchen | 5ea2ab7 | 2015-09-25 22:34:31 | [diff] [blame] | 135 | handle.Close(); |
[email protected] | b0af04c | 2009-05-18 17:46:31 | [diff] [blame] | 136 | } |
| 137 | |
[email protected] | c14eda9 | 2013-05-09 23:15:40 | [diff] [blame] | 138 | // static |
| 139 | size_t SharedMemory::GetHandleLimit() { |
| 140 | // Rounded down from value reported here: |
| 141 | // http://blogs.technet.com/b/markrussinovich/archive/2009/09/29/3283844.aspx |
| 142 | return static_cast<size_t>(1 << 23); |
| 143 | } |
| 144 | |
erikchen | 2096f62 | 2015-06-03 00:26:59 | [diff] [blame] | 145 | // static |
| 146 | SharedMemoryHandle SharedMemory::DuplicateHandle( |
erikchen | 8539d85 | 2015-05-30 01:49:19 | [diff] [blame] | 147 | const SharedMemoryHandle& handle) { |
erikchen | 5ea2ab7 | 2015-09-25 22:34:31 | [diff] [blame] | 148 | DCHECK(handle.BelongsToCurrentProcess()); |
| 149 | HANDLE duped_handle; |
erikchen | 2096f62 | 2015-06-03 00:26:59 | [diff] [blame] | 150 | ProcessHandle process = GetCurrentProcess(); |
erikchen | 5ea2ab7 | 2015-09-25 22:34:31 | [diff] [blame] | 151 | BOOL success = |
| 152 | ::DuplicateHandle(process, handle.GetHandle(), process, &duped_handle, 0, |
| 153 | FALSE, DUPLICATE_SAME_ACCESS); |
erikchen | 2096f62 | 2015-06-03 00:26:59 | [diff] [blame] | 154 | if (success) |
erikchen | 5ea2ab7 | 2015-09-25 22:34:31 | [diff] [blame] | 155 | return SharedMemoryHandle(duped_handle, GetCurrentProcId()); |
| 156 | return SharedMemoryHandle(); |
erikchen | 8539d85 | 2015-05-30 01:49:19 | [diff] [blame] | 157 | } |
| 158 | |
[email protected] | 374f1a8 | 2013-01-10 02:16:24 | [diff] [blame] | 159 | bool SharedMemory::CreateAndMapAnonymous(size_t size) { |
[email protected] | 54e3dfa2 | 2010-10-27 18:16:06 | [diff] [blame] | 160 | return CreateAnonymous(size) && Map(size); |
| 161 | } |
| 162 | |
[email protected] | b05df6b | 2011-12-01 23:19:31 | [diff] [blame] | 163 | bool SharedMemory::Create(const SharedMemoryCreateOptions& options) { |
[email protected] | 67ea507 | 2013-03-28 02:02:18 | [diff] [blame] | 164 | // TODO(bsy,sehr): crbug.com/210609 NaCl forces us to round up 64k here, |
| 165 | // wasting 32k per mapping on average. |
| 166 | static const size_t kSectionMask = 65536 - 1; |
[email protected] | b05df6b | 2011-12-01 23:19:31 | [diff] [blame] | 167 | DCHECK(!options.executable); |
[email protected] | 5d2b449 | 2011-03-01 02:48:05 | [diff] [blame] | 168 | DCHECK(!mapped_file_); |
[email protected] | b05df6b | 2011-12-01 23:19:31 | [diff] [blame] | 169 | if (options.size == 0) |
[email protected] | 54e3dfa2 | 2010-10-27 18:16:06 | [diff] [blame] | 170 | return false; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 171 | |
[email protected] | 67ea507 | 2013-03-28 02:02:18 | [diff] [blame] | 172 | // Check maximum accounting for overflow. |
| 173 | if (options.size > |
| 174 | static_cast<size_t>(std::numeric_limits<int>::max()) - kSectionMask) |
[email protected] | 374f1a8 | 2013-01-10 02:16:24 | [diff] [blame] | 175 | return false; |
| 176 | |
[email protected] | 67ea507 | 2013-03-28 02:02:18 | [diff] [blame] | 177 | size_t rounded_size = (options.size + kSectionMask) & ~kSectionMask; |
thestig | 8badc79 | 2014-12-04 22:14:22 | [diff] [blame] | 178 | name_ = options.name_deprecated ? |
| 179 | ASCIIToUTF16(*options.name_deprecated) : L""; |
[email protected] | 6d6797eb | 2014-08-07 22:07:43 | [diff] [blame] | 180 | SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, FALSE }; |
| 181 | SECURITY_DESCRIPTOR sd; |
| 182 | ACL dacl; |
| 183 | |
[email protected] | dc84fcc | 2014-07-24 11:42:59 | [diff] [blame] | 184 | if (options.share_read_only && name_.empty()) { |
[email protected] | 6d6797eb | 2014-08-07 22:07:43 | [diff] [blame] | 185 | // Add an empty DACL to enforce anonymous read-only sections. |
| 186 | sa.lpSecurityDescriptor = &sd; |
| 187 | if (!InitializeAcl(&dacl, sizeof(dacl), ACL_REVISION)) |
| 188 | return false; |
| 189 | if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) |
| 190 | return false; |
| 191 | if (!SetSecurityDescriptorDacl(&sd, TRUE, &dacl, FALSE)) |
| 192 | return false; |
| 193 | |
[email protected] | dc84fcc | 2014-07-24 11:42:59 | [diff] [blame] | 194 | // Windows ignores DACLs on certain unnamed objects (like shared sections). |
| 195 | // So, we generate a random name when we need to enforce read-only. |
| 196 | uint64_t rand_values[4]; |
thestig | 8badc79 | 2014-12-04 22:14:22 | [diff] [blame] | 197 | RandBytes(&rand_values, sizeof(rand_values)); |
brucedawson | 5604a11d | 2015-10-06 19:22:00 | [diff] [blame] | 198 | name_ = StringPrintf(L"CrSharedMem_%016llx%016llx%016llx%016llx", |
thestig | 8badc79 | 2014-12-04 22:14:22 | [diff] [blame] | 199 | rand_values[0], rand_values[1], |
| 200 | rand_values[2], rand_values[3]); |
[email protected] | dc84fcc | 2014-07-24 11:42:59 | [diff] [blame] | 201 | } |
[email protected] | 6d6797eb | 2014-08-07 22:07:43 | [diff] [blame] | 202 | mapped_file_ = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, |
shrikant | 9426fb8 | 2015-02-24 00:27:33 | [diff] [blame] | 203 | PAGE_READWRITE, 0, static_cast<DWORD>(rounded_size), |
| 204 | name_.empty() ? nullptr : name_.c_str()); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 205 | if (!mapped_file_) |
| 206 | return false; |
| 207 | |
[email protected] | 67ea507 | 2013-03-28 02:02:18 | [diff] [blame] | 208 | requested_size_ = options.size; |
[email protected] | 54e3dfa2 | 2010-10-27 18:16:06 | [diff] [blame] | 209 | |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 210 | // Check if the shared memory pre-exists. |
[email protected] | 54e3dfa2 | 2010-10-27 18:16:06 | [diff] [blame] | 211 | if (GetLastError() == ERROR_ALREADY_EXISTS) { |
[email protected] | 67ea507 | 2013-03-28 02:02:18 | [diff] [blame] | 212 | // If the file already existed, set requested_size_ to 0 to show that |
[email protected] | 54e3dfa2 | 2010-10-27 18:16:06 | [diff] [blame] | 213 | // we don't know the size. |
[email protected] | 67ea507 | 2013-03-28 02:02:18 | [diff] [blame] | 214 | requested_size_ = 0; |
forshaw | 0474abe | 2015-12-18 02:16:59 | [diff] [blame] | 215 | external_section_ = true; |
[email protected] | ff672b7 | 2014-03-05 21:13:52 | [diff] [blame] | 216 | if (!options.open_existing_deprecated) { |
[email protected] | 54e3dfa2 | 2010-10-27 18:16:06 | [diff] [blame] | 217 | Close(); |
| 218 | return false; |
| 219 | } |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 220 | } |
[email protected] | 54e3dfa2 | 2010-10-27 18:16:06 | [diff] [blame] | 221 | |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 222 | return true; |
| 223 | } |
| 224 | |
[email protected] | b6413b49b | 2010-09-29 20:32:22 | [diff] [blame] | 225 | bool SharedMemory::Delete(const std::string& name) { |
[email protected] | 9e51af9 | 2009-02-04 00:58:39 | [diff] [blame] | 226 | // intentionally empty -- there is nothing for us to do on Windows. |
| 227 | return true; |
| 228 | } |
| 229 | |
[email protected] | b6413b49b | 2010-09-29 20:32:22 | [diff] [blame] | 230 | bool SharedMemory::Open(const std::string& name, bool read_only) { |
[email protected] | 5d2b449 | 2011-03-01 02:48:05 | [diff] [blame] | 231 | DCHECK(!mapped_file_); |
forshaw | 0474abe | 2015-12-18 02:16:59 | [diff] [blame] | 232 | DWORD access = FILE_MAP_READ | SECTION_QUERY; |
| 233 | if (!read_only) |
| 234 | access |= FILE_MAP_WRITE; |
thestig | 8badc79 | 2014-12-04 22:14:22 | [diff] [blame] | 235 | name_ = ASCIIToUTF16(name); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 236 | read_only_ = read_only; |
forshaw | 0474abe | 2015-12-18 02:16:59 | [diff] [blame] | 237 | mapped_file_ = |
| 238 | OpenFileMapping(access, false, name_.empty() ? nullptr : name_.c_str()); |
| 239 | if (!mapped_file_) |
| 240 | return false; |
| 241 | // If a name specified assume it's an external section. |
| 242 | if (!name_.empty()) |
| 243 | external_section_ = true; |
| 244 | // Note: size_ is not set in this case. |
| 245 | return true; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 246 | } |
| 247 | |
[email protected] | e29e3f55 | 2013-01-16 09:02:34 | [diff] [blame] | 248 | bool SharedMemory::MapAt(off_t offset, size_t bytes) { |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 249 | if (mapped_file_ == NULL) |
| 250 | return false; |
| 251 | |
[email protected] | 374f1a8 | 2013-01-10 02:16:24 | [diff] [blame] | 252 | if (bytes > static_cast<size_t>(std::numeric_limits<int>::max())) |
| 253 | return false; |
| 254 | |
[email protected] | 421c150 | 2014-03-18 22:33:28 | [diff] [blame] | 255 | if (memory_) |
| 256 | return false; |
| 257 | |
forshaw | 0474abe | 2015-12-18 02:16:59 | [diff] [blame] | 258 | if (external_section_ && !IsSectionSafeToMap(mapped_file_)) |
| 259 | return false; |
| 260 | |
avi | 9beac25 | 2015-12-24 08:44:47 | [diff] [blame] | 261 | memory_ = MapViewOfFile( |
| 262 | mapped_file_, read_only_ ? FILE_MAP_READ : FILE_MAP_READ | FILE_MAP_WRITE, |
| 263 | static_cast<uint64_t>(offset) >> 32, static_cast<DWORD>(offset), bytes); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 264 | if (memory_ != NULL) { |
[email protected] | 404a058 | 2012-08-18 02:17:26 | [diff] [blame] | 265 | DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(memory_) & |
| 266 | (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1)); |
[email protected] | 67ea507 | 2013-03-28 02:02:18 | [diff] [blame] | 267 | mapped_size_ = GetMemorySectionSize(memory_); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 268 | return true; |
| 269 | } |
| 270 | return false; |
| 271 | } |
| 272 | |
| 273 | bool SharedMemory::Unmap() { |
| 274 | if (memory_ == NULL) |
| 275 | return false; |
| 276 | |
| 277 | UnmapViewOfFile(memory_); |
| 278 | memory_ = NULL; |
| 279 | return true; |
| 280 | } |
| 281 | |
| 282 | bool SharedMemory::ShareToProcessCommon(ProcessHandle process, |
thestig | 8badc79 | 2014-12-04 22:14:22 | [diff] [blame] | 283 | SharedMemoryHandle* new_handle, |
[email protected] | 5f58adab | 2013-11-20 23:41:25 | [diff] [blame] | 284 | bool close_self, |
| 285 | ShareMode share_mode) { |
erikchen | 5ea2ab7 | 2015-09-25 22:34:31 | [diff] [blame] | 286 | *new_handle = SharedMemoryHandle(); |
forshaw | 0474abe | 2015-12-18 02:16:59 | [diff] [blame] | 287 | DWORD access = FILE_MAP_READ | SECTION_QUERY; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 288 | DWORD options = 0; |
| 289 | HANDLE mapped_file = mapped_file_; |
| 290 | HANDLE result; |
[email protected] | 5f58adab | 2013-11-20 23:41:25 | [diff] [blame] | 291 | if (share_mode == SHARE_CURRENT_MODE && !read_only_) |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 292 | access |= FILE_MAP_WRITE; |
| 293 | if (close_self) { |
| 294 | // DUPLICATE_CLOSE_SOURCE causes DuplicateHandle to close mapped_file. |
| 295 | options = DUPLICATE_CLOSE_SOURCE; |
| 296 | mapped_file_ = NULL; |
| 297 | Unmap(); |
| 298 | } |
| 299 | |
| 300 | if (process == GetCurrentProcess() && close_self) { |
erikchen | 5ea2ab7 | 2015-09-25 22:34:31 | [diff] [blame] | 301 | *new_handle = SharedMemoryHandle(mapped_file, base::GetCurrentProcId()); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 302 | return true; |
| 303 | } |
| 304 | |
erikchen | 2096f62 | 2015-06-03 00:26:59 | [diff] [blame] | 305 | if (!::DuplicateHandle(GetCurrentProcess(), mapped_file, process, &result, |
| 306 | access, FALSE, options)) { |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 307 | return false; |
erikchen | 2096f62 | 2015-06-03 00:26:59 | [diff] [blame] | 308 | } |
erikchen | 5ea2ab7 | 2015-09-25 22:34:31 | [diff] [blame] | 309 | *new_handle = SharedMemoryHandle(result, base::GetProcId(process)); |
erikchen | 71bc3b2 | 2016-02-01 22:14:28 | [diff] [blame^] | 310 | new_handle->SetOwnershipPassesToIPC(true); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 311 | return true; |
| 312 | } |
| 313 | |
| 314 | |
| 315 | void SharedMemory::Close() { |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 316 | if (mapped_file_ != NULL) { |
erikchen | 5ea2ab7 | 2015-09-25 22:34:31 | [diff] [blame] | 317 | ::CloseHandle(mapped_file_); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 318 | mapped_file_ = NULL; |
| 319 | } |
| 320 | } |
| 321 | |
[email protected] | 5fe733de | 2009-02-11 18:59:20 | [diff] [blame] | 322 | SharedMemoryHandle SharedMemory::handle() const { |
erikchen | 5ea2ab7 | 2015-09-25 22:34:31 | [diff] [blame] | 323 | return SharedMemoryHandle(mapped_file_, base::GetCurrentProcId()); |
[email protected] | 5fe733de | 2009-02-11 18:59:20 | [diff] [blame] | 324 | } |
| 325 | |
[email protected] | 176aa48 | 2008-11-14 03:25:15 | [diff] [blame] | 326 | } // namespace base |