d2d1: Create feature level 10.0 device context state objects.
[wine.git] / dlls / wow64 / file.c
blob7d1c736e48cb05fd1a58ee18b9740ccfc0fc7e97
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 nameW;
63 IO_STATUS_BLOCK io;
64 HANDLE handle;
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 );
73 NtClose( handle );
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 );
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_NtCreateFile
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;
248 IO_STATUS_BLOCK io;
249 HANDLE handle = 0;
250 NTSTATUS status;
252 *handle_ptr = 0;
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 );
258 return status;
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;
277 IO_STATUS_BLOCK io;
278 HANDLE handle = 0;
279 NTSTATUS status;
281 *handle_ptr = 0;
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 );
286 return status;
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;
311 IO_STATUS_BLOCK io;
312 HANDLE handle = 0;
313 NTSTATUS status;
315 *handle_ptr = 0;
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 );
322 return status;
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 );
336 UNICODE_STRING str;
338 return NtCreatePagingFile( unicode_str_32to64( &str, str32 ), min_size, max_size, actual_size );
342 /**********************************************************************
343 * wow64_NtDeleteFile
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 );
371 IO_STATUS_BLOCK io;
372 NTSTATUS status;
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 );
377 return status;
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 );
389 IO_STATUS_BLOCK io;
390 NTSTATUS status;
392 status = NtFlushBuffersFile( handle, iosb_32to64( &io, io32 ));
393 put_iosb( io32, &io );
394 return status;
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 );
414 IO_STATUS_BLOCK io;
415 NTSTATUS status;
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 );
420 return status;
424 /**********************************************************************
425 * wow64_NtLockFile
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 );
440 IO_STATUS_BLOCK io;
441 NTSTATUS status;
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 );
446 return status;
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 );
465 IO_STATUS_BLOCK io;
466 NTSTATUS status;
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 );
472 return status;
476 /**********************************************************************
477 * wow64_NtOpenFile
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;
489 IO_STATUS_BLOCK io;
490 HANDLE handle = 0;
491 NTSTATUS status;
493 *handle_ptr = 0;
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 );
498 return status;
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 );
533 UNICODE_STRING mask;
534 IO_STATUS_BLOCK io;
535 NTSTATUS status;
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 );
541 return status;
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 );
560 IO_STATUS_BLOCK io;
561 NTSTATUS status;
563 status = NtQueryEaFile( handle, iosb_32to64( &io, io32 ), buffer, len,
564 single_entry, list, list_len, index, restart );
565 put_iosb( io32, &io );
566 return status;
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 );
595 IO_STATUS_BLOCK io;
596 NTSTATUS status;
598 status = NtQueryInformationFile( handle, iosb_32to64( &io, io32 ), info, len, class );
599 put_iosb( io32, &io );
600 return status;
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 );
615 IO_STATUS_BLOCK io;
616 NTSTATUS status;
618 status = NtQueryVolumeInformationFile( handle, iosb_32to64( &io, io32 ), buffer, len, class );
619 put_iosb( io32, &io );
620 return status;
624 /**********************************************************************
625 * wow64_NtReadFile
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 );
639 IO_STATUS_BLOCK io;
640 NTSTATUS status;
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 );
645 return status;
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 );
664 IO_STATUS_BLOCK io;
665 NTSTATUS status;
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 );
670 return status;
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 );
685 IO_STATUS_BLOCK io;
686 ULONG_PTR key, value;
687 NTSTATUS status;
689 status = NtRemoveIoCompletion( handle, &key, &value, iosb_32to64( &io, io32 ), timeout );
690 if (!status)
692 *key_ptr = key;
693 *value_ptr = value;
695 put_iosb( io32, &io );
696 return status;
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 );
712 NTSTATUS status;
713 ULONG i;
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;
724 return status;
728 /**********************************************************************
729 * wow64_NtSetEaFile
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 );
738 IO_STATUS_BLOCK io;
739 NTSTATUS status;
741 status = NtSetEaFile( handle, iosb_32to64( &io, io32 ), ptr, len );
742 put_iosb( io32, &io );
743 return status;
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 );
758 IO_STATUS_BLOCK io;
759 NTSTATUS status;
761 switch (class)
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 );
773 break;
775 case FileRenameInformation: /* FILE_RENAME_INFORMATION */
776 case FileLinkInformation: /* FILE_LINK_INFORMATION */
777 if (len >= sizeof(FILE_RENAME_INFORMATION32))
779 OBJECT_ATTRIBUTES attr;
780 UNICODE_STRING name;
781 FILE_RENAME_INFORMATION32 *info32 = ptr;
782 FILE_RENAME_INFORMATION *info;
783 ULONG size;
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;
798 break;
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;
811 break;
813 default:
814 FIXME( "unsupported class %u\n", class );
815 status = io.Status = STATUS_INVALID_INFO_CLASS;
816 break;
818 put_iosb( io32, &io );
819 return status;
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 );
834 IO_STATUS_BLOCK io;
835 NTSTATUS status;
837 status = NtSetVolumeInformationFile( handle, iosb_32to64( &io, io32 ), ptr, len, class );
838 put_iosb( io32, &io );
839 return status;
843 /**********************************************************************
844 * wow64_NtUnlockFile
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 );
854 IO_STATUS_BLOCK io;
855 NTSTATUS status;
857 status = NtUnlockFile( handle, iosb_32to64( &io, io32 ), offset, count, key );
858 put_iosb( io32, &io );
859 return status;
863 /**********************************************************************
864 * wow64_NtWriteFile
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 );
878 IO_STATUS_BLOCK io;
879 NTSTATUS status;
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 );
884 return status;
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 );
903 IO_STATUS_BLOCK io;
904 NTSTATUS status;
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 );
909 return status;
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 );
939 HANDLE handle = 0;
940 NTSTATUS status;
942 *handle_ptr = 0;
943 status = wine_server_fd_to_handle( fd, access, attributes, &handle );
944 put_handle( handle_ptr, handle );
945 return status;
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 );