summaryrefslogtreecommitdiffhomepage
path: root/windows/winutil/src
diff options
context:
space:
mode:
authorOdd Stranne <odd@mullvad.net>2019-06-18 10:03:08 +0200
committerOdd Stranne <odd@mullvad.net>2019-06-26 11:57:30 +0200
commit25a9780ce403fbb0589592e07740e752ef199d12 (patch)
treeaaa26a6a16e8f99d8c47808d1bfbc7b551d4127b /windows/winutil/src
parent8c2a729fd5c64b47f34eee3e4558d363f3aab8d3 (diff)
downloadmullvadvpn-25a9780ce403fbb0589592e07740e752ef199d12.tar.xz
mullvadvpn-25a9780ce403fbb0589592e07740e752ef199d12.zip
Add Windows Update settings migrator
Diffstat (limited to 'windows/winutil/src')
-rw-r--r--windows/winutil/src/extras/migration/migration.cpp40
-rw-r--r--windows/winutil/src/extras/migration/migration.vcxproj189
-rw-r--r--windows/winutil/src/extras/migration/migration.vcxproj.filters11
-rw-r--r--windows/winutil/src/extras/migration/stdafx.cppbin0 -> 594 bytes
-rw-r--r--windows/winutil/src/extras/migration/stdafx.hbin0 -> 642 bytes
-rw-r--r--windows/winutil/src/extras/migration/targetver.hbin0 -> 630 bytes
-rw-r--r--windows/winutil/src/winutil/dllmain.cpp11
-rw-r--r--windows/winutil/src/winutil/migration.cpp133
-rw-r--r--windows/winutil/src/winutil/migration.h18
-rw-r--r--windows/winutil/src/winutil/stdafx.cppbin0 -> 590 bytes
-rw-r--r--windows/winutil/src/winutil/stdafx.hbin0 -> 840 bytes
-rw-r--r--windows/winutil/src/winutil/targetver.h12
-rw-r--r--windows/winutil/src/winutil/winutil.cpp42
-rw-r--r--windows/winutil/src/winutil/winutil.def3
-rw-r--r--windows/winutil/src/winutil/winutil.h35
-rw-r--r--windows/winutil/src/winutil/winutil.rcbin0 -> 1498 bytes
-rw-r--r--windows/winutil/src/winutil/winutil.vcxproj207
-rw-r--r--windows/winutil/src/winutil/winutil.vcxproj.filters21
18 files changed, 722 insertions, 0 deletions
diff --git a/windows/winutil/src/extras/migration/migration.cpp b/windows/winutil/src/extras/migration/migration.cpp
new file mode 100644
index 0000000000..0ee4d458fe
--- /dev/null
+++ b/windows/winutil/src/extras/migration/migration.cpp
@@ -0,0 +1,40 @@
+#include "stdafx.h"
+#include <iostream>
+#include "../../winutil/winutil.h"
+
+void WINUTIL_API ErrorSink(const char *errorMessage, void *)
+{
+ std::cout << "Error: " << errorMessage << std::endl;
+}
+
+int main()
+{
+ const auto status = WinUtil_MigrateAfterWindowsUpdate(ErrorSink, nullptr);
+
+ switch (status)
+ {
+ case WINUTIL_MIGRATION_STATUS::SUCCESS:
+ {
+ std::wcout << L"Success" << std::endl;
+ break;
+ }
+ case WINUTIL_MIGRATION_STATUS::ABORTED:
+ {
+ std::wcout << L"Aborted" << std::endl;
+ break;
+ }
+ case WINUTIL_MIGRATION_STATUS::NOTHING_TO_MIGRATE:
+ {
+ std::wcout << L"Nothing to migrate" << std::endl;
+ break;
+ }
+ case WINUTIL_MIGRATION_STATUS::FAILED:
+ {
+ std::wcout << L"Failed" << std::endl;
+ break;
+ }
+ }
+
+ return 0;
+}
+
diff --git a/windows/winutil/src/extras/migration/migration.vcxproj b/windows/winutil/src/extras/migration/migration.vcxproj
new file mode 100644
index 0000000000..174bae6f4b
--- /dev/null
+++ b/windows/winutil/src/extras/migration/migration.vcxproj
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>15.0</VCProjectVersion>
+ <ProjectGuid>{5DDDC994-A1C4-4B5C-8909-B576E490E40E}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>migration</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)\bin\$(Platform)-$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)\bin\temp\$(Platform)-$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)\bin\$(Platform)-$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)\bin\temp\$(Platform)-$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(SolutionDir)\bin\$(Platform)-$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)\bin\temp\$(Platform)-$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(SolutionDir)\bin\$(Platform)-$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)\bin\temp\$(Platform)-$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>winutil.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(SolutionDir)\bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>winutil.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(SolutionDir)\bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>winutil.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(SolutionDir)\bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>winutil.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(SolutionDir)\bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="stdafx.h" />
+ <ClInclude Include="targetver.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="migration.cpp" />
+ <ClCompile Include="stdafx.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ </ClCompile>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/windows/winutil/src/extras/migration/migration.vcxproj.filters b/windows/winutil/src/extras/migration/migration.vcxproj.filters
new file mode 100644
index 0000000000..9aadc39b15
--- /dev/null
+++ b/windows/winutil/src/extras/migration/migration.vcxproj.filters
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClInclude Include="stdafx.h" />
+ <ClInclude Include="targetver.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="migration.cpp" />
+ <ClCompile Include="stdafx.cpp" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/windows/winutil/src/extras/migration/stdafx.cpp b/windows/winutil/src/extras/migration/stdafx.cpp
new file mode 100644
index 0000000000..326c6605d8
--- /dev/null
+++ b/windows/winutil/src/extras/migration/stdafx.cpp
Binary files differ
diff --git a/windows/winutil/src/extras/migration/stdafx.h b/windows/winutil/src/extras/migration/stdafx.h
new file mode 100644
index 0000000000..94d4ed877d
--- /dev/null
+++ b/windows/winutil/src/extras/migration/stdafx.h
Binary files differ
diff --git a/windows/winutil/src/extras/migration/targetver.h b/windows/winutil/src/extras/migration/targetver.h
new file mode 100644
index 0000000000..567cd346ef
--- /dev/null
+++ b/windows/winutil/src/extras/migration/targetver.h
Binary files differ
diff --git a/windows/winutil/src/winutil/dllmain.cpp b/windows/winutil/src/winutil/dllmain.cpp
new file mode 100644
index 0000000000..f11c65c519
--- /dev/null
+++ b/windows/winutil/src/winutil/dllmain.cpp
@@ -0,0 +1,11 @@
+#include "stdafx.h"
+#include <windows.h>
+
+BOOL APIENTRY DllMain(HMODULE, DWORD, LPVOID)
+{
+ //
+ // Avoid doing work in DllMain since the loader lock is held
+ //
+
+ return TRUE;
+}
diff --git a/windows/winutil/src/winutil/migration.cpp b/windows/winutil/src/winutil/migration.cpp
new file mode 100644
index 0000000000..502f5a8819
--- /dev/null
+++ b/windows/winutil/src/winutil/migration.cpp
@@ -0,0 +1,133 @@
+#include "stdafx.h"
+#include "migration.h"
+#include <libcommon/filesystem.h>
+#include <experimental/filesystem>
+#include <stdexcept>
+
+namespace fs = std::experimental::filesystem;
+
+namespace migration {
+
+//
+// This is being called in a x64 SYSTEM user context
+//
+MigrationStatus MigrateAfterWindowsUpdate()
+{
+ const auto localAppData = common::fs::GetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_DEFAULT, nullptr);
+ const auto mullvadAppData = fs::path(localAppData).append(L"Mullvad VPN");
+
+ //
+ // The main settings file is 'settings.json'
+ // If this file is present inside 'mullvadAppData' we should abort the migration
+ //
+
+ const auto settingsFile = fs::path(mullvadAppData).append(L"settings.json");
+
+ if (fs::exists(settingsFile))
+ {
+ return MigrationStatus::Aborted;
+ }
+
+ //
+ // Validate backup location path and ownership
+ //
+
+ const auto backupRoot = mullvadAppData.root_path().append(L"windows.old");
+ const auto backupMullvadAppData = fs::path(backupRoot).append(mullvadAppData.relative_path());
+
+ if (false == fs::exists(backupMullvadAppData))
+ {
+ return MigrationStatus::NothingToMigrate;
+ }
+
+ DWORD bufferSize = 128;
+ std::vector<uint8_t> buffer(bufferSize);
+
+ for (;;)
+ {
+ if (FALSE == GetFileSecurityW(backupRoot.c_str(), OWNER_SECURITY_INFORMATION,
+ &buffer[0], static_cast<DWORD>(buffer.size()), &bufferSize))
+ {
+ if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
+ {
+ buffer.resize(bufferSize);
+ continue;
+ }
+
+ throw std::runtime_error("Could not acquire security descriptor of backup directory");
+ }
+
+ break;
+ }
+
+ SID *sid = nullptr;
+ BOOL ownerDefaulted = FALSE;
+
+ if (FALSE == GetSecurityDescriptorOwner(reinterpret_cast<SECURITY_DESCRIPTOR *>(&buffer[0]),
+ reinterpret_cast<PSID *>(&sid), &ownerDefaulted))
+ {
+ throw std::runtime_error("Could not determine owner of backup directory");
+ }
+
+ if (FALSE == IsWellKnownSid(sid, WinLocalSystemSid))
+ {
+ throw std::runtime_error("Backup directory is not owned by SYSTEM");
+ }
+
+ //
+ // Ensure destination directory exists
+ //
+
+ if (false == fs::exists(mullvadAppData)
+ && false == fs::create_directory(mullvadAppData))
+ {
+ throw std::runtime_error("Could not create destination directory during migration");
+ }
+
+ //
+ // Specify files that need to be copied over
+ //
+
+ struct FileMigration
+ {
+ std::wstring filename;
+ bool required;
+ };
+
+ const FileMigration filesToMigrate[] = {
+ { L"settings.json", true },
+ { L"account-history.json", false },
+ };
+
+ //
+ // Copy and delete files
+ //
+
+ bool copyStatus = true;
+
+ for (const auto file : filesToMigrate)
+ {
+ const auto from = fs::path(backupMullvadAppData).append(file.filename);
+ const auto to = fs::path(mullvadAppData).append(file.filename);
+
+ std::error_code error;
+
+ if (fs::copy_file(from, to, fs::copy_options::overwrite_existing | fs::copy_options::skip_symlinks, error))
+ {
+ fs::remove(from, error);
+ }
+ else if (file.required)
+ {
+ copyStatus = false;
+ }
+ }
+
+ if (false == copyStatus)
+ {
+ throw std::runtime_error("Failed to copy files during migration");
+ }
+
+ return MigrationStatus::Success;
+}
+
+}
diff --git a/windows/winutil/src/winutil/migration.h b/windows/winutil/src/winutil/migration.h
new file mode 100644
index 0000000000..3b9848c70a
--- /dev/null
+++ b/windows/winutil/src/winutil/migration.h
@@ -0,0 +1,18 @@
+#pragma once
+
+namespace migration {
+
+enum class MigrationStatus
+{
+ Success = 0,
+
+ // Destination already exists
+ Aborted,
+
+ // There's no backup
+ NothingToMigrate,
+};
+
+MigrationStatus MigrateAfterWindowsUpdate();
+
+}
diff --git a/windows/winutil/src/winutil/stdafx.cpp b/windows/winutil/src/winutil/stdafx.cpp
new file mode 100644
index 0000000000..4ab693824c
--- /dev/null
+++ b/windows/winutil/src/winutil/stdafx.cpp
Binary files differ
diff --git a/windows/winutil/src/winutil/stdafx.h b/windows/winutil/src/winutil/stdafx.h
new file mode 100644
index 0000000000..b937b12ccd
--- /dev/null
+++ b/windows/winutil/src/winutil/stdafx.h
Binary files differ
diff --git a/windows/winutil/src/winutil/targetver.h b/windows/winutil/src/winutil/targetver.h
new file mode 100644
index 0000000000..ae4a5c032c
--- /dev/null
+++ b/windows/winutil/src/winutil/targetver.h
@@ -0,0 +1,12 @@
+#pragma once
+
+// Including SDKDDKVer.h defines the highest available Windows platform.
+
+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
+
+#include <WinSDKVer.h>
+
+#define _WIN32_WINNT _WIN32_WINNT_WIN7
+
+#include <SDKDDKVer.h>
diff --git a/windows/winutil/src/winutil/winutil.cpp b/windows/winutil/src/winutil/winutil.cpp
new file mode 100644
index 0000000000..633e181779
--- /dev/null
+++ b/windows/winutil/src/winutil/winutil.cpp
@@ -0,0 +1,42 @@
+#include "stdafx.h"
+#include "winutil.h"
+#include "migration.h"
+#include "libcommon/valuemapper.h"
+#include <stdexcept>
+
+extern "C"
+WINUTIL_LINKAGE
+WINUTIL_MIGRATION_STATUS
+WINUTIL_API
+WinUtil_MigrateAfterWindowsUpdate(
+ WinUtilErrorSink errorSink,
+ void *errorSinkContext
+)
+{
+ try
+ {
+ using value_type = common::ValueMapper<migration::MigrationStatus, WINUTIL_MIGRATION_STATUS>::value_type;
+
+ const common::ValueMapper<migration::MigrationStatus, WINUTIL_MIGRATION_STATUS> mapper =
+ {
+ value_type(migration::MigrationStatus::Success, WINUTIL_MIGRATION_STATUS::SUCCESS),
+ value_type(migration::MigrationStatus::Aborted, WINUTIL_MIGRATION_STATUS::ABORTED),
+ value_type(migration::MigrationStatus::NothingToMigrate, WINUTIL_MIGRATION_STATUS::NOTHING_TO_MIGRATE),
+ };
+
+ return mapper.map(migration::MigrateAfterWindowsUpdate());
+ }
+ catch (const std::exception &err)
+ {
+ if (nullptr != errorSink)
+ {
+ errorSink(err.what(), errorSinkContext);
+ }
+
+ return WINUTIL_MIGRATION_STATUS::FAILED;
+ }
+ catch (...)
+ {
+ return WINUTIL_MIGRATION_STATUS::FAILED;
+ }
+}
diff --git a/windows/winutil/src/winutil/winutil.def b/windows/winutil/src/winutil/winutil.def
new file mode 100644
index 0000000000..9868cafe16
--- /dev/null
+++ b/windows/winutil/src/winutil/winutil.def
@@ -0,0 +1,3 @@
+LIBRARY winutil
+EXPORTS
+ WinUtil_MigrateAfterWindowsUpdate
diff --git a/windows/winutil/src/winutil/winutil.h b/windows/winutil/src/winutil/winutil.h
new file mode 100644
index 0000000000..8939aadc8f
--- /dev/null
+++ b/windows/winutil/src/winutil/winutil.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <cstdint>
+
+#ifdef WINUTIL_EXPORTS
+#define WINUTIL_LINKAGE __declspec(dllexport)
+#else
+#define WINUTIL_LINKAGE __declspec(dllimport)
+#endif
+
+#define WINUTIL_API __stdcall
+
+typedef void (WINUTIL_API *WinUtilErrorSink)(const char *errorMessage, void *context);
+
+enum class WINUTIL_MIGRATION_STATUS : uint32_t
+{
+ SUCCESS = 0,
+
+ // Destination already exists
+ ABORTED,
+
+ // There's no backup
+ NOTHING_TO_MIGRATE,
+
+ FAILED,
+};
+
+extern "C"
+WINUTIL_LINKAGE
+WINUTIL_MIGRATION_STATUS
+WINUTIL_API
+WinUtil_MigrateAfterWindowsUpdate(
+ WinUtilErrorSink errorSink,
+ void *errorSinkContext
+);
diff --git a/windows/winutil/src/winutil/winutil.rc b/windows/winutil/src/winutil/winutil.rc
new file mode 100644
index 0000000000..10008180e2
--- /dev/null
+++ b/windows/winutil/src/winutil/winutil.rc
Binary files differ
diff --git a/windows/winutil/src/winutil/winutil.vcxproj b/windows/winutil/src/winutil/winutil.vcxproj
new file mode 100644
index 0000000000..3359f2718b
--- /dev/null
+++ b/windows/winutil/src/winutil/winutil.vcxproj
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="dllmain.cpp" />
+ <ClCompile Include="migration.cpp" />
+ <ClCompile Include="stdafx.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="winutil.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="migration.h" />
+ <ClInclude Include="stdafx.h" />
+ <ClInclude Include="targetver.h" />
+ <ClInclude Include="winutil.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="winutil.def" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="winutil.rc" />
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>15.0</VCProjectVersion>
+ <ProjectGuid>{C075F50C-1A62-46D1-9494-02C8F48A9419}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>winutil</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)\bin\$(Platform)-$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)\bin\temp\$(Platform)-$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)\bin\$(Platform)-$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)\bin\temp\$(Platform)-$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(SolutionDir)\bin\$(Platform)-$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)\bin\temp\$(Platform)-$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(SolutionDir)\bin\$(Platform)-$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)\bin\temp\$(Platform)-$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>WIN32;_DEBUG;WINUTIL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <AdditionalIncludeDirectories>$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories>
+ <AdditionalDependencies>libcommon.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ModuleDefinitionFile>winutil.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_DEBUG;WINUTIL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <AdditionalIncludeDirectories>$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories>
+ <AdditionalDependencies>libcommon.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ModuleDefinitionFile>winutil.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>WIN32;NDEBUG;WINUTIL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <AdditionalIncludeDirectories>$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories>
+ <AdditionalDependencies>libcommon.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ModuleDefinitionFile>winutil.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>NDEBUG;WINUTIL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <AdditionalIncludeDirectories>$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories>
+ <AdditionalDependencies>libcommon.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ModuleDefinitionFile>winutil.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/windows/winutil/src/winutil/winutil.vcxproj.filters b/windows/winutil/src/winutil/winutil.vcxproj.filters
new file mode 100644
index 0000000000..52c8d08716
--- /dev/null
+++ b/windows/winutil/src/winutil/winutil.vcxproj.filters
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="dllmain.cpp" />
+ <ClCompile Include="stdafx.cpp" />
+ <ClCompile Include="winutil.cpp" />
+ <ClCompile Include="migration.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="stdafx.h" />
+ <ClInclude Include="targetver.h" />
+ <ClInclude Include="winutil.h" />
+ <ClInclude Include="migration.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="winutil.def" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="winutil.rc" />
+ </ItemGroup>
+</Project> \ No newline at end of file