ntdll: Implement NtWow64AllocateVirtualMemory64().

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-06-28 20:25:03 +02:00
parent bfd2d1d77d
commit 19f19d0e2e
4 changed files with 129 additions and 0 deletions

View file

@ -430,6 +430,7 @@
@ stdcall -syscall NtWaitForSingleObject(long long ptr)
@ stub NtWaitHighEventPair
@ stub NtWaitLowEventPair
@ stdcall -syscall -arch=win32 NtWow64AllocateVirtualMemory64(long ptr int64 ptr long long)
@ stdcall -syscall -arch=win32 NtWow64ReadVirtualMemory64(long int64 ptr int64 ptr)
@ stdcall -syscall -arch=win32 NtWow64WriteVirtualMemory64(long int64 ptr int64 ptr)
@ stdcall -syscall NtWriteFile(long long ptr ptr ptr ptr long ptr ptr)
@ -1446,6 +1447,7 @@
@ stdcall -private -syscall ZwWaitForSingleObject(long long ptr) NtWaitForSingleObject
@ stub ZwWaitHighEventPair
@ stub ZwWaitLowEventPair
@ stdcall -syscall -arch=win32 ZwWow64AllocateVirtualMemory64(long ptr int64 ptr long long) NtWow64AllocateVirtualMemory64
@ stdcall -syscall -arch=win32 ZwWow64ReadVirtualMemory64(long int64 ptr int64 ptr) NtWow64ReadVirtualMemory64
@ stdcall -syscall -arch=win32 ZwWow64WriteVirtualMemory64(long int64 ptr int64 ptr) NtWow64WriteVirtualMemory64
@ stdcall -private -syscall ZwWriteFile(long long ptr ptr ptr ptr long ptr ptr) NtWriteFile

View file

@ -28,6 +28,7 @@ static NTSTATUS (WINAPI *pRtlWow64IsWowGuestMachineSupported)(USHORT,BOOLEAN*);
#ifdef _WIN64
static NTSTATUS (WINAPI *pRtlWow64GetCpuAreaInfo)(WOW64_CPURESERVED*,ULONG,WOW64_CPU_AREA_INFO*);
#else
static NTSTATUS (WINAPI *pNtWow64AllocateVirtualMemory64)(HANDLE,ULONG64*,ULONG64,ULONG64*,ULONG,ULONG);
static NTSTATUS (WINAPI *pNtWow64ReadVirtualMemory64)(HANDLE,ULONG64,void*,ULONG64,ULONG64*);
static NTSTATUS (WINAPI *pNtWow64WriteVirtualMemory64)(HANDLE,ULONG64,const void *,ULONG64,ULONG64*);
#endif
@ -48,6 +49,7 @@ static void init(void)
#ifdef _WIN64
GET_PROC( RtlWow64GetCpuAreaInfo );
#else
GET_PROC( NtWow64AllocateVirtualMemory64 );
GET_PROC( NtWow64ReadVirtualMemory64 );
GET_PROC( NtWow64WriteVirtualMemory64 );
#endif
@ -490,6 +492,73 @@ static void test_nt_wow64(void)
}
else win_skip( "NtWow64ReadVirtualMemory64 not supported\n" );
if (pNtWow64AllocateVirtualMemory64)
{
ULONG64 ptr = 0;
ULONG64 size = 0x2345;
status = pNtWow64AllocateVirtualMemory64( process, &ptr, 0, &size,
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
ok( !status, "NtWow64AllocateVirtualMemory64 failed %x\n", status );
ok( ptr, "ptr not set\n" );
ok( size == 0x3000, "size not set %s\n", wine_dbgstr_longlong(size) );
ptr += 0x1000;
status = pNtWow64AllocateVirtualMemory64( process, &ptr, 0, &size,
MEM_RESERVE | MEM_COMMIT, PAGE_READONLY );
ok( status == STATUS_CONFLICTING_ADDRESSES, "NtWow64AllocateVirtualMemory64 failed %x\n", status );
ptr = 0;
size = 0;
status = pNtWow64AllocateVirtualMemory64( process, &ptr, 0, &size,
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
ok( status == STATUS_INVALID_PARAMETER || status == STATUS_INVALID_PARAMETER_4,
"NtWow64AllocateVirtualMemory64 failed %x\n", status );
size = 0x1000;
status = pNtWow64AllocateVirtualMemory64( process, &ptr, 22, &size,
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
ok( status == STATUS_INVALID_PARAMETER || status == STATUS_INVALID_PARAMETER_3,
"NtWow64AllocateVirtualMemory64 failed %x\n", status );
status = pNtWow64AllocateVirtualMemory64( process, &ptr, 33, &size,
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
ok( status == STATUS_INVALID_PARAMETER || status == STATUS_INVALID_PARAMETER_3,
"NtWow64AllocateVirtualMemory64 failed %x\n", status );
status = pNtWow64AllocateVirtualMemory64( process, &ptr, 0x3fffffff, &size,
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
todo_wine_if( !is_wow64 )
ok( !status, "NtWow64AllocateVirtualMemory64 failed %x\n", status );
ok( ptr < 0x40000000, "got wrong ptr %s\n", wine_dbgstr_longlong(ptr) );
if (!status && pNtWow64WriteVirtualMemory64)
{
status = pNtWow64WriteVirtualMemory64( process, ptr, str, sizeof(str), &res );
ok( !status, "NtWow64WriteVirtualMemory64 failed %x\n", status );
ok( res == sizeof(str), "wrong size %s\n", wine_dbgstr_longlong(res) );
ok( !strcmp( (char *)(ULONG_PTR)ptr, str ), "wrong data %s\n",
debugstr_a((char *)(ULONG_PTR)ptr) );
ptr = 0;
status = pNtWow64AllocateVirtualMemory64( process, &ptr, 0, &size,
MEM_RESERVE | MEM_COMMIT, PAGE_READONLY );
ok( !status, "NtWow64AllocateVirtualMemory64 failed %x\n", status );
status = pNtWow64WriteVirtualMemory64( process, ptr, str, sizeof(str), &res );
todo_wine
ok( status == STATUS_PARTIAL_COPY || broken( status == STATUS_ACCESS_VIOLATION ),
"NtWow64WriteVirtualMemory64 failed %x\n", status );
todo_wine
ok( !res, "wrong size %s\n", wine_dbgstr_longlong(res) );
}
ptr = 0x9876543210ull;
status = pNtWow64AllocateVirtualMemory64( process, &ptr, 0, &size,
MEM_RESERVE | MEM_COMMIT, PAGE_READONLY );
todo_wine
ok( !status || broken( status == STATUS_CONFLICTING_ADDRESSES ),
"NtWow64AllocateVirtualMemory64 failed %x\n", status );
if (!status) ok( ptr == 0x9876540000ull, "wrong ptr %s\n", wine_dbgstr_longlong(ptr) );
ptr = 0;
status = pNtWow64AllocateVirtualMemory64( GetCurrentProcess(), &ptr, 0, &size,
MEM_RESERVE | MEM_COMMIT, PAGE_READONLY );
ok( !status || broken( status == STATUS_INVALID_HANDLE ),
"NtWow64AllocateVirtualMemory64 failed %x\n", status );
}
else win_skip( "NtWow64AllocateVirtualMemory64 not supported\n" );
NtClose( process );
}

View file

@ -3689,6 +3689,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG_PTR z
if (!size) return STATUS_INVALID_PARAMETER;
if (zero_bits > 21 && zero_bits < 32) return STATUS_INVALID_PARAMETER_3;
if (zero_bits > 32 && zero_bits < granularity_mask) return STATUS_INVALID_PARAMETER_3;
#ifndef _WIN64
if (!is_wow64 && zero_bits >= 32) return STATUS_INVALID_PARAMETER_3;
#endif
@ -4836,6 +4837,62 @@ NTSTATUS WINAPI NtCreatePagingFile( UNICODE_STRING *name, LARGE_INTEGER *min_siz
#ifndef _WIN64
/***********************************************************************
* NtWow64AllocateVirtualMemory64 (NTDLL.@)
* ZwWow64AllocateVirtualMemory64 (NTDLL.@)
*/
NTSTATUS WINAPI NtWow64AllocateVirtualMemory64( HANDLE process, ULONG64 *ret, ULONG64 zero_bits,
ULONG64 *size_ptr, ULONG type, ULONG protect )
{
void *base;
SIZE_T size;
NTSTATUS status;
TRACE("%p %s %s %x %08x\n", process,
wine_dbgstr_longlong(*ret), wine_dbgstr_longlong(*size_ptr), type, protect );
if (!*size_ptr) return STATUS_INVALID_PARAMETER_4;
if (zero_bits > 21 && zero_bits < 32) return STATUS_INVALID_PARAMETER_3;
if (process != NtCurrentProcess())
{
apc_call_t call;
apc_result_t result;
memset( &call, 0, sizeof(call) );
call.virtual_alloc.type = APC_VIRTUAL_ALLOC;
call.virtual_alloc.addr = *ret;
call.virtual_alloc.size = *size_ptr;
call.virtual_alloc.zero_bits = zero_bits;
call.virtual_alloc.op_type = type;
call.virtual_alloc.prot = protect;
status = server_queue_process_apc( process, &call, &result );
if (status != STATUS_SUCCESS) return status;
if (result.virtual_alloc.status == STATUS_SUCCESS)
{
*ret = result.virtual_alloc.addr;
*size_ptr = result.virtual_alloc.size;
}
return result.virtual_alloc.status;
}
base = (void *)(ULONG_PTR)*ret;
size = *size_ptr;
if ((ULONG_PTR)base != *ret) return STATUS_CONFLICTING_ADDRESSES;
if (size != *size_ptr) return STATUS_WORKING_SET_LIMIT_RANGE;
status = NtAllocateVirtualMemory( process, &base, zero_bits, &size, type, protect );
if (!status)
{
*ret = (ULONG_PTR)base;
*size_ptr = size;
}
return status;
}
/***********************************************************************
* NtWow64ReadVirtualMemory64 (NTDLL.@)
* ZwWow64ReadVirtualMemory64 (NTDLL.@)

View file

@ -4407,6 +4407,7 @@ NTSYSAPI NTSTATUS WINAPI RtlWow64GetCpuAreaInfo(WOW64_CPURESERVED*,ULONG,WOW64_
NTSYSAPI NTSTATUS WINAPI RtlWow64GetThreadContext(HANDLE,WOW64_CONTEXT*);
NTSYSAPI NTSTATUS WINAPI RtlWow64SetThreadContext(HANDLE,const WOW64_CONTEXT*);
#else
NTSYSAPI NTSTATUS WINAPI NtWow64AllocateVirtualMemory64(HANDLE,ULONG64*,ULONG64,ULONG64*,ULONG,ULONG);
NTSYSAPI NTSTATUS WINAPI NtWow64ReadVirtualMemory64(HANDLE,ULONG64,void*,ULONG64,ULONG64*);
NTSYSAPI NTSTATUS WINAPI NtWow64WriteVirtualMemory64(HANDLE,ULONG64,const void*,ULONG64,ULONG64*);
NTSYSAPI LONGLONG WINAPI RtlConvertLongToLargeInteger(LONG);