352 lines
9.5 KiB
C++
352 lines
9.5 KiB
C++
#include ".\launcherupdate.h"
|
|
#include <io.h>
|
|
#include <windows.h>
|
|
#include "MyFolder.h"
|
|
|
|
CLauncherUpdate::CLauncherUpdate(void)
|
|
{
|
|
SetUpdateType( UPDATE_TYPE_LAUNCHER );
|
|
}
|
|
|
|
CLauncherUpdate::~CLauncherUpdate(void)
|
|
{
|
|
}
|
|
|
|
//중간에 종료되어야 할 상황이면, FALSE
|
|
//모든것이 완료 되었을 때는 TRUE를 리턴한다.
|
|
BOOL CLauncherUpdate::StartUpdate()
|
|
{
|
|
// 기본 다운로드 디렉토리 설정
|
|
PROCESS_INFO_MAP_ITER iter;
|
|
|
|
BYTE byUpdateSeq = 0;
|
|
|
|
for( iter = m_mapProcessInfo.begin(); iter != m_mapProcessInfo.end(); ++iter )
|
|
{
|
|
PROCESS_INFO* pInfo = iter->second;
|
|
if( !pInfo ) continue;
|
|
|
|
pInfo->m_byUpdateSequence = byUpdateSeq;
|
|
byUpdateSeq++;
|
|
|
|
if( m_byUpdateNumber != 0 ) //일정한 서버만 업데이트 면..
|
|
{
|
|
if( pInfo->m_byUpdateNumber != m_byUpdateNumber )
|
|
continue;
|
|
}
|
|
|
|
if( GetStartType() != START_TYPE_LAUNCHER ) //런처가 실행했을 경우에는 프로세서 체크를 하지 않는다.
|
|
{
|
|
if( !CheckLiveProcess( pInfo->m_szCheckProcess ) )
|
|
{
|
|
AddMessage( WM_UPDATE_LIVE_PROCESS, pInfo );
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//1. 기본정보 세팅.
|
|
m_UpdateModule.SetUpdateNumber( pInfo->m_byUpdateNumber );
|
|
m_UpdateModule.SetCurVerInfo( pInfo->m_szProcessVer );
|
|
m_UpdateModule.SetProcessName( pInfo->m_szProcessName );
|
|
m_UpdateModule.SetUpdateSequence( pInfo->m_byUpdateSequence );
|
|
|
|
//1. 다운받을 프로세서의 로컬 디렉토리를 생성한다.
|
|
m_UpdateModule.CreateLocalProcessDownDir();
|
|
|
|
//2. 버전을 체크한다.
|
|
eRC_VERSION RcVersion = m_UpdateModule.CheckVersionFiles( m_UpdateModule.GetCurVersion() );
|
|
if( RcVersion == RC_VERSION_FILE_NOTEXIST || RcVersion == RC_VERSION_PARSING_FAIL )
|
|
{
|
|
AddMessage( WM_UPDATE_VERSION_CHECK_FAIL, pInfo );
|
|
return FALSE;
|
|
}
|
|
else if( RcVersion == RC_VERSION_LASTEST ) //최신버전이면. 넘어간다.
|
|
{
|
|
AddMessage( WM_UPDATE_LASTEST_VERSION, pInfo );
|
|
continue;
|
|
}
|
|
|
|
|
|
//3. 현재 실행 상태를 체크해서, 런처가 실행 시킨게 아닌데 업데이트를 해야하는 상황이면..
|
|
if( GetStartType() != START_TYPE_LAUNCHER )
|
|
{
|
|
//아래 명령이 실패든 성공이든, 무조건 프로세스는 종료되어야 한다.
|
|
CopyAndExcute();
|
|
return FALSE;
|
|
}
|
|
|
|
// 한개의 프로세서를 업데이트 한다.
|
|
if( m_UpdateModule.UpdateOneProcess() ) //필요정보, 프로세서이름과 최종버전
|
|
{
|
|
m_UpdateModule.GetCurVersion().GetStringVersion( pInfo->m_szProcessVer, MAX_PATH );
|
|
AddMessage( WM_UPDATE_END_SUCCESS, pInfo );
|
|
}
|
|
else
|
|
{
|
|
AddMessage( WM_UPDATE_END_FAIL, pInfo );
|
|
DeleteFile( DEFAULT_FILELIST_FILE ); //로컬에 다운받아 놨던 파일리스트를 삭제한다.
|
|
DeleteFile( DEFAULT_VERSION_FILE ); //로컬에 다운받아 놨던 버전파일을 삭제한다.
|
|
return FALSE;
|
|
}
|
|
|
|
if( GetStartType() == START_TYPE_LAUNCHER )
|
|
OnLauncherDownloadComplete( );
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//기본 다운로드 디렉토리에 Copy하고 실행한다.
|
|
BOOL CLauncherUpdate::CopyAndExcute()
|
|
{
|
|
DisconnectFTP();
|
|
|
|
//런처 업데이트에서는 프로세서 체크를 하기 전에
|
|
//먼저 현재의 실행 폴더를 템프 폴더에 복사 작업을 먼저해야 한다.
|
|
TCHAR szFromDir[MAX_PATH];
|
|
m_UpdateModule.GetModuleDirectory( szFromDir, MAX_PATH );
|
|
BYTE byCount = GetProcessInfoCount();
|
|
|
|
for( int i = 0; i < byCount ; i++ )
|
|
{
|
|
PROCESS_INFO* pInfo = GetProcessInfo( i+ 1 );
|
|
if( !pInfo ) return FALSE;
|
|
|
|
// TempFolder를 초기화 한다.
|
|
if( !InitTempFolder( pInfo ) ) return FALSE;
|
|
|
|
TCHAR szToPath[MAX_PATH];
|
|
if( !GetCopyFolderPath( pInfo, szToPath, MAX_PATH, FALSE ) ) return FALSE;
|
|
|
|
DeleteLastPathSep( szFromDir, MAX_PATH ); // 끝에 "\\" 가 있으면 삭제한다.
|
|
DeleteLastPathSep( szToPath, MAX_PATH ); // 끝에 "\\" 가 있으면 삭제한다.
|
|
|
|
//현재 런처 디렉토리의 내용을 Copy폴더로 복사한다.
|
|
if( !MyFolder::CopyFoler( szFromDir, szToPath ) )
|
|
{
|
|
m_UpdateModule.AddMessage( WM_COMMAND_MESSAGE, "템프 카피 폴더로 런처폴더 복사 실패");
|
|
return FALSE;
|
|
}
|
|
|
|
//복사가 다 되었으면.. 해당 프로세서를 실행한다.
|
|
string strFile = szToPath;
|
|
strFile += "\\";
|
|
strFile += pInfo->m_szProcessName;
|
|
strFile += "\\";
|
|
strFile += pInfo->m_szCheckProcess;
|
|
|
|
if( _access( strFile.c_str(), 0 ) != -1 ) //파일이 존재하면..
|
|
{
|
|
strFile += " <LAUNCHER> ";
|
|
strFile += m_szExecuteParameter;
|
|
if( !ExcuteProcess( (TCHAR*)strFile.c_str() ) )
|
|
return FALSE;
|
|
}
|
|
|
|
static TCHAR szLog[MAX_PATH];
|
|
_snprintf( szLog, MAX_PATH, "[Copy Folder Success] From : %s, To : %s", szFromDir, szToPath );
|
|
m_UpdateModule.AddMessage( WM_COMMAND_MESSAGE, szLog );
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//런처 업데이트가 완료시 실행되는 함수
|
|
BOOL CLauncherUpdate::OnLauncherDownloadComplete()
|
|
{
|
|
// 현재 런처의 업데이트가 아니면 리턴한다.
|
|
if( GetUpdateType() != UPDATE_TYPE_LAUNCHER )
|
|
return FALSE;
|
|
|
|
//런처 업데이트 완료시
|
|
//1. Down 폴더에서 원본폴더로 복사하고,
|
|
//2. 원본에 버전을 올린다.
|
|
//3. 업데이트된 런처를 실행하고
|
|
//4. 현재 프로세서를 종료한다.
|
|
|
|
for( int i = 0; i < GetProcessInfoCount(); i++ )
|
|
{
|
|
PROCESS_INFO* pInfo = GetProcessInfo( i + 1 );
|
|
|
|
TCHAR szBasicDownDir[MAX_PATH];
|
|
GetLocalBasicDownDir( szBasicDownDir, MAX_PATH );
|
|
|
|
//1. 런처가 다운로드된 곳에서 런처가 실행되는곳으로 복사( TempDown에서 실행위치로 복사 )
|
|
TCHAR szDownPath[MAX_PATH];
|
|
if( !GetDownFolderPath( pInfo, szDownPath, MAX_PATH ) ) return FALSE;
|
|
|
|
TCHAR szExecuteDir[MAX_PATH];
|
|
GetLocalBasicExecuteDir( szExecuteDir, MAX_PATH );
|
|
|
|
if( !MyFolder::CopyFoler( szDownPath, szExecuteDir ) )
|
|
m_UpdateModule.AddMessage( WM_COMMAND_MESSAGE, "폴더 복사 실패" );
|
|
else
|
|
{
|
|
static char szCopyFolder[MAX_PATH];
|
|
_snprintf( szCopyFolder, MAX_PATH, "[Copy Folder Success] From : %s, To : %s", szDownPath, szExecuteDir );
|
|
m_UpdateModule.AddMessage( WM_COMMAND_MESSAGE, szCopyFolder );
|
|
}
|
|
|
|
|
|
//2. INI 파일 복사( Copy에서 실행버전으로.. )
|
|
string strFromFile;
|
|
strFromFile = szBasicDownDir;
|
|
strFromFile += "\\Copy\\";
|
|
strFromFile += pInfo->m_szProcessName;
|
|
strFromFile += "\\";
|
|
strFromFile += DEFAULT_UPDEATEINFO_FILE;
|
|
|
|
string strToFile = szExecuteDir;
|
|
strToFile += "\\";
|
|
strToFile += pInfo->m_szProcessName;
|
|
strToFile += "\\";
|
|
strToFile += DEFAULT_UPDEATEINFO_FILE;
|
|
|
|
if( !CopyFile( strFromFile.c_str(), strToFile.c_str(), FALSE ) )
|
|
{
|
|
TCHAR szMsg[MAX_PATH];
|
|
wsprintf( szMsg, "From = %s, To = %s, ErrorCode = %d", strFromFile.c_str(), strToFile.c_str(), GetLastError() );
|
|
AddMessage( WM_COMMAND_MESSAGE, szMsg );
|
|
}
|
|
else
|
|
{
|
|
static char szCopyFile[MAX_PATH];
|
|
_snprintf( szCopyFile, MAX_PATH, "[Copy File Success] From : %s, To : %s", strFromFile.c_str(), strToFile.c_str() );
|
|
m_UpdateModule.AddMessage( WM_COMMAND_MESSAGE, szCopyFile );
|
|
}
|
|
|
|
//3. 업데이트된 런처 실행
|
|
string strFile = szExecuteDir;
|
|
strFile += "\\";
|
|
strFile += pInfo->m_szProcessName;
|
|
strFile += "\\";
|
|
strFile += pInfo->m_szCheckProcess;
|
|
|
|
if( _access( strFile.c_str(), 0 ) != -1 ) //파일이 존재하면..
|
|
{
|
|
strFile += " <APPLICATION>";
|
|
strFile += m_szExecuteParameter;
|
|
if( !ExcuteProcess( (TCHAR*)strFile.c_str() ) )
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CLauncherUpdate::ExcuteProcess( TCHAR* pszPath )
|
|
{
|
|
if( pszPath == NULL )
|
|
return FALSE;
|
|
|
|
if( WinExec( pszPath, SW_SHOW ) > 31 ) //성공이면..
|
|
m_UpdateModule.SendTerminateProcessMsg();
|
|
else
|
|
{
|
|
m_UpdateModule.AddMessage( WM_COMMAND_MESSAGE, "실행실패" );
|
|
return FALSE; //실패했으면, 실패 처리..
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CLauncherUpdate::InitTempFolder( PROCESS_INFO* pInfo )
|
|
{
|
|
if( !pInfo ) return FALSE;
|
|
|
|
string strCopyPath, strDownPath, strTempPath;
|
|
|
|
//1. 기존의 Copy 폴더가 있으면 Copy폴더 삭제
|
|
TCHAR szCopyFolderPath[MAX_PATH];
|
|
if( !GetCopyFolderPath( pInfo, szCopyFolderPath, MAX_PATH ) ) return FALSE;
|
|
|
|
if( _access( szCopyFolderPath, 0 ) != -1 ) //파일이나 폴더가 존재하면..
|
|
{
|
|
if( !DeleteFolder( szCopyFolderPath ) )
|
|
{
|
|
m_UpdateModule.AddMessage( WM_COMMAND_MESSAGE, "Temp Copy 폴더 삭제 실패");
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//2. 기본의 Down 디렉토리가 있으면 Down폴더 삭제.
|
|
TCHAR szDownFolderPath[MAX_PATH];
|
|
if( !GetDownFolderPath( pInfo, szDownFolderPath, MAX_PATH ) ) return FALSE;
|
|
|
|
if( _access( szDownFolderPath, 0 ) != -1 ) //파일이나 폴더가 존재하면..
|
|
{
|
|
if( !DeleteFolder( szDownFolderPath ) )
|
|
{
|
|
m_UpdateModule.AddMessage( WM_COMMAND_MESSAGE, "Temp Down 폴더 삭제 실패");
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//3. Temp Copy 디렉토리를 만든다.
|
|
if( !CreateDirectory( szCopyFolderPath, NULL ) )
|
|
{
|
|
m_UpdateModule.AddMessage( WM_COMMAND_MESSAGE, "Temp Copy 폴더 생성 실패");
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL CLauncherUpdate::GetCopyFolderPath( PROCESS_INFO* pInfo, OUT TCHAR* pszPath, int nSize, BOOL bIncludeProcessName )
|
|
{
|
|
if( !pInfo || !pszPath ) return FALSE;
|
|
|
|
TCHAR szBasicDownDir[MAX_PATH];
|
|
m_UpdateModule.GetLocalBasicDownDir( szBasicDownDir, MAX_PATH );
|
|
|
|
string strTempPath = szBasicDownDir;
|
|
int nPos = (int)strTempPath.find( "Down" );
|
|
if( nPos == std::string::npos )
|
|
{
|
|
AddMessage( WM_COMMAND_MESSAGE, "Down 찾기 실패" );
|
|
return FALSE;
|
|
}
|
|
|
|
strTempPath.erase( nPos, strTempPath.length() - nPos );
|
|
strTempPath += "Copy";
|
|
if( bIncludeProcessName == TRUE )
|
|
{
|
|
strTempPath += "\\";
|
|
strTempPath += pInfo->m_szProcessName;
|
|
}
|
|
|
|
strncpy( pszPath, strTempPath.c_str(), nSize );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CLauncherUpdate::GetDownFolderPath( PROCESS_INFO* pInfo, OUT TCHAR* pszPath, int nSize, BOOL bIncludeProcessName )
|
|
{
|
|
if( !pInfo ) return FALSE;
|
|
|
|
TCHAR szBasicDownDir[MAX_PATH];
|
|
m_UpdateModule.GetLocalBasicDownDir( szBasicDownDir, MAX_PATH );
|
|
if( bIncludeProcessName == TRUE )
|
|
_snprintf( pszPath, nSize, "%s\\%s", szBasicDownDir, pInfo->m_szProcessName );
|
|
else
|
|
strncpy( pszPath, szBasicDownDir, nSize );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
VOID CLauncherUpdate::DeleteLastPathSep( IN OUT TCHAR* pszPath, int nSize )
|
|
{
|
|
string strPath = pszPath;
|
|
|
|
int nPathSize = (int)strPath.size();
|
|
if( nPathSize > 0 )
|
|
{
|
|
string strEnd = strPath.substr( nPathSize - 1, 1 );
|
|
if( strEnd.compare("\\") == 0 )
|
|
strPath.erase( nPathSize - 1, 1 );
|
|
}
|
|
|
|
strncpy( pszPath, strPath.c_str(), nSize );
|
|
} |