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