LPITEMIDLIST ShellFunctions::GetIDListForParent(LPCSTR lpszFileName) { int temp=LastCharIndex(lpszFileName,'\\'); LPCWSTR szFolder; if (temp==-1) szFolder=alloccopyAtoW(lpszFileName); else szFolder=alloccopyAtoW(lpszFileName,temp+1); LPITEMIDLIST pidl=NULL; IShellFolder *pDesktop; if (FAILED(SHGetDesktopFolder(&pDesktop))) { delete[] szFolder; return NULL; } if (FAILED(pDesktop->ParseDisplayName(NULL,NULL,(LPOLESTR)szFolder,NULL,&pidl,NULL))) { pDesktop->Release(); delete[] szFolder; return NULL; } return pidl; }
LPWSTR ShellFunctions::StrRetToPtrW(STRRET& strret,LPITEMIDLIST lpiil) { LPWSTR pRet=NULL; switch (strret.uType) { case STRRET_OFFSET: pRet=alloccopyAtoW((LPSTR)((LPBYTE)lpiil+strret.uOffset)); break; case STRRET_CSTR: pRet=alloccopyAtoW(strret.cStr); break; case STRRET_WSTR: pRet=alloccopy(strret.pOleStr); CoTaskMemFree(strret.pOleStr); break; } return pRet; }
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; }