Mercurial > minori
diff dep/animone/src/util/win32.cc @ 258:862d0d8619f6
*: HUUUGE changes
animia has been renamed to animone, so instead of thinking of a
health condition, you think of a beautiful flower :)
I've also edited some of the code for animone, but I have no idea
if it even works or not because I don't have a mac or windows
machine lying around. whoops!
... anyway, all of the changes divergent from Anisthesia are now
licensed under BSD. it's possible that I could even rewrite most
of the code to where I don't even have to keep the MIT license,
but that's thinking too far into the future
I've been slacking off on implementing the anime seasons page,
mostly out of laziness. I think I'd have to create another db file
specifically for the seasons
anyway, this code is being pushed *primarily* because the hard drive
it's on is failing! yay :)
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Mon, 01 Apr 2024 02:43:44 -0400 |
parents | |
children | b1f625b0227c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dep/animone/src/util/win32.cc Mon Apr 01 02:43:44 2024 -0400 @@ -0,0 +1,102 @@ +#include "animone/util/win32.h" + +#include <shlobj.h> /* SHGetKnownFolderPath */ +#include <subauth.h> /* UNICODE_STRING */ +#include <windows.h> + +namespace animone::internal::win32 { + +std::string ToUtf8String(const std::wstring& string) { + if (string.empty()) + return std::string(); + + long size = ::WideCharToMultiByte(CP_UTF8, 0, string.c_str(), string.length(), nullptr, 0, nullptr, nullptr); + std::string ret(size, '\0'); + ::WideCharToMultiByte(CP_UTF8, 0, string.c_str(), string.length(), &ret.front(), ret.length(), nullptr, nullptr); + return ret; +} + +std::string ToUtf8String(const UNICODE_STRING& string) { + const auto wctomb = [&string](LPSTR out, int size) -> int { + return ::WideCharToMultiByte(CP_UTF8, 0, string.Buffer, string.Length, out, size, nullptr, nullptr); + }; + + if (string.Length <= 0) + return std::string(); + + long size = wctomb(nullptr, 0); + std::string ret(size, '\0'); + wctomb(&ret.front(), ret.length()); + return ret; +} + +std::wstring ToWstring(const std::string& string) { + const auto mbtowc = [&string](LPWSTR out, int size) -> int { + return ::MultiByteToWideChar(CP_UTF8, 0, string.c_str(), string.length(), out, size); + }; + + if (string.empty()) + return std::wstring(); + + long size = mbtowc(nullptr, 0); + std::wstring ret(size, L'\0'); + mbtowc(&ret.front(), ret.length()); + return ret; +} + +std::wstring GetProcessPath(DWORD process_id) { + // If we try to open a SYSTEM process, this function fails and the last error + // code is ERROR_ACCESS_DENIED. + // + // Note that if we requested PROCESS_QUERY_INFORMATION access right instead + // of PROCESS_QUERY_LIMITED_INFORMATION, this function would fail when used + // to open an elevated process. + Handle process_handle(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id)); + + if (!process_handle) + return std::wstring(); + + std::wstring buffer(MAX_PATH, L'\0'); + DWORD buf_size = buffer.length(); + + // Note that this function requires Windows Vista or above. You may use + // GetProcessImageFileName or GetModuleFileNameEx on earlier versions. + if (!::QueryFullProcessImageNameW(process_handle.get(), 0, &buffer.front(), &buf_size)) + return std::wstring(); + + buffer.resize(buf_size); + return buffer; +} + +std::wstring GetFileNameFromPath(const std::wstring& path) { + const auto pos = path.find_last_of(L"/\\"); + return pos != std::wstring::npos ? path.substr(pos + 1) : path; +} + +std::wstring GetFileNameWithoutExtension(const std::wstring& filename) { + const auto pos = filename.find_last_of(L"."); + return pos != std::wstring::npos ? filename.substr(0, pos) : filename; +} + +static std::wstring GetSystemDirectory() { + PWSTR path_wch; + SHGetKnownFolderPath(FOLDERID_Windows, 0, NULL, &path_wch); + std::wstring path_wstr(path_wch); + CoTaskMemFree(path_wch); + return path_wstr; +} + +bool IsSystemDirectory(const std::string& path) { + return IsSystemDirectory(ToWstring(path)); +} + +bool IsSystemDirectory(std::wstring path) { + ::CharUpperBuffW(&path.front(), path.length()); + + std::wstring windir = GetSystemDirectory(); + ::CharUpperBuffW(&windir.front(), windir.length()); + + return path.find(windir) == 4; +} + +} // namespace animone::internal::win32