[SHELL32]

- Get rid of the functions that handle guid pidls and move their implementation in CRegFolder.cpp.

svn path=/trunk/; revision=72208
This commit is contained in:
Giannis Adamopoulos 2016-08-12 12:21:13 +00:00
parent b3195b9538
commit 43728d3f66
5 changed files with 327 additions and 410 deletions

View file

@ -192,88 +192,6 @@ GetIconOverlay(LPCITEMIDLIST pidl, WCHAR * wTemp, int* pIndex)
return FALSE;
}
HRESULT CGuidItemExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut)
{
CComPtr<IDefaultExtractIconInit> initIcon;
HRESULT hr;
GUID const * riid;
int icon_idx;
WCHAR wTemp[MAX_PATH];
hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit,&initIcon));
if (FAILED(hr))
return hr;
if (_ILIsDesktop(pidl))
{
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DESKTOP);
return initIcon->QueryInterface(iid, ppvOut);
}
riid = _ILGetGUIDPointer(pidl);
if (!riid)
return E_FAIL;
/* my computer and other shell extensions */
static const WCHAR fmt[] = { 'C', 'L', 'S', 'I', 'D', '\\',
'{', '%', '0', '8', 'l', 'x', '-', '%', '0', '4', 'x', '-', '%', '0', '4', 'x', '-',
'%', '0', '2', 'x', '%', '0', '2', 'x', '-', '%', '0', '2', 'x', '%', '0', '2', 'x',
'%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '}', 0
};
WCHAR xriid[50];
swprintf(xriid, fmt,
riid->Data1, riid->Data2, riid->Data3,
riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]);
const WCHAR* iconname = NULL;
if (_ILIsBitBucket(pidl))
{
static const WCHAR szFull[] = {'F','u','l','l',0};
static const WCHAR szEmpty[] = {'E','m','p','t','y',0};
CComPtr<IEnumIDList> EnumIDList;
CoInitialize(NULL);
CComPtr<IShellFolder2> psfRecycleBin;
CComPtr<IShellFolder> psfDesktop;
hr = SHGetDesktopFolder(&psfDesktop);
if (SUCCEEDED(hr))
hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder2, &psfRecycleBin));
if (SUCCEEDED(hr))
hr = psfRecycleBin->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &EnumIDList);
ULONG itemcount;
LPITEMIDLIST pidl = NULL;
if (SUCCEEDED(hr) && (hr = EnumIDList->Next(1, &pidl, &itemcount)) == S_OK)
{
CoTaskMemFree(pidl);
iconname = szFull;
} else {
iconname = szEmpty;
}
}
if (HCR_GetIconW(xriid, wTemp, iconname, MAX_PATH, &icon_idx))
{
initIcon->SetNormalIcon(wTemp, icon_idx);
}
else
{
if (IsEqualGUID(*riid, CLSID_MyComputer))
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_COMPUTER);
else if (IsEqualGUID(*riid, CLSID_MyDocuments))
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_DOCUMENTS);
else if (IsEqualGUID(*riid, CLSID_NetworkPlaces))
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_NETWORK_PLACES);
else
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_FOLDER);
}
return initIcon->QueryInterface(iid, ppvOut);
}
HRESULT CFSExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut)
{
CComPtr<IDefaultExtractIconInit> initIcon;

View file

@ -22,6 +22,88 @@
WINE_DEFAULT_DEBUG_CHANNEL (shell);
HRESULT CGuidItemExtractIcon_CreateInstance(LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut)
{
CComPtr<IDefaultExtractIconInit> initIcon;
HRESULT hr;
GUID const * riid;
int icon_idx;
WCHAR wTemp[MAX_PATH];
hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit,&initIcon));
if (FAILED(hr))
return hr;
if (_ILIsDesktop(pidl))
{
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DESKTOP);
return initIcon->QueryInterface(iid, ppvOut);
}
riid = _ILGetGUIDPointer(pidl);
if (!riid)
return E_FAIL;
/* my computer and other shell extensions */
static const WCHAR fmt[] = { 'C', 'L', 'S', 'I', 'D', '\\',
'{', '%', '0', '8', 'l', 'x', '-', '%', '0', '4', 'x', '-', '%', '0', '4', 'x', '-',
'%', '0', '2', 'x', '%', '0', '2', 'x', '-', '%', '0', '2', 'x', '%', '0', '2', 'x',
'%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '}', 0
};
WCHAR xriid[50];
swprintf(xriid, fmt,
riid->Data1, riid->Data2, riid->Data3,
riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]);
const WCHAR* iconname = NULL;
if (_ILIsBitBucket(pidl))
{
static const WCHAR szFull[] = {'F','u','l','l',0};
static const WCHAR szEmpty[] = {'E','m','p','t','y',0};
CComPtr<IEnumIDList> EnumIDList;
CoInitialize(NULL);
CComPtr<IShellFolder2> psfRecycleBin;
CComPtr<IShellFolder> psfDesktop;
hr = SHGetDesktopFolder(&psfDesktop);
if (SUCCEEDED(hr))
hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder2, &psfRecycleBin));
if (SUCCEEDED(hr))
hr = psfRecycleBin->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &EnumIDList);
ULONG itemcount;
LPITEMIDLIST pidl = NULL;
if (SUCCEEDED(hr) && (hr = EnumIDList->Next(1, &pidl, &itemcount)) == S_OK)
{
CoTaskMemFree(pidl);
iconname = szFull;
} else {
iconname = szEmpty;
}
}
if (HCR_GetIconW(xriid, wTemp, iconname, MAX_PATH, &icon_idx))
{
initIcon->SetNormalIcon(wTemp, icon_idx);
}
else
{
if (IsEqualGUID(*riid, CLSID_MyComputer))
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_COMPUTER);
else if (IsEqualGUID(*riid, CLSID_MyDocuments))
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_DOCUMENTS);
else if (IsEqualGUID(*riid, CLSID_NetworkPlaces))
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_NETWORK_PLACES);
else
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_FOLDER);
}
return initIcon->QueryInterface(iid, ppvOut);
}
class CRegFolder :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellFolder2
@ -31,6 +113,7 @@ class CRegFolder :
CAtlStringW m_rootPath;
CComHeapPtr<ITEMIDLIST> m_pidlRoot;
HRESULT GetGuidItemAttributes (LPCITEMIDLIST pidl, LPDWORD pdwAttributes);
public:
CRegFolder();
~CRegFolder();
@ -90,10 +173,67 @@ HRESULT WINAPI CRegFolder::Initialize(const GUID *pGuid, LPCITEMIDLIST pidlRoot,
return S_OK;
}
HRESULT CRegFolder::GetGuidItemAttributes (LPCITEMIDLIST pidl, LPDWORD pdwAttributes)
{
/* First try to get them from the registry */
if (HCR_GetFolderAttributes(pidl, pdwAttributes) && *pdwAttributes)
{
return S_OK;
}
else
{
/* If we can't get it from the registry we have to query the child */
CComPtr<IShellFolder> psf2;
if (SUCCEEDED(BindToObject(pidl, 0, IID_PPV_ARG(IShellFolder, &psf2))))
{
return psf2->GetAttributesOf(0, NULL, pdwAttributes);
}
}
*pdwAttributes &= SFGAO_CANLINK;
return S_OK;
}
HRESULT WINAPI CRegFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes)
{
return SH_ParseGuidDisplayName(this, hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
LPITEMIDLIST pidl;
if (!lpszDisplayName || !ppidl)
return E_INVALIDARG;
*ppidl = 0;
if (pchEaten)
*pchEaten = 0;
UINT cch = wcslen(lpszDisplayName);
if (cch < 39 || lpszDisplayName[0] != L':' || lpszDisplayName[1] != L':')
return E_FAIL;
pidl = _ILCreateGuidFromStrW(lpszDisplayName + 2);
if (pidl == NULL)
return E_FAIL;
if (cch < 41)
{
*ppidl = pidl;
if (pdwAttributes && *pdwAttributes)
{
GetGuidItemAttributes(*ppidl, pdwAttributes);
}
}
else
{
HRESULT hr = SHELL32_ParseNextElement(this, hwndOwner, pbc, &pidl, lpszDisplayName + 41, pchEaten, pdwAttributes);
if (SUCCEEDED(hr))
{
*ppidl = pidl;
}
return hr;
}
return S_OK;
}
HRESULT WINAPI CRegFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
@ -103,7 +243,39 @@ HRESULT WINAPI CRegFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLI
HRESULT WINAPI CRegFolder::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
{
return SHELL32_BindToGuidItem(m_pidlRoot, pidl, pbcReserved, riid, ppvOut);
CComPtr<IPersistFolder> pFolder;
HRESULT hr;
if (!ppvOut || !pidl || !pidl->mkid.cb)
return E_INVALIDARG;
*ppvOut = NULL;
GUID *pGUID = _ILGetGUIDPointer(pidl);
if (!pGUID)
{
ERR("CRegFolder::BindToObject called for non guid item!\n");
return E_INVALIDARG;
}
LPITEMIDLIST pidlChild = ILCloneFirst (pidl);
if (!pidlChild)
return E_OUTOFMEMORY;
CComPtr<IShellFolder> psf;
hr = SHELL32_CoCreateInitSF(m_pidlRoot, NULL, pidlChild, pGUID, -1, IID_PPV_ARG(IShellFolder, &psf));
ILFree(pidlChild);
if (FAILED(hr))
return hr;
if (_ILIsPidlSimple (pidl))
{
return psf->QueryInterface(riid, ppvOut);
}
else
{
return psf->BindToObject(ILGetNext (pidl), pbcReserved, riid, ppvOut);
}
}
HRESULT WINAPI CRegFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
@ -113,7 +285,27 @@ HRESULT WINAPI CRegFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserv
HRESULT WINAPI CRegFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
{
return SHELL32_CompareGuidItems(this, lParam, pidl1, pidl2);
if (!pidl1 || !pidl2 || pidl1->mkid.cb == 0 || pidl2->mkid.cb == 0)
{
ERR("Got an empty pidl!\n");
return E_INVALIDARG;
}
BOOL bIsGuidFolder1 = _ILIsSpecialFolder(pidl1);
BOOL bIsGuidFolder2 = _ILIsSpecialFolder(pidl2);
if (!bIsGuidFolder1 && !bIsGuidFolder2)
{
ERR("Got no guid pidl!\n");
return E_INVALIDARG;
}
else if (bIsGuidFolder1 && bIsGuidFolder2)
{
return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
}
/* Guid folders come first compared to everything else */
return MAKE_COMPARE_HRESULT(bIsGuidFolder1 ? -1 : 1);
}
HRESULT WINAPI CRegFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
@ -132,7 +324,7 @@ HRESULT WINAPI CRegFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apid
while(cidl > 0 && *apidl)
{
if (_ILIsSpecialFolder(*apidl))
SHELL32_GetGuidItemAttributes(this, *apidl, rgfInOut);
GetGuidItemAttributes(*apidl, rgfInOut);
else
ERR("Got an unkown pidl here!\n");
apidl++;
@ -158,7 +350,7 @@ HRESULT WINAPI CRegFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CH
if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1))
{
hr = CGuidItemExtractIcon_CreateInstance(this, apidl[0], riid, &pObj);
hr = CGuidItemExtractIcon_CreateInstance(apidl[0], riid, &pObj);
}
else
hr = E_NOINTERFACE;
@ -190,20 +382,119 @@ HRESULT WINAPI CRegFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags,
return S_OK;
}
if (pidl->mkid.cb)
HRESULT hr;
GUID const *clsid = _ILGetGUIDPointer (pidl);
/* First of all check if we need to query the name from the child item */
if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING &&
GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL)
{
return SHELL32_GetDisplayNameOfGUIDItem(this, m_rootPath, pidl, dwFlags, strRet);
int bWantsForParsing = FALSE;
/*
* We can only get a filesystem path from a shellfolder if the
* value WantsFORPARSING in CLSID\\{...}\\shellfolder exists.
*
* Exception: The MyComputer folder doesn't have this key,
* but any other filesystem backed folder it needs it.
*/
if (IsEqualIID (*clsid, CLSID_MyComputer))
{
bWantsForParsing = TRUE;
}
else
{
HKEY hkeyClass;
if (HCR_RegOpenClassIDKey(*clsid, &hkeyClass))
{
LONG res = SHGetValueW(hkeyClass, L"Shellfolder", L"WantsForParsing", NULL, NULL, NULL);
bWantsForParsing = (res == ERROR_SUCCESS);
RegCloseKey(hkeyClass);
}
}
if (bWantsForParsing)
{
/*
* we need the filesystem path to the destination folder.
* Only the folder itself can know it
*/
return SHELL32_GetDisplayNameOfChild (this, pidl, dwFlags, strRet);
}
}
return E_FAIL;
/* Allocate the buffer for the result */
LPWSTR pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
if (!pszPath)
return E_OUTOFMEMORY;
hr = S_OK;
if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING)
{
wcscpy(pszPath, m_rootPath);
PWCHAR pItemName = &pszPath[wcslen(pszPath)];
/* parsing name like ::{...} */
pItemName[0] = ':';
pItemName[1] = ':';
SHELL32_GUIDToStringW (*clsid, &pItemName[2]);
}
else
{
/* user friendly name */
if (!HCR_GetClassNameW (*clsid, pszPath, MAX_PATH))
hr = E_FAIL;
}
if (SUCCEEDED(hr))
{
strRet->uType = STRRET_WSTR;
strRet->pOleStr = pszPath;
}
else
{
CoTaskMemFree(pszPath);
}
return hr;
}
HRESULT WINAPI CRegFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, /* simple pidl */
LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut)
{
return SHELL32_SetNameOfGuidItem(pidl, lpName, dwFlags, pPidlOut);
GUID const *clsid = _ILGetGUIDPointer (pidl);
LPOLESTR pStr;
HRESULT hr;
WCHAR szName[100];
if (!clsid)
{
ERR("Pidl is not reg item!\n");
return E_FAIL;
}
hr = StringFromCLSID(*clsid, &pStr);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
swprintf(szName, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\%s", pStr);
DWORD cbData = (wcslen(lpName) + 1) * sizeof(WCHAR);
LONG res = SHSetValueW(HKEY_CURRENT_USER, szName, NULL, RRF_RT_REG_SZ, lpName, cbData);
CoTaskMemFree(pStr);
if (res == ERROR_SUCCESS)
{
*pPidlOut = ILClone(pidl);
return S_OK;
}
return E_FAIL;
}
HRESULT WINAPI CRegFolder::GetDefaultSearchGUID(GUID *pguid)
{
return E_NOTIMPL;
@ -242,7 +533,30 @@ HRESULT WINAPI CRegFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHEL
if (!psd || iColumn >= 2)
return E_INVALIDARG;
return SHELL32_GetDetailsOfGuidItem(this, pidl, iColumn, psd);
GUID const *clsid = _ILGetGUIDPointer (pidl);
if (!clsid)
{
ERR("Pidl is not reg item!\n");
return E_INVALIDARG;
}
switch(iColumn)
{
case 0: /* name */
return GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
case 1: /* comment */
HKEY hKey;
if (HCR_RegOpenClassIDKey(*clsid, &hKey))
{
psd->str.cStr[0] = 0x00;
psd->str.uType = STRRET_CSTR;
RegLoadMUIStringA(hKey, "InfoTip", psd->str.cStr, MAX_PATH, NULL, 0, NULL);
RegCloseKey(hKey);
return S_OK;
}
}
return E_FAIL;
}
HRESULT WINAPI CRegFolder::MapColumnToSCID(UINT column, SHCOLUMNID *pscid)
@ -250,6 +564,7 @@ HRESULT WINAPI CRegFolder::MapColumnToSCID(UINT column, SHCOLUMNID *pscid)
return E_NOTIMPL;
}
/* In latest windows version this is exported but it takes different arguments! */
HRESULT CRegFolder_CreateInstance(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath, REFIID riid, void **ppv)
{
return ShellObjectCreatorInit<CRegFolder>(pGuid, pidlRoot, lpszPath, riid, ppv);

View file

@ -49,34 +49,10 @@ HRESULT SHELL32_BindToFS (LPCITEMIDLIST pidlRoot,
LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path);
HRESULT SHELL32_BindToGuidItem(LPCITEMIDLIST pidlRoot,
PCUIDLIST_RELATIVE pidl,
LPBC pbcReserved,
REFIID riid,
LPVOID *ppvOut);
HRESULT SHELL32_GetGuidItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes);
HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes);
HRESULT SHELL32_GetDisplayNameOfGUIDItem(IShellFolder2* psf, LPCWSTR pszFolderPath, PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet);
HRESULT SHELL32_SetNameOfGuidItem(PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut);
HRESULT SHELL32_GetDetailsOfGuidItem(IShellFolder2* psf, PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd);
HRESULT SH_ParseGuidDisplayName(IShellFolder2 * pFolder,
HWND hwndOwner,
LPBC pbc,
LPOLESTR lpszDisplayName,
DWORD *pchEaten,
PIDLIST_RELATIVE *ppidl,
DWORD *pdwAttributes);
HRESULT SHELL32_CompareDetails(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
HRESULT SHELL32_CompareGuidItems(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot,
LPCITEMIDLIST pidlChild, const GUID* clsid, int csidl, REFIID riid, LPVOID *ppvOut);
@ -107,8 +83,6 @@ static __inline int SHELL32_GUIDToStringW (REFGUID guid, LPWSTR str)
void SHELL_FS_ProcessDisplayFilename(LPWSTR szPath, DWORD dwFlags);
BOOL SHELL_FS_HideExtension(LPWSTR pwszPath);
HRESULT CRegFolder_CreateInstance(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath, REFIID riid, void **ppv);
#ifdef __cplusplus
HRESULT inline SHSetStrRet(LPSTRRET pStrRet, DWORD resId)

View file

@ -287,47 +287,6 @@ HRESULT SHELL32_BindToFS (LPCITEMIDLIST pidlRoot,
return hr;
}
HRESULT SHELL32_BindToGuidItem(LPCITEMIDLIST pidlRoot,
PCUIDLIST_RELATIVE pidl,
LPBC pbcReserved,
REFIID riid,
LPVOID *ppvOut)
{
CComPtr<IPersistFolder> pFolder;
HRESULT hr;
if (!pidlRoot || !ppvOut || !pidl || !pidl->mkid.cb)
return E_INVALIDARG;
*ppvOut = NULL;
GUID *pGUID = _ILGetGUIDPointer(pidl);
if (!pGUID)
{
ERR("SHELL32_BindToGuidItem called for non guid item!\n");
return E_INVALIDARG;
}
LPITEMIDLIST pidlChild = ILCloneFirst (pidl);
if (!pidlChild)
return E_OUTOFMEMORY;
CComPtr<IShellFolder> psf;
hr = SHELL32_CoCreateInitSF(pidlRoot, NULL, pidlChild, pGUID, -1, IID_PPV_ARG(IShellFolder, &psf));
ILFree(pidlChild);
if (FAILED(hr))
return hr;
if (_ILIsPidlSimple (pidl))
{
return psf->QueryInterface(riid, ppvOut);
}
else
{
return psf->BindToObject(ILGetNext (pidl), pbcReserved, riid, ppvOut);
}
}
/***********************************************************************
* SHELL32_GetDisplayNameOfChild
*
@ -371,89 +330,6 @@ HRESULT HCR_GetClassName(REFIID riid, LPSTRRET strRet)
return SHSetStrRet(strRet, wstrName);
}
HRESULT SHELL32_GetDisplayNameOfGUIDItem(IShellFolder2* psf, LPCWSTR pszFolderPath, PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
{
HRESULT hr;
GUID const *clsid = _ILGetGUIDPointer (pidl);
if (!strRet)
return E_INVALIDARG;
/* First of all check if we need to query the name from the child item */
if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING &&
GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL)
{
int bWantsForParsing = FALSE;
/*
* We can only get a filesystem path from a shellfolder if the
* value WantsFORPARSING in CLSID\\{...}\\shellfolder exists.
*
* Exception: The MyComputer folder doesn't have this key,
* but any other filesystem backed folder it needs it.
*/
if (IsEqualIID (*clsid, CLSID_MyComputer))
{
bWantsForParsing = TRUE;
}
else
{
HKEY hkeyClass;
if (HCR_RegOpenClassIDKey(*clsid, &hkeyClass))
{
LONG res = SHGetValueW(hkeyClass, L"Shellfolder", L"WantsForParsing", NULL, NULL, NULL);
bWantsForParsing = (res == ERROR_SUCCESS);
RegCloseKey(hkeyClass);
}
}
if (bWantsForParsing)
{
/*
* we need the filesystem path to the destination folder.
* Only the folder itself can know it
*/
return SHELL32_GetDisplayNameOfChild (psf, pidl, dwFlags, strRet);
}
}
/* Allocate the buffer for the result */
LPWSTR pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
if (!pszPath)
return E_OUTOFMEMORY;
hr = S_OK;
if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING)
{
wcscpy(pszPath, pszFolderPath);
PWCHAR pItemName = &pszPath[wcslen(pszPath)];
/* parsing name like ::{...} */
pItemName[0] = ':';
pItemName[1] = ':';
SHELL32_GUIDToStringW (*clsid, &pItemName[2]);
}
else
{
/* user friendly name */
if (!HCR_GetClassNameW (*clsid, pszPath, MAX_PATH))
hr = E_FAIL;
}
if (SUCCEEDED(hr))
{
strRet->uType = STRRET_WSTR;
strRet->pOleStr = pszPath;
}
else
{
CoTaskMemFree(pszPath);
}
return hr;
}
/***********************************************************************
* SHELL32_GetItemAttributes
*
@ -490,40 +366,6 @@ static const DWORD dwSupportedAttr=
SFGAO_FILESYSTEM | /*0x40000000 */
SFGAO_HASSUBFOLDER; /*0x80000000 */
HRESULT SHELL32_GetGuidItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes)
{
if (!_ILIsSpecialFolder(pidl))
{
ERR("Got wrong type of pidl!\n");
*pdwAttributes &= SFGAO_CANLINK;
return S_OK;
}
if (*pdwAttributes & ~dwSupportedAttr)
{
WARN ("attributes 0x%08x not implemented\n", (*pdwAttributes & ~dwSupportedAttr));
*pdwAttributes &= dwSupportedAttr;
}
/* First try to get them from the registry */
if (HCR_GetFolderAttributes(pidl, pdwAttributes) && *pdwAttributes)
{
return S_OK;
}
else
{
/* If we can't get it from the registry we have to query the child */
CComPtr<IShellFolder> psf2;
if (SUCCEEDED(psf->BindToObject(pidl, 0, IID_PPV_ARG(IShellFolder, &psf2))))
{
return psf2->GetAttributesOf(0, NULL, pdwAttributes);
}
}
*pdwAttributes &= SFGAO_CANLINK;
return S_OK;
}
HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes)
{
DWORD dwFileAttributes, dwShellAttributes;
@ -607,139 +449,6 @@ HRESULT SHELL32_CompareDetails(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST
return MAKE_COMPARE_HRESULT(ret);
}
HRESULT SHELL32_CompareGuidItems(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
{
if (pidl1->mkid.cb == 0 || pidl2->mkid.cb == 0)
{
ERR("Got an empty pidl!\n");
return E_INVALIDARG;
}
BOOL bIsGuidFolder1 = _ILIsSpecialFolder(pidl1);
BOOL bIsGuidFolder2 = _ILIsSpecialFolder(pidl2);
if (!bIsGuidFolder1 && !bIsGuidFolder2)
{
ERR("Got no guid pidl!\n");
return E_INVALIDARG;
}
else if (bIsGuidFolder1 && bIsGuidFolder2)
{
return SHELL32_CompareDetails(isf, lParam, pidl1, pidl2);
}
/* Guid folders come first compared to everything else */
return MAKE_COMPARE_HRESULT(bIsGuidFolder1 ? -1 : 1);
}
HRESULT SH_ParseGuidDisplayName(IShellFolder2 * pFolder,
HWND hwndOwner,
LPBC pbc,
LPOLESTR lpszDisplayName,
DWORD *pchEaten,
PIDLIST_RELATIVE *ppidl,
DWORD *pdwAttributes)
{
LPITEMIDLIST pidl;
if (!lpszDisplayName || !ppidl)
return E_INVALIDARG;
*ppidl = 0;
if (pchEaten)
*pchEaten = 0;
UINT cch = wcslen(lpszDisplayName);
if (cch < 39 || lpszDisplayName[0] != L':' || lpszDisplayName[1] != L':')
return E_FAIL;
pidl = _ILCreateGuidFromStrW(lpszDisplayName + 2);
if (pidl == NULL)
return E_FAIL;
if (cch < 41)
{
*ppidl = pidl;
if (pdwAttributes && *pdwAttributes)
{
SHELL32_GetGuidItemAttributes(pFolder, *ppidl, pdwAttributes);
}
}
else
{
HRESULT hr = SHELL32_ParseNextElement(pFolder, hwndOwner, pbc, &pidl, lpszDisplayName + 41, pchEaten, pdwAttributes);
if (SUCCEEDED(hr))
{
*ppidl = pidl;
}
return hr;
}
return S_OK;
}
HRESULT SHELL32_SetNameOfGuidItem(PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut)
{
GUID const *clsid = _ILGetGUIDPointer (pidl);
LPOLESTR pStr;
HRESULT hr;
WCHAR szName[100];
if (!clsid)
{
ERR("Pidl is not reg item!\n");
return E_FAIL;
}
hr = StringFromCLSID(*clsid, &pStr);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
swprintf(szName, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\%s", pStr);
DWORD cbData = (wcslen(lpName) + 1) * sizeof(WCHAR);
LONG res = SHSetValueW(HKEY_CURRENT_USER, szName, NULL, RRF_RT_REG_SZ, lpName, cbData);
CoTaskMemFree(pStr);
if (res == ERROR_SUCCESS)
{
*pPidlOut = ILClone(pidl);
return S_OK;
}
return E_FAIL;
}
HRESULT SHELL32_GetDetailsOfGuidItem(IShellFolder2* psf, PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd)
{
GUID const *clsid = _ILGetGUIDPointer (pidl);
if (!clsid)
{
ERR("Pidl is not reg item!\n");
return E_FAIL;
}
switch(iColumn)
{
case 0: /* name */
return psf->GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
case 1: /* comment */
HKEY hKey;
if (HCR_RegOpenClassIDKey(*clsid, &hKey))
{
psd->str.cStr[0] = 0x00;
psd->str.uType = STRRET_CSTR;
RegLoadMUIStringA(hKey, "InfoTip", psd->str.cStr, MAX_PATH, NULL, 0, NULL);
RegCloseKey(hKey);
return S_OK;
}
}
return E_FAIL;
}
/***********************************************************************
* SHCreateLinks
*

View file

@ -80,9 +80,10 @@ HRESULT WINAPI IFileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC
HRESULT WINAPI CPanel_ExtractIconA(LPITEMIDLIST pidl, LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) DECLSPEC_HIDDEN;
HRESULT WINAPI CPanel_ExtractIconW(LPITEMIDLIST pidl, LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) DECLSPEC_HIDDEN;
HRESULT CGuidItemExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut);
HRESULT CFSExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut);
HRESULT CRegFolder_CreateInstance(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath, REFIID riid, void **ppv);
/* initialisation for FORMATETC */
#define InitFormatEtc(fe, cf, med) \
{\