[PATCH v2 0/5] MR5342: Draft: shell32: fix wrong search path for FindExecutable/ShellExecute
-- v2: shell32/tests: Check that PathResolve(file, NULL, ...) does not look in the current directory. fixup! shell32/tests: Check ShellExecute is looking in the correct current directory. fixup! shell32/tests: Check FindExecutable is looking in the correct current directory. shell32/tests: Check ShellExecute is looking in the correct current directory. shell32/tests: Check FindExecutable is looking in the correct current directory. https://gitlab.winehq.org/wine/wine/-/merge_requests/5342
From: Yuxuan Shui <yshui(a)codeweavers.com> FindExecutable should look in the current working directory, not relative to the current executable image (which is what SearchPathW(NULL, ...) does). --- dlls/shell32/tests/shlexec.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c index 11332484800..2a039f61f8b 100644 --- a/dlls/shell32/tests/shlexec.c +++ b/dlls/shell32/tests/shlexec.c @@ -2009,9 +2009,11 @@ static void test_urls(void) static void test_find_executable(void) { + char curdir[MAX_PATH]; char notepad_path[MAX_PATH]; char filename[MAX_PATH + 17]; char command[MAX_PATH]; + char *basename = strrchr(argv0, '\\') + 1; const filename_tests_t* test; INT_PTR rc; @@ -2052,6 +2054,23 @@ static void test_find_executable(void) ok(rc == SE_ERR_NOASSOC /* >= win2000 */ || rc > 32 /* win98, nt4 */, "FindExecutable(NULL) returned %Id\n", rc); ok(strcmp(command, "your word") != 0, "FindExecutable(NULL) returned command=[%s]\n", command); + /* Search for the current executabe itself */ + strcpy(command, "your word"); + rc=(INT_PTR)FindExecutableA(argv0, NULL, command); + ok(rc > 32, "FindExecutable(%s) returned %Id\n", argv0, rc); + + /* Make sure FindExecutable uses the correct current directory */ + GetCurrentDirectoryA(MAX_PATH, curdir); + SetCurrentDirectoryA(tmpdir); + rc=CreateDirectoryA("tmpdir", NULL); + ok(rc || GetLastError() == ERROR_ALREADY_EXISTS, "Failed to create 'tmpdir' err %lu\n", GetLastError()); + SetCurrentDirectoryA("tmpdir"); + rc=(INT_PTR)FindExecutableA(basename, NULL, command); + todo_wine ok(rc == SE_ERR_FNF, "FindExecutable(%s) returned %Id\n", basename, rc); + SetCurrentDirectoryA(".."); + RemoveDirectoryA("tmpdir"); + SetCurrentDirectoryA(curdir); + sprintf(filename, "%s\\test file.sfe", tmpdir); rc=(INT_PTR)FindExecutableA(filename, NULL, command); ok(rc > 32, "FindExecutable(%s) returned %Id\n", filename, rc); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5342
From: Yuxuan Shui <yshui(a)codeweavers.com> --- dlls/shell32/tests/shlexec.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c index 2a039f61f8b..0e5d7cab5d2 100644 --- a/dlls/shell32/tests/shlexec.c +++ b/dlls/shell32/tests/shlexec.c @@ -2271,6 +2271,8 @@ static void test_exes(void) { char filename[2 * MAX_PATH + 17]; char params[1024]; + char curdir[MAX_PATH]; + char *basename = strrchr(argv0, '\\') + 1; INT_PTR rc; sprintf(params, "shlexec \"%s\" Exec", child_file); @@ -2358,6 +2360,19 @@ static void test_exes(void) "notaverb", argv0, NULL, NULL, NULL); todo_wine okShell(rc == SE_ERR_NOASSOC, "returned %Iu\n", rc); + /* Check the correct search path is used */ + GetCurrentDirectoryA(MAX_PATH, curdir); + SetCurrentDirectoryA(tmpdir); + rc = CreateDirectoryA("tmpdir", NULL); + okShell(rc || GetLastError() == ERROR_ALREADY_EXISTS, "Failed to create 'tmpdir' err %lu\n", GetLastError()); + SetCurrentDirectoryA("tmpdir"); + rc = shell_execute(NULL, basename, params, NULL); + trace("shell_execute(%s) returned %Iu\n", basename, rc); + todo_wine okShell(rc == SE_ERR_FNF, "returned %Iu\n", rc); + SetCurrentDirectoryA(".."); + RemoveDirectoryA("tmpdir"); + SetCurrentDirectoryA(curdir); + if (!skip_shlexec_tests) { /* A class overrides the normal handling of executables too */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5342
From: Yuxuan Shui <yshui(a)codeweavers.com> --- dlls/shell32/tests/shlexec.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c index 0e5d7cab5d2..92219bd58e6 100644 --- a/dlls/shell32/tests/shlexec.c +++ b/dlls/shell32/tests/shlexec.c @@ -2062,13 +2062,8 @@ static void test_find_executable(void) /* Make sure FindExecutable uses the correct current directory */ GetCurrentDirectoryA(MAX_PATH, curdir); SetCurrentDirectoryA(tmpdir); - rc=CreateDirectoryA("tmpdir", NULL); - ok(rc || GetLastError() == ERROR_ALREADY_EXISTS, "Failed to create 'tmpdir' err %lu\n", GetLastError()); - SetCurrentDirectoryA("tmpdir"); rc=(INT_PTR)FindExecutableA(basename, NULL, command); todo_wine ok(rc == SE_ERR_FNF, "FindExecutable(%s) returned %Id\n", basename, rc); - SetCurrentDirectoryA(".."); - RemoveDirectoryA("tmpdir"); SetCurrentDirectoryA(curdir); sprintf(filename, "%s\\test file.sfe", tmpdir); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5342
From: Yuxuan Shui <yshui(a)codeweavers.com> --- dlls/shell32/tests/shlexec.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c index 92219bd58e6..c9e23c7062e 100644 --- a/dlls/shell32/tests/shlexec.c +++ b/dlls/shell32/tests/shlexec.c @@ -2358,14 +2358,8 @@ static void test_exes(void) /* Check the correct search path is used */ GetCurrentDirectoryA(MAX_PATH, curdir); SetCurrentDirectoryA(tmpdir); - rc = CreateDirectoryA("tmpdir", NULL); - okShell(rc || GetLastError() == ERROR_ALREADY_EXISTS, "Failed to create 'tmpdir' err %lu\n", GetLastError()); - SetCurrentDirectoryA("tmpdir"); rc = shell_execute(NULL, basename, params, NULL); - trace("shell_execute(%s) returned %Iu\n", basename, rc); todo_wine okShell(rc == SE_ERR_FNF, "returned %Iu\n", rc); - SetCurrentDirectoryA(".."); - RemoveDirectoryA("tmpdir"); SetCurrentDirectoryA(curdir); if (!skip_shlexec_tests) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5342
From: Yuxuan Shui <yshui(a)codeweavers.com> --- dlls/shell32/tests/shellpath.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/dlls/shell32/tests/shellpath.c b/dlls/shell32/tests/shellpath.c index 29b47ac8706..329f31ce25e 100644 --- a/dlls/shell32/tests/shellpath.c +++ b/dlls/shell32/tests/shellpath.c @@ -2942,7 +2942,8 @@ if (0) { /* crashes on native */ static void test_PathResolve(void) { WCHAR testfile[MAX_PATH], testfile_lnk[MAX_PATH], regedit_in_testdir[MAX_PATH], regedit_cmd[MAX_PATH]; - WCHAR tempdir[MAX_PATH], path[MAX_PATH]; + WCHAR tempdir[MAX_PATH], path[MAX_PATH], curdir[MAX_PATH]; + WCHAR argv0_dir[MAX_PATH] = {0}, argv0_base[MAX_PATH] = {0}; const WCHAR *dirs[2] = { tempdir, NULL }; HANDLE file, file2; BOOL ret; @@ -3013,6 +3014,17 @@ static void test_PathResolve(void) return; } + ret = GetModuleFileNameW(NULL, argv0_dir, sizeof(argv0_dir)); + ok(ret != 0 && ret < sizeof(argv0_dir), "GetModuleFileName failed\n"); + if (ret != 0 && ret < sizeof(argv0_dir)) + { + WCHAR *basename = wcsrchr(argv0_dir, '\\'), *ext; + *basename = 0; + lstrcpyW(argv0_base, basename + 1); + ext = wcsrchr(argv0_base, '.'); + if (ext) *ext = 0; + } + GetTempPathW(MAX_PATH, tempdir); lstrcpyW(testfile, tempdir); @@ -3038,6 +3050,18 @@ static void test_PathResolve(void) ok(!lstrcmpiW(path, L"C:\\windows\\regedit.exe") || !lstrcmpiW(path, L"C:\\windows\\system32\\regedit.exe"), "unexpected path %s\n", wine_dbgstr_w(path)); + /* show that PathResolve doesn't check current directory */ + if (argv0_base[0]) + { + GetCurrentDirectoryW(MAX_PATH, curdir); + SetCurrentDirectoryW(argv0_dir); + ret = pPathResolve(argv0_base, NULL, PRF_VERIFYEXISTS | PRF_TRYPROGRAMEXTENSIONS); + todo_wine ok(!ret, "resolving argv0 succeeded unexpectedly, result: %s\n", wine_dbgstr_w(argv0_base)); + SetCurrentDirectoryW(curdir); + } + else + win_skip("couldn't get module filename\n"); + for (i = 0; i < ARRAY_SIZE(tests); i++) { winetest_push_context("test %d", i); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5342
participants (2)
-
Yuxuan Shui -
Yuxuan Shui (@yshui)