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 = \
|
C_SRCS = \
|
||||||
registry.c \
|
registry.c \
|
||||||
sync.c \
|
sync.c \
|
||||||
syscall.c
|
syscall.c \
|
||||||
|
virtual.c
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
SYSCALL_ENTRY( NtAddAtom ) \
|
SYSCALL_ENTRY( NtAddAtom ) \
|
||||||
SYSCALL_ENTRY( NtAllocateLocallyUniqueId ) \
|
SYSCALL_ENTRY( NtAllocateLocallyUniqueId ) \
|
||||||
SYSCALL_ENTRY( NtAllocateUuids ) \
|
SYSCALL_ENTRY( NtAllocateUuids ) \
|
||||||
|
SYSCALL_ENTRY( NtAllocateVirtualMemory ) \
|
||||||
|
SYSCALL_ENTRY( NtAllocateVirtualMemoryEx ) \
|
||||||
SYSCALL_ENTRY( NtCancelTimer ) \
|
SYSCALL_ENTRY( NtCancelTimer ) \
|
||||||
SYSCALL_ENTRY( NtClearEvent ) \
|
SYSCALL_ENTRY( NtClearEvent ) \
|
||||||
SYSCALL_ENTRY( NtClearPowerRequest ) \
|
SYSCALL_ENTRY( NtClearPowerRequest ) \
|
||||||
|
@ -57,10 +59,13 @@
|
||||||
SYSCALL_ENTRY( NtEnumerateValueKey ) \
|
SYSCALL_ENTRY( NtEnumerateValueKey ) \
|
||||||
SYSCALL_ENTRY( NtFindAtom ) \
|
SYSCALL_ENTRY( NtFindAtom ) \
|
||||||
SYSCALL_ENTRY( NtFlushKey ) \
|
SYSCALL_ENTRY( NtFlushKey ) \
|
||||||
|
SYSCALL_ENTRY( NtFlushVirtualMemory ) \
|
||||||
|
SYSCALL_ENTRY( NtFreeVirtualMemory ) \
|
||||||
SYSCALL_ENTRY( NtGetCurrentProcessorNumber ) \
|
SYSCALL_ENTRY( NtGetCurrentProcessorNumber ) \
|
||||||
SYSCALL_ENTRY( NtListenPort ) \
|
SYSCALL_ENTRY( NtListenPort ) \
|
||||||
SYSCALL_ENTRY( NtLoadKey ) \
|
SYSCALL_ENTRY( NtLoadKey ) \
|
||||||
SYSCALL_ENTRY( NtLoadKey2 ) \
|
SYSCALL_ENTRY( NtLoadKey2 ) \
|
||||||
|
SYSCALL_ENTRY( NtLockVirtualMemory ) \
|
||||||
SYSCALL_ENTRY( NtMakeTemporaryObject ) \
|
SYSCALL_ENTRY( NtMakeTemporaryObject ) \
|
||||||
SYSCALL_ENTRY( NtOpenDirectoryObject ) \
|
SYSCALL_ENTRY( NtOpenDirectoryObject ) \
|
||||||
SYSCALL_ENTRY( NtOpenEvent ) \
|
SYSCALL_ENTRY( NtOpenEvent ) \
|
||||||
|
@ -76,6 +81,7 @@
|
||||||
SYSCALL_ENTRY( NtOpenSemaphore ) \
|
SYSCALL_ENTRY( NtOpenSemaphore ) \
|
||||||
SYSCALL_ENTRY( NtOpenSymbolicLinkObject ) \
|
SYSCALL_ENTRY( NtOpenSymbolicLinkObject ) \
|
||||||
SYSCALL_ENTRY( NtOpenTimer ) \
|
SYSCALL_ENTRY( NtOpenTimer ) \
|
||||||
|
SYSCALL_ENTRY( NtProtectVirtualMemory ) \
|
||||||
SYSCALL_ENTRY( NtPulseEvent ) \
|
SYSCALL_ENTRY( NtPulseEvent ) \
|
||||||
SYSCALL_ENTRY( NtQueryDefaultLocale ) \
|
SYSCALL_ENTRY( NtQueryDefaultLocale ) \
|
||||||
SYSCALL_ENTRY( NtQueryDefaultUILanguage ) \
|
SYSCALL_ENTRY( NtQueryDefaultUILanguage ) \
|
||||||
|
@ -95,6 +101,7 @@
|
||||||
SYSCALL_ENTRY( NtQueryTimer ) \
|
SYSCALL_ENTRY( NtQueryTimer ) \
|
||||||
SYSCALL_ENTRY( NtQueryTimerResolution ) \
|
SYSCALL_ENTRY( NtQueryTimerResolution ) \
|
||||||
SYSCALL_ENTRY( NtQueryValueKey ) \
|
SYSCALL_ENTRY( NtQueryValueKey ) \
|
||||||
|
SYSCALL_ENTRY( NtReadVirtualMemory ) \
|
||||||
SYSCALL_ENTRY( NtReleaseKeyedEvent ) \
|
SYSCALL_ENTRY( NtReleaseKeyedEvent ) \
|
||||||
SYSCALL_ENTRY( NtReleaseMutant ) \
|
SYSCALL_ENTRY( NtReleaseMutant ) \
|
||||||
SYSCALL_ENTRY( NtReleaseSemaphore ) \
|
SYSCALL_ENTRY( NtReleaseSemaphore ) \
|
||||||
|
@ -120,10 +127,12 @@
|
||||||
SYSCALL_ENTRY( NtSignalAndWaitForSingleObject ) \
|
SYSCALL_ENTRY( NtSignalAndWaitForSingleObject ) \
|
||||||
SYSCALL_ENTRY( NtTerminateJobObject ) \
|
SYSCALL_ENTRY( NtTerminateJobObject ) \
|
||||||
SYSCALL_ENTRY( NtUnloadKey ) \
|
SYSCALL_ENTRY( NtUnloadKey ) \
|
||||||
|
SYSCALL_ENTRY( NtUnlockVirtualMemory ) \
|
||||||
SYSCALL_ENTRY( NtWaitForDebugEvent ) \
|
SYSCALL_ENTRY( NtWaitForDebugEvent ) \
|
||||||
SYSCALL_ENTRY( NtWaitForKeyedEvent ) \
|
SYSCALL_ENTRY( NtWaitForKeyedEvent ) \
|
||||||
SYSCALL_ENTRY( NtWaitForMultipleObjects ) \
|
SYSCALL_ENTRY( NtWaitForMultipleObjects ) \
|
||||||
SYSCALL_ENTRY( NtWaitForSingleObject ) \
|
SYSCALL_ENTRY( NtWaitForSingleObject ) \
|
||||||
|
SYSCALL_ENTRY( NtWriteVirtualMemory ) \
|
||||||
SYSCALL_ENTRY( NtYieldExecution )
|
SYSCALL_ENTRY( NtYieldExecution )
|
||||||
|
|
||||||
#endif /* __WOW64_SYSCALL_H */
|
#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 HANDLE get_handle( UINT **args ) { return LongToHandle( *(*args)++ ); }
|
||||||
static inline void *get_ptr( UINT **args ) { return ULongToPtr( *(*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 )
|
static inline void *apc_32to64( ULONG func )
|
||||||
{
|
{
|
||||||
return func ? Wow64ApcRoutine : NULL;
|
return func ? Wow64ApcRoutine : NULL;
|
||||||
|
@ -137,6 +156,11 @@ static inline void put_handle( ULONG *handle32, HANDLE handle )
|
||||||
*handle32 = HandleToULong( 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 )
|
static inline void put_size( ULONG *size32, SIZE_T size )
|
||||||
{
|
{
|
||||||
if (size32) *size32 = min( size, MAXDWORD );
|
if (size32) *size32 = min( size, MAXDWORD );
|
||||||
|
|
Loading…
Reference in New Issue