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.

417 lines
13 KiB

  1. #ifndef _CDFAGENT_H
  2. #define _CDFAGENT_H
  3. #include "msxml.h"
  4. class CProcessElement;
  5. class CProcessRoot;
  6. class CUrlTrackingCache;
  7. class CRunDeliveryAgentSink
  8. {
  9. public:
  10. // OnAgentProgress not currently called
  11. virtual HRESULT OnAgentProgress()
  12. { return E_NOTIMPL; }
  13. // OnAgentEnd called when agent is complete. fSynchronous means that StartAgent call
  14. // has not yet returned; hrResult will be returned from StartAgent
  15. virtual HRESULT OnAgentEnd(const SUBSCRIPTIONCOOKIE *pSubscriptionCookie,
  16. long lSizeDownloaded, HRESULT hrResult, LPCWSTR wszResult,
  17. BOOL fSynchronous)
  18. { return E_NOTIMPL; }
  19. };
  20. class CProcessElementSink
  21. {
  22. public:
  23. virtual HRESULT OnChildDone(CProcessElement *pChild, HRESULT hr) = 0;
  24. virtual LPCWSTR GetBaseUrl() = 0; // Returned pointer doesn't need to get freed
  25. virtual BOOL IsGlobalLog() = 0;
  26. };
  27. typedef struct CDF_TIME
  28. {
  29. WORD wDay;
  30. WORD wHour;
  31. WORD wMin;
  32. WORD wReserved;
  33. DWORD dwConvertedMinutes; // Day/Hour/Min in Minutes
  34. } CDF_TIME;
  35. //////////////////////////////////////////////////////////////////////////
  36. //
  37. // Channel Agent object
  38. //
  39. //////////////////////////////////////////////////////////////////////////
  40. class CChannelAgent : public CDeliveryAgent,
  41. public CUrlDownloadSink,
  42. public CProcessElementSink
  43. {
  44. friend CProcessElement; // for SendUpdateProgress
  45. friend CProcessRoot; // for laziness
  46. protected:
  47. // properties
  48. LPWSTR m_pwszURL;
  49. DWORD m_dwChannelFlags;
  50. // used during updating
  51. CUrlDownload *m_pCurDownload;
  52. IExtractIcon *m_pChannelIconHelper;
  53. BOOL m_fHasInitCookie; // One time deal, don't try again.
  54. VARIANT m_varChange;
  55. GROUPID m_llCacheGroupID;
  56. GROUPID m_llOldCacheGroupID;
  57. // other agent flags
  58. enum {
  59. FLAG_CDFCHANGED = 0x80000000 // did the CDF change?
  60. };
  61. private:
  62. ~CChannelAgent(void);
  63. public:
  64. CChannelAgent(void);
  65. // CUrlDownloadSink
  66. HRESULT OnAuthenticate(HWND *phwnd, LPWSTR *ppszUsername, LPWSTR *ppszPassword);
  67. HRESULT OnDownloadComplete(UINT iID, int iError);
  68. // CProcessElementSink
  69. HRESULT OnChildDone(CProcessElement *pChild, HRESULT hr);
  70. LPCWSTR GetBaseUrl() { return GetUrl(); }
  71. BOOL IsGlobalLog() { return FALSE; }
  72. // virtual functions overriding CDeliveryAgent
  73. HRESULT AgentPause(DWORD dwFlags);
  74. HRESULT AgentResume(DWORD dwFlags);
  75. HRESULT AgentAbort(DWORD dwFlags);
  76. STDMETHODIMP GetIconLocation(UINT, LPTSTR, UINT, int *, UINT *);
  77. STDMETHODIMP Extract(LPCTSTR, UINT, HICON *, HICON *, UINT);
  78. LPCWSTR GetUrl() { return m_pwszURL; }
  79. ISubscriptionItem *GetStartItem() { return m_pSubscriptionItem; }
  80. BOOL IsChannelFlagSet(DWORD dwFlag) { return dwFlag & m_dwChannelFlags; }
  81. void SetScreenSaverURL(LPCWSTR pwszURL);
  82. protected:
  83. // CDeliveryAgent overrides
  84. HRESULT ModifyUpdateEnd(ISubscriptionItem *pEndItem, UINT *puiRes);
  85. HRESULT StartOperation();
  86. HRESULT StartDownload();
  87. void CleanUp();
  88. // Used during updates
  89. CProcessRoot *m_pProcess;
  90. LPWSTR m_pwszScreenSaverURL;
  91. public:
  92. DWORD m_dwMaxSizeKB;
  93. };
  94. //////////////////////////////////////////////////////////////////////////
  95. //
  96. // CRunDeliveryAgent object
  97. // Will run a delivery agent and host it for you
  98. // Create, call Init, then call StartAgent
  99. // Use static function SafeRelease to safely release this class.
  100. //
  101. //////////////////////////////////////////////////////////////////////////
  102. class CRunDeliveryAgent : public ISubscriptionAgentEvents
  103. {
  104. protected:
  105. virtual ~CRunDeliveryAgent();
  106. CRunDeliveryAgentSink *m_pParent;
  107. ULONG m_cRef;
  108. ISubscriptionItem *m_pItem;
  109. ISubscriptionAgentControl *m_pAgent;
  110. HRESULT m_hrResult;
  111. BOOL m_fInStartAgent;
  112. CLSID m_clsidDest;
  113. void CleanUp();
  114. public:
  115. CRunDeliveryAgent();
  116. HRESULT Init(CRunDeliveryAgentSink *pParent, ISubscriptionItem *pItem, REFCLSID rclsidDest);
  117. void LeaveMeAlone() { m_pParent = NULL; }
  118. inline static void SafeRelease(CRunDeliveryAgent * &pThis)
  119. { if (pThis) { pThis->m_pParent=NULL; pThis->Release(); pThis=NULL; } }
  120. static HRESULT CreateNewItem(ISubscriptionItem **ppItem, REFCLSID rclsidAgent);
  121. // StartAgent will return E_PENDING if agent is running. Otherwise it will return
  122. // synchronous result code from agent.
  123. HRESULT StartAgent();
  124. HRESULT AgentPause(DWORD dwFlags);
  125. HRESULT AgentResume(DWORD dwFlags);
  126. HRESULT AgentAbort(DWORD dwFlags);
  127. // IUnknown members
  128. STDMETHODIMP QueryInterface(REFIID riid, void **ppunk);
  129. STDMETHODIMP_(ULONG) AddRef();
  130. STDMETHODIMP_(ULONG) Release();
  131. // ISubscriptionAgentEvents members
  132. STDMETHODIMP UpdateBegin(const SUBSCRIPTIONCOOKIE *pSubscriptionCookie);
  133. STDMETHODIMP UpdateProgress(const SUBSCRIPTIONCOOKIE *pSubscriptionCookie,
  134. long lSizeDownloaded, long lProgressCurrent, long lProgressMax,
  135. HRESULT hrStatus, LPCWSTR wszStatus);
  136. STDMETHODIMP UpdateEnd(const SUBSCRIPTIONCOOKIE *pSubscriptionCookie,
  137. long lSizeDownloaded,
  138. HRESULT hrResult, LPCWSTR wszResult);
  139. STDMETHODIMP ReportError(const SUBSCRIPTIONCOOKIE *pSubscriptionCookie,
  140. HRESULT hrError, LPCWSTR wszError);
  141. };
  142. class CChannelAgentHolder : public CRunDeliveryAgent,
  143. public IServiceProvider
  144. {
  145. protected:
  146. ~CChannelAgentHolder();
  147. public:
  148. CChannelAgentHolder(CChannelAgent *pChannelAgent, CProcessElement *pProcess);
  149. // IUnknown
  150. STDMETHODIMP QueryInterface(REFIID riid, void **ppunk);
  151. STDMETHODIMP_(ULONG) AddRef();
  152. STDMETHODIMP_(ULONG) Release();
  153. // ServiceProvider
  154. STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
  155. protected:
  156. CChannelAgent *m_pChannelAgent;
  157. CProcessElement *m_pProcess;
  158. };
  159. //////////////////////////////////////////////////////////////////////////
  160. //
  161. // Process Element objects
  162. //
  163. // User of this class
  164. // 1) Creates & passes in self & element
  165. // 2) Calls Run
  166. // 3) If E_PENDING, will receive call back "OnChildDone"
  167. //
  168. // The purpose of this class is simply to allow us to save our state of
  169. // walking the XML OM, so that we can host another deliver agent
  170. // (webcrawler). This requires us to return out to the thread's message
  171. // pump after sending the "agent start" to the web crawler.
  172. // The if a webcrawl is initiated the class creates its own sink. Classes
  173. // also keep references to their spawned enumerations in case of an
  174. // abort, which comes from the root element (CProcessRoot instance)
  175. //
  176. //////////////////////////////////////////////////////////////////////////
  177. class CProcessElement : public CProcessElementSink, public CRunDeliveryAgentSink
  178. {
  179. public:
  180. CProcessElement(CProcessElementSink *pParent, CProcessRoot *pRoot, IXMLElement *pEle);
  181. ~CProcessElement();
  182. // From CRunDeliveryAgent
  183. HRESULT OnAgentEnd(const SUBSCRIPTIONCOOKIE *pSubscriptionCookie,
  184. long lSizeDownloaded, HRESULT hrResult, LPCWSTR wszResult,
  185. BOOL fSynchronous);
  186. typedef HRESULT (CChannelAgent::*PFNHANDLETAG)(LPCWSTR pwszTagName, IXMLElement *pEle);
  187. typedef struct
  188. {
  189. LPCWSTR pwszTagName;
  190. PFNHANDLETAG pfnHandleTag;
  191. } TAGTABLE;
  192. // E_FAIL, E_PENDING, or S_OK
  193. virtual HRESULT Run();
  194. // Called when E_PENDING DoChild returns (from m_pCurChild)
  195. HRESULT OnChildDone(CProcessElement *pChild, HRESULT hr);
  196. HRESULT Pause(DWORD dwFlags);
  197. HRESULT Resume(DWORD dwFlags);
  198. HRESULT Abort(DWORD dwFlags);
  199. IXMLElement *GetCurrentElement() { return m_pChildElement; }
  200. protected:
  201. // Returns E_PENDING, or S_OK if enumeration complete
  202. HRESULT DoEnumeration();
  203. // E_PENDING if webcrawl pending
  204. HRESULT DoChild(CProcessElement *pChild);
  205. // Should return E_PENDING, or S_OK if processing done
  206. // Can return E_ABORT to abort entire CDF processing
  207. virtual HRESULT ProcessItemInEnum(LPCWSTR pwszTagName, IXMLElement *pItem) = 0;
  208. // Called by DoEnumeration when it's done. Return value ignored.
  209. virtual HRESULT EnumerationComplete() { return S_OK; }
  210. // E_PENDING, or E_FAIL
  211. HRESULT DoDeliveryAgent(ISubscriptionItem *pItem, REFCLSID rclsid, LPCWSTR pwszURL=NULL);
  212. HRESULT DoWebCrawl(IXMLElement *pItem, LPCWSTR pwszURL=NULL);
  213. HRESULT DoSoftDist(IXMLElement *pItem);
  214. BOOL ShouldDownloadLogo(IXMLElement *pLogo);
  215. // If relative url, will combine with most recent base URL
  216. // *ppwszRetUrl should be NULL & will be LocalAlloced if needed
  217. HRESULT CombineWithBaseUrl(LPCWSTR pwszUrl, LPWSTR *ppwszRetUrl);
  218. // Returned pointer doesn't need to get freed
  219. LPCWSTR GetBaseUrl() { return m_pParent->GetBaseUrl(); }
  220. BOOL IsGlobalLog() { return m_pParent->IsGlobalLog(); }
  221. CProcessRoot *m_pRoot;
  222. CProcessElement *m_pCurChild;
  223. IXMLElementCollection *m_pCollection;
  224. long m_lIndex;
  225. long m_lMax;
  226. BOOL m_fStartedEnumeration;
  227. BOOL m_fSentEnumerationComplete;
  228. IXMLElement *m_pElement;
  229. IXMLElement *m_pChildElement;
  230. CProcessElementSink *m_pParent;
  231. CRunDeliveryAgent *m_pRunAgent;
  232. };
  233. class CProcessRoot : public CProcessElement
  234. {
  235. public:
  236. CProcessRoot(CChannelAgent *pParent, IXMLElement *pRoot);
  237. ~CProcessRoot();
  238. CChannelAgent *m_pChannelAgent;
  239. DWORD m_dwCurSizeKB;
  240. int m_iTotalStarted;
  241. BOOL m_fMaxSizeExceeded;
  242. protected:
  243. ISubscriptionItem *m_pDefaultStartItem;
  244. CUrlTrackingCache *m_pTracking;
  245. public:
  246. HRESULT CreateStartItem(ISubscriptionItem **ppItem);
  247. IUnknown *DefaultStartItem() { return m_pDefaultStartItem; }
  248. HRESULT Run();
  249. // Called when E_PENDING DoChild returns (from m_pCurChild, a CProcessChannel)
  250. HRESULT OnChildDone(CProcessElement *pChild, HRESULT hr);
  251. HRESULT OnAgentEnd(const SUBSCRIPTIONCOOKIE *, long, HRESULT, LPCWSTR, BOOL);
  252. BOOL IsPaused() { return m_pChannelAgent->IsPaused(); }
  253. BOOL IsChannelFlagSet(DWORD dw) { return m_pChannelAgent->IsChannelFlagSet(dw); }
  254. // HRESULT ProcessLogin(IXMLElement *pElement);
  255. HRESULT DoTrackingFromItem(IXMLElement *pItem, LPCWSTR pwszUrl, BOOL fForceLog);
  256. HRESULT DoTrackingFromLog(IXMLElement *pItem);
  257. protected:
  258. HRESULT ProcessItemInEnum(LPCWSTR pwszTagName, IXMLElement *pItem);
  259. LPCWSTR GetBaseUrl() { return m_pChannelAgent->GetUrl(); }
  260. };
  261. class CProcessChannel : public CProcessElement
  262. {
  263. public:
  264. CProcessChannel(CProcessElementSink *pParent, CProcessRoot *pRoot, IXMLElement *pItem);
  265. ~CProcessChannel();
  266. HRESULT Run();
  267. void SetGlobalLogFlag(BOOL flag) { m_fglobalLog = flag; }
  268. protected:
  269. HRESULT ProcessItemInEnum(LPCWSTR pwszTagName, IXMLElement *pItem);
  270. LPCWSTR GetBaseUrl() { if (m_bstrBaseUrl) return m_bstrBaseUrl; return m_pParent->GetBaseUrl(); }
  271. BOOL IsGlobalLog() { return m_fglobalLog; }
  272. HRESULT CheckPreCache();
  273. BOOL m_fDownloadedHREF;
  274. BSTR m_bstrBaseUrl;
  275. BOOL m_fglobalLog;
  276. };
  277. class CProcessItem : public CProcessElement
  278. {
  279. public:
  280. CProcessItem(CProcessElementSink *pParent, CProcessRoot *pRoot, IXMLElement *pItem);
  281. ~CProcessItem();
  282. protected:
  283. HRESULT ProcessItemInEnum(LPCWSTR pwszTagName, IXMLElement *pItem);
  284. HRESULT EnumerationComplete();
  285. BSTR m_bstrAnchorURL;
  286. BOOL m_fScreenSaver;
  287. BOOL m_fDesktop;
  288. BOOL m_fEmail;
  289. };
  290. class CProcessSchedule : public CProcessElement
  291. {
  292. public:
  293. CProcessSchedule(CProcessElementSink *pParent, CProcessRoot *pRoot, IXMLElement *pItem);
  294. HRESULT Run();
  295. protected:
  296. HRESULT ProcessItemInEnum(LPCWSTR pwszTagName, IXMLElement *pItem);
  297. HRESULT EnumerationComplete();
  298. CDF_TIME m_timeInterval;
  299. CDF_TIME m_timeEarliest;
  300. CDF_TIME m_timeLatest;
  301. SYSTEMTIME m_stStartDate;
  302. SYSTEMTIME m_stEndDate;
  303. public:
  304. TASK_TRIGGER m_tt;
  305. };
  306. class CExtractSchedule : public CProcessElement
  307. {
  308. public:
  309. CExtractSchedule(IXMLElement *pEle, CExtractSchedule *m_pExtractRoot);
  310. HRESULT ProcessItemInEnum(LPCWSTR pwszTagName, IXMLElement *pItem);
  311. HRESULT GetTaskTrigger(TASK_TRIGGER *ptt);
  312. virtual HRESULT Run();
  313. TASK_TRIGGER m_tt;
  314. CExtractSchedule *m_pExtractRoot;
  315. protected:
  316. LPCWSTR GetBaseUrl() { return NULL; }
  317. };
  318. #endif // _CDFAGENT_H