Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

724 lines
22 KiB

  1. #include "local.h"
  2. #include "../security.h"
  3. #include "../favorite.h"
  4. #include "resource.h"
  5. #include "chcommon.h"
  6. #include "hsfolder.h"
  7. #include <mluisupp.h>
  8. #define DM_HSFOLDER 0
  9. STDAPI AddToFavorites(HWND hwnd, LPCITEMIDLIST pidlCur, LPCTSTR pszTitle,
  10. BOOL fDisplayUI, IOleCommandTarget *pCommandTarget, IHTMLDocument2 *pDoc);
  11. #define MAX_ITEM_OPEN 10
  12. static LPCTSTR _GetURLTitleForDisplay(LPBASEPIDL pcei, LPTSTR szBuf, DWORD cchBuf);
  13. static BOOL _ValidateIDListArray(UINT cidl, LPCITEMIDLIST *ppidl)
  14. {
  15. UINT i;
  16. for (i = 0; i < cidl; i++)
  17. {
  18. if (!_IsValid_IDPIDL(ppidl[i]) && !_IsValid_HEIPIDL(ppidl[i]))
  19. return FALSE;
  20. }
  21. return TRUE;
  22. }
  23. //////////////////////////////////////////////////////////////////////////////
  24. //
  25. // CHistItem Object
  26. //
  27. //////////////////////////////////////////////////////////////////////////////
  28. CHistItem::CHistItem()
  29. {
  30. }
  31. CHistItem::~CHistItem()
  32. {
  33. if (_pHCFolder)
  34. _pHCFolder->Release(); // release the pointer to the sf
  35. }
  36. HRESULT CHistItem::Initialize(CHistFolder *pHCFolder, HWND hwnd, UINT cidl, LPCITEMIDLIST *ppidl)
  37. {
  38. HRESULT hres = CBaseItem::Initialize(hwnd, cidl, ppidl);
  39. if (SUCCEEDED(hres))
  40. {
  41. _pHCFolder = pHCFolder;
  42. _pHCFolder->AddRef(); // we're going to hold onto this pointer, so
  43. }
  44. return hres;
  45. }
  46. HRESULT CHistItem_CreateInstance(CHistFolder *pHCFolder, HWND hwnd,
  47. UINT cidl, LPCITEMIDLIST *ppidl, REFIID riid, void **ppv)
  48. {
  49. HRESULT hr;
  50. *ppv = NULL; // null the out param
  51. if (!_ValidateIDListArray(cidl, ppidl))
  52. return E_FAIL;
  53. CHistItem *pHCItem = new CHistItem;
  54. if (pHCItem)
  55. {
  56. hr = pHCItem->Initialize(pHCFolder, hwnd, cidl, ppidl);
  57. if (SUCCEEDED(hr))
  58. hr = pHCItem->QueryInterface(riid, ppv);
  59. pHCItem->Release();
  60. }
  61. else
  62. hr = E_OUTOFMEMORY;
  63. return hr;
  64. }
  65. //////////////////////////////////
  66. //
  67. // IUnknown Methods...
  68. //
  69. HRESULT CHistItem::QueryInterface(REFIID iid, void **ppv)
  70. {
  71. HRESULT hres = CBaseItem::QueryInterface(iid, ppv);
  72. if (FAILED(hres) && iid == IID_IHist)
  73. {
  74. *ppv = (LPVOID)this; // for our friends
  75. AddRef();
  76. hres = S_OK;
  77. }
  78. return hres;
  79. }
  80. //////////////////////////////////
  81. //
  82. // IQueryInfo Methods
  83. //
  84. HRESULT CHistItem::GetInfoTip(DWORD dwFlags, WCHAR **ppwszTip)
  85. {
  86. return _pHCFolder->_GetInfoTip(_ppidl[0], dwFlags, ppwszTip);
  87. }
  88. //////////////////////////////////
  89. //
  90. // IContextMenu Methods
  91. //
  92. HRESULT CHistItem::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst,UINT idCmdLast, UINT uFlags)
  93. {
  94. USHORT cItems;
  95. TraceMsg(DM_HSFOLDER, "hci - cm - QueryContextMenu() called.");
  96. if ((uFlags & CMF_VERBSONLY) || (uFlags & CMF_DVFILE))
  97. {
  98. cItems = MergePopupMenu(&hmenu, POPUP_CONTEXT_URL_VERBSONLY, 0, indexMenu,
  99. idCmdFirst, idCmdLast);
  100. }
  101. else // (uFlags & CMF_NORMAL)
  102. {
  103. UINT idResource = POPUP_CACHECONTEXT_URL;
  104. // always use the cachecontext menu unless:
  105. if ( ((_pHCFolder->_uViewType == VIEWPIDL_ORDER_SITE) &&
  106. (_pHCFolder->_uViewDepth == 0)) ||
  107. (!IsLeaf(_pHCFolder->_foldertype)) )
  108. idResource = POPUP_HISTORYCONTEXT_URL;
  109. cItems = MergePopupMenu(&hmenu, idResource, 0, indexMenu, idCmdFirst, idCmdLast);
  110. if (IsInetcplRestricted(L"History"))
  111. {
  112. DeleteMenu(hmenu, RSVIDM_DELCACHE + idCmdFirst, MF_BYCOMMAND);
  113. _SHPrettyMenu(hmenu);
  114. }
  115. }
  116. if (hmenu)
  117. SetMenuDefaultItem(hmenu, indexMenu, MF_BYPOSITION);
  118. return ResultFromShort(cItems); // number of menu items
  119. }
  120. STDMETHODIMP CHistItem::InvokeCommand(LPCMINVOKECOMMANDINFO pici)
  121. {
  122. UINT i;
  123. int idCmd = _GetCmdID(pici->lpVerb);
  124. HRESULT hres = S_OK;
  125. DWORD dwAction;
  126. BOOL fCancelCopyAndOpen = FALSE;
  127. BOOL fZonesUI = FALSE;
  128. BOOL fMustFlushNotify = FALSE;
  129. BOOL fBulkDelete;
  130. TraceMsg(DM_HSFOLDER, "hci - cm - InvokeCommand() called.");
  131. if (idCmd == RSVIDM_DELCACHE)
  132. {
  133. TCHAR szBuff[INTERNET_MAX_URL_LENGTH+MAX_PATH];
  134. TCHAR szFormat[MAX_PATH];
  135. if (_cItems == 1)
  136. {
  137. TCHAR szTitle[MAX_URL_STRING];
  138. if (_pHCFolder->_foldertype != FOLDER_TYPE_Hist)
  139. {
  140. _GetURLDispName((LPBASEPIDL)_ppidl[0], szTitle, ARRAYSIZE(szTitle));
  141. }
  142. else
  143. {
  144. FILETIME ftStart, ftEnd;
  145. LPCUTSTR pszIntervalName = _GetURLTitle(_ppidl[0]);
  146. if (SUCCEEDED(_ValueToIntervalW(pszIntervalName, &ftStart, &ftEnd)))
  147. {
  148. GetDisplayNameForTimeInterval(&ftStart, &ftEnd, szTitle, ARRAYSIZE(szTitle));
  149. }
  150. }
  151. MLLoadString(IDS_WARN_DELETE_HISTORYITEM, szFormat, ARRAYSIZE(szFormat));
  152. wnsprintf(szBuff, ARRAYSIZE(szBuff), szFormat, szTitle);
  153. }
  154. else
  155. {
  156. MLLoadString(IDS_WARN_DELETE_MULTIHISTORY, szFormat, ARRAYSIZE(szFormat));
  157. wnsprintf(szBuff, ARRAYSIZE(szBuff), szFormat, _cItems);
  158. }
  159. if (DialogBoxParam(MLGetHinst(),
  160. MAKEINTRESOURCE(DLG_HISTCACHE_WARNING),
  161. pici->hwnd,
  162. HistoryConfirmDeleteDlgProc,
  163. (LPARAM)szBuff) != IDYES)
  164. {
  165. return S_FALSE;
  166. }
  167. return _pHCFolder->_DeleteItems(_ppidl, _cItems);
  168. }
  169. // ZONES SECURITY CHECK.
  170. //
  171. // We need to cycle through each action and Zone Check the URLs.
  172. // We pass NOUI when zone checking the URLs because we don't want info
  173. // displayed to the user. We will stop when we find the first questionable
  174. // URL. We will then
  175. for (i = 0; (i < _cItems) && !fZonesUI; i++)
  176. {
  177. if (_ppidl[i])
  178. {
  179. switch (idCmd)
  180. {
  181. case RSVIDM_OPEN:
  182. if ((i < MAX_ITEM_OPEN) && _pHCFolder->_IsLeaf())
  183. {
  184. if (!_ZoneCheck(i, URLACTION_SHELL_VERB))
  185. {
  186. fZonesUI = TRUE;
  187. dwAction = URLACTION_SHELL_VERB;
  188. }
  189. }
  190. break;
  191. case RSVIDM_COPY:
  192. if (_pHCFolder->_IsLeaf())
  193. {
  194. if (!_ZoneCheck(i, URLACTION_SHELL_MOVE_OR_COPY))
  195. {
  196. fZonesUI = TRUE;
  197. dwAction = URLACTION_SHELL_MOVE_OR_COPY;
  198. }
  199. }
  200. break;
  201. }
  202. }
  203. }
  204. if (fZonesUI)
  205. {
  206. LPCTSTR pszUrl = _GetUrl(i-1); // Sub 1 because of for loop above.
  207. if (S_OK != ZoneCheckUrl(pszUrl, dwAction, PUAF_DEFAULT|PUAF_WARN_IF_DENIED, NULL))
  208. {
  209. // The user cannot do this or does not want to do this.
  210. fCancelCopyAndOpen = TRUE;
  211. }
  212. }
  213. i = _cItems;
  214. // NOTE (andrewgu): ie5.5 b#108361
  215. // 1. on older versions of the shell, first deleting the items and then calling
  216. // SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_IDLIST, _pHCFolder->_pidl, NULL) doesn't trigger a refresh;
  217. // 2. but deleting an item and then calling calling
  218. // SHChangeNotify(SHCNE_DELETE, SHCNF_IDLIST, ILCombine(_pHCFolder->_pidl, (LPITEMIDLIST)(_ppcei[i])), NULL) does;
  219. // 3. so the fix is to not set fBulkDelete on older versions of the shell.
  220. if (5 <= GetUIVersion())
  221. fBulkDelete = i > LOTS_OF_FILES;
  222. else
  223. fBulkDelete = FALSE;
  224. // fCancelCopyAndOpen happens if the user cannot or chose not to proceed.
  225. while (i && !fCancelCopyAndOpen)
  226. {
  227. i--;
  228. if (_ppidl[i])
  229. {
  230. switch (idCmd)
  231. {
  232. case RSVIDM_OPEN:
  233. ASSERT(!_pHCFolder->_uViewType);
  234. if (i >= MAX_ITEM_OPEN)
  235. {
  236. hres = S_FALSE;
  237. goto Done;
  238. }
  239. if (!IsLeaf(_pHCFolder->_foldertype))
  240. {
  241. LPITEMIDLIST pidlOpen;
  242. hres = S_FALSE;
  243. pidlOpen = ILCombine(_pHCFolder->_pidl, _ppidl[i]);
  244. if (pidlOpen)
  245. {
  246. IShellBrowser *psb = FileCabinet_GetIShellBrowser(_hwndOwner);
  247. if (psb)
  248. {
  249. psb->AddRef();
  250. psb->BrowseObject(pidlOpen,
  251. (i==_cItems-1) ? SBSP_DEFBROWSER:SBSP_NEWBROWSER);
  252. psb->Release();
  253. hres = S_OK;
  254. }
  255. else
  256. {
  257. hres = _LaunchAppForPidl(pici->hwnd, pidlOpen);
  258. }
  259. ILFree(pidlOpen);
  260. }
  261. }
  262. else
  263. {
  264. TCHAR szDecoded[MAX_URL_STRING];
  265. ConditionallyDecodeUTF8(_GetUrl(i), szDecoded, ARRAYSIZE(szDecoded));
  266. hres = _LaunchApp(pici->hwnd, szDecoded);
  267. }
  268. break;
  269. case RSVIDM_ADDTOFAVORITES:
  270. hres = _AddToFavorites(i);
  271. goto Done;
  272. case RSVIDM_OPEN_NEWWINDOW:
  273. {
  274. LPCTSTR pszUrl = _GetUrl(i);
  275. if (pszUrl)
  276. {
  277. TCHAR szDecoded[MAX_URL_STRING];
  278. ConditionallyDecodeUTF8(_GetUrl(i), szDecoded, ARRAYSIZE(szDecoded));
  279. LPWSTR pwszTarget;
  280. if (SUCCEEDED((hres = SHStrDup(szDecoded, &pwszTarget)))) {
  281. hres = NavToUrlUsingIEW(pwszTarget, TRUE);
  282. CoTaskMemFree(pwszTarget);
  283. }
  284. }
  285. else
  286. {
  287. hres = E_FAIL;
  288. }
  289. goto Done;
  290. }
  291. case RSVIDM_COPY:
  292. if (!_pHCFolder->_IsLeaf())
  293. {
  294. hres = E_FAIL;
  295. }
  296. else
  297. {
  298. OleSetClipboard((IDataObject *)this);
  299. }
  300. goto Done;
  301. case RSVIDM_DELCACHE:
  302. ASSERT(!_pHCFolder->_uViewType);
  303. // if (IsHistory(_pHCFolder->_foldertype))
  304. hres = E_FAIL;
  305. break;
  306. case RSVIDM_PROPERTIES:
  307. // NOTE: We'll probably want to split this into two cases
  308. // and call a function in each case
  309. //
  310. if (IsLeaf(_pHCFolder->_foldertype))
  311. {
  312. // this was a bug in IE4, too:
  313. // the pidl is re-created so that it has the most up-to-date information
  314. // possible -- this way we can avoid assuming that the NSC has cached the
  315. // most up-to-date pidl (which, in most cases, it hasn't)
  316. LPHEIPIDL pidlTemp =
  317. _pHCFolder->_CreateHCacheFolderPidlFromUrl(FALSE,
  318. HPidlToSourceUrl( (LPBASEPIDL)_ppidl[i]));
  319. if (pidlTemp) {
  320. TCHAR szTitle[MAX_URL_STRING];
  321. _GetURLTitleForDisplay((LPBASEPIDL)pidlTemp, szTitle, ARRAYSIZE(szTitle));
  322. _CreatePropSheet(pici->hwnd, (LPCITEMIDLIST)pidlTemp,
  323. DLG_HISTITEMPROP, _sPropDlgProc, szTitle);
  324. LocalFree(pidlTemp);
  325. pidlTemp = NULL;
  326. }
  327. }
  328. else
  329. {
  330. hres = E_FAIL;
  331. }
  332. goto Done;
  333. default:
  334. hres = E_FAIL;
  335. break;
  336. }
  337. ASSERT(SUCCEEDED(hres));
  338. if (FAILED(hres))
  339. TraceMsg(DM_HSFOLDER, "Cachevu failed the command at: %s", HPidlToSourceUrl((LPBASEPIDL)_ppidl[i]));
  340. }
  341. }
  342. Done:
  343. if (fMustFlushNotify)
  344. {
  345. if (fBulkDelete)
  346. {
  347. ASSERT(!_pHCFolder->_uViewType);
  348. _GenerateEvent(SHCNE_UPDATEDIR, _pHCFolder->_pidl, NULL, NULL);
  349. }
  350. SHChangeNotifyHandleEvents();
  351. }
  352. return hres;
  353. }
  354. //////////////////////////////////
  355. //
  356. // IDataObject Methods...
  357. //
  358. HRESULT CHistItem::GetData(LPFORMATETC pFEIn, LPSTGMEDIUM pSTM)
  359. {
  360. HRESULT hres;
  361. #ifdef DEBUG
  362. TCHAR szName[64];
  363. if (!GetClipboardFormatName(pFEIn->cfFormat, szName, sizeof(szName)))
  364. wnsprintf(szName, ARRAYSIZE(szName), TEXT("#%d"), pFEIn->cfFormat);
  365. TraceMsg(DM_HSFOLDER, "hci - do - GetData(%s)", szName);
  366. #endif
  367. pSTM->hGlobal = NULL;
  368. pSTM->pUnkForRelease = NULL;
  369. if ((pFEIn->cfFormat == g_cfFileDescW) && (pFEIn->tymed & TYMED_HGLOBAL))
  370. hres = _CreateFileDescriptorW(pSTM);
  371. else if ((pFEIn->cfFormat == g_cfFileDescA) && (pFEIn->tymed & TYMED_HGLOBAL))
  372. hres = _CreateFileDescriptorA(pSTM);
  373. else if ((pFEIn->cfFormat == g_cfFileContents) && (pFEIn->tymed & TYMED_ISTREAM))
  374. hres = _CreateFileContents(pSTM, pFEIn->lindex);
  375. else if (pFEIn->cfFormat == CF_UNICODETEXT && (pFEIn->tymed & TYMED_HGLOBAL))
  376. hres = _CreateUnicodeTEXT(pSTM);
  377. else if (pFEIn->cfFormat == CF_TEXT && (pFEIn->tymed & TYMED_HGLOBAL))
  378. hres = _CreateHTEXT(pSTM);
  379. else if (pFEIn->cfFormat == g_cfURL && (pFEIn->tymed & TYMED_HGLOBAL))
  380. hres = _CreateURL(pSTM);
  381. else if ((pFEIn->cfFormat == g_cfPreferredEffect) && (pFEIn->tymed & TYMED_HGLOBAL))
  382. hres = _CreatePrefDropEffect(pSTM);
  383. else
  384. hres = DATA_E_FORMATETC;
  385. return hres;
  386. }
  387. HRESULT CHistItem::QueryGetData(LPFORMATETC pFEIn)
  388. {
  389. #ifdef DEBUG
  390. TCHAR szName[64];
  391. if (!GetClipboardFormatName(pFEIn->cfFormat, szName, sizeof(szName)))
  392. wnsprintf(szName, ARRAYSIZE(szName), TEXT("#%d"), pFEIn->cfFormat);
  393. TraceMsg(DM_HSFOLDER, "hci - do - QueryGetData(%s)", szName);
  394. #endif
  395. if (pFEIn->cfFormat == g_cfFileDescW ||
  396. pFEIn->cfFormat == g_cfFileDescA ||
  397. pFEIn->cfFormat == g_cfFileContents ||
  398. pFEIn->cfFormat == g_cfURL ||
  399. pFEIn->cfFormat == CF_UNICODETEXT ||
  400. pFEIn->cfFormat == CF_TEXT ||
  401. pFEIn->cfFormat == g_cfPreferredEffect)
  402. {
  403. TraceMsg(DM_HSFOLDER, " format supported.");
  404. return NOERROR;
  405. }
  406. return S_FALSE;
  407. }
  408. HRESULT CHistItem::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC *ppEnum)
  409. {
  410. FORMATETC Histfmte[] = {
  411. {g_cfFileDescW, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
  412. {g_cfFileDescA, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
  413. {g_cfFileContents, NULL, DVASPECT_CONTENT, -1, TYMED_ISTREAM },
  414. {g_cfURL, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
  415. {CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
  416. {CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
  417. {g_cfPreferredEffect, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
  418. };
  419. return SHCreateStdEnumFmtEtc(ARRAYSIZE(Histfmte), Histfmte, ppEnum);
  420. }
  421. //////////////////////////////////
  422. //
  423. // IExtractIconA Methods...
  424. //
  425. HRESULT CHistItem::GetIconLocation(UINT uFlags, LPSTR pszIconFile, UINT ucchMax, PINT pniIcon, PUINT puFlags)
  426. {
  427. int cbIcon;
  428. if (_pHCFolder->_uViewType) {
  429. switch (_pHCFolder->_uViewType) {
  430. case VIEWPIDL_SEARCH:
  431. case VIEWPIDL_ORDER_FREQ:
  432. case VIEWPIDL_ORDER_TODAY:
  433. cbIcon = IDI_HISTURL;
  434. break;
  435. case VIEWPIDL_ORDER_SITE:
  436. switch(_pHCFolder->_uViewDepth) {
  437. case 0: cbIcon = (uFlags & GIL_OPENICON) ? IDI_HISTOPEN:IDI_HISTFOLDER; break;
  438. case 1: cbIcon = IDI_HISTURL; break;
  439. }
  440. break;
  441. default:
  442. return E_FAIL;
  443. }
  444. }
  445. else {
  446. switch (_pHCFolder->_foldertype)
  447. {
  448. case FOLDER_TYPE_Hist:
  449. cbIcon = IDI_HISTWEEK;
  450. break;
  451. case FOLDER_TYPE_HistInterval:
  452. cbIcon = (uFlags & GIL_OPENICON) ? IDI_HISTOPEN:IDI_HISTFOLDER;
  453. break;
  454. case FOLDER_TYPE_HistDomain:
  455. cbIcon = IDI_HISTURL;
  456. break;
  457. default:
  458. return E_FAIL;
  459. }
  460. }
  461. *puFlags = 0;
  462. *pniIcon = -cbIcon;
  463. StrCpyNA(pszIconFile, "shdocvw.dll", ucchMax);
  464. return S_OK;
  465. }
  466. //////////////////////////////////////////////////////////////////////////////
  467. //
  468. // Helper Routines
  469. //
  470. //////////////////////////////////////////////////////////////////////////////
  471. UNALIGNED const TCHAR* _GetURLTitle(LPBASEPIDL pcei)
  472. {
  473. if (pcei->usSign == HEIPIDL_SIGN)
  474. {
  475. LPHEIPIDL phei = (LPHEIPIDL) pcei;
  476. if (phei->usTitle == 0)
  477. {
  478. const TCHAR* psz = _StripHistoryUrlToUrl(HPidlToSourceUrl((LPBASEPIDL)pcei));
  479. return psz ? _FindURLFileName(psz) : TEXT("");
  480. }
  481. else
  482. {
  483. return (LPTSTR)(((BYTE*)phei)+phei->usTitle);
  484. }
  485. }
  486. else if (VALID_IDSIGN(pcei->usSign))
  487. {
  488. return ((LPHIDPIDL)pcei)->szID;
  489. }
  490. else
  491. {
  492. return TEXT("");
  493. }
  494. }
  495. static LPCTSTR _GetURLTitleForDisplay(LPBASEPIDL pcei, LPTSTR szBuf, DWORD cchBuf)
  496. {
  497. TCHAR szTitle[MAX_URL_STRING];
  498. if (!_URLTitleIsURL(pcei) ||
  499. FAILED(PrepareURLForDisplayUTF8(_GetURLTitleAlign(pcei, szTitle, ARRAYSIZE(szTitle)), szBuf, &cchBuf, TRUE)))
  500. {
  501. ualstrcpyn(szBuf, _GetURLTitle(pcei), cchBuf);
  502. }
  503. return szBuf;
  504. }
  505. UNALIGNED const TCHAR* CHistItem::_GetURLTitle(LPCITEMIDLIST pidl)
  506. {
  507. return ::_GetURLTitle( (LPBASEPIDL)pidl);
  508. }
  509. LPCTSTR CHistItem::_GetUrl(int nIndex)
  510. {
  511. return _StripHistoryUrlToUrl(HPidlToSourceUrl((LPBASEPIDL)_ppidl[nIndex]));
  512. }
  513. LPCTSTR CHistItem::_PidlToSourceUrl(LPCITEMIDLIST pidl)
  514. {
  515. return HPidlToSourceUrl((LPBASEPIDL) pidl);
  516. }
  517. // Return value:
  518. // TRUE - URL is Safe.
  519. // FALSE - URL is questionable and needs to be re-zone checked w/o PUAF_NOUI.
  520. BOOL CHistItem::_ZoneCheck(int nIndex, DWORD dwUrlAction)
  521. {
  522. LPCTSTR pszUrl = _GetUrl(nIndex);
  523. // Yes, then consider anything that is not
  524. // a FILE URL safe.
  525. int nScheme = GetUrlScheme(pszUrl);
  526. if (URL_SCHEME_FILE != nScheme)
  527. return TRUE; // It's safe because it's not a file URL.
  528. if (S_OK != ZoneCheckUrl(pszUrl, dwUrlAction, PUAF_NOUI, NULL))
  529. return FALSE;
  530. return TRUE;
  531. }
  532. //////////////////////////////////////////////////////////////////////////////
  533. //
  534. // Helper Routines
  535. //
  536. //////////////////////////////////////////////////////////////////////////////
  537. INT_PTR CALLBACK CHistItem::_sPropDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  538. {
  539. LPPROPSHEETPAGE lpPropSheet = (LPPROPSHEETPAGE) GetWindowLongPtr(hDlg, DWLP_USER);
  540. LPHEIPIDL phei = lpPropSheet ? (LPHEIPIDL)lpPropSheet->lParam : NULL;
  541. switch(message) {
  542. case WM_INITDIALOG:
  543. {
  544. SHFILEINFO sfi;
  545. TCHAR szBuf[80];
  546. TCHAR szDisplayUrl[INTERNET_MAX_URL_LENGTH];
  547. SetWindowLongPtr(hDlg, DWLP_USER, lParam);
  548. phei = (LPHEIPIDL)((LPPROPSHEETPAGE)lParam)->lParam;
  549. SHGetFileInfo(TEXT(".url"), 0, &sfi, SIZEOF(sfi), SHGFI_ICON |
  550. SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME);
  551. SendDlgItemMessage(hDlg, IDD_ITEMICON, STM_SETICON, (WPARAM)sfi.hIcon, 0);
  552. _GetURLTitleForDisplay((LPBASEPIDL)phei, szDisplayUrl, ARRAYSIZE(szDisplayUrl));
  553. SetDlgItemText(hDlg, IDD_TITLE, szDisplayUrl);
  554. SetDlgItemText(hDlg, IDD_FILETYPE, sfi.szTypeName);
  555. ConditionallyDecodeUTF8(_GetUrlForPidl((LPCITEMIDLIST)phei), szDisplayUrl, ARRAYSIZE(szDisplayUrl));
  556. SetDlgItemText(hDlg, IDD_INTERNET_ADDRESS, szDisplayUrl);
  557. FileTimeToDateTimeStringInternal(&phei->ftLastVisited, szBuf, ARRAYSIZE(szBuf), FALSE);
  558. SetDlgItemText(hDlg, IDD_LAST_VISITED, szBuf);
  559. // It looks like the hitcount is double what it is supposed to be
  560. // (ie - navigate to a site and hitcount += 2)
  561. // For now, we'll just half the hitcount before we display it:
  562. // Above statement is no longer true -- hitcount is correct. Removed the halving of hitcount.
  563. wnsprintf(szBuf, ARRAYSIZE(szBuf), TEXT("%d"), (phei->dwNumHits)) ;
  564. SetDlgItemText(hDlg, IDD_NUMHITS, szBuf);
  565. break;
  566. }
  567. case WM_DESTROY:
  568. {
  569. HICON hIcon = (HICON)SendDlgItemMessage(hDlg, IDD_ITEMICON, STM_GETICON, 0, 0);
  570. if (hIcon)
  571. DestroyIcon(hIcon);
  572. }
  573. break;
  574. case WM_COMMAND:
  575. case WM_HELP:
  576. case WM_CONTEXTMENU:
  577. // user can't change anything, so we don't care about any messages
  578. break;
  579. default:
  580. return FALSE;
  581. } // end of switch
  582. return TRUE;
  583. }
  584. HRESULT CHistItem::_CreateFileDescriptorW(LPSTGMEDIUM pSTM)
  585. {
  586. pSTM->tymed = TYMED_HGLOBAL;
  587. pSTM->pUnkForRelease = NULL;
  588. FILEGROUPDESCRIPTORW *pfgd = (FILEGROUPDESCRIPTORW*)GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTORW) + (_cItems-1) * sizeof(FILEDESCRIPTORW));
  589. if (pfgd == NULL)
  590. {
  591. TraceMsg(DM_HSFOLDER, "hci - Couldn't alloc file descriptor");
  592. return E_OUTOFMEMORY;
  593. }
  594. pfgd->cItems = _cItems; // set the number of items
  595. for (UINT i = 0; i < _cItems; i++)
  596. {
  597. FILEDESCRIPTORW *pfd = &(pfgd->fgd[i]);
  598. _GetURLTitleForDisplay((LPBASEPIDL)_ppidl[i], pfd->cFileName, ARRAYSIZE(pfd->cFileName));
  599. MakeLegalFilenameW(pfd->cFileName);
  600. UINT cchFilename = lstrlenW(pfd->cFileName);
  601. SHTCharToUnicode(L".URL", pfd->cFileName+cchFilename, ARRAYSIZE(pfd->cFileName)-cchFilename);
  602. }
  603. pSTM->hGlobal = pfgd;
  604. return S_OK;
  605. }