mirror of
https://github.com/reactos/reactos.git
synced 2025-06-04 00:40:31 +00:00
[SHELL32]
- Make SHELL32_GetDisplayNameOfChild return the result via a STRRET. Fix all callers accordingly. - Avoid any heap allocations if a shell folder needs to forward the GetDisplayNameOf call to a child. svn path=/trunk/; revision=68877
This commit is contained in:
parent
8828db039a
commit
8da2ae9374
5 changed files with 81 additions and 118 deletions
|
@ -660,7 +660,11 @@ HRESULT WINAPI CDesktopFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFl
|
||||||
if (!strRet)
|
if (!strRet)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
if (!_ILIsDesktop(pidl) && _ILIsPidlSimple(pidl) && _ILIsSpecialFolder(pidl))
|
if (!_ILIsPidlSimple (pidl))
|
||||||
|
{
|
||||||
|
return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet);
|
||||||
|
}
|
||||||
|
else if (!_ILIsDesktop(pidl) && ILIsSpecialFolder(pidl))
|
||||||
{
|
{
|
||||||
return SHELL32_GetDisplayNameOfGUIDItem(this, L"", pidl, dwFlags, strRet);
|
return SHELL32_GetDisplayNameOfGUIDItem(this, L"", pidl, dwFlags, strRet);
|
||||||
}
|
}
|
||||||
|
@ -677,7 +681,7 @@ HRESULT WINAPI CDesktopFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFl
|
||||||
else
|
else
|
||||||
HCR_GetClassNameW(CLSID_ShellDesktop, pszPath, MAX_PATH);
|
HCR_GetClassNameW(CLSID_ShellDesktop, pszPath, MAX_PATH);
|
||||||
}
|
}
|
||||||
else if (_ILIsPidlSimple (pidl))
|
else
|
||||||
{
|
{
|
||||||
int cLen = 0;
|
int cLen = 0;
|
||||||
|
|
||||||
|
@ -710,12 +714,6 @@ HRESULT WINAPI CDesktopFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFl
|
||||||
SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
|
SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* a complex pidl, let the subfolder do the work */
|
|
||||||
hr = SHELL32_GetDisplayNameOfChild (this, pidl, dwFlags,
|
|
||||||
pszPath, MAX_PATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
|
|
@ -483,6 +483,11 @@ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFla
|
||||||
if (!strRet)
|
if (!strRet)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (!_ILIsPidlSimple (pidl))
|
||||||
|
{
|
||||||
|
return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet);
|
||||||
|
}
|
||||||
|
|
||||||
pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
|
pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
|
||||||
if (!pszPath)
|
if (!pszPath)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
@ -496,7 +501,7 @@ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFla
|
||||||
pszPath[1] = ':';
|
pszPath[1] = ':';
|
||||||
SHELL32_GUIDToStringW(CLSID_MyComputer, &pszPath[2]);
|
SHELL32_GUIDToStringW(CLSID_MyComputer, &pszPath[2]);
|
||||||
}
|
}
|
||||||
else if (_ILIsPidlSimple(pidl))
|
else
|
||||||
{
|
{
|
||||||
if (_ILIsSpecialFolder(pidl))
|
if (_ILIsSpecialFolder(pidl))
|
||||||
return SHELL32_GetDisplayNameOfGUIDItem(this, L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", pidl, dwFlags, strRet);
|
return SHELL32_GetDisplayNameOfGUIDItem(this, L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", pidl, dwFlags, strRet);
|
||||||
|
@ -557,11 +562,6 @@ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFla
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Complex pidl. Let the child folder do the work */
|
|
||||||
hr = SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, pszPath, MAX_PATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
|
|
@ -591,67 +591,47 @@ void SHELL_FS_ProcessDisplayFilename(LPWSTR szPath, DWORD dwFlags)
|
||||||
HRESULT WINAPI CFSFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl,
|
HRESULT WINAPI CFSFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl,
|
||||||
DWORD dwFlags, LPSTRRET strRet)
|
DWORD dwFlags, LPSTRRET strRet)
|
||||||
{
|
{
|
||||||
LPWSTR pszPath;
|
|
||||||
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
int len = 0;
|
|
||||||
|
|
||||||
TRACE("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet);
|
|
||||||
pdump(pidl);
|
|
||||||
|
|
||||||
if (!pidl || !strRet)
|
if (!pidl || !strRet)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
|
/* If it is a complex pidl, let the child handle it */
|
||||||
|
if (!_ILIsPidlSimple (pidl)) /* complex pidl */
|
||||||
|
{
|
||||||
|
return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet);
|
||||||
|
}
|
||||||
|
else if (!pidl->mkid.cb) /* empty pidl */
|
||||||
|
{
|
||||||
|
/* If it is an empty pidl return only the path of the folder */
|
||||||
|
if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) &&
|
||||||
|
(GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER) &&
|
||||||
|
sPathTarget)
|
||||||
|
{
|
||||||
|
return SHSetStrRet(strRet, sPathTarget);
|
||||||
|
}
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = 0;
|
||||||
|
LPWSTR pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
|
||||||
if (!pszPath)
|
if (!pszPath)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if (_ILIsDesktop(pidl)) /* empty pidl */
|
if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) &&
|
||||||
|
(GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER) &&
|
||||||
|
sPathTarget)
|
||||||
{
|
{
|
||||||
if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) &&
|
lstrcpynW(pszPath, sPathTarget, MAX_PATH);
|
||||||
(GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER))
|
PathAddBackslashW(pszPath);
|
||||||
{
|
len = wcslen(pszPath);
|
||||||
if (sPathTarget)
|
|
||||||
lstrcpynW(pszPath, sPathTarget, MAX_PATH);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
hr = E_INVALIDARG; /* pidl has to contain exactly one non null SHITEMID */
|
|
||||||
}
|
}
|
||||||
else if (_ILIsPidlSimple(pidl))
|
_ILSimpleGetTextW(pidl, pszPath + len, MAX_PATH + 1 - len);
|
||||||
{
|
if (!_ILIsFolder(pidl)) SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
|
||||||
if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) &&
|
|
||||||
(GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER) &&
|
|
||||||
sPathTarget)
|
|
||||||
{
|
|
||||||
lstrcpynW(pszPath, sPathTarget, MAX_PATH);
|
|
||||||
PathAddBackslashW(pszPath);
|
|
||||||
len = wcslen(pszPath);
|
|
||||||
}
|
|
||||||
_ILSimpleGetTextW(pidl, pszPath + len, MAX_PATH + 1 - len);
|
|
||||||
if (!_ILIsFolder(pidl)) SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
|
|
||||||
} else
|
|
||||||
hr = SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, pszPath, MAX_PATH);
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr)) {
|
strRet->uType = STRRET_WSTR;
|
||||||
/* Win9x always returns ANSI strings, NT always returns Unicode strings */
|
strRet->pOleStr = pszPath;
|
||||||
if (GetVersion() & 0x80000000)
|
|
||||||
{
|
|
||||||
strRet->uType = STRRET_CSTR;
|
|
||||||
if (!WideCharToMultiByte(CP_ACP, 0, pszPath, -1, strRet->cStr, MAX_PATH,
|
|
||||||
NULL, NULL))
|
|
||||||
strRet->cStr[0] = '\0';
|
|
||||||
CoTaskMemFree(pszPath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strRet->uType = STRRET_WSTR;
|
|
||||||
strRet->pOleStr = pszPath;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
CoTaskMemFree(pszPath);
|
|
||||||
|
|
||||||
TRACE ("-- (%p)->(%s)\n", this, strRet->uType == STRRET_CSTR ? strRet->cStr : debugstr_w(strRet->pOleStr));
|
TRACE ("-- (%p)->(%s)\n", this, strRet->uType == STRRET_CSTR ? strRet->cStr : debugstr_w(strRet->pOleStr));
|
||||||
return hr;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
|
|
@ -39,8 +39,7 @@ typedef struct {
|
||||||
LPCWSTR GetNextElementW (LPCWSTR pszNext, LPWSTR pszOut, DWORD dwOut);
|
LPCWSTR GetNextElementW (LPCWSTR pszNext, LPWSTR pszOut, DWORD dwOut);
|
||||||
HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc, LPITEMIDLIST * pidlInOut,
|
HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc, LPITEMIDLIST * pidlInOut,
|
||||||
LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes);
|
LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes);
|
||||||
HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf, LPCITEMIDLIST pidl, DWORD dwFlags, LPWSTR szOut,
|
HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf, LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet);
|
||||||
DWORD dwOutLen);
|
|
||||||
|
|
||||||
HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
|
HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
|
||||||
LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut);
|
LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut);
|
||||||
|
|
|
@ -335,54 +335,34 @@ HRESULT SHELL32_BindToGuidItem(LPCITEMIDLIST pidlRoot,
|
||||||
* virtual folders with the registry key WantsFORPARSING set.
|
* virtual folders with the registry key WantsFORPARSING set.
|
||||||
*/
|
*/
|
||||||
HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf,
|
HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf,
|
||||||
LPCITEMIDLIST pidl, DWORD dwFlags, LPWSTR szOut, DWORD dwOutLen)
|
LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
|
||||||
{
|
{
|
||||||
LPITEMIDLIST pidlFirst;
|
LPITEMIDLIST pidlFirst = ILCloneFirst(pidl);
|
||||||
HRESULT hr = E_INVALIDARG;
|
if (!pidlFirst)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
TRACE ("(%p)->(pidl=%p 0x%08x %p 0x%08x)\n", psf, pidl, dwFlags, szOut, dwOutLen);
|
CComPtr<IShellFolder> psfChild;
|
||||||
pdump (pidl);
|
HRESULT hr = psf->BindToObject(pidlFirst, NULL, IID_PPV_ARG(IShellFolder, &psfChild));
|
||||||
|
if (SUCCEEDED (hr))
|
||||||
pidlFirst = ILCloneFirst(pidl);
|
|
||||||
if (pidlFirst)
|
|
||||||
{
|
{
|
||||||
CComPtr<IShellFolder> psfChild;
|
hr = psfChild->GetDisplayNameOf(ILGetNext (pidl), dwFlags, strRet);
|
||||||
|
}
|
||||||
hr = psf->BindToObject(pidlFirst, NULL, IID_PPV_ARG(IShellFolder, &psfChild));
|
ILFree (pidlFirst);
|
||||||
if (SUCCEEDED (hr))
|
|
||||||
{
|
|
||||||
STRRET strTemp;
|
|
||||||
LPITEMIDLIST pidlNext = ILGetNext (pidl);
|
|
||||||
|
|
||||||
hr = psfChild->GetDisplayNameOf(pidlNext, dwFlags, &strTemp);
|
|
||||||
if (SUCCEEDED (hr))
|
|
||||||
{
|
|
||||||
if(!StrRetToStrNW (szOut, dwOutLen, &strTemp, pidlNext))
|
|
||||||
hr = E_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ILFree (pidlFirst);
|
|
||||||
} else
|
|
||||||
hr = E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
TRACE ("-- ret=0x%08x %s\n", hr, debugstr_w(szOut));
|
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT SHELL32_GetDisplayNameOfGUIDItem(IShellFolder2* psf, LPCWSTR pszFolderPath, PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
|
HRESULT SHELL32_GetDisplayNameOfGUIDItem(IShellFolder2* psf, LPCWSTR pszFolderPath, PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr;
|
||||||
GUID const *clsid = _ILGetGUIDPointer (pidl);
|
GUID const *clsid = _ILGetGUIDPointer (pidl);
|
||||||
|
|
||||||
if (!strRet)
|
if (!strRet)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
LPWSTR pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
|
/* First of all check if we need to query the name from the child item */
|
||||||
if (!pszPath)
|
if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING &&
|
||||||
return E_OUTOFMEMORY;
|
GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL)
|
||||||
|
|
||||||
if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING)
|
|
||||||
{
|
{
|
||||||
int bWantsForParsing;
|
int bWantsForParsing;
|
||||||
|
|
||||||
|
@ -408,32 +388,38 @@ HRESULT SHELL32_GetDisplayNameOfGUIDItem(IShellFolder2* psf, LPCWSTR pszFolderPa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
|
if (bWantsForParsing)
|
||||||
bWantsForParsing)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* we need the filesystem path to the destination folder.
|
* we need the filesystem path to the destination folder.
|
||||||
* Only the folder itself can know it
|
* Only the folder itself can know it
|
||||||
*/
|
*/
|
||||||
hr = SHELL32_GetDisplayNameOfChild (psf, pidl, dwFlags,
|
return SHELL32_GetDisplayNameOfChild (psf, pidl, dwFlags, strRet);
|
||||||
pszPath,
|
|
||||||
MAX_PATH);
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
wcscpy(pszPath, pszFolderPath);
|
|
||||||
PWCHAR pItemName = &pszPath[wcslen(pszPath)];
|
|
||||||
|
|
||||||
/* parsing name like ::{...} */
|
/* Allocate the buffer for the result */
|
||||||
pItemName[0] = ':';
|
LPWSTR pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
|
||||||
pItemName[1] = ':';
|
if (!pszPath)
|
||||||
SHELL32_GUIDToStringW (*clsid, &pItemName[2]);
|
return E_OUTOFMEMORY;
|
||||||
}
|
|
||||||
|
hr = S_OK;
|
||||||
|
|
||||||
|
if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING)
|
||||||
|
{
|
||||||
|
wcscpy(pszPath, pszFolderPath);
|
||||||
|
PWCHAR pItemName = &pszPath[wcslen(pszPath)];
|
||||||
|
|
||||||
|
/* parsing name like ::{...} */
|
||||||
|
pItemName[0] = ':';
|
||||||
|
pItemName[1] = ':';
|
||||||
|
SHELL32_GUIDToStringW (*clsid, &pItemName[2]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* user friendly name */
|
/* user friendly name */
|
||||||
HCR_GetClassNameW (*clsid, pszPath, MAX_PATH);
|
if (!HCR_GetClassNameW (*clsid, pszPath, MAX_PATH))
|
||||||
|
hr = E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
|
|
Loading…
Reference in a new issue