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
@@ -142,19 +141,23 @@ impl Handle {
142
141
buf : & mut [ 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) ) ;
149
- match res {
150
- Ok ( _) => Ok ( Some ( amt as usize ) ) ,
151
- Err ( e) => {
152
- if e. raw_os_error ( ) == Some ( c:: ERROR_IO_PENDING as i32 ) {
153
- Ok ( None )
154
- } else if e. raw_os_error ( ) == Some ( c:: ERROR_BROKEN_PIPE as i32 ) {
155
- Ok ( Some ( 0 ) )
156
- } else {
157
- Err ( e)
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
+ unsafe {
147
+ let len = cmp:: min ( buf. len ( ) , u32:: MAX as usize ) as u32 ;
148
+ let mut amt = 0 ;
149
+ let res =
150
+ cvt ( c:: ReadFile ( self . as_raw_handle ( ) , buf. as_mut_ptr ( ) , len, & mut amt, overlapped) ) ;
151
+ match res {
152
+ Ok ( _) => Ok ( Some ( amt as usize ) ) ,
153
+ Err ( e) => {
154
+ if e. raw_os_error ( ) == Some ( c:: ERROR_IO_PENDING as i32 ) {
155
+ Ok ( None )
156
+ } else if e. raw_os_error ( ) == Some ( c:: ERROR_BROKEN_PIPE as i32 ) {
157
+ Ok ( Some ( 0 ) )
158
+ } else {
159
+ Err ( e)
160
+ }
158
161
}
159
162
}
160
163
}
@@ -230,20 +233,24 @@ impl Handle {
230
233
231
234
// The length is clamped at u32::MAX.
232
235
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
- ) ;
236
+ // SAFETY: It's up to the caller to ensure `buf` is writeable up to
237
+ // the provided `len`.
238
+ let status = unsafe {
239
+ c:: NtReadFile (
240
+ self . as_handle ( ) ,
241
+ ptr:: null_mut ( ) ,
242
+ None ,
243
+ ptr:: null_mut ( ) ,
244
+ & mut io_status,
245
+ buf,
246
+ len,
247
+ offset. map ( |n| n as _ ) . as_ref ( ) ,
248
+ None ,
249
+ )
250
+ } ;
244
251
245
252
let status = if status == c:: STATUS_PENDING {
246
- c:: WaitForSingleObject ( self . as_raw_handle ( ) , c:: INFINITE ) ;
253
+ unsafe { c:: WaitForSingleObject ( self . as_raw_handle ( ) , c:: INFINITE ) } ;
247
254
io_status. status ( )
248
255
} else {
249
256
status
@@ -261,7 +268,7 @@ impl Handle {
261
268
status if c:: nt_success ( status) => Ok ( io_status. Information ) ,
262
269
263
270
status => {
264
- let error = c:: RtlNtStatusToDosError ( status) ;
271
+ let error = unsafe { c:: RtlNtStatusToDosError ( status) } ;
265
272
Err ( io:: Error :: from_raw_os_error ( error as _ ) )
266
273
}
267
274
}
0 commit comments