Module: wine Branch: master Commit: 65caa0f2efc810993d76dcee7d7c94319905349f URL: https://source.winehq.org/git/wine.git/?a=commit;h=65caa0f2efc810993d76dcee7...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Jul 28 15:59:06 2021 +0200
wow64: Implement Wow64AllocateTemp().
Signed-off-by: Alexandre Julliard julliard@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