| OLD | NEW | 
|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "base/files/memory_mapped_file.h" | 5 #include "base/files/memory_mapped_file.h" | 
| 6 | 6 | 
| 7 #include <stddef.h> | 7 #include <stddef.h> | 
| 8 #include <stdint.h> | 8 #include <stdint.h> | 
| 9 | 9 | 
| 10 #include <limits> | 10 #include <limits> | 
| 11 | 11 | 
| 12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" | 
| 13 #include "base/strings/string16.h" | 13 #include "base/strings/string16.h" | 
| 14 #include "base/threading/thread_restrictions.h" | 14 #include "base/threading/thread_restrictions.h" | 
| 15 | 15 | 
| 16 namespace base { | 16 namespace base { | 
| 17 | 17 | 
| 18 MemoryMappedFile::MemoryMappedFile() : data_(NULL), length_(0), image_(false) { | 18 MemoryMappedFile::MemoryMappedFile() : data_(NULL), length_(0) { | 
| 19 } |  | 
| 20 |  | 
| 21 bool MemoryMappedFile::InitializeAsImageSection(const FilePath& file_name) { |  | 
| 22   image_ = true; |  | 
| 23   return Initialize(file_name); |  | 
| 24 } | 19 } | 
| 25 | 20 | 
| 26 bool MemoryMappedFile::MapFileRegionToMemory( | 21 bool MemoryMappedFile::MapFileRegionToMemory( | 
| 27     const MemoryMappedFile::Region& region) { | 22     const MemoryMappedFile::Region& region, | 
|  | 23     Access access) { | 
| 28   ThreadRestrictions::AssertIOAllowed(); | 24   ThreadRestrictions::AssertIOAllowed(); | 
| 29 | 25 | 
| 30   if (!file_.IsValid()) | 26   if (!file_.IsValid()) | 
| 31     return false; | 27     return false; | 
| 32 | 28 | 
| 33   int flags = image_ ? SEC_IMAGE | PAGE_READONLY : PAGE_READONLY; | 29   int flags = 0; | 
|  | 30   uint32_t size_low = 0; | 
|  | 31   uint32_t size_high = 0; | 
|  | 32   switch (access) { | 
|  | 33     case READ_ONLY: | 
|  | 34       flags |= PAGE_READONLY; | 
|  | 35       break; | 
|  | 36     case READ_WRITE: | 
|  | 37       flags |= PAGE_READWRITE; | 
|  | 38       break; | 
|  | 39     case READ_WRITE_EXTEND: | 
|  | 40       flags |= PAGE_READWRITE; | 
|  | 41       size_high = static_cast<uint32_t>(region.size >> 32); | 
|  | 42       size_low = static_cast<uint32_t>(region.size & 0xFFFFFFFF); | 
|  | 43       break; | 
|  | 44   } | 
| 34 | 45 | 
| 35   file_mapping_.Set(::CreateFileMapping(file_.GetPlatformFile(), NULL, | 46   file_mapping_.Set(::CreateFileMapping(file_.GetPlatformFile(), NULL, flags, | 
| 36                                         flags, 0, 0, NULL)); | 47                                         size_high, size_low, NULL)); | 
| 37   if (!file_mapping_.IsValid()) | 48   if (!file_mapping_.IsValid()) | 
| 38     return false; | 49     return false; | 
| 39 | 50 | 
| 40   LARGE_INTEGER map_start = {}; | 51   LARGE_INTEGER map_start = {}; | 
| 41   SIZE_T map_size = 0; | 52   SIZE_T map_size = 0; | 
| 42   int32_t data_offset = 0; | 53   int32_t data_offset = 0; | 
| 43 | 54 | 
| 44   if (region == MemoryMappedFile::Region::kWholeFile) { | 55   if (region == MemoryMappedFile::Region::kWholeFile) { | 
|  | 56     DCHECK_NE(READ_WRITE_EXTEND, access); | 
| 45     int64_t file_len = file_.GetLength(); | 57     int64_t file_len = file_.GetLength(); | 
| 46     if (file_len <= 0 || file_len > std::numeric_limits<int32_t>::max()) | 58     if (file_len <= 0 || file_len > std::numeric_limits<int32_t>::max()) | 
| 47       return false; | 59       return false; | 
| 48     length_ = static_cast<size_t>(file_len); | 60     length_ = static_cast<size_t>(file_len); | 
| 49   } else { | 61   } else { | 
| 50     // The region can be arbitrarily aligned. MapViewOfFile, instead, requires | 62     // The region can be arbitrarily aligned. MapViewOfFile, instead, requires | 
| 51     // that the start address is aligned to the VM granularity (which is | 63     // that the start address is aligned to the VM granularity (which is | 
| 52     // typically larger than a page size, for instance 32k). | 64     // typically larger than a page size, for instance 32k). | 
| 53     // Also, conversely to POSIX's mmap, the |map_size| doesn't have to be | 65     // Also, conversely to POSIX's mmap, the |map_size| doesn't have to be | 
| 54     // aligned and must be less than or equal the mapped file size. | 66     // aligned and must be less than or equal the mapped file size. | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 65         static_cast<uint64_t>(size) > std::numeric_limits<SIZE_T>::max()) { | 77         static_cast<uint64_t>(size) > std::numeric_limits<SIZE_T>::max()) { | 
| 66       DLOG(ERROR) << "Region bounds are not valid for MapViewOfFile"; | 78       DLOG(ERROR) << "Region bounds are not valid for MapViewOfFile"; | 
| 67       return false; | 79       return false; | 
| 68     } | 80     } | 
| 69     map_start.QuadPart = aligned_start; | 81     map_start.QuadPart = aligned_start; | 
| 70     map_size = static_cast<SIZE_T>(size); | 82     map_size = static_cast<SIZE_T>(size); | 
| 71     length_ = static_cast<size_t>(region.size); | 83     length_ = static_cast<size_t>(region.size); | 
| 72   } | 84   } | 
| 73 | 85 | 
| 74   data_ = static_cast<uint8_t*>( | 86   data_ = static_cast<uint8_t*>( | 
| 75       ::MapViewOfFile(file_mapping_.Get(), FILE_MAP_READ, map_start.HighPart, | 87       ::MapViewOfFile(file_mapping_.Get(), | 
| 76                       map_start.LowPart, map_size)); | 88                       (flags & PAGE_READONLY) ? FILE_MAP_READ : FILE_MAP_WRITE, | 
|  | 89                       map_start.HighPart, map_start.LowPart, map_size)); | 
| 77   if (data_ == NULL) | 90   if (data_ == NULL) | 
| 78     return false; | 91     return false; | 
| 79   data_ += data_offset; | 92   data_ += data_offset; | 
| 80   return true; | 93   return true; | 
| 81 } | 94 } | 
| 82 | 95 | 
| 83 void MemoryMappedFile::CloseHandles() { | 96 void MemoryMappedFile::CloseHandles() { | 
| 84   if (data_) | 97   if (data_) | 
| 85     ::UnmapViewOfFile(data_); | 98     ::UnmapViewOfFile(data_); | 
| 86   if (file_mapping_.IsValid()) | 99   if (file_mapping_.IsValid()) | 
| 87     file_mapping_.Close(); | 100     file_mapping_.Close(); | 
| 88   if (file_.IsValid()) | 101   if (file_.IsValid()) | 
| 89     file_.Close(); | 102     file_.Close(); | 
| 90 | 103 | 
| 91   data_ = NULL; | 104   data_ = NULL; | 
| 92   length_ = 0; | 105   length_ = 0; | 
| 93 } | 106 } | 
| 94 | 107 | 
| 95 }  // namespace base | 108 }  // namespace base | 
| OLD | NEW | 
|---|