From dca49e73e50fdc5b4140af7a1366bbb6b143dbbd Mon Sep 17 00:00:00 2001 From: Double Sine Date: Mon, 14 Jan 2019 15:13:44 +0800 Subject: [PATCH] Add FileMapper.hpp --- navicat-patcher/FileMapper.hpp | 96 ++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 navicat-patcher/FileMapper.hpp diff --git a/navicat-patcher/FileMapper.hpp b/navicat-patcher/FileMapper.hpp new file mode 100644 index 0000000..03340eb --- /dev/null +++ b/navicat-patcher/FileMapper.hpp @@ -0,0 +1,96 @@ +#include "Exceptions.hpp" +#include "ResourceGuardWin32.hpp" +#include +#include + +#if defined(UNICODE) || defined(_UNICODE) +using String = std::wstring; +#else +using String = std::string; +#endif + +namespace Patcher { + + class FileMapper { + private: + ResourceGuard _FileHandle; + ResourceGuard _FileMapHandle; + ResourceGuard _FileView; + public: + + static bool IsExist(const String&& FilePath) { + DWORD dwAttr = GetFileAttributes(FilePath.c_str()); + if (dwAttr == INVALID_FILE_ATTRIBUTES) { + if (GetLastError() == ERROR_FILE_NOT_FOUND) + return false; + else + throw SystemError(__BASE_FILE__, __LINE__, GetLastError(), + "GetFileAttributes fails."); + } else { + return (dwAttr & FILE_ATTRIBUTE_DIRECTORY) == 0; + } + } + + template + _Type* GetView() const noexcept { + return reinterpret_cast<_Type*>(_FileView.GetHandle()); + } + + void MapFile(const String& FileName) noexcept { + ResourceGuard TempFileHandle; + ResourceGuard TempFileMapHandle; + ResourceGuard TempFileView; + + TempFileHandle.TakeHoldOf( + CreateFile(FileName.c_str(), + GENERIC_READ | GENERIC_WRITE, + NULL, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL) + ); + if (TempFileHandle.IsValid() == false) + throw SystemError(__BASE_FILE__, __LINE__, GetLastError(), + "CreateFile fails."); + + TempFileMapHandle.TakeHoldOf( + CreateFileMapping(TempFileHandle, + NULL, + PAGE_READWRITE, + 0, + 0, + NULL) + ); + if (TempFileMapHandle.IsValid() == false) + throw SystemError(__BASE_FILE__, __LINE__, GetLastError(), + "CreateFileMapping fails."); + + TempFileView.TakeHoldOf( + MapViewOfFile(TempFileMapHandle, + FILE_MAP_READ | FILE_MAP_WRITE, + 0, + 0, + 0) + ); + if (TempFileView.IsValid() == false) + throw SystemError(__BASE_FILE__, __LINE__, GetLastError(), + "MapViewOfFile fails."); + + _FileView.Release(); + _FileView = std::move(TempFileView); + _FileMapHandle.Release(); + _FileMapHandle = std::move(TempFileMapHandle); + _FileHandle.Release(); + _FileHandle = std::move(TempFileHandle); + } + + void Release() { + _FileView.Release(); + _FileMapHandle.Release(); + _FileHandle.Release(); + } + }; + +} +