Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

680 lines
14 KiB

  1. /************************************************************************
  2. Copyright (c) 2000 - 2000 Microsoft Corporation
  3. Module Name :
  4. progressivedl.h
  5. Abstract :
  6. Main header file for downloader.
  7. Author :
  8. Revision History :
  9. ***********************************************************************/
  10. #pragma once
  11. #define MIN(a, b) (a>b ? b:a)
  12. #define MAX(a, b) (a>b ? a:b)
  13. #define MAX_REPLY_DATA (2 * INTERNET_MAX_URL_LENGTH)
  14. #define E_RETRY HRESULT_FROM_WIN32( ERROR_RETRY )
  15. #define BG_E_HEADER_NOT_FOUND HRESULT_FROM_WIN32( ERROR_HTTP_HEADER_NOT_FOUND )
  16. //
  17. // valid in HTTP 1.1, but not defined in the Windows-XP version of wininet.h
  18. //
  19. #define HTTP_STATUS_RANGE_NOT_SATISFIABLE 416
  20. //----------------------------------------------------------------------
  21. typedef HRESULT (*QMCALLBACK)(DWORD, DWORD, LPBYTE, DWORD);
  22. #define MAX_VIA_HEADER_LENGTH 300
  23. //
  24. // This is the size of the read buffer for downloads. 48kb is dramatically better than 32kb or 64kb,
  25. // for obscure reasons.
  26. //
  27. #define FILE_DATA_BUFFER_LEN (48*1024)
  28. extern BYTE g_FileDataBuffer[];
  29. //--------------------------------------------
  30. struct URL_INFO
  31. {
  32. HINTERNET hInternet;
  33. HINTERNET hConnect;
  34. FILETIME UrlModificationTime;
  35. UINT64 FileSize;
  36. DWORD dwFlags;
  37. bool bHttp11;
  38. bool bRange;
  39. bool fProxy;
  40. //
  41. // Most of these could be stack variables, but they are too big.
  42. //
  43. TCHAR HostName[INTERNET_MAX_URL_LENGTH + 1];
  44. // host-relative URL
  45. //
  46. TCHAR UrlPath[INTERNET_MAX_URL_LENGTH + 1];
  47. INTERNET_PORT Port;
  48. // a copy of <UrlPath> with range information appended as parameters
  49. //
  50. TCHAR BlockUrl[INTERNET_MAX_URL_LENGTH + 1];
  51. TCHAR UserName[UNLEN + 1];
  52. TCHAR Password[UNLEN + 1];
  53. PROXY_SETTINGS_CONTAINER * ProxySettings;
  54. CAutoString ProxyHost;
  55. TCHAR ViaHeader[ MAX_VIA_HEADER_LENGTH + 1];
  56. const CCredentialsContainer * Credentials;
  57. //--------
  58. URL_INFO(
  59. LPCTSTR a_Url,
  60. const PROXY_SETTINGS * a_ProxySettings,
  61. const CCredentialsContainer * a_Credentials,
  62. LPCTSTR HostId = NULL
  63. );
  64. ~URL_INFO();
  65. void Cleanup();
  66. QMErrInfo Connect();
  67. void Disconnect();
  68. BOOL
  69. GetProxyUsage(
  70. HINTERNET hRequest,
  71. QMErrInfo *pQMErrInfo
  72. );
  73. };
  74. //---------------------------------------------
  75. class CUploadJob;
  76. class CJobManager;
  77. class ITransferCallback
  78. {
  79. public:
  80. virtual bool
  81. DownloaderProgress(
  82. UINT64 BytesTransferred,
  83. UINT64 BytesTotal
  84. ) = 0;
  85. virtual bool
  86. PollAbort() = 0;
  87. virtual bool
  88. UploaderProgress(
  89. UINT64 BytesTransferred
  90. ) = 0;
  91. };
  92. class Downloader
  93. {
  94. public:
  95. virtual HRESULT Download( LPCTSTR szURL,
  96. LPCTSTR szDest,
  97. UINT64 Offset,
  98. ITransferCallback *CallBack,
  99. QMErrInfo *pErrInfo,
  100. HANDLE hToken,
  101. BOOL bThrottle,
  102. const PROXY_SETTINGS * pProxySettings, // optional
  103. const CCredentialsContainer * Credentials,
  104. const StringHandle HostId = StringHandle() // optional
  105. ) = 0;
  106. virtual HRESULT GetRemoteFileInformation(
  107. HANDLE hToken,
  108. LPCTSTR szURL,
  109. UINT64 * pFileSize,
  110. FILETIME *pFileTime,
  111. QMErrInfo *pErrInfo,
  112. const PROXY_SETTINGS * pProxySettings, //optional
  113. const CCredentialsContainer * Credentials, // optional
  114. const StringHandle HostId = StringHandle() // optional
  115. ) = 0;
  116. virtual void
  117. Upload(
  118. CUploadJob * job,
  119. ITransferCallback * CallBack,
  120. HANDLE Token,
  121. QMErrInfo & ErrInfo
  122. ) = 0;
  123. virtual ~Downloader() {}
  124. protected:
  125. };
  126. HRESULT CreateHttpDownloader( Downloader **ppDownloader, QMErrInfo *pErrInfo );
  127. void DeleteHttpDownloader( Downloader * pDownloader );
  128. extern DWORD g_dwDownloadThread;
  129. extern HWND ghPDWnd;
  130. //
  131. // conversion factor to go from time in milliseconds to time in 100-nanoseconds.
  132. //
  133. #define ONE_MSEC_IN_100_NSEC (10 * 1000)
  134. class CPeriodicTimer
  135. {
  136. public:
  137. CPeriodicTimer(
  138. LPSECURITY_ATTRIBUTES Security = NULL,
  139. BOOL ManualReset = FALSE,
  140. LPCTSTR Name = NULL
  141. )
  142. {
  143. m_handle = CreateWaitableTimer( Security, ManualReset, Name );
  144. if (!m_handle)
  145. {
  146. ThrowLastError();
  147. }
  148. }
  149. ~CPeriodicTimer()
  150. {
  151. if (m_handle)
  152. {
  153. CloseHandle( m_handle );
  154. }
  155. }
  156. BOOL Start(
  157. LONG Period,
  158. BOOL fResume = FALSE,
  159. PTIMERAPCROUTINE fn = NULL,
  160. LPVOID arg = NULL
  161. )
  162. {
  163. LARGE_INTEGER Time;
  164. //
  165. // negative values are relative; positive values are absolute.
  166. // The period is in milliseconds, but the start time is in units of 100-nanoseconds,
  167. //
  168. Time.QuadPart = -1 * Period * ONE_MSEC_IN_100_NSEC;
  169. return SetWaitableTimer( m_handle, &Time, Period, fn, arg, fResume );
  170. }
  171. BOOL Stop()
  172. {
  173. return CancelWaitableTimer( m_handle );
  174. }
  175. BOOL Wait(
  176. LONG msec = INFINITE
  177. )
  178. {
  179. if (WAIT_OBJECT_0 != WaitForSingleObject( m_handle, msec ))
  180. {
  181. return FALSE;
  182. }
  183. return TRUE;
  184. }
  185. private:
  186. HANDLE m_handle;
  187. };
  188. //
  189. // Network rate is in bytes per second.
  190. //
  191. typedef float NETWORK_RATE;
  192. class CNetworkInterface
  193. {
  194. public:
  195. //
  196. // snapshot indices
  197. //
  198. enum
  199. {
  200. BLOCK_START = 0,
  201. BLOCK_END,
  202. BLOCK_INTERVAL_END,
  203. BLOCK_COUNT
  204. };
  205. typedef float SECONDS;
  206. //
  207. // public interface
  208. //
  209. CNetworkInterface();
  210. void Reset();
  211. void SetInterfaceSpeed();
  212. HRESULT
  213. TakeSnapshot(
  214. int SnapshotIndex
  215. );
  216. HRESULT
  217. SetInterfaceIndex(
  218. const TCHAR host[]
  219. );
  220. BOOL
  221. SetTimerInterval(
  222. SECONDS interval
  223. );
  224. NETWORK_RATE GetInterfaceSpeed()
  225. {
  226. return m_ServerSpeed;
  227. }
  228. float GetPercentFree()
  229. {
  230. return m_PercentFree;
  231. }
  232. void ResetInterface()
  233. {
  234. m_InterfaceIndex = -1;
  235. }
  236. void Wait() { m_Timer.Wait(); }
  237. void StopTimer() { m_Timer.Stop(); }
  238. void CalculateIntervalAndBlockSize( UINT64 MaxBlockSize );
  239. DWORD m_BlockSize;
  240. SECONDS m_BlockInterval;
  241. private:
  242. static const NETWORK_RATE DEFAULT_SPEED;
  243. struct NET_SNAPSHOT
  244. {
  245. LARGE_INTEGER TimeStamp;
  246. UINT BytesIn;
  247. UINT BytesOut;
  248. };
  249. //
  250. // index of the interface that Wininet would use to talk to the server.
  251. //
  252. DWORD m_InterfaceIndex;
  253. //
  254. // the "start" and "end" pictures of network activity.
  255. //
  256. NET_SNAPSHOT m_Snapshots[BLOCK_COUNT];
  257. //
  258. // the apparent speed of the connection to our server
  259. //
  260. NETWORK_RATE m_ServerSpeed;
  261. //
  262. // The local interface's apparent speed
  263. //
  264. NETWORK_RATE m_NetcardSpeed;
  265. //
  266. //
  267. //
  268. float m_PercentFree;
  269. //
  270. // Error value from previous snapshots in the current series {BLOCK_START, BLOCK_END, INTERVAL_END}.
  271. //
  272. HRESULT m_SnapshotError;
  273. //
  274. // true if all three snapshots in the current series are valid.
  275. // If so, then it is safe to calculate network speed and server speed.
  276. //
  277. bool m_SnapshotsValid;
  278. MIB_IFROW m_TempRow;
  279. //
  280. // The download thread sends only one packet per timer notification.
  281. // This is the timer.
  282. //
  283. CPeriodicTimer m_Timer;
  284. enum DOWNLOAD_STATE
  285. {
  286. DOWNLOADED_BLOCK = 0x55,
  287. SKIPPED_ONE_BLOCK,
  288. SKIPPED_TWO_BLOCKS
  289. };
  290. enum DOWNLOAD_STATE m_state;
  291. static HRESULT
  292. FindInterfaceIndex(
  293. const TCHAR host[],
  294. DWORD * pIndex
  295. );
  296. float GetTimeDifference( int start, int finish );
  297. //throttle related
  298. DWORD
  299. BlockSizeFromInterval(
  300. SECONDS interval
  301. );
  302. SECONDS
  303. IntervalFromBlockSize(
  304. DWORD BlockSize
  305. );
  306. };
  307. /////////////////////////////////////////////////////////////////////////////
  308. // CProgressiveDL
  309. //
  310. class CProgressiveDL : public Downloader
  311. {
  312. public:
  313. CProgressiveDL( QMErrInfo *pErrInfo );
  314. ~CProgressiveDL();
  315. // pure virtual method from class Downloader
  316. virtual HRESULT
  317. Download( LPCTSTR szURL,
  318. LPCTSTR szDest,
  319. UINT64 Offset,
  320. ITransferCallback * CallBack,
  321. QMErrInfo *pErrInfo,
  322. HANDLE hToken,
  323. BOOL bThrottle,
  324. const PROXY_SETTINGS *pProxySettings,
  325. const CCredentialsContainer * Credentials,
  326. const StringHandle HostId = StringHandle()
  327. );
  328. virtual HRESULT
  329. GetRemoteFileInformation(
  330. HANDLE hToken,
  331. LPCTSTR szURL,
  332. UINT64 * pFileSize,
  333. FILETIME *pFileTime,
  334. QMErrInfo *pErrInfo,
  335. const PROXY_SETTINGS * pProxySettings,
  336. const CCredentialsContainer * Credentials,
  337. const StringHandle HostId = StringHandle()
  338. );
  339. virtual void
  340. Upload(
  341. CUploadJob * job,
  342. ITransferCallback * CallBack,
  343. HANDLE Token,
  344. QMErrInfo & ErrInfo
  345. );
  346. // other methods
  347. private:
  348. //download related
  349. BOOL
  350. OpenLocalDownloadFile( LPCTSTR Path,
  351. UINT64 Offset,
  352. UINT64 Size,
  353. FILETIME UrlModificationTime,
  354. FILETIME * pFileTime
  355. );
  356. BOOL CloseLocalFile();
  357. BOOL WriteBlockToCache(LPBYTE lpBuffer, DWORD dwRead);
  358. BOOL SetFileTimes();
  359. HRESULT
  360. DownloadFile(
  361. HANDLE hToken,
  362. const PROXY_SETTINGS * ProxySettings,
  363. const CCredentialsContainer * Credentials,
  364. LPCTSTR Url,
  365. LPCWSTR Path,
  366. UINT64 Offset,
  367. StringHandle HostId
  368. );
  369. HRESULT GetNextBlock( );
  370. BOOL DownloadBlock( void * Buffer, DWORD * pdwRead);
  371. HRESULT OpenConnection();
  372. void CloseHandles();
  373. BOOL IsAbortRequested()
  374. {
  375. return m_Callbacks->PollAbort();
  376. }
  377. BOOL IsFileComplete()
  378. {
  379. if (m_CurrentOffset == m_wupdinfo->FileSize)
  380. {
  381. return TRUE;
  382. }
  383. return FALSE;
  384. }
  385. void ClearError();
  386. void
  387. SetError(
  388. ERROR_SOURCE Source,
  389. ERROR_STYLE Style,
  390. UINT64 Code,
  391. char * comment = 0
  392. );
  393. BOOL IsErrorSet()
  394. {
  395. // If the file was aborted, the error wont
  396. // be set.
  397. if (QM_FILE_ABORTED == m_pQMInfo->result)
  398. {
  399. return TRUE;
  400. }
  401. if (QM_SERVER_FILE_CHANGED == m_pQMInfo->result )
  402. {
  403. return TRUE;
  404. }
  405. if (m_pQMInfo->Style != 0)
  406. {
  407. return TRUE;
  408. }
  409. return FALSE;
  410. }
  411. BOOL
  412. GetRemoteResourceInformation(
  413. URL_INFO * Info,
  414. QMErrInfo * pQMErrInfo
  415. );
  416. HRESULT
  417. SetRequestProxy(
  418. HINTERNET hRequest,
  419. URL_INFO & Info,
  420. const PROXY_SETTINGS * ProxySettings
  421. );
  422. //
  423. // These are static so they they don't mess with member data accidentally
  424. //
  425. static bool
  426. DoesErrorIndicateNoISAPI(
  427. DWORD dwHttpError
  428. );
  429. HRESULT CreateBlockUrl( LPTSTR lpszNewUrl, DWORD Length);
  430. HRESULT StartEncodedRangeRequest( DWORD Length );
  431. HRESULT StartRangeRequest( DWORD Length );
  432. //--------------------------------------------------------------------
  433. HANDLE m_hFile;
  434. //download related
  435. URL_INFO * m_wupdinfo;
  436. UINT64 m_CurrentOffset;
  437. HINTERNET m_hOpenRequest;
  438. QMErrInfo *m_pQMInfo;
  439. ITransferCallback * m_Callbacks;
  440. BOOL m_bThrottle;
  441. HRESULT DownloadForegroundFile();
  442. public:
  443. //
  444. // Tracks network statistics.
  445. //
  446. CNetworkInterface m_Network;
  447. };
  448. extern CACHED_AUTOPROXY * g_ProxyCache;
  449. class CAbstractDataReader
  450. {
  451. public:
  452. virtual DWORD GetLength() const = 0;
  453. virtual HRESULT Rewind() = 0;
  454. virtual HRESULT Read( PVOID Buffer, DWORD Length, DWORD * pBytesRead ) = 0;
  455. virtual bool IsCancelled( DWORD BytesRead ) = 0;
  456. };
  457. HRESULT
  458. SendRequest(
  459. HINTERNET hRequest,
  460. URL_INFO * Info,
  461. CAbstractDataReader * Reader = 0
  462. );
  463. HRESULT
  464. SetRequestCredentials(
  465. HINTERNET hRequest,
  466. const CCredentialsContainer & Container
  467. );
  468. HRESULT
  469. SetRequestProxy(
  470. HINTERNET hRequest,
  471. PROXY_SETTINGS_CONTAINER * ProxySettings
  472. );
  473. HRESULT
  474. OpenHttpRequest(
  475. LPCTSTR Verb,
  476. LPCTSTR Protocol,
  477. URL_INFO & Info,
  478. HINTERNET * phRequest
  479. );
  480. URL_INFO *
  481. ConnectToUrl(
  482. LPCTSTR Url,
  483. const PROXY_SETTINGS * ProxySettings,
  484. const CCredentialsContainer * Credentials,
  485. LPCTSTR HostId,
  486. QMErrInfo * pErrInfo
  487. );
  488. HRESULT
  489. GetRequestHeader(
  490. HINTERNET hRequest,
  491. DWORD HeaderIndex,
  492. LPCWSTR HeaderName,
  493. CAutoString & Destination,
  494. size_t MaxChars
  495. );
  496. HRESULT
  497. GetResponseVersion(
  498. HINTERNET hRequest,
  499. unsigned * MajorVersion,
  500. unsigned * MinorVersion
  501. );
  502. HRESULT
  503. AddRangeHeader(
  504. HINTERNET hRequest,
  505. UINT64 Start,
  506. UINT64 End
  507. );
  508. HRESULT
  509. AddIf_Unmodified_SinceHeader(
  510. HINTERNET hRequest,
  511. const FILETIME &Time
  512. );
  513. HRESULT CheckLanManHashDisabled ();