aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/shmem.cpp
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2020-10-21 03:39:05 +0300
committerEgor Tensin <Egor.Tensin@gmail.com>2020-10-21 04:27:40 +0300
commit89f1c684d73ce275671f2cf5c312dd75af1f18d8 (patch)
tree956f2ae4d1abf07341db5aa6c3d60827690ac4d2 /src/shmem.cpp
parentProcess: add runas() (diff)
downloadwinapi-common-89f1c684d73ce275671f2cf5c312dd75af1f18d8.tar.gz
winapi-common-89f1c684d73ce275671f2cf5c312dd75af1f18d8.zip
add Shared{Memory,Object} classes
Diffstat (limited to 'src/shmem.cpp')
-rw-r--r--src/shmem.cpp88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/shmem.cpp b/src/shmem.cpp
new file mode 100644
index 0000000..552351d
--- /dev/null
+++ b/src/shmem.cpp
@@ -0,0 +1,88 @@
+// Copyright (c) 2020 Egor Tensin <Egor.Tensin@gmail.com>
+// This file is part of the "winapi-common" project.
+// For details, see https://github.com/egor-tensin/winapi-common.
+// Distributed under the MIT License.
+
+#include <winapi/error.hpp>
+#include <winapi/handle.hpp>
+#include <winapi/shmem.hpp>
+#include <winapi/utf8.hpp>
+#include <winapi/utils.hpp>
+
+#include <boost/config.hpp>
+
+#include <windows.h>
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <utility>
+
+namespace winapi {
+namespace {
+
+void* do_map(const Handle& mapping, std::size_t nb = 0) {
+ const auto addr = ::MapViewOfFile(static_cast<HANDLE>(mapping), FILE_MAP_ALL_ACCESS, 0, 0, nb);
+
+ if (addr == NULL) {
+ throw error::windows(GetLastError(), "MapViewOfFile");
+ }
+
+ return addr;
+}
+
+} // namespace
+
+void SharedMemory::Unmap::operator()(void* ptr) const {
+ const auto ret = ::UnmapViewOfFile(ptr);
+ assert(ret);
+ WINAPI_UNUSED_PARAMETER(ret);
+};
+
+SharedMemory SharedMemory::create(const std::string& name, std::size_t nb) {
+ const auto nb64 = static_cast<std::uint64_t>(nb);
+ static_assert(sizeof(nb64) == 2 * sizeof(DWORD), "sizeof(DWORD) != 32");
+
+ const auto nb_low = static_cast<DWORD>(nb64);
+ const auto nb_high = static_cast<DWORD>(nb64 >> 32);
+
+ const auto h_mapping = ::CreateFileMappingW(
+ INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, nb_high, nb_low, widen(name).c_str());
+
+ if (h_mapping == NULL) {
+ throw error::windows(GetLastError(), "CreateFileMappingW");
+ }
+
+ Handle mapping{h_mapping};
+ const auto addr = do_map(mapping);
+ return {std::move(mapping), addr};
+}
+
+SharedMemory SharedMemory::open(const std::string& name) {
+ const auto h_mapping = ::OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, widen(name).c_str());
+
+ if (h_mapping == NULL) {
+ throw error::windows(GetLastError(), "OpenFileMappingW");
+ }
+
+ Handle mapping{h_mapping};
+ const auto addr = do_map(mapping);
+ return {std::move(mapping), addr};
+}
+
+SharedMemory::SharedMemory(SharedMemory&& other) BOOST_NOEXCEPT_OR_NOTHROW {
+ swap(other);
+}
+
+SharedMemory& SharedMemory::operator=(SharedMemory other) BOOST_NOEXCEPT_OR_NOTHROW {
+ swap(other);
+ return *this;
+}
+
+void SharedMemory::swap(SharedMemory& other) BOOST_NOEXCEPT_OR_NOTHROW {
+ using std::swap;
+ swap(m_handle, other.m_handle);
+ swap(m_addr, other.m_addr);
+}
+
+} // namespace winapi