Commit aa43d016 authored by Alexandre Julliard's avatar Alexandre Julliard

Authors: Martin Fuchs <martin-fuchs@gmx.net>, Ge van Geldorp <ge@gse.nl>

Reimplementation of SHGetPathFromIDListA/W() using the new helper functions SHELL_GetPathFromIDListA/W(). The new implementation avoids using IShellFolder::GetDisplayNameOf(), so that it - returns the absolute file system path, not relative to the dekstop - returns FALSE as error code if the path can not converted in a valid file system path - doesn't return virtual CLSID paths
parent ff466b17
......@@ -1275,6 +1275,59 @@ HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int n
}
/*************************************************************************
* SHELL_GetPathFromIDListA
*/
HRESULT SHELL_GetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath, UINT uOutSize)
{
LPSTR pstr = pszPath;
LPSTR end = pszPath + uOutSize;
HRESULT hr = S_OK;
/* One case is a PIDL rooted at desktop level */
if (_ILIsValue(pidl) || _ILIsFolder(pidl)) {
hr = SHGetSpecialFolderPathA(0, pstr, CSIDL_DESKTOP, FALSE);
if (SUCCEEDED(hr))
pstr = PathAddBackslashA(pstr);
}
/* The only other valid case is a item ID list beginning at "My Computer" */
else if (_ILIsMyComputer(pidl))
pidl = ILGetNext(pidl);
if (SUCCEEDED(hr)) {
LPSTR txt;
while(pidl && pidl->mkid.cb && pstr<end) {
if (_ILIsSpecialFolder(pidl))
{hr = E_INVALIDARG; break;}
txt = _ILGetTextPointer(pidl);
if (!txt)
{hr = E_INVALIDARG; break;}
lstrcpynA(pstr, txt, end-pstr);
pidl = ILGetNext(pidl);
if (!pidl)
{hr = E_INVALIDARG; break;}
if (!pidl->mkid.cb) {
/* We are at the end and successfully converted the complete PIDL. */
break;
}
pstr = PathAddBackslashA(pstr);
if (!pstr)
{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
......@@ -1292,61 +1345,86 @@ HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int n
BOOL WINAPI SHGetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath)
{
HRESULT hr;
STRRET str;
LPSHELLFOLDER shellfolder;
TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath);
pdump(pidl);
if (!pidl)
return FALSE;
return FALSE;
hr = SHGetDesktopFolder(&shellfolder);
if (SUCCEEDED (hr)) {
hr = IShellFolder_GetDisplayNameOf(shellfolder, pidl, SHGDN_FORPARSING, &str);
if(SUCCEEDED(hr)) {
StrRetToStrNA (pszPath, MAX_PATH, &str, pidl);
}
IShellFolder_Release(shellfolder);
}
hr = SHELL_GetPathFromIDListA(pidl, pszPath, MAX_PATH);
return SUCCEEDED(hr);
}
/* don't allow to return displaynames of the form "::{guid}" */
if (pszPath[0]==':' && pszPath[1]==':') {
*pszPath = '\0';
return FALSE;
/*************************************************************************
* SHELL_GetPathFromIDListW
*/
HRESULT SHELL_GetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSize)
{
LPWSTR pstr = pszPath;
LPWSTR end = pszPath + uOutSize;
HRESULT hr = S_OK;
/* One case is a PIDL rooted at desktop level */
if (_ILIsValue(pidl) || _ILIsFolder(pidl)) {
hr = SHGetSpecialFolderPathW(0, pstr, CSIDL_DESKTOP, FALSE);
if (SUCCEEDED(hr))
pstr = PathAddBackslashW(pstr);
}
/* The only other valid case is a item ID list beginning at "My Computer" */
else if (_ILIsMyComputer(pidl))
pidl = ILGetNext(pidl);
TRACE_(shell)("-- %s, 0x%08lx\n",pszPath, hr);
return SUCCEEDED(hr);
if (SUCCEEDED(hr)) {
LPSTR txt;
while(pidl && pidl->mkid.cb && pstr<end) {
if (_ILIsSpecialFolder(pidl))
{hr = E_INVALIDARG; break;}
txt = _ILGetTextPointer(pidl);
if (!txt)
{hr = E_INVALIDARG; break;}
if (!MultiByteToWideChar(CP_ACP, 0, txt, -1, pstr, uOutSize))
{hr = E_OUTOFMEMORY; break;}
pidl = ILGetNext(pidl);
if (!pidl)
{hr = E_INVALIDARG; break;}
if (!pidl->mkid.cb) {
/* We are at the end and successfully converted the complete PIDL. */
break;
}
pstr = PathAddBackslashW(pstr);
if (!pstr)
{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;
STRRET str;
LPSHELLFOLDER shellfolder;
TRACE_(shell)("(pidl=%p,%p)\n", pidl, debugstr_w(pszPath));
pdump(pidl);
if (!pidl) return FALSE;
hr = SHGetDesktopFolder(&shellfolder);
if (SUCCEEDED(hr)) {
hr = IShellFolder_GetDisplayNameOf(shellfolder, pidl, SHGDN_FORPARSING, &str);
if (SUCCEEDED(hr)) {
StrRetToStrNW(pszPath, MAX_PATH, &str, pidl);
}
IShellFolder_Release(shellfolder);
}
if (!pidl)
return FALSE;
/* don't allow to return displaynames of the form "::{guid}" */
if (pszPath[0]==':' && pszPath[1]==':') {
*pszPath = '\0';
return FALSE;
}
hr = SHELL_GetPathFromIDListW(pidl, pszPath, MAX_PATH);
TRACE_(shell)("-- %s, 0x%08lx\n",debugstr_w(pszPath), hr);
return SUCCEEDED(hr);
......
......@@ -210,4 +210,7 @@ LPITEMIDLIST * _ILCopyCidaToaPidl(LPITEMIDLIST* pidl, LPIDA cida);
BOOL WINAPI ILGetDisplayNameExA(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPSTR path, DWORD type);
BOOL WINAPI ILGetDisplayNameExW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPWSTR path, DWORD type);
HRESULT SHELL_GetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath, UINT uOutSize);
HRESULT SHELL_GetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSize);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment