1use crate::FileId;
2use binrw::prelude::*;
3use modular_bitfield::prelude::*;
4use smb_dtyp::Guid;
5
6#[binrw::binrw]
7#[derive(Debug, PartialEq, Eq)]
8pub struct OplockBreakMsg {
9 #[bw(calc = 24)]
10 #[br(assert(_structure_size == 24))]
11 _structure_size: u16,
12 oplock_level: u8,
13 #[bw(calc = 0)]
14 _reserved: u8,
15 #[bw(calc = 0)]
16 reserved2: u32,
17 file_id: FileId,
18}
19
20#[binrw::binrw]
21#[derive(Debug, PartialEq, Eq)]
22pub struct LeaseBreakNotify {
23 #[bw(calc = 44)]
24 #[br(assert(_structure_size == 44))]
25 _structure_size: u16,
26 new_epoch: u16,
27 ack_required: u32,
28 lease_key: Guid,
29 current_lease_state: LeaseState,
30 new_lease_state: LeaseState,
31 #[bw(calc = 0)]
32 #[br(assert(break_reason == 0))]
33 break_reason: u32,
34 #[bw(calc = 0)]
35 #[br(assert(access_mask_hint == 0))]
36 access_mask_hint: u32,
37 #[bw(calc = 0)]
38 #[br(assert(share_mask_hint == 0))]
39 share_mask_hint: u32,
40}
41
42#[binrw::binrw]
43#[derive(Debug, PartialEq, Eq)]
44#[brw(repr(u8))]
45pub enum OplockLevel {
46 None = 0,
47 II = 1,
48 Exclusive = 2,
49}
50
51#[bitfield]
52#[derive(BinWrite, BinRead, Debug, Default, Clone, Copy, PartialEq, Eq)]
53#[bw(map = |&x| Self::into_bytes(x))]
54#[br(map = Self::from_bytes)]
55pub struct LeaseState {
56 pub read_caching: bool,
57 pub handle_caching: bool,
58 pub write_caching: bool,
59 #[skip]
60 __: B29,
61}
62
63pub type OplockBreakNotify = OplockBreakMsg;
65pub type OplockBreakAck = OplockBreakMsg;
66pub type OplockBreakResponse = OplockBreakMsg;
67
68#[binrw::binrw]
69#[derive(Debug, PartialEq, Eq)]
70pub struct LeaseBreakAckResponse {
71 #[bw(calc = 36)]
72 #[br(assert(_structure_size == 36))]
73 _structure_size: u16,
74 #[bw(calc = 0)]
75 _reserved: u16,
76 #[bw(calc = 0)] #[br(assert(flags == 0))]
78 flags: u32,
79 lease_key: Guid,
80 lease_state: LeaseState,
81 #[bw(calc = 0)] #[br(assert(lease_duration == 0))]
83 lease_duration: u64,
84}
85
86pub type LeaseBreakAck = LeaseBreakAckResponse;
88pub type LeaseBreakResponse = LeaseBreakAckResponse;
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93 use smb_tests::*;
94
95 test_binrw! {
96 struct LeaseBreakNotify {
97 new_epoch: 2,
98 ack_required: 1,
99 lease_key: "70c8619e-165d-315e-d492-a01b0cbb3af2".parse().unwrap(),
100 current_lease_state: LeaseState::new()
101 .with_read_caching(true)
102 .with_handle_caching(true),
103 new_lease_state: LeaseState::new(),
104 } => "2c000200010000009e61c8705d165e31d492a01b0cbb3af20300000000000000000000000000000000000000"
105 }
106
107 test_binrw! {
108 struct LeaseBreakAck {
109 lease_key: "70c8619e-165d-315e-d492-a01b0cbb3af2".parse().unwrap(),
110 lease_state: LeaseState::new(),
111 } => "24000000000000009e61c8705d165e31d492a01b0cbb3af2000000000000000000000000"
112 }
113
114 test_binrw! {
115 struct LeaseBreakAckResponse {
116 lease_key: "70c8619e-165d-315e-d492-a01b0cbb3af2".parse().unwrap(),
117 lease_state: LeaseState::new(),
118 } => "24000000000000009e61c8705d165e31d492a01b0cbb3af2000000000000000000000000"
119 }
120}