160 lines
6.1 KiB
C++
160 lines
6.1 KiB
C++
/*
|
|
* Ipc.hpp
|
|
* Kernel-mode IPC implementation
|
|
* Copyright (c) 2026 Daniel Hammer
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <cstdint>
|
|
|
|
namespace Net::Tcp { struct Connection; }
|
|
|
|
namespace Ipc {
|
|
|
|
static constexpr int MaxHandlesPerProcess = 128;
|
|
static constexpr int MaxSurfaceMapsPerProcess = 64;
|
|
static constexpr uint32_t DefaultStreamCapacity = 4096;
|
|
|
|
enum class HandleType : uint8_t {
|
|
None = 0,
|
|
Stream,
|
|
Mailbox,
|
|
File,
|
|
Socket,
|
|
Surface,
|
|
Process,
|
|
Waitset
|
|
};
|
|
|
|
enum Rights : uint32_t {
|
|
RightWait = 1u << 0,
|
|
RightRead = 1u << 1,
|
|
RightWrite = 1u << 2,
|
|
RightSend = 1u << 3,
|
|
RightRecv = 1u << 4,
|
|
RightMap = 1u << 5,
|
|
RightManage = 1u << 6,
|
|
RightDup = 1u << 7
|
|
};
|
|
|
|
enum Signals : uint32_t {
|
|
SignalNone = 0,
|
|
SignalReadable = 1u << 0,
|
|
SignalWritable = 1u << 1,
|
|
SignalPeerClosed = 1u << 2,
|
|
SignalExited = 1u << 3,
|
|
SignalReady = 1u << 4
|
|
};
|
|
|
|
struct Object;
|
|
struct Stream;
|
|
struct Mailbox;
|
|
struct File;
|
|
struct Socket;
|
|
struct Surface;
|
|
struct ProcessObject;
|
|
struct Waitset;
|
|
|
|
struct HandleEntry {
|
|
bool used;
|
|
uint32_t rights;
|
|
HandleType type;
|
|
Object* object;
|
|
};
|
|
|
|
struct WaitsetReady {
|
|
int32_t index;
|
|
uint32_t signals;
|
|
};
|
|
|
|
void Initialize();
|
|
|
|
int CurrentSlot();
|
|
int SlotForPid(int pid);
|
|
|
|
int InstallHandleForSlot(int slot, Object* object, HandleType type, uint32_t rights);
|
|
int CloseHandleForSlot(int slot, int handle);
|
|
int CloseHandle(int handle);
|
|
int DupHandle(int handle);
|
|
|
|
bool SnapshotHandleForSlot(int slot, int handle, HandleType& type, Object*& object, uint32_t& rights);
|
|
uint32_t GetHandleSignalsForSlot(int slot, int handle);
|
|
|
|
Stream* CreateStream(uint32_t capacity = DefaultStreamCapacity);
|
|
int CreateStreamHandlePairForSlot(int slot, uint32_t capacity, int& outReadHandle, int& outWriteHandle);
|
|
int CreateStreamHandlePair(uint32_t capacity, int& outReadHandle, int& outWriteHandle);
|
|
void RetainStream(Stream* stream, bool readSide, bool writeSide);
|
|
void ReleaseStream(Stream* stream, bool readSide, bool writeSide);
|
|
int StreamRead(Stream* stream, uint8_t* out, int maxLen, bool nonBlocking);
|
|
int StreamWrite(Stream* stream, const uint8_t* data, int len, bool nonBlocking);
|
|
int StreamReadHandle(int handle, uint8_t* out, int maxLen);
|
|
int StreamWriteHandle(int handle, const uint8_t* data, int len);
|
|
bool StreamHasData(Stream* stream);
|
|
|
|
Mailbox* CreateMailbox();
|
|
int CreateMailboxHandlePairForSlot(int slot, int& outSendHandle, int& outRecvHandle);
|
|
int CreateMailboxHandlePair(int& outSendHandle, int& outRecvHandle);
|
|
void RetainMailbox(Mailbox* mailbox, bool sender, bool receiver);
|
|
void ReleaseMailbox(Mailbox* mailbox, bool sender, bool receiver);
|
|
int MailboxSend(Mailbox* mailbox, uint32_t msgType, const void* data, uint16_t len);
|
|
int MailboxRecv(Mailbox* mailbox, uint32_t* msgType, void* data, uint16_t* inOutLen, bool nonBlocking);
|
|
int MailboxSendHandle(int handle, uint32_t msgType, const void* data, uint16_t len, int attachHandle);
|
|
int MailboxRecvHandle(int handle, uint32_t* msgType, void* data, uint16_t* inOutLen, int* outAttachHandle);
|
|
bool MailboxHasMessage(Mailbox* mailbox);
|
|
|
|
int OpenFileHandleForSlot(int slot, const char* path, bool create);
|
|
int OpenFileHandle(const char* path);
|
|
int CreateFileHandle(const char* path);
|
|
int FileReadHandle(int handle, uint8_t* buffer, uint64_t offset, uint64_t size);
|
|
int FileWriteHandle(int handle, const uint8_t* buffer, uint64_t offset, uint64_t size);
|
|
uint64_t FileGetSizeHandle(int handle);
|
|
|
|
int CreateSocketHandleForSlot(int slot, int type);
|
|
int CreateSocketHandle(int type);
|
|
int SocketConnectHandle(int handle, uint32_t ip, uint16_t port);
|
|
int SocketBindHandle(int handle, uint16_t port);
|
|
int SocketListenHandle(int handle);
|
|
int SocketAcceptHandle(int handle);
|
|
int SocketSendHandle(int handle, const uint8_t* data, uint32_t len);
|
|
int SocketRecvHandle(int handle, uint8_t* buffer, uint32_t maxLen);
|
|
int SocketSendToHandle(int handle, const uint8_t* data, uint32_t len, uint32_t destIp, uint16_t destPort);
|
|
int SocketRecvFromHandle(int handle, uint8_t* buffer, uint32_t maxLen, uint32_t* srcIp, uint16_t* srcPort);
|
|
void NotifyTcpConnectionChanged(Net::Tcp::Connection* connection);
|
|
|
|
Surface* CreateSurface(uint64_t byteSize);
|
|
int CreateSurfaceHandle(uint64_t byteSize);
|
|
void RetainSurface(Surface* surface);
|
|
void ReleaseSurface(Surface* surface);
|
|
uint64_t GetSurfaceSize(const Surface* surface);
|
|
int ResizeSurface(Surface* surface, uint64_t newSize);
|
|
int CopySurface(Surface* dst, Surface* src);
|
|
int CopySurfacePreserve(Surface* dst, int dstWidth, int dstHeight,
|
|
Surface* src, int srcWidth, int srcHeight,
|
|
uint32_t fillPixel);
|
|
uint64_t MapSurfaceHandle(int handle);
|
|
int ResizeSurfaceHandle(int handle, uint64_t newSize);
|
|
int MapSurfaceForPid(Surface* surface, int pid, uint64_t pml4Phys, uint64_t& heapNext, uint64_t& outVa);
|
|
int UnmapSurfaceForPid(Surface* surface, int pid, uint64_t pml4Phys);
|
|
|
|
ProcessObject* GetProcessObject(int pid);
|
|
int OpenProcessHandle(int pid);
|
|
void ProcessStartedInSlot(int slot, int pid);
|
|
void ProcessExitedInSlot(int slot, int pid);
|
|
bool ProcessHasExited(ProcessObject* process);
|
|
|
|
uint32_t WaitOnHandle(int handle, uint32_t wantedSignals, uint64_t timeoutMs);
|
|
|
|
int CreateWaitsetHandleForSlot(int slot);
|
|
int CreateWaitsetHandleForCurrent();
|
|
int WaitsetAddHandleForSlot(int slot, int waitsetHandle, int targetHandle, uint32_t signals);
|
|
int WaitsetAddHandle(int waitsetHandle, int targetHandle, uint32_t signals);
|
|
int WaitsetRemoveIndexForSlot(int slot, int waitsetHandle, int index);
|
|
int WaitsetRemoveIndex(int waitsetHandle, int index);
|
|
int WaitsetWaitHandle(int waitsetHandle, WaitsetReady* outReady, uint64_t timeoutMs);
|
|
|
|
void NotifyObjectChanged(Object* object);
|
|
void CleanupProcessSlot(int slot, int pid, uint64_t pml4Phys);
|
|
|
|
}
|