summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2021-01-08 18:15:31 +0100
committerDavid Lönnhager <david.l@mullvad.net>2021-01-12 16:10:21 +0100
commita9649be8cdca53a076e50b999f250fc216903487 (patch)
tree5e4c21f2373ccfed703d3954d5ea4dbf2bbf92f4
parent55249da9c8f7f2e86ea946be393b5f0e98c44765 (diff)
downloadmullvadvpn-a9649be8cdca53a076e50b999f250fc216903487.tar.xz
mullvadvpn-a9649be8cdca53a076e50b999f250fc216903487.zip
Migrate old cache files on Windows
-rw-r--r--dist-assets/windows/installer.nsh35
-rw-r--r--windows/nsis-plugins/src/cleanup/cleaningops.cpp132
-rw-r--r--windows/nsis-plugins/src/cleanup/cleaningops.h2
-rw-r--r--windows/nsis-plugins/src/cleanup/cleanup.cpp32
-rw-r--r--windows/nsis-plugins/src/cleanup/cleanup.def1
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