Mercurial > minori
view dep/animone/src/util/win32.cc @ 338:f63dfa309380
dep/animone: separate *BSD into separate files
they are wholly different operating systems with very different
kernels on the inside
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Wed, 19 Jun 2024 13:06:10 -0400 |
parents | a7d4e5107531 |
children | 74e2365326c6 |
line wrap: on
line source
/* * util/win32.cc: utility functions only useful on windows */ #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::string 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 ToUtf8String(buffer); } std::string GetFileNameFromPath(const std::string& path) { const auto pos = path.find_last_of(L"/\\"); return pos != std::wstring::npos ? path.substr(pos + 1) : path; } static std::wstring GetSystemDirectory() { PWSTR path_wch; SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, SHGFP_TYPE_CURRENT, &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()); // XXX wtf is 4? return path.find(windir) == 4; } bool VerifyProcessPath(const std::string& path) { return !path.empty() && !IsSystemDirectory(path); } bool VerifyProcessFileName(const std::string& name) { static const std::set<std::string> invalid_names = { // System files "explorer.exe", // Windows Explorer "taskeng.exe", // Task Scheduler Engine "taskhost.exe", // Host Process for Windows Tasks "taskhostex.exe", // Host Process for Windows Tasks "taskmgr.exe", // Task Manager "services.exe", // Service Control Manager }; if (name.empty()) return false; for (const auto& invalid_name : invalid_names) if (util::EqualStrings(name, invalid_name)) return false; return true; } } // namespace animone::internal::win32