[798] | 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 |
|
---|