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