⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftptransfer.cpp

📁 Transfer Files to and from an FTP Server
💻 CPP
字号:
// FtpTransfer.cpp : implementation file
//

#include "stdafx.h"
#include "FTP.h"
#include "FtpTransfer.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define FTP_DIR 1
#define LOCAL_DIR 2
#define BUFF_MAX 5000
extern char Clipboard[];
extern CString gCopiedFile;
extern DWORD gFileSize, BytesTransferred, OverallFileSize, TimeElapse, TimePending, TimeStart, AvgCounter;
DWORD WINAPI CopyTheFile(LPVOID lResult);
extern HANDLE hLocalSrcFile, hLocalDestFile;
extern CInternetFile *hInternetSrcFile, *hInternetDestFile;
HANDLE hThread;
DWORD SourceDir, DestDir, gSize;
extern HTREEITEM ghTitem;
extern CListCtrl *ListCtrl;
extern CTreeCtrl *TreeCtrl;
extern CFtpConnection* m_pFtpConnection;
extern bool EndTheTransfer, ThreadEnded;
extern CStatusBar m_wndStatusBar;
/////////////////////////////////////////////////////////////////////////////
// CFtpTransfer dialog


CFtpTransfer::CFtpTransfer(CWnd* pParent /*=NULL*/)
	: CDialog(CFtpTransfer::IDD, pParent)
{
	//{{AFX_DATA_INIT(CFtpTransfer)
	//}}AFX_DATA_INIT
}


void CFtpTransfer::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CFtpTransfer)
	DDX_Control(pDX, IDC_STOP, m_Stop);
	DDX_Control(pDX, IDC_STARTAGAIN, m_Start);
	DDX_Control(pDX, IDC_FILE, m_FileName);
	DDX_Control(pDX, IDC_SINGLE, m_Single);
	DDX_Control(pDX, IDC_OVERALL, m_Overall);
	DDX_Control(pDX, IDC_FTPLIST, m_FtpList);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CFtpTransfer, CDialog)
	//{{AFX_MSG_MAP(CFtpTransfer)
	ON_BN_CLICKED(IDC_HIDE, OnHide)
	ON_BN_CLICKED(IDC_ADDFILE, OnAddfile)
	ON_BN_CLICKED(IDC_COPYFILES, OnCopyfiles)
	ON_BN_CLICKED(IDC_STOP, OnStop)
	ON_BN_CLICKED(IDC_STARTAGAIN, OnStartagain)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFtpTransfer message handlers

BOOL CFtpTransfer::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	m_FtpList.InsertColumn(0, "File", LVCFMT_LEFT, 100);	
	m_FtpList.InsertColumn(1, "Source Folder", LVCFMT_LEFT, 200);
	m_FtpList.InsertColumn(2, "Target Folder", LVCFMT_LEFT, 200);
	m_FtpList.InsertColumn(3, "Size", LVCFMT_LEFT, 75);
	m_Start.EnableWindow(TRUE);
	m_Stop.EnableWindow(FALSE);
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CFtpTransfer::OnHide() 
{
	// TODO: Add your control notification handler code here
	ShowWindow(SW_HIDE);	
}

void CFtpTransfer::OnAddfile() 
{
	// TODO: Add your control notification handler code here
	int i=m_FtpList.GetItemCount();
	m_FtpList.InsertItem(i, gCopiedFile);
	m_FtpList.SetItemText(i, 1, Clipboard);
	CString TmpStr;
	TmpStr.Format("%lu", gFileSize);
//	OverallFileSize += gFileSize;
	m_FtpList.SetItemText(i, 3, TmpStr);
//	AfxMessageBox("DEMO");	
}

void CFtpTransfer::OnCopyfiles() 
{
	// TODO: Add your control notification handler code here
	HTREEITEM hTC = ghTitem;
	CString Dir, Tmp;
//	if(FTP2Local==0){
	m_Start.EnableWindow(FALSE);
	m_Stop.EnableWindow(TRUE);
	OverallFileSize=TimeElapse=TimePending=0;
	for(int i=0; i<m_FtpList.GetItemCount(); i++){
		hTC = ghTitem;
		if(TreeCtrl->GetItemData(hTC)==0){
			Dir = TreeCtrl->GetItemText(hTC);
			while (true)
			{
				hTC = TreeCtrl->GetParentItem(hTC);
				if(!hTC)
					break;

				if (hTC != TreeCtrl->GetRootItem())
					Dir = TreeCtrl->GetItemText(hTC)+"\\"+Dir;
			}
			m_FtpList.SetItemText(i, 2, (LPSTR)(LPCSTR)Dir);
		}
		else{
			Dir = TreeCtrl->GetItemText(hTC);
			while (true)
			{
				if(strcmp(Dir, "/")==0)
					Dir = "";
				hTC = TreeCtrl->GetParentItem(hTC);
				if(!hTC)
					break;
			
				if (hTC != TreeCtrl->GetRootItem()){
					Tmp = TreeCtrl->GetItemText(hTC);
					if(strcmp(Tmp, "/") == 0){
						Dir = Tmp+Dir;
						break;
					}
					Dir = Tmp+"/"+Dir;
				}
			}
			m_FtpList.SetItemText(i, 2, (LPSTR)(LPCSTR)Dir);
		}
		OverallFileSize+=atoi((LPSTR)(LPCSTR)m_FtpList.GetItemText(i, 3));
	}
	m_Overall.SetRange32(0, OverallFileSize);
	m_Overall.SetPos(0);
	while(m_FtpList.GetItemCount()){
//		if(m_FtpList.GetItemData(hTC)==0){
			Dir = m_FtpList.GetItemText(0, 1);
			if((LPSTR)(LPCSTR)Dir[0] == (LPSTR)'/')
				SourceDir = FTP_DIR;
			else
				SourceDir = LOCAL_DIR;
			if(SourceDir == FTP_DIR){
				Dir += "/" + m_FtpList.GetItemText(0, 0);
				try
				{
					hInternetSrcFile=m_pFtpConnection->OpenFile(Dir);
				}
				catch (CInternetException* pEx)
				{
					// catch errors from WinINet
					TCHAR szErr[1024];
					if (pEx->GetErrorMessage(szErr, 1024))
						AfxMessageBox(szErr, MB_OK);
					else
						AfxMessageBox("Unknown Error", MB_OK);
					pEx->Delete();
					goto EndCopy;
				}
				if(!hInternetSrcFile){
					AfxMessageBox("Unable to open internet file");
					goto EndCopy;
				}
			}
			else{
				Dir += "\\" + m_FtpList.GetItemText(0, 0);
				if((hLocalSrcFile=CreateFile(Dir, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
					FILE_ATTRIBUTE_NORMAL, NULL)) ==INVALID_HANDLE_VALUE){
					AfxMessageBox("Unable to open file for reading in local hard disk!");
					hLocalSrcFile = 0;
					goto EndCopy;
				}
			}
			m_FileName.SetWindowText((LPSTR)(LPCSTR)Dir);
			Dir = m_FtpList.GetItemText(0, 2);
			if((LPSTR)(LPCSTR)Dir[0] == (LPSTR)'/')
				DestDir = FTP_DIR;
			else
				DestDir = LOCAL_DIR;
			if(DestDir == LOCAL_DIR){
				Dir += "\\" + m_FtpList.GetItemText(0, 0);
				if((hLocalDestFile=CreateFile(Dir, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS,
					FILE_ATTRIBUTE_NORMAL, NULL)) ==INVALID_HANDLE_VALUE){
					AfxMessageBox("Unable to open file for writing in local hard disk!");
					hLocalDestFile = 0;
					goto EndCopy;
				}
			}
			else
			{
				Dir += "/" + m_FtpList.GetItemText(0, 0);
				try
				{
					hInternetDestFile=m_pFtpConnection->OpenFile(Dir);
				}
				catch (CInternetException* pEx)
				{
					// catch errors from WinINet
					TCHAR szErr[1024];
					if (pEx->GetErrorMessage(szErr, 1024))
						AfxMessageBox(szErr, MB_OK);
					else
						AfxMessageBox("Unknown Error", MB_OK);
					pEx->Delete();
					goto EndCopy;
				}
				if(!hInternetDestFile){
					AfxMessageBox("Unable to open internet file");
					goto EndCopy;
				}
			}
//			if(hInternetSrcFile){
				EndTheTransfer=false;
//				AfxBeginThread(CopyTheFile, this);
				gSize = atoi((LPSTR)(LPCSTR)m_FtpList.GetItemText(0, 3));
				m_Single.SetRange32(0, gSize);
				m_Single.SetPos(0);
				DWORD LocalFilePos=0;
				if(DestDir == LOCAL_DIR)
					LocalFilePos = SetFilePointer(hLocalDestFile, 0, 0, FILE_END);
				else{
					try
					{
						LocalFilePos = hInternetDestFile->Seek(0, CFile::end);
					}
					catch (CInternetException* pEx)
					{
						// catch errors from WinINet
						TCHAR szErr[1024];
						if (pEx->GetErrorMessage(szErr, 1024))
							AfxMessageBox(szErr, MB_OK);
						else
							AfxMessageBox("Unknown Error", MB_OK);
						pEx->Delete();
						LocalFilePos=0;
					}
				}
				if(LocalFilePos != 0){
					if(AfxMessageBox("File already exists!  Resume download?", MB_YESNO|MB_ICONQUESTION)==IDNO){
						if(DestDir==FTP_DIR){
							try
							{
								BytesTransferred = hInternetDestFile->Seek(0, CFile::begin);
							}
							catch (CInternetException* pEx)
							{
								// catch errors from WinINet
								TCHAR szErr[1024];
								if (pEx->GetErrorMessage(szErr, 1024))
									AfxMessageBox(szErr, MB_OK);
								else
									AfxMessageBox("Unknown Error", MB_OK);
								pEx->Delete();
								LocalFilePos=BytesTransferred=0;
							}

						}
						else{
							BytesTransferred = SetFilePointer(hLocalDestFile, 0, 0, FILE_BEGIN);
						}
						if(SourceDir==FTP_DIR){
							try
							{
								BytesTransferred = hInternetSrcFile->Seek(0, CFile::begin);
							}
							catch (CInternetException* pEx)
							{
								// catch errors from WinINet
								TCHAR szErr[1024];
								if (pEx->GetErrorMessage(szErr, 1024))
									AfxMessageBox(szErr, MB_OK);
								else
									AfxMessageBox("Unknown Error", MB_OK);
								pEx->Delete();
								LocalFilePos=BytesTransferred=0;
							}
						}
						else{
							BytesTransferred = SetFilePointer(hLocalSrcFile, 0, 0, FILE_BEGIN);
						}
					}
					else {
						if(DestDir==FTP_DIR){
							try
							{
								BytesTransferred = hInternetDestFile->Seek(LocalFilePos, CFile::begin);
							}
							catch (CInternetException* pEx)
							{
								// catch errors from WinINet
								TCHAR szErr[1024];
								if (pEx->GetErrorMessage(szErr, 1024))
									AfxMessageBox(szErr, MB_OK);
								else
									AfxMessageBox("Unknown Error", MB_OK);
								pEx->Delete();
								LocalFilePos=BytesTransferred=0;
							}
						}
						else{
							BytesTransferred = SetFilePointer(hLocalDestFile, LocalFilePos, 0, FILE_BEGIN);
						}
						if(SourceDir==FTP_DIR){
							try
							{
								BytesTransferred = hInternetSrcFile->Seek(LocalFilePos, CFile::begin);
							}
							catch (CInternetException* pEx)
							{
								// catch errors from WinINet
								TCHAR szErr[1024];
								if (pEx->GetErrorMessage(szErr, 1024))
									AfxMessageBox(szErr, MB_OK);
								else
									AfxMessageBox("Unknown Error", MB_OK);
								pEx->Delete();
								LocalFilePos=BytesTransferred=0;
							}
						}
						else{
							BytesTransferred = SetFilePointer(hLocalSrcFile, LocalFilePos, 0, FILE_BEGIN);
						}
					}
				}
				m_wndStatusBar.SetPaneText(3, "Bytes Copied", TRUE);
				m_wndStatusBar.SetPaneText(4, "Bytes/Sec", TRUE);
				m_wndStatusBar.SetPaneText(1, "Time Elapsed", TRUE);
				m_wndStatusBar.SetPaneText(2, "Time Remain", TRUE);
				TimeElapse=TimePending=TimeStart=AvgCounter=0;
				hThread = ::CreateThread(0, 0, (LPTHREAD_START_ROUTINE)CopyTheFile, this, 0, 0);
				MSG Msg;
				do{
					if(::PeekMessage(&Msg, NULL, WM_NULL, WM_USER-1, PM_NOREMOVE)){
						::PeekMessage(&Msg, NULL, WM_NULL, WM_USER-1, PM_REMOVE);
						TranslateMessage(&Msg);
						DispatchMessage(&Msg);
					}
				}while(WaitForSingleObject(hThread, 50)==WAIT_TIMEOUT);
				m_Overall.OffsetPos(BytesTransferred);
				if(!EndTheTransfer)
					m_FtpList.DeleteItem(0);
				else
					break;
				BytesTransferred = 0;
				if(SourceDir==LOCAL_DIR){
					CloseHandle(hLocalSrcFile);
					hLocalSrcFile=0;
				}
				else{
					try
					{
						hInternetSrcFile->Close();
					}
					catch (CInternetException* pEx)
					{
						// catch errors from WinINet
						TCHAR szErr[1024];
						if (pEx->GetErrorMessage(szErr, 1024))
							AfxMessageBox(szErr, MB_OK);
						else
							AfxMessageBox("Unknown Error", MB_OK);
						pEx->Delete();
						goto EndCopy;
					}
				}
				if(DestDir==LOCAL_DIR){
					CloseHandle(hLocalDestFile);
					hLocalDestFile=0;
				}
				else{
					try
					{
						hInternetDestFile->Close();
					}
					catch (CInternetException* pEx)
					{
						// catch errors from WinINet
						TCHAR szErr[1024];
						if (pEx->GetErrorMessage(szErr, 1024))
							AfxMessageBox(szErr, MB_OK);
						else
							AfxMessageBox("Unknown Error", MB_OK);
						pEx->Delete();
						goto EndCopy;
					}
				}
//			}
//		}
	}
//	else{
//	}
EndCopy:
	if(SourceDir==FTP_DIR){
		if(hInternetSrcFile){
			try
			{
				hInternetSrcFile->Close();
			}
			catch (CInternetException* pEx)
			{
				// catch errors from WinINet
				TCHAR szErr[1024];
				if (pEx->GetErrorMessage(szErr, 1024))
					AfxMessageBox(szErr, MB_OK);
				else
					AfxMessageBox("Unknown Error", MB_OK);
				pEx->Delete();
			}
		}
	}
	else{
		if(hLocalSrcFile)
			CloseHandle(hLocalSrcFile);
	}
	if(DestDir == FTP_DIR){
		if(hInternetDestFile){
			try
			{
				hInternetDestFile->Close();
			}
			catch (CInternetException* pEx)
			{
				// catch errors from WinINet
				TCHAR szErr[1024];
				if (pEx->GetErrorMessage(szErr, 1024))
					AfxMessageBox(szErr, MB_OK);
				else
					AfxMessageBox("Unknown Error", MB_OK);
				pEx->Delete();
			}
		}
	}
	else{
		if(hLocalDestFile)
			CloseHandle(hLocalDestFile);
	}
	m_wndStatusBar.SetPaneText(3, "Bytes Copied", TRUE);
	m_wndStatusBar.SetPaneText(4, "Bytes/Sec", TRUE);
	m_wndStatusBar.SetPaneText(1, "Time Elapsed", TRUE);
	m_wndStatusBar.SetPaneText(2, "Time Remain", TRUE);
	m_Overall.SetPos(0);
	m_Single.SetPos(0);
	m_FileName.SetWindowText(NULL);
	if(!m_FtpList.GetItemCount())
		ShowWindow(SW_HIDE);
	m_Start.EnableWindow(TRUE);
	m_Stop.EnableWindow(FALSE);
}

DWORD WINAPI CopyTheFile(LPVOID lResult)
{
	CFtpTransfer *FtpTrans = (CFtpTransfer *)lResult;
	ThreadEnded = false;
//	if(SourceDir==FTP_DIR){
	BYTE Buffer[BUFF_MAX];
//	char TmpStr[100];
	DWORD Tmp, Tmp1, Tmp2=0;
	while(!EndTheTransfer){
		Tmp1=BUFF_MAX;
		if(SourceDir==FTP_DIR){
			try
			{
				Tmp = hInternetSrcFile->Read(Buffer, BUFF_MAX);
			}
			catch (CInternetException* pEx)
			{
				// catch errors from WinINet
				TCHAR szErr[1024];
				if (pEx->GetErrorMessage(szErr, 1024))
					AfxMessageBox(szErr, MB_OK);
				else
					AfxMessageBox("Unknown Error", MB_OK);
				pEx->Delete();
			}
		}
		else
			ReadFile(hLocalSrcFile, Buffer, BUFF_MAX, &Tmp, NULL);
		if(DestDir==FTP_DIR){
			try
			{
				hInternetDestFile->Write(Buffer, Tmp);
			}
			catch (CInternetException* pEx)
			{
				// catch errors from WinINet
				TCHAR szErr[1024];
				if (pEx->GetErrorMessage(szErr, 1024))
					AfxMessageBox(szErr, MB_OK);
				else
					AfxMessageBox("Unknown Error", MB_OK);
				pEx->Delete();
			}
		}
		else
			WriteFile(hLocalDestFile, Buffer, Tmp, &Tmp1, NULL);
		BytesTransferred += Tmp1;
		if(++Tmp2 == 10){
			FtpTrans->m_Single.SetPos(BytesTransferred);
			Tmp2=0;
		}
		if(Tmp1 != BUFF_MAX)
			break;
	}
	ThreadEnded = true;
	ExitThread(0);
	return 0;
}

void CFtpTransfer::OnStop() 
{
	// TODO: Add your control notification handler code here
	EndTheTransfer=true;	
	m_Start.EnableWindow(TRUE);
	m_Stop.EnableWindow(FALSE);
}

void CFtpTransfer::OnStartagain() 
{
	// TODO: Add your control notification handler code here
	EndTheTransfer=false;
	m_Start.EnableWindow(FALSE);
	m_Stop.EnableWindow(TRUE);
	OnCopyfiles();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -