annotate dep/animone/src/fd/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 * fd/win32.cc: support for 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 *
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
4 * this file is noticably more complex than *nix, and that's because
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
5 * there is no "simple" way to get the paths of a file. In fact, this thing requires
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
6 * you to use *internal functions* that can't even be linked to, hence why we have to
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
7 * use GetProcAddress and such. what a mess.
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
8 *
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
9 * Speaking of which, because this file uses internal functions of the OS, it is not
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
10 * even guaranteed to work far into the future. however, just like with macOS, these
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
11 * things have stayed the same since Vista so if Microsoft *really* wants compatibility
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
12 * then they're pretty much forced to keeping this the same anyway.
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
13 */
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
14 #include "animone/fd/win32.h"
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
15 #include "animone.h"
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
16 #include "animone/util/win32.h"
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
17
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
18 #include <stdexcept>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
19 #include <string>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
20 #include <unordered_map>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
21 #include <vector>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
22
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
23 #include <fileapi.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
24 #include <handleapi.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
25 #include <libloaderapi.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
26 #include <ntdef.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
27 #include <psapi.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
28 #include <shlobj.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
29 #include <stringapiset.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
30 #include <tlhelp32.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
31 #include <windows.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
32 #include <winternl.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
33
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
34 /* SystemExtendedHandleInformation is only available in NT 5.1+ (XP and higher) and provides information for
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
35 * 32-bit PIDs, unlike SystemHandleInformation
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
36 */
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
37 static constexpr SYSTEM_INFORMATION_CLASS SystemExtendedHandleInformation = static_cast<SYSTEM_INFORMATION_CLASS>(0x40);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
38 static constexpr NTSTATUS STATUS_INFO_LENGTH_MISMATCH = 0xC0000004UL;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
39
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
40 /* this is filled in at runtime because it's not guaranteed to be (and isn't)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
41 * constant between different versions of Windows */
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
42 static unsigned short file_type_index = 0;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
43
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
44 struct SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
45 PVOID Object;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
46 ULONG_PTR UniqueProcessId;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
47 HANDLE HandleValue;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
48 ACCESS_MASK GrantedAccess;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
49 USHORT CreatorBackTraceIndex;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
50 USHORT ObjectTypeIndex;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
51 ULONG HandleAttributes;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
52 ULONG Reserved;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
53 };
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
54
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
55 struct SYSTEM_HANDLE_INFORMATION_EX {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
56 ULONG_PTR NumberOfHandles;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
57 ULONG_PTR Reserved;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
58 SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1];
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
59 };
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
60
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
61 namespace animone::internal::win32 {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
62
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
63 class Ntdll {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
64 public:
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
65 Ntdll() {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
66 ntdll = ::GetModuleHandleW(L"ntdll.dll");
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
67 nt_query_system_information = reinterpret_cast<decltype(::NtQuerySystemInformation)*>(
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
68 ::GetProcAddress(ntdll, "NtQuerySystemInformation"));
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
69 nt_query_object = reinterpret_cast<decltype(::NtQueryObject)*>(::GetProcAddress(ntdll, "NtQueryObject"));
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
70 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
71
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
72 NTSTATUS QuerySystemInformation(SYSTEM_INFORMATION_CLASS cls, PVOID sysinfo, ULONG len,
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
73 PULONG retlen){
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
74 return nt_query_system_information(cls, sysinfo, len, retlen);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
75 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
76
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
77 NTSTATUS QueryObject(HANDLE handle, OBJECT_INFORMATION_CLASS cls, PVOID objinf, ULONG objinflen, PULONG retlen) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
78 return nt_query_object(handle, cls, objinf, objinflen, retlen);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
79 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
80
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
81 private:
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
82 HMODULE ntdll;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
83 decltype(::NtQuerySystemInformation)* nt_query_system_information;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
84 decltype(::NtQueryObject)* nt_query_object;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
85 };
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
86
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
87 Ntdll ntdll;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
88
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
89 static HANDLE DuplicateHandle(HANDLE process_handle, HANDLE handle) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
90 HANDLE dup_handle = nullptr;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
91 const bool result =
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
92 ::DuplicateHandle(process_handle, handle, ::GetCurrentProcess(), &dup_handle, 0, false, DUPLICATE_SAME_ACCESS);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
93 return result ? dup_handle : nullptr;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
94 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
95
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
96 static std::vector<SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX> GetSystemHandleInformation() {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
97 /* we should really put a cap on this */
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
98 ULONG cb = 1 << 19;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
99 NTSTATUS status = STATUS_NO_MEMORY;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
100 std::unique_ptr<SYSTEM_HANDLE_INFORMATION_EX> info;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
101
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
102 do {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
103 info.reset(reinterpret_cast<SYSTEM_HANDLE_INFORMATION_EX*>(malloc(cb *= 2)));
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
104 if (!info)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
105 continue;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
106
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
107 status = ntdll.QuerySystemInformation(SystemExtendedHandleInformation, info.get(), cb, &cb);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
108 } while (status == STATUS_INFO_LENGTH_MISMATCH);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
109
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
110 if (!NT_SUCCESS(status))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
111 return {};
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
112
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
113 std::vector<SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX> res;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
114
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
115 ULONG_PTR handles = info->NumberOfHandles;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
116 if (!handles)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
117 return {};
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
118
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
119 res.reserve(handles);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
120
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
121 SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX* entry = info->Handles;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
122 do {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
123 if (entry)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
124 res.push_back(*(entry++));
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
125 } while (--handles);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
126
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
127 return res;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
128 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
129
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
130 static std::wstring GetHandleType(HANDLE handle) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
131 OBJECT_TYPE_INFORMATION info = {0};
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
132 ntdll.QueryObject(handle, ObjectTypeInformation, &info, sizeof(info), NULL);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
133 return std::wstring(info.TypeName.Buffer, info.TypeName.Length);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
134 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
135
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
136 static std::wstring GetFinalPathNameByHandle(HANDLE handle) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
137 std::wstring buffer;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
138
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
139 DWORD size = ::GetFinalPathNameByHandleW(handle, NULL, 0, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
140 buffer.resize(size);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
141 ::GetFinalPathNameByHandleW(handle, &buffer.front(), buffer.size(), FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
142
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
143 return buffer;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
144 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
145
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
146 static bool IsFileHandle(HANDLE handle, unsigned short object_type_index) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
147 if (file_type_index)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
148 return object_type_index == file_type_index;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
149 else if (!handle)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
150 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
151 else if (GetHandleType(handle) == L"File") {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
152 file_type_index = object_type_index;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
153 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
154 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
155 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
156 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
157
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
158 static bool IsFileMaskOk(ACCESS_MASK access_mask) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
159 if (!(access_mask & FILE_READ_DATA))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
160 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
161
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
162 if ((access_mask & FILE_APPEND_DATA) || (access_mask & FILE_WRITE_EA) || (access_mask & FILE_WRITE_ATTRIBUTES))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
163 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
164
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
165 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
166 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
167
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
168 static bool IsFilePathOk(const std::wstring& path) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
169 if (path.empty())
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
170 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
171
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
172 if (IsSystemDirectory(path))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
173 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
174
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
175 const auto file_attributes = GetFileAttributesW(path.c_str());
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
176 if ((file_attributes == INVALID_FILE_ATTRIBUTES) || (file_attributes & FILE_ATTRIBUTE_DIRECTORY))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
177 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
178
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
179 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
180 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
181
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
182 bool GetProcessName(pid_t pid, std::string& name) {
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
183 std::string path = GetProcessPath(pid);
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
184 if (path.empty() || !VerifyProcessPath(path))
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
185 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
186
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
187 name = GetFileNameFromPath(path);
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
188 if (!VerifyProcessFileName(name))
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
189 return false;
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
190
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
191 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
192 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
193
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
194 bool EnumerateOpenProcesses(process_proc_t process_proc) {
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
195 Handle process_snap(::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
196 if (process_snap.get() == INVALID_HANDLE_VALUE)
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
197 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
198
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
199 PROCESSENTRY32 pe32;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
200 pe32.dwSize = sizeof(PROCESSENTRY32);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
201
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
202 if (!::Process32First(process_snap.get(), &pe32))
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
203 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
204
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
205 do {
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
206 std::string name;
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
207 if (!GetProcessName(pe32.th32ProcessID, name))
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
208 continue;
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
209
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
210 if (!process_proc({.platform = ExecutablePlatform::Win32, .pid = pe32.th32ProcessID, .comm = name}))
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
211 return false;
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
212 } while (::Process32Next(process_snap.get(), &pe32));
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
213
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
214 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
215 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
216
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
217 /* this could be changed to being a callback, but... I'm too lazy right now :) */
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
218 bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
219 if (!open_file_proc)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
220 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
221
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
222 std::unordered_map<pid_t, Handle> proc_handles;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
223
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
224 for (const pid_t& pid : pids) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
225 const HANDLE handle = ::OpenProcess(PROCESS_DUP_HANDLE, false, pid);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
226 if (handle != INVALID_HANDLE_VALUE)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
227 proc_handles[pid] = Handle(handle);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
228 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
229
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
230 if (proc_handles.empty())
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
231 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
232
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
233 std::vector<SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX> info = GetSystemHandleInformation();
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
234
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
235 for (const auto& h : info) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
236 const pid_t pid = h.UniqueProcessId;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
237 if (!pids.count(pid))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
238 continue;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
239
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
240 if (!IsFileHandle(nullptr, h.ObjectTypeIndex))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
241 continue;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
242
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
243 if (!IsFileMaskOk(h.GrantedAccess))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
244 continue;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
245
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
246 Handle handle(DuplicateHandle(proc_handles[pid].get(), h.HandleValue));
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
247 if (handle.get() == INVALID_HANDLE_VALUE)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
248 continue;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
249
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
250 if (GetFileType(handle.get()) != FILE_TYPE_DISK)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
251 continue;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
252
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
253 const std::wstring path = GetFinalPathNameByHandle(handle.get());
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
254 if (!IsFilePathOk(path))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
255 continue;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
256
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
257 if (!open_file_proc({pid, ToUtf8String(path)}))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
258 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
259 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
260
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
261 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
262 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
263
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 285
diff changeset
264 } // namespace animone::internal::win32