Skip to main content

asdf_overlay_common/
ipc.rs

1//! Common types and utilities for IPC communication between the overlay client and server.
2
3use asdf_overlay_event::OverlayEvent;
4use bincode::{Decode, Encode};
5use tokio::io::{self, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
6
7use crate::request::Request;
8
9/// Creates a unique IPC address for the given process ID and module handle.
10/// Because there can be multiple overlays in the same process, we need to distinguish with the module handle.
11///
12/// This function is used internally by `asdf-overlay-client` and `asdf-overlay-dll` crates to establish IPC communication.
13pub fn create_ipc_addr(pid: u32, module_handle: u32) -> String {
14    format!("\\\\.\\pipe\\asdf-overlay-{pid}-{module_handle}")
15}
16
17/// Describes a request sent from the client to the server.
18#[derive(Encode, Decode)]
19pub struct ClientRequest {
20    /// Unique identifier for matching responses.
21    pub id: u32,
22
23    /// The actual request data.
24    pub req: Request,
25}
26
27/// Describes a response sent from server to client.
28#[derive(Encode, Decode)]
29pub struct ServerResponse {
30    /// Unique identifier matching the request.
31    pub id: u32,
32
33    /// The raw response data.
34    pub data: Vec<u8>,
35}
36
37/// Describes a packet sent from server to client.
38#[derive(Encode, Decode)]
39pub enum ServerToClientPacket {
40    /// The packet is a response to a specific request.
41    Response(ServerResponse),
42
43    /// The packet is an event notification.
44    Event(OverlayEvent),
45}
46
47/// Describes a frame header for IPC communication.
48#[derive(Debug, Clone, Copy)]
49pub struct Frame {
50    /// Size of the frame body in bytes.
51    pub size: u32,
52}
53
54impl Frame {
55    /// Reads a frame header from the given async reader.
56    pub async fn read(mut r: impl AsyncRead + Unpin) -> io::Result<Self> {
57        Ok(Self {
58            size: r.read_u32().await?,
59        })
60    }
61
62    /// Writes the frame header to the given async writer.
63    pub async fn write(self, mut w: impl AsyncWrite + Unpin) -> io::Result<()> {
64        w.write_u32(self.size).await?;
65        Ok(())
66    }
67}