@@ -9,6 +9,7 @@ use crate::*;
9
9
#[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
10
10
pub enum PseudoHandle {
11
11
CurrentThread ,
12
+ CurrentProcess ,
12
13
}
13
14
14
15
/// Miri representation of a Windows `HANDLE`
@@ -23,16 +24,19 @@ pub enum Handle {
23
24
24
25
impl PseudoHandle {
25
26
const CURRENT_THREAD_VALUE : u32 = 0 ;
27
+ const CURRENT_PROCESS_VALUE : u32 = 1 ;
26
28
27
29
fn value ( self ) -> u32 {
28
30
match self {
29
31
Self :: CurrentThread => Self :: CURRENT_THREAD_VALUE ,
32
+ Self :: CurrentProcess => Self :: CURRENT_PROCESS_VALUE ,
30
33
}
31
34
}
32
35
33
36
fn from_value ( value : u32 ) -> Option < Self > {
34
37
match value {
35
38
Self :: CURRENT_THREAD_VALUE => Some ( Self :: CurrentThread ) ,
39
+ Self :: CURRENT_PROCESS_VALUE => Some ( Self :: CurrentProcess ) ,
36
40
_ => None ,
37
41
}
38
42
}
@@ -244,6 +248,76 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
244
248
interp_ok ( handle. to_scalar ( this) )
245
249
}
246
250
251
+ fn DuplicateHandle (
252
+ & mut self ,
253
+ src_proc : & OpTy < ' tcx > , // HANDLE
254
+ src_handle : & OpTy < ' tcx > , // HANDLE
255
+ target_proc : & OpTy < ' tcx > , // HANDLE
256
+ target_handle : & OpTy < ' tcx > , // LPHANDLE
257
+ desired_access : & OpTy < ' tcx > , // DWORD
258
+ inherit : & OpTy < ' tcx > , // BOOL
259
+ options : & OpTy < ' tcx > , // DWORD
260
+ ) -> InterpResult < ' tcx , Scalar > {
261
+ // ^ Returns BOOL (i32 on Windows)
262
+ let this = self . eval_context_mut ( ) ;
263
+
264
+ let src_proc = this. read_handle ( src_proc, "DuplicateHandle" ) ?;
265
+ let src_handle = this. read_handle ( src_handle, "DuplicateHandle" ) ?;
266
+ let target_proc = this. read_handle ( target_proc, "DuplicateHandle" ) ?;
267
+ let target_handle_ptr = this. read_pointer ( target_handle) ?;
268
+ // Since we only support DUPLICATE_SAME_ACCESS, this value is ignored, but should be valid
269
+ let _ = this. read_scalar ( desired_access) ?. to_u32 ( ) ?;
270
+ // We don't support the CreateProcess API, so inheritable or not means nothing.
271
+ // If we ever add CreateProcess support, this will need to be implemented.
272
+ let _ = this. read_scalar ( inherit) ?;
273
+ let options = this. read_scalar ( options) ?;
274
+
275
+ if src_proc != Handle :: Pseudo ( PseudoHandle :: CurrentProcess ) {
276
+ throw_unsup_format ! (
277
+ "`DuplicateHandle` `hSourceProcessHandle` parameter is not the current process, which is unsupported"
278
+ ) ;
279
+ }
280
+
281
+ if target_proc != Handle :: Pseudo ( PseudoHandle :: CurrentProcess ) {
282
+ throw_unsup_format ! (
283
+ "`DuplicateHandle` `hSourceProcessHandle` parameter is not the current process, which is unsupported"
284
+ ) ;
285
+ }
286
+
287
+ if this. ptr_is_null ( target_handle_ptr) ? {
288
+ throw_unsup_format ! (
289
+ "`DuplicateHandle` `lpTargetHandle` parameter is null, which is unsupported"
290
+ ) ;
291
+ }
292
+
293
+ if options != this. eval_windows ( "c" , "DUPLICATE_SAME_ACCESS" ) {
294
+ throw_unsup_format ! (
295
+ "`DuplicateHandle` `dwOptions` parameter is not `DUPLICATE_SAME_ACCESS`, which is unsupported"
296
+ ) ;
297
+ }
298
+
299
+ let new_handle = match src_handle {
300
+ Handle :: File ( old_fd_num) => {
301
+ let Some ( fd) = this. machine . fds . get ( old_fd_num) else {
302
+ this. invalid_handle ( "DuplicateHandle" ) ?
303
+ } ;
304
+ Handle :: File ( this. machine . fds . insert ( fd) )
305
+ }
306
+ Handle :: Thread ( _) => {
307
+ throw_unsup_format ! (
308
+ "`DuplicateHandle` called on a thread handle, which is unsupported"
309
+ ) ;
310
+ }
311
+ Handle :: Pseudo ( pseudo) => Handle :: Pseudo ( pseudo) ,
312
+ Handle :: Null | Handle :: Invalid => this. invalid_handle ( "DuplicateHandle" ) ?,
313
+ } ;
314
+
315
+ let target_place = this. deref_pointer_as ( target_handle, this. machine . layouts . usize ) ?;
316
+ this. write_scalar ( new_handle. to_scalar ( this) , & target_place) ?;
317
+
318
+ interp_ok ( this. eval_windows ( "c" , "TRUE" ) )
319
+ }
320
+
247
321
fn CloseHandle ( & mut self , handle_op : & OpTy < ' tcx > ) -> InterpResult < ' tcx , Scalar > {
248
322
let this = self . eval_context_mut ( ) ;
249
323
0 commit comments