1 Star 0 Fork 8

zxfann/mfc

forked from 我爱阿牛/mfc 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
wininet-ftp.cpp 59.02 KB
一键复制 编辑 原始数据 按行查看 历史
cc266 提交于 2020-08-04 11:18 . wininet
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323
wininet实现ftp客户端关于传输进度的分析2004-07-18 21:14 wininet提供了接口FtpGetFile实现从ftp服务器下载文件;提供了接口FtpPutFile实现把文件上传到ftp服务器上。通过这两个接口,我们能够完成基本的ftp文件传输客户端功能。但是在传输的同时,我们希望知道当前大概传输了多少,传输完整个文件大概需要多长时间,当前进度是多少,大概还有多长时间才能传输完毕。
单纯依靠这两个接口,我们无法实现这个功能。仔细翻阅msdn,发现wininet还提供了这样一个接口:InternetSetStatusCallback。该函数就是设置文件传输的回调函数,其原型如下:
INTERNET_STATUS_CALLBACKInternetSetStatusCallback(  HINTERNEThInternet,  INTERNET_STATUS_CALLBACKlpfnInternetCallback);该接口为internet会话设置一个状态回调函数:lpfnInternetCallback,该回调函数的原型声明如下:
void CALLBACKInternetStatusCallback(  HINTERNEThInternet,  DWORD_PTRdwContext,  DWORDdwInternetStatus,  LPVOIDlpvStatusInformation,  DWORDdwStatusInformationLength);通过这个回调函数,我们可以实现对当前传输进度的控制:可以统计出到目前已经传输了多少字节,并且计算出传输速率,从而可以得知大概还剩下多少时间。
下面这个类就是实现对ftp文件传输客户端的封装:
//////////////////////////////////////////////////////////////////////////
// 模块名称:文件传输状态控制
// 模块功能:实现对界面时时报告当前文件传输的进度状态,并且实现上传和下载
// 文件的客户端功能。
// 文件名称:ftpclientctrl.h
//________________________________________________________________________
#ifndef _WININET_
#include <wininet.h>
#endif
class CFtpClientCtrl
{
public:
CFtpClientCtrl();
virtual ~CFtpClientCtrl();
enum
{
ftp_begin, // 对于该事件,wparam = ftp_begin,lparam表示要传输的文件大小
ftp_transfer, // 对于该事件,wparam = ftp_transfer,lParam表示已经传输的大小
ftp_end // 对于该事件,wparam = ftp_end,lparam表示结果,0--失败,1--成功
};
// 设置ftp服务器的连接参数
BOOL SetServerParam( LPCTSTR lpszIpAddr, // IP地址
LPCTSTR lpszUser, // 登录名称
LPCTSTR lpszPwd, // 登录口令
WORD wPort = INTERNET_DEFAULT_FTP_PORT, // FTP服务器端口
LPCTSTR lpszProxyName = NULL, // 代理名称
LPCTSTR lpszProxyPwd = NULL); // 代理口令
// 开始下载文件
BOOL BeginDownload( HWND hWnd, // 接收消息的窗口
LPCTSTR lpszRemote, // 远程文件名称
LPCTSTR lpszLocal, // 保存本地的文件
DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输
BOOL BeginDownload( DWORD dwThread, // 接收消息的线程
LPCTSTR lpszRemote, // 远程文件名称
LPCTSTR lpszLocal, // 保存本地的文件
DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输
// 开始上传文件
BOOL BeginUpload( HWND hWnd, // 接收消息的窗口
LPCTSTR lpszRemote, // 远程文件名称
LPCTSTR lpszLocal, // 本地文件名称
DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输
BOOL BeginUpload( DWORD dwThread, // 接收消息的线程
LPCTSTR lpszRemote, // 远程文件名称
LPCTSTR lpszLocal, // 本地文件名称
DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输
// 结束传输文件
BOOL EndFtpFile();
// 得到当前ftp的会话句柄
HINTERNET GetCurrentSession() const{return m_hSession;}
// 得到当前的连接句柄
HINTERNET GetCurrentConnect() const{return m_hConnect;}
// 获取远程文件名称
LPCTSTR GetCurrentRemoteFile() const{return m_szRemote;}
// 获取本地文件名称
LPCTSTR GetCurrentLocalFile() const{return m_szLocal;}
// 获取当前传输的文件类型
DWORD GetCurrentFileType() const{return m_dwFileType;}
// 获取当前传输接收消息窗口
HWND GetCurrentFtpWnd() const{return m_hWnd;}
// 获取当前传输接收消息线程
DWORD GetCurrentFtpThread() const{return m_dwThread;}
// 获取当前已经传输的大小
DWORD GetCurrentFtpSize() const{return m_dwCurrentFtpSize;}
// 递增已经传输的大小
DWORD IncreaseFtpSize(DWORD dwStep);
// 注册一个消息
void RegisterMsgHandle(UINT uMsgHandle){m_uMsgHandle = uMsgHandle;}
// 获取已经注册的消息
UINT GetRegisterMsgHandle() const{return m_uMsgHandle;}
// 获取文件总长度
DWORD GetTotalFileSize() const{return m_dwTotalFileSize;}
// 清除FTP
void ClearFtpSession();
// 设置FTP传输方向
void SetFtpDirect(BOOL bDownload = TRUE){m_bFtpDirect = bDownload;}
// 获取FTP传输方向
BOOL GetFtpDirect() const{return m_bFtpDirect;}
// 判断文件类型是否是ASCII
static BOOL IsFileAscii(LPCTSTR lpszFile);
protected:
// 获取远程文件的大小
DWORD GetRemoteFileSize();
// 获取本地文件的大小
DWORD GetLocalFileSize();
// 下载文件
BOOL DownloadFile( LPCTSTR lpszRemote, // 远程文件名称
LPCTSTR lpszLocal, // 保存本地的文件
DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输
// 上传文件
BOOL UploadFile( LPCTSTR lpszRemote, // 远程文件名称
LPCTSTR lpszLocal, // 保存本地的文件
DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输
protected:
HINTERNET m_hSession; // 应用于InternetOpen
HINTERNET m_hConnect; // 应用于InternetConnect
TCHAR m_szFtpSrvIp[24]; // FTP服务器的ip地址
TCHAR m_szFtpSrvUser[32]; // FTP服务器的登录用户
TCHAR m_szFtpSrvPwd[32]; // FTP服务器的登录口令
TCHAR m_szProxyName[64]; // 代理的名称
TCHAR m_szProxyPwd[32]; // 代理的口令
WORD m_wFtpSrvPort; // FTP服务器的监听端口
HANDLE m_hFtpThread; // FTP传输的线程句柄
DWORD m_dwFtpThread; // FTP传输的线程编号
TCHAR m_szRemote[MAX_PATH]; // 远程文件
TCHAR m_szLocal[MAX_PATH]; // 本地文件
DWORD m_dwFileType; // 传输的文件类型
HWND m_hWnd; // 接收传输进度消息的窗口
DWORD m_dwThread; // 接收传输进度消息的线程
DWORD m_dwCurrentFtpSize; // 当前传输的大小
DWORD m_dwTotalFileSize; // 文件总大小
UINT m_uMsgHandle; // 消息句柄,由外界定义
BOOL m_bFtpDirect; // 传输方向,TRUE为下载,FALSE为上传,默认为TRUE
public:
DWORD m_dwFtpHead; // FTP传输头--自从InternetConnect之后发送的次数
private:
BOOL m_bTransfering; // 是否正在传输
};
//////////////////////////////////////////////////////////////////////////
// 模块名称:文件传输状态控制
// 模块功能:实现对界面时时报告当前文件传输的进度状态,并且实现上传和下载
// 文件的客户端功能。
// 文件名称:ftpclientctrl.cpp
//________________________________________________________________________
#include "FtpClientCtrl.h"
#pragma comment(lib, "wininet.lib")
#define INTERNET_STATUS_USER_INPUT_REQUIRED 0x00000040
#define INTERNET_STATUS_DETECTING_PROXY 80
#define FTP_FILE_ASCII_COUNT 12
LPCTSTR g_lpszAsciiFileFtp[FTP_FILE_ASCII_COUNT] =
{
_T(".txt"),
_T(".ini"),
_T(".c"),
_T(".cpp"),
_T(".h"),
_T(".hpp"),
_T(".bat"),
_T(".html"),
_T(".java"),
_T(".htm"),
_T(".jav"),
_T(".doc")
};
//////////////////////////////////////////////////////////////////////////
// 名称:IsFtpAscii
// 描述:经验判断一个要进行文件传输的文件是否是ASCII方式的
// 原型:BOOL IsFtpAscii(LPCTSTR lpszExt) // 文件后缀
// 参数:
// [in] lpszExt:要判断的文件的后缀名称
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
BOOL IsFtpAscii(LPCTSTR lpszExt)
{
if(lpszExt == NULL)
return FALSE;
for(int nIndex = 0; nIndex < FTP_FILE_ASCII_COUNT; nIndex ++)
{
if(_tcsicmp(lpszExt, g_lpszAsciiFileFtp[nIndex]) == 0)
return TRUE;
}
return FALSE;
}// End IsFtpAscii
// IsFtpAscii结束
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 名称:FormatFtpError
// 描述:获取系统的错误描述
// 原型:void FormatFtpError(DWORD dwError, // 错误码
// LPTSTR *lpMsg) // 描述信息
// 参数:
// [in] dwError:要查询的系统错误码
// [out] *lpMsg:获取得到的错误描述信息,在使用结束后,请调用LocalFree
// 来释放该空间
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
static void FormatFtpError( DWORD dwError, // 系统错误码
LPTSTR *lpMsg) // 错误描述
{
if(lpMsg == NULL)return;
if(dwError > INTERNET_ERROR_BASE)
{
// 对于Internet的错误,要特殊处理
DWORD dwBufLen = 0;
InternetGetLastResponseInfo(&dwError, NULL, &dwBufLen);
LPTSTR pMsg = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, dwBufLen + 1);
InternetGetLastResponseInfo(&dwError, pMsg, &dwBufLen);
*lpMsg = pMsg;
}
else
{
// 查询普通的错误
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)lpMsg,
0,
NULL);
}
}// End FormatFtpError
// FormatFtpError结束
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 名称:FtpCtrl_CallbackStatus
// 描述:文件传输过程中的状态回调函数,用于报告当前文件传输的进度等消息
// 原型:void CALLBACK FtpCtrl_CallbackStatus( HINTERNET hInternet,// 句柄
// DWORD dwContext, // 上下文
// DWORD dwInternetStatus, // 状态
// LPVOID lpvStatusInformation,// 信息
// DWORD dwStatusInformationLength)
// 参数:
// [in] hInternet:Internet连接的句柄,从InternetOpen中得到
// [in] dwContext:自定义的上下文数据
// [in] dwInternetStatus:当前回调的状态
// [in] lpvStatusInformation:当前回调的信息,根据dwInternetStatus的不同
// 状态代表不同的意思
// [in] dwStatusInformationLength:回调信息lpvStatusInformation的长度
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
void CALLBACK FtpCtrl_CallbackStatus( HINTERNET hInternet,
DWORD dwContext,
DWORD dwInternetStatus,
LPVOID lpvStatusInformation,
DWORD dwStatusInformationLength)
{
// 获取上下文信息
CFtpClientCtrl *pcFtpMsg = reinterpret_cast<CFtpClientCtrl*>(dwContext);
if(pcFtpMsg == NULL)
{
return;
}
LPDWORD pdwInformation(NULL);
TRACE("FtpCtrl_CallbackStatus's Internet Status is %d/n", dwInternetStatus);
// 查询当前文件传输状态
switch(dwInternetStatus)
{
case INTERNET_STATUS_RESOLVING_NAME: // 10
TRACE("Looking up the IP address for %s/n", (LPCTSTR)lpvStatusInformation);
break;
case INTERNET_STATUS_NAME_RESOLVED: // 11
TRACE("Name resolved %s/n", (LPCTSTR)lpvStatusInformation);
break;
case INTERNET_STATUS_CONNECTING_TO_SERVER: // 20
// lpvStatusInformation是一个SOCKADDR的指针
TRACE("Connecting to server--%s.../n", (LPCTSTR)lpvStatusInformation);
break;
case INTERNET_STATUS_CONNECTED_TO_SERVER: // 21
// lpvStatusInformation是一个SOCKADDR的指针
TRACE("Connected to server--%s/n", (LPCTSTR)lpvStatusInformation);
break;
case INTERNET_STATUS_SENDING_REQUEST: // 30
TRACE("Sending request/n");
break;
case INTERNET_STATUS_REQUEST_SENT: // 31
{
// 发送数据到服务器
if(!pcFtpMsg->GetFtpDirect())
{
// 只有当处于上传状态的时候,才处理
if(pcFtpMsg->m_dwFtpHead > 0 && pcFtpMsg->m_dwFtpHead < 5)
{
// 5这个值是一个经验值,具体为什么,由于没有深入研究rfc的协议
// 所以还不知道,将来如果知道原因,可以补充上
pcFtpMsg->m_dwFtpHead ++;
}
pdwInformation = (LPDWORD)lpvStatusInformation;
if(pcFtpMsg->m_dwFtpHead == 5)
{
DWORD dwCurrentSize = pcFtpMsg->IncreaseFtpSize(*pdwInformation);
TRACE("本次发送的数据大小为: %d,总共数据为:%d/n", *pdwInformation,
dwCurrentSize);
if(pcFtpMsg->GetCurrentFtpWnd() != NULL)
{
// 首先的第一选择是给窗口发送消息
::PostMessage( pcFtpMsg->GetCurrentFtpWnd(),
pcFtpMsg->GetRegisterMsgHandle(),
CFtpClientCtrl::ftp_transfer,
dwCurrentSize);
}
else if(pcFtpMsg->GetCurrentFtpThread() != 0)
{
::PostThreadMessage(pcFtpMsg->GetCurrentFtpThread(),
pcFtpMsg->GetRegisterMsgHandle(),
CFtpClientCtrl::ftp_transfer,
dwCurrentSize);
}
}// End if 5,经验值
}// end if 文件上传
}
break;
case INTERNET_STATUS_RESPONSE_RECEIVED: // 41
{
// 从服务器接收到的响应
if(pcFtpMsg->GetFtpDirect())
{
// 只有当处于下载状态的时候,才处理
pdwInformation = (LPDWORD)lpvStatusInformation;
if(pcFtpMsg->m_dwFtpHead > 0 && pcFtpMsg->m_dwFtpHead < 6)
{
// 6这个值是一个经验值,具体为什么,由于没有深入研究rfc的协议
// 所以还不知道,将来如果知道原因,可以补充上
pcFtpMsg->m_dwFtpHead ++;
// TRACE("在连接之后第%d次接收数据!/n", pcFtpMsg->m_dwFtpHead);
}
if(pcFtpMsg->m_dwFtpHead == 6)
{
DWORD dwCurrentSize = pcFtpMsg->IncreaseFtpSize(*pdwInformation);
TRACE("Response received: %d, TotalReceived is %d/n",
*pdwInformation, dwCurrentSize);
if(pcFtpMsg->GetCurrentFtpWnd() != NULL)
{
::PostMessage( pcFtpMsg->GetCurrentFtpWnd(),
pcFtpMsg->GetRegisterMsgHandle(),
CFtpClientCtrl::ftp_transfer,
dwCurrentSize);
}
else if(pcFtpMsg->GetCurrentFtpThread() != 0)
{
::PostThreadMessage(pcFtpMsg->GetCurrentFtpThread(),
pcFtpMsg->GetRegisterMsgHandle(),
CFtpClientCtrl::ftp_transfer,
dwCurrentSize);
}
}// End if 6,经验值
}// End if 文件下载
}
break;
case INTERNET_STATUS_RECEIVING_RESPONSE: // 40
// 等待服务器的响应,lpvStatusInformation = NULL
TRACE("等待服务器的响应!/n");
break;
case INTERNET_STATUS_CTL_RESPONSE_RECEIVED: // 42
case INTERNET_STATUS_PREFETCH: // 43
case INTERNET_STATUS_CLOSING_CONNECTION: // 50
TRACE("Closing connection/n");
break;
case INTERNET_STATUS_CONNECTION_CLOSED: // 51
TRACE("Connection closed/n");
break;
case INTERNET_STATUS_HANDLE_CREATED: // 60
{
LPINTERNET_ASYNC_RESULT ptIAR =
reinterpret_cast<LPINTERNET_ASYNC_RESULT>(lpvStatusInformation);
if(hInternet == pcFtpMsg->GetCurrentConnect())
{
TRACE("Connect Handle Created!/n");
pcFtpMsg->m_dwFtpHead = 1;
}
else if(hInternet == pcFtpMsg->GetCurrentSession())
{
TRACE("Session handle created!/n");
}
}
break;
case INTERNET_STATUS_HANDLE_CLOSING: // 70
pcFtpMsg->m_dwFtpHead = 0;
TRACE("Handle closed with dif %d!/n",
pcFtpMsg->GetCurrentFtpSize() - pcFtpMsg->GetTotalFileSize());
break;
case INTERNET_STATUS_DETECTING_PROXY: // 80
TRACE("Detecting proxy/n");
break;
case INTERNET_STATUS_REQUEST_COMPLETE: // 100
// 一个异步操作已经完成,lpvStatusInformation是INTERNET_ASYNC_RESULT的指针
{
LPINTERNET_ASYNC_RESULT ptIAR =
reinterpret_cast<LPINTERNET_ASYNC_RESULT>(lpvStatusInformation);
TRACE("一个异步操作完成,错误为:%d,结果为:%d/n",
ptIAR->dwError, ptIAR->dwResult);
}
break;
case INTERNET_STATUS_REDIRECT: // 110
TRACE("HTTP request redirected to /n");
break;
case INTERNET_STATUS_INTERMEDIATE_RESPONSE: // 120
TRACE("Received intermediate status message from the server./n");
break;
case INTERNET_STATUS_STATE_CHANGE: // 200
TRACE("'Moved between a secure and a nonsecure site/n");
{
LPDWORD pdwRead = (LPDWORD)lpvStatusInformation;
switch(*pdwRead)
{
case INTERNET_STATE_CONNECTED: // 0x00000001
TRACE("Connected state moved between secure and nonsecure site/n");
break;
case INTERNET_STATE_DISCONNECTED: // 0x00000002
TRACE("Disconnected from network/n");
break;
case INTERNET_STATE_DISCONNECTED_BY_USER: // 0x00000010
TRACE("Disconnected by user request/n");
break;
case INTERNET_STATE_IDLE: // 0x00000100
TRACE("No network requests are being made (by Wininet)./n");
break;
case INTERNET_STATE_BUSY: // 0x00000200
TRACE("Network requests are being made (by Wininet)./n");
break;
case INTERNET_STATUS_USER_INPUT_REQUIRED: // 0x00000040
TRACE("The request requires user input to complete/n");
break;
default:
break;
}
}
break;
default:
break;
}
}// End Ftp_CallbackStatus
// Ftp_CallbackStatu结束
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 名称:FtpClientDnloadThread
// 描述:文件传输——下载客户端线程
// 原型:DWORD WINPAI FtpClientDnloadThread(LPVOID pParam) // 入口参数
// 参数:
// [in] pParam:下载文件的入口参数
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
DWORD WINAPI FtpClientDnloadThread(LPVOID pParam) // 入口参数
{
CFtpClientCtrl *pcFtpMsg = reinterpret_cast<CFtpClientCtrl*>(pParam);
if(pcFtpMsg == NULL)
{
return -1;
}
// 获取文件
BOOL bRet = FtpGetFile( pcFtpMsg->GetCurrentConnect(),
pcFtpMsg->GetCurrentRemoteFile(),
pcFtpMsg->GetCurrentLocalFile(),
FALSE,
FILE_ATTRIBUTE_NORMAL,
pcFtpMsg->GetCurrentFileType() |
INTERNET_FLAG_RELOAD |
INTERNET_FLAG_RESYNCHRONIZE,
(DWORD)pcFtpMsg);
LPTSTR lpMsg = NULL;
DWORD dwErr = GetLastError();
FormatFtpError(dwErr, &lpMsg);
TRACE("FtpGetFile Error with %d--%s/n", dwErr, lpMsg);
LocalFree(lpMsg);
lpMsg = NULL;
if(pcFtpMsg->GetCurrentFtpWnd() != NULL)
{
::PostMessage( pcFtpMsg->GetCurrentFtpWnd(),
pcFtpMsg->GetRegisterMsgHandle(),
CFtpClientCtrl::ftp_end,
dwErr);
}
else if(pcFtpMsg->GetCurrentFtpThread() != 0)
{
::PostThreadMessage(pcFtpMsg->GetCurrentFtpThread(),
pcFtpMsg->GetRegisterMsgHandle(),
CFtpClientCtrl::ftp_end,
dwErr);
}
pcFtpMsg->ClearFtpSession();
TRACE("FtpGetFile Thread with id 0x%x end!/n", GetCurrentThreadId());
if(!bRet)
return -1;
return 0;
}// End FtpClientDnloadThread
// FtpClientDnloadThread结束
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 名称:FtpClientUploadThread
// 描述:文件传输——上传文件线程
// 原型:DWORD WINAPI FtpClientUploadThread(LPVOID pParam) // 入口参数
// 参数:
// [in] pParam:上传文件需要的参数
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
DWORD WINAPI FtpClientUploadThread(LPVOID pParam)
{
CFtpClientCtrl *pcFtpMsg = reinterpret_cast<CFtpClientCtrl*>(pParam);
if(pcFtpMsg == NULL)
{
return -1;
}
// 上传文件
BOOL bRet = FtpPutFile( pcFtpMsg->GetCurrentConnect(),
pcFtpMsg->GetCurrentLocalFile(),
pcFtpMsg->GetCurrentRemoteFile(),
pcFtpMsg->GetCurrentFileType() |
INTERNET_FLAG_RESYNCHRONIZE,
(DWORD)pcFtpMsg);
LPTSTR lpMsg = NULL;
DWORD dwErr = GetLastError();
FormatFtpError(dwErr, &lpMsg);
TRACE("FtpPutFile Error with %d--%s/n", dwErr, lpMsg);
LocalFree(lpMsg);
lpMsg = NULL;
if(pcFtpMsg->GetCurrentFtpWnd() != NULL)
{
::PostMessage( pcFtpMsg->GetCurrentFtpWnd(),
pcFtpMsg->GetRegisterMsgHandle(),
CFtpClientCtrl::ftp_end,
dwErr);
}
else if(pcFtpMsg->GetCurrentFtpThread() != 0)
{
::PostThreadMessage(pcFtpMsg->GetCurrentFtpThread(),
pcFtpMsg->GetRegisterMsgHandle(),
CFtpClientCtrl::ftp_end,
dwErr);
}
pcFtpMsg->ClearFtpSession();
TRACE("FtpPutFile Thread with id 0x%x end!/n", GetCurrentThreadId());
if(!bRet)
{
return -1;
}
return 0;
}// End FtpClientUploadThread
// FtpClientUploadThread结束
//////////////////////////////////////////////////////////////////////////
CFtpClientCtrl::CFtpClientCtrl()
:m_wFtpSrvPort(INTERNET_DEFAULT_FTP_PORT)
,m_hSession(NULL)
,m_hConnect(NULL)
,m_hFtpThread(NULL)
,m_dwFtpThread(0)
,m_dwCurrentFtpSize(0)
,m_hWnd(NULL)
,m_dwFileType(FTP_TRANSFER_TYPE_UNKNOWN)
,m_uMsgHandle(0)
,m_bFtpDirect(TRUE)
,m_dwFtpHead(0)
,m_bTransfering(FALSE)
{
::ZeroMemory(m_szFtpSrvIp, 24);
::ZeroMemory(m_szFtpSrvPwd, 32);
::ZeroMemory(m_szFtpSrvUser, 32);
::ZeroMemory(m_szProxyName, 64);
::ZeroMemory(m_szProxyPwd, 32);
::ZeroMemory(m_szRemote, MAX_PATH);
::ZeroMemory(m_szLocal, MAX_PATH);
}
CFtpClientCtrl::~CFtpClientCtrl()
{
InternetCloseHandle(m_hConnect);
InternetCloseHandle(m_hSession);
}
//////////////////////////////////////////////////////////////////////////
// 名称:SetServerParam
// 描述:设置文件传输的FTP服务器参数,包括服务器的地址、端口、用户和,口令等
// 原型:BOOL SetServerParam(LPCTSTR lpszIpAddr, // 服务器地址
// LPCTSTR lpszUser, // 用户
// LPCTSTR lpszPwd, // 口令
// WORD wPort, // 端口
// LPCTSTR lpszProxyName, // 代理名称
// LPCTSTR lpszProxyPwd) // 代理口令
// 参数:
// [in] lpszIpAddr:FTP服务器的地址
// [in] lpszUser:FTP服务器的用户名称
// [in] lpszPwd:FTP服务器的用户口令
// [in] wPort:FTP服务器的侦听端口
// [in] lpszProxyName:FTP服务器的代理用户
// [in] lpszProxyPwd:FTP服务器的代理对应口令
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
BOOL CFtpClientCtrl::SetServerParam(LPCTSTR lpszIpAddr,
LPCTSTR lpszUser,
LPCTSTR lpszPwd,
WORD wPort,
LPCTSTR lpszProxyName,
LPCTSTR lpszProxyPwd)
{
if( lpszIpAddr == NULL ||
lpszUser == NULL ||
lpszPwd == NULL ||
wPort == 0)
return FALSE;
::ZeroMemory(m_szFtpSrvIp, 24);
_sntprintf(m_szFtpSrvIp, 24, _T("%s"), lpszIpAddr);
::ZeroMemory(m_szFtpSrvUser, 32);
_sntprintf(m_szFtpSrvUser, 32, _T("%s"), lpszUser);
::ZeroMemory(m_szFtpSrvPwd, 32);
_sntprintf(m_szFtpSrvPwd, 32, _T("%s"), lpszPwd);
m_wFtpSrvPort = wPort;
::ZeroMemory(m_szProxyName, 64);
_sntprintf(m_szProxyName, 64, _T("%s"), lpszProxyName);
::ZeroMemory(m_szProxyPwd, 32);
_sntprintf(m_szProxyPwd, 32, _T("%s"), lpszProxyPwd);
return TRUE;
}// End SetServerParam
// SetServerParam结束
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 名称:DownloadFile
// 描述:下载文件
// 原型:BOOL DownloadFile( LPCTSTR lpszRemote, // 远程文件
// LPCTSTR lpszLocal, // 本地文件
// DWORD dwFileType) // 文件类型
// 参数:
// [in] lpszRemote:要下载的文件名称
// [in] lpszLocal:文件下载后保存到本地的路径
// [in] dwFileType:文件传输的方式
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
BOOL CFtpClientCtrl::DownloadFile(LPCTSTR lpszRemote,
LPCTSTR lpszLocal,
DWORD dwFileType)
{
::ZeroMemory(m_szRemote, MAX_PATH);
_sntprintf(m_szRemote, MAX_PATH, _T("%s"), lpszRemote);
::ZeroMemory(m_szLocal, MAX_PATH);
_sntprintf(m_szLocal, MAX_PATH, _T("%s"), lpszLocal);
m_dwFileType = dwFileType;
m_dwFtpHead = 0;
m_bFtpDirect = TRUE;
// 设置文件传输方式
if(dwFileType == FTP_TRANSFER_TYPE_UNKNOWN)
{
LPCTSTR lpszExt = _tcsrchr(lpszRemote, '.');
if(IsFtpAscii(lpszExt))
m_dwFileType = FTP_TRANSFER_TYPE_ASCII;
else
m_dwFileType = FTP_TRANSFER_TYPE_BINARY;
}
// 获取远程文件的大小,有的时候不能成功
m_dwTotalFileSize = GetRemoteFileSize();
TRACE("Remote File size is %d/n", m_dwTotalFileSize);
m_dwCurrentFtpSize = 0;
LPTSTR lpMsg = NULL; // 错误信息
// 打开Internet连接
m_hSession = InternetOpen( _T("Ftp_Ctrl"),
INTERNET_OPEN_TYPE_DIRECT,
m_szProxyName,
m_szProxyPwd,
INTERNET_FLAG_NO_CACHE_WRITE);
if(m_hSession == NULL)
{
FormatFtpError(GetLastError(), &lpMsg);
TRACE("InternetOpen Error with %s/n", lpMsg);
LocalFree(lpMsg);
lpMsg = NULL;
return FALSE;
}
// 设置状态回调函数
if(InternetSetStatusCallback(m_hSession, FtpCtrl_CallbackStatus) ==
INTERNET_INVALID_STATUS_CALLBACK)
{
FormatFtpError(GetLastError(), &lpMsg);
TRACE("InternetSetStatusCallback Error with %s/n", lpMsg);
LocalFree(lpMsg);
lpMsg = NULL;
InternetCloseHandle(m_hSession);
return FALSE;
}
// 连接到对方
m_hConnect = InternetConnect( m_hSession,
m_szFtpSrvIp,
m_wFtpSrvPort,
m_szFtpSrvUser,
m_szFtpSrvPwd,
INTERNET_SERVICE_FTP,
INTERNET_FLAG_PASSIVE |
INTERNET_FLAG_EXISTING_CONNECT,
(DWORD)this);
if(m_hConnect == NULL)
{
FormatFtpError(GetLastError(), &lpMsg);
TRACE("InternetConnect Error with %s/n", lpMsg);
LocalFree(lpMsg);
lpMsg = NULL;
InternetCloseHandle(m_hSession);
return FALSE;
}
if(m_hWnd != NULL)
{
// 发送消息,开始下载了
::PostMessage( m_hWnd, m_uMsgHandle,
(WPARAM)ftp_begin, (LPARAM)m_dwTotalFileSize);
}
else if(m_dwThread != 0)
{
::PostThreadMessage(m_dwThread, m_uMsgHandle,
(WPARAM)ftp_begin, (LPARAM)m_dwTotalFileSize);
}
// 创建文件下载线程
m_hFtpThread = CreateThread(NULL,
0,
FtpClientDnloadThread,
this,
0,
&m_dwFtpThread);
if(m_hFtpThread == NULL)
{
FormatFtpError(GetLastError(), &lpMsg);
TRACE("CreateThread Error with %s/n", lpMsg);
LocalFree(lpMsg);
InternetCloseHandle(m_hConnect);
InternetCloseHandle(m_hSession);
return FALSE;
}
m_bTransfering = TRUE;
return TRUE;
}// End DownloadFile
// DownloadFile结束
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 名称:BeginDownload
// 描述:开始下载文件
// 原型:BOOL BeginDownload(HWND hWnd, // 接收消息的窗口
// LPCTSTR lpszRemote, // 远程文件
// LPCTSTR lpszLocal, // 本地文件
// DWORD dwFileType) // 文件类型
// 参数:
// [in] hWnd:用于接收文件传输状态报告的窗口句柄
// [in] lpszRemote:要下载的文件名称,保存在服务器上的
// [in] lpszLocal:文件下载后保存到本地的路径
// [in] dwFileType:文件传输的方式
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
BOOL CFtpClientCtrl::BeginDownload(HWND hWnd,
LPCTSTR lpszRemote,
LPCTSTR lpszLocal,
DWORD dwFileType)
{
if( lpszRemote == NULL ||
lpszLocal == NULL ||
(dwFileType != FTP_TRANSFER_TYPE_BINARY &&
dwFileType != FTP_TRANSFER_TYPE_ASCII &&
dwFileType != FTP_TRANSFER_TYPE_UNKNOWN) ||
hWnd == NULL)
return FALSE;
if(m_bTransfering)
return FALSE;
m_hWnd = hWnd;
return DownloadFile(lpszRemote,
lpszLocal,
dwFileType);
}// End BeginDownload
// BeginDownload结束
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 名称:BeginDownload
// 描述:开始下载文件
// 原型:BOOL BeginDownload(DWORD dwThread, // 接收消息的线程
// LPCTSTR lpszRemote, // 远程文件
// LPCTSTR lpszLocal, // 本地文件
// DWORD dwFileType) // 文件类型
// 参数:
// [in] dwThread:用于接收文件传输状态报告的线程句柄
// [in] lpszRemote:要下载的文件名称,保存在服务器上的
// [in] lpszLocal:文件下载后保存到本地的路径
// [in] dwFileType:文件传输的方式
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
BOOL CFtpClientCtrl::BeginDownload(DWORD dwThread,
LPCTSTR lpszRemote,
LPCTSTR lpszLocal,
DWORD dwFileType)
{
if( lpszRemote == NULL ||
lpszLocal == NULL ||
(dwFileType != FTP_TRANSFER_TYPE_BINARY &&
dwFileType != FTP_TRANSFER_TYPE_ASCII &&
dwFileType != FTP_TRANSFER_TYPE_UNKNOWN) ||
dwThread == 0)
return FALSE;
if(m_bTransfering)
return FALSE;
m_dwThread = dwThread;
return DownloadFile(lpszRemote,
lpszLocal,
dwFileType);
}// End BeginDownload
// BeginDownload结束
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 名称:UploadFile
// 描述:上传文件
// 原型:BOOL UploadFile( LPCTSTR lpszRemote, // 远程文件
// LPCTSTR lpszLocal, // 本地文件
// DWORD dwFileType) // 文件类型
// 参数:
// [in] lpszRemote:上传后保存的文件名称
// [in] lpszLocal:要上传的本地文件路径
// [in] dwFileType:文件传输的方式
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
BOOL CFtpClientCtrl::UploadFile(LPCTSTR lpszRemote,
LPCTSTR lpszLocal,
DWORD dwFileType)
{
m_dwFtpHead = 0;
m_bFtpDirect = FALSE;
::ZeroMemory(m_szRemote, MAX_PATH);
_sntprintf(m_szRemote, MAX_PATH, _T("%s"), lpszRemote);
::ZeroMemory(m_szLocal, MAX_PATH);
_sntprintf(m_szLocal, MAX_PATH, _T("%s"), lpszLocal);
m_dwFileType = dwFileType;
// 设置文件传输的方式
if(dwFileType == FTP_TRANSFER_TYPE_UNKNOWN)
{
LPCTSTR lpszExt = _tcsrchr(lpszLocal, '.');
if(IsFtpAscii(lpszExt))
m_dwFileType = FTP_TRANSFER_TYPE_ASCII;
else
m_dwFileType = FTP_TRANSFER_TYPE_BINARY;
}
// 计算本地文件的大小,只要该文件存在,就能够得到大小
m_dwTotalFileSize = GetLocalFileSize();
if(m_dwTotalFileSize == (DWORD)-1)
{
m_dwTotalFileSize = 0;
return FALSE;
}
TRACE("Local File size is %d/n", m_dwTotalFileSize);
m_dwCurrentFtpSize = 0;
LPTSTR lpMsg = NULL; // 消息描述
// 打开Internet连接会话
m_hSession = InternetOpen( _T("Ftp_Ctrl"),
INTERNET_OPEN_TYPE_DIRECT,
m_szProxyName,
m_szProxyPwd,
INTERNET_FLAG_NO_CACHE_WRITE);
if(m_hSession == NULL)
{
FormatFtpError(GetLastError(), &lpMsg);
TRACE("InternetOpen Error with %s/n", lpMsg);
LocalFree(lpMsg);
lpMsg = NULL;
return FALSE;
}
// 设置文件传输状态回调函数
if(InternetSetStatusCallback(m_hSession, FtpCtrl_CallbackStatus) ==
INTERNET_INVALID_STATUS_CALLBACK)
{
FormatFtpError(GetLastError(), &lpMsg);
TRACE("InternetSetStatusCallback Error with %s/n", lpMsg);
LocalFree(lpMsg);
lpMsg = NULL;
InternetCloseHandle(m_hSession);
return FALSE;
}
// 开始建立文件传输的连接
m_hConnect = InternetConnect( m_hSession,
m_szFtpSrvIp,
m_wFtpSrvPort,
m_szFtpSrvUser,
m_szFtpSrvPwd,
INTERNET_SERVICE_FTP,
INTERNET_FLAG_PASSIVE |
INTERNET_FLAG_EXISTING_CONNECT,
(DWORD)this);
if(m_hConnect == NULL)
{
FormatFtpError(GetLastError(), &lpMsg);
TRACE("InternetConnect Error with %s/n", lpMsg);
LocalFree(lpMsg);
lpMsg = NULL;
InternetCloseHandle(m_hSession);
return FALSE;
}
// 发送消息,通知界面开始传输了
if(m_hWnd != NULL)
{
::PostMessage( m_hWnd, m_uMsgHandle,
(WPARAM)ftp_begin, (LPARAM)m_dwTotalFileSize);
}
else if(m_dwThread != 0)
{
::PostThreadMessage(m_dwThread, m_uMsgHandle,
(WPARAM)ftp_begin, (LPARAM)m_dwTotalFileSize);
}
// 创建文件上传线程
m_hFtpThread = CreateThread(NULL,
0,
FtpClientUploadThread,
this,
0,
&m_dwFtpThread);
if(m_hFtpThread == NULL)
{
FormatFtpError(GetLastError(), &lpMsg);
TRACE("CreateThread Error with %s/n", lpMsg);
LocalFree(lpMsg);
InternetCloseHandle(m_hConnect);
InternetCloseHandle(m_hSession);
return FALSE;
}
m_bTransfering = TRUE;
return TRUE;
}// End UploadFile
// UploadFile结束
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 名称:BeginUpload
// 描述:开始文件上传
// 原型:BOOL BeginUpload(HWND hWnd, // 用于接收消息的窗口句柄
// LPCTSTR lpszRemote, // 上传后保存的文件名称
// LPCTSTR lpszLocal, // 要上传的文件
// DWORD dwFileType) // 文件传输类型
// 参数:
// [in] hWnd:接收文件上传状态报告的窗口句柄
// [in] lpszRemote:文件上传后在服务器端保存的文件名称
// [in] lpszLocal:要上传的本地文件路径
// [in] dwFileType:文件上传的类型
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
BOOL CFtpClientCtrl::BeginUpload(HWND hWnd,
LPCTSTR lpszRemote,
LPCTSTR lpszLocal,
DWORD dwFileType)
{
if( lpszRemote == NULL ||
lpszLocal == NULL ||
(dwFileType != FTP_TRANSFER_TYPE_BINARY &&
dwFileType != FTP_TRANSFER_TYPE_ASCII &&
dwFileType != FTP_TRANSFER_TYPE_UNKNOWN) ||
hWnd == NULL)
return FALSE;
if(m_bTransfering)
return FALSE;
m_hWnd = hWnd;
return UploadFile( lpszRemote,
lpszLocal,
dwFileType);
}// End BeginUpload
// BeginUpload结束
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 名称:BeginUpload
// 描述:开始文件上传
// 原型:BOOL BeginUpload(DWORD dwThread, // 用于接收消息的线程句柄
// LPCTSTR lpszRemote, // 上传后保存的文件名称
// LPCTSTR lpszLocal, // 要上传的文件
// DWORD dwFileType) // 文件传输类型
// 参数:
// [in] dwThread:接收文件上传状态报告的线程句柄
// [in] lpszRemote:文件上传后在服务器端保存的文件名称
// [in] lpszLocal:要上传的本地文件路径
// [in] dwFileType:文件上传的类型
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
BOOL CFtpClientCtrl::BeginUpload(DWORD dwThread,
LPCTSTR lpszRemote,
LPCTSTR lpszLocal,
DWORD dwFileType)
{
if( lpszRemote == NULL ||
lpszLocal == NULL ||
(dwFileType != FTP_TRANSFER_TYPE_BINARY &&
dwFileType != FTP_TRANSFER_TYPE_ASCII &&
dwFileType != FTP_TRANSFER_TYPE_UNKNOWN) ||
dwThread == 0)
return FALSE;
if(m_bTransfering)
return FALSE;
m_dwThread = dwThread;
return UploadFile( lpszRemote,
lpszLocal,
dwFileType);
}// End BeginUpload
// BeginUpload结束
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 名称:EndFtpFile
// 描述:结束文件传输进行的操作
// 原型:BOOL EndFtpFile()
// 参数:
//
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
BOOL CFtpClientCtrl::EndFtpFile()
{
if(m_hConnect)
{
InternetCloseHandle(m_hConnect);
m_hConnect = NULL;
}
return TRUE;
}// End EndFtpFile
// EndFtpFile结束
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 名称:ClearFtpSession
// 描述:清除文件传输会话资源
// 原型:void ClearFtpSession()
// 参数:
//
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
void CFtpClientCtrl::ClearFtpSession()
{
if(m_hConnect != NULL)
{
InternetCloseHandle(m_hConnect);
m_hConnect = NULL;
}
if(m_hSession != NULL)
{
InternetCloseHandle(m_hSession);
m_hSession = 0;
}
m_hWnd = NULL;
m_dwThread = 0;
m_bTransfering = FALSE;
}
//////////////////////////////////////////////////////////////////////////
// 名称:IncreaseFtpSize
// 描述:在文件传输过程中,设置实际已经传输的文件大小
// 原型:DWORD IncreaseFtpSize(DWORD dwStep) // 本地大小
// 参数:
// [in] dwStep:本次状态中传输的大小
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
DWORD CFtpClientCtrl::IncreaseFtpSize(DWORD dwStep)
{
if(m_dwCurrentFtpSize < m_dwTotalFileSize)
m_dwCurrentFtpSize += dwStep;
return m_dwCurrentFtpSize;
}// End IncreaseFtpSize
// IncreaseFtpSize结束
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 名称:GetRemoteFileSize
// 描述:获取远程文件的大小
// 原型:DWORD GetRemoteFileSize()
// 参数:
//
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
DWORD CFtpClientCtrl::GetRemoteFileSize()
{
if(m_szRemote == NULL)
{
return 0;
}
LPTSTR lpMsg = NULL;
// 开始连接网络
HINTERNET hInternet = InternetOpen( _T("Ftp_Ctrl"),
INTERNET_OPEN_TYPE_DIRECT,
m_szProxyName,
m_szProxyPwd,
INTERNET_FLAG_NO_CACHE_WRITE);//INTERNET_FLAG_ASYNC
if(hInternet == NULL)
{
FormatFtpError(GetLastError(), &lpMsg);
TRACE("InternetOpen Error With %d--%s/n", GetLastError(), lpMsg);
LocalFree(lpMsg);
return 0;
}
// 连接
HINTERNET hConnect = InternetConnect( hInternet,
m_szFtpSrvIp,
m_wFtpSrvPort,
m_szFtpSrvUser,
m_szFtpSrvPwd,
INTERNET_SERVICE_FTP,
INTERNET_FLAG_PASSIVE |
INTERNET_FLAG_EXISTING_CONNECT,
0);
if(hConnect == NULL)
{
FormatFtpError(GetLastError(), &lpMsg);
TRACE("InternetConnect Error With %d--%s/n", GetLastError(), lpMsg);
LocalFree(lpMsg);
InternetCloseHandle(hInternet);
return 0;
}
// 打开文件
HINTERNET hFile = FtpOpenFile( hConnect,
m_szRemote,
GENERIC_READ,
m_dwFileType |
INTERNET_FLAG_RELOAD |
INTERNET_FLAG_RESYNCHRONIZE,
0);
if(hFile == NULL)
{
FormatFtpError(GetLastError(), &lpMsg);
TRACE("FtpOpen Error With %d--%s/n", GetLastError(), lpMsg);
LocalFree(lpMsg);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return 0;
}
typedef DWORD (WINAPI *FtpGetFileSize_Proc)(HINTERNET, LPDWORD);
HINSTANCE hInst = LoadLibrary("wininet.dll");
if(hInst == NULL)
{
TRACE("Load Library failed!/n");
InternetCloseHandle(hFile);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return 0;
}
FtpGetFileSize_Proc pfnFtpGetFileSize =
(FtpGetFileSize_Proc)GetProcAddress(hInst, "FtpGetFileSize");
if(pfnFtpGetFileSize == NULL)
{
TRACE("Get Proc FtpGetFileSize Failed!/n");
InternetCloseHandle(hFile);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
FreeLibrary(hInst);
return 0;
}
DWORD dwSize = pfnFtpGetFileSize(hFile, NULL);
FreeLibrary(hInst);
InternetCloseHandle(hFile);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return dwSize;
}// End GetRemoteFileSize
// GetRemoteFileSize结束
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 名称:GetLocalFileSize
// 描述:获取本地文件的大小
// 原型:DWORD GetLocalFileSize()
// 参数:
//
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
DWORD CFtpClientCtrl::GetLocalFileSize()
{
HANDLE hFile = CreateFile( m_szLocal,
0,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
return -1;
}
DWORD dwSize = GetFileSize(hFile, NULL);
CloseHandle(hFile);
return dwSize;
}// End GetLocalFileSize
// GetLocalFileSize结束
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 名称:IsFileAscii
// 描述:判断文件的传输方式是否为ASCII
// 原型:BOOL IsFileAscii(LPCTSTR lpszFile) // 文件名称
// 参数:
// [in] lpszFile:要判断的文件名称
// 备注:
//
// 修改记录
// 日期 版本 修改人 修改内容
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 wjr 创建
//________________________________________________________________________
BOOL CFtpClientCtrl::IsFileAscii(LPCTSTR lpszFile) // 文件名称
{
if(lpszFile == NULL)
return FALSE;
LPCTSTR lpszExt = _tcsrchr(lpszFile, '.'); // 得到文件后缀
return IsFtpAscii(lpszExt);
}// End IsFileAscii
// IsFileAscii结束
//////////////////////////////////////////////////////////////////////////
使用方法:
// 注册文件传输控件必要的参数
m_cFtpCtrl.SetServerParam( szNmsIp), // 网管服务器地址
szFtpUser, // ftp服务器用户
szFtpPwd); // ftp服务器口令
m_cFtpCtrl.RegisterMsgHandle(WM_ FTP_PROGRESS);
// 设置文件传输控件的传输方向
m_cFtpCtrl.SetFtpDirect(FALSE);
if(!m_cFtpCtrl.BeginUpload( GetSafeHwnd(),
m_strRemote,
m_strLocalFile))
{
AfxMessageBox(_T("文件开始上传失败!"));
PostMessage(WM_CLOSE);
return TRUE;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/z1011/mfc.git
[email protected]:z1011/mfc.git
z1011
mfc
mfc
master

搜索帮助