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
3 // found in the LICENSE file.
5 #include "base/files/memory_mapped_file.h"
7 #include "base/files/file_path.h"
8 #include "base/strings/string16.h"
9 #include "base/threading/thread_restrictions.h"
13 MemoryMappedFile::MemoryMappedFile() : data_(NULL
), length_(0), image_(false) {
16 bool MemoryMappedFile::InitializeAsImageSection(const FilePath
& file_name
) {
18 return Initialize(file_name
);
21 bool MemoryMappedFile::MapFileRegionToMemory(
22 const MemoryMappedFile::Region
& region
) {
23 ThreadRestrictions::AssertIOAllowed();
28 int flags
= image_
? SEC_IMAGE
| PAGE_READONLY
: PAGE_READONLY
;
30 file_mapping_
.Set(::CreateFileMapping(file_
.GetPlatformFile(), NULL
,
32 if (!file_mapping_
.IsValid())
35 LARGE_INTEGER map_start
= {};
37 int32 data_offset
= 0;
39 if (region
== MemoryMappedFile::Region::kWholeFile
) {
40 int64 file_len
= file_
.GetLength();
41 if (file_len
<= 0 || file_len
> kint32max
)
43 length_
= static_cast<size_t>(file_len
);
45 // The region can be arbitrarily aligned. MapViewOfFile, instead, requires
46 // that the start address is aligned to the VM granularity (which is
47 // typically larger than a page size, for instance 32k).
48 // Also, conversely to POSIX's mmap, the |map_size| doesn't have to be
49 // aligned and must be less than or equal the mapped file size.
50 // We map here the outer region [|aligned_start|, |aligned_start+size|]
51 // which contains |region| and then add up the |data_offset| displacement.
52 int64 aligned_start
= 0;
54 CalculateVMAlignedBoundaries(
55 region
.offset
, region
.size
, &aligned_start
, &ignored
, &data_offset
);
56 int64 size
= region
.size
+ data_offset
;
58 // Ensure that the casts below in the MapViewOfFile call are sane.
59 if (aligned_start
< 0 || size
< 0 ||
60 static_cast<uint64
>(size
) > std::numeric_limits
<SIZE_T
>::max()) {
61 DLOG(ERROR
) << "Region bounds are not valid for MapViewOfFile";
64 map_start
.QuadPart
= aligned_start
;
65 map_size
= static_cast<SIZE_T
>(size
);
66 length_
= static_cast<size_t>(region
.size
);
69 data_
= static_cast<uint8
*>(::MapViewOfFile(file_mapping_
.Get(),
80 void MemoryMappedFile::CloseHandles() {
82 ::UnmapViewOfFile(data_
);
83 if (file_mapping_
.IsValid())
84 file_mapping_
.Close();