compio_driver\sys\op\general/
iocp.rs1use windows_sys::Win32::{
2 Storage::FileSystem::{ReadFile, WriteFile},
3 System::{
4 IO::{DeviceIoControl, OVERLAPPED},
5 Pipes::ConnectNamedPipe,
6 },
7};
8
9use crate::{OpCode, sys::op::*};
10
11unsafe impl<T: IoBufMut, S: AsFd> OpCode for ReadAt<T, S> {
12 type Control = ();
13
14 unsafe fn operate(&mut self, _: &mut (), optr: *mut OVERLAPPED) -> Poll<io::Result<usize>> {
15 if let Some(overlapped) = unsafe { optr.as_mut() } {
16 overlapped.Anonymous.Anonymous.Offset = (self.offset & 0xFFFFFFFF) as _;
17 overlapped.Anonymous.Anonymous.OffsetHigh = (self.offset >> 32) as _;
18 }
19 let slice = self.buffer.sys_slice_mut();
20 let fd = self.fd.as_fd().as_raw_fd();
21 let mut transferred = 0;
22 let res = unsafe {
23 ReadFile(
24 fd,
25 slice.ptr() as _,
26 slice.len() as _,
27 &mut transferred,
28 optr,
29 )
30 };
31 win32_result(res, transferred)
32 }
33
34 fn cancel(&mut self, _: &mut (), optr: *mut OVERLAPPED) -> io::Result<()> {
35 cancel(self.fd.as_fd().as_raw_fd(), optr)
36 }
37}
38
39unsafe impl<T: IoBuf, S: AsFd> OpCode for WriteAt<T, S> {
40 type Control = ();
41
42 unsafe fn operate(&mut self, _: &mut (), optr: *mut OVERLAPPED) -> Poll<io::Result<usize>> {
43 if let Some(overlapped) = unsafe { optr.as_mut() } {
44 overlapped.Anonymous.Anonymous.Offset = (self.offset & 0xFFFFFFFF) as _;
45 overlapped.Anonymous.Anonymous.OffsetHigh = (self.offset >> 32) as _;
46 }
47 let slice = self.buffer.as_init();
48 let mut transferred = 0;
49 let res = unsafe {
50 WriteFile(
51 self.fd.as_fd().as_raw_fd(),
52 slice.as_ptr() as _,
53 slice.len().try_into().unwrap_or(u32::MAX),
54 &mut transferred,
55 optr,
56 )
57 };
58 win32_result(res, transferred)
59 }
60
61 fn cancel(&mut self, _: &mut (), optr: *mut OVERLAPPED) -> io::Result<()> {
62 cancel(self.fd.as_fd().as_raw_fd(), optr)
63 }
64}
65
66unsafe impl<T: IoBufMut, S: AsFd> OpCode for Read<T, S> {
67 type Control = ();
68
69 unsafe fn operate(&mut self, _: &mut (), optr: *mut OVERLAPPED) -> Poll<io::Result<usize>> {
70 let fd = self.fd.as_fd().as_raw_fd();
71 let mut transferred = 0;
72 let slice = self.buffer.sys_slice_mut();
73 let res = unsafe {
74 ReadFile(
75 fd,
76 slice.ptr() as _,
77 slice.len() as _,
78 &mut transferred,
79 optr,
80 )
81 };
82 win32_result(res, transferred)
83 }
84
85 fn cancel(&mut self, _: &mut (), optr: *mut OVERLAPPED) -> io::Result<()> {
86 cancel(self.fd.as_fd().as_raw_fd(), optr)
87 }
88}
89
90unsafe impl<T: IoBuf, S: AsFd> OpCode for Write<T, S> {
91 type Control = ();
92
93 unsafe fn operate(&mut self, _: &mut (), optr: *mut OVERLAPPED) -> Poll<io::Result<usize>> {
94 let slice = self.buffer.as_init();
95 let mut transferred = 0;
96 let res = unsafe {
97 WriteFile(
98 self.fd.as_fd().as_raw_fd(),
99 slice.as_ptr() as _,
100 slice.len().try_into().unwrap_or(u32::MAX),
101 &mut transferred,
102 optr,
103 )
104 };
105 win32_result(res, transferred)
106 }
107
108 fn cancel(&mut self, _: &mut (), optr: *mut OVERLAPPED) -> io::Result<()> {
109 cancel(self.fd.as_fd().as_raw_fd(), optr)
110 }
111}
112
113pub struct ConnectNamedPipe<S> {
115 pub(crate) fd: S,
116}
117
118impl<S> ConnectNamedPipe<S> {
119 pub fn new(fd: S) -> Self {
121 Self { fd }
122 }
123}
124
125unsafe impl<S: AsFd> OpCode for ConnectNamedPipe<S> {
126 type Control = ();
127
128 unsafe fn operate(&mut self, _: &mut (), optr: *mut OVERLAPPED) -> Poll<io::Result<usize>> {
129 let res = unsafe { ConnectNamedPipe(self.fd.as_fd().as_raw_fd() as _, optr) };
130 win32_result(res, 0)
131 }
132
133 fn cancel(&mut self, _: &mut (), optr: *mut OVERLAPPED) -> io::Result<()> {
134 cancel(self.fd.as_fd().as_raw_fd(), optr)
135 }
136}
137
138#[doc(hidden)]
140pub struct DeviceIoControl<S, I: IoBuf, O: IoBufMut> {
141 pub(crate) fd: S,
142 pub(crate) ioctl_code: u32,
143 pub(crate) input_buffer: Option<I>,
144 pub(crate) output_buffer: Option<O>,
145}
146
147impl<S, I: IoBuf, O: IoBufMut> DeviceIoControl<S, I, O> {
148 pub fn new(fd: S, ioctl_code: u32, input_buffer: Option<I>, output_buffer: Option<O>) -> Self {
150 Self {
151 fd,
152 ioctl_code,
153 input_buffer,
154 output_buffer,
155 }
156 }
157}
158
159impl<S, I: IoBuf, O: IoBufMut> IntoInner for DeviceIoControl<S, I, O> {
160 type Inner = (Option<I>, Option<O>);
161
162 fn into_inner(self) -> Self::Inner {
163 (self.input_buffer, self.output_buffer)
164 }
165}
166
167unsafe impl<S: AsFd, I: IoBuf, O: IoBufMut> OpCode for DeviceIoControl<S, I, O> {
168 type Control = ();
169
170 unsafe fn operate(&mut self, _: &mut (), optr: *mut OVERLAPPED) -> Poll<io::Result<usize>> {
171 let fd = self.fd.as_fd().as_raw_fd();
172
173 let input = self
174 .input_buffer
175 .as_ref()
176 .map_or(SysSlice::null(), |x| x.sys_slice());
177 let output = self
178 .output_buffer
179 .as_mut()
180 .map_or(SysSlice::null(), |x| x.sys_slice_mut());
181
182 let mut transferred = 0;
183 let res = unsafe {
184 DeviceIoControl(
185 fd,
186 self.ioctl_code,
187 input.ptr() as _,
188 input.len() as _,
189 output.ptr() as _,
190 output.len() as _,
191 &mut transferred,
192 optr,
193 )
194 };
195 win32_result(res, transferred)
196 }
197
198 fn cancel(&mut self, _: &mut (), optr: *mut OVERLAPPED) -> io::Result<()> {
199 cancel(self.fd.as_fd().as_raw_fd(), optr)
200 }
201}