Needed for GOG Galaxy.
From: Alex Henrie dhenrale@amazon.com
Needed for GOG Galaxy. --- dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/ntsyscalls.h | 17 ++++++----- dlls/ntdll/tests/wow64.c | 46 +++++++++++++++++++++++++++++ dlls/ntdll/unix/process.c | 62 +++++++++++++++++++++++++++++++++++++++ dlls/wow64/syscall.c | 15 ++++++++++ include/winternl.h | 12 ++++++++ 6 files changed, 145 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 1234205cf1a..d42c94af591 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -450,6 +450,7 @@ @ stdcall -syscall -arch=win32 NtWow64AllocateVirtualMemory64(long ptr int64 ptr long long) @ stdcall -syscall -arch=win32 NtWow64GetNativeSystemInformation(long ptr long ptr) @ stdcall -syscall -arch=win32 NtWow64IsProcessorFeaturePresent(long) +@ stdcall -syscall -arch=win32 NtWow64QueryInformationProcess64(long 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) diff --git a/dlls/ntdll/ntsyscalls.h b/dlls/ntdll/ntsyscalls.h index 55e1436848b..4efc20bebaa 100644 --- a/dlls/ntdll/ntsyscalls.h +++ b/dlls/ntdll/ntsyscalls.h @@ -235,14 +235,15 @@ SYSCALL_ENTRY( 0x00e7, NtWow64AllocateVirtualMemory64, 28 ) \ SYSCALL_ENTRY( 0x00e8, NtWow64GetNativeSystemInformation, 16 ) \ SYSCALL_ENTRY( 0x00e9, NtWow64IsProcessorFeaturePresent, 4 ) \ - SYSCALL_ENTRY( 0x00ea, NtWow64ReadVirtualMemory64, 28 ) \ - SYSCALL_ENTRY( 0x00eb, NtWow64WriteVirtualMemory64, 28 ) \ - SYSCALL_ENTRY( 0x00ec, NtWriteFile, 36 ) \ - SYSCALL_ENTRY( 0x00ed, NtWriteFileGather, 36 ) \ - SYSCALL_ENTRY( 0x00ee, NtWriteVirtualMemory, 20 ) \ - SYSCALL_ENTRY( 0x00ef, NtYieldExecution, 0 ) \ - SYSCALL_ENTRY( 0x00f0, wine_nt_to_unix_file_name, 16 ) \ - SYSCALL_ENTRY( 0x00f1, wine_unix_to_nt_file_name, 12 ) + SYSCALL_ENTRY( 0x00ea, NtWow64QueryInformationProcess64, 20 ) \ + SYSCALL_ENTRY( 0x00eb, NtWow64ReadVirtualMemory64, 28 ) \ + SYSCALL_ENTRY( 0x00ec, NtWow64WriteVirtualMemory64, 28 ) \ + SYSCALL_ENTRY( 0x00ed, NtWriteFile, 36 ) \ + SYSCALL_ENTRY( 0x00ee, NtWriteFileGather, 36 ) \ + SYSCALL_ENTRY( 0x00ef, NtWriteVirtualMemory, 20 ) \ + SYSCALL_ENTRY( 0x00f0, NtYieldExecution, 0 ) \ + SYSCALL_ENTRY( 0x00f1, wine_nt_to_unix_file_name, 16 ) \ + SYSCALL_ENTRY( 0x00f2, wine_unix_to_nt_file_name, 12 )
#define ALL_SYSCALLS64 \ SYSCALL_ENTRY( 0x0000, NtAcceptConnectPort, 48 ) \ diff --git a/dlls/ntdll/tests/wow64.c b/dlls/ntdll/tests/wow64.c index 054e5fac6e9..93de5e53d84 100644 --- a/dlls/ntdll/tests/wow64.c +++ b/dlls/ntdll/tests/wow64.c @@ -56,6 +56,7 @@ static void (WINAPI *pProcessPendingCrossProcessEmulatorWork)(void); static NTSTATUS (WINAPI *pNtWow64AllocateVirtualMemory64)(HANDLE,ULONG64*,ULONG64,ULONG64*,ULONG,ULONG); static NTSTATUS (WINAPI *pNtWow64GetNativeSystemInformation)(SYSTEM_INFORMATION_CLASS,void*,ULONG,ULONG*); static NTSTATUS (WINAPI *pNtWow64IsProcessorFeaturePresent)(ULONG); +static NTSTATUS (WINAPI *pNtWow64QueryInformationProcess64)(HANDLE,PROCESSINFOCLASS,void*,ULONG,ULONG*); static NTSTATUS (WINAPI *pNtWow64ReadVirtualMemory64)(HANDLE,ULONG64,void*,ULONG64,ULONG64*); static NTSTATUS (WINAPI *pNtWow64WriteVirtualMemory64)(HANDLE,ULONG64,const void *,ULONG64,ULONG64*); #endif @@ -140,6 +141,7 @@ static void init(void) GET_PROC( NtWow64AllocateVirtualMemory64 ); GET_PROC( NtWow64GetNativeSystemInformation ); GET_PROC( NtWow64IsProcessorFeaturePresent ); + GET_PROC( NtWow64QueryInformationProcess64 ); GET_PROC( NtWow64ReadVirtualMemory64 ); GET_PROC( NtWow64WriteVirtualMemory64 ); #endif @@ -2595,6 +2597,50 @@ static void test_nt_wow64(void) } else win_skip( "NtWow64IsProcessorFeaturePresent not supported\n" );
+ if (pNtWow64QueryInformationProcess64) + { + PROCESS_BASIC_INFORMATION pbi32; + PROCESS_BASIC_INFORMATION64 pbi64; + ULONG expected_peb; + ULONG class; + + for (class = 0; class <= MaxProcessInfoClass; class++) + { + winetest_push_context( "Process information class %lu", class ); + + switch (class) + { + case ProcessBasicInformation: + status = NtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation, &pbi32, sizeof(pbi32), NULL ); + ok( !status, "NtQueryInformationProcess returned 0x%08lx\n", status ); + + status = NtWow64QueryInformationProcess64( GetCurrentProcess(), ProcessBasicInformation, &pbi64, sizeof(pbi64), NULL ); + ok( !status, "NtWow64QueryInformationProcess64 returned 0x%08lx\n", status ); + + expected_peb = (ULONG)pbi32.PebBaseAddress; + if (is_wow64) expected_peb -= 0x1000; + + ok( pbi64.ExitStatus == pbi32.ExitStatus, "expected %lu got %lu\n", + pbi32.ExitStatus, pbi64.ExitStatus ); + ok( pbi64.PebBaseAddress == expected_peb, "expected 0x%lx got 0x%llx\n", + expected_peb, pbi64.PebBaseAddress ); + ok( pbi64.AffinityMask == pbi32.AffinityMask, "expected 0x%lx got 0x%llx\n", + pbi32.AffinityMask, pbi64.AffinityMask ); + ok( pbi64.UniqueProcessId == pbi32.UniqueProcessId, "expected %ld got %lld\n", + pbi32.UniqueProcessId, pbi64.UniqueProcessId ); + ok( pbi64.InheritedFromUniqueProcessId == pbi32.InheritedFromUniqueProcessId, "expected %ld got %lld\n", + pbi32.UniqueProcessId, pbi64.UniqueProcessId ); + break; + default: + status = NtWow64QueryInformationProcess64( GetCurrentProcess(), class, NULL, 0, NULL ); + ok( status == STATUS_NOT_IMPLEMENTED, "NtWow64QueryInformationProcess64 returned 0x%08lx\n", status ); + } + + winetest_pop_context(); + } + } + else win_skip( "NtWow64QueryInformationProcess64 not supported\n" ); + NtClose( process ); }
diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c index f3551c2e7d7..ec585fe2d6c 100644 --- a/dlls/ntdll/unix/process.c +++ b/dlls/ntdll/unix/process.c @@ -1617,6 +1617,68 @@ NTSTATUS WINAPI NtQueryInformationProcess( HANDLE handle, PROCESSINFOCLASS class return ret; }
+#ifndef _WIN64 + +/********************************************************************** + * NtWow64QueryInformationProcess64 (NTDLL.@) + */ +NTSTATUS WINAPI NtWow64QueryInformationProcess64( HANDLE handle, PROCESSINFOCLASS class, void *info, + ULONG size, ULONG *ret_len ) +{ + NTSTATUS ret; + ULONG len = 0; + + TRACE( "(%p,0x%08x,%p,0x%08x,%p)\n", handle, class, info, (int)size, ret_len ); + + switch (class) + { + case ProcessBasicInformation: + { + PROCESS_BASIC_INFORMATION64 pbi; + const ULONG_PTR affinity_mask = get_system_affinity_mask(); + + if (size >= sizeof(PROCESS_BASIC_INFORMATION64)) + { + if (!info) ret = STATUS_ACCESS_VIOLATION; + else + { + SERVER_START_REQ(get_process_info) + { + req->handle = wine_server_obj_handle( handle ); + if ((ret = wine_server_call( req )) == STATUS_SUCCESS) + { + pbi.ExitStatus = reply->exit_code; + pbi.PebBaseAddress = (ULONG)wine_server_get_ptr( reply->peb ); + pbi.AffinityMask = reply->affinity & affinity_mask; + pbi.BasePriority = reply->priority; + pbi.UniqueProcessId = reply->pid; + pbi.InheritedFromUniqueProcessId = reply->ppid; + } + } + SERVER_END_REQ; + + memcpy( info, &pbi, sizeof(PROCESS_BASIC_INFORMATION64) ); + len = sizeof(PROCESS_BASIC_INFORMATION64); + } + if (size > sizeof(PROCESS_BASIC_INFORMATION64)) ret = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + len = sizeof(PROCESS_BASIC_INFORMATION64); + ret = STATUS_INFO_LENGTH_MISMATCH; + } + } + break; + + default: + return STATUS_NOT_IMPLEMENTED; + } + + if (ret_len) *ret_len = len; + return ret; +} + +#endif
/********************************************************************** * NtSetInformationProcess (NTDLL.@) diff --git a/dlls/wow64/syscall.c b/dlls/wow64/syscall.c index fc60ae37816..9f139b456dc 100644 --- a/dlls/wow64/syscall.c +++ b/dlls/wow64/syscall.c @@ -662,6 +662,21 @@ NTSTATUS WINAPI wow64_NtWow64IsProcessorFeaturePresent( UINT *args ) }
+/********************************************************************** + * wow64_NtWow64QueryInformationProcess64 + */ +NTSTATUS WINAPI wow64_NtWow64QueryInformationProcess64( UINT *args ) +{ + HANDLE handle = get_ptr( &args ); + PROCESSINFOCLASS class = get_ulong( &args ); + void *info = get_ptr( &args ); + ULONG size = get_ulong( &args ); + ULONG *ret_len = get_ptr( &args ); + + return NtQueryInformationProcess( handle, class, info, size, ret_len ); +} + + /********************************************************************** * init_image_mapping */ diff --git a/include/winternl.h b/include/winternl.h index 4f24a921bb1..600057fc8ed 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2636,6 +2636,17 @@ typedef struct _PROCESS_BASIC_INFORMATION { #endif } PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
+#ifdef __WINESRC__ +typedef struct _PROCESS_BASIC_INFORMATION64 { + NTSTATUS ExitStatus; + UINT64 PebBaseAddress; + UINT64 AffinityMask; + LONG BasePriority; + UINT64 UniqueProcessId; + UINT64 InheritedFromUniqueProcessId; +} PROCESS_BASIC_INFORMATION64; +#endif + #define PROCESS_PRIOCLASS_IDLE 1 #define PROCESS_PRIOCLASS_NORMAL 2 #define PROCESS_PRIOCLASS_HIGH 3 @@ -5170,6 +5181,7 @@ NTSYSAPI NTSTATUS WINAPI RtlWow64SetThreadContext(HANDLE,const WOW64_CONTEXT*); NTSYSAPI NTSTATUS WINAPI NtWow64AllocateVirtualMemory64(HANDLE,ULONG64*,ULONG64,ULONG64*,ULONG,ULONG); NTSYSAPI NTSTATUS WINAPI NtWow64GetNativeSystemInformation(SYSTEM_INFORMATION_CLASS,void*,ULONG,ULONG*); NTSYSAPI NTSTATUS WINAPI NtWow64IsProcessorFeaturePresent(UINT); +NTSYSAPI NTSTATUS WINAPI NtWow64QueryInformationProcess64(HANDLE,PROCESSINFOCLASS,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);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=149004
Your paranoid android.
=== w864 (32 bit report) ===
ntdll: wow64.c:2625: Test failed: Process information class 0: expected 0x7f787000 got 0x7f78f000
=== w1064v1507 (32 bit report) ===
ntdll: wow64.c:2625: Test failed: Process information class 0: expected 0x7e95c000 got 0x7e95f000
Looks like the wow64 code is calling NtQueryInformationProcess() on accident?
On Thu Oct 17 03:43:17 2024 +0000, Elizabeth Figura wrote:
Looks like the wow64 code is calling NtQueryInformationProcess() on accident?
Ah, that is a problem. wow64_NtWow64QueryInformationProcess64 shouldn't be calling NtQueryInformationProcess like that, but it can't call NtWow64QueryInformationProcess64 because NtWow64QueryInformationProcess64 is only defined on 32-bit. What is the right way to handle this situation? Should we just expose NtWow64QueryInformationProcess64 on 64-bit too, even though Windows doesn't? Or should I copy the implementation into wow64_NtWow64QueryInformationProcess64 but change it to use NtQueryInformationProcess instead of SERVER_START_REQ/SERVER_END_REQ?
On Thu Oct 17 03:43:17 2024 +0000, Alex Henrie wrote:
Ah, that is a problem. wow64_NtWow64QueryInformationProcess64 shouldn't be calling NtQueryInformationProcess like that, but it can't call NtWow64QueryInformationProcess64 because NtWow64QueryInformationProcess64 is only defined on 32-bit. What is the right way to handle this situation? Should we just expose NtWow64QueryInformationProcess64 on 64-bit too, even though Windows doesn't? Or should I copy the implementation into wow64_NtWow64QueryInformationProcess64 but change it to use NtQueryInformationProcess instead of SERVER_START_REQ/SERVER_END_REQ?
Calling NtQueryInformationProcess is the right thing to do (except you'd need to check the info class).