drt.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 23k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. #include "private.h"
  2. #include "resource.h"
  3. #include <urlmon.h>
  4. #define TF_THISMODULE TF_WEBCHECKCORE
  5. // BUGBUG: These constants (and this file) should be removed from
  6. // webcheck before the final product is shippped.
  7. const TCHAR c_szDefaultDRTURL[] = TEXT("http://adsrv/DRT/");
  8. const TCHAR c_szDefaultLoggedURL[] = TEXT("http://adsrv/drt/cdfpages/page1.htm");
  9. // We cannot define DEFINE_FLOAT_STUFF because there is floating-point
  10. // arithmetic performed in this component.
  11. STDAPI OfflineFolderRegisterServer();
  12. STDAPI OfflineFolderUnregisterServer();
  13. // Prototype of the dialog function
  14. LRESULT CALLBACK DRT_Dialog(HWND, UINT, WPARAM, LPARAM);
  15. //////////////////////////////////////////////////////////////////////////
  16. //
  17. // DRT functions
  18. //
  19. //////////////////////////////////////////////////////////////////////////
  20. class CWCRunSynchronous : public INotificationSink
  21. {
  22.     ULONG   m_cRef;
  23.     int     m_iActive;
  24.     HWND    m_hwndDRT;
  25.     INotificationMgr *m_pManager;
  26.     
  27. public:
  28.     CWCRunSynchronous();
  29.     ~CWCRunSynchronous();
  30.     HRESULT Init();    
  31.     HRESULT SetHwnd(HWND hwnd)  { m_hwndDRT = hwnd; return S_OK; }
  32.     HRESULT UpdateHwnd(INotification  *pNotification);
  33.     INotification *CreateNotification();
  34.     HRESULT RunObject(INotification *pNot, REFCLSID rclsidDest);
  35.     HRESULT OnBeginReport(INotification *pNotification, INotificationReport *pNotificationReport);
  36.     HRESULT OnEndReport(INotification  *pNotification);
  37.     HRESULT OnProgressReport(INotification  *pNotification);
  38.     
  39.     // IUnknown members
  40.     STDMETHODIMP         QueryInterface(REFIID riid, void **punk);
  41.     STDMETHODIMP_(ULONG) AddRef(void);
  42.     STDMETHODIMP_(ULONG) Release(void);
  43.     // INotificationSink members
  44.     STDMETHODIMP         OnNotification(
  45.                 INotification          *pNotification,
  46.                 INotificationReport    *pNotificationReport,
  47.                 DWORD                   dwReserved);
  48. };
  49. CWCRunSynchronous::CWCRunSynchronous()
  50. {
  51.     m_cRef = 1;
  52.     m_iActive=0;
  53.     m_pManager = NULL;
  54. }
  55.     
  56. CWCRunSynchronous::~CWCRunSynchronous()
  57. {
  58.     SAFERELEASE(m_pManager);
  59. }
  60. STDMETHODIMP
  61. CWCRunSynchronous::QueryInterface(REFIID riid, void ** ppv)
  62. {
  63.     *ppv=NULL;
  64.     // Validate requested interface
  65.     if ((IID_IUnknown == riid) ||
  66.         (IID_INotificationSink == riid))
  67.     {
  68.         *ppv=(INotificationSink *)this;
  69.     }
  70.     // Addref through the interface
  71.     if( NULL != *ppv ) {
  72.         ((LPUNKNOWN)*ppv)->AddRef();
  73.         return NOERROR;
  74.     }
  75.     return E_NOINTERFACE;
  76. }
  77. STDMETHODIMP_(ULONG)
  78. CWCRunSynchronous::AddRef(void)
  79. {
  80.     return ++m_cRef;
  81. }
  82. STDMETHODIMP_(ULONG)
  83. CWCRunSynchronous::Release(void)
  84. {
  85.     if( 0L != --m_cRef )
  86.         return m_cRef;
  87.     delete this;
  88.     return 0L;
  89. }
  90. HRESULT CWCRunSynchronous::Init()
  91. {
  92.     HRESULT hr=S_OK;
  93.     // Get reference to the notification manager
  94.     if (!m_pManager)
  95.         hr = CoCreateInstance(CLSID_StdNotificationMgr, NULL, CLSCTX_INPROC_SERVER,
  96.                                 IID_INotificationMgr, (void**)&m_pManager);
  97.     if (FAILED(hr) || !m_pManager)
  98.     {
  99.         return E_FAIL;
  100.     }
  101.     return S_OK;
  102. }
  103. INotification *CWCRunSynchronous::CreateNotification()
  104. {
  105.     INotification *pNot=NULL;
  106.     if (m_pManager)
  107.     {
  108.         m_pManager->CreateNotification(
  109.             NOTIFICATIONTYPE_AGENT_START,
  110.             (NOTIFICATIONFLAGS) 0,
  111.             NULL,
  112.             &pNot,
  113.             0);
  114.     }
  115.     return pNot;
  116. }
  117. HRESULT CWCRunSynchronous::RunObject(INotification *pNot, REFCLSID rclsidDest)
  118. {
  119.     HRESULT hr = E_FAIL;
  120.     if (m_pManager)
  121.     {
  122.         m_iActive ++;
  123.         hr = m_pManager->DeliverNotification(pNot, rclsidDest, 
  124.             DM_NEED_COMPLETIONREPORT,
  125.             (INotificationSink *)this, NULL, 0);
  126.     }
  127.     if (SUCCEEDED(hr))
  128.     {
  129.         MSG msg;
  130.         DBG("CWCRunSynchronous RunItemNow succeeded");
  131.         // Yield and wait for "UpdateEnd" notification
  132.         while (m_iActive > 0 && GetMessage(&msg, NULL, 0, 0))
  133.         {
  134.             TranslateMessage(&msg);
  135.             DispatchMessage(&msg);
  136.         }
  137.     }
  138.     DBG("RunSynchronous RunObject returning");
  139.     return hr;
  140. }
  141. HRESULT CWCRunSynchronous::UpdateHwnd(INotification  *pNotification)
  142. {
  143.     if (m_hwndDRT)
  144.     {
  145.         BSTR bstrURL = NULL;
  146.         if (SUCCEEDED(ReadBSTR(pNotification, NULL, c_szPropCurrentURL, &bstrURL)))
  147.         {
  148.             ASSERT(bstrURL);
  149.             TCHAR szURL[MAX_PATH];
  150.             MyOleStrToStrN(szURL, ARRAYSIZE(szURL), bstrURL);
  151.             PathSetDlgItemPath(m_hwndDRT, IDC_DRTSTATUS, szURL);
  152.             SAFEFREEBSTR(bstrURL);
  153.         }
  154.     }
  155.     
  156.     return S_OK;    
  157. }
  158.                 
  159. // 
  160. // INotificationSink members
  161. //
  162. STDMETHODIMP CWCRunSynchronous::OnNotification(
  163.                 INotification          *pNotification,
  164.                 INotificationReport    *pNotificationReport,
  165.                 DWORD                   dwReserved)
  166. {
  167.     NOTIFICATIONTYPE    nt;
  168.     HRESULT             hr=S_OK;
  169.     DBG("CWCRunSynchronous receiving OnNotification");
  170.     hr = pNotification->GetNotificationInfo(&nt, NULL,NULL,NULL,0);
  171.     if (FAILED(hr))
  172.     {
  173.         DBG("Failed to get notification type!");
  174.         return E_INVALIDARG;
  175.     }
  176.     if (IsEqualGUID(nt, NOTIFICATIONTYPE_BEGIN_REPORT))
  177.         hr = OnBeginReport(pNotification, pNotificationReport);
  178.     else if (IsEqualGUID(nt, NOTIFICATIONTYPE_END_REPORT))
  179.         hr = OnEndReport(pNotification);
  180.     else if (IsEqualGUID(nt, NOTIFICATIONTYPE_PROGRESS_REPORT))
  181.         hr = OnProgressReport(pNotification);
  182.     else DBG("CWCRunSynchronous: Unknown notification type received");        
  183.     // Avoid bogus assert
  184.     if (SUCCEEDED(hr)) hr = S_OK;
  185.     
  186.     return hr;
  187. }
  188. HRESULT CWCRunSynchronous::OnBeginReport(INotification *pNotification, INotificationReport *pNotificationReport)
  189. {
  190.     DBG("CWCRunSynchronous BeginReport received");
  191.     UpdateHwnd(pNotification);
  192.     return S_OK;
  193. }
  194. HRESULT CWCRunSynchronous::OnEndReport(INotification  *pNotification)
  195. {
  196.     DBG("CWCRunSynchronous EndReport received");
  197.     UpdateHwnd(pNotification);
  198.     
  199.     m_iActive --;
  200.     return S_OK;
  201. }
  202. HRESULT CWCRunSynchronous::OnProgressReport(INotification  *pNotification)
  203. {
  204.     DBG("CWCRunSynchronous ProgressReport received");
  205.     UpdateHwnd(pNotification);
  206.     
  207.     return S_OK;
  208. }
  209. #define WF_STATUS_UNINITIALIZED 0
  210. //  We got URL.
  211. #define WF_STATUS_REMOTE        1
  212. //  We got URL & Local File Path
  213. #define WF_STATUS_LOCAL         2
  214. //  Somebody opens this file
  215. #define WF_STATUS_BUSY          3
  216. #define WF_CONTENT_NOTHING      0
  217. #define WF_CONTENT_URL          1
  218. #define WF_CONTENT_PATH         2
  219. #define WF_CONTENT_HANDLE       4
  220. #define WF_CONTENT_TRANSIENT    0x80000000
  221. #define WF_CMD_DELETE       0
  222. #define WF_CMD_CHECK_YES    1
  223. #define WF_CMD_CHECK_NO     2
  224. #define ON_FAILURE_RETURN(HR)   {if(FAILED(HR)) return (HR);}
  225. class CWebFile
  226. {
  227.     protected:
  228.         TCHAR   m_URL[INTERNET_MAX_URL_LENGTH];
  229.         TCHAR   m_Path[MAX_PATH];
  230.         HANDLE  m_Handle;
  231.         UINT    m_uStatus;
  232.         UINT    m_uContentFlags;
  233.         HRESULT WebCrawl(CWCRunSynchronous *);
  234.     public:
  235.         ~CWebFile();
  236.         CWebFile();
  237.         CWebFile(LPCTSTR szURL);
  238.         HRESULT Open(HANDLE &);
  239.         HRESULT Close(void);
  240.         HRESULT Remove(void);
  241.         HRESULT Update(CWCRunSynchronous *);
  242.         HRESULT GetPath(LPTSTR szPath, UINT bufSize)  {
  243.                 if (!(m_uContentFlags & WF_CONTENT_PATH))
  244.                     return E_FAIL;
  245.                 lstrcpyn(szPath, m_Path, bufSize);
  246.                 return S_OK;
  247.             }
  248.         HRESULT GetURL(LPTSTR szURL, UINT bufSize)    {
  249.                 if (!(m_uContentFlags & WF_CONTENT_URL))
  250.                     return E_FAIL;
  251.                 lstrcpyn(szURL, m_URL, bufSize);
  252.                 return S_OK;
  253.             }
  254.         HRESULT SetURL(LPCTSTR szURL)  {
  255.                 if (m_uStatus == WF_STATUS_BUSY)
  256.                     return E_FAIL;
  257.                 lstrcpyn(m_URL, szURL, INTERNET_MAX_URL_LENGTH);
  258.                 m_uContentFlags = WF_CONTENT_URL;
  259.                 m_uStatus = WF_STATUS_REMOTE;
  260.                 return S_OK;
  261.             }
  262. };
  263. CWebFile::CWebFile()
  264. {
  265.     m_Handle = NULL;
  266.     m_URL[0] = m_Path[0] = (TCHAR)0;
  267.     m_uStatus = WF_STATUS_UNINITIALIZED;
  268.     m_uContentFlags = WF_CONTENT_NOTHING;
  269. }
  270. CWebFile::CWebFile(LPCTSTR szURL)
  271. {
  272.     //  BUGBUG. We don't check if it's a valid URL.
  273.     if (!szURL)   {
  274.         CWebFile();
  275.         return;
  276.     }
  277.     
  278.     m_Handle = NULL;
  279.     m_Path[0] = (TCHAR)0;
  280.     SetURL(szURL);
  281. }
  282. CWebFile::~CWebFile()
  283. {
  284.     if (m_uStatus == WF_STATUS_BUSY)
  285.         Close();
  286.     if (m_uStatus == WF_STATUS_LOCAL)   {
  287.         if (m_uContentFlags & WF_CONTENT_TRANSIENT) {
  288.             Remove();
  289.         }
  290.     }
  291.     m_URL[0] = m_Path[0] = (TCHAR)0;
  292.     m_uStatus = WF_STATUS_UNINITIALIZED;
  293.     m_uContentFlags = WF_CONTENT_NOTHING;
  294. }
  295. HRESULT CWebFile::Open(HANDLE & hFile)
  296. {
  297.     if (m_uStatus != WF_STATUS_LOCAL)
  298.         return E_FAIL;
  299.     //  We won't allow multiple open.
  300.     //  BUGBUG should implement ref count. Now only allow access once a time.
  301.     ASSERT(m_uContentFlags & WF_CONTENT_PATH);
  302.     HANDLE  hTmp;
  303.     m_Handle = NULL;
  304.     hTmp = CreateFile(
  305.                 m_Path,
  306.                 GENERIC_READ,
  307.                 FILE_SHARE_READ,
  308.                 NULL,
  309.                 OPEN_EXISTING,
  310.                 FILE_ATTRIBUTE_NORMAL,
  311.                 NULL);
  312.     if (hTmp == INVALID_HANDLE_VALUE) 
  313.         return E_FAIL;
  314.     hFile = hTmp;
  315.     m_Handle = hTmp;
  316.     m_uContentFlags |= WF_CONTENT_HANDLE;
  317.     m_uStatus = WF_STATUS_BUSY;
  318.     return S_OK;
  319. }
  320. HRESULT CWebFile::Close()
  321. {
  322.     if (WF_STATUS_BUSY == m_uStatus)
  323.         m_uStatus = WF_STATUS_LOCAL;
  324.     else
  325.         return E_FAIL;
  326.     if (m_uContentFlags & WF_CONTENT_HANDLE)    {
  327.         BOOL fRet = CloseHandle(m_Handle);
  328.         ASSERT(fRet);
  329.         m_Handle = NULL;
  330.         m_uContentFlags &= (~WF_CONTENT_HANDLE);
  331.     }
  332.     
  333.     return S_OK;
  334. }
  335. HRESULT CWebFile::WebCrawl(CWCRunSynchronous *pCourier)
  336. {
  337.     if (m_uStatus != WF_STATUS_REMOTE)
  338.         return E_INVALIDARG;
  339.     INotification       * pNot = NULL;
  340.     INotificationMgr    * pMgr = NULL;
  341.     HRESULT hr;
  342.     hr = CoInitialize(NULL);
  343.     ON_FAILURE_RETURN(hr);
  344.     hr = CoCreateInstance(CLSID_StdNotificationMgr, NULL, CLSCTX_INPROC_SERVER,
  345.                 IID_INotificationMgr, (void **)&pMgr);
  346.     CoUninitialize();
  347.     ON_FAILURE_RETURN(hr);
  348.     ASSERT(pMgr);
  349.     hr = pMgr->CreateNotification(
  350.                 NOTIFICATIONTYPE_AGENT_START,
  351.                 (NOTIFICATIONFLAGS) 0,
  352.                 NULL, &pNot, 0);
  353.     if (FAILED(hr)) {
  354.         SAFERELEASE(pMgr);
  355.     }
  356.     ASSERT(pNot);
  357.     WCHAR wszURL[INTERNET_MAX_URL_LENGTH];
  358.     MyStrToOleStrN(wszURL, INTERNET_MAX_URL_LENGTH, m_URL);
  359.     WriteOLESTR(pNot, NULL, c_szPropURL, wszURL);
  360.     WriteDWORD(pNot, NULL, c_szPropCrawlFlags, WEBCRAWL_DONT_MAKE_STICKY);
  361.     WriteDWORD(pNot, NULL, c_szPropCrawlLevels, 0);
  362.     hr = pCourier->RunObject(pNot, CLSID_WebCrawlerAgent);
  363.     SAFERELEASE(pMgr);
  364.     SAFERELEASE(pNot);
  365.     return hr;
  366. }
  367. HRESULT CWebFile::Update(CWCRunSynchronous *pCourier)
  368. {
  369.     BYTE    bBuf[MAX_CACHE_ENTRY_INFO_SIZE];
  370.     LPINTERNET_CACHE_ENTRY_INFO pEntry = (LPINTERNET_CACHE_ENTRY_INFO)bBuf;  
  371.     DWORD   dwSize = MAX_CACHE_ENTRY_INFO_SIZE;
  372.     if (m_uStatus == WF_STATUS_LOCAL)   {
  373.         m_uStatus = WF_STATUS_REMOTE;   //  Reload.
  374.         m_uContentFlags &= (~WF_CONTENT_PATH);
  375.     }
  376.     if (m_uStatus != WF_STATUS_REMOTE)
  377.         return E_FAIL;
  378.     ASSERT(pCourier);
  379.     HRESULT hr = WebCrawl(pCourier);
  380.     ON_FAILURE_RETURN(hr); 
  381.     
  382.     if (GetUrlCacheEntryInfo(m_URL, pEntry, &dwSize))   {
  383.         lstrcpyn(m_Path, pEntry->lpszLocalFileName, MAX_PATH);
  384.         m_uStatus = WF_STATUS_LOCAL;
  385.         m_uContentFlags |= WF_CONTENT_PATH;
  386.         return S_OK;
  387.     } else  {
  388.         return E_FAIL;
  389.     }
  390. }
  391. HRESULT CWebFile::Remove()
  392. {
  393.     return E_NOTIMPL;
  394. }
  395. const TCHAR c_szStrURL[] = TEXT("URL");
  396. const TCHAR c_szStrLoggedURL[] = TEXT("LoggedURL");
  397. const TCHAR c_szStrFiles[] = TEXT("Files");
  398. const TCHAR c_szStrNoFiles[] = TEXT("NoFiles");
  399. const TCHAR c_szIntLevels[] = TEXT("Levels");
  400. const TCHAR c_szIntFlags[] = TEXT("Flags");
  401. const TCHAR c_szCDF[] = TEXT("CDF");
  402. const TCHAR c_szCaption[] = TEXT("WebCheck DRT Error");
  403. //BUGBUG-FIXED-OVERFLOW
  404. const TCHAR c_szFailedToGet[] = TEXT("Failed to getnt");
  405. const TCHAR c_szIncorrectlyFetched[] = TEXT("Incorrectly fetchednt");
  406. const TCHAR c_szFailedToDelete[] = TEXT("Failed to deletent");
  407. void CheckCacheLine(TCHAR *strURL, UINT cmd)
  408. {
  409.     BYTE    bBuf[MAX_CACHE_ENTRY_INFO_SIZE];
  410.     LPINTERNET_CACHE_ENTRY_INFO pEntry = (LPINTERNET_CACHE_ENTRY_INFO)bBuf;
  411.     TCHAR szError[256 + INTERNET_MAX_URL_LENGTH];
  412.     DWORD dwSize = sizeof(bBuf);
  413.     LPCTSTR pszErrorText = NULL;
  414.     DWORD dwErrorTextLen = 0; //  Not including NULL terminator
  415.     
  416.     switch (cmd) {
  417.         case WF_CMD_CHECK_YES:
  418.             if (!GetUrlCacheEntryInfo(strURL, pEntry, &dwSize))
  419.             {
  420.                 pszErrorText = c_szFailedToGet;
  421.                 dwErrorTextLen = ARRAYSIZE(c_szFailedToGet) - sizeof(WCHAR);
  422.             }
  423.             break;
  424.             
  425.         case WF_CMD_CHECK_NO:
  426.             if (GetUrlCacheEntryInfo(strURL, pEntry, &dwSize))
  427.             {
  428.                 pszErrorText = c_szIncorrectlyFetched;
  429.                 dwErrorTextLen = ARRAYSIZE(c_szIncorrectlyFetched) - sizeof(WCHAR);
  430.             }
  431.             break;
  432.             
  433.         case WF_CMD_DELETE:
  434.             DeleteUrlCacheEntry(strURL);
  435.             if (GetUrlCacheEntryInfo(strURL, pEntry, &dwSize))
  436.             {
  437.                 pszErrorText = c_szFailedToDelete;
  438.                 dwErrorTextLen = ARRAYSIZE(c_szFailedToDelete) - sizeof(WCHAR);
  439.             }
  440.             break;
  441.             
  442.         default:
  443.             ASSERT(0);
  444.             break;
  445.     }
  446.     if (NULL != pszErrorText)
  447.     {
  448.         ASSERT(0 != dwErrorTextLen);
  449.         lstrcpy(szError, pszErrorText);
  450.         lstrcatn(szError, strURL, ARRAYSIZE(szError));
  451.         MessageBox(NULL, szError, c_szCaption, 0);
  452.     }
  453. }
  454. HRESULT CheckCache(LPCTSTR szURL, CWCRunSynchronous * prs, UINT cmd)
  455. {
  456.     ASSERT(szURL);
  457.     if (szURL[0] == (TCHAR)0)
  458.         return S_FALSE;
  459.     CWebFile wFile(szURL);
  460.     HRESULT hr;
  461.     hr = wFile.Update(prs);
  462.     ON_FAILURE_RETURN(hr);
  463.     HANDLE hFile = NULL;
  464.     hr = wFile.Open(hFile);
  465.     ON_FAILURE_RETURN(hr);
  466.     // Get the file size while we still have the handle open
  467.     UINT cchMax = GetFileSize(hFile, NULL);
  468.     if (0 == cchMax || 0xFFFFFFFF == cchMax)
  469.     {
  470.         wFile.Close();
  471.         return E_FAIL;
  472.     }
  473.     HANDLE hFileMapping = NULL;
  474.     hFileMapping = CreateFileMapping(
  475.             hFile,
  476.             NULL,
  477.             PAGE_READONLY,
  478.             0,
  479.             0,      //  Same size as file.
  480.             NULL    //  No name.
  481.             );
  482.     wFile.Close();
  483.     if (!hFileMapping)
  484.         return E_FAIL;
  485.     char *strBuf = (char *) MapViewOfFile(hFileMapping,
  486.                     FILE_MAP_READ,
  487.                     0, 0, 0);   //  From offset 0, map whole.
  488.     //  Should have internel handle in mapping object.
  489.     BOOL fRet = CloseHandle(hFileMapping);
  490.     ASSERT(fRet);
  491.     if (!strBuf)
  492.         return E_FAIL;
  493.     TCHAR strURL[INTERNET_MAX_URL_LENGTH];
  494.     UINT  i = 0;
  495.     UINT  cch = 0;
  496.     while (cch < cchMax)
  497.     {
  498.         switch (strBuf[cch])
  499.         {
  500.             case 'r':
  501.             case 'n':
  502.                 while (cch < cchMax && (strBuf[cch] == 'r' || strBuf[cch] == 'n'))
  503.                     cch++;
  504.                 if (i > 0)
  505.                 {
  506.                     strURL[i] = 0;
  507.                     CheckCacheLine(strURL, cmd);
  508.                     i = 0;
  509.                 }
  510.                 break;
  511.                 
  512.             case ';':
  513.                 if (0 == i)
  514.                 {
  515.                     // skip the line if the first char is a semi-colon
  516.                     while (cch < cchMax && strBuf[cch] != 'r' && strBuf[cch] != 'n')
  517.                         cch++;
  518.                     while (cch < cchMax && (strBuf[cch] == 'r' || strBuf[cch] == 'n'))
  519.                         cch++;
  520.                     break;
  521.                 }
  522.                 // else fall through
  523.             default:
  524.                 strURL[i] = (TCHAR)strBuf[cch];
  525.                 i++;
  526.                 cch++;
  527.                 ASSERT(INTERNET_MAX_URL_LENGTH > i);
  528.                 break;
  529.         }
  530.     }
  531.     ASSERT(cch == cchMax);
  532.     if (i > 0)    // check for abnormal terminations
  533.     {
  534.         strURL[i] = 0;
  535.         CheckCacheLine(strURL, cmd);
  536.     }
  537.     fRet = UnmapViewOfFile(strBuf);
  538.     ASSERT(fRet);
  539.     return S_OK;
  540. }
  541. HRESULT APIENTRY f3drt(VARIANT *pParam, long *plRetVal)
  542. {
  543.     TCHAR szSection[128];
  544.     
  545.     // Set a default DRT INI file and section in case 
  546.     // the caller didn't specify one.
  547.     CWebFile fIni(TEXT("http://adsrv/drt/drt.ini"));
  548.     lstrcpyn(szSection, TEXT("drt1"), ARRAYSIZE(szSection));
  549.     // Override the default
  550.     if (pParam)
  551.     {
  552.         if (pParam->vt == VT_BSTR)  {
  553.             TCHAR iniURL[INTERNET_MAX_URL_LENGTH];
  554.             BSTR bstr = pParam->bstrVal;
  555.             iniURL[0] = (TCHAR)0;
  556.             MyOleStrToStrN(iniURL, ARRAYSIZE(iniURL),bstr);
  557.             if (PathIsURL(iniURL))  {
  558.                 LPTSTR pBreak = NULL;
  559.                 pBreak = StrChr(iniURL, (WORD)'?');
  560.                 if (pBreak != NULL) {
  561.                     * pBreak = (TCHAR)0;
  562.                     pBreak ++;
  563.                     lstrcpyn(szSection, pBreak, 
  564.                             ARRAYSIZE(szSection));
  565.                 }
  566.                 fIni.SetURL(iniURL);
  567.             }
  568.         }
  569.     }
  570.         
  571.     *plRetVal = -2; // assume error
  572.     HRESULT hr=S_OK;
  573.     CWCRunSynchronous *prs = new CWCRunSynchronous;
  574.     if (!prs || FAILED(prs->Init()))
  575.     {
  576.         if (prs) prs->Release();
  577.         return S_FALSE;
  578.     }
  579.     // Download the INI file
  580.     hr = fIni.Update(prs);
  581.     ON_FAILURE_RETURN(hr);
  582.     TCHAR   targetURL[INTERNET_MAX_URL_LENGTH];
  583.     TCHAR   loggedURL[INTERNET_MAX_URL_LENGTH];
  584.     TCHAR   filesURL[INTERNET_MAX_URL_LENGTH];
  585.     TCHAR   nofilesURL[INTERNET_MAX_URL_LENGTH];
  586.     TCHAR   szPath[MAX_PATH];
  587.     DWORD   dwSize, dwFlags, dwLevels, dwCDF;
  588.     hr = fIni.GetPath(szPath, MAX_PATH);
  589.     ASSERT(SUCCEEDED(hr));
  590.     dwSize = GetPrivateProfileString(
  591.                     szSection,
  592.                     c_szStrURL,
  593.                     c_szDefaultDRTURL,
  594.                     targetURL,
  595.                     INTERNET_MAX_URL_LENGTH,
  596.                     szPath);
  597.                     
  598.     dwSize = GetPrivateProfileString(
  599.                     szSection,
  600.                     c_szStrLoggedURL,
  601.                     c_szDefaultLoggedURL,
  602.                     loggedURL,
  603.                     INTERNET_MAX_URL_LENGTH,
  604.                     szPath);
  605.     dwSize = GetPrivateProfileString(
  606.                     szSection,
  607.                     c_szStrFiles,
  608.                     c_szStrEmpty,
  609.                     filesURL,
  610.                     INTERNET_MAX_URL_LENGTH,
  611.                     szPath);
  612.     CheckCache(filesURL, prs, WF_CMD_DELETE);
  613.     dwSize = GetPrivateProfileString(
  614.                     szSection,
  615.                     c_szStrNoFiles,
  616.                     c_szStrEmpty,
  617.                     nofilesURL,
  618.                     INTERNET_MAX_URL_LENGTH,
  619.                     szPath);
  620.     CheckCache(nofilesURL, prs, WF_CMD_DELETE);
  621.     dwLevels = GetPrivateProfileInt(
  622.                     szSection,
  623.                     c_szIntLevels,
  624.                     1,      //  Default 1 level deep.
  625.                     szPath);
  626.     dwCDF = GetPrivateProfileInt(
  627.                     szSection,
  628.                     c_szCDF,
  629.                     0,
  630.                     szPath);
  631.     dwFlags = GetPrivateProfileInt(
  632.                     szSection,
  633.                     c_szIntFlags,
  634.                     (dwCDF)?(CHANNEL_AGENT_PRECACHE_ALL):(WEBCRAWL_GET_IMAGES | WEBCRAWL_DONT_MAKE_STICKY),
  635.                     szPath);
  636.     INotification *pNot = NULL;
  637.     HWND hWait;    
  638.     // create the AgentStart notification
  639.     pNot = prs->CreateNotification();
  640.     if (!pNot)
  641.         return S_FALSE;
  642.     WCHAR wszURL[INTERNET_MAX_URL_LENGTH];
  643.     MyStrToOleStrN(wszURL, INTERNET_MAX_URL_LENGTH, targetURL);
  644.     WriteOLESTR(pNot, NULL, c_szPropURL, wszURL);
  645.     WriteDWORD(pNot, NULL, c_szPropAgentFlags, DELIVERY_AGENT_FLAG_NO_BROADCAST);
  646.     // Set different properties for webcrawls and channels
  647.     if (dwCDF)
  648.     {
  649.         WriteDWORD(pNot, NULL, c_szPropChannelFlags, dwFlags);
  650.         WriteDWORD(pNot, NULL, c_szPropChannel, 1);
  651.     }
  652.     else
  653.     {
  654.         WriteDWORD(pNot, NULL, c_szPropCrawlFlags, dwFlags);
  655.         WriteDWORD(pNot, NULL, c_szPropCrawlLevels, dwLevels);
  656.     }
  657.  
  658.     // Display the modeless dialog
  659.     hWait = CreateDialog(MLGetHinst(), MAKEINTRESOURCE(IDD_DRT), 
  660.                 GetDesktopWindow(), (DLGPROC)DRT_Dialog);            
  661.     ShowWindow(hWait, SW_SHOW);
  662.     SetWindowPos(hWait, HWND_TOP, 0, 0, 0, 0,
  663.                 SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
  664.     SetForegroundWindow(hWait);
  665.     
  666.     prs->SetHwnd(hWait);
  667.     if (dwCDF)
  668.     {
  669.         // Write something to the log file so logging takes affect
  670.         HIT_LOGGING_INFO hli;
  671.         hli.dwStructSize = sizeof(hli);
  672.         hli.lpszLoggedUrlName = loggedURL;
  673.         GetLocalTime(&(hli.StartTime));
  674.         GetLocalTime(&(hli.EndTime));
  675.         BOOL bRet = WriteHitLogging(&hli);
  676.         ASSERT(bRet);
  677.         
  678.         hr = prs->RunObject(pNot, CLSID_ChannelAgent);
  679.     }
  680.     else
  681.     {
  682.         hr = prs->RunObject(pNot, CLSID_WebCrawlerAgent);
  683.     }
  684.     CheckCache(filesURL, prs, WF_CMD_CHECK_YES);
  685.     CheckCache(nofilesURL, prs, WF_CMD_CHECK_NO);
  686.     prs->SetHwnd(NULL);
  687.     
  688.     pNot->Release(); pNot=NULL;
  689.     // Get rid of the modeless dialog
  690.     if (hWait != NULL)
  691.         DestroyWindow(hWait);
  692.     if (FAILED(hr))
  693.         return S_FALSE;
  694.     *plRetVal = 0;  // no errors
  695.     return S_OK;
  696. }        
  697. //===========================================================================
  698. //
  699. //  FUNCTION: DRT_Dialog(HWND, unsigned, WORD, LONG)
  700. //
  701. //  PURPOSE:  Processes messages for "DRT Test Running" dialog box.
  702. //            This dialog is displayed when a webcheck DRT test is running.
  703. //
  704. //  MESSAGES:
  705. //
  706. //  WM_INITDIALOG - initialize dialog box
  707. //
  708. //===========================================================================
  709. LRESULT CALLBACK DRT_Dialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  710. {
  711.     static RECT rect;
  712.     switch (message) 
  713.     {
  714.         case WM_INITDIALOG:
  715.             // Center the dialog
  716.             GetWindowRect(GetDesktopWindow(), &rect);
  717.             SetWindowPos(hDlg, NULL, rect.left + (rect.right / 4), 
  718.             rect.top + (rect.bottom / 4), 0, 0, SWP_NOSIZE | SWP_NOZORDER);    
  719.             
  720.             return (TRUE);
  721.             break;
  722.         //case WM_COMMAND:
  723.           //  if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
  724.             //{
  725.               //  EndDialog(hDlg, TRUE);
  726.                 //return (TRUE);
  727.             //}
  728.             //break;
  729.     }
  730.     return FALSE;
  731. }