Rationale: - currently, winetest is built either as a 32bit exec or a 64bit exec, containaing a bunch of tests of same bitness. - there's no simple support for having parent process in one bitness, and child process in a different bitness. - lots of cases are not covered in ntdll, kernel32 and kernelbase tests. - there are here and there a couple of tweaks to workaround this, but nothing a bit solid.
Attached is a proposal to extend winetest to support better these use cases: - the idea is to add an extra-option to winetest.exe (64bit) passing the path to the corresponding winetest.exe (32bit). - when running test X (64bit), the path to corresponding test X (32bit) will be passed to test X (64 bit), allowing it to trigger test with test X (32bit). - nothing more is provided: it's up to the test designer to decide whether to use the 32bit child (and to adapt potentially the test) to cope with the difference in bitness between parent and child. - this can be used either in current wow64 setup, and also in multi-arch wow64 setup (just need to change the patch to 32bit winetest.exe)
There's an example of such test at the end of the serie.
Comments, ideas welcomed. And especially if it's something worth continuing.
Note: - this is first shot at it, it should be improved (especially in ensuring that the 32bit/64bit pair is correct).
A+
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- programs/winetest/main.c | 145 +++++++++++++++++++++++---------------- 1 file changed, 87 insertions(+), 58 deletions(-)
diff --git a/programs/winetest/main.c b/programs/winetest/main.c index 74b596b237b..711f38d06e6 100644 --- a/programs/winetest/main.c +++ b/programs/winetest/main.c @@ -54,13 +54,19 @@ struct wine_test char *maindllpath; };
+struct winetest_image +{ + const char *target_dir; + HMODULE module; + struct wine_test *wine_tests; + int nr_of_files, nr_of_tests, nr_of_skips; +}; + char *tag = NULL; char *description = NULL; char *url = NULL; char *email = NULL; BOOL aborting = FALSE; -static struct wine_test *wine_tests; -static int nr_of_files, nr_of_tests, nr_of_skips; static int nr_native_dlls; static const char whitespace[] = " \t\r\n"; static const char testexe[] = "_test.exe"; @@ -640,15 +646,15 @@ static const char* get_test_source_file(const char* test, const char* subtest) return buffer; }
-static void* extract_rcdata (LPCSTR name, LPCSTR type, DWORD* size) +static void* extract_rcdata (HMODULE module, LPCSTR name, LPCSTR type, DWORD* size) { HRSRC rsrc; HGLOBAL hdl; LPVOID addr; - - if (!(rsrc = FindResourceA(NULL, name, type)) || - !(*size = SizeofResource (0, rsrc)) || - !(hdl = LoadResource (0, rsrc)) || + + if (!(rsrc = FindResourceA(module, name, type)) || + !(*size = SizeofResource (module, rsrc)) || + !(hdl = LoadResource (module, rsrc)) || !(addr = LockResource (hdl))) return NULL; return addr; @@ -656,7 +662,7 @@ static void* extract_rcdata (LPCSTR name, LPCSTR type, DWORD* size)
/* Fills in the name and exename fields */ static void -extract_test (struct wine_test *test, const char *dir, LPSTR res_name) +extract_test (struct winetest_image *image, struct wine_test *test, LPSTR res_name) { BYTE* code; DWORD size; @@ -664,11 +670,11 @@ extract_test (struct wine_test *test, const char *dir, LPSTR res_name) HANDLE hfile; DWORD written;
- code = extract_rcdata (res_name, "TESTRES", &size); + code = extract_rcdata (image->module, res_name, "TESTRES", &size); if (!code) report (R_FATAL, "Can't find test resource %s: %d", res_name, GetLastError ()); test->name = xstrdup( res_name ); - test->exename = strmake (NULL, "%s\%s", dir, test->name); + test->exename = strmake (NULL, "%s\%s", image->target_dir, test->name); exepos = strstr (test->name, testexe); if (!exepos) report (R_FATAL, "Not an .exe file: %s", test->name); *exepos = 0; @@ -844,17 +850,18 @@ get_subtests (const char *tempdir, struct wine_test *test, LPSTR res_name) return 0; }
-static void +static BOOL run_test (struct wine_test* test, const char* subtest, HANDLE out_file, const char *tempdir) { /* Build the source filename so analysis tools can link to it */ const char* file = get_test_source_file(test->name, subtest); + BOOL did_run = TRUE;
if (test_filtered_out( test->name, subtest )) { report (R_STEP, "Skipping: %s:%s", test->name, subtest); xprintf ("%s:%s skipped %s\n", test->name, subtest, file); - nr_of_skips++; + did_run = FALSE; } else { @@ -891,6 +898,7 @@ run_test (struct wine_test* test, const char* subtest, HANDLE out_file, const ch else if (status) failures++; } if (failures) report (R_STATUS, "Running tests - %u failures", failures); + return did_run; }
static BOOL CALLBACK @@ -975,7 +983,7 @@ static void get_dll_path(HMODULE dll, char **path, char *filename) static BOOL CALLBACK extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lParam) { - const char *tempdir = (const char *)lParam; + struct winetest_image *image = (struct winetest_image *)lParam; char dllname[MAX_PATH]; char filename[MAX_PATH]; WCHAR dllnameW[MAX_PATH]; @@ -994,11 +1002,11 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP
if (test_filtered_out( lpszName, NULL )) { - nr_of_skips++; + image->nr_of_skips++; if (exclude_tests) xprintf (" %s=skipped\n", dllname); return TRUE; } - extract_test (&wine_tests[nr_of_files], tempdir, lpszName); + extract_test (image, &image->wine_tests[image->nr_of_files], lpszName);
if (pCreateActCtxA != NULL && pActivateActCtx != NULL && pDeactivateActCtx != NULL && pReleaseActCtx != NULL) @@ -1007,7 +1015,7 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP memset(&actctxinfo, 0, sizeof(ACTCTXA)); actctxinfo.cbSize = sizeof(ACTCTXA); actctxinfo.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID; - actctxinfo.lpSource = wine_tests[nr_of_files].exename; + actctxinfo.lpSource = image->wine_tests[image->nr_of_files].exename; actctxinfo.lpResourceName = (LPSTR)CREATEPROCESS_MANIFEST_RESOURCE_ID; actctx = pCreateActCtxA(&actctxinfo); if (actctx != INVALID_HANDLE_VALUE && @@ -1018,18 +1026,18 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP } } else actctx = INVALID_HANDLE_VALUE;
- wine_tests[nr_of_files].maindllpath = NULL; + image->wine_tests[image->nr_of_files].maindllpath = NULL; strcpy(filename, dllname); dll = LoadLibraryExA(dllname, NULL, LOAD_LIBRARY_AS_DATAFILE);
- if (!dll) dll = load_com_dll(dllname, &wine_tests[nr_of_files].maindllpath, filename); + if (!dll) dll = load_com_dll(dllname, &image->wine_tests[image->nr_of_files].maindllpath, filename);
if (!dll && pLoadLibraryShim) { MultiByteToWideChar(CP_ACP, 0, dllname, -1, dllnameW, MAX_PATH); if (SUCCEEDED( pLoadLibraryShim(dllnameW, NULL, NULL, &dll) ) && dll) { - get_dll_path(dll, &wine_tests[nr_of_files].maindllpath, filename); + get_dll_path(dll, &image->wine_tests[image->nr_of_files].maindllpath, filename); FreeLibrary(dll); dll = LoadLibraryExA(filename, NULL, LOAD_LIBRARY_AS_DATAFILE); } @@ -1055,13 +1063,13 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP
if (run) { - err = get_subtests( tempdir, &wine_tests[nr_of_files], lpszName ); + err = get_subtests( image->target_dir, &image->wine_tests[image->nr_of_files], lpszName ); 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++; + image->nr_of_tests += image->wine_tests[image->nr_of_files].subtest_count; + image->nr_of_files++; break; case STATUS_DLL_NOT_FOUND: xprintf (" %s=dll is missing\n", dllname); @@ -1090,8 +1098,40 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP return TRUE; }
+static BOOL init_image(struct winetest_image *image, const char *target_dir) +{ + image->target_dir = target_dir; + image->module = NULL; + image->nr_of_files = image->nr_of_tests = image->nr_of_skips = 0; + report (R_STATUS, "Counting tests"); + if (!EnumResourceNamesA (image->module, "TESTRES", EnumTestFileProc, (LPARAM)&image->nr_of_files)) + report (R_FATAL, "Can't enumerate test files: %d", + GetLastError ()); + image->wine_tests = xalloc(image->nr_of_files * sizeof image->wine_tests[0]); + return TRUE; +} + +static BOOL load_image(struct winetest_image *image, const char *tempdir) +{ + if (!init_image(image, tempdir)) return FALSE; + report (R_STATUS, "Extracting tests"); + report (R_PROGRESS, 0, image->nr_of_files); + image->nr_of_files = 0; + if (!EnumResourceNamesA (image->module, "TESTRES", extract_test_proc, (LPARAM)image)) + report (R_FATAL, "Can't enumerate test files: %d", + GetLastError ()); + return TRUE; +} + +static void dispose_image(struct winetest_image *image) +{ + free(image->wine_tests); + FreeLibrary(image->module); + memset(image, 0, sizeof(*image)); +} + static char * -run_tests (char *logname, char *outdir) +run_tests (char *logname, char *outdir, int *nr_of_skips) { int i; char *strres, *eol, *nextline; @@ -1100,6 +1140,7 @@ run_tests (char *logname, char *outdir) BOOL newdir; DWORD needed; HMODULE kernel32; + struct winetest_image image;
/* Get the current PATH only once */ needed = GetEnvironmentVariableA("PATH", NULL, 0); @@ -1155,7 +1196,7 @@ run_tests (char *logname, char *outdir) xprintf ("Archive: -\n"); /* no longer used */ xprintf ("Tag: %s\n", tag); xprintf ("Build info:\n"); - strres = extract_rcdata ("BUILD_INFO", "STRINGRES", &strsize); + strres = extract_rcdata (NULL, "BUILD_INFO", "STRINGRES", &strsize); while (strres) { eol = memchr (strres, '\n', strsize); if (!eol) { @@ -1174,12 +1215,6 @@ run_tests (char *logname, char *outdir) print_language (); xprintf ("Dll info:\n" );
- report (R_STATUS, "Counting tests"); - if (!EnumResourceNamesA (NULL, "TESTRES", EnumTestFileProc, (LPARAM)&nr_of_files)) - report (R_FATAL, "Can't enumerate test files: %d", - GetLastError ()); - wine_tests = xalloc(nr_of_files * sizeof wine_tests[0]); - /* Do this only once during extraction (and version checking) */ hmscoree = LoadLibraryA("mscoree.dll"); pLoadLibraryShim = NULL; @@ -1191,14 +1226,7 @@ run_tests (char *logname, char *outdir) pDeactivateActCtx = (void *)GetProcAddress(kernel32, "DeactivateActCtx"); pReleaseActCtx = (void *)GetProcAddress(kernel32, "ReleaseActCtx");
- report (R_STATUS, "Extracting tests"); - report (R_PROGRESS, 0, nr_of_files); - nr_of_files = 0; - nr_of_tests = 0; - nr_of_skips = 0; - if (!EnumResourceNamesA (NULL, "TESTRES", extract_test_proc, (LPARAM)tempdir)) - report (R_FATAL, "Can't enumerate test files: %d", - GetLastError ()); + load_image(&image, tempdir);
FreeLibrary(hmscoree);
@@ -1212,9 +1240,9 @@ run_tests (char *logname, char *outdir) report( R_WARNING, "Some dlls are configured as native, you won't be able to submit results." );
report (R_STATUS, "Running tests"); - report (R_PROGRESS, 1, nr_of_tests); - for (i = 0; i < nr_of_files; i++) { - struct wine_test *test = wine_tests + i; + report (R_PROGRESS, 1, image.nr_of_tests); + for (i = 0; i < image.nr_of_files; i++) { + struct wine_test *test = image.wine_tests + i; int j;
if (aborting) break; @@ -1226,7 +1254,8 @@ run_tests (char *logname, char *outdir)
for (j = 0; j < test->subtest_count; j++) { if (aborting) break; - run_test (test, test->subtests[j], logfile, tempdir); + if (!run_test (test, test->subtests[j], logfile, tempdir)) + image.nr_of_skips++; }
if (test->maindllpath) { @@ -1241,7 +1270,8 @@ run_tests (char *logname, char *outdir) logfile = 0; if (newdir) remove_dir (tempdir); - free(wine_tests); + if (nr_of_skips) *nr_of_skips = image.nr_of_skips; + dispose_image(&image); free(curpath);
return logname; @@ -1261,7 +1291,7 @@ static BOOL WINAPI ctrl_handler(DWORD ctrl_type) static BOOL CALLBACK extract_only_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lParam) { - const char *target_dir = (const char *)lParam; + struct winetest_image *image = (struct winetest_image *)lParam; char filename[MAX_PATH];
if (test_filtered_out( lpszName, NULL )) return TRUE; @@ -1269,13 +1299,14 @@ extract_only_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP strcpy(filename, lpszName); CharLowerA(filename);
- extract_test( &wine_tests[nr_of_files], target_dir, filename ); - nr_of_files++; + extract_test( image, &image->wine_tests[image->nr_of_files], filename ); + image->nr_of_files++; return TRUE; }
static void extract_only (const char *target_dir) { + struct winetest_image image; BOOL res;
report (R_DIR, target_dir); @@ -1283,20 +1314,17 @@ static void extract_only (const char *target_dir) if (!res && GetLastError() != ERROR_ALREADY_EXISTS) report (R_FATAL, "Could not create directory: %s (%d)", target_dir, GetLastError ());
- nr_of_files = 0; - report (R_STATUS, "Counting tests"); - if (!EnumResourceNamesA(NULL, "TESTRES", EnumTestFileProc, (LPARAM)&nr_of_files)) - report (R_FATAL, "Can't enumerate test files: %d", GetLastError ()); - - wine_tests = xalloc(nr_of_files * sizeof wine_tests[0] ); + if (!init_image(&image, target_dir)) return;
report (R_STATUS, "Extracting tests"); - report (R_PROGRESS, 0, nr_of_files); - nr_of_files = 0; - if (!EnumResourceNamesA(NULL, "TESTRES", extract_only_proc, (LPARAM)target_dir)) + report (R_PROGRESS, 0, image.nr_of_files); + image.nr_of_files = 0; + if (!EnumResourceNamesA(image.module, "TESTRES", extract_only_proc, (LPARAM)&image)) report (R_FATAL, "Can't enumerate test files: %d", GetLastError ());
report (R_DELTA, 0, "Extracting: Done"); + + dispose_image(&image); }
static void @@ -1494,7 +1522,7 @@ int __cdecl main( int argc, char *argv[] )
if (nb_filters && !exclude_tests) { - run_tests( logname, outdir ); + run_tests( logname, outdir, NULL ); exit( failures ? 3 : 0 ); }
@@ -1521,7 +1549,8 @@ int __cdecl main( int argc, char *argv[] ) "To submit results, winetest needs to be built from a git checkout." );
if (!logname) { - logname = run_tests (NULL, outdir); + int nr_of_skips; + logname = run_tests (NULL, outdir, &nr_of_skips); if (aborting) { DeleteFileA(logname); exit (0); @@ -1543,7 +1572,7 @@ int __cdecl main( int argc, char *argv[] ) } else { - run_tests (logname, outdir); + run_tests ( logname, outdir, NULL ); report (R_STATUS, "Finished - %u failures", failures); } if (prev_crash_dialog) restore_crash_dialog( prev_crash_dialog );
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- programs/winetest/main.c | 46 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/programs/winetest/main.c b/programs/winetest/main.c index 711f38d06e6..1611333bf9f 100644 --- a/programs/winetest/main.c +++ b/programs/winetest/main.c @@ -74,6 +74,17 @@ static char build_id[64]; static BOOL is_wow64; static int failures; static int quiet_mode; +static int multi_arch; +static const char * const arch_dirs[2] = +#if defined(__i386__) || defined(__x86_64__) +{"\i386-windows", "\x86_64-windows"} +#elif defined(__arm__) || defined(__aarch64__) +{"\arm-windows", "\aarch64-windows"} +#else +#error define support for your CPU +#endif + ; +static const char *current_arch_dir = arch_dirs[sizeof(void*)==8];
/* filters for running only specific tests */ static char **filters; @@ -1098,9 +1109,36 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP return TRUE; }
+static void create_multiarch_directories(const char* target_dir) +{ + char tmp[MAX_PATH + 4]; + + if (!multi_arch) return; + + strcpy(tmp, target_dir); + strcat(tmp, arch_dirs[0]); + if (!CreateDirectoryA( tmp, NULL )) + report (R_FATAL, "Could not create directory %s (%d)", tmp, GetLastError()); + strcpy(tmp, target_dir); + strcat(tmp, arch_dirs[1]); + if (!CreateDirectoryA( tmp, NULL )) + report (R_FATAL, "Could not create directory %s (%d)", tmp, GetLastError()); +} + static BOOL init_image(struct winetest_image *image, const char *target_dir) { - image->target_dir = target_dir; + char* new; + + if (multi_arch) + { + new = malloc(strlen(target_dir) + strlen(current_arch_dir) + 1); + strcpy(new, target_dir); + strcat(new, current_arch_dir); + } + else + new = strdup(target_dir); + + image->target_dir = new; image->module = NULL; image->nr_of_files = image->nr_of_tests = image->nr_of_skips = 0; report (R_STATUS, "Counting tests"); @@ -1125,6 +1163,7 @@ static BOOL load_image(struct winetest_image *image, const char *tempdir)
static void dispose_image(struct winetest_image *image) { + free((void*)image->target_dir); free(image->wine_tests); FreeLibrary(image->module); memset(image, 0, sizeof(*image)); @@ -1189,6 +1228,7 @@ run_tests (char *logname, char *outdir, int *nr_of_skips) if (!newdir && (!outdir || GetLastError() != ERROR_ALREADY_EXISTS)) report (R_FATAL, "Could not create directory %s (%d)", tempdir, GetLastError());
+ create_multiarch_directories(tempdir); report (R_DIR, tempdir);
xprintf ("Version 4\n"); @@ -1313,6 +1353,7 @@ static void extract_only (const char *target_dir) res = CreateDirectoryA( target_dir, NULL ); if (!res && GetLastError() != ERROR_ALREADY_EXISTS) report (R_FATAL, "Could not create directory: %s (%d)", target_dir, GetLastError ()); + create_multiarch_directories( target_dir );
if (!init_image(&image, target_dir)) return;
@@ -1474,6 +1515,9 @@ int __cdecl main( int argc, char *argv[] ) case 'd': outdir = argv[++i]; break; + case 'w': + multi_arch = 1; + break; default: report (R_ERROR, "invalid option: -%c", argv[i][1]); usage ();
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/kernel32/tests/debugger.c | 28 ++++++++++++++++++++-------- include/wine/test.h | 17 +++++++++++++++++ 2 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/dlls/kernel32/tests/debugger.c b/dlls/kernel32/tests/debugger.c index 513db658222..a69d46e7c64 100644 --- a/dlls/kernel32/tests/debugger.c +++ b/dlls/kernel32/tests/debugger.c @@ -38,7 +38,7 @@
static int myARGC; static char** myARGV; -static BOOL is_wow64; +static BOOL is_wow64;
static BOOL (WINAPI *pCheckRemoteDebuggerPresent)(HANDLE,PBOOL);
@@ -860,12 +860,13 @@ static void test_RemoteDebugger(void)
struct child_blackbox { + DWORD64 main_teb; LONG failures; };
static void doChild(int argc, char **argv) { - struct child_blackbox blackbox; + struct child_blackbox blackbox = {(ULONG_PTR)NtCurrentTeb(), 0}; const char *blackbox_file; WCHAR path[MAX_PATH]; HMODULE mod; @@ -960,13 +961,15 @@ done:
static HMODULE ole32_mod, oleaut32_mod, oleacc_mod;
-static void check_dll_event( HANDLE process, DEBUG_EVENT *ev ) +static void* check_dll_event( HANDLE process, DEBUG_EVENT *ev ) { WCHAR *p, module[MAX_PATH]; + void* ret = NULL;
switch (ev->dwDebugEventCode) { case CREATE_PROCESS_DEBUG_EVENT: + ret = ev->u.CreateProcessInfo.lpThreadLocalBase; break; case LOAD_DLL_DEBUG_EVENT: if (!pGetMappedFileNameW( process, ev->u.LoadDll.lpBaseOfDll, module, MAX_PATH )) module[0] = 0; @@ -982,9 +985,10 @@ static void check_dll_event( HANDLE process, DEBUG_EVENT *ev ) if (ev->u.UnloadDll.lpBaseOfDll == oleacc_mod) oleacc_mod = (HMODULE)1; break; } + return ret; }
-static void test_debug_loop(int argc, char **argv) +static void test_debug_loop(int argc, char **argv, const char *argv0) { const char *arguments = " debugger child "; struct child_blackbox blackbox; @@ -995,6 +999,7 @@ static void test_debug_loop(int argc, char **argv) DWORD pid; char *cmd; BOOL ret; + void* main_teb = NULL;
if (!pCheckRemoteDebuggerPresent) { @@ -1007,8 +1012,8 @@ static void test_debug_loop(int argc, char **argv) ok(!ret, "DebugActiveProcess() succeeded on own process.\n");
get_file_name(blackbox_file); - cmd = HeapAlloc(GetProcessHeap(), 0, strlen(argv[0]) + strlen(arguments) + strlen(blackbox_file) + 2 + 10); - sprintf(cmd, "%s%s%08lx "%s"", argv[0], arguments, pid, blackbox_file); + cmd = HeapAlloc(GetProcessHeap(), 0, strlen(argv0) + strlen(arguments) + strlen(blackbox_file) + 2 + 10); + sprintf(cmd, "%s%s%08lx "%s"", argv0, arguments, pid, blackbox_file);
memset(&si, 0, sizeof(si)); si.cb = sizeof(si); @@ -1024,13 +1029,15 @@ static void test_debug_loop(int argc, char **argv) for (;;) { DEBUG_EVENT ev; + void* teb;
ret = WaitForDebugEvent(&ev, INFINITE); ok(ret, "WaitForDebugEvent failed, last error %#lx.\n", GetLastError()); if (!ret) break;
if (ev.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break; - check_dll_event( pi.hProcess, &ev ); + teb = check_dll_event( pi.hProcess, &ev ); + if (!main_teb && teb) main_teb = teb; #if defined(__i386__) || defined(__x86_64__) if (ev.dwDebugEventCode == EXCEPTION_DEBUG_EVENT && ev.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) @@ -1062,6 +1069,10 @@ static void test_debug_loop(int argc, char **argv) load_blackbox(blackbox_file, &blackbox, sizeof(blackbox)); ok(!blackbox.failures, "Got %ld failures from child process.\n", blackbox.failures);
+ if (argv0 == winetest_wow64_alt) + ok(main_teb && (ULONG_PTR)main_teb + 0x2000 == blackbox.main_teb, "Got wrong teb %p instead of %I64x)\n", main_teb, blackbox.main_teb); + else + ok(main_teb && (ULONG_PTR)main_teb == blackbox.main_teb, "Got wrong teb %p instead of %I64x)\n", main_teb, blackbox.main_teb); ret = DeleteFileA(blackbox_file); ok(ret, "DeleteFileA failed, last error %#lx.\n", GetLastError()); } @@ -2251,7 +2262,8 @@ START_TEST(debugger) { test_ExitCode(); test_RemoteDebugger(); - test_debug_loop(myARGC, myARGV); + test_debug_loop(myARGC, myARGV, myARGV[0]); + if (winetest_wow64_alt) test_debug_loop(myARGC, myARGV, winetest_wow64_alt); test_debug_children(myARGV[0], DEBUG_PROCESS, TRUE, FALSE); test_debug_children(myARGV[0], DEBUG_ONLY_THIS_PROCESS, FALSE, FALSE); test_debug_children(myARGV[0], DEBUG_PROCESS|DEBUG_ONLY_THIS_PROCESS, FALSE, FALSE); diff --git a/include/wine/test.h b/include/wine/test.h index c28128d9f0c..47ba34eb9c1 100644 --- a/include/wine/test.h +++ b/include/wine/test.h @@ -56,6 +56,9 @@ extern int winetest_mute_threshold; /* current platform */ extern const char *winetest_platform;
+/* alternate (32bit) test instance */ +extern const char *winetest_wow64_alt; + extern void winetest_set_location( const char* file, int line ); extern void winetest_subtest( const char* name ); extern void winetest_ignore_exceptions( BOOL ignore ); @@ -225,6 +228,9 @@ static HANDLE winetest_mutex; static int winetest_argc; static char** winetest_argv;
+/* alternate (32bit) test instance */ +const char *winetest_wow64_alt; + static const struct test *current_test; /* test currently being run */
static LONG successes; /* number of successful tests */ @@ -783,6 +789,7 @@ int main( int argc, char **argv ) { char p[128];
+ DWORD sz; setvbuf (stdout, NULL, _IONBF, 0); winetest_mutex = CreateMutexA(NULL, FALSE, "winetest_print_mutex");
@@ -814,6 +821,16 @@ int main( int argc, char **argv ) if (GetEnvironmentVariableA( "WINETEST_REPORT_FLAKY", p, sizeof(p) )) winetest_report_flaky = atoi(p); if (GetEnvironmentVariableA( "WINETEST_REPORT_SUCCESS", p, sizeof(p) )) winetest_report_success = atoi(p); if (GetEnvironmentVariableA( "WINETEST_TIME", p, sizeof(p) )) winetest_time = atoi(p); + if (sizeof(void*) == 8 && (sz = GetEnvironmentVariableA( "WINETEST_WOW64_ALT", p, sizeof(p)))) + { + char *ptr; + if (sz < sizeof(p)) winetest_wow64_alt = strdup(p); + else if ((ptr = malloc(sz)) && GetEnvironmentVariableA( "WINETEST_WOW64_ALT", ptr, sz)) + winetest_wow64_alt = ptr; + else + free(ptr); + } + winetest_last_time = winetest_start_time = GetTickCount();
if (!strcmp( winetest_platform, "windows" )) SetUnhandledExceptionFilter( exc_filter );
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- programs/winetest/main.c | 69 ++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 17 deletions(-)
diff --git a/programs/winetest/main.c b/programs/winetest/main.c index 1611333bf9f..cadf43864dc 100644 --- a/programs/winetest/main.c +++ b/programs/winetest/main.c @@ -84,7 +84,6 @@ static const char * const arch_dirs[2] = #error define support for your CPU #endif ; -static const char *current_arch_dir = arch_dirs[sizeof(void*)==8];
/* filters for running only specific tests */ static char **filters; @@ -1125,21 +1124,33 @@ static void create_multiarch_directories(const char* target_dir) report (R_FATAL, "Could not create directory %s (%d)", tmp, GetLastError()); }
-static BOOL init_image(struct winetest_image *image, const char *target_dir) +static BOOL init_image(struct winetest_image *image, const char *path, const char *target_dir) { char* new;
if (multi_arch) { - new = malloc(strlen(target_dir) + strlen(current_arch_dir) + 1); + const char* alt = arch_dirs[!!path ^ (sizeof(void*) == 8)]; + new = malloc(strlen(target_dir) + strlen(alt) + 1); strcpy(new, target_dir); - strcat(new, current_arch_dir); + strcat(new, alt); } else new = strdup(target_dir);
image->target_dir = new; - image->module = NULL; + if (path) + { + image->module = LoadLibraryExA(path, NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE); + if (!image->module) + { + report (R_FATAL, "Can't enumerate wow64 alternate test files: %d", + GetLastError ()); + return FALSE; + } + } + else + image->module = NULL; image->nr_of_files = image->nr_of_tests = image->nr_of_skips = 0; report (R_STATUS, "Counting tests"); if (!EnumResourceNamesA (image->module, "TESTRES", EnumTestFileProc, (LPARAM)&image->nr_of_files)) @@ -1149,9 +1160,9 @@ static BOOL init_image(struct winetest_image *image, const char *target_dir) return TRUE; }
-static BOOL load_image(struct winetest_image *image, const char *tempdir) +static BOOL load_image(struct winetest_image *image, const char *path, const char *tempdir) { - if (!init_image(image, tempdir)) return FALSE; + if (!init_image(image, path, tempdir)) return FALSE; report (R_STATUS, "Extracting tests"); report (R_PROGRESS, 0, image->nr_of_files); image->nr_of_files = 0; @@ -1170,7 +1181,7 @@ static void dispose_image(struct winetest_image *image) }
static char * -run_tests (char *logname, char *outdir, int *nr_of_skips) +run_tests (char *logname, char *outdir, char *wow64_alt, int *nr_of_skips) { int i; char *strres, *eol, *nextline; @@ -1179,7 +1190,7 @@ run_tests (char *logname, char *outdir, int *nr_of_skips) BOOL newdir; DWORD needed; HMODULE kernel32; - struct winetest_image image; + struct winetest_image image, image_wow64_alt;
/* Get the current PATH only once */ needed = GetEnvironmentVariableA("PATH", NULL, 0); @@ -1266,7 +1277,9 @@ run_tests (char *logname, char *outdir, int *nr_of_skips) pDeactivateActCtx = (void *)GetProcAddress(kernel32, "DeactivateActCtx"); pReleaseActCtx = (void *)GetProcAddress(kernel32, "ReleaseActCtx");
- load_image(&image, tempdir); + load_image (&image, NULL, tempdir); + if (wow64_alt) + load_image (&image_wow64_alt, wow64_alt, tempdir);
FreeLibrary(hmscoree);
@@ -1283,6 +1296,7 @@ run_tests (char *logname, char *outdir, int *nr_of_skips) report (R_PROGRESS, 1, image.nr_of_tests); for (i = 0; i < image.nr_of_files; i++) { struct wine_test *test = image.wine_tests + i; + char* other = NULL; int j;
if (aborting) break; @@ -1291,7 +1305,18 @@ run_tests (char *logname, char *outdir, int *nr_of_skips) /* We need to add the path (to the main dll) to PATH */ append_path(test->maindllpath); } - + if (wow64_alt) + { + for (j = 0; j < image_wow64_alt.nr_of_files; j++) + { + if (!strcmp(test->name, image_wow64_alt.wine_tests[j].name)) + { + other = image_wow64_alt.wine_tests[j].exename; + break; + } + } + } + SetEnvironmentVariableA( "WINETEST_WOW64_ALT", other ); for (j = 0; j < test->subtest_count; j++) { if (aborting) break; if (!run_test (test, test->subtests[j], logfile, tempdir)) @@ -1312,6 +1337,7 @@ run_tests (char *logname, char *outdir, int *nr_of_skips) remove_dir (tempdir); if (nr_of_skips) *nr_of_skips = image.nr_of_skips; dispose_image(&image); + if (wow64_alt) dispose_image (&image_wow64_alt); free(curpath);
return logname; @@ -1355,7 +1381,7 @@ static void extract_only (const char *target_dir) report (R_FATAL, "Could not create directory: %s (%d)", target_dir, GetLastError ()); create_multiarch_directories( target_dir );
- if (!init_image(&image, target_dir)) return; + if (!init_image(&image, NULL, target_dir)) return;
report (R_STATUS, "Extracting tests"); report (R_PROGRESS, 0, image.nr_of_files); @@ -1389,19 +1415,22 @@ usage (void) " -S URL URL to submit the results to\n" " -t TAG include TAG of characters [-.0-9a-zA-Z] in the report\n" " -u URL include TestBot URL in the report\n" -" -x DIR Extract tests to DIR (default: .\wct) and exit\n"); +" -x DIR Extract tests to DIR (default: .\wct) and exit\n" +" -w EXE Extend tests with another winetest executable.\n" +" (this exec must be 64bit, while [EXE] exec must be 32bit)\n"); }
int __cdecl main( int argc, char *argv[] ) { BOOL (WINAPI *pIsWow64Process)(HANDLE hProcess, PBOOL Wow64Process); - char *logname = NULL, *outdir = NULL; + char *logname = NULL, *outdir = NULL, *wow64_alt = NULL; const char *extract = NULL; const char *cp, *submit = NULL, *submiturl = NULL; int reset_env = 1; int poweroff = 0; int interactive = 1; int prev_crash_dialog = 0; + DWORD bintype; int i;
InitCommonControls(); @@ -1517,6 +1546,12 @@ int __cdecl main( int argc, char *argv[] ) break; case 'w': multi_arch = 1; + wow64_alt = argv[++i]; + if (sizeof(void*) != 8 || !GetBinaryTypeA(wow64_alt, &bintype) || bintype != SCS_32BIT_BINARY) + { + usage(); + exit(2); + } break; default: report (R_ERROR, "invalid option: -%c", argv[i][1]); @@ -1566,7 +1601,7 @@ int __cdecl main( int argc, char *argv[] )
if (nb_filters && !exclude_tests) { - run_tests( logname, outdir, NULL ); + run_tests( logname, outdir, wow64_alt, NULL ); exit( failures ? 3 : 0 ); }
@@ -1594,7 +1629,7 @@ int __cdecl main( int argc, char *argv[] )
if (!logname) { int nr_of_skips; - logname = run_tests (NULL, outdir, &nr_of_skips); + logname = run_tests (NULL, outdir, wow64_alt, &nr_of_skips); if (aborting) { DeleteFileA(logname); exit (0); @@ -1616,7 +1651,7 @@ int __cdecl main( int argc, char *argv[] ) } else { - run_tests ( logname, outdir, NULL ); + run_tests ( logname, outdir, wow64_alt, NULL ); report (R_STATUS, "Finished - %u failures", failures); } if (prev_crash_dialog) restore_crash_dialog( prev_crash_dialog );
This merge request was closed by eric pouech.