Add handle abstractions
This commit is contained in:
parent
038ab2a4bb
commit
b3377fc092
@ -102,6 +102,69 @@ namespace utils::nt
|
|||||||
HMODULE module_;
|
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();
|
__declspec(noreturn) void raise_hard_exception();
|
||||||
std::string load_resource(int id);
|
std::string load_resource(int id);
|
||||||
|
|
||||||
|
@ -48,17 +48,12 @@ namespace utils::thread
|
|||||||
|
|
||||||
std::vector<DWORD> get_thread_ids()
|
std::vector<DWORD> get_thread_ids()
|
||||||
{
|
{
|
||||||
auto* const h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, GetCurrentProcessId());
|
nt::handle<INVALID_HANDLE_VALUE> h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, GetCurrentProcessId());
|
||||||
if (h == INVALID_HANDLE_VALUE)
|
if (!h)
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto _ = utils::finally([h]()
|
|
||||||
{
|
|
||||||
CloseHandle(h);
|
|
||||||
});
|
|
||||||
|
|
||||||
THREADENTRY32 entry{};
|
THREADENTRY32 entry{};
|
||||||
entry.dwSize = sizeof(entry);
|
entry.dwSize = sizeof(entry);
|
||||||
if (!Thread32First(h, &entry))
|
if (!Thread32First(h, &entry))
|
||||||
@ -84,20 +79,15 @@ namespace utils::thread
|
|||||||
return ids;
|
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();
|
const auto ids = get_thread_ids();
|
||||||
|
|
||||||
for (const auto& id : ids)
|
for (const auto& id : ids)
|
||||||
{
|
{
|
||||||
auto* const thread = OpenThread(THREAD_ALL_ACCESS, FALSE, id);
|
handle thread(id, access);
|
||||||
if (thread != nullptr)
|
if (thread)
|
||||||
{
|
{
|
||||||
const auto _ = utils::finally([thread]()
|
|
||||||
{
|
|
||||||
CloseHandle(thread);
|
|
||||||
});
|
|
||||||
|
|
||||||
callback(thread);
|
callback(thread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,30 @@ namespace utils::thread
|
|||||||
return t;
|
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();
|
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 suspend_other_threads();
|
||||||
void resume_other_threads();
|
void resume_other_threads();
|
||||||
|
Loading…
Reference in New Issue
Block a user