This needs more changes, please disregard this series.
Sorry for the noise.

Op di 26 nov. 2019 om 18:06 schreef Gijs Vermeulen <gijsvrm@codeweavers.com>:
Signed-off-by: Gijs Vermeulen <gijsvrm@codeweavers.com>
---
������dlls/shell32/tests/shellpath.c | 131 +++++++++++++++++++++++++++++++++
������1 file changed, 131 insertions(+)

diff --git a/dlls/shell32/tests/shellpath.c b/dlls/shell32/tests/shellpath.c
index 262714a9f3..e9dcf2da8c 100644
--- a/dlls/shell32/tests/shellpath.c
+++ b/dlls/shell32/tests/shellpath.c
@@ -99,6 +99,7 @@ static HRESULT (WINAPI *pSHSetKnownFolderPath)(REFKNOWNFOLDERID, DWORD, HANDLE,
������static HRESULT (WINAPI *pSHGetFolderPathEx)(REFKNOWNFOLDERID, DWORD, HANDLE, LPWSTR, DWORD);
������static BOOL (WINAPI *pPathYetAnotherMakeUniqueName)(PWSTR, PCWSTR, PCWSTR, PCWSTR);
������static HRESULT (WINAPI *pSHGetKnownFolderIDList)(REFKNOWNFOLDERID, DWORD, HANDLE, PIDLIST_ABSOLUTE*);
+static BOOL (WINAPI *pPathResolve)(PWSTR, PZPCWSTR, UINT);

������static DLLVERSIONINFO shellVersion = { 0 };
������static LPMALLOC pMalloc;
@@ -207,6 +208,7 @@ static void loadShell32(void)
������ ������ ������GET_PROC(SHGetMalloc)
������ ������ ������GET_PROC(PathYetAnotherMakeUniqueName)
������ ������ ������GET_PROC(SHGetKnownFolderIDList)
+������ ������ GET_PROC(PathResolve);

������ ������ ������ok(pSHGetMalloc != NULL, "shell32 is missing SHGetMalloc\n");
������ ������ ������if (pSHGetMalloc)
@@ -2864,6 +2866,134 @@ if (0) { /* crashes on native */
������ ������ ������ILFree(pidl);
������}

+static void test_PathResolve(void)
+{
+������ ������ WCHAR testfile[MAX_PATH], testfile_lnk[MAX_PATH], regedit_in_testdir[MAX_PATH], regedit_cmd[MAX_PATH];
+������ ������ WCHAR prev_dir[MAX_PATH], tempdir[MAX_PATH], path[MAX_PATH];
+������ ������ const WCHAR *dirs[2] = { tempdir, NULL };
+������ ������ HANDLE file, file2;
+������ ������ BOOL ret;
+������ ������ int i;
+������ ������ struct {
+������ ������ ������ ������ const WCHAR *path;
+������ ������ ������ ������ UINT flags;
+������ ������ ������ ������ BOOL expected;
+������ ������ ������ ������ const WCHAR *expected_path;
+������ ������ } tests[] = {
+������ ������ ������ ������ /* no flags */
+������ ������ ������ ������ { L"test", 0, FALSE, L"test" },
+������ ������ ������ ������ { L"..\\test", 0, TRUE, L"C:\\test" },
+������ ������ ������ ������ { L".\\test", 0, TRUE, L"C:\\test" },
+������ ������ ������ ������ { L"test\\test", 0, TRUE, L"C:\\test\\test" },
+������ ������ ������ ������ { L"C:\\test", 0, TRUE, L"C:\\test" },
+������ ������ ������ ������ { L"regedit", 0, FALSE, L"regedit" },
+������ ������ ������ ������ { testfile, 0, TRUE, testfile },
+
+������ ������ ������ ������ /* PRF_VERIFYEXISTS */
+������ ������ ������ ������ { L"test", PRF_VERIFYEXISTS, TRUE, testfile_lnk },
+������ ������ ������ ������ { L"C:\\test", PRF_VERIFYEXISTS, FALSE, L"C:\\test" },
+������ ������ ������ ������ /* common extensions are tried even if PRF_TRYPROGRAMEXTENSIONS isn't passed */
+������ ������ ������ ������ /* directories in dirs parameter are always searched first even if PRF_FIRSTDIRDEF isn't passed */
+������ ������ ������ ������ { L"regedit", PRF_VERIFYEXISTS, TRUE, regedit_cmd },
+������ ������ ������ ������ /* .dll is not tried */
+������ ������ ������ ������ { L"bcrypt", PRF_VERIFYEXISTS, FALSE, L"bcrypt" },
+������ ������ ������ ������ { testfile, PRF_VERIFYEXISTS, TRUE, testfile_lnk },
+������ ������ ������ ������ { regedit_in_testdir, PRF_VERIFYEXISTS, TRUE, regedit_cmd },
+
+������ ������ ������ ������ /* PRF_FIRSTDIRDEF */
+������ ������ ������ ������ { L"regedit", PRF_FIRSTDIRDEF, FALSE, L"regedit" },
+
+������ ������ ������ ������ /* RF_VERIFYEXISTS | PRF_FIRSTDIRDEF */
+������ ������ ������ ������ { L"regedit", PRF_VERIFYEXISTS | PRF_FIRSTDIRDEF, TRUE, regedit_cmd },
+
+������ ������ ������ ������ /* PRF_DONTFINDLNK */
+������ ������ ������ ������ { testfile, PRF_DONTFINDLNK, TRUE, testfile },
+������ ������ ������ ������ { regedit_in_testdir, PRF_DONTFINDLNK, TRUE, regedit_in_testdir },
+
+������ ������ ������ ������ /* RF_VERIFYEXISTS | PRF_DONTFINDLNK */
+������ ������ ������ ������ { testfile, PRF_VERIFYEXISTS | PRF_DONTFINDLNK, FALSE, testfile },
+������ ������ ������ ������ /* cmd is also ignored when passing PRF_VERIFYEXISTS | PRF_DONTFINDLNK */
+������ ������ ������ ������ { regedit_in_testdir, PRF_VERIFYEXISTS | PRF_DONTFINDLNK, FALSE, regedit_in_testdir },
+
+������ ������ ������ ������ /* PRF_REQUIREABSOLUTE */
+������ ������ ������ ������ /* seems to be ignored */
+������ ������ ������ ������ { L"..\\test", PRF_REQUIREABSOLUTE, TRUE, L"C:\\test" },
+������ ������ ������ ������ { L".\\test", PRF_REQUIREABSOLUTE, TRUE, L"C:\\test" },
+������ ������ ������ ������ { L"test\\test", PRF_REQUIREABSOLUTE, TRUE, L"C:\\test\\test" },
+������ ������ ������ ������ { L"C:\\test", PRF_REQUIREABSOLUTE, TRUE, L"C:\\test" },
+
+������ ������ ������ ������ /* PRF_VERIFYEXISTS | PRF_REQUIREABSOLUTE */
+������ ������ ������ ������ /* only PRF_VERIFYEXISTS matters*/
+������ ������ ������ ������ { L"test", PRF_VERIFYEXISTS | PRF_REQUIREABSOLUTE, TRUE, testfile_lnk },
+������ ������ ������ ������ { L"C:\\test", PRF_VERIFYEXISTS | PRF_REQUIREABSOLUTE, FALSE, L"C:\\test" },
+������ ������ ������ ������ { L"regedit", PRF_VERIFYEXISTS | PRF_REQUIREABSOLUTE, TRUE, regedit_cmd },
+������ ������ ������ ������ { testfile, PRF_VERIFYEXISTS | PRF_REQUIREABSOLUTE, TRUE, testfile_lnk },
+
+������ ������ ������ ������ /* PRF_TRYPROGRAMEXTENSIONS */
+������ ������ ������ ������ { L"test", PRF_TRYPROGRAMEXTENSIONS, TRUE, testfile_lnk},
+������ ������ ������ ������ { L"C:\\test", PRF_TRYPROGRAMEXTENSIONS, FALSE, L"C:\\test" },
+������ ������ ������ ������ { L"regedit", PRF_TRYPROGRAMEXTENSIONS, TRUE, regedit_cmd },
+������ ������ ������ ������ /* .dll is not tried */
+������ ������ ������ ������ { L"bcrypt", PRF_TRYPROGRAMEXTENSIONS, FALSE, L"bcrypt" },
+������ ������ ������ ������ { testfile, PRF_TRYPROGRAMEXTENSIONS, TRUE, testfile_lnk },
+������ ������ ������ ������ { regedit_in_testdir, PRF_TRYPROGRAMEXTENSIONS, TRUE, regedit_cmd },
+
+������ ������ ������ ������ /* PRF_TRYPROGRAMEXTENSIONS | PRF_DONTFINDLNK */
+������ ������ ������ ������ { testfile, PRF_TRYPROGRAMEXTENSIONS | PRF_DONTFINDLNK, FALSE, testfile },
+������ ������ ������ ������ /* cmd is also ignored when passing PRF_TRYPROGRAMEXTENSIONS | PRF_DONTFINDLNK */
+������ ������ ������ ������ { regedit_in_testdir, PRF_TRYPROGRAMEXTENSIONS | PRF_DONTFINDLNK, FALSE, regedit_in_testdir }
+������ ������ };
+
+������ ������ if (!pPathResolve)
+������ ������ {
+������ ������ ������ ������ win_skip("PathResolve not available\n");
+������ ������ ������ ������ return;
+������ ������ }
+
+������ ������ GetCurrentDirectoryW(MAX_PATH, prev_dir);
+������ ������ SetCurrentDirectoryW(L"C:");
+
+������ ������ GetTempPathW(MAX_PATH, tempdir);
+
+������ ������ lstrcpyW(testfile, tempdir);
+������ ������ lstrcatW(testfile, L"test");
+������ ������ lstrcpyW(testfile_lnk, testfile);
+������ ������ lstrcatW(testfile_lnk, L".lnk");
+
+������ ������ file = CreateFileW(testfile_lnk, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL);
+������ ������ ok(file != INVALID_HANDLE_VALUE, "got %p\n", file);
+
+������ ������ lstrcpyW(regedit_in_testdir, tempdir);
+������ ������ lstrcatW(regedit_in_testdir, L"regedit");
+������ ������ lstrcpyW(regedit_cmd, regedit_in_testdir);
+������ ������ lstrcatW(regedit_cmd, L".cmd");
+
+������ ������ file2 = CreateFileW(regedit_cmd, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL);
+������ ������ ok(file2 != INVALID_HANDLE_VALUE, "got %p\n", file);
+
+������ ������ /* show that resolving regedit with NULL dirs returns regedit.exe */
+������ ������ lstrcpyW(path, L"regedit");
+������ ������ ret = pPathResolve(path, NULL, PRF_VERIFYEXISTS);
+������ ������ ok(ret, "resolving regedit failed unexpectedly\n");
+������ ������ ok(!lstrcmpiW(path, L"C:\\windows\\regedit.exe") || !lstrcmpiW(path, L"C:\\windows\\system32\\regedit.exe"),
+������ ������ ������ ������ ������ ������ "unexpected path %s\n", wine_dbgstr_w(path));
+
+������ ������ for (i = 0; i < ARRAY_SIZE(tests); i++)
+������ ������ {
+������ ������ ������ ������ lstrcpyW(path, tests[i].path);
+
+������ ������ ������ ������ if (!tests[i].expected) SetLastError(0xdeadbeef);
+������ ������ ������ ������ ret = pPathResolve(path, dirs, tests[i].flags);
+������ ������ ������ ������ ok(ret == tests[i].expected, "test %d: expected %d, got %d\n", i, tests[i].expected, ret);
+������ ������ ������ ������ ok(!lstrcmpiW(path, tests[i].expected_path),
+������ ������ ������ ������ ������ ������ ������ ������ "test %d: expected %s, got %s\n", i, wine_dbgstr_w(tests[i].expected_path), wine_dbgstr_w(path));
+������ ������ }
+
+������ ������ CloseHandle(file);
+������ ������ CloseHandle(file2);
+������ ������ SetCurrentDirectoryW(prev_dir);
+}
+
������START_TEST(shellpath)
������{
������ ������ ������if (!init()) return;
@@ -2894,5 +3024,6 @@ START_TEST(shellpath)
������ ������ ������ ������ ������test_DoEnvironmentSubst();
������ ������ ������ ������ ������test_PathYetAnotherMakeUniqueName();
������ ������ ������ ������ ������test_SHGetKnownFolderIDList();
+������ ������ ������ ������ test_PathResolve();
������ ������ ������}
������}
--
2.24.0