1+ #include " resource.h"
12#ifndef __WIL_TOOLHELP32_INCLUDED
23#define __WIL_TOOLHELP32_INCLUDED
34#include < TlHelp32.h>
5+ #include < processthreadsapi.h>
46namespace wil
57{
6- namespace details
7- {
8+ namespace details
9+ {
10+ template <typename TEntry, typename TEnumApi, typename TCallback>
11+ void do_enum_snapshot (HANDLE handle, TEntry& entry, TEnumApi&& enumApiFirst, TEnumApi&& enumApiNext, TCallback&& callback)
12+ {
13+ using result_t = decltype (callback (TEntry{}));
14+ bool enumResult = enumApiFirst (handle, &entry);
15+ if (!enumResult)
16+ return ;
817
9- }
18+ do
19+ {
20+ if constexpr (wistd::is_void_v<result_t >)
21+ {
22+ callback (entry);
23+ }
24+ else if constexpr (wistd::is_same_v<result_t , bool >)
25+ {
26+ if (callback (entry))
27+ return ;
28+ }
29+ else
30+ {
31+ static_assert (
32+ [] {
33+ return false ;
34+ }(),
35+ " Callback must return void or bool" );
36+ }
37+ enumResult = enumApiNext (handle, &entry);
38+ } while (enumResult);
39+ }
40+ } // namespace details
1041
11- template <typename TCallback>
12- void for_each_process (TCallback&& /* callback*/ )
13- {
42+ template <typename TCallback>
43+ void for_each_process (TCallback&& callback)
44+ {
45+ PROCESSENTRY32 entry{};
46+ entry.dwSize = sizeof (entry);
47+ details::do_enum_snapshot (
48+ unique_handle{CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )}.get (),
49+ entry,
50+ &Process32First,
51+ &Process32Next,
52+ wistd::forward<TCallback>(callback));
53+ }
1454
15- }
55+ template <typename TCallback>
56+ void for_each_thread (TCallback&& callback)
57+ {
58+ THREADENTRY32 entry{};
59+ entry.dwSize = sizeof (entry);
60+ details::do_enum_snapshot (
61+ unique_handle{CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, 0 )}.get (),
62+ entry,
63+ &Thread32First,
64+ &Thread32Next,
65+ wistd::forward<TCallback>(callback));
66+ }
1667
17- template <typename TCallback>
18- void for_each_thread (TCallback&& /* callback*/ )
19- {
68+ template <typename TCallback>
69+ void for_each_module (TCallback&& callback, bool include32For64Bit = false )
70+ {
71+ MODULEENTRY32 entry{};
72+ entry.dwSize = sizeof (entry);
73+ details::do_enum_snapshot (
74+ unique_handle{CreateToolhelp32Snapshot (include32For64Bit ? TH32CS_SNAPMODULE32 : TH32CS_SNAPMODULE, 0 )}.get (),
75+ entry,
76+ &Module32First,
77+ &Module32Next,
78+ wistd::forward<TCallback>(callback));
79+ }
2080
21- }
81+ template <typename TCallback>
82+ void for_each_heap_list (TCallback&& callback)
83+ {
84+ HEAPLIST32 entry{};
85+ entry.dwSize = sizeof (entry);
86+ details::do_enum_snapshot (
87+ unique_handle{CreateToolhelp32Snapshot (TH32CS_SNAPHEAPLIST, 0 )}.get (),
88+ entry,
89+ &Heap32ListFirst,
90+ &Heap32ListNext,
91+ wistd::forward<TCallback>(callback));
92+ }
2293
23- template <typename TCallback>
24- void for_each_module (TCallback&& /* callback*/ )
25- {
94+ template <typename TCallback>
95+ void for_each_heap (TCallback&& callback, ULONG_PTR heapId, DWORD pid = GetCurrentProcessId())
96+ {
97+ using result_t = decltype (callback (HEAPENTRY32{}));
2698
27- }
99+ HEAPENTRY32 entry{};
100+ entry.dwSize = sizeof (entry);
28101
29- template <typename TCallback>
30- void for_each_heap (TCallback&& /* callback*/ )
31- {
102+ bool enumResult = Heap32First (&entry, pid, heapId);
103+ do
104+ {
105+ if constexpr (wistd::is_void_v<result_t >)
106+ {
107+ callback (entry);
108+ }
109+ else if constexpr (wistd::is_same_v<result_t , bool >)
110+ {
111+ if (callback (entry))
112+ return ;
113+ }
114+ else
115+ {
116+ static_assert (
117+ [] {
118+ return false ;
119+ }(),
120+ " Callback must return void or bool" );
121+ }
122+ enumResult = Heap32Next (&entry);
123+ } while (enumResult);
124+ }
32125
33- }
126+ template <typename TCallback>
127+ void for_each_heap (TCallback&& callback, HEAPLIST32 const & heapList, DWORD pid = GetCurrentProcessId())
128+ {
129+ for_each_heap (wistd::forward<TCallback>(callback), heapList.th32HeapID , pid);
34130}
131+ } // namespace wil
35132
36133#endif
0 commit comments