/*** 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" namespace Aurora::IO::IPC { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Shared memory ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// IPCSharedMemoryImpl::IPCSharedMemoryImpl(HANDLE handle, void *ptr, const IPC::IPCHandle &ipcHandle) : base_(ptr), len_(ipcHandle.values[0].token.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; IPC::IPCToken token; token.NewId(); token.word = length; handle.PushId(EIPCHandleType::eIPCMemory, token); auto path = token.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 token = handle.GetToken(EIPCHandleType::eIPCMemory, 0); if (!token) { SysPushErrorParseError(); return {}; } auto length = token->token.word; auto path = token->token.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; } }