ntdll: Implement RtlWow64GetCpuAreaInfo().
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7a25671c38
commit
e97a2c4c0f
|
@ -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)
|
||||
|
|
|
@ -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.@)
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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**);
|
||||
|
|
Loading…
Reference in New Issue