@@ -195,69 +195,52 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
195195
196196 // File related shims
197197 "NtWriteFile" => {
198- if !this. frame_in_std ( ) {
199- throw_unsup_format ! (
200- "`NtWriteFile` support is crude and just enough for stdout to work"
201- ) ;
202- }
203-
204198 let [
205199 handle,
206- _event ,
207- _apc_routine ,
208- _apc_context ,
200+ event ,
201+ apc_routine ,
202+ apc_context ,
209203 io_status_block,
210204 buf,
211205 n,
212206 byte_offset,
213- _key ,
207+ key ,
214208 ] = this. check_shim ( abi, sys_conv, link_name, args) ?;
215- let handle = this. read_target_isize ( handle) ?;
216- let buf = this. read_pointer ( buf) ?;
217- let n = this. read_scalar ( n) ?. to_u32 ( ) ?;
218- let byte_offset = this. read_target_usize ( byte_offset) ?; // is actually a pointer
219- let io_status_block = this
220- . deref_pointer_as ( io_status_block, this. windows_ty_layout ( "IO_STATUS_BLOCK" ) ) ?;
221-
222- if byte_offset != 0 {
223- throw_unsup_format ! (
224- "`NtWriteFile` `ByteOffset` parameter is non-null, which is unsupported"
225- ) ;
226- }
227-
228- let written = if handle == -11 || handle == -12 {
229- // stdout/stderr
230- use io:: Write ;
231-
232- let buf_cont =
233- this. read_bytes_ptr_strip_provenance ( buf, Size :: from_bytes ( u64:: from ( n) ) ) ?;
234- let res = if this. machine . mute_stdout_stderr {
235- Ok ( buf_cont. len ( ) )
236- } else if handle == -11 {
237- io:: stdout ( ) . write ( buf_cont)
238- } else {
239- io:: stderr ( ) . write ( buf_cont)
240- } ;
241- // We write at most `n` bytes, which is a `u32`, so we cannot have written more than that.
242- res. ok ( ) . map ( |n| u32:: try_from ( n) . unwrap ( ) )
243- } else {
244- throw_unsup_format ! (
245- "on Windows, writing to anything except stdout/stderr is not supported"
246- )
247- } ;
248- // We have to put the result into io_status_block.
249- if let Some ( n) = written {
250- let io_status_information =
251- this. project_field_named ( & io_status_block, "Information" ) ?;
252- this. write_scalar (
253- Scalar :: from_target_usize ( n. into ( ) , this) ,
254- & io_status_information,
255- ) ?;
256- }
257- // Return whether this was a success. >= 0 is success.
258- // For the error code we arbitrarily pick 0xC0000185, STATUS_IO_DEVICE_ERROR.
259- this. write_scalar (
260- Scalar :: from_u32 ( if written. is_some ( ) { 0 } else { 0xC0000185u32 } ) ,
209+ this. NtWriteFile (
210+ handle,
211+ event,
212+ apc_routine,
213+ apc_context,
214+ io_status_block,
215+ buf,
216+ n,
217+ byte_offset,
218+ key,
219+ dest,
220+ ) ?;
221+ }
222+ "NtReadFile" => {
223+ let [
224+ handle,
225+ event,
226+ apc_routine,
227+ apc_context,
228+ io_status_block,
229+ buf,
230+ n,
231+ byte_offset,
232+ key,
233+ ] = this. check_shim ( abi, sys_conv, link_name, args) ?;
234+ this. NtReadFile (
235+ handle,
236+ event,
237+ apc_routine,
238+ apc_context,
239+ io_status_block,
240+ buf,
241+ n,
242+ byte_offset,
243+ key,
261244 dest,
262245 ) ?;
263246 }
@@ -322,6 +305,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
322305 let res = this. DeleteFileW ( file_name) ?;
323306 this. write_scalar ( res, dest) ?;
324307 }
308+ "SetFilePointerEx" => {
309+ let [ file, distance_to_move, new_file_pointer, move_method] =
310+ this. check_shim ( abi, sys_conv, link_name, args) ?;
311+ let res =
312+ this. SetFilePointerEx ( file, distance_to_move, new_file_pointer, move_method) ?;
313+ this. write_scalar ( res, dest) ?;
314+ }
325315
326316 // Allocation
327317 "HeapAlloc" => {
@@ -700,12 +690,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
700690 }
701691 "GetStdHandle" => {
702692 let [ which] = this. check_shim ( abi, sys_conv, link_name, args) ?;
703- let which = this. read_scalar ( which) ?. to_i32 ( ) ?;
704- // We just make this the identity function, so we know later in `NtWriteFile` which
705- // one it is. This is very fake, but libtest needs it so we cannot make it a
706- // std-only shim.
707- // FIXME: this should return real HANDLEs when io support is added
708- this. write_scalar ( Scalar :: from_target_isize ( which. into ( ) , this) , dest) ?;
693+ let res = this. GetStdHandle ( which) ?;
694+ this. write_scalar ( res, dest) ?;
709695 }
710696 "CloseHandle" => {
711697 let [ handle] = this. check_shim ( abi, sys_conv, link_name, args) ?;
0 commit comments