wow64: Add thunks for the virtual memory syscalls.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a06bcd03b9
commit
dffe2bf8e2
|
@ -7,4 +7,5 @@ EXTRADLLFLAGS = -nodefaultlibs -mno-cygwin -Wl,--image-base,0x6f000000
|
|||
C_SRCS = \
|
||||
registry.c \
|
||||
sync.c \
|
||||
syscall.c
|
||||
syscall.c \
|
||||
virtual.c
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
SYSCALL_ENTRY( NtAddAtom ) \
|
||||
SYSCALL_ENTRY( NtAllocateLocallyUniqueId ) \
|
||||
SYSCALL_ENTRY( NtAllocateUuids ) \
|
||||
SYSCALL_ENTRY( NtAllocateVirtualMemory ) \
|
||||
SYSCALL_ENTRY( NtAllocateVirtualMemoryEx ) \
|
||||
SYSCALL_ENTRY( NtCancelTimer ) \
|
||||
SYSCALL_ENTRY( NtClearEvent ) \
|
||||
SYSCALL_ENTRY( NtClearPowerRequest ) \
|
||||
|
@ -57,10 +59,13 @@
|
|||
SYSCALL_ENTRY( NtEnumerateValueKey ) \
|
||||
SYSCALL_ENTRY( NtFindAtom ) \
|
||||
SYSCALL_ENTRY( NtFlushKey ) \
|
||||
SYSCALL_ENTRY( NtFlushVirtualMemory ) \
|
||||
SYSCALL_ENTRY( NtFreeVirtualMemory ) \
|
||||
SYSCALL_ENTRY( NtGetCurrentProcessorNumber ) \
|
||||
SYSCALL_ENTRY( NtListenPort ) \
|
||||
SYSCALL_ENTRY( NtLoadKey ) \
|
||||
SYSCALL_ENTRY( NtLoadKey2 ) \
|
||||
SYSCALL_ENTRY( NtLockVirtualMemory ) \
|
||||
SYSCALL_ENTRY( NtMakeTemporaryObject ) \
|
||||
SYSCALL_ENTRY( NtOpenDirectoryObject ) \
|
||||
SYSCALL_ENTRY( NtOpenEvent ) \
|
||||
|
@ -76,6 +81,7 @@
|
|||
SYSCALL_ENTRY( NtOpenSemaphore ) \
|
||||
SYSCALL_ENTRY( NtOpenSymbolicLinkObject ) \
|
||||
SYSCALL_ENTRY( NtOpenTimer ) \
|
||||
SYSCALL_ENTRY( NtProtectVirtualMemory ) \
|
||||
SYSCALL_ENTRY( NtPulseEvent ) \
|
||||
SYSCALL_ENTRY( NtQueryDefaultLocale ) \
|
||||
SYSCALL_ENTRY( NtQueryDefaultUILanguage ) \
|
||||
|
@ -95,6 +101,7 @@
|
|||
SYSCALL_ENTRY( NtQueryTimer ) \
|
||||
SYSCALL_ENTRY( NtQueryTimerResolution ) \
|
||||
SYSCALL_ENTRY( NtQueryValueKey ) \
|
||||
SYSCALL_ENTRY( NtReadVirtualMemory ) \
|
||||
SYSCALL_ENTRY( NtReleaseKeyedEvent ) \
|
||||
SYSCALL_ENTRY( NtReleaseMutant ) \
|
||||
SYSCALL_ENTRY( NtReleaseSemaphore ) \
|
||||
|
@ -120,10 +127,12 @@
|
|||
SYSCALL_ENTRY( NtSignalAndWaitForSingleObject ) \
|
||||
SYSCALL_ENTRY( NtTerminateJobObject ) \
|
||||
SYSCALL_ENTRY( NtUnloadKey ) \
|
||||
SYSCALL_ENTRY( NtUnlockVirtualMemory ) \
|
||||
SYSCALL_ENTRY( NtWaitForDebugEvent ) \
|
||||
SYSCALL_ENTRY( NtWaitForKeyedEvent ) \
|
||||
SYSCALL_ENTRY( NtWaitForMultipleObjects ) \
|
||||
SYSCALL_ENTRY( NtWaitForSingleObject ) \
|
||||
SYSCALL_ENTRY( NtWriteVirtualMemory ) \
|
||||
SYSCALL_ENTRY( NtYieldExecution )
|
||||
|
||||
#endif /* __WOW64_SYSCALL_H */
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* WoW64 virtual memory 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 <stdarg.h>
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winnt.h"
|
||||
#include "winternl.h"
|
||||
#include "winioctl.h"
|
||||
#include "wow64_private.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wow);
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtAllocateVirtualMemory
|
||||
*/
|
||||
NTSTATUS WINAPI wow64_NtAllocateVirtualMemory( UINT *args )
|
||||
{
|
||||
HANDLE process = get_handle( &args );
|
||||
ULONG *addr32 = get_ptr( &args );
|
||||
ULONG_PTR zero_bits = get_ulong( &args );
|
||||
ULONG *size32 = get_ptr( &args );
|
||||
ULONG type = get_ulong( &args );
|
||||
ULONG protect = get_ulong( &args );
|
||||
|
||||
void *addr;
|
||||
SIZE_T size;
|
||||
NTSTATUS status;
|
||||
|
||||
status = NtAllocateVirtualMemory( process, addr_32to64( &addr, addr32 ), get_zero_bits( zero_bits ),
|
||||
size_32to64( &size, size32 ), type, protect );
|
||||
if (!status)
|
||||
{
|
||||
put_addr( addr32, addr );
|
||||
put_size( size32, size );
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtAllocateVirtualMemoryEx
|
||||
*/
|
||||
NTSTATUS WINAPI wow64_NtAllocateVirtualMemoryEx( UINT *args )
|
||||
{
|
||||
HANDLE process = get_handle( &args );
|
||||
ULONG *addr32 = get_ptr( &args );
|
||||
ULONG *size32 = get_ptr( &args );
|
||||
ULONG type = get_ulong( &args );
|
||||
ULONG protect = get_ulong( &args );
|
||||
MEM_EXTENDED_PARAMETER *params = get_ptr( &args );
|
||||
ULONG count = get_ulong( &args );
|
||||
|
||||
void *addr;
|
||||
SIZE_T size;
|
||||
NTSTATUS status;
|
||||
|
||||
if (count) FIXME( "%d extended parameters %p\n", count, params );
|
||||
status = NtAllocateVirtualMemoryEx( process, addr_32to64( &addr, addr32 ), size_32to64( &size, size32 ),
|
||||
type, protect, params, count );
|
||||
if (!status)
|
||||
{
|
||||
put_addr( addr32, addr );
|
||||
put_size( size32, size );
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtFlushVirtualMemory
|
||||
*/
|
||||
NTSTATUS WINAPI wow64_NtFlushVirtualMemory( UINT *args )
|
||||
{
|
||||
HANDLE process = get_handle( &args );
|
||||
ULONG *addr32 = get_ptr( &args );
|
||||
ULONG *size32 = get_ptr( &args );
|
||||
ULONG unknown = get_ulong( &args );
|
||||
|
||||
void *addr;
|
||||
SIZE_T size;
|
||||
NTSTATUS status;
|
||||
|
||||
status = NtFlushVirtualMemory( process, (const void **)addr_32to64( &addr, addr32 ),
|
||||
size_32to64( &size, size32 ), unknown );
|
||||
if (!status)
|
||||
{
|
||||
put_addr( addr32, addr );
|
||||
put_size( size32, size );
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtFreeVirtualMemory
|
||||
*/
|
||||
NTSTATUS WINAPI wow64_NtFreeVirtualMemory( UINT *args )
|
||||
{
|
||||
HANDLE process = get_handle( &args );
|
||||
ULONG *addr32 = get_ptr( &args );
|
||||
ULONG *size32 = get_ptr( &args );
|
||||
ULONG type = get_ulong( &args );
|
||||
|
||||
void *addr;
|
||||
SIZE_T size;
|
||||
NTSTATUS status;
|
||||
|
||||
status = NtFreeVirtualMemory( process, addr_32to64( &addr, addr32 ),
|
||||
size_32to64( &size, size32 ), type );
|
||||
if (!status)
|
||||
{
|
||||
put_addr( addr32, addr );
|
||||
put_size( size32, size );
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtLockVirtualMemory
|
||||
*/
|
||||
NTSTATUS WINAPI wow64_NtLockVirtualMemory( UINT *args )
|
||||
{
|
||||
HANDLE process = get_handle( &args );
|
||||
ULONG *addr32 = get_ptr( &args );
|
||||
ULONG *size32 = get_ptr( &args );
|
||||
ULONG unknown = get_ulong( &args );
|
||||
|
||||
void *addr;
|
||||
SIZE_T size;
|
||||
NTSTATUS status;
|
||||
|
||||
status = NtLockVirtualMemory( process, addr_32to64( &addr, addr32 ),
|
||||
size_32to64( &size, size32 ), unknown );
|
||||
if (!status)
|
||||
{
|
||||
put_addr( addr32, addr );
|
||||
put_size( size32, size );
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtProtectVirtualMemory
|
||||
*/
|
||||
NTSTATUS WINAPI wow64_NtProtectVirtualMemory( UINT *args )
|
||||
{
|
||||
HANDLE process = get_handle( &args );
|
||||
ULONG *addr32 = get_ptr( &args );
|
||||
ULONG *size32 = get_ptr( &args );
|
||||
ULONG new_prot = get_ulong( &args );
|
||||
ULONG *old_prot = get_ptr( &args );
|
||||
|
||||
void *addr;
|
||||
SIZE_T size;
|
||||
NTSTATUS status;
|
||||
|
||||
status = NtProtectVirtualMemory( process, addr_32to64( &addr, addr32 ),
|
||||
size_32to64( &size, size32 ), new_prot, old_prot );
|
||||
if (!status)
|
||||
{
|
||||
put_addr( addr32, addr );
|
||||
put_size( size32, size );
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtReadVirtualMemory
|
||||
*/
|
||||
NTSTATUS WINAPI wow64_NtReadVirtualMemory( UINT *args )
|
||||
{
|
||||
HANDLE process = get_handle( &args );
|
||||
const void *addr = get_ptr( &args );
|
||||
void *buffer = get_ptr( &args );
|
||||
SIZE_T size = get_ulong( &args );
|
||||
ULONG *retlen = get_ptr( &args );
|
||||
|
||||
SIZE_T ret_size;
|
||||
NTSTATUS status;
|
||||
|
||||
status = NtReadVirtualMemory( process, addr, buffer, size, &ret_size );
|
||||
put_size( retlen, ret_size );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtUnlockVirtualMemory
|
||||
*/
|
||||
NTSTATUS WINAPI wow64_NtUnlockVirtualMemory( UINT *args )
|
||||
{
|
||||
HANDLE process = get_handle( &args );
|
||||
ULONG *addr32 = get_ptr( &args );
|
||||
ULONG *size32 = get_ptr( &args );
|
||||
ULONG unknown = get_ulong( &args );
|
||||
|
||||
void *addr;
|
||||
SIZE_T size;
|
||||
NTSTATUS status;
|
||||
|
||||
status = NtUnlockVirtualMemory( process, addr_32to64( &addr, addr32 ),
|
||||
size_32to64( &size, size32 ), unknown );
|
||||
if (!status)
|
||||
{
|
||||
put_addr( addr32, addr );
|
||||
put_size( size32, size );
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtWriteVirtualMemory
|
||||
*/
|
||||
NTSTATUS WINAPI wow64_NtWriteVirtualMemory( UINT *args )
|
||||
{
|
||||
HANDLE process = get_handle( &args );
|
||||
void *addr = get_ptr( &args );
|
||||
const void *buffer = get_ptr( &args );
|
||||
SIZE_T size = get_ulong( &args );
|
||||
ULONG *retlen = get_ptr( &args );
|
||||
|
||||
SIZE_T ret_size;
|
||||
NTSTATUS status;
|
||||
|
||||
status = NtWriteVirtualMemory( process, addr, buffer, size, &ret_size );
|
||||
put_size( retlen, ret_size );
|
||||
return status;
|
||||
}
|
|
@ -63,6 +63,25 @@ static inline ULONG get_ulong( UINT **args ) { return *(*args)++; }
|
|||
static inline HANDLE get_handle( UINT **args ) { return LongToHandle( *(*args)++ ); }
|
||||
static inline void *get_ptr( UINT **args ) { return ULongToPtr( *(*args)++ ); }
|
||||
|
||||
static inline ULONG_PTR get_zero_bits( ULONG_PTR zero_bits )
|
||||
{
|
||||
return zero_bits ? zero_bits : 0x7fffffff;
|
||||
}
|
||||
|
||||
static inline void **addr_32to64( void **addr, ULONG *addr32 )
|
||||
{
|
||||
if (!addr32) return NULL;
|
||||
*addr = ULongToPtr( *addr32 );
|
||||
return addr;
|
||||
}
|
||||
|
||||
static inline SIZE_T *size_32to64( SIZE_T *size, ULONG *size32 )
|
||||
{
|
||||
if (!size32) return NULL;
|
||||
*size = *size32;
|
||||
return size;
|
||||
}
|
||||
|
||||
static inline void *apc_32to64( ULONG func )
|
||||
{
|
||||
return func ? Wow64ApcRoutine : NULL;
|
||||
|
@ -137,6 +156,11 @@ static inline void put_handle( ULONG *handle32, HANDLE handle )
|
|||
*handle32 = HandleToULong( handle );
|
||||
}
|
||||
|
||||
static inline void put_addr( ULONG *addr32, void *addr )
|
||||
{
|
||||
if (addr32) *addr32 = PtrToUlong( addr );
|
||||
}
|
||||
|
||||
static inline void put_size( ULONG *size32, SIZE_T size )
|
||||
{
|
||||
if (size32) *size32 = min( size, MAXDWORD );
|
||||
|
|
Loading…
Reference in New Issue