Alexandre Julliard : wow64: Implement Wow64AllocateTemp().

Alexandre Julliard julliard at winehq.org
Wed Jul 28 15:37:40 CDT 2021


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Jul 28 15:59:06 2021 +0200

wow64: Implement Wow64AllocateTemp().

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wow64/sync.c          |  9 +++------
 dlls/wow64/syscall.c       | 42 ++++++++++++++++++++++++++++++++++++++++++
 dlls/wow64/virtual.c       |  7 +++----
 dlls/wow64/wow64.spec      |  2 +-
 dlls/wow64/wow64_private.h |  3 ++-
 include/winternl.h         |  1 +
 6 files changed, 52 insertions(+), 12 deletions(-)

diff --git a/dlls/wow64/sync.c b/dlls/wow64/sync.c
index ef7176bd199..afea4a5c531 100644
--- a/dlls/wow64/sync.c
+++ b/dlls/wow64/sync.c
@@ -757,7 +757,7 @@ NTSTATUS WINAPI wow64_NtQueryDirectoryObject( UINT *args )
     ULONG size = size32 + sizeof(*info) - sizeof(*info32);
 
     if (!single_entry) FIXME( "not implemented\n" );
-    info = RtlAllocateHeap( GetProcessHeap(), 0, size );
+    info = Wow64AllocateTemp( size );
     status = NtQueryDirectoryObject( handle, info, size, single_entry, restart, context, NULL );
     if (!status)
     {
@@ -771,7 +771,6 @@ NTSTATUS WINAPI wow64_NtQueryDirectoryObject( UINT *args )
         memcpy( info32 + 1, info + 1, size );
         if (retlen) *retlen = sizeof(*info32) + size;
     }
-    RtlFreeHeap( GetProcessHeap(), 0, info );
     return status;
 }
 
@@ -845,7 +844,7 @@ NTSTATUS WINAPI wow64_NtQueryObject( UINT *args )
     {
         ULONG size = len + sizeof(OBJECT_NAME_INFORMATION) - sizeof(OBJECT_NAME_INFORMATION32);
         OBJECT_NAME_INFORMATION32 *info32 = ptr;
-        OBJECT_NAME_INFORMATION *info = RtlAllocateHeap( GetProcessHeap(), 0, size );
+        OBJECT_NAME_INFORMATION *info = Wow64AllocateTemp( size );
 
         if (!(status = NtQueryObject( handle, class, info, size, &ret_size )))
         {
@@ -867,7 +866,6 @@ NTSTATUS WINAPI wow64_NtQueryObject( UINT *args )
         {
             if (retlen) *retlen = ret_size - sizeof(*info) + sizeof(*info32);
         }
-        RtlFreeHeap( GetProcessHeap(), 0, info );
         return status;
     }
 
@@ -894,7 +892,7 @@ NTSTATUS WINAPI wow64_NtQueryObject( UINT *args )
         /* assume at most 32 types, with an average 16-char name */
         ULONG ret_size, size = 32 * (sizeof(OBJECT_TYPE_INFORMATION) + 16 * sizeof(WCHAR));
 
-        info = RtlAllocateHeap( GetProcessHeap(), 0, size );
+        info = Wow64AllocateTemp( size );
         if (!(status = NtQueryObject( handle, class, info, size, &ret_size )))
         {
             OBJECT_TYPE_INFORMATION *type;
@@ -915,7 +913,6 @@ NTSTATUS WINAPI wow64_NtQueryObject( UINT *args )
             if (pos32 > len) status = STATUS_INFO_LENGTH_MISMATCH;
             if (retlen) *retlen = pos32;
         }
-        RtlFreeHeap( GetProcessHeap(), 0, info );
         return status;
     }
 
diff --git a/dlls/wow64/syscall.c b/dlls/wow64/syscall.c
index 2f165879195..0000db54c29 100644
--- a/dlls/wow64/syscall.c
+++ b/dlls/wow64/syscall.c
@@ -54,6 +54,14 @@ static const char *syscall_names[] =
 
 static unsigned short syscall_map[1024];
 
+/* header for Wow64AllocTemp blocks; probably not the right layout */
+struct mem_header
+{
+    struct mem_header *next;
+    void              *__pad;
+    BYTE               data[1];
+};
+
 static SYSTEM_DLL_INIT_BLOCK *pLdrSystemDllInitBlock;
 
 void *dummy = RtlUnwind;
@@ -375,6 +383,22 @@ static void process_init(void)
 }
 
 
+/**********************************************************************
+ *           free_temp_data
+ */
+static void free_temp_data(void)
+{
+    struct mem_header *next, *mem;
+
+    for (mem = NtCurrentTeb()->TlsSlots[WOW64_TLS_TEMPLIST]; mem; mem = next)
+    {
+        next = mem->next;
+        RtlFreeHeap( GetProcessHeap(), 0, mem );
+    }
+    NtCurrentTeb()->TlsSlots[WOW64_TLS_TEMPLIST] = NULL;
+}
+
+
 /**********************************************************************
  *           Wow64SystemServiceEx  (NTDLL.@)
  */
@@ -397,10 +421,28 @@ NTSTATUS WINAPI Wow64SystemServiceEx( UINT num, UINT *args )
         status = GetExceptionCode();
     }
     __ENDTRY;
+    free_temp_data();
     return status;
 }
 
 
+/**********************************************************************
+ *           Wow64AllocateTemp
+ *
+ * FIXME: probably not 100% compatible.
+ */
+void * WINAPI Wow64AllocateTemp( SIZE_T size )
+{
+    struct mem_header *mem;
+
+    if (!(mem = RtlAllocateHeap( GetProcessHeap(), 0, offsetof( struct mem_header, data[size] ))))
+        return NULL;
+    mem->next = NtCurrentTeb()->TlsSlots[WOW64_TLS_TEMPLIST];
+    NtCurrentTeb()->TlsSlots[WOW64_TLS_TEMPLIST] = mem;
+    return mem->data;
+}
+
+
 /**********************************************************************
  *           Wow64ApcRoutine  (NTDLL.@)
  */
diff --git a/dlls/wow64/virtual.c b/dlls/wow64/virtual.c
index 36bd91d9f8c..3cf2b934c93 100644
--- a/dlls/wow64/virtual.c
+++ b/dlls/wow64/virtual.c
@@ -198,13 +198,12 @@ NTSTATUS WINAPI wow64_NtGetWriteWatch( UINT *args )
     if (flags & ~WRITE_WATCH_FLAG_RESET) return STATUS_INVALID_PARAMETER;
     if (!addr_ptr) return STATUS_ACCESS_VIOLATION;
 
-    addresses = RtlAllocateHeap( GetProcessHeap(), 0, count * sizeof(*addresses) );
+    addresses = Wow64AllocateTemp( count * sizeof(*addresses) );
     if (!(status = NtGetWriteWatch( handle, flags, base, size, addresses, &count, granularity )))
     {
         for (i = 0; i < count; i++) addr_ptr[i] = PtrToUlong( addresses[i] );
         *count_ptr = count;
     }
-    RtlFreeHeap( GetProcessHeap(), 0, addresses );
     return status;
 }
 
@@ -335,7 +334,7 @@ NTSTATUS WINAPI wow64_NtQueryVirtualMemory( UINT *args )
         MEMORY_SECTION_NAME32 *info32 = ptr;
         SIZE_T size = len + sizeof(*info) - sizeof(*info32);
 
-        info = RtlAllocateHeap( GetProcessHeap(), 0, size );
+        info = Wow64AllocateTemp( size );
         if (!(status = NtQueryVirtualMemory( handle, addr, class, info, size, &res_len )))
         {
             info32->SectionFileName.Length = info->SectionFileName.Length;
@@ -353,7 +352,7 @@ NTSTATUS WINAPI wow64_NtQueryVirtualMemory( UINT *args )
         MEMORY_WORKING_SET_EX_INFORMATION *info;
         ULONG i, count = len / sizeof(*info32);
 
-        info = RtlAllocateHeap( GetProcessHeap(), 0, count * sizeof(*info) );
+        info = Wow64AllocateTemp( 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 )))
         {
diff --git a/dlls/wow64/wow64.spec b/dlls/wow64/wow64.spec
index 8f188043556..4ed20af0f29 100644
--- a/dlls/wow64/wow64.spec
+++ b/dlls/wow64/wow64.spec
@@ -1,6 +1,6 @@
 @ stub Wow64AllocThreadHeap
 @ stub Wow64AllocateHeap
-@ stub Wow64AllocateTemp
+@ stdcall Wow64AllocateTemp(long)
 @ stdcall Wow64ApcRoutine(long long long ptr)
 @ stub Wow64CheckIfNXEnabled
 @ stub Wow64EmulateAtlThunk
diff --git a/dlls/wow64/wow64_private.h b/dlls/wow64/wow64_private.h
index 6ba77720263..e9935303cbb 100644
--- a/dlls/wow64/wow64_private.h
+++ b/dlls/wow64/wow64_private.h
@@ -28,7 +28,8 @@
 ALL_SYSCALLS
 #undef SYSCALL_ENTRY
 
-void WINAPI Wow64ApcRoutine( ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, CONTEXT *context ) DECLSPEC_HIDDEN;
+void * WINAPI Wow64AllocateTemp( SIZE_T size ) DECLSPEC_HIDDEN;
+void   WINAPI Wow64ApcRoutine( ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, CONTEXT *context ) DECLSPEC_HIDDEN;
 
 extern USHORT native_machine DECLSPEC_HIDDEN;
 extern USHORT current_machine DECLSPEC_HIDDEN;
diff --git a/include/winternl.h b/include/winternl.h
index 7d732d895d9..10d6de1f9ed 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -1081,6 +1081,7 @@ typedef struct _TEB64
 
 /* reserved TEB64 TLS slots for Wow64 */
 #define WOW64_TLS_CPURESERVED  1
+#define WOW64_TLS_TEMPLIST     3
 #define WOW64_TLS_FILESYSREDIR 8
 
 




More information about the wine-cvs mailing list