#include "STDAFX.H" #include "PSUPDATER.H" #include "COMMONMACROS.H" #include "BASESET.H" #include "DEBUGUTIL.H" #include "SAFESTRINGMACROS.H" #include "FILESET.H" #include "DIRECTORY.H" #include "STRINGSET.H" #include "..\\..\\SERVER\\SERVERCOMMON\\INIFILE.H" #include #include CPsUpdater* g_PsUpdater = NULL; void __stdcall Internet_Status_Callback (HINTERNET hSession, DWORD Context, DWORD Status, LPVOID pInformation, DWORD InfoLength); CPsUpdater::CPsUpdater() { Close(); } CPsUpdater::~CPsUpdater() { Close(); } void CPsUpdater::Close() { m_PsVersionFileName[0] = _T('\0'); m_PsVersionFileUrl[0] = _T('\0'); m_PsDownloadRootUrl[0] = _T('\0'); m_PsDownloadPathUrl[0] = _T('\0'); m_PsDownloadAccountId[0] = _T('\0'); m_PsDownloadPassword[0] = _T('\0'); m_CurPsVersion[0] = _T('\0'); m_NewPsVersion[0] = _T('\0'); m_CurPsVersionNo = 0; m_NewPsVersionNo = 0; m_IsOpen = false; m_IsUpdate = false; if( m_hInternet ) { ::InternetCloseHandle(m_hInternet); m_hInternet = NULL; } if( m_hInternetConnection ) { ::InternetCloseHandle(m_hInternetConnection); m_hInternetConnection = NULL; } } bool CPsUpdater::Open() { DN_ASSERT(!IsOpen(), "Already Opened!"); // Ç÷£ ½º³À¼¦ ¾÷µ¥ÀÌÆ® °æ·Î Á¤º¸ ÆÄÀÏ ÀÐÀ½ { TCHAR aIniFile[MAX_PATH] = { _T('\0'), }; { TCHAR aLocalPath[MAX_PATH] = { _T('\0'), }; TCHAR aFileName[MAX_PATH] = { _T('\0'), }; TCHAR aExecName[MAX_PATH] = { _T('\0'), }; TCHAR aDrvName[MAX_PATH] = { _T('\0'), }; TCHAR aDirName[MAX_PATH] = { _T('\0'), }; DWORD aRetVal1 = ::GetModuleFileName(NULL, aLocalPath, _countof(aLocalPath)); if (!aRetVal1) { // ¿À·ù ¹ß»ý return false; } errno_t aRetVal2 = _tsplitpath_s(aLocalPath, aDrvName, _countof(aDrvName), aDirName, _countof(aDirName), aFileName, _countof(aFileName), aExecName, _countof(aExecName)); if (aRetVal2) { // ¿À·ù ¹ß»ý return false; } _sntprintf_s(aIniFile, _countof(aIniFile), _T("%s%s%s"), aDrvName, aDirName, DF_PSUD_URLINIFILE); if (_taccess_s(CVarArg(_T("%s"), aIniFile), 0)) { // ÆÄÀÏ ¾øÀ½ return false; } } { CIniFile PsUrlIniFile; BOOL aRetVal3 = PsUrlIniFile.Open(aIniFile); if (!aRetVal3) { return false; } PsUrlIniFile.GetValue(DF_PSUD_URLINIKEY, DF_PSUD_URLINIVAL_VERFILE, m_PsVersionFileName); if (_T('\0') == m_PsVersionFileName[0]) { return false; } PsUrlIniFile.GetValue(DF_PSUD_URLINIKEY, DF_PSUD_URLINIVAL_VERURL, m_PsVersionFileUrl); if (_T('\0') == m_PsVersionFileUrl[0]) { return false; } if (!::PathIsURL(m_PsVersionFileUrl)) { return false; } PsUrlIniFile.GetValue(DF_PSUD_URLINIKEY, DF_PSUD_URLINIVAL_DOWNURL, m_PsDownloadPathUrl); if (_T('\0') == m_PsDownloadPathUrl[0]) { return false; } if (!::PathIsUNC(m_PsDownloadPathUrl)) { return false; } _tcsncpy_s(m_PsDownloadRootUrl, m_PsDownloadPathUrl, _countof(m_PsDownloadRootUrl)); { TCHAR aPsDownloadRootUrl1[MAX_PATH] = { _T('\0'), }; TCHAR aPsDownloadRootUrl2[MAX_PATH] = { _T('\0'), }; while(true) { _tcsncpy_s(aPsDownloadRootUrl1, m_PsDownloadRootUrl, _countof(aPsDownloadRootUrl1)); BOOL aRetVal = ::PathRemoveFileSpec(aPsDownloadRootUrl1); if (!aRetVal) { if (_T('\0') != aPsDownloadRootUrl2[0]) { _tcsncpy_s(m_PsDownloadRootUrl, aPsDownloadRootUrl2, _countof(m_PsDownloadRootUrl)); } break; } _tcsncpy_s(aPsDownloadRootUrl2, m_PsDownloadRootUrl, _countof(aPsDownloadRootUrl2)); _tcsncpy_s(m_PsDownloadRootUrl, aPsDownloadRootUrl1, _countof(m_PsDownloadRootUrl)); } } PsUrlIniFile.GetValue(DF_PSUD_URLINIKEY, DF_PSUD_URLINIVAL_ACCID, m_PsDownloadAccountId, DF_PSUD_ACCIDMAXLEN); // if (_T('\0') == m_PsDownloadAccountId[0]) { // return false; // } PsUrlIniFile.GetValue(DF_PSUD_URLINIKEY, DF_PSUD_URLINIVAL_PASS, m_PsDownloadPassword, DF_PSUD_PASSMAXLEN); // if (_T('\0') == m_PsDownloadPassword[0]) { // return false; // } } } m_IsOpen = true; return true; } bool CPsUpdater::LoadVersion() { DN_ASSERT(IsOpen(), "Not Opened!"); // ·ÎÄà Æú´õ¿¡ ¹öÀü ÆÄÀÏ Á¸Àç¿©ºÎ üũ (TRUE : ¾÷µ¥ÀÌÆ® üũ ½ÃÀÛ / FALSE : ³Ñ¾î°¨) TCHAR aCurPsVersion[DF_PSUD_VERSIONSIZE] = { _T('\0'), }; UINT64 aCurPsVersionNo = 0; { TCHAR aVersionFile[MAX_PATH] = { _T('\0'), }; { TCHAR aLocalPath[MAX_PATH] = { _T('\0'), }; TCHAR aFileName[MAX_PATH] = { _T('\0'), }; TCHAR aExecName[MAX_PATH] = { _T('\0'), }; TCHAR aDrvName[MAX_PATH] = { _T('\0'), }; TCHAR aDirName[MAX_PATH] = { _T('\0'), }; DWORD aRetVal1 = ::GetModuleFileName(NULL, aLocalPath, _countof(aLocalPath)); if (!aRetVal1) { // ¿À·ù ¹ß»ý return false; } errno_t aRetVal2 = _tsplitpath_s(aLocalPath, aDrvName, _countof(aDrvName), aDirName, _countof(aDirName), aFileName, _countof(aFileName), aExecName, _countof(aExecName)); if (aRetVal2) { // ¿À·ù ¹ß»ý return false; } _sntprintf_s(aVersionFile, _countof(aVersionFile), _T("%s%s%s"), aDrvName, aDirName, m_PsVersionFileName); if (_taccess_s(CVarArg(_T("%s"), aVersionFile), 0)) { // ÆÄÀÏ ¾øÀ½ return false; } } CStringSet aStringSet; { CFileSet aPsVersionFile; DWORD aRetVal = aPsVersionFile.Open(CVarArg(_T("%s"), aVersionFile)); if (NOERROR != aRetVal) { return false; } TCHAR aBuffer[DF_PSUD_TMPBUFFSIZE]; DWORD aBufferSize; // WHILE_INFINITE { for (;;) { USES_CONVERSION; ::memset(aBuffer, 0, sizeof(aBuffer)); aBufferSize = sizeof(aBuffer) - sizeof(TCHAR); aRetVal = aPsVersionFile.Read(static_cast(aBuffer), aBufferSize); if (ERROR_HANDLE_EOF == aRetVal) { // Àбâ Á¾·á break; } if (NOERROR != aRetVal) { // ¿À·ù ¹ß»ý return false; } if (0 < aBufferSize) { aStringSet += A2CT(reinterpret_cast(aBuffer)); } else { break; } } } { USES_CONVERSION; WORD aYear, aBuildNo; BYTE aMonth, aDay; bool aRetVal = ParseVersion(T2CA(aStringSet.Get(0)), aYear, aMonth, aDay, aBuildNo); if (!aRetVal) { // ¿À·ù ¹ß»ý return false; } aCurPsVersionNo = MAKELONGLONG(MAKELONG(aBuildNo, aDay), MAKELONG(aMonth, aYear)); } // ¹öÀü ¹®ÀÚ¿­¿¡ ºÒÇÊ¿äÇÑ ¹®ÀÚµé Á¦°Å { USES_CONVERSION; INT aStartPtr = 0; CStringSet aToken = aStringSet.Tokenize(_T("\n\r"), aStartPtr); if (aToken.IsEmpty()) { // ¿À·ù ¹ß»ý return false; } _tcsncpy_s(aCurPsVersion, _countof(aCurPsVersion), aToken.Get(0), _countof(aCurPsVersion)); } } if (_T('\0') == aCurPsVersion[0]) { return false; } _tcsncpy_s(m_CurPsVersion, _countof(m_CurPsVersion), aCurPsVersion, _countof(m_CurPsVersion)); m_CurPsVersionNo = aCurPsVersionNo; return true; } bool CPsUpdater::DoCheck() { DN_ASSERT(IsOpen(), "Not Opened!"); // DN_ASSERT(0 != m_CurPsVersion, "Invalid!"); // ¹öÀü ÆÄÀÏÀÌ Á¸ÀçÇÑ´Ù¸é ¿ø°ÝÁö ¹öÀü °æ·Î¿¡¼­ Ç÷£ ½º³À¼¦ ¹öÀü üũ TCHAR aNewPsVersion[DF_PSUD_VERSIONSIZE] = { _T('\0'), }; UINT64 aNewPsVersionNo = 0; { CHttpClient aHttpClient; aHttpClient.SetOption(200, 5*1000); BYTE aBuffer[DF_PSUD_TMPBUFFSIZE + sizeof(TCHAR)] = { 0, }; TCHAR aPsVersionFileUrl[MAX_PATH] = { _T('\0'), }; DWORD aPsVersionFileUrlSize = _countof(aPsVersionFileUrl); HRESULT aRetVal = ::UrlCombine(m_PsVersionFileUrl, m_PsVersionFileName, aPsVersionFileUrl, &aPsVersionFileUrlSize, 0); if (FAILED(aRetVal)) { return false; } if (TRUE == aHttpClient.Open(CVarArg(_T("%s"), aPsVersionFileUrl))) { INT iRetVal = 1; while (0 < iRetVal) { // ::memset(aBuffer, 0, sizeof(aBuffer)); // ÃßÈÄ¿¡ ::InternetReadFile() ÀÇ ÀÐÀº ¹ÙÀÌÆ® ¼ö ÂüÁ¶Çϵµ·Ï ¼öÁ¤ ÇÊ¿ä iRetVal = aHttpClient.RecvResponse(aBuffer, DF_PSUD_TMPBUFFSIZE); if (0 <= iRetVal) { // iRetVal - 0:¿Ï·á / 1:´õ¹ÞÀ»¼öÀÖÀ½ (*reinterpret_cast(&aBuffer[DF_PSUD_TMPBUFFSIZE])) = _T('\0'); } } if (iRetVal < 0) { // ¿À·ù ¹ß»ý return false; } { WORD aYear, aBuildNo; BYTE aMonth, aDay; bool aLocalRetVal = ParseVersion(reinterpret_cast(aBuffer), aYear, aMonth, aDay, aBuildNo); if (!aLocalRetVal) { // ¿À·ù ¹ß»ý return false; } aNewPsVersionNo = MAKELONGLONG(MAKELONG(aBuildNo, aDay), MAKELONG(aMonth, aYear)); } // ÀÌÀü ¹öÀü°ú ½Å±Ô ¹öÀü ºñ±³ if (m_CurPsVersionNo == aNewPsVersionNo) { return false; } // ¹öÀü ¹®ÀÚ¿­¿¡ ºÒÇÊ¿äÇÑ ¹®ÀÚµé Á¦°Å { USES_CONVERSION; CStringSet aStringSet = A2CT(reinterpret_cast(aBuffer)); INT aStartPtr = 0; CStringSet aToken = aStringSet.Tokenize(_T("\n\r"), aStartPtr); if (aToken.IsEmpty()) { // ¿À·ù ¹ß»ý return false; } _tcsncpy_s(aNewPsVersion, _countof(aNewPsVersion), aToken.Get(0), _countof(aNewPsVersion)); } } else { // ¿À·ù ¹ß»ý return false; } } if (_T('\0') == aNewPsVersion[0]) { return false; } _tcsncpy_s(m_NewPsVersion, _countof(m_NewPsVersion), aNewPsVersion, _countof(m_NewPsVersion)); m_NewPsVersionNo = aNewPsVersionNo; return true; } void CPsUpdater::DoUpdate(eNotifyType pNotifyType) { DN_ASSERT(IsOpen(), "Not Opened!"); // DN_ASSERT(0 != m_CurPsVersion, "Invalid!"); // DN_ASSERT(0 != m_NewPsVersion, "Invalid!"); TCHAR aLocalPath[MAX_PATH] = { _T('\0'), }; TCHAR aFileName[MAX_PATH] = { _T('\0'), }; TCHAR aExecName[MAX_PATH] = { _T('\0'), }; TCHAR aDrvName[MAX_PATH] = { _T('\0'), }; TCHAR aDirName[MAX_PATH] = { _T('\0'), }; // »ç¿ëÀÚ ¾Ë¸² ¸Þ½ÃÁö switch(pNotifyType) { case eNotifyTypeUpdate: // ¾÷µ¥ÀÌÆ® { // P.S.> ÇÁ·Î¼¼½º ½ÃÀÛ ½Ã ±âŸ ÀÚ¿øµé (*.DLL µîµî) ·Îµå ÀüÀ̶ó¸é ¾÷µ¥ÀÌÆ® °¡´É ::MessageBox( HWND_DESKTOP, CVarArg(_T("´ÙÀ½°ú °°Àº ¹öÀüÀÇ Ç÷£ ½º³À¼¦ÀÌ ¹ßÇàµÇ¾ú½À´Ï´Ù.\n\n¹öÀü : %s\n\n'È®ÀÎ' ¹öưÀ» ´©¸£½Ã¸é ÇØ´ç Ç÷£ ½º³À¼¦ ¾÷µ¥ÀÌÆ®°¡ ½ÃÀ۵Ǹç ÀÌÈÄ ¸®¼Ò½º Æú´õµµ º°µµ·Î ¾÷µ¥ÀÌÆ® ÇØÁֽñ⠹ٶø´Ï´Ù."), m_NewPsVersion), _T("Ç÷£ ½º³À¼¦ ¾÷µ¥ÀÌÆ® ¾È³»"), MB_ICONINFORMATION | MB_DEFBUTTON1 ); } break; case eNotifyTypeCheck: // ¹öÀüüũ { // P.S.> ÇÁ·Î¼¼½º ½ÇÇà Áß ±âŸ ÀÚ¿øµé (*.DLL µîµî) ·Îµå ÀÌÈĶó¸é Àç½ÃÀÛ ÇØ¼­ ¾÷µ¥ÀÌÆ® ¹Þ´Â °ÍÀÌ ¾ÈÀü ::MessageBox( HWND_DESKTOP, CVarArg(_T("´ÙÀ½°ú °°Àº ¹öÀüÀÇ Ç÷£ ½º³À¼¦ÀÌ ¹ßÇàµÇ¾ú½À´Ï´Ù.\n\n¹öÀü : %s\n\n'È®ÀÎ' ¹öưÀ» ´©¸£½Å ÈÄ ÇÁ·Î¼¼½º°¡ Á¾·áµÇ¸é Àç½ÃÀÛ ÇØÁֽñ⠹ٶø´Ï´Ù."), m_NewPsVersion), _T("Ç÷£ ½º³À¼¦ ¾÷µ¥ÀÌÆ® ¾È³»"), MB_ICONINFORMATION | MB_DEFBUTTON1 ); } return; default: return; // DN_RETURN_NONE; } // Ç÷£ ½º³À¼¦ ¹öÀüÀÌ ¼­·Î ´Þ¶ó¼­ ÆÐÄ¡°¡ ÇÊ¿äÇÏ´Ù¸é ÇöÀç ½ÇÇàÆÄÀÏ À̸§ º¯°æ { DWORD aRetVal1 = ::GetModuleFileName(NULL, aLocalPath, _countof(aLocalPath)); if (!aRetVal1) { // ¿À·ù ¹ß»ý return; } errno_t aRetVal2 = _tsplitpath_s(aLocalPath, aDrvName, _countof(aDrvName), aDirName, _countof(aDirName), aFileName, _countof(aFileName), aExecName, _countof(aExecName)); if (aRetVal2) { // ¿À·ù ¹ß»ý return; } TCHAR aSrcFile[MAX_PATH] = { _T('\0'), }; TCHAR aTgtFile[MAX_PATH] = { _T('\0'), }; _sntprintf_s(aSrcFile, _countof(aSrcFile), _T("%s%s%s%s"), aDrvName, aDirName, aFileName, aExecName); _sntprintf_s(aTgtFile, _countof(aTgtFile), _T("%s%s%s_%s%s"), aDrvName, aDirName, DF_PSUD_DELFILEPREP, aFileName, aExecName); CFileSet::Remove(aTgtFile); CFileSet::Rename(aSrcFile, aTgtFile); } // ³×Æ®¿öÅ© »óÀÇ Ç÷£ ½º³À»ñ È£½ºÆ®¿¡ ´ëÇÑ Á¢±Ù ±ÇÇÑ È¹µæ { NETRESOURCE stNetResource; stNetResource.dwScope = RESOURCE_GLOBALNET; stNetResource.dwType = RESOURCETYPE_ANY; stNetResource.dwDisplayType = RESOURCEDISPLAYTYPE_DOMAIN; stNetResource.dwUsage = RESOURCEUSAGE_CONNECTABLE; stNetResource.lpLocalName = 0; stNetResource.lpRemoteName = m_PsDownloadRootUrl; stNetResource.lpComment = 0; stNetResource.lpProvider = 0; DWORD aRetVal = ::WNetAddConnection2(&stNetResource, m_PsDownloadPassword, m_PsDownloadAccountId, CONNECT_UPDATE_PROFILE); if (NO_ERROR != aRetVal) { // ¿À·ù ¹ß»ý // return; } } /* // Ç÷£ ½º³À¼¦ÀÇ ÆÄÀϵéÀ» 'xcopy' ¸í·ÉÀ» ÀÌ¿ëÇÏ¿© ·ÎÄà Æú´õ·Î Àüü º¹»ç { TCHAR aSrcPath[MAX_PATH] = { _T('\0'), }; TCHAR aTgtPath[MAX_PATH] = { _T('\0'), }; _sntprintf_s(aSrcPath, _countof(aSrcPath), _T("%s\\%s"), DF_PSUD_SRCHOSTPATH, m_NewPsVersion); _sntprintf_s(aTgtPath, _countof(aTgtPath), _T("%s%s"), aDrvName, aDirName); { TCHAR aExecPath[MAX_PATH] = { _T('\0'), }; UINT aRetVal1 = ::GetSystemDirectory(aExecPath, _countof(aExecPath)); if (!aRetVal1) { // ¿À·ù ¹ß»ý return; } _sntprintf_s(aExecPath, _countof(aExecPath), _T("%s\\xcopy.exe \"%s\\*.*\" \"%s\" /Y /E /H /C /K /R"), aExecPath, aSrcPath, aTgtPath); // _sntprintf_s(aExecPath, _countof(aExecPath), _T("%s\\xcopy.exe \"%s\\*.*\" \"%s\" /Y /E /H /C /K /Q /R"), aExecPath, aSrcPath, aTgtPath); STARTUPINFO aStartupInfo; PROCESS_INFORMATION aProcessInformation; ::memset(&aStartupInfo, 0, sizeof(aStartupInfo)); aStartupInfo.cb = sizeof(aStartupInfo); ::memset(&aProcessInformation, 0, sizeof(aProcessInformation)); BOOL aRetVal = ::CreateProcess(NULL, aExecPath, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &aStartupInfo, &aProcessInformation); // BOOL aRetVal = ::CreateProcess(NULL, aExecPath, NULL, NULL, FALSE, 0, NULL, NULL, &aStartupInfo, &aProcessInformation); if (!aRetVal) { // ¿À·ù ¹ß»ý return; } ::WaitForSingleObject(aProcessInformation.hProcess, INFINITE); ::CloseHandle(aProcessInformation.hProcess); ::CloseHandle(aProcessInformation.hThread); } } */ TP_CONSOLEOUTPUT aConsoleOutput(new(std::nothrow) CConsoleOutput()); { BOOL aRetVal = static_cast(aConsoleOutput.get())->Initialize(NULL); if (!aRetVal) { // ¿À·ù ¹ß»ý } } // Ç÷£ ½º³À¼¦ÀÇ ÆÄÀÏ ¸ñ·ÏÀ» È®ÀÎÇÏ¿© ·ÎÄà Æú´õ·Î º¹»ç TP_COPYFAILLIST aCopyFailList; { TCHAR aPsDownloadFullUrl[MAX_PATH] = { _T('\0'), }; ::PathCombine(aPsDownloadFullUrl, m_PsDownloadPathUrl, m_NewPsVersion); DWORD aRetVal = CopyNewFile(aCopyFailList, aConsoleOutput, CVarArg(_T("%s"), aPsDownloadFullUrl), NULL); if (NOERROR != aRetVal) { // ¿À·ù ¹ß»ý } } if (!aCopyFailList.empty()) { // ¿À·ù ¹ß»ý _tstring aMsg = _T("Ç÷£ ½º³À¼¦ ¾÷µ¥ÀÌÆ® Áß ¾Æ·¡ÀÇ ÆÄÀÏ(µé)ÀÇ º¹»ç¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù.\n\n'È®ÀÎ' ¹öưÀ» ´©¸£½Ã¸é ÇØ´ç ¹öÀüÀÇ Ç÷£ ½º³À¼¦ Æú´õ°¡ ¿­¸®´Ï ¼öµ¿À¸·Î º¹»çÇϽŠÈÄ ¸®¼Ò½º Æú´õµµ º°µµ·Î ¾÷µ¥ÀÌÆ® ÇØÁֽñ⠹ٶø´Ï´Ù.\n\n"); TP_COPYFAILLIST_CTR aIt = aCopyFailList.begin(); for (; aCopyFailList.end() != aIt ; ++aIt) { aMsg += (_T("[") + (*(aIt)) + _T("]\n")); } ::MessageBox( HWND_DESKTOP, aMsg.c_str(), _T("Ç÷£ ½º³À¼¦ ¾÷µ¥ÀÌÆ® ½ÇÆÐ"), MB_ICONWARNING | MB_DEFBUTTON1 ); // Ç÷£ ½º³À¼¦ Æú´õ °³¹æ { TCHAR aEnvVar[32767] = { _T('\0'), }; GetEnvironmentVariable(_T("ProgramFiles"), aEnvVar, _countof(aEnvVar)); TCHAR aIEPath[MAX_PATH] = { _T('\0'), }; { long lRet; HKEY hKey; lRet = ::RegOpenKey(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\IExplore.exe"), &hKey); if (lRet == ERROR_SUCCESS) { long cbData = _countof(aIEPath); ::RegQueryValue(hKey, _T(""), aIEPath, &cbData); ::RegCloseKey(hKey); } else { // ¿À·ù ¹ß»ý return; } } TCHAR aPsDownloadFullUrl[MAX_PATH] = { _T('\0'), }; ::PathCombine(aPsDownloadFullUrl, m_PsDownloadPathUrl, m_NewPsVersion); HINSTANCE aRetVal = ::ShellExecute(HWND_DESKTOP, _T("open"), aIEPath, aPsDownloadFullUrl, NULL, SW_SHOWNORMAL); if (32 >= PtrToInt(aRetVal)) { // ¿À·ù ¹ß»ý return; } } } // ³×Æ®¿öÅ© »óÀÇ Ç÷£ ½º³À»ñ È£½ºÆ®¿¡ ´ëÇÑ Á¢±Ù ±ÇÇÑ ÇØÁ¦ { DWORD aRetVal = ::WNetCancelConnection2(m_PsDownloadRootUrl, CONNECT_UPDATE_PROFILE, TRUE); if (NO_ERROR != aRetVal) { // ¿À·ù ¹ß»ý // return; } } _tcsncpy_s(m_CurPsVersion, _countof(m_CurPsVersion), m_NewPsVersion, _countof(m_CurPsVersion)); m_CurPsVersionNo = m_NewPsVersionNo; } bool CPsUpdater::ParseVersion(LPCSTR pPsVersion, WORD& pYear, BYTE& pMonth, BYTE& pDay, WORD& pBuildNo) { DN_ASSERT(IsOpen(), "Not Opened!"); USES_CONVERSION; CStringSet aStringSet = A2CT(pPsVersion); if (aStringSet.IsEmpty()) { return false; } INT aStartPtr = 0; CStringSet aToken = aStringSet.Tokenize(_T(".\n\r"), aStartPtr); if (aToken.IsEmpty() || !aToken.IsNumeric()) { return false; } pYear = _ttoi(aToken.Get(0)); aToken = aStringSet.Tokenize(_T(".\n\r"), aStartPtr); if (aToken.IsEmpty() || !aToken.IsNumeric()) { return false; } pMonth = _ttoi(aToken.Get(0)); aToken = aStringSet.Tokenize(_T(".\n\r"), aStartPtr); if (aToken.IsEmpty() || !aToken.IsNumeric()) { return false; } pDay = _ttoi(aToken.Get(0)); aToken = aStringSet.Tokenize(_T(".\n\r"), aStartPtr); if (aToken.IsEmpty() || !aToken.IsNumeric()) { return false; } pBuildNo = _ttoi(aToken.Get(0)); return true; } DWORD CPsUpdater::DeleteOldFile(LPCTSTR pLocalPath) { TCHAR aLocalPath[MAX_PATH] = { _T('\0'), }; TCHAR aDrvName[MAX_PATH] = { _T('\0'), }; TCHAR aDirName[MAX_PATH] = { _T('\0'), }; if (!pLocalPath) { DWORD aRetVal1 = ::GetModuleFileName(NULL, aLocalPath, _countof(aLocalPath)); if (!aRetVal1) { // ¿À·ù ¹ß»ý return(HASERROR+0); } errno_t aRetVal2 = _tsplitpath_s(aLocalPath, aDrvName, _countof(aDrvName), aDirName, _countof(aDirName), NULL, 0, NULL, 0); if (aRetVal2) { // ¿À·ù ¹ß»ý return(HASERROR+0); } _sntprintf_s(aLocalPath, _countof(aLocalPath), _T("%s%s"), aDrvName, aDirName); } else { _tcsncpy_s(aLocalPath, _countof(aLocalPath), pLocalPath, _countof(aLocalPath)); } ::PathAddBackslash(aLocalPath); { CDirectory aDirectory; DWORD aRetVal1 = aDirectory.Begin(CVarArg(_T("%s*.*"), aLocalPath)); // DWORD aRetVal1 = aDirectory.Begin(CVarArg(_T("%s%s*.*"), aLocalPath, DF_PSUD_DELFILEPREP)); if (NOERROR != aRetVal1) { // ¿À·ù ¹ß»ý return(aRetVal1); } while(NOERROR == aRetVal1) { if (aDirectory.IsDirectory()) { // µð·ºÅ丮 if (_T('.') != aDirectory.GetFindData().cFileName[0]) { DWORD aRetVal2 = DeleteOldFile(CVarArg(_T("%s%s"), aLocalPath, aDirectory.GetFindData().cFileName)); if (NOERROR != aRetVal2) { // return aRetVal2; // P.S.> »èÁ¦ ½Ã ¿À·ù°¡ ¹ß»ýÇÑ ÆÄÀÏÀº ³Ñ¾î°¡°í Áö¿ï ¼ö ÀÖ´Â ¸¸Å­ ÃÖ´ëÇÑ Áö¿ò } } } else { // ÆÄÀÏ if (_tcsstr(aDirectory.GetFindData().cFileName, DF_PSUD_DELFILEPREP)) { CFileSet::Remove(CVarArg(_T("%s%s"), aLocalPath, aDirectory.GetFindData().cFileName)); } } aRetVal1 = aDirectory.Next(); if (NOERROR != aRetVal1 && ERROR_NO_MORE_FILES != aRetVal1) { // ¿À·ù ¹ß»ý aDirectory.End(); return(aRetVal1); } } aDirectory.End(); } return NOERROR; } DWORD CPsUpdater::CopyNewFile(TP_COPYFAILLIST& pCopyFailList, TP_CONSOLEOUTPUT& pConsoleOutput, LPCTSTR pRemotePath, LPCTSTR pLocalPath) { DN_ASSERT(IsOpen(), "Not Opened!"); DN_ASSERT(NULL != pRemotePath, "Invalid!"); TCHAR aRemotePath[MAX_PATH] = { _T('\0'), }; TCHAR aLocalPath[MAX_PATH] = { _T('\0'), }; TCHAR aDrvName[MAX_PATH] = { _T('\0'), }; TCHAR aDirName[MAX_PATH] = { _T('\0'), }; _tcsncpy_s(aRemotePath, _countof(aRemotePath), pRemotePath, _countof(aRemotePath)); ::PathAddBackslash(aRemotePath); if (!pLocalPath) { DWORD aRetVal1 = ::GetModuleFileName(NULL, aLocalPath, _countof(aLocalPath)); if (!aRetVal1) { // ¿À·ù ¹ß»ý return(HASERROR+0); } errno_t aRetVal2 = _tsplitpath_s(aLocalPath, aDrvName, _countof(aDrvName), aDirName, _countof(aDirName), NULL, 0, NULL, 0); if (aRetVal2) { // ¿À·ù ¹ß»ý return(HASERROR+0); } _sntprintf_s(aLocalPath, _countof(aLocalPath), _T("%s%s"), aDrvName, aDirName); } else { _tcsncpy_s(aLocalPath, _countof(aLocalPath), pLocalPath, _countof(aLocalPath)); } ::PathAddBackslash(aLocalPath); // ¿ø°ÝÁö ÆÄÀÏ ¸ñ·Ï ¼øÈ¸ { CDirectory aDirectory; DWORD aRetVal1 = aDirectory.Begin(CVarArg(_T("%s*.*"), aRemotePath)); if (NOERROR != aRetVal1) { // ¿À·ù ¹ß»ý return(aRetVal1); } while(NOERROR == aRetVal1) { if (aDirectory.IsDirectory()) { // µð·ºÅ丮 if (_T('.') != aDirectory.GetFindData().cFileName[0]) { DWORD aRetVal2 = CopyNewFile(pCopyFailList, pConsoleOutput, CVarArg(_T("%s%s"), aRemotePath, aDirectory.GetFindData().cFileName), CVarArg(_T("%s%s"), aLocalPath, aDirectory.GetFindData().cFileName)); if (NOERROR != aRetVal2) { // return aRetVal2; } } } else { // ÆÄÀÏ BOOL aRetVal2 = TRUE; // ·ÎÄà ÆÄÀÏ È®ÀÎ ¹× À̸§ º¯°æ (DF_PSUD_VERSIONFILE Á¦¿Ü) if (!_tcsicmp(aDirectory.GetFindData().cFileName, m_PsVersionFileName)) { aRetVal2 = FALSE; } if (aRetVal2 && !_taccess_s(CVarArg(_T("%s%s"), aLocalPath, aDirectory.GetFindData().cFileName), 0)) { // ÆÄÀÏ ÀÖÀ½ aRetVal2 = CFileSet::Rename(CVarArg(_T("%s%s"), aLocalPath, aDirectory.GetFindData().cFileName), CVarArg(_T("%s%s_%s"), aLocalPath, DF_PSUD_DELFILEPREP, aDirectory.GetFindData().cFileName)); if (!aRetVal2) { // return(HASERROR+0); } } // ¿ø°ÝÁö ÆÄÀÏ º¹»ç { aRetVal2 = CFileSet::Copy(CVarArg(_T("%s%s"), aRemotePath, aDirectory.GetFindData().cFileName), CVarArg(_T("%s%s"), aLocalPath, aDirectory.GetFindData().cFileName), FALSE); if (!aRetVal2) { pCopyFailList.push_back(aDirectory.GetFindData().cFileName); // return(HASERROR+0); // P.S.> º¹»ç ½Ã ¿À·ù°¡ ¹ß»ýÇÏ¸é »ç¿ëÀÚ¿¡°Ô ÇØ´ç »ç½ÇÀ» ¾Ë¸®°í ¼öµ¿ º¹»çÇÒ ¼ö ÀÖµµ·Ï Áö¿øÇØ¾ß ÇÔ !!! static_cast(pConsoleOutput.get())->Write(CVarArg(_T("Copy (Fail) : %s%s\n"), aLocalPath, aDirectory.GetFindData().cFileName)); } else { static_cast(pConsoleOutput.get())->Write(CVarArg(_T("Copy (Succeed) : %s%s\n"), aLocalPath, aDirectory.GetFindData().cFileName)); } } } aRetVal1 = aDirectory.Next(); if (NOERROR != aRetVal1 && ERROR_NO_MORE_FILES != aRetVal1) { // ¿À·ù ¹ß»ý aDirectory.End(); return(aRetVal1); } } aDirectory.End(); } return NOERROR; } void CPsUpdater::AsyncUpdate() { // ±âÁ¸ÆÄÀÏ »èÁ¦ this->DeleteOldFile(); // ¾÷µ¥ÀÌÆÃ ¿©ºÎ È®ÀÎ if (m_IsUpdate) return; if (!Open()) { #if !defined(_WORK) g_Log.Log(LogType::_ERROR, L"¾÷µ¥ÀÌÆ® Áغñ¿¡ ½ÇÆÐÇß½À´Ï´Ù.\n"); #endif return; } if (!LoadVersion()) { g_Log.Log(LogType::_ERROR, L"¾÷µ¥ÀÌÆ®Áß ¹öÁ¯Àб⿡ ½ÇÆÐÇÏ¿´½À´Ï´Ù. \n"); return; } // ÀÎÅÍ³Ý °ü·ÃÇÔ¼ö È£Ãâ(ºñµ¿±â) ExecInternetFunc(); } void CPsUpdater::ExecInternetFunc() { // ÇØ´ç Url ¸¸µé±â TCHAR aPsVersionFileUrl[MAX_PATH] = { _T('\0'), }; DWORD aPsVersionFileUrlSize = _countof(aPsVersionFileUrl); HRESULT aRetVal = ::UrlCombine(m_PsVersionFileUrl, m_PsVersionFileName, aPsVersionFileUrl, &aPsVersionFileUrlSize, 0); if (FAILED(aRetVal)) { g_Log.Log(LogType::_ERROR, L"¾÷µ¥ÀÌÆ® URL »ý¼º ½ÇÆÐ\n"); return; } m_hInternet = ::InternetOpen(_T("Microsoft Internet Explorer"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC); if (!m_hInternet) return; // ºñµ¿±â È£ÃâÀ» À§ÇÑ ÄݹéÇÔ¼ö ¼³Á¤ ::InternetSetStatusCallback(m_hInternet, (INTERNET_STATUS_CALLBACK)&Internet_Status_Callback); // Url ¿ÀÇ m_hInternetConnection = InternetOpenUrl (m_hInternet, aPsVersionFileUrl, NULL, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_CACHE_WRITE, (DWORD_PTR) this); if( m_hInternetConnection == NULL ) { DWORD Error=GetLastError(); if( Error != WSA_IO_PENDING ) { InternetCloseHandle(m_hInternet); m_hInternet = NULL; } } } void __stdcall Internet_Status_Callback(HINTERNET hSession, DWORD Context, DWORD Status, LPVOID pInformation, DWORD InfoLength) { static HINTERNET hInternetConnection; static DWORD dwNumberOfBytesAvailable = 0; switch (Status) { case INTERNET_STATUS_RESPONSE_RECEIVED: dwNumberOfBytesAvailable = (*(DWORD *)pInformation); break; case INTERNET_STATUS_HANDLE_CREATED: hInternetConnection = * (HINTERNET *) pInformation; break; case INTERNET_STATUS_REQUEST_COMPLETE: { LPBYTE pVersionBuff = new BYTE[dwNumberOfBytesAvailable]; ZeroMemory(pVersionBuff, dwNumberOfBytesAvailable); DWORD dwBytesRead(0); BOOL bRef(TRUE); while (bRef) { bRef = InternetReadFile (hInternetConnection, pVersionBuff, dwNumberOfBytesAvailable, &dwBytesRead); if (!dwBytesRead) bRef = FALSE; } g_PsUpdater->UpdateProcess(pVersionBuff); if (g_PsUpdater) { g_PsUpdater->Close(); SAFE_DELETE(g_PsUpdater); } delete [] pVersionBuff; } break; default: break; } } void CPsUpdater::UpdateProcess(LPBYTE pVersionBuff) { TCHAR aNewPsVersion[DF_PSUD_VERSIONSIZE] = { _T('\0'), }; UINT64 aNewPsVersionNo = 0; // ¹öÀüµ¥ÀÌÅÍ ÆÄ½Ì { WORD aYear, aBuildNo; BYTE aMonth, aDay; bool aLocalRetVal = ParseVersion(reinterpret_cast(pVersionBuff), aYear, aMonth, aDay, aBuildNo); if (!aLocalRetVal) { // ¿À·ù ¹ß»ý return; } aNewPsVersionNo = MAKELONGLONG(MAKELONG(aBuildNo, aDay), MAKELONG(aMonth, aYear)); } // ¹öÀü ¹®ÀÚ¿­¿¡ ºÒÇÊ¿äÇÑ ¹®ÀÚµé Á¦°Å { USES_CONVERSION; CStringSet aStringSet = A2CT(reinterpret_cast(pVersionBuff)); INT aStartPtr = 0; CStringSet aToken = aStringSet.Tokenize(_T("\n\r"), aStartPtr); if (aToken.IsEmpty()) { // ¿À·ù ¹ß»ý return; } _tcsncpy_s(aNewPsVersion, _countof(aNewPsVersion), aToken.Get(0), _countof(aNewPsVersion)); } // ÀÌÀü ¹öÀü°ú ½Å±Ô ¹öÀü ºñ±³ if (m_CurPsVersionNo == aNewPsVersionNo) { return; } if (_T('\0') == aNewPsVersion[0]) { return; } _tcsncpy_s(m_NewPsVersion, _countof(m_NewPsVersion), aNewPsVersion, _countof(m_NewPsVersion)); m_NewPsVersionNo = aNewPsVersionNo; g_Log.Log(LogType::_NORMAL, L"¾÷µ¥ÀÌÆ® ÁغñÁßÀÔ´Ï´Ù\n"); if (!g_PsUpdater) { g_Log.Log(LogType::_ERROR, L"¾÷µ¥ÀÌÆ®°¡ ¿øÈ°ÇÏÁö ¾Ê½À´Ï´Ù.\n"); return; } // ¹öÁ¯ üũ ¿Ï·áÈÄ ¾÷µ¥ÀÌÆ®ÇÑ´Ù. m_IsUpdate = true; g_Log.Log(LogType::_NORMAL, L"¾÷µ¥ÀÌÆ®¸¦ ½ÃÀÛÇÕ´Ï´Ù\n"); DoUpdate(CPsUpdater::eNotifyTypeUpdate); g_PsUpdater->Close(); SAFE_DELETE(g_PsUpdater); ::ExitProcess(0); }