Revert last Wine sync to pidl.c, since it breaks SHGetPathFromIDListW. Fixes
bug 697
Modified: trunk/reactos/lib/shell32/pidl.c

Modified: trunk/reactos/lib/shell32/pidl.c
--- trunk/reactos/lib/shell32/pidl.c	2005-08-11 20:48:55 UTC (rev 17315)
+++ trunk/reactos/lib/shell32/pidl.c	2005-08-11 21:09:56 UTC (rev 17316)
@@ -1210,6 +1210,87 @@
 }
 
 /*************************************************************************
+ * SHELL_GetPathFromIDListA
+ */
+HRESULT SHELL_GetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath, UINT uOutSize)
+{
+    HRESULT hr = S_OK;
+
+    pszPath[0]=0;
+
+    /* One case is a PIDL rooted at desktop level */
+    if (_ILIsDesktop(pidl) || _ILIsValue(pidl) || _ILIsFolder(pidl))
+    {
+        hr = SHGetSpecialFolderPathA(0, pszPath, CSIDL_DESKTOP, FALSE);
+
+        if (SUCCEEDED(hr))
+            PathAddBackslashA(pszPath);
+    }
+    /* The only other valid case is an item ID list beginning at "My Computer" */
+    else if (_ILIsMyComputer(pidl))
+        pidl = ILGetNext(pidl);
+
+    if (SUCCEEDED(hr))
+    {
+        LPSTR txt;
+
+        while(pidl && pidl->mkid.cb)
+        {
+            if (_ILIsSpecialFolder(pidl))
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+
+            txt = _ILGetTextPointer(pidl);
+            if (!txt)
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+
+            if (lstrlenA(txt) > pidl->mkid.cb)
+                ERR("pidl %p is borked\n",pidl);
+
+            /* make sure there's enough space for the next segment */
+            if ((lstrlenA(txt) + lstrlenA(pszPath)) > uOutSize)
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+            lstrcatA( pszPath, txt );
+
+            pidl = ILGetNext(pidl);
+            if (!pidl)
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+
+            /* Are we at the end and successfully converted the complete PIDL? */
+            if (!pidl->mkid.cb)
+                break;
+
+            if ((lstrlenA(pszPath) + 1) > uOutSize)
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+            if (!PathAddBackslashA(pszPath))
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+        }
+    }
+    else
+        hr = E_INVALIDARG;
+
+    TRACE_(shell)("-- %s, 0x%08lx\n", pszPath, hr);
+    return hr;
+}
+
+/*************************************************************************
  * SHGetPathFromIDListA        [SHELL32.@][NT 4.0: SHELL32.220]
  *
  * PARAMETERS
@@ -1226,26 +1307,108 @@
  */
 BOOL WINAPI SHGetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath)
 {
-    WCHAR wszPath[MAX_PATH];
-    BOOL bSuccess;
+    HRESULT hr;
 
-    bSuccess = SHGetPathFromIDListW(pidl, wszPath);
-    if (bSuccess) 
-        WideCharToMultiByte(CP_ACP, 0, wszPath, -1, pszPath, MAX_PATH, NULL, NULL);
+    TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath);
+    pdump(pidl);
 
-    return bSuccess;
+    if (!pidl)
+        return FALSE;
+
+    hr = SHELL_GetPathFromIDListA(pidl, pszPath, MAX_PATH);
+
+    return SUCCEEDED(hr);
 }
 
 /*************************************************************************
+ * SHELL_GetPathFromIDListW
+ */
+HRESULT SHELL_GetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSize)
+{
+    HRESULT hr = S_OK;
+    UINT len;
+
+    pszPath[0]=0;
+
+    /* One case is a PIDL rooted at desktop level */
+    if (_ILIsDesktop(pidl) ||_ILIsValue(pidl) || _ILIsFolder(pidl))
+    {
+        hr = SHGetSpecialFolderPathW(0, pszPath, CSIDL_DESKTOP, FALSE);
+
+        if (SUCCEEDED(hr))
+            PathAddBackslashW(pszPath);
+    }
+    /* The only other valid case is an item ID list beginning at "My Computer" */
+    else if (_ILIsMyComputer(pidl))
+        pidl = ILGetNext(pidl);
+
+    if (SUCCEEDED(hr))
+    {
+        LPSTR txt;
+
+        while(pidl && pidl->mkid.cb)
+        {
+            if (_ILIsSpecialFolder(pidl))
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+
+            txt = _ILGetTextPointer(pidl);
+            if (!txt)
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+
+            if (lstrlenA(txt) > pidl->mkid.cb)
+                ERR("pidl %p is borked\n",pidl);
+            len = MultiByteToWideChar(CP_ACP, 0, txt, -1, NULL, 0);
+            if ( (lstrlenW(pszPath) + len) > uOutSize )
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+
+            MultiByteToWideChar(CP_ACP, 0, txt, -1,
+                                &pszPath[lstrlenW(pszPath)], len);
+
+            pidl = ILGetNext(pidl);
+            if (!pidl)
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+
+            /* Are we at the end and successfully converted the complete PIDL? */
+            if (!pidl->mkid.cb)
+                break;
+
+            if ((lstrlenW(pszPath) + 1) > uOutSize )
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+            if (!PathAddBackslashW(pszPath))
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+        }
+    }
+    else
+        hr = E_INVALIDARG;
+
+    TRACE_(shell)("-- %s, 0x%08lx\n", debugstr_w(pszPath), hr);
+    return hr;
+}
+
+/*************************************************************************
  * SHGetPathFromIDListW             [SHELL32.@]
  */
 BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
 {
     HRESULT hr;
-    LPCITEMIDLIST pidlLast;
-    LPSHELLFOLDER psfFolder;
-    DWORD dwAttributes;
-    STRRET strret;
 
     TRACE_(shell)("(pidl=%p,%p)\n", pidl, debugstr_w(pszPath));
     pdump(pidl);
@@ -1253,19 +1416,8 @@
     if (!pidl)
         return FALSE;
 
-    hr = SHBindToParent(pidl, &IID_IShellFolder, (VOID**)&psfFolder, &pidlLast);
-    if (FAILED(hr)) return FALSE;
+    hr = SHELL_GetPathFromIDListW(pidl, pszPath, MAX_PATH);
 
-    dwAttributes = SFGAO_FILESYSTEM;
-    hr = IShellFolder_GetAttributesOf(psfFolder, 1, &pidlLast, &dwAttributes);
-    if (FAILED(hr) || !(dwAttributes & SFGAO_FILESYSTEM)) return FALSE;
-                
-    hr = IShellFolder_GetDisplayNameOf(psfFolder, pidlLast, SHGDN_FORPARSING, &strret);
-    if (FAILED(hr)) return FALSE;
-
-    hr = StrRetToBufW(&strret, pidlLast, pszPath, MAX_PATH);
-    IShellFolder_Release(psfFolder);
-
     TRACE_(shell)("-- %s, 0x%08lx\n",debugstr_w(pszPath), hr);
     return SUCCEEDED(hr);
 }