wininet提供了接口FtpGetFile實作從ftp伺服器下載下傳檔案;提供了接口FtpPutFile實作把檔案上傳到ftp伺服器上。通過這兩個接口,我們能夠完成基本的ftp檔案傳輸用戶端功能。但是在傳輸的同時,我們希望知道目前大概傳輸了多少,傳輸完整個檔案大概需要多長時間,目前進度是多少,大概還有多長時間才能傳輸完畢。
單純依靠這兩個接口,我們無法實作這個功能。仔細翻閱msdn,發現wininet還提供了這樣一個接口:InternetSetStatusCallback。該函數就是設定檔案傳輸的回調函數,其原型如下:
INTERNET_STATUS_CALLBACK InternetSetStatusCallback(
HINTERNET hInternet ,
INTERNET_STATUS_CALLBACK lpfnInternetCallback
);
該接口為internet會話設定一個狀态回調函數:lpfnInternetCallback,該回調函數的原型聲明如下:
void CALLBACK InternetStatusCallback(
HINTERNET hInternet ,
DWORD_PTR dwContext ,
DWORD dwInternetStatus ,
LPVOID lpvStatusInformation ,
DWORD dwStatusInformationLength
);
通過這個回調函數,我們可以實作對目前傳輸進度的控制:可以統計出到目前已經傳輸了多少位元組,并且計算出傳輸速率,進而可以得知大概還剩下多少時間。
下面這個類就是實作對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;
}