Flutter Engine
mapping_win.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter 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 "flutter/fml/mapping.h"
6 
7 #include <fcntl.h>
8 #include <io.h>
9 #include <windows.h>
10 
11 #include <type_traits>
12 
13 #include "flutter/fml/file.h"
14 #include "flutter/fml/platform/win/errors_win.h"
15 #include "flutter/fml/platform/win/wstring_conversion.h"
16 
17 namespace fml {
18 
19 Mapping::Mapping() = default;
20 
21 Mapping::~Mapping() = default;
22 
23 static bool IsWritable(
24  std::initializer_list<FileMapping::Protection> protection_flags) {
25  for (auto protection : protection_flags) {
26  if (protection == FileMapping::Protection::kWrite) {
27  return true;
28  }
29  }
30  return false;
31 }
32 
33 static bool IsExecutable(
34  std::initializer_list<FileMapping::Protection> protection_flags) {
35  for (auto protection : protection_flags) {
36  if (protection == FileMapping::Protection::kExecute) {
37  return true;
38  }
39  }
40  return false;
41 }
42 
44  std::initializer_list<Protection> protections)
45  : size_(0), mapping_(nullptr) {
46  if (!fd.is_valid()) {
47  return;
48  }
49 
50  const auto mapping_size = ::GetFileSize(fd.get(), nullptr);
51 
52  if (mapping_size == INVALID_FILE_SIZE) {
53  FML_DLOG(ERROR) << "Invalid file size. " << GetLastErrorMessage();
54  return;
55  }
56 
57  if (mapping_size == 0) {
58  valid_ = true;
59  return;
60  }
61 
62  DWORD protect_flags = 0;
63  bool read_only = !IsWritable(protections);
64 
65  if (IsExecutable(protections)) {
66  protect_flags = PAGE_EXECUTE_READ;
67  } else if (read_only) {
68  protect_flags = PAGE_READONLY;
69  } else {
70  protect_flags = PAGE_READWRITE;
71  }
72 
73  mapping_handle_.reset(::CreateFileMapping(fd.get(), // hFile
74  nullptr, // lpAttributes
75  protect_flags, // flProtect
76  0, // dwMaximumSizeHigh
77  0, // dwMaximumSizeLow
78  nullptr // lpName
79  ));
80 
81  if (!mapping_handle_.is_valid()) {
82  return;
83  }
84 
85  const DWORD desired_access = read_only ? FILE_MAP_READ : FILE_MAP_WRITE;
86 
87  auto mapping = reinterpret_cast<uint8_t*>(
88  MapViewOfFile(mapping_handle_.get(), desired_access, 0, 0, mapping_size));
89 
90  if (mapping == nullptr) {
91  FML_DLOG(ERROR) << "Could not setup file mapping. "
93  return;
94  }
95 
96  mapping_ = mapping;
97  size_ = mapping_size;
98  valid_ = true;
99  if (IsWritable(protections)) {
100  mutable_mapping_ = mapping_;
101  }
102 }
103 
105  if (mapping_ != nullptr) {
106  UnmapViewOfFile(mapping_);
107  }
108 }
109 
110 size_t FileMapping::GetSize() const {
111  return size_;
112 }
113 
114 const uint8_t* FileMapping::GetMapping() const {
115  return mapping_;
116 }
117 
118 bool FileMapping::IsValid() const {
119  return valid_;
120 }
121 
122 } // namespace fml
bool IsValid() const
~FileMapping() override
static bool IsWritable(std::initializer_list< FileMapping::Protection > protection_flags)
virtual ~Mapping()
const T & get() const
Definition: unique_object.h:87
Definition: ascii_trie.cc:9
bool is_valid() const
Definition: unique_object.h:89
static bool IsExecutable(std::initializer_list< FileMapping::Protection > protection_flags)
Definition: mapping_win.cc:33
FileMapping(const fml::UniqueFD &fd, std::initializer_list< Protection > protection={ Protection::kRead})
const uint8_t * GetMapping() const override
size_t GetSize() const override
#define FML_DLOG(severity)
Definition: logging.h:85
std::string GetLastErrorMessage()
Definition: errors_win.cc:15