mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[SHELL32] Fix ParseDisplayName Part 2 (#6740)
Follow-up to #6721. Reduce SHParseDisplayName failures. JIRA issue: CORE-19495 - Re-implement CFSFolder::ParseDisplayName method to validate the names. - Add CFSFolder::_ParseSimple, CFSFolder::_GetFindDataFromName, and CFSFolder::_CreateIDListFromName helper methods. - Add PathIsDotOrDotDotW, PathIsValidElement, PathIsDosDevice, and SHILAppend helper functions. - Delete GetNextElementW and add Shell_NextElement function.
This commit is contained in:
parent
f61e14f554
commit
7fdec96009
6 changed files with 288 additions and 138 deletions
|
@ -4,7 +4,7 @@
|
|||
* PURPOSE: file system folder
|
||||
* COPYRIGHT: Copyright 1997 Marcus Meissner
|
||||
* Copyright 1998, 1999, 2002 Juergen Schmied
|
||||
* Copyright 2019 Katayama Hirofumi MZ
|
||||
* Copyright 2019-2024 Katayama Hirofumi MZ
|
||||
* Copyright 2020 Mark Jansen (mark.jansen@reactos.org)
|
||||
*/
|
||||
|
||||
|
@ -539,46 +539,6 @@ static const shvheader GenericSFHeader[] = {
|
|||
|
||||
#define GENERICSHELLVIEWCOLUMNS 6
|
||||
|
||||
/**************************************************************************
|
||||
* SHELL32_CreatePidlFromBindCtx [internal]
|
||||
*
|
||||
* If the caller bound File System Bind Data, assume it is the
|
||||
* find data for the path.
|
||||
* This allows binding of paths that don't exist.
|
||||
*/
|
||||
LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path)
|
||||
{
|
||||
IFileSystemBindData *fsbd = NULL;
|
||||
LPITEMIDLIST pidl = NULL;
|
||||
IUnknown *param = NULL;
|
||||
WIN32_FIND_DATAW wfd;
|
||||
HRESULT r;
|
||||
|
||||
TRACE("%p %s\n", pbc, debugstr_w(path));
|
||||
|
||||
if (!pbc)
|
||||
return NULL;
|
||||
|
||||
/* see if the caller bound File System Bind Data */
|
||||
r = pbc->GetObjectParam((LPOLESTR)STR_FILE_SYS_BIND_DATA, ¶m);
|
||||
if (FAILED(r))
|
||||
return NULL;
|
||||
|
||||
r = param->QueryInterface(IID_PPV_ARG(IFileSystemBindData,&fsbd));
|
||||
if (SUCCEEDED(r))
|
||||
{
|
||||
r = fsbd->GetFindData(&wfd);
|
||||
if (SUCCEEDED(r))
|
||||
{
|
||||
lstrcpynW(&wfd.cFileName[0], path, MAX_PATH);
|
||||
pidl = _ILCreateFromFindDataW(&wfd);
|
||||
}
|
||||
fsbd->Release();
|
||||
}
|
||||
|
||||
return pidl;
|
||||
}
|
||||
|
||||
static HRESULT SHELL32_GetCLSIDForDirectory(LPCWSTR pwszDir, LPCWSTR KeyName, CLSID* pclsidFolder)
|
||||
{
|
||||
WCHAR wszCLSIDValue[CHARS_IN_GUID];
|
||||
|
@ -705,6 +665,91 @@ HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, LPCITEMIDLIST pidl, LPDW
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CFSFolder::_ParseSimple(
|
||||
_In_ LPOLESTR lpszDisplayName,
|
||||
_Out_ WIN32_FIND_DATAW *pFind,
|
||||
_Out_ LPITEMIDLIST *ppidl)
|
||||
{
|
||||
HRESULT hr;
|
||||
LPWSTR pchNext = lpszDisplayName;
|
||||
|
||||
*ppidl = NULL;
|
||||
|
||||
LPITEMIDLIST pidl;
|
||||
for (hr = S_OK; SUCCEEDED(hr); hr = SHILAppend(pidl, ppidl))
|
||||
{
|
||||
hr = Shell_NextElement(&pchNext, pFind->cFileName, _countof(pFind->cFileName), FALSE);
|
||||
if (hr != S_OK)
|
||||
break;
|
||||
|
||||
if (pchNext)
|
||||
pFind->dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
|
||||
|
||||
pidl = _ILCreateFromFindDataW(pFind);
|
||||
if (!pidl)
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
return S_OK;
|
||||
|
||||
if (*ppidl)
|
||||
{
|
||||
ILFree(*ppidl);
|
||||
*ppidl = NULL;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
BOOL CFSFolder::_GetFindDataFromName(_In_ LPCWSTR pszName, _Out_ WIN32_FIND_DATAW *pFind)
|
||||
{
|
||||
WCHAR szPath[MAX_PATH];
|
||||
lstrcpynW(szPath, m_sPathTarget, _countof(szPath));
|
||||
PathAppendW(szPath, pszName);
|
||||
|
||||
HANDLE hFind = ::FindFirstFileW(szPath, pFind);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
::FindClose(hFind);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HRESULT CFSFolder::_CreateIDListFromName(LPCWSTR pszName, DWORD attrs, IBindCtx *pbc, LPITEMIDLIST *ppidl)
|
||||
{
|
||||
*ppidl = NULL;
|
||||
|
||||
if (PathIsDosDevice(pszName))
|
||||
return HRESULT_FROM_WIN32(ERROR_BAD_DEVICE);
|
||||
|
||||
WIN32_FIND_DATAW FindData = { 0 };
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
if (attrs == ULONG_MAX) // Invalid attributes
|
||||
{
|
||||
if (!_GetFindDataFromName(pszName, &FindData))
|
||||
hr = HRESULT_FROM_WIN32(::GetLastError());
|
||||
}
|
||||
else // Pretend as an item of attrs
|
||||
{
|
||||
StringCchCopyW(FindData.cFileName, _countof(FindData.cFileName), pszName);
|
||||
FindData.dwFileAttributes = attrs;
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
*ppidl = _ILCreateFromFindDataW(&FindData);
|
||||
if (!*ppidl)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CFSFolder::ParseDisplayName {SHELL32}
|
||||
*
|
||||
|
@ -736,13 +781,6 @@ HRESULT WINAPI CFSFolder::ParseDisplayName(HWND hwndOwner,
|
|||
DWORD *pchEaten, PIDLIST_RELATIVE *ppidl,
|
||||
DWORD *pdwAttributes)
|
||||
{
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
LPCWSTR szNext = NULL;
|
||||
WCHAR szElement[MAX_PATH];
|
||||
WCHAR szPath[MAX_PATH];
|
||||
LPITEMIDLIST pidlTemp = NULL;
|
||||
DWORD len;
|
||||
|
||||
TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
|
||||
this, hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName),
|
||||
pchEaten, ppidl, pdwAttributes);
|
||||
|
@ -750,67 +788,84 @@ HRESULT WINAPI CFSFolder::ParseDisplayName(HWND hwndOwner,
|
|||
if (!ppidl)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*ppidl = NULL;
|
||||
|
||||
if (!lpszDisplayName)
|
||||
{
|
||||
*ppidl = NULL;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
*ppidl = NULL;
|
||||
|
||||
if (pchEaten)
|
||||
*pchEaten = 0; /* strange but like the original */
|
||||
|
||||
if (*lpszDisplayName)
|
||||
HRESULT hr;
|
||||
WIN32_FIND_DATAW FindData;
|
||||
if (SHIsFileSysBindCtx(pbc, &FindData) == S_OK)
|
||||
{
|
||||
/* get the next element */
|
||||
szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
|
||||
|
||||
pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, szElement);
|
||||
if (pidlTemp != NULL)
|
||||
CComHeapPtr<ITEMIDLIST> pidlTemp;
|
||||
hr = _ParseSimple(lpszDisplayName, &FindData, &pidlTemp);
|
||||
if (SUCCEEDED(hr) && pdwAttributes && *pdwAttributes)
|
||||
{
|
||||
/* We are creating an id list without ensuring that the items exist.
|
||||
If we have a remaining path, this must be a folder.
|
||||
We have to do it now because it is set as a file by default */
|
||||
if (szNext)
|
||||
{
|
||||
pidlTemp->mkid.abID[0] = PT_FOLDER;
|
||||
}
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* build the full pathname to the element */
|
||||
lstrcpynW(szPath, m_sPathTarget, MAX_PATH - 1);
|
||||
PathAddBackslashW(szPath);
|
||||
len = wcslen(szPath);
|
||||
lstrcpynW(szPath + len, szElement, MAX_PATH - len);
|
||||
|
||||
/* get the pidl */
|
||||
hr = _ILCreateFromPathW(szPath, &pidlTemp);
|
||||
LPCITEMIDLIST pidlLast = ILFindLastID(pidlTemp);
|
||||
GetAttributesOf(1, &pidlLast, pdwAttributes);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (szNext && *szNext)
|
||||
{
|
||||
/* try to analyse the next element */
|
||||
hr = SHELL32_ParseNextElement(this, hwndOwner, pbc,
|
||||
&pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes);
|
||||
*ppidl = pidlTemp.Detach();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* it's the last element */
|
||||
if (pdwAttributes && *pdwAttributes)
|
||||
hr = SHELL32_GetFSItemAttributes(this, pidlTemp, pdwAttributes);
|
||||
INT cchElement = lstrlenW(lpszDisplayName) + 1;
|
||||
LPWSTR pszElement = (LPWSTR)alloca(cchElement * sizeof(WCHAR));
|
||||
LPWSTR pchNext = lpszDisplayName;
|
||||
hr = Shell_NextElement(&pchNext, pszElement, cchElement, TRUE);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
hr = _CreateIDListFromName(pszElement, ULONG_MAX, pbc, ppidl);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
if (pchNext) // Is there the next element?
|
||||
{
|
||||
// pszElement seems like a directory
|
||||
if (_GetFindDataFromName(pszElement, &FindData) &&
|
||||
(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
hr = _CreateIDListFromName(pszElement, FILE_ATTRIBUTE_DIRECTORY, pbc, ppidl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// pszElement seems like a non-directory
|
||||
if ((hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ||
|
||||
hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) &&
|
||||
(BindCtx_GetMode(pbc, 0) & STGM_CREATE))
|
||||
{
|
||||
// Pretend like a normal file
|
||||
hr = _CreateIDListFromName(pszElement, FILE_ATTRIBUTE_NORMAL, pbc, ppidl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
*ppidl = pidlTemp;
|
||||
else
|
||||
*ppidl = NULL;
|
||||
{
|
||||
if (pchNext) // Is there next?
|
||||
{
|
||||
CComPtr<IShellFolder> psfChild;
|
||||
hr = BindToObject(*ppidl, pbc, IID_PPV_ARG(IShellFolder, &psfChild));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
DWORD chEaten;
|
||||
CComHeapPtr<ITEMIDLIST> pidlChild;
|
||||
hr = psfChild->ParseDisplayName(hwndOwner, pbc, pchNext, &chEaten, &pidlChild,
|
||||
pdwAttributes);
|
||||
|
||||
// Append pidlChild to ppidl
|
||||
if (SUCCEEDED(hr))
|
||||
hr = SHILAppend(pidlChild.Detach(), ppidl);
|
||||
}
|
||||
else if (pdwAttributes && *pdwAttributes)
|
||||
{
|
||||
GetAttributesOf(1, (LPCITEMIDLIST*)ppidl, pdwAttributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("(%p)->(-- pidl=%p ret=0x%08x)\n", this, ppidl ? *ppidl : 0, hr);
|
||||
|
||||
|
|
|
@ -33,6 +33,14 @@ class CFSFolder :
|
|||
HRESULT _CreateExtensionUIObject(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppvOut);
|
||||
HRESULT _GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut);
|
||||
HRESULT _GetIconHandler(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppvOut);
|
||||
|
||||
HRESULT _ParseSimple(
|
||||
_In_ LPOLESTR lpszDisplayName,
|
||||
_Out_ WIN32_FIND_DATAW *pFind,
|
||||
_Out_ LPITEMIDLIST *ppidl);
|
||||
BOOL _GetFindDataFromName(_In_ LPCWSTR pszName, _Out_ WIN32_FIND_DATAW *pFind);
|
||||
HRESULT _CreateIDListFromName(LPCWSTR pszName, DWORD attrs, IBindCtx *pbc, LPITEMIDLIST *ppidl);
|
||||
|
||||
public:
|
||||
CFSFolder();
|
||||
~CFSFolder();
|
||||
|
|
|
@ -161,8 +161,9 @@ Shell_TranslateIDListAlias(
|
|||
_In_ DWORD dwFlags);
|
||||
|
||||
BOOL BindCtx_ContainsObject(_In_ IBindCtx *pBindCtx, _In_ LPCWSTR pszName);
|
||||
DWORD BindCtx_GetMode(_In_ IBindCtx *pbc, _In_ DWORD dwDefault);
|
||||
BOOL SHSkipJunctionBinding(_In_ IBindCtx *pbc, _In_ CLSID *pclsid);
|
||||
HRESULT SHIsFileSysBindCtx(_In_ IBindCtx *pBindCtx, _Out_opt_ WIN32_FIND_DATAW **ppFindData);
|
||||
HRESULT SHIsFileSysBindCtx(_In_ IBindCtx *pBindCtx, _Out_opt_ WIN32_FIND_DATAW *pFindData);
|
||||
BOOL Shell_FailForceReturn(_In_ HRESULT hr);
|
||||
|
||||
EXTERN_C INT
|
||||
|
@ -211,4 +212,9 @@ BindCtx_RegisterObjectParam(
|
|||
_In_opt_ IUnknown *punk,
|
||||
_Out_ LPBC *ppbc);
|
||||
|
||||
BOOL PathIsDotOrDotDotW(_In_ LPCWSTR pszPath);
|
||||
BOOL PathIsValidElement(_In_ LPCWSTR pszPath);
|
||||
BOOL PathIsDosDevice(_In_ LPCWSTR pszName);
|
||||
HRESULT SHILAppend(_Inout_ LPITEMIDLIST pidl, _Inout_ LPITEMIDLIST *ppidl);
|
||||
|
||||
#endif /* _PRECOMP_H__ */
|
||||
|
|
|
@ -36,14 +36,18 @@ typedef struct {
|
|||
#define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
|
||||
#define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
|
||||
|
||||
LPCWSTR GetNextElementW (LPCWSTR pszNext, LPWSTR pszOut, DWORD dwOut);
|
||||
HRESULT
|
||||
Shell_NextElement(
|
||||
_Inout_ LPWSTR *ppch,
|
||||
_Out_ LPWSTR pszOut,
|
||||
_In_ INT cchOut,
|
||||
_In_ BOOL bValidate);
|
||||
|
||||
HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc, LPITEMIDLIST * pidlInOut,
|
||||
LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes);
|
||||
|
||||
HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf, LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet);
|
||||
|
||||
LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path);
|
||||
|
||||
HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes);
|
||||
|
||||
HRESULT SHELL32_CompareDetails(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
|
||||
|
|
|
@ -26,45 +26,54 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
||||
|
||||
/***************************************************************************
|
||||
* GetNextElement (internal function)
|
||||
*
|
||||
* Gets a part of a string till the first backslash.
|
||||
*
|
||||
* PARAMETERS
|
||||
* pszNext [IN] string to get the element from
|
||||
* pszOut [IN] pointer to buffer which receives string
|
||||
* dwOut [IN] length of pszOut
|
||||
*
|
||||
* RETURNS
|
||||
* LPSTR pointer to first, not yet parsed char
|
||||
*/
|
||||
|
||||
LPCWSTR GetNextElementW (LPCWSTR pszNext, LPWSTR pszOut, DWORD dwOut)
|
||||
HRESULT
|
||||
Shell_NextElement(
|
||||
_Inout_ LPWSTR *ppch,
|
||||
_Out_ LPWSTR pszOut,
|
||||
_In_ INT cchOut,
|
||||
_In_ BOOL bValidate)
|
||||
{
|
||||
LPCWSTR pszTail = pszNext;
|
||||
DWORD dwCopy;
|
||||
*pszOut = UNICODE_NULL;
|
||||
|
||||
TRACE ("(%s %p 0x%08x)\n", debugstr_w (pszNext), pszOut, dwOut);
|
||||
if (!*ppch)
|
||||
return S_FALSE;
|
||||
|
||||
*pszOut = 0x0000;
|
||||
HRESULT hr;
|
||||
LPWSTR pchNext = wcschr(*ppch, L'\\');
|
||||
if (pchNext)
|
||||
{
|
||||
if (*ppch < pchNext)
|
||||
{
|
||||
/* Get an element */
|
||||
StringCchCopyNW(pszOut, cchOut, *ppch, pchNext - *ppch);
|
||||
++pchNext;
|
||||
|
||||
if (!pszNext || !*pszNext)
|
||||
return NULL;
|
||||
if (!*pchNext)
|
||||
pchNext = NULL; /* No next */
|
||||
|
||||
while (*pszTail && (*pszTail != (WCHAR) '\\'))
|
||||
pszTail++;
|
||||
hr = S_OK;
|
||||
}
|
||||
else /* Double backslashes found? */
|
||||
{
|
||||
pchNext = NULL;
|
||||
hr = E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
else /* No more next */
|
||||
{
|
||||
StringCchCopyW(pszOut, cchOut, *ppch);
|
||||
hr = S_OK;
|
||||
}
|
||||
|
||||
dwCopy = pszTail - pszNext + 1;
|
||||
lstrcpynW (pszOut, pszNext, (dwOut < dwCopy) ? dwOut : dwCopy);
|
||||
*ppch = pchNext; /* Go next */
|
||||
|
||||
if (*pszTail)
|
||||
pszTail++;
|
||||
else
|
||||
pszTail = NULL;
|
||||
if (hr == S_OK && bValidate && !PathIsValidElement(pszOut))
|
||||
{
|
||||
*pszOut = UNICODE_NULL;
|
||||
hr = E_INVALIDARG;
|
||||
}
|
||||
|
||||
TRACE ("--(%s %s 0x%08x %p)\n", debugstr_w (pszNext), debugstr_w (pszOut), dwOut, pszTail);
|
||||
return pszTail;
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc,
|
||||
|
|
|
@ -9,6 +9,68 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
||||
|
||||
BOOL PathIsDotOrDotDotW(_In_ LPCWSTR pszPath)
|
||||
{
|
||||
if (pszPath[0] != L'.')
|
||||
return FALSE;
|
||||
return !pszPath[1] || (pszPath[1] == L'.' && !pszPath[2]);
|
||||
}
|
||||
|
||||
#define PATH_VALID_ELEMENT ( \
|
||||
PATH_CHAR_CLASS_DOT | PATH_CHAR_CLASS_SEMICOLON | PATH_CHAR_CLASS_COMMA | \
|
||||
PATH_CHAR_CLASS_SPACE | PATH_CHAR_CLASS_OTHER_VALID \
|
||||
)
|
||||
|
||||
BOOL PathIsValidElement(_In_ LPCWSTR pszPath)
|
||||
{
|
||||
if (!*pszPath || PathIsDotOrDotDotW(pszPath))
|
||||
return FALSE;
|
||||
|
||||
for (LPCWSTR pch = pszPath; *pch; ++pch)
|
||||
{
|
||||
if (!PathIsValidCharW(*pch, PATH_VALID_ELEMENT))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL PathIsDosDevice(_In_ LPCWSTR pszName)
|
||||
{
|
||||
WCHAR szPath[MAX_PATH];
|
||||
StringCchCopyW(szPath, _countof(szPath), pszName);
|
||||
PathRemoveExtensionW(szPath);
|
||||
|
||||
if (lstrcmpiW(szPath, L"NUL") == 0 || lstrcmpiW(szPath, L"PRN") == 0 ||
|
||||
lstrcmpiW(szPath, L"CON") == 0 || lstrcmpiW(szPath, L"AUX") == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (_wcsnicmp(szPath, L"LPT", 3) == 0 || _wcsnicmp(szPath, L"COM", 3) == 0)
|
||||
{
|
||||
if ((L'0' <= szPath[3] && szPath[3] <= L'9') && szPath[4] == UNICODE_NULL)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HRESULT SHILAppend(_Inout_ LPITEMIDLIST pidl, _Inout_ LPITEMIDLIST *ppidl)
|
||||
{
|
||||
LPITEMIDLIST pidlOld = *ppidl;
|
||||
if (!pidlOld)
|
||||
{
|
||||
*ppidl = pidl;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT hr = SHILCombine(*ppidl, pidl, ppidl);
|
||||
ILFree(pidlOld);
|
||||
ILFree(pidl);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
OpenEffectiveToken(
|
||||
_In_ DWORD DesiredAccess,
|
||||
|
@ -49,6 +111,19 @@ BOOL BindCtx_ContainsObject(_In_ IBindCtx *pBindCtx, _In_ LPCWSTR pszName)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD BindCtx_GetMode(_In_ IBindCtx *pbc, _In_ DWORD dwDefault)
|
||||
{
|
||||
if (!pbc)
|
||||
return dwDefault;
|
||||
|
||||
BIND_OPTS BindOpts = { sizeof(BindOpts) };
|
||||
HRESULT hr = pbc->GetBindOptions(&BindOpts);
|
||||
if (FAILED(hr))
|
||||
return dwDefault;
|
||||
|
||||
return BindOpts.grfMode;
|
||||
}
|
||||
|
||||
BOOL SHSkipJunctionBinding(_In_ IBindCtx *pbc, _In_ CLSID *pclsid)
|
||||
{
|
||||
if (!pbc)
|
||||
|
@ -61,7 +136,7 @@ BOOL SHSkipJunctionBinding(_In_ IBindCtx *pbc, _In_ CLSID *pclsid)
|
|||
return pclsid && SHSkipJunction(pbc, pclsid);
|
||||
}
|
||||
|
||||
HRESULT SHIsFileSysBindCtx(_In_ IBindCtx *pBindCtx, _Out_opt_ WIN32_FIND_DATAW **ppFindData)
|
||||
HRESULT SHIsFileSysBindCtx(_In_ IBindCtx *pBindCtx, _Out_opt_ WIN32_FIND_DATAW *pFindData)
|
||||
{
|
||||
CComPtr<IUnknown> punk;
|
||||
CComPtr<IFileSystemBindData> pBindData;
|
||||
|
@ -72,17 +147,10 @@ HRESULT SHIsFileSysBindCtx(_In_ IBindCtx *pBindCtx, _Out_opt_ WIN32_FIND_DATAW *
|
|||
if (FAILED(punk->QueryInterface(IID_PPV_ARG(IFileSystemBindData, &pBindData))))
|
||||
return S_FALSE;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
if (ppFindData)
|
||||
{
|
||||
*ppFindData = (WIN32_FIND_DATAW*)LocalAlloc(LPTR, sizeof(WIN32_FIND_DATAW));
|
||||
if (*ppFindData)
|
||||
pBindData->GetFindData(*ppFindData);
|
||||
else
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
if (pFindData)
|
||||
pBindData->GetFindData(pFindData);
|
||||
|
||||
return hr;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
BOOL Shell_FailForceReturn(_In_ HRESULT hr)
|
||||
|
|
Loading…
Reference in a new issue