UI/updater: Delete files listed as removed in manifest
parent
894bc4078b
commit
9a5e094cb3
|
@ -59,8 +59,8 @@ bool CalculateFileHash(const wchar_t *path, BYTE *hash)
|
|||
|
||||
for (;;) {
|
||||
DWORD read = 0;
|
||||
if (!ReadFile(handle, &hashBuffer[0], hashBuffer.size(), &read,
|
||||
nullptr))
|
||||
if (!ReadFile(handle, &hashBuffer[0], (DWORD)hashBuffer.size(),
|
||||
&read, nullptr))
|
||||
return false;
|
||||
|
||||
if (!read)
|
||||
|
|
|
@ -171,6 +171,20 @@ try {
|
|||
return false;
|
||||
}
|
||||
|
||||
static void MyDeleteFile(const wstring &filename)
|
||||
{
|
||||
/* Try straightforward delete first */
|
||||
if (DeleteFile(filename.c_str()))
|
||||
return;
|
||||
|
||||
DWORD err = GetLastError();
|
||||
if (err == ERROR_FILE_NOT_FOUND)
|
||||
return;
|
||||
|
||||
/* If all else fails, schedule the file to be deleted on reboot */
|
||||
MoveFileEx(filename.c_str(), NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
|
||||
}
|
||||
|
||||
static bool IsSafeFilename(const wchar_t *path)
|
||||
{
|
||||
const wchar_t *p = path;
|
||||
|
@ -326,13 +340,29 @@ struct update_t {
|
|||
}
|
||||
};
|
||||
|
||||
struct deletion_t {
|
||||
wstring originalFilename;
|
||||
wstring deleteMeFilename;
|
||||
|
||||
void UndoRename()
|
||||
{
|
||||
if (!deleteMeFilename.empty())
|
||||
MoveFile(deleteMeFilename.c_str(),
|
||||
originalFilename.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
static vector<update_t> updates;
|
||||
static vector<deletion_t> deletions;
|
||||
static mutex updateMutex;
|
||||
|
||||
static inline void CleanupPartialUpdates()
|
||||
{
|
||||
for (update_t &update : updates)
|
||||
update.CleanPartialUpdate();
|
||||
|
||||
for (deletion_t &deletion : deletions)
|
||||
deletion.UndoRename();
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
@ -745,6 +775,67 @@ static bool AddPackageUpdateFiles(const Json &root, size_t idx,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void AddPackageRemovedFiles(const Json &package)
|
||||
{
|
||||
const Json &removed_files = package["removed_files"];
|
||||
if (!removed_files.is_array())
|
||||
return;
|
||||
|
||||
for (auto &item : removed_files.array_items()) {
|
||||
if (!item.is_string())
|
||||
continue;
|
||||
|
||||
wchar_t removedFileName[MAX_PATH];
|
||||
if (!UTF8ToWideBuf(removedFileName,
|
||||
item.string_value().c_str()))
|
||||
continue;
|
||||
|
||||
/* Ensure paths are safe, also check if file exists */
|
||||
if (!IsSafeFilename(removedFileName))
|
||||
continue;
|
||||
/* Technically GetFileAttributes can fail for other reasons,
|
||||
* so double-check by also checking the last error */
|
||||
if (GetFileAttributesW(removedFileName) ==
|
||||
INVALID_FILE_ATTRIBUTES &&
|
||||
GetLastError() == ERROR_FILE_NOT_FOUND)
|
||||
continue;
|
||||
|
||||
deletion_t deletion;
|
||||
deletion.originalFilename = removedFileName;
|
||||
|
||||
deletions.push_back(deletion);
|
||||
}
|
||||
}
|
||||
|
||||
static bool RenameRemovedFile(deletion_t &deletion)
|
||||
{
|
||||
_TCHAR deleteMeName[MAX_PATH];
|
||||
_TCHAR randomStr[MAX_PATH];
|
||||
|
||||
BYTE junk[40];
|
||||
BYTE hash[BLAKE2_HASH_LENGTH];
|
||||
|
||||
CryptGenRandom(hProvider, sizeof(junk), junk);
|
||||
blake2b(hash, sizeof(hash), junk, sizeof(junk), NULL, 0);
|
||||
HashToString(hash, randomStr);
|
||||
randomStr[8] = 0;
|
||||
|
||||
StringCbCopy(deleteMeName, sizeof(deleteMeName),
|
||||
deletion.originalFilename.c_str());
|
||||
|
||||
StringCbCat(deleteMeName, sizeof(deleteMeName), L".");
|
||||
StringCbCat(deleteMeName, sizeof(deleteMeName), randomStr);
|
||||
StringCbCat(deleteMeName, sizeof(deleteMeName), L".deleteme");
|
||||
|
||||
if (MoveFile(deletion.originalFilename.c_str(), deleteMeName)) {
|
||||
/* Only set this if the file was successfully renamed */
|
||||
deletion.deleteMeFilename = deleteMeName;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void UpdateWithPatchIfAvailable(const char *name, const char *hash,
|
||||
const char *source, int size)
|
||||
{
|
||||
|
@ -1295,6 +1386,9 @@ static bool Update(wchar_t *cmdLine)
|
|||
Status(L"Update failed: Failed to process update packages");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Add removed files to deletion queue (if any) */
|
||||
AddPackageRemovedFiles(packages[i]);
|
||||
}
|
||||
|
||||
SendDlgItemMessage(hwndMain, IDC_PROGRESS, PBM_SETMARQUEE, 0, 0);
|
||||
|
@ -1476,6 +1570,10 @@ static bool Update(wchar_t *cmdLine)
|
|||
}
|
||||
}
|
||||
|
||||
for (deletion_t &deletion : deletions)
|
||||
if (!RenameRemovedFile(deletion))
|
||||
return false;
|
||||
|
||||
/* ------------------------------------- *
|
||||
* Install virtual camera */
|
||||
|
||||
|
@ -1546,6 +1644,10 @@ static bool Update(wchar_t *cmdLine)
|
|||
DeleteFile(update.tempPath.c_str());
|
||||
}
|
||||
|
||||
/* Delete all removed files mentioned in the manifest */
|
||||
for (deletion_t &deletion : deletions)
|
||||
MyDeleteFile(deletion.deleteMeFilename);
|
||||
|
||||
SendDlgItemMessage(hwndMain, IDC_PROGRESS, PBM_SETPOS, 100, 0);
|
||||
|
||||
Status(L"Update complete.");
|
||||
|
|
Loading…
Reference in New Issue