725 lines
22 KiB
C++
725 lines
22 KiB
C++
#include "local.h"
|
|
#include "../security.h"
|
|
#include "../favorite.h"
|
|
#include "resource.h"
|
|
#include "chcommon.h"
|
|
#include "hsfolder.h"
|
|
|
|
#include <mluisupp.h>
|
|
|
|
#define DM_HSFOLDER 0
|
|
|
|
STDAPI AddToFavorites(HWND hwnd, LPCITEMIDLIST pidlCur, LPCTSTR pszTitle,
|
|
BOOL fDisplayUI, IOleCommandTarget *pCommandTarget, IHTMLDocument2 *pDoc);
|
|
|
|
#define MAX_ITEM_OPEN 10
|
|
|
|
static LPCTSTR _GetURLTitleForDisplay(LPBASEPIDL pcei, LPTSTR szBuf, DWORD cchBuf);
|
|
|
|
static BOOL _ValidateIDListArray(UINT cidl, LPCITEMIDLIST *ppidl)
|
|
{
|
|
UINT i;
|
|
|
|
for (i = 0; i < cidl; i++)
|
|
{
|
|
if (!_IsValid_IDPIDL(ppidl[i]) && !_IsValid_HEIPIDL(ppidl[i]))
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CHistItem Object
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
CHistItem::CHistItem()
|
|
{
|
|
}
|
|
|
|
CHistItem::~CHistItem()
|
|
{
|
|
if (_pHCFolder)
|
|
_pHCFolder->Release(); // release the pointer to the sf
|
|
}
|
|
|
|
HRESULT CHistItem::Initialize(CHistFolder *pHCFolder, HWND hwnd, UINT cidl, LPCITEMIDLIST *ppidl)
|
|
{
|
|
HRESULT hres = CBaseItem::Initialize(hwnd, cidl, ppidl);
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
_pHCFolder = pHCFolder;
|
|
_pHCFolder->AddRef(); // we're going to hold onto this pointer, so
|
|
}
|
|
return hres;
|
|
}
|
|
|
|
HRESULT CHistItem_CreateInstance(CHistFolder *pHCFolder, HWND hwnd,
|
|
UINT cidl, LPCITEMIDLIST *ppidl, REFIID riid, void **ppv)
|
|
{
|
|
HRESULT hr;
|
|
|
|
*ppv = NULL; // null the out param
|
|
|
|
if (!_ValidateIDListArray(cidl, ppidl))
|
|
return E_FAIL;
|
|
|
|
CHistItem *pHCItem = new CHistItem;
|
|
if (pHCItem)
|
|
{
|
|
hr = pHCItem->Initialize(pHCFolder, hwnd, cidl, ppidl);
|
|
if (SUCCEEDED(hr))
|
|
hr = pHCItem->QueryInterface(riid, ppv);
|
|
pHCItem->Release();
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//////////////////////////////////
|
|
//
|
|
// IUnknown Methods...
|
|
//
|
|
HRESULT CHistItem::QueryInterface(REFIID iid, void **ppv)
|
|
{
|
|
HRESULT hres = CBaseItem::QueryInterface(iid, ppv);
|
|
|
|
if (FAILED(hres) && iid == IID_IHist)
|
|
{
|
|
*ppv = (LPVOID)this; // for our friends
|
|
AddRef();
|
|
hres = S_OK;
|
|
}
|
|
return hres;
|
|
}
|
|
|
|
//////////////////////////////////
|
|
//
|
|
// IQueryInfo Methods
|
|
//
|
|
HRESULT CHistItem::GetInfoTip(DWORD dwFlags, WCHAR **ppwszTip)
|
|
{
|
|
return _pHCFolder->_GetInfoTip(_ppidl[0], dwFlags, ppwszTip);
|
|
}
|
|
|
|
//////////////////////////////////
|
|
//
|
|
// IContextMenu Methods
|
|
//
|
|
HRESULT CHistItem::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst,UINT idCmdLast, UINT uFlags)
|
|
{
|
|
USHORT cItems;
|
|
|
|
TraceMsg(DM_HSFOLDER, "hci - cm - QueryContextMenu() called.");
|
|
|
|
if ((uFlags & CMF_VERBSONLY) || (uFlags & CMF_DVFILE))
|
|
{
|
|
cItems = MergePopupMenu(&hmenu, POPUP_CONTEXT_URL_VERBSONLY, 0, indexMenu,
|
|
idCmdFirst, idCmdLast);
|
|
|
|
}
|
|
else // (uFlags & CMF_NORMAL)
|
|
{
|
|
UINT idResource = POPUP_CACHECONTEXT_URL;
|
|
|
|
// always use the cachecontext menu unless:
|
|
if ( ((_pHCFolder->_uViewType == VIEWPIDL_ORDER_SITE) &&
|
|
(_pHCFolder->_uViewDepth == 0)) ||
|
|
(!IsLeaf(_pHCFolder->_foldertype)) )
|
|
idResource = POPUP_HISTORYCONTEXT_URL;
|
|
|
|
cItems = MergePopupMenu(&hmenu, idResource, 0, indexMenu, idCmdFirst, idCmdLast);
|
|
|
|
if (IsInetcplRestricted(L"History"))
|
|
{
|
|
DeleteMenu(hmenu, RSVIDM_DELCACHE + idCmdFirst, MF_BYCOMMAND);
|
|
_SHPrettyMenu(hmenu);
|
|
}
|
|
}
|
|
if (hmenu)
|
|
SetMenuDefaultItem(hmenu, indexMenu, MF_BYPOSITION);
|
|
|
|
return ResultFromShort(cItems); // number of menu items
|
|
}
|
|
|
|
STDMETHODIMP CHistItem::InvokeCommand(LPCMINVOKECOMMANDINFO pici)
|
|
{
|
|
UINT i;
|
|
int idCmd = _GetCmdID(pici->lpVerb);
|
|
HRESULT hres = S_OK;
|
|
DWORD dwAction;
|
|
BOOL fCancelCopyAndOpen = FALSE;
|
|
BOOL fZonesUI = FALSE;
|
|
BOOL fMustFlushNotify = FALSE;
|
|
BOOL fBulkDelete;
|
|
|
|
TraceMsg(DM_HSFOLDER, "hci - cm - InvokeCommand() called.");
|
|
|
|
if (idCmd == RSVIDM_DELCACHE)
|
|
{
|
|
TCHAR szBuff[INTERNET_MAX_URL_LENGTH+MAX_PATH];
|
|
TCHAR szFormat[MAX_PATH];
|
|
|
|
if (_cItems == 1)
|
|
{
|
|
TCHAR szTitle[MAX_URL_STRING];
|
|
|
|
if (_pHCFolder->_foldertype != FOLDER_TYPE_Hist)
|
|
{
|
|
_GetURLDispName((LPBASEPIDL)_ppidl[0], szTitle, ARRAYSIZE(szTitle));
|
|
}
|
|
else
|
|
{
|
|
FILETIME ftStart, ftEnd;
|
|
LPCUTSTR pszIntervalName = _GetURLTitle(_ppidl[0]);
|
|
|
|
if (SUCCEEDED(_ValueToIntervalW(pszIntervalName, &ftStart, &ftEnd)))
|
|
{
|
|
GetDisplayNameForTimeInterval(&ftStart, &ftEnd, szTitle, ARRAYSIZE(szTitle));
|
|
}
|
|
}
|
|
|
|
MLLoadString(IDS_WARN_DELETE_HISTORYITEM, szFormat, ARRAYSIZE(szFormat));
|
|
wnsprintf(szBuff, ARRAYSIZE(szBuff), szFormat, szTitle);
|
|
}
|
|
else
|
|
{
|
|
MLLoadString(IDS_WARN_DELETE_MULTIHISTORY, szFormat, ARRAYSIZE(szFormat));
|
|
wnsprintf(szBuff, ARRAYSIZE(szBuff), szFormat, _cItems);
|
|
}
|
|
if (DialogBoxParam(MLGetHinst(),
|
|
MAKEINTRESOURCE(DLG_HISTCACHE_WARNING),
|
|
pici->hwnd,
|
|
HistoryConfirmDeleteDlgProc,
|
|
(LPARAM)szBuff) != IDYES)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
return _pHCFolder->_DeleteItems(_ppidl, _cItems);
|
|
}
|
|
|
|
// ZONES SECURITY CHECK.
|
|
//
|
|
// We need to cycle through each action and Zone Check the URLs.
|
|
// We pass NOUI when zone checking the URLs because we don't want info
|
|
// displayed to the user. We will stop when we find the first questionable
|
|
// URL. We will then
|
|
for (i = 0; (i < _cItems) && !fZonesUI; i++)
|
|
{
|
|
if (_ppidl[i])
|
|
{
|
|
switch (idCmd)
|
|
{
|
|
case RSVIDM_OPEN:
|
|
if ((i < MAX_ITEM_OPEN) && _pHCFolder->_IsLeaf())
|
|
{
|
|
if (!_ZoneCheck(i, URLACTION_SHELL_VERB))
|
|
{
|
|
fZonesUI = TRUE;
|
|
dwAction = URLACTION_SHELL_VERB;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case RSVIDM_COPY:
|
|
if (_pHCFolder->_IsLeaf())
|
|
{
|
|
if (!_ZoneCheck(i, URLACTION_SHELL_MOVE_OR_COPY))
|
|
{
|
|
fZonesUI = TRUE;
|
|
dwAction = URLACTION_SHELL_MOVE_OR_COPY;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (fZonesUI)
|
|
{
|
|
LPCTSTR pszUrl = _GetUrl(i-1); // Sub 1 because of for loop above.
|
|
if (S_OK != ZoneCheckUrl(pszUrl, dwAction, PUAF_DEFAULT|PUAF_WARN_IF_DENIED, NULL))
|
|
{
|
|
// The user cannot do this or does not want to do this.
|
|
fCancelCopyAndOpen = TRUE;
|
|
}
|
|
}
|
|
|
|
i = _cItems;
|
|
|
|
// NOTE (andrewgu): ie5.5 b#108361
|
|
// 1. on older versions of the shell, first deleting the items and then calling
|
|
// SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_IDLIST, _pHCFolder->_pidl, NULL) doesn't trigger a refresh;
|
|
// 2. but deleting an item and then calling calling
|
|
// SHChangeNotify(SHCNE_DELETE, SHCNF_IDLIST, ILCombine(_pHCFolder->_pidl, (LPITEMIDLIST)(_ppcei[i])), NULL) does;
|
|
// 3. so the fix is to not set fBulkDelete on older versions of the shell.
|
|
if (5 <= GetUIVersion())
|
|
fBulkDelete = i > LOTS_OF_FILES;
|
|
else
|
|
fBulkDelete = FALSE;
|
|
|
|
// fCancelCopyAndOpen happens if the user cannot or chose not to proceed.
|
|
while (i && !fCancelCopyAndOpen)
|
|
{
|
|
i--;
|
|
if (_ppidl[i])
|
|
{
|
|
|
|
switch (idCmd)
|
|
{
|
|
case RSVIDM_OPEN:
|
|
ASSERT(!_pHCFolder->_uViewType);
|
|
if (i >= MAX_ITEM_OPEN)
|
|
{
|
|
hres = S_FALSE;
|
|
goto Done;
|
|
}
|
|
|
|
if (!IsLeaf(_pHCFolder->_foldertype))
|
|
{
|
|
LPITEMIDLIST pidlOpen;
|
|
|
|
hres = S_FALSE;
|
|
pidlOpen = ILCombine(_pHCFolder->_pidl, _ppidl[i]);
|
|
if (pidlOpen)
|
|
{
|
|
IShellBrowser *psb = FileCabinet_GetIShellBrowser(_hwndOwner);
|
|
if (psb)
|
|
{
|
|
psb->AddRef();
|
|
psb->BrowseObject(pidlOpen,
|
|
(i==_cItems-1) ? SBSP_DEFBROWSER:SBSP_NEWBROWSER);
|
|
psb->Release();
|
|
hres = S_OK;
|
|
}
|
|
else
|
|
{
|
|
hres = _LaunchAppForPidl(pici->hwnd, pidlOpen);
|
|
}
|
|
ILFree(pidlOpen);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TCHAR szDecoded[MAX_URL_STRING];
|
|
ConditionallyDecodeUTF8(_GetUrl(i), szDecoded, ARRAYSIZE(szDecoded));
|
|
|
|
hres = _LaunchApp(pici->hwnd, szDecoded);
|
|
}
|
|
break;
|
|
|
|
case RSVIDM_ADDTOFAVORITES:
|
|
hres = _AddToFavorites(i);
|
|
goto Done;
|
|
case RSVIDM_OPEN_NEWWINDOW:
|
|
{
|
|
LPCTSTR pszUrl = _GetUrl(i);
|
|
if (pszUrl)
|
|
{
|
|
TCHAR szDecoded[MAX_URL_STRING];
|
|
ConditionallyDecodeUTF8(_GetUrl(i), szDecoded, ARRAYSIZE(szDecoded));
|
|
LPWSTR pwszTarget;
|
|
|
|
if (SUCCEEDED((hres = SHStrDup(szDecoded, &pwszTarget)))) {
|
|
hres = NavToUrlUsingIEW(pwszTarget, TRUE);
|
|
CoTaskMemFree(pwszTarget);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hres = E_FAIL;
|
|
}
|
|
goto Done;
|
|
}
|
|
case RSVIDM_COPY:
|
|
if (!_pHCFolder->_IsLeaf())
|
|
{
|
|
hres = E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
OleSetClipboard((IDataObject *)this);
|
|
}
|
|
goto Done;
|
|
|
|
case RSVIDM_DELCACHE:
|
|
ASSERT(!_pHCFolder->_uViewType);
|
|
// if (IsHistory(_pHCFolder->_foldertype))
|
|
hres = E_FAIL;
|
|
break;
|
|
|
|
case RSVIDM_PROPERTIES:
|
|
// NOTE: We'll probably want to split this into two cases
|
|
// and call a function in each case
|
|
//
|
|
if (IsLeaf(_pHCFolder->_foldertype))
|
|
{
|
|
// this was a bug in IE4, too:
|
|
// the pidl is re-created so that it has the most up-to-date information
|
|
// possible -- this way we can avoid assuming that the NSC has cached the
|
|
// most up-to-date pidl (which, in most cases, it hasn't)
|
|
LPHEIPIDL pidlTemp =
|
|
_pHCFolder->_CreateHCacheFolderPidlFromUrl(FALSE,
|
|
HPidlToSourceUrl( (LPBASEPIDL)_ppidl[i]));
|
|
if (pidlTemp) {
|
|
TCHAR szTitle[MAX_URL_STRING];
|
|
_GetURLTitleForDisplay((LPBASEPIDL)pidlTemp, szTitle, ARRAYSIZE(szTitle));
|
|
_CreatePropSheet(pici->hwnd, (LPCITEMIDLIST)pidlTemp,
|
|
DLG_HISTITEMPROP, _sPropDlgProc, szTitle);
|
|
LocalFree(pidlTemp);
|
|
pidlTemp = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hres = E_FAIL;
|
|
}
|
|
goto Done;
|
|
|
|
default:
|
|
hres = E_FAIL;
|
|
break;
|
|
}
|
|
|
|
ASSERT(SUCCEEDED(hres));
|
|
if (FAILED(hres))
|
|
TraceMsg(DM_HSFOLDER, "Cachevu failed the command at: %s", HPidlToSourceUrl((LPBASEPIDL)_ppidl[i]));
|
|
}
|
|
}
|
|
Done:
|
|
if (fMustFlushNotify)
|
|
{
|
|
if (fBulkDelete)
|
|
{
|
|
ASSERT(!_pHCFolder->_uViewType);
|
|
_GenerateEvent(SHCNE_UPDATEDIR, _pHCFolder->_pidl, NULL, NULL);
|
|
}
|
|
|
|
SHChangeNotifyHandleEvents();
|
|
}
|
|
return hres;
|
|
}
|
|
|
|
//////////////////////////////////
|
|
//
|
|
// IDataObject Methods...
|
|
//
|
|
|
|
HRESULT CHistItem::GetData(LPFORMATETC pFEIn, LPSTGMEDIUM pSTM)
|
|
{
|
|
HRESULT hres;
|
|
|
|
#ifdef DEBUG
|
|
TCHAR szName[64];
|
|
if (!GetClipboardFormatName(pFEIn->cfFormat, szName, sizeof(szName)))
|
|
wnsprintf(szName, ARRAYSIZE(szName), TEXT("#%d"), pFEIn->cfFormat);
|
|
|
|
TraceMsg(DM_HSFOLDER, "hci - do - GetData(%s)", szName);
|
|
#endif
|
|
|
|
pSTM->hGlobal = NULL;
|
|
pSTM->pUnkForRelease = NULL;
|
|
|
|
if ((pFEIn->cfFormat == g_cfFileDescW) && (pFEIn->tymed & TYMED_HGLOBAL))
|
|
hres = _CreateFileDescriptorW(pSTM);
|
|
|
|
else if ((pFEIn->cfFormat == g_cfFileDescA) && (pFEIn->tymed & TYMED_HGLOBAL))
|
|
hres = _CreateFileDescriptorA(pSTM);
|
|
|
|
else if ((pFEIn->cfFormat == g_cfFileContents) && (pFEIn->tymed & TYMED_ISTREAM))
|
|
hres = _CreateFileContents(pSTM, pFEIn->lindex);
|
|
|
|
else if (pFEIn->cfFormat == CF_UNICODETEXT && (pFEIn->tymed & TYMED_HGLOBAL))
|
|
hres = _CreateUnicodeTEXT(pSTM);
|
|
|
|
else if (pFEIn->cfFormat == CF_TEXT && (pFEIn->tymed & TYMED_HGLOBAL))
|
|
hres = _CreateHTEXT(pSTM);
|
|
|
|
else if (pFEIn->cfFormat == g_cfURL && (pFEIn->tymed & TYMED_HGLOBAL))
|
|
hres = _CreateURL(pSTM);
|
|
|
|
else if ((pFEIn->cfFormat == g_cfPreferredEffect) && (pFEIn->tymed & TYMED_HGLOBAL))
|
|
hres = _CreatePrefDropEffect(pSTM);
|
|
|
|
else
|
|
hres = DATA_E_FORMATETC;
|
|
return hres;
|
|
}
|
|
|
|
HRESULT CHistItem::QueryGetData(LPFORMATETC pFEIn)
|
|
{
|
|
#ifdef DEBUG
|
|
TCHAR szName[64];
|
|
if (!GetClipboardFormatName(pFEIn->cfFormat, szName, sizeof(szName)))
|
|
wnsprintf(szName, ARRAYSIZE(szName), TEXT("#%d"), pFEIn->cfFormat);
|
|
|
|
TraceMsg(DM_HSFOLDER, "hci - do - QueryGetData(%s)", szName);
|
|
#endif
|
|
|
|
if (pFEIn->cfFormat == g_cfFileDescW ||
|
|
pFEIn->cfFormat == g_cfFileDescA ||
|
|
pFEIn->cfFormat == g_cfFileContents ||
|
|
pFEIn->cfFormat == g_cfURL ||
|
|
pFEIn->cfFormat == CF_UNICODETEXT ||
|
|
pFEIn->cfFormat == CF_TEXT ||
|
|
pFEIn->cfFormat == g_cfPreferredEffect)
|
|
{
|
|
TraceMsg(DM_HSFOLDER, " format supported.");
|
|
return NOERROR;
|
|
}
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT CHistItem::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC *ppEnum)
|
|
{
|
|
FORMATETC Histfmte[] = {
|
|
{g_cfFileDescW, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
|
|
{g_cfFileDescA, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
|
|
{g_cfFileContents, NULL, DVASPECT_CONTENT, -1, TYMED_ISTREAM },
|
|
{g_cfURL, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
|
|
{CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
|
|
{CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
|
|
{g_cfPreferredEffect, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
|
|
};
|
|
return SHCreateStdEnumFmtEtc(ARRAYSIZE(Histfmte), Histfmte, ppEnum);
|
|
}
|
|
|
|
//////////////////////////////////
|
|
//
|
|
// IExtractIconA Methods...
|
|
//
|
|
HRESULT CHistItem::GetIconLocation(UINT uFlags, LPSTR pszIconFile, UINT ucchMax, PINT pniIcon, PUINT puFlags)
|
|
{
|
|
int cbIcon;
|
|
|
|
if (_pHCFolder->_uViewType) {
|
|
switch (_pHCFolder->_uViewType) {
|
|
case VIEWPIDL_SEARCH:
|
|
case VIEWPIDL_ORDER_FREQ:
|
|
case VIEWPIDL_ORDER_TODAY:
|
|
cbIcon = IDI_HISTURL;
|
|
break;
|
|
case VIEWPIDL_ORDER_SITE:
|
|
switch(_pHCFolder->_uViewDepth) {
|
|
case 0: cbIcon = (uFlags & GIL_OPENICON) ? IDI_HISTOPEN:IDI_HISTFOLDER; break;
|
|
case 1: cbIcon = IDI_HISTURL; break;
|
|
}
|
|
break;
|
|
default:
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
else {
|
|
switch (_pHCFolder->_foldertype)
|
|
{
|
|
case FOLDER_TYPE_Hist:
|
|
cbIcon = IDI_HISTWEEK;
|
|
break;
|
|
case FOLDER_TYPE_HistInterval:
|
|
cbIcon = (uFlags & GIL_OPENICON) ? IDI_HISTOPEN:IDI_HISTFOLDER;
|
|
break;
|
|
case FOLDER_TYPE_HistDomain:
|
|
cbIcon = IDI_HISTURL;
|
|
break;
|
|
default:
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
*puFlags = 0;
|
|
*pniIcon = -cbIcon;
|
|
StrCpyNA(pszIconFile, "shdocvw.dll", ucchMax);
|
|
return S_OK;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Helper Routines
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
UNALIGNED const TCHAR* _GetURLTitle(LPBASEPIDL pcei)
|
|
{
|
|
if (pcei->usSign == HEIPIDL_SIGN)
|
|
{
|
|
LPHEIPIDL phei = (LPHEIPIDL) pcei;
|
|
|
|
if (phei->usTitle == 0)
|
|
{
|
|
const TCHAR* psz = _StripHistoryUrlToUrl(HPidlToSourceUrl((LPBASEPIDL)pcei));
|
|
|
|
return psz ? _FindURLFileName(psz) : TEXT("");
|
|
}
|
|
else
|
|
{
|
|
return (LPTSTR)(((BYTE*)phei)+phei->usTitle);
|
|
}
|
|
}
|
|
else if (VALID_IDSIGN(pcei->usSign))
|
|
{
|
|
return ((LPHIDPIDL)pcei)->szID;
|
|
}
|
|
else
|
|
{
|
|
return TEXT("");
|
|
}
|
|
}
|
|
|
|
static LPCTSTR _GetURLTitleForDisplay(LPBASEPIDL pcei, LPTSTR szBuf, DWORD cchBuf)
|
|
{
|
|
TCHAR szTitle[MAX_URL_STRING];
|
|
if (!_URLTitleIsURL(pcei) ||
|
|
FAILED(PrepareURLForDisplayUTF8(_GetURLTitleAlign(pcei, szTitle, ARRAYSIZE(szTitle)), szBuf, &cchBuf, TRUE)))
|
|
{
|
|
ualstrcpyn(szBuf, _GetURLTitle(pcei), cchBuf);
|
|
}
|
|
|
|
return szBuf;
|
|
}
|
|
|
|
UNALIGNED const TCHAR* CHistItem::_GetURLTitle(LPCITEMIDLIST pidl)
|
|
{
|
|
return ::_GetURLTitle( (LPBASEPIDL)pidl);
|
|
}
|
|
|
|
LPCTSTR CHistItem::_GetUrl(int nIndex)
|
|
{
|
|
return _StripHistoryUrlToUrl(HPidlToSourceUrl((LPBASEPIDL)_ppidl[nIndex]));
|
|
}
|
|
|
|
LPCTSTR CHistItem::_PidlToSourceUrl(LPCITEMIDLIST pidl)
|
|
{
|
|
return HPidlToSourceUrl((LPBASEPIDL) pidl);
|
|
}
|
|
|
|
|
|
// Return value:
|
|
// TRUE - URL is Safe.
|
|
// FALSE - URL is questionable and needs to be re-zone checked w/o PUAF_NOUI.
|
|
BOOL CHistItem::_ZoneCheck(int nIndex, DWORD dwUrlAction)
|
|
{
|
|
LPCTSTR pszUrl = _GetUrl(nIndex);
|
|
|
|
// Yes, then consider anything that is not
|
|
// a FILE URL safe.
|
|
|
|
int nScheme = GetUrlScheme(pszUrl);
|
|
if (URL_SCHEME_FILE != nScheme)
|
|
return TRUE; // It's safe because it's not a file URL.
|
|
|
|
if (S_OK != ZoneCheckUrl(pszUrl, dwUrlAction, PUAF_NOUI, NULL))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Helper Routines
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
INT_PTR CALLBACK CHistItem::_sPropDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
LPPROPSHEETPAGE lpPropSheet = (LPPROPSHEETPAGE) GetWindowLongPtr(hDlg, DWLP_USER);
|
|
LPHEIPIDL phei = lpPropSheet ? (LPHEIPIDL)lpPropSheet->lParam : NULL;
|
|
|
|
switch(message) {
|
|
|
|
case WM_INITDIALOG:
|
|
{
|
|
SHFILEINFO sfi;
|
|
TCHAR szBuf[80];
|
|
TCHAR szDisplayUrl[INTERNET_MAX_URL_LENGTH];
|
|
|
|
SetWindowLongPtr(hDlg, DWLP_USER, lParam);
|
|
phei = (LPHEIPIDL)((LPPROPSHEETPAGE)lParam)->lParam;
|
|
|
|
SHGetFileInfo(TEXT(".url"), 0, &sfi, SIZEOF(sfi), SHGFI_ICON |
|
|
SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME);
|
|
|
|
SendDlgItemMessage(hDlg, IDD_ITEMICON, STM_SETICON, (WPARAM)sfi.hIcon, 0);
|
|
|
|
_GetURLTitleForDisplay((LPBASEPIDL)phei, szDisplayUrl, ARRAYSIZE(szDisplayUrl));
|
|
SetDlgItemText(hDlg, IDD_TITLE, szDisplayUrl);
|
|
|
|
SetDlgItemText(hDlg, IDD_FILETYPE, sfi.szTypeName);
|
|
|
|
ConditionallyDecodeUTF8(_GetUrlForPidl((LPCITEMIDLIST)phei), szDisplayUrl, ARRAYSIZE(szDisplayUrl));
|
|
SetDlgItemText(hDlg, IDD_INTERNET_ADDRESS, szDisplayUrl);
|
|
|
|
FileTimeToDateTimeStringInternal(&phei->ftLastVisited, szBuf, ARRAYSIZE(szBuf), FALSE);
|
|
SetDlgItemText(hDlg, IDD_LAST_VISITED, szBuf);
|
|
|
|
// It looks like the hitcount is double what it is supposed to be
|
|
// (ie - navigate to a site and hitcount += 2)
|
|
// For now, we'll just half the hitcount before we display it:
|
|
|
|
// Above statement is no longer true -- hitcount is correct. Removed the halving of hitcount.
|
|
wnsprintf(szBuf, ARRAYSIZE(szBuf), TEXT("%d"), (phei->dwNumHits)) ;
|
|
SetDlgItemText(hDlg, IDD_NUMHITS, szBuf);
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
case WM_DESTROY:
|
|
{
|
|
HICON hIcon = (HICON)SendDlgItemMessage(hDlg, IDD_ITEMICON, STM_GETICON, 0, 0);
|
|
if (hIcon)
|
|
DestroyIcon(hIcon);
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
case WM_HELP:
|
|
case WM_CONTEXTMENU:
|
|
// user can't change anything, so we don't care about any messages
|
|
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
} // end of switch
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
HRESULT CHistItem::_CreateFileDescriptorW(LPSTGMEDIUM pSTM)
|
|
{
|
|
|
|
pSTM->tymed = TYMED_HGLOBAL;
|
|
pSTM->pUnkForRelease = NULL;
|
|
|
|
FILEGROUPDESCRIPTORW *pfgd = (FILEGROUPDESCRIPTORW*)GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTORW) + (_cItems-1) * sizeof(FILEDESCRIPTORW));
|
|
if (pfgd == NULL)
|
|
{
|
|
TraceMsg(DM_HSFOLDER, "hci - Couldn't alloc file descriptor");
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
pfgd->cItems = _cItems; // set the number of items
|
|
|
|
for (UINT i = 0; i < _cItems; i++)
|
|
{
|
|
FILEDESCRIPTORW *pfd = &(pfgd->fgd[i]);
|
|
|
|
_GetURLTitleForDisplay((LPBASEPIDL)_ppidl[i], pfd->cFileName, ARRAYSIZE(pfd->cFileName));
|
|
|
|
MakeLegalFilenameW(pfd->cFileName);
|
|
|
|
UINT cchFilename = lstrlenW(pfd->cFileName);
|
|
SHTCharToUnicode(L".URL", pfd->cFileName+cchFilename, ARRAYSIZE(pfd->cFileName)-cchFilename);
|
|
}
|
|
|
|
pSTM->hGlobal = pfgd;
|
|
|
|
return S_OK;
|
|
}
|
|
|