最近写的FTP更新客户端,已实现了部分功能,也进行了一下简单的测试,还没完善,如果哪位有兴趣,请帮忙看看,哪些地方需要改善,或给点建议,谢谢!
流程:更新客户端启动后,从FTP服务器下载update.txt,同时在本地会遍历当前的文件及子目录,
将所有文件及文件夹信息存储到local.txt文件中,将下载下来的update.txt与local.txt进行对比,
得出需要更新的文件,然后向FTP服务器请求下载。//WinFile.h
#ifndef WIN_FILE_H
#define WIN_FILE_H
#endif#include <tchar.h>
#include <Windows.h>
#include <stdio.h>
#include <vector>
#include <map>
#include <fstream>
#include <string>
#include <map>
#include "Log.h"using namespace std;#define TRACE ATLTRACE
#define MAXSIZE 256
#define BUFSIZE 4096
#define MAX_SIZE_TO_READ 1024*1024struct tagFILEINFO
{
std::string strCreateTime;
std::string strLastWriteTime;
std::string strSize;
std::string strFilePath;
};struct USER_DEFINE_FIND_DATA : public WIN32_FIND_DATA
{
TCHAR strFilePath[MAXSIZE];
};// global variable
typedef pair <int, string> Int_Pair;class CFileManage
{
public:
//default construction function
CFileManage(); //Get all file list then store to a vector
vector<USER_DEFINE_FIND_DATA> GetFileInfo()
{
return m_vFileInfo;
} //after read txt per row, store to a map,this function is to get the map when called!
map<int,string> GetUpdateFile()
{
return m_mapUpdateFile;
} //Initialization some function
VOID Initialization(); //recursion browse current directory and subdirectory,find all of directory and file
vector<USER_DEFINE_FIND_DATA> Win32RecurseDirectory( TCHAR* strDirectoryName); //Write into a file
BOOL Win32WriteFile(HANDLE hHandle, LPCTSTR strBuffer, DWORD dwNumberOfBytesToWrite, DWORD dwNumberOfBytesWritten ); //Write all directory file to a text,
VOID Win32WriteToText(std::vector<USER_DEFINE_FIND_DATA> vFileInfo, std::string strDestPath);
VOID Win32ReadFromText(TCHAR *strReadBuf,std::string strSourcePath); //Read string form text,only implement read ASCII text now, we should read a function to translate UNICODE text form ASCII.
//you must pass value of reference,else you can't find the right result.the reason .Why vector is ok?
VOID Win32ReadAsciiFile(TCHAR* strFileName, map <int, string> &mapRead); //prase string
tagFILEINFO ParseString(std::string strTemp); //Compare file,return the different between of two file and store to a vector.
BOOL Win32CompareFile(std::string strstrSourceFilePath,std::string strDestFilePath,vector<string>& vFileNeedToUpdate); //default destruction function
~CFileManage();private:
map <int,string> m_MapLocalFile;
map <int,string> m_MapUpdateFile;
map <int, string>::iterator m_IterLocalFile;
map <int, string>::iterator m_IterUpdateFile;
tagFILEINFO m_StructFileInfo; typedef pair<string,tagFILEINFO> m_PairUpdateFileInfo;
typedef pair<string,tagFILEINFO> m_PairLocalFileInfo;
map<string,tagFILEINFO> m_MapLocalFileInfo;
map<string,tagFILEINFO> m_MapUpdateFileInfo;
map<string,tagFILEINFO>::const_iterator m_IterBrowseFile;private:
//copy structure function,it's not need to implement .just a declaration
CFileManage(const CFileManage&); //assignment operator function
CFileManage& operator = (const CFileManage);private:
vector<USER_DEFINE_FIND_DATA> m_vFileInfo;
map<int,string> m_mapUpdateFile;
CLogOutput m_LogOutput;
};
流程:更新客户端启动后,从FTP服务器下载update.txt,同时在本地会遍历当前的文件及子目录,
将所有文件及文件夹信息存储到local.txt文件中,将下载下来的update.txt与local.txt进行对比,
得出需要更新的文件,然后向FTP服务器请求下载。//WinFile.h
#ifndef WIN_FILE_H
#define WIN_FILE_H
#endif#include <tchar.h>
#include <Windows.h>
#include <stdio.h>
#include <vector>
#include <map>
#include <fstream>
#include <string>
#include <map>
#include "Log.h"using namespace std;#define TRACE ATLTRACE
#define MAXSIZE 256
#define BUFSIZE 4096
#define MAX_SIZE_TO_READ 1024*1024struct tagFILEINFO
{
std::string strCreateTime;
std::string strLastWriteTime;
std::string strSize;
std::string strFilePath;
};struct USER_DEFINE_FIND_DATA : public WIN32_FIND_DATA
{
TCHAR strFilePath[MAXSIZE];
};// global variable
typedef pair <int, string> Int_Pair;class CFileManage
{
public:
//default construction function
CFileManage(); //Get all file list then store to a vector
vector<USER_DEFINE_FIND_DATA> GetFileInfo()
{
return m_vFileInfo;
} //after read txt per row, store to a map,this function is to get the map when called!
map<int,string> GetUpdateFile()
{
return m_mapUpdateFile;
} //Initialization some function
VOID Initialization(); //recursion browse current directory and subdirectory,find all of directory and file
vector<USER_DEFINE_FIND_DATA> Win32RecurseDirectory( TCHAR* strDirectoryName); //Write into a file
BOOL Win32WriteFile(HANDLE hHandle, LPCTSTR strBuffer, DWORD dwNumberOfBytesToWrite, DWORD dwNumberOfBytesWritten ); //Write all directory file to a text,
VOID Win32WriteToText(std::vector<USER_DEFINE_FIND_DATA> vFileInfo, std::string strDestPath);
VOID Win32ReadFromText(TCHAR *strReadBuf,std::string strSourcePath); //Read string form text,only implement read ASCII text now, we should read a function to translate UNICODE text form ASCII.
//you must pass value of reference,else you can't find the right result.the reason .Why vector is ok?
VOID Win32ReadAsciiFile(TCHAR* strFileName, map <int, string> &mapRead); //prase string
tagFILEINFO ParseString(std::string strTemp); //Compare file,return the different between of two file and store to a vector.
BOOL Win32CompareFile(std::string strstrSourceFilePath,std::string strDestFilePath,vector<string>& vFileNeedToUpdate); //default destruction function
~CFileManage();private:
map <int,string> m_MapLocalFile;
map <int,string> m_MapUpdateFile;
map <int, string>::iterator m_IterLocalFile;
map <int, string>::iterator m_IterUpdateFile;
tagFILEINFO m_StructFileInfo; typedef pair<string,tagFILEINFO> m_PairUpdateFileInfo;
typedef pair<string,tagFILEINFO> m_PairLocalFileInfo;
map<string,tagFILEINFO> m_MapLocalFileInfo;
map<string,tagFILEINFO> m_MapUpdateFileInfo;
map<string,tagFILEINFO>::const_iterator m_IterBrowseFile;private:
//copy structure function,it's not need to implement .just a declaration
CFileManage(const CFileManage&); //assignment operator function
CFileManage& operator = (const CFileManage);private:
vector<USER_DEFINE_FIND_DATA> m_vFileInfo;
map<int,string> m_mapUpdateFile;
CLogOutput m_LogOutput;
};
//WinFile.cpp
#ifndef WIN_FILE_H
#include "WinFile.h"
#endif#define LOCAL_FILE_PATH _T(".\\")
#define WRITE_UPDATE_TXT_PATH _T(".\\local.txt")CFileManage::CFileManage()
{
Initialization();
}
CFileManage::~CFileManage()
{};VOID CFileManage::Initialization()
{
Win32RecurseDirectory(LOCAL_FILE_PATH);
Win32WriteToText(GetFileInfo(),WRITE_UPDATE_TXT_PATH);
}vector<USER_DEFINE_FIND_DATA> CFileManage::Win32RecurseDirectory(TCHAR* strDirectoryName)
{
TCHAR *strPathName = new TCHAR[BUFSIZE];
TCHAR *strTempPath = new TCHAR[BUFSIZE];
BOOL bSearchFile = FALSE;
BOOL bFinished = FALSE;
DWORD dwPos = 0;
USER_DEFINE_FIND_DATA Filedata;
ZeroMemory(&Filedata,sizeof(Filedata));
HANDLE hFindFile = INVALID_HANDLE_VALUE; //save current path to a strPathName variable
_tcscpy(strPathName,strDirectoryName); //add a \ to the end of strPathName
if (strPathName[_tcslen(strPathName)-1] != _T('\\'))
{
_tcscat(strPathName,_T("\\"));
}
//add a * to the end of strPathName
_tcscat(strPathName,_T("*.*")); //find the first file in the directory,if succeeds,return value is a search handle used in a subsequent call to FindNextFile or FindClose.
bSearchFile = (INVALID_HANDLE_VALUE !=(hFindFile = FindFirstFile(strPathName,&Filedata)));
if (bSearchFile)
{
//if direction is current or subdirectories ,ignore it
if (_tcscmp(Filedata.cFileName,_T(".")) && _tcscmp(Filedata.cFileName,_T("..")))
{
m_LogOutput.FormatOutput(_T(" %s\n"),Filedata.cFileName);
}
while (!bFinished)
{
//Continues a file search next file,recurse calls RecurseDirectory,until no file or direction left
if (FindNextFile(hFindFile,&Filedata))
{
if ((Filedata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && _tcscmp(Filedata.cFileName,_T(".")) && _tcscmp(Filedata.cFileName,_T("..")))
{
_tcscpy(strTempPath,strDirectoryName);
_tcscat(strTempPath,Filedata.cFileName);
_tcscat(strTempPath,_T("\\"));
m_LogOutput.FormatOutput(_T(" %s\n"),Filedata.cFileName);
_tcscpy(Filedata.strFilePath,strTempPath);
_tcscat(Filedata.strFilePath,Filedata.cFileName);
m_vFileInfo.push_back(Filedata);
Win32RecurseDirectory(strTempPath);
}
else if (_tcscmp(Filedata.cFileName,_T(".")) && _tcscmp(Filedata.cFileName,_T("..")))
{
m_LogOutput.FormatOutput(_T(" %s\n"),Filedata.cFileName);
_tcscpy(Filedata.strFilePath,strDirectoryName);
_tcscat(Filedata.strFilePath,Filedata.cFileName);
m_vFileInfo.push_back(Filedata);
}
}
else
{
if( GetLastError() == ERROR_NO_MORE_FILES )
{
bFinished = TRUE;
}
else
{
bFinished = TRUE;
}
}
}
}
else
{
m_LogOutput.FormatOutput(_T("Invalid File Handle. GetLastError reports %d\n"), GetLastError ());
}
delete []strPathName;
delete []strTempPath;
FindClose(hFindFile);
return m_vFileInfo;
}BOOL CFileManage::Win32WriteFile(HANDLE hHandle,LPCTSTR strBuffer,DWORD dwNumberOfBytesToWrite,DWORD dwNumberOfBytesWritten )
{
if (!WriteFile(hHandle,strBuffer,dwNumberOfBytesToWrite,&dwNumberOfBytesToWrite,NULL))
{
m_LogOutput.FormatOutput(_T("WriteFile failed at %d\n"),GetLastError());
return FALSE;
}
return TRUE;
}VOID CFileManage::Win32WriteToText(std::vector<USER_DEFINE_FIND_DATA> vFileInfo,std::string strDestPath)
{
DWORD dwByteWrite = 0;
SYSTEMTIME systemCreateTime;
SYSTEMTIME systemChangeTime;
FILETIME fileCreateTime;
FILETIME fileLastChageTime;
TCHAR szTemp[MAXSIZE];
ZeroMemory(szTemp,sizeof(TCHAR)*MAXSIZE);
ZeroMemory(&systemCreateTime,sizeof(systemCreateTime));
ZeroMemory(&fileCreateTime,sizeof(fileCreateTime));
ZeroMemory(&fileLastChageTime,sizeof(fileLastChageTime));
ZeroMemory(&systemChangeTime,sizeof(systemChangeTime)); //create a file ,if the file not exist,create it ,else open it.
HANDLE hFile = CreateFile(
strDestPath.c_str(),
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL); if (INVALID_HANDLE_VALUE == hFile)
{
m_LogOutput.FormatOutput(_T("CreateFile failed at %d\n"),GetLastError());
return;
}
for (int i = 0;i < vFileInfo.size();i++ )
{
fileCreateTime = vFileInfo[i].ftCreationTime;
fileLastChageTime = vFileInfo[i].ftLastWriteTime;
if (!FileTimeToSystemTime(&fileCreateTime,&systemCreateTime))
{
m_LogOutput.FormatOutput(_T("fileCreateTime FileTimeToSystemTime failed at %d\n"),GetLastError());
}
if (!FileTimeToSystemTime(&fileLastChageTime,&systemChangeTime))
{
m_LogOutput.FormatOutput(_T("fileLastChageTime FileTimeToSystemTime failed at %d\n"),GetLastError());
} _stprintf(szTemp,_T("%d/%d/%d--%d:%d:%d,%d/%d/%d--%d:%d:%d,%d,%s,\r\n" ),systemCreateTime.wMonth,systemCreateTime.wDay,
systemCreateTime.wYear,systemCreateTime.wHour,systemCreateTime.wMinute,systemCreateTime.wSecond,
systemChangeTime.wMonth,systemChangeTime.wDay,systemChangeTime.wYear,systemChangeTime.wHour,systemChangeTime.wMinute,systemChangeTime.wSecond,
vFileInfo[i].nFileSizeLow,vFileInfo[i].strFilePath); Win32WriteFile(hFile,szTemp,_tcslen(szTemp),dwByteWrite);
}
CloseHandle(hFile);
}VOID CFileManage::Win32ReadFromText(TCHAR *strReadBuf,std::string strSourcePath)
{
HANDLE hFile = INVALID_HANDLE_VALUE;
BOOL bResult = FALSE;
DWORD dwNumberOfBytesToRead = MAX_SIZE_TO_READ;
DWORD dwNumberOfBytesRead = 0;
//opens a file,if the file not exist,return .
hFile = CreateFile(
strSourcePath.c_str(),
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
bResult = ReadFile(hFile,strReadBuf,dwNumberOfBytesToRead,&dwNumberOfBytesRead,NULL);
if (!bResult)
{
m_LogOutput.FormatOutput(_T("ReadFile failed at %d\n"),GetLastError());
return;
}
CloseHandle(hFile);
}VOID CFileManage::Win32ReadAsciiFile(TCHAR* strFileName,map <int, string> &mapRead)
{
int iCoutn = 0;
ifstream ifs(strFileName);
string strRead;
while (!ifs.eof()) // when the file not exist ,infinitude loop.why?
{
iCoutn ++;
getline(ifs,strRead,'\n');
if (strRead.size() != 0)
{
mapRead.insert(Int_Pair(iCoutn,strRead));
}
}
ifs.close();
}
tagFILEINFO CFileManage::ParseString(std::string strTemp)
{
int nCh = _T(',');
int nCount = 1;
int result = 0;
TCHAR *pdest;
std::string strLeft;
tagFILEINFO structLocalFile;
ZeroMemory(&structLocalFile,sizeof(structLocalFile));
// Search forward.
while (1)
{
pdest = strchr(const_cast<TCHAR*>(strTemp.c_str()), nCh ); //returns a pointer to the first occurrence of gCh in strTemp, or NULL if c is not found
if ( pdest != NULL )
{
m_LogOutput.FormatOutput(_T("Result: first %c found at position %d\n"), nCh, result );
}
else
{
return structLocalFile;
} //the position of which you first find the char ch
result = (int)(pdest - strTemp.c_str() + 1); //store a file information to struct.
switch (nCount)
{ case 1:
{
for (int m = 0;m < result - 1 ; m++)
{
structLocalFile.strCreateTime += strTemp[m];
}
break;
}
case 2:
{
for (int m = 0;m < result - 1 ; m++)
{
structLocalFile.strLastWriteTime += strTemp[m];
}
break;
}
case 3:
{
for (int m = 0;m < result - 1 ; m++)
{
structLocalFile.strSize += strTemp[m];
}
break;
}
case 4:
{
for (int m = 0;m < result - 1 ; m++)
{
structLocalFile.strFilePath += strTemp[m];
}
break;
}
default:
return structLocalFile;
}
int iLen = strlen(pdest); if (strLeft.size() != 0)
{
strLeft.clear();
} //copy string from pdest to strLeft
for (int i = 1 ;i < iLen ; i++)
{
strLeft += pdest[i];
}
int nLen = strlen(strTemp.c_str());
strTemp = const_cast<char*>((TCHAR *)strLeft.c_str());
nCount ++;
}
return structLocalFile;
}BOOL CFileManage::Win32CompareFile(std::string strstrSourceFilePath,std::string strDestFilePath,std::vector<string>& vFileNeedToUpdate)
{
map<string,tagFILEINFO>::const_iterator l_IterResult;
Win32ReadAsciiFile(const_cast<TCHAR*>(strstrSourceFilePath.c_str()),m_MapLocalFile);
Win32ReadAsciiFile(const_cast<TCHAR*>(strDestFilePath.c_str()),m_mapUpdateFile);
for (m_IterLocalFile = m_MapLocalFile.begin(); m_IterLocalFile != m_MapLocalFile.end(); m_IterLocalFile++)
{
m_StructFileInfo = ParseString(m_IterLocalFile->second);
m_MapLocalFileInfo.insert(m_PairLocalFileInfo(m_StructFileInfo.strFilePath,m_StructFileInfo));
}
for (m_IterUpdateFile = m_mapUpdateFile.begin(); m_IterUpdateFile != m_mapUpdateFile.end(); m_IterUpdateFile++)
{
m_StructFileInfo = ParseString(m_IterUpdateFile->second);
m_MapUpdateFileInfo.insert(m_PairUpdateFileInfo(m_StructFileInfo.strFilePath,m_StructFileInfo));
}
//compare string
for (m_IterBrowseFile = m_MapUpdateFileInfo.begin(); m_IterBrowseFile != m_MapUpdateFileInfo.end(); m_IterBrowseFile++)
{
l_IterResult = m_MapLocalFileInfo.find(m_IterBrowseFile->first);
if (l_IterResult != m_MapLocalFileInfo.end() && l_IterResult->second.strFilePath.size() != 0)
{
m_LogOutput.FormatOutput(_T("The element of map m_MapLocalFileInfo with a key %s is found\n"),l_IterResult ->first.c_str());
//sting have operator ==,or you can use wcscmp to compare string
if (
l_IterResult->second.strCreateTime == m_IterBrowseFile->second.strCreateTime &&
l_IterResult->second.strLastWriteTime == m_IterBrowseFile->second.strLastWriteTime &&
l_IterResult->second.strSize == m_IterBrowseFile->second.strSize
)
{
m_LogOutput.FormatOutput(_T("the file is not need to be update\n"));
}
}
else
{
m_LogOutput.FormatOutput(_T("the file % s is need to be update\n"),m_IterBrowseFile->first.c_str());
if (m_IterBrowseFile->first.size() != 0)
{
vFileNeedToUpdate.push_back(m_IterBrowseFile->first);
}
}
}
return TRUE;
}
//WinNet.h
#ifndef Win_Net_H
#define Win_Net_H
#endif#ifndef WIN_FILE_H
#include "WinFile.h"
#endif#ifndef LOG_H
#include "Log.h"
#endif#include <tchar.h>
#include <Windows.h>
#include <WinInet.h>
#include <iostream>
#include <string>
#include <vector>#pragma comment(lib,"Wininet")
using namespace std;enum ErrorType
{
Success,
InternetConnectFailure,
InternetSessionFailure,
ConfigDownloadFailure,
FileDownloadFailure,
NoExecutableVersion,
UpdateNotRequired,
UpdateNotComplete
};class CWinUpdate
{
public: //default construction function
CWinUpdate();
//Initializes an application's use of the WinINet functions.
VOID InitWinINet(std::string); VOID Initialization(); //Opens an File Transfer Protocol
//strServerName:specifies the host name of an Internet ,you can also specifies a IP address ,such as 192.168.0.103
//strUserName: name of the user to log on
//strUserPassword: password the user to login
VOID OpenWinINetConnection(std::string strServerName,std::string strUserName,std::string strUserPassword); //Creates a new directory on the FTP server.make sure the HINTERNET which Internet return is not close,else it will failed!
BOOL WinInetCreateDirectory(std::string strDirectory); //Deletes a file stored on the FTP server.make sure the HINTERNET which Internet return is not close,else it will failed!
BOOL WinInetDeleteFile(std::string strFileName); //Retrieves a file from the FTP server and stores it under the specified file name, creating a new local file
BOOL WinInetDownloadFile(std::string strRomteFile,std::string strLocalNewFile); //Stores a file on the FTP server.
BOOL WinUploadFile(std::string strRomteNewFile,std::string strLocalFile); //checkout if there is any file have changed!
ErrorType CheckoutUpdate(/*TCHAR* strReadFileName,*/std::string strstrSourceFilePath,std::string strDestFilePath,vector<string>& vNeedToUpdate); //default destruction function VOID DownAllUpdateFiles(vector<string>& vNeedToUpdate);
~CWinUpdate();public:
CFileManage m_FileManage;private:
//copy structure function,it's not need to implement .just a declaretion
CWinUpdate(const CWinUpdate& );
//assignment operator function
CWinUpdate& operator = (const CWinUpdate& );private:
DWORD dwContext;
HINTERNET hOpen;
HINTERNET hConnection;
CLogOutput m_LogOutput;
};
//WinNet.cpp
#ifndef Win_Net_H
#include "WinNet.h"
#endif#include <stdio.h>
#define APPNAME _T("FTP Client Update App")
#define SERVER_NAME _T("192.168.0.103")
#define USER_NAME _T("www.dyzd.com")
#define USER_PASSWORD _T("www.dyzd.com")#define ROMOTE_FILE_PATH _T("update.txt")
#define LOCAL_TXT_PATH _T(".\\update.txt")CWinUpdate::CWinUpdate()
{
dwContext = 0;
Initialization();
}CWinUpdate::~CWinUpdate()
{
InternetCloseHandle(hOpen);
InternetCloseHandle(hConnection);
}VOID CWinUpdate::Initialization()
{
InitWinINet(APPNAME);
OpenWinINetConnection(SERVER_NAME,USER_NAME,USER_PASSWORD);
//download download.txt from FTP server
WinInetDownloadFile(ROMOTE_FILE_PATH,LOCAL_TXT_PATH);
}VOID CWinUpdate::InitWinINet(std::string appName)
{
hOpen = InternetOpen(appName.c_str(),INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,INTERNET_FLAG_ASYNC);
if (NULL == hOpen)
{
m_LogOutput.FormatOutput(_T("InternetOpen failed at %d\n"),GetLastError());
}
}VOID CWinUpdate::OpenWinINetConnection(std::string strServerName,std::string strUserName,std::string strUserPassword)
{
hConnection = InternetConnect(hOpen,strServerName.c_str(),INTERNET_DEFAULT_FTP_PORT,strUserName.c_str(),strUserPassword.c_str(),INTERNET_SERVICE_FTP,INTERNET_FLAG_PASSIVE,dwContext);
if (NULL == hConnection)
{
m_LogOutput.FormatOutput(_T("InternetConnection failed at %d\n"),GetLastError());
}
}BOOL CWinUpdate::WinInetCreateDirectory(std::string strDirectory)
{ if (!FtpCreateDirectory(hConnection,strDirectory.c_str()))
{
m_LogOutput.FormatOutput(_T("FtpCreateDirectory failed at %d\n"),GetLastError());
return FALSE;
}
return TRUE;;
}BOOL CWinUpdate::WinInetDeleteFile(std::string strFileName)
{
if (!FtpDeleteFile(hConnection,strFileName.c_str()))
{
m_LogOutput.FormatOutput(_T("FtpCreateDirectory failed at %d\n"),GetLastError());
return FALSE;
}
return TRUE;
}BOOL CWinUpdate::WinInetDownloadFile(std::string strRomteFile,std::string strLocalNewFile)
{
if (!FtpGetFile(hConnection,strRomteFile.c_str(),strLocalNewFile.c_str(),FALSE,FILE_ATTRIBUTE_NORMAL,FTP_TRANSFER_TYPE_BINARY|INTERNET_FLAG_RELOAD,0))
{
m_LogOutput.FormatOutput(_T("FtpGetFile failed at %d\n"),GetLastError());
return FALSE;
}
return TRUE;
}BOOL CWinUpdate::WinUploadFile(std::string strRomteNewFile,std::string strLocalFile)
{
if (!FtpPutFile(hConnection,strLocalFile.c_str(),strRomteNewFile.c_str(),FTP_TRANSFER_TYPE_BINARY|INTERNET_FLAG_RELOAD,0))
{
m_LogOutput.FormatOutput(_T("FtpputFile failed at %d\n"),GetLastError());
return FALSE;
}
return TRUE;
}ErrorType CWinUpdate::CheckoutUpdate(/*TCHAR* strReadFileName,*/std::string strstrSourceFilePath,std::string strDestFilePath,vector<string>& vNeedToUpdate)
{
//m_FileManage.Win32ReadAsciiFile(strReadFileName,m_FileManage.GetUpdateFile());
m_FileManage.Win32CompareFile(strstrSourceFilePath,strDestFilePath,vNeedToUpdate);
return Success;
}VOID CWinUpdate::DownAllUpdateFiles(vector<string>& vNeedToUpdate)
{
for (int i = 0; i < vNeedToUpdate.size(); i++)
{
WinInetDownloadFile(vNeedToUpdate[i],vNeedToUpdate[i]);
}}
//Log.cpp
#ifndef LOG_H
#include "Log.h"
#endifCLogOutput::CLogOutput()
{}CLogOutput::~CLogOutput()
{}
VOID CLogOutput::FormatOutput(const TCHAR *format,...)
{
TCHAR buf[4096], *p = buf;
va_list args;
int n; va_start(args, format);
// buf-3 is room for CR/LF/NUL
n = _vsnprintf(p, sizeof buf - 3, format, args);
va_end(args); p += (n < 0) ? sizeof buf - 3 : n; while ( p > buf && isspace(p[-1]) )
*--p = '\0'; *p++ = '\r';
*p++ = '\n';
*p = '\0'; OutputDebugString(buf);
}//log.h
#ifndef LOG_H
#define LOG_H
#endif#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include <Windows.h>class CLogOutput
{
public:
CLogOutput();
VOID FormatOutput(const TCHAR *format,...);
~CLogOutput();
};//test.cpp
#include <Windows.h>
#include "WinFile.h"
#include "WinNet.h"#define LOCAL_FILE_PATH _T(".\\local.txt")
#define UPDATE_FILE_PATH _T(".\\update.txt")int main()
{
std::vector<string> vFileNeedToUpdate;
CWinUpdate winUpdate;
winUpdate.CheckoutUpdate(/*UPDATE_TXT_PATH,*/LOCAL_FILE_PATH,UPDATE_FILE_PATH,vFileNeedToUpdate);
winUpdate.DownAllUpdateFiles(vFileNeedToUpdate);
return 0;
}
//log.h
#ifndef LOG_H
#define LOG_H
#endif#include <tchar.h>
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include <Windows.h>
#include <string>
class CLogOutput
{
public:
CLogOutput();
VOID FormatOutput(const TCHAR *format,...);
BOOL WinWriteFile(HANDLE hHandle,LPCTSTR strBuffer,DWORD dwNumberOfBytesToWrite,DWORD dwNumberOfBytesWritten );
VOID WriteLog(std::string strDestPath,TCHAR* strBuf);
~CLogOutput();
private:
HANDLE mhFile;
};//Log.cpp
#ifndef LOG_H
#include "Log.h"
#endifCLogOutput::CLogOutput()
{
mhFile = INVALID_HANDLE_VALUE;
}CLogOutput::~CLogOutput()
{ if (INVALID_HANDLE_VALUE != mhFile)
{
CloseHandle(mhFile);
}
}VOID CLogOutput::FormatOutput(const TCHAR *format,...)
{
TCHAR buf[4096];
TCHAR *p = buf;
va_list args;
int n; va_start(args, format);
// buf-3 is room for CR/LF/NUL
n = _vsnprintf(p, sizeof buf - 3, format, args);
va_end(args); p += (n < 0) ? sizeof buf - 3 : n;
while ( p > buf && isspace(p[-1]) )
{
*--p = '\0';
}
*p++ = '\r';
*p++ = '\n';
*p = '\0'; OutputDebugString(buf);
WriteLog(_T("C:\\update.log"),buf);
}VOID CLogOutput::WriteLog(std::string strDestPath,TCHAR* strBuf)
{
DWORD dwByteWrite = 0;
TCHAR strTemp[256];
ZeroMemory(strTemp,sizeof(TCHAR)*256);
SYSTEMTIME systemTime;
//create a file ,if the file not exist,create it ,else open it.
mhFile = CreateFile(
strDestPath.c_str(),
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE == mhFile)
{
_tprintf(_T("CreateFile failed at %d\n"),GetLastError());
return;
}
GetSystemTime(&systemTime);
_stprintf(strTemp,_T("%d/%d/%d/ %d/%d/%d %s"),systemTime.wYear,systemTime.wMonth,systemTime.wDay,
systemTime.wHour,systemTime.wMinute,systemTime.wMilliseconds,strBuf);
SetFilePointer(mhFile,0,NULL,FILE_END);
WinWriteFile(mhFile,strTemp,_tcslen(strTemp),dwByteWrite);
}BOOL CLogOutput::WinWriteFile(HANDLE hHandle,LPCTSTR strBuffer,DWORD dwNumberOfBytesToWrite,DWORD dwNumberOfBytesWritten )
{
if (!WriteFile(hHandle,strBuffer,dwNumberOfBytesToWrite,&dwNumberOfBytesToWrite,NULL))
{
_tprintf(_T("WriteFile failed at %d\n"),GetLastError());
return FALSE;
}
return TRUE;
}
//WinFile.h
#ifndef WIN_FILE_H
#define WIN_FILE_H
#endif#include <tchar.h>
#include <Windows.h>
#include <stdio.h>
#include <vector>
#include <map>
#include <fstream>
#include <string>
#include <map>
#include "Log.h"using namespace std;#define TRACE ATLTRACE
#define MAXSIZE 256
#define BUFSIZE 4096
#define MAX_SIZE_TO_READ 1024*1024struct tagFILEINFO
{
std::string strCreateTime;
std::string strLastWriteTime;
std::string strSize;
std::string strFilePath;
};struct USER_DEFINE_FIND_DATA : public WIN32_FIND_DATA
{
TCHAR strFilePath[MAXSIZE];
};// global variable
typedef pair <int, string> Int_Pair;class CFileManage
{
public:
//default construction function
CFileManage(); //Get all file list then store to a vector
vector<USER_DEFINE_FIND_DATA> GetFileInfo()
{
return m_vFileInfo;
} //after read txt per row, store to a map,this function is to get the map when called!
map<int,string> GetUpdateFile()
{
return m_mapUpdateFile;
} //Initialization some function
VOID Initialization(); //recursion browse current directory and subdirectory,find all of directory and file
VOID Win32RecurseDirectory( TCHAR* strDirectoryName); //Write into a file
BOOL Win32WriteFile(HANDLE hHandle, LPCTSTR strBuffer, DWORD dwNumberOfBytesToWrite, DWORD dwNumberOfBytesWritten ); //Write all directory file to a text,
VOID Win32WriteToText(std::vector<USER_DEFINE_FIND_DATA> vFileInfo, std::string strDestPath);
VOID Win32ReadFromText(TCHAR *strReadBuf,std::string strSourcePath); //Read string form text,only implement read ASCII text now, we should read a function to translate UNICODE text form ASCII.
//you must pass value of reference,else you can't find the right result.the reason .Why vector is ok?
VOID Win32ReadAsciiFile(TCHAR* strFileName, map <int, string> &mapRead); //prase string
tagFILEINFO ParseString(std::string strTemp); //Compare file,return the different between of two file and store to a vector.
BOOL Win32CompareFile(std::string strstrSourceFilePath,std::string strDestFilePath,vector<string>& vFileNeedToUpdate); //Creates a new directory
BOOL Win32CreateDirectory(std::string strNewDirectory); //default destruction function
~CFileManage();private:
map <int,string> m_MapLocalFile;
map <int,string> m_MapUpdateFile;
map <int, string>::iterator m_IterLocalFile;
map <int, string>::iterator m_IterUpdateFile;
tagFILEINFO m_StructFileInfo; typedef pair<string,tagFILEINFO> m_PairUpdateFileInfo;
typedef pair<string,tagFILEINFO> m_PairLocalFileInfo;
map<string,tagFILEINFO> m_MapLocalFileInfo;
map<string,tagFILEINFO> m_MapUpdateFileInfo;
map<string,tagFILEINFO>::const_iterator m_IterBrowseFile;private:
//copy structure function,it's not need to implement .just a declaration
CFileManage(const CFileManage&); //assignment operator function
CFileManage& operator = (const CFileManage);private:
vector<USER_DEFINE_FIND_DATA> m_vFileInfo;
typedef pair<string,USER_DEFINE_FIND_DATA> m_strPair;
map<int,string> m_mapUpdateFile;
CLogOutput m_LogOutput;
};
#ifndef WIN_FILE_H
#include "WinFile.h"
#endif#define LOCAL_FILE_PATH _T(".\\")
#define WRITE_UPDATE_TXT_PATH _T(".\\local.txt")CFileManage::CFileManage()
{
Initialization();
}
CFileManage::~CFileManage()
{};VOID CFileManage::Initialization()
{
Win32RecurseDirectory(LOCAL_FILE_PATH);
Win32WriteToText(GetFileInfo(),WRITE_UPDATE_TXT_PATH);
}VOID CFileManage::Win32RecurseDirectory(TCHAR* strDirectoryName)
{
TCHAR *strPathName = new TCHAR[BUFSIZE];
TCHAR *strTempPath = new TCHAR[BUFSIZE];
BOOL bSearchFile = FALSE;
BOOL bFinished = FALSE;
DWORD dwPos = 0;
USER_DEFINE_FIND_DATA Filedata;
ZeroMemory(&Filedata,sizeof(Filedata));
HANDLE hFindFile = INVALID_HANDLE_VALUE; //save current path to a strPathName variable
_tcscpy(strPathName,strDirectoryName); //add a \ to the end of strPathName
if (strPathName[_tcslen(strPathName)-1] != _T('\\'))
{
_tcscat(strPathName,_T("\\"));
}
//add a * to the end of strPathName
_tcscat(strPathName,_T("*.*")); //find the first file in the directory,if succeeds,return value is a search handle used in a subsequent call to FindNextFile or FindClose.
bSearchFile = (INVALID_HANDLE_VALUE !=(hFindFile = FindFirstFile(strPathName,&Filedata)));
if (bSearchFile)
{
//if direction is current or subdirectories ,ignore it
if (_tcscmp(Filedata.cFileName,_T(".")) && _tcscmp(Filedata.cFileName,_T("..")))
{
m_LogOutput.FormatOutput(_T(" %s\n"),Filedata.cFileName);
}
while (!bFinished)
{
//Continues a file search next file,recurse calls RecurseDirectory,until no file or direction left
if (FindNextFile(hFindFile,&Filedata))
{
if ((Filedata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && _tcscmp(Filedata.cFileName,_T(".")) && _tcscmp(Filedata.cFileName,_T("..")))
{
_tcscpy(strTempPath,strDirectoryName);
_tcscat(strTempPath,Filedata.cFileName);
_tcscat(strTempPath,_T("\\"));
_tcscpy(Filedata.strFilePath,strTempPath);
//_tcscat(Filedata.strFilePath,Filedata.cFileName);
m_vFileInfo.push_back(Filedata);
Win32RecurseDirectory(strTempPath);
}
else if (_tcscmp(Filedata.cFileName,_T(".")) && _tcscmp(Filedata.cFileName,_T("..")))
{
_tcscpy(Filedata.strFilePath,strDirectoryName);
_tcscat(Filedata.strFilePath,Filedata.cFileName);
m_vFileInfo.push_back(Filedata);
}
}
else
{
if( GetLastError() == ERROR_NO_MORE_FILES )
{
bFinished = TRUE;
}
else
{
bFinished = TRUE;
}
}
}
}
else
{
m_LogOutput.FormatOutput(_T("Invalid File Handle. GetLastError reports %d\n"), GetLastError ());
}
delete []strPathName;
delete []strTempPath;
FindClose(hFindFile);
return;
}BOOL CFileManage::Win32WriteFile(HANDLE hHandle,LPCTSTR strBuffer,DWORD dwNumberOfBytesToWrite,DWORD dwNumberOfBytesWritten )
{
if (!WriteFile(hHandle,strBuffer,dwNumberOfBytesToWrite,&dwNumberOfBytesToWrite,NULL))
{
m_LogOutput.FormatOutput(_T("WriteFile failed at %d\n"),GetLastError());
return FALSE;
}
return TRUE;
}VOID CFileManage::Win32WriteToText(std::vector<USER_DEFINE_FIND_DATA> vFileInfo,std::string strDestPath)
{
DWORD dwByteWrite = 0;
SYSTEMTIME stUTCCreateTime;
SYSTEMTIME stUTCChangeTime;
SYSTEMTIME stCreateTime;
SYSTEMTIME stChangeTime;
FILETIME fileCreateTime;
FILETIME fileLastChageTime;
TCHAR szTemp[MAXSIZE];
ZeroMemory(szTemp,sizeof(TCHAR)*MAXSIZE);
ZeroMemory(&stCreateTime,sizeof(stCreateTime));
ZeroMemory(&fileCreateTime,sizeof(fileCreateTime));
ZeroMemory(&fileLastChageTime,sizeof(fileLastChageTime));
ZeroMemory(&stChangeTime,sizeof(stChangeTime));
ZeroMemory(&stUTCCreateTime,sizeof(stUTCCreateTime));
ZeroMemory(&stUTCChangeTime,sizeof(stUTCChangeTime)); //create a file ,if the file not exist,create it ,else open it.
HANDLE hFile = CreateFile(
strDestPath.c_str(),
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL); if (INVALID_HANDLE_VALUE == hFile)
{
m_LogOutput.FormatOutput(_T("CreateFile failed at %d\n"),GetLastError());
return;
}
for (int i = 0;i < vFileInfo.size();i++ )
{
GetSystemTime(&stChangeTime);
GetSystemTime(&stCreateTime);
fileCreateTime = vFileInfo[i].ftCreationTime;
fileLastChageTime = vFileInfo[i].ftLastWriteTime; //Converts a file time to system time format.
if (!FileTimeToSystemTime(&fileCreateTime,&stUTCCreateTime))
{
m_LogOutput.FormatOutput(_T("fileCreateTime FileTimeToSystemTime failed at %d\n"),GetLastError());
}
//Converts a time in Coordinated Universal Time (UTC) to a specified time zone's corresponding local time.
SystemTimeToTzSpecificLocalTime(NULL, &stUTCCreateTime, &stCreateTime); if (!FileTimeToSystemTime(&fileLastChageTime,&stUTCChangeTime))
{
m_LogOutput.FormatOutput(_T("fileLastChageTime FileTimeToSystemTime failed at %d\n"),GetLastError());
}
SystemTimeToTzSpecificLocalTime(NULL, &stUTCChangeTime, &stChangeTime); _stprintf(szTemp,_T("%d/%d/%d--%d:%d:%d,%d/%d/%d--%d:%d:%d,%d,%s,\r\n" ),stCreateTime.wMonth,stCreateTime.wDay,
stCreateTime.wYear,stCreateTime.wHour,stCreateTime.wMinute,stCreateTime.wSecond,
stChangeTime.wMonth,stChangeTime.wDay,stChangeTime.wYear,stChangeTime.wHour,stChangeTime.wMinute,stChangeTime.wSecond,
vFileInfo[i].nFileSizeLow,vFileInfo[i].strFilePath); Win32WriteFile(hFile,szTemp,_tcslen(szTemp),dwByteWrite);
}
CloseHandle(hFile);
}VOID CFileManage::Win32ReadFromText(TCHAR *strReadBuf,std::string strSourcePath)
{
HANDLE hFile = INVALID_HANDLE_VALUE;
BOOL bResult = FALSE;
DWORD dwNumberOfBytesToRead = MAX_SIZE_TO_READ;
DWORD dwNumberOfBytesRead = 0;
//opens a file,if the file not exist,return .
hFile = CreateFile(
strSourcePath.c_str(),
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
bResult = ReadFile(hFile,strReadBuf,dwNumberOfBytesToRead,&dwNumberOfBytesRead,NULL);
if (!bResult)
{
m_LogOutput.FormatOutput(_T("ReadFile failed at %d\n"),GetLastError());
return;
}
CloseHandle(hFile);
}
VOID CFileManage::Win32ReadAsciiFile(TCHAR* strFileName,map <int, string> &mapRead)
{
int iCoutn = 0;
ifstream ifs(strFileName);
string strRead;
while (!ifs.eof()) // when the file not exist ,infinitude loop.why?
{
iCoutn ++;
getline(ifs,strRead,'\n');
if (strRead.size() != 0)
{
mapRead.insert(Int_Pair(iCoutn,strRead));
}
}
ifs.close();
}tagFILEINFO CFileManage::ParseString(std::string strTemp)
{
int nCh = _T(',');
int nCount = 1;
int result = 0;
TCHAR *pdest;
std::string strLeft;
tagFILEINFO structLocalFile;
ZeroMemory(&structLocalFile,sizeof(structLocalFile));
// Search forward.
while (1)
{
pdest = strchr(const_cast<TCHAR*>(strTemp.c_str()), nCh ); //returns a pointer to the first occurrence of gCh in strTemp, or NULL if c is not found
if ( pdest != NULL )
{
//m_LogOutput.FormatOutput(_T("Result: first %c found at position %d\n"), nCh, result );
}
else
{
return structLocalFile;
} //the position of which you first find the char ch
result = (int)(pdest - strTemp.c_str() + 1); //store a file information to struct.
switch (nCount)
{ case 1:
{
for (int m = 0;m < result - 1 ; m++)
{
structLocalFile.strCreateTime += strTemp[m];
}
break;
}
case 2:
{
for (int m = 0;m < result - 1 ; m++)
{
structLocalFile.strLastWriteTime += strTemp[m];
}
break;
}
case 3:
{
for (int m = 0;m < result - 1 ; m++)
{
structLocalFile.strSize += strTemp[m];
}
break;
}
case 4:
{
for (int m = 0;m < result - 1 ; m++)
{
structLocalFile.strFilePath += strTemp[m];
}
break;
}
default:
return structLocalFile;
}
int iLen = strlen(pdest); if (strLeft.size() != 0)
{
strLeft.clear();
} //copy string from pdest to strLeft
for (int i = 1 ;i < iLen ; i++)
{
strLeft += pdest[i];
}
int nLen = strlen(strTemp.c_str());
strTemp = const_cast<char*>((TCHAR *)strLeft.c_str());
nCount ++;
}
return structLocalFile;
}BOOL CFileManage::Win32CompareFile(std::string strstrSourceFilePath,std::string strDestFilePath,std::vector<string>& vFileNeedToUpdate)
{
map<string,tagFILEINFO>::const_iterator l_IterResult;
Win32ReadAsciiFile(const_cast<TCHAR*>(strstrSourceFilePath.c_str()),m_MapLocalFile);
Win32ReadAsciiFile(const_cast<TCHAR*>(strDestFilePath.c_str()),m_mapUpdateFile);
for (m_IterLocalFile = m_MapLocalFile.begin(); m_IterLocalFile != m_MapLocalFile.end(); m_IterLocalFile++)
{
m_StructFileInfo = ParseString(m_IterLocalFile->second);
m_MapLocalFileInfo.insert(m_PairLocalFileInfo(m_StructFileInfo.strFilePath,m_StructFileInfo));
}
for (m_IterUpdateFile = m_mapUpdateFile.begin(); m_IterUpdateFile != m_mapUpdateFile.end(); m_IterUpdateFile++)
{
m_StructFileInfo = ParseString(m_IterUpdateFile->second);
m_MapUpdateFileInfo.insert(m_PairUpdateFileInfo(m_StructFileInfo.strFilePath,m_StructFileInfo));
}
//compare string
for (m_IterBrowseFile = m_MapUpdateFileInfo.begin(); m_IterBrowseFile != m_MapUpdateFileInfo.end(); m_IterBrowseFile++)
{
l_IterResult = m_MapLocalFileInfo.find(m_IterBrowseFile->first);
//if no specify file found, means it need to update.else check it if were changed or not .
if (l_IterResult != m_MapLocalFileInfo.end() && l_IterResult->second.strFilePath.size() != 0)
{
//sting have operator ==,or you can use wcscmp to compare string
if (!(
//l_IterResult->second.strLastWriteTime == m_IterBrowseFile->second.strLastWriteTime &&
l_IterResult->second.strSize == m_IterBrowseFile->second.strSize &&
l_IterResult->second.strFilePath == m_IterBrowseFile->second.strFilePath
))
{
//m_LogOutput.FormatOutput(_T("%s is need to update\n"),m_IterBrowseFile->first.c_str());
if (m_IterBrowseFile->first.size() != 0)
{
vFileNeedToUpdate.push_back(m_IterBrowseFile->first);
}
}
}
else
{
if (m_IterBrowseFile->first.size() != 0)
{
vFileNeedToUpdate.push_back(m_IterBrowseFile->first);
}
}
}
return TRUE;
}BOOL CFileManage::Win32CreateDirectory(std::string strNewDirectory)
{
if (!CreateDirectory(strNewDirectory.c_str(),NULL))
{
DWORD dwError = GetLastError();
if (ERROR_ALREADY_EXISTS == dwError)
{
m_LogOutput.FormatOutput(_T("The specified directory already exists."));
}
else if (ERROR_PATH_NOT_FOUND == dwError)
{
m_LogOutput.FormatOutput(_T("One or more intermediate directories do not exist; this function will only create the final directory in the path."));
}
return FALSE;
}
return TRUE;
}
//WinNet.h
#ifndef Win_Net_H
#define Win_Net_H
#endif#ifndef WIN_FILE_H
#include "WinFile.h"
#endif#ifndef LOG_H
#include "Log.h"
#endif#include <tchar.h>
#include <Windows.h>
#include <WinInet.h>
#include <iostream>
#include <string>
#include <vector>#pragma comment(lib,"Wininet")
using namespace std;enum ErrorType
{
Success,
InternetConnectFailure,
InternetSessionFailure,
ConfigDownloadFailure,
FileDownloadFailure,
NoExecutableVersion,
UpdateNotRequired,
UpdateNotComplete
};class CWinUpdate
{
public: //default construction function
CWinUpdate();
//Initializes an application's use of the WinINet functions.
VOID InitWinINet(std::string); VOID Initialization(); //Opens an File Transfer Protocol
//strServerName:specifies the host name of an Internet ,you can also specifies a IP address ,such as 192.168.0.103
//strUserName: name of the user to log on
//strUserPassword: password the user to login
VOID OpenWinINetConnection(std::string strServerName,std::string strUserName,std::string strUserPassword); //Creates a new directory on the FTP server.make sure the HINTERNET which Internet return is not close,else it will failed!
BOOL WinInetCreateDirectory(std::string strDirectory); //Deletes a file stored on the FTP server.make sure the HINTERNET which Internet return is not close,else it will failed!
BOOL WinInetDeleteFile(std::string strFileName); //Retrieves a file from the FTP server and stores it under the specified file name, creating a new local file
BOOL WinInetDownloadFile(std::string strRomteFile,std::string strLocalNewFile); //Stores a file on the FTP server.
BOOL WinUploadFile(std::string strRomteNewFile,std::string strLocalFile); //checkout if there is any file have changed!
ErrorType CheckoutUpdate(std::string strstrSourceFilePath,std::string strDestFilePath,vector<string>& vNeedToUpdate); //default destruction function VOID DownAllUpdateFiles(vector<string>& vNeedToUpdate);
~CWinUpdate();public:
CFileManage m_FileManage;private:
//copy structure function,it's not need to implement .just a declaretion
CWinUpdate(const CWinUpdate& );
//assignment operator function
CWinUpdate& operator = (const CWinUpdate& );private:
DWORD dwContext;
HINTERNET hOpen;
HINTERNET hConnection;
CLogOutput m_LogOutput;
};
//WinNet.cpp
#ifndef Win_Net_H
#include "WinNet.h"
#endif#include <stdio.h>
#define APPNAME _T("FTP Client Update App")
#define SERVER_NAME _T("192.168.0.103")
#define USER_NAME _T("www.dyzd.com")
#define USER_PASSWORD _T("www.dyzd.com")
#define ROMOTE_FILE_PATH _T("update.txt")
#define LOCAL_TXT_PATH _T(".\\update.txt")CWinUpdate::CWinUpdate()
{
dwContext = 0;
Initialization();
}CWinUpdate::~CWinUpdate()
{
InternetCloseHandle(hOpen);
InternetCloseHandle(hConnection);
}VOID CWinUpdate::Initialization()
{
InitWinINet(APPNAME);
OpenWinINetConnection(SERVER_NAME,USER_NAME,USER_PASSWORD);
//download download.txt from FTP server
WinInetDownloadFile(ROMOTE_FILE_PATH,LOCAL_TXT_PATH);
}VOID CWinUpdate::InitWinINet(std::string appName)
{
hOpen = InternetOpen(appName.c_str(),INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,INTERNET_FLAG_ASYNC);
if (NULL == hOpen)
{
m_LogOutput.FormatOutput(_T("InternetOpen failed at %d\n"),GetLastError());
}
}VOID CWinUpdate::OpenWinINetConnection(std::string strServerName,std::string strUserName,std::string strUserPassword)
{
hConnection = InternetConnect(hOpen,strServerName.c_str(),INTERNET_DEFAULT_FTP_PORT,strUserName.c_str(),strUserPassword.c_str(),INTERNET_SERVICE_FTP,INTERNET_FLAG_PASSIVE,dwContext);
if (NULL == hConnection)
{
m_LogOutput.FormatOutput(_T("InternetConnection failed at %d\n"),GetLastError());
}
}BOOL CWinUpdate::WinInetCreateDirectory(std::string strDirectory)
{ if (!FtpCreateDirectory(hConnection,strDirectory.c_str()))
{
m_LogOutput.FormatOutput(_T("FtpCreateDirectory failed at %d\n"),GetLastError());
return FALSE;
}
return TRUE;;
}BOOL CWinUpdate::WinInetDeleteFile(std::string strFileName)
{
if (!FtpDeleteFile(hConnection,strFileName.c_str()))
{
m_LogOutput.FormatOutput(_T("FtpCreateDirectory failed at %d\n"),GetLastError());
return FALSE;
}
return TRUE;
}BOOL CWinUpdate::WinInetDownloadFile(std::string strRomteFile,std::string strLocalNewFile)
{
if (!FtpGetFile(hConnection,strRomteFile.c_str(),strLocalNewFile.c_str(),FALSE,FILE_ATTRIBUTE_NORMAL,FTP_TRANSFER_TYPE_BINARY|INTERNET_FLAG_RELOAD,0))
{
DWORD dwError = GetLastError();
//ERROR 123 means there is no specify folder exist,create a folder.if not,failed when download form FTP server ,ERROR 5.
if (123 == dwError)
{
m_FileManage.Win32CreateDirectory(strRomteFile);
return TRUE;
}
else if (5 == dwError)
{
//do nothing
}
else if (3 == dwError)
{
//do nothing
}
else
{
m_LogOutput.FormatOutput(_T("FtpGetFile failed at %d\n"),GetLastError());
return FALSE;
}
}
return TRUE;
}BOOL CWinUpdate::WinUploadFile(std::string strRomteNewFile,std::string strLocalFile)
{
if (!FtpPutFile(hConnection,strLocalFile.c_str(),strRomteNewFile.c_str(),FTP_TRANSFER_TYPE_BINARY|INTERNET_FLAG_RELOAD,0))
{
m_LogOutput.FormatOutput(_T("FtpputFile failed at %d\n"),GetLastError());
return FALSE;
}
return TRUE;
}ErrorType CWinUpdate::CheckoutUpdate(std::string strstrSourceFilePath,std::string strDestFilePath,vector<string>& vNeedToUpdate)
{
m_FileManage.Win32CompareFile(strstrSourceFilePath,strDestFilePath,vNeedToUpdate);
DownAllUpdateFiles(vNeedToUpdate);
return Success;
}VOID CWinUpdate::DownAllUpdateFiles(vector<string>& vNeedToUpdate)
{
for (int i = 0; i < vNeedToUpdate.size(); i++)
{
if (WinInetDownloadFile(vNeedToUpdate[i],vNeedToUpdate[i]))
{
m_LogOutput.FormatOutput(_T("%s update successed.\n"),vNeedToUpdate[i].c_str());
}
}
}
//log.h
#ifndef LOG_H
#define LOG_H
#endif#include <tchar.h>
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include <Windows.h>
#include <string>
class CLogOutput
{
public:
CLogOutput();
VOID FormatOutput(const TCHAR *format,...);
BOOL WinWriteFile(HANDLE hHandle,LPCTSTR strBuffer,DWORD dwNumberOfBytesToWrite,DWORD dwNumberOfBytesWritten );
VOID WriteLog(std::string strDestPath,TCHAR* strBuf);
~CLogOutput();
private:
HANDLE mhFile;
};//Log.cpp
#ifndef LOG_H
#include "Log.h"
#endifCLogOutput::CLogOutput()
{
mhFile = INVALID_HANDLE_VALUE;
}CLogOutput::~CLogOutput()
{ if (INVALID_HANDLE_VALUE != mhFile)
{
CloseHandle(mhFile);
}
}VOID CLogOutput::FormatOutput(const TCHAR *format,...)
{
TCHAR buf[4096];
TCHAR *p = buf;
va_list args;
int n; va_start(args, format);
// buf-3 is room for CR/LF/NUL
n = _vsnprintf(p, sizeof buf - 3, format, args);
va_end(args); p += (n < 0) ? sizeof buf - 3 : n;
while ( p > buf && isspace(p[-1]) )
{
*--p = '\0';
}
*p++ = '\r';
*p++ = '\n';
*p = '\0'; OutputDebugString(buf);
WriteLog(_T(".\\update.log"),buf);
}VOID CLogOutput::WriteLog(std::string strDestPath,TCHAR* strBuf)
{
DWORD dwByteWrite = 0;
TCHAR strTemp[256];
ZeroMemory(strTemp,sizeof(TCHAR)*256);
SYSTEMTIME stLocal,stUTC;
//create a file ,if the file not exist,create it ,else open it.
mhFile = CreateFile(
strDestPath.c_str(),
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE == mhFile)
{
_tprintf(_T("CreateFile failed at %d\n"),GetLastError());
return;
}
//Get a file time.
GetSystemTime(&stUTC);
//Converts a time in Coordinated Universal Time (UTC) to a specified time zone's corresponding local time.
SystemTimeToTzSpecificLocalTime(NULL,&stUTC,&stLocal);
_stprintf(strTemp,_T("%d/%d/%d %d:%d:%d %s"),stLocal.wYear,stLocal.wMonth,stLocal.wDay,
stLocal.wHour,stLocal.wMinute,stLocal.wSecond,strBuf);
SetFilePointer(mhFile,0,NULL,FILE_END);
WinWriteFile(mhFile,strTemp,_tcslen(strTemp),dwByteWrite);
}BOOL CLogOutput::WinWriteFile(HANDLE hHandle,LPCTSTR strBuffer,DWORD dwNumberOfBytesToWrite,DWORD dwNumberOfBytesWritten )
{
if (!WriteFile(hHandle,strBuffer,dwNumberOfBytesToWrite,&dwNumberOfBytesToWrite,NULL))
{
_tprintf(_T("WriteFile failed at %d\n"),GetLastError());
return FALSE;
}
return TRUE;
}//test.cpp
#include <Windows.h>
#include "WinFile.h"
#include "WinNet.h"#define LOCAL_FILE_PATH _T(".\\local.txt")
#define UPDATE_FILE_PATH _T(".\\update.txt")int main()
{
std::vector<string> vFileNeedToUpdate;
CWinUpdate winUpdate;
winUpdate.CheckoutUpdate(LOCAL_FILE_PATH,UPDATE_FILE_PATH,vFileNeedToUpdate);
return 0;
}