ironrdp_pdu/gcc/
monitor_data.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use bitflags::bitflags;
use ironrdp_core::{
    cast_length, ensure_fixed_part_size, invalid_field_err, Decode, DecodeResult, Encode, EncodeResult, ReadCursor,
    WriteCursor,
};

pub const MONITOR_COUNT_SIZE: usize = 4;
pub const MONITOR_SIZE: usize = 20;
pub const MONITOR_FLAGS_SIZE: usize = 4;

const MONITOR_COUNT_MAX: usize = 16;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ClientMonitorData {
    pub monitors: Vec<Monitor>,
}

impl ClientMonitorData {
    const NAME: &'static str = "ClientMonitorData";

    const FIXED_PART_SIZE: usize = 4 /* flags */ + 4 /* count */;
}

impl Encode for ClientMonitorData {
    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
        ensure_fixed_part_size!(in: dst);

        dst.write_u32(0); // flags
        dst.write_u32(cast_length!("nMonitors", self.monitors.len())?);

        for monitor in self.monitors.iter().take(MONITOR_COUNT_MAX) {
            monitor.encode(dst)?;
        }

        Ok(())
    }

    fn name(&self) -> &'static str {
        Self::NAME
    }

    fn size(&self) -> usize {
        Self::FIXED_PART_SIZE + self.monitors.len() * Monitor::FIXED_PART_SIZE
    }
}

impl<'de> Decode<'de> for ClientMonitorData {
    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
        ensure_fixed_part_size!(in: src);

        let _flags = src.read_u32(); // is unused
        let monitor_count = src.read_u32();

        if monitor_count > MONITOR_COUNT_MAX as u32 {
            return Err(invalid_field_err!("nMonitors", "too many monitors"));
        }

        let mut monitors = Vec::with_capacity(monitor_count as usize);
        for _ in 0..monitor_count {
            monitors.push(Monitor::decode(src)?);
        }

        Ok(Self { monitors })
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Monitor {
    pub left: i32,
    pub top: i32,
    pub right: i32,
    pub bottom: i32,
    pub flags: MonitorFlags,
}

impl Monitor {
    const NAME: &'static str = "Monitor";

    const FIXED_PART_SIZE: usize = 4 /* left */ + 4 /* top */ + 4 /* right */ + 4 /* bottom */ + 4 /* flags */;
}

impl Encode for Monitor {
    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
        ensure_fixed_part_size!(in: dst);

        dst.write_i32(self.left);
        dst.write_i32(self.top);
        dst.write_i32(self.right);
        dst.write_i32(self.bottom);
        dst.write_u32(self.flags.bits());

        Ok(())
    }

    fn name(&self) -> &'static str {
        Self::NAME
    }

    fn size(&self) -> usize {
        Self::FIXED_PART_SIZE
    }
}

impl<'de> Decode<'de> for Monitor {
    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
        ensure_fixed_part_size!(in: src);

        let left = src.read_i32();
        let top = src.read_i32();
        let right = src.read_i32();
        let bottom = src.read_i32();
        let flags = MonitorFlags::from_bits(src.read_u32())
            .ok_or_else(|| invalid_field_err!("flags", "invalid monitor flags"))?;

        Ok(Self {
            left,
            top,
            right,
            bottom,
            flags,
        })
    }
}

bitflags! {
    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct MonitorFlags: u32 {
        const PRIMARY = 1;
    }
}