diff --git a/src/libipc/platform/win/mmap_impl.h b/src/libipc/platform/win/api.h similarity index 72% rename from src/libipc/platform/win/mmap_impl.h rename to src/libipc/platform/win/api.h index de73f14..45f94e3 100644 --- a/src/libipc/platform/win/mmap_impl.h +++ b/src/libipc/platform/win/api.h @@ -1,35 +1,85 @@ /** - * \file libipc/platform/win/mmap_impl.h + * \file libipc/platform/win/api.h * \author mutouyun (orz@orzz.org) */ #pragma once +#include +#include +#include + #include #include -#include - #include "libimp/log.h" #include "libimp/system.h" +#include "libimp/codecvt.h" -#include "libipc/shm.h" - -#include "get_sa.h" -#include "to_tchar.h" -#include "close_handle.h" +#include "libipc/def.h" LIBIPC_NAMESPACE_BEG_ - using namespace ::LIBIMP; -struct shm_handle { - std::string file; - std::size_t f_sz; - void *memp; - HANDLE h_fmap; -}; +namespace winapi { -namespace { +using tstring = std::basic_string; + +inline tstring to_tstring(std::string const &str) { + tstring des; + ::LIBIMP::cvt_sstr(str, des); + return des; +} + +/** + * \brief Create a SECURITY_ATTRIBUTES structure singleton + * \see https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa379560(v=vs.85) + */ +inline LPSECURITY_ATTRIBUTES get_sa() { + static struct initiator { + + SECURITY_DESCRIPTOR sd_; + SECURITY_ATTRIBUTES sa_; + + bool succ_ = false; + + initiator() { + using namespace ::LIBIMP; + LIBIMP_LOG_("get_sa"); + if (!::InitializeSecurityDescriptor(&sd_, SECURITY_DESCRIPTOR_REVISION)) { + log.error("failed: InitializeSecurityDescriptor(SECURITY_DESCRIPTOR_REVISION). " + "error = ", sys::error()); + return; + } + if (!::SetSecurityDescriptorDacl(&sd_, TRUE, NULL, FALSE)) { + log.error("failed: SetSecurityDescriptorDacl. error = ", sys::error()); + return; + } + sa_.nLength = sizeof(SECURITY_ATTRIBUTES); + sa_.bInheritHandle = FALSE; + sa_.lpSecurityDescriptor = &sd_; + succ_ = true; + } + } handle; + return handle.succ_ ? &handle.sa_ : nullptr; +} + +/** + * \brief Closes an open object handle. + * \see https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle + */ +inline result close_handle(HANDLE h) noexcept { + LIBIMP_LOG_(); + if (h == NULL) { + log.error("handle is null."); + return std::make_error_code(std::errc::invalid_argument); + } + if (!::CloseHandle(h)) { + auto err = sys::error(); + log.error("failed: CloseHandle(", h, "). error = ", err); + return err; + } + return std::error_code{}; +} /** * \brief Creates or opens a file mapping object for a specified file. @@ -50,7 +100,7 @@ result mmap_open(std::string const &file, std::size_t size, mode::type t log.error("file name is empty."); return std::make_error_code(std::errc::invalid_argument); } - auto t_name = detail::to_tstring(file); + auto t_name = winapi::to_tstring(file); if (t_name.empty()) { log.error("file name is empty. (TCHAR conversion failed)"); return std::make_error_code(std::errc::invalid_argument); @@ -69,7 +119,7 @@ result mmap_open(std::string const &file, std::size_t size, mode::type t // Creates or opens a named or unnamed file mapping object for a specified file. auto try_create = [&]() -> result { - HANDLE h = ::CreateFileMapping(INVALID_HANDLE_VALUE, detail::get_sa(), PAGE_READWRITE | SEC_COMMIT, + HANDLE h = ::CreateFileMapping(INVALID_HANDLE_VALUE, winapi::get_sa(), PAGE_READWRITE | SEC_COMMIT, /// \remark dwMaximumSizeHigh always 0 here. 0, static_cast(size), t_name.c_str()); if (h == NULL) { @@ -161,5 +211,5 @@ result mmap_release(HANDLE h, LPCVOID mem) { return winapi::close_handle(h); } -} // namespace +} // namespace winapi LIBIPC_NAMESPACE_END_ diff --git a/src/libipc/platform/win/close_handle.h b/src/libipc/platform/win/close_handle.h deleted file mode 100644 index b7c51e7..0000000 --- a/src/libipc/platform/win/close_handle.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * \file libipc/platform/win/close_handle.h - * \author mutouyun (orz@orzz.org) - */ -#pragma once - -#include - -#include "libimp/log.h" -#include "libimp/system.h" - -#include "libipc/def.h" - -LIBIPC_NAMESPACE_BEG_ -using namespace ::LIBIMP; - -namespace winapi { - -/** - * \brief Closes an open object handle. - * \see https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle - */ -inline result close_handle(HANDLE h) noexcept { - LIBIMP_LOG_(); - if (h == NULL) { - log.error("handle is null."); - return std::make_error_code(std::errc::invalid_argument); - } - if (!::CloseHandle(h)) { - auto err = sys::error(); - log.error("failed: CloseHandle(", h, "). error = ", err); - return err; - } - return std::error_code{}; -} - -} // namespace winapi -LIBIPC_NAMESPACE_END_ diff --git a/src/libipc/platform/win/event_impl.h b/src/libipc/platform/win/event_impl.h index be441fc..ada9d56 100644 --- a/src/libipc/platform/win/event_impl.h +++ b/src/libipc/platform/win/event_impl.h @@ -9,15 +9,11 @@ #include #include -#include - #include "libimp/log.h" #include "libpmr/new.h" #include "libipc/event.h" -#include "get_sa.h" -#include "to_tchar.h" -#include "close_handle.h" +#include "api.h" LIBIPC_NAMESPACE_BEG_ @@ -45,8 +41,8 @@ bool is_valid(evt_t evt) noexcept { */ result evt_open(std::string name) noexcept { LIBIMP_LOG_(); - auto t_name = detail::to_tstring(name); - auto h = ::CreateEvent(detail::get_sa(), + auto t_name = winapi::to_tstring(name); + auto h = ::CreateEvent(winapi::get_sa(), /*bManualReset*/ FALSE, /*bInitialState*/FALSE, /*lpName*/ t_name.c_str()); diff --git a/src/libipc/platform/win/get_sa.h b/src/libipc/platform/win/get_sa.h deleted file mode 100644 index 91ec7d3..0000000 --- a/src/libipc/platform/win/get_sa.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * \file libipc/platform/win/get_sa.h - * \author mutouyun (orz@orzz.org) - */ -#pragma once - -#include - -#include "libimp/system.h" -#include "libimp/log.h" - -#include "libipc/def.h" - -LIBIPC_NAMESPACE_BEG_ -namespace detail { - -/** - * \brief Create a SECURITY_ATTRIBUTES structure singleton - * \see https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa379560(v=vs.85) - */ -inline LPSECURITY_ATTRIBUTES get_sa() { - static struct initiator { - - SECURITY_DESCRIPTOR sd_; - SECURITY_ATTRIBUTES sa_; - - bool succ_ = false; - - initiator() { - using namespace ::LIBIMP; - LIBIMP_LOG_("get_sa"); - if (!::InitializeSecurityDescriptor(&sd_, SECURITY_DESCRIPTOR_REVISION)) { - log.error("failed: InitializeSecurityDescriptor(SECURITY_DESCRIPTOR_REVISION). " - "error = ", sys::error()); - return; - } - if (!::SetSecurityDescriptorDacl(&sd_, TRUE, NULL, FALSE)) { - log.error("failed: SetSecurityDescriptorDacl. error = ", sys::error()); - return; - } - sa_.nLength = sizeof(SECURITY_ATTRIBUTES); - sa_.bInheritHandle = FALSE; - sa_.lpSecurityDescriptor = &sd_; - succ_ = true; - } - } handle; - return handle.succ_ ? &handle.sa_ : nullptr; -} - -} // namespace detail -LIBIPC_NAMESPACE_END_ \ No newline at end of file diff --git a/src/libipc/platform/win/process_impl.h b/src/libipc/platform/win/process_impl.h deleted file mode 100644 index 3468825..0000000 --- a/src/libipc/platform/win/process_impl.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * \file libipc/platform/win/process_impl.h - * \author mutouyun (orz@orzz.org) - */ -#pragma once - -#include -#include - -#include "libimp/log.h" -#include "libipc/process.h" - -LIBIPC_NAMESPACE_BEG_ -using namespace ::LIBIMP; - -/// \brief Experimental fork() on Windows. -/// \see https://gist.github.com/Cr4sh/126d844c28a7fbfd25c6 -/// https://github.com/huntandhackett/process-cloning -namespace { - -typedef SSIZE_T pid_t; - -pid_t fork() { - LIBIMP_LOG_(); - - RTL_USER_PROCESS_INFORMATION process_info; - NTSTATUS status; - - /* lets do this */ - status = RtlCloneUserProcess(RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES - , NULL, NULL, NULL, &process_info); - if (status == STATUS_PROCESS_CLONED) { - // Executing inside the clone... - // Re-attach to the parent's console to be able to write to it - FreeConsole(); - AttachConsole(ATTACH_PARENT_PROCESS); - return 0; - } else { - // Executing inside the original (parent) process... - if (!NT_SUCCESS(status)) { - log.error("failed: RtlCloneUserProcess(...)"); - return -1; - } - return (pid_t)process_info.ProcessHandle; - } - - /* NOTREACHED */ -} - -#define WNOHANG 1 /* Don't block waiting. */ - -/// \see https://man7.org/linux/man-pages/man3/wait.3p.html -/// https://learn.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntwaitforsingleobject -pid_t waitpid(pid_t pid, int */*status*/, int options) { - LIBIMP_LOG_(); - if (pid == -1) { - return -1; - } - if (options & WNOHANG) { - return pid; - } - NTSTATUS status = NtWaitForSingleObject((HANDLE)pid, FALSE, NULL); - if (!NT_SUCCESS(status)) { - log.error("failed: NtWaitForSingleObject(...)"); - return -1; - } - return pid; -} - -} // namespace -LIBIPC_NAMESPACE_END_ diff --git a/src/libipc/platform/win/shm_impl.h b/src/libipc/platform/win/shm_impl.h index e6b0296..1dde5ef 100644 --- a/src/libipc/platform/win/shm_impl.h +++ b/src/libipc/platform/win/shm_impl.h @@ -12,28 +12,34 @@ #include "libpmr/new.h" #include "libipc/shm.h" -#include "mmap_impl.h" -#include "close_handle.h" +#include "api.h" LIBIPC_NAMESPACE_BEG_ using namespace ::LIBIMP; using namespace ::LIBPMR; +struct shm_handle { + std::string file; + std::size_t f_sz; + void *memp; + HANDLE h_fmap; +}; + result shm_open(std::string name, std::size_t size, mode::type type) noexcept { LIBIMP_LOG_(); - auto h = mmap_open(name, size, type); + auto h = winapi::mmap_open(name, size, type); if (*h == NULL) { log.error("failed: mmap_open(name = ", name, ", size = ", size, ", type = ", type, ")."); return h.error(); } - auto mem = mmap_memof(*h); + auto mem = winapi::mmap_memof(*h); if (*mem == NULL) { log.error("failed: mmap_memof(", *h, ")."); winapi::close_handle(*h); return mem.error(); } - auto sz = mmap_sizeof(*mem); + auto sz = winapi::mmap_sizeof(*mem); if (!sz) { log.error("failed: mmap_sizeof(", *mem, ")."); winapi::close_handle(*h); @@ -49,7 +55,7 @@ result shm_close(shm_t h) noexcept { return std::make_error_code(std::errc::invalid_argument); } auto shm = static_cast(h); - auto ret = mmap_release(shm->h_fmap, shm->memp); + auto ret = winapi::mmap_release(shm->h_fmap, shm->memp); $delete(shm); return ret; } diff --git a/src/libipc/platform/win/to_tchar.h b/src/libipc/platform/win/to_tchar.h deleted file mode 100644 index 9f0e580..0000000 --- a/src/libipc/platform/win/to_tchar.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - * \file libipc/platform/win/to_tchar.h - * \author mutouyun (orz@orzz.org) - */ -#pragma once - -#include - -#include - -#include "libimp/codecvt.h" - -#include "libipc/def.h" - -LIBIPC_NAMESPACE_BEG_ -namespace detail { - -using tstring = std::basic_string; - -inline tstring to_tstring(std::string const &str) { - tstring des; - ::LIBIMP::cvt_sstr(str, des); - return des; -} - -} // namespace detail -LIBIPC_NAMESPACE_END_ \ No newline at end of file