diff --git a/src/common/utils/nt.hpp b/src/common/utils/nt.hpp index 86001bea..dce0cbf1 100644 --- a/src/common/utils/nt.hpp +++ b/src/common/utils/nt.hpp @@ -102,6 +102,69 @@ namespace utils::nt HMODULE module_; }; + template + class handle + { + public: + handle() = default; + + handle(const HANDLE h) + : handle_(h) + { + } + + ~handle() + { + if (*this) + { + CloseHandle(this->handle_); + this->handle_ = InvalidHandle; + } + } + + handle(const handle&) = delete; + handle& operator=(const handle&) = delete; + + handle(handle&& obj) noexcept + : handle() + { + this->operator=(std::move(obj)); + } + + handle& operator=(handle&& obj) noexcept + { + if (this != &obj) + { + this->~handle(); + this->handle_ = obj.handle_; + obj.handle_ = InvalidHandle; + } + + return *this; + } + + handle& operator=(HANDLE h) noexcept + { + this->~handle(); + this->handle_ = h; + + return *this; + } + + operator bool() const + { + return this->handle_ != InvalidHandle; + } + + operator HANDLE() const + { + return this->handle_; + } + + private: + HANDLE handle_{InvalidHandle}; + }; + __declspec(noreturn) void raise_hard_exception(); std::string load_resource(int id); diff --git a/src/common/utils/thread.cpp b/src/common/utils/thread.cpp index 714704b6..cb3eeacd 100644 --- a/src/common/utils/thread.cpp +++ b/src/common/utils/thread.cpp @@ -48,17 +48,12 @@ namespace utils::thread std::vector get_thread_ids() { - auto* const h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, GetCurrentProcessId()); - if (h == INVALID_HANDLE_VALUE) + nt::handle h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, GetCurrentProcessId()); + if (!h) { return {}; } - const auto _ = utils::finally([h]() - { - CloseHandle(h); - }); - THREADENTRY32 entry{}; entry.dwSize = sizeof(entry); if (!Thread32First(h, &entry)) @@ -84,20 +79,15 @@ namespace utils::thread return ids; } - void for_each_thread(const std::function& callback) + void for_each_thread(const std::function& callback, const DWORD access) { const auto ids = get_thread_ids(); for (const auto& id : ids) { - auto* const thread = OpenThread(THREAD_ALL_ACCESS, FALSE, id); - if (thread != nullptr) + handle thread(id, access); + if (thread) { - const auto _ = utils::finally([thread]() - { - CloseHandle(thread); - }); - callback(thread); } } diff --git a/src/common/utils/thread.hpp b/src/common/utils/thread.hpp index 4ea3598c..dfdf1d65 100644 --- a/src/common/utils/thread.hpp +++ b/src/common/utils/thread.hpp @@ -17,8 +17,30 @@ namespace utils::thread return t; } + class handle + { + public: + handle(const DWORD thread_id, const DWORD access = THREAD_ALL_ACCESS) + : handle_(OpenThread(access, FALSE, thread_id)) + { + } + + operator bool() const + { + return this->handle_; + } + + operator HANDLE() const + { + return this->handle_; + } + + private: + nt::handle<> handle_{}; + }; + std::vector get_thread_ids(); - void for_each_thread(const std::function& callback); + void for_each_thread(const std::function& callback, DWORD access = THREAD_ALL_ACCESS); void suspend_other_threads(); void resume_other_threads();