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