Fix a lurking infinite loop in SHGetPathFromIDList.
This commit is contained in:
parent
41a9757654
commit
114975d937
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue