@@ -432,6 +432,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
432
432
throw_unsup_format ! ( "`NtWriteFile` `Key` parameter is not null, which is unsupported" ) ;
433
433
}
434
434
435
+ // We have to put the result into io_status_block.
436
+ let io_status_information = this. project_field_named ( & io_status_block, "Information" ) ?;
437
+
435
438
let written = match handle {
436
439
Handle :: Pseudo ( pseudo @ ( PseudoHandle :: Stdout | PseudoHandle :: Stderr ) ) => {
437
440
// stdout/stderr
@@ -445,33 +448,39 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
445
448
io:: Write :: write ( & mut io:: stderr ( ) , buf_cont)
446
449
} ;
447
450
// We write at most `n` bytes, which is a `u32`, so we cannot have written more than that.
448
- res. ok ( ) . map ( |n| u32:: try_from ( n) . unwrap ( ) )
451
+ if let Ok ( n) = res {
452
+ this. write_scalar (
453
+ Scalar :: from_target_usize ( n. try_into ( ) . unwrap ( ) , this) ,
454
+ & io_status_information,
455
+ ) ?;
456
+ true
457
+ } else {
458
+ false
459
+ }
449
460
}
450
461
Handle :: File ( fd) => {
451
462
let Some ( desc) = this. machine . fds . get ( fd) else {
452
463
this. invalid_handle ( "NtWriteFile" ) ?
453
464
} ;
454
465
455
- let errno_layout = this. machine . layouts . u32 ;
456
- let out_place = this. allocate ( errno_layout, MiriMemoryKind :: Machine . into ( ) ) ?;
457
- desc. write ( & desc, this. machine . communicate ( ) , buf, n as usize , & out_place, this) ?;
458
- let written = this. read_scalar ( & out_place) ?. to_u32 ( ) ?;
459
- this. deallocate_ptr ( out_place. ptr ( ) , None , MiriMemoryKind :: Machine . into ( ) ) ?;
460
- Some ( written)
466
+ // TODO: Windows expects this function to return its error, not set the global one
467
+ desc. write (
468
+ & desc,
469
+ this. machine . communicate ( ) ,
470
+ buf,
471
+ n as usize ,
472
+ & io_status_information,
473
+ this,
474
+ ) ?;
475
+ let written = this. read_scalar ( & io_status_information) ?. to_i64 ( ) ?;
476
+ written != -1
461
477
}
462
478
_ => this. invalid_handle ( "NtWriteFile" ) ?,
463
479
} ;
464
480
465
- // We have to put the result into io_status_block.
466
- if let Some ( n) = written {
467
- let io_status_information =
468
- this. project_field_named ( & io_status_block, "Information" ) ?;
469
- this. write_scalar ( Scalar :: from_target_usize ( n. into ( ) , this) , & io_status_information) ?;
470
- }
471
-
472
481
// Return whether this was a success. >= 0 is success.
473
482
// For the error code we arbitrarily pick 0xC0000185, STATUS_IO_DEVICE_ERROR.
474
- interp_ok ( Scalar :: from_u32 ( if written. is_some ( ) { 0 } else { 0xC0000185u32 } ) )
483
+ interp_ok ( Scalar :: from_u32 ( if written { 0 } else { 0xC0000185u32 } ) )
475
484
}
476
485
477
486
fn NtReadFile (
@@ -527,40 +536,48 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
527
536
throw_unsup_format ! ( "`NtWriteFile` `Key` parameter is not null, which is unsupported" ) ;
528
537
}
529
538
539
+ let io_status_information = this. project_field_named ( & io_status_block, "Information" ) ?;
540
+
530
541
let read = match handle {
531
542
Handle :: Pseudo ( PseudoHandle :: Stdin ) => {
532
543
// stdout/stderr
533
544
let mut buf_cont = vec ! [ 0u8 ; n as usize ] ;
534
545
let res = io:: Read :: read ( & mut io:: stdin ( ) , & mut buf_cont) ;
535
546
this. write_bytes_ptr ( buf, buf_cont) ?;
536
547
// We write at most `n` bytes, which is a `u32`, so we cannot have written more than that.
537
- res. ok ( ) . map ( |n| u32:: try_from ( n) . unwrap ( ) )
548
+ if let Ok ( n) = res {
549
+ this. write_scalar (
550
+ Scalar :: from_target_usize ( n. try_into ( ) . unwrap ( ) , this) ,
551
+ & io_status_information,
552
+ ) ?;
553
+ true
554
+ } else {
555
+ false
556
+ }
538
557
}
539
558
Handle :: File ( fd) => {
540
559
let Some ( desc) = this. machine . fds . get ( fd) else {
541
560
this. invalid_handle ( "NtReadFile" ) ?
542
561
} ;
543
562
544
- let errno_layout = this. machine . layouts . u32 ;
545
- let out_place = this. allocate ( errno_layout, MiriMemoryKind :: Machine . into ( ) ) ?;
546
- desc. read ( & desc, this. machine . communicate ( ) , buf, n as usize , & out_place, this) ?;
547
- let read = this. read_scalar ( & out_place) ?. to_u32 ( ) ?;
548
- this. deallocate_ptr ( out_place. ptr ( ) , None , MiriMemoryKind :: Machine . into ( ) ) ?;
549
- Some ( read)
563
+ // TODO: Windows expects this function to return its error, not set the global one
564
+ desc. read (
565
+ & desc,
566
+ this. machine . communicate ( ) ,
567
+ buf,
568
+ n as usize ,
569
+ & io_status_information,
570
+ this,
571
+ ) ?;
572
+ let read = this. read_scalar ( & io_status_information) ?. to_i64 ( ) ?;
573
+ read != -1
550
574
}
551
575
_ => this. invalid_handle ( "NtReadFile" ) ?,
552
576
} ;
553
577
554
- // We have to put the result into io_status_block.
555
- if let Some ( n) = read {
556
- let io_status_information =
557
- this. project_field_named ( & io_status_block, "Information" ) ?;
558
- this. write_scalar ( Scalar :: from_target_usize ( n. into ( ) , this) , & io_status_information) ?;
559
- }
560
-
561
578
// Return whether this was a success. >= 0 is success.
562
579
// For the error code we arbitrarily pick 0xC0000185, STATUS_IO_DEVICE_ERROR.
563
- interp_ok ( Scalar :: from_u32 ( if read. is_some ( ) { 0 } else { 0xC0000185u32 } ) )
580
+ interp_ok ( Scalar :: from_u32 ( if read { 0 } else { 0xC0000185u32 } ) )
564
581
}
565
582
566
583
fn SetFilePointerEx (
0 commit comments