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
131
|
use bitflags::bitflags;
use windows_kernel_sys::base::{
FILE_ANY_ACCESS,
FILE_READ_DATA,
FILE_WRITE_DATA,
METHOD_BUFFERED,
METHOD_IN_DIRECT,
METHOD_NEITHER,
METHOD_OUT_DIRECT,
};
use crate::device::DeviceType;
bitflags! {
pub struct RequiredAccess: u32 {
const ANY_ACCESS = FILE_ANY_ACCESS;
const READ_DATA = FILE_READ_DATA;
const WRITE_DATA = FILE_WRITE_DATA;
const READ_WRITE_DATA = FILE_READ_DATA | FILE_WRITE_DATA;
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum TransferMethod {
Neither = METHOD_NEITHER,
InputDirect = METHOD_IN_DIRECT,
OutputDirect = METHOD_OUT_DIRECT,
Buffered = METHOD_BUFFERED,
}
impl From<u32> for TransferMethod {
fn from(value: u32) -> Self {
match value & 0x3 {
METHOD_NEITHER => Self::Neither,
METHOD_IN_DIRECT => Self::InputDirect,
METHOD_OUT_DIRECT => Self::OutputDirect,
METHOD_BUFFERED => Self::Buffered,
_ => unreachable!(),
}
}
}
// impl Into<u32> for TransferMethod {
// fn into(self) -> u32 {
// match self {
// Self::Neither => METHOD_NEITHER,
// Self::InputDirect => METHOD_IN_DIRECT,
// Self::OutputDirect => METHOD_OUT_DIRECT,
// Self::Buffered => METHOD_BUFFERED,
// }
// }
// }
impl From<TransferMethod> for u32 {
fn from(t: TransferMethod) -> Self {
match t {
TransferMethod::Neither => METHOD_NEITHER,
TransferMethod::InputDirect => METHOD_IN_DIRECT,
TransferMethod::OutputDirect => METHOD_OUT_DIRECT,
TransferMethod::Buffered => METHOD_BUFFERED,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ControlCode(
pub DeviceType,
pub RequiredAccess,
pub u32,
pub TransferMethod,
);
impl ControlCode {
const ACCESS_BITS: usize = 2;
const ACCESS_MASK: u32 = (1 << Self::ACCESS_BITS) - 1;
const ACCESS_SHIFT: usize = Self::NUM_SHIFT + Self::NUM_BITS;
const METHOD_BITS: usize = 2;
const METHOD_MASK: u32 = (1 << Self::METHOD_BITS) - 1;
const METHOD_SHIFT: usize = 0;
const NUM_BITS: usize = 12;
const NUM_MASK: u32 = (1 << Self::NUM_BITS) - 1;
const NUM_SHIFT: usize = Self::METHOD_SHIFT + Self::METHOD_BITS;
const TYPE_BITS: usize = 16;
const TYPE_MASK: u32 = (1 << Self::TYPE_BITS) - 1;
const TYPE_SHIFT: usize = Self::ACCESS_SHIFT + Self::ACCESS_BITS;
pub fn device_type(&self) -> DeviceType { self.0 }
pub fn required_access(&self) -> RequiredAccess { self.1 }
pub fn number(&self) -> u32 { self.2 }
pub fn transfer_method(&self) -> TransferMethod { self.3 }
}
impl From<u32> for ControlCode {
fn from(value: u32) -> Self {
let method = (value >> Self::METHOD_SHIFT) & Self::METHOD_MASK;
let num = (value >> Self::NUM_SHIFT) & Self::NUM_MASK;
let access = (value >> Self::ACCESS_SHIFT) & Self::ACCESS_MASK;
let ty = (value >> Self::TYPE_SHIFT) & Self::TYPE_MASK;
Self(
ty.into(),
RequiredAccess::from_bits(access).unwrap_or(RequiredAccess::READ_DATA),
num,
method.into(),
)
}
}
// impl Into<u32> for ControlCode {
// fn into(self) -> u32 {
// let method = Into::<u32>::into(self.3) << Self::METHOD_SHIFT;
// let num = self.2 << Self::NUM_SHIFT;
// let access = self.1.bits() << Self::ACCESS_SHIFT;
// let ty = Into::<u32>::into(self.0) << Self::TYPE_SHIFT;
//
// ty | access | num | method
// }
// }
impl From<ControlCode> for u32 {
fn from(c: ControlCode) -> Self {
let method = Into::<u32>::into(c.3) << ControlCode::METHOD_SHIFT;
let num = c.2 << ControlCode::NUM_SHIFT;
let access = c.1.bits() << ControlCode::ACCESS_SHIFT;
let ty = Into::<u32>::into(c.0) << ControlCode::TYPE_SHIFT;
ty | access | num | method
}
}
|