From f324f3c31ef4b0a6b5273aca534c173d68932462 Mon Sep 17 00:00:00 2001 From: Andrew Eikum Date: Thu, 11 Nov 2010 15:58:12 -0600 Subject: [PATCH] shell32: Don't fail if the path doesn't exist in Unix in IShellFolder::ParseDisplayName. --- dlls/shell32/shfldr_unixfs.c | 25 +++++++++++++++++----- dlls/shell32/tests/shelllink.c | 10 +++------ dlls/shell32/tests/shlfolder.c | 47 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/dlls/shell32/shfldr_unixfs.c b/dlls/shell32/shfldr_unixfs.c index 11f3686f0fe..14bf900b132 100644 --- a/dlls/shell32/shfldr_unixfs.c +++ b/dlls/shell32/shfldr_unixfs.c @@ -368,8 +368,8 @@ static inline BOOL UNIXFS_is_pidl_of_type(LPCITEMIDLIST pIDL, SHCONTF fFilter) { */ static BOOL UNIXFS_get_unix_path(LPCWSTR pszDosPath, char *pszCanonicalPath) { - char *pPathTail, *pElement, *pCanonicalTail, szPath[FILENAME_MAX], *pszUnixPath; - WCHAR wszDrive[] = { '?', ':', '\\', 0 }; + char *pPathTail, *pElement, *pCanonicalTail, szPath[FILENAME_MAX], *pszUnixPath, has_failed = 0, mb_path[FILENAME_MAX]; + WCHAR wszDrive[] = { '?', ':', '\\', 0 }, dospath[PATH_MAX], *dospath_end; int cDriveSymlinkLen; TRACE("(pszDosPath=%s, pszCanonicalPath=%p)\n", debugstr_w(pszDosPath), pszCanonicalPath); @@ -388,11 +388,26 @@ static BOOL UNIXFS_get_unix_path(LPCWSTR pszDosPath, char *pszCanonicalPath) if (szPath[strlen(szPath)-1] != '/') strcat(szPath, "/"); /* Append the part relative to the drive symbolic link target. */ - pszUnixPath = wine_get_unix_file_name(pszDosPath); - if (!pszUnixPath) return FALSE; + lstrcpyW(dospath, pszDosPath); + dospath_end = dospath + lstrlenW(dospath); + while(!(pszUnixPath = wine_get_unix_file_name(dospath))){ + if(has_failed) + *dospath_end = '/'; + else + has_failed = 1; + while(*dospath_end != '\\' && *dospath_end != '/') + --dospath_end; + *dospath_end = '\0'; + } strcat(szPath, pszUnixPath + cDriveSymlinkLen); HeapFree(GetProcessHeap(), 0, pszUnixPath); - + + if(has_failed && WideCharToMultiByte(CP_UNIXCP, 0, dospath_end + 1, -1, + mb_path, FILENAME_MAX, NULL, NULL) > 0){ + strcat(szPath, "/"); + strcat(szPath, mb_path); + } + /* pCanonicalTail always points to the end of the canonical path constructed * thus far. pPathTail points to the still to be processed part of the input * path. pElement points to the path element currently investigated. diff --git a/dlls/shell32/tests/shelllink.c b/dlls/shell32/tests/shelllink.c index 1b38b0dc82a..55ba936068e 100644 --- a/dlls/shell32/tests/shelllink.c +++ b/dlls/shell32/tests/shelllink.c @@ -204,16 +204,14 @@ static void test_get_set(void) /* Test the interaction of SetPath and SetIDList */ tmp_pidl=NULL; r = IShellLinkA_GetIDList(sl, &tmp_pidl); - todo_wine ok(r == S_OK, "GetIDList failed (0x%08x)\n", r); + ok(r == S_OK, "GetIDList failed (0x%08x)\n", r); if (r == S_OK) { BOOL ret; strcpy(buffer,"garbage"); ret = SHGetPathFromIDListA(tmp_pidl, buffer); - todo_wine { ok(ret, "SHGetPathFromIDListA failed\n"); - } if (ret) ok(lstrcmpi(buffer,str)==0, "GetIDList returned '%s'\n", buffer); pILFree(tmp_pidl); @@ -326,11 +324,9 @@ static void test_get_set(void) i=0xdeadbeef; strcpy(buffer,"garbage"); r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i); - todo_wine { ok(r == S_OK, "GetIconLocation failed (0x%08x)\n", r); - } - ok(*buffer=='\0', "GetIconLocation returned '%s'\n", buffer); - ok(i==0, "GetIconLocation returned %d\n", i); + todo_wine ok(*buffer=='\0', "GetIconLocation returned '%s'\n", buffer); + todo_wine ok(i==0, "GetIconLocation returned %d\n", i); str="c:\\nonexistent\\file"; r = IShellLinkA_SetIconLocation(sl, str, 0xbabecafe); diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index 67a9630e3e7..6294c5db761 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -4041,6 +4041,7 @@ static void test_ParseDisplayNamePBC(void) WCHAR wFileSystemBindData[] = {'F','i','l','e',' ','S','y','s','t','e','m',' ','B','i','n','d',' ','D','a','t','a',0}; WCHAR adirW[] = {'C',':','\\','f','s','b','d','d','i','r',0}; + WCHAR afileW[] = {'C',':','\\','f','s','b','d','d','i','r','\\','f','i','l','e','.','t','x','t',0}; const HRESULT exp_err = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); IShellFolder *psf; @@ -4067,6 +4068,9 @@ static void test_ParseDisplayNamePBC(void) hres = IShellFolder_ParseDisplayName(psf, NULL, NULL, adirW, NULL, &pidl, NULL); ok(hres == exp_err || broken(hres == E_FAIL) /* NT4 */, "ParseDisplayName failed with wrong error: 0x%08x\n", hres); + hres = IShellFolder_ParseDisplayName(psf, NULL, NULL, afileW, NULL, &pidl, NULL); + ok(hres == exp_err || broken(hres == E_FAIL) /* NT4 */, + "ParseDisplayName failed with wrong error: 0x%08x\n", hres); /* fails on unknown dir with IBindCtx with no IFileSystemBindData */ hres = CreateBindCtx(0, &pbc); @@ -4075,6 +4079,9 @@ static void test_ParseDisplayNamePBC(void) hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, adirW, NULL, &pidl, NULL); ok(hres == exp_err || broken(hres == E_FAIL) /* NT4 */, "ParseDisplayName failed with wrong error: 0x%08x\n", hres); + hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, afileW, NULL, &pidl, NULL); + ok(hres == exp_err || broken(hres == E_FAIL) /* NT4 */, + "ParseDisplayName failed with wrong error: 0x%08x\n", hres); /* unknown dir with IBindCtx with IFileSystemBindData */ hres = IBindCtx_RegisterObjectParam(pbc, wFileSystemBindData, (IUnknown*)&fsbd); @@ -4091,6 +4098,14 @@ static void test_ParseDisplayNamePBC(void) ILFree(pidl); } + hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, afileW, NULL, &pidl, NULL); + ok(hres == S_OK || broken(hres == E_FAIL) /* NT4 */, + "ParseDisplayName failed: 0x%08x\n", hres); + if(SUCCEEDED(hres)){ + verify_pidl(pidl, afileW); + ILFree(pidl); + } + /* set FIND_DATA struct to NULLs */ pidl = (ITEMIDLIST*)0xdeadbeef; fsbdVtbl.GetFindData = fsbd_GetFindData_nul; @@ -4102,6 +4117,14 @@ static void test_ParseDisplayNamePBC(void) ILFree(pidl); } + hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, afileW, NULL, &pidl, NULL); + ok(hres == S_OK || broken(hres == E_FAIL) /* NT4 */, + "ParseDisplayName failed: 0x%08x\n", hres); + if(SUCCEEDED(hres)){ + verify_pidl(pidl, afileW); + ILFree(pidl); + } + /* set FIND_DATA struct to junk */ pidl = (ITEMIDLIST*)0xdeadbeef; fsbdVtbl.GetFindData = fsbd_GetFindData_junk; @@ -4113,6 +4136,14 @@ static void test_ParseDisplayNamePBC(void) ILFree(pidl); } + hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, afileW, NULL, &pidl, NULL); + ok(hres == S_OK || broken(hres == E_FAIL) /* NT4 */, + "ParseDisplayName failed: 0x%08x\n", hres); + if(SUCCEEDED(hres)){ + verify_pidl(pidl, afileW); + ILFree(pidl); + } + /* set FIND_DATA struct to invalid data */ pidl = (ITEMIDLIST*)0xdeadbeef; fsbdVtbl.GetFindData = fsbd_GetFindData_invalid; @@ -4124,6 +4155,14 @@ static void test_ParseDisplayNamePBC(void) ILFree(pidl); } + hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, afileW, NULL, &pidl, NULL); + ok(hres == S_OK || broken(hres == E_FAIL) /* NT4 */, + "ParseDisplayName failed: 0x%08x\n", hres); + if(SUCCEEDED(hres)){ + verify_pidl(pidl, afileW); + ILFree(pidl); + } + /* set FIND_DATA struct to valid data */ pidl = (ITEMIDLIST*)0xdeadbeef; fsbdVtbl.GetFindData = fsbd_GetFindData_valid; @@ -4135,6 +4174,14 @@ static void test_ParseDisplayNamePBC(void) ILFree(pidl); } + hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, afileW, NULL, &pidl, NULL); + ok(hres == S_OK || broken(hres == E_FAIL) /* NT4 */, + "ParseDisplayName failed: 0x%08x\n", hres); + if(SUCCEEDED(hres)){ + verify_pidl(pidl, afileW); + ILFree(pidl); + } + IBindCtx_Release(pbc); IShellFolder_Release(psf); } -- 2.11.4.GIT