Alexandre Julliard : wow64: Add a thunk for the NtQueryVirtualMemory syscall.

Alexandre Julliard julliard at winehq.org
Tue Jul 27 15:51:00 CDT 2021


Module: wine
Branch: master
Commit: ee2ee4d1ef1a6149a919fcad1f8ef324cbe18672
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=ee2ee4d1ef1a6149a919fcad1f8ef324cbe18672

Author: Alexandre Julliard <julliard at 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 at 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
  */




More information about the wine-cvs mailing list