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

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@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Francois Gouget 2021-03-16 10:34:07 +01:00 committed by Alexandre Julliard
parent 46424c6196
commit e618fb526d
1 changed files with 32 additions and 14 deletions

View File

@ -608,11 +608,12 @@ static void append_path( const char *path)
value of WaitForSingleObject. value of WaitForSingleObject.
*/ */
static int 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; STARTUPINFOA si;
PROCESS_INFORMATION pi; 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 */ /* Flush to disk so we know which test caused Windows to crash if it does */
if (out_file) 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.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
si.hStdOutput = out_file ? out_file : GetStdHandle( STD_OUTPUT_HANDLE ); si.hStdOutput = out_file ? out_file : GetStdHandle( STD_OUTPUT_HANDLE );
si.hStdError = out_file ? out_file : GetStdHandle( STD_ERROR_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)) NULL, tempdir, &si, &pi))
{ {
if (nocritical) SetErrorMode(old_errmode);
if (pid) *pid = 0; if (pid) *pid = 0;
return -2; return -2;
} }
if (nocritical) SetErrorMode(old_errmode);
CloseHandle (pi.hThread); CloseHandle (pi.hThread);
if (pid) *pid = pi.dwProcessId; if (pid) *pid = pi.dwProcessId;
status = wait_process( pi.hProcess, ms ); 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 */ /* We need to add the path (to the main dll) to PATH */
append_path(test->maindllpath); append_path(test->maindllpath);
} }
status = run_ex (cmd, subfile, tempdir, 5000, NULL); status = run_ex (cmd, subfile, tempdir, 5000, TRUE, NULL);
err = GetLastError(); err = GetLastError();
if (test->maindllpath) { if (test->maindllpath) {
/* Restore PATH again */ /* Restore PATH again */
@ -792,7 +803,7 @@ run_test (struct wine_test* test, const char* subtest, HANDLE out_file, const ch
char *cmd = strmake (NULL, "%s %s", test->exename, subtest); char *cmd = strmake (NULL, "%s %s", test->exename, subtest);
report (R_STEP, "Running: %s:%s", test->name, subtest); report (R_STEP, "Running: %s:%s", test->name, subtest);
xprintf ("%s:%s start %s -\n", test->name, subtest, file); 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); heap_free (cmd);
xprintf ("%s:%s:%04x done (%d) in %ds\n", test->name, subtest, pid, status, (GetTickCount()-start)/1000); xprintf ("%s:%s:%04x done (%d) in %ds\n", test->name, subtest, pid, status, (GetTickCount()-start)/1000);
if (status) failures++; if (status) failures++;
@ -943,12 +954,7 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP
} }
run = TRUE; run = TRUE;
if (!dll) if (dll)
{
xprintf (" %s=dll is missing\n", dllname);
run = FALSE;
}
else
{ {
if (is_stub_dll(dllname)) if (is_stub_dll(dllname))
{ {
@ -967,14 +973,26 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP
if (run) if (run)
{ {
err = get_subtests( tempdir, &wine_tests[nr_of_files], lpszName ); 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)); xprintf (" %s=%s\n", dllname, get_file_version(filename));
nr_of_tests += wine_tests[nr_of_files].subtest_count; nr_of_tests += wine_tests[nr_of_files].subtest_count;
nr_of_files++; nr_of_files++;
} break;
else 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); xprintf (" %s=load error %u\n", dllname, err);
break;
}
} }
if (actctx != INVALID_HANDLE_VALUE) if (actctx != INVALID_HANDLE_VALUE)