#include "WinFctHelper.hpp" #if YYCC_OS == YYCC_OS_WINDOWS #include "EncodingHelper.hpp" #include "COMHelper.hpp" namespace YYCC::WinFctHelper { HMODULE GetCurrentModule() { // Reference: https://stackoverflow.com/questions/557081/how-do-i-get-the-hmodule-for-the-currently-executing-code HMODULE hModule = NULL; ::GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, // get address and do not inc ref counter. (LPCWSTR)GetCurrentModule, &hModule); return hModule; } bool GetTempDirectory(yycc_u8string& ret) { // create wchar buffer for receiving the temp path. std::wstring wpath(MAX_PATH + 1u, L'\0'); DWORD expected_size; // fetch temp folder while (true) { if ((expected_size = ::GetTempPathW(static_cast<DWORD>(wpath.size()), wpath.data())) == 0) { // failed, set to empty return false; } if (expected_size > static_cast<DWORD>(wpath.size())) { // buffer is too short, need enlarge and do fetching again wpath.resize(expected_size); } else { // ok. shrink to real length, break while break; } } // resize result wpath.resize(expected_size); // convert to utf8 and return return YYCC::EncodingHelper::WcharToUTF8(wpath, ret); } bool GetModuleFileName(HINSTANCE hModule, yycc_u8string& ret) { // create wchar buffer for receiving the temp path. std::wstring wpath(MAX_PATH + 1u, L'\0'); DWORD copied_size; while (true) { if ((copied_size = ::GetModuleFileNameW(hModule, wpath.data(), static_cast<DWORD>(wpath.size()))) == 0) { // failed, return return false; } // check insufficient buffer if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // buffer is not enough, enlarge it and try again. wpath.resize(wpath.size() + MAX_PATH); } else { // ok, break while break; } } // resize result wpath.resize(copied_size); // convert to utf8 and return return YYCC::EncodingHelper::WcharToUTF8(wpath, ret); } bool GetLocalAppData(yycc_u8string& ret) { // check whether com initialized if (!COMHelper::IsInitialized()) return false; // fetch path LPWSTR _known_path; HRESULT hr = SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_CREATE, NULL, &_known_path); if (FAILED(hr)) return false; COMHelper::SmartLPWSTR known_path(_known_path); // convert to utf8 return YYCC::EncodingHelper::WcharToUTF8(known_path.get(), ret); } bool IsValidCodePage(UINT code_page) { CPINFOEXW cpinfo; return ::GetCPInfoExW(code_page, 0, &cpinfo); } BOOL CopyFile(const yycc_u8string_view& lpExistingFileName, const yycc_u8string_view& lpNewFileName, BOOL bFailIfExists) { std::wstring wExistingFileName, wNewFileName; if (!YYCC::EncodingHelper::UTF8ToWchar(lpExistingFileName, wExistingFileName)) return FALSE; if (!YYCC::EncodingHelper::UTF8ToWchar(lpNewFileName, wNewFileName)) return FALSE; return ::CopyFileW(wExistingFileName.c_str(), wNewFileName.c_str(), bFailIfExists); } BOOL MoveFile(const yycc_u8string_view& lpExistingFileName, const yycc_u8string_view& lpNewFileName) { std::wstring wExistingFileName, wNewFileName; if (!YYCC::EncodingHelper::UTF8ToWchar(lpExistingFileName, wExistingFileName)) return FALSE; if (!YYCC::EncodingHelper::UTF8ToWchar(lpNewFileName, wNewFileName)) return FALSE; return ::MoveFileW(wExistingFileName.c_str(), wNewFileName.c_str()); } BOOL DeleteFile(const yycc_u8string_view& lpFileName) { std::wstring wFileName; if (!YYCC::EncodingHelper::UTF8ToWchar(lpFileName, wFileName)) return FALSE; return ::DeleteFileW(wFileName.c_str()); } } #endif