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);