HRESULT GetDisplayName(LPCITEMIDLIST pidlDirectory,TCHAR *szDisplayName,UINT cchMax,DWORD uFlags) { if(pidlDirectory == NULL || szDisplayName == NULL) { return E_FAIL; } IShellFolder *pShellFolder = NULL; LPITEMIDLIST pidlRelative = NULL; STRRET str; HRESULT hr; hr = SHBindToParent(pidlDirectory, IID_PPV_ARGS(&pShellFolder), (LPCITEMIDLIST *)&pidlRelative); if(SUCCEEDED(hr)) { hr = pShellFolder->GetDisplayNameOf(pidlRelative,uFlags,&str); if(SUCCEEDED(hr)) { hr = StrRetToBuf(&str,pidlDirectory,szDisplayName,cchMax); } pShellFolder->Release(); } return hr; }
DWORD Network::GetComputerNameFromIDList(LPITEMIDLIST lpiil,LPSTR szName,DWORD dwBufferLen) { // May be computer? IShellFolder *psf; if (!SUCCEEDED(SHGetDesktopFolder(&psf))) return 0; SHDESCRIPTIONID di; if (!SUCCEEDED(SHGetDataFromIDList(psf,lpiil,SHGDFIL_DESCRIPTIONID,&di,sizeof(SHDESCRIPTIONID)))) { psf->Release(); return 0; } if (di.clsid!=CLSID_NetworkPlaces) { psf->Release(); return 0; } STRRET str; if (!SUCCEEDED(psf->GetDisplayNameOf(lpiil,SHGDN_FORPARSING,&str))) { psf->Release(); return 0; } psf->Release(); if (ShellFunctions::StrRetToStr(str,lpiil,szName,dwBufferLen)) return istrlen(szName); return 0; }
HRESULT CFShellUtil::GetItemIdName( LPCITEMIDLIST pItemIdList, LPTSTR pFriendlyName, UINT cchBuf, DWORD dwFlags, IShellFolder* pSF ) { HRESULT hr = S_OK; STRRET strRet = {0}; IShellFolder* pShellFolder = pSF; if ( pShellFolder == NULL ) { COM_VERIFY(SHGetDesktopFolder( &pShellFolder )); if ( !pShellFolder ) { return hr; } } COM_VERIFY(pShellFolder->GetDisplayNameOf( pItemIdList, dwFlags, &strRet)); if (SUCCEEDED(hr)) { COM_VERIFY(StrRetToBuf( &strRet, pItemIdList, pFriendlyName, cchBuf)); } if ( NULL == pSF ) { pShellFolder->Release(); pShellFolder = NULL; } return hr; }
void GetExplorerWindows(std::vector<PairHwndPath>& windows, BOOL needPaths) { IShellWindows *psw; if(SUCCEEDED(CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_ALL, IID_IShellWindows, (void**)&psw))) { VARIANT v; V_VT(&v) = VT_I4; IDispatch* pdisp; for(V_I4(&v) = 0; psw->Item(v, &pdisp) == S_OK; V_I4(&v)++) { IWebBrowserApp *pwba; if(SUCCEEDED(pdisp->QueryInterface(IID_IWebBrowserApp, (void**)&pwba))) { PairHwndPath pair; if(SUCCEEDED(pwba->get_HWND((LONG_PTR*)&pair.hwnd))) { IServiceProvider *psp; if(needPaths && SUCCEEDED(pwba->QueryInterface(IID_IServiceProvider, (void**)&psp))) { IShellBrowser *psb; if(SUCCEEDED(psp->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, (void**)&psb))) { IShellView *psv; if(SUCCEEDED(psb->QueryActiveShellView(&psv))) { IFolderView *pfv; if(SUCCEEDED(psv->QueryInterface(IID_IFolderView, (void**)&pfv))) { IPersistFolder2 *ppf2; if(SUCCEEDED(pfv->GetFolder(IID_IPersistFolder2, (void**)&ppf2))) { LPITEMIDLIST pidlFolder; if(SUCCEEDED(ppf2->GetCurFolder(&pidlFolder))) { if(!SHGetPathFromIDList(pidlFolder, pair.path)) { IShellFolder* psf; LPCITEMIDLIST pidlLast; if(SUCCEEDED(SHBindToParent(pidlFolder, IID_IShellFolder, (void**)&psf, &pidlLast))) { STRRET strret; if(SUCCEEDED(psf->GetDisplayNameOf(pidlLast, 0x8000, &strret))) { StrRetToBuf(&strret, pidlLast, pair.path, MAX_PATH); } else { pair.path[0] = 0; } psf->Release(); } } CoTaskMemFree(pidlFolder); } ppf2->Release(); } pfv->Release(); } psv->Release(); } psb->Release(); } psp->Release(); } windows.push_back(pair); } pwba->Release(); } pdisp->Release(); } psw->Release(); } }
/* 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]); }
/* 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); }
/* * Class: sun_awt_shell_Win32ShellFolder * Method: getFileSystemPath * Signature: (JJ)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_sun_awt_shell_Win32ShellFolder_getFileSystemPath__JJ (JNIEnv* env, jclass cls, jlong parentIShellFolder, jlong relativePIDL) { IShellFolder* pParent = (IShellFolder*)parentIShellFolder; if (pParent == NULL) { return NULL; } LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL; if (pidl == NULL) { return NULL; } STRRET strret; pParent->GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_FORPARSING, &strret); return jstringFromSTRRET(env, pidl, &strret); }
// Use the IShellFolder API to get the connection name for the given Guid. static HRESULT lana_ShellGetNameFromGuidW(WCHAR *wGuid, WCHAR *wName, int NameSize) { // This is the GUID for the network connections folder. It is constant. // {7007ACC7-3202-11D1-AAD2-00805FC1270E} const GUID CLSID_NetworkConnections = { 0x7007ACC7, 0x3202, 0x11D1, { 0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E } }; LPITEMIDLIST pidl; IShellFolder *pShellFolder; IMalloc *pShellMalloc; // Build the display name in the form "::{GUID}". if (wcslen(wGuid) >= MAX_PATH) return E_INVALIDARG; WCHAR szAdapterGuid[MAX_PATH + 2]; swprintf(szAdapterGuid, L"::%ls", wGuid); // Initialize COM. CoInitialize(NULL); // Get the shell allocator. HRESULT hr = SHGetMalloc(&pShellMalloc); if (SUCCEEDED(hr)) { // Create an instance of the network connections folder. hr = CoCreateInstance(CLSID_NetworkConnections, NULL, CLSCTX_INPROC_SERVER, IID_IShellFolder, reinterpret_cast<LPVOID *>(&pShellFolder)); } if (SUCCEEDED(hr)) { hr = pShellFolder->ParseDisplayName(NULL, NULL, szAdapterGuid, NULL, &pidl, NULL); } if (SUCCEEDED(hr)) { // Get the display name; this returns the friendly name. STRRET sName; hr = pShellFolder->GetDisplayNameOf(pidl, SHGDN_NORMAL, &sName); if (SUCCEEDED(hr)) wcsncpy(wName, sName.pOleStr, NameSize); pShellMalloc->Free(pidl); } CoUninitialize(); return hr; }
/* * Class: sun_awt_shell_Win32ShellFolder * Method: getDisplayName * Signature: (JJ)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_sun_awt_shell_Win32ShellFolder_getDisplayName__JJ (JNIEnv* env, jobject folder, jlong parentIShellFolder, jlong relativePIDL) { IShellFolder* pParent = (IShellFolder*)parentIShellFolder; if (pParent == NULL) { return NULL; } LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL; if (pidl == NULL) { return NULL; } STRRET strret; if (pParent->GetDisplayNameOf(pidl, SHGDN_NORMAL, &strret) != S_OK) { return NULL; } return jstringFromSTRRET(env, pidl, &strret); }
/* * Class: sun_awt_shell_Win32ShellFolder2 * Method: getDisplayNameOf * Signature: (JJ)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_sun_awt_shell_Win32ShellFolder2_getDisplayNameOf (JNIEnv* env, jclass cls, jlong parentIShellFolder, jlong relativePIDL, jint attrs) { IShellFolder* pParent = (IShellFolder*)parentIShellFolder; if (pParent == NULL) { return NULL; } LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL; if (pidl == NULL) { return NULL; } STRRET strret; if (pParent->GetDisplayNameOf(pidl, attrs, &strret) != S_OK) { return NULL; } return jstringFromSTRRET(env, pidl, &strret); }
stdstring ItemIDList::toString() { IShellFolder *shellFolder = NULL; IShellFolder *parentFolder = NULL; STRRET name; TCHAR * szDisplayName = NULL; stdstring ret; HRESULT hr; hr = ::SHGetDesktopFolder(&shellFolder); if (!SUCCEEDED(hr)) return ret; if (parent_) { hr = shellFolder->BindToObject(parent_, 0, IID_IShellFolder, (void**) &parentFolder); if (!SUCCEEDED(hr)) parentFolder = shellFolder; } else { parentFolder = shellFolder; } if ((parentFolder != 0)&&(item_ != 0)) { hr = parentFolder->GetDisplayNameOf(item_, SHGDN_NORMAL | SHGDN_FORPARSING, &name); if (!SUCCEEDED(hr)) { parentFolder->Release(); return ret; } hr = StrRetToStr (&name, item_, &szDisplayName); if (!SUCCEEDED(hr)) return ret; } parentFolder->Release(); if (szDisplayName == NULL) { CoTaskMemFree(szDisplayName); return ret; //to avoid a crash! } ret = szDisplayName; CoTaskMemFree(szDisplayName); return ret; }
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); }
CString GetSpeacialFolderLocation(int csidl) { IShellFolder *desktop; LPITEMIDLIST pidl; STRRET strRet; if(FAILED(SHGetDesktopFolder(&desktop))) { return L""; } if(FAILED(SHGetSpecialFolderLocation(NULL, csidl, &pidl))) { return L""; } if(FAILED(desktop->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strRet))) { return L""; } if(pidl) { ILFree(pidl); } return strRet.pOleStr; }
void CShellBrowser::OnFileActionAdded(const TCHAR *szFileName) { IShellFolder *pShellFolder = NULL; LPITEMIDLIST pidlFull = NULL; LPITEMIDLIST pidlRelative = NULL; Added_t Added; TCHAR FullFileName[MAX_PATH]; TCHAR szDisplayName[MAX_PATH]; STRRET str; BOOL bFileAdded = FALSE; HRESULT hr; StringCchCopy(FullFileName,SIZEOF_ARRAY(FullFileName),m_CurDir); PathAppend(FullFileName,szFileName); hr = GetIdlFromParsingName(FullFileName,&pidlFull); /* It is possible that by the time a file is registered here, it will have already been renamed. In this the following check will fail. If the file is not added, store its filename. */ if(SUCCEEDED(hr)) { hr = SHBindToParent(pidlFull, IID_PPV_ARGS(&pShellFolder), (LPCITEMIDLIST *)&pidlRelative); if(SUCCEEDED(hr)) { /* If this is a virtual folder, only use SHGDN_INFOLDER. If this is a real folder, combine SHGDN_INFOLDER with SHGDN_FORPARSING. This is so that items in real folders can still be shown with extensions, even if the global, Explorer option is disabled. */ if(m_bVirtualFolder) hr = pShellFolder->GetDisplayNameOf(pidlRelative,SHGDN_INFOLDER,&str); else hr = pShellFolder->GetDisplayNameOf(pidlRelative,SHGDN_INFOLDER|SHGDN_FORPARSING,&str); if(SUCCEEDED(hr)) { StrRetToBuf(&str,pidlRelative,szDisplayName,SIZEOF_ARRAY(szDisplayName)); std::list<DroppedFile_t>::iterator itr; BOOL bDropped = FALSE; if(!m_DroppedFileNameList.empty()) { for(itr = m_DroppedFileNameList.begin();itr != m_DroppedFileNameList.end();itr++) { if(lstrcmp(szDisplayName,itr->szFileName) == 0) { bDropped = TRUE; break; } } } /* Only insert the item in its sorted position if it wasn't dropped in. */ if(m_bInsertSorted && !bDropped) { int iItemId; int iSorted; iItemId = SetItemInformation(m_pidlDirectory,pidlRelative,szDisplayName); iSorted = DetermineItemSortedPosition(iItemId); AddItemInternal(iSorted,iItemId,TRUE); } else { /* Just add the item to the end of the list. */ AddItemInternal(m_pidlDirectory,pidlRelative,szDisplayName,-1,FALSE); } InsertAwaitingItems(m_bShowInGroups); bFileAdded = TRUE; } pShellFolder->Release(); } CoTaskMemFree(pidlFull); } if(!bFileAdded) { /* The file does not exist. However, it is possible that is was simply renamed shortly after been created. Record the filename temporarily (so that it can later be added). */ StringCchCopy(Added.szFileName,SIZEOF_ARRAY(Added.szFileName),szFileName); m_FilesAdded.push_back(Added); } }
///////////////////////////////////////////////////////////////////////////// // IShellInit Functions ///////////////////////////////////////////////////////////////////////////// STDMETHODIMP CShellExt::XShellInit::Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdobj, HKEY hkeyProgID) { METHOD_PROLOGUE(CShellExt, ShellInit); HRESULT hres = E_FAIL; FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; STGMEDIUM medium; // We must have a data object if ((pdobj == NULL) && (pidlFolder == NULL)) return E_FAIL; pThis->m_bIsSymlink=false; pThis->m_bIsMountpoint=false; pThis->m_bIsPathInAFS=false; pThis->m_bDirSelected=false; if (pdobj) { // Use the given IDataObject to get a list of filenames (CF_HDROP) hres = pdobj->GetData(&fmte, &medium); if (FAILED(hres)) { return E_FAIL; } int nNumFiles = DragQueryFile((HDROP)medium.hGlobal, 0xFFFFFFFF, NULL, 0); if (nNumFiles == 0) hres = E_FAIL; else { pThis->m_bDirSelected = FALSE; for (int ii = 0; ii < nNumFiles; ii++) { CString strFileName; // Get the size of the file name string int nNameLen = DragQueryFile((HDROP)medium.hGlobal, ii, 0, 0); // Make room for it in our string object LPTSTR pszFileNameBuf = strFileName.GetBuffer(nNameLen + 1); // +1 for the terminating NULL ASSERT(pszFileNameBuf); // Get the file name DragQueryFile((HDROP)medium.hGlobal, ii, pszFileNameBuf, nNameLen + 1); strFileName.ReleaseBuffer(); if (!IsPathInAfs(strFileName)) { pThis->m_astrFileNames.RemoveAll(); pThis->m_bIsPathInAFS=false; break; } else { pThis->m_bIsSymlink=pThis->m_bIsSymlink||IsSymlink(strFileName); pThis->m_bIsMountpoint=pThis->m_bIsMountpoint||IsMountPoint(strFileName); pThis->m_bIsPathInAFS=true; } if (IsADir(strFileName)) pThis->m_bDirSelected = TRUE; pThis->m_astrFileNames.Add(strFileName); } // Release the data ReleaseStgMedium(&medium); } } if ((pThis->m_astrFileNames.GetSize() == 0)&&(pidlFolder)) { // if there are no valid files selected, try the folder background IShellFolder *parentFolder = NULL; STRRET name; TCHAR * szDisplayName = NULL; hres = ::SHGetDesktopFolder(&parentFolder); if (FAILED(hres)) return hres; hres = parentFolder->GetDisplayNameOf(pidlFolder, SHGDN_NORMAL | SHGDN_FORPARSING, &name); if (FAILED(hres)) { parentFolder->Release(); return hres; } hres = StrRetToStr (&name, pidlFolder, &szDisplayName); if (FAILED(hres)) return hres; parentFolder->Release(); if (szDisplayName) { pThis->m_bDirSelected = TRUE; CString strFileName = CString(szDisplayName); if (IsPathInAfs(strFileName)) { pThis->m_bIsSymlink=IsSymlink(strFileName); pThis->m_bIsMountpoint=IsMountPoint(strFileName); pThis->m_bIsPathInAFS=true; pThis->m_astrFileNames.Add(strFileName); } CoTaskMemFree(szDisplayName); } } if (pThis->m_astrFileNames.GetSize() > 0) hres = NOERROR; else hres = E_FAIL; return hres; }
void CDeskBand::Rename(HWND hwnd, const std::map<std::wstring, ULONG>& items) { // fill the list of selected file/foldernames m_filelist.clear(); if (items.size() > 1) { for (std::map<std::wstring, ULONG>::const_iterator it = items.begin(); it != items.end(); ++it) { size_t pos = it->first.find_last_of('\\'); if (pos != std::wstring::npos) { m_filelist.insert(it->first.substr(pos+1)); } } } else if (items.size() == 1) { for (std::map<std::wstring, ULONG>::const_iterator it = items.begin(); it != items.end(); ++it) { size_t pos = it->first.find_last_of('\\'); if (pos != std::wstring::npos) { m_filelist.insert(it->first.substr(pos+1)); } } } else { // no files or only one file were selected. // use all files and folders in the current folder instead IServiceProvider * pServiceProvider = NULL; if (SUCCEEDED(GetIServiceProvider(hwnd, &pServiceProvider))) { IShellBrowser * pShellBrowser; if (SUCCEEDED(pServiceProvider->QueryService(SID_SShellBrowser, IID_IShellBrowser, (LPVOID*)&pShellBrowser))) { IShellView * pShellView; if (SUCCEEDED(pShellBrowser->QueryActiveShellView(&pShellView))) { IFolderView * pFolderView; if (SUCCEEDED(pShellView->QueryInterface(IID_IFolderView, (LPVOID*)&pFolderView))) { // hooray! we got the IFolderView interface! // that means the explorer is active and well :) // but we also need the IShellFolder interface because // we need its GetCurFolder() method IPersistFolder2 * pPersistFolder; if (SUCCEEDED(pFolderView->GetFolder(IID_IPersistFolder2, (LPVOID*)&pPersistFolder))) { LPITEMIDLIST folderpidl; if (SUCCEEDED(pPersistFolder->GetCurFolder(&folderpidl))) { // we have the current folder TCHAR buf[MAX_PATH] = {0}; // find the path of the folder if (SHGetPathFromIDList(folderpidl, buf)) { m_currentDirectory = buf; } // if m_currentDirectory is empty here, that means // the current directory is a virtual path IShellFolder * pShellFolder; if (SUCCEEDED(pPersistFolder->QueryInterface(IID_IShellFolder, (LPVOID*)&pShellFolder))) { // find all selected items IEnumIDList * pEnum; if (SUCCEEDED(pFolderView->Items(SVGIO_ALLVIEW, IID_IEnumIDList, (LPVOID*)&pEnum))) { LPITEMIDLIST pidl; WCHAR buf[MAX_PATH] = {0}; ULONG fetched = 0; ULONG attribs = 0; do { pidl = NULL; if (SUCCEEDED(pEnum->Next(1, &pidl, &fetched))) { if (fetched) { // the pidl we get here is relative! attribs = SFGAO_FILESYSTEM|SFGAO_FOLDER; if (SUCCEEDED(pShellFolder->GetAttributesOf(1, (LPCITEMIDLIST*)&pidl, &attribs))) { if (attribs & SFGAO_FILESYSTEM) { // create an absolute pidl with the pidl we got above LPITEMIDLIST abspidl = CPidl::Append(folderpidl, pidl); if (abspidl) { if (SHGetPathFromIDList(abspidl, buf)) { std::wstring p = buf; size_t pos = p.find_last_of('\\'); if (pos != std::wstring::npos) { m_filelist.insert(p.substr(pos+1)); } } CoTaskMemFree(abspidl); } } } } CoTaskMemFree(pidl); } } while(fetched); pEnum->Release(); } pShellFolder->Release(); } CoTaskMemFree(folderpidl); } pPersistFolder->Release(); } pFolderView->Release(); } pShellView->Release(); } pShellBrowser->Release(); } pServiceProvider->Release(); } } // show the rename dialog m_bDialogShown = TRUE; CRenameDlg dlg(hwnd); dlg.SetFileList(m_filelist); if (dlg.DoModal(g_hInst, IDD_RENAMEDLG, hwnd, NULL) == IDOK) { try { const std::tr1::wregex regCheck(dlg.GetMatchString(), dlg.GetRegexFlags()); NumberReplaceHandler handler(dlg.GetReplaceString()); // start renaming the files IServiceProvider * pServiceProvider = NULL; if (SUCCEEDED(GetIServiceProvider(hwnd, &pServiceProvider))) { IShellBrowser * pShellBrowser; if (SUCCEEDED(pServiceProvider->QueryService(SID_SShellBrowser, IID_IShellBrowser, (LPVOID*)&pShellBrowser))) { IShellView * pShellView; if (SUCCEEDED(pShellBrowser->QueryActiveShellView(&pShellView))) { IFolderView * pFolderView; if (SUCCEEDED(pShellView->QueryInterface(IID_IFolderView, (LPVOID*)&pFolderView))) { // hooray! we got the IFolderView interface! // that means the explorer is active and well :) // but we also need the IShellFolder interface because // we need its GetDisplayNameOf() method IPersistFolder2 * pPersistFolder; if (SUCCEEDED(pFolderView->GetFolder(IID_IPersistFolder2, (LPVOID*)&pPersistFolder))) { IShellFolder * pShellFolder; if (SUCCEEDED(pPersistFolder->QueryInterface(IID_IShellFolder, (LPVOID*)&pShellFolder))) { // our next task is to enumerate all the // items in the folder view and select those // which match the text in the edit control int nCount = 0; if (SUCCEEDED(pFolderView->ItemCount(SVGIO_ALLVIEW, &nCount))) { for (int i=0; i<nCount; ++i) { LPITEMIDLIST pidl; if (SUCCEEDED(pFolderView->Item(i, &pidl))) { STRRET str; if (SUCCEEDED(pShellFolder->GetDisplayNameOf(pidl, // SHGDN_FORPARSING needed to get the extensions even if they're not shown SHGDN_INFOLDER|SHGDN_FORPARSING, &str))) { TCHAR dispname[MAX_PATH]; StrRetToBuf(&str, pidl, dispname, _countof(dispname)); std::wstring replaced; try { std::wstring sDispName = dispname; // check if the item is in the list of selected items if (m_filelist.find(sDispName) != m_filelist.end()) { replaced = std::tr1::regex_replace(sDispName, regCheck, dlg.GetReplaceString()); replaced = handler.ReplaceCounters(replaced); if (replaced.compare(sDispName)) { ITEMIDLIST * pidlrenamed; pShellFolder->SetNameOf(NULL, pidl, replaced.c_str(), SHGDN_FORPARSING|SHGDN_INFOLDER, &pidlrenamed); // if the rename was successful, select the renamed item if (pidlrenamed) pFolderView->SelectItem(i, SVSI_CHECK|SVSI_SELECT); } } } catch (std::exception) { } } CoTaskMemFree(pidl); } } } pShellFolder->Release(); } pPersistFolder->Release(); } pFolderView->Release(); } pShellView->Release(); } pShellBrowser->Release(); } pServiceProvider->Release(); } } catch (std::exception) { } } m_bDialogShown = FALSE; }
BOOL Network::GetNethoodTarget(LPCWSTR szFolder,LPWSTR szTarget,DWORD nBufferLen) { CStringW file(szFolder); if (file.LastChar()!=L'\\') file << L'\\'; file << L"desktop.ini"; WCHAR cls[300]; if (IsUnicodeSystem()) { if (!GetPrivateProfileStringW(L".ShellClassInfo",L"CLSID2",szwEmpty,cls,300,file)) return FALSE; } else { char clsA[300]; if (!GetPrivateProfileString(".ShellClassInfo","CLSID2",szEmpty,clsA,300,W2A(file))) return FALSE; MultiByteToWideChar(CP_ACP,0,clsA,-1,cls,300); } if (wcscmp(cls,L"{0AFACED1-E828-11D1-9187-B532F1E9575D}")!=0) return FALSE; // Folder shortcut IShellLink* psl; if (!SUCCEEDED(CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(void**)&psl))) return FALSE; IPersistFile* ppf; if (!SUCCEEDED(psl->QueryInterface(IID_IPersistFile,(void**)&ppf))) { psl->Release(); return FALSE; } IShellFolder* psf; if (!SUCCEEDED(SHGetDesktopFolder(&psf))) { ppf->Release(); psl->Release(); return FALSE; } file=szFolder; if (file.LastChar()!=L'\\') file << L'\\'; file << L"target.lnk"; BOOL bRet=FALSE; if (SUCCEEDED(ppf->Load(file,0))) { LPITEMIDLIST il; if (SUCCEEDED(psl->GetIDList(&il))) { STRRET str; if (SUCCEEDED(psf->GetDisplayNameOf(il,SHGDN_FORPARSING,&str))) { if (ShellFunctions::StrRetToStr(str,il,szTarget,nBufferLen)) bRet=2; } else { SHDESCRIPTIONID di; if (SUCCEEDED(SHGetDataFromIDList(psf,il,SHGDFIL_DESCRIPTIONID,&di,sizeof(SHDESCRIPTIONID)))) { if (di.clsid==CLSID_NetworkPlaces) { if (SUCCEEDED(psf->GetDisplayNameOf(il,SHGDN_FORPARSING,&str))) { if (ShellFunctions::StrRetToStr(str,il,szTarget,nBufferLen)) bRet=szTarget[0]=='\\' && szTarget[1]=='\\'; } } } } CoTaskMemFree(il); } } psf->Release(); ppf->Release(); psl->Release(); return bRet; }
void FileDialog::FilterFiles(HWND hDlg) { HWND parent = ::GetParent(hDlg); IShellFolder *ishell = NULL; LPMALLOC imalloc = NULL; HRESULT hr; // Get pointer to the ListView control HWND lv = ::GetDlgItem(::GetDlgItem(parent, lst2), 1); if (lv == NULL) { wxASSERT(lv != NULL); return; } // Get shell's memory allocation interface (must be Release()'d) hr = SHGetMalloc(&imalloc); if ((hr != NOERROR) || (imalloc == NULL)) { wxASSERT((hr == NOERROR) && (imalloc != NULL)); return; } // Init LVITEM lvi; wxZeroMemory(lvi); // Process all items int fltcnt = m_Filters.GetCount(); int itmcnt = ::SendMessage(lv, LVM_GETITEMCOUNT, 0, 0); for (int itm = 0; itm < itmcnt; itm++) { // Retrieve the file IDL lvi.iItem = itm; lvi.mask = LVIF_PARAM; if (ListView_GetItem(lv, &lvi) != TRUE) { wxASSERT(FALSE); break; } LPCITEMIDLIST fidl = (LPCITEMIDLIST) lvi.lParam; // Retrieve the IShellFolder interface of the parent (must be Release()'d) if (ishell == NULL) { hr = SHBindToParent(fidl, IID_IShellFolder, (void **)&ishell, NULL); if (!SUCCEEDED(hr)) { wxASSERT(SUCCEEDED(hr)); break; } } // Get the attributes of the object DWORD attr = SFGAO_FOLDER | SFGAO_STREAM; hr = ishell->GetAttributesOf(1, &fidl, &attr); if (!SUCCEEDED(hr)) { wxASSERT(SUCCEEDED(hr)); break; } // Allow all folders (things like zip files get filtered below) if (attr == SFGAO_FOLDER) { continue; } // Retrieve the parsable name of the object (includes extension) STRRET str; hr = ishell->GetDisplayNameOf(fidl, SHGDN_INFOLDER | SHGDN_FORPARSING, &str); if (hr != NOERROR) { // For some objects, we get back an error of 80070057. I'm assuming this // means there is no way to represent the name (like some sort of virtual name) // or I've not used the correct PIDL. But, in either case, it "probably" // represents some sort of folder (at least in all cases I've seen), so we // simply allow it to display. continue; } // Convert result to wxString wxString filename; switch (str.uType) { case STRRET_WSTR: filename = str.pOleStr; imalloc->Free(str.pOleStr); break; case STRRET_OFFSET: filename = wxString(((char *)fidl) + str.uOffset, wxConvISO8859_1); break; case STRRET_CSTR: filename = wxString(str.cStr, wxConvISO8859_1); break; } // Attempt to match it to all of our filters bool match = false; for (int flt = 0; flt < fltcnt; flt++) { if (wxMatchWild(m_Filters[flt], filename, false)) { match = true; break; } } // Remove it from the display if it didn't match any of the filters. if (!match) { ListView_DeleteItem(lv, itm); itm--; itmcnt--; } } done: // Release the interface if (ishell) { ishell->Release(); } // Release the interface if (imalloc) { imalloc->Release(); } }
/* updates the names of the file-item through its PIDL */ static void update_by_pidl(FileItem* fileitem) { STRRET strret; TCHAR pszName[MAX_PATH]; IShellFolder *pFolder = NULL; if (fileitem == rootitem) pFolder = shl_idesktop; else { ASSERT(fileitem->parent); shl_idesktop->BindToObject(fileitem->parent->fullpidl, NULL, IID_IShellFolder, (LPVOID *)&pFolder); } /****************************************/ /* get the file name */ if (pFolder != NULL && pFolder->GetDisplayNameOf(fileitem->pidl, SHGDN_NORMAL | SHGDN_FORPARSING, &strret) == S_OK) { StrRetToBuf(&strret, fileitem->pidl, pszName, MAX_PATH); fileitem->filename = pszName; } else if (shl_idesktop->GetDisplayNameOf(fileitem->fullpidl, SHGDN_NORMAL | SHGDN_FORPARSING, &strret) == S_OK) { StrRetToBuf(&strret, fileitem->fullpidl, pszName, MAX_PATH); fileitem->filename = pszName; } else fileitem->filename = "ERR"; /****************************************/ /* get the name to display */ if (fileitem->isFolder() && pFolder && pFolder->GetDisplayNameOf(fileitem->pidl, SHGDN_INFOLDER, &strret) == S_OK) { StrRetToBuf(&strret, fileitem->pidl, pszName, MAX_PATH); fileitem->displayname = pszName; } else if (fileitem->isFolder() && shl_idesktop->GetDisplayNameOf(fileitem->fullpidl, SHGDN_INFOLDER, &strret) == S_OK) { StrRetToBuf(&strret, fileitem->fullpidl, pszName, MAX_PATH); fileitem->displayname = pszName; } else { fileitem->displayname = base::get_file_name(fileitem->filename); } if (pFolder != NULL && pFolder != shl_idesktop) { pFolder->Release(); } }
void CShellBrowser::BrowseVirtualFolder(LPITEMIDLIST pidlDirectory) { IShellFolder *pShellFolder = NULL; IEnumIDList *pEnumIDList = NULL; LPITEMIDLIST rgelt = NULL; STRRET str; SHCONTF EnumFlags; TCHAR szFileName[MAX_PATH]; ULONG uFetched; HRESULT hr; DetermineFolderVirtual(pidlDirectory); hr = BindToIdl(pidlDirectory, IID_PPV_ARGS(&pShellFolder)); if(SUCCEEDED(hr)) { m_pidlDirectory = ILClone(pidlDirectory); EnumFlags = SHCONTF_FOLDERS|SHCONTF_NONFOLDERS; if(m_bShowHidden) EnumFlags |= SHCONTF_INCLUDEHIDDEN; hr = pShellFolder->EnumObjects(m_hOwner,EnumFlags,&pEnumIDList); if(SUCCEEDED(hr) && pEnumIDList != NULL) { uFetched = 1; while(pEnumIDList->Next(1,&rgelt,&uFetched) == S_OK && (uFetched == 1)) { ULONG uAttributes = SFGAO_FOLDER; pShellFolder->GetAttributesOf(1,(LPCITEMIDLIST *)&rgelt,&uAttributes); /* If this is a virtual folder, only use SHGDN_INFOLDER. If this is a real folder, combine SHGDN_INFOLDER with SHGDN_FORPARSING. This is so that items in real folders can still be shown with extensions, even if the global, Explorer option is disabled. Also use only SHGDN_INFOLDER if this item is a folder. This is to ensure that specific folders in Windows 7 (those under C:\Users\Username) appear correctly. */ if(m_bVirtualFolder || (uAttributes & SFGAO_FOLDER)) hr = pShellFolder->GetDisplayNameOf(rgelt,SHGDN_INFOLDER,&str); else hr = pShellFolder->GetDisplayNameOf(rgelt,SHGDN_INFOLDER|SHGDN_FORPARSING,&str); if(SUCCEEDED(hr)) { StrRetToBuf(&str,rgelt,szFileName,MAX_PATH); AddItemInternal(pidlDirectory,rgelt,szFileName,-1,FALSE); } CoTaskMemFree((LPVOID)rgelt); } pEnumIDList->Release(); } pShellFolder->Release(); } }
void FileDialog::FilterFiles(HWND hDlg, bool refresh) { HWND parent = ::GetParent(hDlg); IShellFolder *ishell = NULL; IShellBrowser *ishellbrowser = NULL; // Does not have to be released IShellView *ishellview = NULL; IFolderView *ifolderview = NULL; LPMALLOC imalloc = NULL; HRESULT hr; // Get pointer to the ListView control HWND lv = ::GetDlgItem(::GetDlgItem(parent, lst2), 1); if (lv == NULL) { wxASSERT(lv != NULL); return; } // Get shell's memory allocation interface (must be Release()'d) hr = SHGetMalloc(&imalloc); if ((hr != NOERROR) || (imalloc == NULL)) { wxASSERT((hr == NOERROR) && (imalloc != NULL)); return; } // Get IShellBrowser interface for current dialog ishellbrowser = (IShellBrowser*)::SendMessage(parent, WM_GETISHELLBROWSER, 0, 0); if (ishellbrowser) { // Get IShellBrowser interface for returned browser if (ishellbrowser->QueryActiveShellView(&ishellview) == S_OK) { // Get the IFolderView interface...available on XP or greater ishellview->QueryInterface(IID_IFolderView, (void **)&ifolderview); } } // Init LVITEM lvi; wxZeroMemory(lvi); // Process all items int fltcnt = (int) m_Filters.GetCount(); int itmcnt = ::SendMessage(lv, LVM_GETITEMCOUNT, 0, 0); for (int itm = 0; itm < itmcnt; itm++) { // Retrieve the file IDL lvi.iItem = itm; lvi.mask = LVIF_PARAM; if (ListView_GetItem(lv, &lvi) != TRUE) { wxASSERT(FALSE); break; } LPCITEMIDLIST fidl = (LPCITEMIDLIST) lvi.lParam; // On Vista, lParam no longer contains the pidl so retrieve it via the // IFolderView interface. This interface is only available on XP or higher // so if that limitation isn't workable, use IShellView::GetItemObject() to // retrieve items. if (fidl == NULL && ifolderview != NULL) { ifolderview->Item(itm, (LPITEMIDLIST *) &fidl); } if (fidl == NULL) { wxASSERT(fidl != NULL); break; } // Retrieve the IShellFolder interface of the parent (must be Release()'d) if (ishell == NULL) { hr = SHBindToParentLocal(fidl, IID_IShellFolder, (void **)&ishell, NULL); if (!SUCCEEDED(hr)) { wxASSERT(SUCCEEDED(hr)); break; } } // Get the attributes of the object DWORD attr = SFGAO_FOLDER | SFGAO_BROWSABLE; hr = ishell->GetAttributesOf(1, &fidl, &attr); if (!SUCCEEDED(hr)) { wxASSERT(SUCCEEDED(hr)); break; } // Allow all folders (things like zip files get filtered below) if ((attr & (SFGAO_FOLDER)) && !(attr & SFGAO_BROWSABLE)) { continue; } // Retrieve the parsable name of the object (includes extension) STRRET str; hr = ishell->GetDisplayNameOf(fidl, SHGDN_INFOLDER | SHGDN_FORPARSING, &str); if (hr != NOERROR) { // For some objects, we get back an error of 80070057. I'm assuming this // means there is no way to represent the name (like some sort of virtual name) // or I've not used the correct PIDL. But, in either case, it "probably" // represents some sort of folder (at least in all cases I've seen), so we // simply allow it to display. continue; } // Convert result to wxString wxString filename; switch (str.uType) { case STRRET_WSTR: filename = str.pOleStr; imalloc->Free(str.pOleStr); break; case STRRET_OFFSET: filename = wxString(((char *)fidl) + str.uOffset, wxConvISO8859_1); break; case STRRET_CSTR: filename = wxString(str.cStr, wxConvISO8859_1); break; } // Convert the filename to lowercase (and remember to write filters in lowercase!) filename = filename.Lower(); // Attempt to match it to all of our filters bool match = false; for (int flt = 0; flt < fltcnt; flt++) { if (wxMatchWild(m_Filters[flt], filename, false)) { match = true; break; } } // Remove it from the display if it didn't match any of the filters. if (!match) { ListView_DeleteItem(lv, itm); itm--; itmcnt--; } } // On Vista and maybe XP, we seem to need to refresh the view after // changing the filters. But, only refresh for type changes and not // selection changes since it causes additional selection change // events to occur. if (ishellview && refresh) { ishellview->Refresh(); } // Release the interface if (ifolderview) { ifolderview->Release(); } // Release the interface if (ishellview) { ishellview->Release(); } // Release the interface if (ishell) { ishell->Release(); } // Release the interface if (imalloc) { imalloc->Release(); } }
/* * Class: sun_awt_shell_Win32ShellFolder * Method: getLinkLocation * Signature: (JJ)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_sun_awt_shell_Win32ShellFolder_getLinkLocation (JNIEnv* env, jobject folder, jlong parentIShellFolder, jlong relativePIDL) { HRESULT hres; IShellLink* psl; char szGotPath[MAX_PATH]; WIN32_FIND_DATA wfd; CHAR szBuf[MAX_PATH]; STRRET strret; OLECHAR olePath[MAX_PATH]; // wide-char version of path name LPWSTR wstr; IShellFolder* pParent = (IShellFolder*)parentIShellFolder; if (pParent == NULL) { return NULL; } LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL; if (pidl == NULL) { return NULL; } pParent->GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_FORPARSING, &strret); switch (strret.uType) { case STRRET_CSTR : // IShellFolder::ParseDisplayName requires the path name in Unicode. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, strret.cStr, -1, olePath, MAX_PATH); wstr = olePath; break; case STRRET_OFFSET : MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (CHAR *)(pidl + strret.uOffset), -1, olePath, MAX_PATH); wstr = olePath; break; case STRRET_WSTR : wstr = strret.pOleStr; break; } CoInitialize(NULL); hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *) &psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf); if (SUCCEEDED(hres)) { hres = ppf->Load(wstr, STGM_READ); if (SUCCEEDED(hres)) { //hres = psl->Resolve(NULL, SLR_NO_UI); hres = psl->Resolve(NULL, 0); if (SUCCEEDED(hres)) { hres = psl->GetPath(szGotPath, MAX_PATH, (WIN32_FIND_DATA *)&wfd, SLGP_SHORTPATH); if (SUCCEEDED(hres)) { lstrcpy(szBuf, szGotPath); } } } ppf->Release(); } psl->Release(); } CoUninitialize(); if (SUCCEEDED(hres)) { return JNU_NewStringPlatform(env, szBuf); } else { return NULL; } }
/* * Class: sun_awt_shell_Win32ShellFolder2 * Method: getLinkLocation * Signature: (JJZ)J; */ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getLinkLocation (JNIEnv* env, jclass cls, jlong parentIShellFolder, jlong relativePIDL, jboolean resolve) { HRESULT hres; STRRET strret; OLECHAR olePath[MAX_PATH]; // wide-char version of path name LPWSTR wstr; IShellFolder* pParent = (IShellFolder*)parentIShellFolder; if (pParent == NULL) { return NULL; } LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL; if (pidl == NULL) { return NULL; } hres = pParent->GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_FORPARSING, &strret); if (FAILED(hres)) { return NULL; } switch (strret.uType) { case STRRET_CSTR : // IShellFolder::ParseDisplayName requires the path name in Unicode. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, strret.cStr, -1, olePath, MAX_PATH); wstr = olePath; break; case STRRET_OFFSET : MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (CHAR *)pidl + strret.uOffset, -1, olePath, MAX_PATH); wstr = olePath; break; case STRRET_WSTR : wstr = strret.pOleStr; break; default: return NULL; } IShellLinkW* psl; hres = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID *)&psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf); if (SUCCEEDED(hres)) { hres = ppf->Load(wstr, STGM_READ); if (SUCCEEDED(hres)) { if (resolve) { hres = psl->Resolve(NULL, 0); // Ignore failure } pidl = (LPITEMIDLIST)NULL; hres = psl->GetIDList(&pidl); } ppf->Release(); } psl->Release(); } if (strret.uType == STRRET_WSTR) { CoTaskMemFree(strret.pOleStr); } if (SUCCEEDED(hres)) { return (jlong)pidl; } else { return 0; } }
STDMETHODIMP CLocateShellExtension::Initialize(LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj, HKEY hRegKey) { DebugFormatMessage("CLocateShellExtension::Initialize(%X,%X,%X)",pIDFolder,pDataObj,hRegKey); if (pDataObj==NULL) return E_INVALIDARG; FORMATETC FormatEtc; STGMEDIUM med; FormatEtc.cfFormat=RegisterClipboardFormat(CFSTR_SHELLIDLIST); FormatEtc.ptd=NULL; FormatEtc.dwAspect=DVASPECT_CONTENT; FormatEtc.lindex=-1; FormatEtc.tymed=TYMED_HGLOBAL; if (pDataObj->GetData(&FormatEtc,&med)==S_OK) { // May be computer? IShellFolder *psf; if (!SUCCEEDED(SHGetDesktopFolder(&psf))) { DebugMessage("No IShellFolder interface"); return E_FAIL; } // Retrieving data from item id list BYTE* pData=(BYTE*)GlobalLock(med.hGlobal); UINT nFiles=((int*)pData)[0]; UINT i,nLines=1,nSubIDListLen,nIDListLen; WCHAR szPath[_MAX_PATH]; nSubIDListLen=GetIDListSize((LPITEMIDLIST)(pData+((int*)pData)[1]))-2; for (i=0;i<nFiles;i++) { nIDListLen=GetIDListSize((LPITEMIDLIST)(pData+((int*)pData)[2+i])); // Constructing IDList from parent item and item LPITEMIDLIST pItemIDList=(LPITEMIDLIST)new BYTE[nSubIDListLen+nIDListLen+2]; CopyMemory((BYTE*)pItemIDList,(LPCSTR)(pData+((int*)pData)[1]),nSubIDListLen); CopyMemory((BYTE*)(pItemIDList)+nSubIDListLen,(LPCSTR)(pData+((int*)pData)[2+i]),nIDListLen); if (SHGetPathFromIDListW(pItemIDList,szPath)) { DebugFormatMessage(L"SHGetPathFromIDListW gives %s",szPath); if (IsDirectory(szPath)) { WCHAR szTarget[MAX_PATH]; switch (GetNethoodTarget(szPath,szTarget,MAX_PATH)) { case 1: m_aComputers.Add(alloccopy(szTarget)); break; case 2: m_aDirectories.Add(alloccopy(szTarget)); break; case 0: m_aDirectories.Add(alloccopy(szPath)); break; } } else m_aFiles.Add(alloccopy(szPath)); } else { DebugHexDump("idlist",(BYTE*)pItemIDList,nSubIDListLen+nIDListLen); STRRET str; if (SUCCEEDED(psf->GetDisplayNameOf(pItemIDList,SHGDN_NORMAL|SHGDN_FORPARSING,&str))) { if (SUCCEEDED(StrRetToBufW(&str,pItemIDList,szPath,MAX_PATH))) { if (szPath[0]!='\\' && szPath[1]!='\\') DebugFormatMessage("Cannot add item %s",szPath); else m_aComputers.Add(alloccopy(szPath)); } else DebugMessage("StrRetToStr failed"); } else DebugMessage("GetDisplayNameOf failed"); } delete[] (BYTE*)pItemIDList; } GlobalUnlock(med.hGlobal); if (med.pUnkForRelease==NULL) GlobalFree(med.hGlobal); else med.pUnkForRelease->Release(); psf->Release(); } else { FormatEtc.cfFormat=CF_HDROP; if (m_pDataObj->GetData(&FormatEtc,&med)==S_OK) { LPDROPFILES df=(LPDROPFILES)GlobalLock(med.hGlobal); if (df->fWide) { LPWSTR lpPtr=(LPWSTR)((BYTE*)df+df->pFiles); SIZE_T nLen; while (nLen=wcslen(lpPtr)) { DebugFormatMessage(L"HDROP contains file %s",(LPCSTR)(lpPtr)); if (IsDirectory(lpPtr)) { WCHAR szTarget[MAX_PATH]; switch (GetNethoodTarget(lpPtr,szTarget,MAX_PATH)) { case 1: m_aComputers.Add(alloccopy(szTarget)); break; case 2: m_aDirectories.Add(alloccopy(szTarget)); break; case 0: m_aDirectories.Add(alloccopy(lpPtr,nLen)); break; } } else m_aFiles.Add(alloccopy(lpPtr,nLen)); lpPtr+=nLen+1; } } else { LPSTR lpPtr=(LPSTR)df+df->pFiles; SIZE_T nLen; while (nLen=strlen(lpPtr)) { LPWSTR lpFile=alloccopyAtoW(lpPtr,nLen); if (IsDirectory(lpFile)) m_aDirectories.Add(lpFile); else m_aFiles.Add(lpFile); lpPtr+=nLen+1; } } GlobalUnlock(med.hGlobal); if (med.pUnkForRelease==NULL) GlobalFree(med.hGlobal); else med.pUnkForRelease->Release(); } } // Initialize can be called more than once if (m_pDataObj) m_pDataObj->Release(); // duplicate the object pointer and registry handle if (pDataObj) { m_pDataObj = pDataObj; pDataObj->AddRef(); } return NOERROR; }