From 67b553671695c232e4a0ac435b56be3dda0aa6fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Thu, 11 Aug 2005 21:09:56 +0000 Subject: [PATCH] Revert last Wine sync to pidl.c, since it breaks SHGetPathFromIDListW. Fixes bug 697 svn path=/trunk/; revision=17316 --- reactos/lib/shell32/pidl.c | 196 ++++++++++++++++++++++++++++++++----- 1 file changed, 174 insertions(+), 22 deletions(-) diff --git a/reactos/lib/shell32/pidl.c b/reactos/lib/shell32/pidl.c index 97632bcc189..1d582ba3220 100644 --- a/reactos/lib/shell32/pidl.c +++ b/reactos/lib/shell32/pidl.c @@ -1209,6 +1209,87 @@ HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, return E_INVALIDARG; } +/************************************************************************* + * 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] * @@ -1226,14 +1307,100 @@ HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, */ 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; } /************************************************************************* @@ -1242,10 +1409,6 @@ BOOL WINAPI SHGetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath) 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,18 +1416,7 @@ BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath) if (!pidl) return FALSE; - hr = SHBindToParent(pidl, &IID_IShellFolder, (VOID**)&psfFolder, &pidlLast); - if (FAILED(hr)) return FALSE; - - 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); + hr = SHELL_GetPathFromIDListW(pidl, pszPath, MAX_PATH); TRACE_(shell)("-- %s, 0x%08lx\n",debugstr_w(pszPath), hr); return SUCCEEDED(hr);