Module: wine Branch: master Commit: 04264305633ce75b8a1aadd1401cc646cfd872df URL: https://source.winehq.org/git/wine.git/?a=commit;h=04264305633ce75b8a1aadd14...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Jul 5 12:09:54 2021 +0200
ntdll: Implement NtWow64GetNativeSystemInformation().
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/ntdll.spec | 2 ++ dlls/ntdll/tests/wow64.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/unix/virtual.c | 23 ++++++++++++++++ include/winternl.h | 1 + 4 files changed, 95 insertions(+)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 1067bbca96f..85fa37fddb3 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -431,6 +431,7 @@ @ stub NtWaitHighEventPair @ stub NtWaitLowEventPair @ stdcall -syscall -arch=win32 NtWow64AllocateVirtualMemory64(long ptr int64 ptr long long) +@ stdcall -syscall -arch=win32 NtWow64GetNativeSystemInformation(long ptr long ptr) @ stdcall -syscall -arch=win32 NtWow64ReadVirtualMemory64(long int64 ptr int64 ptr) @ stdcall -syscall -arch=win32 NtWow64WriteVirtualMemory64(long int64 ptr int64 ptr) @ stdcall -syscall NtWriteFile(long long ptr ptr ptr ptr long ptr ptr) @@ -1450,6 +1451,7 @@ @ stub ZwWaitHighEventPair @ stub ZwWaitLowEventPair @ stdcall -syscall -arch=win32 ZwWow64AllocateVirtualMemory64(long ptr int64 ptr long long) NtWow64AllocateVirtualMemory64 +@ stdcall -syscall -arch=win32 ZwWow64GetNativeSystemInformation(long ptr long ptr) NtWow64GetNativeSystemInformation @ stdcall -syscall -arch=win32 ZwWow64ReadVirtualMemory64(long int64 ptr int64 ptr) NtWow64ReadVirtualMemory64 @ stdcall -syscall -arch=win32 ZwWow64WriteVirtualMemory64(long int64 ptr int64 ptr) NtWow64WriteVirtualMemory64 @ stdcall -private -syscall ZwWriteFile(long long ptr ptr ptr ptr long ptr ptr) NtWriteFile diff --git a/dlls/ntdll/tests/wow64.c b/dlls/ntdll/tests/wow64.c index 82543c250af..807d5486a15 100644 --- a/dlls/ntdll/tests/wow64.c +++ b/dlls/ntdll/tests/wow64.c @@ -21,7 +21,9 @@
#include "ntdll_test.h"
+static NTSTATUS (WINAPI *pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS,void*,ULONG,ULONG*); static NTSTATUS (WINAPI *pNtQuerySystemInformationEx)(SYSTEM_INFORMATION_CLASS,void*,ULONG,void*,ULONG,ULONG*); +static NTSTATUS (WINAPI *pRtlGetNativeSystemInformation)(SYSTEM_INFORMATION_CLASS,void*,ULONG,ULONG*); static USHORT (WINAPI *pRtlWow64GetCurrentMachine)(void); static NTSTATUS (WINAPI *pRtlWow64GetProcessMachines)(HANDLE,WORD*,WORD*); static NTSTATUS (WINAPI *pRtlWow64GetThreadContext)(HANDLE,WOW64_CONTEXT*); @@ -31,6 +33,7 @@ static NTSTATUS (WINAPI *pRtlWow64GetCpuAreaInfo)(WOW64_CPURESERVED*,ULONG,WOW64 static NTSTATUS (WINAPI *pRtlWow64GetThreadSelectorEntry)(HANDLE,THREAD_DESCRIPTOR_INFORMATION*,ULONG,ULONG*); #else static NTSTATUS (WINAPI *pNtWow64AllocateVirtualMemory64)(HANDLE,ULONG64*,ULONG64,ULONG64*,ULONG,ULONG); +static NTSTATUS (WINAPI *pNtWow64GetNativeSystemInformation)(SYSTEM_INFORMATION_CLASS,void*,ULONG,ULONG*); static NTSTATUS (WINAPI *pNtWow64ReadVirtualMemory64)(HANDLE,ULONG64,void*,ULONG64,ULONG64*); static NTSTATUS (WINAPI *pNtWow64WriteVirtualMemory64)(HANDLE,ULONG64,const void *,ULONG64,ULONG64*); #endif @@ -45,7 +48,9 @@ static void init(void) if (!IsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
#define GET_PROC(func) p##func = (void *)GetProcAddress( ntdll, #func ) + GET_PROC( NtQuerySystemInformation ); GET_PROC( NtQuerySystemInformationEx ); + GET_PROC( RtlGetNativeSystemInformation ); GET_PROC( RtlWow64GetCurrentMachine ); GET_PROC( RtlWow64GetProcessMachines ); GET_PROC( RtlWow64GetThreadContext ); @@ -55,6 +60,7 @@ static void init(void) GET_PROC( RtlWow64GetThreadSelectorEntry ); #else GET_PROC( NtWow64AllocateVirtualMemory64 ); + GET_PROC( NtWow64GetNativeSystemInformation ); GET_PROC( NtWow64ReadVirtualMemory64 ); GET_PROC( NtWow64WriteVirtualMemory64 ); #endif @@ -884,6 +890,69 @@ static void test_nt_wow64(void) } else win_skip( "NtWow64AllocateVirtualMemory64 not supported\n" );
+ if (pNtWow64GetNativeSystemInformation) + { + ULONG i, len; + SYSTEM_BASIC_INFORMATION sbi, sbi2, sbi3; + + memset( &sbi, 0xcc, sizeof(sbi) ); + status = pNtQuerySystemInformation( SystemBasicInformation, &sbi, sizeof(sbi), &len ); + ok( status == STATUS_SUCCESS, "failed %x\n", status ); + ok( len == sizeof(sbi), "wrong length %d\n", len ); + + memset( &sbi2, 0xcc, sizeof(sbi2) ); + status = pRtlGetNativeSystemInformation( SystemBasicInformation, &sbi2, sizeof(sbi2), &len ); + ok( status == STATUS_SUCCESS, "failed %x\n", status ); + ok( len == sizeof(sbi2), "wrong length %d\n", len ); + + ok( sbi.HighestUserAddress == (void *)0x7ffeffff, "wrong limit %p\n", sbi.HighestUserAddress); + todo_wine_if( is_wow64 ) + ok( sbi2.HighestUserAddress == (is_wow64 ? (void *)0xfffeffff : (void *)0x7ffeffff), + "wrong limit %p\n", sbi.HighestUserAddress); + + memset( &sbi3, 0xcc, sizeof(sbi3) ); + status = pNtWow64GetNativeSystemInformation( SystemBasicInformation, &sbi3, sizeof(sbi3), &len ); + ok( status == STATUS_SUCCESS, "failed %x\n", status ); + ok( len == sizeof(sbi3), "wrong length %d\n", len ); + ok( !memcmp( &sbi2, &sbi3, offsetof(SYSTEM_BASIC_INFORMATION,NumberOfProcessors)+1 ), + "info is different\n" ); + + memset( &sbi3, 0xcc, sizeof(sbi3) ); + status = pNtWow64GetNativeSystemInformation( SystemEmulationBasicInformation, &sbi3, sizeof(sbi3), &len ); + ok( status == STATUS_SUCCESS, "failed %x\n", status ); + ok( len == sizeof(sbi3), "wrong length %d\n", len ); + ok( !memcmp( &sbi, &sbi3, offsetof(SYSTEM_BASIC_INFORMATION,NumberOfProcessors)+1 ), + "info is different\n" ); + + for (i = 0; i < 256; i++) + { + NTSTATUS expect = pNtQuerySystemInformation( i, NULL, 0, &len ); + status = pNtWow64GetNativeSystemInformation( i, NULL, 0, &len ); + switch (i) + { + case SystemNativeBasicInformation: + ok( status == STATUS_INVALID_INFO_CLASS || status == STATUS_INFO_LENGTH_MISMATCH || + broken(status == STATUS_NOT_IMPLEMENTED) /* vista */, "%u: %x / %x\n", i, status, expect ); + break; + case SystemBasicInformation: + case SystemCpuInformation: + case SystemEmulationBasicInformation: + case SystemEmulationProcessorInformation: + ok( status == expect, "%u: %x / %x\n", i, status, expect ); + break; + default: + if (is_wow64) /* only a few info classes are supported on Wow64 */ + ok( status == STATUS_INVALID_INFO_CLASS || + broken(status == STATUS_NOT_IMPLEMENTED), /* vista */ + "%u: %x\n", i, status ); + else + ok( status == expect, "%u: %x / %x\n", i, status, expect ); + break; + } + } + } + else win_skip( "NtWow64GetNativeSystemInformation not supported\n" ); + NtClose( process ); }
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index c99cb424b57..1838e9d9791 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -4988,4 +4988,27 @@ NTSTATUS WINAPI NtWow64WriteVirtualMemory64( HANDLE process, ULONG64 addr, const return status; }
+ +/*********************************************************************** + * NtWow64GetNativeSystemInformation (NTDLL.@) + * ZwWow64GetNativeSystemInformation (NTDLL.@) + */ +NTSTATUS WINAPI NtWow64GetNativeSystemInformation( SYSTEM_INFORMATION_CLASS class, void *info, + ULONG len, ULONG *retlen ) +{ + switch (class) + { + case SystemBasicInformation: + case SystemCpuInformation: + case SystemEmulationBasicInformation: + case SystemEmulationProcessorInformation: + return NtQuerySystemInformation( class, info, len, retlen ); + case SystemNativeBasicInformation: + return NtQuerySystemInformation( SystemBasicInformation, info, len, retlen ); + default: + if (is_wow64) return STATUS_INVALID_INFO_CLASS; + return NtQuerySystemInformation( class, info, len, retlen ); + } +} + #endif /* _WIN64 */ diff --git a/include/winternl.h b/include/winternl.h index 6716b5fe699..6dc88fee343 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -4410,6 +4410,7 @@ NTSYSAPI NTSTATUS WINAPI RtlWow64GetThreadSelectorEntry(HANDLE,THREAD_DESCRIPTO NTSYSAPI NTSTATUS WINAPI RtlWow64SetThreadContext(HANDLE,const WOW64_CONTEXT*); #else NTSYSAPI NTSTATUS WINAPI NtWow64AllocateVirtualMemory64(HANDLE,ULONG64*,ULONG64,ULONG64*,ULONG,ULONG); +NTSYSAPI NTSTATUS WINAPI NtWow64GetNativeSystemInformation(SYSTEM_INFORMATION_CLASS,void*,ULONG,ULONG*); NTSYSAPI NTSTATUS WINAPI NtWow64ReadVirtualMemory64(HANDLE,ULONG64,void*,ULONG64,ULONG64*); NTSYSAPI NTSTATUS WINAPI NtWow64WriteVirtualMemory64(HANDLE,ULONG64,const void*,ULONG64,ULONG64*); NTSYSAPI LONGLONG WINAPI RtlConvertLongToLargeInteger(LONG);