From 6d990112ad5ba4a670b71d40de7dfd9cedfd32cc Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 27 Aug 2020 20:35:52 +0300 Subject: =?UTF-8?q?fixes=20#2555=20(PluginUpdater:=20=D0=BD=D0=B5=D0=BA?= =?UTF-8?q?=D0=BE=D1=80=D1=80=D0=B5=D0=BA=D1=82=D0=BD=D0=BE=D0=B5=20=D0=BE?= =?UTF-8?q?=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B5=20=D0=BD?= =?UTF-8?q?=D0=B5=D1=81=D0=BA=D0=BE=D0=BB=D1=8C=D0=BA=D0=B8=D1=85=20=D0=BC?= =?UTF-8?q?=D0=B8=D1=80=D0=B0=D0=BD=D0=B4=20=D0=BE=D0=B4=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=BD=D0=BE)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/PluginUpdater/src/DlgListNew.cpp | 2 +- plugins/PluginUpdater/src/DlgUpdate.cpp | 22 +++++++++--- plugins/PluginUpdater/src/Utils.cpp | 59 ++++++++++++++++++++++++-------- plugins/PluginUpdater/src/stdafx.h | 4 +-- plugins/PluginUpdater/src/unzipfile.cpp | 41 ++++++++++------------ plugins/PluginUpdater/src/version.h | 2 +- 6 files changed, 84 insertions(+), 46 deletions(-) (limited to 'plugins/PluginUpdater') diff --git a/plugins/PluginUpdater/src/DlgListNew.cpp b/plugins/PluginUpdater/src/DlgListNew.cpp index 53cf844391..8ea1056727 100644 --- a/plugins/PluginUpdater/src/DlgListNew.cpp +++ b/plugins/PluginUpdater/src/DlgListNew.cpp @@ -312,7 +312,7 @@ public: if (DownloadFile(&p->File, nlc)) { m_list.SetItemText(i, 1, TranslateT("Succeeded.")); - if (unzip(p->File.tszDiskPath, tszMirandaPath, tszFileBack, false)) + if (!unzip(p->File.tszDiskPath, tszMirandaPath, tszFileBack, false)) SafeDeleteFile(p->File.tszDiskPath); // remove .zip after successful update db_unset(0, DB_MODULE_NEW_FILES, _T2A(p->tszOldName)); } diff --git a/plugins/PluginUpdater/src/DlgUpdate.cpp b/plugins/PluginUpdater/src/DlgUpdate.cpp index 66f83c9287..a0215d0d41 100644 --- a/plugins/PluginUpdater/src/DlgUpdate.cpp +++ b/plugins/PluginUpdater/src/DlgUpdate.cpp @@ -85,13 +85,21 @@ class CUpdateDLg : public CDlgBase Netlib_CloseHandle(nlc); // 3) Unpack all zips + DWORD dwErrorCode; for (auto &it : todo) { if (it->bEnabled) { if (it->bDeleteOnly) { // we need only to backup the old file wchar_t *ptszRelPath = it->tszNewName + wcslen(tszMirandaPath) + 1, tszBackFile[MAX_PATH]; mir_snwprintf(tszBackFile, L"%s\\%s", tszFileBack, ptszRelPath); - BackupFile(it->tszNewName, tszBackFile); + if (dwErrorCode = BackupFile(it->tszNewName, tszBackFile)) { +LBL_Error: + Skin_PlaySound("updatefailed"); + CMStringW wszError(FORMAT, TranslateT("Unpack operation failed with error code=%d, update terminated"), dwErrorCode); + MessageBox(pDlg->GetHwnd(), wszError, TranslateT("Plugin Updater"), MB_OK | MB_ICONERROR); + pDlg->Close(); + return; + } } else { // if file name differs, we also need to backup the old file here @@ -100,11 +108,14 @@ class CUpdateDLg : public CDlgBase wchar_t tszSrcPath[MAX_PATH], tszBackFile[MAX_PATH]; mir_snwprintf(tszSrcPath, L"%s\\%s", tszMirandaPath.get(), it->tszOldName); mir_snwprintf(tszBackFile, L"%s\\%s", tszFileBack, it->tszOldName); - BackupFile(tszSrcPath, tszBackFile); + if (dwErrorCode = BackupFile(tszSrcPath, tszBackFile)) + goto LBL_Error; } - if (unzip(it->File.tszDiskPath, tszMirandaPath, tszFileBack, true)) - SafeDeleteFile(it->File.tszDiskPath); // remove .zip after successful update + if (dwErrorCode = unzip(it->File.tszDiskPath, tszMirandaPath, tszFileBack, true)) + goto LBL_Error; + + SafeDeleteFile(it->File.tszDiskPath); // remove .zip after successful update } } } @@ -449,11 +460,12 @@ static void DlgUpdateSilent(void *param) } // remove .zip after successful update - if (unzip(it->File.tszDiskPath, tszMirandaPath, tszFileBack, true)) + if (!unzip(it->File.tszDiskPath, tszMirandaPath, tszFileBack, true)) SafeDeleteFile(it->File.tszDiskPath); } } } + delete &UpdateFiles; Skin_PlaySound("updatecompleted"); diff --git a/plugins/PluginUpdater/src/Utils.cpp b/plugins/PluginUpdater/src/Utils.cpp index fdf60f8cd2..5d4b8c0311 100644 --- a/plugins/PluginUpdater/src/Utils.cpp +++ b/plugins/PluginUpdater/src/Utils.cpp @@ -86,7 +86,7 @@ bool ParseHashes(const wchar_t *ptszUrl, ptrW &baseUrl, SERVLIST &arHashes) return false; } - if (!unzip(pFileUrl.tszDiskPath, g_tszTempPath, nullptr, true)) { + if (unzip(pFileUrl.tszDiskPath, g_tszTempPath, nullptr, true)) { Netlib_LogfW(hNetlibUser, L"Unzipping list of available updates from %s failed", baseUrl.get()); ShowPopup(TranslateT("Plugin Updater"), TranslateT("An error occurred while checking for new updates."), POPUP_TYPE_ERROR); Skin_PlaySound("updatefailed"); @@ -141,8 +141,7 @@ bool ParseHashes(const wchar_t *ptszUrl, ptrW &baseUrl, SERVLIST &arHashes) if (UpdateMode == UPDATE_MODE_STABLE) g_plugin.setByte(DB_SETTING_UPDATE_MODE, UPDATE_MODE_TRUNK); } - else - g_plugin.setByte(DB_SETTING_DONT_SWITCH_TO_STABLE, 0); + else g_plugin.setByte(DB_SETTING_DONT_SWITCH_TO_STABLE, 0); return true; } @@ -459,20 +458,22 @@ int TransactPipe(int opcode, const wchar_t *p1, const wchar_t *p2) else *dst++ = 0; DWORD dwBytes = 0, dwError; - if (WriteFile(hPipe, buf, (DWORD)((BYTE *)dst - buf), &dwBytes, nullptr) == 0) - return 0; + if (!WriteFile(hPipe, buf, (DWORD)((BYTE *)dst - buf), &dwBytes, nullptr)) + return GetLastError(); dwError = 0; - if (ReadFile(hPipe, &dwError, sizeof(DWORD), &dwBytes, nullptr) == 0) return 0; - if (dwBytes != sizeof(DWORD)) return 0; + if (!ReadFile(hPipe, &dwError, sizeof(DWORD), &dwBytes, nullptr)) + return GetLastError(); + if (dwBytes != sizeof(DWORD)) + return ERROR_BAD_ARGUMENTS; - return dwError == ERROR_SUCCESS; + return dwError; } int SafeCopyFile(const wchar_t *pSrc, const wchar_t *pDst) { if (hPipe == nullptr) - return CopyFile(pSrc, pDst, FALSE); + return CopyFileW(pSrc, pDst, FALSE); return TransactPipe(1, pSrc, pDst); } @@ -480,10 +481,35 @@ int SafeCopyFile(const wchar_t *pSrc, const wchar_t *pDst) int SafeMoveFile(const wchar_t *pSrc, const wchar_t *pDst) { if (hPipe == nullptr) { - DeleteFile(pDst); - if (MoveFile(pSrc, pDst) == 0) // use copy on error - CopyFile(pSrc, pDst, FALSE); - DeleteFile(pSrc); + if (!DeleteFileW(pDst)) { + DWORD dwError = GetLastError(); + if (dwError != ERROR_ACCESS_DENIED && dwError != ERROR_FILE_NOT_FOUND) + return dwError; + } + + if (!MoveFileW(pSrc, pDst)) { // use copy on error + switch (DWORD dwError = GetLastError()) { + case ERROR_ALREADY_EXISTS: + return 0; // this file was included into many archives, so Miranda tries to move it again & again + + case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + case ERROR_LOCK_VIOLATION: + // use copy routine if a move operation isn't available + // for example, when files are on different disks + if (!CopyFileW(pSrc, pDst, FALSE)) + return GetLastError(); + + if (!DeleteFileW(pSrc)) + return GetLastError(); + break; + + default: + return dwError; + } + } + + return ERROR_SUCCESS; } return TransactPipe(2, pSrc, pDst); @@ -515,10 +541,13 @@ int SafeCreateFilePath(const wchar_t *pFolder) return TransactPipe(5, pFolder, nullptr); } -void BackupFile(wchar_t *ptszSrcFileName, wchar_t *ptszBackFileName) +int BackupFile(wchar_t *ptszSrcFileName, wchar_t *ptszBackFileName) { SafeCreateFilePath(ptszBackFileName); - SafeMoveFile(ptszSrcFileName, ptszBackFileName); + + if (int iErrorCode = SafeMoveFile(ptszSrcFileName, ptszBackFileName)) + return iErrorCode; + return 0; } ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/PluginUpdater/src/stdafx.h b/plugins/PluginUpdater/src/stdafx.h index 57f173b294..1bc95e97d5 100644 --- a/plugins/PluginUpdater/src/stdafx.h +++ b/plugins/PluginUpdater/src/stdafx.h @@ -249,7 +249,7 @@ void UnloadNetlib(); void CALLBACK RestartPrompt(void *); -void BackupFile(wchar_t *ptszSrcFileName, wchar_t *ptszBackFileName); +int BackupFile(wchar_t *ptszSrcFileName, wchar_t *ptszBackFileName); bool ParseHashes(const wchar_t *ptszUrl, ptrW &baseUrl, SERVLIST &arHashes); int CompareHashes(const ServListEntry *p1, const ServListEntry *p2); @@ -262,7 +262,7 @@ void __stdcall OpenPluginOptions(void*); void CheckUpdateOnStartup(); void __stdcall InitTimer(void *type); -bool unzip(const wchar_t *ptszZipFile, wchar_t *ptszDestPath, wchar_t *ptszBackPath,bool ch); +int unzip(const wchar_t *ptszZipFile, wchar_t *ptszDestPath, wchar_t *ptszBackPath,bool ch); /////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/PluginUpdater/src/unzipfile.cpp b/plugins/PluginUpdater/src/unzipfile.cpp index 18a95fd726..9e3c21da09 100644 --- a/plugins/PluginUpdater/src/unzipfile.cpp +++ b/plugins/PluginUpdater/src/unzipfile.cpp @@ -30,7 +30,7 @@ static void PrepareFileName(wchar_t *dest, size_t destSize, const wchar_t *ptszP *p = '\\'; } -bool extractCurrentFile(unzFile uf, wchar_t *ptszDestPath, wchar_t *ptszBackPath, bool ch) +int extractCurrentFile(unzFile uf, wchar_t *ptszDestPath, wchar_t *ptszBackPath, bool ch) { unz_file_info64 file_info; char filename[MAX_PATH]; @@ -38,7 +38,7 @@ bool extractCurrentFile(unzFile uf, wchar_t *ptszDestPath, wchar_t *ptszBackPath int err = unzGetCurrentFileInfo64(uf, &file_info, filename, sizeof(filename), buf, DATA_BUF_SIZE, nullptr, 0); if (err != UNZ_OK) - return false; + return err; for (char *p = strchr(filename, '/'); p; p = strchr(p+1, '/')) *p = '\\'; @@ -49,21 +49,20 @@ bool extractCurrentFile(unzFile uf, wchar_t *ptszDestPath, wchar_t *ptszBackPath return true; wchar_t tszDestFile[MAX_PATH], tszBackFile[MAX_PATH]; - wchar_t *ptszNewName = mir_utf8decodeW(filename); + ptrW ptszNewName(mir_utf8decodeW(filename)); if (ptszNewName == nullptr) ptszNewName = mir_a2u(filename); if (!(file_info.external_fa & FILE_ATTRIBUTE_DIRECTORY)) { err = unzOpenCurrentFile(uf); - if (err != UNZ_OK) { - mir_free(ptszNewName); - return false; - } + if (err != UNZ_OK) + return err; if (ptszBackPath != nullptr) { PrepareFileName(tszDestFile, _countof(tszDestFile), ptszDestPath, ptszNewName); PrepareFileName(tszBackFile, _countof(tszBackFile), ptszBackPath, ptszNewName); - BackupFile(tszDestFile, tszBackFile); + if (err = BackupFile(tszDestFile, tszBackFile)) + return err; } PrepareFileName(tszDestFile, _countof(tszDestFile), ptszDestPath, ptszNewName); @@ -74,16 +73,15 @@ bool extractCurrentFile(unzFile uf, wchar_t *ptszDestPath, wchar_t *ptszBackPath ptszFile2unzip = tszDestFile; else { wchar_t tszTempPath[MAX_PATH]; - GetTempPath( _countof(tszTempPath), tszTempPath); - GetTempFileName(tszTempPath, L"PUtemp", GetCurrentProcessId(), tszBackFile); + GetTempPathW(_countof(tszTempPath), tszTempPath); + GetTempFileNameW(tszTempPath, L"PUtemp", GetCurrentProcessId(), tszBackFile); ptszFile2unzip = tszBackFile; } HANDLE hFile = CreateFile(ptszFile2unzip, GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, file_info.external_fa, nullptr); - if (hFile == INVALID_HANDLE_VALUE) { - mir_free(ptszNewName); - return false; - } + if (hFile == INVALID_HANDLE_VALUE) + return GetLastError(); + while (true) { err = unzReadCurrentFile(uf, buf, DATA_BUF_SIZE); if (err <= 0) @@ -91,7 +89,7 @@ bool extractCurrentFile(unzFile uf, wchar_t *ptszDestPath, wchar_t *ptszBackPath DWORD bytes; if (!WriteFile(hFile, buf, err, &bytes, FALSE)) { - err = UNZ_ERRNO; + err = GetLastError(); break; } } @@ -108,13 +106,12 @@ bool extractCurrentFile(unzFile uf, wchar_t *ptszDestPath, wchar_t *ptszBackPath if (hPipe) SafeMoveFile(ptszFile2unzip, tszDestFile); } - mir_free(ptszNewName); - return true; + return err; } -bool unzip(const wchar_t *ptszZipFile, wchar_t *ptszDestPath, wchar_t *ptszBackPath,bool ch) +int unzip(const wchar_t *ptszZipFile, wchar_t *ptszDestPath, wchar_t *ptszBackPath,bool ch) { - bool bResult = true; + int iErrorCode = 0; zlib_filefunc64_def ffunc; fill_fopen64_filefunc(&ffunc); @@ -122,12 +119,12 @@ bool unzip(const wchar_t *ptszZipFile, wchar_t *ptszDestPath, wchar_t *ptszBackP unzFile uf = unzOpen2_64(ptszZipFile, &ffunc); if (uf) { do { - if (!extractCurrentFile(uf, ptszDestPath, ptszBackPath,ch)) - bResult = false; + if (int err = extractCurrentFile(uf, ptszDestPath, ptszBackPath,ch)) + iErrorCode = err; } while (unzGoToNextFile(uf) == UNZ_OK); unzClose(uf); } - return bResult; + return iErrorCode; } diff --git a/plugins/PluginUpdater/src/version.h b/plugins/PluginUpdater/src/version.h index e289793974..d976946bdf 100644 --- a/plugins/PluginUpdater/src/version.h +++ b/plugins/PluginUpdater/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 2 #define __RELEASE_NUM 0 -#define __BUILD_NUM 7 +#define __BUILD_NUM 8 #include -- cgit v1.2.3