Wininet provides interface ftpgetfile implementation from the FTP server download file; provides interface ftpputfile implementations to upload files to the FTP server. With these two interfaces, we can complete the basic FTP file transfer client function. But while transferring, we want to know how much it is currently transmitted, how long it takes to transmit a complete file, the current progress is how long it can be transferred.
With this two interfaces, we cannot achieve this feature. Carefully read MSDN and found that Wininet also provided an interface: InternetSetStatusCallback. This function is the setup function to set the file transfer, the prototype is as follows:
Internet_Status_Callback InternetStatusCallback
Hinternet Hinternet,
Internet_Status_Callback LPFNInternetCallback
);
This interface sets a status callback function for the Internet session: LPFNInternetCallback, the prototype declaration of the callback function is as follows:
Void Callback InternetStatusCallback
Hinternet Hinternet,
DWORD_PTR DWCONTEXT,
DWORD DWINTERNETSTATUS,
LPVOID LPVSTATUSINFORMATION,
DWORD DWSTATUSINFORMATIONLENGTH
);
Through this callback function, we can implement the control of the current transmission schedule: You can count how many bytes currently transmitted, and calculate the transmission rate, so that it is possible to know how much remaining.
Below this is to implement a package for the FTP file transfer client:
//
// Module Name: File Transfer Status Control
// Module function: Implement the progress status of the current file transfer when the interface is realized, and implement the upload and download
// The client function of the file.
// File Name: ftpclientctrl.h
// ____________________________________________________________
#ifndef _wininet_
#include
#ENDIF
Class CFTPCLIENTCTRL
{
PUBLIC:
CFTPClientCtrl ();
Virtual ~ cftpclientctrl ();
ENUM
{
FTP_BEGIN, / / For this event, wparam = ftp_begin, LPARAM represents the size of the file to be transmitted
FTP_TRANSFER, // For this event, wparam = ftp_transfer, LPARAM indicates the size of the transferred
FTP_END / / For this event, wparam = ftp_end, lparam represents the result, 0 - failed, 1-- success
}
/ / Set the connection parameters of the FTP server
Bool setServerParam (LPCTSTR LPSZIPADDR, // IP address
LPCTSTR LPSZUSER, // Login Name
LPCTSTR LPSZPWD, // Login Password
Word wport = Internet_default_ftp_port, // FTP server port
LPCTSTR LPSZPROXYNAME = NULL, // Agent Name
LPCTSTR LPSZPROXYPWD = NULL); // Agent Password
/ / Start downloading files
Bool Begindownload (HWND HWND, // Received Window of Messages
LPCTSTR LPSZREMOTE, / / Remote File Name
LPCTSTR LPSZLOCAL, / / Save local files
DWORD DWFILETYPE = ftp_transfer_type_unknown); // File Transfer
Bool Begindownload (DWORD DWTHREAD, // Receive Message Thread
LPCTSTR LPSZREMOTE, / / Remote File Name
LPCTSTR LPSZLOCAL, / / Save local files
DWORD DWFILETYPE = ftp_transfer_type_unknown); // File Transfer
// Start uploading files
Bool Beginupload (HWND HWND, // Receive the window window
LPCTSTR LPSZREMOTE, / / Remote File Name
LPCTSTSTR LPSZLOCAL, // Local file name
DWORD DWFILETYPE = ftp_transfer_type_unknown); // File Transfer
Bool Beginupload (DWORD DWTHREAD, // Receive Message Thread
LPCTSTR LPSZREMOTE, / / Remote File Name
LPCTSTSTR LPSZLOCAL, // Local file name
DWORD DWFILETYPE = ftp_transfer_type_unknown); // File Transfer
// End the transfer file
BOOL endftpfile ();
// Get the current FTP session handle
Hinternet getcurrentsession () const {return m_hsession;}
// Get the current connection handle
Hinternet getcurrentconnect () const {return m_hconnect;}
// Get a remote file name
LPCTSTR getCurrentRemotefile () const {return m_szremote;}
/ / Get the name of the local file
LPCTSTR getcurrentlocalfile () const {return m_szlocal;
// Get the file type of currently transmitted
DWORD getCurrentFileType () const {return m_dwfiletype;
/ / Get the current transmission reception message window
HWnd getcurrentftpwnd () const {return m_hwnd;}
/ / Get the current transmission reception message thread
DWORD getCurrentFThread () const {return m_dwthread;}
/ / Get the size of the currently transmitted
DWORD getCurrentFTPSIZE () const {return m_dwcurrentftpsize;}
// Incremental size
DWORD INCRESEFTPSIZE (DWORD DWSTEP);
// Register a message
Void registermsghandle (uint umsghandle) {m_umsghandle = umsghandle;}
// Get registered messages
Uint getregistermsghandle () const {return m_umsghandle;} // Get the total length of the file
Dword gettotalfilesize () const {return m_dwtotalfilesize;}
/ / Clear FTP
Void clearftpsession ();
/ / Set the FTP transfer direction
Void setftpdirect (bool bdownload = true) {m_bftpdirect = bdownload;}
/ / Get the direction of FTP transmission
Bool getftpdirect () const {return m_bftpdirect;}
/ / Judgment if the file type is ASCII
Static Bool IsFileASCII (LPCTSTR LPSZFILE);
protected:
/ / Get the size of the remote file
DWORD getRemoteFileSize ();
/ / Get the size of the local file
DWORD getLocalFileSize ();
// download file
Bool Downloadfile (LPCTSTR LPSZREMOTE, // Remote File Name
LPCTSTR LPSZLOCAL, / / Save local files
DWORD DWFILETYPE = ftp_transfer_type_unknown); // File Transfer
// upload files
Bool UploadFile (LPCTSTR LPSZREMOTE, / / Remote File Name
LPCTSTR LPSZLOCAL, / / Save local files
DWORD DWFILETYPE = ftp_transfer_type_unknown); // File Transfer
protected:
Hinternet M_HSession; // Applied to Internetopen
Hinternet M_HConnect; // Applied to InternetConnect
TCHAR M_SZFTPSRVIP [24]; // FTP server IP address
TCHAR M_SZFTPSRVUSER [32]; // FTP server login user
TCHAR M_SZFTPSRVPWD [32]; / / FTP server login password
TCHAR M_SZPROXYNAME [64]; // The name of the agent
TCHAR M_SZPROXYPWD [32]; // The password of the agent
Word M_Wftpsrvport; // FTP server listening port
Handle M_Hftpthread; // FTP Transfer Thread Handle
DWORD M_DWFTPTHREAD; / / FTP Transfer Thread Number
TCHAR M_SZREMOTE [MAX_PATH]; // Remote File
TCHAR M_SZLOCAL [MAX_PATH]; // Local File
DWORD M_DWFILETYPE; // Transfer file type
HWND M_HWND; // Receive the window of the transfer schedule message
DWORD M_DWTHREAD; / / Receive threads of transmission progress messages
DWORD M_DWCURRENTFTPSIZE; // The current transmission of the current
DWORD M_DWTOTALFILESIZE; / / File Total size uint m_umsghandle; // message handle, defined by the outside world
Bool m_bftpdirect; // Transfer Direction, True is a download, false is uploaded, default is TRUE
PUBLIC:
DWORD M_DWFTPHEAD; // FTP Transmission Header - Since InternetConnect, the number of times
Private:
BOOL M_BTRANSFERING; / / Whether it is transferred
}
//
// Module Name: File Transfer Status Control
// Module function: Implement the progress status of the current file transfer when the interface is realized, and implement the upload and download
// The client function of the file.
// File Name: 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")
}
//
// Name: isftpascii
// Description: Experience determined whether a file to be filed is ASCII mode
// Prototype: BOOL ISFTPASCII (LPCTSTR LPSZEXT) // File suffix
// Parameter:
// [in] lpszext: The name of the file to be judged
// Remarks:
//
// Modify the record
// Date version modifier modification content
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
// 2003/09/08 V2.00 WJR creation
// ____________________________________________________________
Bool IsftPascii (LPCTSTR LPSZEXT)
{
IF (lpszext == NULL)
Return False;
For (int NINDEX = 0; NINDEX IF (_tcsicmp (lpszext, g_lpszasciififtp [nindex]) == 0) Return True; } Return False; } // end isftpascii // isftPascii ends // // // Name: FormatftPerror // Description: Get the error description of the system // prototype: void formatftperror (DWORD DWERROR, / / error code // LPTSTR * LPMSG) // Description Information // Parameter: // [in] dwerror: System error code to query // [out] * lpmsg: Get the resulting error description information, please call LocalFree after use // to release this space // Remarks: // // Modify the record // Date version modifier modification content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 WJR creation // ____________________________________________________________ Static void formatftperror (DWORD DWERROR, / / system error code LPTSTR * LPMSG) // Error Description { IF (lpmsg == null) return; IF (dwerror> internet_error_base) { / / For the incorrect of the Internet, special processing DWORD dwbufflen = 0; InternetGetlastResponseInfo (& DWERROR, NULL, & DWBUFLEN); LPTSTR PMSG = (LPTSTR) Localalloc (LMEM_ZEROINIT, DWBUFLEN 1); InternetGetlastResponseInfo (& DWERROR, PMSG, & DWBUFLEN); * lpmsg = PMSG; } Else { // Query ordinary errors 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 end // // // Name: ftpctrl_callbackstatus // Description: The status callback function during the file transfer process is used to report the progress of the current file transmission. // prototype: Void Callback ftpctrl_callbackstatus (Hinternet Hinternet, // handle // DWORD DWCONTEXT, / / Context // dword dwinternetStatus, // status // LPVOID LPVSTATUSINFORMATION, // Information // DWORD DWSTATUSINFORMATIONLENGTH) // Parameter: // [in] Hinternet: INTERNET connection handle, get it from Internetopen // [in] dwconText: Custom context data // [in] dwinternetStatus: The status of current callback // [in] LPVSTATUSINFORMATION: The current callback information, according to DWInternetStatus // Status represents different meaning // [in] DWSTATUSINFORMATIONLENGTH: The length of the callback information lpvStatusInformation // Remarks: // // Modify the record // Date version modifier modification content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 WJR creation // ____________________________________________________________ Void Callback ftpctrl_callbackstatus (Hinternet Hinternet, DWORD DWCONTEXT, DWORD DWINTERNETSTATUS, LPVOID LPVSTATUSINFORMATION, DWORD DWSTATUSINFORMATIONLENGTH) { // Get context information CFTPClientCtrl * pcftpmsg = reinterpret_cast IF (PCFTPMSG == NULL) { Return; } LPDWORD PDWINFORMATION (NULL); Trace ("ftpctrl_callbackstatus's Internet status is% d / n", dwinternetStatus); / / query the current file transfer status Switch (dwinternetStatus) { Case internet_status_resolving_name: // 10 Trace ("Looking Up 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 is a socketdr pointer Trace ("Connecting to Server -% s ... / n", (lpctstr) lpvstatusinformation; Break; Case internet_status_connected_to_server: // 21 // lpvstatusInformation is a socketdr pointer Trace ("Connected To Server -% S / N", (LPCTSTR) LPVSTATISITIONFORMATION; Break; Case Internet_Status_Sending_Request: // 30 Trace ("Sending Request / N"); Break; Case internet_status_request_sent: // 31 { // Send data to the server IF (! PCFTPMSG-> getftpdirect ()) { // Only when it is in the upload state, IF (pcftpmsg-> m_dwftphead> 0 && pcftpmsg-> m_dwftphead <5) { // 5 This value is an empirical value, why is it, because there is no in-depth study of RFC protocol // So I don't know, if I know the reason, I can add it. PCFTPMSG-> m_dwftphead ; } PDWINFORMATION = (LPDWORD) LPVSTATUSINFORMATION; IF (PCFTPMSG-> m_dwftphead == 5) { DWORD DWCURRENTSIZE = PCFTPMSG-> IncreaseftPsize (* pdwinformation); TRACE ("The size of the data sent is:% D, total data is:% D / N", * pdwinformation, dwcurrentsize; IF (pcftpmsg-> getcurrentftpwnd ()! = null) { // First, the first choice is to send a message to the window. :: 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, experience value } // end if file upload } Break; Case internet_status_response_received: // 41 { // Response received from the server IF (PCFTPMSG-> getftpdirect ()) { // Only when it is in a download state, PDWINFORMATION = (LPDWORD) LPVSTATUSINFORMATION; IF (pcftpmsg-> m_dwftphead> 0 && pcftpmsg-> m_dwftphead <6) { // 6 This value is an empirical value. Why is it specifically, because there is no deep research of RFC protocol // So I don't know, if I know the reason, I can add it. PCFTPMSG-> m_dwftphead ; // trace ("Receive Data after the connection after the connection! / 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, experience value } // End IF file download } Break; Case internet_status_receiving_response: // 40 // Waiting for the server response, lpvstatusinformation = null Trace ("Response! / N" of the waiter! / 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 PTIR = Reinterpret_cast 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 by! / N", Pcftpmsg-> getcurrentftpsize () - pcftpmsg-> gettotalFileSize ()); Break; Case internet_status_dtecting_proxy: // 80 Trace ("Detecting Proxy / N"); Break; Case internet_status_request_complete: // 100 // An asynchronous operation has been completed, LPVSTATUSINFORMATION is the pointer to Internet_async_Result { LPINTERNET_ASYNC_RESULT PTIR = Reinterpret_cast TRACE ("A asynchronous operation is completed, the error is:% D, the result is:% D / N", Ptiar-> dwerror, ptiar-> dwresult; } Break; Case Internet_Status_Redirect: // 110 "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 "'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 "" NO NetWork Requests Are Being Made (BY Wininet) ./ N "); Break; Case internet_state_busy: // 0x00000200 "" 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 end // // // Name: ftpclientDnloadThread // Description: File Transfer - Download Client Thread // Prototype: DWord Winpai ftpclientDnloadThread (LPVOID PPARAM) // Entrance parameters // Parameter: // [in] PPARAM: The entry parameters of download files // Remarks: // // Modify the record // Date version modifier modification content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 WJR creation // ____________________________________________________________ DWORD WINAPI FTPCLIENTDNLOADTHREAD (LPVOID PPARAM) // Entrance Parameters { CFTPClientCtrl * pcftpmsg = reinterpret_cast IF (PCFTPMSG == NULL) { Return -1; } // Get files Bool Bret = ftpGetfile (pcftpmsg-> getcurrentconnect (), pcftpmsg-> getcurrentremotefile (), Pcftpmsg-> getCurrentlocalFile (), False, FILE_ATTRIBUTE_NORMAL, PCFTPMSG-> getCurrentFileType () | Internet_flag_reeload | 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 ends // // // Name: ftpclientuploadthread // Description: File Transfer - Upload File Thread // Prototype: DWORD WINAPI FTPCLIENTUPLOADTHREAD (LPVOID PPARAM) // Entrance Parameters // Parameter: // [in] PPARAM: Parameters required for upload files // Remarks: // // Modify the record // Date version modifier modification content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 WJR creation // ____________________________________________________________ DWORD WINAPI FTPCLITUPLOADTHREAD (LPVOID PPARAM) { CFTPClientCtrl * pcftpmsg = reinterpret_cast IF (PCFTPMSG == NULL) { Return -1; } // upload files 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 ends // 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); } // // Name: setServerParam // Description: Set the FTP server parameters of the file transfer, including the address of the server, port, user, and password, etc. // prototype: BOOL setServerParam (LPCTSTR LPSZIPADDR, // server address // LPCTSTR LPSZUSER, // User // LPCTSTR LPSZPWD, // password // Word Wport, // Port // LPCTSTR LPSZPROXYNAME, / / Agent Name // lpctstr lpszproxypwd) // proxy password // Parameter: // [in] lpszipaddr: the address of the FTP server // [in] LPSZUSER: User name of the FTP server // [in] LPSZPWD: User password for FTP server // [in] WPORT: FTP server listening port // [in] LPSZPROXYNAME: Agent User of the FTP Server // [in] lpszproxypwd: Agent corresponding password for the FTP server // Remarks: // // Modify the record // Date version modifier modification content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 WJR creation // ____________________________________________________________ Bool CFTPClientCtrl :: setServerParam (LPCTSTSTR 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 end // // // Name: Downloadfile // Description: Download file // Prototype: BOOL Downloadfile (LPCTSTR LPSZREMOTE, // Remote File // LPCTSTR LPSZLOCAL, // Local file // dword dwfiletype) // file type // Parameter: // [in] lpszremote: The name of the file to download // [in] lpszlocal: Save to the local path after the file is downloaded // [in] DWFILETYPE: File transfer method // Remarks: // // Modify the record // Date version modifier modification content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 WJR creation // ____________________________________________________________ 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; // Set file transfer method 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;} / / Get the size of the remote file, sometimes it is not successful m_dwtotalfilesize = getRemoteFileSize (); Trace ("Remote File Size IS% D / N", M_DWTOTAlFileSize; m_dwcurrentftpsize = 0; LPTSTR LPMSG = NULL; / / Error message // Open Internet connection 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; } // Set the status callback function IF (InternetSetStatusCallback (m_hsession, ftpctrl_callbackstatus) == Internet_INValid_status_callback) { FormatftPerror (GetLastError (), & lpmsg); Trace ("InternetStatusCallback Error With% S / N", LPMSG); Localfree (lpmsg); LPMSG = NULL; InternetCloseHandle (M_HSession); Return False; } // Connect to each other 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) { // Send a message and start downloading :: 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; } // Create a file download thread 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 end // // // Name: Begindownloadload // Description: Start downloading files // prototype: BOOL Begindownload (HWND HWND, // Receive the window of the message // LPCTSTR LPSZREMOTE, // Remote File // LPCTSTR LPSZLOCAL, // Local file // dword dwfiletype) // file type // Parameter: // [in] hWnd: Window handle for receiving file transfer status report // [in] lpszremote: To download the file name, save it on the server // [in] lpszlocal: Save to the local path after the file is downloaded // [in] DWFILETYPE: File transfer method // Remarks: // // Modify the record // Date version modifier modification content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 WJR creation // ____________________________________________________________ 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 Begindownloadload // begindownload end // // // Name: Begindownloadload // Description: Start downloading files // Prototype: BOOL Begindownload (DWORD DWTHREAD, // Receive Message Thread // LPCTSTR LPSZREMOTE, // Remote File // LPCTSTR LPSZLOCAL, // Local file // dword dwfiletype) // file type // Parameter: // [in] DWTHREAD: Thread handle used to receive file transfer status report // [in] lpszremote: To download the file name, save it on the server // [in] lpszlocal: Save to the local path after the file is downloaded // [in] DWFILETYPE: File transfer method // Remarks: // // Modify the record // Date version modifier modification content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 WJR creation // ____________________________________________________________ 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 Begindownloadload // begindownload end // // // Name: UploadFile // Description: Upload file // prototype: BOOL UPLOADFILE (LPCTSTSTR LPSZREMOTE, // Remote File // LPCTSTR LPSZLOCAL, // Local file // DWORD DWFILETYPE) // File Type / / Parameter: // [in] lpszremote: file name saved after uploading // [in] LPSZLOCAL: The local file path to upload // [in] DWFILETYPE: File transfer method // Remarks: // // Modify the record // Date version modifier modification content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 WJR creation // ____________________________________________________________ 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; / / Set the way the file is transferred 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; } / / Calculate the size of the local file, as long as the file exists, you can get the size. 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; // Message Description / / Open Internet Connection Session 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; } / / Set file transfer status callback function IF (InternetSetStatusCallback (m_hsession, ftpctrl_callbackstatus) == Internet_INValid_status_callback) { FormatftPerror (GetLastError (), & lpmsg); Trace ("InternetStatusCallback Error With% S / N", LPMSG); Localfree (lpmsg); LPMSG = NULL; InternetCloseHandle (M_HSession); Return False; } // Start establishment of file transfer 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; } // Send a message, the notification interface starts to transmit 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; } // Create a file upload thread 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 ends // // // Name: Beginupload // Description: Start file upload // Prototype: BOOL Beginupload (HWND HWND, // Used window handle // lpctstr lpszremote, // Saved file name after upload // LPCTSTR LPSZLOCAL, // To upload the file // dword dwfiletype) // File transfer type // Parameter: // [in] hwnd: Receive the window handle of the file upload status report // [in] lpszremote: File name saved after the server is uploaded // [in] LPSZLOCAL: The local file path to upload // [in] dwfiletype: Type of file upload // Remarks: // // Modify the record // Date version modifier modification content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 WJR creation // ____________________________________________________________ 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 // // // Name: Beginupload // Description: Start file upload // Prototype: BOOL Beginupload (DWORD DWTHREAD, // Thread Handle for Receiving Messages // LPCTSTR LPSZREMOTE, // Upload file name // LPCTSTR LPSZLOCAL, // To upload the file // dword dwfiletype) // File transfer type // Parameter: // [in] dwthread: Receive file upload status report thread handle // [in] lpszremote: file name saved after the file is uploaded // [in] LPSZLOCAL: The local file path to upload // [in] dwfiletype: Type of file upload // Remarks: // // Modify the record // Date version modifier modification content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 WJR creation // ____________________________________________________________ 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 // // // Name: Endftpfile // Description: End file transfer operation // prototype: BOOL endftpfile () // Parameter: // // Remarks: // // Modify the record // Date version modifier modification content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 WJR creation // ____________________________________________________________ Bool cftpclientctrl :: endftpfile () { IF (m_hconnect) { InternetCloseHandle (M_HConnect); m_hconnect = NULL; } Return True; } // end endftpfile // endftpfile // // // Name: ClearftpSession // Description: Clear file transfer session resources // prototype: void clearftpsession () // Parameter: // // Remarks: // // Modify the record // Date version modifier modification content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 WJR creation // ____________________________________________________________ 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; } // // Name: IncreaseftPSIZE // Description: During the file transfer process, set the file size that is actually transmitted. // Prototype: DWORD IncreaseftPsize (DWORD DWSTEP) // Local Size // Parameter: // [in] DWSTEP: The size of the transmission in this state // Remarks: // // Modify the record // Date version modifier modification content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 WJR creation // ____________________________________________________________ DWORD CFTPCLIENTCTRL :: IncreaseftPsize (DWORD DWSTEP) { IF (m_dwcurrentftpsize m_dwcurrentftpsize = dwstep; Return m_dwcurrentftpsize; } // end increaseftpsize // IncreaseftPsize end // // // Name: getRemoteFileSize // Description: Get the size of the remote file // prototype: dword getremotefilesize () // Parameter: // // Remarks: // // Modify the record // Date version modifier modification content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~ 2003/09/08 V2.00 WJR creation // ____________________________________________________________ DWORD CFTPCLIENTCTRL :: getRemoteFileSize () { IF (m_szremote == null) { Return 0; } LPTSTR lpmsg = NULL; // Start connectivity network 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; } // connection 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; } // open a file Hinternet Hfile = ftpopenfile (hconnect, m_szremote, Generic_read, m_dwfiletype | Internet_flag_reeload | 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 (WinTroc) (Hinternet, LPDWORD); Hinstance hinst = loadingLibrary ("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 end // // // Name: getLocalFileSize // Description: Get the size of the local file // prototype: dWord getLocalFileSize () // Parameter: // // Remarks: // // Modify the record // Date version modifier modification content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 WJR creation // ____________________________________________________________ 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 end // // // Name: isfileaSCII // Description: Is it a way to transfer whether the file is ASCII // Prototype: BOOL IsFileASCII (LPCTSTR LPSZFILE) // File Name // Parameter: // [in] lpszfile: The name of the file to be judged // Remarks: // // Modify the record // Date modified version of human modify the content // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 WJR creation // ____________________________________________________________ Bool cftpclientctrl :: isfileASCII (LPCTSTR LPSZFILE) // file name { IF (LPSZFILE == NULL) Return False; LPCTSTR LPSZEXT = _TCSRCHR (lpszfile, '.'); // Get file suffixes Return isftPascii (LPSZEXT); } // end isfileascii // IsFileASCII end // Instructions: // Register file transfer control necessary parameters m_cftpctrl.setserverparam (sznmsip), // network management server address SZFTPUSER, / / FTP server user SZFTPPWD; // FTP server password m_cftpctrl.registermsghandle (WM_ ftp_progress); / / Set the transfer direction of the file transfer control m_cftpctrl.setftpdirect (false); IF (! m_cftpctrl.beginupload (getsafehwnd (), M_Strremote, m_strlocalfile))) { AfxMessageBox (_t ("file starts to upload failed!")) Postmessage (WM_CLOSE); Return True; }