Mercurial > libanimone
annotate src/util/win32.cc @ 22:bc22d57076e3
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 | 973734ebd2be |
children | 1cfa7d57c022 |
rev | line source |
---|---|
19
6596be6917a1
dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents:
14
diff
changeset
|
1 /* |
6596be6917a1
dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents:
14
diff
changeset
|
2 * util/win32.cc: utility functions only useful on windows |
6596be6917a1
dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents:
14
diff
changeset
|
3 */ |
14
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
4 #include "animone/util/win32.h" |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
5 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
6 #include <shlobj.h> /* SHGetKnownFolderPath */ |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
7 #include <subauth.h> /* UNICODE_STRING */ |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
8 #include <windows.h> |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
9 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
10 namespace animone::internal::win32 { |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
11 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
12 std::string ToUtf8String(const std::wstring& string) { |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
13 if (string.empty()) |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
14 return std::string(); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
15 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
16 long size = ::WideCharToMultiByte(CP_UTF8, 0, string.c_str(), string.length(), nullptr, 0, nullptr, nullptr); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
17 std::string ret(size, '\0'); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
18 ::WideCharToMultiByte(CP_UTF8, 0, string.c_str(), string.length(), &ret.front(), ret.length(), nullptr, nullptr); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
19 return ret; |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
20 } |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
21 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
22 std::string ToUtf8String(const UNICODE_STRING& string) { |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
23 const auto wctomb = [&string](LPSTR out, int size) -> int { |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
24 return ::WideCharToMultiByte(CP_UTF8, 0, string.Buffer, string.Length, out, size, nullptr, nullptr); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
25 }; |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
26 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
27 if (string.Length <= 0) |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
28 return std::string(); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
29 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
30 long size = wctomb(nullptr, 0); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
31 std::string ret(size, '\0'); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
32 wctomb(&ret.front(), ret.length()); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
33 return ret; |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
34 } |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
35 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
36 std::wstring ToWstring(const std::string& string) { |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
37 const auto mbtowc = [&string](LPWSTR out, int size) -> int { |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
38 return ::MultiByteToWideChar(CP_UTF8, 0, string.c_str(), string.length(), out, size); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
39 }; |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
40 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
41 if (string.empty()) |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
42 return std::wstring(); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
43 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
44 long size = mbtowc(nullptr, 0); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
45 std::wstring ret(size, L'\0'); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
46 mbtowc(&ret.front(), ret.length()); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
47 return ret; |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
48 } |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
49 |
21
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
50 std::string GetProcessPath(DWORD process_id) { |
14
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
51 // If we try to open a SYSTEM process, this function fails and the last error |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
52 // code is ERROR_ACCESS_DENIED. |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
53 // |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
54 // Note that if we requested PROCESS_QUERY_INFORMATION access right instead |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
55 // of PROCESS_QUERY_LIMITED_INFORMATION, this function would fail when used |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
56 // to open an elevated process. |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
57 Handle process_handle(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id)); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
58 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
59 if (!process_handle) |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
60 return std::wstring(); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
61 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
62 std::wstring buffer(MAX_PATH, L'\0'); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
63 DWORD buf_size = buffer.length(); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
64 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
65 // Note that this function requires Windows Vista or above. You may use |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
66 // GetProcessImageFileName or GetModuleFileNameEx on earlier versions. |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
67 if (!::QueryFullProcessImageNameW(process_handle.get(), 0, &buffer.front(), &buf_size)) |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
68 return std::wstring(); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
69 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
70 buffer.resize(buf_size); |
21
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
71 return ToUtf8String(buffer); |
14
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
72 } |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
73 |
21
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
74 std::string GetFileNameFromPath(const std::string& path) { |
14
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
75 const auto pos = path.find_last_of(L"/\\"); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
76 return pos != std::wstring::npos ? path.substr(pos + 1) : path; |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
77 } |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
78 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
79 static std::wstring GetSystemDirectory() { |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
80 PWSTR path_wch; |
21
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
81 SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, SHGFP_TYPE_CURRENT, &path_wch); |
14
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
82 std::wstring path_wstr(path_wch); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
83 CoTaskMemFree(path_wch); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
84 return path_wstr; |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
85 } |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
86 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
87 bool IsSystemDirectory(const std::string& path) { |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
88 return IsSystemDirectory(ToWstring(path)); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
89 } |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
90 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
91 bool IsSystemDirectory(std::wstring path) { |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
92 ::CharUpperBuffW(&path.front(), path.length()); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
93 |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
94 std::wstring windir = GetSystemDirectory(); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
95 ::CharUpperBuffW(&windir.front(), windir.length()); |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
96 |
21
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
97 // XXX wtf is 4? |
14
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
98 return path.find(windir) == 4; |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
99 } |
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
100 |
21
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
101 bool VerifyProcessPath(const std::string& path) { |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
102 return !path.empty() && !IsSystemDirectory(path); |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
103 } |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
104 |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
105 bool VerifyProcessFileName(const std::string& name) { |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
106 static const std::set<std::string> invalid_names = { |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
107 // System files |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
108 "explorer.exe", // Windows Explorer |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
109 "taskeng.exe", // Task Scheduler Engine |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
110 "taskhost.exe", // Host Process for Windows Tasks |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
111 "taskhostex.exe", // Host Process for Windows Tasks |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
112 "taskmgr.exe", // Task Manager |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
113 "services.exe", // Service Control Manager |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
114 }; |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
115 |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
116 if (name.empty()) |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
117 return false; |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
118 |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
119 for (const auto& invalid_name : invalid_names) |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
120 if (util::EqualStrings(name, invalid_name)) |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
121 return false; |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
122 |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
123 return true; |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
124 } |
973734ebd2be
dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents:
19
diff
changeset
|
125 |
14
27b988a1048c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
0
diff
changeset
|
126 } // namespace animone::internal::win32 |