[SHELL32] Don't free original PIDLs in CDefView::OnChangeNotify (#6916)

Follow-up to #6898. These PIDLs shouldn't be
freed because they are not allocated by
CoTaskMemAlloc.
We should use PIDLs mainly in internal data
instead of physical paths for change
notifications.

JIRA issue: CORE-13950
JIRA issue: CORE-19612

- Re-implement SHGetRealIDL function.
- Translate child IDLs by using SHGetRealIDL.
- Use newly-defined pidl0Temp and pidl1Temp
  for temporary creation.
- Improve ILIsParentOrSpecialParent function
  without using SHGetPathFromIDListW function.
This commit is contained in:
Katayama Hirofumi MZ 2024-05-25 07:54:53 +09:00 committed by GitHub
parent eb43a803bd
commit 327b6c64a6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 78 additions and 29 deletions

View file

@ -2,13 +2,27 @@
* PROJECT: shell32
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
* PURPOSE: Utility functions
* COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
* COPYRIGHT: Copyright 2023-2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
*/
#include "precomp.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
HRESULT
SHILClone(
_In_opt_ LPCITEMIDLIST pidl,
_Outptr_ LPITEMIDLIST *ppidl)
{
if (!pidl)
{
*ppidl = NULL;
return S_OK;
}
*ppidl = ILClone(pidl);
return (*ppidl ? S_OK : E_OUTOFMEMORY);
}
BOOL PathIsDotOrDotDotW(_In_ LPCWSTR pszPath)
{
if (pszPath[0] != L'.')
@ -1242,3 +1256,41 @@ PathIsEqualOrSubFolder(
return strPath1.CompareNoCase(strCommon) == 0;
}
/*************************************************************************
* SHGetRealIDL [SHELL32.98]
*/
EXTERN_C
HRESULT WINAPI
SHGetRealIDL(
_In_ IShellFolder *psf,
_In_ PCUITEMID_CHILD pidlSimple,
_Outptr_ PITEMID_CHILD *ppidlReal)
{
HRESULT hr;
STRRET strret;
WCHAR szPath[MAX_PATH];
SFGAOF attrs;
*ppidlReal = NULL;
hr = IShellFolder_GetDisplayNameOf(psf, pidlSimple, SHGDN_INFOLDER | SHGDN_FORPARSING,
&strret, 0);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = StrRetToBufW(&strret, pidlSimple, szPath, _countof(szPath));
if (FAILED_UNEXPECTEDLY(hr))
return hr;
attrs = SFGAO_FILESYSTEM;
hr = psf->GetAttributesOf(1, &pidlSimple, &attrs);
if (SUCCEEDED(hr) && !(attrs & SFGAO_FILESYSTEM))
return SHILClone(pidlSimple, ppidlReal);
hr = IShellFolder_ParseDisplayName(psf, NULL, NULL, szPath, NULL, ppidlReal, NULL);
if (hr == E_INVALIDARG || hr == E_NOTIMPL)
return SHILClone(pidlSimple, ppidlReal);
return hr;
}