[SHELL32]

- Add a few helper functions: SH_ParseGuidDisplayName, SHELL32_SetNameOfGuidItem, SHELL32_GetDetailsOfGuidItem.
- SHELL32_SetNameOfGuidItem is based on a patch for CORE-5995
- Use the helpers in CControlPanelFolder, CDesktopFolder and CDrivesFolder. Implements getting the comment and renaming registry items in these folders and share some more code.

svn path=/trunk/; revision=69328
This commit is contained in:
Giannis Adamopoulos 2015-09-23 15:02:05 +00:00
parent 6a3a86fe62
commit d7a9abc45b
5 changed files with 219 additions and 212 deletions

View file

@ -294,63 +294,8 @@ HRESULT WINAPI CControlPanelFolder::ParseDisplayName(
PIDLIST_RELATIVE *ppidl,
DWORD *pdwAttributes)
{
WCHAR szElement[MAX_PATH];
LPCWSTR szNext = NULL;
LPITEMIDLIST pidlTemp = NULL;
HRESULT hr = S_OK;
CLSID clsid;
TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
this, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName),
pchEaten, ppidl, pdwAttributes);
if (!lpszDisplayName || !ppidl)
return E_INVALIDARG;
*ppidl = 0;
if (pchEaten)
*pchEaten = 0; /* strange but like the original */
if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
{
szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
TRACE ("-- element: %s\n", debugstr_w (szElement));
CLSIDFromString (szElement + 2, &clsid);
pidlTemp = _ILCreateGuid (PT_GUID, clsid);
}
else if( (pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, lpszDisplayName)) )
{
*ppidl = pidlTemp;
return S_OK;
}
if (SUCCEEDED(hr) && pidlTemp)
{
if (szNext && *szNext)
{
hr = SHELL32_ParseNextElement(this, hwndOwner, pbc,
&pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes);
}
else
{
if (pdwAttributes && *pdwAttributes)
{
if (_ILIsCPanelStruct(pidlTemp))
*pdwAttributes &= SFGAO_CANLINK;
else if (_ILIsSpecialFolder(pidlTemp))
SHELL32_GetGuidItemAttributes(this, pidlTemp, pdwAttributes);
else
ERR("Got an unkown pidl here!\n");
}
}
}
*ppidl = pidlTemp;
TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr);
return hr;
/* We only support parsing guid names */
return SH_ParseGuidDisplayName(this, hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
}
/**************************************************************************
@ -626,46 +571,36 @@ HRESULT WINAPI CControlPanelFolder::GetDetailsEx(PCUITEMID_CHILD pidl, const SHC
HRESULT WINAPI CControlPanelFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd)
{
HRESULT hr;
TRACE("(%p)->(%p %i %p)\n", this, pidl, iColumn, psd);
if (!psd || iColumn >= CONROLPANELSHELLVIEWCOLUMNS)
return E_INVALIDARG;
if (!pidl) {
if (!pidl)
{
psd->fmt = ControlPanelSFHeader[iColumn].fmt;
psd->cxChar = ControlPanelSFHeader[iColumn].cxChar;
return SHSetStrRet(&psd->str, shell32_hInstance, ControlPanelSFHeader[iColumn].colnameid);
} else {
switch(iColumn) {
}
else if (_ILIsSpecialFolder(pidl))
{
return SHELL32_GetDetailsOfGuidItem(this, pidl, iColumn, psd);
}
else
{
PIDLCPanelStruct *pCPanel = _ILGetCPanelPointer(pidl);
if (!pCPanel)
return E_FAIL;
switch(iColumn)
{
case 0: /* name */
hr = GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
break;
return SHSetStrRet(&psd->str, pCPanel->szName + pCPanel->offsDispName);
case 1: /* comment */
{
PIDLCPanelStruct* pCPanel = _ILGetCPanelPointer(pidl);
if (pCPanel)
return SHSetStrRet(&psd->str, pCPanel->szName + pCPanel->offsComment);
if (_ILIsSpecialFolder(pidl))
{
HKEY hKey;
GUID *pGuid = _ILGetGUIDPointer(pidl);
if (HCR_RegOpenClassIDKey(*pGuid, &hKey))
{
psd->str.cStr[0] = 0x00;
psd->str.uType = STRRET_CSTR;
RegLoadMUIStringA(hKey, "InfoTip", psd->str.cStr, MAX_PATH, NULL, 0, NULL);
RegCloseKey(hKey);
}
}
break;
}
return SHSetStrRet(&psd->str, pCPanel->szName + pCPanel->offsComment);
}
hr = S_OK;
}
return hr;
return S_OK;
}
HRESULT WINAPI CControlPanelFolder::MapColumnToSCID(UINT column, SHCOLUMNID *pscid)

View file

@ -315,12 +315,10 @@ HRESULT WINAPI CDesktopFolder::ParseDisplayName(
PIDLIST_RELATIVE *ppidl,
DWORD *pdwAttributes)
{
WCHAR szElement[MAX_PATH];
LPCWSTR szNext = NULL;
LPITEMIDLIST pidlTemp = NULL;
PARSEDURLW urldata;
HRESULT hr = S_OK;
CLSID clsid;
TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
this, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName),
@ -329,14 +327,11 @@ HRESULT WINAPI CDesktopFolder::ParseDisplayName(
if (!ppidl)
return E_INVALIDARG;
if (!lpszDisplayName)
{
*ppidl = NULL;
return E_INVALIDARG;
}
*ppidl = NULL;
if (!lpszDisplayName)
return E_INVALIDARG;
if (pchEaten)
*pchEaten = 0; /* strange but like the original */
@ -344,10 +339,7 @@ HRESULT WINAPI CDesktopFolder::ParseDisplayName(
if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
{
szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
TRACE ("-- element: %s\n", debugstr_w (szElement));
CLSIDFromString (szElement + 2, &clsid);
pidlTemp = _ILCreateGuid (PT_GUID, clsid);
return SH_ParseGuidDisplayName(this, hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
}
else if (PathGetDriveNumberW (lpszDisplayName) >= 0)
{
@ -370,8 +362,7 @@ HRESULT WINAPI CDesktopFolder::ParseDisplayName(
if (urldata.nScheme == URL_SCHEME_SHELL) /* handle shell: urls */
{
TRACE ("-- shell url: %s\n", debugstr_w(urldata.pszSuffix));
SHCLSIDFromStringW (urldata.pszSuffix + 2, &clsid);
pidlTemp = _ILCreateGuid (PT_GUID, clsid);
pidlTemp = _ILCreateGuidFromStrW(urldata.pszSuffix + 2);
}
else
return IEParseDisplayNameWithBCW(CP_ACP, lpszDisplayName, pbc, ppidl);
@ -449,7 +440,7 @@ HRESULT WINAPI CDesktopFolder::BindToObject(
if (_ILIsSpecialFolder(pidl))
return SHELL32_BindToGuidItem(pidlRoot, pidl, pbcReserved, riid, ppvOut);
return SHELL32_BindToFS( pidlRoot, sPathTarget, pidl, riid, ppvOut );
return m_DesktopFSFolder->BindToObject(pidl, pbcReserved, riid, ppvOut );
}
/**************************************************************************
@ -773,13 +764,7 @@ HRESULT WINAPI CDesktopFolder::SetNameOf(
debugstr_w (lpName), dwFlags, pPidlOut);
if (_ILGetGUIDPointer(pidl))
{
if (SUCCEEDED(BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder2, &psf))))
{
hr = psf->SetNameOf(hwndOwner, pidl, lpName, dwFlags, pPidlOut);
return hr;
}
}
return SHELL32_SetNameOfGuidItem(pidl, lpName, dwFlags, pPidlOut);
/* build source path */
lstrcpynW(szSrc, sPathTarget, MAX_PATH);
@ -897,6 +882,10 @@ HRESULT WINAPI CDesktopFolder::GetDetailsOf(
psd->str.cStr, MAX_PATH);
return S_OK;
}
else if (_ILIsSpecialFolder(pidl))
{
return SHELL32_GetDetailsOfGuidItem(this, pidl, iColumn, psd);
}
/* the data from the pidl */
psd->str.uType = STRRET_CSTR;

View file

@ -208,7 +208,6 @@ HRESULT WINAPI CDrivesFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLEST
LPCWSTR szNext = NULL;
WCHAR szElement[MAX_PATH];
LPITEMIDLIST pidlTemp = NULL;
CLSID clsid;
TRACE("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", this,
hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName),
@ -221,10 +220,7 @@ HRESULT WINAPI CDrivesFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLEST
/* handle CLSID paths */
if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
{
szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
TRACE ("-- element: %s\n", debugstr_w (szElement));
CLSIDFromString (szElement + 2, &clsid);
pidlTemp = _ILCreateGuid (PT_GUID, clsid);
return SH_ParseGuidDisplayName(this, hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
}
/* do we have an absolute path name ? */
else if (PathGetDriveNumberW (lpszDisplayName) >= 0 &&
@ -487,6 +483,15 @@ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFla
{
return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet);
}
else if (!_ILIsDesktop(pidl) && _ILIsSpecialFolder(pidl))
{
return SHELL32_GetDisplayNameOfGUIDItem(this, L"", pidl, dwFlags, strRet);
}
else if (pidl->mkid.cb && !_ILIsDrive(pidl))
{
ERR("Wrong pidl type\n");
return E_INVALIDARG;
}
pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
if (!pszPath)
@ -503,63 +508,51 @@ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFla
}
else
{
if (_ILIsSpecialFolder(pidl))
return SHELL32_GetDisplayNameOfGUIDItem(this, L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", pidl, dwFlags, strRet);
else if (_ILIsDrive(pidl))
_ILSimpleGetTextW(pidl, pszPath, MAX_PATH); /* append my own path */
/* long view "lw_name (C:)" */
if (!(dwFlags & SHGDN_FORPARSING))
{
_ILSimpleGetTextW(pidl, pszPath, MAX_PATH); /* append my own path */
/* long view "lw_name (C:)" */
if (!(dwFlags & SHGDN_FORPARSING))
{
WCHAR wszDrive[18] = {0};
DWORD dwVolumeSerialNumber, dwMaximumComponentLength, dwFileSystemFlags;
static const WCHAR wszOpenBracket[] = {' ', '(', 0};
static const WCHAR wszCloseBracket[] = {')', 0};
WCHAR wszDrive[18] = {0};
DWORD dwVolumeSerialNumber, dwMaximumComponentLength, dwFileSystemFlags;
static const WCHAR wszOpenBracket[] = {' ', '(', 0};
static const WCHAR wszCloseBracket[] = {')', 0};
lstrcpynW(wszDrive, pszPath, 4);
pszPath[0] = L'\0';
GetVolumeInformationW(wszDrive, pszPath,
MAX_PATH - 7,
&dwVolumeSerialNumber,
&dwMaximumComponentLength, &dwFileSystemFlags, NULL, 0);
pszPath[MAX_PATH-1] = L'\0';
if (!wcslen(pszPath))
lstrcpynW(wszDrive, pszPath, 4);
pszPath[0] = L'\0';
GetVolumeInformationW(wszDrive, pszPath,
MAX_PATH - 7,
&dwVolumeSerialNumber,
&dwMaximumComponentLength, &dwFileSystemFlags, NULL, 0);
pszPath[MAX_PATH-1] = L'\0';
if (!wcslen(pszPath))
{
UINT DriveType, ResourceId;
DriveType = GetDriveTypeW(wszDrive);
switch(DriveType)
{
UINT DriveType, ResourceId;
DriveType = GetDriveTypeW(wszDrive);
switch(DriveType)
{
case DRIVE_FIXED:
ResourceId = IDS_DRIVE_FIXED;
break;
case DRIVE_REMOTE:
ResourceId = IDS_DRIVE_NETWORK;
break;
case DRIVE_CDROM:
ResourceId = IDS_DRIVE_CDROM;
break;
default:
ResourceId = 0;
}
if (ResourceId)
{
dwFileSystemFlags = LoadStringW(shell32_hInstance, ResourceId, pszPath, MAX_PATH);
if (dwFileSystemFlags > MAX_PATH - 7)
pszPath[MAX_PATH-7] = L'\0';
}
case DRIVE_FIXED:
ResourceId = IDS_DRIVE_FIXED;
break;
case DRIVE_REMOTE:
ResourceId = IDS_DRIVE_NETWORK;
break;
case DRIVE_CDROM:
ResourceId = IDS_DRIVE_CDROM;
break;
default:
ResourceId = 0;
}
if (ResourceId)
{
dwFileSystemFlags = LoadStringW(shell32_hInstance, ResourceId, pszPath, MAX_PATH);
if (dwFileSystemFlags > MAX_PATH - 7)
pszPath[MAX_PATH-7] = L'\0';
}
wcscat (pszPath, wszOpenBracket);
wszDrive[2] = L'\0';
wcscat (pszPath, wszDrive);
wcscat (pszPath, wszCloseBracket);
}
}
else
{
/* Neither a shell namespace extension nor a drive letter. */
ERR("Wrong pidl type\n");
CoTaskMemFree(pszPath);
return E_INVALIDARG;
wcscat (pszPath, wszOpenBracket);
wszDrive[2] = L'\0';
wcscat (pszPath, wszDrive);
wcscat (pszPath, wszCloseBracket);
}
}
@ -590,14 +583,8 @@ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFla
HRESULT WINAPI CDrivesFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl,
LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut)
{
LPWSTR sName;
HKEY hKey;
UINT length;
WCHAR szName[30];
TRACE("(%p)->(%p,pidl=%p,%s,%u,%p)\n", this,
hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut);
if (_ILIsDrive(pidl))
{
if (_ILSimpleGetTextW(pidl, szName, _countof(szName)))
@ -607,35 +594,7 @@ HRESULT WINAPI CDrivesFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl,
return S_OK;
}
if (pPidlOut != NULL)
*pPidlOut = _ILCreateMyComputer();
length = (wcslen(lpName) + 1) * sizeof(WCHAR);
sName = (LPWSTR)SHAlloc(length);
if (!sName)
return E_OUTOFMEMORY;
if (RegOpenKeyExW(HKEY_CURRENT_USER,
L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}",
0,
KEY_WRITE,
&hKey) != ERROR_SUCCESS)
{
WARN("Error: failed to open registry key\n");
}
else
{
RegSetValueExW(hKey, NULL, 0, REG_SZ, (const LPBYTE)lpName, length);
RegCloseKey(hKey);
}
wcscpy(sName, lpName);
SHFree(this->sName);
this->sName = sName;
TRACE("result %s\n", debugstr_w(sName));
return S_OK;
return SHELL32_SetNameOfGuidItem(pidl, lpName, dwFlags, pPidlOut);
}
HRESULT WINAPI CDrivesFolder::GetDefaultSearchGUID(GUID * pguid)
@ -696,6 +655,10 @@ HRESULT WINAPI CDrivesFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, S
psd->str.cStr, MAX_PATH);
return S_OK;
}
else if (_ILIsSpecialFolder(pidl))
{
return SHELL32_GetDetailsOfGuidItem(this, pidl, iColumn, psd);
}
else
{
char szPath[MAX_PATH];
@ -713,20 +676,14 @@ HRESULT WINAPI CDrivesFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, S
_ILGetFileType(pidl, psd->str.cStr, MAX_PATH);
break;
case 2: /* total size */
if (_ILIsDrive(pidl))
{
_ILSimpleGetText (pidl, szPath, MAX_PATH);
GetDiskFreeSpaceExA (szPath, NULL, &ulBytes, NULL);
StrFormatByteSize64A (ulBytes.QuadPart, psd->str.cStr, MAX_PATH);
}
_ILSimpleGetText (pidl, szPath, MAX_PATH);
GetDiskFreeSpaceExA (szPath, NULL, &ulBytes, NULL);
StrFormatByteSize64A (ulBytes.QuadPart, psd->str.cStr, MAX_PATH);
break;
case 3: /* free size */
if (_ILIsDrive(pidl))
{
_ILSimpleGetText (pidl, szPath, MAX_PATH);
GetDiskFreeSpaceExA (szPath, &ulBytes, NULL, NULL);
StrFormatByteSize64A (ulBytes.QuadPart, psd->str.cStr, MAX_PATH);
}
_ILSimpleGetText (pidl, szPath, MAX_PATH);
GetDiskFreeSpaceExA (szPath, &ulBytes, NULL, NULL);
StrFormatByteSize64A (ulBytes.QuadPart, psd->str.cStr, MAX_PATH);
break;
}
hr = S_OK;

View file

@ -62,6 +62,18 @@ HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, LPCITEMIDLIST pidl, LPDW
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(IShellFolder * pFolder,
HWND hwndOwner,
LPBC pbc,
LPOLESTR lpszDisplayName,
DWORD *pchEaten,
PIDLIST_RELATIVE *ppidl,
DWORD *pdwAttributes);
extern "C"
BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey);

View file

@ -682,6 +682,120 @@ HRESULT SHELL32_CompareIDs(IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pi
return nReturn;
}
HRESULT SH_ParseGuidDisplayName(IShellFolder * 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 < 40)
return E_FAIL;
if (lpszDisplayName[0] != L':' || lpszDisplayName[1] != L':' || lpszDisplayName[2] != L'{' || lpszDisplayName[40] != L'}')
return E_FAIL;
pidl = _ILCreateGuidFromStrW(lpszDisplayName + 2);
if (pidl == NULL)
return E_FAIL;
if (cch < 42)
{
*ppidl = pidl;
if (pdwAttributes && *pdwAttributes)
{
SHELL32_GetGuidItemAttributes(pFolder, *ppidl, pdwAttributes);
}
}
else
{
IShellFolder* psf;
LPITEMIDLIST pidlChild;
HRESULT hres;
hres = SHELL32_BindToGuidItem(NULL, pidl, NULL, IID_PPV_ARG(IShellFolder, &psf));
if (SUCCEEDED(hres))
{
return psf->ParseDisplayName(hwndOwner, pbc, lpszDisplayName + 42, pchEaten, &pidlChild, pdwAttributes);
}
}
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->GetDetailsOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, psd);
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
*