void CShellBrowser::AddToIconFinderQueue(const LVITEM *plvItem) { EnterCriticalSection(&g_icon_cs); ListViewInfo_t lvil; lvil.hListView = m_hListView; lvil.iItem = plvItem->iItem; lvil.pidlFull = ILCombine(m_pidlDirectory,m_pExtraItemInfo[(int)plvItem->lParam].pridl); lvil.hEvent = m_hIconEvent; g_pListViewInfoList.push_back(lvil); /* This code CANNOT run at the same time as the queue remover code. Therefore, if this runs before the remover code is called, the number of APCs queued/ran will mismatch, and no APC will be queued. If it is run after the remover code is called, the number of APCs queued/ran will be the same. At this point, there is no way to stop the currently running APC from exiting. A new APC will thus be queued (and MUST be queued). The awake/asleep status of the thread therefore does NOT matter. */ if(g_nAPCsRan == g_nAPCsQueued) { g_nAPCsQueued++; QueueUserAPC(FindIconAPC,m_hThread,NULL); } LeaveCriticalSection(&g_icon_cs); }
HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc, LPITEMIDLIST * pidlInOut, LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes) { LPITEMIDLIST pidlOut = NULL, pidlTemp = NULL; IShellFolder *psfChild; HRESULT hr; TRACE ("(%p, %p, %p, %s)\n", psf, pbc, pidlInOut ? *pidlInOut : NULL, debugstr_w (szNext)); /* get the shellfolder for the child pidl and let it analyse further */ hr = IShellFolder2_BindToObject (psf, *pidlInOut, pbc, &IID_IShellFolder, (LPVOID *) & psfChild); if (SUCCEEDED(hr)) { hr = IShellFolder_ParseDisplayName (psfChild, hwndOwner, pbc, szNext, pEaten, &pidlOut, pdwAttributes); IShellFolder_Release (psfChild); if (SUCCEEDED(hr)) { pidlTemp = ILCombine (*pidlInOut, pidlOut); if (!pidlTemp) hr = E_OUTOFMEMORY; } if (pidlOut) ILFree (pidlOut); } ILFree (*pidlInOut); *pidlInOut = pidlTemp; TRACE ("-- pidl=%p ret=0x%08x\n", pidlInOut ? *pidlInOut : NULL, hr); return hr; }
static void DoOpenExplore(ItemCmImpl *This, HWND hwnd, LPCSTR verb) { UINT i, bFolderFound = FALSE; LPITEMIDLIST pidlFQ; SHELLEXECUTEINFOA sei; /* Find the first item in the list that is not a value. These commands should never be invoked if there isn't at least one folder item in the list.*/ for(i = 0; i<This->cidl; i++) { if(!_ILIsValue(This->apidl[i])) { bFolderFound = TRUE; break; } } if (!bFolderFound) return; pidlFQ = ILCombine(This->pidl, This->apidl[i]); ZeroMemory(&sei, sizeof(sei)); sei.cbSize = sizeof(sei); sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME; sei.lpIDList = pidlFQ; sei.lpClass = "Folder"; sei.hwnd = hwnd; sei.nShow = SW_SHOWNORMAL; sei.lpVerb = verb; ShellExecuteExA(&sei); SHFree(pidlFQ); }
void CSearchDialog::AddMenuEntries(LPITEMIDLIST pidlParent, const std::list<LPITEMIDLIST> &pidlItemList,DWORD_PTR dwData,HMENU hMenu) { LPITEMIDLIST pidlComplete = ILCombine(pidlParent,pidlItemList.front()); SFGAOF ItemAttributes = SFGAO_FOLDER; GetItemAttributes(pidlComplete,&ItemAttributes); CoTaskMemFree(pidlComplete); TCHAR szTemp[64]; if((ItemAttributes & SFGAO_FOLDER) == SFGAO_FOLDER) { LoadString(GetInstance(),IDS_SEARCH_OPEN_FOLDER_LOCATION, szTemp,SIZEOF_ARRAY(szTemp)); } else { LoadString(GetInstance(),IDS_SEARCH_OPEN_FILE_LOCATION, szTemp,SIZEOF_ARRAY(szTemp)); } MENUITEMINFO mii; mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_STRING|MIIM_ID; mii.wID = MENU_ID_OPEN_FILE_LOCATION; mii.dwTypeData = szTemp; InsertMenuItem(hMenu,1,TRUE,&mii); }
HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) { int size = 0; WCHAR szTemp[MAX_PATH], *szFileName; LPITEMIDLIST pidl; HGLOBAL hGlobal; BOOL bSuccess; TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); /* get path of combined pidl */ pidl = ILCombine(pidlRoot, apidl[0]); if (!pidl) return 0; bSuccess = SHGetPathFromIDListW(pidl, szTemp); SHFree(pidl); if (!bSuccess) return 0; size = (strlenW(szTemp)+1) * sizeof(WCHAR); /* fill the structure */ hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size); if(!hGlobal) return hGlobal; szFileName = (WCHAR *)GlobalLock(hGlobal); memcpy(szFileName, szTemp, size); GlobalUnlock(hGlobal); return hGlobal; }
BOOL Explorerplusplus::HandleShellMenuItem(LPITEMIDLIST pidlParent, const std::list<LPITEMIDLIST> &pidlItemList,DWORD_PTR dwData,TCHAR *szCmd) { FileContextMenuInfo_t *pfcmi = reinterpret_cast<FileContextMenuInfo_t *>(dwData); if(StrCmpI(szCmd,_T("open")) == 0) { /* If ppidl is NULL, open the item specified by pidlParent in the current listview. If ppidl is not NULL, open each of the items specified in ppidl. */ if(pidlItemList.size() == 0) { OpenItem(pidlParent,FALSE,FALSE); } else { LPITEMIDLIST pidlComplete = NULL; for each(auto pidl in pidlItemList) { pidlComplete = ILCombine(pidlParent,pidl); OpenItem(pidlComplete,FALSE,FALSE); CoTaskMemFree(pidlComplete); } } m_bTreeViewOpenInNewTab = TRUE; return TRUE; }
/************************************************************************** * ISF_ControlPanel_fnGetUIObjectOf * * PARAMETERS * HWND hwndOwner, //[in ] Parent window for any output * UINT cidl, //[in ] array size * LPCITEMIDLIST* apidl, //[in ] simple pidl array * REFIID riid, //[in ] Requested Interface * UINT* prgfInOut, //[ ] reserved * LPVOID* ppvObject) //[out] Resulting Interface * */ static HRESULT WINAPI ISF_ControlPanel_fnGetUIObjectOf(IShellFolder2 *iface, HWND hwndOwner, UINT cidl, LPCITEMIDLIST *apidl, REFIID riid, UINT *prgfInOut, void **ppvOut) { ICPanelImpl *This = impl_from_IShellFolder2(iface); LPITEMIDLIST pidl; IUnknown *pObj = NULL; HRESULT hr = E_INVALIDARG; TRACE("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n", This, hwndOwner, cidl, apidl, shdebugstr_guid(riid), prgfInOut, ppvOut); if (ppvOut) { *ppvOut = NULL; if (IsEqualIID(riid, &IID_IContextMenu) &&(cidl >= 1)) { return ItemMenu_Constructor((IShellFolder*)iface, This->pidlRoot, apidl, cidl, riid, ppvOut); } else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1)) { pObj = (LPUNKNOWN) IDataObject_Constructor(hwndOwner, This->pidlRoot, apidl, cidl); hr = S_OK; } else if (IsEqualIID(riid, &IID_IExtractIconA) &&(cidl == 1)) { pidl = ILCombine(This->pidlRoot, apidl[0]); pObj = (LPUNKNOWN) IExtractIconA_Constructor(pidl); SHFree(pidl); hr = S_OK; } else if (IsEqualIID(riid, &IID_IExtractIconW) &&(cidl == 1)) { pidl = ILCombine(This->pidlRoot, apidl[0]); pObj = (LPUNKNOWN) IExtractIconW_Constructor(pidl); SHFree(pidl); hr = S_OK; } else if ((IsEqualIID(riid,&IID_IShellLinkW) || IsEqualIID(riid,&IID_IShellLinkA)) && (cidl == 1)) { pidl = ILCombine(This->pidlRoot, apidl[0]); hr = IShellLink_ConstructFromFile(NULL, riid, pidl,(LPVOID*)&pObj); SHFree(pidl); } else { hr = E_NOINTERFACE; } if (SUCCEEDED(hr) && !pObj) hr = E_OUTOFMEMORY; *ppvOut = pObj; } TRACE("(%p)->hr=0x%08x\n", This, hr); return hr; }
/* TODO: These groups have changed as of Windows Vista. */ void CShellBrowser::DetermineItemTotalSizeGroup(int iItemInternal,TCHAR *szGroupHeader,int cchMax) const { IShellFolder *pShellFolder = NULL; LPITEMIDLIST pidlComplete = NULL; LPITEMIDLIST pidlDirectory = NULL; LPITEMIDLIST pidlRelative = NULL; TCHAR *SizeGroups[] = {_T("Unspecified"),_T("Small"),_T("Medium"),_T("Huge"),_T("Gigantic")}; TCHAR szItem[MAX_PATH]; STRRET str; ULARGE_INTEGER nTotalBytes; ULARGE_INTEGER nFreeBytes; BOOL bRoot; BOOL bRes = FALSE; ULARGE_INTEGER TotalSizeGroupLimits[6]; int nGroups = 5; int iSize = 0; int i; TotalSizeGroupLimits[0].QuadPart = 0; TotalSizeGroupLimits[1].QuadPart = 0; TotalSizeGroupLimits[2].QuadPart = GBYTE; TotalSizeGroupLimits[3].QuadPart = 20 * TotalSizeGroupLimits[2].QuadPart; TotalSizeGroupLimits[4].QuadPart = 100 * TotalSizeGroupLimits[2].QuadPart; GetIdlFromParsingName(m_CurDir,&pidlDirectory); pidlComplete = ILCombine(pidlDirectory,m_pExtraItemInfo[iItemInternal].pridl); SHBindToParent(pidlComplete, IID_PPV_ARGS(&pShellFolder), (LPCITEMIDLIST *) &pidlRelative); pShellFolder->GetDisplayNameOf(pidlRelative,SHGDN_FORPARSING,&str); StrRetToBuf(&str,pidlRelative,szItem,SIZEOF_ARRAY(szItem)); bRoot = PathIsRoot(szItem); if(bRoot) { bRes = GetDiskFreeSpaceEx(szItem,NULL,&nTotalBytes,&nFreeBytes); CoTaskMemFree(pidlDirectory); CoTaskMemFree(pidlComplete); pShellFolder->Release(); i = nGroups - 1; while(nTotalBytes.QuadPart < TotalSizeGroupLimits[i].QuadPart && i > 0) i--; iSize = i; } if(!bRoot || !bRes) { iSize = 0; } StringCchCopy(szGroupHeader,cchMax,SizeGroups[iSize]); }
/*********************************************************************** * SHOpenFolderAndSelectItems * * Unimplemented. */ EXTERN_C HRESULT WINAPI SHOpenFolderAndSelectItems(LPITEMIDLIST pidlFolder, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD dwFlags) { ERR("SHOpenFolderAndSelectItems() is hackplemented\n"); PCIDLIST_ABSOLUTE pidlItem; if (cidl) { /* Firefox sends a full pidl here dispite the fact it is a PCUITEMID_CHILD_ARRAY -_- */ if (ILGetNext(apidl[0]) != NULL) { pidlItem = apidl[0]; } else { pidlItem = ILCombine(pidlFolder, apidl[0]); } } else { pidlItem = pidlFolder; } CComPtr<IShellFolder> psfDesktop; HRESULT hr = SHGetDesktopFolder(&psfDesktop); if (FAILED_UNEXPECTEDLY(hr)) return hr; STRRET strret; hr = psfDesktop->GetDisplayNameOf(pidlItem, SHGDN_FORPARSING, &strret); if (FAILED_UNEXPECTEDLY(hr)) return hr; WCHAR wszBuf[MAX_PATH]; hr = StrRetToBufW(&strret, pidlItem, wszBuf, _countof(wszBuf)); if (FAILED_UNEXPECTEDLY(hr)) return hr; WCHAR wszParams[MAX_PATH]; wcscpy(wszParams, L"/select,"); wcscat(wszParams, wszBuf); SHELLEXECUTEINFOW sei; memset(&sei, 0, sizeof sei); sei.cbSize = sizeof sei; sei.fMask = SEE_MASK_WAITFORINPUTIDLE; sei.lpFile = L"explorer.exe"; sei.lpParameters = wszParams; if (ShellExecuteExW(&sei)) return S_OK; else return E_FAIL; }
HRESULT WINAPI SHCreateShellItem(LPCITEMIDLIST pidlParent, IShellFolder *psfParent, LPCITEMIDLIST pidl, IShellItem **ppsi) { LPITEMIDLIST new_pidl; HRESULT ret; TRACE("(%p,%p,%p,%p)\n", pidlParent, psfParent, pidl, ppsi); *ppsi = NULL; if (!pidl) { return E_INVALIDARG; } else if (pidlParent || psfParent) { LPITEMIDLIST temp_parent=NULL; if (!pidlParent) { IPersistFolder2* ppf2Parent; if (FAILED(IShellFolder_QueryInterface(psfParent, &IID_IPersistFolder2, (void**)&ppf2Parent))) { FIXME("couldn't get IPersistFolder2 interface of parent\n"); return E_NOINTERFACE; } if (FAILED(IPersistFolder2_GetCurFolder(ppf2Parent, &temp_parent))) { FIXME("couldn't get parent PIDL\n"); IPersistFolder2_Release(ppf2Parent); return E_NOINTERFACE; } pidlParent = temp_parent; IPersistFolder2_Release(ppf2Parent); } new_pidl = ILCombine(pidlParent, pidl); ILFree(temp_parent); if (!new_pidl) return E_OUTOFMEMORY; } else { new_pidl = ILClone(pidl); if (!new_pidl) return E_OUTOFMEMORY; } ret = SHCreateItemFromIDList(new_pidl, &IID_IShellItem, (void**)ppsi); ILFree(new_pidl); return ret; }
void CShellBrowser::QueryFullItemNameInternal(int iItemInternal,TCHAR *szFullFileName,UINT cchMax) const { LPITEMIDLIST pidlComplete = NULL; pidlComplete = ILCombine(m_pidlDirectory,m_pExtraItemInfo[iItemInternal].pridl); GetDisplayName(pidlComplete,szFullFileName,cchMax,SHGDN_FORPARSING); CoTaskMemFree(pidlComplete); }
/*********************************************************************** * SHELL32_CoCreateInitSF * * Creates a shell folder and initializes it with a pidl and a root folder * via IPersistFolder3 or IPersistFolder. * * NOTES * pathRoot can be NULL for Folders being a drive. * In this case the absolute path is built from pidlChild (eg. C:) */ static HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot, LPCITEMIDLIST pidlChild, REFCLSID clsid, IShellFolder** ppsfOut) { HRESULT hr; CComPtr<IShellFolder> pShellFolder; TRACE ("%p %s %p\n", pidlRoot, debugstr_w(pathRoot), pidlChild); hr = SHCoCreateInstance(NULL, &clsid, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder)); if (SUCCEEDED (hr)) { LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild); CComPtr<IPersistFolder> ppf; CComPtr<IPersistFolder3> ppf3; if (SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3)))) { PERSIST_FOLDER_TARGET_INFO ppfti; ZeroMemory (&ppfti, sizeof (ppfti)); /* fill the PERSIST_FOLDER_TARGET_INFO */ ppfti.dwAttributes = -1; ppfti.csidl = -1; /* build path */ if (pathRoot) { lstrcpynW (ppfti.szTargetParsingName, pathRoot, MAX_PATH - 1); PathAddBackslashW(ppfti.szTargetParsingName); /* FIXME: why have drives a backslash here ? */ } if (pidlChild) { int len = wcslen(ppfti.szTargetParsingName); if (!_ILSimpleGetTextW(pidlChild, ppfti.szTargetParsingName + len, MAX_PATH - len)) hr = E_INVALIDARG; } ppf3->InitializeEx(NULL, pidlAbsolute, &ppfti); } else if (SUCCEEDED((hr = pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder, &ppf))))) { ppf->Initialize(pidlAbsolute); } ILFree (pidlAbsolute); } *ppsfOut = pShellFolder.Detach(); TRACE ("-- (%p) ret=0x%08x\n", *ppsfOut, hr); return hr; }
void CreateLnkOnDesktop(const LPWSTR connTitle) { IShellLink *SLink; IPersistFile *PF; HRESULT HRes; TCHAR desktop_path[MAX_PATH] = TEXT(""); TCHAR pszFullLnkPath[MAX_PATH]; CoInitialize(NULL); ITEMIDLIST* pidl1 = NULL; SHGetFolderLocation(NULL, CSIDL_CONNECTIONS, NULL, 0, &pidl1); IShellFolder *desktop, *ncfolder; SHGetDesktopFolder(&desktop); desktop->BindToObject(pidl1, NULL, IID_IShellFolder, (void**)&ncfolder); IEnumIDList *items; ncfolder->EnumObjects(NULL, SHCONTF_NONFOLDERS, &items); ITEMIDLIST* pidl2 = NULL; while (S_OK == items->Next(1, &pidl2, NULL)) { STRRET sr = {STRRET_WSTR}; ncfolder->GetDisplayNameOf(pidl2, SHGDN_NORMAL, &sr); TCHAR buf[MAX_PATH] = TEXT(""); StrRetToBuf(&sr, pidl2, buf, MAX_PATH); if (0 == StrCmpI(buf, connTitle)) { ITEMIDLIST* pidl3 = ILCombine(pidl1, pidl2); HRESULT HRes = CoCreateInstance(CLSID_ShellLink, 0, CLSCTX_INPROC_SERVER, IID_IShellLink, ( LPVOID*)&SLink); SLink->SetIDList(pidl3); SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, desktop_path); StringCbPrintf(pszFullLnkPath, MAX_PATH * sizeof(TCHAR), TEXT("%s\\%s.lnk"), desktop_path, connTitle); HRes = SLink->QueryInterface(IID_IPersistFile, (LPVOID*)&PF); HRes = PF->Save((LPCOLESTR)pszFullLnkPath, TRUE); PF->Release(); SLink->Release(); ILFree(pidl3); ILFree(pidl2); break; } ILFree(pidl2); pidl2 = NULL; } ncfolder->Release(); desktop->Release(); ILFree(pidl1); CoUninitialize(); }
/* Updates an items pidl, returning a pointer to the new idl. */ LPITEMIDLIST CMyTreeView::UpdateItemInfo(LPITEMIDLIST pidlParent,int iItemId) { ItemInfo_t *pItemInfo = NULL; pItemInfo = &m_pItemInfo[iItemId]; CoTaskMemFree(pItemInfo->pidl); m_pItemInfo[iItemId].pidl = ILCombine(pidlParent,m_pItemInfo[iItemId].pridl); return m_pItemInfo[iItemId].pidl; }
/* TODO: Need to sort based on percentage free. */ void CShellBrowser::DetermineItemFreeSpaceGroup(int iItemInternal,TCHAR *szGroupHeader,int cchMax) const { std::list<TypeGroup_t>::iterator itr; LPITEMIDLIST pidlComplete = NULL; LPITEMIDLIST pidlDirectory = NULL; TCHAR szFreeSpace[MAX_PATH]; IShellFolder *pShellFolder = NULL; LPITEMIDLIST pidlRelative = NULL; STRRET str; TCHAR szItem[MAX_PATH]; ULARGE_INTEGER nTotalBytes; ULARGE_INTEGER nFreeBytes; BOOL bRoot; BOOL bRes = FALSE; GetIdlFromParsingName(m_CurDir,&pidlDirectory); pidlComplete = ILCombine(pidlDirectory,m_pExtraItemInfo[iItemInternal].pridl); SHBindToParent(pidlComplete, IID_PPV_ARGS(&pShellFolder), (LPCITEMIDLIST *)&pidlRelative); pShellFolder->GetDisplayNameOf(pidlRelative,SHGDN_FORPARSING,&str); StrRetToBuf(&str,pidlRelative,szItem,SIZEOF_ARRAY(szItem)); CoTaskMemFree(pidlDirectory); CoTaskMemFree(pidlComplete); pShellFolder->Release(); bRoot = PathIsRoot(szItem); if(bRoot) { bRes = GetDiskFreeSpaceEx(szItem,NULL,&nTotalBytes,&nFreeBytes); LARGE_INTEGER lDiv1; LARGE_INTEGER lDiv2; lDiv1.QuadPart = 100; lDiv2.QuadPart = 10; /* Divide by 10 to remove the one's digit, then multiply by 10 so that only the ten's digit rmains. */ StringCchPrintf(szFreeSpace,SIZEOF_ARRAY(szFreeSpace), _T("%I64d%% free"),(((nFreeBytes.QuadPart * lDiv1.QuadPart) / nTotalBytes.QuadPart) / lDiv2.QuadPart) * lDiv2.QuadPart); } if(!bRoot || !bRes) { StringCchCopy(szFreeSpace,SIZEOF_ARRAY(szFreeSpace),_T("Unspecified")); } StringCchCopy(szGroupHeader,cchMax,szFreeSpace); }
static HRESULT erase_items(HWND parent,const LPCITEMIDLIST * apidl, UINT cidl, BOOL confirm) { UINT i=0; HRESULT ret = S_OK; LPITEMIDLIST recyclebin; if(confirm) { WCHAR arg[MAX_PATH]; WCHAR message[100]; WCHAR caption[50]; switch(cidl) { case 0: return S_OK; case 1: { WIN32_FIND_DATAW data; TRASH_UnpackItemID(&((*apidl)->mkid),&data); lstrcpynW(arg,data.cFileName,MAX_PATH); LoadStringW(shell32_hInstance,IDS_RECYCLEBIN_ERASEITEM,message, sizeof(message)/sizeof(WCHAR)); break; } default: { static const WCHAR format[]={'%','u','\0'}; LoadStringW(shell32_hInstance,IDS_RECYCLEBIN_ERASEMULTIPLE, message,sizeof(message)/sizeof(WCHAR)); sprintfW(arg,format,cidl); break; } } LoadStringW(shell32_hInstance,IDS_RECYCLEBIN_ERASE_CAPTION,caption, sizeof(caption)/sizeof(WCHAR)); if(ShellMessageBoxW(shell32_hInstance,parent,message,caption, MB_YESNO|MB_ICONEXCLAMATION,arg)!=IDYES) return ret; } SHGetFolderLocation(parent,CSIDL_BITBUCKET,0,0,&recyclebin); for (; i<cidl; i++) { if(SUCCEEDED(TRASH_EraseItem(apidl[i]))) SHChangeNotify(SHCNE_DELETE,SHCNF_IDLIST, ILCombine(recyclebin,apidl[i]),0); } ILFree(recyclebin); return S_OK; }
int CALLBACK CShellBrowser::SortByName(int InternalIndex1,int InternalIndex2) const { if(m_bVirtualFolder) { TCHAR FullFileName1[MAX_PATH]; LPITEMIDLIST pidlComplete1 = ILCombine(m_pidlDirectory,m_pExtraItemInfo[InternalIndex1].pridl); GetDisplayName(pidlComplete1,FullFileName1,SHGDN_FORPARSING); CoTaskMemFree(pidlComplete1); TCHAR FullFileName2[MAX_PATH]; LPITEMIDLIST pidlComplete2 = ILCombine(m_pidlDirectory,m_pExtraItemInfo[InternalIndex2].pridl); GetDisplayName(pidlComplete2,FullFileName2,SHGDN_FORPARSING); CoTaskMemFree(pidlComplete2); BOOL IsRoot1 = PathIsRoot(FullFileName1); BOOL IsRoot2 = PathIsRoot(FullFileName2); if(IsRoot1 && !IsRoot2) { return -1; } else if(!IsRoot1 && IsRoot2) { return 1; } else if(IsRoot1 && IsRoot2) { /* If the items been compared are both drives, sort by drive letter, rather than display name. */ return StrCmpLogicalW(FullFileName1,FullFileName2); } } std::wstring Name1 = GetNameColumnText(InternalIndex1); std::wstring Name2 = GetNameColumnText(InternalIndex2); return StrCmpLogicalW(Name1.c_str(),Name2.c_str()); }
BOOL CSearchDialog::HandleShellMenuItem(LPITEMIDLIST pidlParent, const std::list<LPITEMIDLIST> &pidlItemList,DWORD_PTR dwData,TCHAR *szCmd) { if(StrCmpI(szCmd,_T("open")) == 0) { for each(auto pidlItem in pidlItemList) { LPITEMIDLIST pidlComplete = ILCombine(pidlParent,pidlItem); m_pexpp->OpenItem(pidlComplete,FALSE,FALSE); CoTaskMemFree(pidlComplete); } return TRUE; }
/*********************************************************************** * SHELL32_CoCreateInitSF * * Creates a shell folder and initializes it with a pidl and a root folder * via IPersistFolder3 or IPersistFolder. * * NOTES * pathRoot can be NULL for Folders being a drive. * In this case the absolute path is built from pidlChild (eg. C:) */ static HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot, LPCITEMIDLIST pidlChild, REFCLSID clsid, LPVOID * ppvOut) { HRESULT hr; TRACE ("(%p %s %p %s %p)\n", pidlRoot, debugstr_w(pathRoot), pidlChild, debugstr_guid(clsid), ppvOut); hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IShellFolder, ppvOut); if (SUCCEEDED (hr)) { LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild); IPersistFolder *pPF; IPersistFolder3 *ppf; if (_ILIsFolder(pidlChild) && SUCCEEDED (IUnknown_QueryInterface ((IUnknown *) * ppvOut, &IID_IPersistFolder3, (LPVOID *) & ppf))) { PERSIST_FOLDER_TARGET_INFO ppfti; ZeroMemory (&ppfti, sizeof (ppfti)); /* fill the PERSIST_FOLDER_TARGET_INFO */ ppfti.dwAttributes = -1; ppfti.csidl = -1; /* build path */ if (pathRoot) { lstrcpynW (ppfti.szTargetParsingName, pathRoot, MAX_PATH - 1); PathAddBackslashW(ppfti.szTargetParsingName); /* FIXME: why have drives a backslash here ? */ } if (pidlChild) { int len = lstrlenW(ppfti.szTargetParsingName); if (!_ILSimpleGetTextW(pidlChild, ppfti.szTargetParsingName + len, MAX_PATH - len)) hr = E_INVALIDARG; } IPersistFolder3_InitializeEx (ppf, NULL, pidlAbsolute, &ppfti); IPersistFolder3_Release (ppf); } else if (SUCCEEDED ((hr = IUnknown_QueryInterface ((IUnknown *) * ppvOut, &IID_IPersistFolder, (LPVOID *) & pPF)))) { IPersistFolder_Initialize (pPF, pidlAbsolute); IPersistFolder_Release (pPF); } ILFree (pidlAbsolute); } TRACE ("-- (%p) ret=0x%08x\n", *ppvOut, hr); return hr; }
HRESULT CShellView2::SelectAndPositionItem(LPCITEMIDLIST pidlItem,UINT uFlags,POINT *ppt) { LPITEMIDLIST pidlComplete = NULL; LPITEMIDLIST pidlDirectory = NULL; /* The idlist passed is only a relative (child) one. Combine it with the tabs' current directory to get a full idlist. */ pidlDirectory = m_pexpp->GetActiveShellBrowser()->QueryCurrentDirectoryIdl(); pidlComplete = ILCombine(pidlDirectory,pidlItem); m_pexpp->GetActiveShellBrowser()->QueueRename(pidlComplete); CoTaskMemFree(pidlDirectory); CoTaskMemFree(pidlComplete); return S_OK; }
static void DoRestore(RecycleBinMenu *This) { /*TODO add prompts*/ UINT i; for(i=0;i<This->cidl;i++) { WIN32_FIND_DATAW data; TRASH_UnpackItemID(&((This->apidl[i])->mkid),&data); if(PathFileExistsW(data.cFileName)) { PIDLIST_ABSOLUTE dest_pidl = ILCreateFromPathW(data.cFileName); WCHAR message[100]; WCHAR caption[50]; if(_ILIsFolder(ILFindLastID(dest_pidl))) LoadStringW(shell32_hInstance,IDS_RECYCLEBIN_OVERWRITEFOLDER, message,sizeof(message)/sizeof(WCHAR)); else LoadStringW(shell32_hInstance,IDS_RECYCLEBIN_OVERWRITEFILE, message,sizeof(message)/sizeof(WCHAR)); LoadStringW(shell32_hInstance,IDS_RECYCLEBIN_OVERWRITE_CAPTION, caption,sizeof(caption)/sizeof(WCHAR)); if(ShellMessageBoxW(shell32_hInstance,GetActiveWindow(),message, caption,MB_YESNO|MB_ICONEXCLAMATION, data.cFileName)!=IDYES) continue; } if(SUCCEEDED(TRASH_RestoreItem(This->apidl[i]))) { IPersistFolder2 *persist; LPITEMIDLIST root_pidl; PIDLIST_ABSOLUTE dest_pidl = ILCreateFromPathW(data.cFileName); BOOL is_folder = _ILIsFolder(ILFindLastID(dest_pidl)); IShellFolder2_QueryInterface(This->folder,&IID_IPersistFolder2, (void**)&persist); IPersistFolder2_GetCurFolder(persist,&root_pidl); SHChangeNotify(is_folder ? SHCNE_RMDIR : SHCNE_DELETE, SHCNF_IDLIST,ILCombine(root_pidl,This->apidl[i]),0); SHChangeNotify(is_folder ? SHCNE_MKDIR : SHCNE_CREATE, SHCNF_IDLIST,dest_pidl,0); ILFree(dest_pidl); ILFree(root_pidl); } } }
void Explorerplusplus::AddMenuEntries(LPITEMIDLIST pidlParent, const std::list<LPITEMIDLIST> &pidlItemList,DWORD_PTR dwData,HMENU hMenu) { assert(dwData != NULL); FileContextMenuInfo_t *pfcmi = reinterpret_cast<FileContextMenuInfo_t *>(dwData); bool AddNewTabMenuItem = false; if(pfcmi->uFrom == FROM_LISTVIEW) { if(pidlItemList.size() == 1) { SFGAOF FileAttributes = SFGAO_FOLDER; LPITEMIDLIST pidlComplete = ILCombine(pidlParent,pidlItemList.front()); GetItemAttributes(pidlComplete,&FileAttributes); CoTaskMemFree(pidlComplete); if(FileAttributes & SFGAO_FOLDER) { AddNewTabMenuItem = true; } } } else if(pfcmi->uFrom == FROM_TREEVIEW) { /* The treeview only contains folders, so the new tab menu item will always be shown. */ AddNewTabMenuItem = true; } if(AddNewTabMenuItem) { MENUITEMINFO mii; TCHAR szTemp[64]; LoadString(m_hLanguageModule,IDS_GENERAL_OPEN_IN_NEW_TAB,szTemp,SIZEOF_ARRAY(szTemp)); mii.cbSize = sizeof(mii); mii.fMask = MIIM_STRING|MIIM_ID; mii.wID = MENU_OPEN_IN_NEW_TAB; mii.dwTypeData = szTemp; InsertMenuItem(hMenu,1,TRUE,&mii); } }
void CShellBrowser::DetermineItemTypeGroupVirtual(int iItemInternal,TCHAR *szGroupHeader,int cchMax) const { LPITEMIDLIST pidlComplete = NULL; LPITEMIDLIST pidlDirectory = NULL; SHFILEINFO shfi; std::list<TypeGroup_t>::iterator itr; GetIdlFromParsingName(m_CurDir,&pidlDirectory); pidlComplete = ILCombine(pidlDirectory,m_pExtraItemInfo[iItemInternal].pridl); SHGetFileInfo((LPTSTR)pidlComplete,0,&shfi,sizeof(shfi),SHGFI_PIDL|SHGFI_TYPENAME); StringCchCopy(szGroupHeader,cchMax,shfi.szTypeName); CoTaskMemFree(pidlComplete); CoTaskMemFree(pidlDirectory); }
// // A helper function to be called from ISF::GetDisplayNameOf implementation // HRESULT SHGetPathHelper(LPCITEMIDLIST pidlFolder, LPCITEMIDLIST pidl, LPSTRRET pStrRet) { HRESULT hres; LPITEMIDLIST pidlFull = ILCombine(pidlFolder, pidl); if (pidlFull) { #ifdef UNICODE TCHAR szName[MAX_PATH]; #endif pStrRet->uType = STRRET_CSTR; // Return no name if failure pStrRet->cStr[0] = '\0'; #ifdef UNICODE if (SHGetPathFromIDList(pidlFull, szName)) { pStrRet->pOleStr = (LPOLESTR)SHAlloc((lstrlen(szName)+1)*SIZEOF(TCHAR)); if ( pStrRet->pOleStr != NULL ) { lstrcpy(pStrRet->pOleStr, szName); pStrRet->uType = STRRET_OLESTR; hres = S_OK; } else { hres = E_OUTOFMEMORY; } } #else if (SHGetPathFromIDList(pidlFull, pStrRet->cStr)) { hres = NOERROR; } #endif else { hres = E_INVALIDARG; } ILFree(pidlFull); } else { hres = E_OUTOFMEMORY; } return hres; }
void CShellBrowser::DetermineItemFileSystemGroup(int iItemInternal,TCHAR *szGroupHeader,int cchMax) const { LPITEMIDLIST pidlComplete = NULL; IShellFolder *pShellFolder = NULL; LPITEMIDLIST pidlRelative = NULL; TCHAR szFileSystemName[MAX_PATH]; TCHAR szItem[MAX_PATH]; STRRET str; BOOL bRoot; BOOL bRes; pidlComplete = ILCombine(m_pidlDirectory,m_pExtraItemInfo[iItemInternal].pridl); SHBindToParent(pidlComplete, IID_PPV_ARGS(&pShellFolder), (LPCITEMIDLIST *)&pidlRelative); pShellFolder->GetDisplayNameOf(pidlRelative,SHGDN_FORPARSING,&str); StrRetToBuf(&str,pidlRelative,szItem,SIZEOF_ARRAY(szItem)); bRoot = PathIsRoot(szItem); if(bRoot) { bRes = GetVolumeInformation(szItem,NULL,0,NULL,NULL,NULL,szFileSystemName, SIZEOF_ARRAY(szFileSystemName)); if(!bRes || *szFileSystemName == '\0') { /* TODO: Move into string table. */ StringCchCopy(szFileSystemName,SIZEOF_ARRAY(szFileSystemName),_T("Unspecified")); } } else { /* TODO: Move into string table. */ StringCchCopy(szFileSystemName,SIZEOF_ARRAY(szFileSystemName),_T("Unspecified")); } StringCchCopy(szGroupHeader,cchMax,szFileSystemName); pShellFolder->Release(); CoTaskMemFree(pidlComplete); }
HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc, LPITEMIDLIST * pidlInOut, LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes) { HRESULT hr = E_INVALIDARG; LPITEMIDLIST pidlIn = pidlInOut ? *pidlInOut : NULL; LPITEMIDLIST pidlOut = NULL; LPITEMIDLIST pidlTemp = NULL; CComPtr<IShellFolder> psfChild; TRACE ("(%p, %p, %p, %s)\n", psf, pbc, pidlIn, debugstr_w (szNext)); /* get the shellfolder for the child pidl and let it analyse further */ hr = psf->BindToObject(pidlIn, pbc, IID_PPV_ARG(IShellFolder, &psfChild)); if (FAILED(hr)) return hr; hr = psfChild->ParseDisplayName(hwndOwner, pbc, szNext, pEaten, &pidlOut, pdwAttributes); if (FAILED(hr)) return hr; pidlTemp = ILCombine (pidlIn, pidlOut); if (!pidlTemp) { hr = E_OUTOFMEMORY; if (pidlOut) ILFree(pidlOut); return hr; } if (pidlOut) ILFree (pidlOut); if (pidlIn) ILFree (pidlIn); *pidlInOut = pidlTemp; TRACE ("-- pidl=%p ret=0x%08x\n", pidlInOut ? *pidlInOut : NULL, hr); return S_OK; }
/****************************************************************************** * InsertTreeViewItem [Internal] * * PARAMS * info [I] data for the dialog * lpsf [I] IShellFolder interface of the item's parent shell folder * pidl [I] ITEMIDLIST of the child to insert, relative to parent * pidlParent [I] ITEMIDLIST of the parent shell folder * pEnumIL [I] Iterator for the children of the item to be inserted * hParent [I] The treeview-item that represents the parent shell folder * * RETURNS * Success: Handle to the created and inserted treeview-item * Failure: NULL */ static HTREEITEM InsertTreeViewItem( browse_info *info, IShellFolder * lpsf, LPCITEMIDLIST pidl, LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL, HTREEITEM hParent) { TVITEMW tvi; TVINSERTSTRUCTW tvins; WCHAR szBuff[MAX_PATH]; LPTV_ITEMDATA lptvid=0; tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; tvi.cChildren= pEnumIL ? 1 : 0; tvi.mask |= TVIF_CHILDREN; lptvid = SHAlloc( sizeof(TV_ITEMDATA) ); if (!lptvid) return NULL; if (!GetName(lpsf, pidl, SHGDN_NORMAL, szBuff)) return NULL; tvi.pszText = szBuff; tvi.cchTextMax = MAX_PATH; tvi.lParam = (LPARAM)lptvid; IShellFolder_AddRef(lpsf); lptvid->lpsfParent = lpsf; lptvid->lpi = ILClone(pidl); lptvid->lpifq = pidlParent ? ILCombine(pidlParent, pidl) : ILClone(pidl); lptvid->pEnumIL = pEnumIL; GetNormalAndSelectedIcons(lptvid->lpifq, &tvi); tvins.u.item = tvi; tvins.hInsertAfter = NULL; tvins.hParent = hParent; return (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_INSERTITEM, 0, (LPARAM)&tvins ); }
HRESULT STDMETHODCALLTYPE CFolder::ParseName(BSTR bName, FolderItem **ppid) { TRACE("(%p, %s, %p)\n", this, wine_dbgstr_w(bName), ppid); if (!ppid) return E_POINTER; *ppid = NULL; CComPtr<IShellFolder> psfCurrent; HRESULT hr = GetShellFolder(psfCurrent); if (FAILED_UNEXPECTEDLY(hr)) return hr; CComHeapPtr<ITEMIDLIST_RELATIVE> relativePidl; hr = psfCurrent->ParseDisplayName(NULL, NULL, bName, NULL, &relativePidl, NULL); if (!SUCCEEDED(hr)) return S_FALSE; CFolderItem* item = new CComObject<CFolderItem>(); item->AddRef(); item->Init(ILCombine(m_idlist, relativePidl)); *ppid = item; return S_OK; }
void GetDrives (CDriveArray &array) { array.clear (); IShellFolder *psfDesktop; SHGetDesktopFolder(&psfDesktop); if(psfDesktop == NULL) return; LPITEMIDLIST pidlMyComputer; SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidlMyComputer); if(pidlMyComputer == NULL) { psfDesktop->Release(); return; } IShellFolder *psfMyComputer; psfDesktop->BindToObject(pidlMyComputer, NULL, IID_IShellFolder, (LPVOID*)&psfMyComputer); if(psfMyComputer) { IEnumIDList* pEnum; if(SUCCEEDED(psfMyComputer->EnumObjects(NULL, SHCONTF_FOLDERS|SHCONTF_INCLUDEHIDDEN, &pEnum))) { ITEMIDLIST* pidl; DWORD dwFetched = 1; TCHAR path[MAX_PATH]; while(SUCCEEDED(pEnum->Next(1, &pidl, &dwFetched)) && dwFetched) { SHFILEINFO sfi; //LPITEMIDLIST pidl_full = Pidl_Concatenate (pidlMyComputer, pidl); LPITEMIDLIST pidl_full = ILCombine (pidlMyComputer, pidl); SHGetPathFromIDList (pidl_full, path); UINT nType = GetDriveType( path); // if( DRIVE_REMOVABLE < nType && nType <= DRIVE_RAMDISK ) if( nType != DRIVE_UNKNOWN && nType != DRIVE_NO_ROOT_DIR ) if(SHGetFileInfo((LPCTSTR)pidl_full, 0, &sfi, sizeof(sfi), SHGFI_PIDL | SHGFI_DISPLAYNAME | SHGFI_TYPENAME | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_LINKOVERLAY)) { CDriveInfo info; info.m_Name = sfi.szDisplayName; info.m_Path = path; info.m_Type = sfi.szTypeName; info.m_nImage = sfi.iIcon; info.m_nType = nType; DWORD SectorsPerCluster; // sectors per cluster DWORD BytesPerSector; // bytes per sector DWORD NumberOfFreeClusters; // free clusters DWORD TotalNumberOfClusters; // total clusters // TRACE (L"%s %s\n", sfi.szDisplayName, path); if (nType != DRIVE_REMOVABLE ) if (GetDiskFreeSpace (path, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters)) { DWORD BytesPerCluster = BytesPerSector * SectorsPerCluster; info.m_FreeSpace = UInt32x32To64(NumberOfFreeClusters, BytesPerCluster); info.m_TotalSize= UInt32x32To64(TotalNumberOfClusters, BytesPerCluster); } array.push_back (info); } } pEnum->Release (); } psfMyComputer->Release(); } CoTaskMemFree(pidlMyComputer); psfDesktop->Release(); }
HRESULT WINAPI SHGetItemFromDataObject(IDataObject *pdtobj, DATAOBJ_GET_ITEM_FLAGS dwFlags, REFIID riid, void **ppv) { FORMATETC fmt; STGMEDIUM medium; HRESULT ret; TRACE("%p, %x, %s, %p\n", pdtobj, dwFlags, debugstr_guid(riid), ppv); if(!pdtobj) return E_INVALIDARG; fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW); fmt.ptd = NULL; fmt.dwAspect = DVASPECT_CONTENT; fmt.lindex = -1; fmt.tymed = TYMED_HGLOBAL; ret = IDataObject_GetData(pdtobj, &fmt, &medium); if(SUCCEEDED(ret)) { LPIDA pida = GlobalLock(medium.u.hGlobal); if((pida->cidl > 1 && !(dwFlags & DOGIF_ONLY_IF_ONE)) || pida->cidl == 1) { LPITEMIDLIST pidl; /* Get the first pidl (parent + child1) */ pidl = ILCombine((LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[0]), (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[1])); ret = SHCreateItemFromIDList(pidl, riid, ppv); ILFree(pidl); } else { ret = E_FAIL; } GlobalUnlock(medium.u.hGlobal); GlobalFree(medium.u.hGlobal); } if(FAILED(ret) && !(dwFlags & DOGIF_NO_HDROP)) { TRACE("Attempting to fall back on CF_HDROP.\n"); fmt.cfFormat = CF_HDROP; fmt.ptd = NULL; fmt.dwAspect = DVASPECT_CONTENT; fmt.lindex = -1; fmt.tymed = TYMED_HGLOBAL; ret = IDataObject_GetData(pdtobj, &fmt, &medium); if(SUCCEEDED(ret)) { DROPFILES *df = GlobalLock(medium.u.hGlobal); LPBYTE files = (LPBYTE)df + df->pFiles; BOOL multiple_files = FALSE; ret = E_FAIL; if(!df->fWide) { WCHAR filename[MAX_PATH]; PCSTR first_file = (PCSTR)files; if(*(files + lstrlenA(first_file) + 1) != 0) multiple_files = TRUE; if( !(multiple_files && (dwFlags & DOGIF_ONLY_IF_ONE)) ) { MultiByteToWideChar(CP_ACP, 0, first_file, -1, filename, MAX_PATH); ret = SHCreateItemFromParsingName(filename, NULL, riid, ppv); } } else { PCWSTR first_file = (PCWSTR)files; if(*((PCWSTR)files + lstrlenW(first_file) + 1) != 0) multiple_files = TRUE; if( !(multiple_files && (dwFlags & DOGIF_ONLY_IF_ONE)) ) ret = SHCreateItemFromParsingName(first_file, NULL, riid, ppv); } GlobalUnlock(medium.u.hGlobal); GlobalFree(medium.u.hGlobal); } } if(FAILED(ret) && !(dwFlags & DOGIF_NO_URL)) { FIXME("Failed to create item, should try CF_URL.\n"); } return ret; }