[PATCH] winetest: Fix detecting whether a test can be run or not.

Francois Gouget fgouget at codeweavers.com
Tue Mar 16 04:34:07 CDT 2021


Rather than second-guessing the loader, run 'test.exe --list' with the
critical-error handler message box disabled and use the resulting exit
codes.
But keep the activation context and COM code to improve the chances of
getting the dll version.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45032
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50783
Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
Note that when a dll is missing (entirely / entry points / ordinals),
it's not possible to issue 'skipped' lines because the test unit names
are not even known.
Also this introduces additional forms of the 'dll is missing' error in 
the 'Dll info' section, which winetest/dissect should understand in 
order to produce appropriate summary.txt files (that patch is in since 
yesterday).
---
 programs/winetest/main.c | 46 ++++++++++++++++++++++++++++------------
 1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/programs/winetest/main.c b/programs/winetest/main.c
index 2e5fdc6ab8c..225e9a2548b 100644
--- a/programs/winetest/main.c
+++ b/programs/winetest/main.c
@@ -608,11 +608,12 @@ static void append_path( const char *path)
    value of WaitForSingleObject.
  */
 static int
-run_ex (char *cmd, HANDLE out_file, const char *tempdir, DWORD ms, DWORD* pid)
+run_ex (char *cmd, HANDLE out_file, const char *tempdir, DWORD ms, BOOL nocritical, DWORD* pid)
 {
     STARTUPINFOA si;
     PROCESS_INFORMATION pi;
-    DWORD wait, status;
+    DWORD wait, status, flags;
+    UINT old_errmode;
 
     /* Flush to disk so we know which test caused Windows to crash if it does */
     if (out_file)
@@ -623,14 +624,24 @@ run_ex (char *cmd, HANDLE out_file, const char *tempdir, DWORD ms, DWORD* pid)
     si.hStdInput  = GetStdHandle( STD_INPUT_HANDLE );
     si.hStdOutput = out_file ? out_file : GetStdHandle( STD_OUTPUT_HANDLE );
     si.hStdError  = out_file ? out_file : GetStdHandle( STD_ERROR_HANDLE );
+    if (nocritical)
+    {
+        old_errmode = SetErrorMode(0);
+        SetErrorMode(old_errmode | SEM_FAILCRITICALERRORS);
+        flags = 0;
+    }
+    else
+        flags = CREATE_DEFAULT_ERROR_MODE;
 
-    if (!CreateProcessA (NULL, cmd, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE,
+    if (!CreateProcessA (NULL, cmd, NULL, NULL, TRUE, flags,
                          NULL, tempdir, &si, &pi))
     {
+        if (nocritical) SetErrorMode(old_errmode);
         if (pid) *pid = 0;
         return -2;
     }
 
+    if (nocritical) SetErrorMode(old_errmode);
     CloseHandle (pi.hThread);
     if (pid) *pid = pi.dwProcessId;
     status = wait_process( pi.hProcess, ms );
@@ -716,7 +727,7 @@ get_subtests (const char *tempdir, struct wine_test *test, LPSTR res_name)
         /* We need to add the path (to the main dll) to PATH */
         append_path(test->maindllpath);
     }
-    status = run_ex (cmd, subfile, tempdir, 5000, NULL);
+    status = run_ex (cmd, subfile, tempdir, 5000, TRUE, NULL);
     err = GetLastError();
     if (test->maindllpath) {
         /* Restore PATH again */
@@ -795,7 +806,7 @@ run_test (struct wine_test* test, const char* subtest, HANDLE out_file, const ch
         char *cmd = strmake (NULL, "%s %s", test->exename, subtest);
         report (R_STEP, "Running: %s:%s", test->name, subtest);
         xprintf ("%s:%s start %s -\n", test->name, subtest, file);
-        status = run_ex (cmd, out_file, tempdir, 120000, &pid);
+        status = run_ex (cmd, out_file, tempdir, 120000, FALSE, &pid);
         heap_free (cmd);
         xprintf ("%s:%s:%04x done (%d) in %ds\n", test->name, subtest, pid, status, (GetTickCount()-start)/1000);
         if (status) failures++;
@@ -946,12 +957,7 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP
     }
 
     run = TRUE;
-    if (!dll)
-    {
-        xprintf ("    %s=dll is missing\n", dllname);
-        run = FALSE;
-    }
-    else
+    if (dll)
     {
         if (is_stub_dll(dllname))
         {
@@ -970,14 +976,26 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP
     if (run)
     {
         err = get_subtests( tempdir, &wine_tests[nr_of_files], lpszName );
-        if (!err)
+        switch (err)
         {
+        case 0:
             xprintf ("    %s=%s\n", dllname, get_file_version(filename));
             nr_of_tests += wine_tests[nr_of_files].subtest_count;
             nr_of_files++;
-        }
-        else
+            break;
+        case STATUS_DLL_NOT_FOUND:
+            xprintf ("    %s=dll is missing\n", dllname);
+            break;
+        case STATUS_ORDINAL_NOT_FOUND:
+            xprintf ("    %s=dll is missing an ordinal (%s)\n", dllname, get_file_version(filename));
+            break;
+        case STATUS_ENTRYPOINT_NOT_FOUND:
+            xprintf ("    %s=dll is missing an entrypoint (%s)\n", dllname, get_file_version(filename));
+            break;
+        default:
             xprintf ("    %s=load error %u\n", dllname, err);
+            break;
+        }
     }
 
     if (actctx != INVALID_HANDLE_VALUE)
-- 
2.20.1



More information about the wine-devel mailing list