[SHELL32] Fix ParseDisplayName Part 3 (#6746)

Follow-up to #6740. Reduce SHParseDisplayName
failures.
JIRA issue: CORE-19495
- Add CRegFolder::_IsInNameSpace helper method.
- Half-implement CRegFolder::ParseDisplayName
  method.
- Parse class string by using GUIDFromStringW
  function.
- Return CO_E_CLASSSTRING for invalid CLSID
  string.
This commit is contained in:
Katayama Hirofumi MZ 2024-04-15 03:24:09 +09:00 committed by GitHub
parent 8feb078692
commit 63e5885b37
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -313,6 +313,8 @@ class CRegFolder :
CComHeapPtr<ITEMIDLIST> m_pidlRoot; CComHeapPtr<ITEMIDLIST> m_pidlRoot;
HRESULT GetGuidItemAttributes (LPCITEMIDLIST pidl, LPDWORD pdwAttributes); HRESULT GetGuidItemAttributes (LPCITEMIDLIST pidl, LPDWORD pdwAttributes);
BOOL _IsInNameSpace(_In_ LPCITEMIDLIST pidl);
public: public:
CRegFolder(); CRegFolder();
~CRegFolder(); ~CRegFolder();
@ -401,46 +403,76 @@ HRESULT CRegFolder::GetGuidItemAttributes (LPCITEMIDLIST pidl, LPDWORD pdwAttrib
return S_OK; return S_OK;
} }
BOOL CRegFolder::_IsInNameSpace(_In_ LPCITEMIDLIST pidl)
{
CLSID clsid = *_ILGetGUIDPointer(pidl);
if (IsEqualGUID(clsid, CLSID_Printers))
return TRUE;
if (IsEqualGUID(clsid, CLSID_ConnectionFolder))
return TRUE;
FIXME("Check registry\n");
return TRUE;
}
HRESULT WINAPI CRegFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, HRESULT WINAPI CRegFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes) ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes)
{ {
LPITEMIDLIST pidl; if (!ppidl)
if (!lpszDisplayName || !ppidl)
return E_INVALIDARG; return E_INVALIDARG;
*ppidl = 0; *ppidl = NULL;
if (pchEaten) if (!lpszDisplayName)
*pchEaten = 0; return E_INVALIDARG;
UINT cch = wcslen(lpszDisplayName); if (lpszDisplayName[0] != L':' || lpszDisplayName[1] != L':')
if (cch < 39 || lpszDisplayName[0] != L':' || lpszDisplayName[1] != L':') {
return E_FAIL; FIXME("What should we do here?\n");
return E_FAIL;
pidl = _ILCreateGuidFromStrW(lpszDisplayName + 2); }
if (pidl == NULL)
return E_FAIL; LPWSTR pch, pchNextOfComma = NULL;
for (pch = &lpszDisplayName[2]; *pch && *pch != L'\\'; ++pch)
if (cch < 41) {
if (*pch == L',' && !pchNextOfComma)
pchNextOfComma = pch + 1;
}
CLSID clsid;
if (!GUIDFromStringW(&lpszDisplayName[2], &clsid))
return CO_E_CLASSSTRING;
if (pchNextOfComma)
{
FIXME("Delegate folder\n");
return E_FAIL;
}
CComHeapPtr<ITEMIDLIST> pidlTemp(_ILCreateGuid(PT_GUID, clsid));
if (!pidlTemp)
return E_OUTOFMEMORY;
if (!_IsInNameSpace(pidlTemp) && !(BindCtx_GetMode(pbc, 0) & STGM_CREATE))
return E_INVALIDARG;
*ppidl = pidlTemp.Detach();
if (!*pch)
{ {
*ppidl = pidl;
if (pdwAttributes && *pdwAttributes) if (pdwAttributes && *pdwAttributes)
{
GetGuidItemAttributes(*ppidl, pdwAttributes); GetGuidItemAttributes(*ppidl, pdwAttributes);
}
} return S_OK;
else
{
HRESULT hr = SHELL32_ParseNextElement(this, hwndOwner, pbc, &pidl, lpszDisplayName + 41, pchEaten, pdwAttributes);
if (SUCCEEDED(hr))
{
*ppidl = pidl;
}
return hr;
} }
return S_OK; HRESULT hr = SHELL32_ParseNextElement(this, hwndOwner, pbc, ppidl, pch + 1, pchEaten,
pdwAttributes);
if (FAILED(hr))
{
ILFree(*ppidl);
*ppidl = NULL;
}
return hr;
} }
HRESULT WINAPI CRegFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList) HRESULT WINAPI CRegFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)