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
;
62 UNICODE_STRING windows
= RTL_CONSTANT_STRING( L
"\\??\\C:\\windows" );
63 UNICODE_STRING system32
= RTL_CONSTANT_STRING( L
"\\??\\C:\\windows\\system32" );
67 InitializeObjectAttributes( &attr
, &windows
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
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 attr
.ObjectName
= &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 /**********************************************************************
231 * wow64_NtCancelSynchronousIoFile
233 NTSTATUS WINAPI
wow64_NtCancelSynchronousIoFile( UINT
*args
)
235 HANDLE handle
= get_handle( &args
);
236 IO_STATUS_BLOCK32
*io_ptr
= get_ptr( &args
);
237 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
242 status
= NtCancelSynchronousIoFile( handle
, (IO_STATUS_BLOCK
*)io_ptr
, iosb_32to64( &io
, io32
));
243 put_iosb( io32
, &io
);
248 /**********************************************************************
251 NTSTATUS WINAPI
wow64_NtCreateFile( UINT
*args
)
253 ULONG
*handle_ptr
= get_ptr( &args
);
254 ACCESS_MASK access
= get_ulong( &args
);
255 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
256 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
257 LARGE_INTEGER
*alloc_size
= get_ptr( &args
);
258 ULONG attributes
= get_ulong( &args
);
259 ULONG sharing
= get_ulong( &args
);
260 ULONG disposition
= get_ulong( &args
);
261 ULONG options
= get_ulong( &args
);
262 void *ea_buffer
= get_ptr( &args
);
263 ULONG ea_length
= get_ulong( &args
);
265 struct object_attr64 attr
;
271 status
= NtCreateFile( &handle
, access
, objattr_32to64_redirect( &attr
, attr32
),
272 iosb_32to64( &io
, io32
), alloc_size
, attributes
,
273 sharing
, disposition
, options
, ea_buffer
, ea_length
);
274 put_handle( handle_ptr
, handle
);
275 put_iosb( io32
, &io
);
280 /**********************************************************************
281 * wow64_NtCreateMailslotFile
283 NTSTATUS WINAPI
wow64_NtCreateMailslotFile( UINT
*args
)
285 ULONG
*handle_ptr
= get_ptr( &args
);
286 ACCESS_MASK access
= get_ulong( &args
);
287 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
288 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
289 ULONG options
= get_ulong( &args
);
290 ULONG quota
= get_ulong( &args
);
291 ULONG msg_size
= get_ulong( &args
);
292 LARGE_INTEGER
*timeout
= get_ptr( &args
);
294 struct object_attr64 attr
;
300 status
= NtCreateMailslotFile( &handle
, access
, objattr_32to64( &attr
, attr32
),
301 iosb_32to64( &io
, io32
), options
, quota
, msg_size
, timeout
);
302 put_handle( handle_ptr
, handle
);
303 put_iosb( io32
, &io
);
308 /**********************************************************************
309 * wow64_NtCreateNamedPipeFile
311 NTSTATUS WINAPI
wow64_NtCreateNamedPipeFile( UINT
*args
)
313 ULONG
*handle_ptr
= get_ptr( &args
);
314 ACCESS_MASK access
= get_ulong( &args
);
315 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
316 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
317 ULONG sharing
= get_ulong( &args
);
318 ULONG dispo
= get_ulong( &args
);
319 ULONG options
= get_ulong( &args
);
320 ULONG pipe_type
= get_ulong( &args
);
321 ULONG read_mode
= get_ulong( &args
);
322 ULONG completion_mode
= get_ulong( &args
);
323 ULONG max_inst
= get_ulong( &args
);
324 ULONG inbound_quota
= get_ulong( &args
);
325 ULONG outbound_quota
= get_ulong( &args
);
326 LARGE_INTEGER
*timeout
= get_ptr( &args
);
328 struct object_attr64 attr
;
334 status
= NtCreateNamedPipeFile( &handle
, access
, objattr_32to64( &attr
, attr32
),
335 iosb_32to64( &io
, io32
), sharing
, dispo
, options
,
336 pipe_type
, read_mode
, completion_mode
, max_inst
,
337 inbound_quota
, outbound_quota
, timeout
);
338 put_handle( handle_ptr
, handle
);
339 put_iosb( io32
, &io
);
344 /**********************************************************************
345 * wow64_NtCreatePagingFile
347 NTSTATUS WINAPI
wow64_NtCreatePagingFile( UINT
*args
)
349 UNICODE_STRING32
*str32
= get_ptr( &args
);
350 LARGE_INTEGER
*min_size
= get_ptr( &args
);
351 LARGE_INTEGER
*max_size
= get_ptr( &args
);
352 LARGE_INTEGER
*actual_size
= get_ptr( &args
);
356 return NtCreatePagingFile( unicode_str_32to64( &str
, str32
), min_size
, max_size
, actual_size
);
360 /**********************************************************************
363 NTSTATUS WINAPI
wow64_NtDeleteFile( UINT
*args
)
365 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
367 struct object_attr64 attr
;
369 return NtDeleteFile( objattr_32to64_redirect( &attr
, attr32
));
373 /**********************************************************************
374 * wow64_NtDeviceIoControlFile
376 NTSTATUS WINAPI
wow64_NtDeviceIoControlFile( UINT
*args
)
378 HANDLE handle
= get_handle( &args
);
379 HANDLE event
= get_handle( &args
);
380 ULONG apc
= get_ulong( &args
);
381 ULONG apc_param
= get_ulong( &args
);
382 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
383 ULONG code
= get_ulong( &args
);
384 void *in_buf
= get_ptr( &args
);
385 ULONG in_len
= get_ulong( &args
);
386 void *out_buf
= get_ptr( &args
);
387 ULONG out_len
= get_ulong( &args
);
392 status
= NtDeviceIoControlFile( handle
, event
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
393 iosb_32to64( &io
, io32
), code
, in_buf
, in_len
, out_buf
, out_len
);
394 put_iosb( io32
, &io
);
399 /**********************************************************************
400 * wow64_NtFlushBuffersFile
402 NTSTATUS WINAPI
wow64_NtFlushBuffersFile( UINT
*args
)
404 HANDLE handle
= get_handle( &args
);
405 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
410 status
= NtFlushBuffersFile( handle
, iosb_32to64( &io
, io32
));
411 put_iosb( io32
, &io
);
416 /**********************************************************************
417 * wow64_NtFsControlFile
419 NTSTATUS WINAPI
wow64_NtFsControlFile( UINT
*args
)
421 HANDLE handle
= get_handle( &args
);
422 HANDLE event
= get_handle( &args
);
423 ULONG apc
= get_ulong( &args
);
424 ULONG apc_param
= get_ulong( &args
);
425 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
426 ULONG code
= get_ulong( &args
);
427 void *in_buf
= get_ptr( &args
);
428 ULONG in_len
= get_ulong( &args
);
429 void *out_buf
= get_ptr( &args
);
430 ULONG out_len
= get_ulong( &args
);
435 status
= NtFsControlFile( handle
, event
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
436 iosb_32to64( &io
, io32
), code
, in_buf
, in_len
, out_buf
, out_len
);
437 put_iosb( io32
, &io
);
442 /**********************************************************************
445 NTSTATUS WINAPI
wow64_NtLockFile( UINT
*args
)
447 HANDLE handle
= get_handle( &args
);
448 HANDLE event
= get_handle( &args
);
449 ULONG apc
= get_ulong( &args
);
450 ULONG apc_param
= get_ulong( &args
);
451 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
452 LARGE_INTEGER
*offset
= get_ptr( &args
);
453 LARGE_INTEGER
*count
= get_ptr( &args
);
454 ULONG
*key
= get_ptr( &args
);
455 BOOLEAN dont_wait
= get_ulong( &args
);
456 BOOLEAN exclusive
= get_ulong( &args
);
461 status
= NtLockFile( handle
, event
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
462 iosb_32to64( &io
, io32
), offset
, count
, key
, dont_wait
, exclusive
);
463 put_iosb( io32
, &io
);
468 /**********************************************************************
469 * wow64_NtNotifyChangeDirectoryFile
471 NTSTATUS WINAPI
wow64_NtNotifyChangeDirectoryFile( UINT
*args
)
473 HANDLE handle
= get_handle( &args
);
474 HANDLE event
= get_handle( &args
);
475 ULONG apc
= get_ulong( &args
);
476 ULONG apc_param
= get_ulong( &args
);
477 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
478 void *buffer
= get_ptr( &args
);
479 ULONG len
= get_ulong( &args
);
480 ULONG filter
= get_ulong( &args
);
481 BOOLEAN subtree
= get_ulong( &args
);
486 status
= NtNotifyChangeDirectoryFile( handle
, event
, apc_32to64( apc
),
487 apc_param_32to64( apc
, apc_param
), iosb_32to64( &io
, io32
),
488 buffer
, len
, filter
, subtree
);
489 put_iosb( io32
, &io
);
494 /**********************************************************************
497 NTSTATUS WINAPI
wow64_NtOpenFile( UINT
*args
)
499 ULONG
*handle_ptr
= get_ptr( &args
);
500 ACCESS_MASK access
= get_ulong( &args
);
501 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
502 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
503 ULONG sharing
= get_ulong( &args
);
504 ULONG options
= get_ulong( &args
);
506 struct object_attr64 attr
;
512 status
= NtOpenFile( &handle
, access
, objattr_32to64_redirect( &attr
, attr32
),
513 iosb_32to64( &io
, io32
), sharing
, options
);
514 put_handle( handle_ptr
, handle
);
515 put_iosb( io32
, &io
);
520 /**********************************************************************
521 * wow64_NtQueryAttributesFile
523 NTSTATUS WINAPI
wow64_NtQueryAttributesFile( UINT
*args
)
525 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
526 FILE_BASIC_INFORMATION
*info
= get_ptr( &args
);
528 struct object_attr64 attr
;
530 return NtQueryAttributesFile( objattr_32to64_redirect( &attr
, attr32
), info
);
534 /**********************************************************************
535 * wow64_NtQueryDirectoryFile
537 NTSTATUS WINAPI
wow64_NtQueryDirectoryFile( UINT
*args
)
539 HANDLE handle
= get_handle( &args
);
540 HANDLE event
= get_handle( &args
);
541 ULONG apc
= get_ulong( &args
);
542 ULONG apc_param
= get_ulong( &args
);
543 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
544 void *buffer
= get_ptr( &args
);
545 ULONG len
= get_ulong( &args
);
546 FILE_INFORMATION_CLASS
class = get_ulong( &args
);
547 BOOLEAN single_entry
= get_ulong( &args
);
548 UNICODE_STRING32
*mask32
= get_ptr( &args
);
549 BOOLEAN restart_scan
= get_ulong( &args
);
555 status
= NtQueryDirectoryFile( handle
, event
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
556 iosb_32to64( &io
, io32
), buffer
, len
, class, single_entry
,
557 unicode_str_32to64( &mask
, mask32
), restart_scan
);
558 put_iosb( io32
, &io
);
563 /**********************************************************************
564 * wow64_NtQueryEaFile
566 NTSTATUS WINAPI
wow64_NtQueryEaFile( UINT
*args
)
568 HANDLE handle
= get_handle( &args
);
569 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
570 void *buffer
= get_ptr( &args
);
571 ULONG len
= get_ulong( &args
);
572 BOOLEAN single_entry
= get_ulong( &args
);
573 void *list
= get_ptr( &args
);
574 ULONG list_len
= get_ulong( &args
);
575 ULONG
*index
= get_ptr( &args
);
576 BOOLEAN restart
= get_ulong( &args
);
581 status
= NtQueryEaFile( handle
, iosb_32to64( &io
, io32
), buffer
, len
,
582 single_entry
, list
, list_len
, index
, restart
);
583 put_iosb( io32
, &io
);
588 /**********************************************************************
589 * wow64_NtQueryFullAttributesFile
591 NTSTATUS WINAPI
wow64_NtQueryFullAttributesFile( UINT
*args
)
593 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
594 FILE_NETWORK_OPEN_INFORMATION
*info
= get_ptr( &args
);
596 struct object_attr64 attr
;
598 return NtQueryFullAttributesFile( objattr_32to64_redirect( &attr
, attr32
), info
);
602 /**********************************************************************
603 * wow64_NtQueryInformationFile
605 NTSTATUS WINAPI
wow64_NtQueryInformationFile( UINT
*args
)
607 HANDLE handle
= get_handle( &args
);
608 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
609 void *info
= get_ptr( &args
);
610 ULONG len
= get_ulong( &args
);
611 FILE_INFORMATION_CLASS
class = get_ulong( &args
);
616 status
= NtQueryInformationFile( handle
, iosb_32to64( &io
, io32
), info
, len
, class );
617 put_iosb( io32
, &io
);
622 /**********************************************************************
623 * wow64_NtQueryVolumeInformationFile
625 NTSTATUS WINAPI
wow64_NtQueryVolumeInformationFile( UINT
*args
)
627 HANDLE handle
= get_handle( &args
);
628 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
629 void *buffer
= get_ptr( &args
);
630 ULONG len
= get_ulong( &args
);
631 FS_INFORMATION_CLASS
class = get_ulong( &args
);
636 status
= NtQueryVolumeInformationFile( handle
, iosb_32to64( &io
, io32
), buffer
, len
, class );
637 put_iosb( io32
, &io
);
642 /**********************************************************************
645 NTSTATUS WINAPI
wow64_NtReadFile( UINT
*args
)
647 HANDLE handle
= get_handle( &args
);
648 HANDLE event
= get_handle( &args
);
649 ULONG apc
= get_ulong( &args
);
650 ULONG apc_param
= get_ulong( &args
);
651 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
652 void *buffer
= get_ptr( &args
);
653 ULONG len
= get_ulong( &args
);
654 LARGE_INTEGER
*offset
= get_ptr( &args
);
655 ULONG
*key
= get_ptr( &args
);
660 status
= NtReadFile( handle
, event
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
661 iosb_32to64( &io
, io32
), buffer
, len
, offset
, key
);
662 put_iosb( io32
, &io
);
667 /**********************************************************************
668 * wow64_NtReadFileScatter
670 NTSTATUS WINAPI
wow64_NtReadFileScatter( UINT
*args
)
672 HANDLE handle
= get_handle( &args
);
673 HANDLE event
= get_handle( &args
);
674 ULONG apc
= get_ulong( &args
);
675 ULONG apc_param
= get_ulong( &args
);
676 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
677 FILE_SEGMENT_ELEMENT
*segments
= get_ptr( &args
);
678 ULONG len
= get_ulong( &args
);
679 LARGE_INTEGER
*offset
= get_ptr( &args
);
680 ULONG
*key
= get_ptr( &args
);
685 status
= NtReadFileScatter( handle
, event
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
686 iosb_32to64( &io
, io32
), segments
, len
, offset
, key
);
687 put_iosb( io32
, &io
);
692 /**********************************************************************
693 * wow64_NtRemoveIoCompletion
695 NTSTATUS WINAPI
wow64_NtRemoveIoCompletion( UINT
*args
)
697 HANDLE handle
= get_handle( &args
);
698 ULONG
*key_ptr
= get_ptr( &args
);
699 ULONG
*value_ptr
= get_ptr( &args
);
700 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
701 LARGE_INTEGER
*timeout
= get_ptr( &args
);
704 ULONG_PTR key
, value
;
707 status
= NtRemoveIoCompletion( handle
, &key
, &value
, iosb_32to64( &io
, io32
), timeout
);
713 put_iosb( io32
, &io
);
718 /**********************************************************************
719 * wow64_NtRemoveIoCompletionEx
721 NTSTATUS WINAPI
wow64_NtRemoveIoCompletionEx( UINT
*args
)
723 HANDLE handle
= get_handle( &args
);
724 FILE_IO_COMPLETION_INFORMATION32
*info32
= get_ptr( &args
);
725 ULONG count
= get_ulong( &args
);
726 ULONG
*written
= get_ptr( &args
);
727 LARGE_INTEGER
*timeout
= get_ptr( &args
);
728 BOOLEAN alertable
= get_ulong( &args
);
732 FILE_IO_COMPLETION_INFORMATION
*info
= Wow64AllocateTemp( count
* sizeof(*info
) );
734 status
= NtRemoveIoCompletionEx( handle
, info
, count
, written
, timeout
, alertable
);
735 for (i
= 0; i
< *written
; i
++)
737 info32
[i
].CompletionKey
= info
[i
].CompletionKey
;
738 info32
[i
].CompletionValue
= info
[i
].CompletionValue
;
739 info32
[i
].IoStatusBlock
.Status
= info
[i
].IoStatusBlock
.Status
;
740 info32
[i
].IoStatusBlock
.Information
= info
[i
].IoStatusBlock
.Information
;
746 /**********************************************************************
749 NTSTATUS WINAPI
wow64_NtSetEaFile( UINT
*args
)
751 HANDLE handle
= get_handle( &args
);
752 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
753 void *ptr
= get_ptr( &args
);
754 ULONG len
= get_ulong( &args
);
759 status
= NtSetEaFile( handle
, iosb_32to64( &io
, io32
), ptr
, len
);
760 put_iosb( io32
, &io
);
765 /**********************************************************************
766 * wow64_NtSetInformationFile
768 NTSTATUS WINAPI
wow64_NtSetInformationFile( UINT
*args
)
770 HANDLE handle
= get_handle( &args
);
771 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
772 void *ptr
= get_ptr( &args
);
773 ULONG len
= get_ulong( &args
);
774 FILE_INFORMATION_CLASS
class = get_ulong( &args
);
781 case FileBasicInformation
: /* FILE_BASIC_INFORMATION */
782 case FilePositionInformation
: /* FILE_POSITION_INFORMATION */
783 case FileEndOfFileInformation
: /* FILE_END_OF_FILE_INFORMATION */
784 case FilePipeInformation
: /* FILE_PIPE_INFORMATION */
785 case FileMailslotSetInformation
: /* FILE_MAILSLOT_SET_INFORMATION */
786 case FileIoCompletionNotificationInformation
: /* FILE_IO_COMPLETION_NOTIFICATION_INFORMATION */
787 case FileIoPriorityHintInformation
: /* FILE_IO_PRIORITY_HINT_INFO */
788 case FileValidDataLengthInformation
: /* FILE_VALID_DATA_LENGTH_INFORMATION */
789 case FileDispositionInformation
: /* FILE_DISPOSITION_INFORMATION */
790 status
= NtSetInformationFile( handle
, iosb_32to64( &io
, io32
), ptr
, len
, class );
793 case FileRenameInformation
: /* FILE_RENAME_INFORMATION */
794 case FileLinkInformation
: /* FILE_LINK_INFORMATION */
795 if (len
>= sizeof(FILE_RENAME_INFORMATION32
))
797 OBJECT_ATTRIBUTES attr
;
799 FILE_RENAME_INFORMATION32
*info32
= ptr
;
800 FILE_RENAME_INFORMATION
*info
;
803 name
.Buffer
= info32
->FileName
;
804 name
.Length
= info32
->FileNameLength
;
805 InitializeObjectAttributes( &attr
, &name
, 0, LongToHandle( info32
->RootDirectory
), 0 );
806 get_file_redirect( &attr
);
807 size
= offsetof( FILE_RENAME_INFORMATION
, FileName
[name
.Length
/sizeof(WCHAR
)] );
808 info
= Wow64AllocateTemp( size
);
809 info
->ReplaceIfExists
= info32
->ReplaceIfExists
;
810 info
->RootDirectory
= attr
.RootDirectory
;
811 info
->FileNameLength
= name
.Length
;
812 memcpy( info
->FileName
, name
.Buffer
, info
->FileNameLength
);
813 status
= NtSetInformationFile( handle
, iosb_32to64( &io
, io32
), info
, size
, class );
815 else status
= io
.Status
= STATUS_INVALID_PARAMETER_3
;
818 case FileCompletionInformation
: /* FILE_COMPLETION_INFORMATION */
819 if (len
>= sizeof(FILE_COMPLETION_INFORMATION32
))
821 FILE_COMPLETION_INFORMATION32
*info32
= ptr
;
822 FILE_COMPLETION_INFORMATION info
;
824 info
.CompletionPort
= LongToHandle( info32
->CompletionPort
);
825 info
.CompletionKey
= info32
->CompletionKey
;
826 status
= NtSetInformationFile( handle
, iosb_32to64( &io
, io32
), &info
, sizeof(info
), class );
828 else status
= io
.Status
= STATUS_INVALID_PARAMETER_3
;
832 FIXME( "unsupported class %u\n", class );
833 status
= io
.Status
= STATUS_INVALID_INFO_CLASS
;
836 put_iosb( io32
, &io
);
841 /**********************************************************************
842 * wow64_NtSetVolumeInformationFile
844 NTSTATUS WINAPI
wow64_NtSetVolumeInformationFile( UINT
*args
)
846 HANDLE handle
= get_handle( &args
);
847 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
848 void *ptr
= get_ptr( &args
);
849 ULONG len
= get_ulong( &args
);
850 FS_INFORMATION_CLASS
class = get_ulong( &args
);
855 status
= NtSetVolumeInformationFile( handle
, iosb_32to64( &io
, io32
), ptr
, len
, class );
856 put_iosb( io32
, &io
);
861 /**********************************************************************
864 NTSTATUS WINAPI
wow64_NtUnlockFile( UINT
*args
)
866 HANDLE handle
= get_handle( &args
);
867 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
868 LARGE_INTEGER
*offset
= get_ptr( &args
);
869 LARGE_INTEGER
*count
= get_ptr( &args
);
870 ULONG
*key
= get_ptr( &args
);
875 status
= NtUnlockFile( handle
, iosb_32to64( &io
, io32
), offset
, count
, key
);
876 put_iosb( io32
, &io
);
881 /**********************************************************************
884 NTSTATUS WINAPI
wow64_NtWriteFile( UINT
*args
)
886 HANDLE handle
= get_handle( &args
);
887 HANDLE event
= get_handle( &args
);
888 ULONG apc
= get_ulong( &args
);
889 ULONG apc_param
= get_ulong( &args
);
890 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
891 void *buffer
= get_ptr( &args
);
892 ULONG len
= get_ulong( &args
);
893 LARGE_INTEGER
*offset
= get_ptr( &args
);
894 ULONG
*key
= get_ptr( &args
);
899 status
= NtWriteFile( handle
, event
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
900 iosb_32to64( &io
, io32
), buffer
, len
, offset
, key
);
901 put_iosb( io32
, &io
);
906 /**********************************************************************
907 * wow64_NtWriteFileGather
909 NTSTATUS WINAPI
wow64_NtWriteFileGather( UINT
*args
)
911 HANDLE handle
= get_handle( &args
);
912 HANDLE event
= get_handle( &args
);
913 ULONG apc
= get_ulong( &args
);
914 ULONG apc_param
= get_ulong( &args
);
915 IO_STATUS_BLOCK32
*io32
= get_ptr( &args
);
916 FILE_SEGMENT_ELEMENT
*segments
= get_ptr( &args
);
917 ULONG len
= get_ulong( &args
);
918 LARGE_INTEGER
*offset
= get_ptr( &args
);
919 ULONG
*key
= get_ptr( &args
);
924 status
= NtWriteFileGather( handle
, event
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
925 iosb_32to64( &io
, io32
), segments
, len
, offset
, key
);
926 put_iosb( io32
, &io
);
931 /**********************************************************************
932 * wow64_wine_nt_to_unix_file_name
934 NTSTATUS WINAPI
wow64_wine_nt_to_unix_file_name( UINT
*args
)
936 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
937 char *nameA
= get_ptr( &args
);
938 ULONG
*size
= get_ptr( &args
);
939 UINT disposition
= get_ulong( &args
);
941 struct object_attr64 attr
;
943 return wine_nt_to_unix_file_name( objattr_32to64_redirect( &attr
, attr32
), nameA
, size
, disposition
);
947 /**********************************************************************
948 * wow64_wine_unix_to_nt_file_name
950 NTSTATUS WINAPI
wow64_wine_unix_to_nt_file_name( UINT
*args
)
952 const char *name
= get_ptr( &args
);
953 WCHAR
*buffer
= get_ptr( &args
);
954 ULONG
*size
= get_ptr( &args
);
956 return wine_unix_to_nt_file_name( name
, buffer
, size
);