smb_msg/lock.rs
1//! Classic Lock request & response.
2
3use super::FileId;
4use binrw::prelude::*;
5use modular_bitfield::prelude::*;
6use smb_msg_derive::*;
7
8/// SMB2 LOCK Request packet used to lock or unlock portions of a file.
9/// Multiple segments of the file can be affected with a single request,
10/// but they all must be within the same file.
11///
12/// Reference: MS-SMB2 2.2.26
13#[smb_request(size = 48)]
14pub struct LockRequest {
15 /// Number of SMB2_LOCK_ELEMENT structures in the locks array.
16 /// Must be greater than or equal to 1.
17 #[bw(try_calc = locks.len().try_into())]
18 lock_count: u16,
19 /// Lock sequence information for the request.
20 pub lock_sequence: LockSequence,
21 /// File identifier on which to perform the byte range locks or unlocks.
22 pub file_id: FileId,
23 /// Array of lock elements defining the ranges to be locked or unlocked.
24 #[br(count = lock_count)]
25 pub locks: Vec<LockElement>,
26}
27
28/// Lock sequence information containing sequence number and index.
29/// In SMB 2.0.2 dialect, this field is unused and must be reserved.
30/// In all other dialects, contains sequence number and index fields.
31///
32/// Reference: MS-SMB2 2.2.26
33#[smb_dtyp::mbitfield]
34pub struct LockSequence {
35 /// 4-bit integer value containing the lock sequence number.
36 pub number: B4,
37 /// 28-bit integer value that must contain a value from 0 to 64, where 0 is reserved.
38 pub index: B28,
39}
40
41/// SMB2_LOCK_ELEMENT structure used to indicate segments of files
42/// that are locked or unlocked in SMB2 LOCK requests.
43///
44/// Reference: MS-SMB2 2.2.26.1
45#[smb_request_binrw]
46pub struct LockElement {
47 /// Starting offset in bytes from where the range being locked or unlocked starts.
48 pub offset: u64,
49 /// Length in bytes of the range being locked or unlocked.
50 pub length: u64,
51 /// Flags describing how the range is being locked or unlocked and how to process the operation.
52 pub flags: LockFlag,
53 reserved: u32,
54}
55
56/// Lock flags describing how the range is being locked or unlocked.
57/// Valid combinations are: shared lock, exclusive lock, unlock,
58/// or any of shared/exclusive combined with fail_immediately.
59///
60/// Reference: MS-SMB2 2.2.26.1
61#[smb_dtyp::mbitfield]
62pub struct LockFlag {
63 /// Range must be locked shared, allowing other opens to read or take shared locks.
64 /// Other opens must not be allowed to write within the range.
65 pub shared: bool,
66 /// Range must be locked exclusive, not allowing other opens to read, write, or lock within the range.
67 pub exclusive: bool,
68 /// Range must be unlocked from a previous lock. Unlock range must be identical to lock range.
69 pub unlock: bool,
70 /// Lock operation must fail immediately if it conflicts with an existing lock,
71 /// instead of waiting for the range to become available.
72 pub fail_immediately: bool,
73 #[skip]
74 __: B28,
75}
76
77/// SMB2 LOCK Response packet sent by the server in response to an SMB2 LOCK Request.
78///
79/// Reference: MS-SMB2 2.2.27
80#[smb_response(size = 4)]
81#[derive(Default)]
82pub struct LockResponse {
83 reserved: u16,
84}
85
86#[cfg(test)]
87mod tests {
88
89 // TODO: tests
90}