Flutter Engine
The 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
17namespace fml {
18
19Mapping::Mapping() = default;
20
21Mapping::~Mapping() = default;
22
23static 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
33static 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 set up 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
104FileMapping::~FileMapping() {
105 if (mapping_ != nullptr) {
106 UnmapViewOfFile(mapping_);
107 }
108}
109
110size_t FileMapping::GetSize() const {
111 return size_;
112}
113
114const uint8_t* FileMapping::GetMapping() const {
115 return mapping_;
116}
117
118bool FileMapping::IsDontNeedSafe() const {
119 return mutable_mapping_ == nullptr;
120}
121
122bool FileMapping::IsValid() const {
123 return valid_;
124}
125
126} // namespace fml
FileMapping(const fml::UniqueFD &fd, std::initializer_list< Protection > protection={ Protection::kRead})
virtual ~Mapping()
bool is_valid() const
Definition: unique_object.h:89
const T & get() const
Definition: unique_object.h:87
#define FML_DLOG(severity)
Definition: logging.h:102
Definition: ascii_trie.cc:9
static bool IsExecutable(std::initializer_list< FileMapping::Protection > protection_flags)
Definition: mapping_win.cc:33
static bool IsWritable(std::initializer_list< FileMapping::Protection > protection_flags)
std::string GetLastErrorMessage()
Definition: errors_win.cc:15
#define ERROR(message)
Definition: elf_loader.cc:260
unsigned long DWORD
Definition: windows_types.h:22