[BROWSEUI] auto-completion: Reduce failures in ACListISF (#3589)

Reduce failures in ACListISF testcase. Skip left space in auto-completion. Accept the pair of drive letter and colon. CORE-9281
This commit is contained in:
Katayama Hirofumi MZ 2021-04-06 21:56:40 +09:00 committed by GitHub
parent a105b5d355
commit 2eaf0afcd2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 69 deletions

View file

@ -174,7 +174,9 @@ HRESULT CACListISF::GetDisplayName(LPCITEMIDLIST pidlChild, CComHeapPtr<WCHAR>&
return hr; return hr;
} }
HRESULT CACListISF::GetPathName(LPCITEMIDLIST pidlChild, CComHeapPtr<WCHAR>& pszPath) HRESULT
CACListISF::GetPaths(LPCITEMIDLIST pidlChild, CComHeapPtr<WCHAR>& pszRaw,
CComHeapPtr<WCHAR>& pszExpanded)
{ {
TRACE("(%p, %p)\n", this, pidlChild); TRACE("(%p, %p)\n", this, pidlChild);
@ -183,29 +185,24 @@ HRESULT CACListISF::GetPathName(LPCITEMIDLIST pidlChild, CComHeapPtr<WCHAR>& psz
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
CStringW szPath; CStringW szRawPath, szExpanded;
if (m_szExpand.GetLength() && m_iNextLocation == LT_DIRECTORY) if (m_szRawPath.GetLength() && m_iNextLocation == LT_DIRECTORY)
{ {
INT cchExpand = m_szExpand.GetLength(); INT cchExpand = m_szRawPath.GetLength();
if (StrCmpNIW(pszChild, m_szExpand, cchExpand) != 0 || if (StrCmpNIW(pszChild, m_szRawPath, cchExpand) != 0 ||
pszChild[0] != L'\\' || pszChild[1] != L'\\') pszChild[0] != L'\\' || pszChild[1] != L'\\')
{ {
szPath = m_szExpand; szRawPath = m_szRawPath;
szExpanded = m_szExpanded;
} }
} }
szPath += pszChild; szRawPath += pszChild;
szExpanded += pszChild;
INT cchMax = szPath.GetLength() + 1; SHStrDupW(szRawPath, &pszRaw);
CComHeapPtr<WCHAR> pszFullPath; SHStrDupW(szExpanded, &pszExpanded);
if (!pszFullPath.Allocate(cchMax)) TRACE("pszRaw: '%S'\n", static_cast<LPCWSTR>(pszRaw));
{ TRACE("pszExpanded: '%S'\n", static_cast<LPCWSTR>(pszExpanded));
ERR("Out of memory\n");
return E_OUTOFMEMORY;
}
StringCchCopyW(pszFullPath, cchMax, szPath);
pszPath.Attach(pszFullPath.Detach());
TRACE("pszPath: '%S'\n", static_cast<LPCWSTR>(pszPath));
return S_OK; return S_OK;
} }
@ -232,7 +229,7 @@ STDMETHODIMP CACListISF::Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched)
HRESULT hr; HRESULT hr;
CComHeapPtr<ITEMIDLIST> pidlChild; CComHeapPtr<ITEMIDLIST> pidlChild;
CComHeapPtr<WCHAR> pszPathName; CComHeapPtr<WCHAR> pszRawPath, pszExpanded;
do do
{ {
@ -243,38 +240,16 @@ STDMETHODIMP CACListISF::Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched)
if (hr != S_OK) if (hr != S_OK)
break; break;
pszPathName.Free(); pszRawPath.Free();
GetPathName(pidlChild, pszPathName); pszExpanded.Free();
if (!pszPathName) GetPaths(pidlChild, pszRawPath, pszExpanded);
if (!pszRawPath || !pszExpanded)
continue; continue;
if (m_dwOptions & (ACLO_FILESYSONLY | ACLO_FILESYSDIRS)) if ((m_dwOptions & ACLO_FILESYSDIRS) && !PathIsDirectoryW(pszExpanded))
{
DWORD attrs = SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM;
LPCITEMIDLIST pidlRef = pidlChild;
hr = m_pShellFolder->GetAttributesOf(1, &pidlRef, &attrs);
if (SUCCEEDED(hr))
{
if (!(attrs & (SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR)))
continue; continue;
} else if ((m_dwOptions & ACLO_FILESYSONLY) && !PathFileExistsW(pszExpanded))
}
if (m_dwOptions & ACLO_FILESYSDIRS)
{
if (wcschr(pszPathName, L'%') != NULL)
{
WCHAR szPath[MAX_PATH];
ExpandEnvironmentStringsW(pszPathName, szPath, _countof(szPath));
if (!PathIsDirectoryW(szPath))
continue; continue;
}
else
{
if (!PathIsDirectoryW(pszPathName))
continue;
}
}
hr = S_OK; hr = S_OK;
break; break;
@ -283,7 +258,7 @@ STDMETHODIMP CACListISF::Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched)
if (hr == S_OK) if (hr == S_OK)
{ {
*rgelt = pszPathName.Detach(); *rgelt = pszRawPath.Detach();
if (pceltFetched) if (pceltFetched)
*pceltFetched = 1; *pceltFetched = 1;
} }
@ -301,7 +276,7 @@ STDMETHODIMP CACListISF::Reset()
TRACE("(%p)\n", this); TRACE("(%p)\n", this);
m_iNextLocation = LT_DIRECTORY; m_iNextLocation = LT_DIRECTORY;
m_szExpand = L""; m_szRawPath = L"";
SHELLSTATE ss = { 0 }; SHELLSTATE ss = { 0 };
SHGetSetSettings(&ss, SSF_SHOWALLOBJECTS, FALSE); SHGetSetSettings(&ss, SSF_SHOWALLOBJECTS, FALSE);
@ -341,19 +316,27 @@ STDMETHODIMP CACListISF::Expand(LPCOLESTR pszExpand)
{ {
TRACE("(%p, %ls)\n", this, pszExpand); TRACE("(%p, %ls)\n", this, pszExpand);
m_szExpand = pszExpand; m_szRawPath = pszExpand;
m_iNextLocation = LT_DIRECTORY; m_iNextLocation = LT_DIRECTORY;
// skip left space
while (*pszExpand == L' ')
++pszExpand;
// expand environment variables (%WINDIR% etc.) // expand environment variables (%WINDIR% etc.)
WCHAR szExpanded[MAX_PATH]; WCHAR szExpanded[MAX_PATH], szPath1[MAX_PATH], szPath2[MAX_PATH];
if (wcschr(pszExpand, L'%') != NULL && ExpandEnvironmentStringsW(pszExpand, szExpanded, _countof(szExpanded));
ExpandEnvironmentStringsW(pszExpand, szExpanded, _countof(szExpanded)))
{
pszExpand = szExpanded; pszExpand = szExpanded;
}
// get full path // get full path
WCHAR szPath1[MAX_PATH], szPath2[MAX_PATH]; if (szExpanded[0] && szExpanded[1] == L':' && szExpanded[2] == 0)
{
// 'C:' --> 'C:\'
szExpanded[2] = L'\\';
szExpanded[3] = 0;
}
else
{
if (PathIsRelativeW(pszExpand) && if (PathIsRelativeW(pszExpand) &&
SHGetPathFromIDListW(m_pidlCurDir, szPath1) && SHGetPathFromIDListW(m_pidlCurDir, szPath1) &&
PathCombineW(szPath2, szPath1, pszExpand)) PathCombineW(szPath2, szPath1, pszExpand))
@ -361,14 +344,20 @@ STDMETHODIMP CACListISF::Expand(LPCOLESTR pszExpand)
pszExpand = szPath2; pszExpand = szPath2;
} }
GetFullPathNameW(pszExpand, _countof(szPath1), szPath1, NULL); GetFullPathNameW(pszExpand, _countof(szPath1), szPath1, NULL);
pszExpand = szPath1;
}
CComHeapPtr<ITEMIDLIST> pidl; CComHeapPtr<ITEMIDLIST> pidl;
HRESULT hr = SHParseDisplayName(szPath1, NULL, &pidl, NULL, NULL); m_szExpanded = pszExpand;
HRESULT hr = SHParseDisplayName(m_szExpanded, NULL, &pidl, NULL, NULL);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = SetLocation(pidl.Detach()); hr = SetLocation(pidl.Detach());
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
m_szExpand = L""; {
m_szRawPath = L"";
m_szExpanded = L"";
}
} }
return hr; return hr;
} }
@ -448,4 +437,3 @@ STDMETHODIMP CACListISF::SetDirectory(LPCWSTR pwzPath)
m_pidlCurDir.Attach(pidl); m_pidlCurDir.Attach(pidl);
return S_OK; return S_OK;
} }

View file

@ -43,7 +43,8 @@ private:
DWORD m_dwOptions; DWORD m_dwOptions;
LOCATION_TYPE m_iNextLocation; LOCATION_TYPE m_iNextLocation;
BOOL m_fShowHidden; BOOL m_fShowHidden;
CStringW m_szExpand; CStringW m_szRawPath;
CStringW m_szExpanded;
CComHeapPtr<ITEMIDLIST> m_pidlLocation; CComHeapPtr<ITEMIDLIST> m_pidlLocation;
CComHeapPtr<ITEMIDLIST> m_pidlCurDir; CComHeapPtr<ITEMIDLIST> m_pidlCurDir;
CComPtr<IEnumIDList> m_pEnumIDList; CComPtr<IEnumIDList> m_pEnumIDList;
@ -57,7 +58,8 @@ public:
HRESULT NextLocation(); HRESULT NextLocation();
HRESULT SetLocation(LPITEMIDLIST pidl); HRESULT SetLocation(LPITEMIDLIST pidl);
HRESULT GetDisplayName(LPCITEMIDLIST pidlChild, CComHeapPtr<WCHAR>& pszChild); HRESULT GetDisplayName(LPCITEMIDLIST pidlChild, CComHeapPtr<WCHAR>& pszChild);
HRESULT GetPathName(LPCITEMIDLIST pidlChild, CComHeapPtr<WCHAR>& pszPath); HRESULT GetPaths(LPCITEMIDLIST pidlChild, CComHeapPtr<WCHAR>& pszRaw,
CComHeapPtr<WCHAR>& pszExpanded);
// *** IEnumString methods *** // *** IEnumString methods ***
STDMETHODIMP Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched) override; STDMETHODIMP Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched) override;