annotate dep/animone/src/util/win32.cc @ 337:a7d4e5107531

dep/animone: REFACTOR ALL THE THINGS 1: animone now has its own syntax divergent from anisthesia, making different platforms actually have their own sections 2: process names in animone are now called `comm' (this will probably break things). this is what its called in bsd/linux so I'm just going to use it everywhere 3: the X11 code now checks for the existence of a UTF-8 window title and passes it if available 4: ANYTHING THATS NOT LINUX IS 100% UNTESTED AND CAN AND WILL BREAK! I still actually need to test the bsd code. to be honest I'm probably going to move all of the bsds into separate files because they're all essentially different operating systems at this point
author Paper <paper@paper.us.eu.org>
date Wed, 19 Jun 2024 12:51:15 -0400
parents a4257370de16
children 74e2365326c6
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
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
50 std::string GetProcessPath(DWORD process_id) {
301
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);
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
71 return ToUtf8String(buffer);
301
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
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
74 std::string GetFileNameFromPath(const std::string& path) {
301
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 static std::wstring GetSystemDirectory() {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
80 PWSTR path_wch;
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
81 SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, SHGFP_TYPE_CURRENT, &path_wch);
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
82 std::wstring path_wstr(path_wch);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
83 CoTaskMemFree(path_wch);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
84 return path_wstr;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
85 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
86
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
87 bool IsSystemDirectory(const std::string& path) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
88 return IsSystemDirectory(ToWstring(path));
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
89 }
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 bool IsSystemDirectory(std::wstring path) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
92 ::CharUpperBuffW(&path.front(), path.length());
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
93
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
94 std::wstring windir = GetSystemDirectory();
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
95 ::CharUpperBuffW(&windir.front(), windir.length());
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
96
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
97 // XXX wtf is 4?
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
98 return path.find(windir) == 4;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
99 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
100
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
101 bool VerifyProcessPath(const std::string& path) {
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
102 return !path.empty() && !IsSystemDirectory(path);
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
103 }
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
104
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
105 bool VerifyProcessFileName(const std::string& name) {
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
106 static const std::set<std::string> invalid_names = {
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
107 // System files
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
108 "explorer.exe", // Windows Explorer
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
109 "taskeng.exe", // Task Scheduler Engine
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
110 "taskhost.exe", // Host Process for Windows Tasks
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
111 "taskhostex.exe", // Host Process for Windows Tasks
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
112 "taskmgr.exe", // Task Manager
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
113 "services.exe", // Service Control Manager
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
114 };
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
115
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
116 if (name.empty())
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
117 return false;
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
118
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
119 for (const auto& invalid_name : invalid_names)
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
120 if (util::EqualStrings(name, invalid_name))
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
121 return false;
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
122
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
123 return true;
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
124 }
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
125
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
126 } // namespace animone::internal::win32