Files
2022-10-26 12:25:11 +08:00

760 lines
21 KiB
C++

#include ".\updatemodule.h"
#include <io.h>
#include <Tlhelp32.h> //PROCESSENTRY32
#include <shlwapi.h> //PathIsDirectory
#include "ScriptParser.h"
CUpdateModule::CUpdateModule(void)
{
ZeroMemory( &m_UpdateInfo, sizeof(m_UpdateInfo) );
ZeroMemory( m_szBasicDownDir, MAX_PATH ); //로컬에 다운로드할 기본 경로.
m_bUpdateStart = TRUE;
m_fnMsgCallback = NULL;
}
CUpdateModule::~CUpdateModule(void)
{
}
BOOL CUpdateModule::ConnectFTP( TCHAR* pszIP, int nPort, TCHAR* pszID, TCHAR* pszPass )
{
DWORD ErrorCode = 0;
return m_FtpNetwork.Connect( pszIP, nPort, pszID, pszPass, ErrorCode );
}
VOID CUpdateModule::DisconnectFTP()
{
if( m_FtpNetwork.IsConnectFTP() == TRUE )
m_FtpNetwork.DisConnect();
}
BOOL CUpdateModule::GetFtpIP( TCHAR* pszIP, int nSize )
{
if( pszIP == NULL || (strcmp( pszIP, "" ) == 0) )
return FALSE;
m_FtpNetwork.GetIP( pszIP, nSize );
return TRUE;
}
int CUpdateModule::GetFtpPort()
{
return m_FtpNetwork.GetPort();
}
HANDLE CUpdateModule::MakeLocalFile( const TCHAR* pszLocalFilePath)
{
HANDLE hLocalFile = CreateFile(pszLocalFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if( hLocalFile == INVALID_HANDLE_VALUE )
{
//1. 읽기 전용속성인지 체크한다.
if( GetFileAttributes( pszLocalFilePath ) && FILE_ATTRIBUTE_READONLY )
{
if( SetFileAttributes( pszLocalFilePath, FILE_ATTRIBUTE_NORMAL ) )
{
hLocalFile = CreateFile(pszLocalFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if( hLocalFile ) return hLocalFile;
}
return NULL;
}
return NULL;
}
return hLocalFile;
}
//pszRemoteFilePath : 파일이름이 포함된 원격지 경로, 루트부터 시작된 경로여야 한다.
//pszLocalPath : 파일이름이 포함되지 않은 순수한 로컬 경로
BOOL CUpdateModule::DownloadFile( const TCHAR* pszRemoteFilePath, TCHAR* pszLocalPath)
{
HANDLE hLocalFile = INVALID_HANDLE_VALUE;
HINTERNET hFtpFile = NULL;
//1. 원격서버 경로를 분석한다.
TCHAR szRemoteDir[MAX_PATH];
TCHAR szRemoteFileName[MAX_PATH];
GetSplitFilePath( pszRemoteFilePath, szRemoteDir, szRemoteFileName );
CHAR szRealLocalFilePath[MAX_PATH];
GetLocalFileName( pszLocalPath, szRemoteFileName, szRealLocalFilePath );
__try
{
hLocalFile = MakeLocalFile( szRealLocalFilePath );
if(hLocalFile == NULL)
{
AddMessage( WM_COMMAND_MESSAGE, "로컬 파일 생성 실패" );
return FALSE;
}
//////////////////////////////////////////////////////////////////////////
// 원격지 작업 폴더 설정
if( !SetRemoteDirectory( szRemoteDir ) )
{
strncpy( m_UpdateInfo.m_szFileName, szRemoteDir, MAX_PATH );
AddMessage( WM_FTP_DIRECTORY_NOTFOUND, &m_UpdateInfo );
return FALSE; //원격지에 해당 디렉토리가 존재하지 않습니다.
}
//////////////////////////////////////////////////////////////////////////
// 원격지 파일정보 얻기
WIN32_FIND_DATA info;
if( !m_FtpNetwork.GetFileInfo( szRemoteFileName, info ) ) //파일이 존재하지 않으면..
{
strncpy( m_UpdateInfo.m_szFileName, szRemoteFileName, MAX_PATH );
AddMessage( WM_FTP_FILE_NOTFOUND, &m_UpdateInfo );
return FALSE; //하나라도 파일이 존재하지 않으면 업데이트를 취소한다.
}
//////////////////////////////////////////////////////////////////////////
// 3 . 원격지 파일 열기
hFtpFile = m_FtpNetwork.OpenFtpFile( szRemoteFileName );
if( hFtpFile == NULL )
{
strncpy( m_UpdateInfo.m_szFileName, szRemoteFileName, MAX_PATH );
AddMessage( WM_FTP_FILE_OPEN_FAIL, &m_UpdateInfo );
DeleteFile( szRealLocalFilePath );
return FALSE; // 파일 하나만 실패해도 다운로드를 멈춤다.
}
//////////////////////////////////////////////////////////////////////////
// 4. 원격지 파일 다운로드
strncpy( m_UpdateInfo.m_szFileName, info.cFileName, MAX_PATH );
AddMessage( WM_FILE_DOWNLOAD_START, &m_UpdateInfo );
if( !m_FtpNetwork.DownloadFile( hFtpFile, info, hLocalFile ) )
{
// 파일 얻기에 실패하면, 현재 만들어진 로컬 파일도 삭제한다.
DeleteFile( szRealLocalFilePath );
AddMessage( WM_FILE_DOWNLOAD_FAIL, &m_UpdateInfo );
return FALSE;
}
//파일 다운로드 성공
AddMessage( WM_FILE_DOWNLOAD_END, &m_UpdateInfo );
}
__finally
{
if ( hFtpFile )
InternetCloseHandle( hFtpFile );
if ( hLocalFile != INVALID_HANDLE_VALUE )
CloseHandle(hLocalFile);
}
return TRUE;
}
BOOL CUpdateModule::GetSplitFilePath(const TCHAR* pszFilePath, TCHAR* pszDir, TCHAR* pszFile)
{
char pszFileName[MAX_PATH];
char pszFileExt[MAX_PATH];
//여기서 서버폴더 조건이 따른다.
//서버의 폴더는 루트에서 하위 1단계 까지만 존재한다.
_splitpath(pszFilePath, NULL, pszDir, pszFileName, pszFileExt );
if(pszDir == NULL || (strcmp(pszDir, "") == 0) )
wsprintf(pszDir, "\\");
wsprintf( pszFile, "%s%s", pszFileName, pszFileExt);
return TRUE;
}
//원격지의 파일리스트 파일의 경로를 구한다.
void CUpdateModule::GetRemoteFileListPath( char* pszFilePath, int nSize, const char* pszVerFolder )
{
TCHAR szCurServer[MAX_PATH];
GetProcessName( szCurServer, MAX_PATH );
if( szCurServer == NULL || strcmp( szCurServer, "" ) == 0 )
_snprintf( pszFilePath, nSize, "%s\\%s", pszVerFolder, DEFAULT_FILELIST_FILE );
else
_snprintf( pszFilePath, nSize, "%s\\%s\\%s", szCurServer, pszVerFolder, DEFAULT_FILELIST_FILE );
}
BOOL CUpdateModule::GetLocalFileName(const TCHAR* pszLocalPath, const TCHAR* pszRemoteFileName, TCHAR* pszLocalFilePath)
{
// 여기서 로컬 파일이름이 없다면 원격파일이름과 동일하게 만든다.
if ( (!pszLocalPath) || ( strcmp(pszLocalPath, "") == 0 ) )
wsprintf( pszLocalFilePath, ".\\%s", pszRemoteFileName );
else
{
// 끝에 \ 이 있는지 없는지 검사해서 적용한다.
if (pszLocalPath[strlen(pszLocalPath)-1] != '\\')
wsprintf(pszLocalFilePath, "%s\\%s", pszLocalPath, pszRemoteFileName );
else
wsprintf(pszLocalFilePath, "%s%s", pszLocalPath, pszRemoteFileName);
}
return TRUE;
}
//pszRemoteDir은 루트에 .\ 이런 것이 안붙는다.
//pszRemoteDir은 루트에서 부터의 경로이다.
//루트는 아무것도 안 붙는다.
//만일 .\AgentServer\\sss 경로에 있는 sss 폴더를 세팅하고 싶으면..
//pszRemoteDir은 AgentServer\\sss 이 되어야 한다.
BOOL CUpdateModule::SetRemoteDirectory(const TCHAR* pszRemoteDir)
{
BOOL bSuccess = FALSE;
//1. 루트로 설정
bSuccess = m_FtpNetwork.SetDirectory( "/" );
//2. 루트로 부터 디렉토리 설정
bSuccess = m_FtpNetwork.SetDirectory( pszRemoteDir );
return bSuccess;
}
//로컬 파일과 서버파일을 비교하여 다운 받을지 안 받을지를 결정한다.
//TRUE : 파일을 다운 받는다.
//FALSE : 파일을 다운 받지 않는다.
BOOL CUpdateModule::CanFileDownload( const TCHAR* pszLocalFilePath, const WIN32_FIND_DATA& remoteFileInfo )
{
//////////////////////////////////////////////////////////////////////////
// 현재 이 파일을 다운 받은적이 있는지 체크..
// 1. 서버파일과 똑같은 로컬파일이 있는지 체크
HANDLE hFile = CreateFile( pszLocalFilePath, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( hFile != INVALID_HANDLE_VALUE ) //파일이 존재한다.
{
//1. 로컬파일 정보 읽어오기
FILETIME localFileTime, remoteFileTime;
GetFileTime( hFile, NULL, NULL, &localFileTime );
//2. 원격지 파일 시간정보
remoteFileTime = remoteFileInfo.ftLastWriteTime;
// 정보를 다 읽었으니, 핸들을 닫는다.
CloseHandle( hFile );
// 두 파일의 시간이 동일하지 않다.
if( ( remoteFileTime.dwHighDateTime != localFileTime.dwHighDateTime ) ||
( remoteFileTime.dwLowDateTime != localFileTime.dwLowDateTime ) )
{
return TRUE;
}
else //시간마져 동일하다면... 파일의 크기 비교
{
FILE* pFile = fopen( pszLocalFilePath, "r");
long nLen = _filelength( _fileno(pFile) );
fclose(pFile);
return FALSE;
if( nLen == remoteFileInfo.nFileSizeLow ) //파일의 크기가 같다면..
return FALSE; //파일을 다운 받지 않는다.
else
return TRUE;
}
}
else //파일이 존재 하지 않으면..
return TRUE;
}
//파일 리스트에 있는 파일들을 다운 받는다.
BOOL CUpdateModule::DownloadFilesOnFileList( TCHAR* pszRemoteDirPath )
{
// 로컬에 리스트 파일을 다운 받았으면, 반드시 실행파일 경로에 있다. 따라서 이름만 써준다.
CScriptParser parser;
TCHAR szPath[MAX_PATH];
GetModuleDirectory( szPath, MAX_PATH );
SetCurrentDirectory( szPath );
if( !parser.SetFile( DEFAULT_FILELIST_FILE ) )
{
AddMessage( WM_UPDATE_ERROR ); //파일 리스트 파일 열기 실패.....
return FALSE;
}
string strLocalRelativeDirPath; //로컬 저장 디렉토리 상대경로
// 파일 리스트를 분석해서, 파일 리스트에 있는 파일들을 다운 받는 구문..
while( m_bUpdateStart )
{
UDTToken Token = parser.GetToken();
if( Token == END )
break;
if( Token == NAME ) // 파일이름인 경우
{
// 원격지 호스트의 전체경로이름
CHAR szCurrentRemoteFilePath[MAX_PATH];
ZeroMemory( szCurrentRemoteFilePath, MAX_PATH );
_snprintf( szCurrentRemoteFilePath, MAX_PATH, "%s\\%s", pszRemoteDirPath, parser.GetTokenString() );
string strAbsoluteDirPath;
GetAbsolteLocalDownDir( strLocalRelativeDirPath, strAbsoluteDirPath );
//////////////////////////////////////////////////////////////////////////
// 현재 이 파일을 다운 받은적이 있는지 체크..
// 1. 서버파일과 똑같은 로컬파일이 있는지 체크
string strLocalFilePath;
strLocalFilePath = strAbsoluteDirPath;
strLocalFilePath += "\\";
strLocalFilePath += parser.GetTokenString();
if ( !DownloadFile( szCurrentRemoteFilePath, const_cast<char*>(strAbsoluteDirPath.c_str()) ) )
return FALSE;
}
if( Token == NUMBER ) // 폴더이름인 경우
{
// 0이면 폴더를 생성하라는 명령이므로, 0 다음에 나오는 값을 읽어야 한다.
// 그 값이 폴더 명이다.
Token = parser.GetToken();
//1. 기본 로컬 경로 폴더가 있는지 체크. 없으면 생성
strLocalRelativeDirPath = "\\";
strLocalRelativeDirPath += parser.GetTokenString();
string strAbsoluteDirPath;
GetAbsolteLocalDownDir( strLocalRelativeDirPath, strAbsoluteDirPath );
strAbsoluteDirPath += "\\";
MakeDirectory( (TCHAR*)strAbsoluteDirPath.c_str() );
}
}
if( m_bUpdateStart == FALSE )
return FALSE;
return TRUE;
}
//상대경로로 부터 로컬의 다운로드 절대 경로를 얻는다.
void CUpdateModule::GetAbsolteLocalDownDir( string strRelativeDir, string& strAbsolteDir )
{
if( strRelativeDir.length() == 0 )
strRelativeDir = "\\";
//만일 m_szBasicDownDir 가 null 이 들어 있을수 있다.. 따라서 그때는..
//현재 실행중인 디렉토리로 설정한다.
// 다운로드 디렉토리에 strRelativeDir(상대경로)를 덧붙여서 저장시킬 현재 로컬의 절대경로를 얻는다.
if( GetLocalBasicDownDir() == NULL || ( strcmp( GetLocalBasicDownDir(), "" ) == 0 ) )
{
char szDir[MAX_PATH];
GetModuleDirectory( szDir, MAX_PATH );
strAbsolteDir = szDir;
strAbsolteDir += strRelativeDir;
}
else
{
strAbsolteDir = GetLocalBasicDownDir();
strAbsolteDir += "\\";
strAbsolteDir += GetProcessName();
strAbsolteDir += strRelativeDir;
}
}
//현재 이 모듈이 위치하고 있는 곳의 절대경로를 리턴한다.
void CUpdateModule::GetModuleDirectory( TCHAR* pszDirPath, int nSize )
{
ZeroMemory( pszDirPath, nSize );
TCHAR szPath[MAX_PATH];
TCHAR szDrive[MAX_PATH], szDir[MAX_PATH];
GetModuleFileName( NULL, szPath, MAX_PATH);
_splitpath( szPath, szDrive, szDir, NULL, NULL );
_snprintf( pszDirPath, nSize, "%s%s", szDrive, szDir);
}
// 01.02.03 과 같은 문자열에서 각각의 버전을 뽑아내는 함수.
void CUpdateModule::GetVersionFromString( char* pszVersion, byte* byVer, int nMaxVerCount )
{
// char* szTok;
string strVersion = pszVersion;
int nCnt = 0;
while( strVersion.size() != 0)
{
if( nCnt >= nMaxVerCount )
break;
int nIdx = (int)strVersion.find('.');
if( nIdx == string::npos )
{
if( !strVersion.empty() )
{
byVer[nCnt] = atoi( strVersion.c_str() );
}
strVersion.clear();
}
else
{
string strVer = strVersion.substr( 0, nIdx );
byVer[nCnt] = atoi( strVer.c_str() );
strVersion.erase( 0, nIdx + 1);
nCnt++;
}
}
}
//현재 컴퓨터에 업데이트하고 있는 프로그램이 실행중인지 체크.
//실행중인 프로그램이 하나라도 있으면 TRUE리턴
//아니면 FASLE를 리턴..
BOOL CUpdateModule::CheckLiveProcess( TCHAR* pszProcess, BOOL bKillProcess )
{
if( !pszProcess || strcmp( pszProcess, "" ) == 0 )
return FALSE;
// 프로세스 체크 런쳐나 게임 클라이언트가 실행중인지 체크한다
HANDLE hSnapShot;
//Get the snapshot of the system
hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPALL, NULL );
PROCESSENTRY32 pEntry;
pEntry.dwSize = sizeof(pEntry);
//Get first process
Process32First (hSnapShot,&pEntry);
//Iterate thru all processes
DWORD dwPID = GetCurrentProcessId();
while(TRUE)
{
BOOL bRet = Process32Next (hSnapShot,&pEntry);
if( bRet == FALSE )
break;
//자기 자신은 넘어간다.
if(dwPID == pEntry.th32ProcessID)
continue;
// 실행 중인지 체크하도록 한다.
if( strcmp(pEntry.szExeFile, pszProcess ) == 0 ) //현재 같은 프로그램이 실행중이라면..
{
if( bKillProcess )
{
KillProcess(pEntry.th32ProcessID);
return FALSE;
}
else
return TRUE;
}
}// End While
return FALSE;
}
// 이 함수는 서버의 버전파일을 다운 받아서, 현재 클라이언트의 버전과 비교하여,
// 업데이트를 할지 안 할지를 결정하는 함수다.
// 버전체크 실패면, FALSE
// 업데이트 파일이 없으면, FALSE
// 성공이면, TRUE
eRC_VERSION CUpdateModule::CheckVersionFiles( CVersionInfo& rVerInfo )
{
// 1 . 서버에 있는 버전 파일을 다운 받는다.
// 현재 다운받을려는 서버의 폴더에 있는 버전 파일을 다운 받는다. 받은 파일은 로컬에 다운받는다.
TCHAR szVerFilePath[MAX_PATH];
GetRemoteVersionFilePath( szVerFilePath, MAX_PATH );
//현재 디렉토리 설정..
TCHAR szPath[MAX_PATH];
GetModuleDirectory( szPath, MAX_PATH );
SetCurrentDirectory( szPath );
//다운받은 버전파일은 언제 삭제할 것인가?
if( !DownloadFile( szVerFilePath ) )
return RC_VERSION_FILE_NOTEXIST;
// 2 . 다운 받은 버전 파일에서 현재 클라이언트의 버전과 비교하여 받을 파일이 있으면 해당 폴더에서 목록파일을 받는다.
if( !GetUpdateFolderCount( rVerInfo, m_byUpdateFolderCount ) )
{
return RC_VERSION_PARSING_FAIL;
}
DeleteFile( DEFAULT_VERSION_FILE );
if( m_byUpdateFolderCount == 0 ) //업데이트 할 파일이 없다. 현재 최신버전 이다.
return RC_VERSION_LASTEST;
return RC_VERSION_NEED_UPDATE;
}
//원격지의 버전폴더의 경로를 반환한다.
void CUpdateModule::GetRemoteVersionFolderPath( TCHAR* pszFolderPath, int nSize, const TCHAR* pszVerFolder )
{
TCHAR szCurServer[MAX_PATH];
GetProcessName( szCurServer, MAX_PATH );
if( szCurServer == NULL || strcmp( szCurServer, "" ) == 0 )
_snprintf( pszFolderPath, nSize, "%s", pszVerFolder );
else
_snprintf( pszFolderPath, nSize, "%s\\%s", szCurServer, pszVerFolder );
}
BOOL CUpdateModule::Init()
{
m_bUpdateStart = TRUE;
m_FtpNetwork.m_fnMsgCallBack = m_fnMsgCallback;
AddMessage( WM_UPDATE_MODULE_INIT );
return TRUE;
}
//기본 디렉토리 경로를 포함하는 FTP서버상의 버전파일 경로를 구한다.
void CUpdateModule::GetRemoteVersionFilePath( TCHAR* pszVerFilePath, int nSize )
{
TCHAR szAppName[MAX_PATH];
ZeroMemory( szAppName, MAX_PATH );
GetProcessName( szAppName, MAX_PATH );
if( szAppName == NULL || (strcmp( szAppName, "" ) == 0 ) )
strncpy( pszVerFilePath, DEFAULT_VERSION_FILE, nSize ); //만일 디폴트 디렉토리가 없으면 루트에서 찾는다.
else
_snprintf( pszVerFilePath, nSize, "%s\\%s", szAppName, DEFAULT_VERSION_FILE );
}
//한개의 프로세서내에는 여러개의 패치 버전이 존재한다.
//서버에서 다운받은 현재 프로세서의(FTP에 존재하는 NAME폴더내의 ) wz_version.dat 파일에서
//현재의 로컬 버전과 비교하여, 몇개의 버전을 패치하여야 하는지 패치(폴더)의 개수를
//구하는 함수이다.
BOOL CUpdateModule::GetUpdateFolderCount( CVersionInfo CurVersion, OUT BYTE& byUpdateFolderCount )
{
UDTToken Token;
CScriptParser parser;
CVersionInfo NewVersion;
byUpdateFolderCount = 0; //업데이트 폴더 개수 초기화..
TCHAR szPath[MAX_PATH];
GetModuleDirectory( szPath, MAX_PATH );
SetCurrentDirectory( szPath );
if( !parser.SetFile( DEFAULT_VERSION_FILE ) )
return FALSE;
while(TRUE)
{
Token = parser.GetToken();
if( Token == END )
break;
if( Token == NAME )
{
NewVersion.Init();
NewVersion.SetVersionFromString( parser.GetTokenString() );
//새로운 버전이 현재 로컬의 버전보다 크다면..
//업데이트할 폴더의 정보와 개수를 증가시킨다.
if( NewVersion.GetTotalVersion() > CurVersion.GetTotalVersion() )
{
strncpy( m_UpdateFolderInfo[byUpdateFolderCount].m_szFolderName, parser.GetTokenString(), MAX_FOLDER_NAME );
m_UpdateFolderInfo[byUpdateFolderCount].m_Version = NewVersion;
byUpdateFolderCount++;
}
if( byUpdateFolderCount >= MAX_UPDATE_FOLDER_COUNT )
return FALSE;
}
}
return TRUE;
}
//한개의 프로세스단위를 업데이트 한다.
BOOL CUpdateModule::UpdateOneProcess()
{
TCHAR szCurLocalDirectory[MAX_PATH]; // 현재 로컬 호스트의 디렉토리 경로
// 현재 실행파일의 디렉토리를 구한다.
GetModuleDirectory( szCurLocalDirectory, MAX_PATH );
//1. 현재의 프로세서에 업데이트할 폴더의 개수만큼 루프를 돈다.
//for (int i = 0; i < m_byUpdateFolderCount; i++ )
//{
int i = m_byUpdateFolderCount-1;
//원격지의 파일리스트 파일의 경로를 얻어온다.
TCHAR szFileListFilePath[MAX_PATH];
GetRemoteFileListPath( szFileListFilePath, MAX_PATH, m_UpdateFolderInfo[i].m_szFolderName );
TCHAR szLocalListPath[MAX_PATH];
GetModuleDirectory( szLocalListPath, MAX_PATH );
//리스트 파일 다운로드(실행파일 위치에 다운 받는다.)
if ( !DownloadFile(szFileListFilePath, szLocalListPath) )
return FALSE;
//다운받을 버전의 폴더경로를 가져온다.
TCHAR szVerFolerPath[MAX_PATH];
GetRemoteVersionFolderPath( szVerFolerPath, MAX_PATH, m_UpdateFolderInfo[i].m_szFolderName );
//해당 버전 폴더에 있는 파일 리스트의 파일들을 다운받는다.
if( !DownloadFilesOnFileList( szVerFolerPath ) )
{
DeleteFile( DEFAULT_FILELIST_FILE ); //로컬에 다운받아 놨던 파일리스트를 삭제한다.
DeleteFile( DEFAULT_VERSION_FILE ); //로컬에 다운받아 놨던 버전파일을 삭제한다.
return FALSE; //하나만 잘 못되도, 프로그램을 종료한다.
}
// 여기까지 왔으면 윗 버전으로의 업데이트가 성공한 것이므로 업된 버전 저장
m_CurVersion = m_UpdateFolderInfo[i].m_Version;
m_CurVersion.GetStringVersion( m_UpdateInfo.m_szProcessVer, MAX_PATH );
// 업데이트 중 프로그램 버전을 알린다.
AddMessage( WM_UPDATE_VERSION_ALARM, &m_UpdateInfo );
DeleteFile( DEFAULT_FILELIST_FILE ); //로컬에 다운받아 놨던 파일리스트를 삭제한다.
DeleteFile( DEFAULT_VERSION_FILE ); //로컬에 다운받아 놨던 버전파일을 삭제한다.
//}
return TRUE;
}
//파일리스트 파일은 반드시 다운로드 받는 버전폴더에 존재해야 한다.
//예 : AgentServer\00.00.01\filelist.dat
void CUpdateModule::GetLocalFileListPath( char* pszFilePath, int nSize, const char* pszVerFolder )
{
TCHAR szCurServer[MAX_PATH];
GetProcessName( szCurServer, MAX_PATH );
if( szCurServer == NULL || strcmp( szCurServer, "" ) == 0 )
_snprintf( pszFilePath, nSize, "%s\\%s", pszVerFolder, DEFAULT_FILELIST_FILE );
else
_snprintf( pszFilePath, nSize, "%s\\%s\\%s", szCurServer, pszVerFolder, DEFAULT_FILELIST_FILE );
}
//로컬의 버전폴더의 경로를 반환한다.
void CUpdateModule::GetLocalVersionFolderPath( char* OUT pszFolderPath, int IN nSize, const char* IN pszVerFolder )
{
if( GetLocalBasicDownDir() == NULL || (strcmp( GetLocalBasicDownDir(), "" ) == 0 ) )
strncpy( pszFolderPath, pszVerFolder, nSize );
else
_snprintf( pszFolderPath, nSize, "%s\\%s", GetLocalBasicDownDir(), pszVerFolder );
}
void CUpdateModule::SetProcessName( TCHAR* pszName )
{
if( !pszName ) return;
strncpy( m_UpdateInfo.m_szProcessName, pszName, MAX_PATH );
}
void CUpdateModule::GetProcessName( TCHAR* pszName, int nSize )
{
ZeroMemory( pszName, nSize );
strncpy( pszName, m_UpdateInfo.m_szProcessName, nSize );
}
void CUpdateModule::AddMessage( UINT uMsg, VOID* pData )
{
if( !m_fnMsgCallback ) return;
m_fnMsgCallback( uMsg, pData );
}
void CUpdateModule::SetLocalBasicDownDir( TCHAR* pszDir )
{
if( pszDir == NULL || strcmp( pszDir, "" ) == 0 )
return;
ZeroMemory( m_szBasicDownDir, MAX_PATH );
strncpy( m_szBasicDownDir, pszDir, MAX_PATH );
}
void CUpdateModule::GetLocalBasicDownDir( TCHAR* pszDir, int nSize )
{
strncpy( pszDir, m_szBasicDownDir, nSize );
}
void CUpdateModule::MakeDirectory( const char* pszDir )
{
if( pszDir == NULL || strcmp( pszDir, "" ) == 0 )
return;
int nLen = (int)strlen( pszDir ) + 1;
char* szBuf = new char[nLen];
strncpy( szBuf, pszDir, nLen );
for( int i = 0; i < nLen; i++ )
{
if( szBuf[i] && szBuf[i] != '\\' )
continue;
szBuf[i] = '\0';
if( PathIsDirectory(szBuf) == FALSE )
CreateDirectory( szBuf, NULL );
szBuf[i] = '\\';
}
delete[] szBuf;
}
//현재 다운받을 어플리케이션의 기본 디렉토리를 생성한다.
void CUpdateModule::CreateLocalProcessDownDir( )
{
string strDir;
if( GetLocalBasicDownDir() == NULL || strcmp( GetLocalBasicDownDir(), "") == 0 )
strDir = "";
else
{
strDir += GetLocalBasicDownDir();
strDir += '\\';
}
TCHAR szAppName[MAX_PATH];
GetProcessName( szAppName, MAX_PATH );
strDir += szAppName;
MakeDirectory( strDir.c_str() );
}
void CUpdateModule::SendTerminateProcessMsg()
{
AddMessage( WM_TERMINATE_PROCESS );
}
void CUpdateModule::SetCurVerInfo( TCHAR* pszVersion )
{
strncpy( m_UpdateInfo.m_szProcessVer, pszVersion, MAX_PATH );
m_CurVersion.SetVersionFromString( pszVersion );
}
VOID CUpdateModule::KillProcess(DWORD th32ProcessID)
{
UINT uExitCode = 0;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, th32ProcessID);
if(TerminateProcess(hProcess, uExitCode))
AddMessage( WM_COMMAND_MESSAGE, "프로세스 삭제 성공" );
else
AddMessage( WM_COMMAND_MESSAGE, "프로세스 삭제 실패" ) ;
CloseHandle(hProcess);
}
VOID CUpdateModule::StopUpdate()
{
m_bUpdateStart = FALSE;
}
VOID CUpdateModule::SetMsgCallBack( fnMsgCallBack CallBack )
{
if( !CallBack ) return;
m_fnMsgCallback = CallBack;
m_FtpNetwork.SetMsgCallBack( m_fnMsgCallback );
}