最近写的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;

};

解决方案 »

  1.   


    //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();
    }
      

  2.   


    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;
    }
      

  3.   


    //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;

    };
      

  4.   


    //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]);
    }}
      

  5.   


    //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;
    }
      

  6.   


    //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;
    }
      

  7.   


    //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;

    };
      

  8.   

    //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);
    }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);
    }
      

  9.   


    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;
    }
      

  10.   


    //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;

    };
      

  11.   


    //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());
    }

    }
    }
      

  12.   


    //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;
    }