diff options
| author | David Lönnhager <david.l@mullvad.net> | 2021-01-08 18:15:31 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2021-01-12 16:10:21 +0100 |
| commit | a9649be8cdca53a076e50b999f250fc216903487 (patch) | |
| tree | 5e4c21f2373ccfed703d3954d5ea4dbf2bbf92f4 | |
| parent | 55249da9c8f7f2e86ea946be393b5f0e98c44765 (diff) | |
| download | mullvadvpn-a9649be8cdca53a076e50b999f250fc216903487.tar.xz mullvadvpn-a9649be8cdca53a076e50b999f250fc216903487.zip | |
Migrate old cache files on Windows
| -rw-r--r-- | dist-assets/windows/installer.nsh | 35 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/cleanup/cleaningops.cpp | 132 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/cleanup/cleaningops.h | 2 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/cleanup/cleanup.cpp | 32 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/cleanup/cleanup.def | 1 |
5 files changed, 132 insertions, 70 deletions
diff --git a/dist-assets/windows/installer.nsh b/dist-assets/windows/installer.nsh index 704b0773b4..7d30b158fe 100644 --- a/dist-assets/windows/installer.nsh +++ b/dist-assets/windows/installer.nsh @@ -324,6 +324,40 @@ !define InstallTrayIcon '!insertmacro "InstallTrayIcon"' # +# MigrateCache +# +# Move old cache files to the new cache directory. +# This is for upgrades from versions <= 2020.8-beta2. +# +!macro MigrateCache + + log::Log "MigrateCache()" + + Push $0 + Push $1 + + cleanup::MigrateCache + + Pop $0 + Pop $1 + + ${If} $0 != ${MULLVAD_SUCCESS} + log::Log "Failed to migrate cache: $1" + Goto MigrateCache_return + ${EndIf} + + log::Log "MigrateCache() completed successfully" + + MigrateCache_return: + + Pop $1 + Pop $0 + +!macroend + +!define MigrateCache '!insertmacro "MigrateCache"' + +# # RemoveLogsAndCache # # Call into helper DLL instructing it to remove all logs and cache @@ -628,6 +662,7 @@ SetShellVarContext current RMDir /r "$LOCALAPPDATA\mullvad-vpn-updater" + ${MigrateCache} ${RemoveRelayCache} ${RemoveApiAddressCache} diff --git a/windows/nsis-plugins/src/cleanup/cleaningops.cpp b/windows/nsis-plugins/src/cleanup/cleaningops.cpp index 1a711bf3d8..b0b3fa4631 100644 --- a/windows/nsis-plugins/src/cleanup/cleaningops.cpp +++ b/windows/nsis-plugins/src/cleanup/cleaningops.cpp @@ -105,6 +105,12 @@ std::wstring GetSystemUserLocalAppData() return common::fs::GetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_DEFAULT, processToken); } +std::filesystem::path GetSystemCacheDirectory() +{ + const auto programData = common::fs::GetKnownFolderPath(FOLDERID_ProgramData, KF_FLAG_DEFAULT, nullptr); + return std::filesystem::path(programData).append(L"Mullvad VPN").append(L"cache"); +} + template <class It> size_t EqualTokensCount(It lhsBegin, It lhsEnd, It rhsBegin, It rhsEnd) { @@ -125,6 +131,48 @@ size_t EqualTokensCount(It lhsBegin, It lhsEnd, It rhsBegin, It rhsEnd) namespace cleaningops { +// +// Migrate cache for versions <= 2020.8-beta2. +// +void MigrateCacheServiceUser() +{ + const auto newCacheDir = GetSystemCacheDirectory(); + common::fs::Mkdir(newCacheDir); + + const auto localAppData = GetSystemUserLocalAppData(); + const auto oldCacheDir = std::filesystem::path(localAppData).append(L"Mullvad VPN"); + + common::fs::ScopedNativeFileSystem nativeFileSystem; + + common::security::AddAdminToObjectDacl(oldCacheDir, SE_FILE_OBJECT); + + { + common::fs::FileEnumerator files(oldCacheDir); + + auto notNamedSet = std::make_unique<common::fs::FilterNotNamedSet>(); + + notNamedSet->addObject(L"account-history.json"); + notNamedSet->addObject(L"settings.json"); + + files.addFilter(std::move(notNamedSet)); + files.addFilter(std::make_unique<common::fs::FilterFiles>()); + + WIN32_FIND_DATAW file; + + while (files.next(file)) + { + const auto source = std::filesystem::path(files.getDirectory()).append(file.cFileName); + const auto target = std::filesystem::path(newCacheDir).append(file.cFileName); + std::filesystem::rename(source, target); + } + } + + // + // This fails unless the directory is empty. Settings remain in this directory. + // + RemoveDirectoryW(std::wstring(L"\\\\?\\").append(oldCacheDir).c_str()); +} + void RemoveLogsCacheCurrentUser() { const auto localAppData = common::fs::GetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_DEFAULT, nullptr); @@ -238,27 +286,8 @@ void RemoveLogsServiceUser() const auto programData = common::fs::GetKnownFolderPath(FOLDERID_ProgramData, KF_FLAG_DEFAULT, nullptr); const auto appdir = std::filesystem::path(programData).append(L"Mullvad VPN"); - std::filesystem::remove_all(appdir); -} - -void RemoveCacheServiceUser() -{ - const auto localAppData = GetSystemUserLocalAppData(); - const auto mullvadAppData = std::filesystem::path(localAppData).append(L"Mullvad VPN"); - - common::fs::ScopedNativeFileSystem nativeFileSystem; - - common::security::AddAdminToObjectDacl(mullvadAppData, SE_FILE_OBJECT); - { - common::fs::FileEnumerator files(mullvadAppData); - - auto notNamedSet = std::make_unique<common::fs::FilterNotNamedSet>(); - - notNamedSet->addObject(L"account-history.json"); - notNamedSet->addObject(L"settings.json"); - - files.addFilter(std::move(notNamedSet)); + common::fs::FileEnumerator files(appdir); files.addFilter(std::make_unique<common::fs::FilterFiles>()); WIN32_FIND_DATAW file; @@ -272,52 +301,21 @@ void RemoveCacheServiceUser() } } - // - // This fails unless the directory is empty. - // Which is what we want, since removing cache and settings files are separate operations. - // - RemoveDirectoryW(std::wstring(L"\\\\?\\").append(mullvadAppData).c_str()); + RemoveDirectoryW(std::wstring(L"\\\\?\\").append(appdir).c_str()); } -void RemoveSettingsServiceUser() +void RemoveCacheServiceUser() { - const auto localAppData = GetSystemUserLocalAppData(); - const auto mullvadAppData = std::filesystem::path(localAppData).append(L"Mullvad VPN"); - - common::fs::ScopedNativeFileSystem nativeFileSystem; - - common::security::AddAdminToObjectDacl(mullvadAppData, SE_FILE_OBJECT); - - { - common::fs::FileEnumerator files(mullvadAppData); - - auto filter = std::make_unique<common::fs::FilterNamedSet>(); - - filter->addObject(L"account-history.json"); - filter->addObject(L"settings.json"); - - files.addFilter(std::move(filter)); - files.addFilter(std::make_unique<common::fs::FilterFiles>()); - - WIN32_FIND_DATAW file; - - while (files.next(file)) - { - const auto target = std::filesystem::path(files.getDirectory()).append(file.cFileName); + const auto cacheDir = GetSystemCacheDirectory(); - std::error_code dummy; - std::filesystem::remove(target, dummy); - } - } + std::error_code dummy; + std::filesystem::remove_all(cacheDir, dummy); - // - // This fails unless the directory is empty. - // Which is what we want, since removing cache and settings files are separate operations. - // - RemoveDirectoryW(std::wstring(L"\\\\?\\").append(mullvadAppData).c_str()); + const auto appdir = cacheDir.parent_path(); + RemoveDirectoryW(std::wstring(L"\\\\?\\").append(appdir).c_str()); } -void RemoveRelayCacheServiceUser() +void RemoveSettingsServiceUser() { const auto localAppData = GetSystemUserLocalAppData(); const auto mullvadAppData = std::filesystem::path(localAppData).append(L"Mullvad VPN"); @@ -326,22 +324,18 @@ void RemoveRelayCacheServiceUser() common::security::AddAdminToObjectDacl(mullvadAppData, SE_FILE_OBJECT); - const auto cacheFile = std::filesystem::path(mullvadAppData).append(L"relays.json"); + std::filesystem::remove_all(mullvadAppData); +} +void RemoveRelayCacheServiceUser() +{ + const auto cacheFile = GetSystemCacheDirectory().append(L"relays.json"); std::filesystem::remove(cacheFile); } void RemoveApiAddressCacheServiceUser() { - const auto programData = common::fs::GetKnownFolderPath(FOLDERID_ProgramData, KF_FLAG_DEFAULT, nullptr); - const auto mullvadProgramData = std::filesystem::path(programData).append(L"Mullvad VPN"); - - common::fs::ScopedNativeFileSystem nativeFileSystem; - - common::security::AddAdminToObjectDacl(mullvadProgramData, SE_FILE_OBJECT); - - const auto cacheFile = std::filesystem::path(mullvadProgramData).append(L"api-ip-address.txt"); - + const auto cacheFile = GetSystemCacheDirectory().append(L"api-ip-address.txt"); std::filesystem::remove(cacheFile); } diff --git a/windows/nsis-plugins/src/cleanup/cleaningops.h b/windows/nsis-plugins/src/cleanup/cleaningops.h index 057eb305b8..47633ffb03 100644 --- a/windows/nsis-plugins/src/cleanup/cleaningops.h +++ b/windows/nsis-plugins/src/cleanup/cleaningops.h @@ -3,6 +3,8 @@ namespace cleaningops { +void MigrateCacheServiceUser(); + void RemoveLogsCacheCurrentUser(); void RemoveLogsCacheOtherUsers(); void RemoveLogsServiceUser(); diff --git a/windows/nsis-plugins/src/cleanup/cleanup.cpp b/windows/nsis-plugins/src/cleanup/cleanup.cpp index 528efb2f7a..ca943934a7 100644 --- a/windows/nsis-plugins/src/cleanup/cleanup.cpp +++ b/windows/nsis-plugins/src/cleanup/cleanup.cpp @@ -23,8 +23,8 @@ void __declspec(dllexport) NSISCALL RemoveLogsAndCache { cleaningops::RemoveLogsCacheCurrentUser, cleaningops::RemoveLogsCacheOtherUsers, - cleaningops::RemoveLogsServiceUser, cleaningops::RemoveCacheServiceUser, + cleaningops::RemoveLogsServiceUser, }; bool success = true; @@ -47,6 +47,36 @@ void __declspec(dllexport) NSISCALL RemoveLogsAndCache pushint(success ? NsisStatus::SUCCESS : NsisStatus::GENERAL_ERROR); } +void __declspec(dllexport) NSISCALL MigrateCache +( + HWND hwndParent, + int string_size, + LPTSTR variables, + stack_t** stacktop, + extra_parameters* extra, + ... +) +{ + EXDLL_INIT(); + + try + { + cleaningops::MigrateCacheServiceUser(); + pushstring(L""); + pushint(NsisStatus::SUCCESS); + } + catch (std::exception &err) + { + pushstring(common::string::ToWide(err.what()).c_str()); + pushint(NsisStatus::GENERAL_ERROR); + } + catch (...) + { + pushstring(L"Unspecified error"); + pushint(NsisStatus::GENERAL_ERROR); + } +} + void __declspec(dllexport) NSISCALL RemoveSettings ( HWND hwndParent, diff --git a/windows/nsis-plugins/src/cleanup/cleanup.def b/windows/nsis-plugins/src/cleanup/cleanup.def index 779e620691..da22c683d6 100644 --- a/windows/nsis-plugins/src/cleanup/cleanup.def +++ b/windows/nsis-plugins/src/cleanup/cleanup.def @@ -2,6 +2,7 @@ LIBRARY cleanup EXPORTS +MigrateCache RemoveLogsAndCache RemoveSettings RemoveRelayCache |
