Alexandre Julliard : ntdll: Implement NtQuerySystemInformationEx(SystemSupportedProcessorArchitectures).
Alexandre Julliard
julliard at winehq.org
Fri Apr 23 15:20:17 CDT 2021
Module: wine
Branch: master
Commit: 126a14ac9ade799f9cb88fb0c509b964c5d98e76
URL: https://source.winehq.org/git/wine.git/?a=commit;h=126a14ac9ade799f9cb88fb0c509b964c5d98e76
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri Apr 23 12:14:35 2021 +0200
ntdll: Implement NtQuerySystemInformationEx(SystemSupportedProcessorArchitectures).
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/tests/info.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++
dlls/ntdll/unix/system.c | 38 ++++++++++++++++
2 files changed, 152 insertions(+)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 56b6687467b..3a71a9f245c 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -2884,6 +2884,119 @@ static void test_query_data_alignment(void)
#endif
}
+static void test_process_architecture( HANDLE process, USHORT expect_machine, USHORT expect_native )
+{
+ NTSTATUS status;
+ ULONG i, len, buffer[8];
+
+ len = 0xdead;
+ status = pNtQuerySystemInformationEx( SystemSupportedProcessorArchitectures, &process, sizeof(process),
+ &buffer, sizeof(buffer), &len );
+ ok( !status, "failed %x\n", status );
+ ok( !(len & 3), "wrong len %x\n", len );
+ len /= sizeof(DWORD);
+ for (i = 0; i < len - 1; i++)
+ {
+ USHORT flags = HIWORD(buffer[i]);
+ USHORT machine = LOWORD(buffer[i]);
+
+ if (flags & 8)
+ ok( machine == expect_machine, "wrong current machine %x\n", buffer[i]);
+ else
+ ok( machine != expect_machine, "wrong machine %x\n", buffer[i]);
+
+ /* FIXME: not quite sure what the other flags mean,
+ * observed on amd64 Windows: (flags & 7) == 7 for MACHINE_AMD64 and 2 for MACHINE_I386
+ */
+ if (flags & 4)
+ ok( machine == expect_native, "wrong native machine %x\n", buffer[i]);
+ else
+ ok( machine != expect_native, "wrong machine %x\n", buffer[i]);
+ }
+ ok( !buffer[i], "missing terminating null\n" );
+
+ len = i * sizeof(DWORD);
+ status = pNtQuerySystemInformationEx( SystemSupportedProcessorArchitectures, &process, sizeof(process),
+ &buffer, len, &len );
+ ok( status == STATUS_BUFFER_TOO_SMALL, "failed %x\n", status );
+ ok( len == (i + 1) * sizeof(DWORD), "wrong len %u\n", len );
+}
+
+static void test_query_architectures(void)
+{
+#ifdef __i386__
+ USHORT current_machine = IMAGE_FILE_MACHINE_I386;
+ USHORT native_machine = is_wow64 ? IMAGE_FILE_MACHINE_AMD64 : IMAGE_FILE_MACHINE_I386;
+#elif defined __x86_64__
+ USHORT current_machine = IMAGE_FILE_MACHINE_AMD64;
+ USHORT native_machine = IMAGE_FILE_MACHINE_AMD64;
+#elif defined __arm__
+ USHORT current_machine = IMAGE_FILE_MACHINE_ARMNT;
+ USHORT native_machine = is_wow64 ? IMAGE_FILE_MACHINE_ARM64 : IMAGE_FILE_MACHINE_ARMNT;
+#elif defined __aarch64__
+ USHORT current_machine = IMAGE_FILE_MACHINE_ARM64;
+ USHORT native_machine = IMAGE_FILE_MACHINE_ARM64;
+#else
+ USHORT current_machine = 0;
+ USHORT native_machine = 0;
+#endif
+ PROCESS_INFORMATION pi;
+ STARTUPINFOA si = { sizeof(si) };
+ NTSTATUS status;
+ HANDLE process;
+ ULONG len, buffer[8];
+
+ if (!pNtQuerySystemInformationEx) return;
+
+ process = GetCurrentProcess();
+ status = pNtQuerySystemInformationEx( SystemSupportedProcessorArchitectures, &process, sizeof(process),
+ &buffer, sizeof(buffer), &len );
+ if (status == STATUS_INVALID_INFO_CLASS)
+ {
+ win_skip( "SystemSupportedProcessorArchitectures not supported\n" );
+ return;
+ }
+ ok( !status, "failed %x\n", status );
+
+ process = (HANDLE)0xdeadbeef;
+ status = pNtQuerySystemInformationEx( SystemSupportedProcessorArchitectures, &process, sizeof(process),
+ &buffer, sizeof(buffer), &len );
+ ok( status == STATUS_INVALID_HANDLE, "failed %x\n", status );
+ process = (HANDLE)0xdeadbeef;
+ status = pNtQuerySystemInformationEx( SystemSupportedProcessorArchitectures, &process, 3,
+ &buffer, sizeof(buffer), &len );
+ ok( status == STATUS_INVALID_PARAMETER || broken(status == STATUS_INVALID_HANDLE),
+ "failed %x\n", status );
+ process = GetCurrentProcess();
+ status = pNtQuerySystemInformationEx( SystemSupportedProcessorArchitectures, &process, 3,
+ &buffer, sizeof(buffer), &len );
+ ok( status == STATUS_INVALID_PARAMETER || broken( status == STATUS_SUCCESS),
+ "failed %x\n", status );
+ status = pNtQuerySystemInformationEx( SystemSupportedProcessorArchitectures, NULL, 0,
+ &buffer, sizeof(buffer), &len );
+ ok( status == STATUS_INVALID_PARAMETER, "failed %x\n", status );
+
+ test_process_architecture( GetCurrentProcess(), current_machine, native_machine );
+ test_process_architecture( 0, 0, native_machine );
+
+ if (CreateProcessA( "C:\\Program Files\\Internet Explorer\\iexplore.exe", NULL, NULL, NULL,
+ FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi ))
+ {
+ test_process_architecture( pi.hProcess, native_machine, native_machine );
+ TerminateProcess( pi.hProcess, 0 );
+ CloseHandle( pi.hProcess );
+ CloseHandle( pi.hThread );
+ }
+ if (CreateProcessA( "C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe", NULL, NULL, NULL,
+ FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi ))
+ {
+ test_process_architecture( pi.hProcess, IMAGE_FILE_MACHINE_I386, native_machine );
+ TerminateProcess( pi.hProcess, 0 );
+ CloseHandle( pi.hProcess );
+ CloseHandle( pi.hThread );
+ }
+}
+
static void test_thread_lookup(void)
{
OBJECT_BASIC_INFORMATION obj_info;
@@ -3145,6 +3258,7 @@ START_TEST(info)
test_query_cpusetinfo();
test_query_firmware();
test_query_data_alignment();
+ test_query_architectures();
/* NtPowerInformation */
test_query_battery();
diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c
index d3e380b8c32..491cdb37b8f 100644
--- a/dlls/ntdll/unix/system.c
+++ b/dlls/ntdll/unix/system.c
@@ -2926,6 +2926,44 @@ NTSTATUS WINAPI NtQuerySystemInformationEx( SYSTEM_INFORMATION_CLASS class,
return ret;
break;
}
+
+ case SystemSupportedProcessorArchitectures:
+ {
+ HANDLE process;
+ ULONG i;
+ USHORT machine = 0;
+
+ if (!query || query_len < sizeof(HANDLE)) return STATUS_INVALID_PARAMETER;
+ process = *(HANDLE *)query;
+ if (process)
+ {
+ SERVER_START_REQ( get_process_info )
+ {
+ req->handle = wine_server_obj_handle( process );
+ if (!(ret = wine_server_call( req ))) machine = reply->machine;
+ }
+ SERVER_END_REQ;
+ if (ret) return ret;
+ }
+
+ len = (supported_machines_count + 1) * sizeof(ULONG);
+ if (size < len)
+ {
+ ret = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+ for (i = 0; i < supported_machines_count; i++)
+ {
+ USHORT flags = 2; /* supported (?) */
+ if (!i) flags |= 5; /* native machine (?) */
+ if (supported_machines[i] == machine) flags |= 8; /* current machine */
+ ((DWORD *)info)[i] = MAKELONG( supported_machines[i], flags );
+ }
+ ((DWORD *)info)[i] = 0;
+ ret = STATUS_SUCCESS;
+ break;
+ }
+
default:
FIXME( "(0x%08x,%p,%u,%p,%u,%p) stub\n", class, query, query_len, info, size, ret_size );
break;
More information about the wine-cvs
mailing list