diff --git a/src/libipc/platform/win/comfortable_prefix.h b/src/libipc/platform/win/comfortable_prefix.h new file mode 100644 index 00000000..92f7ac18 --- /dev/null +++ b/src/libipc/platform/win/comfortable_prefix.h @@ -0,0 +1,44 @@ +#pragma once + +#include + +#include "libipc/memory/resource.h" + +namespace ipc { +namespace detail { + +/// \brief This routine returns `true` if the caller's process is a member of the Administrators local group. +/// Caller is NOT expected to be impersonating anyone and is expected to be able to open its own process and process token. +/// \return true - Caller has Administrators local group. +/// false - Caller does not have Administrators local group. +/// \see https://learn.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-checktokenmembership +inline bool is_user_admin() { + SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; + PSID AdministratorsGroup; + BOOL b = AllocateAndInitializeSid(&NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, 0, 0, 0, 0, 0, + &AdministratorsGroup); + if (b) { + if (!CheckTokenMembership(NULL, AdministratorsGroup, &b)) { + b = FALSE; + } + FreeSid(AdministratorsGroup); + } + return !!(b); +} + +/// \brief Identify the user group and add the appropriate prefix to the string. +/// \see http://msdn.microsoft.com/en-us/library/aa366551(v=VS.85).aspx +/// https://stackoverflow.com/questions/3999157/system-error-0x5-createfilemapping +inline ipc::string make_comfortable_prefix(ipc::string &&txt) { + if (is_user_admin()) { + return ipc::string{"Global\\"} + txt; + } + return txt; +} + +} // namespace detail +} // namespace ipc diff --git a/src/libipc/platform/win/mutex.h b/src/libipc/platform/win/mutex.h index 97f4a64c..49244d8b 100644 --- a/src/libipc/platform/win/mutex.h +++ b/src/libipc/platform/win/mutex.h @@ -9,6 +9,7 @@ #include "to_tchar.h" #include "get_sa.h" +#include "comfortable_prefix.h" namespace ipc { namespace detail { @@ -33,7 +34,8 @@ class mutex { bool open(char const *name) noexcept { close(); - h_ = ::CreateMutex(detail::get_sa(), FALSE, ipc::detail::to_tchar(ipc::string{"Global\\"} + name).c_str()); + h_ = ::CreateMutex(detail::get_sa(), FALSE, + detail::to_tchar(detail::make_comfortable_prefix(name)).c_str()); if (h_ == NULL) { ipc::error("fail CreateMutex[%lu]: %s\n", ::GetLastError(), name); return false; diff --git a/src/libipc/platform/win/semaphore.h b/src/libipc/platform/win/semaphore.h index b979ba3a..39184e97 100644 --- a/src/libipc/platform/win/semaphore.h +++ b/src/libipc/platform/win/semaphore.h @@ -8,6 +8,7 @@ #include "to_tchar.h" #include "get_sa.h" +#include "comfortable_prefix.h" namespace ipc { namespace detail { @@ -32,7 +33,7 @@ class semaphore { close(); h_ = ::CreateSemaphore(detail::get_sa(), static_cast(count), LONG_MAX, - ipc::detail::to_tchar(ipc::string{"Global\\"} + name).c_str()); + detail::to_tchar(detail::make_comfortable_prefix(name)).c_str()); if (h_ == NULL) { ipc::error("fail CreateSemaphore[%lu]: %s\n", ::GetLastError(), name); return false; diff --git a/src/libipc/platform/win/shm_win.cpp b/src/libipc/platform/win/shm_win.cpp index be3fd45c..c1718350 100755 --- a/src/libipc/platform/win/shm_win.cpp +++ b/src/libipc/platform/win/shm_win.cpp @@ -13,6 +13,7 @@ #include "to_tchar.h" #include "get_sa.h" +#include "comfortable_prefix.h" namespace { @@ -33,7 +34,7 @@ id_t acquire(char const * name, std::size_t size, unsigned mode) { return nullptr; } HANDLE h; - auto fmt_name = ipc::detail::to_tchar(ipc::string{"Global\\__IPC_SHM__"} + name); + auto fmt_name = ipc::detail::to_tchar(detail::make_comfortable_prefix("__IPC_SHM__") + name); // Opens a named file mapping object. if (mode == open) { h = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, fmt_name.c_str()); diff --git a/src/libipc/sync/condition.cpp b/src/libipc/sync/condition.cpp index 06d90e19..b97d09be 100644 --- a/src/libipc/sync/condition.cpp +++ b/src/libipc/sync/condition.cpp @@ -2,6 +2,7 @@ #include "libipc/condition.h" #include "libipc/utility/pimpl.h" +#include "libipc/utility/log.h" #include "libipc/memory/resource.h" #include "libipc/platform/detail.h" #if defined(IPC_OS_WINDOWS_) @@ -49,6 +50,10 @@ bool condition::valid() const noexcept { } bool condition::open(char const *name) noexcept { + if (name == nullptr || name[0] == '\0') { + ipc::error("fail condition open: name is empty\n"); + return false; + } return impl(p_)->cond_.open(name); } diff --git a/src/libipc/sync/mutex.cpp b/src/libipc/sync/mutex.cpp index 79f1a910..40aad651 100644 --- a/src/libipc/sync/mutex.cpp +++ b/src/libipc/sync/mutex.cpp @@ -2,6 +2,7 @@ #include "libipc/mutex.h" #include "libipc/utility/pimpl.h" +#include "libipc/utility/log.h" #include "libipc/memory/resource.h" #include "libipc/platform/detail.h" #if defined(IPC_OS_WINDOWS_) @@ -49,6 +50,10 @@ bool mutex::valid() const noexcept { } bool mutex::open(char const *name) noexcept { + if (name == nullptr || name[0] == '\0') { + ipc::error("fail mutex open: name is empty\n"); + return false; + } return impl(p_)->lock_.open(name); } diff --git a/src/libipc/sync/semaphore.cpp b/src/libipc/sync/semaphore.cpp index 23f6bdce..33539f10 100644 --- a/src/libipc/sync/semaphore.cpp +++ b/src/libipc/sync/semaphore.cpp @@ -2,6 +2,7 @@ #include "libipc/semaphore.h" #include "libipc/utility/pimpl.h" +#include "libipc/utility/log.h" #include "libipc/memory/resource.h" #include "libipc/platform/detail.h" #if defined(IPC_OS_WINDOWS_) @@ -47,6 +48,10 @@ bool semaphore::valid() const noexcept { } bool semaphore::open(char const *name, std::uint32_t count) noexcept { + if (name == nullptr || name[0] == '\0') { + ipc::error("fail semaphore open: name is empty\n"); + return false; + } return impl(p_)->sem_.open(name, count); }