Leaked source code of windows server 2003
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.

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