Add handle abstractions
This commit is contained in:
parent
038ab2a4bb
commit
b3377fc092
@ -102,6 +102,69 @@ namespace utils::nt
|
||||
HMODULE module_;
|
||||
};
|
||||
|
||||
template <HANDLE InvalidHandle = nullptr>
|
||||
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);
|
||||
|
||||
|
@ -48,17 +48,12 @@ namespace utils::thread
|
||||
|
||||
std::vector<DWORD> get_thread_ids()
|
||||
{
|
||||
auto* const h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, GetCurrentProcessId());
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
nt::handle<INVALID_HANDLE_VALUE> 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<void(HANDLE)>& callback)
|
||||
void for_each_thread(const std::function<void(HANDLE)>& 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);
|
||||
}
|
||||
}
|
||||
|
@ -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<DWORD> get_thread_ids();
|
||||
void for_each_thread(const std::function<void(HANDLE)>& callback);
|
||||
void for_each_thread(const std::function<void(HANDLE)>& callback, DWORD access = THREAD_ALL_ACCESS);
|
||||
|
||||
void suspend_other_threads();
|
||||
void resume_other_threads();
|
||||
|
Loading…
Reference in New Issue
Block a user