Mercurial > libanimone
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 |
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 |