--- 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);
}