Alexandre Julliard : ntdll: Implement NtWow64GetNativeSystemInformation().

Alexandre Julliard julliard at winehq.org
Mon Jul 5 16:24:19 CDT 2021


Module: wine
Branch: master
Commit: 04264305633ce75b8a1aadd1401cc646cfd872df
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=04264305633ce75b8a1aadd1401cc646cfd872df

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Jul  5 12:09:54 2021 +0200

ntdll: Implement NtWow64GetNativeSystemInformation().

Signed-off-by: Alexandre Julliard <julliard at 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);




More information about the wine-cvs mailing list