4 * Copyright 2021 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define WIN32_NO_STATUS
30 #include "wow64_private.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(wow
);
36 static FILE_OBJECTID_BUFFER windir_id
, sysdir_id
;
38 static inline NTSTATUS
get_file_id( HANDLE handle
, FILE_OBJECTID_BUFFER
*id
)
42 return NtFsControlFile( handle
, 0, NULL
, NULL
, &io
, FSCTL_GET_OBJECT_ID
, NULL
, 0, id
, sizeof(*id
) );
45 static inline ULONG
starts_with_path( const WCHAR
*name
, ULONG name_len
, const WCHAR
*prefix
)
47 ULONG len
= wcslen( prefix
);
49 if (name_len
< len
) return 0;
50 if (wcsnicmp( name
, prefix
, len
)) return 0;
51 if (name_len
> len
&& name
[len
] != '\\') return 0;
56 /***********************************************************************
59 void init_file_redirects(void)
61 OBJECT_ATTRIBUTES attr
;
66 InitializeObjectAttributes( &attr
, &nameW
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
67 RtlInitUnicodeString( &nameW
, L
"\\??\\C:\\windows" );
68 if (!NtOpenFile( &handle
, SYNCHRONIZE
| FILE_LIST_DIRECTORY
, &attr
, &io
,
69 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
|
70 FILE_OPEN_FOR_BACKUP_INTENT
| FILE_DIRECTORY_FILE
))
72 get_file_id( handle
, &windir_id
);
75 RtlInitUnicodeString( &nameW
, L
"\\??\\C:\\windows\\system32" );
76 if (!NtOpenFile( &handle
, SYNCHRONIZE
| FILE_LIST_DIRECTORY
, &attr
, &io
,
77 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
|
78 FILE_OPEN_FOR_BACKUP_INTENT
| FILE_DIRECTORY_FILE
))
80 get_file_id( handle
, &sysdir_id
);
86 /***********************************************************************
89 * Helper for get_file_redirect().
91 static BOOL
replace_path( OBJECT_ATTRIBUTES
*attr
, ULONG prefix_len
, const WCHAR
*match
,
92 const WCHAR
*replace_dir
, const WCHAR
*replace_name
)
94 const WCHAR
*name
= attr
->ObjectName
->Buffer
;
95 ULONG match_len
, replace_len
, len
= attr
->ObjectName
->Length
/ sizeof(WCHAR
);
99 if (!starts_with_path( name
+ prefix_len
, len
- prefix_len
, match
)) return FALSE
;
101 match_len
= wcslen( match
);
102 replace_len
= wcslen( replace_dir
);
103 if (replace_name
) replace_len
+= wcslen( replace_name
);
104 str
.Length
= (len
+ replace_len
- match_len
) * sizeof(WCHAR
);
105 str
.MaximumLength
= str
.Length
+ sizeof(WCHAR
);
106 if (!(p
= str
.Buffer
= Wow64AllocateTemp( str
.MaximumLength
))) return FALSE
;
108 memcpy( p
, name
, prefix_len
* sizeof(WCHAR
) );
110 wcscpy( p
, replace_dir
);
114 wcscpy( p
, replace_name
);
117 name
+= prefix_len
+ match_len
;
118 len
-= prefix_len
+ match_len
;
119 memcpy( p
, name
, len
* sizeof(WCHAR
) );
121 *attr
->ObjectName
= str
;
126 /***********************************************************************
129 BOOL
get_file_redirect( OBJECT_ATTRIBUTES
*attr
)
131 static const WCHAR
* const no_redirect
[] =
133 L
"system32\\catroot", L
"system32\\catroot2", L
"system32\\driversstore",
134 L
"system32\\drivers\\etc", L
"system32\\logfiles", L
"system32\\spool"
136 static const WCHAR windirW
[] = L
"\\??\\C:\\windows\\";
137 const WCHAR
*name
= attr
->ObjectName
->Buffer
;
138 unsigned int i
, prefix_len
= 0, len
= attr
->ObjectName
->Length
/ sizeof(WCHAR
);
139 const WCHAR
*syswow64dir
;
140 UNICODE_STRING redir
;
142 if (!len
) return FALSE
;
144 if (!attr
->RootDirectory
)
146 prefix_len
= wcslen( windirW
);
147 if (len
< prefix_len
|| wcsnicmp( name
, windirW
, prefix_len
)) return FALSE
;
151 FILE_OBJECTID_BUFFER id
;
153 if (get_file_id( attr
->RootDirectory
, &id
)) return FALSE
;
154 if (memcmp( &id
, &windir_id
, sizeof(id
) ))
156 if (memcmp( &id
, &sysdir_id
, sizeof(id
) )) return FALSE
;
157 if (NtCurrentTeb()->TlsSlots
[WOW64_TLS_FILESYSREDIR
]) return FALSE
;
158 if (name
[0] == '\\') return FALSE
;
160 /* only check for paths that should NOT be redirected */
161 for (i
= 0; i
< ARRAY_SIZE( no_redirect
); i
++)
162 if (starts_with_path( name
, len
, no_redirect
[i
] + 9 /* "system32\\" */)) return FALSE
;
164 /* redirect everything else */
165 syswow64dir
= get_machine_wow64_dir( current_machine
);
166 redir
.Length
= (wcslen(syswow64dir
) + 1 + len
) * sizeof(WCHAR
);
167 redir
.MaximumLength
= redir
.Length
+ sizeof(WCHAR
);
168 if (!(redir
.Buffer
= Wow64AllocateTemp( redir
.MaximumLength
))) return FALSE
;
169 wcscpy( redir
.Buffer
, syswow64dir
);
170 wcscat( redir
.Buffer
, L
"\\" );
171 memcpy( redir
.Buffer
+ wcslen(redir
.Buffer
), name
, len
* sizeof(WCHAR
) );
172 redir
.Buffer
[redir
.Length
/ sizeof(WCHAR
)] = 0;
173 attr
->RootDirectory
= 0;
174 *attr
->ObjectName
= redir
;
179 /* sysnative is redirected even when redirection is disabled */
181 if (replace_path( attr
, prefix_len
, L
"sysnative", L
"system32", NULL
)) return TRUE
;
183 if (NtCurrentTeb()->TlsSlots
[WOW64_TLS_FILESYSREDIR
]) return FALSE
;
185 for (i
= 0; i
< ARRAY_SIZE( no_redirect
); i
++)
186 if (starts_with_path( name
+ prefix_len
, len
- prefix_len
, no_redirect
[i
] )) return FALSE
;
188 syswow64dir
= get_machine_wow64_dir( current_machine
) + wcslen( windirW
);
189 if (replace_path( attr
, prefix_len
, L
"system32", syswow64dir
, NULL
)) return TRUE
;
190 if (replace_path( attr
, prefix_len
, L
"regedit.exe", syswow64dir
, L
"\\regedit.exe" )) return TRUE
;
195 /**********************************************************************
196 * wow64_NtCancelIoFile
198 NTSTATUS WINAPI
wow64_NtCancelIoFile( UINT
*args
)
200 HANDLE handle
= get_handle( &args
);
201 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
206 status
= NtCancelIoFile( handle
, iosb_32to64( &io
, io32
));
207 put_iosb( io32
, &io
);
212 /**********************************************************************
213 * wow64_NtCancelIoFileEx
215 NTSTATUS WINAPI
wow64_NtCancelIoFileEx( UINT
*args
)
217 HANDLE handle
= get_handle( &args
);
218 IO_STATUS_BLOCK32
*io_ptr
= get_ptr( &args
);
219 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
224 status
= NtCancelIoFileEx( handle
, (IO_STATUS_BLOCK
*)io_ptr
, iosb_32to64( &io
, io32
));
225 put_iosb( io32
, &io
);
230 /**********************************************************************
233 NTSTATUS WINAPI
wow64_NtCreateFile( UINT
*args
)
235 ULONG
*handle_ptr
= get_ptr( &args
);
236 ACCESS_MASK access
= get_ulong( &args
);
237 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
238 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
239 LARGE_INTEGER
*alloc_size
= get_ptr( &args
);
240 ULONG attributes
= get_ulong( &args
);
241 ULONG sharing
= get_ulong( &args
);
242 ULONG disposition
= get_ulong( &args
);
243 ULONG options
= get_ulong( &args
);
244 void *ea_buffer
= get_ptr( &args
);
245 ULONG ea_length
= get_ulong( &args
);
247 struct object_attr64 attr
;
253 status
= NtCreateFile( &handle
, access
, objattr_32to64_redirect( &attr
, attr32
),
254 iosb_32to64( &io
, io32
), alloc_size
, attributes
,
255 sharing
, disposition
, options
, ea_buffer
, ea_length
);
256 put_handle( handle_ptr
, handle
);
257 put_iosb( io32
, &io
);
262 /**********************************************************************
263 * wow64_NtCreateMailslotFile
265 NTSTATUS WINAPI
wow64_NtCreateMailslotFile( UINT
*args
)
267 ULONG
*handle_ptr
= get_ptr( &args
);
268 ACCESS_MASK access
= get_ulong( &args
);
269 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
270 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
271 ULONG options
= get_ulong( &args
);
272 ULONG quota
= get_ulong( &args
);
273 ULONG msg_size
= get_ulong( &args
);
274 LARGE_INTEGER
*timeout
= get_ptr( &args
);
276 struct object_attr64 attr
;
282 status
= NtCreateMailslotFile( &handle
, access
, objattr_32to64( &attr
, attr32
),
283 iosb_32to64( &io
, io32
), options
, quota
, msg_size
, timeout
);
284 put_handle( handle_ptr
, handle
);
285 put_iosb( io32
, &io
);
290 /**********************************************************************
291 * wow64_NtCreateNamedPipeFile
293 NTSTATUS WINAPI
wow64_NtCreateNamedPipeFile( UINT
*args
)
295 ULONG
*handle_ptr
= get_ptr( &args
);
296 ACCESS_MASK access
= get_ulong( &args
);
297 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
298 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
299 ULONG sharing
= get_ulong( &args
);
300 ULONG dispo
= get_ulong( &args
);
301 ULONG options
= get_ulong( &args
);
302 ULONG pipe_type
= get_ulong( &args
);
303 ULONG read_mode
= get_ulong( &args
);
304 ULONG completion_mode
= get_ulong( &args
);
305 ULONG max_inst
= get_ulong( &args
);
306 ULONG inbound_quota
= get_ulong( &args
);
307 ULONG outbound_quota
= get_ulong( &args
);
308 LARGE_INTEGER
*timeout
= get_ptr( &args
);
310 struct object_attr64 attr
;
316 status
= NtCreateNamedPipeFile( &handle
, access
, objattr_32to64( &attr
, attr32
),
317 iosb_32to64( &io
, io32
), sharing
, dispo
, options
,
318 pipe_type
, read_mode
, completion_mode
, max_inst
,
319 inbound_quota
, outbound_quota
, timeout
);
320 put_handle( handle_ptr
, handle
);
321 put_iosb( io32
, &io
);
326 /**********************************************************************
327 * wow64_NtCreatePagingFile
329 NTSTATUS WINAPI
wow64_NtCreatePagingFile( UINT
*args
)
331 UNICODE_STRING32
*str32
= get_ptr( &args
);
332 LARGE_INTEGER
*min_size
= get_ptr( &args
);
333 LARGE_INTEGER
*max_size
= get_ptr( &args
);
334 LARGE_INTEGER
*actual_size
= get_ptr( &args
);
338 return NtCreatePagingFile( unicode_str_32to64( &str
, str32
), min_size
, max_size
, actual_size
);
342 /**********************************************************************
345 NTSTATUS WINAPI
wow64_NtDeleteFile( UINT
*args
)
347 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
349 struct object_attr64 attr
;
351 return NtDeleteFile( objattr_32to64_redirect( &attr
, attr32
));
355 /**********************************************************************
356 * wow64_NtDeviceIoControlFile
358 NTSTATUS WINAPI
wow64_NtDeviceIoControlFile( UINT
*args
)
360 HANDLE handle
= get_handle( &args
);
361 HANDLE event
= get_handle( &args
);
362 ULONG apc
= get_ulong( &args
);
363 ULONG apc_param
= get_ulong( &args
);
364 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
365 ULONG code
= get_ulong( &args
);
366 void *in_buf
= get_ptr( &args
);
367 ULONG in_len
= get_ulong( &args
);
368 void *out_buf
= get_ptr( &args
);
369 ULONG out_len
= get_ulong( &args
);
374 status
= NtDeviceIoControlFile( handle
, event
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
375 iosb_32to64( &io
, io32
), code
, in_buf
, in_len
, out_buf
, out_len
);
376 put_iosb( io32
, &io
);
381 /**********************************************************************
382 * wow64_NtFlushBuffersFile
384 NTSTATUS WINAPI
wow64_NtFlushBuffersFile( UINT
*args
)
386 HANDLE handle
= get_handle( &args
);
387 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
392 status
= NtFlushBuffersFile( handle
, iosb_32to64( &io
, io32
));
393 put_iosb( io32
, &io
);
398 /**********************************************************************
399 * wow64_NtFsControlFile
401 NTSTATUS WINAPI
wow64_NtFsControlFile( UINT
*args
)
403 HANDLE handle
= get_handle( &args
);
404 HANDLE event
= get_handle( &args
);
405 ULONG apc
= get_ulong( &args
);
406 ULONG apc_param
= get_ulong( &args
);
407 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
408 ULONG code
= get_ulong( &args
);
409 void *in_buf
= get_ptr( &args
);
410 ULONG in_len
= get_ulong( &args
);
411 void *out_buf
= get_ptr( &args
);
412 ULONG out_len
= get_ulong( &args
);
417 status
= NtFsControlFile( handle
, event
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
418 iosb_32to64( &io
, io32
), code
, in_buf
, in_len
, out_buf
, out_len
);
419 put_iosb( io32
, &io
);
424 /**********************************************************************
427 NTSTATUS WINAPI
wow64_NtLockFile( UINT
*args
)
429 HANDLE handle
= get_handle( &args
);
430 HANDLE event
= get_handle( &args
);
431 ULONG apc
= get_ulong( &args
);
432 ULONG apc_param
= get_ulong( &args
);
433 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
434 LARGE_INTEGER
*offset
= get_ptr( &args
);
435 LARGE_INTEGER
*count
= get_ptr( &args
);
436 ULONG
*key
= get_ptr( &args
);
437 BOOLEAN dont_wait
= get_ulong( &args
);
438 BOOLEAN exclusive
= get_ulong( &args
);
443 status
= NtLockFile( handle
, event
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
444 iosb_32to64( &io
, io32
), offset
, count
, key
, dont_wait
, exclusive
);
445 put_iosb( io32
, &io
);
450 /**********************************************************************
451 * wow64_NtNotifyChangeDirectoryFile
453 NTSTATUS WINAPI
wow64_NtNotifyChangeDirectoryFile( UINT
*args
)
455 HANDLE handle
= get_handle( &args
);
456 HANDLE event
= get_handle( &args
);
457 ULONG apc
= get_ulong( &args
);
458 ULONG apc_param
= get_ulong( &args
);
459 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
460 void *buffer
= get_ptr( &args
);
461 ULONG len
= get_ulong( &args
);
462 ULONG filter
= get_ulong( &args
);
463 BOOLEAN subtree
= get_ulong( &args
);
468 status
= NtNotifyChangeDirectoryFile( handle
, event
, apc_32to64( apc
),
469 apc_param_32to64( apc
, apc_param
), iosb_32to64( &io
, io32
),
470 buffer
, len
, filter
, subtree
);
471 put_iosb( io32
, &io
);
476 /**********************************************************************
479 NTSTATUS WINAPI
wow64_NtOpenFile( UINT
*args
)
481 ULONG
*handle_ptr
= get_ptr( &args
);
482 ACCESS_MASK access
= get_ulong( &args
);
483 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
484 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
485 ULONG sharing
= get_ulong( &args
);
486 ULONG options
= get_ulong( &args
);
488 struct object_attr64 attr
;
494 status
= NtOpenFile( &handle
, access
, objattr_32to64_redirect( &attr
, attr32
),
495 iosb_32to64( &io
, io32
), sharing
, options
);
496 put_handle( handle_ptr
, handle
);
497 put_iosb( io32
, &io
);
502 /**********************************************************************
503 * wow64_NtQueryAttributesFile
505 NTSTATUS WINAPI
wow64_NtQueryAttributesFile( UINT
*args
)
507 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
508 FILE_BASIC_INFORMATION
*info
= get_ptr( &args
);
510 struct object_attr64 attr
;
512 return NtQueryAttributesFile( objattr_32to64_redirect( &attr
, attr32
), info
);
516 /**********************************************************************
517 * wow64_NtQueryDirectoryFile
519 NTSTATUS WINAPI
wow64_NtQueryDirectoryFile( UINT
*args
)
521 HANDLE handle
= get_handle( &args
);
522 HANDLE event
= get_handle( &args
);
523 ULONG apc
= get_ulong( &args
);
524 ULONG apc_param
= get_ulong( &args
);
525 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
526 void *buffer
= get_ptr( &args
);
527 ULONG len
= get_ulong( &args
);
528 FILE_INFORMATION_CLASS
class = get_ulong( &args
);
529 BOOLEAN single_entry
= get_ulong( &args
);
530 UNICODE_STRING32
*mask32
= get_ptr( &args
);
531 BOOLEAN restart_scan
= get_ulong( &args
);
537 status
= NtQueryDirectoryFile( handle
, event
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
538 iosb_32to64( &io
, io32
), buffer
, len
, class, single_entry
,
539 unicode_str_32to64( &mask
, mask32
), restart_scan
);
540 put_iosb( io32
, &io
);
545 /**********************************************************************
546 * wow64_NtQueryEaFile
548 NTSTATUS WINAPI
wow64_NtQueryEaFile( UINT
*args
)
550 HANDLE handle
= get_handle( &args
);
551 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
552 void *buffer
= get_ptr( &args
);
553 ULONG len
= get_ulong( &args
);
554 BOOLEAN single_entry
= get_ulong( &args
);
555 void *list
= get_ptr( &args
);
556 ULONG list_len
= get_ulong( &args
);
557 ULONG
*index
= get_ptr( &args
);
558 BOOLEAN restart
= get_ulong( &args
);
563 status
= NtQueryEaFile( handle
, iosb_32to64( &io
, io32
), buffer
, len
,
564 single_entry
, list
, list_len
, index
, restart
);
565 put_iosb( io32
, &io
);
570 /**********************************************************************
571 * wow64_NtQueryFullAttributesFile
573 NTSTATUS WINAPI
wow64_NtQueryFullAttributesFile( UINT
*args
)
575 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
576 FILE_NETWORK_OPEN_INFORMATION
*info
= get_ptr( &args
);
578 struct object_attr64 attr
;
580 return NtQueryFullAttributesFile( objattr_32to64_redirect( &attr
, attr32
), info
);
584 /**********************************************************************
585 * wow64_NtQueryInformationFile
587 NTSTATUS WINAPI
wow64_NtQueryInformationFile( UINT
*args
)
589 HANDLE handle
= get_handle( &args
);
590 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
591 void *info
= get_ptr( &args
);
592 ULONG len
= get_ulong( &args
);
593 FILE_INFORMATION_CLASS
class = get_ulong( &args
);
598 status
= NtQueryInformationFile( handle
, iosb_32to64( &io
, io32
), info
, len
, class );
599 put_iosb( io32
, &io
);
604 /**********************************************************************
605 * wow64_NtQueryVolumeInformationFile
607 NTSTATUS WINAPI
wow64_NtQueryVolumeInformationFile( UINT
*args
)
609 HANDLE handle
= get_handle( &args
);
610 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
611 void *buffer
= get_ptr( &args
);
612 ULONG len
= get_ulong( &args
);
613 FS_INFORMATION_CLASS
class = get_ulong( &args
);
618 status
= NtQueryVolumeInformationFile( handle
, iosb_32to64( &io
, io32
), buffer
, len
, class );
619 put_iosb( io32
, &io
);
624 /**********************************************************************
627 NTSTATUS WINAPI
wow64_NtReadFile( UINT
*args
)
629 HANDLE handle
= get_handle( &args
);
630 HANDLE event
= get_handle( &args
);
631 ULONG apc
= get_ulong( &args
);
632 ULONG apc_param
= get_ulong( &args
);
633 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
634 void *buffer
= get_ptr( &args
);
635 ULONG len
= get_ulong( &args
);
636 LARGE_INTEGER
*offset
= get_ptr( &args
);
637 ULONG
*key
= get_ptr( &args
);
642 status
= NtReadFile( handle
, event
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
643 iosb_32to64( &io
, io32
), buffer
, len
, offset
, key
);
644 put_iosb( io32
, &io
);
649 /**********************************************************************
650 * wow64_NtReadFileScatter
652 NTSTATUS WINAPI
wow64_NtReadFileScatter( UINT
*args
)
654 HANDLE handle
= get_handle( &args
);
655 HANDLE event
= get_handle( &args
);
656 ULONG apc
= get_ulong( &args
);
657 ULONG apc_param
= get_ulong( &args
);
658 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
659 FILE_SEGMENT_ELEMENT
*segments
= get_ptr( &args
);
660 ULONG len
= get_ulong( &args
);
661 LARGE_INTEGER
*offset
= get_ptr( &args
);
662 ULONG
*key
= get_ptr( &args
);
667 status
= NtReadFileScatter( handle
, event
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
668 iosb_32to64( &io
, io32
), segments
, len
, offset
, key
);
669 put_iosb( io32
, &io
);
674 /**********************************************************************
675 * wow64_NtRemoveIoCompletion
677 NTSTATUS WINAPI
wow64_NtRemoveIoCompletion( UINT
*args
)
679 HANDLE handle
= get_handle( &args
);
680 ULONG
*key_ptr
= get_ptr( &args
);
681 ULONG
*value_ptr
= get_ptr( &args
);
682 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
683 LARGE_INTEGER
*timeout
= get_ptr( &args
);
686 ULONG_PTR key
, value
;
689 status
= NtRemoveIoCompletion( handle
, &key
, &value
, iosb_32to64( &io
, io32
), timeout
);
695 put_iosb( io32
, &io
);
700 /**********************************************************************
701 * wow64_NtRemoveIoCompletionEx
703 NTSTATUS WINAPI
wow64_NtRemoveIoCompletionEx( UINT
*args
)
705 HANDLE handle
= get_handle( &args
);
706 FILE_IO_COMPLETION_INFORMATION32
*info32
= get_ptr( &args
);
707 ULONG count
= get_ulong( &args
);
708 ULONG
*written
= get_ptr( &args
);
709 LARGE_INTEGER
*timeout
= get_ptr( &args
);
710 BOOLEAN alertable
= get_ulong( &args
);
714 FILE_IO_COMPLETION_INFORMATION
*info
= Wow64AllocateTemp( count
* sizeof(*info
) );
716 status
= NtRemoveIoCompletionEx( handle
, info
, count
, written
, timeout
, alertable
);
717 for (i
= 0; i
< *written
; i
++)
719 info32
[i
].CompletionKey
= info
[i
].CompletionKey
;
720 info32
[i
].CompletionValue
= info
[i
].CompletionValue
;
721 info32
[i
].IoStatusBlock
.Status
= info
[i
].IoStatusBlock
.Status
;
722 info32
[i
].IoStatusBlock
.Information
= info
[i
].IoStatusBlock
.Information
;
728 /**********************************************************************
731 NTSTATUS WINAPI
wow64_NtSetEaFile( UINT
*args
)
733 HANDLE handle
= get_handle( &args
);
734 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
735 void *ptr
= get_ptr( &args
);
736 ULONG len
= get_ulong( &args
);
741 status
= NtSetEaFile( handle
, iosb_32to64( &io
, io32
), ptr
, len
);
742 put_iosb( io32
, &io
);
747 /**********************************************************************
748 * wow64_NtSetInformationFile
750 NTSTATUS WINAPI
wow64_NtSetInformationFile( UINT
*args
)
752 HANDLE handle
= get_handle( &args
);
753 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
754 void *ptr
= get_ptr( &args
);
755 ULONG len
= get_ulong( &args
);
756 FILE_INFORMATION_CLASS
class = get_ulong( &args
);
763 case FileBasicInformation
: /* FILE_BASIC_INFORMATION */
764 case FilePositionInformation
: /* FILE_POSITION_INFORMATION */
765 case FileEndOfFileInformation
: /* FILE_END_OF_FILE_INFORMATION */
766 case FilePipeInformation
: /* FILE_PIPE_INFORMATION */
767 case FileMailslotSetInformation
: /* FILE_MAILSLOT_SET_INFORMATION */
768 case FileIoCompletionNotificationInformation
: /* FILE_IO_COMPLETION_NOTIFICATION_INFORMATION */
769 case FileIoPriorityHintInformation
: /* FILE_IO_PRIORITY_HINT_INFO */
770 case FileValidDataLengthInformation
: /* FILE_VALID_DATA_LENGTH_INFORMATION */
771 case FileDispositionInformation
: /* FILE_DISPOSITION_INFORMATION */
772 status
= NtSetInformationFile( handle
, iosb_32to64( &io
, io32
), ptr
, len
, class );
775 case FileRenameInformation
: /* FILE_RENAME_INFORMATION */
776 case FileLinkInformation
: /* FILE_LINK_INFORMATION */
777 if (len
>= sizeof(FILE_RENAME_INFORMATION32
))
779 OBJECT_ATTRIBUTES attr
;
781 FILE_RENAME_INFORMATION32
*info32
= ptr
;
782 FILE_RENAME_INFORMATION
*info
;
785 name
.Buffer
= info32
->FileName
;
786 name
.Length
= info32
->FileNameLength
;
787 InitializeObjectAttributes( &attr
, &name
, 0, LongToHandle( info32
->RootDirectory
), 0 );
788 get_file_redirect( &attr
);
789 size
= offsetof( FILE_RENAME_INFORMATION
, FileName
[name
.Length
/sizeof(WCHAR
)] );
790 info
= Wow64AllocateTemp( size
);
791 info
->ReplaceIfExists
= info32
->ReplaceIfExists
;
792 info
->RootDirectory
= attr
.RootDirectory
;
793 info
->FileNameLength
= name
.Length
;
794 memcpy( info
->FileName
, name
.Buffer
, info
->FileNameLength
);
795 status
= NtSetInformationFile( handle
, iosb_32to64( &io
, io32
), info
, size
, class );
797 else status
= io
.Status
= STATUS_INVALID_PARAMETER_3
;
800 case FileCompletionInformation
: /* FILE_COMPLETION_INFORMATION */
801 if (len
>= sizeof(FILE_COMPLETION_INFORMATION32
))
803 FILE_COMPLETION_INFORMATION32
*info32
= ptr
;
804 FILE_COMPLETION_INFORMATION info
;
806 info
.CompletionPort
= LongToHandle( info32
->CompletionPort
);
807 info
.CompletionKey
= info32
->CompletionKey
;
808 status
= NtSetInformationFile( handle
, iosb_32to64( &io
, io32
), &info
, sizeof(info
), class );
810 else status
= io
.Status
= STATUS_INVALID_PARAMETER_3
;
814 FIXME( "unsupported class %u\n", class );
815 status
= io
.Status
= STATUS_INVALID_INFO_CLASS
;
818 put_iosb( io32
, &io
);
823 /**********************************************************************
824 * wow64_NtSetVolumeInformationFile
826 NTSTATUS WINAPI
wow64_NtSetVolumeInformationFile( UINT
*args
)
828 HANDLE handle
= get_handle( &args
);
829 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
830 void *ptr
= get_ptr( &args
);
831 ULONG len
= get_ulong( &args
);
832 FS_INFORMATION_CLASS
class = get_ulong( &args
);
837 status
= NtSetVolumeInformationFile( handle
, iosb_32to64( &io
, io32
), ptr
, len
, class );
838 put_iosb( io32
, &io
);
843 /**********************************************************************
846 NTSTATUS WINAPI
wow64_NtUnlockFile( UINT
*args
)
848 HANDLE handle
= get_handle( &args
);
849 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
850 LARGE_INTEGER
*offset
= get_ptr( &args
);
851 LARGE_INTEGER
*count
= get_ptr( &args
);
852 ULONG
*key
= get_ptr( &args
);
857 status
= NtUnlockFile( handle
, iosb_32to64( &io
, io32
), offset
, count
, key
);
858 put_iosb( io32
, &io
);
863 /**********************************************************************
866 NTSTATUS WINAPI
wow64_NtWriteFile( UINT
*args
)
868 HANDLE handle
= get_handle( &args
);
869 HANDLE event
= get_handle( &args
);
870 ULONG apc
= get_ulong( &args
);
871 ULONG apc_param
= get_ulong( &args
);
872 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
873 void *buffer
= get_ptr( &args
);
874 ULONG len
= get_ulong( &args
);
875 LARGE_INTEGER
*offset
= get_ptr( &args
);
876 ULONG
*key
= get_ptr( &args
);
881 status
= NtWriteFile( handle
, event
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
882 iosb_32to64( &io
, io32
), buffer
, len
, offset
, key
);
883 put_iosb( io32
, &io
);
888 /**********************************************************************
889 * wow64_NtWriteFileGather
891 NTSTATUS WINAPI
wow64_NtWriteFileGather( UINT
*args
)
893 HANDLE handle
= get_handle( &args
);
894 HANDLE event
= get_handle( &args
);
895 ULONG apc
= get_ulong( &args
);
896 ULONG apc_param
= get_ulong( &args
);
897 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
898 FILE_SEGMENT_ELEMENT
*segments
= get_ptr( &args
);
899 ULONG len
= get_ulong( &args
);
900 LARGE_INTEGER
*offset
= get_ptr( &args
);
901 ULONG
*key
= get_ptr( &args
);
906 status
= NtWriteFileGather( handle
, event
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
907 iosb_32to64( &io
, io32
), segments
, len
, offset
, key
);
908 put_iosb( io32
, &io
);
913 /**********************************************************************
914 * wow64_wine_nt_to_unix_file_name
916 NTSTATUS WINAPI
wow64_wine_nt_to_unix_file_name( UINT
*args
)
918 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
919 char *nameA
= get_ptr( &args
);
920 ULONG
*size
= get_ptr( &args
);
921 UINT disposition
= get_ulong( &args
);
923 struct object_attr64 attr
;
925 return wine_nt_to_unix_file_name( objattr_32to64_redirect( &attr
, attr32
), nameA
, size
, disposition
);
929 /**********************************************************************
930 * wow64_wine_server_fd_to_handle
932 NTSTATUS WINAPI
wow64_wine_server_fd_to_handle( UINT
*args
)
934 int fd
= get_ulong( &args
);
935 ACCESS_MASK access
= get_ulong( &args
);
936 ULONG attributes
= get_ulong( &args
);
937 ULONG
*handle_ptr
= get_ptr( &args
);
943 status
= wine_server_fd_to_handle( fd
, access
, attributes
, &handle
);
944 put_handle( handle_ptr
, handle
);
949 /**********************************************************************
950 * wow64_wine_server_handle_to_fd
952 NTSTATUS WINAPI
wow64_wine_server_handle_to_fd( UINT
*args
)
954 HANDLE handle
= get_handle( &args
);
955 ACCESS_MASK access
= get_ulong( &args
);
956 int *unix_fd
= get_ptr( &args
);
957 unsigned int *options
= get_ptr( &args
);
959 return wine_server_handle_to_fd( handle
, access
, unix_fd
, options
);
963 /**********************************************************************
964 * wow64_wine_unix_to_nt_file_name
966 NTSTATUS WINAPI
wow64_wine_unix_to_nt_file_name( UINT
*args
)
968 const char *name
= get_ptr( &args
);
969 WCHAR
*buffer
= get_ptr( &args
);
970 ULONG
*size
= get_ptr( &args
);
972 return wine_unix_to_nt_file_name( name
, buffer
, size
);