@@ -308,22 +308,7 @@ impl File {
308308 && creation == c:: OPEN_ALWAYS
309309 && unsafe { c:: GetLastError ( ) } == c:: ERROR_ALREADY_EXISTS
310310 {
311- unsafe {
312- // This originally used `FileAllocationInfo` instead of
313- // `FileEndOfFileInfo` but that wasn't supported by WINE.
314- // It's arguable which fits the semantics of `OpenOptions`
315- // better so let's just use the more widely supported method.
316- let eof = c:: FILE_END_OF_FILE_INFO { EndOfFile : 0 } ;
317- let result = c:: SetFileInformationByHandle (
318- handle. as_raw_handle ( ) ,
319- c:: FileEndOfFileInfo ,
320- ptr:: addr_of!( eof) . cast :: < c_void > ( ) ,
321- mem:: size_of :: < c:: FILE_END_OF_FILE_INFO > ( ) as u32 ,
322- ) ;
323- if result == 0 {
324- return Err ( io:: Error :: last_os_error ( ) ) ;
325- }
326- }
311+ Self :: truncate_inner ( handle. as_raw_handle ( ) , 0 ) ?
327312 }
328313 Ok ( File { handle : Handle :: from_inner ( handle) } )
329314 } else {
@@ -341,8 +326,30 @@ impl File {
341326 }
342327
343328 pub fn truncate ( & self , size : u64 ) -> io:: Result < ( ) > {
344- let info = c:: FILE_END_OF_FILE_INFO { EndOfFile : size as i64 } ;
345- api:: set_file_information_by_handle ( self . handle . as_raw_handle ( ) , & info) . io_result ( )
329+ Self :: truncate_inner ( self . handle . as_raw_handle ( ) , size)
330+ }
331+
332+ pub fn truncate_inner ( handle : RawHandle , size : u64 ) -> io:: Result < ( ) > {
333+ if c:: SetFileInformationByHandle :: option ( ) . is_some ( ) {
334+ let info = c:: FILE_END_OF_FILE_INFO { EndOfFile : size as i64 } ;
335+ api:: set_file_information_by_handle ( handle, & info) . io_result ( )
336+ } else {
337+ let mut saved_pos = 0i64 ;
338+ unsafe {
339+ // get current file pointer position
340+ cvt ( c:: SetFilePointerEx ( handle, 0 , & mut saved_pos, c:: FILE_CURRENT ) ) ?;
341+
342+ // seek to new end position
343+ cvt ( c:: SetFilePointerEx ( handle, size as i64 , ptr:: null_mut ( ) , c:: FILE_BEGIN ) ) ?;
344+
345+ // set current position as end of file
346+ cvt ( c:: SetEndOfFile ( handle) ) ?;
347+
348+ // go back to saved position
349+ cvt ( c:: SetFilePointerEx ( handle, saved_pos, ptr:: null_mut ( ) , c:: FILE_BEGIN ) ) ?;
350+ }
351+ Ok ( ( ) )
352+ }
346353 }
347354
348355 #[ cfg( not( target_vendor = "uwp" ) ) ]
@@ -351,7 +358,9 @@ impl File {
351358 let mut info: c:: BY_HANDLE_FILE_INFORMATION = mem:: zeroed ( ) ;
352359 cvt ( c:: GetFileInformationByHandle ( self . handle . as_raw_handle ( ) , & mut info) ) ?;
353360 let mut reparse_tag = 0 ;
354- if info. dwFileAttributes & c:: FILE_ATTRIBUTE_REPARSE_POINT != 0 {
361+ if info. dwFileAttributes & c:: FILE_ATTRIBUTE_REPARSE_POINT != 0
362+ && c:: GetFileInformationByHandleEx :: option ( ) . is_some ( )
363+ {
355364 let mut attr_tag: c:: FILE_ATTRIBUTE_TAG_INFO = mem:: zeroed ( ) ;
356365 cvt ( c:: GetFileInformationByHandleEx (
357366 self . handle . as_raw_handle ( ) ,
0 commit comments