include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / wow64 / file.c
blobbdc9f4f2b2c9702746d827a89256f06fff3e001b
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 if (pBTCpuNotifyReadFile) pBTCpuNotifyReadFile( handle, buffer, len, FALSE, 0 );
661 status = NtReadFile( handle, event, apc_32to64( apc ), apc_param_32to64( apc, apc_param ),
662 iosb_32to64( &io, io32 ), buffer, len, offset, key );
663 if (pBTCpuNotifyReadFile) pBTCpuNotifyReadFile( handle, buffer, len, TRUE, status );
664 put_iosb( io32, &io );
665 return status;
669 /**********************************************************************
670 * wow64_NtReadFileScatter
672 NTSTATUS WINAPI wow64_NtReadFileScatter( UINT *args )
674 HANDLE handle = get_handle( &args );
675 HANDLE event = get_handle( &args );
676 ULONG apc = get_ulong( &args );
677 ULONG apc_param = get_ulong( &args );
678 IO_STATUS_BLOCK32 *io32 = get_ptr( &args );
679 FILE_SEGMENT_ELEMENT *segments = get_ptr( &args );
680 ULONG len = get_ulong( &args );
681 LARGE_INTEGER *offset = get_ptr( &args );
682 ULONG *key = get_ptr( &args );
684 IO_STATUS_BLOCK io;
685 NTSTATUS status;
687 status = NtReadFileScatter( handle, event, apc_32to64( apc ), apc_param_32to64( apc, apc_param ),
688 iosb_32to64( &io, io32 ), segments, len, offset, key );
689 put_iosb( io32, &io );
690 return status;
694 /**********************************************************************
695 * wow64_NtRemoveIoCompletion
697 NTSTATUS WINAPI wow64_NtRemoveIoCompletion( UINT *args )
699 HANDLE handle = get_handle( &args );
700 ULONG *key_ptr = get_ptr( &args );
701 ULONG *value_ptr = get_ptr( &args );
702 IO_STATUS_BLOCK32 *io32 = get_ptr( &args );
703 LARGE_INTEGER *timeout = get_ptr( &args );
705 IO_STATUS_BLOCK io;
706 ULONG_PTR key, value;
707 NTSTATUS status;
709 status = NtRemoveIoCompletion( handle, &key, &value, iosb_32to64( &io, io32 ), timeout );
710 if (!status)
712 *key_ptr = key;
713 *value_ptr = value;
715 put_iosb( io32, &io );
716 return status;
720 /**********************************************************************
721 * wow64_NtRemoveIoCompletionEx
723 NTSTATUS WINAPI wow64_NtRemoveIoCompletionEx( UINT *args )
725 HANDLE handle = get_handle( &args );
726 FILE_IO_COMPLETION_INFORMATION32 *info32 = get_ptr( &args );
727 ULONG count = get_ulong( &args );
728 ULONG *written = get_ptr( &args );
729 LARGE_INTEGER *timeout = get_ptr( &args );
730 BOOLEAN alertable = get_ulong( &args );
732 NTSTATUS status;
733 ULONG i;
734 FILE_IO_COMPLETION_INFORMATION *info = Wow64AllocateTemp( count * sizeof(*info) );
736 status = NtRemoveIoCompletionEx( handle, info, count, written, timeout, alertable );
737 for (i = 0; i < *written; i++)
739 info32[i].CompletionKey = info[i].CompletionKey;
740 info32[i].CompletionValue = info[i].CompletionValue;
741 info32[i].IoStatusBlock.Status = info[i].IoStatusBlock.Status;
742 info32[i].IoStatusBlock.Information = info[i].IoStatusBlock.Information;
744 return status;
748 /**********************************************************************
749 * wow64_NtSetEaFile
751 NTSTATUS WINAPI wow64_NtSetEaFile( UINT *args )
753 HANDLE handle = get_handle( &args );
754 IO_STATUS_BLOCK32 *io32 = get_ptr( &args );
755 void *ptr = get_ptr( &args );
756 ULONG len = get_ulong( &args );
758 IO_STATUS_BLOCK io;
759 NTSTATUS status;
761 status = NtSetEaFile( handle, iosb_32to64( &io, io32 ), ptr, len );
762 put_iosb( io32, &io );
763 return status;
767 /**********************************************************************
768 * wow64_NtSetInformationFile
770 NTSTATUS WINAPI wow64_NtSetInformationFile( UINT *args )
772 HANDLE handle = get_handle( &args );
773 IO_STATUS_BLOCK32 *io32 = get_ptr( &args );
774 void *ptr = get_ptr( &args );
775 ULONG len = get_ulong( &args );
776 FILE_INFORMATION_CLASS class = get_ulong( &args );
778 IO_STATUS_BLOCK io;
779 NTSTATUS status;
781 switch (class)
783 case FileBasicInformation: /* FILE_BASIC_INFORMATION */
784 case FilePositionInformation: /* FILE_POSITION_INFORMATION */
785 case FileEndOfFileInformation: /* FILE_END_OF_FILE_INFORMATION */
786 case FilePipeInformation: /* FILE_PIPE_INFORMATION */
787 case FileMailslotSetInformation: /* FILE_MAILSLOT_SET_INFORMATION */
788 case FileIoCompletionNotificationInformation: /* FILE_IO_COMPLETION_NOTIFICATION_INFORMATION */
789 case FileIoPriorityHintInformation: /* FILE_IO_PRIORITY_HINT_INFO */
790 case FileValidDataLengthInformation: /* FILE_VALID_DATA_LENGTH_INFORMATION */
791 case FileDispositionInformation: /* FILE_DISPOSITION_INFORMATION */
792 case FileDispositionInformationEx: /* FILE_DISPOSITION_INFORMATION_EX */
793 status = NtSetInformationFile( handle, iosb_32to64( &io, io32 ), ptr, len, class );
794 break;
796 case FileRenameInformation: /* FILE_RENAME_INFORMATION */
797 case FileRenameInformationEx: /* FILE_RENAME_INFORMATION */
798 case FileLinkInformation: /* FILE_LINK_INFORMATION */
799 case FileLinkInformationEx: /* FILE_LINK_INFORMATION */
800 if (len >= sizeof(FILE_RENAME_INFORMATION32))
802 OBJECT_ATTRIBUTES attr;
803 UNICODE_STRING name;
804 FILE_RENAME_INFORMATION32 *info32 = ptr;
805 FILE_RENAME_INFORMATION *info;
806 ULONG size;
808 name.Buffer = info32->FileName;
809 name.Length = info32->FileNameLength;
810 InitializeObjectAttributes( &attr, &name, 0, LongToHandle( info32->RootDirectory ), 0 );
811 get_file_redirect( &attr );
812 size = offsetof( FILE_RENAME_INFORMATION, FileName[name.Length/sizeof(WCHAR)] );
813 info = Wow64AllocateTemp( size );
814 info->Flags = info32->Flags;
815 info->RootDirectory = attr.RootDirectory;
816 info->FileNameLength = name.Length;
817 memcpy( info->FileName, name.Buffer, info->FileNameLength );
818 status = NtSetInformationFile( handle, iosb_32to64( &io, io32 ), info, size, class );
820 else status = io.Status = STATUS_INVALID_PARAMETER_3;
821 break;
823 case FileCompletionInformation: /* FILE_COMPLETION_INFORMATION */
824 if (len >= sizeof(FILE_COMPLETION_INFORMATION32))
826 FILE_COMPLETION_INFORMATION32 *info32 = ptr;
827 FILE_COMPLETION_INFORMATION info;
829 info.CompletionPort = LongToHandle( info32->CompletionPort );
830 info.CompletionKey = info32->CompletionKey;
831 status = NtSetInformationFile( handle, iosb_32to64( &io, io32 ), &info, sizeof(info), class );
833 else status = io.Status = STATUS_INVALID_PARAMETER_3;
834 break;
836 default:
837 FIXME( "unsupported class %u\n", class );
838 status = io.Status = STATUS_INVALID_INFO_CLASS;
839 break;
841 put_iosb( io32, &io );
842 return status;
846 /**********************************************************************
847 * wow64_NtSetVolumeInformationFile
849 NTSTATUS WINAPI wow64_NtSetVolumeInformationFile( UINT *args )
851 HANDLE handle = get_handle( &args );
852 IO_STATUS_BLOCK32 *io32 = get_ptr( &args );
853 void *ptr = get_ptr( &args );
854 ULONG len = get_ulong( &args );
855 FS_INFORMATION_CLASS class = get_ulong( &args );
857 IO_STATUS_BLOCK io;
858 NTSTATUS status;
860 status = NtSetVolumeInformationFile( handle, iosb_32to64( &io, io32 ), ptr, len, class );
861 put_iosb( io32, &io );
862 return status;
866 /**********************************************************************
867 * wow64_NtUnlockFile
869 NTSTATUS WINAPI wow64_NtUnlockFile( UINT *args )
871 HANDLE handle = get_handle( &args );
872 IO_STATUS_BLOCK32 *io32 = get_ptr( &args );
873 LARGE_INTEGER *offset = get_ptr( &args );
874 LARGE_INTEGER *count = get_ptr( &args );
875 ULONG *key = get_ptr( &args );
877 IO_STATUS_BLOCK io;
878 NTSTATUS status;
880 status = NtUnlockFile( handle, iosb_32to64( &io, io32 ), offset, count, key );
881 put_iosb( io32, &io );
882 return status;
886 /**********************************************************************
887 * wow64_NtWriteFile
889 NTSTATUS WINAPI wow64_NtWriteFile( UINT *args )
891 HANDLE handle = get_handle( &args );
892 HANDLE event = get_handle( &args );
893 ULONG apc = get_ulong( &args );
894 ULONG apc_param = get_ulong( &args );
895 IO_STATUS_BLOCK32 *io32 = get_ptr( &args );
896 void *buffer = get_ptr( &args );
897 ULONG len = get_ulong( &args );
898 LARGE_INTEGER *offset = get_ptr( &args );
899 ULONG *key = get_ptr( &args );
901 IO_STATUS_BLOCK io;
902 NTSTATUS status;
904 status = NtWriteFile( handle, event, apc_32to64( apc ), apc_param_32to64( apc, apc_param ),
905 iosb_32to64( &io, io32 ), buffer, len, offset, key );
906 put_iosb( io32, &io );
907 return status;
911 /**********************************************************************
912 * wow64_NtWriteFileGather
914 NTSTATUS WINAPI wow64_NtWriteFileGather( UINT *args )
916 HANDLE handle = get_handle( &args );
917 HANDLE event = get_handle( &args );
918 ULONG apc = get_ulong( &args );
919 ULONG apc_param = get_ulong( &args );
920 IO_STATUS_BLOCK32 *io32 = get_ptr( &args );
921 FILE_SEGMENT_ELEMENT *segments = get_ptr( &args );
922 ULONG len = get_ulong( &args );
923 LARGE_INTEGER *offset = get_ptr( &args );
924 ULONG *key = get_ptr( &args );
926 IO_STATUS_BLOCK io;
927 NTSTATUS status;
929 status = NtWriteFileGather( handle, event, apc_32to64( apc ), apc_param_32to64( apc, apc_param ),
930 iosb_32to64( &io, io32 ), segments, len, offset, key );
931 put_iosb( io32, &io );
932 return status;
936 /**********************************************************************
937 * wow64_wine_nt_to_unix_file_name
939 NTSTATUS WINAPI wow64_wine_nt_to_unix_file_name( UINT *args )
941 OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args );
942 char *nameA = get_ptr( &args );
943 ULONG *size = get_ptr( &args );
944 UINT disposition = get_ulong( &args );
946 struct object_attr64 attr;
948 return wine_nt_to_unix_file_name( objattr_32to64_redirect( &attr, attr32 ), nameA, size, disposition );
952 /**********************************************************************
953 * wow64_wine_unix_to_nt_file_name
955 NTSTATUS WINAPI wow64_wine_unix_to_nt_file_name( UINT *args )
957 const char *name = get_ptr( &args );
958 WCHAR *buffer = get_ptr( &args );
959 ULONG *size = get_ptr( &args );
961 return wine_unix_to_nt_file_name( name, buffer, size );