/************************************************************************** * CDesktopFolder::GetDisplayNameOf * * NOTES * special case: pidl = null gives desktop-name back */ HRESULT WINAPI CDesktopFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet) { TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet); pdump (pidl); if (!strRet) return E_INVALIDARG; if (!_ILIsPidlSimple (pidl)) { return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet); } else if (!_ILIsDesktop(pidl) && _ILIsSpecialFolder(pidl)) { return SHELL32_GetDisplayNameOfGUIDItem(this, L"", pidl, dwFlags, strRet); } else if (_ILIsDesktop(pidl)) { if ((GET_SHGDN_RELATION(dwFlags) == SHGDN_NORMAL) && (GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING)) return SHSetStrRet(strRet, sPathTarget); else return HCR_GetClassName(CLSID_ShellDesktop, strRet); } /* file system folder or file rooted at the desktop */ CComPtr<IShellFolder2> psf; HRESULT hr = _GetSFFromPidl(pidl, &psf); if (FAILED_UNEXPECTEDLY(hr)) return hr; return psf->GetDisplayNameOf(pidl, dwFlags, strRet); }
/************************************************************************** * CFontsFolder::GetDisplayNameOf * */ HRESULT WINAPI CFontsFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet) { PIDLFontStruct *pFont; TRACE("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet); pdump (pidl); if (!strRet) return E_INVALIDARG; pFont = _ILGetFontStruct(pidl); if (pFont) { strRet->pOleStr = (LPWSTR)CoTaskMemAlloc((wcslen(pFont->szName) + 1) * sizeof(WCHAR)); if (!strRet->pOleStr) return E_OUTOFMEMORY; wcscpy(strRet->pOleStr, pFont->szName); strRet->uType = STRRET_WSTR; } else if (!pidl->mkid.cb) { WCHAR wszPath[MAX_PATH]; if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) && (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING)) { if (!SHGetSpecialFolderPathW(NULL, wszPath, CSIDL_FONTS, FALSE)) return E_FAIL; } else if (!HCR_GetClassNameW(CLSID_FontsFolderShortcut, wszPath, MAX_PATH)) return E_FAIL; strRet->pOleStr = (LPWSTR)CoTaskMemAlloc((wcslen(wszPath) + 1) * sizeof(WCHAR)); if (!strRet->pOleStr) return E_OUTOFMEMORY; wcscpy(strRet->pOleStr, wszPath); strRet->uType = STRRET_WSTR; } else return E_INVALIDARG; return S_OK; }
/************************************************************************** * ISF_Desktop_fnGetDisplayNameOf * * NOTES * special case: pidl = null gives desktop-name back */ static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf (IShellFolder2 * iface, LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet) { IDesktopFolderImpl *This = impl_from_IShellFolder2(iface); HRESULT hr = S_OK; LPWSTR pszPath; TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", This, pidl, dwFlags, strRet); pdump (pidl); if (!strRet) return E_INVALIDARG; pszPath = CoTaskMemAlloc((MAX_PATH +1) * sizeof(WCHAR)); if (!pszPath) return E_OUTOFMEMORY; if (_ILIsDesktop (pidl)) { if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) && (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING)) strcpyW(pszPath, This->sPathTarget); else HCR_GetClassNameW(&CLSID_ShellDesktop, pszPath, MAX_PATH); } else if (_ILIsPidlSimple (pidl)) { GUID const *clsid; if ((clsid = _ILGetGUIDPointer (pidl))) { if (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING) { int bWantsForParsing; /* * 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 { /* get the "WantsFORPARSING" flag from the registry */ static const WCHAR clsidW[] = { 'C','L','S','I','D','\\',0 }; static const WCHAR shellfolderW[] = { '\\','s','h','e','l','l','f','o','l','d','e','r',0 }; static const WCHAR wantsForParsingW[] = { 'W','a','n','t','s','F','o','r','P','a','r','s','i','n', 'g',0 }; WCHAR szRegPath[100]; LONG r; lstrcpyW (szRegPath, clsidW); SHELL32_GUIDToStringW (clsid, &szRegPath[6]); lstrcatW (szRegPath, shellfolderW); r = SHGetValueW(HKEY_CLASSES_ROOT, szRegPath, wantsForParsingW, NULL, NULL, NULL); if (r == ERROR_SUCCESS) bWantsForParsing = TRUE; else bWantsForParsing = FALSE; } if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) && bWantsForParsing) { /* * we need the filesystem path to the destination folder. * Only the folder itself can know it */ hr = SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags, pszPath, MAX_PATH); } else { /* parsing name like ::{...} */ pszPath[0] = ':'; pszPath[1] = ':'; SHELL32_GUIDToStringW (clsid, &pszPath[2]); } } else { /* user friendly name */ HCR_GetClassNameW (clsid, pszPath, MAX_PATH); } } else { int cLen = 0; /* file system folder or file rooted at the desktop */ if ((GET_SHGDN_FOR(dwFlags) == SHGDN_FORPARSING) && (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER)) { lstrcpynW(pszPath, This->sPathTarget, MAX_PATH - 1); PathAddBackslashW(pszPath); cLen = lstrlenW(pszPath); } _ILSimpleGetTextW(pidl, pszPath + cLen, MAX_PATH - cLen); if (!_ILIsFolder(pidl)) SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags); } } else { /* a complex pidl, let the subfolder do the work */ hr = SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags, pszPath, MAX_PATH); } if (SUCCEEDED(hr)) { /* Win9x always returns ANSI strings, NT always returns Unicode strings */ if (GetVersion() & 0x80000000) { strRet->uType = STRRET_CSTR; if (!WideCharToMultiByte(CP_ACP, 0, pszPath, -1, strRet->u.cStr, MAX_PATH, NULL, NULL)) strRet->u.cStr[0] = '\0'; CoTaskMemFree(pszPath); } else { strRet->uType = STRRET_WSTR; strRet->u.pOleStr = pszPath; } } else CoTaskMemFree(pszPath); TRACE ("-- (%p)->(%s,0x%08x)\n", This, strRet->uType == STRRET_CSTR ? strRet->u.cStr : debugstr_w(strRet->u.pOleStr), hr); return hr; }
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; }
/************************************************************************** * CAdminToolsFolder::GetDisplayNameOf * */ HRESULT WINAPI CAdminToolsFolder::GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet) { HRESULT hr = S_OK; LPWSTR pszPath, pOffset; TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet); pdump (pidl); if (!strRet) return E_INVALIDARG; pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR)); if (!pszPath) return E_OUTOFMEMORY; ZeroMemory(pszPath, (MAX_PATH + 1) * sizeof(WCHAR)); if (!pidl->mkid.cb) { if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) && (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING)) wcscpy(pszPath, szTarget); else if (!HCR_GetClassNameW(CLSID_AdminFolderShortcut, pszPath, MAX_PATH)) hr = E_FAIL; } else if (_ILIsPidlSimple(pidl)) { if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) && (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER) && szTarget) { wcscpy(pszPath, szTarget); pOffset = PathAddBackslashW(pszPath); if (pOffset) { if (!_ILSimpleGetTextW(pidl, pOffset, MAX_PATH + 1 - (pOffset - pszPath))) hr = E_FAIL; } else hr = E_FAIL; } else { if (_ILSimpleGetTextW(pidl, pszPath, MAX_PATH + 1)) { if (SHELL_FS_HideExtension(pszPath)) PathRemoveExtensionW(pszPath); } else hr = E_FAIL; } } else if (_ILIsSpecialFolder(pidl)) { BOOL bSimplePidl = _ILIsPidlSimple(pidl); if (bSimplePidl) { if (!_ILSimpleGetTextW(pidl, pszPath, MAX_PATH)) hr = E_FAIL; } else if ((dwFlags & SHGDN_FORPARSING) && !bSimplePidl) { int len = 0; wcscpy(pszPath, szTarget); PathAddBackslashW(pszPath); len = wcslen(pszPath); if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags | SHGDN_INFOLDER, pszPath + len, MAX_PATH + 1 - len))) { CoTaskMemFree(pszPath); return E_OUTOFMEMORY; } } } if (SUCCEEDED(hr)) { strRet->uType = STRRET_WSTR; strRet->pOleStr = pszPath; TRACE ("-- (%p)->(%s,0x%08x)\n", this, debugstr_w(strRet->pOleStr), hr); } else CoTaskMemFree(pszPath); return hr; }