1 | #include "stdafx.h"
|
---|
2 | #include "ProcessAndModule.h"
|
---|
3 | #include "OSVersion.h"
|
---|
4 |
|
---|
5 | #include <memory>
|
---|
6 | #include <psapi.h>
|
---|
7 | #include <tlhelp32.h>
|
---|
8 |
|
---|
9 | #pragma comment(lib, "psapi.lib")
|
---|
10 |
|
---|
11 | namespace ActiveBasic { namespace Common {
|
---|
12 |
|
---|
13 | struct HandleDeleter
|
---|
14 | {
|
---|
15 | typedef HANDLE pointer;
|
---|
16 |
|
---|
17 | void operator ()(pointer h) const
|
---|
18 | {
|
---|
19 | ::CloseHandle(h);
|
---|
20 | }
|
---|
21 | };
|
---|
22 |
|
---|
23 | typedef std::unique_ptr<HANDLE, HandleDeleter> UniqueHandle;
|
---|
24 |
|
---|
25 | boost::filesystem::path GetModuleFilePath(HANDLE hProcess, HMODULE hmod)
|
---|
26 | {
|
---|
27 | if (GetOSVersion().dwPlatformId == VER_PLATFORM_WIN32_NT)
|
---|
28 | {
|
---|
29 | WCHAR temp[MAX_PATH] = {};
|
---|
30 | if (::GetModuleFileNameExW(hProcess, hmod, temp, MAX_PATH) != 0)
|
---|
31 | {
|
---|
32 | return temp;
|
---|
33 | }
|
---|
34 | }
|
---|
35 | else
|
---|
36 | {
|
---|
37 | CHAR temp[MAX_PATH] = {};
|
---|
38 | if (::GetModuleFileNameA(hmod, temp, MAX_PATH) != 0)
|
---|
39 | {
|
---|
40 | return boost::filesystem::path(Jenga::Common::ToWString(temp));
|
---|
41 | }
|
---|
42 | }
|
---|
43 | throw std::runtime_error("GetModuleFileName or GetModuleFileNameEx failed");
|
---|
44 | }
|
---|
45 |
|
---|
46 | namespace {
|
---|
47 |
|
---|
48 | struct Toolhelp32Function
|
---|
49 | {
|
---|
50 | decltype(::CreateToolhelp32Snapshot)* pCreateToolhelp32Snapshot;
|
---|
51 | decltype(::Process32First)* pProcess32First;
|
---|
52 | decltype(::Process32Next)* pProcess32Next;
|
---|
53 | decltype(::Module32First)* pModule32First;
|
---|
54 | decltype(::Module32Next)* pModule32Next;
|
---|
55 | };
|
---|
56 |
|
---|
57 | Toolhelp32Function const& GetToolhelp32Function(HMODULE hmodKernel)
|
---|
58 | {
|
---|
59 | static Toolhelp32Function const tf =
|
---|
60 | {
|
---|
61 | reinterpret_cast<decltype(::CreateToolhelp32Snapshot)*>(::GetProcAddress(hmodKernel, "CreateToolhelp32Snapshot")),
|
---|
62 | reinterpret_cast<decltype(::Process32First)*>(::GetProcAddress(hmodKernel, "Process32First")),
|
---|
63 | reinterpret_cast<decltype(::Process32Next)*>(::GetProcAddress(hmodKernel, "Process32Next")),
|
---|
64 | reinterpret_cast<decltype(::Module32First)*>(::GetProcAddress(hmodKernel, "Module32First")),
|
---|
65 | reinterpret_cast<decltype(::Module32Next)*>(::GetProcAddress(hmodKernel, "Module32Next")),
|
---|
66 | };
|
---|
67 | return tf;
|
---|
68 | }
|
---|
69 |
|
---|
70 | UniqueHandle CreateToolhelp32SnapshotHelper(Toolhelp32Function const& tf, DWORD flags, DWORD processId = 0)
|
---|
71 | {
|
---|
72 | UniqueHandle h(tf.pCreateToolhelp32Snapshot(flags, processId));
|
---|
73 | if (h.get() == INVALID_HANDLE_VALUE)
|
---|
74 | {
|
---|
75 | h.release();
|
---|
76 | return UniqueHandle();
|
---|
77 | }
|
---|
78 | return h;
|
---|
79 | }
|
---|
80 |
|
---|
81 | } // unnamed namespace
|
---|
82 |
|
---|
83 | std::vector<DWORD> GetProcesses()
|
---|
84 | {
|
---|
85 | auto const& tf = GetToolhelp32Function(::GetModuleHandle(TEXT("kernel32")));
|
---|
86 | if (tf.pCreateToolhelp32Snapshot)
|
---|
87 | {
|
---|
88 | UniqueHandle h = CreateToolhelp32SnapshotHelper(tf, TH32CS_SNAPPROCESS);
|
---|
89 | if (h == nullptr)
|
---|
90 | {
|
---|
91 | return std::vector<DWORD>();
|
---|
92 | }
|
---|
93 | std::vector<DWORD> processes;
|
---|
94 | PROCESSENTRY32 pe = {sizeof pe};
|
---|
95 | if (tf.pProcess32First(h.get(), &pe))
|
---|
96 | {
|
---|
97 | do
|
---|
98 | {
|
---|
99 | processes.push_back(pe.th32ProcessID);
|
---|
100 | } while (tf.pProcess32Next(h.get(), &pe));
|
---|
101 | }
|
---|
102 | return processes;
|
---|
103 | }
|
---|
104 | else
|
---|
105 | {
|
---|
106 | std::vector<DWORD> processes(8192);
|
---|
107 | DWORD cbNeeded = 0;
|
---|
108 | if (EnumProcesses(processes.data(), processes.size() * sizeof (DWORD), &cbNeeded))
|
---|
109 | {
|
---|
110 | processes.resize(cbNeeded / sizeof (DWORD));
|
---|
111 | return processes;
|
---|
112 | }
|
---|
113 | return std::vector<DWORD>();
|
---|
114 | }
|
---|
115 | }
|
---|
116 |
|
---|
117 | boost::filesystem::path GetExecutableModulePath(DWORD processId)
|
---|
118 | {
|
---|
119 | if (ActiveBasic::Common::Is9x())
|
---|
120 | {
|
---|
121 | auto const& tf = GetToolhelp32Function(::GetModuleHandle(TEXT("kernel32")));
|
---|
122 | UniqueHandle h = CreateToolhelp32SnapshotHelper(tf, TH32CS_SNAPMODULE, processId);
|
---|
123 | if (h == nullptr)
|
---|
124 | {
|
---|
125 | return boost::filesystem::path();
|
---|
126 | }
|
---|
127 | MODULEENTRY32 me = {sizeof me};
|
---|
128 | if (tf.pModule32First(h.get(), &me))
|
---|
129 | {
|
---|
130 | return boost::filesystem::path(me.szExePath);
|
---|
131 | }
|
---|
132 | else
|
---|
133 | {
|
---|
134 | return boost::filesystem::path();
|
---|
135 | }
|
---|
136 | }
|
---|
137 | else
|
---|
138 | {
|
---|
139 | UniqueHandle hProcess(::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId));
|
---|
140 | // PSAPIが使える環境はそちらを優先。
|
---|
141 | WCHAR filename[MAX_PATH] = {};
|
---|
142 | ::GetModuleFileNameExW(hProcess.get(), nullptr, filename, MAX_PATH);
|
---|
143 | return boost::filesystem::path(filename);
|
---|
144 | }
|
---|
145 | }
|
---|
146 |
|
---|
147 | std::vector<HMODULE> GetModules(DWORD processId)
|
---|
148 | {
|
---|
149 | auto const& tf = GetToolhelp32Function(::GetModuleHandle(TEXT("kernel32")));
|
---|
150 | if (tf.pCreateToolhelp32Snapshot)
|
---|
151 | {
|
---|
152 | UniqueHandle h = CreateToolhelp32SnapshotHelper(tf, TH32CS_SNAPMODULE, processId);
|
---|
153 | if (h == nullptr)
|
---|
154 | {
|
---|
155 | return std::vector<HMODULE>();
|
---|
156 | }
|
---|
157 | std::vector<HMODULE> modules;
|
---|
158 | MODULEENTRY32 me = {sizeof me};
|
---|
159 | if (tf.pModule32First(h.get(), &me))
|
---|
160 | {
|
---|
161 | do
|
---|
162 | {
|
---|
163 | modules.push_back(me.hModule);
|
---|
164 | } while (tf.pModule32Next(h.get(), &me));
|
---|
165 | }
|
---|
166 | return modules;
|
---|
167 | }
|
---|
168 | else
|
---|
169 | {
|
---|
170 | UniqueHandle hProcess(::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId));
|
---|
171 | const DWORD MAX_MODULE = 1024;
|
---|
172 | std::vector<HMODULE> module(MAX_MODULE);
|
---|
173 | DWORD cbReturned = 0;
|
---|
174 | EnumProcessModules(hProcess.get(), module.data(), sizeof (HMODULE) * MAX_MODULE, &cbReturned);
|
---|
175 | module.resize(cbReturned / sizeof (HMODULE));
|
---|
176 | return module;
|
---|
177 | }
|
---|
178 | }
|
---|
179 |
|
---|
180 | }}
|
---|
181 |
|
---|