418 lines
13 KiB
C
418 lines
13 KiB
C
|
#ifndef _CDFAGENT_H
|
||
|
#define _CDFAGENT_H
|
||
|
|
||
|
#include "msxml.h"
|
||
|
|
||
|
class CProcessElement;
|
||
|
class CProcessRoot;
|
||
|
|
||
|
class CUrlTrackingCache;
|
||
|
|
||
|
class CRunDeliveryAgentSink
|
||
|
{
|
||
|
public:
|
||
|
// OnAgentProgress not currently called
|
||
|
virtual HRESULT OnAgentProgress()
|
||
|
{ return E_NOTIMPL; }
|
||
|
// OnAgentEnd called when agent is complete. fSynchronous means that StartAgent call
|
||
|
// has not yet returned; hrResult will be returned from StartAgent
|
||
|
virtual HRESULT OnAgentEnd(const SUBSCRIPTIONCOOKIE *pSubscriptionCookie,
|
||
|
long lSizeDownloaded, HRESULT hrResult, LPCWSTR wszResult,
|
||
|
BOOL fSynchronous)
|
||
|
{ return E_NOTIMPL; }
|
||
|
};
|
||
|
|
||
|
class CProcessElementSink
|
||
|
{
|
||
|
public:
|
||
|
virtual HRESULT OnChildDone(CProcessElement *pChild, HRESULT hr) = 0;
|
||
|
virtual LPCWSTR GetBaseUrl() = 0; // Returned pointer doesn't need to get freed
|
||
|
virtual BOOL IsGlobalLog() = 0;
|
||
|
};
|
||
|
|
||
|
typedef struct CDF_TIME
|
||
|
{
|
||
|
WORD wDay;
|
||
|
WORD wHour;
|
||
|
WORD wMin;
|
||
|
WORD wReserved;
|
||
|
DWORD dwConvertedMinutes; // Day/Hour/Min in Minutes
|
||
|
} CDF_TIME;
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Channel Agent object
|
||
|
//
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
class CChannelAgent : public CDeliveryAgent,
|
||
|
public CUrlDownloadSink,
|
||
|
public CProcessElementSink
|
||
|
{
|
||
|
friend CProcessElement; // for SendUpdateProgress
|
||
|
friend CProcessRoot; // for laziness
|
||
|
protected:
|
||
|
// properties
|
||
|
LPWSTR m_pwszURL;
|
||
|
DWORD m_dwChannelFlags;
|
||
|
|
||
|
// used during updating
|
||
|
CUrlDownload *m_pCurDownload;
|
||
|
IExtractIcon *m_pChannelIconHelper;
|
||
|
|
||
|
BOOL m_fHasInitCookie; // One time deal, don't try again.
|
||
|
|
||
|
VARIANT m_varChange;
|
||
|
|
||
|
GROUPID m_llCacheGroupID;
|
||
|
GROUPID m_llOldCacheGroupID;
|
||
|
|
||
|
// other agent flags
|
||
|
enum {
|
||
|
FLAG_CDFCHANGED = 0x80000000 // did the CDF change?
|
||
|
};
|
||
|
|
||
|
private:
|
||
|
~CChannelAgent(void);
|
||
|
|
||
|
public:
|
||
|
CChannelAgent(void);
|
||
|
|
||
|
// CUrlDownloadSink
|
||
|
HRESULT OnAuthenticate(HWND *phwnd, LPWSTR *ppszUsername, LPWSTR *ppszPassword);
|
||
|
HRESULT OnDownloadComplete(UINT iID, int iError);
|
||
|
|
||
|
// CProcessElementSink
|
||
|
HRESULT OnChildDone(CProcessElement *pChild, HRESULT hr);
|
||
|
LPCWSTR GetBaseUrl() { return GetUrl(); }
|
||
|
BOOL IsGlobalLog() { return FALSE; }
|
||
|
|
||
|
// virtual functions overriding CDeliveryAgent
|
||
|
HRESULT AgentPause(DWORD dwFlags);
|
||
|
HRESULT AgentResume(DWORD dwFlags);
|
||
|
HRESULT AgentAbort(DWORD dwFlags);
|
||
|
STDMETHODIMP GetIconLocation(UINT, LPTSTR, UINT, int *, UINT *);
|
||
|
STDMETHODIMP Extract(LPCTSTR, UINT, HICON *, HICON *, UINT);
|
||
|
|
||
|
LPCWSTR GetUrl() { return m_pwszURL; }
|
||
|
ISubscriptionItem *GetStartItem() { return m_pSubscriptionItem; }
|
||
|
|
||
|
BOOL IsChannelFlagSet(DWORD dwFlag) { return dwFlag & m_dwChannelFlags; }
|
||
|
|
||
|
void SetScreenSaverURL(LPCWSTR pwszURL);
|
||
|
|
||
|
protected:
|
||
|
// CDeliveryAgent overrides
|
||
|
HRESULT ModifyUpdateEnd(ISubscriptionItem *pEndItem, UINT *puiRes);
|
||
|
HRESULT StartOperation();
|
||
|
HRESULT StartDownload();
|
||
|
void CleanUp();
|
||
|
|
||
|
// Used during updates
|
||
|
CProcessRoot *m_pProcess;
|
||
|
LPWSTR m_pwszScreenSaverURL;
|
||
|
|
||
|
public:
|
||
|
DWORD m_dwMaxSizeKB;
|
||
|
};
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CRunDeliveryAgent object
|
||
|
// Will run a delivery agent and host it for you
|
||
|
// Create, call Init, then call StartAgent
|
||
|
// Use static function SafeRelease to safely release this class.
|
||
|
//
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
class CRunDeliveryAgent : public ISubscriptionAgentEvents
|
||
|
{
|
||
|
protected:
|
||
|
virtual ~CRunDeliveryAgent();
|
||
|
|
||
|
CRunDeliveryAgentSink *m_pParent;
|
||
|
|
||
|
ULONG m_cRef;
|
||
|
|
||
|
ISubscriptionItem *m_pItem;
|
||
|
ISubscriptionAgentControl *m_pAgent;
|
||
|
|
||
|
HRESULT m_hrResult;
|
||
|
BOOL m_fInStartAgent;
|
||
|
|
||
|
CLSID m_clsidDest;
|
||
|
|
||
|
void CleanUp();
|
||
|
|
||
|
public:
|
||
|
CRunDeliveryAgent();
|
||
|
|
||
|
HRESULT Init(CRunDeliveryAgentSink *pParent, ISubscriptionItem *pItem, REFCLSID rclsidDest);
|
||
|
|
||
|
void LeaveMeAlone() { m_pParent = NULL; }
|
||
|
|
||
|
inline static void SafeRelease(CRunDeliveryAgent * &pThis)
|
||
|
{ if (pThis) { pThis->m_pParent=NULL; pThis->Release(); pThis=NULL; } }
|
||
|
|
||
|
static HRESULT CreateNewItem(ISubscriptionItem **ppItem, REFCLSID rclsidAgent);
|
||
|
|
||
|
// StartAgent will return E_PENDING if agent is running. Otherwise it will return
|
||
|
// synchronous result code from agent.
|
||
|
HRESULT StartAgent();
|
||
|
|
||
|
HRESULT AgentPause(DWORD dwFlags);
|
||
|
HRESULT AgentResume(DWORD dwFlags);
|
||
|
HRESULT AgentAbort(DWORD dwFlags);
|
||
|
|
||
|
// IUnknown members
|
||
|
STDMETHODIMP QueryInterface(REFIID riid, void **ppunk);
|
||
|
STDMETHODIMP_(ULONG) AddRef();
|
||
|
STDMETHODIMP_(ULONG) Release();
|
||
|
|
||
|
// ISubscriptionAgentEvents members
|
||
|
STDMETHODIMP UpdateBegin(const SUBSCRIPTIONCOOKIE *pSubscriptionCookie);
|
||
|
STDMETHODIMP UpdateProgress(const SUBSCRIPTIONCOOKIE *pSubscriptionCookie,
|
||
|
long lSizeDownloaded, long lProgressCurrent, long lProgressMax,
|
||
|
HRESULT hrStatus, LPCWSTR wszStatus);
|
||
|
STDMETHODIMP UpdateEnd(const SUBSCRIPTIONCOOKIE *pSubscriptionCookie,
|
||
|
long lSizeDownloaded,
|
||
|
HRESULT hrResult, LPCWSTR wszResult);
|
||
|
STDMETHODIMP ReportError(const SUBSCRIPTIONCOOKIE *pSubscriptionCookie,
|
||
|
HRESULT hrError, LPCWSTR wszError);
|
||
|
};
|
||
|
|
||
|
class CChannelAgentHolder : public CRunDeliveryAgent,
|
||
|
public IServiceProvider
|
||
|
{
|
||
|
protected:
|
||
|
~CChannelAgentHolder();
|
||
|
|
||
|
public:
|
||
|
CChannelAgentHolder(CChannelAgent *pChannelAgent, CProcessElement *pProcess);
|
||
|
|
||
|
// IUnknown
|
||
|
STDMETHODIMP QueryInterface(REFIID riid, void **ppunk);
|
||
|
STDMETHODIMP_(ULONG) AddRef();
|
||
|
STDMETHODIMP_(ULONG) Release();
|
||
|
|
||
|
// ServiceProvider
|
||
|
STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
|
||
|
|
||
|
protected:
|
||
|
CChannelAgent *m_pChannelAgent;
|
||
|
CProcessElement *m_pProcess;
|
||
|
};
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Process Element objects
|
||
|
//
|
||
|
// User of this class
|
||
|
// 1) Creates & passes in self & element
|
||
|
// 2) Calls Run
|
||
|
// 3) If E_PENDING, will receive call back "OnChildDone"
|
||
|
//
|
||
|
// The purpose of this class is simply to allow us to save our state of
|
||
|
// walking the XML OM, so that we can host another deliver agent
|
||
|
// (webcrawler). This requires us to return out to the thread's message
|
||
|
// pump after sending the "agent start" to the web crawler.
|
||
|
// The if a webcrawl is initiated the class creates its own sink. Classes
|
||
|
// also keep references to their spawned enumerations in case of an
|
||
|
// abort, which comes from the root element (CProcessRoot instance)
|
||
|
//
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
class CProcessElement : public CProcessElementSink, public CRunDeliveryAgentSink
|
||
|
{
|
||
|
public:
|
||
|
CProcessElement(CProcessElementSink *pParent, CProcessRoot *pRoot, IXMLElement *pEle);
|
||
|
~CProcessElement();
|
||
|
|
||
|
// From CRunDeliveryAgent
|
||
|
HRESULT OnAgentEnd(const SUBSCRIPTIONCOOKIE *pSubscriptionCookie,
|
||
|
long lSizeDownloaded, HRESULT hrResult, LPCWSTR wszResult,
|
||
|
BOOL fSynchronous);
|
||
|
|
||
|
typedef HRESULT (CChannelAgent::*PFNHANDLETAG)(LPCWSTR pwszTagName, IXMLElement *pEle);
|
||
|
typedef struct
|
||
|
{
|
||
|
LPCWSTR pwszTagName;
|
||
|
PFNHANDLETAG pfnHandleTag;
|
||
|
} TAGTABLE;
|
||
|
|
||
|
// E_FAIL, E_PENDING, or S_OK
|
||
|
virtual HRESULT Run();
|
||
|
|
||
|
// Called when E_PENDING DoChild returns (from m_pCurChild)
|
||
|
HRESULT OnChildDone(CProcessElement *pChild, HRESULT hr);
|
||
|
|
||
|
|
||
|
HRESULT Pause(DWORD dwFlags);
|
||
|
HRESULT Resume(DWORD dwFlags);
|
||
|
HRESULT Abort(DWORD dwFlags);
|
||
|
|
||
|
IXMLElement *GetCurrentElement() { return m_pChildElement; }
|
||
|
|
||
|
protected:
|
||
|
// Returns E_PENDING, or S_OK if enumeration complete
|
||
|
HRESULT DoEnumeration();
|
||
|
|
||
|
// E_PENDING if webcrawl pending
|
||
|
HRESULT DoChild(CProcessElement *pChild);
|
||
|
|
||
|
// Should return E_PENDING, or S_OK if processing done
|
||
|
// Can return E_ABORT to abort entire CDF processing
|
||
|
virtual HRESULT ProcessItemInEnum(LPCWSTR pwszTagName, IXMLElement *pItem) = 0;
|
||
|
|
||
|
// Called by DoEnumeration when it's done. Return value ignored.
|
||
|
virtual HRESULT EnumerationComplete() { return S_OK; }
|
||
|
|
||
|
// E_PENDING, or E_FAIL
|
||
|
HRESULT DoDeliveryAgent(ISubscriptionItem *pItem, REFCLSID rclsid, LPCWSTR pwszURL=NULL);
|
||
|
HRESULT DoWebCrawl(IXMLElement *pItem, LPCWSTR pwszURL=NULL);
|
||
|
HRESULT DoSoftDist(IXMLElement *pItem);
|
||
|
|
||
|
BOOL ShouldDownloadLogo(IXMLElement *pLogo);
|
||
|
|
||
|
// If relative url, will combine with most recent base URL
|
||
|
// *ppwszRetUrl should be NULL & will be LocalAlloced if needed
|
||
|
HRESULT CombineWithBaseUrl(LPCWSTR pwszUrl, LPWSTR *ppwszRetUrl);
|
||
|
|
||
|
// Returned pointer doesn't need to get freed
|
||
|
LPCWSTR GetBaseUrl() { return m_pParent->GetBaseUrl(); }
|
||
|
BOOL IsGlobalLog() { return m_pParent->IsGlobalLog(); }
|
||
|
|
||
|
CProcessRoot *m_pRoot;
|
||
|
|
||
|
CProcessElement *m_pCurChild;
|
||
|
IXMLElementCollection *m_pCollection;
|
||
|
long m_lIndex;
|
||
|
long m_lMax;
|
||
|
BOOL m_fStartedEnumeration;
|
||
|
BOOL m_fSentEnumerationComplete;
|
||
|
|
||
|
IXMLElement *m_pElement;
|
||
|
IXMLElement *m_pChildElement;
|
||
|
|
||
|
CProcessElementSink *m_pParent;
|
||
|
|
||
|
CRunDeliveryAgent *m_pRunAgent;
|
||
|
};
|
||
|
|
||
|
class CProcessRoot : public CProcessElement
|
||
|
{
|
||
|
public:
|
||
|
CProcessRoot(CChannelAgent *pParent, IXMLElement *pRoot);
|
||
|
~CProcessRoot();
|
||
|
|
||
|
CChannelAgent *m_pChannelAgent;
|
||
|
DWORD m_dwCurSizeKB;
|
||
|
int m_iTotalStarted;
|
||
|
BOOL m_fMaxSizeExceeded;
|
||
|
|
||
|
protected:
|
||
|
ISubscriptionItem *m_pDefaultStartItem;
|
||
|
CUrlTrackingCache *m_pTracking;
|
||
|
|
||
|
public:
|
||
|
HRESULT CreateStartItem(ISubscriptionItem **ppItem);
|
||
|
IUnknown *DefaultStartItem() { return m_pDefaultStartItem; }
|
||
|
|
||
|
HRESULT Run();
|
||
|
|
||
|
// Called when E_PENDING DoChild returns (from m_pCurChild, a CProcessChannel)
|
||
|
HRESULT OnChildDone(CProcessElement *pChild, HRESULT hr);
|
||
|
HRESULT OnAgentEnd(const SUBSCRIPTIONCOOKIE *, long, HRESULT, LPCWSTR, BOOL);
|
||
|
|
||
|
BOOL IsPaused() { return m_pChannelAgent->IsPaused(); }
|
||
|
BOOL IsChannelFlagSet(DWORD dw) { return m_pChannelAgent->IsChannelFlagSet(dw); }
|
||
|
|
||
|
// HRESULT ProcessLogin(IXMLElement *pElement);
|
||
|
HRESULT DoTrackingFromItem(IXMLElement *pItem, LPCWSTR pwszUrl, BOOL fForceLog);
|
||
|
HRESULT DoTrackingFromLog(IXMLElement *pItem);
|
||
|
|
||
|
protected:
|
||
|
HRESULT ProcessItemInEnum(LPCWSTR pwszTagName, IXMLElement *pItem);
|
||
|
|
||
|
LPCWSTR GetBaseUrl() { return m_pChannelAgent->GetUrl(); }
|
||
|
};
|
||
|
|
||
|
class CProcessChannel : public CProcessElement
|
||
|
{
|
||
|
public:
|
||
|
CProcessChannel(CProcessElementSink *pParent, CProcessRoot *pRoot, IXMLElement *pItem);
|
||
|
~CProcessChannel();
|
||
|
|
||
|
HRESULT Run();
|
||
|
|
||
|
void SetGlobalLogFlag(BOOL flag) { m_fglobalLog = flag; }
|
||
|
|
||
|
protected:
|
||
|
HRESULT ProcessItemInEnum(LPCWSTR pwszTagName, IXMLElement *pItem);
|
||
|
|
||
|
LPCWSTR GetBaseUrl() { if (m_bstrBaseUrl) return m_bstrBaseUrl; return m_pParent->GetBaseUrl(); }
|
||
|
|
||
|
BOOL IsGlobalLog() { return m_fglobalLog; }
|
||
|
|
||
|
HRESULT CheckPreCache();
|
||
|
|
||
|
BOOL m_fDownloadedHREF;
|
||
|
BSTR m_bstrBaseUrl;
|
||
|
BOOL m_fglobalLog;
|
||
|
};
|
||
|
|
||
|
class CProcessItem : public CProcessElement
|
||
|
{
|
||
|
public:
|
||
|
CProcessItem(CProcessElementSink *pParent, CProcessRoot *pRoot, IXMLElement *pItem);
|
||
|
~CProcessItem();
|
||
|
|
||
|
protected:
|
||
|
HRESULT ProcessItemInEnum(LPCWSTR pwszTagName, IXMLElement *pItem);
|
||
|
HRESULT EnumerationComplete();
|
||
|
|
||
|
BSTR m_bstrAnchorURL;
|
||
|
BOOL m_fScreenSaver;
|
||
|
BOOL m_fDesktop;
|
||
|
BOOL m_fEmail;
|
||
|
};
|
||
|
|
||
|
class CProcessSchedule : public CProcessElement
|
||
|
{
|
||
|
public:
|
||
|
CProcessSchedule(CProcessElementSink *pParent, CProcessRoot *pRoot, IXMLElement *pItem);
|
||
|
|
||
|
HRESULT Run();
|
||
|
|
||
|
protected:
|
||
|
HRESULT ProcessItemInEnum(LPCWSTR pwszTagName, IXMLElement *pItem);
|
||
|
HRESULT EnumerationComplete();
|
||
|
|
||
|
CDF_TIME m_timeInterval;
|
||
|
CDF_TIME m_timeEarliest;
|
||
|
CDF_TIME m_timeLatest;
|
||
|
|
||
|
SYSTEMTIME m_stStartDate;
|
||
|
SYSTEMTIME m_stEndDate;
|
||
|
|
||
|
public:
|
||
|
TASK_TRIGGER m_tt;
|
||
|
};
|
||
|
|
||
|
class CExtractSchedule : public CProcessElement
|
||
|
{
|
||
|
public:
|
||
|
CExtractSchedule(IXMLElement *pEle, CExtractSchedule *m_pExtractRoot);
|
||
|
HRESULT ProcessItemInEnum(LPCWSTR pwszTagName, IXMLElement *pItem);
|
||
|
HRESULT GetTaskTrigger(TASK_TRIGGER *ptt);
|
||
|
|
||
|
virtual HRESULT Run();
|
||
|
|
||
|
TASK_TRIGGER m_tt;
|
||
|
CExtractSchedule *m_pExtractRoot;
|
||
|
|
||
|
protected:
|
||
|
LPCWSTR GetBaseUrl() { return NULL; }
|
||
|
};
|
||
|
|
||
|
#endif // _CDFAGENT_H
|