Alexandre Julliard : ntdll: Implement RtlWow64GetCpuAreaInfo().
Alexandre Julliard
julliard at winehq.org
Wed May 12 15:44:28 CDT 2021
Module: wine
Branch: master
Commit: e97a2c4c0f330ac1a523ca42573ba93bcc295710
URL: https://source.winehq.org/git/wine.git/?a=commit;h=e97a2c4c0f330ac1a523ca42573ba93bcc295710
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed May 12 15:30:41 2021 +0200
ntdll: Implement RtlWow64GetCpuAreaInfo().
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/ntdll.spec | 1 +
dlls/ntdll/process.c | 36 +++++++++++++++++++++++++++++++++
dlls/ntdll/tests/info.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++-
include/winternl.h | 29 +++++++++++++++++++++++----
4 files changed, 114 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 05712d842c4..06ca3d3957c 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1070,6 +1070,7 @@
@ stdcall RtlWalkHeap(long ptr)
@ stdcall RtlWow64EnableFsRedirection(long)
@ stdcall RtlWow64EnableFsRedirectionEx(long ptr)
+@ stdcall -arch=win64 RtlWow64GetCpuAreaInfo(ptr long ptr)
@ stdcall RtlWow64GetCurrentMachine()
@ stdcall RtlWow64GetProcessMachines(long ptr ptr)
@ stdcall -arch=x86_64 RtlWow64GetThreadContext(long ptr)
diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
index dbb94cfb8b7..82b1b69c4ea 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -108,6 +108,42 @@ NTSTATUS WINAPI RtlWow64IsWowGuestMachineSupported( USHORT machine, BOOLEAN *sup
}
+#ifdef _WIN64
+
+/**********************************************************************
+ * RtlWow64GetCpuAreaInfo (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlWow64GetCpuAreaInfo( WOW64_CPURESERVED *cpu, ULONG reserved, WOW64_CPU_AREA_INFO *info )
+{
+ static const struct { ULONG machine, align, size, offset, flag; } data[] =
+ {
+#define ENTRY(machine,type,flag) { machine, TYPE_ALIGNMENT(type), sizeof(type), offsetof(type,ContextFlags), flag },
+ ENTRY( IMAGE_FILE_MACHINE_I386, I386_CONTEXT, CONTEXT_i386 )
+ ENTRY( IMAGE_FILE_MACHINE_AMD64, AMD64_CONTEXT, CONTEXT_AMD64 )
+ ENTRY( IMAGE_FILE_MACHINE_ARMNT, ARM_CONTEXT, CONTEXT_ARM )
+ ENTRY( IMAGE_FILE_MACHINE_ARM64, ARM64_NT_CONTEXT, CONTEXT_ARM64 )
+#undef ENTRY
+ };
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(data); i++)
+ {
+#define ALIGN(ptr,align) ((void *)(((ULONG_PTR)(ptr) + (align) - 1) & ~((align) - 1)))
+ if (data[i].machine != cpu->Machine) continue;
+ info->Context = ALIGN( cpu + 1, data[i].align );
+ info->ContextEx = ALIGN( (char *)info->Context + data[i].size, sizeof(void *) );
+ info->ContextFlagsLocation = (char *)info->Context + data[i].offset;
+ info->ContextFlag = data[i].flag;
+ info->CpuReserved = cpu;
+ info->Machine = data[i].machine;
+ return STATUS_SUCCESS;
+#undef ALIGN
+ }
+ return STATUS_INVALID_PARAMETER;
+}
+
+#endif
+
/**********************************************************************
* RtlCreateUserProcess (NTDLL.@)
*/
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 1c1722ee392..bca2086fee9 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -25,6 +25,7 @@
static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
static NTSTATUS (WINAPI * pNtSetSystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG);
static NTSTATUS (WINAPI * pRtlGetNativeSystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
+static NTSTATUS (WINAPI * pRtlWow64GetCpuAreaInfo)( WOW64_CPURESERVED *cpu, ULONG reserved, WOW64_CPU_AREA_INFO *info );
static USHORT (WINAPI * pRtlWow64GetCurrentMachine)(void);
static NTSTATUS (WINAPI * pRtlWow64GetProcessMachines)(HANDLE,WORD*,WORD*);
static NTSTATUS (WINAPI * pRtlWow64IsWowGuestMachineSupported)(USHORT,BOOLEAN*);
@@ -85,6 +86,7 @@ static BOOL InitFunctionPtrs(void)
NTDLL_GET_PROC(NtQuerySystemInformation);
NTDLL_GET_PROC(NtSetSystemInformation);
NTDLL_GET_PROC(RtlGetNativeSystemInformation);
+ NTDLL_GET_PROC(RtlWow64GetCpuAreaInfo);
NTDLL_GET_PROC(RtlWow64GetCurrentMachine);
NTDLL_GET_PROC(RtlWow64GetProcessMachines);
NTDLL_GET_PROC(RtlWow64IsWowGuestMachineSupported);
@@ -3133,7 +3135,56 @@ static void test_thread_info(void)
static void test_wow64(void)
{
-#ifndef _WIN64
+#ifdef _WIN64
+ if (pRtlWow64GetCpuAreaInfo)
+ {
+ static const struct
+ {
+ USHORT machine;
+ NTSTATUS expect;
+ ULONG align, size, offset, flag;
+ } tests[] =
+ {
+ { IMAGE_FILE_MACHINE_I386, 0, 4, 0x2cc, 0x00, 0x00010000 },
+ { IMAGE_FILE_MACHINE_AMD64, 0, 16, 0x4d0, 0x30, 0x00100000 },
+ { IMAGE_FILE_MACHINE_ARMNT, 0, 8, 0x1a0, 0x00, 0x00200000 },
+ { IMAGE_FILE_MACHINE_ARM64, 0, 16, 0x390, 0x00, 0x00400000 },
+ { IMAGE_FILE_MACHINE_ARM, STATUS_INVALID_PARAMETER },
+ { IMAGE_FILE_MACHINE_THUMB, STATUS_INVALID_PARAMETER },
+ };
+ USHORT buffer[2048];
+ WOW64_CPURESERVED *cpu;
+ WOW64_CPU_AREA_INFO info;
+ ULONG i, j;
+ NTSTATUS status;
+#define ALIGN(ptr,align) ((void *)(((ULONG_PTR)(ptr) + (align) - 1) & ~((align) - 1)))
+
+ for (i = 0; i < ARRAY_SIZE(tests); i++)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ cpu = (WOW64_CPURESERVED *)(buffer + j);
+ cpu->Flags = 0;
+ cpu->Machine = tests[i].machine;
+ status = pRtlWow64GetCpuAreaInfo( cpu, 0, &info );
+ ok( status == tests[i].expect, "%u:%u: failed %x\n", i, j, status );
+ if (status) continue;
+ ok( info.Context == ALIGN( cpu + 1, tests[i].align ), "%u:%u: wrong offset %u\n",
+ i, j, (ULONG)((char *)info.Context - (char *)cpu) );
+ ok( info.ContextEx == ALIGN( (char *)info.Context + tests[i].size, sizeof(void*) ),
+ "%u:%u: wrong ex offset %u\n", i, j, (ULONG)((char *)info.ContextEx - (char *)cpu) );
+ ok( info.ContextFlagsLocation == (char *)info.Context + tests[i].offset,
+ "%u:%u: wrong flags offset %u\n",
+ i, j, (ULONG)((char *)info.ContextFlagsLocation - (char *)info.Context) );
+ ok( info.CpuReserved == cpu, "%u:%u: wrong cpu %p / %p\n", info.CpuReserved, cpu );
+ ok( info.ContextFlag == tests[i].flag, "%u:%u: wrong flag %08x\n", i, j, info.ContextFlag );
+ ok( info.Machine == tests[i].machine, "%u:%u: wrong machine %x\n", i, j, info.Machine );
+ }
+ }
+#undef ALIGN
+ }
+ else win_skip( "RtlWow64GetCpuAreaInfo not supported\n" );
+#else
if (is_wow64)
{
PEB64 *peb64;
diff --git a/include/winternl.h b/include/winternl.h
index 1839f4a0151..c9868fb5e39 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -3588,6 +3588,25 @@ typedef enum _DEBUGOBJECTINFOCLASS
MaxDebugObjectInfoClass
} DEBUGOBJECTINFOCLASS, *PDEBUGOBJECTINFOCLASS;
+
+typedef struct _WOW64_CPURESERVED
+{
+ USHORT Flags;
+ USHORT Machine;
+ /* CONTEXT context */
+ /* CONTEXT_EX *context_ex */
+} WOW64_CPURESERVED, *PWOW64_CPURESERVED;
+
+typedef struct _WOW64_CPU_AREA_INFO
+{
+ void *Context;
+ void *ContextEx;
+ void *ContextFlagsLocation;
+ WOW64_CPURESERVED *CpuReserved;
+ ULONG ContextFlag;
+ USHORT Machine;
+} WOW64_CPU_AREA_INFO, *PWOW64_CPU_AREA_INFO;
+
/***********************************************************************
* Function declarations
*/
@@ -4249,10 +4268,6 @@ NTSYSAPI NTSTATUS WINAPI RtlWow64EnableFsRedirection(BOOLEAN);
NTSYSAPI NTSTATUS WINAPI RtlWow64EnableFsRedirectionEx(ULONG,ULONG*);
NTSYSAPI USHORT WINAPI RtlWow64GetCurrentMachine(void);
NTSYSAPI NTSTATUS WINAPI RtlWow64GetProcessMachines(HANDLE,USHORT*,USHORT*);
-#ifdef __x86_64__
-NTSYSAPI NTSTATUS WINAPI RtlWow64GetThreadContext(HANDLE, WOW64_CONTEXT *);
-NTSYSAPI NTSTATUS WINAPI RtlWow64SetThreadContext(HANDLE, const WOW64_CONTEXT *);
-#endif
NTSYSAPI NTSTATUS WINAPI RtlWow64IsWowGuestMachineSupported(USHORT,BOOLEAN*);
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG,PCWSTR,PCWSTR,ULONG,PVOID,ULONG);
NTSYSAPI NTSTATUS WINAPI RtlZombifyActivationContext(HANDLE);
@@ -4263,6 +4278,12 @@ NTSYSAPI NTSTATUS WINAPI RtlpUnWaitCriticalSection(RTL_CRITICAL_SECTION *);
NTSYSAPI NTSTATUS WINAPI vDbgPrintEx(ULONG,ULONG,LPCSTR,__ms_va_list);
NTSYSAPI NTSTATUS WINAPI vDbgPrintExWithPrefix(LPCSTR,ULONG,ULONG,LPCSTR,__ms_va_list);
+#ifdef _WIN64
+NTSYSAPI NTSTATUS WINAPI RtlWow64GetCpuAreaInfo(WOW64_CPURESERVED*,ULONG,WOW64_CPU_AREA_INFO*);
+NTSYSAPI NTSTATUS WINAPI RtlWow64GetThreadContext(HANDLE,WOW64_CONTEXT*);
+NTSYSAPI NTSTATUS WINAPI RtlWow64SetThreadContext(HANDLE,const WOW64_CONTEXT*);
+#endif
+
#if defined(__x86_64__) || defined(__i386__)
NTSYSAPI NTSTATUS WINAPI RtlCopyExtendedContext(CONTEXT_EX*,ULONG,CONTEXT_EX*);
NTSYSAPI NTSTATUS WINAPI RtlInitializeExtendedContext(void*,ULONG,CONTEXT_EX**);
More information about the wine-cvs
mailing list