diff options
| author | David Lönnhager <david.l@mullvad.net> | 2021-02-17 13:27:23 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2021-02-17 13:27:23 +0100 |
| commit | eb497836502753fca300f84dca9d810bf733ab7e (patch) | |
| tree | ba3919abe53fbb2022396e77215527a25e450e98 | |
| parent | 9f1eeca0791459be6d62bfd7ea687fdfc4833dc8 (diff) | |
| parent | d513426b9d2b7d1616300d2ce6fdbf3e2dbb02c0 (diff) | |
| download | mullvadvpn-eb497836502753fca300f84dca9d810bf733ab7e.tar.xz mullvadvpn-eb497836502753fca300f84dca9d810bf733ab7e.zip | |
Merge branch 'improve-KB2921916-check'
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | dist-assets/windows/installer.nsh | 19 | ||||
| -rw-r--r-- | windows/nsis-plugins/nsis-plugins.sln | 9 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/osinfo/dllmain.cpp | 11 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/osinfo/osinfo.cpp | 45 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/osinfo/osinfo.def | 5 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/osinfo/osinfo.vcxproj | 124 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/osinfo/osinfo.vcxproj.filters | 19 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/osinfo/stdafx.cpp | 8 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/osinfo/stdafx.h | 16 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/osinfo/targetver.h | 12 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/osinfo/update.cpp | 97 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/osinfo/update.h | 11 |
13 files changed, 374 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 236800d178..c89daa4b0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ Line wrap the file at 100 chars. Th #### Windows - Fix failure when Wintun adapter name conflicts with that of a non-Wintun adapter. +- Fix detection of SetupAPI patch when not installed by KB2921916. ## [2021.1] - 2021-02-10 diff --git a/dist-assets/windows/installer.nsh b/dist-assets/windows/installer.nsh index 7d30b158fe..6c8f32c2c0 100644 --- a/dist-assets/windows/installer.nsh +++ b/dist-assets/windows/installer.nsh @@ -22,6 +22,11 @@ !define MULLVAD_GENERAL_ERROR 0 !define MULLVAD_SUCCESS 1 +# Return codes for KB2921916 check +!define PATCH_ERROR 0 +!define PATCH_PRESENT 1 +!define PATCH_MISSING 2 + # Return codes from driverlogic !define DL_ADAPTER_NOT_FOUND -2 !define DL_GENERAL_ERROR -1 @@ -89,15 +94,21 @@ log::Log "InstallWin7Hotfix()" - nsExec::ExecToStack '"$SYSDIR\cmd.exe" /c ""$SYSDIR\wbem\wmic.exe" qfe get hotfixid | "$SYSDIR\find.exe" "KB2921916""' + osinfo::HasWindows7Sha2Fix Pop $0 Pop $1 - ${If} $0 == 0 - log::Log "KB2921916 is already installed" + ${If} $0 == ${PATCH_PRESENT} + log::Log "KB2921916 is already installed or superseded" Goto InstallWin7Hotfix_return_success ${EndIf} + ${If} $0 == ${PATCH_ERROR} + log::LogWithDetails "Detection of KB2921916 failed" $1 + MessageBox MB_OK "Detection of KB2921916 failed" + Goto InstallWin7Hotfix_return_abort + ${EndIf} + MessageBox MB_ICONINFORMATION|MB_YESNO "Windows hotfix KB2921916 must be installed for this app to work. Continue?" IDNO InstallWin7Hotfix_return_abort log::Log "Extracting KB2921916" @@ -115,6 +126,8 @@ ${If} $0 == 3010 MessageBox MB_OK "You may need to restart your computer for the patch to take effect." ${Else} + StrCpy $R0 "Failed to install the hotfix: error $0" + log::Log $R0 MessageBox MB_OK "Failed to install the hotfix." Goto InstallWin7Hotfix_return_abort ${EndIf} diff --git a/windows/nsis-plugins/nsis-plugins.sln b/windows/nsis-plugins/nsis-plugins.sln index 487b4bebf4..102a73eb08 100644 --- a/windows/nsis-plugins/nsis-plugins.sln +++ b/windows/nsis-plugins/nsis-plugins.sln @@ -43,6 +43,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msiutil", "src\msiutil\msiu {1344152F-2BAD-4198-8E51-31AAC32BFBB2} = {1344152F-2BAD-4198-8E51-31AAC32BFBB2} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osinfo", "src\osinfo\osinfo.vcxproj", "{5ECCC4BC-599B-4F49-8D8F-63A2CF64764F}" + ProjectSection(ProjectDependencies) = postProject + {B52E2D10-A94A-4605-914A-2DCEF6A757EF} = {B52E2D10-A94A-4605-914A-2DCEF6A757EF} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x86 = Debug|x86 @@ -81,6 +86,10 @@ Global {83487059-2549-4DF9-A785-A4FD5211234B}.Debug|x86.Build.0 = Debug|Win32 {83487059-2549-4DF9-A785-A4FD5211234B}.Release|x86.ActiveCfg = Release|Win32 {83487059-2549-4DF9-A785-A4FD5211234B}.Release|x86.Build.0 = Release|Win32 + {5ECCC4BC-599B-4F49-8D8F-63A2CF64764F}.Debug|x86.ActiveCfg = Debug|Win32 + {5ECCC4BC-599B-4F49-8D8F-63A2CF64764F}.Debug|x86.Build.0 = Debug|Win32 + {5ECCC4BC-599B-4F49-8D8F-63A2CF64764F}.Release|x86.ActiveCfg = Release|Win32 + {5ECCC4BC-599B-4F49-8D8F-63A2CF64764F}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/windows/nsis-plugins/src/osinfo/dllmain.cpp b/windows/nsis-plugins/src/osinfo/dllmain.cpp new file mode 100644 index 0000000000..f11c65c519 --- /dev/null +++ b/windows/nsis-plugins/src/osinfo/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/osinfo/osinfo.cpp b/windows/nsis-plugins/src/osinfo/osinfo.cpp new file mode 100644 index 0000000000..f80a4b2b26 --- /dev/null +++ b/windows/nsis-plugins/src/osinfo/osinfo.cpp @@ -0,0 +1,45 @@ +#include <stdafx.h> +#include "../error.h" +#include "update.h" +#include <libcommon/string.h> +#include <windows.h> +#include <nsis/pluginapi.h> +#include <functional> +#include <vector> + +enum PatchStatus +{ + PATCH_ERROR = 0, + PATCH_PRESENT, + PATCH_MISSING +}; + +void __declspec(dllexport) NSISCALL HasWindows7Sha2Fix +( + HWND hwndParent, + int string_size, + LPTSTR variables, + stack_t** stacktop, + extra_parameters* extra, + ... +) +{ + EXDLL_INIT(); + + try + { + const auto success = update::HasSetupApiSha2Fix(); + pushstring(L""); + pushint(success ? PatchStatus::PATCH_PRESENT : PatchStatus::PATCH_MISSING); + } + catch (const std::exception& err) + { + pushstring(common::string::ToWide(err.what()).c_str()); + pushint(PatchStatus::PATCH_ERROR); + } + catch (...) + { + pushstring(L"Unspecified error"); + pushint(PatchStatus::PATCH_ERROR); + } +} diff --git a/windows/nsis-plugins/src/osinfo/osinfo.def b/windows/nsis-plugins/src/osinfo/osinfo.def new file mode 100644 index 0000000000..ec18cc35e8 --- /dev/null +++ b/windows/nsis-plugins/src/osinfo/osinfo.def @@ -0,0 +1,5 @@ +LIBRARY osinfo + +EXPORTS + +HasWindows7Sha2Fix diff --git a/windows/nsis-plugins/src/osinfo/osinfo.vcxproj b/windows/nsis-plugins/src/osinfo/osinfo.vcxproj new file mode 100644 index 0000000000..6935bdb2a7 --- /dev/null +++ b/windows/nsis-plugins/src/osinfo/osinfo.vcxproj @@ -0,0 +1,124 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="16.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>16.0</VCProjectVersion> + <ProjectGuid>{5ECCC4BC-599B-4F49-8D8F-63A2CF64764F}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>osinfo</RootNamespace> + <WindowsTargetPlatformVersion>10.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>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</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;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>$(ProjectDir)../../../../dist-assets/binaries/x86_64-pc-windows-msvc/;$(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/x86_64-pc-windows-msvc/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>osinfo.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;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>$(ProjectDir)../../../../dist-assets/binaries/x86_64-pc-windows-msvc/;$(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/x86_64-pc-windows-msvc/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>osinfo.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="update.h" /> + <ClInclude Include="stdafx.h" /> + <ClInclude Include="targetver.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="update.cpp" /> + <ClCompile Include="dllmain.cpp" /> + <ClCompile Include="osinfo.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="osinfo.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/osinfo/osinfo.vcxproj.filters b/windows/nsis-plugins/src/osinfo/osinfo.vcxproj.filters new file mode 100644 index 0000000000..6b31d70d05 --- /dev/null +++ b/windows/nsis-plugins/src/osinfo/osinfo.vcxproj.filters @@ -0,0 +1,19 @@ +<?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" /> + <ClInclude Include="os.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="dllmain.cpp" /> + <ClCompile Include="os.cpp" /> + <ClCompile Include="stdafx.cpp" /> + <ClCompile Include="cleaningops.cpp" /> + <ClCompile Include="os.cpp" /> + </ItemGroup> + <ItemGroup> + <None Include="os.def" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/windows/nsis-plugins/src/osinfo/stdafx.cpp b/windows/nsis-plugins/src/osinfo/stdafx.cpp new file mode 100644 index 0000000000..3b6341d106 --- /dev/null +++ b/windows/nsis-plugins/src/osinfo/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/osinfo/stdafx.h b/windows/nsis-plugins/src/osinfo/stdafx.h new file mode 100644 index 0000000000..f3a07375c7 --- /dev/null +++ b/windows/nsis-plugins/src/osinfo/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/osinfo/targetver.h b/windows/nsis-plugins/src/osinfo/targetver.h new file mode 100644 index 0000000000..ae4a5c032c --- /dev/null +++ b/windows/nsis-plugins/src/osinfo/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/nsis-plugins/src/osinfo/update.cpp b/windows/nsis-plugins/src/osinfo/update.cpp new file mode 100644 index 0000000000..4f33310236 --- /dev/null +++ b/windows/nsis-plugins/src/osinfo/update.cpp @@ -0,0 +1,97 @@ +#include <stdafx.h> +#include "update.h" +#include <libcommon/error.h> +#include <libcommon/filesystem.h> +#include <libcommon/memory.h> +#include <algorithm> +#include <fstream> +#include <filesystem> + +namespace +{ + +// Jason found this to be a reliable marker of the signature check fix: +// https://git.zx2c4.com/wireguard-windows/tree/installer/customactions.c#n145 +const char PATCH_MARKER[] = "Signature Hash"; + +} + +namespace update +{ + +bool HasSetupApiSha2Fix() +{ + common::memory::ScopeDestructor destructor; + + common::fs::ScopedNativeFileSystem nativeFileSystem; + + const auto systemDir = common::fs::GetKnownFolderPath(FOLDERID_System, KF_FLAG_DEFAULT, NULL); + const auto setupApiPath = std::filesystem::path(systemDir).append(L"setupapi.dll"); + + const auto setupApiHandle = CreateFileW( + setupApiPath.c_str(), + GENERIC_READ, + FILE_SHARE_READ, + nullptr, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + nullptr + ); + + if (INVALID_HANDLE_VALUE == setupApiHandle) + { + THROW_WINDOWS_ERROR(GetLastError(), "CreateFileW"); + } + + destructor += [=]() { + CloseHandle(setupApiHandle); + }; + + const auto mapping = CreateFileMappingW(setupApiHandle, nullptr, PAGE_READONLY, 0, 0, nullptr); + + if (nullptr == mapping) + { + THROW_WINDOWS_ERROR(GetLastError(), "CreateFileMappingW"); + } + + destructor += [=]() { + CloseHandle(mapping); + }; + + const auto bytes = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); + + if (nullptr == bytes) + { + THROW_WINDOWS_ERROR(GetLastError(), "MapViewOfFile"); + } + + destructor += [=]() { + UnmapViewOfFile(bytes); + }; + + MEMORY_BASIC_INFORMATION meminfo; + + if (0 == VirtualQuery(bytes, &meminfo, sizeof(meminfo))) + { + THROW_WINDOWS_ERROR(GetLastError(), "VirtualQuery"); + } + + constexpr auto PATCH_MARKER_SIZE = sizeof(PATCH_MARKER) - 1; + + if (meminfo.RegionSize < PATCH_MARKER_SIZE) + { + return false; + } + + for (size_t i = 0; i <= meminfo.RegionSize - PATCH_MARKER_SIZE; i++) + { + if (0 == memcmp((void*)((char*)bytes + i), PATCH_MARKER, PATCH_MARKER_SIZE)) + { + return true; + } + } + + return false; +} + +} diff --git a/windows/nsis-plugins/src/osinfo/update.h b/windows/nsis-plugins/src/osinfo/update.h new file mode 100644 index 0000000000..ae33258b56 --- /dev/null +++ b/windows/nsis-plugins/src/osinfo/update.h @@ -0,0 +1,11 @@ +#pragma once + +namespace update +{ + +// Checks whether SHA-2 signatures can be verified correctly +// on Windows 7. Without this patch, the driver cannot be +// installed from a service. +bool HasSetupApiSha2Fix(); + +} |
