/************************************************************************** * 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); }
static HRESULT WINAPI ShellItem_GetAttributes(IShellItem2 *iface, SFGAOF sfgaoMask, SFGAOF *psfgaoAttribs) { ShellItem *This = impl_from_IShellItem2(iface); IShellFolder *parent_folder; LPITEMIDLIST child_pidl; HRESULT ret; TRACE("(%p,%x,%p)\n", iface, sfgaoMask, psfgaoAttribs); if (_ILIsDesktop(This->pidl)) ret = SHGetDesktopFolder(&parent_folder); else ret = ShellItem_get_parent_shellfolder(This, &parent_folder); if (SUCCEEDED(ret)) { child_pidl = ILFindLastID(This->pidl); *psfgaoAttribs = sfgaoMask; ret = IShellFolder_GetAttributesOf(parent_folder, 1, (LPCITEMIDLIST*)&child_pidl, psfgaoAttribs); *psfgaoAttribs &= sfgaoMask; IShellFolder_Release(parent_folder); if (SUCCEEDED(ret)) { if(sfgaoMask == *psfgaoAttribs) return S_OK; else return S_FALSE; } } return ret; }
static HRESULT ShellItem_get_parent_shellfolder(ShellItem *This, IShellFolder **ppsf) { LPITEMIDLIST parent_pidl; IShellFolder *desktop; HRESULT ret; ret = ShellItem_get_parent_pidl(This, &parent_pidl); if (SUCCEEDED(ret)) { ret = SHGetDesktopFolder(&desktop); if (SUCCEEDED(ret)) { if (_ILIsDesktop(parent_pidl)) { *ppsf = desktop; } else { ret = IShellFolder_BindToObject(desktop, parent_pidl, NULL, &IID_IShellFolder, (void**)ppsf); IShellFolder_Release(desktop); } } ILFree(parent_pidl); } return ret; }
/************************************************************************** * CDesktopFolder::CompareIDs */ HRESULT WINAPI CDesktopFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2) { bool bIsDesktopFolder1, bIsDesktopFolder2; if (!pidl1 || !pidl2) { ERR("Got null pidl pointer (%Ix %p %p)!\n", lParam, pidl1, pidl2); return E_INVALIDARG; } bIsDesktopFolder1 = _ILIsDesktop(pidl1); bIsDesktopFolder2 = _ILIsDesktop(pidl2); if (bIsDesktopFolder1 || bIsDesktopFolder2) return MAKE_COMPARE_HRESULT(bIsDesktopFolder1 - bIsDesktopFolder2); if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2)) return m_regFolder->CompareIDs(lParam, pidl1, pidl2); return m_DesktopFSFolder->CompareIDs(lParam, pidl1, pidl2); }
/************************************************************************** * CDesktopFolder::GetAttributesOf */ HRESULT WINAPI CDesktopFolder::GetAttributesOf( UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut) { HRESULT hr = S_OK; TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n", this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0); if (cidl && !apidl) return E_INVALIDARG; if (*rgfInOut == 0) *rgfInOut = ~0; if(cidl == 0) *rgfInOut &= dwDesktopAttributes; else { /* TODO: always add SFGAO_CANLINK */ for (UINT i = 0; i < cidl; ++i) { pdump(*apidl); if (_ILIsDesktop(*apidl)) *rgfInOut &= dwDesktopAttributes; else if (_ILIsMyComputer(apidl[i])) *rgfInOut &= dwMyComputerAttributes; else if (_ILIsNetHood(apidl[i])) *rgfInOut &= dwMyNetPlacesAttributes; else if (_ILIsSpecialFolder(apidl[i])) SHELL32_GetGuidItemAttributes(this, apidl[i], rgfInOut); else if (_ILIsFolder(apidl[i]) || _ILIsValue(apidl[i])) { CComPtr<IShellFolder2> psf; HRESULT hr = _GetSFFromPidl(apidl[i], &psf); if (FAILED_UNEXPECTEDLY(hr)) continue; psf->GetAttributesOf(1, &apidl[i], rgfInOut); } else ERR("Got an unknown pidl type!!!\n"); } } /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */ *rgfInOut &= ~SFGAO_VALIDATE; TRACE("-- result=0x%08x\n", *rgfInOut); return hr; }
HRESULT SHELL32_CompareChildren(IShellFolder2* psf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) { PUIDLIST_RELATIVE nextpidl1 = ILGetNext (pidl1); PUIDLIST_RELATIVE nextpidl2 = ILGetNext (pidl2); bool isEmpty1 = _ILIsDesktop(nextpidl1); bool isEmpty2 = _ILIsDesktop(nextpidl2); if (isEmpty1 || isEmpty2) return MAKE_COMPARE_HRESULT(isEmpty2 - isEmpty1); PITEMID_CHILD firstpidl = ILCloneFirst (pidl1); if (!firstpidl) return E_OUTOFMEMORY; CComPtr<IShellFolder> psf2; HRESULT hr = psf->BindToObject(firstpidl, 0, IID_PPV_ARG(IShellFolder, &psf2)); ILFree(firstpidl); if (FAILED(hr)) return MAKE_COMPARE_HRESULT(0); return psf2->CompareIDs(lParam, nextpidl1, nextpidl2); }
/************************************************************************** * ISF_Desktop_fnGetAttributesOf */ static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf (IShellFolder2 * iface, UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut) { IDesktopFolderImpl *This = impl_from_IShellFolder2(iface); IShellFolder *shell_folder = (IShellFolder*)iface; static const DWORD dwDesktopAttributes = SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR | SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER; static const DWORD dwMyComputerAttributes = SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET | SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER; TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n", This, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0); if (!rgfInOut) return E_INVALIDARG; if (cidl && !apidl) return E_INVALIDARG; if (*rgfInOut == 0) *rgfInOut = ~0; if(cidl == 0) { *rgfInOut &= dwDesktopAttributes; } else { while (cidl > 0 && *apidl) { pdump (*apidl); if (_ILIsDesktop(*apidl)) { *rgfInOut &= dwDesktopAttributes; } else if (_ILIsMyComputer(*apidl)) { *rgfInOut &= dwMyComputerAttributes; } else { SHELL32_GetItemAttributes ( shell_folder, *apidl, rgfInOut); } apidl++; cidl--; } } /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */ *rgfInOut &= ~SFGAO_VALIDATE; TRACE ("-- result=0x%08x\n", *rgfInOut); return S_OK; }
HRESULT CALLBACK RegFolderContextMenuCallback(IShellFolder *psf, HWND hwnd, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES) return S_OK; PIDLIST_ABSOLUTE pidlFolder; PUITEMID_CHILD *apidl; UINT cidl; HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl); if (FAILED_UNEXPECTEDLY(hr)) return hr; if (_ILIsMyComputer(apidl[0])) { if (32 >= (UINT)ShellExecuteW(hwnd, L"open", L"rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl", NULL, NULL, SW_SHOWNORMAL)) hr = E_FAIL; } else if (_ILIsDesktop(apidl[0])) { if (32 >= (UINT)ShellExecuteW(hwnd, L"open", L"rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL, NULL, SW_SHOWNORMAL)) hr = E_FAIL; } else if (_ILIsNetHood(apidl[0])) { // FIXME path! if (32 >= (UINT)ShellExecuteW(NULL, L"open", L"explorer.exe", L"::{7007ACC7-3202-11D1-AAD2-00805FC1270E}", NULL, SW_SHOWDEFAULT)) hr = E_FAIL; } else if (_ILIsBitBucket(apidl[0])) { /* FIXME: detect the drive path of bitbucket if appropiate */ if (!SH_ShowRecycleBinProperties(L'C')) hr = E_FAIL; } SHFree(pidlFolder); _ILFreeaPidl(apidl, cidl); return hr; }
static HRESULT WINAPI ShellItem_BindToHandler(IShellItem2 *iface, IBindCtx *pbc, REFGUID rbhid, REFIID riid, void **ppvOut) { ShellItem *This = impl_from_IShellItem2(iface); HRESULT ret; TRACE("(%p,%p,%s,%p,%p)\n", iface, pbc, shdebugstr_guid(rbhid), riid, ppvOut); *ppvOut = NULL; if (IsEqualGUID(rbhid, &BHID_SFObject)) { IShellFolder *psf; ret = ShellItem_get_shellfolder(This, pbc, &psf); if (SUCCEEDED(ret)) { ret = IShellFolder_QueryInterface(psf, riid, ppvOut); IShellFolder_Release(psf); } return ret; } else if (IsEqualGUID(rbhid, &BHID_SFUIObject)) { IShellFolder *psf_parent; if (_ILIsDesktop(This->pidl)) ret = SHGetDesktopFolder(&psf_parent); else ret = ShellItem_get_parent_shellfolder(This, &psf_parent); if (SUCCEEDED(ret)) { LPCITEMIDLIST pidl = ILFindLastID(This->pidl); ret = IShellFolder_GetUIObjectOf(psf_parent, NULL, 1, &pidl, riid, NULL, ppvOut); IShellFolder_Release(psf_parent); } return ret; } else if (IsEqualGUID(rbhid, &BHID_DataObject)) { return ShellItem_BindToHandler(&This->IShellItem2_iface, pbc, &BHID_SFUIObject, &IID_IDataObject, ppvOut); } FIXME("Unsupported BHID %s.\n", debugstr_guid(rbhid)); return MK_E_NOOBJECT; }
static HRESULT ShellItem_get_shellfolder(ShellItem *This, IBindCtx *pbc, IShellFolder **ppsf) { IShellFolder *desktop; HRESULT ret; ret = SHGetDesktopFolder(&desktop); if (SUCCEEDED(ret)) { if (_ILIsDesktop(This->pidl)) { *ppsf = desktop; IShellFolder_AddRef(*ppsf); } else { ret = IShellFolder_BindToObject(desktop, This->pidl, pbc, &IID_IShellFolder, (void**)ppsf); } IShellFolder_Release(desktop); } return ret; }
HRESULT CRegFolder::GetGuidItemAttributes (LPCITEMIDLIST pidl, LPDWORD pdwAttributes) { DWORD dwAttributes = *pdwAttributes; /* First try to get them from the registry */ if (!HCR_GetFolderAttributes(pidl, pdwAttributes)) { /* We couldn't get anything */ *pdwAttributes = 0; } /* Items have more attributes when on desktop */ if (_ILIsDesktop(m_pidlRoot)) { *pdwAttributes |= (dwAttributes & (SFGAO_CANLINK|SFGAO_CANDELETE|SFGAO_CANRENAME|SFGAO_HASPROPSHEET)); } /* In any case, links can be created */ if (*pdwAttributes == NULL) { *pdwAttributes |= (dwAttributes & SFGAO_CANLINK); } 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; }
/****************************************************************************** * InitializeTreeView [Internal] * * Called from WM_INITDIALOG handler. * * PARAMS * hwndParent [I] The BrowseForFolder dialog * root [I] ITEMIDLIST of the root shell folder */ static void InitializeTreeView( browse_info *info ) { LPITEMIDLIST pidlParent, pidlChild; HIMAGELIST hImageList; HRESULT hr; IShellFolder *lpsfParent, *lpsfRoot; IEnumIDList * pEnumChildren = NULL; HTREEITEM item; DWORD flags; LPCITEMIDLIST root = info->lpBrowseInfo->pidlRoot; TRACE("%p\n", info ); Shell_GetImageLists(NULL, &hImageList); if (hImageList) SendMessageW( info->hwndTreeView, TVM_SETIMAGELIST, 0, (LPARAM)hImageList ); /* We want to call InsertTreeViewItem down the code, in order to insert * the root item of the treeview. Due to InsertTreeViewItem's signature, * we need the following to do this: * * + An ITEMIDLIST corresponding to _the parent_ of root. * + An ITEMIDLIST, which is a relative path from root's parent to root * (containing a single SHITEMID). * + An IShellFolder interface pointer of root's parent folder. * * If root is 'Desktop', then root's parent is also 'Desktop'. */ pidlParent = ILClone(root); ILRemoveLastID(pidlParent); pidlChild = ILClone(ILFindLastID(root)); if (_ILIsDesktop(pidlParent)) { hr = SHGetDesktopFolder(&lpsfParent); } else { IShellFolder *lpsfDesktop; hr = SHGetDesktopFolder(&lpsfDesktop); if (!SUCCEEDED(hr)) { WARN("SHGetDesktopFolder failed! hr = %08x\n", hr); return; } hr = IShellFolder_BindToObject(lpsfDesktop, pidlParent, 0, &IID_IShellFolder, (LPVOID*)&lpsfParent); IShellFolder_Release(lpsfDesktop); } if (!SUCCEEDED(hr)) { WARN("Could not bind to parent shell folder! hr = %08x\n", hr); return; } if (pidlChild && pidlChild->mkid.cb) { hr = IShellFolder_BindToObject(lpsfParent, pidlChild, 0, &IID_IShellFolder, (LPVOID*)&lpsfRoot); } else { lpsfRoot = lpsfParent; hr = IShellFolder_AddRef(lpsfParent); } if (!SUCCEEDED(hr)) { WARN("Could not bind to root shell folder! hr = %08x\n", hr); IShellFolder_Release(lpsfParent); return; } flags = BrowseFlagsToSHCONTF( info->lpBrowseInfo->ulFlags ); hr = IShellFolder_EnumObjects( lpsfRoot, info->hWnd, flags, &pEnumChildren ); if (!SUCCEEDED(hr)) { WARN("Could not get child iterator! hr = %08x\n", hr); IShellFolder_Release(lpsfParent); IShellFolder_Release(lpsfRoot); return; } SendMessageW( info->hwndTreeView, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT ); item = InsertTreeViewItem( info, lpsfParent, pidlChild, pidlParent, pEnumChildren, TVI_ROOT ); SendMessageW( info->hwndTreeView, TVM_EXPAND, TVE_EXPAND, (LPARAM)item ); IShellFolder_Release(lpsfRoot); IShellFolder_Release(lpsfParent); }
/*********************************************************************** * SHELL32_CompareIDs */ HRESULT SHELL32_CompareIDs(IShellFolder2 *sf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) { int type1, type2; char szTemp1[MAX_PATH]; char szTemp2[MAX_PATH]; HRESULT nReturn; LPITEMIDLIST firstpidl, nextpidl1, nextpidl2; IShellFolder *psf; /* test for empty pidls */ BOOL isEmpty1 = _ILIsDesktop (pidl1); BOOL isEmpty2 = _ILIsDesktop (pidl2); if (isEmpty1 && isEmpty2) return MAKE_HRESULT( SEVERITY_SUCCESS, 0, 0 ); if (isEmpty1) return MAKE_HRESULT( SEVERITY_SUCCESS, 0, (WORD)-1 ); if (isEmpty2) return MAKE_HRESULT( SEVERITY_SUCCESS, 0, 1 ); /* test for different types. Sort order is the PT_* constant */ type1 = _ILGetDataPointer (pidl1)->type; type2 = _ILGetDataPointer (pidl2)->type; if (type1 < type2) return MAKE_HRESULT( SEVERITY_SUCCESS, 0, (WORD)-1 ); else if (type1 > type2) return MAKE_HRESULT( SEVERITY_SUCCESS, 0, 1 ); /* test for name of pidl */ _ILSimpleGetText (pidl1, szTemp1, MAX_PATH); _ILSimpleGetText (pidl2, szTemp2, MAX_PATH); nReturn = lstrcmpiA (szTemp1, szTemp2); if (nReturn < 0) return MAKE_HRESULT( SEVERITY_SUCCESS, 0, (WORD)-1 ); else if (nReturn > 0) return MAKE_HRESULT( SEVERITY_SUCCESS, 0, 1 ); /* test of complex pidls */ firstpidl = ILCloneFirst (pidl1); nextpidl1 = ILGetNext (pidl1); nextpidl2 = ILGetNext (pidl2); /* optimizing: test special cases and bind not deeper */ /* the deeper shellfolder would do the same */ isEmpty1 = _ILIsDesktop (nextpidl1); isEmpty2 = _ILIsDesktop (nextpidl2); if (isEmpty1 && isEmpty2) { nReturn = MAKE_HRESULT( SEVERITY_SUCCESS, 0, 0 ); } else if (isEmpty1) { nReturn = MAKE_HRESULT( SEVERITY_SUCCESS, 0, (WORD)-1 ); } else if (isEmpty2) { nReturn = MAKE_HRESULT( SEVERITY_SUCCESS, 0, 1 ); /* optimizing end */ } else if (SUCCEEDED(IShellFolder2_BindToObject(sf, firstpidl, NULL, &IID_IShellFolder, (void **)&psf))) { nReturn = IShellFolder_CompareIDs (psf, lParam, nextpidl1, nextpidl2); IShellFolder_Release (psf); } ILFree (firstpidl); return nReturn; }
/************************************************************************** * IExtractIconW_Constructor */ IExtractIconW* IExtractIconW_Constructor(LPCITEMIDLIST pidl) { CComPtr<IDefaultExtractIconInit> initIcon; IExtractIconW *extractIcon; GUID const * riid; int icon_idx; UINT flags; CHAR sTemp[MAX_PATH]; WCHAR wTemp[MAX_PATH]; LPITEMIDLIST pSimplePidl = ILFindLastID(pidl); HRESULT hr; hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit,&initIcon)); if (FAILED(hr)) return NULL; hr = initIcon->QueryInterface(IID_PPV_ARG(IExtractIconW,&extractIcon)); if (FAILED(hr)) return NULL; if (_ILIsDesktop(pSimplePidl)) { initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DESKTOP); } else if ((riid = _ILGetGUIDPointer(pSimplePidl))) { /* 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(pSimplePidl)) { static const WCHAR szFull[] = {'F','u','l','l',0}; static const WCHAR szEmpty[] = {'E','m','p','t','y',0}; IEnumIDList *EnumIDList = NULL; CoInitialize(NULL); IShellFolder2 *psfRecycleBin = NULL; IShellFolder *psfDesktop = NULL; hr = SHGetDesktopFolder(&psfDesktop); if (SUCCEEDED(hr)) hr = psfDesktop->BindToObject(pSimplePidl, NULL, IID_IShellFolder2, (void**) &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 (psfDesktop) psfDesktop->Release(); if (psfRecycleBin) psfRecycleBin->Release(); if (EnumIDList) EnumIDList->Release(); } 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); } } else if (_ILIsDrive (pSimplePidl)) { static const WCHAR drive[] = { 'D', 'r', 'i', 'v', 'e', 0 }; int icon_idx = -1; if (_ILGetDrive(pSimplePidl, sTemp, MAX_PATH)) { switch(GetDriveTypeA(sTemp)) { case DRIVE_REMOVABLE: icon_idx = IDI_SHELL_FLOPPY; break; case DRIVE_CDROM: icon_idx = IDI_SHELL_CDROM; break; case DRIVE_REMOTE: icon_idx = IDI_SHELL_NETDRIVE; break; case DRIVE_RAMDISK: icon_idx = IDI_SHELL_RAMDISK; break; case DRIVE_NO_ROOT_DIR: icon_idx = IDI_SHELL_CDROM; break; } } if (icon_idx != -1) { initIcon->SetNormalIcon(swShell32Name, -icon_idx); } else { if (HCR_GetIconW(drive, wTemp, NULL, MAX_PATH, &icon_idx)) initIcon->SetNormalIcon(wTemp, icon_idx); else initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DRIVE); } } else if (_ILIsFolder (pSimplePidl)) { if (SUCCEEDED(getIconLocationForFolder( pidl, 0, wTemp, MAX_PATH, &icon_idx, &flags))) { initIcon->SetNormalIcon(wTemp, icon_idx); // FIXME: if/when getIconLocationForFolder does something for // GIL_FORSHORTCUT, code below should be uncommented. and // the following line removed. initIcon->SetShortcutIcon(wTemp, icon_idx); } if (SUCCEEDED(getIconLocationForFolder( pidl, GIL_DEFAULTICON, wTemp, MAX_PATH, &icon_idx, &flags))) { initIcon->SetDefaultIcon(wTemp, icon_idx); } // if (SUCCEEDED(getIconLocationForFolder( // pidl, GIL_FORSHORTCUT, wTemp, MAX_PATH, // &icon_idx, // &flags))) // { // initIcon->SetShortcutIcon(wTemp, icon_idx); // } if (SUCCEEDED(getIconLocationForFolder( pidl, GIL_OPENICON, wTemp, MAX_PATH, &icon_idx, &flags))) { initIcon->SetOpenIcon(wTemp, icon_idx); } } else { BOOL found = FALSE; if (_ILIsCPanelStruct(pSimplePidl)) { if (SUCCEEDED(CPanel_GetIconLocationW(pSimplePidl, wTemp, MAX_PATH, &icon_idx))) found = TRUE; } else if (_ILGetExtension(pSimplePidl, sTemp, MAX_PATH)) { if (HCR_MapTypeToValueA(sTemp, sTemp, MAX_PATH, TRUE) && HCR_GetIconA(sTemp, sTemp, NULL, MAX_PATH, &icon_idx)) { if (!lstrcmpA("%1", sTemp)) /* icon is in the file */ { SHGetPathFromIDListW(pidl, wTemp); icon_idx = 0; } else { MultiByteToWideChar(CP_ACP, 0, sTemp, -1, wTemp, MAX_PATH); } found = TRUE; } else if (!lstrcmpiA(sTemp, "lnkfile")) { /* extract icon from shell shortcut */ CComPtr<IShellFolder> dsf; CComPtr<IShellLinkW> psl; if (SUCCEEDED(SHGetDesktopFolder(&dsf))) { HRESULT hr = dsf->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*)&pidl, IID_IShellLinkW, NULL, (LPVOID *)&psl); if (SUCCEEDED(hr)) { hr = psl->GetIconLocation(wTemp, MAX_PATH, &icon_idx); if (SUCCEEDED(hr) && *sTemp) found = TRUE; } } } } if (!found) /* default icon */ initIcon->SetNormalIcon(swShell32Name, 0); else initIcon->SetNormalIcon(wTemp, icon_idx); } return extractIcon; }
/****************************************************************************** * HCR_GetFolderAttributes [Internal] * * Query the registry for a shell folders' attributes * * PARAMS * pidlFolder [I] A simple pidl of type PT_GUID. * pdwAttributes [IO] In: Attributes to be queried, OUT: Resulting attributes. * * RETURNS * TRUE: Found information for the attributes in the registry * FALSE: No attribute information found * * NOTES * If queried for an attribute, which is set in the CallForAttributes registry * value, the function binds to the shellfolder objects and queries it. */ BOOL HCR_GetFolderAttributes(LPCITEMIDLIST pidlFolder, LPDWORD pdwAttributes) { HKEY hSFKey; LPOLESTR pwszCLSID; LONG lResult; DWORD dwTemp, dwLen; static const WCHAR wszAttributes[] = { 'A','t','t','r','i','b','u','t','e','s',0 }; static const WCHAR wszCallForAttributes[] = { 'C','a','l','l','F','o','r','A','t','t','r','i','b','u','t','e','s',0 }; WCHAR wszShellFolderKey[] = { 'C','L','S','I','D','\\','{','0','0','0','2','1','4','0','0','-', '0','0','0','0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0','0', '0','0','0','4','6','}','\\','S','h','e','l','l','F','o','l','d','e','r',0 }; TRACE("(pidlFolder=%p, pdwAttributes=%p)\n", pidlFolder, pdwAttributes); if (!_ILIsPidlSimple(pidlFolder)) { static BOOL firstHit = TRUE; if (firstHit) { ERR("should be called for simple PIDL's only!\n"); firstHit = FALSE; } return FALSE; } if (!_ILIsDesktop(pidlFolder)) { if (FAILED(StringFromCLSID(_ILGetGUIDPointer(pidlFolder), &pwszCLSID))) return FALSE; memcpy(&wszShellFolderKey[6], pwszCLSID, 38 * sizeof(WCHAR)); CoTaskMemFree(pwszCLSID); } lResult = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszShellFolderKey, 0, KEY_READ, &hSFKey); #ifdef __REACTOS__ if (lResult != ERROR_SUCCESS) { ERR("Cannot open key: %ls\n", wszShellFolderKey); return FALSE; } #else if (lResult != ERROR_SUCCESS) return FALSE; #endif dwLen = sizeof(DWORD); lResult = RegQueryValueExW(hSFKey, wszCallForAttributes, 0, NULL, (LPBYTE)&dwTemp, &dwLen); if ((lResult == ERROR_SUCCESS) && (dwTemp & *pdwAttributes)) { LPSHELLFOLDER psfDesktop, psfFolder; HRESULT hr; RegCloseKey(hSFKey); hr = SHGetDesktopFolder(&psfDesktop); if (SUCCEEDED(hr)) { hr = IShellFolder_BindToObject(psfDesktop, pidlFolder, NULL, &IID_IShellFolder, (LPVOID*)&psfFolder); if (SUCCEEDED(hr)) { hr = IShellFolder_GetAttributesOf(psfFolder, 0, NULL, pdwAttributes); IShellFolder_Release(psfFolder); } IShellFolder_Release(psfDesktop); } if (FAILED(hr)) return FALSE; } else { lResult = RegQueryValueExW(hSFKey, wszAttributes, 0, NULL, (LPBYTE)&dwTemp, &dwLen); RegCloseKey(hSFKey); if (lResult == ERROR_SUCCESS) { *pdwAttributes &= dwTemp; } else { return FALSE; } } TRACE("-- *pdwAttributes == 0x%08x\n", *pdwAttributes); return TRUE; }
/************************************************************************** * IExtractIconW::GetIconLocation * * mapping filetype to icon */ static HRESULT WINAPI IExtractIconW_fnGetIconLocation(IExtractIconW * iface, UINT uFlags, LPWSTR szIconFile, UINT cchMax, int * piIndex, UINT * pwFlags) { IExtractIconWImpl *This = impl_from_IExtractIconW(iface); char sTemp[MAX_PATH]; int icon_idx; GUID const * riid; LPITEMIDLIST pSimplePidl = ILFindLastID(This->pidl); TRACE("(%p) (flags=%u %p %u %p %p)\n", This, uFlags, szIconFile, cchMax, piIndex, pwFlags); if (pwFlags) *pwFlags = 0; if (_ILIsDesktop(pSimplePidl)) { lstrcpynW(szIconFile, swShell32Name, cchMax); *piIndex = -IDI_SHELL_DESKTOP; } /* my computer and other shell extensions */ else if ((riid = _ILGetGUIDPointer(pSimplePidl))) { 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]; sprintfW(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]); if (HCR_GetDefaultIconW(xriid, szIconFile, cchMax, &icon_idx)) { *piIndex = icon_idx; } else { lstrcpynW(szIconFile, swShell32Name, cchMax); if(IsEqualGUID(riid, &CLSID_MyComputer)) *piIndex = -IDI_SHELL_MY_COMPUTER; else if(IsEqualGUID(riid, &CLSID_MyDocuments)) *piIndex = -IDI_SHELL_MY_DOCUMENTS; else if(IsEqualGUID(riid, &CLSID_NetworkPlaces)) *piIndex = -IDI_SHELL_MY_NETWORK_PLACES; else if(IsEqualGUID(riid, &CLSID_UnixFolder) || IsEqualGUID(riid, &CLSID_UnixDosFolder)) *piIndex = -IDI_SHELL_DRIVE; else *piIndex = -IDI_SHELL_FOLDER; } } else if (_ILIsDrive (pSimplePidl)) { static const WCHAR drive[] = { 'D','r','i','v','e',0 }; int icon_idx = -1; if (_ILGetDrive(pSimplePidl, sTemp, MAX_PATH)) { switch(GetDriveTypeA(sTemp)) { case DRIVE_REMOVABLE: icon_idx = IDI_SHELL_FLOPPY; break; case DRIVE_CDROM: icon_idx = IDI_SHELL_CDROM; break; case DRIVE_REMOTE: icon_idx = IDI_SHELL_NETDRIVE; break; case DRIVE_RAMDISK: icon_idx = IDI_SHELL_RAMDISK; break; } } if (icon_idx != -1) { lstrcpynW(szIconFile, swShell32Name, cchMax); *piIndex = -icon_idx; } else { if (HCR_GetDefaultIconW(drive, szIconFile, cchMax, &icon_idx)) { *piIndex = icon_idx; } else { lstrcpynW(szIconFile, swShell32Name, cchMax); *piIndex = -IDI_SHELL_DRIVE; } } } else if (_ILIsFolder (pSimplePidl)) { getIconLocationForFolder(This, uFlags, szIconFile, cchMax, piIndex, pwFlags); } else { BOOL found = FALSE; if (_ILIsCPanelStruct(pSimplePidl)) { if (SUCCEEDED(CPanel_GetIconLocationW(pSimplePidl, szIconFile, cchMax, piIndex))) found = TRUE; } else if (_ILGetExtension(pSimplePidl, sTemp, MAX_PATH)) { if (HCR_MapTypeToValueA(sTemp, sTemp, MAX_PATH, TRUE) && HCR_GetDefaultIconA(sTemp, sTemp, MAX_PATH, &icon_idx)) { if (!lstrcmpA("%1", sTemp)) /* icon is in the file */ { SHGetPathFromIDListW(This->pidl, szIconFile); *piIndex = 0; } else { MultiByteToWideChar(CP_ACP, 0, sTemp, -1, szIconFile, cchMax); *piIndex = icon_idx; } found = TRUE; } else if (!lstrcmpiA(sTemp, "lnkfile")) { /* extract icon from shell shortcut */ IShellFolder* dsf; IShellLinkW* psl; if (SUCCEEDED(SHGetDesktopFolder(&dsf))) { HRESULT hr = IShellFolder_GetUIObjectOf(dsf, NULL, 1, (LPCITEMIDLIST*)&This->pidl, &IID_IShellLinkW, NULL, (LPVOID*)&psl); if (SUCCEEDED(hr)) { hr = IShellLinkW_GetIconLocation(psl, szIconFile, MAX_PATH, piIndex); if (SUCCEEDED(hr) && *szIconFile) found = TRUE; IShellLinkW_Release(psl); } IShellFolder_Release(dsf); } } } if (!found) /* default icon */ { lstrcpynW(szIconFile, swShell32Name, cchMax); *piIndex = 0; } } TRACE("-- %s %x\n", debugstr_w(szIconFile), *piIndex); return S_OK; }
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); }