ftpdownload.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:51k
源码类别:

模拟服务器

开发平台:

C/C++

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // FtpDownload.cpp: implementation of the CFtpDownload class.
  3. ////////////////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "SocksPacket.h"
  6. #include "FtpDownload.h"
  7. #include "Resource.h"
  8. #define READ_BUFFER_SIZE 10240
  9. #define DEFAULT_SAVE_DIR _T("C:\")
  10. #define Check(a,b) if((a)) return (b);
  11. //////////////////////////////////////////////////////////////////////
  12. // Construction/Destruction
  13. //////////////////////////////////////////////////////////////////////
  14. CFtpDownload::CFtpDownload()
  15. {
  16. m_strDownloadUrl = _T("");
  17. m_strSavePath = _T(""); // 可以是全路径或保存目录
  18. m_strTempSavePath = _T(""); //临时文件的路径
  19. // 停止下载
  20. m_bStopDownload = FALSE;
  21. m_hStopEvent = NULL;
  22. // 强制重新下载(不管已有的文件是否与远程文件相同)
  23. m_bForceDownload = FALSE;
  24. // 是否支持断点续传
  25. m_bSupportResume = FALSE;
  26. // PASV方式
  27. m_bPasv = TRUE;
  28. // 文件以及下载大小
  29. m_dwFileSize = 0; // 文件总的大小
  30. m_dwFileDownloadedSize = 0; // 文件总共已经下载的大小
  31. m_dwDownloadSize = 0; // 本次需要下载的大小
  32. m_dwDownloadedSize = 0; // 本次已经下载的大小
  33. // 超时TIMEOUT 连接超时、发送超时、接收超时(单位:毫秒)
  34. m_dwConnTimeout = FTP_CONN_TIMEOUT;
  35. m_dwRecvTimeout = FTP_RECV_TIMEOUT;
  36. m_dwSendTimeout = FTP_SEND_TIMEOUT;
  37. // 重试机制
  38. m_nRetryType = FTP_RETRY_NONE; //重试类型(0:不重试 1:重试一定次数 2:总是重试)
  39. m_nRetryTimes = 0; //重试次数
  40. m_nRetryDelay = 0; //重试延迟(单位:毫秒)
  41. m_nRetryMax = 0; //重试的最大次数
  42. // 错误处理
  43. m_nErrorCount = 0; //错误次数 (暂时没有作用)
  44. m_strError = _T(""); //错误信息 (暂时没有作用)
  45. // 向其他窗口发送消息
  46. m_bNotify = FALSE; // 是否向外发送通知消息
  47. m_hNotifyWnd = NULL; // 被通知的窗口
  48. m_nNotifyMessage = 0; // 被通知的消息
  49.     
  50. // 是否使用代理 
  51. m_bProxy = FALSE;
  52. m_strProxyServer = _T("");
  53. m_nProxyPort = 0;
  54. m_nProxyType = FTP_PROXY_NONE;
  55. // 代理是否需要验证
  56. m_bProxyAuthorization = FALSE;
  57. m_strProxyUsername = _T("");
  58. m_strProxyPassword = _T("");
  59. // FTP用户和口令
  60. m_bAuthorization = FALSE;
  61. m_strUsername = _T("anonymous");
  62. m_strPassword = _T("mail@unknow.com");
  63. // 下载过程中所用的变量
  64. m_strServer = _T("");
  65. m_strObject = _T("");
  66. m_strFileName = _T("");
  67. m_nPort = DEFAULT_FTP_PORT;
  68. }
  69. CFtpDownload::~CFtpDownload()
  70. {
  71. CloseControlSocket();
  72. CloseDataSocket();
  73. }
  74. //////////////////////////////////////////////////////////////////////////////////
  75. // 函数名:BOOL GetIEProxy(
  76. // CString &strProxyServer,
  77. // int &nProxyPort,
  78. // int &nProxyType ) 
  79. // 用  途:获取IE的Proxy设置
  80. // 对全局变量的影响:无
  81. // 参  数:
  82. // strProxyServer : 代理服务器地址
  83. // nProxyPort     : 代理服务器的端口
  84. // nProxyType     : 代理服务器的类型
  85. // 返回值:BOOL
  86. ////////////////////////////////////////////////////////////////////////////////
  87. BOOL CFtpDownload::GetIEProxy(CString &strProxyServer, int &nProxyPort, int &nProxyType)
  88. {
  89.     // 读取注册表
  90.     HKEY hRegKey;
  91.     DWORD dwRet = RegOpenKeyEx(
  92.         HKEY_CURRENT_USER,
  93.         "Software\Microsoft\Windows\CurrentVersion\Internet Settings",
  94.         0L,
  95.         KEY_QUERY_VALUE,&hRegKey
  96.     );
  97.     if (dwRet != ERROR_SUCCESS)
  98.         return FALSE;
  99.     
  100.     TCHAR szAddr[256] = { 0 };
  101.     DWORD dwLen = 256;
  102.     dwRet = RegQueryValueEx(hRegKey,"ProxyServer",NULL,NULL,(LPBYTE)szAddr,&dwLen);
  103.     if (dwRet != ERROR_SUCCESS)
  104.     {
  105.         RegCloseKey(hRegKey);
  106.         return FALSE;
  107.     }
  108.     RegCloseKey(hRegKey);
  109.     
  110.     // 注:可能存在所有代理同一的情况,此时无 http=...ftp=...信息
  111.     //    comment by Linsuyi, 2002/01/22  23:30
  112.     // 
  113.     // 分析Proxy的设置
  114.     //http=193.168.10.1:80;socks=192.168.10.235:1080
  115.     //193.168.10.1:1090
  116.     //ftp=193.168.10.1:1090;gopher=193.168.10.1:1090;https=193.168.10.1:1090;socks=193.168.10.2:1080
  117.     int nPos = -1;
  118.     CString strProxy = szAddr;
  119.     
  120.     if (strProxy.IsEmpty())
  121.         return FALSE;
  122.     
  123.     strProxy.MakeLower();
  124.     nProxyType = FTP_PROXY_NONE;
  125.        
  126.     nPos = strProxy.Find("socks=");
  127.     if (-1 == nPos)
  128.         return FALSE;
  129.     
  130.     strProxy = strProxy.Mid( nPos+strlen("socks="));
  131.     nProxyType = FTP_PROXY_SOCKS5;
  132.     
  133.     nPos = strProxy.Find(";");
  134.     if (nPos != -1)
  135.      strProxy = strProxy.Left(nPos);
  136.     
  137.     nPos = strProxy.Find(":");
  138.     strProxyServer = strProxy.Left(nPos);
  139.     nProxyPort = _ttoi(strProxy.Mid(nPos+1));
  140.     if (nProxyPort <= 0)
  141.         return FALSE;
  142.     
  143.     return TRUE;
  144. }
  145. // 设置代理
  146. void CFtpDownload::SetProxy(LPCTSTR lpszProxyServer,int nProxyPort, BOOL bProxy/*=TRUE*/, BOOL bProxyAuthorization /*=FALSE*/, LPCTSTR lpszProxyUsername /*=NULL*/, LPCTSTR lpszProxyPassword /*=NULL*/, int nProxyType /*=FTP_PROXY_NONE*/)
  147. {
  148.     if (bProxy && (FTP_PROXY_USEIE == nProxyType))
  149.     {
  150.         if (!GetIEProxy(m_strProxyServer,m_nProxyPort,m_nProxyType))
  151.         {
  152.             m_bProxy                = FALSE;
  153.             m_bProxyAuthorization   = FALSE;
  154.             m_nProxyPort            = 0;
  155.             m_nProxyType            = FTP_PROXY_NONE;
  156.             m_strProxyServer        = _T("");
  157.             m_strProxyUsername      = _T("");
  158.             m_strProxyPassword      = _T("");
  159.         }
  160.         else
  161.         {
  162.             m_bProxy                = TRUE;
  163.             
  164.             if (lpszProxyUsername != NULL)
  165.             {
  166.                 m_bProxyAuthorization   = TRUE;
  167.                 m_strProxyUsername      = lpszProxyUsername;
  168.                 m_strProxyPassword      = lpszProxyPassword;
  169.             }
  170.             else
  171.             {
  172.                 m_bProxyAuthorization   = FALSE;
  173.                 m_strProxyUsername      = _T("");
  174.                 m_strProxyPassword      = _T("");
  175.             }
  176.         }
  177.     }
  178.     else if (bProxy && (lpszProxyServer != NULL) && (nProxyPort != 0))
  179.     {
  180.         m_bProxy = TRUE;
  181.         m_strProxyServer = lpszProxyServer;
  182.         m_nProxyPort = nProxyPort;
  183.         m_nProxyType = nProxyType;
  184.         
  185.         if (bProxyAuthorization && lpszProxyUsername != NULL)
  186.         {
  187.             m_bProxyAuthorization = TRUE;
  188.             m_strProxyUsername = lpszProxyUsername;
  189.             m_strProxyPassword = lpszProxyPassword;
  190.         }
  191.         else
  192.         {
  193.             m_bProxyAuthorization = FALSE;
  194.             m_strProxyUsername = _T("");
  195.             m_strProxyPassword = _T("");
  196.         }
  197.     }
  198.     else
  199.     {
  200.         m_bProxy = FALSE;
  201.         m_bProxyAuthorization = FALSE;
  202.         m_nProxyPort = 0;
  203.         
  204.         m_nProxyType = FTP_PROXY_NONE;
  205.         m_strProxyServer = _T("");
  206.         m_strProxyUsername = _T("");
  207.         m_strProxyPassword = _T("");
  208.     }
  209. }
  210. // 设置是否需要发送消息给调用窗口
  211. void CFtpDownload::SetNotifyWnd(HWND hNotifyWnd, int nNotifyMsg, BOOL bNotify)
  212. {
  213.     if (bNotify && (hNotifyWnd != NULL) && ::IsWindow(hNotifyWnd) )
  214.     {
  215.         m_bNotify  = TRUE;
  216.         m_hNotifyWnd = hNotifyWnd;
  217.         m_nNotifyMessage = nNotifyMsg;
  218.     }
  219.     else
  220.     {
  221.         m_bNotify  = FALSE;
  222.         m_hNotifyWnd = NULL;
  223.         m_nNotifyMessage = 0;
  224.     }
  225. }
  226. // 设置超时
  227. void CFtpDownload::SetTimeout(DWORD dwSendTimeout, DWORD dwRecvTimeout, DWORD dwConnTimeout)
  228. {
  229. if( dwSendTimeout > 0 )
  230. m_dwSendTimeout = dwSendTimeout;
  231. if( dwRecvTimeout > 0 )
  232. m_dwRecvTimeout = dwRecvTimeout;
  233. if( dwConnTimeout > 0 )
  234. m_dwConnTimeout = dwConnTimeout;
  235. }
  236. // 设置重试的机制
  237. // nRetryType = 0  不重试 FTP_RETRY_NONE
  238. // nRetryType = 1  重试一定次数 FTP_RETRY_TIMES
  239. // nRetryType = 2  永远重试(可能陷入死循环) FTP_RETRY_ALWAYS
  240. void CFtpDownload::SetRetry(int nRetryType, int nRetryDelay, int nRetryMax)
  241. {
  242. m_nRetryType  = nRetryType;
  243. m_nRetryDelay = nRetryDelay;
  244. m_nRetryMax   = nRetryMax;
  245. // 检查一下m_nRetryMax,如果为0,设为缺省值
  246. if( (FTP_RETRY_TIMES == m_nRetryType) && (0 == m_nRetryMax) )
  247. m_nRetryMax = DEFAULT_FTP_RETRY_MAX;
  248. }
  249. // 设置用户名和口号
  250. void CFtpDownload::SetAuthorization(LPCTSTR lpszUsername, LPCTSTR lpszPassword, BOOL byAuthorization)
  251. {
  252. if( byAuthorization && lpszUsername != NULL )
  253. {
  254. m_bAuthorization = TRUE;
  255. m_strUsername  = lpszUsername;
  256. m_strPassword  = lpszPassword;
  257. }
  258. else
  259. {
  260. m_bAuthorization = FALSE;
  261. m_strUsername  = _T("anonymous");
  262. m_strPassword  = _T("hello@dont.know.com");
  263. }
  264. }
  265. // 设置PASV模式
  266. void CFtpDownload::SetPasv(BOOL bPasv /*= TRUE*/)
  267. {
  268. m_bPasv = bPasv;
  269. }
  270. // 停止下载
  271. void CFtpDownload::StopDownload()
  272. {
  273. m_bStopDownload = TRUE;
  274. if ( m_hStopEvent != NULL )
  275. SetEvent(m_hStopEvent);
  276. }
  277. // 创建控制SOCKET
  278. BOOL CFtpDownload::CreateControlSocket()
  279. {
  280. CloseControlSocket();
  281. return m_cControlSocket.Create(AF_INET,SOCK_STREAM,0,READ_BUFFER_SIZE);
  282. }
  283. // 创建数据SOCKET
  284. BOOL CFtpDownload::CreateDataSocket( SOCKET hSocket /*= INVALID_SOCKET */)
  285. {
  286. CloseDataSocket();
  287. return m_cDataSocket.Create(AF_INET,SOCK_STREAM,0,READ_BUFFER_SIZE,hSocket);
  288. }
  289. // 关闭控制SOCKET
  290. void CFtpDownload::CloseControlSocket()
  291. {
  292. m_cControlSocket.Close(TRUE);
  293. }
  294. // 关闭数据SOCKET
  295. void CFtpDownload::CloseDataSocket()
  296. {
  297. m_cDataSocket.Close(TRUE);
  298. }
  299. // 从URL里面拆分出Server和Object来
  300. BOOL CFtpDownload::ParseURL(LPCTSTR lpszURL, CString &strServer, CString &strObject,int& nPort)
  301. {
  302. CString strURL(lpszURL);
  303. strURL.TrimLeft();
  304. strURL.TrimRight();
  305. // 清除数据
  306. strServer = _T("");
  307. strObject = _T("");
  308. nPort   = 0;
  309. int nPos = strURL.Find("://");
  310. if( nPos == -1 )
  311. return FALSE;
  312. // 进一步验证是否为Ftp://
  313. CString strTemp = strURL.Left( nPos+lstrlen("://") );
  314. //strTemp.MakeLower();
  315. //if( strTemp.Compare("ftp://") != 0 )
  316.     if(strTemp.CompareNoCase("ftp://") != 0)
  317. return FALSE;
  318. strURL = strURL.Mid( strTemp.GetLength() );
  319. nPos = strURL.Find('/');
  320. if ( nPos == -1 )
  321. return FALSE;
  322. strObject = strURL.Mid(nPos);
  323. strTemp   = strURL.Left(nPos);
  324. // 查找是否有端口号
  325. nPos = strTemp.Find(":");
  326. if( nPos == -1 )
  327. {
  328. strServer = strTemp;
  329. nPort   = DEFAULT_FTP_PORT;
  330. }
  331. else
  332. {
  333. strServer = strTemp.Left( nPos );
  334. strTemp   = strTemp.Mid( nPos+1 );
  335. nPort   = (int)_ttoi((LPCTSTR)strTemp);
  336. }
  337. return TRUE;
  338. }
  339. // 从下载URL中获取文件名
  340. void CFtpDownload::GetFileName()
  341. {
  342. // 获取的文件名
  343. int nSlash = m_strObject.ReverseFind(_T('/'));
  344. if (nSlash == -1)
  345. nSlash = m_strObject.ReverseFind(_T('\'));
  346. if (nSlash != -1 && m_strObject.GetLength() > 1)
  347. m_strFileName = m_strObject.Right(m_strObject.GetLength() - nSlash - 1);
  348. else
  349. m_strFileName = m_strObject;
  350. }
  351. // 将字符串转化成时间
  352. CTime CFtpDownload::GetTime(LPCTSTR lpszTime)
  353. {
  354. CString strTime(lpszTime);
  355. CTime dTime = CTime::GetCurrentTime();
  356. int nPos = strTime.FindOneOf(" t");
  357. if( nPos == -1 )
  358. return dTime;
  359. CString strAllMonth = "jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec";
  360. CString strDay,strMonth,strYear,strHour,strMinute;
  361. int nDay,nMonth,nYear,nHour,nMinute,nSecond;
  362. strMonth = strTime.Left( nPos );
  363. strTime = strTime.Mid( nPos +1 );
  364. strTime.TrimLeft();
  365. nPos = strAllMonth.Find(strMonth);
  366. if( nPos == -1 )
  367. return dTime;
  368. strMonth.Format("%d",((nPos/4)+1));
  369. nMonth = atoi(strMonth);
  370. nPos = strTime.FindOneOf(" t");
  371. if( nPos == -1 )
  372. return dTime;
  373. strDay = strTime.Left( nPos );
  374. nDay = atoi(strDay);
  375. strTime = strTime.Mid( nPos+1 );
  376. strTime.TrimLeft();
  377. nPos = strTime.FindOneOf(":");
  378. if (nPos != -1)
  379. {
  380. strHour = strTime.Left( nPos );
  381. nHour = atoi(strHour);
  382. strTime = strTime.Mid( nPos+1 );
  383. strTime.TrimLeft();
  384. nPos = strTime.FindOneOf(":");
  385. if( nPos != -1 )
  386. {
  387. strMinute = strTime.Left( nPos );
  388. nMinute = atoi(strMinute);
  389. strTime = strTime.Mid( nPos+1 );
  390. strTime.TrimLeft();
  391. nSecond = atoi(strTime);
  392. }
  393. else
  394. {
  395. nMinute = atoi(strTime);
  396. nSecond = 0;
  397. }
  398. }
  399. else
  400. {
  401. nHour = 0;
  402. nMinute = 0;
  403. nSecond = 0;
  404. }
  405. nYear = dTime.GetYear();
  406. dTime = CTime(nYear,nMonth,nDay,nHour,nMinute,nSecond);
  407. return dTime;
  408. }
  409. // 获得返回码
  410. BOOL CFtpDownload::GetReplyCode(LPCTSTR lpszResponse,DWORD& dwReplyCode,BOOL& bMultiLine)
  411. {
  412. CString strSource(lpszResponse);
  413. dwReplyCode = 0;
  414. bMultiLine = FALSE;
  415. if( strSource.GetLength() < 3 )
  416. return FALSE;
  417. dwReplyCode = (DWORD)_ttoi(strSource.Left(3));
  418. if( strSource.GetLength() >= 4 )
  419. bMultiLine = (strSource.GetAt(3) == '-' );
  420. else
  421. bMultiLine = FALSE;
  422. return TRUE;
  423. }
  424. // 获取数据通道的信息
  425. BOOL CFtpDownload::GetDataReply(CString& strReply)
  426. {
  427. char szReadBuf[1025];
  428. strReply = _T("");
  429. // 接收信息
  430. ZeroMemory(szReadBuf,1025);
  431. if( m_cDataSocket.BSDGetString(szReadBuf,1024,m_dwRecvTimeout) != SOCKET_SUCCESS )
  432. return FALSE;
  433. strReply += szReadBuf;
  434. return TRUE;
  435. }
  436. // 获得Reply信息
  437. BOOL CFtpDownload::GetReply(CString& strReply,DWORD& dwReplyCode)
  438. {
  439. char szReadBuf[1025];
  440. CString strResponse;
  441. DWORD dwStartCode;
  442. BOOL bMultiLine;
  443. strReply = _T("");
  444. dwReplyCode = 0;
  445. // 先接收一行
  446. ZeroMemory(szReadBuf,1025);
  447. if( m_cControlSocket.BSDGetString(szReadBuf,1024,m_dwRecvTimeout) != SOCKET_SUCCESS )
  448. return FALSE;
  449. strReply += szReadBuf;
  450. if( !GetReplyCode(szReadBuf,dwReplyCode,bMultiLine) )
  451. return FALSE;
  452. if( !bMultiLine )
  453. return TRUE;
  454. dwStartCode = dwReplyCode;
  455. while(TRUE)
  456. {
  457. ZeroMemory(szReadBuf,1025);
  458. if( m_cControlSocket.BSDGetString(szReadBuf,1024,m_dwRecvTimeout) != SOCKET_SUCCESS )
  459. return FALSE;
  460. strReply += szReadBuf;
  461. strReply += "rn";
  462. if( !GetReplyCode(szReadBuf,dwReplyCode,bMultiLine) )
  463. return FALSE;
  464. if( dwStartCode == dwReplyCode && !bMultiLine )
  465. break;
  466. }
  467. return TRUE;
  468. }
  469. // 发送FTP命令
  470. BOOL CFtpDownload::SendCommand(LPCTSTR lpszCmd,LPCTSTR lpszParameter)
  471. {
  472. CString strCmd(lpszCmd);
  473. if( lpszParameter != NULL && lstrlen(lpszParameter)>0 )
  474. {
  475. strCmd += " ";
  476. strCmd += lpszParameter;
  477. }
  478. strCmd += "rn";
  479.  
  480. if( m_cControlSocket.Send(strCmd,strCmd.GetLength(),m_dwSendTimeout) != strCmd.GetLength() )
  481. return FALSE;
  482. return TRUE;
  483. }
  484. // 从Pasv的返回信息中获得IP和端口
  485. BOOL CFtpDownload::GetPasvIP(LPCTSTR lpszReply,CString& strPasvIP,int& nPasvPort)
  486. {
  487. CString strReply(lpszReply);
  488. CString strPort1,strPort2;
  489. strPasvIP = _T("");
  490. nPasvPort = 0;
  491. int nPos = strReply.Find('(');
  492. if( nPos == -1 )
  493. return FALSE;
  494. strPasvIP = strReply.Mid( nPos + 1 );
  495. nPos = strPasvIP.Find(')');
  496. if( nPos == -1 )
  497. return FALSE;
  498. strPasvIP = strPasvIP.Left(nPos);
  499. nPos = strPasvIP.ReverseFind(',');
  500. if( nPos == -1)
  501. return FALSE;
  502. strPort2 = strPasvIP.Right(strPasvIP.GetLength() - nPos -1 );
  503. strPasvIP = strPasvIP.Left(nPos);
  504. nPos = strPasvIP.ReverseFind(',');
  505. if( nPos == -1 )
  506. return FALSE;
  507. strPort1 = strPasvIP.Right(strPasvIP.GetLength() - nPos -1 );
  508. strPasvIP = strPasvIP.Left(nPos);
  509. strPasvIP.Replace(',','.');
  510. nPasvPort = (int) ( atoi(strPort1)*256+atoi(strPort2) );
  511. return TRUE;
  512. }
  513. // 获取文件时间和大小
  514. BOOL CFtpDownload::GetInfo(LPCTSTR lpszReply,DWORD& dwSize,CTime& TimeLastModified)
  515. {
  516. CString strReply(lpszReply);
  517. dwSize = 0;
  518. TimeLastModified = CTime::GetCurrentTime();
  519. //-rwxr-xr-x   1 ftpuser  ftpusers  14712179 Sep 13 09:55 csmproxy50nt.exe
  520. //-r--r--r--  1 root  wheel  454454 Oct  5 10:54 /pub/socks/dante-1.1.4.tar.gz
  521. //-r-xr-xr-x   1 0        0         986400 Jun 16  1998 /pub/Networks/Socket/Winsock/ws2setup.exe
  522. strReply.TrimLeft();
  523. strReply.TrimRight();
  524. strReply.MakeLower();
  525. int nCount = 0;
  526. int nPos ;
  527. while( nCount < 4 )
  528. {
  529. nPos = strReply.FindOneOf(" t");
  530. if( nPos == -1 )
  531. return FALSE;
  532. strReply = strReply.Mid(nPos+1);
  533. strReply.TrimLeft();
  534. nCount ++;
  535. }
  536. nPos = strReply.FindOneOf(" t");
  537. if( nPos == -1 )
  538. return FALSE;
  539. CString strSize = strReply.Left(nPos);
  540. dwSize = (DWORD)_ttol(strSize);
  541. strReply = strReply.Mid(nPos+1);
  542. strReply.TrimLeft();
  543. int nPos1 = strReply.ReverseFind(' ');
  544. int nPos2 = strReply.ReverseFind('t');
  545. if( nPos1 != -1 )
  546. {
  547. if( nPos2 != -1 )
  548. {
  549. nPos = ( nPos1 <= nPos2 )? nPos1:nPos2;
  550. }
  551. else
  552. {
  553. nPos = nPos1;
  554. }
  555. }
  556. else
  557. {
  558. if( nPos2 != -1 )
  559. {
  560. nPos = nPos2;
  561. }
  562. else
  563. {
  564. return FALSE;
  565. }
  566. }
  567. strReply = strReply.Left(nPos);
  568. strReply.TrimRight();
  569. TimeLastModified = GetTime(strReply);
  570. return TRUE;
  571. }
  572. // 发送请求
  573. int CFtpDownload::SendRequest(BOOL bPasv /*= TRUE*/)
  574. {
  575. while (TRUE)
  576. {
  577. CString strSend, strReply;
  578. DWORD dwSize, dwReplyCode;
  579. // 用于保存PASV或PORT的参数
  580. CString strIP;
  581. int nPort;
  582. CString         sMes;
  583.         strIP = _T("");
  584. nPort = 0;
  585. // 非PASV 
  586. CBufSocket cListenSocket;
  587. m_dwFileDownloadedSize = 0;
  588. m_dwDownloadSize    = 0;
  589. // 创建控制套接字
  590. Check( !CreateControlSocket(), FTP_REQUEST_FAIL);
  591. // 建立控制通道
  592. Check( m_bStopDownload,FTP_REQUEST_STOP);
  593. int nRet = MakeConnection(&m_cControlSocket,m_strServer,m_nPort);
  594. Check( ( nRet != FTP_REQUEST_SUCCESS ), nRet );
  595. Check( m_bStopDownload,FTP_REQUEST_STOP);
  596. Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);// 先获取服务器的Greeting信息
  597. //seawind
  598. Check( m_bStopDownload,FTP_REQUEST_STOP);
  599.         
  600.         //Removed by linsuyi 2001/01/31 16:32
  601.         // sMes.LoadString(IDS_CREATE_CHANNELS_SUCCESS);
  602.         // sMes += strReply;
  603.         // TRACE1("%s ", sMes);
  604.         
  605. // 开始发送命令
  606. // USER
  607. Check( m_bStopDownload,FTP_REQUEST_STOP);
  608. Check( !SendCommand(FTP_CMD_USER,m_strUsername) ,FTP_REQUEST_ERROR );
  609. Check( m_bStopDownload,FTP_REQUEST_STOP);
  610. Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR );
  611. //seawind
  612. Check( m_bStopDownload,FTP_REQUEST_STOP);
  613.         //Removed by linsuyi 2001/01/31 16:32
  614.         // sMes.Empty();
  615.         // sMes.LoadString(IDS_USER_COMMAND_SUCCESS);
  616.         // sMes += strReply;
  617. // TRACE1("%s ", sMes);
  618. switch(dwReplyCode)
  619. {
  620. case 230:
  621. break;
  622. case 331: // Need Password
  623. // PASS
  624. Check( m_bStopDownload,FTP_REQUEST_STOP);
  625. Check( !SendCommand(FTP_CMD_PASS,m_strPassword),FTP_REQUEST_ERROR);
  626. Check( m_bStopDownload,FTP_REQUEST_STOP);
  627. Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);
  628. //seawind
  629. Check( m_bStopDownload,FTP_REQUEST_STOP);
  630. Check( dwReplyCode != 230 ,FTP_REQUEST_FAIL);
  631.             //Removed by linsuyi 2001/01/31 16:32
  632.             // sMes.Empty();
  633.             // sMes.LoadString(IDS_PASS_COMMAND_SUCCESS);
  634.             // sMes += strReply;
  635. // TRACE1("%s ", sMes);
  636. break;
  637. default:
  638. return FTP_REQUEST_FAIL;
  639. break;
  640. }
  641. // 测试是否支持断点续传
  642. // REST 10
  643. Check( m_bStopDownload,FTP_REQUEST_STOP);
  644. Check( !SendCommand(FTP_CMD_REST,_T("10")),FTP_REQUEST_ERROR);
  645. Check( m_bStopDownload,FTP_REQUEST_STOP);
  646. Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);
  647. //seawind
  648. Check( m_bStopDownload,FTP_REQUEST_STOP);
  649. if( dwReplyCode == 350 )
  650. m_bSupportResume = TRUE;
  651. else
  652. m_bSupportResume = FALSE;
  653.         
  654.         //Removed by linsuyi 2001/01/31 16:32
  655.         // sMes.LoadString(IDS_REST10_COMMAND_SUCCESS);
  656.         // sMes += strReply;
  657.         // TRACE1("%s ", sMes);
  658.         
  659. // 字符模式
  660. Check( m_bStopDownload,FTP_REQUEST_STOP);
  661. Check( !SendCommand(FTP_CMD_TYPE,_T("A")),FTP_REQUEST_ERROR);
  662. Check( m_bStopDownload,FTP_REQUEST_STOP);
  663. Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);
  664. //seawind
  665. Check( m_bStopDownload,FTP_REQUEST_STOP);
  666. Check( dwReplyCode != 200 ,FTP_REQUEST_FAIL); // 必须至少支持这种模式
  667.         //Removed by linsuyi 2001/01/31 16:32
  668.         // sMes.Empty();
  669.         // sMes.LoadString(IDS_TYPEA_COMMAND_SUCCESS);
  670.         // sMes += strReply;
  671.         // TRACE1("%s ", sMes);
  672. // 是否支持PASV
  673. if( bPasv )
  674. {
  675. // PASV
  676. Check( m_bStopDownload,FTP_REQUEST_STOP);
  677. Check( !SendCommand(FTP_CMD_PASV,NULL),FTP_REQUEST_ERROR);
  678. Check( m_bStopDownload,FTP_REQUEST_STOP);
  679. Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);
  680. //seawind
  681.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  682.         
  683.             //Removed by linsuyi 2001/01/31 16:32
  684.             // sMes.Empty();
  685.             // sMes.LoadString(IDS_PASV_COMMAND_SUCCESS);
  686.             // sMes += strReply;
  687.             // TRACE1("%s ", sMes);
  688. if( dwReplyCode == 227 )
  689. {
  690. if( GetPasvIP(strReply,strIP,nPort) )
  691. {
  692. m_bPasv = TRUE;
  693. // 建立数据通道
  694. Check( m_bStopDownload,FTP_REQUEST_STOP);
  695. Check( !CreateDataSocket(),FTP_REQUEST_FAIL);
  696. nRet = MakeConnection(&m_cDataSocket,strIP,nPort);
  697. Check( nRet != FTP_REQUEST_SUCCESS,nRet);
  698. }
  699. else
  700. m_bPasv = FALSE;
  701. }
  702. else
  703. m_bPasv = FALSE;
  704. }
  705. dwSize = 0;
  706. m_TimeLastModified = CTime::GetCurrentTime();
  707.         // 根据是否采用PASV,而有很大区别
  708.         if (bPasv && m_bPasv)   // PASV
  709.         {
  710.             // 执行LIST命令
  711.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  712.             Check( !SendCommand(FTP_CMD_LIST, m_strObject ),FTP_REQUEST_ERROR);
  713.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  714.             Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);
  715.             //seawind
  716.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  717.             
  718.             //Removed by linsuyi 2001/01/31 16:32
  719.             // sMes.Empty();
  720.             // sMes.LoadString(IDS_LIST_COMMAND_SUCCESS);
  721.             // sMes += strReply;
  722.             // TRACE1("%s ", sMes);
  723.             
  724.             if ((dwReplyCode == 125) || ( dwReplyCode == 150 ))
  725.             {
  726.                 //从数据通道读取信息
  727.                 Check(m_bStopDownload, FTP_REQUEST_STOP);
  728.                 if (GetDataReply(strReply))
  729.                 {
  730.                     //Removed by linsuyi 2001/01/31 16:32
  731.                     // sMes.Empty();
  732.                     // sMes.LoadString(IDS_LIST_DATA_CHANNELS);
  733.                     // sMes += strReply;
  734.                     // TRACE1("%s ", sMes);
  735.                     
  736.                     if (!GetInfo(strReply,dwSize,m_TimeLastModified))
  737.                     {
  738.                         // TODO:
  739.                     }
  740.                 }
  741.                 CloseDataSocket();
  742.                 
  743.                 //从控制通道读取信息
  744.                 Check( m_bStopDownload,FTP_REQUEST_STOP);
  745.                 Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);
  746.                 //seawind
  747.                 Check( m_bStopDownload,FTP_REQUEST_STOP);
  748.                 Check( dwReplyCode != 250 && dwReplyCode != 226,FTP_REQUEST_ERROR);
  749.                 
  750.                 //Removed by linsuyi 2001/01/31 16:32
  751.                 // sMes.Empty();
  752.                 // sMes.LoadString(IDS_LIST_CONTROL_CHANNELS);
  753.                 // sMes += strReply;
  754.                 // TRACE1("%s ", sMes);
  755.                 
  756.             }   //125.150 -- LIST COMMAND [PASV]
  757.             
  758.             //Bin模式
  759.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  760.             Check( !SendCommand(FTP_CMD_TYPE,_T("I")),FTP_REQUEST_ERROR);
  761.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  762.             Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);
  763.             //seawind
  764.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  765.             
  766.             //Removed by linsuyi 2001/01/31 16:32
  767.             // sMes.Empty();
  768.             // sMes.LoadString(IDS_TYPEI_COMMAND_SUCCESS);
  769.             // sMes += strReply;
  770.             // TRACE1("%s ", sMes);
  771.                         
  772.             if( dwReplyCode != 200 )
  773.             {
  774.                 // TODO:
  775.             }
  776.             
  777.             // PASV命令
  778.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  779.             Check( !SendCommand(FTP_CMD_PASV,NULL ),FTP_REQUEST_ERROR);
  780.             Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);
  781.             //seawind
  782.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  783.             Check( dwReplyCode != 227,FTP_REQUEST_ERROR);
  784.             Check( !GetPasvIP(strReply,strIP,nPort),FTP_REQUEST_ERROR);
  785.             
  786.             //Removed by linsuyi 2001/01/31 16:32
  787.             // sMes.Empty();
  788.             // sMes.LoadString(IDS_PASV_PASV_COMMAND_SUCCESS);
  789.             // sMes += strReply;
  790.             // TRACE1("%s ", sMes);
  791.             
  792.             // 建立数据通道
  793.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  794.             Check( !CreateDataSocket(),FTP_REQUEST_FAIL);
  795.             nRet = MakeConnection(&m_cDataSocket,strIP,nPort);
  796.             Check( nRet != FTP_REQUEST_SUCCESS,nRet);
  797.             
  798.             //Removed by linsuyi 2001/01/31 16:32
  799.             // sMes.Empty();
  800.             // sMes.LoadString(IDS_PASV_CREATE_DATA_CHANNELS_SUCCESS);
  801.             // sMes += strReply;
  802.             // TRACE1("%s ", sMes);
  803.         }
  804.         else    // 不采用PASV
  805.         {
  806.             
  807.             char szListenIP[128],szTemp[128];
  808.             int nListenPort;
  809.             DWORD dwListenIP;
  810.             CString strListenIP;
  811.             
  812.             // 是否为SOCKS代理
  813.             if( m_nProxyType == FTP_PROXY_SOCKS4 ||
  814.                 m_nProxyType == FTP_PROXY_SOCKS4A||
  815.                 m_nProxyType == FTP_PROXY_SOCKS5 )
  816.             {
  817.                 if( !CreateDataSocket() )
  818.                     return FTP_REQUEST_FAIL;
  819.                 
  820.                 Check( m_bStopDownload,FTP_REQUEST_STOP);
  821.                 nRet = MakeConnection( &m_cDataSocket,m_strServer,m_nPort,TRUE,&dwListenIP,&nListenPort);
  822.                 Check( nRet != FTP_REQUEST_SUCCESS,nRet);
  823.                 strListenIP.Format("%d,%d,%d,%d",(dwListenIP>>24)&0xFF,(dwListenIP>>16)&0xFF,(dwListenIP>>8)&0xFF,(dwListenIP)&0xFF);
  824.             }
  825.             else
  826.             {
  827.                 //没有代理
  828.                 Check( m_bStopDownload,FTP_REQUEST_STOP);
  829.                 Check( !cListenSocket.Create(),FTP_REQUEST_FAIL);
  830.                 Check( !cListenSocket.Bind(0), FTP_REQUEST_ERROR);
  831.                 Check( !cListenSocket.Listen(1),FTP_REQUEST_ERROR);
  832.                 
  833.                 ZeroMemory(szListenIP,128);
  834.                 Check( !m_cControlSocket.GetSockName(szListenIP,nListenPort),FTP_REQUEST_ERROR);
  835.                 
  836.                 ZeroMemory(szTemp,128);
  837.                 Check( !cListenSocket.GetSockName(szTemp,nListenPort),FTP_REQUEST_ERROR);
  838.                 
  839.                 strListenIP =  _T("");
  840.                 strListenIP += szListenIP;
  841.                 strListenIP.Replace('.',',');
  842.             }
  843.             
  844.             strSend.Format(",%d,%d",nListenPort/256,nListenPort%256);
  845.             strSend = strListenIP+strSend;
  846.             
  847.             // PORT
  848.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  849.             Check( !SendCommand(FTP_CMD_PORT,strSend ),FTP_REQUEST_ERROR);
  850.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  851.             Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);
  852.             //seawind
  853.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  854.             Check( dwReplyCode != 200, FTP_REQUEST_FAIL ); // 必须支持该命令
  855.             
  856.             //Removed by linsuyi 2001/01/31 16:32
  857.             // sMes.Empty();
  858.             // sMes.LoadString(IDS_NOPASV_PORT_COMMAND_SUCCESS);
  859.             // sMes += strReply;
  860.             // TRACE1("%s ", sMes);
  861.             
  862.             // 执行LIST命令
  863.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  864.             Check( !SendCommand(FTP_CMD_LIST, m_strObject),FTP_REQUEST_ERROR);
  865.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  866.             Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);
  867.             //seawind
  868.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  869.             
  870.             //Removed by linsuyi 2001/01/31 16:32
  871.             // sMes.Empty();
  872.             // sMes.LoadString(IDS_NOPASV_LIST_COMMAND_SUCCESS);
  873.             // sMes += strReply;
  874.             // TRACE1("%s ", sMes);
  875.             
  876.             if( (dwReplyCode == 125) || ( dwReplyCode == 150 ) )
  877.             {
  878.                 if( m_nProxyType == FTP_PROXY_SOCKS4 ||
  879.                     m_nProxyType == FTP_PROXY_SOCKS4A||
  880.                     m_nProxyType == FTP_PROXY_SOCKS5 )
  881.                 {
  882.                     CSocksPacket cSocks( &m_cDataSocket );
  883.                     
  884.                     switch ( m_nProxyType )
  885.                     {
  886.                     case FTP_PROXY_SOCKS4A:
  887.                         Check( !cSocks.RecvPacket(PACKET_SOCKS4AREP,m_dwRecvTimeout),FTP_REQUEST_ERROR);
  888.                         Check( !cSocks.IsSocksOK(),FTP_REQUEST_FAIL);
  889.                         break;
  890.                     case FTP_PROXY_SOCKS4:
  891.                         Check( !cSocks.RecvPacket(PACKET_SOCKS4REP,m_dwRecvTimeout),FTP_REQUEST_ERROR);
  892.                         Check( !cSocks.IsSocksOK(),FTP_REQUEST_FAIL);
  893.                         break;
  894.                     case FTP_PROXY_SOCKS5:
  895.                         Check( !cSocks.RecvPacket(PACKET_SOCKS5REP,m_dwRecvTimeout),FTP_REQUEST_ERROR);
  896.                         Check( !cSocks.IsSocksOK(),FTP_REQUEST_FAIL);
  897.                         break;
  898.                     }
  899.                 }
  900.                 else
  901.                 {
  902.                     // ACCEPT
  903.                     SOCKET hSocket = cListenSocket.Accept(NULL,0,m_hStopEvent,WSA_INFINITE);
  904.                     Check( hSocket == INVALID_SOCKET,FTP_REQUEST_ERROR);
  905.                     Check( !CreateDataSocket(hSocket),FTP_REQUEST_FAIL);
  906.                 }
  907.                 
  908.                 // 从数据通道读取信息
  909.                 Check( m_bStopDownload,FTP_REQUEST_STOP);
  910.                 if (GetDataReply(strReply))
  911.                 {
  912.                     //Removed by linsuyi 2001/01/31 16:32
  913.                     // sMes.Empty();
  914.                     // sMes.LoadString(IDS_NOPASV_LIST_DATA_CHANNELS);
  915.                     // sMes += strReply;
  916.                     // TRACE1("%s ", sMes);
  917.                     
  918.                     if( !GetInfo(strReply,dwSize,m_TimeLastModified) )
  919.                     {
  920.                         // TODO:
  921.                     }
  922.                 }
  923.                 CloseDataSocket();
  924.                 
  925.                 // 从控制通道读取信息
  926.                 Check( m_bStopDownload,FTP_REQUEST_STOP);
  927.                 Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);
  928.                 //seawind
  929.                 Check( m_bStopDownload,FTP_REQUEST_STOP);
  930.                 Check( dwReplyCode != 250 && dwReplyCode != 226,FTP_REQUEST_ERROR);
  931.                 
  932.                 //Removed by linsuyi 2001/01/31 16:32
  933.                 // sMes.Empty();
  934.                 // sMes.LoadString(IDS_NOPASV_LIST_CONTROL_CHANNELS);
  935.                 // sMes += strReply;
  936.                 // TRACE1("%s ", sMes);
  937.             } // LIST
  938.             
  939.             // Bin模式
  940.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  941.             Check( !SendCommand(FTP_CMD_TYPE,_T("I")),FTP_REQUEST_ERROR);
  942.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  943.             Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);
  944.             //seawind
  945.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  946.             
  947.             //Removed by linsuyi 2001/01/31 16:32
  948.             // sMes.Empty();
  949.             // sMes.LoadString(IDS_NOPASV_TYPEI_COMMAND_SUCCESS);
  950.             // sMes += strReply;
  951.             // TRACE1("%s ", sMes);
  952.             
  953.             if (dwReplyCode != 200)
  954.             {
  955.                 // TODO:
  956.             }
  957.             
  958.             // PORT命令
  959.             if (
  960.                 (m_nProxyType == FTP_PROXY_SOCKS4) ||
  961.                 (m_nProxyType == FTP_PROXY_SOCKS4A) ||
  962.                 (m_nProxyType == FTP_PROXY_SOCKS5)
  963.             )
  964.             {
  965.                 Check( m_bStopDownload,FTP_REQUEST_STOP);
  966.                 Check( !CreateDataSocket(),FTP_REQUEST_FAIL);
  967.                 nRet = MakeConnection( &m_cDataSocket,m_strServer,m_nPort,TRUE,&dwListenIP,&nListenPort);
  968.                 Check( nRet != FTP_REQUEST_SUCCESS,nRet);
  969.                 strListenIP.Format("%d,%d,%d,%d",(dwListenIP>>24)&0xFF,(dwListenIP>>16)&0xFF,(dwListenIP>>8)&0xFF,(dwListenIP)&0xFF);
  970.             }
  971.             else
  972.             {
  973.                 Check( m_bStopDownload,FTP_REQUEST_STOP);
  974.                 Check( !cListenSocket.Create(),FTP_REQUEST_FAIL);
  975.                 Check( !cListenSocket.Bind(0),FTP_REQUEST_ERROR);
  976.                 Check( !cListenSocket.Listen(1),FTP_REQUEST_ERROR);
  977.                 
  978.                 ZeroMemory(szListenIP,128);
  979.                 Check( !m_cControlSocket.GetSockName(szListenIP,nListenPort),FTP_REQUEST_ERROR);
  980.                 
  981.                 ZeroMemory(szTemp,128);
  982.                 Check( !cListenSocket.GetSockName(szTemp,nListenPort),FTP_REQUEST_ERROR);
  983.                 
  984.                 strListenIP = _T("");
  985.                 strListenIP += szListenIP;
  986.                 strListenIP.Replace('.',',');
  987.             }
  988.             
  989.             strSend.Format(",%d,%d",nListenPort/256,nListenPort%256);
  990.             strSend = strListenIP+strSend;
  991.             
  992.             // PORT
  993.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  994.             Check( !SendCommand(FTP_CMD_PORT,strSend ),FTP_REQUEST_ERROR);
  995.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  996.             Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);
  997.             //seawind
  998.             Check( m_bStopDownload,FTP_REQUEST_STOP);
  999.             Check( dwReplyCode != 200, FTP_REQUEST_FAIL);// 必须支持该命令
  1000.             
  1001.             //Removed by linsuyi 2001/01/31 16:32
  1002.             // sMes.Empty();
  1003.             // sMes.LoadString(IDS_NOPASV_PORT_COMMAND_SUCCESS);
  1004.             // sMes += strReply;
  1005.             // TRACE1("%s ", sMes);
  1006.             
  1007.         }   // NO PASV
  1008.         
  1009.         // 准备下载
  1010.         if (dwSize == 0)
  1011.         {
  1012. // 试一试SIZE命令
  1013. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1014. Check( !SendCommand(FTP_CMD_SIZE, m_strObject ),FTP_REQUEST_ERROR);
  1015. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1016. Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);
  1017. //seawind
  1018. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1019.             //Removed by linsuyi 2001/01/31 16:32
  1020.             // sMes.Empty();
  1021.             // sMes.LoadString(IDS_SIZE_COMMAND_SUCCESS);
  1022.             // sMes += strReply;
  1023.             // TRACE1("%s ", sMes);
  1024.             
  1025. if( dwReplyCode == 213 )
  1026. {
  1027. strReply.TrimLeft();
  1028. strReply.TrimRight();
  1029. int nPos = strReply.Find(' ');
  1030. if( nPos != -1 )
  1031. {
  1032. strReply = strReply.Mid( nPos + 1 );
  1033. strReply.TrimLeft();
  1034. dwSize = (DWORD)_ttol(strReply);
  1035. }
  1036. }
  1037. }
  1038. // 判断m_strSavePath是否为路径
  1039. GetFileName();
  1040. if( m_strSavePath.Right(1) == '\' )
  1041. {
  1042. m_strTempSavePath = m_strSavePath;
  1043. m_strTempSavePath += m_strFileName;
  1044. m_strTempSavePath += ".tmp";
  1045. }
  1046. CString strRange;
  1047. m_dwFileDownloadedSize = 0;
  1048. if( m_bSupportResume )
  1049. {
  1050. // 查看文件已经下载的长度
  1051. CFileStatus fileDownStatus;
  1052. if (CFile::GetStatus(m_strTempSavePath,fileDownStatus) && !m_bForceDownload )
  1053. m_dwFileDownloadedSize = fileDownStatus.m_size;
  1054. strRange.Format(_T("%d"),m_dwFileDownloadedSize );
  1055. // REST COMMAND
  1056. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1057. Check( !SendCommand(FTP_CMD_REST,strRange ),FTP_REQUEST_ERROR);
  1058. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1059. Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);
  1060. //seawind
  1061. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1062. Check( dwReplyCode != 350,FTP_REQUEST_ERROR);
  1063.             //Removed by linsuyi 2001/01/31 16:32
  1064.             // sMes.Empty();
  1065.             // sMes.LoadString(IDS_REST_COMMAND_SUCCESS);
  1066.             // sMes += strReply;
  1067.             // TRACE1("%s ", sMes);
  1068. }
  1069. // 注意
  1070. m_dwFileSize  = dwSize;
  1071. m_dwDownloadSize = dwSize - m_dwFileDownloadedSize;
  1072. Check( m_dwDownloadSize < 0,FTP_REQUEST_FAIL);
  1073. // 发送RETR命令
  1074. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1075. Check( !SendCommand(FTP_CMD_RETR,m_strObject ),FTP_REQUEST_ERROR);
  1076. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1077. Check( !GetReply(strReply,dwReplyCode),FTP_REQUEST_ERROR);
  1078. //seawind
  1079. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1080. Check( (dwReplyCode != 125 && dwReplyCode != 150 && dwReplyCode != 110),FTP_REQUEST_FAIL);
  1081.         
  1082.         //Removed by linsuyi 2001/01/31 16:32
  1083.         // sMes.Empty();
  1084.         // sMes.LoadString(IDS_RETR_COMMAND_SUCCESS);
  1085.         // sMes += strReply;
  1086.         // TRACE1("%s ", sMes);
  1087.         
  1088.         // 非PASV方式要创建数据通道
  1089. if( !bPasv || !m_bPasv )
  1090. {
  1091. if( m_nProxyType == FTP_PROXY_SOCKS4 ||
  1092. m_nProxyType == FTP_PROXY_SOCKS4A||
  1093. m_nProxyType == FTP_PROXY_SOCKS5 )
  1094. {
  1095. CSocksPacket cSocks( &m_cDataSocket );
  1096. switch ( m_nProxyType )
  1097. {
  1098. case FTP_PROXY_SOCKS4A:
  1099. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1100. Check( !cSocks.RecvPacket(PACKET_SOCKS4AREP,m_dwRecvTimeout),FTP_REQUEST_ERROR);
  1101. Check( !cSocks.IsSocksOK(),FTP_REQUEST_FAIL);
  1102. break;
  1103. case FTP_PROXY_SOCKS4:
  1104. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1105. Check( !cSocks.RecvPacket(PACKET_SOCKS4REP,m_dwRecvTimeout),FTP_REQUEST_ERROR);
  1106. Check( !cSocks.IsSocksOK(),FTP_REQUEST_FAIL);
  1107. break;
  1108. case FTP_PROXY_SOCKS5:
  1109. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1110. Check( !cSocks.RecvPacket(PACKET_SOCKS5REP,m_dwRecvTimeout),FTP_REQUEST_ERROR);
  1111. Check( !cSocks.IsSocksOK(),FTP_REQUEST_FAIL);
  1112. break;
  1113. }
  1114. }
  1115. else
  1116. {
  1117. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1118. SOCKET hSocket = cListenSocket.Accept(NULL,0,m_hStopEvent,WSA_INFINITE);
  1119. Check( hSocket == INVALID_SOCKET,FTP_REQUEST_ERROR);
  1120. Check( !CreateDataSocket(hSocket),FTP_REQUEST_FAIL);
  1121. }
  1122. } // NO PASV 建立数据通道
  1123. return FTP_REQUEST_SUCCESS;
  1124. }// WHILE LOOP
  1125. return FTP_REQUEST_SUCCESS;
  1126. }
  1127. // 开始下载
  1128. int CFtpDownload::Download(LPCTSTR lpszDownloadUrl,LPCTSTR lpszSavePath,BOOL bForceDownload /*= FALSE */)
  1129. {
  1130. m_bStopDownload   = FALSE;
  1131. m_bForceDownload  = bForceDownload;
  1132. m_nRetryTimes   = 0;
  1133. m_nErrorCount   = 0;
  1134. m_strTempSavePath = _T("");
  1135. // 检验要下载的URL是否为空
  1136. m_strDownloadUrl = lpszDownloadUrl;
  1137. m_strDownloadUrl.TrimLeft();
  1138. m_strDownloadUrl.TrimRight();
  1139. if( m_strDownloadUrl.IsEmpty() )
  1140. return FTP_RESULT_FAIL;
  1141. // 检验要下载的URL是否有效
  1142. if ( !ParseURL(m_strDownloadUrl, m_strServer, m_strObject, m_nPort))
  1143. {
  1144. // 在前面加上"ftp://"再试
  1145. m_strDownloadUrl = _T("ftp://") + m_strDownloadUrl;
  1146. if ( !ParseURL(m_strDownloadUrl,m_strServer, m_strObject, m_nPort) )
  1147. {
  1148. TRACE(_T("Failed to parse the URL: %sn"), m_strDownloadUrl);
  1149. return FTP_RESULT_FAIL;
  1150. }
  1151. }
  1152. // 检查本地保存路径
  1153. m_strSavePath =  lpszSavePath;
  1154. m_strSavePath.TrimLeft();
  1155. m_strSavePath.TrimRight();
  1156. if( m_strSavePath.IsEmpty() )
  1157. m_strSavePath = DEFAULT_SAVE_DIR;
  1158. if( m_strSavePath.Right(1) != '\' ) // 只有路径,没有文件名
  1159. {
  1160. m_strTempSavePath =  m_strSavePath;
  1161. m_strTempSavePath += ".tmp";
  1162. }
  1163. // 创建停止事件
  1164. if( m_hStopEvent == NULL )
  1165. {
  1166. m_hStopEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
  1167. if( m_hStopEvent == NULL )
  1168. return FTP_RESULT_FAIL;
  1169. //seawind
  1170. m_cControlSocket.m_hStopEvent = m_hStopEvent;
  1171. m_cDataSocket.m_hStopEvent = m_hStopEvent;
  1172. }
  1173. ResetEvent( m_hStopEvent );
  1174. // 设置下载数据
  1175. m_dwDownloadedSize = 0;
  1176. m_dwFileDownloadedSize = 0;
  1177. m_dwFileSize = 0;
  1178. m_dwDownloadSize = 0;
  1179. BOOL bSendOnce = TRUE; // 用于控制向hWndNotify窗口发送消息
  1180. ReDownload:
  1181. int nRequestRet = SendRequest( m_bPasv ) ;
  1182. //seawind
  1183. //if (WaitForSingleObject(m_hStopEvent, 0) == WAIT_OBJECT_0)
  1184. // return HTTP_RESULT_STOP;
  1185. Check( m_bStopDownload,FTP_RESULT_STOP);
  1186. switch(nRequestRet)
  1187. {
  1188. case FTP_REQUEST_SUCCESS:
  1189. TRACE0("nn***FTP_REQUEST_SUCCESS");
  1190. break;
  1191. case FTP_REQUEST_STOP:
  1192. TRACE0("nn***FTP_REQUEST_STOP");
  1193. return FTP_RESULT_STOP;
  1194. break;
  1195. case FTP_REQUEST_FAIL:
  1196. TRACE0("nn***FTP_REQUEST_FAIL");
  1197. return FTP_RESULT_FAIL;
  1198. break;
  1199. case FTP_REQUEST_ERROR:
  1200. TRACE0("nn***FTP_REQUEST_ERROR");
  1201. // 停止下载?
  1202. Check( m_bStopDownload,FTP_RESULT_STOP);
  1203. switch( m_nRetryType )
  1204. {
  1205. case FTP_RETRY_NONE:
  1206. return FTP_RESULT_FAIL;
  1207. break;
  1208. case FTP_RETRY_ALWAYS:
  1209. if( m_nRetryDelay > 0 )
  1210. {
  1211. //为了让等待时也能退出,不能使用Sleep函数
  1212. if( WaitForSingleObject(m_hStopEvent,m_nRetryDelay) == WAIT_OBJECT_0 )
  1213. return FTP_RESULT_STOP;
  1214. }
  1215. goto ReDownload;
  1216. break;
  1217. case FTP_RETRY_TIMES:
  1218. if( m_nRetryTimes > m_nRetryMax )
  1219. return FTP_RESULT_FAIL;
  1220. m_nRetryTimes++;
  1221. if( m_nRetryDelay > 0 )
  1222. {
  1223. //为了让等待时也能退出,不能使用Sleep函数
  1224. if( WaitForSingleObject(m_hStopEvent,m_nRetryDelay) == WAIT_OBJECT_0 )
  1225. return FTP_RESULT_STOP;
  1226. }
  1227. goto ReDownload;
  1228. break;
  1229. default:
  1230. return FTP_RESULT_FAIL;
  1231. break;
  1232. }
  1233. break;
  1234. default:
  1235. return FTP_RESULT_FAIL;
  1236. break;
  1237. }
  1238. // Now Support none content-length header
  1239. //if (m_dwDownloadSize == 0)
  1240. // return FTP_RESULT_FAIL;
  1241. if( m_strSavePath.Right(1) == '\' )
  1242. m_strSavePath += m_strFileName;
  1243. if( !m_bForceDownload ) // 非强制下载,检查Last-Modified
  1244. {
  1245. CFileStatus fileStatus;
  1246. if (CFile::GetStatus(m_strSavePath,fileStatus))
  1247. {
  1248. // 可能会存在1秒的误差
  1249. if (( fileStatus.m_mtime - m_TimeLastModified <=2 && m_TimeLastModified-fileStatus.m_mtime<=2 ) && (DWORD)fileStatus.m_size == m_dwFileSize )
  1250. return FTP_RESULT_SAMEAS;
  1251. }
  1252. }
  1253. CFile fileDown;
  1254. if(! fileDown.Open(m_strTempSavePath,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite|CFile::shareDenyWrite) )
  1255. {
  1256. TRACE0("nn*** FILE OPEN FAILED!");
  1257. return FTP_RESULT_FAIL;
  1258. }
  1259. // 应该判断一下是否支持断点续传
  1260. if( m_bSupportResume )
  1261. {
  1262. try
  1263. {
  1264. fileDown.SeekToEnd();
  1265. }
  1266. catch(CFileException* e)                                         
  1267. {
  1268.   e->Delete();
  1269.   return FTP_RESULT_FAIL;
  1270. }
  1271. }
  1272. if( bSendOnce && m_bNotify )
  1273. {
  1274. FTPDOWNLOADSTATUS DownloadStatus;
  1275. DownloadStatus.dwFileSize  = m_dwFileSize;
  1276. DownloadStatus.strFileName = m_strFileName;
  1277. DownloadStatus.dwFileDownloadedSize  = m_dwFileDownloadedSize;
  1278. DownloadStatus.nStatusType = FTP_STATUS_FILESIZE;
  1279. if (WaitForSingleObject(m_hStopEvent, 0) != WAIT_OBJECT_0)
  1280. ::SendMessage(m_hNotifyWnd,m_nNotifyMessage,MSG_FTPDOWNLOAD_STATUS,(LPARAM)&DownloadStatus);
  1281. DownloadStatus.nStatusType = FTP_STATUS_FILENAME;
  1282. if (WaitForSingleObject(m_hStopEvent, 0) != WAIT_OBJECT_0)
  1283. ::SendMessage(m_hNotifyWnd,m_nNotifyMessage,MSG_FTPDOWNLOAD_STATUS,(LPARAM)&DownloadStatus);
  1284. DownloadStatus.nStatusType = FTP_STATUS_FILEDOWNLOADEDSIZE;
  1285. if (WaitForSingleObject(m_hStopEvent, 0) != WAIT_OBJECT_0)
  1286. ::SendMessage(m_hNotifyWnd,m_nNotifyMessage,MSG_FTPDOWNLOAD_STATUS,(LPARAM)&DownloadStatus);
  1287. bSendOnce = FALSE;
  1288. }
  1289. m_dwDownloadedSize = 0;
  1290. // 现在开始读取数据
  1291. char szReadBuf[READ_BUFFER_SIZE+1];
  1292. /////////////////////////////////////////////
  1293. // 如果m_dwDownloadSize = 0 (说明大小未知)
  1294. if( m_dwDownloadSize == 0 )
  1295. m_dwDownloadSize = 0xFFFFFFFF;
  1296. ////////////////////////////////////////////
  1297. do
  1298. {
  1299. // 停止下载?
  1300. Check( m_bStopDownload,FTP_RESULT_STOP);
  1301. ZeroMemory(szReadBuf,READ_BUFFER_SIZE+1);
  1302. int nRet = m_cDataSocket.BSDGetData(szReadBuf,READ_BUFFER_SIZE,m_dwRecvTimeout);
  1303. //seawind
  1304. Check( m_bStopDownload, FTP_RESULT_STOP);
  1305. if (nRet <= 0)
  1306. {
  1307. ////////////////////////////////////////
  1308. if( m_dwDownloadSize == 0xFFFFFFFF )
  1309. break;
  1310. ///////////////////////////////////////
  1311. fileDown.Close();
  1312. m_nErrorCount++;
  1313. goto ReDownload; //再次发送请求
  1314. }
  1315. // 将数据写入文件
  1316. try
  1317. {
  1318. fileDown.Write(szReadBuf,nRet);
  1319. }
  1320. catch(CFileException* e)
  1321. {
  1322. e->Delete();
  1323. fileDown.Close();
  1324. goto ReDownload;
  1325. }
  1326. m_dwDownloadedSize += nRet;
  1327. m_dwFileDownloadedSize += nRet;
  1328. // 通知消息
  1329. if (m_bNotify)
  1330. {
  1331. FTPDOWNLOADSTATUS DownloadStatus;
  1332.             
  1333. DownloadStatus.nStatusType = FTP_STATUS_FILEDOWNLOADEDSIZE;
  1334. DownloadStatus.dwFileDownloadedSize = m_dwFileDownloadedSize;
  1335. DownloadStatus.dwFileSize = m_dwFileSize;
  1336. DownloadStatus.strFileName = m_strFileName;
  1337. if (WaitForSingleObject(m_hStopEvent, 0) != WAIT_OBJECT_0)
  1338. ::SendMessage(m_hNotifyWnd,m_nNotifyMessage,MSG_FTPDOWNLOAD_STATUS,(LPARAM)&DownloadStatus);
  1339. }
  1340.     } while(m_dwDownloadedSize < m_dwDownloadSize);
  1341.     
  1342. TRACE0("nn***FILE DOWNLOAD SUCCESS!");
  1343. // 关闭文件
  1344. fileDown.Close();
  1345. //关闭SOCKET
  1346. CloseControlSocket();
  1347. CloseDataSocket();
  1348. // 文件改名
  1349. //首先将已有的文件删除
  1350. ::DeleteFile(m_strSavePath);
  1351.     
  1352.     //再将新下载的文件改名
  1353. ::MoveFile(m_strTempSavePath, m_strSavePath);
  1354.     
  1355.     //再将新下载的文件的时间改回去
  1356.     CFileStatus fileStatus;
  1357.     
  1358.     fileStatus.m_size = 0;
  1359.     fileStatus.m_attribute = 0;
  1360.     
  1361.     try
  1362.     {
  1363.         CFile::GetStatus(m_strSavePath, fileStatus);
  1364.         
  1365.         fileStatus.m_mtime = m_TimeLastModified;
  1366.         CFile::SetStatus(m_strSavePath,fileStatus);
  1367.     }
  1368.     catch(CFileException *e)
  1369.     {
  1370.         e->Delete();
  1371.     }
  1372.     
  1373.     // 不再进行其他操作
  1374.     return FTP_RESULT_SUCCESS;
  1375. }
  1376. // 建立连接
  1377. int CFtpDownload::MakeConnection(CBufSocket* pBufSocket,CString strServer,int nPort,BOOL bBind /*= FALSE*/ ,LPDWORD lpdwIP /*= NULL*/,LPINT lpnPort /*= NULL*/)
  1378. {
  1379. CSocksPacket cSocks( pBufSocket );
  1380. DWORD dwIP;
  1381. BYTE byAuth,byAtyp,byCmd;
  1382. SOCKSREPPACKET pack;
  1383. CString strAuth,strAddr,strIP,strDigit;
  1384. strAuth = _T("");
  1385. strAddr = _T("");
  1386. // 检查是否为BIND命令
  1387. if( bBind && ( m_nProxyType == FTP_PROXY_SOCKS4  || 
  1388. m_nProxyType == FTP_PROXY_SOCKS4A || 
  1389. m_nProxyType == FTP_PROXY_SOCKS5 ) )
  1390. {
  1391. byCmd = CMD_BIND;
  1392. if( lpdwIP == NULL || lpnPort == NULL )
  1393. return FTP_REQUEST_ERROR;
  1394. }
  1395. else
  1396. {
  1397. bBind = FALSE;
  1398. byCmd = CMD_CONNECT;
  1399. }
  1400. switch( m_nProxyType )
  1401. {
  1402. case FTP_PROXY_NONE:
  1403. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1404. Check( !pBufSocket->Connect(strServer,nPort,m_dwConnTimeout,TRUE),FTP_REQUEST_ERROR);
  1405. break;
  1406. case FTP_PROXY_SOCKS4A:
  1407. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1408. dwIP = CBufSocket::GetIP(strServer,TRUE);
  1409. if( dwIP == INADDR_NONE )
  1410. {
  1411. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1412. Check( !pBufSocket->Connect(m_strProxyServer,m_nProxyPort,m_dwConnTimeout,TRUE),FTP_REQUEST_ERROR);
  1413. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1414. Check( !cSocks.SendSocks4aReq(byCmd,nPort,strServer,m_strProxyUsername,m_dwSendTimeout),FTP_REQUEST_ERROR);
  1415. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1416. ZeroMemory(&pack,sizeof(SOCKSREPPACKET));
  1417. Check( !cSocks.RecvPacket(&pack,PACKET_SOCKS4AREP,m_dwRecvTimeout),FTP_REQUEST_ERROR);
  1418. Check( !cSocks.IsSocksOK(&pack,PACKET_SOCKS4AREP),FTP_REQUEST_FAIL);// 请求有错误,重试可能是没有用的
  1419. // 如果是BIND命令
  1420. if( bBind )
  1421. {
  1422. if( pack.socks4aRep.dwDestIP == 0 )
  1423. *lpdwIP = ntohl(CBufSocket::GetIP( m_strProxyServer ));
  1424. else
  1425. *lpdwIP = pack.socks4aRep.dwDestIP;
  1426. *lpnPort= (int)pack.socks4aRep.wDestPort;
  1427. }
  1428. break;// NOTICE:如果本地能够解析域名,可以使用SOCKS4 Proxy
  1429. }
  1430. case FTP_PROXY_SOCKS4:
  1431. // 必须要得到Proxy Server的IP地址(不能为域名)
  1432. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1433. dwIP = CBufSocket::GetIP(strServer,TRUE);
  1434. Check( dwIP == INADDR_NONE ,FTP_REQUEST_ERROR);
  1435. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1436. Check( !pBufSocket->Connect(m_strProxyServer,m_nProxyPort,m_dwConnTimeout,TRUE),FTP_REQUEST_ERROR);
  1437. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1438. Check( !cSocks.SendSocks4Req( byCmd,nPort,dwIP,m_strProxyUsername,m_dwSendTimeout),FTP_REQUEST_ERROR);
  1439. ZeroMemory(&pack,sizeof(SOCKSREPPACKET));
  1440. Check( !cSocks.RecvPacket(&pack,PACKET_SOCKS4REP,m_dwRecvTimeout),FTP_REQUEST_ERROR);
  1441. Check( !cSocks.IsSocksOK(&pack,PACKET_SOCKS4REP),FTP_REQUEST_FAIL); // 请求有错误,重试可能是没有用的
  1442. // 如果是BIND命令
  1443. if( bBind )
  1444. {
  1445. if( pack.socks4Rep.dwDestIP == 0 )
  1446. *lpdwIP = ntohl(CBufSocket::GetIP( m_strProxyServer) );
  1447. else
  1448. *lpdwIP = pack.socks4Rep.dwDestIP;
  1449. *lpnPort= (int)pack.socks4Rep.wDestPort;
  1450. }
  1451. break;
  1452. case FTP_PROXY_SOCKS5:
  1453. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1454. Check( !pBufSocket->Connect(m_strProxyServer,m_nProxyPort,m_dwConnTimeout,TRUE),FTP_REQUEST_ERROR);
  1455. if( m_bProxyAuthorization )
  1456. {
  1457. char ch = (char)AUTH_NONE;
  1458. strAuth += ch;
  1459. ch  = (char)AUTH_PASSWD;
  1460. strAuth += ch;
  1461. }
  1462. else
  1463. {
  1464. char ch = (char)AUTH_NONE;
  1465. strAuth += ch;
  1466. }
  1467. byAuth =(BYTE)strAuth.GetLength();
  1468. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1469. Check( !cSocks.SendSocks5AuthReq(byAuth,(LPCTSTR)strAuth,m_dwSendTimeout),FTP_REQUEST_ERROR);
  1470. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1471. ZeroMemory(&pack,sizeof(SOCKSREPPACKET));
  1472. Check( !cSocks.RecvPacket(&pack,PACKET_SOCKS5AUTHREP,m_dwRecvTimeout),FTP_REQUEST_ERROR);
  1473. Check( !cSocks.IsSocksOK(&pack,PACKET_SOCKS5AUTHREP),FTP_REQUEST_FAIL); // 请求有错误,重试可能是没有用的
  1474. switch( pack.socks5AuthRep.byAuth )
  1475. {
  1476. case AUTH_NONE:
  1477. break;
  1478. case AUTH_PASSWD:
  1479. Check( !m_bProxyAuthorization ,FTP_REQUEST_FAIL);
  1480. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1481. Check( !cSocks.SendSocks5AuthPasswdReq(m_strProxyUsername,m_strProxyPassword,m_dwSendTimeout),FTP_REQUEST_ERROR);
  1482. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1483. ZeroMemory(&pack,sizeof(SOCKSREPPACKET));
  1484. Check( !cSocks.RecvPacket(&pack,PACKET_SOCKS5AUTHPASSWDREP,m_dwRecvTimeout),FTP_REQUEST_ERROR);
  1485. Check( !cSocks.IsSocksOK(&pack,PACKET_SOCKS5AUTHPASSWDREP) ,FTP_REQUEST_FAIL); // 请求有错误,重试可能是没有用的
  1486. break;
  1487. case AUTH_GSSAPI:
  1488. case AUTH_CHAP:
  1489. case AUTH_UNKNOWN:
  1490. default:
  1491. return FTP_REQUEST_FAIL;
  1492. break;
  1493. }
  1494. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1495. dwIP = CBufSocket::GetIP(strServer,TRUE);
  1496. if( dwIP != INADDR_NONE )
  1497. {
  1498. byAtyp = ATYP_IPV4ADDR;
  1499. // 不需要转换字节序(已经是网络字节序)
  1500. strAddr += (char)( (dwIP    ) &0x000000ff); 
  1501. strAddr += (char)( (dwIP>>8 ) &0x000000ff); 
  1502. strAddr += (char)( (dwIP>>16) &0x000000ff); 
  1503. strAddr += (char)( (dwIP>>24) &0x000000ff); 
  1504. }
  1505. else
  1506. {
  1507. byAtyp = ATYP_HOSTNAME;
  1508. char ch = (char)strServer.GetLength();
  1509. strAddr += ch;
  1510. strAddr += strServer;
  1511. }
  1512. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1513. Check( !cSocks.SendSocks5Req(byCmd,byAtyp,strAddr,nPort,m_dwSendTimeout),FTP_REQUEST_ERROR);
  1514. Check( m_bStopDownload,FTP_REQUEST_STOP);
  1515. ZeroMemory(&pack,sizeof(SOCKSREPPACKET));
  1516. Check( !cSocks.RecvPacket(&pack,PACKET_SOCKS5REP,m_dwRecvTimeout),FTP_REQUEST_ERROR);
  1517. Check( !cSocks.IsSocksOK(&pack,PACKET_SOCKS5REP),FTP_REQUEST_FAIL); // 请求有错误,重试可能是没有用的
  1518. // 如果是BIND命令
  1519. if( bBind )
  1520. {
  1521. Check( pack.socks5Rep.byAtyp != ATYP_IPV4ADDR,FTP_REQUEST_ERROR);
  1522. strIP  = _T("");
  1523. strDigit.Format("%d",(BYTE)pack.socks5Rep.pszBindAddr[0]);
  1524. strIP += strDigit;
  1525. strIP += ".";
  1526. strDigit.Format("%d",(BYTE)pack.socks5Rep.pszBindAddr[1]);
  1527. strIP += strDigit;
  1528. strIP += ".";
  1529. strDigit.Format("%d",(BYTE)pack.socks5Rep.pszBindAddr[2]);
  1530. strIP += strDigit;
  1531. strIP += ".";
  1532. strDigit.Format("%d",(BYTE)pack.socks5Rep.pszBindAddr[3]);
  1533. strIP += strDigit;
  1534. *lpdwIP = ntohl( inet_addr(strIP) );
  1535. if( *lpdwIP == 0 )
  1536. *lpdwIP = ntohl( CBufSocket::GetIP( m_strProxyServer ) );
  1537. *lpnPort= (int)pack.socks5Rep.wBindPort;
  1538. }
  1539. break;
  1540. default:
  1541. return FTP_REQUEST_FAIL;
  1542. break;
  1543. }
  1544. return FTP_REQUEST_SUCCESS;
  1545. }
  1546. //seawind
  1547. BOOL CFtpDownload::IsUserStop()
  1548. {
  1549. ASSERT(m_hStopEvent != NULL);
  1550. if (WaitForSingleObject(m_hStopEvent, 0) == WAIT_OBJECT_0)
  1551. return TRUE;
  1552. else
  1553. return FALSE;
  1554. }