From 114975d9379ba76755ce1e7b53343eb34a9d5afc Mon Sep 17 00:00:00 2001 From: Michael Jung Date: Sat, 25 Jun 2005 18:32:17 +0000 Subject: [PATCH] Fix a lurking infinite loop in SHGetPathFromIDList. --- dlls/shell32/shlfolder.c | 68 +++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/dlls/shell32/shlfolder.c b/dlls/shell32/shlfolder.c index 928e0495925..6992d7e2cac 100644 --- a/dlls/shell32/shlfolder.c +++ b/dlls/shell32/shlfolder.c @@ -70,14 +70,26 @@ static const WCHAR wszDotShellClassInfo[] = { * TRUE if returned non-NULL value. * FALSE otherwise. */ -BOOL SHELL32_GetCustomFolderAttribute( - LPCITEMIDLIST pidl, LPCWSTR pwszHeading, LPCWSTR pwszAttribute, +static inline BOOL SHELL32_GetCustomFolderAttributeFromPath( + LPWSTR pwszFolderPath, LPCWSTR pwszHeading, LPCWSTR pwszAttribute, LPWSTR pwszValue, DWORD cchValue) { static const WCHAR wszDesktopIni[] = {'d','e','s','k','t','o','p','.','i','n','i',0}; static const WCHAR wszDefault[] = {0}; + + PathAddBackslashW(pwszFolderPath); + PathAppendW(pwszFolderPath, wszDesktopIni); + return GetPrivateProfileStringW(pwszHeading, pwszAttribute, wszDefault, + pwszValue, cchValue, pwszFolderPath); +} + +BOOL SHELL32_GetCustomFolderAttribute( + LPCITEMIDLIST pidl, LPCWSTR pwszHeading, LPCWSTR pwszAttribute, + LPWSTR pwszValue, DWORD cchValue) +{ DWORD dwAttrib = FILE_ATTRIBUTE_SYSTEM; + WCHAR wszFolderPath[MAX_PATH]; /* Hack around not having system attribute on non-Windows file systems */ if (0) @@ -85,20 +97,15 @@ BOOL SHELL32_GetCustomFolderAttribute( if (dwAttrib & FILE_ATTRIBUTE_SYSTEM) { - DWORD ret; - WCHAR wszDesktopIniPath[MAX_PATH]; - - if (!SHGetPathFromIDListW(pidl, wszDesktopIniPath)) + if (!SHGetPathFromIDListW(pidl, wszFolderPath)) return FALSE; - PathAppendW(wszDesktopIniPath, wszDesktopIni); - ret = GetPrivateProfileStringW(pwszHeading, pwszAttribute, - wszDefault, pwszValue, cchValue, wszDesktopIniPath); - return ret; + + return SHELL32_GetCustomFolderAttributeFromPath(wszFolderPath, pwszHeading, + pwszAttribute, pwszValue, cchValue); } return FALSE; } - /*************************************************************************** * GetNextElement (internal function) * @@ -256,7 +263,7 @@ HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCSTR pathRoot, * means you probably can't use it for your IShellFolder implementation. */ HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot, - LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut) + LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut) { GUID const *clsid; IShellFolder *pSF; @@ -264,40 +271,45 @@ HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot, LPITEMIDLIST pidlChild; if (!pidlRoot || !ppvOut || !pidlComplete || !pidlComplete->mkid.cb) - return E_INVALIDARG; + return E_INVALIDARG; *ppvOut = NULL; pidlChild = ILCloneFirst (pidlComplete); if ((clsid = _ILGetGUIDPointer (pidlChild))) { - /* virtual folder */ - hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, clsid, &IID_IShellFolder, (LPVOID *) & pSF); + /* virtual folder */ + hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, clsid, &IID_IShellFolder, (LPVOID *) & pSF); } else { /* file system folder */ CLSID clsidFolder = CLSID_ShellFSFolder; static const WCHAR wszCLSID[] = {'C','L','S','I','D',0}; - WCHAR wszCLSIDValue[CHARS_IN_GUID]; - LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild); + WCHAR wszCLSIDValue[CHARS_IN_GUID], wszFolderPath[MAX_PATH], *pwszPathTail = wszFolderPath; + /* see if folder CLSID should be overridden by desktop.ini file */ - if (SHELL32_GetCustomFolderAttribute (pidlAbsolute, + if (pathRoot) { + MultiByteToWideChar(CP_ACP, 0, pathRoot, -1, wszFolderPath, MAX_PATH); + pwszPathTail = PathAddBackslashW(wszFolderPath); + } + MultiByteToWideChar(CP_ACP, 0, _ILGetTextPointer(pidlChild), -1, pwszPathTail, MAX_PATH); + if (SHELL32_GetCustomFolderAttributeFromPath (wszFolderPath, wszDotShellClassInfo, wszCLSID, wszCLSIDValue, CHARS_IN_GUID)) CLSIDFromString (wszCLSIDValue, &clsidFolder); - ILFree (pidlAbsolute); - hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, + + hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, &clsidFolder, &IID_IShellFolder, (LPVOID *)&pSF); } ILFree (pidlChild); if (SUCCEEDED (hr)) { - if (_ILIsPidlSimple (pidlComplete)) { - /* no sub folders */ - hr = IShellFolder_QueryInterface (pSF, riid, ppvOut); - } else { - /* go deeper */ - hr = IShellFolder_BindToObject (pSF, ILGetNext (pidlComplete), NULL, riid, ppvOut); - } - IShellFolder_Release (pSF); + if (_ILIsPidlSimple (pidlComplete)) { + /* no sub folders */ + hr = IShellFolder_QueryInterface (pSF, riid, ppvOut); + } else { + /* go deeper */ + hr = IShellFolder_BindToObject (pSF, ILGetNext (pidlComplete), NULL, riid, ppvOut); + } + IShellFolder_Release (pSF); } TRACE ("-- returning (%p) %08lx\n", *ppvOut, hr);