annotate src/util/win32.cc @ 21:973734ebd2be

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 6596be6917a1
children 1cfa7d57c022
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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