// ManualPatchPage.cpp : ±¸Çö ÆÄÀÏÀÔ´Ï´Ù. // #include "stdafx.h" #include "PatchMaker.h" #include "ManualPatchPage.h" #include "UtilityFunc.h" #include "PMSetting.h" #include "PMSettingConstant.h" #include "atlenc.h" #include #include #include ".\manualpatchpage.h" // CManualPatchPage ´ëÈ­ »óÀÚÀÔ´Ï´Ù. IMPLEMENT_DYNAMIC(CManualPatchPage, CPropertyPage) CManualPatchPage::CManualPatchPage(CPMSetting& pmSetting, DWORD dwPatchVersion) : CPropertyPage(CManualPatchPage::IDD) , m_szMPFolder(_T("")) , m_szMPSFXFile(_T("")) , m_szMPFileName(_T("")) , m_dwMPMinver(0) , m_dwMPMaxver(dwPatchVersion) , m_szPatchType(_T("")) , m_szFileProgress(_T("0/0")) , m_pmSettingOption(pmSetting) , m_hManualPatchThread(0) { m_ProgressData.m_bStopWorkerThread = FALSE; m_ProgressData.m_nTotalFiles = 0; m_ProgressData.m_nAddedFiles = 0; m_ProgressData.m_dwTotalFileSize = 0LL; m_ProgressData.m_dwCurrentFileSize = 0LL; } CManualPatchPage::~CManualPatchPage() { } void CManualPatchPage::DoDataExchange(CDataExchange* pDX) { CPropertyPage::DoDataExchange(pDX); DDX_Text(pDX, IDC_ED_MP_MANUAL_PATCH_FILE, m_szMPFolder); DDX_Text(pDX, IDC_ED_MP_MANUAL_SFX_FILE, m_szMPSFXFile); DDX_Text(pDX, IDC_ED_MP_PATCH_FILE_NAME, m_szMPFileName); DDX_Text(pDX, IDC_ED_MP_MIN_VER, m_dwMPMinver); DDX_Text(pDX, IDC_ED_MP_CUR_VER, m_dwMPMaxver); DDX_Text(pDX, IDC_ED_MP_PATCH_TYPE, m_szPatchType); DDX_Control(pDX, IDC_ED_MP_CONSOLE, m_edProgressLog); DDX_Control(pDX, IDC_PRG_MP, m_TotalProgressBar); DDX_Control(pDX, IDC_ED_MP_ERR_CONSOLE, m_edErrLog); DDX_Text(pDX, IDC_ST_MP_PRORGRESS, m_szFileProgress); } BEGIN_MESSAGE_MAP(CManualPatchPage, CPropertyPage) ON_BN_CLICKED(ID_MP_CREATE, OnBnClickedMpCreate) ON_BN_CLICKED(ID_MP_CANCEL, OnBnClickedMpCancel) ON_BN_CLICKED(IDC_BTN_MP_SELECT_FILE, OnBnClickedBtnMpSelectFile) ON_WM_CREATE() ON_WM_TIMER() ON_WM_CLOSE() ON_BN_CLICKED(IDC_CLEAR_LOG, OnBnClickedClearLog) END_MESSAGE_MAP() // CManualPatchPage ¸Þ½ÃÁö 󸮱âÀÔ´Ï´Ù. struct MPWorkerData { CManualPatchPage* m_lpPage; CString m_szMPFolder; CString m_szMPSFXFile; CString m_szMPFileName; CString m_szPatchType; DWORD m_dwMPMaxver; DWORD m_dwMPMinver; }; void CManualPatchPage::UpdateManualPatchStatus(MPProgressData& progressData) { //! MANUAL_PATCH_LOCK m_ProgressLock.Lock(); // µ¥ÀÌÅ͸¦ °»½ÅÇÑ´Ù progressData.m_bStopWorkerThread = m_ProgressData.m_bStopWorkerThread; m_ProgressData.m_nTotalFiles = progressData.m_nTotalFiles; m_ProgressData.m_nAddedFiles = progressData.m_nAddedFiles; m_ProgressData.m_dwCurrentFileSize = progressData.m_dwCurrentFileSize; m_ProgressData.m_dwTotalFileSize = progressData.m_dwTotalFileSize; m_ProgressData.m_ProgressList.AddTail(&progressData.m_ProgressList); m_ProgressData.m_ErrorList.AddTail(&progressData.m_ErrorList); m_ProgressData.m_TotalProgressList.AddTail((&progressData.m_TotalProgressList)); //! MANUAL_PATCH_UNLOCK m_ProgressLock.Unlock(); progressData.m_ProgressList.RemoveAll(); progressData.m_ErrorList.RemoveAll(); } template bool EnumerateAllLeafFiles(FnProcess fnProcess, LPCTSTR lpRootPath) { CString szTemp; CList dirStack; CFileFind fileFind; szTemp.SetString(lpRootPath); szTemp.Trim(); int nLength = szTemp.GetLength(); // µÚ¿¡ \\*.* ȤÀº *.*¸¦ ºÙ¿© ÁØ´Ù. szTemp.Append( (1 < nLength && _T('\\') != szTemp.GetString()[nLength - 1]) ? _T("\\*.*") : _T("*.*")); dirStack.AddTail(szTemp); BOOL bWorking = FALSE; while(!dirStack.IsEmpty()) { szTemp.SetString(dirStack.RemoveTail()); if (bWorking = fileFind.FindFile(szTemp)) { while(bWorking) { bWorking = fileFind.FindNextFile(); if (!fileFind.IsDots()) { szTemp.SetString(fileFind.GetFilePath()); if (fileFind.IsDirectory()) { // Æú´õÀÎ °æ¿ì szTemp.Append(_T("\\*.*")); dirStack.AddTail(szTemp); } // vssver.scc´Â Æ÷ÇÔ ¾È ÇÔ else if(0 != szTemp.CompareNoCase(_T("vssver.scc")) && !fnProcess(fileFind)) { // ÀÛ¾÷À» Ãë¼ÒÇÏ¿´À½ return false; } } } } else { return false; } } return true; } class CGetTotalFileNumAndSize { public: CGetTotalFileNumAndSize(ULONGLONG& dwTotalFileSize, int& nTotalFileNum) : m_dwTotalFileSize(dwTotalFileSize) , m_nTotalFileNum(nTotalFileNum) { } bool operator () (const CFileFind& fileFind) { m_dwTotalFileSize += fileFind.GetLength(); ++m_nTotalFileNum; return true; } private: ULONGLONG& m_dwTotalFileSize; int& m_nTotalFileNum; }; class CCompressFiles { public: CCompressFiles( CManualPatchPage& mpPage, MPProgressData& progressData, CZipArchive& zipArchive, CString& szErrorString) : m_MPPage(mpPage) , m_ProgressData(progressData) , m_ZipArchive(zipArchive) , m_szErrorString(szErrorString) { } bool operator () (const CFileFind& fileFind) { // ÆÄÀÏÀ» ¾ÐÃàÇØ¼­ Ãß°¡ÇÑ´Ù. m_szFileName = fileFind.GetFilePath(); // ÆÄÀÏ ¼Ó¼ºÀ» ±âº» ¼Ó¼ºÀ¸·Î ¹Ù²Þ SetFileAttributes(m_szFileName, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE); if (m_ZipArchive.AddNewFile(m_szFileName, Z_BEST_COMPRESSION, false)) { // µ¥ÀÌÅ͸¦ °»½ÅÇÑ´Ù. ULONGLONG dwFileSize = fileFind.GetLength(); m_ProgressData.m_dwCurrentFileSize += dwFileSize; ++m_ProgressData.m_nAddedFiles; PMUtil::SetCurrentTime(m_szErrorString); m_szErrorString.AppendFormat(_T("ÆÄÀÏ Ãß°¡ : %s"), m_szFileName); m_ProgressData.m_ProgressList.AddTail(m_szErrorString); } else { // ¿¡·¯ ·Î±×¸¦ ³²±ä´Ù. DWORD dwError = GetLastError(); PMUtil::SetCurrentTime(m_szErrorString); m_szErrorString.AppendFormat(_T("ÀÛ¾÷ ½ÇÆÐ : %s : "), m_szFileName); PMUtil::AppendErrorMessage(m_szErrorString, dwError); m_ProgressData.m_ErrorList.AddTail(m_szErrorString); } // µ¥ÀÌÅ͸¦ ¾÷µ¥ÀÌÆ®ÇÑ´Ù. m_MPPage.UpdateManualPatchStatus(m_ProgressData); return (FALSE == m_ProgressData.m_bStopWorkerThread); } private: CManualPatchPage& m_MPPage; MPProgressData& m_ProgressData; CZipArchive& m_ZipArchive; CString& m_szErrorString; CString m_szFileName; }; unsigned __stdcall CManualPatchPage::ManualPatchWorker(void* pArg) { MPWorkerData* lpWorkerData = reinterpret_cast(pArg); CManualPatchPage* lpPage = lpWorkerData->m_lpPage; // µ¥ÀÌÅÍ Á¤ÀÇ CZipArchive zipArchive; CString szSFXFileName; CString szZipFileName; CString szErrorString; const int MAX_ERROR_LEN = 256; TCHAR szErrorMsg[MAX_ERROR_LEN]; MPProgressData progressData; progressData.m_bStopWorkerThread = FALSE; progressData.m_dwTotalFileSize = 0LL; progressData.m_dwCurrentFileSize = 0LL; progressData.m_nTotalFiles = 0; progressData.m_nAddedFiles = 0; szSFXFileName.SetString(lpWorkerData->m_szMPFileName); szZipFileName.SetString(lpWorkerData->m_szMPFileName); int nPos = szZipFileName.ReverseFind(_T('.')); if (0 < nPos) { szZipFileName.Truncate(nPos); szZipFileName.Append(_T(".zip"), nPos); } // Àüü ÆÄÀÏ °³¼ö ¹× ÆÄÀÏ ¿ë·®À» °è»êÇÑ´Ù. if (!EnumerateAllLeafFiles(CGetTotalFileNumAndSize( progressData.m_dwTotalFileSize, progressData.m_nTotalFiles), lpWorkerData->m_szMPFolder)) { DWORD dwError = GetLastError(); PMUtil::SetCurrentTime(szErrorString); if (progressData.m_bStopWorkerThread) { szErrorString.AppendFormat(_T("ÀÛ¾÷ ½ÇÆÐ : ÀÛ¾÷À» Ãë¼ÒÇÏ¿´½À´Ï´Ù")); } else { szErrorString.AppendFormat(_T("ÀÛ¾÷ ½ÇÆÐ : ¾ÐÃàÇÒ ÆÄÀÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù : ")); PMUtil::AppendErrorMessage(szErrorString, dwError); } progressData.m_ErrorList.AddTail(szErrorString); progressData.m_TotalProgressList.AddTail(szErrorString); } else { TRY { bool bSucceededJob = false; zipArchive.Open(szZipFileName, CZipArchive::zipCreate); zipArchive.SetRootPath(lpWorkerData->m_szMPFolder); // ÆÄÀÏÀ» Ãß°¡/¾ÐÃàÇÑ´Ù. ¿¡·¯ ·Î±×´Â ³»ºÎ¿¡¼­ ³²±ä´Ù. if (!EnumerateAllLeafFiles( CCompressFiles(*lpPage, progressData, zipArchive, szErrorString), lpWorkerData->m_szMPFolder)) { DWORD dwError = GetLastError(); PMUtil::SetCurrentTime(szErrorString); if (progressData.m_bStopWorkerThread) { szErrorString.AppendFormat(_T("ÀÛ¾÷ ½ÇÆÐ : ÀÛ¾÷À» Ãë¼ÒÇÏ¿´½À´Ï´Ù")); } else { szErrorString.AppendFormat(_T("ÀÛ¾÷ ½ÇÆÐ : ¾ÐÃàÇÒ ÆÄÀÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù : ")); PMUtil::AppendErrorMessage(szErrorString, dwError); } progressData.m_ErrorList.AddTail(szErrorString); progressData.m_TotalProgressList.AddTail(szErrorString); } else { /* TODO : ÇÊ¿äÇÑ µ¥ÀÌÅ͸¦ Ã߸®°í, BASE64ÀÎÄÚµùÀ» ÇÑ ÈÄ Comment¿¡ ¾¥¼Å ¹Ú´Â´Ù. ÇÊ¿ä µ¥ÀÌÅÍ 1. ¾ÐÃà Àü ¿ë·® : µð½ºÅ© ¿ë·® üũ 2. ÃÖ¼Ò¹öÀü : ±ò¸± À§Ä¡¿¡ Ŭ¶óÀÌ¾ðÆ®°¡ ÀÖ´Ù¸é, ÃÖ¼Ò¹öÀüÀ» üũÇÑ´Ù. 3. ÆÐÄ¡¹öÀü : ±ò¸± À§Ä¡¿¡ Ŭ¶óÀÌ¾ðÆ®°¡ ÀÖ´Ù¸é, ÇöÀç ¹öÀüÀ» Ã¼Å©ÇØ¼­ ´õ ³ôÀº°¡ È®ÀÎÇÑ´Ù. 4. ±âº»À¸·Î Àоî¿Ã ·¹Áö½ºÆ®¸® À§Ä¡ */ CMemFile srcData; srcData.Write(&progressData.m_dwTotalFileSize, sizeof(progressData.m_dwTotalFileSize)); // ÆÐÄ¡ ŸÀÔ¿¡ µû¶ó¼­ ¹öÀüÀ» ´Ù½Ã ¼¼ÆÃ. PMConst::AdjustVersionInfoByPatchType(lpWorkerData->m_szPatchType, lpWorkerData->m_dwMPMinver, lpWorkerData->m_dwMPMaxver); srcData.Write(&lpWorkerData->m_dwMPMinver, sizeof(lpWorkerData->m_dwMPMinver)); srcData.Write(&lpWorkerData->m_dwMPMaxver, sizeof(lpWorkerData->m_dwMPMaxver)); int nInstalledPathLen = 0; int nValueNameLen = 0; CString szInstalledPath, szValueName; if (PMConst::GetRYLInstalledRegKey( lpWorkerData->m_szPatchType, szInstalledPath, szValueName)) { nInstalledPathLen = szInstalledPath.GetLength(); nValueNameLen = szValueName.GetLength(); srcData.Write(&nInstalledPathLen, sizeof(nInstalledPathLen)); srcData.Write(&nValueNameLen, sizeof(nValueNameLen)); srcData.Write(szInstalledPath.GetString(), nInstalledPathLen * sizeof(TCHAR)); srcData.Write(szValueName.GetString(), nValueNameLen * sizeof(TCHAR)); } else { srcData.Write(&nInstalledPathLen, sizeof(nInstalledPathLen)); srcData.Write(&nValueNameLen, sizeof(nValueNameLen)); } int nSrcLen = static_cast(srcData.GetLength()); int nDstLen = Base64EncodeGetRequiredLength(nSrcLen); LPSTR lpEncodedData = (LPSTR)malloc(sizeof(CHAR) * (nDstLen + 1)); if (0 != lpEncodedData) { BYTE* lpSrcData = srcData.Detach(); if (Base64Encode(lpSrcData, nSrcLen, lpEncodedData, &nDstLen)) { lpEncodedData[nDstLen] = (CHAR)0; bSucceededJob = zipArchive.SetGlobalComment(lpEncodedData); } free(lpSrcData); free(lpEncodedData); } } zipArchive.Close(); if (!progressData.m_bStopWorkerThread) { PMUtil::SetCurrentTime(szErrorString); szErrorString.AppendFormat(_T("¼öµ¿ÆÐÄ¡ ÀÛ¾÷ : ¾ÐÃàÀ» ¿Ï·áÇÏ¿´½À´Ï´Ù. SFXÆÄÀÏÀ» »ý¼ºÇÏ´Â ÁßÀÔ´Ï´Ù..")); progressData.m_ProgressList.AddTail(szErrorString); lpPage->UpdateManualPatchStatus(progressData); if (!bSucceededJob) { PMUtil::SetCurrentTime(szErrorString); szErrorString.AppendFormat(_T("¼öµ¿ÆÐÄ¡ ÀÛ¾÷ ½ÇÆÐ : ¼öµ¿ÆÐÄ¡ µ¥ÀÌÅ͸¦ Comment·Î ³²±â´Â µ¥ ½ÇÆÐÇß½À´Ï´Ù")); progressData.m_ErrorList.AddTail(szErrorString); } else { // SFXÇì´õ¸¦ ºÙ¿©¼­ ÆÄÀÏÀ» Çϳª ´õ ¸¸µç´Ù. CFile sfxFile, zipFile, resultFile; PMUtil::SetCurrentTime(szErrorString); if (!sfxFile.Open(lpWorkerData->m_szMPSFXFile, CFile::modeRead | CFile::shareDenyWrite | CFile::typeBinary)) { szErrorString.AppendFormat(_T("¼öµ¿ÆÐÄ¡ ÀÛ¾÷ ½ÇÆÐ : SFXÆÄÀÏ %s¸¦ Àбâ À§ÇØ ¿©´Â µ¥ ½ÇÆÐÇß½À´Ï´Ù"), lpWorkerData->m_szMPSFXFile); } else if(!zipFile.Open(szZipFileName, CFile::modeRead | CFile::shareDenyWrite | CFile::typeBinary)) { szErrorString.AppendFormat( _T("¼öµ¿ÆÐÄ¡ ÀÛ¾÷ ½ÇÆÐ : ZIPÆÄÀÏ %s¸¦ Àбâ À§ÇØ ¿©´Â µ¥ ½ÇÆÐÇß½À´Ï´Ù"), szZipFileName); } else if(!resultFile.Open(szSFXFileName, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite | CFile::typeBinary)) { szErrorString.AppendFormat( _T("¼öµ¿ÆÐÄ¡ ÀÛ¾÷ ½ÇÆÐ : ¼öµ¿ÆÐÄ¡ ÆÄÀÏ %s¸¦ ¾²±â À§ÇØ ¿©´Â µ¥ ½ÇÆÐÇß½À´Ï´Ù"), szSFXFileName); } else { const int MAX_FILE_BUFFER = 8192; char szTempBuffer[MAX_FILE_BUFFER]; UINT nReadBytes = 0; UINT nCount = 0; progressData.m_dwTotalFileSize = sfxFile.GetLength() + zipFile.GetLength(); progressData.m_dwCurrentFileSize = 0; lpPage->UpdateManualPatchStatus(progressData); // ÇÁ·Î±×¸®½º ¹Ù¸¦ È®½ÇÈ÷ °»½ÅÇÒ ¼ö ÀÖµµ·Ï Àá½Ã ±â´Ù·Á ÁØ´Ù. Sleep(300); // ¼öµ¿ÆÐÄ¡ ÆÄÀÏ¿¡ SFX½ÇÇàºÎ ºÙÀÓ while(0 < (nReadBytes = sfxFile.Read(szTempBuffer, MAX_FILE_BUFFER))) { resultFile.Write(szTempBuffer, nReadBytes); progressData.m_dwCurrentFileSize += nReadBytes; if (0 == (++nCount % 10)) { lpPage->UpdateManualPatchStatus(progressData); } } // ¼öµ¿ÆÐÄ¡ ÆÄÀÏ¿¡ ZIPÆÄÀÏ ºÙÀÓ while(0 < (nReadBytes = zipFile.Read(szTempBuffer, MAX_FILE_BUFFER))) { resultFile.Write(szTempBuffer, nReadBytes); progressData.m_dwCurrentFileSize += nReadBytes; if (0 == (++nCount % 10)) { lpPage->UpdateManualPatchStatus(progressData); } } szErrorString.Empty(); } if (!szErrorString.IsEmpty()) { progressData.m_ErrorList.AddTail(szErrorString); lpPage->UpdateManualPatchStatus(progressData); } } PMUtil::SetCurrentTime(szErrorString); szErrorString.AppendFormat(_T("¼öµ¿ÆÐÄ¡ ÀÛ¾÷ ¿Ï·á : %d °³ ÆÄÀÏ Áß %d°³¸¦ ¿Ï·áÇÏ¿´½À´Ï´Ù. ÀÛ¾÷À» %sÇÏ¿´½À´Ï´Ù"), progressData.m_nTotalFiles, progressData.m_nAddedFiles, bSucceededJob && progressData.m_nTotalFiles == progressData.m_nAddedFiles ? _T("¼º°ø") : _T("½ÇÆÐ")); progressData.m_ProgressList.AddTail(szErrorString); progressData.m_TotalProgressList.AddTail(szErrorString); } } CATCH_ALL(e) { e->GetErrorMessage(szErrorMsg, MAX_ERROR_LEN - 1); szErrorMsg[MAX_ERROR_LEN - 1] = 0; PMUtil::SetCurrentTime(szErrorString); if (e->IsKindOf(RUNTIME_CLASS(CZipException))) { szErrorString.AppendFormat( _T("ÀÛ¾÷ ½ÇÆÐ : CZipArchive ¶óÀ̺귯¸®¿¡¼­ ¿¡·¯°¡ ¹ß»ýÇß½À´Ï´Ù. %s"), szErrorMsg); } else if (e->IsKindOf(RUNTIME_CLASS(CFileException))) { szErrorString.AppendFormat( _T("ÀÛ¾÷ ½ÇÆÐ : ÆÄÀÏ °ü·Ã ÀÛ¾÷¿¡¼­ ¿¡·¯°¡ ¹ß»ýÇß½À´Ï´Ù. %s"), szErrorMsg); } else { szErrorString.AppendFormat( _T("ÀÛ¾÷ ½ÇÆÐ : ¾Ë ¼ö ¾ø´Â ÀÛ¾÷¿¡¼­ ¿¡·¯°¡ ¹ß»ýÇß½À´Ï´Ù. %s"), szErrorMsg); } progressData.m_ErrorList.AddTail(szErrorString); progressData.m_TotalProgressList.AddTail(szErrorString); e->Delete(); } END_CATCH_ALL } // µ¥ÀÌÅ͸¦ ¾÷µ¥ÀÌÆ®ÇÑ´Ù. lpPage->UpdateManualPatchStatus(progressData); delete lpWorkerData; return 0; } void CManualPatchPage::OnBnClickedMpCreate() { // TODO: ¿©±â¿¡ ÄÁÆ®·Ñ ¾Ë¸² 󸮱â Äڵ带 Ãß°¡ÇÕ´Ï´Ù. UpdateData(TRUE); CFile file; if (0 == m_szMPFileName.GetLength() || !file.Open(m_szMPFileName, CFile::modeCreate)) { MessageBox(_T("¼öµ¿ÆÐÄ¡ ÆÄÀÏ À̸§ÀÌ ¾ø°Å³ª, ¿Ã¹Ù¸¥ ÆÄÀÏ À̸§ÀÌ ¾Æ´Õ´Ï´Ù. ´Ù½Ã ÀÔ·ÂÇØÁÖ¼¼¿ä"), _T("¿Ã¹Ù¸£Áö ¾ÊÀº ÆÄÀÏ À̸§"), MB_OK | MB_ICONERROR); } else { file.Close(); DeleteFile(m_szMPFileName); if (!theApp.IsManualPatchOperate()) { MPWorkerData* lpWorkerData = new MPWorkerData; if (lpWorkerData) { lpWorkerData->m_lpPage = this; lpWorkerData->m_szMPFolder.SetString(m_szMPFolder); lpWorkerData->m_szMPSFXFile.SetString(m_szMPSFXFile); lpWorkerData->m_szMPFileName.SetString(m_szMPFileName); lpWorkerData->m_szPatchType.SetString(m_szPatchType); lpWorkerData->m_dwMPMaxver = m_dwMPMaxver; lpWorkerData->m_dwMPMinver = m_dwMPMinver; InitMPWorkerData(); unsigned int nThreadID = 0; m_hManualPatchThread = reinterpret_cast( _beginthreadex(0, 0, ManualPatchWorker, lpWorkerData, 0, &nThreadID)); if (0 == m_hManualPatchThread) { MessageBox(_T("¼öµ¿ÆÐÄ¡ ½º·¹µå¸¦ »ý¼ºÇÒ ¼ö ¾ø½À´Ï´Ù"), _T("»ý¼º ¿¡·¯"), MB_OK | MB_ICONERROR); } else { static UINT nManualPatchDlgItems[] = { ID_MP_CREATE, IDC_ED_MP_PATCH_FILE_NAME, IDC_BTN_MP_SELECT_FILE }; PMUtil::EnableDlgItems(*this, nManualPatchDlgItems, sizeof(nManualPatchDlgItems)/sizeof(UINT), false); CWnd* lpWnd = GetDlgItem(ID_MP_CANCEL); if (lpWnd) { lpWnd->EnableWindow(TRUE); } // ÇÁ·Î±×¸®½º ¹Ù Ãâ·ÂÀ» À§ÇÑ Å¸À̸Ӹ¦ µ¹¸°´Ù. SetTimer(PMConst::MP_PROGRESS_TIMER_ID, PMConst::PROGRESS_TIMER_UPDATE_TIME, 0); // ¼öµ¿ÆÐÄ¡°¡ µ¹°í ÀÖ´Ù°í ¼³Á¤ÇÑ´Ù. theApp.SetManualPatchOperate(true); } } } } } void CManualPatchPage::OnBnClickedMpCancel() { // TODO: ¿©±â¿¡ ÄÁÆ®·Ñ ¾Ë¸² 󸮱â Äڵ带 Ãß°¡ÇÕ´Ï´Ù. if (theApp.IsManualPatchOperate()) { // ÀÌ¹Ì ½º·¹µå°¡ ÀÛµ¿Çϰí ÀÖ´Ù¸é, ½º·¹µå¸¦ Ãë¼ÒÇϵµ·Ï º¯¼ö¸¦ ¼¼ÆÃÇÑ´Ù. StopWorker(); } } void CManualPatchPage::OnBnClickedBtnMpSelectFile() { // TODO: ¿©±â¿¡ ÄÁÆ®·Ñ ¾Ë¸² 󸮱â Äڵ带 Ãß°¡ÇÕ´Ï´Ù. PMUtil::BrowseForNewFile(GetSafeHwnd(), _T("¼öµ¿ÆÐÄ¡ ÆÄÀÏ À̸§À» ¼±ÅÃÇØÁÖ¼¼¿ä"), _T("Manual Patch File\0*.exe"), _T("exe"), m_szMPFileName); UpdateData(FALSE); } BOOL CManualPatchPage::OnSetActive() { // TODO: ¿©±â¿¡ Ư¼öÈ­µÈ Äڵ带 Ãß°¡ ¹×/¶Ç´Â ±âº» Ŭ·¡½º¸¦ È£ÃâÇÕ´Ï´Ù. // µ¥ÀÌÅ͸¦ ¼Â¾÷¿¡¼­ Àоî¿É´Ï´Ù. if (!theApp.IsManualPatchOperate()) { // ½º·¹µå°¡ µ¿ÀÛÁßÀÌ ¾Æ´Ñ °æ¿ì¿¡¸¸ µ¥ÀÌÅ͸¦ °»½ÅÇÕ´Ï´Ù. m_pmSettingOption.GetSettingData(PMConst::PatchType, m_szPatchType); m_pmSettingOption.GetSettingData(PMConst::MP_Folder, m_szMPFolder); m_pmSettingOption.GetSettingData(PMConst::MP_SFXFile, m_szMPSFXFile); CString szValue; m_pmSettingOption.GetSettingData(PMConst::MP_MinVer, szValue); m_dwMPMinver = atol(szValue); UpdateData(FALSE); } return CPropertyPage::OnSetActive(); } BOOL CManualPatchPage::OnInitDialog() { CPropertyPage::OnInitDialog(); // TODO: ¿©±â¿¡ Ãß°¡ ÃʱâÈ­ ÀÛ¾÷À» Ãß°¡ÇÕ´Ï´Ù. // Cancel¹öưÀº óÀ½¿¡´Â DisableÇÑ´Ù. CWnd* lpWnd = GetDlgItem(ID_MP_CANCEL); if (lpWnd) { lpWnd->EnableWindow(FALSE); } m_edProgressLog.SetLimitText(UINT_MAX); m_edErrLog.SetLimitText(UINT_MAX); return TRUE; // return TRUE unless you set the focus to a control // ¿¹¿Ü: OCX ¼Ó¼º ÆäÀÌÁö´Â FALSE¸¦ ¹ÝÈ¯ÇØ¾ß ÇÕ´Ï´Ù. } afx_msg void CManualPatchPage::OnTimer(UINT_PTR nIDEvent) { if (nIDEvent == PMConst::MP_PROGRESS_TIMER_ID) { int nLowerRange = 0; int nUpperRange = 0; int nCurrentPos = m_TotalProgressBar.GetPos(); m_TotalProgressBar.GetRange(nLowerRange, nUpperRange); //! MANUAL_PATCH_LOCK m_ProgressLock.Lock(); if (m_ProgressData.m_dwTotalFileSize != nUpperRange) { // Àüü Range°¡ º¯°æµÇ¸é °»½ÅÇÑ´Ù - 2.1±â°¡ ÀÌ»óÀ» ¼öµ¿ÆÐÄ¡ ÇÒ ÀÏÀº ¾ø´Ù;; m_TotalProgressBar.SetRange32(0, static_cast(m_ProgressData.m_dwTotalFileSize)); } if (m_ProgressData.m_dwCurrentFileSize != nCurrentPos) { // ÆÄÀÏ À§Ä¡°¡ º¯°æµÇ¸é °»½ÅÇÑ´Ù. m_TotalProgressBar.SetPos( static_cast(m_ProgressData.m_dwCurrentFileSize)); } m_szFileProgress.Format(_T("%d/%d"), m_ProgressData.m_nAddedFiles, m_ProgressData.m_nTotalFiles); // ·Î±×¸¦ Ãâ·ÂÇÑ´Ù. POSITION pos = m_ProgressData.m_ProgressList.GetHeadPosition(); while(0 != pos) { m_edProgressLog.AddLine(m_ProgressData.m_ProgressList.GetNext(pos)); } pos = m_ProgressData.m_TotalProgressList.GetHeadPosition(); while(0 != pos) { theApp.AddTotalProgressLog(m_ProgressData.m_TotalProgressList.GetNext(pos)); } pos = m_ProgressData.m_ErrorList.GetHeadPosition(); while(0 != pos) { m_edErrLog.AddLine(m_ProgressData.m_ErrorList.GetNext(pos)); } m_ProgressData.m_ProgressList.RemoveAll(); m_ProgressData.m_TotalProgressList.RemoveAll(); m_ProgressData.m_ErrorList.RemoveAll(); //! MANUAL_PATCH_UNLOCK m_ProgressLock.Unlock(); UpdateData(FALSE); if (WAIT_OBJECT_0 == WaitForSingleObject(m_hManualPatchThread, 0)) { // ½º·¹µå°¡ Á¾·áµÇ¾ú´Ù. ŸÀ̸Ӹ¦ Á¦°ÅÇϰí, ´Ù½Ã ¼öµ¿ÆÐÄ¡ ¿É¼ÇÀ» EnableÇÑ´Ù. StopWorker(); } } } void CManualPatchPage::InitMPWorkerData() { m_hManualPatchThread = 0; m_ProgressData.m_bStopWorkerThread = FALSE; m_ProgressData.m_nTotalFiles = 0; m_ProgressData.m_nAddedFiles = 0; m_ProgressData.m_ProgressList.RemoveAll(); m_ProgressData.m_ErrorList.RemoveAll(); } void CManualPatchPage::StopWorker() { if (0 != m_hManualPatchThread) { m_ProgressLock.Lock(); //! MANUAL_PATCH_LOCK m_ProgressData.m_bStopWorkerThread = TRUE; m_ProgressLock.Unlock(); //! MANUAL_PATCH_UNLOCK WaitForSingleObject(m_hManualPatchThread, INFINITE); CloseHandle(m_hManualPatchThread); KillTimer(PMConst::MP_PROGRESS_TIMER_ID); InitMPWorkerData(); static UINT nManualPatchDlgItems[] = { ID_MP_CREATE, IDC_ED_MP_PATCH_FILE_NAME, IDC_BTN_MP_SELECT_FILE }; PMUtil::EnableDlgItems(*this, nManualPatchDlgItems, sizeof(nManualPatchDlgItems)/sizeof(UINT), true); CWnd* lpWnd = GetDlgItem(ID_MP_CANCEL); if (lpWnd) { lpWnd->EnableWindow(FALSE); } theApp.SetManualPatchOperate(false); } } void CManualPatchPage::OnClose() { // TODO: ¿©±â¿¡ ¸Þ½ÃÁö 󸮱â Äڵ带 Ãß°¡ ¹×/¶Ç´Â ±âº»°ªÀ» È£ÃâÇÕ´Ï´Ù. StopWorker(); CPropertyPage::OnClose(); } void CManualPatchPage::OnBnClickedClearLog() { // TODO: ¿©±â¿¡ ÄÁÆ®·Ñ ¾Ë¸² 󸮱â Äڵ带 Ãß°¡ÇÕ´Ï´Ù. m_edProgressLog.SetWindowText(_T("")); m_edErrLog.SetWindowText(_T("")); }