@@ -332,16 +332,7 @@ impl File {
332332 mem:: size_of :: < c:: FILE_ALLOCATION_INFO > ( ) as u32 ,
333333 ) ;
334334 if result == 0 {
335- let eof = c:: FILE_END_OF_FILE_INFO { EndOfFile : 0 } ;
336- let result = c:: SetFileInformationByHandle (
337- handle. as_raw_handle ( ) ,
338- c:: FileEndOfFileInfo ,
339- ( & raw const eof) . cast :: < c_void > ( ) ,
340- mem:: size_of :: < c:: FILE_END_OF_FILE_INFO > ( ) as u32 ,
341- ) ;
342- if result == 0 {
343- return Err ( io:: Error :: last_os_error ( ) ) ;
344- }
335+ Self :: truncate_inner ( handle. as_raw_handle ( ) , 0 ) ?
345336 }
346337 }
347338 }
@@ -475,8 +466,37 @@ impl File {
475466 }
476467
477468 pub fn truncate ( & self , size : u64 ) -> io:: Result < ( ) > {
469+ Self :: truncate_inner ( self . handle . as_raw_handle ( ) , size)
470+ }
471+
472+ #[ cfg( not( target_vendor = "rust9x" ) ) ]
473+ pub fn truncate_inner ( handle : RawHandle , size : u64 ) -> io:: Result < ( ) > {
478474 let info = c:: FILE_END_OF_FILE_INFO { EndOfFile : size as i64 } ;
479- api:: set_file_information_by_handle ( self . handle . as_raw_handle ( ) , & info) . io_result ( )
475+ api:: set_file_information_by_handle ( handle, & info) . io_result ( )
476+ }
477+
478+ #[ cfg( target_vendor = "rust9x" ) ]
479+ pub fn truncate_inner ( handle : RawHandle , size : u64 ) -> io:: Result < ( ) > {
480+ if c:: SetFileInformationByHandle :: available ( ) . is_some ( ) {
481+ let info = c:: FILE_END_OF_FILE_INFO { EndOfFile : size as i64 } ;
482+ api:: set_file_information_by_handle ( handle, & info) . io_result ( )
483+ } else {
484+ let mut saved_pos = 0i64 ;
485+ unsafe {
486+ // get current file pointer position
487+ cvt ( c:: SetFilePointerEx ( handle, 0 , & mut saved_pos, c:: FILE_CURRENT ) ) ?;
488+
489+ // seek to new end position
490+ cvt ( c:: SetFilePointerEx ( handle, size as i64 , ptr:: null_mut ( ) , c:: FILE_BEGIN ) ) ?;
491+
492+ // set current position as end of file
493+ cvt ( c:: SetEndOfFile ( handle) ) ?;
494+
495+ // go back to saved position
496+ cvt ( c:: SetFilePointerEx ( handle, saved_pos, ptr:: null_mut ( ) , c:: FILE_BEGIN ) ) ?;
497+ }
498+ Ok ( ( ) )
499+ }
480500 }
481501
482502 #[ cfg( not( target_vendor = "uwp" ) ) ]
@@ -486,15 +506,22 @@ impl File {
486506 cvt ( c:: GetFileInformationByHandle ( self . handle . as_raw_handle ( ) , & mut info) ) ?;
487507 let mut reparse_tag = 0 ;
488508 if info. dwFileAttributes & c:: FILE_ATTRIBUTE_REPARSE_POINT != 0 {
489- let mut attr_tag: c:: FILE_ATTRIBUTE_TAG_INFO = mem:: zeroed ( ) ;
490- cvt ( c:: GetFileInformationByHandleEx (
491- self . handle . as_raw_handle ( ) ,
492- c:: FileAttributeTagInfo ,
493- ( & raw mut attr_tag) . cast ( ) ,
494- mem:: size_of :: < c:: FILE_ATTRIBUTE_TAG_INFO > ( ) . try_into ( ) . unwrap ( ) ,
495- ) ) ?;
496- if attr_tag. FileAttributes & c:: FILE_ATTRIBUTE_REPARSE_POINT != 0 {
497- reparse_tag = attr_tag. ReparseTag ;
509+ #[ cfg( target_vendor = "rust9x" ) ]
510+ let f = c:: GetFileInformationByHandleEx :: available ( ) ;
511+ #[ cfg( not( target_vendor = "rust9x" ) ) ]
512+ let f = Some ( c:: GetFileInformationByHandleEx ) ;
513+
514+ if let Some ( f) = f {
515+ let mut attr_tag: c:: FILE_ATTRIBUTE_TAG_INFO = mem:: zeroed ( ) ;
516+ cvt ( f (
517+ self . handle . as_raw_handle ( ) ,
518+ c:: FileAttributeTagInfo ,
519+ ( & raw mut attr_tag) . cast ( ) ,
520+ mem:: size_of :: < c:: FILE_ATTRIBUTE_TAG_INFO > ( ) . try_into ( ) . unwrap ( ) ,
521+ ) ) ?;
522+ if attr_tag. FileAttributes & c:: FILE_ATTRIBUTE_REPARSE_POINT != 0 {
523+ reparse_tag = attr_tag. ReparseTag ;
524+ }
498525 }
499526 }
500527 Ok ( FileAttr {
0 commit comments