helpdownload.cpp

Go to the documentation of this file.
00001 // $Id: helpdownload.cpp 836 2006-04-18 16:06:15Z gerry $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 
00099 #include "camtypes.h" 
00100 
00101 #include "helpdownload.h"
00102 //#include "webster.h"
00103 #include "impexpop.h"
00104 //#include "resimmap.h" //_R(IDS_HTML_DOWNLOADFAILED)
00105 #include "xmlutils.h"
00106 #include "fileutil.h"
00107 #include "resdll.h"
00108 //#include "phil.h"
00109 #include "helpdownloadwebdialog.h"
00110 #include "helpuser.h"
00111 #include "registry.h"
00112 #include "product.h"
00113 #include "afxdisp.h"
00114 #include "menuops.h"
00115 #include "progress.h"
00116 
00117 #import "webfileupdater.dll"
00118 using namespace WEBFILEUPDATERLib;
00119 
00120 
00121 DECLARE_SOURCE("$Revision: 836 $");
00122 
00123 CC_IMPLEMENT_DYNCREATE(HelpDownloadOp, DownloadOp)
00124 CC_IMPLEMENT_DYNCREATE(HelpDownloadDlg, Operation)
00125 
00126 typedef BOOL (WINAPI *P_GDFSE)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
00127 
00128 #define new CAM_DEBUG_NEW
00129 
00130 
00131 /********************************************************************************************
00132 
00133     Preference: IndexBaseURL
00134     Section:    Update
00135     Range:      string (URL)
00136     Purpose:    Sets the base URL which will be used to check for Help and Support file
00137                 updates
00138 
00139 ********************************************************************************************/
00140 
00141 #ifdef PROD_XS
00142 String_256 HelpDownloadOp::IndexBaseURL = "http://xara.xaraonline.com/XaraXS/Resources/HelpAndSupport";
00143 #else
00144 String_256 HelpDownloadOp::IndexBaseURL = "http://xara.xaraonline.com/XaraX2/Resources/HelpAndSupport";
00145 #endif
00146 
00147 /********************************************************************************************
00148 
00149     Preference: HighBandwidth
00150     Section:    Update
00151     Range:      0 or 1 (TRUE or FALSE)
00152     Purpose:    Sets the base URL which will be used to check for Help and Support file
00153                 updates
00154 
00155 ********************************************************************************************/
00156 
00157 BOOL HelpDownloadOp::HighBandwidth = FALSE;
00158 
00159 
00160 /********************************************************************************************
00161 
00162     Preference: DeferredCopySrc
00163     Section:    Update
00164     Range:      string (Path)
00165     Purpose:    Gives the full path to the deferred copy source file (if any)
00166 
00167 ********************************************************************************************/
00168 
00169     String_256 HelpDownloadOp::DeferredCopySrc = "";
00170 
00171 
00172 /********************************************************************************************
00173 
00174     Preference: DeferredCopyDest
00175     Section:    Update
00176     Range:      string (Path)
00177     Purpose:    Gives the full path to the deferred copy destination file (if any)
00178 
00179 ********************************************************************************************/
00180 
00181     String_256 HelpDownloadOp::DeferredCopyDest = "";
00182 
00183 
00184 /********************************************************************************************
00185 
00186     Preference: IndexLeafName
00187     Section:    Update
00188     Range:      string
00189     Purpose:    Gives the leafname of the index file. Useful for testing releases of new
00190                 file sets
00191 
00192 ********************************************************************************************/
00193 
00194     String_32 HelpDownloadOp::IndexLeafName = "index.xml";
00195 
00196 
00197 /********************************************************************************************
00198 
00199     Preference: CurrentIndexRelease
00200     Section:    Update
00201     Range:      0..35536
00202     Purpose:    Gives the leafname of the index file. Useful for testing releases of new
00203                 file sets
00204 
00205 ********************************************************************************************/
00206 
00207     INT32 HelpDownloadOp::CurrentIndexRelease = 0;
00208 
00209 
00210 /********************************************************************************************
00211 
00212 >   HelpDownloadParam::HelpDownloadParam()
00213 
00214     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00215     Created:    07/04/2004
00216     Inputs:     
00217     Returns:    
00218     Purpose:    Default constructor. Do nothing
00219     Errors:     
00220 
00221 ********************************************************************************************/
00222 
00223 HelpDownloadParam::HelpDownloadParam()
00224 {
00225     PathName pathTemp = FileUtil::GetTemporaryPathName();
00226     file = pathTemp.GetPath();
00227     m_pIndexDoc = NULL;
00228 }
00229 
00230 /********************************************************************************************
00231 
00232 >   HelpDownloadParam::~HelpDownloadParam()
00233 
00234     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00235     Created:    07/04/2004
00236     Inputs:     
00237     Returns:    
00238     Purpose:    Destructor. Do nothing
00239     Errors:     
00240 
00241 ********************************************************************************************/
00242 
00243 HelpDownloadParam::~HelpDownloadParam()
00244 {
00245 //  m_pIndexDoc is a smart ptr, doesn't need to be NULLed
00246 }
00247 
00248 /********************************************************************************************
00249 
00250 >   BOOL HelpDownloadOp::CheckForNewFiles(BOOL bForeground)
00251 
00252     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00253     Created:    07/04/2004
00254     Inputs:     bForeground - TRUE: check for new index synchronously then parse index
00255                              FALSE: parse index then check for new index asyncronously
00256     Returns:    FALSE always (at the moment)
00257     Purpose:    To parse the HelpAndSupport index file and to check for a new version
00258                 of said file.
00259                 The order in which those two operations are done depends on the state
00260                 of the foreground flag.
00261     Errors:     
00262 
00263 ********************************************************************************************/
00264 
00265 BOOL HelpDownloadOp::CheckForNewFiles(BOOL bForeground)
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 }
00304 
00305 
00306 /********************************************************************************************
00307 
00308 >   BOOL HelpDownloadOp::CheckIndexFile()
00309 
00310     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00311     Created:    20/04/2004
00312     Inputs:     
00313     Returns:    TRUE if the check found something to update
00314                 FALSE if there was nothing to do.
00315     Purpose:    
00316     Errors:     
00317 
00318 ********************************************************************************************/
00319 
00320 BOOL HelpDownloadOp::CheckIndexFile()
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 }
00356 
00357 
00358 /********************************************************************************************
00359 
00360 >   CString HelpDownloadOp::GetSupportFilepath(const CString& strLeafName, const CString& strSupportFolder)
00361 
00362     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00363     Created:    20/04/2004
00364     Inputs:     Leaf name (may include relative folders)
00365     Returns:    Full path to specified leaf file
00366     Purpose:    
00367     Errors:     
00368 
00369 ********************************************************************************************/
00370 
00371 CString HelpDownloadOp::GetSupportFilepath(const CString& strLeafName, const CString& strSupportFolder)
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 }
00402 
00403 
00404 CString HelpDownloadOp::GetIndexFileForLocale(const CString& strLocale)
00405 {
00406     if (strLocale.IsEmpty())
00407         return CResDll::GetCurrentLocale() + _T("\\") + IndexLeafName;
00408     else
00409         return strLocale + _T("\\") + IndexLeafName;
00410 }
00411 
00412 
00413 CString HelpDownloadOp::GetFileForLocale(const CString& strLocale, const CString& strFile)
00414 {
00415     if (strLocale.IsEmpty())
00416         return CResDll::GetCurrentLocale() + _T("\\") + strFile;
00417     else
00418         return strLocale + _T("\\") + strFile;
00419 }
00420 
00421 
00422 /********************************************************************************************
00423 
00424 >   BOOL HelpDownloadOp::Init()
00425 
00426     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00427     Created:    07/04/2004
00428     Inputs:     
00429     Returns:    TRUE if the Init worked ok
00430     Purpose:    
00431     Errors:     
00432 
00433 ********************************************************************************************/
00434 
00435 BOOL HelpDownloadOp::Init()
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 }
00458 
00459 
00460 /********************************************************************************************
00461 
00462 >   OpState HelpDownloadOp::GetState(String_256*, OpDescriptor*)
00463 
00464     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00465     Created:    07/04/2004
00466     Inputs:     
00467     Returns:    
00468     Purpose:    
00469     Errors:     
00470 
00471 ********************************************************************************************/
00472 
00473 OpState HelpDownloadOp::GetState(String_256*, OpDescriptor*)
00474 {
00475     OpState OpSt;
00476     return(OpSt);
00477 }
00478 
00479 
00480 /********************************************************************************************
00481 
00482 >   BOOL HelpDownloadOp::OnDocChangingMsg(Document* pChangingDoc, DocChangingMsg::DocState State)
00483 
00484     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00485     Created:    07/04/2004
00486     Inputs:     pChangingDoc -
00487                 State -
00488     Returns:    
00489     Purpose:    End (abort) the operation when for instance the current document has been destroyed
00490                 while downloading.
00491     Errors:     
00492 
00493 ********************************************************************************************/
00494 
00495 BOOL HelpDownloadOp::OnDocChangingMsg(Document* pChangingDoc, DocChangingMsg::DocState State)
00496 {
00497     return TRUE;
00498 }
00499 
00500 
00501 /********************************************************************************************
00502 
00503 >   void HelpDownloadOp::OnDownloadSuccess()
00504 
00505     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00506     Created:    07/04/2004
00507     Inputs:     
00508     Returns:    
00509     Purpose:    Function called when the download has finished and is successful
00510                 
00511     Errors:     
00512 
00513 ********************************************************************************************/
00514 
00515 void HelpDownloadOp::OnDownloadSuccess()
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 }
00580 
00581 
00582 /********************************************************************************************
00583 
00584 >   void HelpDownloadOp::OnDownloadFail()
00585 
00586     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00587     Created:    07/04/2004
00588     Inputs:     
00589     Returns:    
00590     Purpose:    Function called when the download has failed
00591     Errors:     
00592 
00593 ********************************************************************************************/
00594 
00595 
00596 void HelpDownloadOp::OnDownloadFail()
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 }
00616 
00617 
00618 /********************************************************************************************
00619 
00620 >   void HelpDownloadOp::OnDownloadAbort()
00621 
00622     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00623     Created:    07/04/2004
00624     Inputs:     
00625     Returns:    
00626     Purpose:    Function called when the user aborts download
00627     Errors:     
00628 
00629 ********************************************************************************************/
00630 
00631 void HelpDownloadOp::OnDownloadAbort()
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 }
00645 
00646 
00647 /********************************************************************************************
00648 
00649 >   BOOL HelpDownloadOp::ProcessDownloadIndex(IXMLDOMDocumentPtr pDoc, BOOL bSilent, BOOL* pbDidSomething)
00650 
00651     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00652     Created:    07/04/2004
00653     Inputs:     
00654     Returns:    TRUE if the Index file can be deleted
00655     Purpose:    
00656     Errors:     
00657 
00658 ********************************************************************************************/
00659 
00660 BOOL HelpDownloadOp::ProcessDownloadIndex(IXMLDOMDocumentPtr pDoc, BOOL bSilent, BOOL* pbDidSomething)
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 }
00816 
00817 
00818 /********************************************************************************************
00819 
00820 >   IXMLDOMNodePtr HelpDownloadOp::FindFirstOption(IXMLDOMDocumentPtr pDoc,
00821                                                    CString* pstrResourceType,
00822                                                    CString* pstrLocale)
00823 
00824     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00825     Created:    08/04/2004
00826     Inputs:     
00827     Returns:    Full path to the specified resource file
00828     Purpose:    
00829     Errors:     
00830 
00831 ********************************************************************************************/
00832 
00833 IXMLDOMNodePtr HelpDownloadOp::FindFirstOption(IXMLDOMDocumentPtr pDoc,
00834                                                CString* pstrResourceType,
00835                                                CString* pstrLocale)
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 }
00962 
00963 
00964 /********************************************************************************************
00965 
00966 >   CString HelpDownloadOp::GetFullResourcePath(const CString& strResourceType,
00967                                                 const CString& strFilename,
00968                                                 const CString& strLocale = _T(""))
00969 
00970     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00971     Created:    08/04/2004
00972     Inputs:     
00973     Returns:    Full path to the specified resource file
00974     Purpose:    
00975     Errors:     
00976 
00977 ********************************************************************************************/
00978 
00979 CString HelpDownloadOp::GetFullResourcePath(const CString& strResourceType,
00980                                             const CString& strFilename,
00981                                             const CString& strLocale)
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 }
01000 
01001 
01002 /********************************************************************************************
01003 
01004 >   BOOL HelpDownloadOp::MatchFileAttributes(const CString& strFilePath, COleDateTime datetime, UINT32 size)
01005 
01006     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01007     Created:    08/04/2004
01008     Inputs:     
01009     Returns:    TRUE if the file exists and has the specified date or younger and size
01010     Purpose:    
01011     Errors:     
01012 
01013 ********************************************************************************************/
01014 
01015 BOOL HelpDownloadOp::MatchFileAttributes(const CString& strFilePath, const COleDateTime& datetime, UINT32 size)
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 }
01051 
01052 
01053 /********************************************************************************************
01054 
01055 >   BOOL HelpDownloadOp::FileOnCD(IXMLDOMDocumentPtr pDoc, const CString& strFilePath, COleDateTime datetime, UINT32 size, const CString& strType)
01056 
01057     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01058     Created:    08/04/2004
01059     Inputs:     
01060     Returns:    TRUE if the file exists on the CD (or a larger version exists on CD)
01061     Purpose:    
01062     Errors:     
01063 
01064 ********************************************************************************************/
01065 
01066 BOOL HelpDownloadOp::FileOnCD(IXMLDOMDocumentPtr pDoc,
01067                               const CString& strName,
01068                               const COleDateTime& datetime,
01069                               UINT32 size,
01070                               const CString& strLocale,
01071                               const CString& strType)
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 }
01136 
01137 
01138 /********************************************************************************************
01139 
01140 >   BOOL HelpDownloadOp::LegalFileType(const CString& strFilename)
01141 
01142     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01143     Created:    08/04/2004
01144     Inputs:     
01145     Returns:    TRUE if the filename has an acceptable file extension
01146     Purpose:    Applies some security checking
01147     Errors:     
01148 
01149 ********************************************************************************************/
01150 
01151 BOOL HelpDownloadOp::LegalFileType(const CString& strFilename)
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 }
01159 
01160 
01161 /********************************************************************************************
01162 
01163 >   BOOL HelpDownloadOp::LegalPathname(const CString& strPathname)
01164 
01165     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01166     Created:    08/04/2004
01167     Inputs:     
01168     Returns:    TRUE if the filename has an acceptable file extension
01169     Purpose:    Applies some security checking
01170     Errors:     
01171 
01172 ********************************************************************************************/
01173 
01174 BOOL HelpDownloadOp::LegalPathname(const CString& strPathname)
01175 {
01176     return (camStrstr(strPathname, _T(".."))==NULL);
01177 }
01178 
01179 
01180 /********************************************************************************************
01181 
01182 >   BOOL HelpDownloadOp::HasBeenDownloaded(IXMLDOMNodePtr pNode)
01183 
01184     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01185     Created:    08/04/2004
01186     Inputs:     
01187     Returns:    TRUE if the node contains a Downloaded node with a true value
01188     Purpose:    Check whether the specified option node has been downloaded before
01189     Errors:     
01190 
01191 ********************************************************************************************/
01192 
01193 BOOL HelpDownloadOp::HasBeenDownloaded(IXMLDOMNodePtr pNode)
01194 {
01195     return (pNode!=NULL && CXMLUtils::GetNodeBOOL(pNode, "Downloaded"));
01196 }
01197 
01198 
01199 /********************************************************************************************
01200 >   void HelpDownloadOp::DeferFileCopy(const String_256& pTempFile, const String_256& pDestFile)
01201 
01202     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01203     Created:    15/04/2004
01204     Returns:    -
01205     Purpose:    Records the specified file copy operation as being deferred until we next
01206                 start up...
01207     SeeAlso:    DoDeferredFileCopy
01208 ********************************************************************************************/
01209 
01210 void HelpDownloadOp::DeferFileCopy(const String_256& pTempFile, const String_256& pDestFile)
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 }
01226 
01227 
01228 
01229 /********************************************************************************************
01230 >   void HelpDownloadOp::DoDeferredFileCopy()
01231 
01232     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01233     Created:    15/04/2004
01234     Returns:    -
01235     Purpose:    Check to see if there is a deferred file copy pending and if so, do it
01236     SeeAlso:    UserHelpDeferFileCopy
01237 ********************************************************************************************/
01238 
01239 void HelpDownloadOp::DoDeferredFileCopy()
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 }
01266 
01267 
01268 
01269 /********************************************************************************************
01270 
01271 >   BOOL HelpDownloadOp::EnoughDiskSpace(const CString& strPath, const UINT32 sizeRequired)
01272 
01273     Author:         Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01274     Created:        20/04/2004
01275     Returns:        TRUE is enough space, FALSE otherwise
01276     Purpose:        Check for enough space for the specified file
01277 
01278 ********************************************************************************************/
01279 
01280 BOOL HelpDownloadOp::EnoughDiskSpace(const CString& strPath, const UINT32 sizeRequired)
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 }
01319 
01320 
01321 
01322 /********************************************************************************************
01323 
01324 >   BOOL HelpDownloadDlg::Init()
01325 
01326     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01327     Created:    07/04/2004
01328     Inputs:     
01329     Returns:    TRUE if the Init worked ok
01330     Purpose:    
01331     Errors:     
01332 
01333 ********************************************************************************************/
01334 
01335 BOOL HelpDownloadDlg::Init()
01336 {
01337     return RegisterOpDescriptor(
01338         0,                                  // Tool ID
01339         _R(IDS_HELPDOWNLOADDLG),                // String resource ID
01340         CC_RUNTIME_CLASS(HelpDownloadDlg),  // Runtime class
01341         OPTOKEN_HELPDOWNLOADDLG,            // Token string
01342         HelpDownloadDlg::GetState,          // GetState function
01343         0,                                  // Help ID
01344         0,                                  // Bubble ID
01345         0,                                  // Resource ID
01346         0                                   // Control ID
01347     );
01348 
01349 }
01350 
01351 
01352 /********************************************************************************************
01353 
01354 >   OpState HelpDownloadDlg::GetState(String_256*, OpDescriptor*)
01355 
01356     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01357     Created:    07/04/2004
01358     Inputs:     
01359     Returns:    
01360     Purpose:    
01361     Errors:     
01362 
01363 ********************************************************************************************/
01364 
01365 OpState HelpDownloadDlg::GetState(String_256*, OpDescriptor*)
01366 {
01367     OpState OpSt;
01368     return(OpSt);
01369 }
01370 
01371 
01372 /********************************************************************************************
01373 
01374 >   void HelpDownloadDlg::Do(OpDescriptor*)
01375 
01376     Author:         Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01377     Created:        16/04/2004
01378     Returns:        
01379     Purpose:        The default operation is called from the menu
01380 
01381 ********************************************************************************************/
01382 
01383 void HelpDownloadDlg::Do(OpDescriptor* od)
01384 {
01385     HelpDownloadOp::CheckForNewFiles(TRUE);     // Foreground!
01386 }
01387 
01388 
01389 

Generated on Sat Nov 10 03:48:36 2007 for Camelot by  doxygen 1.4.4