cmd: DIR command outputs free space for the path.
[wine.git] / dlls / wow64 / file.c
blobfc867f79f2815a5fedd14cef758103a1ea0baa47
1 /*
2 * WoW64 file functions
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
21 #include <stdarg.h>
23 #include "ntstatus.h"
24 #define WIN32_NO_STATUS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winnt.h"
28 #include "winternl.h"
29 #include "winioctl.h"
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 )
40 IO_STATUS_BLOCK io;
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;
52 return len;
56 /***********************************************************************
57 * init_file_redirects
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" );
64 IO_STATUS_BLOCK io;
65 HANDLE handle;
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 );
73 NtClose( handle );
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 );
81 NtClose( handle );
86 /***********************************************************************
87 * replace_path
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);
96 UNICODE_STRING str;
97 WCHAR *p;
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) );
109 p += prefix_len;
110 wcscpy( p, replace_dir );
111 p += wcslen(p);
112 if (replace_name)
114 wcscpy( p, replace_name );
115 p += wcslen(p);
117 name += prefix_len + match_len;
118 len -= prefix_len + match_len;
119 memcpy( p, name, len * sizeof(WCHAR) );
120 p[len] = 0;
121 *attr->ObjectName = str;
122 return TRUE;
126 /***********************************************************************
127 * get_file_redirect
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;
149 else
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;
175 return TRUE;
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;
191 return FALSE;
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 );
203 IO_STATUS_BLOCK io;
204 NTSTATUS status;
206 status = NtCancelIoFile( handle, iosb_32to64( &io, io32 ));
207 put_iosb( io32, &io );
208 return status;
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 );
221 IO_STATUS_BLOCK io;
222 NTSTATUS status;
224 status = NtCancelIoFileEx( handle, (IO_STATUS_BLOCK *)io_ptr, iosb_32to64( &io, io32 ));
225 put_iosb( io32, &io );
226 return status;
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 );
239 IO_STATUS_BLOCK io;
240 NTSTATUS status;
242 status = NtCancelSynchronousIoFile( handle, (IO_STATUS_BLOCK *)io_ptr, iosb_32to64( &io, io32 ));
243 put_iosb( io32, &io );
244 return status;
248 /**********************************************************************
249 * wow64_NtCreateFile
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;
266 IO_STATUS_BLOCK io;
267 HANDLE handle = 0;
268 NTSTATUS status;
270 *handle_ptr = 0;
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 );
276 return status;
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;
295 IO_STATUS_BLOCK io;
296 HANDLE handle = 0;
297 NTSTATUS status;
299 *handle_ptr = 0;
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 );
304 return status;
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;
329 IO_STATUS_BLOCK io;
330 HANDLE handle = 0;
331 NTSTATUS status;
333 *handle_ptr = 0;
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 );
340 return status;
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 );
354 UNICODE_STRING str;
356 return NtCreatePagingFile( unicode_str_32to64( &str, str32 ), min_size, max_size, actual_size );
360 /**********************************************************************
361 * wow64_NtDeleteFile
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 );
389 IO_STATUS_BLOCK io;
390 NTSTATUS status;
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 );
395 return status;
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 );
407 IO_STATUS_BLOCK io;
408 NTSTATUS status;
410 status = NtFlushBuffersFile( handle, iosb_32to64( &io, io32 ));
411 put_iosb( io32, &io );
412 return status;
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 );
432 IO_STATUS_BLOCK io;
433 NTSTATUS status;
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 );
438 return status;
442 /**********************************************************************
443 * wow64_NtLockFile
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 );
458 IO_STATUS_BLOCK io;
459 NTSTATUS status;
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 );
464 return status;
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 );
483 IO_STATUS_BLOCK io;
484 NTSTATUS status;
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 );
490 return status;
494 /**********************************************************************
495 * wow64_NtOpenFile
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;
507 IO_STATUS_BLOCK io;
508 HANDLE handle = 0;
509 NTSTATUS status;
511 *handle_ptr = 0;
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 );
516 return status;
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 );
551 UNICODE_STRING mask;
552 IO_STATUS_BLOCK io;
553 NTSTATUS status;
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 );
559 return status;
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 );
578 IO_STATUS_BLOCK io;
579 NTSTATUS status;
581 status = NtQueryEaFile( handle, iosb_32to64( &io, io32 ), buffer, len,
582 single_entry, list, list_len, index, restart );
583 put_iosb( io32, &io );
584 return status;
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 );
613 IO_STATUS_BLOCK io;
614 NTSTATUS status;
616 status = NtQueryInformationFile( handle, iosb_32to64( &io, io32 ), info, len, class );
617 put_iosb( io32, &io );
618 return status;
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 );
633 IO_STATUS_BLOCK io;
634 NTSTATUS status;
636 status = NtQueryVolumeInformationFile( handle, iosb_32to64( &io, io32 ), buffer, len, class );
637 put_iosb( io32, &io );
638 return status;
642 /**********************************************************************
643 * wow64_NtReadFile
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 );
657 IO_STATUS_BLOCK io;
658 NTSTATUS status;
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 );
663 return status;
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 );
682 IO_STATUS_BLOCK io;
683 NTSTATUS status;
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 );
688 return status;
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 );
703 IO_STATUS_BLOCK io;
704 ULONG_PTR key, value;
705 NTSTATUS status;
707 status = NtRemoveIoCompletion( handle, &key, &value, iosb_32to64( &io, io32 ), timeout );
708 if (!status)
710 *key_ptr = key;
711 *value_ptr = value;
713 put_iosb( io32, &io );
714 return status;
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 );
730 NTSTATUS status;
731 ULONG i;
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;
742 return status;
746 /**********************************************************************
747 * wow64_NtSetEaFile
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 );
756 IO_STATUS_BLOCK io;
757 NTSTATUS status;
759 status = NtSetEaFile( handle, iosb_32to64( &io, io32 ), ptr, len );
760 put_iosb( io32, &io );
761 return status;
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 );
776 IO_STATUS_BLOCK io;
777 NTSTATUS status;
779 switch (class)
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 case FileDispositionInformationEx: /* FILE_DISPOSITION_INFORMATION_EX */
791 status = NtSetInformationFile( handle, iosb_32to64( &io, io32 ), ptr, len, class );
792 break;
794 case FileRenameInformation: /* FILE_RENAME_INFORMATION */
795 case FileLinkInformation: /* FILE_LINK_INFORMATION */
796 if (len >= sizeof(FILE_RENAME_INFORMATION32))
798 OBJECT_ATTRIBUTES attr;
799 UNICODE_STRING name;
800 FILE_RENAME_INFORMATION32 *info32 = ptr;
801 FILE_RENAME_INFORMATION *info;
802 ULONG size;
804 name.Buffer = info32->FileName;
805 name.Length = info32->FileNameLength;
806 InitializeObjectAttributes( &attr, &name, 0, LongToHandle( info32->RootDirectory ), 0 );
807 get_file_redirect( &attr );
808 size = offsetof( FILE_RENAME_INFORMATION, FileName[name.Length/sizeof(WCHAR)] );
809 info = Wow64AllocateTemp( size );
810 info->ReplaceIfExists = info32->ReplaceIfExists;
811 info->RootDirectory = attr.RootDirectory;
812 info->FileNameLength = name.Length;
813 memcpy( info->FileName, name.Buffer, info->FileNameLength );
814 status = NtSetInformationFile( handle, iosb_32to64( &io, io32 ), info, size, class );
816 else status = io.Status = STATUS_INVALID_PARAMETER_3;
817 break;
819 case FileCompletionInformation: /* FILE_COMPLETION_INFORMATION */
820 if (len >= sizeof(FILE_COMPLETION_INFORMATION32))
822 FILE_COMPLETION_INFORMATION32 *info32 = ptr;
823 FILE_COMPLETION_INFORMATION info;
825 info.CompletionPort = LongToHandle( info32->CompletionPort );
826 info.CompletionKey = info32->CompletionKey;
827 status = NtSetInformationFile( handle, iosb_32to64( &io, io32 ), &info, sizeof(info), class );
829 else status = io.Status = STATUS_INVALID_PARAMETER_3;
830 break;
832 default:
833 FIXME( "unsupported class %u\n", class );
834 status = io.Status = STATUS_INVALID_INFO_CLASS;
835 break;
837 put_iosb( io32, &io );
838 return status;
842 /**********************************************************************
843 * wow64_NtSetVolumeInformationFile
845 NTSTATUS WINAPI wow64_NtSetVolumeInformationFile( UINT *args )
847 HANDLE handle = get_handle( &args );
848 IO_STATUS_BLOCK32 *io32 = get_ptr( &args );
849 void *ptr = get_ptr( &args );
850 ULONG len = get_ulong( &args );
851 FS_INFORMATION_CLASS class = get_ulong( &args );
853 IO_STATUS_BLOCK io;
854 NTSTATUS status;
856 status = NtSetVolumeInformationFile( handle, iosb_32to64( &io, io32 ), ptr, len, class );
857 put_iosb( io32, &io );
858 return status;
862 /**********************************************************************
863 * wow64_NtUnlockFile
865 NTSTATUS WINAPI wow64_NtUnlockFile( UINT *args )
867 HANDLE handle = get_handle( &args );
868 IO_STATUS_BLOCK32 *io32 = get_ptr( &args );
869 LARGE_INTEGER *offset = get_ptr( &args );
870 LARGE_INTEGER *count = get_ptr( &args );
871 ULONG *key = get_ptr( &args );
873 IO_STATUS_BLOCK io;
874 NTSTATUS status;
876 status = NtUnlockFile( handle, iosb_32to64( &io, io32 ), offset, count, key );
877 put_iosb( io32, &io );
878 return status;
882 /**********************************************************************
883 * wow64_NtWriteFile
885 NTSTATUS WINAPI wow64_NtWriteFile( UINT *args )
887 HANDLE handle = get_handle( &args );
888 HANDLE event = get_handle( &args );
889 ULONG apc = get_ulong( &args );
890 ULONG apc_param = get_ulong( &args );
891 IO_STATUS_BLOCK32 *io32 = get_ptr( &args );
892 void *buffer = get_ptr( &args );
893 ULONG len = get_ulong( &args );
894 LARGE_INTEGER *offset = get_ptr( &args );
895 ULONG *key = get_ptr( &args );
897 IO_STATUS_BLOCK io;
898 NTSTATUS status;
900 status = NtWriteFile( handle, event, apc_32to64( apc ), apc_param_32to64( apc, apc_param ),
901 iosb_32to64( &io, io32 ), buffer, len, offset, key );
902 put_iosb( io32, &io );
903 return status;
907 /**********************************************************************
908 * wow64_NtWriteFileGather
910 NTSTATUS WINAPI wow64_NtWriteFileGather( UINT *args )
912 HANDLE handle = get_handle( &args );
913 HANDLE event = get_handle( &args );
914 ULONG apc = get_ulong( &args );
915 ULONG apc_param = get_ulong( &args );
916 IO_STATUS_BLOCK32 *io32 = get_ptr( &args );
917 FILE_SEGMENT_ELEMENT *segments = get_ptr( &args );
918 ULONG len = get_ulong( &args );
919 LARGE_INTEGER *offset = get_ptr( &args );
920 ULONG *key = get_ptr( &args );
922 IO_STATUS_BLOCK io;
923 NTSTATUS status;
925 status = NtWriteFileGather( handle, event, apc_32to64( apc ), apc_param_32to64( apc, apc_param ),
926 iosb_32to64( &io, io32 ), segments, len, offset, key );
927 put_iosb( io32, &io );
928 return status;
932 /**********************************************************************
933 * wow64_wine_nt_to_unix_file_name
935 NTSTATUS WINAPI wow64_wine_nt_to_unix_file_name( UINT *args )
937 OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args );
938 char *nameA = get_ptr( &args );
939 ULONG *size = get_ptr( &args );
940 UINT disposition = get_ulong( &args );
942 struct object_attr64 attr;
944 return wine_nt_to_unix_file_name( objattr_32to64_redirect( &attr, attr32 ), nameA, size, disposition );
948 /**********************************************************************
949 * wow64_wine_unix_to_nt_file_name
951 NTSTATUS WINAPI wow64_wine_unix_to_nt_file_name( UINT *args )
953 const char *name = get_ptr( &args );
954 WCHAR *buffer = get_ptr( &args );
955 ULONG *size = get_ptr( &args );
957 return wine_unix_to_nt_file_name( name, buffer, size );