/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuIPCMemory.NT.cpp Date: 2022-4-15 Author: Reece ***/ #include #include "IPC.hpp" #include "AuIPCHandle.hpp" #include "AuIPCMemory.NT.hpp" namespace Aurora::IO::IPC { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Shared memory ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// IPCSharedMemoryImpl::IPCSharedMemoryImpl(HANDLE handle, void *pBase, const IPC::IPCHandle &ipcHandle) : pBase_(pBase), uLen_(ipcHandle.values[0].token.word), handle_(handle), ipcHandle_(ipcHandle) { } IPCSharedMemoryImpl::~IPCSharedMemoryImpl() { if (this->pBase_) { ::UnmapViewOfFile(this->pBase_); this->pBase_ = nullptr; } AuWin32CloseHandle(this->handle_); } Memory::MemoryViewWrite IPCSharedMemoryImpl::GetMemory() { return AuMemoryViewWrite(this->pBase_, this->uLen_); } AuUInt IPCSharedMemoryImpl::GetLength() { return this->uLen_; } AuString IPCSharedMemoryImpl::ExportToString() { return this->ipcHandle_.ToString(); } AUKN_SYM AuSPtr NewSharedMemory(AuUInt uLength) { IPC::IPCHandle handle; IPC::IPCToken token; token.NewId(); token.word = uLength; handle.PushId(EIPCHandleType::eIPCMemory, token); auto path = token.ToNTPath(); auto file = CreateFileMappingA(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, #if defined(AURORA_IS_64BIT) AuBitsToHigher(uLength), AuBitsToLower(uLength), #else 0, uLength, #endif path.c_str()); if ((file == INVALID_HANDLE_VALUE) || (!file)) { return {}; } auto map = ::MapViewOfFile(file, FILE_MAP_ALL_ACCESS, 0, 0, uLength); if (!map) { SysPushErrorIO(); AuWin32CloseHandle(file); return {}; } auto pObject = AuMakeShared(file, map, handle); if (!pObject) { SysPushErrorMem(); ::UnmapViewOfFile(map); AuWin32CloseHandle(file); return {}; } return pObject; } 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 uLength = 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, uLength); if (!map) { SysPushErrorIO(); AuWin32CloseHandle(file); return {}; } auto pObject = AuMakeShared(file, map, handle); if (!pObject) { SysPushErrorMem(); ::UnmapViewOfFile(map); AuWin32CloseHandle(file); return {}; } return pObject; } }