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