Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
0
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);
}
Пример #4
0
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);
}
Пример #5
0
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;
	}
Пример #7
0
/**************************************************************************
*	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;
}
Пример #8
0
/* 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]);
}
Пример #9
0
/***********************************************************************
 *  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;
}
Пример #10
0
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;
}
Пример #11
0
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);
}
Пример #12
0
/***********************************************************************
 *    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;
}
Пример #13
0
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;
}
Пример #15
0
/* 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);
}
Пример #16
0
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;
}
Пример #17
0
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());
}
Пример #18
0
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;
	}
Пример #19
0
/***********************************************************************
 *	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;
}
Пример #20
0
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;
}
Пример #21
0
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);
	}
}
Пример #23
0
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);
}
Пример #24
0
//
// 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;
}
Пример #25
0
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);
}
Пример #26
0
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;
}
Пример #27
0
/******************************************************************************
 * 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 );
}
Пример #28
0
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;
}
Пример #29
0
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();    	
}
Пример #30
0
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;
}