/************************************************************************** * 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)) { 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); }
/************************************************************************** * ISF_ControlPanel_fnGetDisplayNameOf */ static HRESULT WINAPI ISF_ControlPanel_fnGetDisplayNameOf(IShellFolder2 * iface, LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet) { ICPanelImpl *This = (ICPanelImpl *)iface; CHAR szPath[MAX_PATH]; WCHAR wszPath[MAX_PATH+1]; /* +1 for potential backslash */ PIDLCPanelStruct* pcpanel; *szPath = '\0'; TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n", This, pidl, dwFlags, strRet); pdump(pidl); if (!pidl || !strRet) return E_INVALIDARG; pcpanel = _ILGetCPanelPointer(pidl); if (pcpanel) { lstrcpyA(szPath, pcpanel->szName+pcpanel->offsDispName); if (!(dwFlags & SHGDN_FORPARSING)) FIXME("retrieve display name from control panel app\n"); } /* take names of special folders only if its only this folder */ else if (_ILIsSpecialFolder(pidl)) { BOOL bSimplePidl = _ILIsPidlSimple(pidl); if (bSimplePidl) { _ILSimpleGetTextW(pidl, wszPath, MAX_PATH); /* append my own path */ } else { FIXME("special pidl\n"); } if ((dwFlags & SHGDN_FORPARSING) && !bSimplePidl) { /* go deeper if needed */ int len = 0; PathAddBackslashW(wszPath); len = lstrlenW(wszPath); if (!SUCCEEDED (SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_INFOLDER, wszPath + len, MAX_PATH + 1 - len))) return E_OUTOFMEMORY; if (!WideCharToMultiByte(CP_ACP, 0, wszPath, -1, szPath, MAX_PATH, NULL, NULL)) wszPath[0] = '\0'; } } strRet->uType = STRRET_CSTR; lstrcpynA(strRet->u.cStr, szPath, MAX_PATH); TRACE("--(%p)->(%s)\n", This, szPath); 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; }
/************************************************************************** * CControlPanelFolder::GetDisplayNameOf */ HRESULT WINAPI CControlPanelFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet) { CHAR szName[MAX_PATH]; WCHAR wszName[MAX_PATH+1]; /* +1 for potential backslash */ PIDLCPanelStruct *pCPanel; HRESULT hr; *szName = '\0'; TRACE("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet); pdump(pidl); if (!pidl) return S_FALSE; pCPanel = _ILGetCPanelPointer(pidl); if (pCPanel) { /* copy display name from pidl - it was retrived from applet before; SHGDN_FORPARSING does not need special handling */ lstrcpyA(szName, pCPanel->szName + pCPanel->offsDispName); } /* take names of special folders only if it's only this folder */ else if (_ILIsSpecialFolder(pidl)) { BOOL bSimplePidl = _ILIsPidlSimple(pidl); SFGAOF Attr = SFGAO_FILESYSTEM; SHELL32_GetItemAttributes(this, pidl, &Attr); if (Attr & SFGAO_FILESYSTEM) { hr = SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, wszName, sizeof(wszName)); if (FAILED(hr)) return hr; } else if (bSimplePidl) { _ILSimpleGetTextW(pidl, wszName, MAX_PATH); /* append my own path */ } else { FIXME("special pidl\n"); if (dwFlags & SHGDN_FORPARSING) { /* go deeper if needed */ int cchName; PathAddBackslashW(wszName); cchName = wcslen(wszName); hr = SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, wszName + cchName, MAX_PATH + 1 - cchName); if (FAILED(hr)) return hr; } } if (!WideCharToMultiByte(CP_ACP, 0, wszName, -1, szName, MAX_PATH, NULL, NULL)) szName[0] = '\0'; } strRet->uType = STRRET_CSTR; lstrcpynA(strRet->cStr, szName, MAX_PATH); TRACE("--(%p)->(%s)\n", this, szName); return S_OK; }
/************************************************************************** * 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; }