// Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "flutter/fml/mapping.h" #include #include #include #include #include "flutter/fml/file.h" #include "flutter/fml/platform/win/errors_win.h" #include "flutter/fml/platform/win/wstring_conversion.h" namespace fml { Mapping::Mapping() = default; Mapping::~Mapping() = default; static bool IsWritable( std::initializer_list protection_flags) { for (auto protection : protection_flags) { if (protection == FileMapping::Protection::kWrite) { return true; } } return false; } static bool IsExecutable( std::initializer_list protection_flags) { for (auto protection : protection_flags) { if (protection == FileMapping::Protection::kExecute) { return true; } } return false; } FileMapping::FileMapping(const fml::UniqueFD& fd, std::initializer_list protections) : size_(0), mapping_(nullptr) { if (!fd.is_valid()) { return; } const auto mapping_size = ::GetFileSize(fd.get(), nullptr); if (mapping_size == INVALID_FILE_SIZE) { FML_DLOG(ERROR) << "Invalid file size. " << GetLastErrorMessage(); return; } if (mapping_size == 0) { valid_ = true; return; } DWORD protect_flags = 0; bool read_only = !IsWritable(protections); if (IsExecutable(protections)) { protect_flags = PAGE_EXECUTE_READ; } else if (read_only) { protect_flags = PAGE_READONLY; } else { protect_flags = PAGE_READWRITE; } mapping_handle_.reset(::CreateFileMapping(fd.get(), // hFile nullptr, // lpAttributes protect_flags, // flProtect 0, // dwMaximumSizeHigh 0, // dwMaximumSizeLow nullptr // lpName )); if (!mapping_handle_.is_valid()) { return; } const DWORD desired_access = read_only ? FILE_MAP_READ : FILE_MAP_WRITE; auto mapping = reinterpret_cast( MapViewOfFile(mapping_handle_.get(), desired_access, 0, 0, mapping_size)); if (mapping == nullptr) { FML_DLOG(ERROR) << "Could not setup file mapping. " << GetLastErrorMessage(); return; } mapping_ = mapping; size_ = mapping_size; valid_ = true; if (IsWritable(protections)) { mutable_mapping_ = mapping_; } } FileMapping::~FileMapping() { if (mapping_ != nullptr) { UnmapViewOfFile(mapping_); } } size_t FileMapping::GetSize() const { return size_; } const uint8_t* FileMapping::GetMapping() const { return mapping_; } bool FileMapping::IsValid() const { return valid_; } } // namespace fml