/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #include "MemMappedFileInternal.hpp" #include "Base/Logger.hpp" #include "Host/Windows/ErrorUtils.hpp" namespace OpenVulkano { #ifdef _MSC_VER MemMappedFileInternal::MemMappedFileInternal(const char* file, MemMappedFile::FileMode fileMode) : size(0), fileHandle(nullptr), fileMappingHandle(nullptr) { DWORD openMode { 0 }, mapMode { 0 }, viewMode { 0 }; switch (fileMode) { case MemMappedFile::FileMode::READ_ONLY: openMode = GENERIC_READ; mapMode = PAGE_READONLY; viewMode = FILE_MAP_READ; break; case MemMappedFile::FileMode::WRITE_ONLY: openMode = GENERIC_WRITE; mapMode = PAGE_READWRITE; viewMode = FILE_MAP_WRITE; break; case MemMappedFile::FileMode::READ_WRITE: openMode = GENERIC_ALL; mapMode = PAGE_READWRITE; viewMode = FILE_MAP_ALL_ACCESS; break; default: break; } fileHandle = CreateFileA(file, // file to open openMode, // open for switch case NULL, // share mode NULL, // default security OPEN_ALWAYS, // always FILE_ATTRIBUTE_NORMAL, // normal file NULL); // no attribute template if (fileHandle == INVALID_HANDLE_VALUE || fileHandle == NULL) { Logger::FILESYS->critical("Failed to open file: {}.", ErrorUtils::GetLastErrorMessage()); return; } LARGE_INTEGER fileSize; if (!GetFileSizeEx(fileHandle, &fileSize)) { Logger::FILESYS->critical("Failed to get size of file: {}", ErrorUtils::GetLastErrorMessage()); CloseHandle(fileHandle); return; } size = fileSize.QuadPart; fileMappingHandle = CreateFileMappingA(fileHandle, NULL, // default security mapMode, // mod for switch case 0, // maximum object size (high-order) 0, // maximum object size (low-order) NULL); // name of the mapping object if (fileMappingHandle == INVALID_HANDLE_VALUE || fileMappingHandle == NULL) { Logger::FILESYS->critical("Failed to create file mapping handle: {}", ErrorUtils::GetLastErrorMessage()); CloseHandle(fileHandle); size = 0; return; } address = MapViewOfFile(fileMappingHandle, // handle to the map object viewMode, // access for switch case 0, // max. object size 0, // size of the hFile 0); // map the entire file if (address == nullptr) { Logger::FILESYS->critical("Failed to create file mapping: {}", ErrorUtils::GetLastErrorMessage()); CloseHandle(fileMappingHandle); CloseHandle(fileHandle); size = 0; } } MemMappedFileInternal::~MemMappedFileInternal() { UnmapViewOfFile(address); CloseHandle(fileMappingHandle); CloseHandle(fileHandle); } #else MemMappedFileInternal::MemMappedFileInternal(const char* file, MemMappedFile::FileMode fileMode) { fileHandle = open(file, fileMode); if (fstat(fileHandle, &fileStat) == -1) { Logger::FILESYS->critical("Failed to query stats for file: {}", file); return; } address = mmap(nullptr, fileStat.st_size, fileMode + 1, MAP_SHARED, fileHandle, 0); if (address == MAP_FAILED) { Logger::FILESYS->critical("Failed to memory map file: {}", file); address = nullptr; } size = fileStat.st_size; } MemMappedFileInternal::~MemMappedFileInternal() { munmap(address, fileStat.st_size); close(fileHandle); } #endif }