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. 4 5 #include "base/files/memory_mapped_file.h" 6 7 #include "base/files/file_path.h" 8 #include "base/logging.h" 9 #include "base/metrics/histogram.h" 10 #include "base/strings/string16.h" 11 #include "base/threading/thread_restrictions.h" 12 13 namespace base { 14 15 MemoryMappedFile::MemoryMappedFile() 16 : file_(INVALID_HANDLE_VALUE), 17 file_mapping_(INVALID_HANDLE_VALUE), 18 data_(NULL), 19 length_(INVALID_FILE_SIZE) { 20 } 21 22 bool MemoryMappedFile::InitializeAsImageSection(const FilePath& file_name) { 23 if (IsValid()) 24 return false; 25 file_ = CreatePlatformFile(file_name, PLATFORM_FILE_OPEN | PLATFORM_FILE_READ, 26 NULL, NULL); 27 28 if (file_ == kInvalidPlatformFileValue) { 29 DLOG(ERROR) << "Couldn't open " << file_name.AsUTF8Unsafe(); 30 return false; 31 } 32 33 if (!MapFileToMemoryInternalEx(SEC_IMAGE)) { 34 CloseHandles(); 35 return false; 36 } 37 38 return true; 39 } 40 41 bool MemoryMappedFile::MapFileToMemoryInternal() { 42 return MapFileToMemoryInternalEx(0); 43 } 44 45 bool MemoryMappedFile::MapFileToMemoryInternalEx(int flags) { 46 ThreadRestrictions::AssertIOAllowed(); 47 48 if (file_ == INVALID_HANDLE_VALUE) 49 return false; 50 51 length_ = ::GetFileSize(file_, NULL); 52 if (length_ == INVALID_FILE_SIZE) 53 return false; 54 55 file_mapping_ = ::CreateFileMapping(file_, NULL, PAGE_READONLY | flags, 56 0, 0, NULL); 57 if (!file_mapping_) { 58 // According to msdn, system error codes are only reserved up to 15999. 59 // http://msdn.microsoft.com/en-us/library/ms681381(v=VS.85).aspx. 60 UMA_HISTOGRAM_ENUMERATION("MemoryMappedFile.CreateFileMapping", 61 logging::GetLastSystemErrorCode(), 16000); 62 return false; 63 } 64 65 data_ = static_cast<uint8*>( 66 ::MapViewOfFile(file_mapping_, FILE_MAP_READ, 0, 0, 0)); 67 if (!data_) { 68 UMA_HISTOGRAM_ENUMERATION("MemoryMappedFile.MapViewOfFile", 69 logging::GetLastSystemErrorCode(), 16000); 70 } 71 return data_ != NULL; 72 } 73 74 void MemoryMappedFile::CloseHandles() { 75 if (data_) 76 ::UnmapViewOfFile(data_); 77 if (file_mapping_ != INVALID_HANDLE_VALUE) 78 ::CloseHandle(file_mapping_); 79 if (file_ != INVALID_HANDLE_VALUE) 80 ::CloseHandle(file_); 81 82 data_ = NULL; 83 file_mapping_ = file_ = INVALID_HANDLE_VALUE; 84 length_ = INVALID_FILE_SIZE; 85 } 86 87 } // namespace base 88