mirror of
https://github.com/reactos/reactos.git
synced 2024-10-31 20:02:55 +00:00
[SHELL32][SDK] Fix ParseDisplayName Part 1 (#6721)
JIRA issue: CORE-19495 - Implement SHParseDisplayName and CDesktopFolder::ParseDisplayName. - Add CStubFolderBase, CShellUrlStub, CFileUrlStub, CIDListUrlStub, and CHttpUrlStub helper classes. - Add SHGetSpecialFolderID and Shell_ParseSpecialFolder helper functions. - Add BindCtx_ContainsObject, BindCtx_GetUIWindow, BindCtx_RegisterObjectParam, SHBindToObject, SHBindToObjectEx, SHCoInitializeAnyApartment, SHGetAttributes, SHGetNameAndFlagsW, SHIsFileSysBindCtx, SHSkipJunctionBinding, Shell_DisplayNameOf, and Shell_FailForceReturn helper functions. - Modify CSIDL data.
This commit is contained in:
parent
e85ef799fe
commit
d05dcf6a02
|
@ -24,6 +24,223 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
||||
|
||||
STDMETHODIMP
|
||||
CShellUrlStub::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten,
|
||||
PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes)
|
||||
{
|
||||
LPWSTR pch;
|
||||
INT cch, csidl;
|
||||
HRESULT hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
|
||||
PARSEDURLW ParsedURL = { sizeof(ParsedURL) };
|
||||
|
||||
::ParseURLW(lpszDisplayName, &ParsedURL);
|
||||
|
||||
DWORD attrs = (pdwAttributes ? *pdwAttributes : 0) | SFGAO_STREAM;
|
||||
if (ParsedURL.pszSuffix[0] == L':' && ParsedURL.pszSuffix[1] == L':')
|
||||
{
|
||||
CComPtr<IShellFolder> psfDesktop;
|
||||
hr = SHGetDesktopFolder(&psfDesktop);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
CComPtr<IBindCtx> pBindCtx;
|
||||
hr = ::CreateBindCtx(0, &pBindCtx);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
BIND_OPTS BindOps = { sizeof(BindOps) };
|
||||
BindOps.grfMode = STGM_CREATE;
|
||||
pBindCtx->SetBindOptions(&BindOps);
|
||||
hr = psfDesktop->ParseDisplayName(hwndOwner, pBindCtx,
|
||||
(LPWSTR)ParsedURL.pszSuffix,
|
||||
pchEaten, ppidl, &attrs);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
csidl = Shell_ParseSpecialFolder(ParsedURL.pszSuffix, &pch, &cch);
|
||||
if (csidl == -1)
|
||||
{
|
||||
ERR("\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
CComHeapPtr<ITEMIDLIST> pidlLocation;
|
||||
hr = SHGetFolderLocation(hwndOwner, (csidl | CSIDL_FLAG_CREATE), NULL, 0, &pidlLocation);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
if (pch && *pch)
|
||||
{
|
||||
CComPtr<IShellFolder> psfFolder;
|
||||
hr = SHBindToObject(NULL, pidlLocation, IID_PPV_ARG(IShellFolder, &psfFolder));
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
CComHeapPtr<ITEMIDLIST> pidlNew;
|
||||
hr = psfFolder->ParseDisplayName(hwndOwner, pbc, pch, pchEaten, &pidlNew, &attrs);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = SHILCombine(pidlLocation, pidlNew, ppidl);
|
||||
if (pchEaten)
|
||||
*pchEaten += cch;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (attrs)
|
||||
hr = SHGetNameAndFlagsW(pidlLocation, 0, NULL, 0, &attrs);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (pchEaten)
|
||||
*pchEaten = cch;
|
||||
*ppidl = pidlLocation.Detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: SHWindowsPolicy
|
||||
if (SUCCEEDED(hr) && (attrs & SFGAO_STREAM) &&
|
||||
!BindCtx_ContainsObject(pbc, STR_PARSE_SHELL_PROTOCOL_TO_FILE_OBJECTS))
|
||||
{
|
||||
ILFree(*ppidl);
|
||||
*ppidl = NULL;
|
||||
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (pdwAttributes)
|
||||
*pdwAttributes = attrs;
|
||||
|
||||
// FIXME: SHWindowsPolicy
|
||||
if (FAILED(hr) && !Shell_FailForceReturn(hr))
|
||||
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CFileUrlStub::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten,
|
||||
PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes)
|
||||
{
|
||||
WCHAR szPath[MAX_PATH];
|
||||
DWORD cchPath = _countof(szPath);
|
||||
HRESULT hr = PathCreateFromUrlW(lpszDisplayName, szPath, &cchPath, 0);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
CComPtr<IShellFolder> psfDesktop;
|
||||
hr = SHGetDesktopFolder(&psfDesktop);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
return psfDesktop->ParseDisplayName(hwndOwner, pbc, szPath, pchEaten, ppidl, pdwAttributes);
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CIDListUrlStub::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten,
|
||||
PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes)
|
||||
{
|
||||
return E_NOTIMPL; // FIXME
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CHttpUrlStub::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten,
|
||||
PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes)
|
||||
{
|
||||
return E_NOTIMPL; // FIXME
|
||||
}
|
||||
|
||||
BOOL CDesktopFolder::_TryUrlJunctions(
|
||||
LPCWSTR pcszURL,
|
||||
IBindCtx *pBindCtx,
|
||||
IShellFolder **ppShellFolder,
|
||||
LPITEMIDLIST *ppidl)
|
||||
{
|
||||
PARSEDURLW ParsedURL = { sizeof(ParsedURL) };
|
||||
::ParseURLW(pcszURL, &ParsedURL);
|
||||
|
||||
*ppShellFolder = NULL;
|
||||
switch (ParsedURL.nScheme)
|
||||
{
|
||||
case URL_SCHEME_FILE:
|
||||
*ppShellFolder = &m_FileUrlStub;
|
||||
break;
|
||||
|
||||
case URL_SCHEME_HTTP:
|
||||
case URL_SCHEME_HTTPS:
|
||||
if (!BindCtx_ContainsObject(pBindCtx, STR_PARSE_PREFER_FOLDER_BROWSING))
|
||||
break;
|
||||
*ppShellFolder = &m_HttpUrlStub;
|
||||
break;
|
||||
|
||||
case URL_SCHEME_SHELL:
|
||||
*ppShellFolder = &m_ShellUrlStub;
|
||||
break;
|
||||
|
||||
case URL_SCHEME_MSSHELLROOTED:
|
||||
*ppShellFolder = NULL; // FIXME
|
||||
break;
|
||||
|
||||
case URL_SCHEME_MSSHELLIDLIST:
|
||||
*ppShellFolder = &m_IDListUrlStub;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return !!*ppShellFolder;
|
||||
}
|
||||
|
||||
BOOL CDesktopFolder::_GetParentForParsing(
|
||||
LPCWSTR pszPath,
|
||||
IBindCtx *pbc,
|
||||
IShellFolder **ppParentFolder,
|
||||
LPITEMIDLIST *ppidlParent)
|
||||
{
|
||||
WCHAR wch = *pszPath;
|
||||
if (((L'A' <= wch && wch <= L'Z') || (L'a' <= wch && wch <= L'z')) && (pszPath[1] == ':'))
|
||||
*ppidlParent = _ILCreateMyComputer();
|
||||
else if (PathIsUNCW(pszPath))
|
||||
*ppidlParent = _ILCreateNetwork();
|
||||
else if (UrlIsW(pszPath, URLIS_URL) && !SHSkipJunctionBinding(pbc, NULL))
|
||||
_TryUrlJunctions(pszPath, pbc, ppParentFolder, ppidlParent);
|
||||
|
||||
if (!*ppParentFolder && *ppidlParent)
|
||||
SHBindToObject(NULL, *ppidlParent, IID_PPV_ARG(IShellFolder, ppParentFolder));
|
||||
|
||||
return *ppParentFolder != NULL;
|
||||
}
|
||||
|
||||
HRESULT CDesktopFolder::_ChildParseDisplayName(
|
||||
IShellFolder *pParentFolder,
|
||||
LPCITEMIDLIST pidlParent,
|
||||
HWND hwndOwner,
|
||||
IBindCtx *pBindCtx,
|
||||
LPWSTR lpszDisplayName,
|
||||
DWORD *pchEaten,
|
||||
LPITEMIDLIST *ppidl,
|
||||
DWORD *pdwAttributes)
|
||||
{
|
||||
LPITEMIDLIST pidlChild;
|
||||
HRESULT hr = pParentFolder->ParseDisplayName(hwndOwner, pBindCtx, lpszDisplayName,
|
||||
pchEaten, &pidlChild, pdwAttributes);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (pidlParent)
|
||||
{
|
||||
*ppidl = ILCombine(pidlParent, pidlChild);
|
||||
ILFree(pidlChild);
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppidl = pidlChild;
|
||||
}
|
||||
|
||||
return (*ppidl ? S_OK : E_OUTOFMEMORY);
|
||||
}
|
||||
|
||||
/*
|
||||
CDesktopFolder should create two file system folders internally, one representing the
|
||||
user's desktop folder, and the other representing the common desktop folder. It should
|
||||
|
@ -285,11 +502,6 @@ HRESULT WINAPI CDesktopFolder::ParseDisplayName(
|
|||
PIDLIST_RELATIVE *ppidl,
|
||||
DWORD *pdwAttributes)
|
||||
{
|
||||
LPCWSTR szNext = NULL;
|
||||
LPITEMIDLIST pidlTemp = NULL;
|
||||
PARSEDURLW urldata;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
|
||||
this, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName),
|
||||
pchEaten, ppidl, pdwAttributes);
|
||||
|
@ -302,78 +514,98 @@ HRESULT WINAPI CDesktopFolder::ParseDisplayName(
|
|||
if (!lpszDisplayName)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (pchEaten)
|
||||
*pchEaten = 0; /* strange but like the original */
|
||||
|
||||
urldata.cbSize = sizeof(urldata);
|
||||
if (!*lpszDisplayName)
|
||||
{
|
||||
*ppidl = _ILCreateMyComputer();
|
||||
return (*ppidl ? S_OK : E_OUTOFMEMORY);
|
||||
}
|
||||
|
||||
if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
|
||||
{
|
||||
return m_regFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
|
||||
return m_regFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl,
|
||||
pdwAttributes);
|
||||
}
|
||||
else if (PathGetDriveNumberW (lpszDisplayName) >= 0)
|
||||
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
CComHeapPtr<ITEMIDLIST> pidlParent;
|
||||
CComPtr<IShellFolder> pParentFolder;
|
||||
if (_GetParentForParsing(lpszDisplayName, pbc, &pParentFolder, &pidlParent))
|
||||
{
|
||||
/* it's a filesystem path with a drive. Let MyComputer/UnixDosFolder parse it */
|
||||
pidlTemp = _ILCreateMyComputer ();
|
||||
szNext = lpszDisplayName;
|
||||
}
|
||||
else if (PathIsUNCW(lpszDisplayName))
|
||||
{
|
||||
pidlTemp = _ILCreateNetwork();
|
||||
szNext = lpszDisplayName;
|
||||
}
|
||||
else if( (pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, lpszDisplayName)) )
|
||||
{
|
||||
*ppidl = pidlTemp;
|
||||
return S_OK;
|
||||
}
|
||||
else if (SUCCEEDED(ParseURLW(lpszDisplayName, &urldata)))
|
||||
{
|
||||
if (urldata.nScheme == URL_SCHEME_SHELL) /* handle shell: urls */
|
||||
{
|
||||
TRACE ("-- shell url: %s\n", debugstr_w(urldata.pszSuffix));
|
||||
pidlTemp = _ILCreateGuidFromStrW(urldata.pszSuffix + 2);
|
||||
}
|
||||
else
|
||||
return IEParseDisplayNameWithBCW(CP_ACP, lpszDisplayName, pbc, ppidl);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*lpszDisplayName)
|
||||
{
|
||||
/* it's a filesystem path on the desktop. Let a FSFolder parse it */
|
||||
hr = m_DesktopFSFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
|
||||
if (pchEaten)
|
||||
*pchEaten = 0;
|
||||
|
||||
hr = _ChildParseDisplayName(pParentFolder,
|
||||
pidlParent,
|
||||
hwndOwner,
|
||||
pbc,
|
||||
lpszDisplayName,
|
||||
pchEaten,
|
||||
ppidl,
|
||||
pdwAttributes);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (BindCtx_ContainsObject(pbc, STR_PARSE_TRANSLATE_ALIASES))
|
||||
{
|
||||
LPITEMIDLIST pidlAlias;
|
||||
if (SUCCEEDED(Shell_TranslateIDListAlias(*ppidl, NULL, &pidlAlias, 0xFFFF)))
|
||||
{
|
||||
ILFree(*ppidl);
|
||||
*ppidl = pidlAlias;
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
if (Shell_FailForceReturn(hr))
|
||||
return hr;
|
||||
|
||||
return m_SharedDesktopFSFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
|
||||
}
|
||||
else
|
||||
pidlTemp = _ILCreateMyComputer();
|
||||
if (BindCtx_ContainsObject(pbc, STR_DONT_PARSE_RELATIVE))
|
||||
return E_INVALIDARG;
|
||||
|
||||
szNext = NULL;
|
||||
if (SHIsFileSysBindCtx(pbc, NULL) == S_OK)
|
||||
return hr;
|
||||
|
||||
BIND_OPTS BindOps = { sizeof(BindOps) };
|
||||
BOOL bCreate = FALSE;
|
||||
if (pbc && SUCCEEDED(pbc->GetBindOptions(&BindOps)) && (BindOps.grfMode & STGM_CREATE))
|
||||
{
|
||||
BindOps.grfMode &= ~STGM_CREATE;
|
||||
bCreate = TRUE;
|
||||
pbc->SetBindOptions(&BindOps);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr) && pidlTemp)
|
||||
if (m_DesktopFSFolder)
|
||||
{
|
||||
if (szNext && *szNext)
|
||||
{
|
||||
hr = SHELL32_ParseNextElement(this, hwndOwner, pbc,
|
||||
&pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pdwAttributes && *pdwAttributes)
|
||||
{
|
||||
GetAttributesOf(1, &pidlTemp, pdwAttributes);
|
||||
}
|
||||
}
|
||||
hr = m_DesktopFSFolder->ParseDisplayName(hwndOwner,
|
||||
pbc,
|
||||
lpszDisplayName,
|
||||
pchEaten,
|
||||
ppidl,
|
||||
pdwAttributes);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
*ppidl = pidlTemp;
|
||||
else
|
||||
*ppidl = NULL;
|
||||
if (FAILED(hr) && m_SharedDesktopFSFolder)
|
||||
{
|
||||
hr = m_SharedDesktopFSFolder->ParseDisplayName(hwndOwner,
|
||||
pbc,
|
||||
lpszDisplayName,
|
||||
pchEaten,
|
||||
ppidl,
|
||||
pdwAttributes);
|
||||
}
|
||||
|
||||
if (FAILED(hr) && bCreate && m_DesktopFSFolder)
|
||||
{
|
||||
BindOps.grfMode |= STGM_CREATE;
|
||||
pbc->SetBindOptions(&BindOps);
|
||||
hr = m_DesktopFSFolder->ParseDisplayName(hwndOwner,
|
||||
pbc,
|
||||
lpszDisplayName,
|
||||
pchEaten,
|
||||
ppidl,
|
||||
pdwAttributes);
|
||||
}
|
||||
|
||||
TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr);
|
||||
|
||||
|
|
|
@ -23,6 +23,73 @@
|
|||
#ifndef _CDESKTOPFOLDER_H_
|
||||
#define _CDESKTOPFOLDER_H_
|
||||
|
||||
class CStubFolderBase : public IShellFolder
|
||||
{
|
||||
public:
|
||||
CStubFolderBase() { }
|
||||
|
||||
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override { return E_NOTIMPL; }
|
||||
STDMETHODIMP_(ULONG) AddRef() override { return 3; }
|
||||
STDMETHODIMP_(ULONG) Release() override { return 2; }
|
||||
|
||||
// IShellFolder methods
|
||||
STDMETHODIMP ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
|
||||
DWORD *pchEaten, PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes) override
|
||||
{ return E_NOTIMPL; }
|
||||
STDMETHODIMP EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList) override
|
||||
{ return E_NOTIMPL; }
|
||||
STDMETHODIMP BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut) override
|
||||
{ return E_NOTIMPL; }
|
||||
STDMETHODIMP BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut) override
|
||||
{ return E_NOTIMPL; }
|
||||
STDMETHODIMP CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2) override
|
||||
{ return E_NOTIMPL; }
|
||||
STDMETHODIMP CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut) override
|
||||
{ return E_NOTIMPL; }
|
||||
STDMETHODIMP GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut) override
|
||||
{ return E_NOTIMPL; }
|
||||
STDMETHODIMP GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl,
|
||||
REFIID riid, UINT * prgfInOut, LPVOID * ppvOut) override
|
||||
{ return E_NOTIMPL; }
|
||||
STDMETHODIMP GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet) override
|
||||
{ return E_NOTIMPL; }
|
||||
STDMETHODIMP SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName,
|
||||
DWORD dwFlags, PITEMID_CHILD *pPidlOut) override
|
||||
{ return E_NOTIMPL; }
|
||||
};
|
||||
|
||||
class CShellUrlStub : public CStubFolderBase
|
||||
{
|
||||
public:
|
||||
STDMETHODIMP
|
||||
ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten,
|
||||
PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes) override;
|
||||
};
|
||||
|
||||
class CFileUrlStub : public CStubFolderBase
|
||||
{
|
||||
public:
|
||||
STDMETHODIMP
|
||||
ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten,
|
||||
PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes) override;
|
||||
};
|
||||
|
||||
class CIDListUrlStub : public CStubFolderBase
|
||||
{
|
||||
public:
|
||||
STDMETHODIMP
|
||||
ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten,
|
||||
PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes) override;
|
||||
};
|
||||
|
||||
class CHttpUrlStub : public CStubFolderBase
|
||||
{
|
||||
public:
|
||||
STDMETHODIMP
|
||||
ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten,
|
||||
PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes) override;
|
||||
};
|
||||
|
||||
class CDesktopFolder :
|
||||
public CComCoClass<CDesktopFolder, &CLSID_ShellDesktop>,
|
||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||
|
@ -37,11 +104,37 @@ class CDesktopFolder :
|
|||
CComPtr<IShellFolder2> m_SharedDesktopFSFolder;
|
||||
CComPtr<IShellFolder2> m_regFolder;
|
||||
|
||||
// Stub URL objects
|
||||
CShellUrlStub m_ShellUrlStub;
|
||||
CFileUrlStub m_FileUrlStub;
|
||||
CIDListUrlStub m_IDListUrlStub;
|
||||
CHttpUrlStub m_HttpUrlStub;
|
||||
|
||||
LPWSTR sPathTarget; /* complete path to target used for enumeration and ChangeNotify */
|
||||
LPITEMIDLIST pidlRoot; /* absolute pidl */
|
||||
|
||||
HRESULT _GetSFFromPidl(LPCITEMIDLIST pidl, IShellFolder2** psf);
|
||||
|
||||
BOOL _TryUrlJunctions(
|
||||
LPCWSTR pcszURL,
|
||||
IBindCtx *pBindCtx,
|
||||
IShellFolder **ppShellFolder,
|
||||
LPITEMIDLIST *ppidl);
|
||||
BOOL _GetParentForParsing(
|
||||
LPCWSTR pszPath,
|
||||
IBindCtx *pbc,
|
||||
IShellFolder **ppParentFolder,
|
||||
LPITEMIDLIST *ppidlParent);
|
||||
HRESULT _ChildParseDisplayName(
|
||||
IShellFolder *pParentFolder,
|
||||
LPCITEMIDLIST pidlParent,
|
||||
HWND hwndOwner,
|
||||
IBindCtx *pBindCtx,
|
||||
LPWSTR lpszDisplayName,
|
||||
DWORD *pchEaten,
|
||||
LPITEMIDLIST *ppidl,
|
||||
DWORD *pdwAttributes);
|
||||
|
||||
public:
|
||||
CDesktopFolder();
|
||||
~CDesktopFolder();
|
||||
|
|
|
@ -153,4 +153,62 @@ public:
|
|||
END_MSG_MAP()
|
||||
};
|
||||
|
||||
HRESULT
|
||||
Shell_TranslateIDListAlias(
|
||||
_In_ LPCITEMIDLIST pidl,
|
||||
_In_ HANDLE hToken,
|
||||
_Out_ LPITEMIDLIST *ppidlAlias,
|
||||
_In_ DWORD dwFlags);
|
||||
|
||||
BOOL BindCtx_ContainsObject(_In_ IBindCtx *pBindCtx, _In_ LPCWSTR pszName);
|
||||
BOOL SHSkipJunctionBinding(_In_ IBindCtx *pbc, _In_ CLSID *pclsid);
|
||||
HRESULT SHIsFileSysBindCtx(_In_ IBindCtx *pBindCtx, _Out_opt_ WIN32_FIND_DATAW **ppFindData);
|
||||
BOOL Shell_FailForceReturn(_In_ HRESULT hr);
|
||||
|
||||
EXTERN_C INT
|
||||
Shell_ParseSpecialFolder(_In_ LPCWSTR pszStart, _Out_ LPWSTR *ppch, _Out_ INT *pcch);
|
||||
|
||||
HRESULT
|
||||
Shell_DisplayNameOf(
|
||||
_In_ IShellFolder *psf,
|
||||
_In_ LPCITEMIDLIST pidl,
|
||||
_In_ DWORD dwFlags,
|
||||
_Out_ LPWSTR pszBuf,
|
||||
_In_ UINT cchBuf);
|
||||
|
||||
HRESULT SHBindToObject(
|
||||
_In_opt_ IShellFolder *psf,
|
||||
_In_ LPCITEMIDLIST pidl,
|
||||
_In_ REFIID riid,
|
||||
_Out_ void **ppvObj);
|
||||
|
||||
HRESULT
|
||||
SHBindToObjectEx(
|
||||
_In_opt_ IShellFolder *pShellFolder,
|
||||
_In_ LPCITEMIDLIST pidl,
|
||||
_In_opt_ IBindCtx *pBindCtx,
|
||||
_In_ REFIID riid,
|
||||
_Out_ void **ppvObj);
|
||||
|
||||
DWORD
|
||||
SHGetAttributes(_In_ IShellFolder *psf, _In_ LPCITEMIDLIST pidl, _In_ DWORD dwAttributes);
|
||||
HRESULT SHCoInitializeAnyApartment(VOID);
|
||||
|
||||
HRESULT
|
||||
SHGetNameAndFlagsW(
|
||||
_In_ LPCITEMIDLIST pidl,
|
||||
_In_ DWORD dwFlags,
|
||||
_Out_opt_ LPWSTR pszText,
|
||||
_In_ UINT cchBuf,
|
||||
_Inout_opt_ DWORD *pdwAttributes);
|
||||
|
||||
EXTERN_C HWND BindCtx_GetUIWindow(_In_ IBindCtx *pBindCtx);
|
||||
|
||||
EXTERN_C HRESULT
|
||||
BindCtx_RegisterObjectParam(
|
||||
_In_ IBindCtx *pBindCtx,
|
||||
_In_ LPOLESTR pszKey,
|
||||
_In_opt_ IUnknown *punk,
|
||||
_Out_ LPBC *ppbc);
|
||||
|
||||
#endif /* _PRECOMP_H__ */
|
||||
|
|
|
@ -31,6 +31,316 @@ OpenEffectiveToken(
|
|||
return ret;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
Shell_TranslateIDListAlias(
|
||||
_In_ LPCITEMIDLIST pidl,
|
||||
_In_ HANDLE hToken,
|
||||
_Out_ LPITEMIDLIST *ppidlAlias,
|
||||
_In_ DWORD dwFlags)
|
||||
{
|
||||
return E_FAIL; //FIXME
|
||||
}
|
||||
|
||||
BOOL BindCtx_ContainsObject(_In_ IBindCtx *pBindCtx, _In_ LPCWSTR pszName)
|
||||
{
|
||||
CComPtr<IUnknown> punk;
|
||||
if (!pBindCtx || FAILED(pBindCtx->GetObjectParam(const_cast<LPWSTR>(pszName), &punk)))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL SHSkipJunctionBinding(_In_ IBindCtx *pbc, _In_ CLSID *pclsid)
|
||||
{
|
||||
if (!pbc)
|
||||
return FALSE;
|
||||
|
||||
BIND_OPTS BindOps = { sizeof(BindOps) };
|
||||
if (SUCCEEDED(pbc->GetBindOptions(&BindOps)) && BindOps.grfFlags == OLECONTF_LINKS)
|
||||
return TRUE;
|
||||
|
||||
return pclsid && SHSkipJunction(pbc, pclsid);
|
||||
}
|
||||
|
||||
HRESULT SHIsFileSysBindCtx(_In_ IBindCtx *pBindCtx, _Out_opt_ WIN32_FIND_DATAW **ppFindData)
|
||||
{
|
||||
CComPtr<IUnknown> punk;
|
||||
CComPtr<IFileSystemBindData> pBindData;
|
||||
|
||||
if (!pBindCtx || FAILED(pBindCtx->GetObjectParam((LPWSTR)STR_FILE_SYS_BIND_DATA, &punk)))
|
||||
return S_FALSE;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
BOOL Shell_FailForceReturn(_In_ HRESULT hr)
|
||||
{
|
||||
DWORD code = HRESULT_CODE(hr);
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case ERROR_BAD_NETPATH:
|
||||
case ERROR_BAD_NET_NAME:
|
||||
case ERROR_CANCELLED:
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return (ERROR_FILE_NOT_FOUND <= code && code <= ERROR_PATH_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT
|
||||
SHBindToObjectEx(
|
||||
_In_opt_ IShellFolder *pShellFolder,
|
||||
_In_ LPCITEMIDLIST pidl,
|
||||
_In_opt_ IBindCtx *pBindCtx,
|
||||
_In_ REFIID riid,
|
||||
_Out_ void **ppvObj)
|
||||
{
|
||||
CComPtr<IShellFolder> psfDesktop;
|
||||
|
||||
*ppvObj = NULL;
|
||||
|
||||
if (!pShellFolder)
|
||||
{
|
||||
SHGetDesktopFolder(&psfDesktop);
|
||||
if (!psfDesktop)
|
||||
return E_FAIL;
|
||||
|
||||
pShellFolder = psfDesktop;
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
if (_ILIsDesktop(pidl))
|
||||
hr = pShellFolder->QueryInterface(riid, ppvObj);
|
||||
else
|
||||
hr = pShellFolder->BindToObject(pidl, pBindCtx, riid, ppvObj);
|
||||
|
||||
if (SUCCEEDED(hr) && !*ppvObj)
|
||||
hr = E_FAIL;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT SHBindToObject(
|
||||
_In_opt_ IShellFolder *psf,
|
||||
_In_ LPCITEMIDLIST pidl,
|
||||
_In_ REFIID riid,
|
||||
_Out_ void **ppvObj)
|
||||
{
|
||||
return SHBindToObjectEx(psf, pidl, NULL, riid, ppvObj);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
Shell_DisplayNameOf(
|
||||
_In_ IShellFolder *psf,
|
||||
_In_ LPCITEMIDLIST pidl,
|
||||
_In_ DWORD dwFlags,
|
||||
_Out_ LPWSTR pszBuf,
|
||||
_In_ UINT cchBuf)
|
||||
{
|
||||
*pszBuf = UNICODE_NULL;
|
||||
STRRET sr;
|
||||
HRESULT hr = psf->GetDisplayNameOf(pidl, dwFlags, &sr);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
return StrRetToBufW(&sr, pidl, pszBuf, cchBuf);
|
||||
}
|
||||
|
||||
DWORD
|
||||
SHGetAttributes(_In_ IShellFolder *psf, _In_ LPCITEMIDLIST pidl, _In_ DWORD dwAttributes)
|
||||
{
|
||||
LPCITEMIDLIST pidlLast;
|
||||
|
||||
if (psf)
|
||||
{
|
||||
psf->AddRef();
|
||||
pidlLast = pidl;
|
||||
}
|
||||
else
|
||||
{
|
||||
SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psf), &pidlLast);
|
||||
}
|
||||
|
||||
if (!psf)
|
||||
return 0;
|
||||
|
||||
DWORD oldAttrs = dwAttributes;
|
||||
if (FAILED(psf->GetAttributesOf(1, &pidlLast, &dwAttributes)))
|
||||
dwAttributes = 0;
|
||||
else
|
||||
dwAttributes &= oldAttrs;
|
||||
|
||||
if ((dwAttributes & SFGAO_FOLDER) &&
|
||||
(dwAttributes & SFGAO_STREAM) &&
|
||||
!(dwAttributes & SFGAO_STORAGEANCESTOR) &&
|
||||
(oldAttrs & SFGAO_STORAGEANCESTOR) &&
|
||||
(SHGetObjectCompatFlags(psf, NULL) & 0x200))
|
||||
{
|
||||
dwAttributes &= ~(SFGAO_STREAM | SFGAO_STORAGEANCESTOR);
|
||||
dwAttributes |= SFGAO_STORAGEANCESTOR;
|
||||
}
|
||||
|
||||
if (psf)
|
||||
psf->Release();
|
||||
|
||||
return dwAttributes;
|
||||
}
|
||||
|
||||
HRESULT SHCoInitializeAnyApartment(VOID)
|
||||
{
|
||||
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
|
||||
if (FAILED(hr))
|
||||
hr = CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
SHGetNameAndFlagsW(
|
||||
_In_ LPCITEMIDLIST pidl,
|
||||
_In_ DWORD dwFlags,
|
||||
_Out_opt_ LPWSTR pszText,
|
||||
_In_ UINT cchBuf,
|
||||
_Inout_opt_ DWORD *pdwAttributes)
|
||||
{
|
||||
if (pszText)
|
||||
*pszText = UNICODE_NULL;
|
||||
|
||||
HRESULT hrCoInit = SHCoInitializeAnyApartment();
|
||||
|
||||
CComPtr<IShellFolder> psfFolder;
|
||||
LPCITEMIDLIST ppidlLast;
|
||||
HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psfFolder), &ppidlLast);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (pszText)
|
||||
hr = Shell_DisplayNameOf(psfFolder, ppidlLast, dwFlags, pszText, cchBuf);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (pdwAttributes)
|
||||
*pdwAttributes = SHGetAttributes(psfFolder, ppidlLast, *pdwAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hrCoInit))
|
||||
CoUninitialize();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
EXTERN_C HWND
|
||||
BindCtx_GetUIWindow(_In_ IBindCtx *pBindCtx)
|
||||
{
|
||||
HWND hWnd = NULL;
|
||||
|
||||
CComPtr<IUnknown> punk;
|
||||
if (pBindCtx && SUCCEEDED(pBindCtx->GetObjectParam((LPWSTR)L"UI During Binding", &punk)))
|
||||
IUnknown_GetWindow(punk, &hWnd);
|
||||
|
||||
return hWnd;
|
||||
}
|
||||
|
||||
class CDummyOleWindow : public IOleWindow
|
||||
{
|
||||
protected:
|
||||
LONG m_cRefs;
|
||||
HWND m_hWnd;
|
||||
|
||||
public:
|
||||
CDummyOleWindow() : m_cRefs(1), m_hWnd(NULL) { }
|
||||
virtual ~CDummyOleWindow() { }
|
||||
|
||||
// IUnknown methods
|
||||
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObj) override
|
||||
{
|
||||
static const QITAB c_tab[] =
|
||||
{
|
||||
QITABENT(CDummyOleWindow, IOleWindow),
|
||||
{ NULL }
|
||||
};
|
||||
return ::QISearch(this, c_tab, riid, ppvObj);
|
||||
}
|
||||
STDMETHODIMP_(ULONG) AddRef() override
|
||||
{
|
||||
return ++m_cRefs;
|
||||
}
|
||||
STDMETHODIMP_(ULONG) Release() override
|
||||
{
|
||||
if (--m_cRefs == 0)
|
||||
{
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return m_cRefs;
|
||||
}
|
||||
|
||||
// IOleWindow methods
|
||||
STDMETHODIMP GetWindow(HWND *phWnd) override
|
||||
{
|
||||
*phWnd = m_hWnd;
|
||||
if (!m_hWnd)
|
||||
return E_NOTIMPL;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode) override
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
};
|
||||
|
||||
EXTERN_C HRESULT
|
||||
BindCtx_RegisterObjectParam(
|
||||
_In_ IBindCtx *pBindCtx,
|
||||
_In_ LPOLESTR pszKey,
|
||||
_In_opt_ IUnknown *punk,
|
||||
_Out_ LPBC *ppbc)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
CDummyOleWindow *pUnknown = NULL;
|
||||
|
||||
*ppbc = pBindCtx;
|
||||
|
||||
if (pBindCtx)
|
||||
{
|
||||
pBindCtx->AddRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = CreateBindCtx(0, ppbc);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (!punk)
|
||||
punk = pUnknown = new CDummyOleWindow();
|
||||
|
||||
hr = (*ppbc)->RegisterObjectParam(pszKey, punk);
|
||||
|
||||
if (pUnknown)
|
||||
pUnknown->Release();
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
(*ppbc)->Release();
|
||||
*ppbc = NULL;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* SHSetFolderPathA (SHELL32.231)
|
||||
*
|
||||
|
|
|
@ -54,6 +54,15 @@ extern BOOL WINAPI Free(LPVOID);
|
|||
static LPSTR _ILGetSTextPointer(LPCITEMIDLIST pidl);
|
||||
static LPWSTR _ILGetTextPointerW(LPCITEMIDLIST pidl);
|
||||
|
||||
EXTERN_C HWND BindCtx_GetUIWindow(_In_ IBindCtx *pBindCtx);
|
||||
|
||||
EXTERN_C HRESULT
|
||||
BindCtx_RegisterObjectParam(
|
||||
_In_ IBindCtx *pBindCtx,
|
||||
_In_ LPOLESTR pszKey,
|
||||
_In_opt_ IUnknown *punk,
|
||||
_Out_ LPBC *ppbc);
|
||||
|
||||
/*************************************************************************
|
||||
* ILGetDisplayNameExA
|
||||
*
|
||||
|
@ -1396,39 +1405,59 @@ HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCI
|
|||
HRESULT WINAPI SHParseDisplayName(LPCWSTR pszName, IBindCtx *pbc,
|
||||
LPITEMIDLIST *ppidl, SFGAOF sfgaoIn, SFGAOF *psfgaoOut)
|
||||
{
|
||||
HRESULT hr;
|
||||
LPWSTR pszNameDup;
|
||||
IShellFolder *psfDesktop;
|
||||
HRESULT hr=E_FAIL;
|
||||
ULONG dwAttr=sfgaoIn;
|
||||
IBindCtx *pBindCtx = NULL;
|
||||
|
||||
if(!ppidl)
|
||||
return E_INVALIDARG;
|
||||
TRACE("(%s, %p, %p, 0x%X, %p)\n", pszName, pbc, ppidl, sfgaoIn, psfgaoOut);
|
||||
|
||||
if (!pszName)
|
||||
{
|
||||
*ppidl = NULL;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (psfgaoOut)
|
||||
*psfgaoOut = 0;
|
||||
|
||||
pszNameDup = StrDupW(pszName);
|
||||
if (!pszNameDup)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
psfDesktop = NULL;
|
||||
hr = SHGetDesktopFolder(&psfDesktop);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
*ppidl = NULL;
|
||||
LocalFree(pszNameDup);
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = IShellFolder_ParseDisplayName(psfDesktop, (HWND)NULL, pbc, (LPOLESTR)pszName, (ULONG *)NULL, ppidl, &dwAttr);
|
||||
|
||||
IShellFolder_Release(psfDesktop);
|
||||
if (!pbc)
|
||||
{
|
||||
hr = BindCtx_RegisterObjectParam(NULL, STR_PARSE_TRANSLATE_ALIASES, NULL, &pBindCtx);
|
||||
pbc = pBindCtx;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (psfgaoOut) *psfgaoOut = dwAttr;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppidl = NULL;
|
||||
ULONG sfgao = sfgaoIn, cchEaten;
|
||||
HWND hwndUI = BindCtx_GetUIWindow(pbc);
|
||||
hr = psfDesktop->lpVtbl->ParseDisplayName(psfDesktop,
|
||||
hwndUI,
|
||||
pbc,
|
||||
pszNameDup,
|
||||
&cchEaten,
|
||||
ppidl,
|
||||
(psfgaoOut ? &sfgao : NULL));
|
||||
if (SUCCEEDED(hr) && psfgaoOut)
|
||||
*psfgaoOut = (sfgao & sfgaoIn);
|
||||
}
|
||||
|
||||
LocalFree(pszNameDup);
|
||||
|
||||
if (psfDesktop)
|
||||
psfDesktop->lpVtbl->Release(psfDesktop);
|
||||
|
||||
if (pBindCtx)
|
||||
pBindCtx->lpVtbl->Release(pBindCtx);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
|
@ -1104,14 +1104,14 @@ static const CSIDL_DATA CSIDL_Data[] =
|
|||
{ /* 0x03 - CSIDL_CONTROLS (.CPL files) */
|
||||
&FOLDERID_ControlPanelFolder,
|
||||
CSIDL_Type_SystemPath,
|
||||
NULL,
|
||||
L"ControlPanelFolder",
|
||||
NULL,
|
||||
-IDI_SHELL_CONTROL_PANEL
|
||||
},
|
||||
{ /* 0x04 - CSIDL_PRINTERS */
|
||||
&FOLDERID_PrintersFolder,
|
||||
CSIDL_Type_SystemPath,
|
||||
NULL,
|
||||
L"PrintersFolder",
|
||||
NULL,
|
||||
-IDI_SHELL_PRINTERS_FOLDER
|
||||
},
|
||||
|
@ -1151,7 +1151,7 @@ static const CSIDL_DATA CSIDL_Data[] =
|
|||
{ /* 0x0a - CSIDL_BITBUCKET - Recycle Bin */
|
||||
&FOLDERID_RecycleBinFolder,
|
||||
CSIDL_Type_Disallowed,
|
||||
NULL,
|
||||
L"RecycleBinFolder",
|
||||
NULL
|
||||
},
|
||||
{ /* 0x0b - CSIDL_STARTMENU */
|
||||
|
@ -1210,14 +1210,14 @@ static const CSIDL_DATA CSIDL_Data[] =
|
|||
{ /* 0x11 - CSIDL_DRIVES */
|
||||
&FOLDERID_ComputerFolder,
|
||||
CSIDL_Type_Disallowed,
|
||||
NULL,
|
||||
L"MyComputerFolder",
|
||||
NULL,
|
||||
-IDI_SHELL_COMPUTER_FOLDER
|
||||
},
|
||||
{ /* 0x12 - CSIDL_NETWORK */
|
||||
&FOLDERID_NetworkFolder,
|
||||
CSIDL_Type_Disallowed,
|
||||
NULL,
|
||||
L"NetworkPlacesFolder",
|
||||
NULL,
|
||||
-IDI_SHELL_NETWORK_FOLDER
|
||||
},
|
||||
|
@ -1341,21 +1341,21 @@ static const CSIDL_DATA CSIDL_Data[] =
|
|||
{ /* 0x24 - CSIDL_WINDOWS */
|
||||
&FOLDERID_Windows,
|
||||
CSIDL_Type_WindowsPath,
|
||||
NULL,
|
||||
L"Windows",
|
||||
NULL,
|
||||
-IDI_SHELL_SYSTEM_GEAR
|
||||
},
|
||||
{ /* 0x25 - CSIDL_SYSTEM */
|
||||
&FOLDERID_System,
|
||||
CSIDL_Type_SystemPath,
|
||||
NULL,
|
||||
L"System",
|
||||
NULL,
|
||||
-IDI_SHELL_SYSTEM_GEAR
|
||||
},
|
||||
{ /* 0x26 - CSIDL_PROGRAM_FILES */
|
||||
&FOLDERID_ProgramFiles,
|
||||
CSIDL_Type_CurrVer,
|
||||
L"ProgramFilesDir",
|
||||
L"ProgramFiles",
|
||||
MAKEINTRESOURCEW(IDS_PROGRAM_FILES),
|
||||
#ifdef __REACTOS__
|
||||
0
|
||||
|
@ -1390,21 +1390,21 @@ static const CSIDL_DATA CSIDL_Data[] =
|
|||
{ /* 0x2a - CSIDL_PROGRAM_FILESX86 */
|
||||
&FOLDERID_ProgramFilesX86,
|
||||
CSIDL_Type_CurrVer,
|
||||
L"ProgramFilesDir (x86)",
|
||||
L"ProgramFilesX86",
|
||||
L"Program Files (x86)",
|
||||
-IDI_SHELL_PROGRAMS_FOLDER
|
||||
},
|
||||
{ /* 0x2b - CSIDL_PROGRAM_FILES_COMMON */
|
||||
&FOLDERID_ProgramFilesCommon,
|
||||
CSIDL_Type_CurrVer,
|
||||
L"CommonFilesDir",
|
||||
L"ProgramFilesCommon",
|
||||
MAKEINTRESOURCEW(IDS_PROGRAM_FILES_COMMON),
|
||||
-IDI_SHELL_PROGRAMS_FOLDER
|
||||
},
|
||||
{ /* 0x2c - CSIDL_PROGRAM_FILES_COMMONX86 */
|
||||
&FOLDERID_ProgramFilesCommonX86,
|
||||
CSIDL_Type_CurrVer,
|
||||
L"CommonFilesDir (x86)",
|
||||
L"ProgramFilesCommonX86",
|
||||
L"Program Files (x86)\\Common Files",
|
||||
-IDI_SHELL_PROGRAMS_FOLDER
|
||||
},
|
||||
|
@ -1436,7 +1436,7 @@ static const CSIDL_DATA CSIDL_Data[] =
|
|||
{ /* 0x31 - CSIDL_CONNECTIONS */
|
||||
&FOLDERID_ConnectionsFolder,
|
||||
CSIDL_Type_Disallowed,
|
||||
NULL,
|
||||
L"ConnectionsFolder",
|
||||
NULL,
|
||||
-IDI_SHELL_NETWORK_CONNECTIONS
|
||||
},
|
||||
|
@ -1842,6 +1842,43 @@ static const CSIDL_DATA CSIDL_Data[] =
|
|||
#endif
|
||||
};
|
||||
|
||||
INT SHGetSpecialFolderID(_In_ LPCWSTR pszName)
|
||||
{
|
||||
UINT csidl;
|
||||
|
||||
for (csidl = 0; csidl < _countof(CSIDL_Data); ++csidl)
|
||||
{
|
||||
const CSIDL_DATA *pData = &CSIDL_Data[csidl];
|
||||
if (pData->szValueName && lstrcmpiW(pszName, pData->szValueName) == 0)
|
||||
return csidl;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
INT Shell_ParseSpecialFolder(_In_ LPCWSTR pszStart, _Out_ LPWSTR *ppch, _Out_ INT *pcch)
|
||||
{
|
||||
LPCWSTR pszPath, pchBackslash;
|
||||
WCHAR szPath[MAX_PATH];
|
||||
|
||||
pchBackslash = StrChrW(pszStart, L'\\');
|
||||
if (pchBackslash)
|
||||
{
|
||||
*ppch = (LPWSTR)(pchBackslash + 1);
|
||||
*pcch = (pchBackslash - pszStart) + 1;
|
||||
StrCpyNW(szPath, pszStart, max(*pcch, _countof(szPath)));
|
||||
pszPath = szPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppch = NULL;
|
||||
*pcch = lstrlenW(pszStart);
|
||||
pszPath = pszStart;
|
||||
}
|
||||
|
||||
return SHGetSpecialFolderID(pszPath);
|
||||
}
|
||||
|
||||
#ifndef __REACTOS__
|
||||
static HRESULT _SHExpandEnvironmentStrings(LPCWSTR szSrc, LPWSTR szDest);
|
||||
#else
|
||||
|
|
|
@ -219,6 +219,12 @@ interface IShellFolder : IUnknown
|
|||
cpp_quote("#define SFGAO_STORAGECAPMASK 0x70C50008L")
|
||||
cpp_quote("#define SFGAO_PKEYSFGAOMASK 0x81044000L")
|
||||
|
||||
cpp_quote("#define STR_PARSE_SHELL_PROTOCOL_TO_FILE_OBJECTS L\"Parse Shell Protocol To File Objects\"")
|
||||
cpp_quote("#define STR_FILE_SYS_BIND_DATA L\"File System Bind Data\"")
|
||||
cpp_quote("#define STR_PARSE_PREFER_FOLDER_BROWSING L\"Parse Prefer Folder Browsing\"")
|
||||
cpp_quote("#define STR_PARSE_TRANSLATE_ALIASES L\"Parse Translate Aliases\"")
|
||||
cpp_quote("#define STR_DONT_PARSE_RELATIVE L\"Don't Parse Relative\"")
|
||||
|
||||
typedef ULONG SFGAOF;
|
||||
|
||||
HRESULT ParseDisplayName(
|
||||
|
|
|
@ -322,6 +322,8 @@ IContextMenu_Invoke(
|
|||
_In_ LPCSTR lpVerb,
|
||||
_In_ UINT uFlags);
|
||||
|
||||
DWORD WINAPI SHGetObjectCompatFlags(IUnknown *pUnk, const CLSID *clsid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
|
Loading…
Reference in a new issue