mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
Refactor file names and include headers in Windows platform code
This commit is contained in:
parent
7421b95939
commit
1c2fee0d72
@ -1,35 +1,85 @@
|
|||||||
/**
|
/**
|
||||||
* \file libipc/platform/win/mmap_impl.h
|
* \file libipc/platform/win/api.h
|
||||||
* \author mutouyun (orz@orzz.org)
|
* \author mutouyun (orz@orzz.org)
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <securitybaseapi.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
#include <Windows.h>
|
|
||||||
|
|
||||||
#include "libimp/log.h"
|
#include "libimp/log.h"
|
||||||
#include "libimp/system.h"
|
#include "libimp/system.h"
|
||||||
|
#include "libimp/codecvt.h"
|
||||||
|
|
||||||
#include "libipc/shm.h"
|
#include "libipc/def.h"
|
||||||
|
|
||||||
#include "get_sa.h"
|
|
||||||
#include "to_tchar.h"
|
|
||||||
#include "close_handle.h"
|
|
||||||
|
|
||||||
LIBIPC_NAMESPACE_BEG_
|
LIBIPC_NAMESPACE_BEG_
|
||||||
|
|
||||||
using namespace ::LIBIMP;
|
using namespace ::LIBIMP;
|
||||||
|
|
||||||
struct shm_handle {
|
namespace winapi {
|
||||||
std::string file;
|
|
||||||
std::size_t f_sz;
|
|
||||||
void *memp;
|
|
||||||
HANDLE h_fmap;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace {
|
using tstring = std::basic_string<TCHAR>;
|
||||||
|
|
||||||
|
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<void> 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.
|
* \brief Creates or opens a file mapping object for a specified file.
|
||||||
@ -50,7 +100,7 @@ result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode::type t
|
|||||||
log.error("file name is empty.");
|
log.error("file name is empty.");
|
||||||
return std::make_error_code(std::errc::invalid_argument);
|
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()) {
|
if (t_name.empty()) {
|
||||||
log.error("file name is empty. (TCHAR conversion failed)");
|
log.error("file name is empty. (TCHAR conversion failed)");
|
||||||
return std::make_error_code(std::errc::invalid_argument);
|
return std::make_error_code(std::errc::invalid_argument);
|
||||||
@ -69,7 +119,7 @@ result<HANDLE> 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.
|
// Creates or opens a named or unnamed file mapping object for a specified file.
|
||||||
auto try_create = [&]() -> result<HANDLE> {
|
auto try_create = [&]() -> result<HANDLE> {
|
||||||
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.
|
/// \remark dwMaximumSizeHigh always 0 here.
|
||||||
0, static_cast<DWORD>(size), t_name.c_str());
|
0, static_cast<DWORD>(size), t_name.c_str());
|
||||||
if (h == NULL) {
|
if (h == NULL) {
|
||||||
@ -161,5 +211,5 @@ result<void> mmap_release(HANDLE h, LPCVOID mem) {
|
|||||||
return winapi::close_handle(h);
|
return winapi::close_handle(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace winapi
|
||||||
LIBIPC_NAMESPACE_END_
|
LIBIPC_NAMESPACE_END_
|
||||||
@ -1,38 +0,0 @@
|
|||||||
/**
|
|
||||||
* \file libipc/platform/win/close_handle.h
|
|
||||||
* \author mutouyun (orz@orzz.org)
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <Windows.h>
|
|
||||||
|
|
||||||
#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<void> 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_
|
|
||||||
@ -9,15 +9,11 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
#include <Windows.h>
|
|
||||||
|
|
||||||
#include "libimp/log.h"
|
#include "libimp/log.h"
|
||||||
#include "libpmr/new.h"
|
#include "libpmr/new.h"
|
||||||
#include "libipc/event.h"
|
#include "libipc/event.h"
|
||||||
|
|
||||||
#include "get_sa.h"
|
#include "api.h"
|
||||||
#include "to_tchar.h"
|
|
||||||
#include "close_handle.h"
|
|
||||||
|
|
||||||
LIBIPC_NAMESPACE_BEG_
|
LIBIPC_NAMESPACE_BEG_
|
||||||
|
|
||||||
@ -45,8 +41,8 @@ bool is_valid(evt_t evt) noexcept {
|
|||||||
*/
|
*/
|
||||||
result<evt_t> evt_open(std::string name) noexcept {
|
result<evt_t> evt_open(std::string name) noexcept {
|
||||||
LIBIMP_LOG_();
|
LIBIMP_LOG_();
|
||||||
auto t_name = detail::to_tstring(name);
|
auto t_name = winapi::to_tstring(name);
|
||||||
auto h = ::CreateEvent(detail::get_sa(),
|
auto h = ::CreateEvent(winapi::get_sa(),
|
||||||
/*bManualReset*/ FALSE,
|
/*bManualReset*/ FALSE,
|
||||||
/*bInitialState*/FALSE,
|
/*bInitialState*/FALSE,
|
||||||
/*lpName*/ t_name.c_str());
|
/*lpName*/ t_name.c_str());
|
||||||
|
|||||||
@ -1,51 +0,0 @@
|
|||||||
/**
|
|
||||||
* \file libipc/platform/win/get_sa.h
|
|
||||||
* \author mutouyun (orz@orzz.org)
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <securitybaseapi.h>
|
|
||||||
|
|
||||||
#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_
|
|
||||||
@ -1,71 +0,0 @@
|
|||||||
/**
|
|
||||||
* \file libipc/platform/win/process_impl.h
|
|
||||||
* \author mutouyun (orz@orzz.org)
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <phnt_windows.h>
|
|
||||||
#include <phnt.h>
|
|
||||||
|
|
||||||
#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_
|
|
||||||
@ -12,28 +12,34 @@
|
|||||||
#include "libpmr/new.h"
|
#include "libpmr/new.h"
|
||||||
#include "libipc/shm.h"
|
#include "libipc/shm.h"
|
||||||
|
|
||||||
#include "mmap_impl.h"
|
#include "api.h"
|
||||||
#include "close_handle.h"
|
|
||||||
|
|
||||||
LIBIPC_NAMESPACE_BEG_
|
LIBIPC_NAMESPACE_BEG_
|
||||||
|
|
||||||
using namespace ::LIBIMP;
|
using namespace ::LIBIMP;
|
||||||
using namespace ::LIBPMR;
|
using namespace ::LIBPMR;
|
||||||
|
|
||||||
|
struct shm_handle {
|
||||||
|
std::string file;
|
||||||
|
std::size_t f_sz;
|
||||||
|
void *memp;
|
||||||
|
HANDLE h_fmap;
|
||||||
|
};
|
||||||
|
|
||||||
result<shm_t> shm_open(std::string name, std::size_t size, mode::type type) noexcept {
|
result<shm_t> shm_open(std::string name, std::size_t size, mode::type type) noexcept {
|
||||||
LIBIMP_LOG_();
|
LIBIMP_LOG_();
|
||||||
auto h = mmap_open(name, size, type);
|
auto h = winapi::mmap_open(name, size, type);
|
||||||
if (*h == NULL) {
|
if (*h == NULL) {
|
||||||
log.error("failed: mmap_open(name = ", name, ", size = ", size, ", type = ", type, ").");
|
log.error("failed: mmap_open(name = ", name, ", size = ", size, ", type = ", type, ").");
|
||||||
return h.error();
|
return h.error();
|
||||||
}
|
}
|
||||||
auto mem = mmap_memof(*h);
|
auto mem = winapi::mmap_memof(*h);
|
||||||
if (*mem == NULL) {
|
if (*mem == NULL) {
|
||||||
log.error("failed: mmap_memof(", *h, ").");
|
log.error("failed: mmap_memof(", *h, ").");
|
||||||
winapi::close_handle(*h);
|
winapi::close_handle(*h);
|
||||||
return mem.error();
|
return mem.error();
|
||||||
}
|
}
|
||||||
auto sz = mmap_sizeof(*mem);
|
auto sz = winapi::mmap_sizeof(*mem);
|
||||||
if (!sz) {
|
if (!sz) {
|
||||||
log.error("failed: mmap_sizeof(", *mem, ").");
|
log.error("failed: mmap_sizeof(", *mem, ").");
|
||||||
winapi::close_handle(*h);
|
winapi::close_handle(*h);
|
||||||
@ -49,7 +55,7 @@ result<void> shm_close(shm_t h) noexcept {
|
|||||||
return std::make_error_code(std::errc::invalid_argument);
|
return std::make_error_code(std::errc::invalid_argument);
|
||||||
}
|
}
|
||||||
auto shm = static_cast<shm_handle *>(h);
|
auto shm = static_cast<shm_handle *>(h);
|
||||||
auto ret = mmap_release(shm->h_fmap, shm->memp);
|
auto ret = winapi::mmap_release(shm->h_fmap, shm->memp);
|
||||||
$delete(shm);
|
$delete(shm);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +0,0 @@
|
|||||||
/**
|
|
||||||
* \file libipc/platform/win/to_tchar.h
|
|
||||||
* \author mutouyun (orz@orzz.org)
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <tchar.h>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "libimp/codecvt.h"
|
|
||||||
|
|
||||||
#include "libipc/def.h"
|
|
||||||
|
|
||||||
LIBIPC_NAMESPACE_BEG_
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
using tstring = std::basic_string<TCHAR>;
|
|
||||||
|
|
||||||
inline tstring to_tstring(std::string const &str) {
|
|
||||||
tstring des;
|
|
||||||
::LIBIMP::cvt_sstr(str, des);
|
|
||||||
return des;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
LIBIPC_NAMESPACE_END_
|
|
||||||
Loading…
x
Reference in New Issue
Block a user