@@ -11,7 +11,7 @@ use crate::slice;
11
11
use crate :: sync:: Arc ;
12
12
use crate :: sys:: handle:: Handle ;
13
13
use crate :: sys:: time:: SystemTime ;
14
- use crate :: sys:: { c, cvt} ;
14
+ use crate :: sys:: { c, cvt, AlignedAs } ;
15
15
use crate :: sys_common:: { AsInner , FromInner , IntoInner } ;
16
16
use crate :: thread;
17
17
@@ -47,6 +47,9 @@ pub struct ReadDir {
47
47
first : Option < c:: WIN32_FIND_DATAW > ,
48
48
}
49
49
50
+ type AlignedReparseBuf =
51
+ AlignedAs < c:: REPARSE_DATA_BUFFER , [ u8 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] > ;
52
+
50
53
struct FindNextFileHandle ( c:: HANDLE ) ;
51
54
52
55
unsafe impl Send for FindNextFileHandle { }
@@ -326,9 +329,9 @@ impl File {
326
329
cvt ( c:: GetFileInformationByHandle ( self . handle . as_raw_handle ( ) , & mut info) ) ?;
327
330
let mut reparse_tag = 0 ;
328
331
if info. dwFileAttributes & c:: FILE_ATTRIBUTE_REPARSE_POINT != 0 {
329
- let mut b = [ 0 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ;
332
+ let mut b = AlignedReparseBuf :: new ( [ 0u8 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ) ;
330
333
if let Ok ( ( _, buf) ) = self . reparse_point ( & mut b) {
331
- reparse_tag = buf. ReparseTag ;
334
+ reparse_tag = ( * buf) . ReparseTag ;
332
335
}
333
336
}
334
337
Ok ( FileAttr {
@@ -389,7 +392,7 @@ impl File {
389
392
attr. file_size = info. AllocationSize as u64 ;
390
393
attr. number_of_links = Some ( info. NumberOfLinks ) ;
391
394
if attr. file_type ( ) . is_reparse_point ( ) {
392
- let mut b = [ 0 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ;
395
+ let mut b = AlignedReparseBuf :: new ( [ 0 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ) ;
393
396
if let Ok ( ( _, buf) ) = self . reparse_point ( & mut b) {
394
397
attr. reparse_tag = buf. ReparseTag ;
395
398
}
@@ -458,10 +461,13 @@ impl File {
458
461
Ok ( Self { handle : self . handle . try_clone ( ) ? } )
459
462
}
460
463
461
- fn reparse_point < ' a > (
464
+ // NB: returned pointer is derived from `space`, and has provenance to
465
+ // match. A raw pointer is returned rather than a reference in order to
466
+ // avoid narrowing provenance to the actual `REPARSE_DATA_BUFFER`.
467
+ fn reparse_point (
462
468
& self ,
463
- space : & ' a mut [ u8 ; c :: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ,
464
- ) -> io:: Result < ( c:: DWORD , & ' a c:: REPARSE_DATA_BUFFER ) > {
469
+ space : & mut AlignedReparseBuf ,
470
+ ) -> io:: Result < ( c:: DWORD , * const c:: REPARSE_DATA_BUFFER ) > {
465
471
unsafe {
466
472
let mut bytes = 0 ;
467
473
cvt ( {
@@ -470,36 +476,38 @@ impl File {
470
476
c:: FSCTL_GET_REPARSE_POINT ,
471
477
ptr:: null_mut ( ) ,
472
478
0 ,
473
- space. as_mut_ptr ( ) as * mut _ ,
474
- space. len ( ) as c:: DWORD ,
479
+ space. value . as_mut_ptr ( ) as * mut _ ,
480
+ space. value . len ( ) as c:: DWORD ,
475
481
& mut bytes,
476
482
ptr:: null_mut ( ) ,
477
483
)
478
484
} ) ?;
479
- Ok ( ( bytes, & * ( space. as_ptr ( ) as * const c:: REPARSE_DATA_BUFFER ) ) )
485
+ Ok ( ( bytes, space. value . as_ptr ( ) . cast :: < c:: REPARSE_DATA_BUFFER > ( ) ) )
480
486
}
481
487
}
482
488
483
489
fn readlink ( & self ) -> io:: Result < PathBuf > {
484
- let mut space = [ 0u8 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ;
490
+ let mut space = AlignedReparseBuf :: new ( [ 0u8 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ) ;
485
491
let ( _bytes, buf) = self . reparse_point ( & mut space) ?;
486
492
unsafe {
487
- let ( path_buffer, subst_off, subst_len, relative) = match buf. ReparseTag {
493
+ let ( path_buffer, subst_off, subst_len, relative) = match ( * buf) . ReparseTag {
488
494
c:: IO_REPARSE_TAG_SYMLINK => {
489
495
let info: * const c:: SYMBOLIC_LINK_REPARSE_BUFFER =
490
- & buf. rest as * const _ as * const _ ;
496
+ ptr:: addr_of!( ( * buf) . rest) . cast ( ) ;
497
+ assert ! ( info. is_aligned( ) ) ;
491
498
(
492
- & ( * info) . PathBuffer as * const _ as * const u16 ,
499
+ ptr :: addr_of! ( ( * info) . PathBuffer ) . cast :: < u16 > ( ) ,
493
500
( * info) . SubstituteNameOffset / 2 ,
494
501
( * info) . SubstituteNameLength / 2 ,
495
502
( * info) . Flags & c:: SYMLINK_FLAG_RELATIVE != 0 ,
496
503
)
497
504
}
498
505
c:: IO_REPARSE_TAG_MOUNT_POINT => {
499
506
let info: * const c:: MOUNT_POINT_REPARSE_BUFFER =
500
- & buf. rest as * const _ as * const _ ;
507
+ ptr:: addr_of!( ( * buf) . rest) . cast ( ) ;
508
+ assert ! ( info. is_aligned( ) ) ;
501
509
(
502
- & ( * info) . PathBuffer as * const _ as * const u16 ,
510
+ ptr :: addr_of! ( ( * info) . PathBuffer ) . cast :: < u16 > ( ) ,
503
511
( * info) . SubstituteNameOffset / 2 ,
504
512
( * info) . SubstituteNameLength / 2 ,
505
513
false ,
0 commit comments