wow64: Implement Wow64AllocateTemp().

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-07-28 15:59:06 +02:00
parent 04d52eb83f
commit 65caa0f2ef
6 changed files with 52 additions and 12 deletions

View file

@ -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;
}

View file

@ -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.@)
*/

View file

@ -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 )))
{

View file

@ -1,6 +1,6 @@
@ stub Wow64AllocThreadHeap
@ stub Wow64AllocateHeap
@ stub Wow64AllocateTemp
@ stdcall Wow64AllocateTemp(long)
@ stdcall Wow64ApcRoutine(long long long ptr)
@ stub Wow64CheckIfNXEnabled
@ stub Wow64EmulateAtlThunk

View file

@ -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;

View file

@ -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