1
1
#![ unstable( issue = "none" , feature = "windows_handle" ) ]
2
- #![ allow( unsafe_op_in_unsafe_fn) ]
3
2
4
3
#[ cfg( test) ]
5
4
mod tests;
@@ -73,7 +72,7 @@ impl IntoRawHandle for Handle {
73
72
74
73
impl FromRawHandle for Handle {
75
74
unsafe fn from_raw_handle ( raw_handle : RawHandle ) -> Self {
76
- Self ( FromRawHandle :: from_raw_handle ( raw_handle) )
75
+ unsafe { Self ( FromRawHandle :: from_raw_handle ( raw_handle) ) }
77
76
}
78
77
}
79
78
@@ -139,13 +138,23 @@ impl Handle {
139
138
140
139
pub unsafe fn read_overlapped (
141
140
& self ,
142
- buf : & mut [ u8 ] ,
141
+ buf : & mut [ mem :: MaybeUninit < u8 > ] ,
143
142
overlapped : * mut c:: OVERLAPPED ,
144
143
) -> io:: Result < Option < usize > > {
145
- let len = cmp:: min ( buf. len ( ) , u32:: MAX as usize ) as u32 ;
146
- let mut amt = 0 ;
147
- let res =
148
- cvt ( c:: ReadFile ( self . as_raw_handle ( ) , buf. as_mut_ptr ( ) , len, & mut amt, overlapped) ) ;
144
+ // SAFETY: We have exclusive access to the buffer and it's up to the caller to
145
+ // ensure the OVERLAPPED pointer is valid for the lifetime of this function.
146
+ let ( res, amt) = unsafe {
147
+ let len = cmp:: min ( buf. len ( ) , u32:: MAX as usize ) as u32 ;
148
+ let mut amt = 0 ;
149
+ let res = cvt ( c:: ReadFile (
150
+ self . as_raw_handle ( ) ,
151
+ buf. as_mut_ptr ( ) . cast :: < u8 > ( ) ,
152
+ len,
153
+ & mut amt,
154
+ overlapped,
155
+ ) ) ;
156
+ ( res, amt)
157
+ } ;
149
158
match res {
150
159
Ok ( _) => Ok ( Some ( amt as usize ) ) ,
151
160
Err ( e) => {
@@ -230,20 +239,24 @@ impl Handle {
230
239
231
240
// The length is clamped at u32::MAX.
232
241
let len = cmp:: min ( len, u32:: MAX as usize ) as u32 ;
233
- let status = c:: NtReadFile (
234
- self . as_handle ( ) ,
235
- ptr:: null_mut ( ) ,
236
- None ,
237
- ptr:: null_mut ( ) ,
238
- & mut io_status,
239
- buf,
240
- len,
241
- offset. map ( |n| n as _ ) . as_ref ( ) ,
242
- None ,
243
- ) ;
242
+ // SAFETY: It's up to the caller to ensure `buf` is writeable up to
243
+ // the provided `len`.
244
+ let status = unsafe {
245
+ c:: NtReadFile (
246
+ self . as_handle ( ) ,
247
+ ptr:: null_mut ( ) ,
248
+ None ,
249
+ ptr:: null_mut ( ) ,
250
+ & mut io_status,
251
+ buf,
252
+ len,
253
+ offset. map ( |n| n as _ ) . as_ref ( ) ,
254
+ None ,
255
+ )
256
+ } ;
244
257
245
258
let status = if status == c:: STATUS_PENDING {
246
- c:: WaitForSingleObject ( self . as_raw_handle ( ) , c:: INFINITE ) ;
259
+ unsafe { c:: WaitForSingleObject ( self . as_raw_handle ( ) , c:: INFINITE ) } ;
247
260
io_status. status ( )
248
261
} else {
249
262
status
@@ -261,7 +274,7 @@ impl Handle {
261
274
status if c:: nt_success ( status) => Ok ( io_status. Information ) ,
262
275
263
276
status => {
264
- let error = c:: RtlNtStatusToDosError ( status) ;
277
+ let error = unsafe { c:: RtlNtStatusToDosError ( status) } ;
265
278
Err ( io:: Error :: from_raw_os_error ( error as _ ) )
266
279
}
267
280
}
0 commit comments