258
|
1 #include "animone/util/win32.h"
|
|
2
|
|
3 #include <shlobj.h> /* SHGetKnownFolderPath */
|
|
4 #include <subauth.h> /* UNICODE_STRING */
|
|
5 #include <windows.h>
|
|
6
|
|
7 namespace animone::internal::win32 {
|
|
8
|
|
9 std::string ToUtf8String(const std::wstring& string) {
|
|
10 if (string.empty())
|
|
11 return std::string();
|
|
12
|
|
13 long size = ::WideCharToMultiByte(CP_UTF8, 0, string.c_str(), string.length(), nullptr, 0, nullptr, nullptr);
|
|
14 std::string ret(size, '\0');
|
|
15 ::WideCharToMultiByte(CP_UTF8, 0, string.c_str(), string.length(), &ret.front(), ret.length(), nullptr, nullptr);
|
|
16 return ret;
|
|
17 }
|
|
18
|
|
19 std::string ToUtf8String(const UNICODE_STRING& string) {
|
|
20 const auto wctomb = [&string](LPSTR out, int size) -> int {
|
|
21 return ::WideCharToMultiByte(CP_UTF8, 0, string.Buffer, string.Length, out, size, nullptr, nullptr);
|
|
22 };
|
|
23
|
|
24 if (string.Length <= 0)
|
|
25 return std::string();
|
|
26
|
|
27 long size = wctomb(nullptr, 0);
|
|
28 std::string ret(size, '\0');
|
|
29 wctomb(&ret.front(), ret.length());
|
|
30 return ret;
|
|
31 }
|
|
32
|
|
33 std::wstring ToWstring(const std::string& string) {
|
|
34 const auto mbtowc = [&string](LPWSTR out, int size) -> int {
|
|
35 return ::MultiByteToWideChar(CP_UTF8, 0, string.c_str(), string.length(), out, size);
|
|
36 };
|
|
37
|
|
38 if (string.empty())
|
|
39 return std::wstring();
|
|
40
|
|
41 long size = mbtowc(nullptr, 0);
|
|
42 std::wstring ret(size, L'\0');
|
|
43 mbtowc(&ret.front(), ret.length());
|
|
44 return ret;
|
|
45 }
|
|
46
|
|
47 std::wstring GetProcessPath(DWORD process_id) {
|
|
48 // If we try to open a SYSTEM process, this function fails and the last error
|
|
49 // code is ERROR_ACCESS_DENIED.
|
|
50 //
|
|
51 // Note that if we requested PROCESS_QUERY_INFORMATION access right instead
|
|
52 // of PROCESS_QUERY_LIMITED_INFORMATION, this function would fail when used
|
|
53 // to open an elevated process.
|
|
54 Handle process_handle(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id));
|
|
55
|
|
56 if (!process_handle)
|
|
57 return std::wstring();
|
|
58
|
|
59 std::wstring buffer(MAX_PATH, L'\0');
|
|
60 DWORD buf_size = buffer.length();
|
|
61
|
|
62 // Note that this function requires Windows Vista or above. You may use
|
|
63 // GetProcessImageFileName or GetModuleFileNameEx on earlier versions.
|
|
64 if (!::QueryFullProcessImageNameW(process_handle.get(), 0, &buffer.front(), &buf_size))
|
|
65 return std::wstring();
|
|
66
|
|
67 buffer.resize(buf_size);
|
|
68 return buffer;
|
|
69 }
|
|
70
|
|
71 std::wstring GetFileNameFromPath(const std::wstring& path) {
|
|
72 const auto pos = path.find_last_of(L"/\\");
|
|
73 return pos != std::wstring::npos ? path.substr(pos + 1) : path;
|
|
74 }
|
|
75
|
|
76 std::wstring GetFileNameWithoutExtension(const std::wstring& filename) {
|
|
77 const auto pos = filename.find_last_of(L".");
|
|
78 return pos != std::wstring::npos ? filename.substr(0, pos) : filename;
|
|
79 }
|
|
80
|
|
81 static std::wstring GetSystemDirectory() {
|
|
82 PWSTR path_wch;
|
|
83 SHGetKnownFolderPath(FOLDERID_Windows, 0, NULL, &path_wch);
|
|
84 std::wstring path_wstr(path_wch);
|
|
85 CoTaskMemFree(path_wch);
|
|
86 return path_wstr;
|
|
87 }
|
|
88
|
|
89 bool IsSystemDirectory(const std::string& path) {
|
|
90 return IsSystemDirectory(ToWstring(path));
|
|
91 }
|
|
92
|
|
93 bool IsSystemDirectory(std::wstring path) {
|
|
94 ::CharUpperBuffW(&path.front(), path.length());
|
|
95
|
|
96 std::wstring windir = GetSystemDirectory();
|
|
97 ::CharUpperBuffW(&windir.front(), windir.length());
|
|
98
|
|
99 return path.find(windir) == 4;
|
|
100 }
|
|
101
|
|
102 } // namespace animone::internal::win32
|