DownloadPub.cpp
上传用户:oadesign
上传日期:2013-12-25
资源大小:265k
文件大小:18k
源码类别:

进程与线程

开发平台:

Visual C++

  1. // DownloadPub.cpp: implementation of the CDownloadPub class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "NetDownMTR.h"
  6. #include "DownloadPub.h"
  7. // for PathFindExtension () / PathFindFileName ()
  8. #include "Shlwapi.h"
  9. #pragma comment ( lib, "shlwapi.lib" )
  10. #ifdef _DEBUG
  11. #undef THIS_FILE
  12. static char THIS_FILE[]=__FILE__;
  13. #define new DEBUG_NEW
  14. #endif
  15. // 下载数据保存的临时缓冲大小
  16. #define TEMP_SAVE_BUFFER_SIZE (10*NET_BUFFER_SIZE)
  17. // 当下载的数据达到这个数的时候才保存到文件中
  18. #define WRITE_TEMP_SAVE_MIN_BYTES (TEMP_SAVE_BUFFER_SIZE / 2)
  19. void DownloadNotify ( int nIndex, UINT nNotityType, LPVOID lpNotifyData, LPVOID pDownloadMTR );
  20. //////////////////////////////////////////////////////////////////////
  21. // Construction/Destruction
  22. //////////////////////////////////////////////////////////////////////
  23. CDownloadPub::CDownloadPub()
  24. {
  25. m_hThread = NULL;
  26. m_TimeLastModified = -1;
  27. m_csDownloadUrl = _T("");
  28. m_csSaveFileName = _T("");
  29. m_Proc_SaveDownloadInfo = NULL;
  30. m_wSaveDownloadInfo_Param = NULL;
  31. m_bSupportResume = FALSE;
  32. m_nFileTotalSize = -1;
  33. m_csReferer = _T("");
  34. m_csUserAgent = _T("XieHongWei-HttpDown/2.0");
  35. m_csUsername = _T("");
  36. m_csPassword = _T("");
  37. m_csProtocolType = "http";
  38. m_csServer = _T("");
  39. m_csObject = _T("");
  40. m_csFileName = _T("");
  41. m_nPort = DEFAULT_HTTP_PORT ;
  42. m_nIndex = -1;
  43. ResetVar ();
  44. m_hEvtEndModule = ::CreateEvent ( NULL, TRUE, FALSE, NULL );
  45. m_pDownloadMTR = NULL;
  46. }
  47. void CDownloadPub::ResetVar()
  48. {
  49. Clear_Thread_Handle ();
  50. m_nWillDownloadStartPos = 0;
  51. m_nWillDownloadSize = -1;
  52. m_nDownloadedSize = 0;
  53. m_nTempSaveBytes = 0;
  54. m_bDownloadSuccess = FALSE;
  55. }
  56. CDownloadPub::~CDownloadPub()
  57. {
  58. StopDownload ();
  59. Clear_Thread_Handle ();
  60. }
  61. void CDownloadPub::StopDownload ()
  62. {
  63. if ( HANDLE_IS_VALID(m_hEvtEndModule) )
  64. {
  65. ::SetEvent ( m_hEvtEndModule );
  66. WaitForThreadEnd ( m_hThread,30*1000 );
  67. CLOSE_HANDLE ( m_hEvtEndModule );
  68. m_hEvtEndModule = NULL;
  69. Clear_Thread_Handle ();
  70. }
  71. }
  72. //
  73. // 设置认证信息
  74. //
  75. void CDownloadPub::SetAuthorization ( LPCTSTR lpszUsername, LPCTSTR lpszPassword )
  76. {
  77. if( lpszUsername != NULL )
  78. {
  79. m_csUsername  = GET_SAFE_STRING(lpszUsername);
  80. m_csPassword  = GET_SAFE_STRING(lpszPassword);
  81. }
  82. else
  83. {
  84. m_csUsername  = _T("");
  85. m_csPassword  = _T("");
  86. }
  87. }
  88. // 设置Referer
  89. void CDownloadPub::SetReferer(LPCTSTR lpszReferer)
  90. {
  91. if( lpszReferer != NULL )
  92. m_csReferer = lpszReferer;
  93. else
  94. m_csReferer = _T("");
  95. }
  96. // 设置UserAgent
  97. void CDownloadPub::SetUserAgent(LPCTSTR lpszUserAgent)
  98. {
  99. m_csUserAgent = lpszUserAgent;
  100. if( m_csUserAgent.IsEmpty())
  101. m_csUserAgent = _T("XieHongWei-HttpDown/2.0");
  102. }
  103. //
  104. // 设置保存下载信息回调函数
  105. //
  106. void CDownloadPub::Set_SaveDownloadInfo_Callback ( FUNC_SaveDownloadInfo Proc_SaveDownloadInfo, WPARAM wParam )
  107. {
  108. m_Proc_SaveDownloadInfo = Proc_SaveDownloadInfo;
  109. m_wSaveDownloadInfo_Param = wParam;
  110. }
  111. //
  112. // 下载任务的线程函数
  113. //
  114. DWORD WINAPI ThreadProc_Download(
  115.   LPVOID lpParameter   // thread data
  116. )
  117. {
  118. CDownloadPub *pDownloadPub = (CDownloadPub*)lpParameter;
  119. ASSERT ( pDownloadPub );
  120. return pDownloadPub->ThreadProc_Download ();
  121. }
  122. BOOL CDownloadPub::ThreadProc_Download()
  123. {
  124. for ( int i=0; i<RETRY_TIMES; i++ )
  125. {
  126. if ( DownloadOnce () )
  127. return DownloadEnd(TRUE);
  128. SLEEP_RETURN_Down ( 5*1000 );
  129. }
  130. return DownloadEnd(FALSE);
  131. }
  132. BOOL CDownloadPub::DownloadOnce()
  133. {
  134. // 打开文件
  135. if ( !OpenFileForSave () )
  136. return FALSE;
  137. // 连接到服务器
  138. if ( !m_SocketClient.Is_Connected () )
  139. {
  140. if ( !Connect () )
  141. return FALSE;
  142. }
  143. return TRUE;
  144. }
  145. //
  146. // 创建线程下载文件
  147. //
  148. BOOL CDownloadPub::Download (
  149. int nWillDownloadStartPos, // 要下载文件的开始位置
  150. int nWillDownloadSize, // 本次需要下载的大小,-1表示一直下载到文件尾
  151. int nDownloadedSize // 已下载的字节数,指完全写到文件中的字节数
  152. )
  153. {
  154. // 设置下载参数
  155. m_nWillDownloadStartPos = nWillDownloadStartPos;
  156. Set_WillDownloadSize ( nWillDownloadSize );
  157. if ( m_nFileTotalSize > 0 && Get_WillDownloadSize() > m_nFileTotalSize )
  158. {
  159. Set_WillDownloadSize ( m_nFileTotalSize );
  160. }
  161. Set_DownloadedSize ( nDownloadedSize );
  162. // 创建一个下载线程
  163. DWORD dwThreadId = 0;
  164. m_hThread = CreateThread ( NULL, 0, ::ThreadProc_Download, LPVOID(this), 0, &dwThreadId );
  165. if ( !HANDLE_IS_VALID(m_hThread) )
  166. {
  167. Log ( L_WARNING, "Create download thread failed" );
  168. return FALSE;
  169. }
  170. return TRUE;
  171. }
  172. //
  173. // 下载结束
  174. //
  175. BOOL CDownloadPub::DownloadEnd(BOOL bRes)
  176. {
  177. m_bDownloadSuccess = bRes;
  178. m_SocketClient.Disconnect ();
  179. if ( HANDLE_IS_VALID ( m_file.m_hFile ) )
  180. {
  181. m_file.Close ();
  182. }
  183. TRACE ( "=============== 线程。%d 下载 %s 结束n", m_nIndex, bRes?"成功":"!!! 失败 !!!" );
  184. return bRes;
  185. }
  186. BOOL CDownloadPub::Connect()
  187. {
  188. if ( !HANDLE_IS_VALID(m_hEvtEndModule) )
  189. return FALSE;
  190. if ( m_csServer.IsEmpty() )
  191. {
  192. Log ( L_WARNING, "Please set download URL" );
  193. return FALSE;
  194. }
  195. m_SocketClient.SetEventOfEndModule ( m_hEvtEndModule );
  196. // 连接到服务器
  197. if ( !m_SocketClient.Connect ( m_csServer, m_nPort ) )
  198. return FALSE;
  199. TRACE ( "对象.%d 连接到服务器 成功n", m_nIndex );
  200. return TRUE;
  201. }
  202. BOOL CDownloadPub::SetDownloadUrl(LPCTSTR lpszDownloadUrl)
  203. {
  204. if ( !lpszDownloadUrl ) return FALSE;
  205. m_csDownloadUrl = lpszDownloadUrl;
  206. // 检验要下载的URL是否为空
  207. m_csDownloadUrl.TrimLeft();
  208. m_csDownloadUrl.TrimRight();
  209. if( m_csDownloadUrl.IsEmpty() )
  210. return FALSE;
  211. // 检验要下载的URL是否有效
  212. if ( !ParseURL(m_csDownloadUrl, m_csServer, m_csObject, m_nPort, m_csProtocolType))
  213. {
  214. TRACE(_T("Failed to parse the URL: %sn"), m_csDownloadUrl);
  215. return FALSE;
  216. }
  217. return TRUE;
  218. }
  219. //
  220. // 从服务器接收数据并保存到文件中
  221. //
  222. BOOL CDownloadPub::RecvDataAndSaveToFile(CSocketClient &SocketClient,char *szTailData/*=NULL*/, int nTailSize/*=0*/)
  223. {
  224. int nDownloadedSize = Get_DownloadedSize();
  225. if ( szTailData && nTailSize > 0 )
  226. {
  227. nDownloadedSize = SaveDataToFile ( szTailData, nTailSize );
  228. if ( nDownloadedSize < 0 )
  229. {
  230. return FALSE;
  231. }
  232. }
  233. char szRecvBuf[NET_BUFFER_SIZE] = {0}, *szTempSaveBuf = new char[TEMP_SAVE_BUFFER_SIZE];
  234. if ( !szTempSaveBuf )
  235. {
  236. Log ( L_ERROR, "Allocate memory failed" );
  237. return FALSE;
  238. }
  239. m_nTempSaveBytes = 0;
  240. while ( TRUE )
  241. {
  242. BOOL bDownloadFinished = FALSE;
  243. int nReadSize = 0;
  244. int nTempSaveBytes = Get_TempSaveBytes ();
  245. int nRecvTotalBytes = nDownloadedSize+nTempSaveBytes; // 保存在文件中的字节数加上临时缓冲中的字节数就是总共接收到字节数
  246. int nWillDownloadSize = Get_WillDownloadSize ();
  247. // 从字节数判断,本次下载已经完成了
  248. if ( nWillDownloadSize > 0 && nRecvTotalBytes >= nWillDownloadSize )
  249. {
  250. bDownloadFinished = TRUE;
  251. }
  252. else
  253. {
  254. int nRecvBytesThisTimes = sizeof(szRecvBuf);
  255. if ( nWillDownloadSize > 0 )
  256. nRecvBytesThisTimes = nWillDownloadSize - nRecvTotalBytes;
  257. ASSERT ( nRecvBytesThisTimes >= 0 );
  258. nRecvBytesThisTimes = MIN ( nRecvBytesThisTimes, sizeof(szRecvBuf) );
  259. nReadSize = SocketClient.Receive ( szRecvBuf, nRecvBytesThisTimes );
  260. // 读不到数据了,所以认为下载已经完成
  261. if ( nReadSize <= 0 )
  262. {
  263. if ( nWillDownloadSize <= 0 )
  264. {
  265. bDownloadFinished = TRUE;
  266. }
  267. }
  268. else
  269. {
  270. // TRACE ( "对象.%d, 收到 %d 字节,我的任务是 %d (0x%08x)字节n",
  271. // m_nIndex, nReadSize, nWillDownloadSize , nWillDownloadSize );
  272. }
  273. }
  274. // 先将数据保存到临时缓冲中
  275. if ( nReadSize > 0 )
  276. {
  277. nReadSize = MIN ( nReadSize, TEMP_SAVE_BUFFER_SIZE-nTempSaveBytes );
  278. memcpy ( szTempSaveBuf+nTempSaveBytes, szRecvBuf, nReadSize );
  279. nTempSaveBytes += nReadSize;
  280. ASSERT ( nTempSaveBytes < TEMP_SAVE_BUFFER_SIZE );
  281. }
  282. // 当下载已完成或者收到的数据超过一定数量时才保存到文件中
  283. if ( bDownloadFinished || nTempSaveBytes >= WRITE_TEMP_SAVE_MIN_BYTES )
  284. {
  285. // 保存文件失败,下载也应该终止
  286. nDownloadedSize = SaveDataToFile ( szTempSaveBuf, nTempSaveBytes );
  287. if ( nDownloadedSize < 0 )
  288. {
  289. break;
  290. }
  291. nTempSaveBytes = 0;
  292. }
  293. Set_TempSaveBytes ( nTempSaveBytes );
  294. if ( bDownloadFinished )
  295. {
  296. ASSERT ( (nWillDownloadSize > 0 && nDownloadedSize >= nWillDownloadSize) || (nReadSize <= 0 && nWillDownloadSize <= 0) );
  297. break;
  298. }
  299. SLEEP_BREAK ( 1 );
  300. }
  301. if ( szTempSaveBuf ) delete[] szTempSaveBuf;
  302. szTempSaveBuf = NULL;
  303. BOOL bRes = FALSE;
  304. int nWillDownloadSize = Get_WillDownloadSize ();
  305. if ( nWillDownloadSize != -1 )
  306. {
  307. if ( nDownloadedSize >= nWillDownloadSize )
  308. bRes = TRUE;
  309. }
  310. else if ( nDownloadedSize > 0 )
  311. {
  312. bRes = TRUE;
  313. }
  314. return bRes;
  315. }
  316. int CDownloadPub::SaveDataToFile(char *data, int size)
  317. {
  318. ASSERT ( HANDLE_IS_VALID ( m_file.m_hFile ) );
  319. if ( !data || size < 0 )
  320. return -1;
  321. int nDownloadedSize = -1;
  322. // 保存下载的数据
  323. ASSERT ( HANDLE_IS_VALID(m_file.m_hFile) );
  324. BOOL bRet = TRUE;
  325. TRY
  326. {
  327. m_file.Write ( data, size );
  328. }
  329. CATCH( CFileException, e )
  330. {
  331. e->Delete ();
  332. bRet = FALSE;
  333. }
  334. END_CATCH
  335. if ( !bRet )
  336. {
  337. Log ( L_WARNING, "Write data to local file [%s] failed", m_file.GetFileName() );
  338. }
  339. else
  340. {
  341. nDownloadedSize = Get_DownloadedSize();
  342. // TRACE ( "对象.%d, 保存 %d(0x%08x) 字节,偏移 %d(0x%08x) 字节, 共 %d(0x%08x) 字节n",
  343. // m_nIndex, size, size, m_nWillDownloadStartPos+nDownloadedSize, m_nWillDownloadStartPos+nDownloadedSize,
  344. // nDownloadedSize + size, nDownloadedSize + size );
  345. nDownloadedSize += size;
  346. Set_DownloadedSize ( nDownloadedSize );
  347. if ( m_Proc_SaveDownloadInfo )
  348. m_Proc_SaveDownloadInfo ( m_nIndex, nDownloadedSize, size, m_wSaveDownloadInfo_Param );
  349. }
  350. if ( !bRet ) return -1;
  351. return nDownloadedSize;
  352. }
  353. BOOL CDownloadPub::GetRemoteSiteInfo()
  354. {
  355. return TRUE;
  356. }
  357. CString CDownloadPub::GetRemoteFileName()
  358. {
  359. int nPos = m_csObject.ReverseFind ( '/' );
  360. if ( nPos <= 0 ) return m_csObject;
  361. return m_csObject.Mid ( nPos+1 );
  362. }
  363. const char* g_szBase64TAB = _T( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" );
  364. // BASE64编码
  365. int Base64Encode(LPCTSTR lpszEncoding, CString &strEncoded)
  366. {
  367. UINT m_nBase64Mask[]= { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
  368. int nDigit;
  369. int nNumBits = 6;
  370. int nIndex = 0;
  371. int nInputSize;
  372. strEncoded = _T( "" );
  373. if( lpszEncoding == NULL )
  374. return 0;
  375. if( ( nInputSize = lstrlen(lpszEncoding) ) == 0 )
  376. return 0;
  377. int nBitsRemaining = 0;
  378. long lBitsStorage =0;
  379. long lScratch =0;
  380. int nBits;
  381. UCHAR c;
  382. while( nNumBits > 0 )
  383. {
  384. while( ( nBitsRemaining < nNumBits ) &&  ( nIndex < nInputSize ) ) 
  385. {
  386. c = lpszEncoding[ nIndex++ ];
  387. lBitsStorage <<= 8;
  388. lBitsStorage |= (c & 0xff);
  389. nBitsRemaining += 8;
  390. }
  391. if( nBitsRemaining < nNumBits ) 
  392. {
  393. lScratch = lBitsStorage << ( nNumBits - nBitsRemaining );
  394. nBits    = nBitsRemaining;
  395. nBitsRemaining = 0;
  396. }  
  397. else 
  398. {
  399. lScratch = lBitsStorage >> ( nBitsRemaining - nNumBits );
  400. nBits  = nNumBits;
  401. nBitsRemaining -= nNumBits;
  402. }
  403. nDigit = (int)(lScratch & m_nBase64Mask[nNumBits]);
  404. nNumBits = nBits;
  405. if( nNumBits <=0 )
  406. break;
  407. strEncoded += g_szBase64TAB[ nDigit ];
  408. }
  409. // Pad with '=' as per RFC 1521
  410. while( strEncoded.GetLength() % 4 != 0 )
  411. strEncoded += '=';
  412. return strEncoded.GetLength();
  413. }
  414. // STATIC BASE64解码
  415. int Base64Decode(LPCTSTR lpszDecoding, CString &strDecoded)
  416. {
  417. int nIndex =0;
  418. int nDigit;
  419.     int nDecode[ 256 ];
  420. int nSize;
  421. int nNumBits = 6;
  422. if( lpszDecoding == NULL )
  423. return 0;
  424. if( ( nSize = lstrlen(lpszDecoding) ) == 0 )
  425. return 0;
  426. // Build Decode Table
  427. for( int i = 0; i < 256; i++ ) 
  428. nDecode[i] = -2; // Illegal digit
  429. for( i=0; i < 64; i++ )
  430. {
  431. nDecode[ g_szBase64TAB[ i ] ] = i;
  432. nDecode[ '=' ] = -1; 
  433.     }
  434. // Clear the output buffer
  435. strDecoded = _T("");
  436. long lBitsStorage  =0;
  437. int nBitsRemaining = 0;
  438. int nScratch = 0;
  439. UCHAR c;
  440. // Decode the Input
  441. for( nIndex = 0, i = 0; nIndex < nSize; nIndex++ )
  442. {
  443. c = lpszDecoding[ nIndex ];
  444. // 忽略所有不合法的字符
  445. if( c> 0x7F)
  446. continue;
  447. nDigit = nDecode[c];
  448. if( nDigit >= 0 ) 
  449. {
  450. lBitsStorage = (lBitsStorage << nNumBits) | (nDigit & 0x3F);
  451. nBitsRemaining += nNumBits;
  452. while( nBitsRemaining > 7 ) 
  453. {
  454. nScratch = lBitsStorage >> (nBitsRemaining - 8);
  455. strDecoded += (nScratch & 0xFF);
  456. i++;
  457. nBitsRemaining -= 8;
  458. }
  459. }
  460.     }
  461. return strDecoded.GetLength();
  462. }
  463. //
  464. // 从URL里面拆分出Server、Object、协议类型等信息,其中 Object 里的值是区分大小写的,否则有些网站可能会下载不了
  465. //
  466. BOOL ParseURL(LPCTSTR lpszURL, CString &strServer, CString &strObject,USHORT& nPort, CString &csProtocolType)
  467. {
  468. if ( !lpszURL || strlen(lpszURL) < 1 ) return FALSE;
  469. CString csURL_Lower(lpszURL);
  470. csURL_Lower.TrimLeft();
  471. csURL_Lower.TrimRight();
  472. csURL_Lower.Replace ( "\", "/" );
  473. CString csURL = csURL_Lower;
  474. csURL_Lower.MakeLower ();
  475. // 清除数据
  476. strServer = _T("");
  477. strObject = _T("");
  478. nPort   = 0;
  479. int nPos = csURL_Lower.Find("://");
  480. if( nPos == -1 )
  481. {
  482. csURL_Lower.Insert ( 0, "http://" );
  483. csURL.Insert ( 0, "http://" );
  484. nPos = 4;
  485. }
  486. csProtocolType = csURL_Lower.Left ( nPos );
  487. csURL_Lower = csURL_Lower.Mid( csProtocolType.GetLength()+3 );
  488. csURL = csURL.Mid( csProtocolType.GetLength()+3 );
  489. nPos = csURL_Lower.Find('/');
  490. if ( nPos == -1 )
  491. return FALSE;
  492. strObject = csURL.Mid(nPos);
  493. CString csServerAndPort = csURL_Lower.Left(nPos);
  494. // 查找是否有端口号,站点服务器域名一般用小写
  495. nPos = csServerAndPort.Find(":");
  496. if( nPos == -1 )
  497. {
  498. strServer = csServerAndPort;
  499. nPort = DEFAULT_HTTP_PORT;
  500. if ( csProtocolType == "ftp" )
  501. nPort = DEFAULT_FTP_PORT;
  502. }
  503. else
  504. {
  505. strServer = csServerAndPort.Left( nPos );
  506. csServerAndPort   = csServerAndPort.Mid( nPos+1 );
  507. nPort   = (USHORT)_ttoi((LPCTSTR)csServerAndPort);
  508. }
  509. return TRUE;
  510. }
  511. void CDownloadPub::Set_DownloadedSize(int nDownloadedSize)
  512. {
  513. m_CSFor_DownloadedSize.Lock ();
  514. m_nDownloadedSize = nDownloadedSize;
  515. m_CSFor_DownloadedSize.Unlock ();
  516. DownloadNotify ( m_nIndex, NOTIFY_TYPE_THREAD_DOWNLOADED_SIZE, (LPVOID)nDownloadedSize, m_pDownloadMTR );
  517. }
  518. int CDownloadPub::Get_DownloadedSize()
  519. {
  520. int nDownloadedSize = 0;
  521. m_CSFor_DownloadedSize.Lock ();
  522. nDownloadedSize = m_nDownloadedSize;
  523. m_CSFor_DownloadedSize.Unlock ();
  524. return nDownloadedSize;
  525. }
  526. void CDownloadPub::Set_TempSaveBytes(int nTempSaveBytes)
  527. {
  528. m_CSFor_TempSaveBytes.Lock ();
  529. m_nTempSaveBytes = nTempSaveBytes;
  530. m_CSFor_TempSaveBytes.Unlock ();
  531. }
  532. int CDownloadPub::Get_TempSaveBytes()
  533. {
  534. int nTempSaveBytes = 0;
  535. m_CSFor_TempSaveBytes.Lock ();
  536. nTempSaveBytes = m_nTempSaveBytes;
  537. m_CSFor_TempSaveBytes.Unlock ();
  538. return nTempSaveBytes;
  539. }
  540. void CDownloadPub::Set_WillDownloadSize(int nWillDownloadSize)
  541. {
  542. m_CSFor_WillDownloadSize.Lock ();
  543. m_nWillDownloadSize = nWillDownloadSize;
  544. m_CSFor_WillDownloadSize.Unlock ();
  545. DownloadNotify ( m_nIndex, NOTIFY_TYPE_WILL_DOWNLOAD_SIZE, (LPVOID)m_nWillDownloadSize, m_pDownloadMTR );
  546. }
  547. int CDownloadPub::Get_WillDownloadSize()
  548. {
  549. int nWillDownloadSize = 0;
  550. m_CSFor_WillDownloadSize.Lock ();
  551. nWillDownloadSize = m_nWillDownloadSize;
  552. m_CSFor_WillDownloadSize.Unlock ();
  553. return nWillDownloadSize;
  554. }
  555. BOOL CDownloadPub::SetSaveFileName(LPCTSTR lpszSaveFileName)
  556. {
  557. if ( !lpszSaveFileName ) return FALSE;
  558. m_csSaveFileName = lpszSaveFileName;
  559. if ( m_csSaveFileName.IsEmpty() )
  560. return FALSE;
  561. return TRUE;
  562. }
  563. //
  564. // 获取尚未下载的字节数,写到文件中的和临时缓冲里的都算是已经下载的
  565. //
  566. int CDownloadPub::GetUndownloadBytes()
  567. {
  568. // 总共需要下载的字节数减去已经下载的字节数
  569. return Get_WillDownloadSize () - ( Get_DownloadedSize () + Get_TempSaveBytes () );
  570. }
  571. BOOL CDownloadPub::OpenFileForSave()
  572. {
  573. ASSERT ( !m_csSaveFileName.IsEmpty() );
  574. // 打开本地文件
  575. if ( HANDLE_IS_VALID ( m_file.m_hFile ) )
  576. {
  577. m_file.Close ();
  578. }
  579. BOOL bRet = FALSE;
  580. TRY
  581. {
  582. if ( m_file.Open ( m_csSaveFileName, CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite|CFile::typeBinary|CFile::shareDenyNone ) )
  583. {
  584. int nWillDownloadStartPos = Get_WillDownloadStartPos ();
  585. nWillDownloadStartPos += Get_DownloadedSize ();
  586. if ( m_file.Seek ( nWillDownloadStartPos, CFile::begin ) == nWillDownloadStartPos )
  587. bRet = TRUE;
  588. }
  589. }
  590. CATCH( CFileException, e )
  591. {
  592. e->Delete ();
  593. bRet = FALSE;
  594. }
  595. END_CATCH
  596. if ( !bRet )
  597. {
  598. Log ( L_WARNING, "Open file [%s] failed. %s", m_csSaveFileName, ::hwFormatMessage ( GetLastError() ) );
  599. }
  600. return bRet;
  601. }
  602. void CDownloadPub::Clear_Thread_Handle()
  603. {
  604. CLOSE_HANDLE ( m_hThread );
  605. }
  606. // 消息通知的回调函数
  607. FUNC_DownloadNotify f_Proc_DownloadNotify = NULL;
  608. WPARAM f_wDownloadNotify_Param = NULL;
  609. //
  610. // 设置通知回调函数
  611. //
  612. void Set_DownloadNotify_Callback ( FUNC_DownloadNotify Proc_DownloadNotify, WPARAM wParam )
  613. {
  614. f_Proc_DownloadNotify = Proc_DownloadNotify;
  615. f_wDownloadNotify_Param = wParam;
  616. }
  617. void DownloadNotify ( int nIndex, UINT nNotityType, LPVOID lpNotifyData, LPVOID pDownloadMTR )
  618. {
  619. ASSERT ( pDownloadMTR );
  620. t_DownloadNotifyPara DownloadNotifyPara = {0};
  621. DownloadNotifyPara.nIndex = nIndex;
  622. DownloadNotifyPara.nNotityType = nNotityType;
  623. DownloadNotifyPara.lpNotifyData = lpNotifyData;
  624. DownloadNotifyPara.pDownloadMTR = pDownloadMTR;
  625. if ( f_Proc_DownloadNotify )
  626. f_Proc_DownloadNotify ( &DownloadNotifyPara, f_wDownloadNotify_Param );
  627. }
  628. //
  629. // 获取下载对象的文件名(带扩展名的)
  630. //
  631. CString CDownloadPub::GetDownloadObjectFileName(CString *pcsExtensionName)
  632. {
  633. ASSERT ( !m_csObject.IsEmpty() );
  634. CString csOnlyPath, csOnlyFileName, csExtensionName;
  635. if ( !PartPathAndFileAndExtensionName ( m_csObject, &csOnlyPath, &csOnlyFileName, &csExtensionName ) )
  636. return "";
  637. if ( pcsExtensionName ) *pcsExtensionName = csExtensionName;
  638. if ( !csExtensionName.IsEmpty() )
  639. {
  640. csOnlyFileName += ".";
  641. csOnlyFileName += csExtensionName;
  642. }
  643. return csOnlyFileName;
  644. }