@@ -136,6 +136,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
136
136
let result = this. GetUserProfileDirectoryW ( token, buf, size) ?;
137
137
this. write_scalar ( result, dest) ?;
138
138
}
139
+ "GetCurrentProcess" => {
140
+ let [ ] =
141
+ this. check_shim ( abi, ExternAbi :: System { unwind : false } , link_name, args) ?;
142
+ this. write_scalar (
143
+ Handle :: Pseudo ( PseudoHandle :: CurrentProcess ) . to_scalar ( this) ,
144
+ dest,
145
+ ) ?;
146
+ }
139
147
"GetCurrentProcessId" => {
140
148
let [ ] =
141
149
this. check_shim ( abi, ExternAbi :: System { unwind : false } , link_name, args) ?;
@@ -145,71 +153,54 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
145
153
146
154
// File related shims
147
155
"NtWriteFile" => {
148
- if !this. frame_in_std ( ) {
149
- throw_unsup_format ! (
150
- "`NtWriteFile` support is crude and just enough for stdout to work"
151
- ) ;
152
- }
153
-
154
156
let [
155
157
handle,
156
- _event ,
157
- _apc_routine ,
158
- _apc_context ,
158
+ event ,
159
+ apc_routine ,
160
+ apc_context ,
159
161
io_status_block,
160
162
buf,
161
163
n,
162
164
byte_offset,
163
- _key ,
165
+ key ,
164
166
] = this. check_shim ( abi, ExternAbi :: System { unwind : false } , link_name, args) ?;
165
- let handle = this. read_target_isize ( handle) ?;
166
- let buf = this. read_pointer ( buf) ?;
167
- let n = this. read_scalar ( n) ?. to_u32 ( ) ?;
168
- let byte_offset = this. read_target_usize ( byte_offset) ?; // is actually a pointer
169
- let io_status_block = this
170
- . deref_pointer_as ( io_status_block, this. windows_ty_layout ( "IO_STATUS_BLOCK" ) ) ?;
171
-
172
- if byte_offset != 0 {
173
- throw_unsup_format ! (
174
- "`NtWriteFile` `ByteOffset` parameter is non-null, which is unsupported"
175
- ) ;
176
- }
177
-
178
- let written = if handle == -11 || handle == -12 {
179
- // stdout/stderr
180
- use io:: Write ;
181
-
182
- let buf_cont =
183
- this. read_bytes_ptr_strip_provenance ( buf, Size :: from_bytes ( u64:: from ( n) ) ) ?;
184
- let res = if this. machine . mute_stdout_stderr {
185
- Ok ( buf_cont. len ( ) )
186
- } else if handle == -11 {
187
- io:: stdout ( ) . write ( buf_cont)
188
- } else {
189
- io:: stderr ( ) . write ( buf_cont)
190
- } ;
191
- // We write at most `n` bytes, which is a `u32`, so we cannot have written more than that.
192
- res. ok ( ) . map ( |n| u32:: try_from ( n) . unwrap ( ) )
193
- } else {
194
- throw_unsup_format ! (
195
- "on Windows, writing to anything except stdout/stderr is not supported"
196
- )
197
- } ;
198
- // We have to put the result into io_status_block.
199
- if let Some ( n) = written {
200
- let io_status_information =
201
- this. project_field_named ( & io_status_block, "Information" ) ?;
202
- this. write_scalar (
203
- Scalar :: from_target_usize ( n. into ( ) , this) ,
204
- & io_status_information,
205
- ) ?;
206
- }
207
- // Return whether this was a success. >= 0 is success.
208
- // For the error code we arbitrarily pick 0xC0000185, STATUS_IO_DEVICE_ERROR.
209
- this. write_scalar (
210
- Scalar :: from_u32 ( if written. is_some ( ) { 0 } else { 0xC0000185u32 } ) ,
211
- dest,
167
+ let res = this. NtWriteFile (
168
+ handle,
169
+ event,
170
+ apc_routine,
171
+ apc_context,
172
+ io_status_block,
173
+ buf,
174
+ n,
175
+ byte_offset,
176
+ key,
177
+ ) ?;
178
+ this. write_scalar ( res, dest) ?;
179
+ }
180
+ "NtReadFile" => {
181
+ let [
182
+ handle,
183
+ event,
184
+ apc_routine,
185
+ apc_context,
186
+ io_status_block,
187
+ buf,
188
+ n,
189
+ byte_offset,
190
+ key,
191
+ ] = this. check_shim ( abi, ExternAbi :: System { unwind : false } , link_name, args) ?;
192
+ let res = this. NtReadFile (
193
+ handle,
194
+ event,
195
+ apc_routine,
196
+ apc_context,
197
+ io_status_block,
198
+ buf,
199
+ n,
200
+ byte_offset,
201
+ key,
212
202
) ?;
203
+ this. write_scalar ( res, dest) ?;
213
204
}
214
205
"GetFullPathNameW" => {
215
206
let [ filename, size, buffer, filepart] =
@@ -268,6 +259,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
268
259
let res = this. GetFileInformationByHandle ( handle, info) ?;
269
260
this. write_scalar ( res, dest) ?;
270
261
}
262
+ "DeleteFileW" => {
263
+ let [ file_name] =
264
+ this. check_shim ( abi, ExternAbi :: System { unwind : false } , link_name, args) ?;
265
+ let res = this. DeleteFileW ( file_name) ?;
266
+ this. write_scalar ( res, dest) ?;
267
+ }
268
+ "SetFilePointerEx" => {
269
+ let [ file, distance_to_move, new_file_pointer, move_method] =
270
+ this. check_shim ( abi, ExternAbi :: System { unwind : false } , link_name, args) ?;
271
+ let res =
272
+ this. SetFilePointerEx ( file, distance_to_move, new_file_pointer, move_method) ?;
273
+ this. write_scalar ( res, dest) ?;
274
+ }
271
275
272
276
// Allocation
273
277
"HeapAlloc" => {
@@ -654,12 +658,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
654
658
"GetStdHandle" => {
655
659
let [ which] =
656
660
this. check_shim ( abi, ExternAbi :: System { unwind : false } , link_name, args) ?;
657
- let which = this. read_scalar ( which) ?. to_i32 ( ) ?;
658
- // We just make this the identity function, so we know later in `NtWriteFile` which
659
- // one it is. This is very fake, but libtest needs it so we cannot make it a
660
- // std-only shim.
661
- // FIXME: this should return real HANDLEs when io support is added
662
- this. write_scalar ( Scalar :: from_target_isize ( which. into ( ) , this) , dest) ?;
661
+ let res = this. GetStdHandle ( which) ?;
662
+ this. write_scalar ( res, dest) ?;
663
663
}
664
664
"CloseHandle" => {
665
665
let [ handle] =
0 commit comments