Module: wine Branch: master Commit: ee2ee4d1ef1a6149a919fcad1f8ef324cbe18672 URL: https://source.winehq.org/git/wine.git/?a=commit;h=ee2ee4d1ef1a6149a919fcad1...
Author: Alexandre Julliard julliard@winehq.org Date: Tue Jul 27 12:00:27 2021 +0200
wow64: Add a thunk for the NtQueryVirtualMemory syscall.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/wow64/struct32.h | 36 ++++++++++++++++++++++ dlls/wow64/syscall.h | 1 + dlls/wow64/virtual.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+)
diff --git a/dlls/wow64/struct32.h b/dlls/wow64/struct32.h index b96fdae80ca..069564948d0 100644 --- a/dlls/wow64/struct32.h +++ b/dlls/wow64/struct32.h @@ -69,6 +69,42 @@ typedef struct UNICODE_STRING32 ObjectTypeName; } DIRECTORY_BASIC_INFORMATION32;
+typedef struct +{ + ULONG BaseAddress; + ULONG AllocationBase; + DWORD AllocationProtect; + ULONG RegionSize; + DWORD State; + DWORD Protect; + DWORD Type; +} MEMORY_BASIC_INFORMATION32; + +typedef struct +{ + UNICODE_STRING32 SectionFileName; +} MEMORY_SECTION_NAME32; + +typedef union +{ + ULONG Flags; + struct { + ULONG Valid : 1; + ULONG ShareCount : 3; + ULONG Win32Protection : 11; + ULONG Shared : 1; + ULONG Node : 6; + ULONG Locked : 1; + ULONG LargePage : 1; + }; +} MEMORY_WORKING_SET_EX_BLOCK32; + +typedef struct +{ + ULONG VirtualAddress; + MEMORY_WORKING_SET_EX_BLOCK32 VirtualAttributes; +} MEMORY_WORKING_SET_EX_INFORMATION32; + typedef struct { ULONG BaseAddress; diff --git a/dlls/wow64/syscall.h b/dlls/wow64/syscall.h index 95c2cf646e3..2cdca8a3e8d 100644 --- a/dlls/wow64/syscall.h +++ b/dlls/wow64/syscall.h @@ -105,6 +105,7 @@ SYSCALL_ENTRY( NtQueryTimer ) \ SYSCALL_ENTRY( NtQueryTimerResolution ) \ SYSCALL_ENTRY( NtQueryValueKey ) \ + SYSCALL_ENTRY( NtQueryVirtualMemory ) \ SYSCALL_ENTRY( NtReadVirtualMemory ) \ SYSCALL_ENTRY( NtReleaseKeyedEvent ) \ SYSCALL_ENTRY( NtReleaseMutant ) \ diff --git a/dlls/wow64/virtual.c b/dlls/wow64/virtual.c index fad79a2de60..e1eaa053109 100644 --- a/dlls/wow64/virtual.c +++ b/dlls/wow64/virtual.c @@ -291,6 +291,88 @@ NTSTATUS WINAPI wow64_NtProtectVirtualMemory( UINT *args ) }
+/********************************************************************** + * wow64_NtQueryVirtualMemory + */ +NTSTATUS WINAPI wow64_NtQueryVirtualMemory( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + void *addr = get_ptr( &args ); + MEMORY_INFORMATION_CLASS class = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + SIZE_T res_len = 0; + NTSTATUS status; + + switch (class) + { + case MemoryBasicInformation: /* MEMORY_BASIC_INFORMATION */ + if (len >= sizeof(MEMORY_BASIC_INFORMATION32)) + { + MEMORY_BASIC_INFORMATION info; + MEMORY_BASIC_INFORMATION32 *info32 = ptr; + + if (!(status = NtQueryVirtualMemory( handle, addr, class, &info, sizeof(info), &res_len ))) + { + info32->BaseAddress = PtrToUlong( info.BaseAddress ); + info32->AllocationBase = PtrToUlong( info.AllocationBase ); + info32->AllocationProtect = info.AllocationProtect; + info32->RegionSize = info.RegionSize; + info32->State = info.State; + info32->Protect = info.Protect; + info32->Type = info.Type; + } + } + else status = STATUS_INFO_LENGTH_MISMATCH; + res_len = sizeof(MEMORY_BASIC_INFORMATION32); + break; + + case MemorySectionName: /* MEMORY_SECTION_NAME */ + { + MEMORY_SECTION_NAME *info; + MEMORY_SECTION_NAME32 *info32 = ptr; + SIZE_T size = len + sizeof(*info) - sizeof(*info32); + + info = RtlAllocateHeap( GetProcessHeap(), 0, size ); + if (!(status = NtQueryVirtualMemory( handle, addr, class, info, size, &res_len ))) + { + info32->SectionFileName.Length = info->SectionFileName.Length; + info32->SectionFileName.MaximumLength = info->SectionFileName.MaximumLength; + info32->SectionFileName.Buffer = PtrToUlong( info32 + 1 ); + memcpy( info32 + 1, info->SectionFileName.Buffer, info->SectionFileName.MaximumLength ); + } + res_len += sizeof(*info32) - sizeof(*info); + break; + } + + case MemoryWorkingSetExInformation: /* MEMORY_WORKING_SET_EX_INFORMATION */ + { + MEMORY_WORKING_SET_EX_INFORMATION32 *info32 = ptr; + MEMORY_WORKING_SET_EX_INFORMATION *info; + ULONG i, count = len / sizeof(*info32); + + info = RtlAllocateHeap( GetProcessHeap(), 0, count * sizeof(*info) ); + for (i = 0; i < count; i++) info[i].VirtualAddress = ULongToPtr( info32[i].VirtualAddress ); + if (!(status = NtQueryVirtualMemory( handle, addr, class, info, count * sizeof(*info), &res_len ))) + { + count = res_len / sizeof(*info); + for (i = 0; i < count; i++) info32[i].VirtualAttributes.Flags = info[i].VirtualAttributes.Flags; + res_len = count * sizeof(*info32); + } + break; + } + + default: + FIXME( "unsupported class %u\n", class ); + return STATUS_INVALID_INFO_CLASS; + } + if (!status || status == STATUS_INFO_LENGTH_MISMATCH) put_size( retlen, res_len ); + return status; +} + + /********************************************************************** * wow64_NtReadVirtualMemory */