@@ -388,21 +388,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
388388
389389 let class = this. read_scalar ( class) ?. to_u32 ( ) ?;
390390 let buffer_size = this. read_scalar ( buffer_size) ?. to_u32 ( ) ?;
391- let file_info = this. read_pointer ( file_information) ?;
391+ let file_information = this. read_pointer ( file_information) ?;
392392 this. check_ptr_access (
393- file_info ,
393+ file_information ,
394394 Size :: from_bytes ( buffer_size) ,
395395 CheckInAllocMsg :: MemoryAccess ,
396396 ) ?;
397397
398- let file = this. read_handle ( file, "GetFileInformationByHandle " ) ?;
398+ let file = this. read_handle ( file, "SetFileInformationByHandle " ) ?;
399399 let fd_num = if let Handle :: File ( fd_num) = file {
400400 fd_num
401401 } else {
402- this. invalid_handle ( "GetFileInformationByHandle " ) ?
402+ this. invalid_handle ( "SetFileInformationByHandle " ) ?
403403 } ;
404404 let Some ( desc) = this. machine . fds . get ( fd_num) else {
405- this. invalid_handle ( "GetFileInformationByHandle " ) ?
405+ this. invalid_handle ( "SetFileInformationByHandle " ) ?
406406 } ;
407407 let file = desc. downcast :: < FileHandle > ( ) . ok_or_else ( || {
408408 err_unsup_format ! (
@@ -411,10 +411,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
411411 } ) ?;
412412
413413 if class == this. eval_windows_u32 ( "c" , "FileEndOfFileInfo" ) {
414- let ptr = this. deref_pointer_as (
415- file_information,
416- this. windows_ty_layout ( "FILE_END_OF_FILE_INFO" ) ,
417- ) ?;
414+ let ptr = this
415+ . ptr_to_mplace ( file_information, this. windows_ty_layout ( "FILE_END_OF_FILE_INFO" ) ) ;
418416 let new_len =
419417 this. read_scalar ( & this. project_field_named ( & ptr, "EndOfFile" ) ?) ?. to_i64 ( ) ?;
420418 match file. file . set_len ( new_len. try_into ( ) . unwrap ( ) ) {
@@ -424,6 +422,35 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
424422 interp_ok ( this. eval_windows ( "c" , "FALSE" ) )
425423 }
426424 }
425+ } else if class == this. eval_windows_u32 ( "c" , "FileAllocationInfo" ) {
426+ // File allocation size is independent of file EOF position on Windows, except that
427+ // EOF must be <= allocation size. So we only do something if the file is bigger than
428+ // the requested allocation size.
429+ let ptr = this
430+ . ptr_to_mplace ( file_information, this. windows_ty_layout ( "FILE_ALLOCATION_INFO" ) ) ;
431+ let new_alloc_size: u64 = this
432+ . read_scalar ( & this. project_field_named ( & ptr, "AllocationSize" ) ?) ?
433+ . to_i64 ( ) ?
434+ . try_into ( )
435+ . unwrap ( ) ;
436+ let old_len = match file. file . metadata ( ) {
437+ Ok ( m) => m. len ( ) ,
438+ Err ( e) => {
439+ this. set_last_error ( e) ?;
440+ return interp_ok ( this. eval_windows ( "c" , "FALSE" ) ) ;
441+ }
442+ } ;
443+ if new_alloc_size < old_len {
444+ match file. file . set_len ( new_alloc_size) {
445+ Ok ( _) => interp_ok ( this. eval_windows ( "c" , "TRUE" ) ) ,
446+ Err ( e) => {
447+ this. set_last_error ( e) ?;
448+ interp_ok ( this. eval_windows ( "c" , "FALSE" ) )
449+ }
450+ }
451+ } else {
452+ interp_ok ( this. eval_windows ( "c" , "TRUE" ) )
453+ }
427454 } else {
428455 throw_unsup_format ! (
429456 "SetFileInformationByHandle: Unsupported `FileInformationClass` value {}" ,
0 commit comments