00001
00002
00003
00004
00005
00006 #if !defined(AFX_FSINTERNETDOWNLOADER_H__0EEB4A27_85D5_4B6A_BB66_2B11A70AEB7C__INCLUDED_)
00007 #define AFX_FSINTERNETDOWNLOADER_H__0EEB4A27_85D5_4B6A_BB66_2B11A70AEB7C__INCLUDED_
00008
00009 #include "DownloadProperties.h"
00010 #if _MSC_VER > 1000
00011 #pragma once
00012 #endif
00013
00014 #include "list.h"
00015 #include "fsSpeedMeter.h"
00016 #include "fsMirrorURLsMgr.h"
00017 #include "fsMutex.h"
00018 #include "fsArchiveInternetStream.h"
00019 #include "fsArchiveRebuilder.h"
00020 #include "vmsCriticalSection.h"
00021
00022 enum fsSectionState
00023 {
00024 SS_DOWNLOADING,
00025 SS_RECONNECTING,
00026 SS_ERROR,
00027 SS_WRITEERROR,
00028 SS_DONE,
00029 SS_CREATING,
00030 SS_STOPPED,
00031 SS_ERRSTOPPED,
00032 SS_NEEDSTOP
00033 };
00034
00035 struct fsSection_v1
00036 {
00037 UINT uStart, uEnd, uCurrent;
00038 UINT uSpeed;
00039 fsInternetURLFile *file;
00040 fsSectionState state;
00041 fsInternetResult lastErr;
00042 UINT uSpeedLimit;
00043 int iSection;
00044 class fsInternetDownloader *pThis;
00045 };
00046
00047 struct fsSection_v2
00048 {
00049 UINT uStart, uEnd, uCurrent;
00050 UINT uSpeed;
00051 fsInternetURLFile *file;
00052 fsSectionState state;
00053 fsInternetResult lastErr;
00054 UINT uSpeedLimit;
00055 int iSection;
00056 class fsInternetDownloader *pThis;
00057 UINT nMirrorURL;
00058 DWORD adwReserved [20];
00059
00060 fsSection_v2 ()
00061 {
00062 nMirrorURL = UINT_MAX;
00063 ZeroMemory (adwReserved, sizeof (adwReserved));
00064 }
00065 };
00066
00067 struct fsSection_v3
00068 {
00069 UINT64 uStart, uEnd, uCurrent;
00070 UINT uSpeed;
00071 fsInternetURLFile *file;
00072 fsSectionState state;
00073 fsInternetResult lastErr;
00074 UINT uSpeedLimit;
00075 int iSection;
00076 class fsInternetDownloader *pThis;
00077 UINT nMirrorURL;
00078 DWORD adwReserved [20];
00079
00080 fsSection_v3 ()
00081 {
00082 nMirrorURL = UINT_MAX;
00083 ZeroMemory (adwReserved, sizeof (adwReserved));
00084 }
00085 };
00086
00087 struct fsSection
00088 {
00089 UINT64 uStart, uEnd, uCurrent;
00090 UINT uSpeed;
00091 fsInternetURLFile *file;
00092 fsSectionState state;
00093 fsInternetResult lastErr;
00094 UINT uSpeedLimit;
00095 int iSection;
00096 class fsInternetDownloader *pThis;
00097
00098 UINT nMirrorURL;
00099 UINT64 uDStart, uDEnd, uDCurrent;
00100
00101 fsSection ()
00102 {
00103 file = NULL;
00104 nMirrorURL = UINT_MAX;
00105 }
00106
00107 fsSection& operator= (fsSection_v1& s)
00108 {
00109 uStart = s.uStart;
00110 uEnd = s.uEnd == UINT_MAX ? _UI64_MAX : s.uEnd;
00111 uCurrent = s.uCurrent;
00112
00113 uDStart = uStart;
00114 uDCurrent = uCurrent;
00115 uDEnd = uEnd;
00116
00117 uSpeed = s.uSpeed;
00118 state = s.state;
00119 lastErr = s.lastErr;
00120 uSpeedLimit = s.uSpeedLimit;
00121 iSection = s.iSection;
00122 pThis = s.pThis;
00123 return *this;
00124 }
00125
00126 fsSection& operator= (fsSection_v2& s)
00127 {
00128 uStart = s.uStart;
00129 uEnd = s.uEnd == UINT_MAX ? _UI64_MAX : s.uEnd;
00130 uCurrent = s.uCurrent;
00131
00132 uDStart = uStart;
00133 uDCurrent = uCurrent;
00134 uDEnd = uEnd;
00135
00136 uSpeed = s.uSpeed;
00137 state = s.state;
00138 lastErr = s.lastErr;
00139 uSpeedLimit = s.uSpeedLimit;
00140 iSection = s.iSection;
00141 pThis = s.pThis;
00142 nMirrorURL = s.nMirrorURL;
00143 return *this;
00144 }
00145
00146 fsSection& operator= (fsSection_v3& s)
00147 {
00148 uStart = s.uStart;
00149 uEnd = s.uEnd;
00150 uCurrent = s.uCurrent;
00151
00152 uDStart = uStart;
00153 uDCurrent = uCurrent;
00154 uDEnd = uEnd;
00155
00156 uSpeed = s.uSpeed;
00157 state = s.state;
00158 lastErr = s.lastErr;
00159 uSpeedLimit = s.uSpeedLimit;
00160 iSection = s.iSection;
00161 pThis = s.pThis;
00162 nMirrorURL = s.nMirrorURL;
00163 return *this;
00164 }
00165 };
00166
00167 typedef DWORD (*fsDownloaderEventFunc)(enum fsDownloaderEvent ev, UINT uParam, LPVOID lpAppParam);
00168
00169 enum fsDownloaderEvent
00170 {
00171 DE_CONNECTING,
00172 DE_CONNECTED,
00173 DE_FAILCONNECT,
00174 DE_PAUSE,
00175
00176 DE_ERROROCCURED,
00177
00178 DE_SECTIONADDED,
00179
00180 DE_SECTIONSTARTED,
00181
00182 DE_SECTIONSTOPPED,
00183
00184 DE_SECTIONDONE,
00185
00186 DE_WRITEERROR,
00187
00188 DE_REDIRECTING,
00189
00190 DE_REDIRECTINGOKCONTINUEOPENING,
00191
00192 DE_NEEDFILE,
00193
00194 DE_NEEDFILE_FINALINITIALIZATION,
00195
00196 DE_SCR,
00197
00198 DE_QUERYNEWSECTION,
00199
00200 DE_ERRFROMSERVER,
00201
00202 DE_ALLSTOPPEDORDONE,
00203
00204 DE_RESTARTINGBECAUSENORANGES,
00205
00206 DE_DIALOGWITHSERVER,
00207
00208 DE_SECTDOWNLOADING,
00209
00210 DE_EXTERROR,
00211
00212 DE_STARTINGSEARCHINGFORMIRRORS,
00213
00214 DE_CONNECTINGMIRRSERVER,
00215
00216 DE_GETTINGMIRRSEARCHRESULTS,
00217
00218 DE_MIRRFOUND,
00219
00220 DE_MEASURINGMIRRSPEED,
00221
00222 DE_MIRRDONE,
00223
00224 DE_MIRRFAILED,
00225
00226 DE_NOMIRRFOUND,
00227
00228 DE_TRYINGANOTHERMIRROR,
00229
00230 DE_BADFILESIZE,
00231
00232 DE_FILESIZETOOBIG,
00233
00234 DE_CONFIRMARCHIVEDETECTION,
00235 DE_ZIPPREVIEWSTARTED,
00236 DE_ZIPPREVIEWFAILED,
00237
00238 DE_ARCHIVEDETECTED,
00239
00240 DE_MAYADDSECTION,
00241
00242 DE_STARTINGDOWNLOAD,
00243 DE_STARTINGDOWNLOAD_CONNECTING,
00244 DE_STARTINGDOWNLOAD_FAILEDTOCONNECT,
00245
00246 DE_SPEEDISTOOLOW,
00247
00248 };
00249
00250 struct fsDlgWithServerInfo
00251 {
00252 fsInetFileDialogDirection dir;
00253 LPCSTR pszMsg;
00254 int iSection;
00255 };
00256
00257 enum fsInternetDownloaderStates
00258 {
00259 IDS_MIRRSEARCHPERFORMED = 1,
00260 IDS_ZIPPREVIEWPERFORMED = 2,
00261 IDS_ZIPPREVIEWALLOWED = 4,
00262 IDS_USEZIPPREVIEW = 8,
00263 };
00264
00265 #define MAX_NOT_COMPLETED_SECTION_COUNT 20
00266
00267 class fsInternetDownloader
00268 {
00269 public:
00270
00271 BOOL IsCompletelyStopped ();
00272
00273 static void ResetTotalTrafficInfo();
00274
00275 static UINT64 get_TotalSpeed();
00276
00277 static UINT64 get_TotalTraffic();
00278
00279 static BOOL is_PauseMode();
00280 static void set_PauseMode (BOOL bPause);
00281
00282 BOOL is_WasAccessedAtLeastOnce();
00283 FILETIME get_FileDate();
00284
00285 fsString get_URL (BOOL bIncludeAuthInfo = FALSE);
00286
00287 BOOL RemoveMirror (int iIndex);
00288
00289 void Set_Timeout (UINT u);
00290
00291 UINT64 GetLDFileSize();
00292
00293 DWORD GetState();
00294
00295 void UseZipPreview (BOOL b);
00296
00297 LPCSTR Get_FileName();
00298
00299 UINT64 GetDownloadedBytesCount();
00300
00301 int GetFoundMirrorCount();
00302
00303 LPCSTR GetContentType();
00304
00305 void Set_MirrPingTime (int iMirr, DWORD dw);
00306
00307 BOOL IsMirrSearchPerformed();
00308
00309 BOOL MeasureMirrorsSpeed();
00310
00311 int GetMirrorRefs (int iMirrorIndex);
00312
00313 void Set_BaseServerPingTime (DWORD dw);
00314
00315 DWORD Get_BaseServerPingTime();
00316
00317 void AddMirror (fsDownload_NetworkProperties* dnp, BOOL bIsGood = TRUE, BOOL bDontMeasureSpeed = FALSE);
00318
00319 void RemoveAllMirrors ();
00320
00321 BOOL GetMirrorIsGood (int iMirr);
00322
00323 DWORD GetMirrorPingTime (int iMirr);
00324
00325 void Set_MirrDontSearchIfSizeUnk (BOOL b);
00326 void Set_MirrMaxCount(UINT u);
00327 void Set_MirrFileMinSize(UINT u);
00328 void Set_MirrCalcSpeed (BOOL b);
00329 void Set_SearchForMirrors (BOOL bSearch);
00330
00331 BOOL IsSectionCreatingNow ();
00332
00333 fsInternetResult FindMirrors();
00334
00335 fsInternetResult AddMirrorURL (LPCSTR pszUrl, LPCSTR pszUser = NULL, LPCSTR pszPassword = NULL, BOOL bDontMeasureSpeed = FALSE);
00336
00337 int GetMirrorURLCount();
00338
00339 fsDownload_NetworkProperties* MirrorDNP (int iMirror);
00340
00341
00342 fsInternetResult StartDownloading(UINT uStartFrom = 0);
00343
00344 void StopDownloading();
00345
00346 void UseDetailedLog (BOOL b = TRUE);
00347
00348 fsInternetResult LaunchOneMoreSection ();
00349
00350 int GetStoppedSectionCount ();
00351
00352 fsInternetResult QuerySize();
00353
00354 LPCSTR GetSuggestedFileName();
00355
00356 void StopSection();
00357
00358 void LockWriteFile (BOOL bLock);
00359
00360 void DeleteAllSections();
00361
00362 int GetCreatingNowSectionCount(UINT nMirror);
00363
00364 float GetPercentDone ();
00365
00366 fsResumeSupportType IsResumeSupported();
00367
00368 UINT GetTrafficLimit();
00369
00370 void StopOnAccDenied (BOOL b);
00371
00372 void StopOnFileNotFound (BOOL b);
00373
00374 void DontRestartIfNoRanges (BOOL b);
00375
00376 void ResetSections();
00377
00378 void SetOutputFile (HANDLE hOutFile);
00379
00380 UINT64 GetBytesLeft();
00381
00382 int GetDoneSectionCount();
00383
00384 int GetDownloadingSectionCount();
00385
00386 BOOL IsAllSectionsOk();
00387
00388 int GetRunningSectionCount();
00389
00390 UINT64 GetSSFileSize();
00391
00392 BOOL IsRunning();
00393
00394 fsInternetResult GetSectionLastError(int iSection);
00395
00396 BOOL IsHavingError();
00397
00398 BOOL IsStoppedByUser();
00399
00400 BOOL IsDone();
00401
00402 UINT64 GetSectionMaxSize();
00403
00404 void SetMaxReconnectionNumber (UINT uMax);
00405
00406 void SetEventFunc (fsDownloaderEventFunc pfn, LPVOID lpParam);
00407
00408 UINT GetSpeed();
00409
00410 void LimitTraffic (UINT uLimit);
00411
00412 BOOL IsDownloading();
00413
00414 BOOL SaveSectionsState (LPBYTE pBuffer, LPDWORD pdwSize);
00415
00416 BOOL RestoreSectionsState (LPBYTE pBuffer, DWORD dwSize, DWORD dwVer);
00417
00418 BOOL RestoreSectionsState_vlt5 (LPBYTE pBuffer, DWORD dwSize, DWORD dwVer);
00419
00420 BOOL RestoreSectionsState_vlt4 (LPVOID pBuffer, DWORD dwSize);
00421
00422 void SetSectionMinSize (UINT uMinSize);
00423
00424 int GetNumberOfSections();
00425
00426 BOOL SetSection_TrafficLimit (int iSection, UINT uLimit);
00427
00428 BOOL GetSectionInfo (int iSection, fsSection* pSection, BOOL bNoCacheAccounting = FALSE);
00429
00430 void SetRetryTime (DWORD dwMilliseconds);
00431
00432 fsInternetResult AddSection(BOOL bQueryCreation = TRUE);
00433
00434 fsDownload_NetworkProperties* DNP(int nSection = -1);
00435
00436 void ApplyProperties(class fsInternetURLFile *pFile, fsDownload_NetworkProperties* dnp);
00437 void ApplyProxySettings (fsInternetSession* pSession, fsDownload_NetworkProperties* dnp);
00438
00439 fsInternetDownloader();
00440 virtual ~fsInternetDownloader();
00441
00442 protected:
00443 struct _inc_tOU_param {
00444 fsInternetDownloader *pthis;
00445 fsInternetURLFile *pFile;
00446 UINT64 uStartPos;
00447 fsDownload_NetworkProperties *dnp;
00448 };
00449 static DWORD WINAPI _threadOpenUrl (LPVOID lp);
00450
00451 DWORD m_dwForceCacheSizePerSection;
00452
00453 DWORD m_dwDataLenInCache;
00454
00455 static void OnDataDownloaded (UINT64 nDataSize);
00456
00457 static UINT64 m_nTotalTraffic;
00458
00459
00460 static fsSpeedMeter m_TotalSpeed;
00461
00462 static vmsCriticalSection m_csDataRcvd;
00463
00464 static BOOL m_bPauseMode;
00465 BOOL m_bWasAccessedAtLeastOnce;
00466 FILETIME m_fileDate;
00467 CRITICAL_SECTION m_csSections;
00468
00469 BOOL m_bAddingSection;
00470
00471 UINT m_uTimeout;
00472
00473 BOOL IsMayZIP (BOOL bIsExeMay);
00474
00475 void ApplyArchiveRebuilding (fsArchive::fsArchiveRebuilder* ar, UINT64 uAddOffset = 0);
00476 fsArchiveInternetStream* m_pZipPreviewStream;
00477
00478 fsInternetResult CheckIsZIP(UINT64 uStartPosition, fsInternetURLFile **ppFileToCloseIfNeed);
00479 BOOL RestoreSectionsState_v5(LPBYTE pBuffer, DWORD dwSize);
00480 fsString m_strContentType;
00481 DWORD m_dwState;
00482 CRITICAL_SECTION m_csOpenUrl;
00483
00484 fsInternetResult Auto_SearchMirrors ();
00485
00486 BOOL m_bMirrDontSearchIfSizeUnk;
00487 BOOL m_uMirrRecalcSpeedTime;
00488 UINT m_cMaxMirrs;
00489 UINT m_uMirrFileMinSize;
00490 BOOL m_bMirrMeasureSpeed;
00491
00492 UINT FindNotBusyMirrorIndex();
00493
00494 static void _MirrMgrEvents (fsMirrorURLsMgrEvent ev, LPVOID lp);
00495 BOOL m_bSearchForMirrors;
00496
00497 fsMirrorURLsMgr* m_pMirrURLMgr;
00498 BOOL m_bDetLog;
00499
00500 static void _InetFileDialogFunc (fsInetFileDialogDirection dir, LPCSTR pszMsg, LPVOID lp1, LPVOID lp2);
00501
00502 fsInternetResult QuerySize (fsInternetURLFile* file);
00503 fsString m_strSuggFileName;
00504
00505 int m_cBaseSectCreatingNow;
00506 fsResumeSupportType m_enRST;
00507 CRITICAL_SECTION m_csDone;
00508
00509 fsInternetURLFile *m_pOpeningFile;
00510
00511 BOOL m_bStopOnAccDenied;
00512 BOOL m_bStopOnFileNotFound;
00513
00514 BOOL m_bDontRestartIfNoRanges;
00515
00516 UINT64 m_uSSFileSize;
00517 UINT64 m_uLDFileSize;
00518
00519 void UpdateTrafficLimit();
00520 fsSpeedMeter m_speed;
00521
00522 BOOL SleepInterval();
00523 CRITICAL_SECTION m_csAddSection;
00524
00525 DWORD Event (fsDownloaderEvent enEvent, UINT uDesc = 0);
00526 UINT m_uTrafficLimit;
00527
00528 volatile UINT m_cThreads, m_cRunningThreads;
00529 volatile BOOL m_bNeedStop;
00530 UINT m_uSectionMinSize;
00531 CRITICAL_SECTION m_csWriteToFile;
00532 HANDLE m_hOutFile;
00533 UINT m_uRetryTime;
00534
00535 fsInternetResult OpenUrl (UINT64 uStartPos, fsInternetURLFile **ppFile, int iSectIndex, UINT &nMirror, BOOL bCheckFileSize = FALSE, LPCSTR pszContentTypeReq = NULL);
00536 fsInternetResult OpenUrl_imp (UINT64 uStartPos, fsInternetURLFile **ppFile, int iSectIndex, UINT &nMirror, BOOL bCheckFileSize, int iAttempt, LPCSTR pszContentTypeReq = NULL);
00537
00538 static DWORD WINAPI _threadDownload(LPVOID lp);
00539
00540 fsInternetResult CreateAdditionalSection (BOOL bQueryCreation = TRUE);
00541
00542 BOOL CreateSection (fsSection §, BOOL bCreateThread = TRUE, BOOL bReduceSCN = TRUE);
00543
00544 fsInternetResult CreateMainSection (UINT uStartFrom = 0, BOOL bQueryCreation = TRUE);
00545 BOOL m_bErrDownloading;
00546 fsDownload_NetworkProperties m_dnp;
00547
00548 struct fsSectionEx : public fsSection
00549 {
00550 DWORD dwCacheLen;
00551
00552 fsSectionEx (const fsSection& s) {
00553 CopyMemory (this, &s, sizeof (s));
00554 dwCacheLen = 0;
00555 }
00556
00557 fsSectionEx () {
00558 dwCacheLen = 0;
00559 }
00560 };
00561 fs::list <fsSectionEx> m_vSections;
00562 fsDownloaderEventFunc m_pfnEvents;
00563 LPVOID m_lpEvent;
00564 UINT m_uMaxAttempts;
00565 BOOL m_bNoNewSections;
00566
00567 struct fsMirrorURLInfo
00568 {
00569 fsDownload_NetworkProperties dnp;
00570 DWORD dwPingTime;
00571
00572 BOOL bIsGood;
00573
00574 int cSectsCreatingNow;
00575
00576 fsMirrorURLInfo ()
00577 {
00578 dwPingTime = UINT_MAX;
00579 bIsGood = TRUE;
00580 cSectsCreatingNow = 0;
00581 }
00582 };
00583
00584 fs::list <fsMirrorURLInfo> m_vMirrs;
00585 DWORD m_dwBaseServerPingTime;
00586 fsString m_strFileName;
00587
00588 int m_cMirrsFound;
00589
00590 private:
00591 static BOOL __threadDownload_flushdata (fsSectionEx* sect, LPBYTE pBuffer, DWORD dwRead, LPBYTE &pbCache, DWORD &dwCacheSize, DWORD &dwCacheLen);
00592 };
00593
00594 #endif