/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: IPCMemory.NT.cpp Date: 2022-4-15 Author: Reece ***/ #include #include "IPC.hpp" #include "IPCHandle.hpp" #include "IPCMemory.NT.hpp" #include #include namespace Aurora::IPC { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Shared memory ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// struct IPCSharedMemoryImpl : IPCSharedMemory { IPCSharedMemoryImpl(HANDLE handle, void *ptr, const IPC::IPCHandle &ipcHandle); ~IPCSharedMemoryImpl(); virtual Memory::MemoryViewWrite GetMemory() override; virtual AuUInt GetLength() override; virtual AuString ExportToString() override; private: IPC::IPCHandle ipcHandle_; bool owns_; HANDLE handle_{}; void *base_{}; AuUInt len_ {}; }; IPCSharedMemoryImpl::IPCSharedMemoryImpl(HANDLE handle, void *ptr, const IPC::IPCHandle &ipcHandle) : base_(ptr), len_(ipcHandle.word), handle_(handle), ipcHandle_(ipcHandle) { } IPCSharedMemoryImpl::~IPCSharedMemoryImpl() { if (this->base_) { ::UnmapViewOfFile(this->base_); } AuWin32CloseHandle(this->handle_); } Memory::MemoryViewWrite IPCSharedMemoryImpl::GetMemory() { return AuMemoryViewWrite(this->base_, this->len_); } AuUInt IPCSharedMemoryImpl::GetLength() { return this->len_; } AuString IPCSharedMemoryImpl::ExportToString() { return this->ipcHandle_.ToString(); } AUKN_SYM AuSPtr NewSharedMemory(AuUInt length) { IPC::IPCHandle handle; handle.NewId(length); auto path = handle.ToNTPath(); auto file = CreateFileMappingA(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, #if defined(AURORA_IS_64BIT) AuBitsToHigher(length), AuBitsToLower(length), #else 0, length, #endif path.c_str()); if ((file == INVALID_HANDLE_VALUE) || (!file)) { return {}; } auto map = MapViewOfFile(file, FILE_MAP_ALL_ACCESS, 0, 0, length); if (!map) { SysPushErrorIO(); AuWin32CloseHandle(file); return {}; } auto object = AuMakeShared(file, map, handle); if (!object) { SysPushErrorMem(); ::UnmapViewOfFile(map); AuWin32CloseHandle(file); return {}; } return object; } AUKN_SYM AuSPtr ImportSharedMemory(const AuString &handleString) { IPC::IPCHandle handle; if (!handle.FromString(handleString)) { SysPushErrorParseError(); return {}; } auto length = handle.word; auto path = handle.ToNTPath(); auto file = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, path.c_str()); if ((file == INVALID_HANDLE_VALUE) || (!file)) { return {}; } auto map = MapViewOfFile(file, FILE_MAP_ALL_ACCESS, 0, 0, length); if (!map) { SysPushErrorIO(); AuWin32CloseHandle(file); return {}; } auto object = AuMakeShared(file, map, handle); if (!object) { SysPushErrorMem(); ::UnmapViewOfFile(map); AuWin32CloseHandle(file); return {}; } return object; } }