Mercurial > minori
comparison dep/animone/src/fd/win32.cc @ 342:adb79bdde329
dep/animone: fix tons of issues
for example, the window ID stuff was just... completely wrong. since we're
supporting multiple different window systems, it *has* to be a union rather
than just a single integer type. HWND is also not a DWORD, it's a pointer(!),
so now it's stored as a std::uintptr_t.
(this probably breaks things)
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Thu, 20 Jun 2024 03:03:05 -0400 |
parents | 74e2365326c6 |
children | 1faa72660932 |
comparison
equal
deleted
inserted
replaced
341:052ec053ee37 | 342:adb79bdde329 |
---|---|
10 * even guaranteed to work far into the future. however, just like with macOS, these | 10 * even guaranteed to work far into the future. however, just like with macOS, these |
11 * things have stayed the same since Vista so if Microsoft *really* wants compatibility | 11 * things have stayed the same since Vista so if Microsoft *really* wants compatibility |
12 * then they're pretty much forced to keeping this the same anyway. | 12 * then they're pretty much forced to keeping this the same anyway. |
13 */ | 13 */ |
14 #include "animone/fd/win32.h" | 14 #include "animone/fd/win32.h" |
15 #include "animone/util.h" | |
15 #include "animone.h" | 16 #include "animone.h" |
16 #include "animone/util/win32.h" | 17 #include "animone/util/win32.h" |
17 | 18 |
18 #include <stdexcept> | 19 #include <stdexcept> |
19 #include <string> | 20 #include <string> |
20 #include <unordered_map> | 21 #include <unordered_map> |
21 #include <vector> | 22 #include <vector> |
23 #include <optional> | |
22 | 24 |
23 #include <fileapi.h> | 25 #include <fileapi.h> |
24 #include <handleapi.h> | 26 #include <handleapi.h> |
25 #include <libloaderapi.h> | 27 #include <libloaderapi.h> |
26 #include <ntdef.h> | 28 #include <ntdef.h> |
139 } | 141 } |
140 | 142 |
141 /* ------------------------------------------------------------------- */ | 143 /* ------------------------------------------------------------------- */ |
142 | 144 |
143 static bool GetSystemDirectory(std::wstring& str) { | 145 static bool GetSystemDirectory(std::wstring& str) { |
144 PWSTR path_wch; | 146 str.assign(MAX_PATH, '\0'); |
145 | 147 |
146 if (FAILED(::SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, SHGFP_TYPE_CURRENT, &path_wch))) | 148 return SUCCEEDED(::SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, SHGFP_TYPE_CURRENT, &str.front())); |
147 return false; | |
148 | |
149 str.assign(path_wch); | |
150 | |
151 ::CoTaskMemFree(path_wch); | |
152 return true; | |
153 } | |
154 | |
155 static bool IsSystemDirectory(const std::string& path) { | |
156 return IsSystemDirectory(ToWstring(path)); | |
157 } | 149 } |
158 | 150 |
159 static bool IsSystemDirectory(std::wstring path) { | 151 static bool IsSystemDirectory(std::wstring path) { |
160 std::wstring windir; | 152 std::wstring windir; |
161 if (!GetSystemDirectory(windir)) | 153 if (!GetSystemDirectory(windir)) |
164 ::CharUpperBuffW(&path.front(), path.length()); | 156 ::CharUpperBuffW(&path.front(), path.length()); |
165 ::CharUpperBuffW(&windir.front(), windir.length()); | 157 ::CharUpperBuffW(&windir.front(), windir.length()); |
166 | 158 |
167 // XXX wtf is 4? | 159 // XXX wtf is 4? |
168 return path.find(windir) == 4; | 160 return path.find(windir) == 4; |
161 } | |
162 | |
163 static bool IsSystemDirectory(const std::string& path) { | |
164 return IsSystemDirectory(ToWstring(path)); | |
169 } | 165 } |
170 | 166 |
171 static bool IsFileHandle(HANDLE handle, unsigned short object_type_index) { | 167 static bool IsFileHandle(HANDLE handle, unsigned short object_type_index) { |
172 /* this is filled in at runtime because it's not guaranteed to be (and isn't) | 168 /* this is filled in at runtime because it's not guaranteed to be (and isn't) |
173 * constant between different versions of Windows */ | 169 * constant between different versions of Windows */ |
177 return object_type_index == file_type_index.value(); | 173 return object_type_index == file_type_index.value(); |
178 } else if (!handle) { | 174 } else if (!handle) { |
179 /* XXX what? */ | 175 /* XXX what? */ |
180 return true; | 176 return true; |
181 } else if (GetHandleType(handle) == L"File") { | 177 } else if (GetHandleType(handle) == L"File") { |
182 file_type_index.reset(object_type_index); | 178 file_type_index = object_type_index; |
183 return true; | 179 return true; |
184 } | 180 } |
185 | 181 |
186 return false; | 182 return false; |
187 } | 183 } |
210 return true; | 206 return true; |
211 } | 207 } |
212 | 208 |
213 /* ------------------------------------------------------------------- */ | 209 /* ------------------------------------------------------------------- */ |
214 | 210 |
215 static std::string GetProcessPath(DWORD process_id) { | 211 static bool GetProcessPath(DWORD process_id, std::string& path) { |
216 // If we try to open a SYSTEM process, this function fails and the last error | 212 // If we try to open a SYSTEM process, this function fails and the last error |
217 // code is ERROR_ACCESS_DENIED. | 213 // code is ERROR_ACCESS_DENIED. |
218 // | 214 // |
219 // Note that if we requested PROCESS_QUERY_INFORMATION access right instead | 215 // Note that if we requested PROCESS_QUERY_INFORMATION access right instead |
220 // of PROCESS_QUERY_LIMITED_INFORMATION, this function would fail when used | 216 // of PROCESS_QUERY_LIMITED_INFORMATION, this function would fail when used |
221 // to open an elevated process. | 217 // to open an elevated process. |
222 Handle process_handle(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id)); | 218 Handle process_handle(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id)); |
223 | 219 |
224 if (!process_handle) | 220 if (!process_handle) |
225 return std::wstring(); | 221 return false; |
226 | 222 |
227 std::wstring buffer(MAX_PATH, L'\0'); | 223 std::wstring buffer(MAX_PATH, L'\0'); |
228 DWORD buf_size = buffer.length(); | 224 DWORD buf_size = buffer.length(); |
229 | 225 |
230 // Note that this function requires Windows Vista or above. You may use | 226 // Note that this function requires Windows Vista or above. You may use |
231 // GetProcessImageFileName or GetModuleFileNameEx on earlier versions. | 227 // GetProcessImageFileName or GetModuleFileNameEx on earlier versions. |
232 if (!::QueryFullProcessImageNameW(process_handle.get(), 0, &buffer.front(), &buf_size)) | 228 if (!::QueryFullProcessImageNameW(process_handle.get(), 0, &buffer.front(), &buf_size)) |
233 return std::wstring(); | 229 return false; |
234 | 230 |
235 buffer.resize(buf_size); | 231 buffer.resize(buf_size); |
236 return ToUtf8String(buffer); | 232 path = ToUtf8String(buffer); |
233 return true; | |
237 } | 234 } |
238 | 235 |
239 static std::string GetFilenameFromPath(const std::string& path) { | 236 static std::string GetFilenameFromPath(const std::string& path) { |
240 const auto pos = path.find_last_of(L"/\\"); | 237 const auto pos = path.find_last_of("/\\"); |
241 return pos != std::wstring::npos ? path.substr(pos + 1) : path; | 238 return pos != std::wstring::npos ? path.substr(pos + 1) : path; |
242 } | 239 } |
243 | 240 |
244 static bool VerifyProcessPath(const std::string& path) { | 241 static bool VerifyProcessPath(const std::string& path) { |
245 return !path.empty() && !IsSystemDirectory(path); | 242 return !path.empty() && !IsSystemDirectory(path); |
268 | 265 |
269 /* ------------------------------------------------------------------- */ | 266 /* ------------------------------------------------------------------- */ |
270 /* extern functions */ | 267 /* extern functions */ |
271 | 268 |
272 bool GetProcessName(pid_t pid, std::string& name) { | 269 bool GetProcessName(pid_t pid, std::string& name) { |
273 std::string path = GetProcessPath(pid); | 270 if (!GetProcessPath(pid, name) || !VerifyProcessPath(name)) |
274 if (path.empty() || !VerifyProcessPath(path)) | 271 return false; |
275 return false; | 272 |
276 | 273 name = GetFilenameFromPath(name); |
277 name = GetFilenameFromPath(path); | |
278 if (!VerifyProcessFilename(name)) | 274 if (!VerifyProcessFilename(name)) |
279 return false; | 275 return false; |
280 | 276 |
281 return true; | 277 return true; |
282 } | 278 } |
295 do { | 291 do { |
296 std::string name; | 292 std::string name; |
297 if (!GetProcessName(pe32.th32ProcessID, name)) | 293 if (!GetProcessName(pe32.th32ProcessID, name)) |
298 continue; | 294 continue; |
299 | 295 |
300 if (!process_proc({.platform = ExecutablePlatform::Win32, .pid = pe32.th32ProcessID, .comm = name})) | 296 if (!process_proc({.pid = pe32.th32ProcessID, .platform = ExecutablePlatform::Win32, .comm = name})) |
301 return false; | 297 return false; |
302 } while (::Process32Next(process_snap.get(), &pe32)); | 298 } while (::Process32Next(process_snap.get(), &pe32)); |
303 | 299 |
304 return true; | 300 return true; |
305 } | 301 } |