HelpDownloadOp Class Reference

#include <helpdownload.h>

Inheritance diagram for HelpDownloadOp:

DownloadOp Operation MessageHandler ListItem CCObject SimpleCCObject List of all members.

Public Member Functions

 HelpDownloadOp ()
virtual ~HelpDownloadOp ()
virtual BOOL OnDocChangingMsg (Document *pChangingDoc, DocChangingMsg::DocState State)
 End (abort) the operation when for instance the current document has been destroyed while downloading.

Static Public Member Functions

static BOOL CheckForNewFiles (BOOL bForeground)
 To parse the HelpAndSupport index file and to check for a new version of said file. The order in which those two operations are done depends on the state of the foreground flag.
static BOOL Init ()
static OpState GetState (String_256 *, OpDescriptor *)
static void DeferFileCopy (const String_256 &pTempFile, const String_256 &pDestFile)
 Records the specified file copy operation as being deferred until we next start up...
static void DoDeferredFileCopy ()
 Check to see if there is a deferred file copy pending and if so, do it.

Static Public Attributes

static String_256 IndexBaseURL = "http://xara.xaraonline.com/XaraX2/Resources/HelpAndSupport"
 Sets the base URL which will be used to check for Help and Support file updates.
static String_256 DeferredCopySrc = ""
 Gives the full path to the deferred copy source file (if any).
static String_256 DeferredCopyDest = ""
 Gives the full path to the deferred copy destination file (if any).
static BOOL HighBandwidth = FALSE
 Sets the base URL which will be used to check for Help and Support file updates.
static String_32 IndexLeafName = "index.xml"
 Gives the leafname of the index file. Useful for testing releases of new file sets.
static INT32 CurrentIndexRelease = 0
 Gives the leafname of the index file. Useful for testing releases of new file sets.

Protected Member Functions

virtual void OnDownloadSuccess ()
 Function called when the download has finished and is successful.
virtual void OnDownloadFail ()
 Function called when the download has failed.
virtual void OnDownloadAbort ()
 Function called when the user aborts download.

Static Protected Member Functions

static CString GetSupportFilepath (const CString &strLeafName=_T(""), const CString &strSupportFolder=_T("HelpAndSupport\\"))
static CString GetIndexFileForLocale (const CString &strLocale)
static CString GetFileForLocale (const CString &strLocale, const CString &strFile)
static CString GetFullResourcePath (const CString &strResourceType, const CString &strFilename, const CString &strLocale=_T(""))
static BOOL MatchFileAttributes (const CString &strFilePath, const COleDateTime &datetime, UINT32 size)
static BOOL CheckIndexFile ()
static BOOL FileOnCD (IXMLDOMDocumentPtr pDoc, const CString &strName, const COleDateTime &datetime, UINT32 size, const CString &strLocale, const CString &strType)
static BOOL LegalFileType (const CString &strFilename)
 Applies some security checking.
static BOOL LegalPathname (const CString &strPathname)
 Applies some security checking.
static BOOL HasBeenDownloaded (IXMLDOMNodePtr pNode)
 Check whether the specified option node has been downloaded before.
static BOOL ProcessDownloadIndex (IXMLDOMDocumentPtr pDoc, BOOL bSilent=FALSE, BOOL *pbDidSomething=NULL)
static BOOL EnoughDiskSpace (const CString &strPath, const UINT32 sizeRequired)
 Check for enough space for the specified file.
static IXMLDOMNodePtr FindFirstOption (IXMLDOMDocumentPtr pDoc, CString *pstrResourceType, CString *pstrLocale)

Detailed Description

Definition at line 153 of file helpdownload.h.


Constructor & Destructor Documentation

HelpDownloadOp::HelpDownloadOp  )  [inline]
 

Definition at line 161 of file helpdownload.h.

00161 {};

virtual HelpDownloadOp::~HelpDownloadOp  )  [inline, virtual]
 

Definition at line 162 of file helpdownload.h.

00162 {};


Member Function Documentation

BOOL HelpDownloadOp::CheckForNewFiles BOOL  bForeground  )  [static]
 

To parse the HelpAndSupport index file and to check for a new version of said file. The order in which those two operations are done depends on the state of the foreground flag.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/04/2004
Parameters:
bForeground - TRUE: check for new index synchronously then parse index [INPUTS] FALSE: parse index then check for new index asyncronously
Returns:
FALSE always (at the moment)

Errors:

Definition at line 265 of file helpdownload.cpp.

00266 {
00267     if (!bForeground)
00268     {
00269         //---------------------------------------------
00270         // First, check for an index file from a previous download
00271         CheckIndexFile();
00272     }
00273 
00274     //---------------------------------------------
00275     // Next ask the server to start an asynchronous download of an index file
00276 
00277     if (bForeground)
00278         Progress::Start(FALSE, _R(IDS_UPDATING_HANDS), -1);
00279 
00280     CString strClientFolder = GetSupportFilepath();
00281     strClientFolder.TrimRight('\\');
00282     BOOL bOK = OpUpdate::UpdateFiles(bForeground, strClientFolder, (CString)IndexBaseURL, (CString)IndexLeafName, _T("UpdateHelpAndSupport"));
00283 
00284     if (bForeground)
00285         Progress::Stop();
00286 
00287     if (bOK && bForeground)
00288     {
00289         //---------------------------------------------
00290         // Finally, in foreground mode Check through the newly downloaded index file
00291         CurrentIndexRelease = 0;            // Reset version checking
00292         BOOL bDidSomething = CheckIndexFile();
00293         if (!bDidSomething)
00294         {
00295             // We found nothing to update so we must tell the user, not just
00296             // leave him dangling.
00297             CHelpDownloadWebDialog dlgReportNothing(_T("HelpAndSupportOK.web"));
00298             dlgReportNothing.DoModal();
00299         }
00300     }
00301 
00302     return FALSE;
00303 }

BOOL HelpDownloadOp::CheckIndexFile  )  [static, protected]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/04/2004
Parameters:
[INPUTS] 
Returns:
TRUE if the check found something to update FALSE if there was nothing to do.

Errors:

Definition at line 320 of file helpdownload.cpp.

00321 {
00322     IXMLDOMDocumentPtr pDoc = CXMLUtils::NewDocument();
00323     HRESULT hr;
00324     BOOL bDidSomething = FALSE;
00325 
00326     // Ensure that the HelpAndSupport folder exists...
00327     ::CreateDirectory(GetSupportFilepath(), NULL);
00328 
00329     VARIANT_BOOL varResult;
00330 
00331     CString strIndexFilename = GetSupportFilepath(GetIndexFileForLocale(_T("")));
00332     hr = pDoc->load(_variant_t(strIndexFilename), &varResult);
00333     if (FAILED(hr) || varResult==VARIANT_FALSE)
00334     {
00335         // Fallback to ENG like WFU does...
00336         strIndexFilename = GetSupportFilepath(GetIndexFileForLocale(_T("ENG")));
00337         hr = pDoc->load(_variant_t(strIndexFilename), &varResult);
00338     }
00339 
00340     // If we loaded an index document successfully then parse it...
00341     if (SUCCEEDED(hr) && varResult==VARIANT_TRUE)
00342     {
00343         // The index file still exists, so we must parse it, check for updates and then delete it
00344         // bSilent = FALSE because this is a user-initiated first call of ProcessDownloadIndex
00345         BOOL bFinishedWithIndex = ProcessDownloadIndex(pDoc, FALSE, &bDidSomething);
00346 // Don't delete the index file because if it was non-English, that could cause the logic above
00347 // to start scanning the English index file!
00348 //      if (bFinishedWithIndex)
00349 //      {
00350 //          ::DeleteFile(strIndexFilename);
00351 //      }
00352     }
00353 
00354     return bDidSomething;
00355 }

void HelpDownloadOp::DeferFileCopy const String_256 pTempFile,
const String_256 pDestFile
[static]
 

Records the specified file copy operation as being deferred until we next start up...

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/04/2004
Returns:
-
See also:
DoDeferredFileCopy

Definition at line 1210 of file helpdownload.cpp.

01211 {
01212     // NOTE: Can't use prefs because this function is called before the prefs system
01213     // has been initialised...
01214 //  GetRegString(hKey, TEXT("DeferredCopySrc"), &DeferredCopySrc);
01215 //  GetRegString(hKey, TEXT("DeferredCopyDest"), &DeferredCopyDest);
01216 
01217     if (DeferredCopySrc.IsEmpty())
01218     {
01219         DeferredCopySrc = pTempFile;
01220         DeferredCopyDest = pDestFile;
01221     }
01222 
01223 //  SetRegString(hKey, TEXT("DeferredCopySrc"), &DeferredCopySrc);
01224 //  SetRegString(hKey, TEXT("DeferredCopyDest"), &DeferredCopyDest);
01225 }

void HelpDownloadOp::DoDeferredFileCopy  )  [static]
 

Check to see if there is a deferred file copy pending and if so, do it.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/04/2004
Returns:
-
See also:
UserHelpDeferFileCopy

Definition at line 1239 of file helpdownload.cpp.

01240 {
01241     // NOTE: Can't use prefs because this function is called before the prefs system
01242     // has been initialised...
01243     HKEY hKey = OpenRegKey(hAppStateRegKey, TEXT("Options\\Update"));
01244     if (hKey)
01245     {
01246         GetRegString(hKey, TEXT("DeferredCopySrc"), &DeferredCopySrc);
01247         GetRegString(hKey, TEXT("DeferredCopyDest"), &DeferredCopyDest);
01248 
01249         if (!DeferredCopySrc.IsEmpty() && !DeferredCopyDest.IsEmpty())
01250         {
01251             BOOL bOK = ::CopyFile((LPCTSTR)DeferredCopySrc, (LPCTSTR)DeferredCopyDest, FALSE);
01252         }
01253 
01254         if (!DeferredCopySrc.IsEmpty())
01255             ::DeleteFile((LPCTSTR)DeferredCopySrc);
01256 
01257         DeferredCopySrc = "";
01258         DeferredCopyDest = "";
01259 
01260         SetRegString(hKey, TEXT("DeferredCopySrc"), &DeferredCopySrc);
01261         SetRegString(hKey, TEXT("DeferredCopyDest"), &DeferredCopyDest);
01262 
01263         CloseRegKey(hKey);
01264     }
01265 }

BOOL HelpDownloadOp::EnoughDiskSpace const CString &  strPath,
const UINT32  sizeRequired
[static, protected]
 

Check for enough space for the specified file.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/04/2004
Returns:
TRUE is enough space, FALSE otherwise

Definition at line 1280 of file helpdownload.cpp.

01281 {
01282     TCHAR szDrive[_MAX_DRIVE + 1];
01283     _tsplitpath(strPath, szDrive, NULL, NULL, NULL);
01284     camStrcat(szDrive, _T("\\"));
01285 
01286     // Get pointer to the GetDiskFreeSpaceEx function if it exists on this platform...
01287     BOOL fResult = FALSE;
01288     P_GDFSE pGetDiskFreeSpaceEx = NULL;
01289     pGetDiskFreeSpaceEx = (P_GDFSE)GetProcAddress(GetModuleHandle ("kernel32.dll"), "GetDiskFreeSpaceExA");
01290 
01291     unsigned __int64 i64FreeBytesToCaller, i64TotalBytes, i64FreeBytes;
01292     DWORD dwSectorsPerCluster, dwBytesPerSector, dwNumberOfFreeClusters, dwTotalNumberOfClusters;
01293 
01294     if (pGetDiskFreeSpaceEx)
01295     {
01296         fResult = pGetDiskFreeSpaceEx(szDrive, (PULARGE_INTEGER)&i64FreeBytesToCaller, (PULARGE_INTEGER)&i64TotalBytes, (PULARGE_INTEGER)&i64FreeBytes);
01297 
01298         // Test to see if our requested cache size is larger than the current available space !!!
01299         if (fResult)
01300             return ((__int64)sizeRequired < i64FreeBytesToCaller);
01301     }
01302     else
01303     {
01304         fResult = GetDiskFreeSpace (szDrive, &dwSectorsPerCluster, &dwBytesPerSector, &dwNumberOfFreeClusters, &dwTotalNumberOfClusters);
01305         if (fResult)
01306         {
01307             // Force 64bit maths so that drives over 4Gb work properly !!! 
01308             i64FreeBytes = (__int64)dwNumberOfFreeClusters * dwSectorsPerCluster * dwBytesPerSector;
01309 
01310             // Test to see if our requested cache size is larger than the current available space !!!
01311             return ((__int64)sizeRequired < i64FreeBytes);
01312         }
01313     }
01314 
01315     // Just incase we failed to call either of the above functions...
01316     if (!fResult) { ERROR3("Can't GetDiskFreeSpace()!"); }
01317     return FALSE;
01318 }

BOOL HelpDownloadOp::FileOnCD IXMLDOMDocumentPtr  pDoc,
const CString &  strName,
const COleDateTime &  datetime,
UINT32  size,
const CString &  strLocale,
const CString &  strType
[static, protected]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/04/2004
Parameters:
[INPUTS] 
Returns:
TRUE if the file exists on the CD (or a larger version exists on CD)

Errors:

Definition at line 1066 of file helpdownload.cpp.

01072 {
01073     if (pDoc==NULL)
01074         return FALSE;
01075 
01076     // Now select the appropriate option file for this resource...
01077     IXMLDOMNodePtr pNode = NULL;
01078     IXMLDOMNodeListPtr pOptionsList = NULL;
01079     CString strOptionSelector;
01080 
01081     // First look for the appropriate bandwidth option
01082     strOptionSelector = _T("//si:Resource/si:Option[");
01083     if (strType==_T("large"))
01084         strOptionSelector += _T("(@size=\"large\" or @size=\"cd\") ");
01085     else
01086         strOptionSelector += _T("(@size=\"small\" or @size=\"large\" or @size=\"cd\") ");
01087 //  if (HighBandwidth)
01088 //      strOptionSelector += _T("@size=\"large\" ");
01089 //  else
01090 //      strOptionSelector += _T("@size=\"small\" ");
01091     strOptionSelector += _T("and @locale=\"") + strLocale + "\" ";
01092     strOptionSelector += _T("and si:Name=\"") + strName + "\" ";
01093     strOptionSelector += _T("]");
01094     HRESULT hr = pDoc->selectNodes(_bstr_t(strOptionSelector), &pOptionsList);
01095     if (SUCCEEDED(hr) && pOptionsList!=NULL)
01096     {
01097         hr = pOptionsList->nextNode(&pNode);
01098         while (pNode)
01099         {
01100             CString strCDName = CXMLUtils::GetNodeString(pNode, _T("si:Name"));
01101             COleDateTime dtCDdate;
01102             BOOL bdateOK = dtCDdate.ParseDateTime(CXMLUtils::GetNodeString(pNode, _T("si:DateTime")), 0, MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_ENGLISH_UK), SORT_DEFAULT));
01103             UINT32 ulCDSize = CXMLUtils::GetNodeLong(pNode, _T("si:Size"));
01104 
01105             // We know that locale and size match already
01106             // Now test the Name, Date and Size
01107             if (dtCDdate.GetStatus()!=COleDateTime::valid || datetime.GetStatus()!=COleDateTime::valid)
01108             {
01109                 if (strCDName==strName
01110 //                  && ulCDSize==size       // Don't check size - if type is same or larger that's good enough
01111                     )
01112                 {
01113                     // The specified file is the same as one on the CD...
01114                     return TRUE;
01115                 }
01116             }
01117             else
01118             {
01119                 if (strCDName==strName
01120                     && dtCDdate==datetime
01121 //                  && ulCDSize==size       // Don't check size - if type is same or larger that's good enough
01122                     )
01123                 {
01124                     // The specified file is the same as one on the CD...
01125                     return TRUE;
01126                 }
01127             }
01128 
01129             hr = pOptionsList->nextNode(&pNode);
01130         }
01131     }
01132 
01133 
01134     return FALSE;
01135 }

IXMLDOMNodePtr HelpDownloadOp::FindFirstOption IXMLDOMDocumentPtr  pDoc,
CString *  pstrResourceType,
CString *  pstrLocale
[static, protected]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/04/2004
Parameters:
[INPUTS] 
Returns:
Full path to the specified resource file

Errors:

Definition at line 833 of file helpdownload.cpp.

00836 {
00837     HRESULT hr;
00838     IXMLDOMNodePtr pOptionNode = NULL;
00839     IXMLDOMNodeListPtr pList = NULL;
00840     IXMLDOMNodePtr pResourceNode = NULL;
00841     CString strType = "";
00842 
00843     // Iterate through the list of Resource nodes, picking the appropriate Option...
00844     hr = pDoc->selectNodes(_bstr_t("//si:Resource"), &pList);
00845     if (SUCCEEDED(hr) && pList!=NULL)
00846     {
00847         hr = pList->nextNode(&pResourceNode);
00848         while (pResourceNode)
00849         {
00850             pOptionNode = NULL;
00851             CString strResourceType = CXMLUtils::GetAttributeString(pResourceNode, _T("type"));
00852             if (pstrResourceType)
00853                 *pstrResourceType = strResourceType;
00854 
00855             // Now select the appropriate option file for this resource...
00856             CString strOptionSelector;
00857             CString strLocale = CResDll::GetCurrentLocale();
00858             if (pstrLocale)
00859                 *pstrLocale = strLocale;
00860             INT32 i=2;
00861             while (pOptionNode==NULL && i--)
00862             {
00863                 if (i==0)
00864                 {
00865                     // Fallback to the default Locale if we didn't find anything yet
00866                     strLocale = _T("ENG");
00867                     if (pstrLocale)
00868                         *pstrLocale = strLocale;
00869                 }
00870 
00871                 // First look for the appropriate bandwidth option
00872                 strOptionSelector = _T("si:Option[");
00873                 if (HighBandwidth)
00874                 {
00875                     strType = _T("large");
00876                     strOptionSelector += _T("@size=\"large\" ");
00877                 }
00878                 else
00879                 {
00880                     strType = _T("small");
00881                     strOptionSelector += _T("@size=\"small\" ");
00882                 }
00883                 strOptionSelector += _T("and @locale=\"") + strLocale + "\" ";
00884                 strOptionSelector += _T("]");
00885                 hr = pResourceNode->selectSingleNode(_bstr_t(strOptionSelector), &pOptionNode);
00886 
00887                 // If we can do high bandwith things but didn't find a specific high bandwidth
00888                 // option then look for a low bandwidth option
00889                 if ((FAILED(hr) || pOptionNode==NULL) && HighBandwidth)
00890                 {
00891                     strOptionSelector = _T("si:Option[");
00892                     strOptionSelector += _T("@size=\"small\" ");
00893                     strOptionSelector += _T("and @locale=\"") + strLocale + "\" ";
00894                     strOptionSelector += _T("]");
00895                     strType = _T("");
00896                     hr = pResourceNode->selectSingleNode(_bstr_t(strOptionSelector), &pOptionNode);
00897                 }
00898             }
00899 
00900             if (pOptionNode==NULL)
00901                 pOptionNode = pResourceNode;
00902 
00903             if (pOptionNode)
00904             {
00905                 // Extract useful info from the OptionNode and then test it...
00906                 CString strURL = CXMLUtils::GetNodeString(pOptionNode, _T("si:URL"));
00907                 CString strFilename = CXMLUtils::GetNodeString(pOptionNode, _T("si:Name"));
00908                 COleDateTime filedate;
00909                 BOOL bdateOK = filedate.ParseDateTime(CXMLUtils::GetNodeString(pOptionNode, _T("si:DateTime")), 0, MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_ENGLISH_UK), SORT_DEFAULT));
00910 
00911                 UINT32 filesize = CXMLUtils::GetNodeLong(pOptionNode, _T("si:Size"));
00912                 CString strDescription = CXMLUtils::GetNodeString(pOptionNode, _T("si:Description"));
00913 
00914                 CString strPathname = GetFullResourcePath(strResourceType, strFilename, strLocale);
00915 
00916                 // Make sure we've got the correct CD Index loaded...
00917 //              if (strLocale!=*pstrCDIndexLocale)
00918 //              {
00919                     IXMLDOMDocumentPtr pCDIndexDoc = CXMLUtils::NewDocument();
00920                     VARIANT_BOOL varResult;
00921 //                  &pstrCDIndexLocale = strLocale;
00922                     CString strCDIndexFilename = GetSupportFilepath(GetFileForLocale(strLocale, _T("cdindex.xml")));
00923                     hr = pCDIndexDoc->load(_variant_t(strCDIndexFilename), &varResult);
00924                     if (FAILED(hr) || varResult==VARIANT_FALSE)
00925                         pCDIndexDoc = NULL;
00926 //              }
00927 
00928                 // Now check to see if we're allowed to download this file
00929                 if (!strFilename.IsEmpty()                                      // If we have a filename
00930                     && strPathname!=DeferredCopyDest                            // And it's not already a deferred copy
00931                     && !MatchFileAttributes(strPathname, filedate, filesize)    // And it differs from the online file
00932                     && !FileOnCD(pCDIndexDoc, strFilename, filedate, filesize, strLocale, strType)  // And it's not on the CD
00933                     && LegalFileType(strFilename)                               // And file type is acceptable
00934                     && LegalPathname(strPathname)                               // And pathname doesn't escape our folder
00935                     )
00936                 {
00937                     // If this file has already been downloaded in this session
00938                     if (HasBeenDownloaded(pOptionNode))
00939                     {
00940                         // Tell the user that something's gone wrong
00941                         String_256 strMessage;
00942                         String_256 strName = CXMLUtils::GetNodeString(pOptionNode, _T("si:Name"));
00943                         strMessage.MakeMsg(_R(IDS_WARN_REPEATDOWNLOAD), &strName);
00944                         Error::SetError(0, strMessage, 0);
00945                         INT32 ret = InformWarning(0, _R(IDS_CONTINUEUPDATE), _R(IDS_STOPUPDATE));
00946                         if (ret==2) // _R(IDS_STOP)
00947                             return NULL;
00948         
00949                         // and continue looking for another option to download...
00950                     }
00951                     else
00952                         // Else return it for downloading
00953                         return pOptionNode;
00954                 }
00955             }
00956             hr = pList->nextNode(&pResourceNode);
00957         }
00958     }
00959 
00960     return NULL;
00961 }

CString HelpDownloadOp::GetFileForLocale const CString &  strLocale,
const CString &  strFile
[static, protected]
 

Definition at line 413 of file helpdownload.cpp.

00414 {
00415     if (strLocale.IsEmpty())
00416         return CResDll::GetCurrentLocale() + _T("\\") + strFile;
00417     else
00418         return strLocale + _T("\\") + strFile;
00419 }

CString HelpDownloadOp::GetFullResourcePath const CString &  strResourceType,
const CString &  strFilename,
const CString &  strLocale = _T("")
[static, protected]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/04/2004
Parameters:
[INPUTS] 
Returns:
Full path to the specified resource file

Errors:

Definition at line 979 of file helpdownload.cpp.

00982 {
00983     CString strPath;
00984 
00985     if (strResourceType.CompareNoCase(_T("Movie"))==0)
00986     {
00987         // It's a movie
00988         strPath = GetSupportFilepath(GetFileForLocale(strLocale, strFilename));
00989     }
00990     else if (strResourceType.CompareNoCase(_T("Help"))==0)
00991     {
00992         // It's a help file
00993         strPath = GetSupportFilepath(GetFileForLocale(strLocale, strFilename));
00994     }
00995     else
00996         ERROR3("Unknown Support Resource Type");
00997 
00998     return strPath;
00999 }

CString HelpDownloadOp::GetIndexFileForLocale const CString &  strLocale  )  [static, protected]
 

Definition at line 404 of file helpdownload.cpp.

00405 {
00406     if (strLocale.IsEmpty())
00407         return CResDll::GetCurrentLocale() + _T("\\") + IndexLeafName;
00408     else
00409         return strLocale + _T("\\") + IndexLeafName;
00410 }

OpState HelpDownloadOp::GetState String_256 ,
OpDescriptor
[static]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/04/2004
Parameters:
[INPUTS] 
Returns:

Errors:

Reimplemented from DownloadOp.

Definition at line 473 of file helpdownload.cpp.

00474 {
00475     OpState OpSt;
00476     return(OpSt);
00477 }

CString HelpDownloadOp::GetSupportFilepath const CString &  strLeafName = _T(""),
const CString &  strSupportFolder = _T("HelpAndSupport\\")
[static, protected]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/04/2004
Parameters:
Leaf name (may include relative folders) [INPUTS]
Returns:
Full path to specified leaf file

Errors:

Definition at line 371 of file helpdownload.cpp.

00372 {
00373     CString strPath;
00374     LPTSTR pathbuffer = strPath.GetBuffer(_MAX_PATH);
00375 
00376     TCHAR achzExePath[_MAX_PATH];
00377     if (::GetModuleFileName(AfxGetInstanceHandle(), achzExePath, _MAX_PATH) == 0)
00378     {
00379         TRACEUSER( "Phil", _T("GetModuleFileName failed in GetSupportFilepath\n"));
00380         return _T("");
00381     }
00382 
00383     TCHAR achzDrive[_MAX_DRIVE];
00384     TCHAR achzDirectory[_MAX_DIR];
00385     TCHAR achzFileName[_MAX_FNAME];
00386     TCHAR achzExtn[_MAX_EXT];
00387     TCHAR achzLeafPath[_MAX_DIR];
00388     TCHAR achzLeafFile[_MAX_FNAME];
00389     TCHAR achzLeafExtension[_MAX_EXT];
00390     _tsplitpath(achzExePath, achzDrive, achzDirectory, achzFileName, achzExtn);
00391     _tsplitpath(strLeafName, NULL, achzLeafPath, achzLeafFile, achzLeafExtension);
00392 
00393     camStrcat(achzDirectory, strSupportFolder);
00394     camStrcat(achzDirectory, achzLeafPath);
00395 
00396     _tmakepath(pathbuffer, achzDrive, achzDirectory, achzLeafFile, achzLeafExtension);
00397 
00398     strPath.ReleaseBuffer();
00399 
00400     return strPath;
00401 }

BOOL HelpDownloadOp::HasBeenDownloaded IXMLDOMNodePtr  pNode  )  [static, protected]
 

Check whether the specified option node has been downloaded before.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/04/2004
Parameters:
[INPUTS] 
Returns:
TRUE if the node contains a Downloaded node with a true value

Errors:

Definition at line 1193 of file helpdownload.cpp.

01194 {
01195     return (pNode!=NULL && CXMLUtils::GetNodeBOOL(pNode, "Downloaded"));
01196 }

BOOL HelpDownloadOp::Init void   )  [static]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/04/2004
Parameters:
[INPUTS] 
Returns:
TRUE if the Init worked ok

Errors:

Reimplemented from DownloadOp.

Definition at line 435 of file helpdownload.cpp.

00436 {
00437     Camelot.DeclareSection("Update", 12);   // 12 because OpUpdate also puts 6 entries here...
00438     Camelot.DeclarePref("Update", "HighBandwidth", &HighBandwidth);
00439     Camelot.DeclarePref("Update", "DeferredCopySrc", &DeferredCopySrc);
00440     Camelot.DeclarePref("Update", "DeferredCopyDest", &DeferredCopyDest);
00441     Camelot.DeclarePref("Update", "HelpAndSupportIndexLeafName", &IndexLeafName);
00442     Camelot.DeclarePref("Update", "HelpAndSupportCurrentIndexRelease", &CurrentIndexRelease);
00443 
00444     HelpDownloadDlg::Init();
00445 
00446     return RegisterOpDescriptor(
00447         0,                                  // Tool ID
00448         _R(IDS_HELPDOWNLOADOP),                 // String resource ID
00449         CC_RUNTIME_CLASS(HelpDownloadOp),   // Runtime class
00450         OPTOKEN_HELPDOWNLOADOP,             // Token string
00451         HelpDownloadOp::GetState,           // GetState function
00452         0,                                  // Help ID
00453         0,                                  // Bubble ID
00454         0,                                  // Resource ID
00455         0                                   // Control ID
00456     );
00457 }

BOOL HelpDownloadOp::LegalFileType const CString &  strFilename  )  [static, protected]
 

Applies some security checking.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/04/2004
Parameters:
[INPUTS] 
Returns:
TRUE if the filename has an acceptable file extension

Errors:

Definition at line 1151 of file helpdownload.cpp.

01152 {
01153     TCHAR achzExtn[_MAX_EXT];
01154 
01155     _tsplitpath(strFilename, NULL, NULL, NULL, achzExtn);
01156 
01157     return (camStrstr(_T(".htm .txt .xml .chm .mpg .avi .jpg .png .gif .web .xar .wix .wmv"), achzExtn)!=NULL);
01158 }

BOOL HelpDownloadOp::LegalPathname const CString &  strPathname  )  [static, protected]
 

Applies some security checking.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/04/2004
Parameters:
[INPUTS] 
Returns:
TRUE if the filename has an acceptable file extension

Errors:

Definition at line 1174 of file helpdownload.cpp.

01175 {
01176     return (camStrstr(strPathname, _T(".."))==NULL);
01177 }

BOOL HelpDownloadOp::MatchFileAttributes const CString &  strFilePath,
const COleDateTime &  datetime,
UINT32  size
[static, protected]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/04/2004
Parameters:
[INPUTS] 
Returns:
TRUE if the file exists and has the specified date or younger and size

Errors:

Definition at line 1015 of file helpdownload.cpp.

01016 {
01017     try
01018     {
01019         HANDLE hFile;
01020         WIN32_FIND_DATA FindFileInfo;
01021         hFile = ::FindFirstFile(strFilePath, &FindFileInfo);
01022         unsigned __int64 i64filesize = 0;
01023         if (hFile!=INVALID_HANDLE_VALUE)
01024         {
01025             i64filesize = ((__int64)FindFileInfo.nFileSizeHigh*((__int64)MAXDWORD+1))+FindFileInfo.nFileSizeLow;
01026             ::FindClose(hFile);
01027         }
01028         // NOTE! For FAT volumes, FindFirstFile automatically converts the local stored times
01029         // into UTC times!!!
01030         // So whether FAT or NTFS, ftLastWriteTime is in UTC.
01031         COleDateTime filetime(FindFileInfo.ftLastWriteTime);
01032 
01033         if (datetime.GetStatus()!=COleDateTime::valid || filetime.GetStatus()!=COleDateTime::valid)
01034         {
01035             TRACE( _T("MatchFileAttributes one or other COleDateTime is invalid!\n"));
01036             return i64filesize==size;
01037         }
01038 
01039 TRACEUSER( "Phil", _T("MFA: File = %s\n"), strFilePath);
01040 TRACEUSER( "Phil", _T("MFA: UK xml time  = %s\n"), datetime.Format(LOCALE_NOUSEROVERRIDE, MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_ENGLISH_UK), SORT_DEFAULT)));
01041 TRACEUSER( "Phil", _T("MFA: UK file time = %s\n"), filetime.Format(LOCALE_NOUSEROVERRIDE, MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_ENGLISH_UK), SORT_DEFAULT)));
01042 TRACEUSER( "Phil", _T("MFA: xml size  = %d\n"), size);
01043 TRACEUSER( "Phil", _T("MFA: file size = %d\n"), i64filesize);
01044         return (filetime>=datetime && i64filesize==size);
01045     }
01046     catch (...)
01047     {
01048         return FALSE;
01049     }
01050 }

BOOL HelpDownloadOp::OnDocChangingMsg Document pChangingDoc,
DocChangingMsg::DocState  State
[virtual]
 

End (abort) the operation when for instance the current document has been destroyed while downloading.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/04/2004
Parameters:
pChangingDoc - [INPUTS] State -
Returns:

Errors:

Reimplemented from MessageHandler.

Definition at line 495 of file helpdownload.cpp.

00496 {
00497     return TRUE;
00498 }

void HelpDownloadOp::OnDownloadAbort  )  [protected, virtual]
 

Function called when the user aborts download.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/04/2004
Parameters:
[INPUTS] 
Returns:

Errors:

Reimplemented from DownloadOp.

Definition at line 631 of file helpdownload.cpp.

00632 {
00633 
00634     // get a pointer to the OpParam so that I can retrieve some useful information
00635     HelpDownloadParam* pGenericParam = (HelpDownloadParam*) pParam;
00636 
00637     String_256 GenericFile = pGenericParam->strURL;
00638     if (IsUserName("Phil"))
00639         TRACE1("HelpDownloadOp::OnDownloadAbort(), file = %s\n", (TCHAR*)GenericFile);
00640 
00641     // stop the import op
00642 //  SelOperation* Op = pGenericParam->m_Op;
00643 //  ((OpMenuImport*)Op)->EndImport();
00644 }

void HelpDownloadOp::OnDownloadFail  )  [protected, virtual]
 

Function called when the download has failed.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/04/2004
Parameters:
[INPUTS] 
Returns:

Errors:

Reimplemented from DownloadOp.

Definition at line 596 of file helpdownload.cpp.

00597 {
00598     //First get a pointer to the parameters
00599     HelpDownloadParam* pGenParam = (HelpDownloadParam*) pParam;
00600 
00601     if (pGenParam==NULL)
00602     {
00603         ERROR2RAW("OpBitmapDownload::OnDownloadFail - no download parameters");
00604         return;
00605     }
00606 
00607     //And put it up as a message
00608     String_256 strMessage;
00609     PathName path(pGenParam->m_pathDestination);
00610     String_256 strLeafname = path.GetFileName();
00611     strMessage.MakeMsg(_R(IDS_HANDS_DOWNLOADFAILED), &strLeafname);
00612     Error::SetError(0, strMessage, 0);
00613     InformError();
00614 
00615 }

void HelpDownloadOp::OnDownloadSuccess  )  [protected, virtual]
 

Function called when the download has finished and is successful.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/04/2004
Parameters:
[INPUTS] 
Returns:

Errors:

Reimplemented from DownloadOp.

Definition at line 515 of file helpdownload.cpp.

00516 {
00517     // get a pointer to the OpParam so that I can retrieve some useful information
00518     HelpDownloadParam* pGenericParam = (HelpDownloadParam*) pParam;
00519 
00520     String_256 GenericFile = (pGenericParam->file).GetFileName();
00521     if (IsUserName("Phil"))
00522         TRACE1("HelpDownloadOp::OnDownloadSuccess(), file = %s\n", (TCHAR*)GenericFile);
00523 
00524     PathName pathTemp = pGenericParam->file;
00525     String_256 URL = pGenericParam->strURL;
00526     PathName pathDestination = pGenericParam->m_pathDestination;
00527 
00528     // NOTE: DON'T "Touch" the downloaded file with the specified time
00529     // There is not an easy way to guarantee that you will be setting
00530     // a UTC time into the file's status (FAT doesn't store UTC).
00531     // Just rely on the time the file was last modified by the downloader...
00532 
00533     if (pGenericParam->m_strResourceType==String_16("Help"))
00534     {
00535         // ------------------------------------------
00536         // File is a new Help file
00537         // Attempt to copy into place
00538         // ::MoveFile(pathTemp.GetPath(), pathDestination.GetPath());
00539         // Can't use MoveFile in case temp path and dest path are on different drives
00540         BOOL bOK = ::CopyFile(pathTemp.GetPath(), pathDestination.GetPath(), FALSE);
00541         if (bOK)
00542         {
00543             ::DeleteFile(pathTemp.GetPath());
00544         }
00545         else
00546         {
00547             // We must remember this temp file location for later processing...
00548             DeferFileCopy(pathTemp.GetPath(), pathDestination.GetPath());
00549         }
00550     }
00551     else
00552     {
00553         // ------------------------------------------
00554         // Generic Help and Support file
00555         // Just copy into final location
00556         // ::MoveFile(pathTemp.GetPath(), pathDestination.GetPath());
00557         // Can't use MoveFile in case temp path and dest path are on different drives
00558         BOOL bOK = ::CopyFile(pathTemp.GetPath(), pathDestination.GetPath(), FALSE);
00559         if (bOK)
00560         {
00561             ::DeleteFile(pathTemp.GetPath());
00562         }
00563         else
00564         {
00565             // We must remember this temp file location for later processing...
00566             DeferFileCopy(pathTemp.GetPath(), pathDestination.GetPath());
00567         }
00568     }
00569 
00570     // Update the download count for this option node in the index xml
00571     // (In memory ONLY!)
00572     IXMLDOMNodePtr pOptionNode = pGenericParam->m_pOptionNode;
00573     if (pOptionNode)
00574     {
00575         CXMLUtils::ReplaceElement(pOptionNode, "Downloaded", TRUE);
00576     }
00577 
00578     BOOL bFinishedWithIndex = ProcessDownloadIndex(pGenericParam->m_pIndexDoc, TRUE);
00579 }

BOOL HelpDownloadOp::ProcessDownloadIndex IXMLDOMDocumentPtr  pDoc,
BOOL  bSilent = FALSE,
BOOL *  pbDidSomething = NULL
[static, protected]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/04/2004
Parameters:
[INPUTS] 
Returns:
TRUE if the Index file can be deleted

Errors:

Definition at line 660 of file helpdownload.cpp.

00661 {
00662     // For each resource declared in the index,
00663     //   Select appropriate option (given current locale and bandwidth prefs)
00664     //   Test whether that option is out of date on the client machine
00665     //   If so, attempt to download it by creating an instance of this Op
00666     HRESULT hr;
00667 
00668     if (pbDidSomething)
00669         *pbDidSomething = FALSE;
00670 
00671     // Check whether we're online or not before even doing any of this!
00672     DWORD Flags = 0;
00673     if (!InternetGetConnectedState(&Flags, 0))
00674         // Not connected - do nothing
00675         return FALSE;
00676 
00677     // Read the update number from the XML
00678     IXMLDOMNodePtr pRoot = NULL;
00679     hr = pDoc->selectSingleNode(_bstr_t("/HelpAndSupportFiles"), &pRoot);
00680     if (SUCCEEDED(hr) && pRoot!=NULL)
00681     {
00682         INT32 ThisRelease = CXMLUtils::GetAttributeLong(pRoot, "ReleaseNumber");
00683         if (CurrentIndexRelease>=ThisRelease)
00684             return FALSE;
00685     }
00686 
00687     // Load up the CD index if we can find it...
00688     // This is not essential - only used to avoid download of files which are on the CD
00689 //  IXMLDOMDocumentPtr pCDIndexDoc = CXMLUtils::NewDocument();
00690 //  VARIANT_BOOL varResult;
00691 //  CString strCDIndexLocale = CResDll::GetCurrentLocale();
00692 //  CString strCDIndexFilename = GetSupportFilepath(GetFileForLocale(strCDIndexLocale, _T("cdindex.xml")));
00693 //  hr = pCDIndexDoc->load(_variant_t(strCDIndexFilename), &varResult);
00694 //  if (FAILED(hr) || varResult==VARIANT_FALSE)
00695 //      pCDIndexDoc = NULL;
00696 
00697     IXMLDOMNodePtr pOptionNode = NULL;
00698     CString strResourceType;
00699     CString strLocale;
00700     pOptionNode = FindFirstOption(pDoc, &strResourceType, &strLocale);
00701     if (pOptionNode)
00702     {
00703         // We have found something that needs to be updated but we must
00704         // ask the user before we go ahead...
00705         if (pbDidSomething)
00706             *pbDidSomething = TRUE;
00707 
00708         if (!bSilent)
00709         {
00710             INT32 ret = IDOK;
00711             CHelpDownloadWebDialog webdlg(_T("NewHelpAndSupportFile.web"));
00712             webdlg.m_bFastConnection = HighBandwidth;
00713             ret = webdlg.DoModal();
00714             if (ret!=IDOK)
00715             {
00716                 if (ret==_R(IDB_IGNORE))
00717                 {
00718                     // The user doesn't want to download help files
00719                     // To streamline the process we will take that to mean that
00720                     // he doesn't want to be asked again either!
00721                     // So we delete the index file and update our record of the
00722                     // current release number to prevent further prompts
00723                     // until a new one is delivered from the server
00724                     CurrentIndexRelease = CXMLUtils::GetAttributeLong(pRoot, "ReleaseNumber");  // Default to 0
00725                     pOptionNode = NULL;
00726                     return TRUE;                // And tell the caller he can delete the file
00727                 }
00728                 else
00729                 {
00730                     // We'll leave the release number alone, leave the index in place
00731                     // and come back to it another time...
00732                     return FALSE;
00733                 }
00734             }
00735             else
00736             {
00737                 BOOL bChanged = (HighBandwidth!=webdlg.m_bFastConnection);
00738 
00739                 // Record the state of the internet speed switch
00740                 HighBandwidth = webdlg.m_bFastConnection;
00741 
00742                 if (bChanged)
00743                 {
00744                     // User changed the bandwidth selection so start scan again
00745                     // (may result in pOptionNode being NULL! But what can you do?)
00746                     pOptionNode = FindFirstOption(pDoc, &strResourceType, &strLocale);
00747                 }
00748             }
00749         }
00750 
00751         if (pOptionNode)
00752         {
00753             // Extract useful info from the OptionNode and then test it...
00754             CString strURL = CXMLUtils::GetNodeString(pOptionNode, _T("si:URL"));
00755             CString strFilename = CXMLUtils::GetNodeString(pOptionNode, _T("si:Name"));
00756             COleDateTime filedate;
00757             BOOL bdateOK = filedate.ParseDateTime(CXMLUtils::GetNodeString(pOptionNode, _T("si:DateTime")), 0, MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_ENGLISH_UK), SORT_DEFAULT));
00758 
00759             UINT32 filesize = CXMLUtils::GetNodeLong(pOptionNode, _T("si:Size"));
00760             CString strDescription = CXMLUtils::GetNodeString(pOptionNode, _T("si:Description"));
00761 
00762             ERROR2IF(strResourceType.IsEmpty(), FALSE, "About to download but Resource type is unknown.");
00763             ERROR2IF(strLocale.IsEmpty(), FALSE, "About to download but Resource locale is unknown.");
00764             CString strPathname = GetFullResourcePath(strResourceType, strFilename, strLocale);
00765 
00766             // Invoke a background download of the specified file...
00767             // When this download has completed, this routine will be called again
00768             // to find the next item in the index for download and this time
00769             // bSilent will be FALSE so it will NOT prompt the user any more.
00770             //
00771             HelpDownloadParam* pParam = new HelpDownloadParam;
00772             if (pParam==NULL)
00773                 return FALSE;
00774 
00775             // Check for enough disk space...
00776             // On both the temp location and the final destination
00777             //
00778             while ((!EnoughDiskSpace((CString)pParam->file.GetPath(), filesize) || !EnoughDiskSpace(strPathname, filesize*2)))
00779             {
00780                 INT32 ret = InformWarning(_R(IDS_NOTENOUGHSPACETODOWNLOAD), _R(IDS_TRYAGAIN), _R(IDS_CANCEL));
00781                 if (ret==2) // _R(IDS_CANCEL)
00782                     return FALSE;
00783             }
00784 
00785             // Don't set pParam->file
00786             // Use default value (a temp path), then copy to pathDestination
00787             // in OnDownloadSuccess handler
00788             // pParam->file             = String_256(strPathname);
00789             pParam->bHasProgressDlg     = TRUE;
00790             pParam->m_pathDestination   = String_256(strPathname);
00791             pParam->strURL              = String_256(strURL);
00792             if (!strDescription.IsEmpty())
00793                 pParam->strDescription  = String_256(strDescription);
00794             pParam->type                = TYPE_SUPPORT;
00795             pParam->m_strResourceType   = String_16(strResourceType);
00796             pParam->priority            = AsynchDownload::PRIORITY_NORMAL;
00797             pParam->m_date              = filedate;
00798             pParam->m_pIndexDoc         = pDoc;
00799             pParam->m_pOptionNode       = pOptionNode;
00800 
00801             OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_HELPDOWNLOADOP);
00802             if (pOpDesc)
00803             {
00804                 pOpDesc->Invoke(pParam, FALSE);
00805             }
00806 
00807             return FALSE;
00808         }
00809     }
00810 
00811     // Nothing useful in the index file so we can mark ourselves up to date
00812     // and delete the index...
00813     CurrentIndexRelease = CXMLUtils::GetAttributeLong(pRoot, "ReleaseNumber");  // Default to 0
00814     return TRUE;
00815 }


Member Data Documentation

INT32 HelpDownloadOp::CurrentIndexRelease = 0 [static]
 

Gives the leafname of the index file. Useful for testing releases of new file sets.

Preference: CurrentIndexRelease Section: Update Range: 0..35536

Definition at line 208 of file helpdownload.h.

String_256 HelpDownloadOp::DeferredCopyDest = "" [static]
 

Gives the full path to the deferred copy destination file (if any).

Preference: DeferredCopyDest Section: Update Range: string (Path)

Definition at line 205 of file helpdownload.h.

String_256 HelpDownloadOp::DeferredCopySrc = "" [static]
 

Gives the full path to the deferred copy source file (if any).

Preference: DeferredCopySrc Section: Update Range: string (Path)

Definition at line 204 of file helpdownload.h.

BOOL HelpDownloadOp::HighBandwidth = FALSE [static]
 

Sets the base URL which will be used to check for Help and Support file updates.

Preference: HighBandwidth Section: Update Range: 0 or 1 (TRUE or FALSE)

Definition at line 206 of file helpdownload.h.

String_256 HelpDownloadOp::IndexBaseURL = "http://xara.xaraonline.com/XaraX2/Resources/HelpAndSupport" [static]
 

Sets the base URL which will be used to check for Help and Support file updates.

Preference: IndexBaseURL Section: Update Range: string (URL)

Definition at line 203 of file helpdownload.h.

String_32 HelpDownloadOp::IndexLeafName = "index.xml" [static]
 

Gives the leafname of the index file. Useful for testing releases of new file sets.

Preference: IndexLeafName Section: Update Range: string

Definition at line 207 of file helpdownload.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:55:07 2007 for Camelot by  doxygen 1.4.4