diff options
| author | Yuqian Yang <crupest@crupest.life> | 2025-11-15 16:43:25 +0800 |
|---|---|---|
| committer | Yuqian Yang <crupest@crupest.life> | 2025-11-16 00:01:49 +0800 |
| commit | 246eb9266b9349b44cbe96f3f839124ab30cbb89 (patch) | |
| tree | 31604c8a4764d3a601d56599e56c98d91bd97758 /include/cru/base/platform/win/Base.h | |
| parent | b92aa78ac19476049ab881b49c51b1a970a4a973 (diff) | |
| download | cru-246eb9266b9349b44cbe96f3f839124ab30cbb89.tar.gz cru-246eb9266b9349b44cbe96f3f839124ab30cbb89.tar.bz2 cru-246eb9266b9349b44cbe96f3f839124ab30cbb89.zip | |
Impl win subprocess.
Diffstat (limited to 'include/cru/base/platform/win/Base.h')
| -rw-r--r-- | include/cru/base/platform/win/Base.h | 113 |
1 files changed, 106 insertions, 7 deletions
diff --git a/include/cru/base/platform/win/Base.h b/include/cru/base/platform/win/Base.h index 83420461..8d221c83 100644 --- a/include/cru/base/platform/win/Base.h +++ b/include/cru/base/platform/win/Base.h @@ -5,6 +5,10 @@ #endif #include "../../Base.h" +#include "../../Bitmask.h" + +#include <optional> +#include <string_view> #define NOMINMAX #define WIN32_LEAN_AND_MEAN @@ -17,8 +21,7 @@ namespace cru::platform::win { class CRU_BASE_API HResultError : public Exception { public: - explicit HResultError(HRESULT h_result); - HResultError(HRESULT h_result, std::string_view message); + explicit HResultError(HRESULT h_result, std::string_view message = ""); HRESULT GetHResult() const { return h_result_; } @@ -26,16 +29,14 @@ class CRU_BASE_API HResultError : public Exception { HRESULT h_result_; }; -inline void ThrowIfFailed(const HRESULT h_result) { - if (FAILED(h_result)) throw HResultError(h_result); -} - -inline void ThrowIfFailed(const HRESULT h_result, std::string_view message) { +inline void CheckHResult(const HRESULT h_result, + std::string_view message = "") { if (FAILED(h_result)) throw HResultError(h_result, message); } class CRU_BASE_API Win32Error : public Exception { public: + Win32Error(); // ::GetLastError is automatically called to get the error code. // The same as Win32Error(::GetLastError(), message) explicit Win32Error(std::string_view message); @@ -46,4 +47,102 @@ class CRU_BASE_API Win32Error : public Exception { private: DWORD error_code_; }; + +inline void CheckWinReturn(BOOL r, std::string_view message = "") { + if (r == FALSE) { + throw Win32Error(message); + } +} + +template <typename H, void (*CloseFunc)(H handle) noexcept> +class CRU_BASE_API TWin32Handle { + public: + TWin32Handle() : handle_(std::nullopt), auto_close_(false) {} + + TWin32Handle(H handle, bool auto_close) + : handle_(handle), auto_close_(auto_close) {} + + CRU_DELETE_COPY(TWin32Handle) + + TWin32Handle(TWin32Handle&& other) noexcept + : handle_(other.handle_), auto_close_(other.auto_close_) { + other.handle_ = std::nullopt; + other.auto_close_ = false; + } + + TWin32Handle& operator=(TWin32Handle&& other) noexcept { + if (this != &other) { + DoClose(); + handle_ = other.handle_; + auto_close_ = other.auto_close_; + other.handle_ = std::nullopt; + other.auto_close_ = false; + } + return *this; + } + + ~TWin32Handle() { DoClose(); } + + public: + bool IsValid() const { return handle_.has_value(); } + + void CheckValid( + std::optional<std::string_view> additional_message = std::nullopt) const { + if (!IsValid()) { + std::string message("The win32 handle is invalid."); + if (additional_message) { + message += " "; + message += *additional_message; + } + throw Exception(std::move(message)); + } + } + + H Get() const { + CheckValid(); + return *handle_; + } + + H Release() { + CheckValid(); + auto handle = *handle_; + handle_ = std::nullopt; + auto_close_ = false; + return handle; + } + + private: + void DoClose() { + if (auto_close_ && handle_) { + CloseFunc(*handle_); + } + } + + private: + std::optional<H> handle_; + bool auto_close_; +}; + +namespace details { +inline void MyCloseHandle(HANDLE handle) noexcept { ::CloseHandle(handle); } +} // namespace details + +using Win32Handle = TWin32Handle<HANDLE, details::MyCloseHandle>; + +struct UniDirectionalWin32PipeResult { + Win32Handle read; + Win32Handle write; +}; + +namespace details { +struct Win32PipeFlagTag; +} +using Win32PipeFlag = Bitmask<details::Win32PipeFlagTag>; +struct Win32PipeFlags { + constexpr static auto ReadInheritable = Win32PipeFlag::FromOffset(1); + constexpr static auto WriteInheritable = Win32PipeFlag::FromOffset(2); +}; + +CRU_BASE_API UniDirectionalWin32PipeResult +OpenUniDirectionalPipe(Win32PipeFlag flag = {}); } // namespace cru::platform::win |
