@@ -314,22 +314,11 @@ impl File {
314314 && creation == c:: OPEN_ALWAYS
315315 && api:: get_last_error ( ) == WinError :: ALREADY_EXISTS
316316 {
317- unsafe {
318- // This originally used `FileAllocationInfo` instead of
319- // `FileEndOfFileInfo` but that wasn't supported by WINE.
320- // It's arguable which fits the semantics of `OpenOptions`
321- // better so let's just use the more widely supported method.
322- let eof = c:: FILE_END_OF_FILE_INFO { EndOfFile : 0 } ;
323- let result = c:: SetFileInformationByHandle (
324- handle. as_raw_handle ( ) ,
325- c:: FileEndOfFileInfo ,
326- ( & raw const eof) . cast :: < c_void > ( ) ,
327- mem:: size_of :: < c:: FILE_END_OF_FILE_INFO > ( ) as u32 ,
328- ) ;
329- if result == 0 {
330- return Err ( io:: Error :: last_os_error ( ) ) ;
331- }
332- }
317+ // This originally used `FileAllocationInfo` instead of
318+ // `FileEndOfFileInfo` but that wasn't supported by WINE.
319+ // It's arguable which fits the semantics of `OpenOptions`
320+ // better so let's just use the more widely supported method.
321+ Self :: truncate_inner ( handle. as_raw_handle ( ) , 0 ) ?
333322 }
334323 Ok ( File { handle : Handle :: from_inner ( handle) } )
335324 } else {
@@ -461,8 +450,37 @@ impl File {
461450 }
462451
463452 pub fn truncate ( & self , size : u64 ) -> io:: Result < ( ) > {
453+ Self :: truncate_inner ( self . handle . as_raw_handle ( ) , size)
454+ }
455+
456+ #[ cfg( not( target_vendor = "rust9x" ) ) ]
457+ pub fn truncate_inner ( handle : RawHandle , size : u64 ) -> io:: Result < ( ) > {
464458 let info = c:: FILE_END_OF_FILE_INFO { EndOfFile : size as i64 } ;
465- api:: set_file_information_by_handle ( self . handle . as_raw_handle ( ) , & info) . io_result ( )
459+ api:: set_file_information_by_handle ( handle, & info) . io_result ( )
460+ }
461+
462+ #[ cfg( target_vendor = "rust9x" ) ]
463+ pub fn truncate_inner ( handle : RawHandle , size : u64 ) -> io:: Result < ( ) > {
464+ if c:: SetFileInformationByHandle :: available ( ) . is_some ( ) {
465+ let info = c:: FILE_END_OF_FILE_INFO { EndOfFile : size as i64 } ;
466+ api:: set_file_information_by_handle ( handle, & info) . io_result ( )
467+ } else {
468+ let mut saved_pos = 0i64 ;
469+ unsafe {
470+ // get current file pointer position
471+ cvt ( c:: SetFilePointerEx ( handle, 0 , & mut saved_pos, c:: FILE_CURRENT ) ) ?;
472+
473+ // seek to new end position
474+ cvt ( c:: SetFilePointerEx ( handle, size as i64 , ptr:: null_mut ( ) , c:: FILE_BEGIN ) ) ?;
475+
476+ // set current position as end of file
477+ cvt ( c:: SetEndOfFile ( handle) ) ?;
478+
479+ // go back to saved position
480+ cvt ( c:: SetFilePointerEx ( handle, saved_pos, ptr:: null_mut ( ) , c:: FILE_BEGIN ) ) ?;
481+ }
482+ Ok ( ( ) )
483+ }
466484 }
467485
468486 #[ cfg( not( target_vendor = "uwp" ) ) ]
@@ -472,15 +490,22 @@ impl File {
472490 cvt ( c:: GetFileInformationByHandle ( self . handle . as_raw_handle ( ) , & mut info) ) ?;
473491 let mut reparse_tag = 0 ;
474492 if info. dwFileAttributes & c:: FILE_ATTRIBUTE_REPARSE_POINT != 0 {
475- let mut attr_tag: c:: FILE_ATTRIBUTE_TAG_INFO = mem:: zeroed ( ) ;
476- cvt ( c:: GetFileInformationByHandleEx (
477- self . handle . as_raw_handle ( ) ,
478- c:: FileAttributeTagInfo ,
479- ( & raw mut attr_tag) . cast ( ) ,
480- mem:: size_of :: < c:: FILE_ATTRIBUTE_TAG_INFO > ( ) . try_into ( ) . unwrap ( ) ,
481- ) ) ?;
482- if attr_tag. FileAttributes & c:: FILE_ATTRIBUTE_REPARSE_POINT != 0 {
483- reparse_tag = attr_tag. ReparseTag ;
493+ #[ cfg( target_vendor = "rust9x" ) ]
494+ let f = c:: GetFileInformationByHandleEx :: available ( ) ;
495+ #[ cfg( not( target_vendor = "rust9x" ) ) ]
496+ let f = Some ( c:: GetFileInformationByHandleEx ) ;
497+
498+ if let Some ( f) = f {
499+ let mut attr_tag: c:: FILE_ATTRIBUTE_TAG_INFO = mem:: zeroed ( ) ;
500+ cvt ( f (
501+ self . handle . as_raw_handle ( ) ,
502+ c:: FileAttributeTagInfo ,
503+ ( & raw mut attr_tag) . cast ( ) ,
504+ mem:: size_of :: < c:: FILE_ATTRIBUTE_TAG_INFO > ( ) . try_into ( ) . unwrap ( ) ,
505+ ) ) ?;
506+ if attr_tag. FileAttributes & c:: FILE_ATTRIBUTE_REPARSE_POINT != 0 {
507+ reparse_tag = attr_tag. ReparseTag ;
508+ }
484509 }
485510 }
486511 Ok ( FileAttr {
0 commit comments