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.

1673 lines
46 KiB

  1. #include "private.h"
  2. #include "subsmgrp.h"
  3. #include "offl_cpp.h"
  4. #include "helper.h"
  5. #include "propshts.h"
  6. #include "apithk.h"
  7. #include <mluisupp.h>
  8. #undef TF_THISMODULE
  9. #define TF_THISMODULE TF_WEBCHECKCORE
  10. extern HRESULT LoadSubscription(LPCTSTR url, LPMYPIDL *);
  11. extern TCHAR szInternetSettings[];
  12. extern void PropagateGeneralProp(HWND, POOEBuf);
  13. extern INT_PTR CALLBACK EnableScreenSaverDlgProc(HWND, UINT, WPARAM, LPARAM);
  14. extern HRESULT CreateSubscriptionFromOOEBuf(POOEBuf, LPMYPIDL *);
  15. extern BOOL CALLBACK _AddOnePropSheetPage(HPROPSHEETPAGE, LPARAM);
  16. extern TCHAR g_szDontAskScreenSaver[]; // from WIZARDS.CPP
  17. #define MAX_STR_LENGTH 200
  18. extern DWORD aHelpIDs[];
  19. extern TCHAR c_szHelpFile[];
  20. typedef struct
  21. {
  22. CSubscriptionMgr* pMgr;
  23. LPCWSTR pwszName;
  24. LPCWSTR pwszUrl;
  25. SUBSCRIPTIONINFO* pSubsInfo;
  26. SUBSCRIPTIONTYPE subsType;
  27. DWORD dwFlags;
  28. } SUBSCRIBE_ADI_INFO;
  29. static const TCHAR SUBSCRIBEADIPROP[] = TEXT("SADIP");
  30. INT_PTR CALLBACK SummarizeDesktopSubscriptionDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  31. ////////////////////////////////////////////////////////////////////////////////
  32. // Private imports from shdocvw (AddToFavorites API)
  33. //
  34. STDAPI SHAddSubscribeFavorite (HWND hwnd, LPCWSTR pwszURL, LPCWSTR pwszName, DWORD dwFlags,
  35. SUBSCRIPTIONTYPE subsType, SUBSCRIPTIONINFO* pInfo);
  36. ////////////////////////////////////////////////////////////////////////////////
  37. void UpdateSubsInfoFromOOE (SUBSCRIPTIONINFO* pInfo, POOEBuf pooe);
  38. HRESULT CreateBSTRFromTSTR(BSTR * pBstr, LPCTSTR sz)
  39. {
  40. int i = lstrlen(sz) + 1;
  41. *pBstr = SysAllocStringLen(NULL, i);
  42. if(NULL == *pBstr)
  43. return E_OUTOFMEMORY;
  44. MyStrToOleStrN(*pBstr, i, sz);
  45. return S_OK;
  46. }
  47. //////////////////////////////////////////////////////////////////////////
  48. //////////////////////////////////////////////////////////////////////////
  49. //
  50. // Subsctiption Manager
  51. //
  52. //////////////////////////////////////////////////////////////////////////
  53. //////////////////////////////////////////////////////////////////////////
  54. //
  55. // constructor / destructor
  56. //
  57. CSubscriptionMgr::CSubscriptionMgr(void)
  58. {
  59. ASSERT(NULL == _pidl);
  60. m_cRef = 1;
  61. m_eInitSrc = _INIT_FROM_URL; // Default.
  62. m_oldType = SUBSTYPE_URL; // Default.
  63. DllAddRef();
  64. }
  65. CSubscriptionMgr::~CSubscriptionMgr()
  66. {
  67. if (_pidl)
  68. {
  69. COfflineFolderEnum::FreePidl(_pidl);
  70. _pidl = NULL;
  71. }
  72. SAFELOCALFREE(m_pBuf);
  73. SAFERELEASE(m_pUIHelper);
  74. DllRelease();
  75. }
  76. //
  77. // IUnknown members
  78. //
  79. STDMETHODIMP CSubscriptionMgr::QueryInterface(REFIID riid, void ** ppv)
  80. {
  81. *ppv=NULL;
  82. // Validate requested interface
  83. if ((IID_IUnknown == riid) ||
  84. (IID_ISubscriptionMgr == riid) ||
  85. (IID_ISubscriptionMgr2 == riid))
  86. {
  87. *ppv=(ISubscriptionMgr2 *)this;
  88. }
  89. else if(IID_ISubscriptionMgrPriv == riid)
  90. {
  91. *ppv=(ISubscriptionMgrPriv *)this;
  92. }
  93. else if(IID_IShellExtInit == riid)
  94. {
  95. *ppv=(IShellExtInit *)this;
  96. }
  97. else if(IID_IShellPropSheetExt == riid)
  98. {
  99. *ppv=(IShellPropSheetExt *)this;
  100. }
  101. else
  102. {
  103. return E_NOINTERFACE;
  104. }
  105. ((LPUNKNOWN)*ppv)->AddRef();
  106. return S_OK;
  107. }
  108. STDMETHODIMP_(ULONG) CSubscriptionMgr::AddRef(void)
  109. {
  110. return ++m_cRef;
  111. }
  112. STDMETHODIMP_(ULONG) CSubscriptionMgr::Release(void)
  113. {
  114. if( 0L != --m_cRef )
  115. return m_cRef;
  116. delete this;
  117. return 0L;
  118. }
  119. HRESULT CSubscriptionMgr::RemovePages(HWND hDlg)
  120. {
  121. HRESULT hr;
  122. ASSERT(NULL != m_pUIHelper);
  123. if (NULL == m_pUIHelper)
  124. {
  125. return E_UNEXPECTED;
  126. }
  127. ISubscriptionAgentShellExt *psase;
  128. hr = m_pUIHelper->QueryInterface(IID_ISubscriptionAgentShellExt, (void **)&psase);
  129. if (SUCCEEDED(hr))
  130. {
  131. hr = psase->RemovePages(hDlg);
  132. psase->Release();
  133. }
  134. return hr;
  135. }
  136. HRESULT CSubscriptionMgr::SaveSubscription()
  137. {
  138. HRESULT hr;
  139. ASSERT(NULL != m_pUIHelper);
  140. if (NULL == m_pUIHelper)
  141. {
  142. return E_UNEXPECTED;
  143. }
  144. DWORD dwMaxCount = SHRestricted2W(REST_MaxSubscriptionCount, NULL, 0);
  145. DWORD dwCount;
  146. SUBSCRIPTIONTYPE subsType = (m_eInitSrc == _INIT_FROM_INTSHCUT) ?
  147. SUBSTYPE_URL :
  148. SUBSTYPE_CHANNEL;
  149. if ((dwMaxCount > 0) &&
  150. SUCCEEDED(CountSubscriptions(subsType, &dwCount)) &&
  151. (dwCount >= dwMaxCount))
  152. {
  153. SGMessageBox(GetForegroundWindow(), IDS_RESTRICTED, MB_OK);
  154. return E_ACCESSDENIED;
  155. }
  156. ISubscriptionAgentShellExt *psase;
  157. hr = m_pUIHelper->QueryInterface(IID_ISubscriptionAgentShellExt, (void **)&psase);
  158. if (SUCCEEDED(hr))
  159. {
  160. hr = psase->SaveSubscription();
  161. psase->Release();
  162. }
  163. return hr;
  164. }
  165. HRESULT CSubscriptionMgr::URLChange(LPCWSTR pwszNewURL)
  166. {
  167. return E_NOTIMPL;
  168. }
  169. HRESULT GetInfoFromDataObject(IDataObject *pido,
  170. TCHAR *pszPath, DWORD cchPath,
  171. TCHAR *pszFriendlyName, DWORD cchFriendlyName,
  172. TCHAR *pszURL, DWORD cchURL,
  173. INIT_SRC_ENUM *peInitSrc)
  174. {
  175. STGMEDIUM stgmed;
  176. FORMATETC fmtetc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
  177. HRESULT hr = pido->GetData(&fmtetc, &stgmed);
  178. if (hr == S_OK)
  179. {
  180. TCHAR szTempURL[INTERNET_MAX_URL_LENGTH];
  181. TCHAR *pszSection;
  182. TCHAR *pszEntry;
  183. TCHAR szTempPath[MAX_PATH];
  184. TCHAR szIniPath[MAX_PATH];
  185. if (DragQueryFile((HDROP)stgmed.hGlobal, 0, szTempPath, ARRAYSIZE(szTempPath)))
  186. {
  187. // save path
  188. if (NULL != pszPath)
  189. {
  190. StrCpyN(pszPath, szTempPath, cchPath);
  191. }
  192. StrCpyN(szIniPath, szTempPath, ARRAYSIZE(szIniPath));
  193. // make friendly name from path
  194. if (NULL != pszFriendlyName)
  195. {
  196. PathStripPath(szTempPath);
  197. PathRemoveExtension(szTempPath);
  198. StrCpyN(pszFriendlyName, szTempPath, cchFriendlyName);
  199. }
  200. if ((NULL != pszURL) || (NULL != peInitSrc))
  201. {
  202. if (PathIsDirectory(szIniPath))
  203. {
  204. PathAppend(szIniPath, TEXT("desktop.ini"));
  205. pszSection = TEXT("Channel");
  206. pszEntry = TEXT("CDFURL");
  207. if (NULL != peInitSrc)
  208. *peInitSrc = _INIT_FROM_CHANNEL;
  209. }
  210. else
  211. {
  212. pszSection = TEXT("InternetShortcut");
  213. pszEntry = TEXT("URL");
  214. if (NULL != peInitSrc)
  215. *peInitSrc = _INIT_FROM_INTSHCUT;
  216. }
  217. if (NULL != pszURL)
  218. {
  219. // canonicalize url
  220. if (SHGetIniString(pszSection, pszEntry,
  221. szTempURL,
  222. INTERNET_MAX_URL_LENGTH,
  223. szIniPath))
  224. {
  225. if(!InternetCanonicalizeUrl(szTempURL, pszURL, &cchURL, ICU_NO_ENCODE))
  226. {
  227. // failed - use non-canonical version
  228. StrCpyN(pszURL, szTempURL, cchURL);
  229. }
  230. }
  231. else
  232. {
  233. hr = E_FAIL;
  234. }
  235. }
  236. }
  237. }
  238. else
  239. {
  240. hr = E_FAIL;
  241. }
  242. ReleaseStgMedium(&stgmed);
  243. }
  244. return hr;
  245. }
  246. //
  247. // IShellExtInit / IShellPropSheetExt members
  248. //
  249. STDMETHODIMP CSubscriptionMgr::Initialize(LPCITEMIDLIST pcidlFolder, IDataObject * pido, HKEY hkeyProgID)
  250. {
  251. HRESULT hr;
  252. ISubscriptionItem *psi;
  253. CLSID clsid;
  254. SUBSCRIPTIONCOOKIE cookie;
  255. hr = GetInfoFromDataObject(pido, m_pszPath, ARRAYSIZE(m_pszPath),
  256. m_pszFriendly, ARRAYSIZE(m_pszFriendly),
  257. m_pszURL, ARRAYSIZE(m_pszURL),
  258. &m_eInitSrc);
  259. if (SUCCEEDED(hr))
  260. {
  261. hr = DoGetItemFromURL(m_pszURL, &psi);
  262. if (SUCCEEDED(hr))
  263. {
  264. SUBSCRIPTIONITEMINFO sii;
  265. sii.cbSize = sizeof(SUBSCRIPTIONITEMINFO);
  266. hr = psi->GetSubscriptionItemInfo(&sii);
  267. if (SUCCEEDED(hr))
  268. {
  269. clsid = sii.clsidAgent;
  270. }
  271. psi->GetCookie(&cookie);
  272. psi->Release();
  273. }
  274. if (FAILED(hr))
  275. {
  276. // New subscription
  277. hr = S_OK;
  278. CreateCookie(&cookie);
  279. switch (m_eInitSrc)
  280. {
  281. case _INIT_FROM_INTSHCUT:
  282. clsid = CLSID_WebCrawlerAgent;
  283. break;
  284. case _INIT_FROM_CHANNEL:
  285. clsid = CLSID_ChannelAgent;
  286. break;
  287. default:
  288. hr = E_FAIL;
  289. break;
  290. }
  291. }
  292. if (SUCCEEDED(hr))
  293. {
  294. // HACKHACK:
  295. // We call coinit and uninit and keep an object pointer around.
  296. // This ain't cool but will work as long as the agents are in
  297. // webcheck. Need to fix this for multi-cast handler.
  298. hr = CoInitialize(NULL);
  299. if (SUCCEEDED(hr))
  300. {
  301. hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER,
  302. IID_IUnknown, (void**)&m_pUIHelper);
  303. if (SUCCEEDED(hr))
  304. {
  305. ISubscriptionAgentShellExt *psase;
  306. hr = m_pUIHelper->QueryInterface(IID_ISubscriptionAgentShellExt, (void **)&psase);
  307. if (SUCCEEDED(hr))
  308. {
  309. WCHAR wszURL[ARRAYSIZE(m_pszURL)];
  310. WCHAR wszName[MAX_NAME + 1];
  311. MyStrToOleStrN(wszURL, ARRAYSIZE(wszURL), m_pszURL);
  312. MyStrToOleStrN(wszName, ARRAYSIZE(wszName), m_pszFriendly);
  313. hr = psase->Initialize(&cookie, wszURL, wszName,
  314. (clsid == CLSID_ChannelAgent) ?
  315. SUBSTYPE_CHANNEL : SUBSTYPE_URL);
  316. psase->Release();
  317. }
  318. }
  319. CoUninitialize();
  320. }
  321. }
  322. }
  323. return hr;
  324. }
  325. STDMETHODIMP CSubscriptionMgr::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
  326. {
  327. HRESULT hr;
  328. if (SHRestricted2W(REST_NoEditingSubscriptions, NULL, 0))
  329. return E_FAIL;
  330. ASSERT(NULL != m_pUIHelper);
  331. if (NULL == m_pUIHelper)
  332. {
  333. return E_UNEXPECTED;
  334. }
  335. IShellPropSheetExt *pspse;
  336. hr = m_pUIHelper->QueryInterface(IID_IShellPropSheetExt, (void **)&pspse);
  337. if (SUCCEEDED(hr))
  338. {
  339. hr = pspse->AddPages(lpfnAddPage, lParam);
  340. pspse->Release();
  341. }
  342. return hr;
  343. }
  344. STDMETHODIMP CSubscriptionMgr::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE lpfnReplacePage, LPARAM lParam)
  345. {
  346. return E_NOTIMPL;
  347. }
  348. //////////////////////////////////////////////////////////////////////////
  349. //////////////////////////////////////////////////////////////////////////
  350. //
  351. // ISubscriptionMgr members
  352. //
  353. STDMETHODIMP CSubscriptionMgr::IsSubscribed(LPCWSTR pURL, BOOL * pFSub)
  354. {
  355. HRESULT hr;
  356. ASSERT (pURL && pFSub);
  357. MyOleStrToStrN(m_pszURL, INTERNET_MAX_URL_LENGTH, pURL);
  358. * pFSub = FALSE;
  359. if (!_pidl)
  360. {
  361. hr = LoadSubscription(m_pszURL, &_pidl);
  362. if ((hr != S_OK) || (!_pidl))
  363. return S_OK;
  364. }
  365. else if (UrlCompare(URL(&(_pidl->ooe)), m_pszURL, TRUE))
  366. {
  367. COfflineFolderEnum::FreePidl(_pidl);
  368. _pidl = NULL;
  369. hr = LoadSubscription(m_pszURL, &_pidl);
  370. if ((hr != S_OK) || (!_pidl))
  371. return S_OK;
  372. }
  373. * pFSub = TRUE;
  374. return S_OK;
  375. }
  376. STDMETHODIMP CSubscriptionMgr::DeleteSubscription(LPCWSTR pURL, HWND hwnd)
  377. {
  378. ASSERT(pURL);
  379. MyOleStrToStrN(m_pszURL, INTERNET_MAX_URL_LENGTH, pURL);
  380. if (!_pidl)
  381. {
  382. HRESULT hr;
  383. hr = LoadSubscription(m_pszURL, &_pidl);
  384. if ((hr != S_OK) || (!_pidl))
  385. return E_FAIL;
  386. }
  387. // This is a restricted action. The restriction
  388. // is checked in ConfirmDelete. If you remove this call,
  389. // you must add the restriction check here.
  390. if (!ConfirmDelete(hwnd, 1, &_pidl))
  391. return E_FAIL;
  392. HRESULT hr = DoDeleteSubscription(&(_pidl->ooe));
  393. if (SUCCEEDED(hr))
  394. {
  395. TraceMsg(TF_ALWAYS, "%s(URL:%s) deleted", NAME(&(_pidl->ooe)), URL(&(_pidl->ooe)));
  396. _GenerateEvent(SHCNE_DELETE, (LPITEMIDLIST)_pidl, NULL);
  397. COfflineFolderEnum::FreePidl(_pidl);
  398. _pidl = NULL;
  399. }
  400. return hr;
  401. }
  402. STDMETHODIMP CSubscriptionMgr::ShowSubscriptionProperties(LPCWSTR pURL, HWND hwnd)
  403. {
  404. HRESULT hr = S_OK;
  405. LPMYPIDL oldPidl = NULL, newPidl = NULL;
  406. ASSERT(pURL);
  407. MyOleStrToStrN(m_pszURL, INTERNET_MAX_URL_LENGTH, pURL);
  408. if (!m_pBuf)
  409. {
  410. m_pBuf = (OOEBuf *)MemAlloc(LPTR, sizeof(OOEBuf));
  411. if (NULL == m_pBuf)
  412. {
  413. hr = E_OUTOFMEMORY;
  414. }
  415. }
  416. if (SUCCEEDED(hr))
  417. {
  418. GetDefaultOOEBuf(m_pBuf, SUBSTYPE_URL);
  419. if(SUCCEEDED(LoadSubscription(m_pszURL, &oldPidl)))
  420. {
  421. POOEntry pooe = &(oldPidl->ooe);
  422. StrCpyN(m_pszFriendly, NAME(&(oldPidl->ooe)), ARRAYSIZE(m_pszFriendly));
  423. CopyToOOEBuf(&(oldPidl->ooe), m_pBuf);
  424. m_pBuf->m_dwPropSheetFlags = PSF_IS_ALREADY_SUBSCRIBED;
  425. }
  426. else
  427. {
  428. CreateCookie(&m_pBuf->m_Cookie);
  429. StrCpyN(m_pszFriendly, m_pszURL, ARRAYSIZE(m_pszFriendly));
  430. StrCpyN(m_pBuf->m_URL, m_pszURL, ARRAYSIZE(m_pBuf->m_URL));
  431. StrCpyN(m_pBuf->m_Name, m_pszURL, ARRAYSIZE(m_pBuf->m_Name));
  432. }
  433. hr = CoCreateInstance(*(&m_pBuf->clsidDest), NULL, CLSCTX_INPROC_SERVER,
  434. IID_IUnknown, (void **)&m_pUIHelper);
  435. if (SUCCEEDED(hr))
  436. {
  437. ISubscriptionAgentShellExt *psase;
  438. hr = m_pUIHelper->QueryInterface(IID_ISubscriptionAgentShellExt, (void **)&psase);
  439. if (SUCCEEDED(hr))
  440. {
  441. WCHAR wszURL[MAX_URL + 1];
  442. WCHAR wszName[MAX_NAME + 1];
  443. MyStrToOleStrN(wszURL, ARRAYSIZE(wszURL), m_pBuf->m_URL);
  444. MyStrToOleStrN(wszName, ARRAYSIZE(wszName), m_pBuf->m_Name);
  445. hr = psase->Initialize(&m_pBuf->m_Cookie, wszURL, wszName, (SUBSCRIPTIONTYPE)-1);
  446. psase->Release();
  447. }
  448. if (SUCCEEDED(hr))
  449. {
  450. PROPSHEETHEADER psh = { 0 } ;
  451. HPROPSHEETPAGE hPropPage[MAX_PROP_PAGES];
  452. // initialize propsheet header.
  453. psh.dwSize = sizeof(PROPSHEETHEADER);
  454. psh.dwFlags = PSH_PROPTITLE;
  455. psh.hwndParent = hwnd;
  456. psh.pszCaption = m_pszFriendly;
  457. psh.hInstance = g_hInst;
  458. psh.nPages = 0;
  459. psh.nStartPage = 0;
  460. psh.phpage = hPropPage;
  461. PROPSHEETPAGE psp;
  462. psp.dwSize = sizeof(PROPSHEETPAGE);
  463. psp.dwFlags = PSP_DEFAULT;
  464. psp.hInstance = MLGetHinst();
  465. psp.pszIcon = NULL;
  466. psp.pszTitle = NULL;
  467. psp.lParam = (LPARAM)this;
  468. psp.pszTemplate = MAKEINTRESOURCE(IDD_SUBSPROPS_SUMMARY);
  469. psp.pfnDlgProc = SummaryPropDlgProc;
  470. psh.phpage[psh.nPages++] = Whistler_CreatePropertySheetPageW(&psp);
  471. if (NULL != hPropPage[0])
  472. {
  473. if (m_pBuf->m_dwPropSheetFlags & PSF_IS_ALREADY_SUBSCRIBED)
  474. {
  475. hr = AddPages(_AddOnePropSheetPage, (LPARAM)&psh);
  476. }
  477. if (SUCCEEDED(hr))
  478. {
  479. INT_PTR iRet = PropertySheet(&psh);
  480. if (iRet < 0)
  481. {
  482. hr = E_FAIL;
  483. }
  484. else
  485. {
  486. hr = LoadSubscription(m_pszURL, &newPidl);
  487. if (SUCCEEDED(hr))
  488. {
  489. if (_pidl)
  490. {
  491. COfflineFolderEnum::FreePidl(_pidl);
  492. }
  493. _pidl = newPidl;
  494. }
  495. }
  496. }
  497. }
  498. }
  499. }
  500. if (NULL != oldPidl)
  501. {
  502. COfflineFolderEnum::FreePidl(oldPidl);
  503. }
  504. }
  505. return hr;
  506. }
  507. //
  508. //
  509. //
  510. void
  511. CSubscriptionMgr::ChangeSubscriptionValues (
  512. OOEBuf *pCurrent,
  513. SUBSCRIPTIONINFO *pNew
  514. )
  515. {
  516. //
  517. // Channel flags
  518. //
  519. if (SUBSINFO_CHANNELFLAGS & pNew->fUpdateFlags)
  520. {
  521. pCurrent->fChannelFlags = pNew->fChannelFlags;
  522. }
  523. //
  524. // The subscription schedule.
  525. //
  526. if (SUBSINFO_SCHEDULE & pNew->fUpdateFlags)
  527. {
  528. switch (pNew->schedule)
  529. {
  530. case SUBSSCHED_DAILY:
  531. case SUBSSCHED_MANUAL:
  532. case SUBSSCHED_WEEKLY:
  533. LoadGroupCookie(&pCurrent->groupCookie, pNew->schedule);
  534. break;
  535. case SUBSSCHED_CUSTOM:
  536. pCurrent->groupCookie = pNew->customGroupCookie;
  537. break;
  538. case SUBSSCHED_AUTO:
  539. {
  540. // FEATURE. We should look at subType;
  541. memset(&pCurrent->groupCookie, 0, sizeof(pCurrent->groupCookie)); //t-mattgi so it will look at the trigger
  542. PTASK_TRIGGER pNewTrigger = ((PTASK_TRIGGER)pNew->pTrigger);
  543. if (pNewTrigger && pNewTrigger->cbTriggerSize == sizeof(TASK_TRIGGER))
  544. {
  545. pCurrent->m_Trigger = *pNewTrigger;
  546. }
  547. else //bad trigger; use daily as default
  548. {
  549. pCurrent->m_Trigger.cbTriggerSize = 0;
  550. pCurrent->groupCookie = NOTFCOOKIE_SCHEDULE_GROUP_DAILY;
  551. }
  552. }
  553. pCurrent->fChannelFlags |= CHANNEL_AGENT_DYNAMIC_SCHEDULE;
  554. break;
  555. default:
  556. ASSERT(FALSE);
  557. break;
  558. }
  559. }
  560. //
  561. // Recurse levels.
  562. //
  563. if (SUBSINFO_RECURSE & pNew->fUpdateFlags)
  564. pCurrent->m_RecurseLevels = pNew->dwRecurseLevels;
  565. //
  566. // Webcrawler flags. Note: The flags are not or'd with the current flags.
  567. // The caller must set all of the webcrawler flags they want to use.
  568. //
  569. if (SUBSINFO_WEBCRAWL & pNew->fUpdateFlags)
  570. pCurrent->m_RecurseFlags = pNew->fWebcrawlerFlags;
  571. //
  572. // Mail notification.
  573. //
  574. if (SUBSINFO_MAILNOT & pNew->fUpdateFlags)
  575. pCurrent->bMail = pNew->bMailNotification;
  576. else
  577. pCurrent->bMail = FALSE;
  578. //
  579. // Need password.
  580. //
  581. if (SUBSINFO_NEEDPASSWORD & pNew->fUpdateFlags)
  582. pCurrent->bNeedPassword = pNew->bNeedPassword;
  583. else
  584. pCurrent->bNeedPassword = FALSE;
  585. //
  586. // User name.
  587. //
  588. if (SUBSINFO_USER & pNew->fUpdateFlags)
  589. {
  590. if (pNew->bstrUserName)
  591. {
  592. MyOleStrToStrN(pCurrent->username, MAX_USERNAME, pNew->bstrUserName);
  593. }
  594. pCurrent->bNeedPassword = pNew->bNeedPassword;
  595. }
  596. //
  597. // Password.
  598. //
  599. if (SUBSINFO_PASSWORD & pNew->fUpdateFlags)
  600. {
  601. if (pNew->bstrPassword)
  602. {
  603. MyOleStrToStrN(pCurrent->password, MAX_PASSWORD, pNew->bstrPassword);
  604. }
  605. pCurrent->bNeedPassword = pNew->bNeedPassword;
  606. }
  607. //
  608. // Friendly Name.
  609. //
  610. if (SUBSINFO_FRIENDLYNAME & pNew->fUpdateFlags)
  611. {
  612. if (pNew->bstrFriendlyName)
  613. {
  614. MyOleStrToStrN(pCurrent->m_Name, MAX_NAME, pNew->bstrFriendlyName);
  615. }
  616. }
  617. //
  618. // Gleam
  619. //
  620. if (SUBSINFO_GLEAM & pNew->fUpdateFlags)
  621. {
  622. pCurrent->bGleam = pNew->bGleam;
  623. }
  624. //
  625. // Changes only (notification only)
  626. //
  627. if (SUBSINFO_CHANGESONLY & pNew->fUpdateFlags)
  628. {
  629. pCurrent->bChangesOnly = pNew->bChangesOnly;
  630. }
  631. //
  632. // dwMaxSizeKB
  633. //
  634. if (SUBSINFO_MAXSIZEKB & pNew->fUpdateFlags)
  635. {
  636. pCurrent->m_SizeLimit = pNew->dwMaxSizeKB;
  637. }
  638. //
  639. // Task flags
  640. //
  641. if (SUBSINFO_TASKFLAGS & pNew->fUpdateFlags)
  642. {
  643. pCurrent->grfTaskTrigger = pNew->fTaskFlags;
  644. }
  645. return;
  646. }
  647. //
  648. // CSubscriptionMgr::CountSubscriptions
  649. // FEATURE: We could make this public if other people need it. An enumerator
  650. // would be more useful though...
  651. //
  652. HRESULT CSubscriptionMgr::CountSubscriptions(SUBSCRIPTIONTYPE subType, PDWORD pdwCount)
  653. {
  654. HRESULT hr;
  655. IEnumSubscription *pes;
  656. ASSERT(NULL != pdwCount);
  657. *pdwCount = 0;
  658. hr = EnumSubscriptions(0, &pes);
  659. if (SUCCEEDED(hr))
  660. {
  661. SUBSCRIPTIONCOOKIE cookie;
  662. while (S_OK == pes->Next(1, &cookie, NULL))
  663. {
  664. ISubscriptionItem *psi;
  665. DWORD dwRet;
  666. if (SUCCEEDED(SubscriptionItemFromCookie(FALSE, &cookie, &psi)))
  667. {
  668. if (SUCCEEDED(ReadDWORD(psi, c_szPropChannel, &dwRet)) && dwRet)
  669. {
  670. if (SUBSTYPE_CHANNEL == subType)
  671. (*pdwCount)++;
  672. }
  673. else if (SUCCEEDED(ReadDWORD(psi, c_szPropDesktopComponent, &dwRet)) && dwRet)
  674. {
  675. if (SUBSTYPE_DESKTOPURL == subType || SUBSTYPE_DESKTOPCHANNEL == subType)
  676. (*pdwCount)++;
  677. }
  678. else
  679. {
  680. if (SUBSTYPE_URL == subType)
  681. (*pdwCount)++;
  682. }
  683. psi->Release();
  684. }
  685. }
  686. }
  687. return hr;
  688. }
  689. //
  690. // CSubscriptionMgr::IsValidSubscriptionInfo
  691. //
  692. #define SUBSCRIPTIONSCHEDULE_MAX 4
  693. BOOL CSubscriptionMgr::IsValidSubscriptionInfo(SUBSCRIPTIONTYPE subType, SUBSCRIPTIONINFO *pSI)
  694. {
  695. if (pSI->cbSize != sizeof(SUBSCRIPTIONINFO))
  696. {
  697. return FALSE;
  698. }
  699. else if (pSI->fUpdateFlags & ~SUBSINFO_ALLFLAGS)
  700. {
  701. return FALSE;
  702. }
  703. else if (pSI->pTrigger && ((TASK_TRIGGER*)(pSI->pTrigger))->cbTriggerSize &&
  704. (subType == SUBSTYPE_URL || subType == SUBSTYPE_DESKTOPURL)) // || pSI->schedule != SUBSSCHED_AUTO))
  705. {
  706. return FALSE;
  707. }
  708. else if (pSI->fUpdateFlags & SUBSINFO_SCHEDULE)
  709. {
  710. if (pSI->schedule > SUBSCRIPTIONSCHEDULE_MAX)
  711. {
  712. return FALSE;
  713. }
  714. if (pSI->schedule == SUBSSCHED_CUSTOM && pSI->customGroupCookie == CLSID_NULL)
  715. {
  716. return FALSE;
  717. }
  718. }
  719. return TRUE;
  720. }
  721. ////////////////////////////////////////////////////////////////////////////////
  722. //
  723. // *** RemoveURLMapping ***
  724. //
  725. // Description:
  726. // Removes the cache and registry settings that wininet uses to map the
  727. // given url to a local file.
  728. //
  729. ////////////////////////////////////////////////////////////////////////////////
  730. #define PRELOAD_REG_KEY \
  731. TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Cache\\Preload")
  732. void RemoveURLMapping(LPCWSTR pszURL)
  733. {
  734. BYTE cei[MY_MAX_CACHE_ENTRY_INFO];
  735. DWORD cbcei = sizeof(cei);
  736. LPINTERNET_CACHE_ENTRY_INFOW pcei = (LPINTERNET_CACHE_ENTRY_INFOW)cei;
  737. //
  738. // Look up the url in the cache
  739. //
  740. if (GetUrlCacheEntryInfoExW(pszURL, pcei, &cbcei, NULL, 0, NULL, 0))
  741. {
  742. //
  743. // see if it has a mapping because it is a preinstalled cache entry
  744. //
  745. if (pcei->CacheEntryType & INSTALLED_CACHE_ENTRY)
  746. {
  747. //
  748. // Clear the flag
  749. //
  750. pcei->CacheEntryType &= ~INSTALLED_CACHE_ENTRY;
  751. SetUrlCacheEntryInfoW(pszURL, pcei, CACHE_ENTRY_ATTRIBUTE_FC);
  752. //
  753. // Now remove the mapping from the registry
  754. //
  755. HKEY hk;
  756. if (RegOpenKeyEx(HKEY_CURRENT_USER, PRELOAD_REG_KEY, 0, KEY_WRITE, &hk) == ERROR_SUCCESS)
  757. {
  758. RegDeleteValueW(hk, pszURL);
  759. RegCloseKey(hk);
  760. }
  761. }
  762. }
  763. }
  764. //
  765. // CSubscriptionMgr::CreateSubscription
  766. // entry point for creating a subscription
  767. // flags:
  768. // CREATESUBS_FROMFAVORITES -- already exists in favorites, use alternate summary dialog
  769. // that doesn't do AddToFavorites. Valid only for channel or url.
  770. // CREATESUBS_INACTIVEPLATINUM -- when creating a channel subscription, show Activate Channel dialog
  771. // valid only for channel subscriptions with CREATESUBS_FROMFAVORITES
  772. // CREATESUBS_ADDTOFAVORITES -- display summary dialog before wizard
  773. // default summary: for channel or url, use AddToFavorites from shdocvw
  774. // for desktop item, just a confirmation dialog
  775. // for other, no summary -- straight to wizard
  776. // CREATESUBS_NOUI -- totally silent
  777. // CREATESUBS_NOSAVE -- update subscription in memory buffer, not on disk (pInfo must be non-NULL)
  778. //
  779. STDMETHODIMP
  780. CSubscriptionMgr::CreateSubscription (
  781. HWND hwnd,
  782. LPCWSTR pwszURL,
  783. LPCWSTR pwszFriendlyName,
  784. DWORD dwFlags,
  785. SUBSCRIPTIONTYPE subsType,
  786. SUBSCRIPTIONINFO *pInfo
  787. )
  788. {
  789. HRESULT hr = E_INVALIDARG;
  790. BOOL bAlready;
  791. if (IsFlagSet(dwFlags, CREATESUBS_NOUI) || !IsFlagSet (dwFlags, CREATESUBS_ADDTOFAVORITES))
  792. { //no UI, so skip ATF dialog
  793. hr = CreateSubscriptionNoSummary (hwnd, pwszURL, pwszFriendlyName, dwFlags,
  794. subsType, pInfo);
  795. if (hr == S_OK)
  796. {
  797. //
  798. // The user successfully subscribed to this URL so remove
  799. // mappings used for preinstalled content as this URL is now
  800. // "Activated"
  801. //
  802. RemoveURLMapping(pwszURL);
  803. }
  804. }
  805. else
  806. {
  807. switch (subsType)
  808. {
  809. case SUBSTYPE_URL:
  810. case SUBSTYPE_CHANNEL:
  811. hr = SHAddSubscribeFavorite (hwnd, pwszURL, pwszFriendlyName,
  812. dwFlags, subsType, pInfo);
  813. break;
  814. case SUBSTYPE_DESKTOPCHANNEL:
  815. case SUBSTYPE_DESKTOPURL:
  816. hr = IsSubscribed (pwszURL, &bAlready);
  817. if (SUCCEEDED (hr) && bAlready)
  818. break; //don't display summary dialog since it has nothing useful for this case
  819. hr = CreateDesktopSubscription (hwnd, pwszURL, pwszFriendlyName,
  820. dwFlags, subsType, pInfo);
  821. break;
  822. default: //SUBSTYPE_EXTERNAL -- don't know what kind of summary to show
  823. hr = CreateSubscriptionNoSummary (hwnd, pwszURL, pwszFriendlyName, dwFlags,
  824. subsType, pInfo);
  825. break;
  826. }
  827. }
  828. return hr;
  829. }
  830. //
  831. // CSubscriptionMgr::CreateSubscriptionNoSummary
  832. // modify a SUBSCRIPTIONINFO interactively, using the wizard
  833. // persists info to Subscriptions folder, unless SUBSINFO_NOSAVE passed
  834. //
  835. STDMETHODIMP
  836. CSubscriptionMgr::CreateSubscriptionNoSummary (
  837. HWND hwnd,
  838. LPCWSTR pwszURL,
  839. LPCWSTR pwszFriendlyName,
  840. DWORD dwFlags,
  841. SUBSCRIPTIONTYPE subType,
  842. SUBSCRIPTIONINFO *pInfo
  843. )
  844. {
  845. HRESULT hr = S_OK;
  846. //
  847. // Validate the parameters.
  848. //
  849. if (!IS_VALID_SUBSCRIPTIONTYPE(subType)
  850. || !pwszURL
  851. || !pwszFriendlyName
  852. || (!pInfo && (dwFlags & CREATESUBS_NOSAVE))
  853. || (pInfo && !IsValidSubscriptionInfo(subType, pInfo)))
  854. {
  855. ASSERT(FALSE);
  856. return E_INVALIDARG;
  857. }
  858. //
  859. // Fail if already subscribed and we aren't in no save or no UI mode.
  860. // Caller is responsible for UI.
  861. //
  862. BOOL fAlreadySubscribed;
  863. if ((FAILED(IsSubscribed(pwszURL, &fAlreadySubscribed)) || fAlreadySubscribed) &&
  864. (!(dwFlags & (CREATESUBS_NOSAVE | CREATESUBS_NOUI))))
  865. {
  866. return E_FAIL;
  867. }
  868. //
  869. // Fail if restrictions are in place.
  870. // FEATURE: Currently cdfview is handling channel restrictions for
  871. // but we should probably do it here.
  872. // Should we have a flag parameter to override this?
  873. //
  874. if (SUBSTYPE_URL == subType)
  875. {
  876. DWORD dwMaxCount = SHRestricted2W(REST_MaxSubscriptionCount, NULL, 0);
  877. DWORD dwCount;
  878. if (SHRestricted2W(REST_NoAddingSubscriptions, pwszURL, 0)
  879. || ((dwMaxCount > 0)
  880. && SUCCEEDED(CountSubscriptions(subType, &dwCount))
  881. && (dwCount >= dwMaxCount)))
  882. {
  883. if (!IsFlagSet(dwFlags, CREATESUBS_NOUI))
  884. SGMessageBox(hwnd, IDS_RESTRICTED, MB_OK);
  885. return E_ACCESSDENIED;
  886. }
  887. }
  888. //
  889. // Get the subscription defaults and merge in the caller's info
  890. //
  891. OOEBuf subProps;
  892. GetDefaultOOEBuf(&subProps, subType);
  893. //this is (intentionally) duplicated below... it needs to be after the ChangeSubscriptionValues()
  894. //call, but we need to grab the url first to make sure it's subscribable.
  895. MyOleStrToStrN(subProps.m_URL, INTERNET_MAX_URL_LENGTH, pwszURL);
  896. // Does this mean we can't support plugin protocols?
  897. if (/*(subType != SUBSTYPE_EXTERNAL) &&*/ !IsHTTPPrefixed(subProps.m_URL))
  898. {
  899. return E_INVALIDARG;
  900. }
  901. if (pInfo)
  902. {
  903. ChangeSubscriptionValues(&subProps, pInfo);
  904. if (fAlreadySubscribed)
  905. {
  906. ReadCookieFromInetDB(subProps.m_URL, &subProps.m_Cookie);
  907. subProps.m_dwPropSheetFlags |= PSF_IS_ALREADY_SUBSCRIBED;
  908. }
  909. }
  910. // Disallow password caching if restriction is in place. This both
  911. // skips the wizard page and prevents the caller's password from
  912. // being saved.
  913. if (SHRestricted2W(REST_NoSubscriptionPasswords, NULL, 0))
  914. {
  915. subProps.bNeedPassword = FALSE;
  916. subProps.username[0] = 0;
  917. subProps.password[0] = 0;
  918. subProps.dwFlags &= ~(PROP_WEBCRAWL_UNAME | PROP_WEBCRAWL_PSWD);
  919. }
  920. //the passed-in name and url override whatever's in the info buffer
  921. MyOleStrToStrN(subProps.m_URL, INTERNET_MAX_URL_LENGTH, pwszURL);
  922. MyOleStrToStrN(subProps.m_Name, MAX_NAME_QUICKLINK, pwszFriendlyName);
  923. //
  924. // If we're in UI mode, initialize the wizard
  925. //
  926. if (!IsFlagSet(dwFlags, CREATESUBS_NOUI))
  927. {
  928. hr = CreateWizard(hwnd, subType, &subProps);
  929. } // !NOUI
  930. //
  931. // If we're not in NOSAVE mode, then create/save the subscription
  932. //
  933. if (SUCCEEDED(hr))
  934. {
  935. if (!IsFlagSet(dwFlags, CREATESUBS_NOSAVE))
  936. {
  937. //hack to let AddToFavorites dialog display the screen-saver-activate dialog -- it
  938. //needs to pass NOUI, which disables all UI, but if you also pass FROMFAVORITES and not
  939. //ADDTOFAVORITES then we still let this dialog slip through. (Shouldn't affect anyone
  940. //else because FROMFAVORITES is always used with ADDTOFAVORITES.)
  941. if (!IsFlagSet(dwFlags, CREATESUBS_NOUI) ||
  942. (IsFlagSet(dwFlags, CREATESUBS_FROMFAVORITES) && !IsFlagSet (dwFlags, CREATESUBS_ADDTOFAVORITES)))
  943. {
  944. // See if the user wants to be asked about enabling the screen saver.
  945. DWORD dwValue = BST_UNCHECKED;
  946. ReadRegValue( HKEY_CURRENT_USER,
  947. WEBCHECK_REGKEY,
  948. g_szDontAskScreenSaver,
  949. &dwValue,
  950. SIZEOF(dwValue));
  951. if (
  952. (subProps.fChannelFlags & CHANNEL_AGENT_PRECACHE_SCRNSAVER)
  953. &&
  954. (dwValue == BST_UNCHECKED)
  955. &&
  956. !IsADScreenSaverActive()
  957. )
  958. {
  959. DialogBoxParam( MLGetHinst(),
  960. MAKEINTRESOURCE(IDD_SUBSCRIPTION_ENABLECHANNELSAVER),
  961. hwnd,
  962. EnableScreenSaverDlgProc,
  963. 0L);
  964. }
  965. }
  966. //
  967. // Create a new pidl with the user specified properties.
  968. //
  969. if (_pidl)
  970. {
  971. COfflineFolderEnum::FreePidl(_pidl);
  972. _pidl = NULL;
  973. SAFERELEASE(m_pUIHelper);
  974. }
  975. hr = CreateSubscriptionFromOOEBuf(&subProps, &_pidl);
  976. if (SUCCEEDED(hr))
  977. {
  978. ASSERT(_pidl);
  979. //
  980. // Send a notification that a subscription has changed.
  981. //
  982. _GenerateEvent(SHCNE_CREATE, (LPITEMIDLIST)_pidl, NULL);
  983. }
  984. } //!NOSAVE
  985. else if (S_OK == hr)
  986. {
  987. //in NOSAVE mode, so don't actually create subscription -- save it back
  988. //to passed-in buffer
  989. ASSERT (pInfo);
  990. pInfo->fUpdateFlags = SUBSINFO_ALLFLAGS; //fill in all possible fields
  991. UpdateSubsInfoFromOOE (pInfo, &subProps);
  992. }
  993. }
  994. return hr;
  995. }
  996. STDMETHODIMP
  997. CSubscriptionMgr::CreateDesktopSubscription (HWND hwnd, LPCWSTR pwszURL, LPCWSTR pwszFriendlyName,
  998. DWORD dwFlags, SUBSCRIPTIONTYPE subsType, SUBSCRIPTIONINFO *pInfo)
  999. {
  1000. HRESULT hr;
  1001. SUBSCRIPTIONINFO siTemp = { sizeof(SUBSCRIPTIONINFO), 0 };
  1002. if (!pInfo)
  1003. pInfo = &siTemp; //make sure we have a valid buffer if caller doesn't give us one
  1004. //make sure adminrestrictions allow this
  1005. if (SHRestricted2W(REST_NoAddingChannels, pwszURL, 0))
  1006. return E_FAIL;
  1007. SUBSCRIBE_ADI_INFO parms = { this, pwszFriendlyName, pwszURL, pInfo, subsType, dwFlags };
  1008. //make sure this url is subscribable; if not, show error dialog
  1009. {
  1010. TCHAR sz[MAX_URL];
  1011. MyOleStrToStrN (sz, ARRAYSIZE(sz), pwszURL);
  1012. if (!IsHTTPPrefixed (sz))
  1013. {
  1014. SGMessageBox(hwnd, IDS_HTTPONLY, MB_ICONINFORMATION | MB_OK);
  1015. return E_INVALIDARG;
  1016. }
  1017. }
  1018. INT_PTR iDlgResult = DialogBoxParam (MLGetHinst(), MAKEINTRESOURCE(IDD_DESKTOP_SUBSCRIPTION_SUMMARY),
  1019. hwnd, SummarizeDesktopSubscriptionDlgProc, (LPARAM)&parms);
  1020. switch (iDlgResult)
  1021. {
  1022. case -1:
  1023. hr = E_FAIL;
  1024. break;
  1025. case IDCANCEL:
  1026. hr = S_FALSE;
  1027. break;
  1028. default:
  1029. hr = CreateSubscriptionNoSummary (hwnd, pwszURL, pwszFriendlyName,
  1030. CREATESUBS_NOUI | dwFlags, subsType, pInfo);
  1031. break;
  1032. }
  1033. return hr;
  1034. }
  1035. STDMETHODIMP
  1036. CSubscriptionMgr::GetDefaultInfo(
  1037. SUBSCRIPTIONTYPE subType,
  1038. SUBSCRIPTIONINFO *pInfo
  1039. )
  1040. {
  1041. //
  1042. // Validate the parameters.
  1043. //
  1044. if (!IS_VALID_SUBSCRIPTIONTYPE(subType)
  1045. || !pInfo
  1046. || (pInfo->cbSize != sizeof(SUBSCRIPTIONINFO)))
  1047. {
  1048. ASSERT(FALSE);
  1049. return E_INVALIDARG;
  1050. }
  1051. memset((void *)pInfo, 0, sizeof(SUBSCRIPTIONINFO));
  1052. pInfo->cbSize = sizeof(SUBSCRIPTIONINFO);
  1053. // Fill in default structure. Note that lines are commented out
  1054. // below to indicate the field is initialized to 0 without wasting
  1055. // code (memset above already cleared structure out.)
  1056. pInfo->fUpdateFlags = SUBSINFO_RECURSE | SUBSINFO_MAILNOT
  1057. | SUBSINFO_WEBCRAWL
  1058. /*| SUBSINFO_SCHEDULE */ | SUBSINFO_CHANGESONLY
  1059. | SUBSINFO_CHANNELFLAGS;
  1060. pInfo->dwRecurseLevels = DEFAULTLEVEL;
  1061. pInfo->schedule = SUBSSCHED_AUTO;
  1062. switch (subType)
  1063. {
  1064. case SUBSTYPE_URL:
  1065. // pInfo->bChangesOnly = FALSE;
  1066. // pInfo->bMailNotification = FALSE;
  1067. // pInfo->bPasswordNeeded = FALSE;
  1068. pInfo->fWebcrawlerFlags = DEFAULTFLAGS;
  1069. break;
  1070. case SUBSTYPE_CHANNEL:
  1071. // pInfo->bChangesOnly = FALSE;
  1072. // pInfo->bMailNotification = FALSE;
  1073. pInfo->fChannelFlags = CHANNEL_AGENT_PRECACHE_ALL | CHANNEL_AGENT_DYNAMIC_SCHEDULE;
  1074. break;
  1075. case SUBSTYPE_DESKTOPCHANNEL:
  1076. // pInfo->bChangesOnly = FALSE;
  1077. // pInfo->bMailNotification = FALSE;
  1078. pInfo->fChannelFlags = CHANNEL_AGENT_PRECACHE_ALL | CHANNEL_AGENT_DYNAMIC_SCHEDULE;
  1079. break;
  1080. case SUBSTYPE_DESKTOPURL:
  1081. // pInfo->bChangesOnly = FALSE;
  1082. // pInfo->bMailNotification = FALSE;
  1083. pInfo->fWebcrawlerFlags = DEFAULTFLAGS;
  1084. break;
  1085. default:
  1086. return E_NOTIMPL;
  1087. }
  1088. return S_OK;
  1089. }
  1090. STDMETHODIMP
  1091. CSubscriptionMgr::GetSubscriptionInfo(
  1092. LPCWSTR pwszURL,
  1093. SUBSCRIPTIONINFO *pInfo
  1094. )
  1095. {
  1096. HRESULT hr;
  1097. //
  1098. // Validate the parameters.
  1099. //
  1100. if (!pInfo
  1101. || !pwszURL
  1102. || (pInfo->cbSize != sizeof(SUBSCRIPTIONINFO)))
  1103. {
  1104. ASSERT(FALSE);
  1105. return E_INVALIDARG;
  1106. }
  1107. BOOL bSubscribe;
  1108. hr = IsSubscribed(pwszURL, &bSubscribe);
  1109. RETURN_ON_FAILURE(hr);
  1110. if (!bSubscribe)
  1111. {
  1112. return E_FAIL;
  1113. }
  1114. // We cannot rely on the caller passing us a clean SUBSCRIPTIONINFO
  1115. // structure. We need to clean it ourselves.
  1116. DWORD dwFlags = pInfo->fUpdateFlags;
  1117. ZeroMemory(pInfo, sizeof(SUBSCRIPTIONINFO));
  1118. pInfo->cbSize = sizeof(SUBSCRIPTIONINFO);
  1119. pInfo->fUpdateFlags = dwFlags;
  1120. OOEBuf ooeb; // Alas, we need the code in UpdateSubsInfoFromOOE
  1121. CopyToOOEBuf (&(_pidl->ooe), &ooeb); //to work once for a buf and once for an entry, and it's
  1122. UpdateSubsInfoFromOOE (pInfo, &ooeb); //easier to convert entry->buf so we do that here.
  1123. return S_OK;
  1124. }
  1125. void UpdateSubsInfoFromOOE (SUBSCRIPTIONINFO* pInfo, POOEBuf pooe)
  1126. {
  1127. DWORD dwFlags = pInfo->fUpdateFlags & SUBSINFO_ALLFLAGS;
  1128. SUBSCRIPTIONTYPE subType = GetItemCategory(pooe);
  1129. if (dwFlags & SUBSINFO_USER)
  1130. {
  1131. SAFEFREEBSTR (pInfo->bstrUserName);
  1132. CreateBSTRFromTSTR(&(pInfo->bstrUserName), pooe->username);
  1133. }
  1134. if (dwFlags & SUBSINFO_PASSWORD)
  1135. {
  1136. SAFEFREEBSTR (pInfo->bstrPassword);
  1137. CreateBSTRFromTSTR(&(pInfo->bstrPassword), pooe->password);
  1138. }
  1139. if (dwFlags & SUBSINFO_FRIENDLYNAME)
  1140. {
  1141. SAFEFREEBSTR (pInfo->bstrFriendlyName);
  1142. CreateBSTRFromTSTR(&(pInfo->bstrFriendlyName), pooe->m_Name);
  1143. }
  1144. pInfo->fUpdateFlags = dwFlags;
  1145. if (dwFlags & SUBSINFO_SCHEDULE)
  1146. {
  1147. pInfo->schedule = GetGroup(pooe);
  1148. if (pInfo->schedule == SUBSSCHED_CUSTOM)
  1149. {
  1150. if (pooe->groupCookie != GUID_NULL)
  1151. {
  1152. pInfo->customGroupCookie = pooe->groupCookie;
  1153. }
  1154. else
  1155. {
  1156. GetItemSchedule(&pooe->m_Cookie, &pInfo->customGroupCookie);
  1157. if (pInfo->customGroupCookie == GUID_NULL)
  1158. {
  1159. pInfo->schedule = SUBSSCHED_MANUAL;
  1160. }
  1161. }
  1162. }
  1163. }
  1164. if (PTASK_TRIGGER pInfoTrigger = (PTASK_TRIGGER)pInfo->pTrigger)
  1165. {
  1166. if (pInfoTrigger->cbTriggerSize == pooe->m_Trigger.cbTriggerSize)
  1167. *(pInfoTrigger) = pooe->m_Trigger;
  1168. else
  1169. pInfoTrigger->cbTriggerSize = 0;
  1170. }
  1171. //otherwise, it's already null and we can't do anything about it... luckily, we'll never
  1172. //have a trigger that we need to write back to a SUBSCRIPTIONINFO that didn't already have
  1173. //one.
  1174. if (dwFlags & SUBSINFO_RECURSE)
  1175. pInfo->dwRecurseLevels = pooe->m_RecurseLevels;
  1176. if (dwFlags & SUBSINFO_WEBCRAWL)
  1177. pInfo->fWebcrawlerFlags = pooe->m_RecurseFlags;
  1178. if (dwFlags & SUBSINFO_MAILNOT)
  1179. pInfo->bMailNotification = pooe->bMail;
  1180. if (dwFlags & SUBSINFO_GLEAM)
  1181. pInfo->bGleam = pooe->bGleam;
  1182. if (dwFlags & SUBSINFO_CHANGESONLY)
  1183. pInfo->bChangesOnly = pooe->bChangesOnly;
  1184. if (dwFlags & SUBSINFO_NEEDPASSWORD)
  1185. pInfo->bNeedPassword = pooe->bNeedPassword;
  1186. if (dwFlags & SUBSINFO_CHANNELFLAGS)
  1187. {
  1188. if ((subType==SUBSTYPE_CHANNEL)||(subType==SUBSTYPE_DESKTOPCHANNEL))
  1189. {
  1190. pInfo->fChannelFlags = pooe->fChannelFlags;
  1191. }
  1192. else
  1193. {
  1194. pInfo->fChannelFlags = 0;
  1195. pInfo->fUpdateFlags &= (~SUBSINFO_CHANNELFLAGS);
  1196. }
  1197. }
  1198. if (dwFlags & SUBSINFO_MAXSIZEKB)
  1199. pInfo->dwMaxSizeKB = pooe->m_SizeLimit;
  1200. if (dwFlags & SUBSINFO_TYPE)
  1201. {
  1202. pInfo->subType = GetItemCategory(pooe);
  1203. ASSERT(IS_VALID_SUBSCRIPTIONTYPE(pInfo->subType));
  1204. }
  1205. if (dwFlags & SUBSINFO_TASKFLAGS)
  1206. {
  1207. pInfo->fTaskFlags = pooe->grfTaskTrigger;
  1208. }
  1209. }
  1210. STDMETHODIMP
  1211. CSubscriptionMgr::UpdateSubscription(LPCWSTR pwszURL)
  1212. {
  1213. ASSERT(pwszURL);
  1214. BOOL bSubscribe = FALSE;
  1215. HRESULT hr = IsSubscribed(pwszURL, &bSubscribe);
  1216. CLSID clsId;
  1217. RETURN_ON_FAILURE(hr);
  1218. if (!bSubscribe)
  1219. {
  1220. return E_INVALIDARG;
  1221. }
  1222. //
  1223. // Fail if restrictions are in place.
  1224. // FEATURE: Should we have a flag parameter to override this?
  1225. //
  1226. if (SHRestricted2W(REST_NoManualUpdates, NULL, 0))
  1227. {
  1228. SGMessageBox(NULL, IDS_RESTRICTED, MB_OK);
  1229. return E_ACCESSDENIED;
  1230. }
  1231. clsId = _pidl->ooe.m_Cookie;
  1232. hr = SendUpdateRequests(NULL, &clsId, 1);
  1233. _pidl->ooe.m_Cookie = clsId;
  1234. return hr;
  1235. }
  1236. STDMETHODIMP
  1237. CSubscriptionMgr::UpdateAll()
  1238. {
  1239. //
  1240. // Fail if restrictions are in place.
  1241. // FEATURE: Should we have a flag parameter to override this?
  1242. //
  1243. if (SHRestricted2W(REST_NoManualUpdates, NULL, 0))
  1244. {
  1245. SGMessageBox(NULL, IDS_RESTRICTED, MB_OK);
  1246. return E_ACCESSDENIED;
  1247. }
  1248. return SendUpdateRequests(NULL, NULL, 0);
  1249. }
  1250. HRESULT MergeOOEBuf(POOEBuf p1, POOEBuf p2, DWORD fMask)
  1251. {
  1252. ASSERT(p1 && p2);
  1253. DWORD dwMask = p2->dwFlags & fMask;
  1254. if (dwMask == 0)
  1255. return S_OK;
  1256. if (p1->clsidDest != p2->clsidDest)
  1257. return E_INVALIDARG;
  1258. if (dwMask & PROP_WEBCRAWL_COOKIE)
  1259. {
  1260. // We shouldn't merge cookies.
  1261. }
  1262. if (dwMask & PROP_WEBCRAWL_SIZE)
  1263. {
  1264. p1->m_SizeLimit = p2->m_SizeLimit;
  1265. }
  1266. if (dwMask & PROP_WEBCRAWL_FLAGS)
  1267. {
  1268. p1->m_RecurseFlags = p2->m_RecurseFlags;
  1269. }
  1270. if (dwMask & PROP_WEBCRAWL_LEVEL)
  1271. {
  1272. p1->m_RecurseLevels = p2->m_RecurseLevels;
  1273. }
  1274. if (dwMask & PROP_WEBCRAWL_URL)
  1275. {
  1276. StrCpyN(p1->m_URL, p2->m_URL, MAX_URL);
  1277. }
  1278. if (dwMask & PROP_WEBCRAWL_NAME)
  1279. {
  1280. StrCpyN(p1->m_Name, p2->m_Name, MAX_NAME);
  1281. }
  1282. if (dwMask & PROP_WEBCRAWL_PSWD)
  1283. {
  1284. StrCpyN(p1->password, p2->password, MAX_PASSWORD);
  1285. }
  1286. if (dwMask & PROP_WEBCRAWL_UNAME)
  1287. {
  1288. StrCpyN(p1->username, p2->username, MAX_USERNAME);
  1289. }
  1290. if (dwMask & PROP_WEBCRAWL_DESKTOP)
  1291. {
  1292. p1->bDesktop = p2->bDesktop;
  1293. }
  1294. if (dwMask & PROP_WEBCRAWL_CHANNEL)
  1295. {
  1296. p1->bChannel = p2->bChannel;
  1297. }
  1298. if (dwMask & PROP_WEBCRAWL_EMAILNOTF)
  1299. {
  1300. p1->bMail = p2->bMail;
  1301. }
  1302. if (dwMask & PROP_WEBCRAWL_RESCH)
  1303. {
  1304. p1->grfTaskTrigger = p2->grfTaskTrigger;
  1305. p1->groupCookie = p2->groupCookie;
  1306. p1->fChannelFlags |= (p2->fChannelFlags & CHANNEL_AGENT_DYNAMIC_SCHEDULE);
  1307. }
  1308. if (dwMask & PROP_WEBCRAWL_LAST)
  1309. {
  1310. p1->m_LastUpdated = p2->m_LastUpdated;
  1311. }
  1312. if (dwMask & PROP_WEBCRAWL_STATUS)
  1313. {
  1314. p1->status = p2->status;
  1315. }
  1316. if (dwMask & PROP_WEBCRAWL_PRIORITY)
  1317. {
  1318. p1->m_Priority = p2->m_Priority;
  1319. }
  1320. if (dwMask & PROP_WEBCRAWL_GLEAM)
  1321. {
  1322. p1->bGleam = p2->bGleam;
  1323. }
  1324. if (dwMask & PROP_WEBCRAWL_CHANGESONLY)
  1325. {
  1326. p1->bChangesOnly = p2->bChangesOnly;
  1327. }
  1328. if (dwMask & PROP_WEBCRAWL_CHANNELFLAGS)
  1329. {
  1330. p1->fChannelFlags = p2->fChannelFlags;
  1331. }
  1332. p1->dwFlags |= (p2->dwFlags & fMask & (~PROP_WEBCRAWL_COOKIE));
  1333. return S_OK;
  1334. }
  1335. INT_PTR CALLBACK SummarizeDesktopSubscriptionDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1336. {
  1337. SUBSCRIBE_ADI_INFO* pInfo = (SUBSCRIBE_ADI_INFO*)GetProp(hDlg,SUBSCRIBEADIPROP);
  1338. switch (uMsg)
  1339. {
  1340. case WM_INITDIALOG:
  1341. pInfo = (SUBSCRIBE_ADI_INFO*)lParam;
  1342. ASSERT (pInfo);
  1343. SetProp (hDlg, SUBSCRIBEADIPROP, (HANDLE)pInfo);
  1344. { //block to declare vars to update captions
  1345. TCHAR sz[MAX_URL];
  1346. if (pInfo->subsType == SUBSTYPE_DESKTOPCHANNEL)
  1347. {
  1348. if(MLLoadString(
  1349. (pInfo->pSubsInfo->bNeedPassword ? IDS_DESKTOPCHANNEL_SUMMARY_TEXT : IDS_DESKTOPCHANNEL_SUMMARY_NOPW),
  1350. sz, ARRAYSIZE(sz)))
  1351. {
  1352. SetDlgItemText(hDlg, IDC_DESKTOP_SUMMARY_TEXT, sz);
  1353. }
  1354. }
  1355. MyOleStrToStrN (sz, ARRAYSIZE(sz), pInfo->pwszName);
  1356. SetListViewToString(GetDlgItem(hDlg, IDC_SUBSCRIBE_ADI_NAME), sz);
  1357. MyOleStrToStrN (sz, ARRAYSIZE(sz), pInfo->pwszUrl);
  1358. SetListViewToString (GetDlgItem (hDlg, IDC_SUBSCRIBE_ADI_URL), sz);
  1359. }
  1360. break;
  1361. case WM_COMMAND:
  1362. ASSERT (pInfo);
  1363. switch (GET_WM_COMMAND_ID(wParam, lParam))
  1364. {
  1365. case IDCANCEL:
  1366. EndDialog(hDlg, IDCANCEL);
  1367. break;
  1368. case IDOK:
  1369. //subscription happens in calling function when we return IDOK
  1370. EndDialog(hDlg, IDOK);
  1371. break;
  1372. case IDC_SUBSCRIBE_CUSTOMIZE:
  1373. //run through wizard in NOSAVE mode
  1374. if (pInfo->pMgr &&
  1375. S_OK == pInfo->pMgr->CreateSubscriptionNoSummary (hDlg, pInfo->pwszUrl,
  1376. pInfo->pwszName, pInfo->dwFlags | CREATESUBS_NOSAVE,
  1377. pInfo->subsType, pInfo->pSubsInfo))
  1378. {
  1379. SendMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, IDOK), TRUE);
  1380. }
  1381. break;
  1382. }
  1383. break;
  1384. case WM_NOTIFY:
  1385. if (LOWORD(wParam) == IDC_SUBSCRIBE_ADI_URL)
  1386. {
  1387. NM_LISTVIEW * pnmlv = (NM_LISTVIEW *)lParam;
  1388. if (pnmlv->hdr.code == LVN_GETINFOTIP)
  1389. {
  1390. TCHAR szURL[MAX_URL];
  1391. LV_ITEM lvi = {0};
  1392. lvi.mask = LVIF_TEXT;
  1393. lvi.pszText = szURL;
  1394. lvi.cchTextMax = ARRAYSIZE(szURL);
  1395. if (!ListView_GetItem (GetDlgItem (hDlg, IDC_SUBSCRIBE_ADI_URL), &lvi))
  1396. return FALSE;
  1397. NMLVGETINFOTIP * pTip = (NMLVGETINFOTIP *)pnmlv;
  1398. ASSERT(pTip);
  1399. StrCpyN(pTip->pszText, szURL, pTip->cchTextMax);
  1400. return TRUE;
  1401. }
  1402. }
  1403. break;
  1404. case WM_DESTROY:
  1405. RemoveProp (hDlg, SUBSCRIBEADIPROP);
  1406. break;
  1407. }
  1408. return FALSE;
  1409. }