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}