annotate dep/animone/src/util/win32.cc @ 327:b5d6c27c308f

anime: refactor Anime::SeriesSeason to Season class ToLocalString has also been altered to take in both season and year because lots of locales actually treat formatting seasons differently! most notably is Russian which adds a suffix at the end to notate seasons(??)
author Paper <paper@paper.us.eu.org>
date Thu, 13 Jun 2024 01:49:18 -0400
parents a4257370de16
children a7d4e5107531
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
310
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
1 /*
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
2 * util/win32.cc: utility functions only useful on windows
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
3 */
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
4 #include "animone/util/win32.h"
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
5
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
6 #include <shlobj.h> /* SHGetKnownFolderPath */
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
7 #include <subauth.h> /* UNICODE_STRING */
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
8 #include <windows.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
9
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
10 namespace animone::internal::win32 {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
11
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
12 std::string ToUtf8String(const std::wstring& string) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
13 if (string.empty())
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
14 return std::string();
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
15
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
16 long size = ::WideCharToMultiByte(CP_UTF8, 0, string.c_str(), string.length(), nullptr, 0, nullptr, nullptr);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
17 std::string ret(size, '\0');
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
18 ::WideCharToMultiByte(CP_UTF8, 0, string.c_str(), string.length(), &ret.front(), ret.length(), nullptr, nullptr);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
19 return ret;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
20 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
21
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
22 std::string ToUtf8String(const UNICODE_STRING& string) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
23 const auto wctomb = [&string](LPSTR out, int size) -> int {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
24 return ::WideCharToMultiByte(CP_UTF8, 0, string.Buffer, string.Length, out, size, nullptr, nullptr);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
25 };
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
26
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
27 if (string.Length <= 0)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
28 return std::string();
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
29
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
30 long size = wctomb(nullptr, 0);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
31 std::string ret(size, '\0');
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
32 wctomb(&ret.front(), ret.length());
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
33 return ret;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
34 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
35
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
36 std::wstring ToWstring(const std::string& string) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
37 const auto mbtowc = [&string](LPWSTR out, int size) -> int {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
38 return ::MultiByteToWideChar(CP_UTF8, 0, string.c_str(), string.length(), out, size);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
39 };
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
40
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
41 if (string.empty())
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
42 return std::wstring();
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
43
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
44 long size = mbtowc(nullptr, 0);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
45 std::wstring ret(size, L'\0');
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
46 mbtowc(&ret.front(), ret.length());
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
47 return ret;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
48 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
49
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
50 std::wstring GetProcessPath(DWORD process_id) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
51 // If we try to open a SYSTEM process, this function fails and the last error
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
52 // code is ERROR_ACCESS_DENIED.
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
53 //
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
54 // Note that if we requested PROCESS_QUERY_INFORMATION access right instead
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
55 // of PROCESS_QUERY_LIMITED_INFORMATION, this function would fail when used
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
56 // to open an elevated process.
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
57 Handle process_handle(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id));
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
58
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
59 if (!process_handle)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
60 return std::wstring();
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
61
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
62 std::wstring buffer(MAX_PATH, L'\0');
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
63 DWORD buf_size = buffer.length();
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
64
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
65 // Note that this function requires Windows Vista or above. You may use
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
66 // GetProcessImageFileName or GetModuleFileNameEx on earlier versions.
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
67 if (!::QueryFullProcessImageNameW(process_handle.get(), 0, &buffer.front(), &buf_size))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
68 return std::wstring();
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
69
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
70 buffer.resize(buf_size);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
71 return buffer;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
72 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
73
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
74 std::wstring GetFileNameFromPath(const std::wstring& path) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
75 const auto pos = path.find_last_of(L"/\\");
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
76 return pos != std::wstring::npos ? path.substr(pos + 1) : path;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
77 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
78
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
79 std::wstring GetFileNameWithoutExtension(const std::wstring& filename) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
80 const auto pos = filename.find_last_of(L".");
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
81 return pos != std::wstring::npos ? filename.substr(0, pos) : filename;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
82 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
83
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
84 static std::wstring GetSystemDirectory() {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
85 PWSTR path_wch;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
86 SHGetKnownFolderPath(FOLDERID_Windows, 0, NULL, &path_wch);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
87 std::wstring path_wstr(path_wch);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
88 CoTaskMemFree(path_wch);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
89 return path_wstr;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
90 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
91
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
92 bool IsSystemDirectory(const std::string& path) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
93 return IsSystemDirectory(ToWstring(path));
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
94 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
95
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
96 bool IsSystemDirectory(std::wstring path) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
97 ::CharUpperBuffW(&path.front(), path.length());
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
98
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
99 std::wstring windir = GetSystemDirectory();
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
100 ::CharUpperBuffW(&windir.front(), windir.length());
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
101
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
102 return path.find(windir) == 4;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
103 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
104
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
105 } // namespace animone::internal::win32