Andrew Eikum : shell32: Don't fail if the path doesn' t exist in Unix in IShellFolder::ParseDisplayName.

Alexandre Julliard julliard at winehq.org
Fri Nov 12 11:22:33 CST 2010


Module: wine
Branch: master
Commit: f324f3c31ef4b0a6b5273aca534c173d68932462
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f324f3c31ef4b0a6b5273aca534c173d68932462

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Thu Nov 11 15:58:12 2010 -0600

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 11f3686..14bf900 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 1b38b0d..55ba936 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 67a9630..6294c5d 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);
 }




More information about the wine-cvs mailing list