diff options
| author | Odd Stranne <odd@mullvad.net> | 2018-08-16 22:06:56 +0200 |
|---|---|---|
| committer | Odd Stranne <odd@mullvad.net> | 2018-08-29 12:14:24 +0200 |
| commit | e0fbb5dfda63ebb054a47aaf88a270ab1334a68a (patch) | |
| tree | f89aae227ff12068e03842b849f5afff52eb0db0 | |
| parent | ac290fef91b3fb7fe35cffada330c56436d223ed (diff) | |
| download | mullvadvpn-e0fbb5dfda63ebb054a47aaf88a270ab1334a68a.tar.xz mullvadvpn-e0fbb5dfda63ebb054a47aaf88a270ab1334a68a.zip | |
Add uninstaller plugin for extended system cleaning
| -rw-r--r-- | windows/nsis-plugins/nsis-plugins.sln | 9 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/cleanup/cleaningops.cpp | 269 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/cleanup/cleaningops.h | 13 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/cleanup/cleanup.cpp | 81 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/cleanup/cleanup.def | 6 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/cleanup/cleanup.vcxproj | 124 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/cleanup/cleanup.vcxproj.filters | 17 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/cleanup/dllmain.cpp | 11 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/cleanup/stdafx.cpp | 8 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/cleanup/stdafx.h | 16 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/cleanup/targetver.h | 12 |
11 files changed, 566 insertions, 0 deletions
diff --git a/windows/nsis-plugins/nsis-plugins.sln b/windows/nsis-plugins/nsis-plugins.sln index 3b3e7a7f62..0f2f5533f2 100644 --- a/windows/nsis-plugins/nsis-plugins.sln +++ b/windows/nsis-plugins/nsis-plugins.sln @@ -7,6 +7,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "driverlogic", "src\driverlo {B52E2D10-A94A-4605-914A-2DCEF6A757EF} = {B52E2D10-A94A-4605-914A-2DCEF6A757EF} EndProjectSection EndProject +Project("{54BCC44A-7EAA-4BB3-8CF5-564137999875}") = "cleanup", "src\cleanup\cleanup.vcxproj", "{47B5C1C1-67D7-4544-9037-8E7F44C1E5BD}" + ProjectSection(ProjectDependencies) = postProject + {B52E2D10-A94A-4605-914A-2DCEF6A757EF} = {B52E2D10-A94A-4605-914A-2DCEF6A757EF} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcommon", "..\windows-libraries\src\libcommon\libcommon.vcxproj", "{B52E2D10-A94A-4605-914A-2DCEF6A757EF}" EndProject Global @@ -19,6 +24,10 @@ Global {AABA9AB7-A7D0-4BB5-A1FA-92F566023E0D}.Debug|x86.Build.0 = Debug|Win32 {AABA9AB7-A7D0-4BB5-A1FA-92F566023E0D}.Release|x86.ActiveCfg = Release|Win32 {AABA9AB7-A7D0-4BB5-A1FA-92F566023E0D}.Release|x86.Build.0 = Release|Win32 + {47B5C1C1-67D7-4544-9037-8E7F44C1E5BD}.Debug|x86.ActiveCfg = Debug|Win32 + {47B5C1C1-67D7-4544-9037-8E7F44C1E5BD}.Debug|x86.Build.0 = Debug|Win32 + {47B5C1C1-67D7-4544-9037-8E7F44C1E5BD}.Release|x86.ActiveCfg = Release|Win32 + {47B5C1C1-67D7-4544-9037-8E7F44C1E5BD}.Release|x86.Build.0 = Release|Win32 {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Debug|x86.ActiveCfg = Debug|Win32 {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Debug|x86.Build.0 = Debug|Win32 {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Release|x86.ActiveCfg = Release|Win32 diff --git a/windows/nsis-plugins/src/cleanup/cleaningops.cpp b/windows/nsis-plugins/src/cleanup/cleaningops.cpp new file mode 100644 index 0000000000..dd14b9035c --- /dev/null +++ b/windows/nsis-plugins/src/cleanup/cleaningops.cpp @@ -0,0 +1,269 @@ +#include "stdafx.h" +#include "cleaningops.h" +#include <libcommon/filesystem.h> +#include <libcommon/fileenumerator.h> +#include <libcommon/string.h> +#include <libcommon/memory.h> +#include <libcommon/security.h> +#include <libcommon/process.h> +#include <experimental/filesystem> +#include <utility> +#include <functional> +#include <processthreadsapi.h> + +namespace +{ + +// +// Returns range in lhs that is also present in rhs. +// Equalence/equivalence determined by 'comp'. +// +// Returns pair<lhsBegin, lhsBegin> if there is no mirrored range. +// +template<typename ForwardIterator> +std::pair<ForwardIterator, ForwardIterator> +mirrored_range +( + ForwardIterator lhsBegin, ForwardIterator lhsEnd, + ForwardIterator rhsBegin, ForwardIterator rhsEnd, + std::function<bool(const typename ForwardIterator::value_type &, const typename ForwardIterator::value_type &)> comp +) +{ + ForwardIterator begin = lhsBegin; + + while (lhsBegin != lhsEnd + && rhsBegin != rhsEnd) + { + if (false == comp(*lhsBegin, *rhsBegin)) + { + break; + } + + ++lhsBegin; + ++rhsBegin; + } + + return std::make_pair(begin, lhsBegin); +} + +std::wstring ConstructLocalAppDataPath(const std::wstring &base, const std::wstring &user, + const std::pair<std::vector<std::wstring>::iterator, std::vector<std::wstring>::iterator> &tokens) +{ + auto result = common::fs::MakePath(base, user); + + std::for_each(tokens.first, tokens.second, [&](const std::wstring &token) + { + result = common::fs::MakePath(result, token); + }); + + return result; +} + +std::wstring GetSystemUserLocalAppData() +{ + common::security::AdjustCurrentProcessTokenPrivilege(L"SeDebugPrivilege"); + + common::memory::ScopeDestructor sd; + + sd += [] + { + common::security::AdjustCurrentProcessTokenPrivilege(L"SeDebugPrivilege", false); + }; + + auto systemDir = common::fs::GetKnownFolderPath(FOLDERID_System, KF_FLAG_DEFAULT, NULL); + auto lsassPid = common::process::GetProcessIdFromName(common::fs::MakePath(systemDir, L"lsass.exe")); + + auto processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, lsassPid); + + if (nullptr == processHandle) + { + throw std::runtime_error("Failed to access the \"LSASS\" process"); + } + + HANDLE processToken; + + auto status = OpenProcessToken(processHandle, TOKEN_READ | TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &processToken); + + CloseHandle(processHandle); + + if (FALSE == status) + { + throw std::runtime_error("Failed to acquire process token for the \"LSASS\" process"); + } + + sd += [&]() + { + CloseHandle(processToken); + }; + + return common::fs::GetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_DEFAULT, processToken); +} + +} // anonymous namespace + +namespace cleaningops +{ + +void RemoveLogsCacheCurrentUser() +{ + auto localAppData = common::fs::GetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_DEFAULT, nullptr); + + auto appdir = common::fs::MakePath(localAppData, L"Mullvad VPN"); + + std::experimental::filesystem::remove_all(appdir); +} + +void RemoveLogsCacheOtherUsers() +{ + // + // Determine relative path to "local app data" from home directory. + // + // Beware, the local app data path may be overriden from its default location + // as a node somewhere beneath the home directory. + // + + auto localAppData = common::fs::GetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_DEFAULT, nullptr); + auto homeDir = common::fs::GetKnownFolderPath(FOLDERID_Profile, KF_FLAG_DEFAULT, nullptr); + + // + // Tokenize to get rid of slashes pointing in different directions. + // + auto localAppDataTokens = common::string::Tokenize(localAppData, L"\\/"); + auto homeDirTokens = common::string::Tokenize(homeDir, L"\\/"); + + auto mirror = mirrored_range + ( + localAppDataTokens.begin(), localAppDataTokens.end(), + homeDirTokens.begin(), homeDirTokens.end(), + [](const std::wstring &lhs, const std::wstring &rhs) + { + return 0 == _wcsicmp(lhs.c_str(), rhs.c_str()); + } + ); + + auto equalTokensCount = (size_t)std::distance(mirror.first, mirror.second); + + // + // Abort if "local app data" is not beneath home dir. + // + if (equalTokensCount < homeDirTokens.size()) + { + return; + } + + auto relativeLocalAppData = std::make_pair(std::next(localAppDataTokens.begin(), equalTokensCount), localAppDataTokens.end()); + auto currentUser = *homeDirTokens.rbegin(); + + // + // Find all other users and construct the most plausible path for their + // respective "local app data" dirs. + // + + auto parentHomeDir = common::fs::GetKnownFolderPath(FOLDERID_UserProfiles, KF_FLAG_DEFAULT, nullptr); + + common::fs::FileEnumerator files(parentHomeDir); + + files.addFilter(std::make_unique<common::fs::FilterDirectories>()); + files.addFilter(std::make_unique<common::fs::FilterNotRelativeDirs>()); + + auto notNamedSet = std::make_unique<common::fs::FilterNotNamedSet>(); + + notNamedSet->addObject(std::wstring(currentUser)); + notNamedSet->addObject(L"All Users"); // Redirects to 'c:\programdata'. + notNamedSet->addObject(L"Public"); // Shared documents, not an actual user or user template. + + files.addFilter(std::move(notNamedSet)); + + WIN32_FIND_DATAW file; + + while (files.next(file)) + { + auto userLocalAppData = ConstructLocalAppDataPath(files.getDirectory(), file.cFileName, relativeLocalAppData); + + std::error_code dummy; + std::experimental::filesystem::remove_all(common::fs::MakePath(userLocalAppData, L"Mullvad VPN"), dummy); + } +} + +void RemoveLogsServiceUser() +{ + auto programData = common::fs::GetKnownFolderPath(FOLDERID_ProgramData, KF_FLAG_DEFAULT, nullptr); + + auto appdir = common::fs::MakePath(programData, L"Mullvad VPN"); + + std::experimental::filesystem::remove_all(appdir); +} + +void RemoveCacheServiceUser() +{ + auto localAppData = GetSystemUserLocalAppData(); + auto mullvadAppData = common::fs::MakePath(localAppData, 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)); + files.addFilter(std::make_unique<common::fs::FilterFiles>()); + + WIN32_FIND_DATAW file; + + while (files.next(file)) + { + std::error_code dummy; + std::experimental::filesystem::remove(common::fs::MakePath(files.getDirectory(), file.cFileName), 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()); +} + +void RemoveSettingsServiceUser() +{ + auto localAppData = GetSystemUserLocalAppData(); + auto mullvadAppData = common::fs::MakePath(localAppData, 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)) + { + std::error_code dummy; + std::experimental::filesystem::remove(common::fs::MakePath(files.getDirectory(), file.cFileName), 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()); +} + +} diff --git a/windows/nsis-plugins/src/cleanup/cleaningops.h b/windows/nsis-plugins/src/cleanup/cleaningops.h new file mode 100644 index 0000000000..219d4333de --- /dev/null +++ b/windows/nsis-plugins/src/cleanup/cleaningops.h @@ -0,0 +1,13 @@ +#pragma once + +namespace cleaningops +{ + +void RemoveLogsCacheCurrentUser(); +void RemoveLogsCacheOtherUsers(); +void RemoveLogsServiceUser(); +void RemoveCacheServiceUser(); + +void RemoveSettingsServiceUser(); + +} diff --git a/windows/nsis-plugins/src/cleanup/cleanup.cpp b/windows/nsis-plugins/src/cleanup/cleanup.cpp new file mode 100644 index 0000000000..c7890d60b7 --- /dev/null +++ b/windows/nsis-plugins/src/cleanup/cleanup.cpp @@ -0,0 +1,81 @@ +#include <stdafx.h> +#include "cleaningops.h" +#include <windows.h> +#include <nsis/pluginapi.h> +#include <functional> +#include <vector> + +enum class RemoveLogsAndCacheStatus +{ + GENERAL_ERROR = 0, + SUCCESS +}; + +void __declspec(dllexport) NSISCALL RemoveLogsAndCache +( + HWND hwndParent, + int string_size, + LPTSTR variables, + stack_t **stacktop, + extra_parameters *extra, + ... +) +{ + EXDLL_INIT(); + + std::vector<std::function<void()> > functions = + { + cleaningops::RemoveLogsCacheCurrentUser, + cleaningops::RemoveLogsCacheOtherUsers, + cleaningops::RemoveLogsServiceUser, + cleaningops::RemoveCacheServiceUser, + }; + + bool success = true; + + // + // Invoke all functions and take note of any failure. + // + for (const auto &function : functions) + { + try + { + function(); + } + catch (...) + { + success = false; + } + } + + pushint(success ? RemoveLogsAndCacheStatus::SUCCESS : RemoveLogsAndCacheStatus::GENERAL_ERROR); +} + +enum class RemoveSettingsStatus +{ + GENERAL_ERROR = 0, + SUCCESS +}; + +void __declspec(dllexport) NSISCALL RemoveSettings +( + HWND hwndParent, + int string_size, + LPTSTR variables, + stack_t **stacktop, + extra_parameters *extra, + ... +) +{ + EXDLL_INIT(); + + try + { + cleaningops::RemoveSettingsServiceUser(); + pushint(RemoveSettingsStatus::SUCCESS); + } + catch (...) + { + pushint(RemoveSettingsStatus::GENERAL_ERROR); + } +} diff --git a/windows/nsis-plugins/src/cleanup/cleanup.def b/windows/nsis-plugins/src/cleanup/cleanup.def new file mode 100644 index 0000000000..590d311b7a --- /dev/null +++ b/windows/nsis-plugins/src/cleanup/cleanup.def @@ -0,0 +1,6 @@ +LIBRARY cleanup + +EXPORTS + +RemoveLogsAndCache +RemoveSettings diff --git a/windows/nsis-plugins/src/cleanup/cleanup.vcxproj b/windows/nsis-plugins/src/cleanup/cleanup.vcxproj new file mode 100644 index 0000000000..8ceab43448 --- /dev/null +++ b/windows/nsis-plugins/src/cleanup/cleanup.vcxproj @@ -0,0 +1,124 @@ +<?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> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{47B5C1C1-67D7-4544-9037-8E7F44C1E5BD}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>cleanup</RootNamespace> + <WindowsTargetPlatformVersion>10.0.16299.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> + <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> + <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)'=='Release|Win32'"> + <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>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>WIN32;_DEBUG;CLEANUP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>$(ProjectDir)../../../../dist-assets/binaries/windows/;$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories> + <LanguageStandard>stdcpplatest</LanguageStandard> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>$(ProjectDir)../../../../dist-assets/binaries/windows/nsis/;$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>libcommon.lib;pluginapi-x86-unicode.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> + <IgnoreSpecificDefaultLibraries>libc.lib</IgnoreSpecificDefaultLibraries> + <ModuleDefinitionFile>cleanup.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>WIN32;NDEBUG;CLEANUP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>$(ProjectDir)../../../../dist-assets/binaries/windows/;$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <LanguageStandard>stdcpplatest</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>$(ProjectDir)../../../../dist-assets/binaries/windows/nsis/;$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>libcommon.lib;pluginapi-x86-unicode.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> + <IgnoreSpecificDefaultLibraries>libc.lib</IgnoreSpecificDefaultLibraries> + <ModuleDefinitionFile>cleanup.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="cleaningops.h" /> + <ClInclude Include="stdafx.h" /> + <ClInclude Include="targetver.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="cleaningops.cpp" /> + <ClCompile Include="dllmain.cpp" /> + <ClCompile Include="cleanup.cpp" /> + <ClCompile Include="stdafx.cpp"> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> + </ClCompile> + </ItemGroup> + <ItemGroup> + <None Include="cleanup.def" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/windows/nsis-plugins/src/cleanup/cleanup.vcxproj.filters b/windows/nsis-plugins/src/cleanup/cleanup.vcxproj.filters new file mode 100644 index 0000000000..43d93655d9 --- /dev/null +++ b/windows/nsis-plugins/src/cleanup/cleanup.vcxproj.filters @@ -0,0 +1,17 @@ +<?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" /> + <ClInclude Include="cleaningops.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="dllmain.cpp" /> + <ClCompile Include="cleanup.cpp" /> + <ClCompile Include="stdafx.cpp" /> + <ClCompile Include="cleaningops.cpp" /> + </ItemGroup> + <ItemGroup> + <None Include="cleanup.def" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/windows/nsis-plugins/src/cleanup/dllmain.cpp b/windows/nsis-plugins/src/cleanup/dllmain.cpp new file mode 100644 index 0000000000..f11c65c519 --- /dev/null +++ b/windows/nsis-plugins/src/cleanup/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/nsis-plugins/src/cleanup/stdafx.cpp b/windows/nsis-plugins/src/cleanup/stdafx.cpp new file mode 100644 index 0000000000..3b6341d106 --- /dev/null +++ b/windows/nsis-plugins/src/cleanup/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// driverlogic.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/windows/nsis-plugins/src/cleanup/stdafx.h b/windows/nsis-plugins/src/cleanup/stdafx.h new file mode 100644 index 0000000000..f3a07375c7 --- /dev/null +++ b/windows/nsis-plugins/src/cleanup/stdafx.h @@ -0,0 +1,16 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include <windows.h> + + + +// TODO: reference additional headers your program requires here diff --git a/windows/nsis-plugins/src/cleanup/targetver.h b/windows/nsis-plugins/src/cleanup/targetver.h new file mode 100644 index 0000000000..ae4a5c032c --- /dev/null +++ b/windows/nsis-plugins/src/cleanup/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> |
