diff --git a/dlls/wow64/Makefile.in b/dlls/wow64/Makefile.in index 693fdefaae4..f56d1f0aad9 100644 --- a/dlls/wow64/Makefile.in +++ b/dlls/wow64/Makefile.in @@ -5,6 +5,7 @@ IMPORTS = ntdll winecrt0 EXTRADLLFLAGS = -nodefaultlibs -mno-cygwin -Wl,--image-base,0x6f000000 C_SRCS = \ + file.c \ registry.c \ sync.c \ syscall.c \ diff --git a/dlls/wow64/file.c b/dlls/wow64/file.c new file mode 100644 index 00000000000..361aa1905ee --- /dev/null +++ b/dlls/wow64/file.c @@ -0,0 +1,100 @@ +/* + * WoW64 file functions + * + * Copyright 2021 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "winternl.h" +#include "wow64_private.h" + + +/********************************************************************** + * wow64_NtCreateFile + */ +NTSTATUS WINAPI wow64_NtCreateFile( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + IO_STATUS_BLOCK32 *io32 = get_ptr( &args ); + LARGE_INTEGER *alloc_size = get_ptr( &args ); + ULONG attributes = get_ulong( &args ); + ULONG sharing = get_ulong( &args ); + ULONG disposition = get_ulong( &args ); + ULONG options = get_ulong( &args ); + void *ea_buffer = get_ptr( &args ); + ULONG ea_length = get_ulong( &args ); + + struct object_attr64 attr; + IO_STATUS_BLOCK io; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateFile( &handle, access, objattr_32to64( &attr, attr32 ), + iosb_32to64( &io, io32 ), alloc_size, attributes, + sharing, disposition, options, ea_buffer, ea_length ); + put_handle( handle_ptr, handle ); + put_iosb( io32, &io ); + return status; +} + + +/********************************************************************** + * wow64_NtDeleteFile + */ +NTSTATUS WINAPI wow64_NtDeleteFile( UINT *args ) +{ + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + + struct object_attr64 attr; + + return NtDeleteFile( objattr_32to64( &attr, attr32 )); +} + + +/********************************************************************** + * wow64_NtOpenFile + */ +NTSTATUS WINAPI wow64_NtOpenFile( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + IO_STATUS_BLOCK32 *io32 = get_ptr( &args ); + ULONG sharing = get_ulong( &args ); + ULONG options = get_ulong( &args ); + + struct object_attr64 attr; + IO_STATUS_BLOCK io; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenFile( &handle, access, objattr_32to64( &attr, attr32 ), + iosb_32to64( &io, io32 ), sharing, options ); + put_handle( handle_ptr, handle ); + put_iosb( io32, &io ); + return status; +} diff --git a/dlls/wow64/struct32.h b/dlls/wow64/struct32.h index 069564948d0..76055115b08 100644 --- a/dlls/wow64/struct32.h +++ b/dlls/wow64/struct32.h @@ -31,6 +31,16 @@ typedef struct ULONG SecurityQualityOfService; } OBJECT_ATTRIBUTES32; +typedef struct +{ + union + { + NTSTATUS Status; + ULONG Pointer; + }; + ULONG Information; +} IO_STATUS_BLOCK32; + typedef struct { UNICODE_STRING32 Name; diff --git a/dlls/wow64/syscall.h b/dlls/wow64/syscall.h index ab25bcb501d..2b542658f9e 100644 --- a/dlls/wow64/syscall.h +++ b/dlls/wow64/syscall.h @@ -38,6 +38,7 @@ SYSCALL_ENTRY( NtCreateDebugObject ) \ SYSCALL_ENTRY( NtCreateDirectoryObject ) \ SYSCALL_ENTRY( NtCreateEvent ) \ + SYSCALL_ENTRY( NtCreateFile ) \ SYSCALL_ENTRY( NtCreateIoCompletion ) \ SYSCALL_ENTRY( NtCreateJobObject ) \ SYSCALL_ENTRY( NtCreateKey ) \ @@ -53,6 +54,7 @@ SYSCALL_ENTRY( NtDebugContinue ) \ SYSCALL_ENTRY( NtDelayExecution ) \ SYSCALL_ENTRY( NtDeleteAtom ) \ + SYSCALL_ENTRY( NtDeleteFile ) \ SYSCALL_ENTRY( NtDeleteKey ) \ SYSCALL_ENTRY( NtDeleteValueKey ) \ SYSCALL_ENTRY( NtDuplicateObject ) \ @@ -73,6 +75,7 @@ SYSCALL_ENTRY( NtMapViewOfSection ) \ SYSCALL_ENTRY( NtOpenDirectoryObject ) \ SYSCALL_ENTRY( NtOpenEvent ) \ + SYSCALL_ENTRY( NtOpenFile ) \ SYSCALL_ENTRY( NtOpenIoCompletion ) \ SYSCALL_ENTRY( NtOpenJobObject ) \ SYSCALL_ENTRY( NtOpenKey ) \ diff --git a/dlls/wow64/wow64_private.h b/dlls/wow64/wow64_private.h index e9935303cbb..303914c540e 100644 --- a/dlls/wow64/wow64_private.h +++ b/dlls/wow64/wow64_private.h @@ -105,6 +105,13 @@ static inline void *apc_param_32to64( ULONG func, ULONG context ) return (void *)(ULONG_PTR)(((ULONG64)func << 32) | context); } +static inline IO_STATUS_BLOCK *iosb_32to64( IO_STATUS_BLOCK *io, IO_STATUS_BLOCK32 *io32 ) +{ + if (!io32) return NULL; + io->Pointer = io32; + return io; +} + static inline UNICODE_STRING *unicode_str_32to64( UNICODE_STRING *str, const UNICODE_STRING32 *str32 ) { if (!str32) return NULL; @@ -178,6 +185,17 @@ static inline void put_size( ULONG *size32, SIZE_T size ) if (size32) *size32 = min( size, MAXDWORD ); } +static inline void put_iosb( IO_STATUS_BLOCK32 *io32, const IO_STATUS_BLOCK *io ) +{ + /* sync I/O modifies the 64-bit iosb right away, so in that case we update the 32-bit one */ + /* async I/O leaves the 64-bit one untouched and updates the 32-bit one directly later on */ + if (io32 && io->Pointer != io32) + { + io32->Status = io->Status; + io32->Information = io->Information; + } +} + extern void put_section_image_info( SECTION_IMAGE_INFORMATION32 *info32, const SECTION_IMAGE_INFORMATION *info ) DECLSPEC_HIDDEN;