summaryrefslogtreecommitdiff
path: root/plugins/PluginUpdater/src
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2020-08-27 20:35:52 +0300
committerGeorge Hazan <ghazan@miranda.im>2020-08-27 20:35:52 +0300
commit6d990112ad5ba4a670b71d40de7dfd9cedfd32cc (patch)
treef599470d9af322a60e13dd1e8b9666463a097539 /plugins/PluginUpdater/src
parent77fa06bdc1a3efb7689c3ec39c8a943f7a289920 (diff)
fixes #2555 (PluginUpdater: некорректное обновление при работе нескольких миранд одновременно)
Diffstat (limited to 'plugins/PluginUpdater/src')
-rw-r--r--plugins/PluginUpdater/src/DlgListNew.cpp2
-rw-r--r--plugins/PluginUpdater/src/DlgUpdate.cpp22
-rw-r--r--plugins/PluginUpdater/src/Utils.cpp59
-rw-r--r--plugins/PluginUpdater/src/stdafx.h4
-rw-r--r--plugins/PluginUpdater/src/unzipfile.cpp41
-rw-r--r--plugins/PluginUpdater/src/version.h2
6 files changed, 84 insertions, 46 deletions
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 <stdver.h>