Module: wine Branch: master Commit: 257221843f6fc8fb0b96ba4a8873e4e9c6588f84 URL: https://gitlab.winehq.org/wine/wine/-/commit/257221843f6fc8fb0b96ba4a8873e4e...
Author: Alexandre Julliard julliard@winehq.org Date: Tue Jul 11 16:56:50 2023 +0200
ntdll: Implement RtlWow64GetSharedInfoProcess().
---
dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/process.c | 15 ++++++++++++ dlls/ntdll/tests/wow64.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ include/winternl.h | 2 ++ 4 files changed, 78 insertions(+)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 2be318b128a..011f0648522 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -1104,6 +1104,7 @@ @ stdcall -arch=win64 RtlWow64GetCurrentCpuArea(ptr ptr ptr) @ stdcall RtlWow64GetCurrentMachine() @ stdcall RtlWow64GetProcessMachines(long ptr ptr) +@ stdcall RtlWow64GetSharedInfoProcess(long ptr ptr) @ stdcall -arch=win64 RtlWow64GetThreadContext(long ptr) @ stdcall -arch=win64 RtlWow64GetThreadSelectorEntry(long ptr long ptr) @ stdcall RtlWow64IsWowGuestMachineSupported(long ptr) diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c index 3f78559d8df..09cc86889b9 100644 --- a/dlls/ntdll/process.c +++ b/dlls/ntdll/process.c @@ -128,6 +128,21 @@ NTSTATUS WINAPI RtlWow64GetProcessMachines( HANDLE process, USHORT *current_ret, }
+/********************************************************************** + * RtlWow64GetSharedInfoProcess (NTDLL.@) + */ +NTSTATUS WINAPI RtlWow64GetSharedInfoProcess( HANDLE process, BOOLEAN *is_wow64, WOW64INFO *info ) +{ + PEB32 *peb32; + NTSTATUS status = NtQueryInformationProcess( process, ProcessWow64Information, + &peb32, sizeof(peb32), NULL ); + if (status) return status; + if (peb32) status = NtReadVirtualMemory( process, peb32 + 1, info, sizeof(*info), NULL ); + *is_wow64 = !!peb32; + return status; +} + + /********************************************************************** * RtlWow64IsWowGuestMachineSupported (NTDLL.@) */ diff --git a/dlls/ntdll/tests/wow64.c b/dlls/ntdll/tests/wow64.c index 46523d47c46..e9f1c10ec43 100644 --- a/dlls/ntdll/tests/wow64.c +++ b/dlls/ntdll/tests/wow64.c @@ -21,6 +21,7 @@
#include "ntdll_test.h" #include "winioctl.h" +#include "winuser.h" #include "ddk/wdm.h"
static NTSTATUS (WINAPI *pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS,void*,ULONG,ULONG*); @@ -28,6 +29,7 @@ static NTSTATUS (WINAPI *pNtQuerySystemInformationEx)(SYSTEM_INFORMATION_CLASS,v 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 *pRtlWow64GetSharedInfoProcess)(HANDLE,BOOLEAN*,WOW64INFO*); static NTSTATUS (WINAPI *pRtlWow64GetThreadContext)(HANDLE,WOW64_CONTEXT*); static NTSTATUS (WINAPI *pRtlWow64IsWowGuestMachineSupported)(USHORT,BOOLEAN*); static NTSTATUS (WINAPI *pNtMapViewOfSectionEx)(HANDLE,HANDLE,PVOID*,const LARGE_INTEGER*,SIZE_T*,ULONG,ULONG,MEM_EXTENDED_PARAMETER*,ULONG); @@ -87,6 +89,7 @@ static void init(void) GET_PROC( RtlGetNativeSystemInformation ); GET_PROC( RtlWow64GetCurrentMachine ); GET_PROC( RtlWow64GetProcessMachines ); + GET_PROC( RtlWow64GetSharedInfoProcess ); GET_PROC( RtlWow64GetThreadContext ); GET_PROC( RtlWow64IsWowGuestMachineSupported ); #ifdef _WIN64 @@ -278,6 +281,9 @@ static void test_peb_teb(void) RTL_USER_PROCESS_PARAMETERS params; RTL_USER_PROCESS_PARAMETERS32 params32; ULONG_PTR peb_ptr; + ULONG buffer[16]; + WOW64INFO *wow64info = (WOW64INFO *)buffer; + BOOLEAN wow64;
Wow64DisableWow64FsRedirection( &redir );
@@ -370,6 +376,47 @@ static void test_peb_teb(void) params32.EnvironmentSize, params.EnvironmentSize ); }
+ ResumeThread( pi.hThread ); + WaitForInputIdle( pi.hProcess, 1000 ); + + if (pRtlWow64GetSharedInfoProcess) + { + ULONG i, peb_data[0x200]; + + wow64 = 0xcc; + memset( buffer, 0xcc, sizeof(buffer) ); + status = pRtlWow64GetSharedInfoProcess( pi.hProcess, &wow64, wow64info ); + ok( !status, "RtlWow64GetSharedInfoProcess failed %lx\n", status ); + ok( wow64 == TRUE, "wrong wow64 %u\n", wow64 ); + todo_wine_if (!wow64info->NativeSystemPageSize) /* not set in old wow64 */ + { + ok( wow64info->NativeSystemPageSize == 0x1000, "wrong page size %lx\n", + wow64info->NativeSystemPageSize ); + ok( wow64info->CpuFlags == (native_machine == IMAGE_FILE_MACHINE_AMD64 ? WOW64_CPUFLAGS_MSFT64 : WOW64_CPUFLAGS_SOFTWARE), + "wrong flags %lx\n", wow64info->CpuFlags ); + ok( wow64info->NativeMachineType == native_machine, "wrong machine %x / %x\n", + wow64info->NativeMachineType, native_machine ); + ok( wow64info->EmulatedMachineType == IMAGE_FILE_MACHINE_I386, "wrong machine %x\n", + wow64info->EmulatedMachineType ); + } + ok( buffer[sizeof(*wow64info) / sizeof(ULONG)] == 0xcccccccc, "buffer set %lx\n", + buffer[sizeof(*wow64info) / sizeof(ULONG)] ); + if (ReadProcessMemory( pi.hProcess, (void *)peb_ptr, peb_data, sizeof(peb_data), &res )) + { + ULONG limit = (sizeof(peb_data) - sizeof(wow64info)) / sizeof(ULONG); + for (i = 0; i < limit; i++) + { + if (!memcmp( peb_data + i, wow64info, sizeof(*wow64info) )) + { + trace( "wow64info found at %lx\n", i * 4 ); + break; + } + } + ok( i < limit, "wow64info not found in PEB\n" ); + } + } + else win_skip( "RtlWow64GetSharedInfoProcess not supported\n" ); + ret = DebugActiveProcess( pi.dwProcessId ); ok( ret, "debugging failed\n" ); if (!ReadProcessMemory( pi.hProcess, proc_info.PebBaseAddress, &peb, sizeof(peb), &res )) res = 0; @@ -416,6 +463,19 @@ static void test_peb_teb(void) ok( proc_info.PebBaseAddress == teb.Peb, "wrong peb %p / %p\n", proc_info.PebBaseAddress, teb.Peb );
+ ResumeThread( pi.hThread ); + WaitForInputIdle( pi.hProcess, 1000 ); + + if (pRtlWow64GetSharedInfoProcess) + { + wow64 = 0xcc; + memset( buffer, 0xcc, sizeof(buffer) ); + status = pRtlWow64GetSharedInfoProcess( pi.hProcess, &wow64, wow64info ); + ok( !status, "RtlWow64GetSharedInfoProcess failed %lx\n", status ); + ok( !wow64, "wrong wow64 %u\n", wow64 ); + ok( buffer[0] == 0xcccccccc, "buffer set %lx\n", buffer[0] ); + } + TerminateProcess( pi.hProcess, 0 ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); diff --git a/include/winternl.h b/include/winternl.h index faa8621c152..f57b5b43d37 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -4013,6 +4013,7 @@ typedef struct _WOW64INFO ULONG unknown[5]; USHORT NativeMachineType; USHORT EmulatedMachineType; + ULONG unknown2; } WOW64INFO;
#define WOW64_CPUFLAGS_MSFT64 0x01 @@ -4820,6 +4821,7 @@ NTSYSAPI NTSTATUS WINAPI RtlWow64EnableFsRedirection(BOOLEAN); NTSYSAPI NTSTATUS WINAPI RtlWow64EnableFsRedirectionEx(ULONG,ULONG*); NTSYSAPI USHORT WINAPI RtlWow64GetCurrentMachine(void); NTSYSAPI NTSTATUS WINAPI RtlWow64GetProcessMachines(HANDLE,USHORT*,USHORT*); +NTSYSAPI NTSTATUS WINAPI RtlWow64GetSharedInfoProcess(HANDLE,BOOLEAN*,WOW64INFO*); NTSYSAPI NTSTATUS WINAPI RtlWow64IsWowGuestMachineSupported(USHORT,BOOLEAN*); NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG,PCWSTR,PCWSTR,ULONG,PVOID,ULONG); NTSYSAPI NTSTATUS WINAPI RtlZombifyActivationContext(HANDLE);