aboutsummaryrefslogtreecommitdiff
path: root/src/ext
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-05-11 07:51:09 -0700
committerRob Mensching <rob@firegiant.com>2021-05-11 07:51:09 -0700
commit6e7ce6b67efe767dd61cb7653e7baef71eb9c369 (patch)
tree0492f75fddc779d5553666ee5c2eb7097cb930f5 /src/ext
parent4608361a88ef82e15caf3574ac107486f5fe135c (diff)
parent3caaf742fcd19170a8732570654d3b2cbb18830f (diff)
downloadwix-6e7ce6b67efe767dd61cb7653e7baef71eb9c369.tar.gz
wix-6e7ce6b67efe767dd61cb7653e7baef71eb9c369.tar.bz2
wix-6e7ce6b67efe767dd61cb7653e7baef71eb9c369.zip
Merge Dependency.wixext
Diffstat (limited to 'src/ext')
-rw-r--r--src/ext/Dependency/Dependency.wixext.sln61
-rw-r--r--src/ext/Dependency/Directory.Build.props27
-rw-r--r--src/ext/Dependency/Directory.Build.targets51
-rw-r--r--src/ext/Dependency/Directory.csproj.props13
-rw-r--r--src/ext/Dependency/Directory.csproj.targets26
-rw-r--r--src/ext/Dependency/Directory.vcxproj.props93
-rw-r--r--src/ext/Dependency/README.md2
-rw-r--r--src/ext/Dependency/appveyor.cmd19
-rw-r--r--src/ext/Dependency/appveyor.yml42
-rw-r--r--src/ext/Dependency/ca/custommsierrors.h5
-rw-r--r--src/ext/Dependency/ca/dependencyca.vcxproj73
-rw-r--r--src/ext/Dependency/ca/dependencyca.vcxproj.filters36
-rw-r--r--src/ext/Dependency/ca/dllmain.cpp27
-rw-r--r--src/ext/Dependency/ca/precomp.h18
-rw-r--r--src/ext/Dependency/ca/wixdepca.cpp516
-rw-r--r--src/ext/Dependency/ca/wixdepca.def8
-rw-r--r--src/ext/Dependency/nuget.config18
-rw-r--r--src/ext/Dependency/test/WixToolsetTest.Dependency/DependencyExtensionFixture.cs38
-rw-r--r--src/ext/Dependency/test/WixToolsetTest.Dependency/TestData/UsingProvides/Package.en-us.wxl11
-rw-r--r--src/ext/Dependency/test/WixToolsetTest.Dependency/TestData/UsingProvides/Package.wxs21
-rw-r--r--src/ext/Dependency/test/WixToolsetTest.Dependency/WixToolsetTest.Dependency.csproj39
-rw-r--r--src/ext/Dependency/wix.snkbin0 -> 596 bytes
-rw-r--r--src/ext/Dependency/wixext/DependencyCompiler.cs61
-rw-r--r--src/ext/Dependency/wixext/DependencyDecompiler.cs347
-rw-r--r--src/ext/Dependency/wixext/DependencyExtensionData.cs29
-rw-r--r--src/ext/Dependency/wixext/DependencyExtensionFactory.cs17
-rw-r--r--src/ext/Dependency/wixext/WixToolset.Dependency.wixext.csproj32
-rw-r--r--src/ext/Dependency/wixext/WixToolset.Dependency.wixext.nuspec25
-rw-r--r--src/ext/Dependency/wixext/WixToolset.Dependency.wixext.targets11
-rw-r--r--src/ext/Dependency/wixlib/DependencyExtension.wxs21
-rw-r--r--src/ext/Dependency/wixlib/DependencyExtension_Platform.wxi28
-rw-r--r--src/ext/Dependency/wixlib/DependencyExtension_arm64.wxs7
-rw-r--r--src/ext/Dependency/wixlib/DependencyExtension_x64.wxs7
-rw-r--r--src/ext/Dependency/wixlib/DependencyExtension_x86.wxs7
-rw-r--r--src/ext/Dependency/wixlib/caDecor.wxi39
-rw-r--r--src/ext/Dependency/wixlib/caerr.wxi96
-rw-r--r--src/ext/Dependency/wixlib/dependency.wixproj30
-rw-r--r--src/ext/Dependency/wixlib/en-us.wxl7
38 files changed, 1908 insertions, 0 deletions
diff --git a/src/ext/Dependency/Dependency.wixext.sln b/src/ext/Dependency/Dependency.wixext.sln
new file mode 100644
index 00000000..e771ddf6
--- /dev/null
+++ b/src/ext/Dependency/Dependency.wixext.sln
@@ -0,0 +1,61 @@
1
2Microsoft Visual Studio Solution File, Format Version 12.00
3# Visual Studio Version 16
4VisualStudioVersion = 16.0.30204.135
5MinimumVisualStudioVersion = 10.0.40219.1
6Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dependencyca", "src\ca\dependencyca.vcxproj", "{B86AF46C-0F90-49CC-923F-A800B088D015}"
7EndProject
8Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "dependency", "src\wixlib\dependency.wixproj", "{58ED0EC8-73F8-4EE1-8664-A53486D38EC8}"
9EndProject
10Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Dependency.wixext", "src\wixext\WixToolset.Dependency.wixext.csproj", "{A0B6D3F1-AE5E-423B-BA92-60C9926CA498}"
11EndProject
12Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.Dependency", "src\test\WixToolsetTest.Dependency\WixToolsetTest.Dependency.csproj", "{E2AB6AA2-359D-4305-92B0-D90C8F87AF9B}"
13EndProject
14Global
15 GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 Debug|Any CPU = Debug|Any CPU
17 Debug|x86 = Debug|x86
18 Release|Any CPU = Release|Any CPU
19 Release|x86 = Release|x86
20 EndGlobalSection
21 GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 {B86AF46C-0F90-49CC-923F-A800B088D015}.Debug|Any CPU.ActiveCfg = Debug|Win32
23 {B86AF46C-0F90-49CC-923F-A800B088D015}.Debug|Any CPU.Build.0 = Debug|Win32
24 {B86AF46C-0F90-49CC-923F-A800B088D015}.Debug|x86.ActiveCfg = Debug|Win32
25 {B86AF46C-0F90-49CC-923F-A800B088D015}.Debug|x86.Build.0 = Debug|Win32
26 {B86AF46C-0F90-49CC-923F-A800B088D015}.Release|Any CPU.ActiveCfg = Release|Win32
27 {B86AF46C-0F90-49CC-923F-A800B088D015}.Release|Any CPU.Build.0 = Release|Win32
28 {B86AF46C-0F90-49CC-923F-A800B088D015}.Release|x86.ActiveCfg = Release|Win32
29 {B86AF46C-0F90-49CC-923F-A800B088D015}.Release|x86.Build.0 = Release|Win32
30 {58ED0EC8-73F8-4EE1-8664-A53486D38EC8}.Debug|Any CPU.ActiveCfg = Debug|x86
31 {58ED0EC8-73F8-4EE1-8664-A53486D38EC8}.Debug|Any CPU.Build.0 = Debug|x86
32 {58ED0EC8-73F8-4EE1-8664-A53486D38EC8}.Debug|x86.ActiveCfg = Debug|x86
33 {58ED0EC8-73F8-4EE1-8664-A53486D38EC8}.Debug|x86.Build.0 = Debug|x86
34 {58ED0EC8-73F8-4EE1-8664-A53486D38EC8}.Release|Any CPU.ActiveCfg = Release|x86
35 {58ED0EC8-73F8-4EE1-8664-A53486D38EC8}.Release|Any CPU.Build.0 = Release|x86
36 {58ED0EC8-73F8-4EE1-8664-A53486D38EC8}.Release|x86.ActiveCfg = Release|x86
37 {58ED0EC8-73F8-4EE1-8664-A53486D38EC8}.Release|x86.Build.0 = Release|x86
38 {A0B6D3F1-AE5E-423B-BA92-60C9926CA498}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39 {A0B6D3F1-AE5E-423B-BA92-60C9926CA498}.Debug|Any CPU.Build.0 = Debug|Any CPU
40 {A0B6D3F1-AE5E-423B-BA92-60C9926CA498}.Debug|x86.ActiveCfg = Debug|Any CPU
41 {A0B6D3F1-AE5E-423B-BA92-60C9926CA498}.Debug|x86.Build.0 = Debug|Any CPU
42 {A0B6D3F1-AE5E-423B-BA92-60C9926CA498}.Release|Any CPU.ActiveCfg = Release|Any CPU
43 {A0B6D3F1-AE5E-423B-BA92-60C9926CA498}.Release|Any CPU.Build.0 = Release|Any CPU
44 {A0B6D3F1-AE5E-423B-BA92-60C9926CA498}.Release|x86.ActiveCfg = Release|Any CPU
45 {A0B6D3F1-AE5E-423B-BA92-60C9926CA498}.Release|x86.Build.0 = Release|Any CPU
46 {E2AB6AA2-359D-4305-92B0-D90C8F87AF9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
47 {E2AB6AA2-359D-4305-92B0-D90C8F87AF9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
48 {E2AB6AA2-359D-4305-92B0-D90C8F87AF9B}.Debug|x86.ActiveCfg = Debug|Any CPU
49 {E2AB6AA2-359D-4305-92B0-D90C8F87AF9B}.Debug|x86.Build.0 = Debug|Any CPU
50 {E2AB6AA2-359D-4305-92B0-D90C8F87AF9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
51 {E2AB6AA2-359D-4305-92B0-D90C8F87AF9B}.Release|Any CPU.Build.0 = Release|Any CPU
52 {E2AB6AA2-359D-4305-92B0-D90C8F87AF9B}.Release|x86.ActiveCfg = Release|Any CPU
53 {E2AB6AA2-359D-4305-92B0-D90C8F87AF9B}.Release|x86.Build.0 = Release|Any CPU
54 EndGlobalSection
55 GlobalSection(SolutionProperties) = preSolution
56 HideSolutionNode = FALSE
57 EndGlobalSection
58 GlobalSection(ExtensibilityGlobals) = postSolution
59 SolutionGuid = {77F012B1-8E94-4F85-9450-066C6BD15000}
60 EndGlobalSection
61EndGlobal
diff --git a/src/ext/Dependency/Directory.Build.props b/src/ext/Dependency/Directory.Build.props
new file mode 100644
index 00000000..b3c6287c
--- /dev/null
+++ b/src/ext/Dependency/Directory.Build.props
@@ -0,0 +1,27 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3<!--
4 Do NOT modify this file. Update the canonical version in Home\repo-template\src\Directory.Build.props
5 then update all of the repos.
6-->
7<Project>
8 <PropertyGroup>
9 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
10 <EnableSourceLink Condition=" '$(NCrunch)' == '1' ">false</EnableSourceLink>
11 <MSBuildWarningsAsMessages>MSB3246</MSBuildWarningsAsMessages>
12
13 <ProjectName Condition=" '$(ProjectName)' == '' ">$(MSBuildProjectName)</ProjectName>
14 <BaseOutputPath>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\build\))</BaseOutputPath>
15 <BaseIntermediateOutputPath>$(BaseOutputPath)obj\$(ProjectName)\</BaseIntermediateOutputPath>
16 <OutputPath>$(BaseOutputPath)$(Configuration)\</OutputPath>
17
18 <Authors>WiX Toolset Team</Authors>
19 <Company>WiX Toolset</Company>
20 <Copyright>Copyright (c) .NET Foundation and contributors. All rights reserved.</Copyright>
21 <PackageLicenseExpression>MS-RL</PackageLicenseExpression>
22 <Product>WiX Toolset</Product>
23 </PropertyGroup>
24
25 <Import Project="Directory$(MSBuildProjectExtension).props" Condition=" Exists('Directory$(MSBuildProjectExtension).props') " />
26 <Import Project="Custom.Build.props" Condition=" Exists('Custom.Build.props') " />
27</Project>
diff --git a/src/ext/Dependency/Directory.Build.targets b/src/ext/Dependency/Directory.Build.targets
new file mode 100644
index 00000000..2fcc765a
--- /dev/null
+++ b/src/ext/Dependency/Directory.Build.targets
@@ -0,0 +1,51 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3<!--
4 Do NOT modify this file. Update the canonical version in Home\repo-template\src\Directory.Build.targets
5 then update all of the repos.
6-->
7<!--
8 Replace PackageReferences with ProjectReferences when the projects can be found in .sln.
9 See the original here: https://github.com/dotnet/sdk/issues/1151#issuecomment-385133284
10-->
11<Project>
12 <PropertyGroup>
13 <ReplacePackageReferences>true</ReplacePackageReferences>
14 <TheSolutionPath Condition=" '$(NCrunch)'=='' ">$(SolutionPath)</TheSolutionPath>
15 <TheSolutionPath Condition=" '$(NCrunch)'=='1' ">$(NCrunchOriginalSolutionPath)</TheSolutionPath>
16 </PropertyGroup>
17
18 <Choose>
19 <When Condition="$(ReplacePackageReferences) AND '$(TheSolutionPath)' != '' AND '$(TheSolutionPath)' != '*undefined*' AND Exists('$(TheSolutionPath)')">
20
21 <PropertyGroup>
22 <SolutionFileContent>$([System.IO.File]::ReadAllText($(TheSolutionPath)))</SolutionFileContent>
23 <SmartSolutionDir>$([System.IO.Path]::GetDirectoryName( $(TheSolutionPath) ))</SmartSolutionDir>
24 <RegexPattern>(?&lt;="[PackageName]", ")(.*)(?=", ")</RegexPattern>
25 </PropertyGroup>
26
27 <ItemGroup>
28 <!-- Keep the identity of the PackageReference -->
29 <SmartPackageReference Include="@(PackageReference)">
30 <PackageName>%(Identity)</PackageName>
31 <InSolution>$(SolutionFileContent.Contains('\%(Identity).csproj'))</InSolution>
32 </SmartPackageReference>
33
34 <!-- Filter them by mapping them to another ItemGroup using the WithMetadataValue item function -->
35 <PackageInSolution Include="@(SmartPackageReference->WithMetadataValue('InSolution', True))">
36 <Pattern>$(RegexPattern.Replace('[PackageName]','%(PackageName)') )</Pattern>
37 <SmartPath>$([System.Text.RegularExpressions.Regex]::Match('$(SolutionFileContent)', '%(Pattern)'))</SmartPath>
38 </PackageInSolution>
39
40 <ProjectReference Include="@(PackageInSolution->'$(SmartSolutionDir)\%(SmartPath)' )"/>
41
42 <!-- Remove the package references that are now referenced as projects -->
43 <PackageReference Remove="@(PackageInSolution->'%(PackageName)')"/>
44 </ItemGroup>
45
46 </When>
47 </Choose>
48
49 <Import Project="Directory$(MSBuildProjectExtension).targets" Condition=" Exists('Directory$(MSBuildProjectExtension).targets') " />
50 <Import Project="Custom.Build.targets" Condition=" Exists('Custom.Build.targets') " />
51</Project>
diff --git a/src/ext/Dependency/Directory.csproj.props b/src/ext/Dependency/Directory.csproj.props
new file mode 100644
index 00000000..81d24ad1
--- /dev/null
+++ b/src/ext/Dependency/Directory.csproj.props
@@ -0,0 +1,13 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2<!--
3 Do NOT modify this file. Update the canonical version in Home\repo-template\src\CSharp.Build.props
4 then update all of the repos.
5-->
6<Project>
7 <PropertyGroup>
8 <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
9 <SignAssembly>true</SignAssembly>
10 <AssemblyOriginatorKeyFile>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)wix.snk))</AssemblyOriginatorKeyFile>
11 <NBGV_EmitThisAssemblyClass>false</NBGV_EmitThisAssemblyClass>
12 </PropertyGroup>
13</Project>
diff --git a/src/ext/Dependency/Directory.csproj.targets b/src/ext/Dependency/Directory.csproj.targets
new file mode 100644
index 00000000..c3270426
--- /dev/null
+++ b/src/ext/Dependency/Directory.csproj.targets
@@ -0,0 +1,26 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2<!--
3 Do NOT modify this file. Update the canonical version in Home\repo-template\src\Directory.csproj.targets
4 then update all of the repos.
5-->
6<Project>
7 <PropertyGroup>
8 <CreateDocumentation Condition=" '$(CreateDocumentationFile)'!='true' ">false</CreateDocumentation>
9 <DocumentationFile Condition=" '$(CreateDocumentationFile)'=='true' ">$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
10 </PropertyGroup>
11
12 <Target Name="SetNuspecProperties" DependsOnTargets="InitializeSourceControlInformation" AfterTargets="GetBuildVersion"
13 Condition=" Exists('$(MSBuildProjectName).nuspec') ">
14 <PropertyGroup>
15 <ProjectUrl Condition=" '$(ProjectUrl)'=='' and '$(PrivateRepositoryUrl)'!='' ">$(PrivateRepositoryUrl.Replace('.git',''))</ProjectUrl>
16
17 <NuspecFile>$(MSBuildProjectName).nuspec</NuspecFile>
18 <NuspecBasePath Condition=" '$(NuspecBasePath)'=='' ">$(OutputPath)..\</NuspecBasePath>
19 <NuspecProperties>$(NuspecProperties);Id=$(PackageId);Authors=$(Authors);Copyright=$(Copyright);Description=$(Description);Title=$(Title)</NuspecProperties>
20 <NuspecProperties>$(NuspecProperties);Version=$(PackageVersion);RepositoryCommit=$(SourceRevisionId);RepositoryType=$(RepositoryType);RepositoryUrl=$(PrivateRepositoryUrl);ProjectFolder=$(MSBuildProjectDirectory)\;ProjectUrl=$(ProjectUrl)</NuspecProperties>
21 <PublishRepositoryUrl>true</PublishRepositoryUrl>
22 <SymbolPackageFormat>snupkg</SymbolPackageFormat>
23 </PropertyGroup>
24 </Target>
25
26</Project>
diff --git a/src/ext/Dependency/Directory.vcxproj.props b/src/ext/Dependency/Directory.vcxproj.props
new file mode 100644
index 00000000..664bc1d8
--- /dev/null
+++ b/src/ext/Dependency/Directory.vcxproj.props
@@ -0,0 +1,93 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project>
5 <PropertyGroup>
6 <Platform Condition=" '$(Platform)' == '' OR '$(Platform)' == 'AnyCPU' ">Win32</Platform>
7 <IntDir>$(BaseIntermediateOutputPath)$(Configuration)\$(Platform)\</IntDir>
8 <OutDir>$(OutputPath)$(Platform)\</OutDir>
9
10 <!-- NBGV properties -->
11 <AssemblyCompany>$(Company)</AssemblyCompany>
12 <AssemblyCopyright>$(Copyright)</AssemblyCopyright>
13
14 <RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
15 <NuGetTargetMoniker>native,Version=v0.0</NuGetTargetMoniker>
16 </PropertyGroup>
17
18 <PropertyGroup Condition="'$(WindowsTargetPlatformVersion)'=='' AND '$(VisualStudioVersion)'>='15.0'">
19 <WindowsTargetPlatformVersion>$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0'))</WindowsTargetPlatformVersion>
20 </PropertyGroup>
21
22 <ItemDefinitionGroup>
23 <ClCompile>
24 <DisableSpecificWarnings>$(DisableSpecificCompilerWarnings)</DisableSpecificWarnings>
25 <WarningLevel>Level4</WarningLevel>
26 <AdditionalIncludeDirectories>$(ProjectDir)inc;$(MSBuildProjectDirectory);$(IntDir);$(SqlCESdkIncludePath);$(ProjectAdditionalIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
27 <PreprocessorDefinitions>WIN32;_WINDOWS;_WIN32_MSI=500;_WIN32_WINNT=0x0501;$(ArmPreprocessorDefinitions);$(UnicodePreprocessorDefinitions);_CRT_STDIO_LEGACY_WIDE_SPECIFIERS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
28 <PrecompiledHeader>Use</PrecompiledHeader>
29 <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
30 <CallingConvention Condition="'$(Platform)'=='Win32'">StdCall</CallingConvention>
31 <TreatWarningAsError>true</TreatWarningAsError>
32 <ExceptionHandling>false</ExceptionHandling>
33 <AdditionalOptions>-YlprecompDefine</AdditionalOptions>
34 <AdditionalOptions Condition=" $(PlatformToolset.StartsWith('v14')) ">/Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
35 <MultiProcessorCompilation Condition=" $(NUMBER_OF_PROCESSORS) &gt; 4 ">true</MultiProcessorCompilation>
36 </ClCompile>
37 <ResourceCompile>
38 <PreprocessorDefinitions>$(ArmPreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
39 <AdditionalIncludeDirectories>$(ProjectAdditionalResourceIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
40 </ResourceCompile>
41 <Lib>
42 <AdditionalLibraryDirectories>$(OutDir);$(AdditionalMultiTargetLibraryPath);$(ProjectAdditionalLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
43 </Lib>
44 <Link>
45 <SubSystem>$(ProjectSubSystem)</SubSystem>
46 <ModuleDefinitionFile>$(ProjectModuleDefinitionFile)</ModuleDefinitionFile>
47 <NoEntryPoint>$(ResourceOnlyDll)</NoEntryPoint>
48 <GenerateDebugInformation>true</GenerateDebugInformation>
49 <AdditionalDependencies>$(ProjectAdditionalLinkLibraries);advapi32.lib;comdlg32.lib;user32.lib;oleaut32.lib;gdi32.lib;shell32.lib;ole32.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
50 <AdditionalLibraryDirectories>$(OutDir);$(AdditionalMultiTargetLibraryPath);$(ArmLibraryDirectories);$(ProjectAdditionalLinkLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
51 <AdditionalOptions Condition=" $(PlatformToolset.StartsWith('v14')) ">/IGNORE:4099 %(AdditionalOptions)</AdditionalOptions>
52 </Link>
53 </ItemDefinitionGroup>
54
55 <ItemDefinitionGroup Condition=" '$(Platform)'=='Win32' and '$(PlatformToolset)'!='v100'">
56 <ClCompile>
57 <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
58 </ClCompile>
59 </ItemDefinitionGroup>
60 <ItemDefinitionGroup Condition=" '$(Platform)'=='arm' ">
61 <ClCompile>
62 <CallingConvention>CDecl</CallingConvention>
63 </ClCompile>
64 </ItemDefinitionGroup>
65 <ItemDefinitionGroup Condition=" '$(ConfigurationType)'=='StaticLibrary' ">
66 <ClCompile>
67 <DebugInformationFormat>OldStyle</DebugInformationFormat>
68 <OmitDefaultLibName>true</OmitDefaultLibName>
69 <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
70 </ClCompile>
71 </ItemDefinitionGroup>
72 <ItemDefinitionGroup Condition=" '$(Configuration)'=='Debug' ">
73 <ClCompile>
74 <Optimization>Disabled</Optimization>
75 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
76 <PreprocessorDefinitions>_DEBUG;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
77 <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
78 </ClCompile>
79 </ItemDefinitionGroup>
80 <ItemDefinitionGroup Condition=" '$(Configuration)'=='Release' ">
81 <ClCompile>
82 <Optimization>MinSpace</Optimization>
83 <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
84 <FunctionLevelLinking>true</FunctionLevelLinking>
85 <IntrinsicFunctions>true</IntrinsicFunctions>
86 <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
87 </ClCompile>
88 <Link>
89 <EnableCOMDATFolding>true</EnableCOMDATFolding>
90 <OptimizeReferences>true</OptimizeReferences>
91 </Link>
92 </ItemDefinitionGroup>
93</Project>
diff --git a/src/ext/Dependency/README.md b/src/ext/Dependency/README.md
new file mode 100644
index 00000000..09feba68
--- /dev/null
+++ b/src/ext/Dependency/README.md
@@ -0,0 +1,2 @@
1# Dependency.wixext
2WixToolset.Dependency.wixext - Dependency WiX Toolset Extension
diff --git a/src/ext/Dependency/appveyor.cmd b/src/ext/Dependency/appveyor.cmd
new file mode 100644
index 00000000..3450d535
--- /dev/null
+++ b/src/ext/Dependency/appveyor.cmd
@@ -0,0 +1,19 @@
1@setlocal
2@pushd %~dp0
3@set _C=Release
4@if /i "%1"=="debug" set _C=Debug
5
6:: Restore
7msbuild -p:Configuration=%_C% -t:Restore || exit /b
8
9:: Build
10msbuild -p:Configuration=%_C% src\test\WixToolsetTest.Dependency\WixToolsetTest.Dependency.csproj || exit /b
11
12:: Test
13dotnet test -c %_C% --no-build src\test\WixToolsetTest.Dependency || exit /b
14
15:: Pack
16msbuild -p:Configuration=%_C% -p:NoBuild=true -t:Pack src\wixext\WixToolset.Dependency.wixext.csproj || exit /b
17
18@popd
19@endlocal
diff --git a/src/ext/Dependency/appveyor.yml b/src/ext/Dependency/appveyor.yml
new file mode 100644
index 00000000..c53cc9cc
--- /dev/null
+++ b/src/ext/Dependency/appveyor.yml
@@ -0,0 +1,42 @@
1# Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2#
3# Do NOT modify this file. Update the canonical version in Home\repo-template\src\appveyor.yml
4# then update all of the repos.
5
6branches:
7 only:
8 - master
9 - develop
10
11image: Visual Studio 2019
12
13version: 0.0.0.{build}
14configuration: Release
15
16environment:
17 DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
18 DOTNET_CLI_TELEMETRY_OPTOUT: 1
19 NUGET_XMLDOC_MODE: skip
20
21build_script:
22 - appveyor.cmd
23
24pull_requests:
25 do_not_increment_build_number: true
26
27nuget:
28 disable_publish_on_pr: true
29
30skip_branch_with_pr: true
31skip_tags: true
32
33artifacts:
34- path: build\Release\**\*.nupkg
35 name: nuget
36- path: build\Release\**\*.snupkg
37 name: snupkg
38
39notifications:
40- provider: Slack
41 incoming_webhook:
42 secure: p5xuu+4x2JHfwGDMDe5KcG1k7gZxqYc4jWVwvyNZv5cvkubPD2waJs5yXMAXZNN7Z63/3PWHb7q4KoY/99AjauYa1nZ4c5qYqRPFRBKTHfA=
diff --git a/src/ext/Dependency/ca/custommsierrors.h b/src/ext/Dependency/ca/custommsierrors.h
new file mode 100644
index 00000000..26450452
--- /dev/null
+++ b/src/ext/Dependency/ca/custommsierrors.h
@@ -0,0 +1,5 @@
1#pragma once
2// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
3
4#define msierrDependencyMissingDependencies 26451
5#define msierrDependencyHasDependents 26452
diff --git a/src/ext/Dependency/ca/dependencyca.vcxproj b/src/ext/Dependency/ca/dependencyca.vcxproj
new file mode 100644
index 00000000..2a0760d6
--- /dev/null
+++ b/src/ext/Dependency/ca/dependencyca.vcxproj
@@ -0,0 +1,73 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
5 <ItemGroup Label="ProjectConfigurations">
6 <ProjectConfiguration Include="Debug|Win32">
7 <Configuration>Debug</Configuration>
8 <Platform>Win32</Platform>
9 </ProjectConfiguration>
10 <ProjectConfiguration Include="Release|Win32">
11 <Configuration>Release</Configuration>
12 <Platform>Win32</Platform>
13 </ProjectConfiguration>
14 <ProjectConfiguration Include="Debug|x64">
15 <Configuration>Debug</Configuration>
16 <Platform>x64</Platform>
17 </ProjectConfiguration>
18 <ProjectConfiguration Include="Release|x64">
19 <Configuration>Release</Configuration>
20 <Platform>x64</Platform>
21 </ProjectConfiguration>
22 <ProjectConfiguration Include="Debug|ARM64">
23 <Configuration>Debug</Configuration>
24 <Platform>ARM64</Platform>
25 </ProjectConfiguration>
26 <ProjectConfiguration Include="Release|ARM64">
27 <Configuration>Release</Configuration>
28 <Platform>ARM64</Platform>
29 </ProjectConfiguration>
30 </ItemGroup>
31
32 <PropertyGroup Label="Globals">
33 <ProjectGuid>{B86AF46C-0F90-49CC-923F-A800B088D015}</ProjectGuid>
34 <ConfigurationType>DynamicLibrary</ConfigurationType>
35 <PlatformToolset>v142</PlatformToolset>
36 <CharacterSet>Unicode</CharacterSet>
37 <TargetName>dependencyca</TargetName>
38 <ProjectModuleDefinitionFile>wixdepca.def</ProjectModuleDefinitionFile>
39 <Description>WiX Toolset Dependency CustomAction</Description>
40 <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
41 </PropertyGroup>
42
43 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
44 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
45
46 <PropertyGroup>
47 <ProjectAdditionalLinkLibraries>msi.lib</ProjectAdditionalLinkLibraries>
48 </PropertyGroup>
49
50 <ItemGroup>
51 <ClCompile Include="dllmain.cpp">
52 <PrecompiledHeader>Create</PrecompiledHeader>
53 </ClCompile>
54 <ClCompile Include="wixdepca.cpp" />
55 </ItemGroup>
56
57 <ItemGroup>
58 <ClInclude Include="precomp.h" />
59 </ItemGroup>
60
61 <ItemGroup>
62 <None Include="wixdepca.def" />
63 </ItemGroup>
64
65 <ItemGroup>
66 <PackageReference Include="WixToolset.Dutil" Version="4.0.72" />
67 <PackageReference Include="WixToolset.WcaUtil" Version="4.0.19" />
68 <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" />
69 <PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37" />
70 </ItemGroup>
71
72 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
73</Project>
diff --git a/src/ext/Dependency/ca/dependencyca.vcxproj.filters b/src/ext/Dependency/ca/dependencyca.vcxproj.filters
new file mode 100644
index 00000000..bfe457e2
--- /dev/null
+++ b/src/ext/Dependency/ca/dependencyca.vcxproj.filters
@@ -0,0 +1,36 @@
1<?xml version="1.0" encoding="utf-8"?>
2<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <ItemGroup>
4 <Filter Include="Source Files">
5 <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
6 <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
7 </Filter>
8 <Filter Include="Header Files">
9 <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
10 <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
11 </Filter>
12 <Filter Include="Resource Files">
13 <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
14 <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
15 </Filter>
16 </ItemGroup>
17 <ItemGroup>
18 <ClCompile Include="wixdepca.cpp">
19 <Filter>Source Files</Filter>
20 </ClCompile>
21 <ClCompile Include="dllmain.cpp">
22 <Filter>Source Files</Filter>
23 </ClCompile>
24 </ItemGroup>
25 <ItemGroup>
26 <ClInclude Include="precomp.h">
27 <Filter>Header Files</Filter>
28 </ClInclude>
29 </ItemGroup>
30 <ItemGroup>
31 <None Include="wixdepca.def">
32 <Filter>Source Files</Filter>
33 </None>
34 <None Include="packages.config" />
35 </ItemGroup>
36</Project> \ No newline at end of file
diff --git a/src/ext/Dependency/ca/dllmain.cpp b/src/ext/Dependency/ca/dllmain.cpp
new file mode 100644
index 00000000..7d299feb
--- /dev/null
+++ b/src/ext/Dependency/ca/dllmain.cpp
@@ -0,0 +1,27 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5/********************************************************************
6DllMain - standard entry point for all WiX custom actions.
7
8********************************************************************/
9extern "C" BOOL WINAPI DllMain(
10 IN HINSTANCE hInstance,
11 IN ULONG ulReason,
12 IN LPVOID)
13{
14 switch(ulReason)
15 {
16 case DLL_PROCESS_ATTACH:
17 WcaGlobalInitialize(hInstance);
18 ::DisableThreadLibraryCalls(hInstance);
19 break;
20
21 case DLL_PROCESS_DETACH:
22 WcaGlobalFinalize();
23 break;
24 }
25
26 return TRUE;
27}
diff --git a/src/ext/Dependency/ca/precomp.h b/src/ext/Dependency/ca/precomp.h
new file mode 100644
index 00000000..5fd06cff
--- /dev/null
+++ b/src/ext/Dependency/ca/precomp.h
@@ -0,0 +1,18 @@
1#pragma once
2// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
3
4
5#include <windows.h>
6#include <msiquery.h>
7#include <intsafe.h>
8#include <strsafe.h>
9
10#include "wcautil.h"
11#include "fileutil.h"
12#include "strutil.h"
13#include "memutil.h"
14#include "regutil.h"
15#include "dictutil.h"
16#include "deputil.h"
17
18#include "CustomMsiErrors.h"
diff --git a/src/ext/Dependency/ca/wixdepca.cpp b/src/ext/Dependency/ca/wixdepca.cpp
new file mode 100644
index 00000000..d6433707
--- /dev/null
+++ b/src/ext/Dependency/ca/wixdepca.cpp
@@ -0,0 +1,516 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5#define IDNOACTION 0
6#define INITIAL_STRINGDICT_SIZE 4
7
8LPCWSTR vcsDependencyProviderQuery =
9 L"SELECT `WixDependencyProvider`.`WixDependencyProvider`, `WixDependencyProvider`.`Component_`, `WixDependencyProvider`.`ProviderKey`, `WixDependencyProvider`.`Attributes` "
10 L"FROM `WixDependencyProvider`";
11enum eDependencyProviderQuery { dpqId = 1, dpqComponent, dpqProviderKey, dpqAttributes };
12
13LPCWSTR vcsDependencyQuery =
14 L"SELECT `WixDependency`.`WixDependency`, `WixDependencyProvider`.`Component_`, `WixDependency`.`ProviderKey`, `WixDependency`.`MinVersion`, `WixDependency`.`MaxVersion`, `WixDependency`.`Attributes` "
15 L"FROM `WixDependencyProvider`, `WixDependency`, `WixDependencyRef` "
16 L"WHERE `WixDependency`.`WixDependency` = `WixDependencyRef`.`WixDependency_` AND `WixDependencyProvider`.`WixDependencyProvider` = `WixDependencyRef`.`WixDependencyProvider_`";
17enum eDependencyComponentQuery { dqId = 1, dqComponent, dqProviderKey, dqMinVersion, dqMaxVersion, dqAttributes };
18
19static HRESULT EnsureRequiredDependencies(
20 __in MSIHANDLE hInstall,
21 __in BOOL fMachineContext
22 );
23
24static HRESULT EnsureAbsentDependents(
25 __in MSIHANDLE hInstall,
26 __in BOOL fMachineContext
27 );
28
29static HRESULT SplitIgnoredDependents(
30 __deref_inout STRINGDICT_HANDLE* psdIgnoredDependents
31 );
32
33static HRESULT CreateDependencyRecord(
34 __in int iMessageId,
35 __in_ecount(cDependencies) const DEPENDENCY* rgDependencies,
36 __in UINT cDependencies,
37 __out MSIHANDLE *phRecord
38 );
39
40static LPCWSTR LogDependencyName(
41 __in_z LPCWSTR wzName
42 );
43
44/***************************************************************************
45 WixDependencyRequire - Checks that all required dependencies are installed.
46
47***************************************************************************/
48extern "C" UINT __stdcall WixDependencyRequire(
49 __in MSIHANDLE hInstall
50 )
51{
52 HRESULT hr = S_OK;
53 UINT er = ERROR_SUCCESS;
54 BOOL fMachineContext = FALSE;
55
56 hr = WcaInitialize(hInstall, "WixDependencyRequire");
57 ExitOnFailure(hr, "Failed to initialize.");
58
59 hr = RegInitialize();
60 ExitOnFailure(hr, "Failed to initialize the registry functions.");
61
62 // Determine whether we're installing per-user or per-machine.
63 fMachineContext = WcaIsPropertySet("ALLUSERS");
64
65 // Check for any provider components being (re)installed that their requirements are already installed.
66 hr = EnsureRequiredDependencies(hInstall, fMachineContext);
67 ExitOnFailure(hr, "Failed to ensure required dependencies for (re)installing components.");
68
69LExit:
70 RegUninitialize();
71
72 er = FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS;
73 return WcaFinalize(er);
74}
75
76/***************************************************************************
77 WixDependencyCheck - Check dependencies based on component state.
78
79 Note: may return ERROR_NO_MORE_ITEMS to terminate the session early.
80***************************************************************************/
81extern "C" UINT __stdcall WixDependencyCheck(
82 __in MSIHANDLE hInstall
83 )
84{
85 HRESULT hr = S_OK;
86 UINT er = ERROR_SUCCESS;
87 BOOL fMachineContext = FALSE;
88
89 hr = WcaInitialize(hInstall, "WixDependencyCheck");
90 ExitOnFailure(hr, "Failed to initialize.");
91
92 hr = RegInitialize();
93 ExitOnFailure(hr, "Failed to initialize the registry functions.");
94
95 // Determine whether we're installing per-user or per-machine.
96 fMachineContext = WcaIsPropertySet("ALLUSERS");
97
98 // Check for any dependents of provider components being uninstalled.
99 hr = EnsureAbsentDependents(hInstall, fMachineContext);
100 ExitOnFailure(hr, "Failed to ensure absent dependents for uninstalling components.");
101
102LExit:
103 RegUninitialize();
104
105 er = FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS;
106 return WcaFinalize(er);
107}
108
109/***************************************************************************
110 EnsureRequiredDependencies - Check that dependencies are installed for
111 any provider component that is being installed or reinstalled.
112
113 Note: Skipped if DISABLEDEPENDENCYCHECK is set.
114***************************************************************************/
115static HRESULT EnsureRequiredDependencies(
116 __in MSIHANDLE /*hInstall*/,
117 __in BOOL fMachineContext
118 )
119{
120 HRESULT hr = S_OK;
121 DWORD er = ERROR_SUCCESS;
122 STRINGDICT_HANDLE sdDependencies = NULL;
123 HKEY hkHive = NULL;
124 PMSIHANDLE hView = NULL;
125 PMSIHANDLE hRec = NULL;
126 LPWSTR sczId = NULL;
127 LPWSTR sczComponent = NULL;
128 LPWSTR sczProviderKey = NULL;
129 LPWSTR sczMinVersion = NULL;
130 LPWSTR sczMaxVersion = NULL;
131 int iAttributes = 0;
132 WCA_TODO tComponentAction = WCA_TODO_UNKNOWN;
133 DEPENDENCY* rgDependencies = NULL;
134 UINT cDependencies = 0;
135 PMSIHANDLE hDependencyRec = NULL;
136
137 // Skip the dependency check if the WixDependency table is missing (no dependencies to check for).
138 hr = WcaTableExists(L"WixDependency");
139 if (S_FALSE == hr)
140 {
141 WcaLog(LOGMSG_STANDARD, "Skipping the dependency check since no dependencies are authored.");
142 ExitFunction1(hr = S_OK);
143 }
144
145 // If the table exists but not the others, the database was not authored correctly.
146 ExitOnFailure(hr, "Failed to check if the WixDependency table exists.");
147
148 // Initialize the dictionary to keep track of unique dependency keys.
149 hr = DictCreateStringList(&sdDependencies, INITIAL_STRINGDICT_SIZE, DICT_FLAG_CASEINSENSITIVE);
150 ExitOnFailure(hr, "Failed to initialize the unique dependency string list.");
151
152 // Set the registry hive to use depending on install context.
153 hkHive = fMachineContext ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
154
155 // Loop over the provider components.
156 hr = WcaOpenExecuteView(vcsDependencyQuery, &hView);
157 ExitOnFailure(hr, "Failed to open the query view for dependencies.");
158
159 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
160 {
161 hr = WcaGetRecordString(hRec, dqId, &sczId);
162 ExitOnFailure(hr, "Failed to get WixDependency.WixDependency.");
163
164 hr = WcaGetRecordString(hRec, dqComponent, &sczComponent);
165 ExitOnFailure(hr, "Failed to get WixDependencyProvider.Component_.");
166
167 // Skip the current component if its not being installed or reinstalled.
168 tComponentAction = WcaGetComponentToDo(sczComponent);
169 if (WCA_TODO_INSTALL != tComponentAction && WCA_TODO_REINSTALL != tComponentAction)
170 {
171 WcaLog(LOGMSG_STANDARD, "Skipping dependency check for %ls because the component %ls is not being (re)installed.", sczId, sczComponent);
172 continue;
173 }
174
175 hr = WcaGetRecordString(hRec, dqProviderKey, &sczProviderKey);
176 ExitOnFailure(hr, "Failed to get WixDependency.ProviderKey.");
177
178 hr = WcaGetRecordString(hRec, dqMinVersion, &sczMinVersion);
179 ExitOnFailure(hr, "Failed to get WixDependency.MinVersion.");
180
181 hr = WcaGetRecordString(hRec, dqMaxVersion, &sczMaxVersion);
182 ExitOnFailure(hr, "Failed to get WixDependency.MaxVersion.");
183
184 hr = WcaGetRecordInteger(hRec, dqAttributes, &iAttributes);
185 ExitOnFailure(hr, "Failed to get WixDependency.Attributes.");
186
187 // Check the registry to see if the required providers (dependencies) exist.
188 hr = DepCheckDependency(hkHive, sczProviderKey, sczMinVersion, sczMaxVersion, iAttributes, sdDependencies, &rgDependencies, &cDependencies);
189 if (E_NOTFOUND != hr)
190 {
191 ExitOnFailure(hr, "Failed dependency check for %ls.", sczId);
192 }
193 }
194
195 if (E_NOMOREITEMS != hr)
196 {
197 ExitOnFailure(hr, "Failed to enumerate all of the rows in the dependency query view.");
198 }
199 else
200 {
201 hr = S_OK;
202 }
203
204 // If we collected any dependencies in the previous check, pump a message and prompt the user.
205 if (0 < cDependencies)
206 {
207 hr = CreateDependencyRecord(msierrDependencyMissingDependencies, rgDependencies, cDependencies, &hDependencyRec);
208 ExitOnFailure(hr, "Failed to create the dependency record for message %d.", msierrDependencyMissingDependencies);
209
210 // Send a yes/no message with a warning icon since continuing could be detrimental.
211 // This is sent as a USER message to better detect whether a user or dependency-aware bootstrapper is responding
212 // or if Windows Installer or a dependency-unaware boostrapper is returning a typical default response.
213 er = WcaProcessMessage(static_cast<INSTALLMESSAGE>(INSTALLMESSAGE_USER | MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2), hDependencyRec);
214 switch (er)
215 {
216 // Only a user or dependency-aware bootstrapper that prompted the user should return IDYES to continue anyway.
217 case IDYES:
218 ExitFunction1(hr = S_OK);
219
220 // Only a user or dependency-aware bootstrapper that prompted the user should return IDNO to terminate the operation.
221 case IDNO:
222 WcaSetReturnValue(ERROR_INSTALL_USEREXIT);
223 ExitFunction1(hr = S_OK);
224
225 // A dependency-aware bootstrapper should return IDCANCEL if running silently and the operation should be canceled.
226 case IDCANCEL:
227 __fallthrough;
228
229 // Bootstrappers which are not dependency-aware may return IDOK for unhandled messages.
230 case IDOK:
231 __fallthrough;
232
233 // Windows Installer returns 0 for USER messages when silent or passive, or when a bootstrapper does not handle the message.
234 case IDNOACTION:
235 WcaSetReturnValue(ERROR_INSTALL_FAILURE);
236 ExitFunction1(hr = S_OK);
237
238 default:
239 ExitOnFailure(hr = E_UNEXPECTED, "Unexpected message response %d from user or bootstrapper application.", er);
240 }
241 }
242
243LExit:
244 ReleaseDependencyArray(rgDependencies, cDependencies);
245 ReleaseStr(sczId);
246 ReleaseStr(sczComponent);
247 ReleaseStr(sczProviderKey);
248 ReleaseStr(sczMinVersion);
249 ReleaseStr(sczMaxVersion);
250 ReleaseDict(sdDependencies);
251
252 return hr;
253}
254
255/***************************************************************************
256 EnsureAbsentDependents - Checks that there are no dependents
257 registered for providers that are being uninstalled.
258
259 Note: Skipped if UPGRADINGPRODUCTCODE is set.
260***************************************************************************/
261static HRESULT EnsureAbsentDependents(
262 __in MSIHANDLE /*hInstall*/,
263 __in BOOL fMachineContext
264 )
265{
266 HRESULT hr = S_OK;
267 DWORD er = ERROR_SUCCESS;
268 STRINGDICT_HANDLE sdIgnoredDependents = NULL;
269 HKEY hkHive = NULL;
270 PMSIHANDLE hView = NULL;
271 PMSIHANDLE hRec = NULL;
272 LPWSTR sczId = NULL;
273 LPWSTR sczComponent = NULL;
274 LPWSTR sczProviderKey = NULL;
275 int iAttributes = 0;
276 WCA_TODO tComponentAction = WCA_TODO_UNKNOWN;
277 DEPENDENCY* rgDependents = NULL;
278 UINT cDependents = 0;
279 PMSIHANDLE hDependencyRec = NULL;
280
281 // Skip the dependent check if the WixDependencyProvider table is missing (no dependency providers).
282 hr = WcaTableExists(L"WixDependencyProvider");
283 if (S_FALSE == hr)
284 {
285 WcaLog(LOGMSG_STANDARD, "Skipping the dependents check since no dependency providers are authored.");
286 ExitFunction1(hr = S_OK);
287 }
288
289 ExitOnFailure(hr, "Failed to check if the WixDependencyProvider table exists.");
290
291 // Split the IGNOREDEPENDENCIES property for use below if set. If it is "ALL", then quit now.
292 hr = SplitIgnoredDependents(&sdIgnoredDependents);
293 ExitOnFailure(hr, "Failed to get the ignored dependents.");
294
295 hr = DictKeyExists(sdIgnoredDependents, L"ALL");
296 if (E_NOTFOUND != hr)
297 {
298 ExitOnFailure(hr, "Failed to check if \"ALL\" was set in IGNOREDEPENDENCIES.");
299
300 // Otherwise...
301 WcaLog(LOGMSG_STANDARD, "Skipping the dependencies check since IGNOREDEPENDENCIES contains \"ALL\".");
302 ExitFunction();
303 }
304 else
305 {
306 // Key was not found, so proceed.
307 hr = S_OK;
308 }
309
310 // Set the registry hive to use depending on install context.
311 hkHive = fMachineContext ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
312
313 // Loop over the provider components.
314 hr = WcaOpenExecuteView(vcsDependencyProviderQuery, &hView);
315 ExitOnFailure(hr, "Failed to open the query view for dependency providers.");
316
317 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
318 {
319 hr = WcaGetRecordString(hRec, dpqId, &sczId);
320 ExitOnFailure(hr, "Failed to get WixDependencyProvider.WixDependencyProvider.");
321
322 hr = WcaGetRecordString(hRec, dpqComponent, &sczComponent);
323 ExitOnFailure(hr, "Failed to get WixDependencyProvider.Component.");
324
325 // Skip the current component if its not being uninstalled.
326 tComponentAction = WcaGetComponentToDo(sczComponent);
327 if (WCA_TODO_UNINSTALL != tComponentAction)
328 {
329 WcaLog(LOGMSG_STANDARD, "Skipping dependents check for %ls because the component %ls is not being uninstalled.", sczId, sczComponent);
330 continue;
331 }
332
333 hr = WcaGetRecordString(hRec, dpqProviderKey, &sczProviderKey);
334 ExitOnFailure(hr, "Failed to get WixDependencyProvider.ProviderKey.");
335
336 hr = WcaGetRecordInteger(hRec, dpqAttributes, &iAttributes);
337 ExitOnFailure(hr, "Failed to get WixDependencyProvider.Attributes.");
338
339 // Check the registry to see if the provider has any dependents registered.
340 hr = DepCheckDependents(hkHive, sczProviderKey, iAttributes, sdIgnoredDependents, &rgDependents, &cDependents);
341 ExitOnFailure(hr, "Failed dependents check for %ls.", sczId);
342 }
343
344 if (E_NOMOREITEMS != hr)
345 {
346 ExitOnFailure(hr, "Failed to enumerate all of the rows in the dependency provider query view.");
347 }
348 else
349 {
350 hr = S_OK;
351 }
352
353 // If we collected any providers with dependents in the previous check, pump a message and prompt the user.
354 if (0 < cDependents)
355 {
356 hr = CreateDependencyRecord(msierrDependencyHasDependents, rgDependents, cDependents, &hDependencyRec);
357 ExitOnFailure(hr, "Failed to create the dependency record for message %d.", msierrDependencyHasDependents);
358
359 // Send a yes/no message with a warning icon since continuing could be detrimental.
360 // This is sent as a USER message to better detect whether a user or dependency-aware bootstrapper is responding
361 // or if Windows Installer or a dependency-unaware boostrapper is returning a typical default response.
362 er = WcaProcessMessage(static_cast<INSTALLMESSAGE>(INSTALLMESSAGE_USER | MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2), hDependencyRec);
363 switch (er)
364 {
365 // Only a user or dependency-aware bootstrapper that prompted the user should return IDYES to continue anyway.
366 case IDYES:
367 ExitFunction1(hr = S_OK);
368
369 // Only a user or dependency-aware bootstrapper that prompted the user should return IDNO to terminate the operation.
370 case IDNO:
371 __fallthrough;
372
373 // Bootstrappers which are not dependency-aware may return IDOK for unhandled messages.
374 case IDOK:
375 __fallthrough;
376
377 // Windows Installer returns 0 for USER messages when silent or passive, or when a bootstrapper does not handle the message.
378 case IDNOACTION:
379 WcaSetReturnValue(ERROR_NO_MORE_ITEMS);
380 ExitFunction1(hr = S_OK);
381
382 // A dependency-aware bootstrapper should return IDCANCEL if running silently and the operation should be canceled.
383 case IDCANCEL:
384 WcaSetReturnValue(ERROR_INSTALL_FAILURE);
385 ExitFunction1(hr = S_OK);
386
387 default:
388 hr = E_UNEXPECTED;
389 ExitOnFailure(hr, "Unexpected message response %d from user or bootstrapper application.", er);
390 }
391 }
392
393LExit:
394 ReleaseDependencyArray(rgDependents, cDependents);
395 ReleaseStr(sczId);
396 ReleaseStr(sczComponent);
397 ReleaseStr(sczProviderKey);
398
399 return hr;
400}
401
402/***************************************************************************
403 SplitIgnoredDependents - Splits the IGNOREDEPENDENCIES property into a map.
404
405***************************************************************************/
406static HRESULT SplitIgnoredDependents(
407 __deref_inout STRINGDICT_HANDLE* psdIgnoredDependents
408 )
409{
410 HRESULT hr = S_OK;
411 LPWSTR sczIgnoreDependencies = NULL;
412 LPCWSTR wzDelim = L";";
413 LPWSTR wzContext = NULL;
414
415 hr = WcaGetProperty(L"IGNOREDEPENDENCIES", &sczIgnoreDependencies);
416 ExitOnFailure(hr, "Failed to get the string value of the IGNOREDEPENDENCIES property.");
417
418 hr = DictCreateStringList(psdIgnoredDependents, INITIAL_STRINGDICT_SIZE, DICT_FLAG_CASEINSENSITIVE);
419 ExitOnFailure(hr, "Failed to create the string dictionary.");
420
421 // Parse through the semicolon-delimited tokens and add to the string dictionary.
422 for (LPCWSTR wzToken = ::wcstok_s(sczIgnoreDependencies, wzDelim, &wzContext); wzToken; wzToken = ::wcstok_s(NULL, wzDelim, &wzContext))
423 {
424 hr = DictAddKey(*psdIgnoredDependents, wzToken);
425 ExitOnFailure(hr, "Failed to ignored dependency \"%ls\" to the string dictionary.", wzToken);
426 }
427
428LExit:
429 ReleaseStr(sczIgnoreDependencies);
430
431 return hr;
432}
433
434/***************************************************************************
435 CreateDependencyRecord - Creates a record containing the message template
436 and records to send to the UI handler.
437
438 Notes: Callers should call WcaProcessMessage and handle return codes.
439***************************************************************************/
440static HRESULT CreateDependencyRecord(
441 __in int iMessageId,
442 __in_ecount(cDependencies) const DEPENDENCY* rgDependencies,
443 __in UINT cDependencies,
444 __out MSIHANDLE *phRecord
445 )
446{
447 HRESULT hr = S_OK;
448 UINT er = ERROR_SUCCESS;
449 UINT cParams = 0;
450 UINT iParam = 0;
451
452 // Should not be PMSIHANDLE.
453 MSIHANDLE hRec = NULL;
454
455 // Calculate the number of parameters based on the format:
456 // msgId, count, key1, name1, key2, name2, etc.
457 cParams = 2 + 2 * cDependencies;
458
459 hRec = ::MsiCreateRecord(cParams);
460 ExitOnNull(hRec, hr, E_OUTOFMEMORY, "Not enough memory to create the message record.");
461
462 er = ::MsiRecordSetInteger(hRec, ++iParam, iMessageId);
463 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set the message identifier into the message record.");
464
465 er = ::MsiRecordSetInteger(hRec, ++iParam, cDependencies);
466 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set the number of dependencies into the message record.");
467
468 // Now loop through each dependency and add the key and name to the record.
469 for (UINT i = 0; i < cDependencies; i++)
470 {
471 const DEPENDENCY* pDependency = &rgDependencies[i];
472
473 // Log message type-specific information.
474 switch (iMessageId)
475 {
476 // Send a user message when installing a component that is missing some dependencies.
477 case msierrDependencyMissingDependencies:
478 WcaLog(LOGMSG_VERBOSE, "The dependency \"%ls\" is missing or is not the required version.", pDependency->sczKey);
479 break;
480
481 // Send a user message when uninstalling a component that still has registered dependents.
482 case msierrDependencyHasDependents:
483 WcaLog(LOGMSG_VERBOSE, "Found dependent \"%ls\", name: \"%ls\".", pDependency->sczKey, LogDependencyName(pDependency->sczName));
484 break;
485 }
486
487 er = ::MsiRecordSetStringW(hRec, ++iParam, pDependency->sczKey);
488 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set the dependency key \"%ls\" into the message record.", pDependency->sczKey);
489
490 er = ::MsiRecordSetStringW(hRec, ++iParam, pDependency->sczName);
491 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set the dependency name \"%ls\" into the message record.", pDependency->sczName);
492 }
493
494 // Only assign the out parameter if successful to this point.
495 *phRecord = hRec;
496 hRec = NULL;
497
498LExit:
499 if (hRec)
500 {
501 ::MsiCloseHandle(hRec);
502 }
503
504 return hr;
505}
506
507/***************************************************************************
508 LogDependencyName - Returns the dependency name or "Unknown" if null.
509
510***************************************************************************/
511static LPCWSTR LogDependencyName(
512 __in_z LPCWSTR wzName
513 )
514{
515 return wzName ? wzName : L"Unknown";
516}
diff --git a/src/ext/Dependency/ca/wixdepca.def b/src/ext/Dependency/ca/wixdepca.def
new file mode 100644
index 00000000..651c6373
--- /dev/null
+++ b/src/ext/Dependency/ca/wixdepca.def
@@ -0,0 +1,8 @@
1; Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3
4LIBRARY "dependencyca"
5
6EXPORTS
7 WixDependencyRequire
8 WixDependencyCheck
diff --git a/src/ext/Dependency/nuget.config b/src/ext/Dependency/nuget.config
new file mode 100644
index 00000000..10ef488d
--- /dev/null
+++ b/src/ext/Dependency/nuget.config
@@ -0,0 +1,18 @@
1<?xml version="1.0" encoding="utf-8"?>
2<configuration>
3 <packageSources>
4 <clear />
5 <add key="wixtoolset-burn" value="https://ci.appveyor.com/nuget/wixtoolset-burn" />
6 <add key="wixtoolset-data" value="https://ci.appveyor.com/nuget/wixtoolset-data" />
7 <add key="wixtoolset-extensibility" value="https://ci.appveyor.com/nuget/wixtoolset-extensibility" />
8 <add key="wixtoolset-core" value="https://ci.appveyor.com/nuget/wixtoolset-core" />
9 <add key="wixtoolset-core-native" value="https://ci.appveyor.com/nuget/wixtoolset-core-native" />
10 <add key="wixtoolset-data" value="https://ci.appveyor.com/nuget/wixtoolset-data" />
11 <add key="wixtoolset-dtf" value="https://ci.appveyor.com/nuget/wixtoolset-dtf" />
12 <add key="wixtoolset-dutil" value="https://ci.appveyor.com/nuget/wixtoolset-dutil" />
13 <add key="wixtoolset-wcautil" value="https://ci.appveyor.com/nuget/wixtoolset-wcautil" />
14 <add key="wixtoolset-tools" value="https://ci.appveyor.com/nuget/wixtoolset-tools" />
15 <add key="wixbuildtools" value="https://ci.appveyor.com/nuget/wixbuildtools" />
16 <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
17 </packageSources>
18</configuration> \ No newline at end of file
diff --git a/src/ext/Dependency/test/WixToolsetTest.Dependency/DependencyExtensionFixture.cs b/src/ext/Dependency/test/WixToolsetTest.Dependency/DependencyExtensionFixture.cs
new file mode 100644
index 00000000..708ae658
--- /dev/null
+++ b/src/ext/Dependency/test/WixToolsetTest.Dependency/DependencyExtensionFixture.cs
@@ -0,0 +1,38 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolsetTest.Dependency
4{
5 using System.Linq;
6 using System.Text.RegularExpressions;
7 using WixBuildTools.TestSupport;
8 using WixToolset.Core.TestPackage;
9 using WixToolset.Dependency;
10 using Xunit;
11
12 public class DependencyExtensionFixture
13 {
14 [Fact]
15 public void CanBuildUsingProvides()
16 {
17 var folder = TestData.Get(@"TestData\UsingProvides");
18 var build = new Builder(folder, typeof(DependencyExtensionFactory), new[] { folder });
19
20 var results = build.BuildAndQuery(Build, "CustomAction", "WixDependencyProvider")
21 .Select(r => Regex.Replace(r, "{[^}]*}", "{*}"))
22 .ToArray();
23 WixAssert.CompareLineByLine(new[]
24 {
25 "CustomAction:Wix4DependencyCheck_X86\t1\tDependencyCA_X86\tWixDependencyCheck\t",
26 "CustomAction:Wix4DependencyRequire_X86\t1\tDependencyCA_X86\tWixDependencyRequire\t",
27 "WixDependencyProvider:dep74OfIcniaqxA7EprRGBw4Oyy3r8\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo\tUsingProvides\t\t\t",
28 "WixDependencyProvider:depTpv28q7slcxvXPWmU4Z0GfbiI.4\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo\t{*}\t\t\t",
29 }, results);
30 }
31
32 private static void Build(string[] args)
33 {
34 var result = WixRunner.Execute(args)
35 .AssertSuccess();
36 }
37 }
38}
diff --git a/src/ext/Dependency/test/WixToolsetTest.Dependency/TestData/UsingProvides/Package.en-us.wxl b/src/ext/Dependency/test/WixToolsetTest.Dependency/TestData/UsingProvides/Package.en-us.wxl
new file mode 100644
index 00000000..38c12ac1
--- /dev/null
+++ b/src/ext/Dependency/test/WixToolsetTest.Dependency/TestData/UsingProvides/Package.en-us.wxl
@@ -0,0 +1,11 @@
1<?xml version="1.0" encoding="utf-8"?>
2
3<!--
4This file contains the declaration of all the localizable strings.
5-->
6<WixLocalization xmlns="http://wixtoolset.org/schemas/v4/wxl" Culture="en-US">
7
8 <String Id="DowngradeError">A newer version of [ProductName] is already installed.</String>
9 <String Id="FeatureTitle">MsiPackage</String>
10
11</WixLocalization>
diff --git a/src/ext/Dependency/test/WixToolsetTest.Dependency/TestData/UsingProvides/Package.wxs b/src/ext/Dependency/test/WixToolsetTest.Dependency/TestData/UsingProvides/Package.wxs
new file mode 100644
index 00000000..65984395
--- /dev/null
+++ b/src/ext/Dependency/test/WixToolsetTest.Dependency/TestData/UsingProvides/Package.wxs
@@ -0,0 +1,21 @@
1<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
2 xmlns:dep="http://wixtoolset.org/schemas/v4/wxs/dependency">
3 <Package Name="MsiPackage" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a" InstallerVersion="200">
4 <MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" />
5
6 <StandardDirectory Id="ProgramFilesFolder">
7 <Directory Id="INSTALLFOLDER" Name="MsiPackage" />
8 </StandardDirectory>
9
10 <Feature Id="ProductFeature" Title="!(loc.FeatureTitle)">
11 <Component Directory="INSTALLFOLDER">
12 <File Name="example.txt" Source="Package.wxs" />
13 <Provides Key="UsingProvides" dep:Check="yes" />
14 <Provides>
15 <Requires ProviderKey="UsingRequires" Minimum="1.0.0.0" dep:Enforce="yes" />
16 </Provides>
17 </Component>
18 </Feature>
19
20 </Package>
21</Wix>
diff --git a/src/ext/Dependency/test/WixToolsetTest.Dependency/WixToolsetTest.Dependency.csproj b/src/ext/Dependency/test/WixToolsetTest.Dependency/WixToolsetTest.Dependency.csproj
new file mode 100644
index 00000000..0b80dc83
--- /dev/null
+++ b/src/ext/Dependency/test/WixToolsetTest.Dependency/WixToolsetTest.Dependency.csproj
@@ -0,0 +1,39 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup>
6 <TargetFramework>netcoreapp3.1</TargetFramework>
7 <DebugType>embedded</DebugType>
8 <IsPackable>false</IsPackable>
9 </PropertyGroup>
10
11 <PropertyGroup>
12 <NoWarn>NU1701</NoWarn>
13 </PropertyGroup>
14
15 <ItemGroup>
16 <Content Include="TestData\**" CopyToOutputDirectory="PreserveNewest" />
17 </ItemGroup>
18
19 <ItemGroup>
20 <ProjectReference Include="..\..\wixext\WixToolset.Dependency.wixext.csproj" />
21 </ItemGroup>
22
23 <ItemGroup>
24 <PackageReference Include="WixToolset.Core" Version="4.0.*" />
25 <PackageReference Include="WixToolset.Core.Burn" Version="4.0.*" />
26 <PackageReference Include="WixToolset.Core.WindowsInstaller" Version="4.0.*" />
27 <PackageReference Include="WixToolset.Core.TestPackage" Version="4.0.*" />
28 </ItemGroup>
29
30 <ItemGroup>
31 <PackageReference Include="WixBuildTools.TestSupport" Version="4.0.*" />
32 </ItemGroup>
33
34 <ItemGroup>
35 <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
36 <PackageReference Include="xunit" Version="2.4.1" />
37 <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" PrivateAssets="All" />
38 </ItemGroup>
39</Project>
diff --git a/src/ext/Dependency/wix.snk b/src/ext/Dependency/wix.snk
new file mode 100644
index 00000000..3908a66a
--- /dev/null
+++ b/src/ext/Dependency/wix.snk
Binary files differ
diff --git a/src/ext/Dependency/wixext/DependencyCompiler.cs b/src/ext/Dependency/wixext/DependencyCompiler.cs
new file mode 100644
index 00000000..3d6c84a7
--- /dev/null
+++ b/src/ext/Dependency/wixext/DependencyCompiler.cs
@@ -0,0 +1,61 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Dependency
4{
5 using System.Collections.Generic;
6 using System.Xml.Linq;
7 using WixToolset.Data;
8 using WixToolset.Extensibility;
9 using WixToolset.Extensibility.Data;
10
11 /// <summary>
12 /// The compiler for the WiX Toolset Dependency Extension.
13 /// </summary>
14 public sealed class DependencyCompiler : BaseCompilerExtension
15 {
16 public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/dependency";
17
18 /// <summary>
19 /// Processes an attribute for the Compiler.
20 /// </summary>
21 /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
22 /// <param name="parentElement">Parent element of attribute.</param>
23 /// <param name="attribute">Attribute to process.</param>
24 public override void ParseAttribute(Intermediate intermediate, IntermediateSection section, XElement parentElement, XAttribute attribute, IDictionary<string, string> context)
25 {
26 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(parentElement);
27 var addCheck = YesNoType.NotSet;
28 var addRequire = YesNoType.NotSet;
29
30 switch (parentElement.Name.LocalName)
31 {
32 case "Provides":
33 if (attribute.Name.LocalName == "Check" && parentElement.Parent?.Name.LocalName == "Component")
34 {
35 addCheck = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute);
36 }
37 break;
38 case "Requires":
39 case "RequiresRef":
40 if (attribute.Name.LocalName == "Enforce" && parentElement.Parent?.Parent?.Name.LocalName == "Component")
41 {
42 addRequire = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute);
43 }
44 break;
45 }
46
47 if (addCheck == YesNoType.NotSet && addRequire == YesNoType.NotSet)
48 {
49 this.ParseHelper.UnexpectedAttribute(parentElement, attribute);
50 }
51 else if (addCheck == YesNoType.Yes)
52 {
53 this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4DependencyCheck", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64);
54 }
55 else if (addRequire == YesNoType.Yes)
56 {
57 this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4DependencyRequire", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64);
58 }
59 }
60 }
61}
diff --git a/src/ext/Dependency/wixext/DependencyDecompiler.cs b/src/ext/Dependency/wixext/DependencyDecompiler.cs
new file mode 100644
index 00000000..31de3097
--- /dev/null
+++ b/src/ext/Dependency/wixext/DependencyDecompiler.cs
@@ -0,0 +1,347 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Dependency
4{
5#if TODO_CONSIDER_DECOMPILER
6 using System;
7 using System.Collections.Generic;
8 using System.Collections.ObjectModel;
9 using WixToolset;
10 using WixToolset.Data;
11 using WixToolset.Extensibility;
12 using WixToolset.Extensions.Serialize.Dependency;
13 using Dependency = WixToolset.Extensions.Serialize.Dependency;
14 using Wix = WixToolset.Data.Serialize;
15
16 /// <summary>
17 /// The decompiler for the WiX toolset dependency extension.
18 /// </summary>
19 public sealed class DependencyDecompiler : DecompilerExtension
20 {
21 private RegistryKeyValueCollection registryValues;
22 private Dictionary<string, string> keyCache;
23
24 /// <summary>
25 /// Creates a new instance of the <see cref="DependencyDecompiler"/> class.
26 /// </summary>
27 public DependencyDecompiler()
28 {
29 this.registryValues = new RegistryKeyValueCollection();
30 this.keyCache = new Dictionary<string, string>();
31
32 this.TableDefinitions = DependencyExtensionData.GetExtensionTableDefinitions();
33 }
34
35 /// <summary>
36 /// Get the extensions library to be removed.
37 /// </summary>
38 /// <param name="tableDefinitions">Table definitions for library.</param>
39 /// <returns>Library to remove from decompiled output.</returns>
40 public override Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions)
41 {
42 return DependencyExtensionData.GetExtensionLibrary(tableDefinitions);
43 }
44
45 /// <summary>
46 /// Decompiles an extension table.
47 /// </summary>
48 /// <param name="table">The table to decompile.</param>
49 public override void DecompileTable(Table table)
50 {
51 switch (table.Name)
52 {
53 case "WixDependencyProvider":
54 this.DecompileWixDependencyProviderTable(table);
55 break;
56
57 case "WixDependency":
58 this.DecompileWixDependencyTable(table);
59 break;
60
61 case "WixDependencyRef":
62 this.DecompileWixDependencyRefTable(table);
63 break;
64
65 default:
66 base.DecompileTable(table);
67 break;
68 }
69 }
70
71 /// <summary>
72 /// Finalize decompilation by removing registry values that the compiler writes.
73 /// </summary>
74 /// <param name="tables">The collection of all tables.</param>
75 public override void Finish(TableIndexedCollection tables)
76 {
77 // Remove generated registry rows.
78 this.FinalizeRegistryTable(tables);
79
80 // Remove extension properties.
81 this.FinalizeProperties();
82 }
83
84 /// <summary>
85 /// Decompiles the WixDependencyProvider table.
86 /// </summary>
87 /// <param name="table">The table to decompile.</param>
88 private void DecompileWixDependencyProviderTable(Table table)
89 {
90 foreach (Row row in table.Rows)
91 {
92 Provides provides = new Provides();
93
94 provides.Id = (string)row[0];
95 provides.Key = (string)row[2];
96
97 if (null != row[3])
98 {
99 provides.Version = (string)row[3];
100 }
101
102 if (null != row[4])
103 {
104 provides.DisplayName = (string)row[4];
105 }
106
107 // Nothing to parse for attributes currently.
108
109 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]);
110 if (null != component)
111 {
112 component.AddChild(provides);
113 }
114 else
115 {
116 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component"));
117 }
118
119 // Index the provider to parent the RequiresRef elements.
120 this.Core.IndexElement(row, provides);
121
122 // Add the provider-specific registry keys to be removed during finalization.
123 // Only remove specific keys that the compiler writes.
124 string keyProvides = String.Concat(DependencyCommon.RegistryRoot, provides.Key);
125
126 this.registryValues.Add(keyProvides, null);
127 this.registryValues.Add(keyProvides, "Version");
128 this.registryValues.Add(keyProvides, "DisplayName");
129 this.registryValues.Add(keyProvides, "Attributes");
130
131 // Cache the provider key.
132 this.keyCache[provides.Id] = provides.Key;
133 }
134 }
135
136 /// <summary>
137 /// Decompiles the WixDependency table.
138 /// </summary>
139 /// <param name="table">The table to decompile.</param>
140 private void DecompileWixDependencyTable(Table table)
141 {
142 foreach (Row row in table.Rows)
143 {
144 Requires requires = new Requires();
145
146 requires.Id = (string)row[0];
147 requires.ProviderKey = (string)row[1];
148
149 if (null != row[2])
150 {
151 requires.Minimum = (string)row[2];
152 }
153
154 if (null != row[3])
155 {
156 requires.Maximum = (string)row[3];
157 }
158
159 if (null != row[4])
160 {
161 int attributes = (int)row[4];
162
163 if (0 != (attributes & DependencyCommon.RequiresAttributesMinVersionInclusive))
164 {
165 requires.IncludeMinimum = Dependency.YesNoType.yes;
166 }
167
168 if (0 != (attributes & DependencyCommon.RequiresAttributesMaxVersionInclusive))
169 {
170 requires.IncludeMaximum = Dependency.YesNoType.yes;
171 }
172 }
173
174 this.Core.RootElement.AddChild(requires);
175
176 // Cache the requires key.
177 this.keyCache[requires.Id] = requires.ProviderKey;
178 }
179 }
180
181 /// <summary>
182 /// Decompiles the WixDependencyRef table.
183 /// </summary>
184 /// <param name="table">The table to decompile.</param>
185 private void DecompileWixDependencyRefTable(Table table)
186 {
187 foreach (Row row in table.Rows)
188 {
189 RequiresRef requiresRef = new RequiresRef();
190
191 requiresRef.Id = (string)row[1];
192
193 Provides provides = (Provides)this.Core.GetIndexedElement("WixDependencyProvider", (string)row[0]);
194 if (null != provides)
195 {
196 provides.AddChild(requiresRef);
197 }
198 else
199 {
200 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "WixDependencyProvider_", (string)row[0], "WixDependencyProvider"));
201 }
202
203 // Get the cached keys for the provider and dependency IDs and generate registry rows.
204 string providesKey = null;
205 string requiresKey = null;
206
207 if (null != provides && this.keyCache.ContainsKey(provides.Id))
208 {
209 providesKey = this.keyCache[provides.Id];
210 }
211 else
212 {
213 this.Core.OnMessage(DependencyWarnings.ProvidesKeyNotFound(row.SourceLineNumbers, provides.Id));
214 }
215
216 if (this.keyCache.ContainsKey(requiresRef.Id))
217 {
218 requiresKey = this.keyCache[requiresRef.Id];
219 }
220 else
221 {
222 this.Core.OnMessage(DependencyWarnings.RequiresKeyNotFound(row.SourceLineNumbers, requiresRef.Id));
223 }
224
225 if (!this.Core.EncounteredError)
226 {
227 // Add the dependency-specific registry keys to be removed during finalization.
228 // Only remove specific keys that the compiler writes.
229 string keyRequires = String.Format(@"{0}{1}\{2}\{3}", DependencyCommon.RegistryRoot, requiresKey, DependencyCommon.RegistryDependents, providesKey);
230
231 this.registryValues.Add(keyRequires, "*");
232 this.registryValues.Add(keyRequires, "MinVersion");
233 this.registryValues.Add(keyRequires, "MaxVersion");
234 this.registryValues.Add(keyRequires, "Attributes");
235 }
236 }
237 }
238
239 /// <summary>
240 /// Removes rows from the Registry table that are generated by this extension.
241 /// </summary>
242 /// <param name="tables">The collection of tables.</param>
243 private void FinalizeRegistryTable(TableIndexedCollection tables)
244 {
245 Table registryTable = tables["Registry"];
246 if (null != registryTable)
247 {
248 foreach (Row registryRow in registryTable.Rows)
249 {
250 // Check if the compiler writes this registry value; if so, it should be removed.
251 if (this.registryValues.Contains(registryRow))
252 {
253 Wix.ISchemaElement elem = this.Core.GetIndexedElement(registryRow);
254
255 // If the registry row was found, remove it from its parent.
256 if (null != elem && null != elem.ParentElement)
257 {
258 Wix.IParentElement elemParent = elem.ParentElement as Wix.IParentElement;
259 if (null != elemParent)
260 {
261 elemParent.RemoveChild(elem);
262 }
263 }
264 }
265 }
266 }
267 }
268
269 /// <summary>
270 /// Removes properties defined by this extension.
271 /// </summary>
272 /// <param name="tables">The collection of tables.</param>
273 private void FinalizeProperties()
274 {
275 string[] properties = new string[] { "DISABLEDEPENDENCYCHECK", "IGNOREDEPENDENCIES" };
276 foreach (string property in properties)
277 {
278 Wix.Property elem = this.Core.GetIndexedElement("Property", property) as Wix.Property;
279 if (null != elem)
280 {
281 // If a value is defined, log a warning we're removing it.
282 if (!String.IsNullOrEmpty(elem.Value))
283 {
284 this.Core.OnMessage(DependencyWarnings.PropertyRemoved(elem.Id));
285 }
286
287 // If the property row was found, remove it from its parent.
288 if (null != elem.ParentElement)
289 {
290 Wix.IParentElement elemParent = elem.ParentElement as Wix.IParentElement;
291 if (null != elemParent)
292 {
293 elemParent.RemoveChild(elem);
294 }
295 }
296 }
297 }
298 }
299
300 /// <summary>
301 /// Provides an O(1) lookup for registry key and value name pairs for use in the decompiler.
302 /// </summary>
303 private sealed class RegistryKeyValueCollection : KeyedCollection<int, KeyValuePair<string, string>>
304 {
305 /// <summary>
306 /// Adds the registry key and value name pair to the collection if it doesn't already exist.
307 /// </summary>
308 /// <param name="key">The registry key to add.</param>
309 /// <param name="name">The registry value name to add.</param>
310 internal void Add(string key, string name)
311 {
312 KeyValuePair<string, string> pair = new KeyValuePair<string, string>(key, name);
313 if (!this.Contains(pair))
314 {
315 this.Add(pair);
316 }
317 }
318
319 /// <summary>
320 /// Returns whether the collection contains the registry key and value name pair from the <see cref="Row"/>.
321 /// </summary>
322 /// <param name="row">The registry <see cref="Row"/> to search for.</param>
323 /// <returns>True if the collection contains the registry key and value name pair from the <see cref="Row"/>; otherwise, false.</returns>
324 internal bool Contains(Row row)
325 {
326 if (null == row)
327 {
328 return false;
329 }
330
331 KeyValuePair<string, string> pair = new KeyValuePair<string, string>((string)row[2], (string)row[3]);
332 return this.Contains(pair);
333 }
334
335 /// <summary>
336 /// Return the hash code of the key and value pair concatenated with a colon as a delimiter.
337 /// </summary>
338 /// <param name="pair">The registry key and value name pair.</param>
339 /// <returns></returns>
340 protected override int GetKeyForItem(KeyValuePair<string, string> pair)
341 {
342 return String.Concat(pair.Key, ":", pair.Value).GetHashCode();
343 }
344 }
345 }
346#endif
347}
diff --git a/src/ext/Dependency/wixext/DependencyExtensionData.cs b/src/ext/Dependency/wixext/DependencyExtensionData.cs
new file mode 100644
index 00000000..2f30c2bf
--- /dev/null
+++ b/src/ext/Dependency/wixext/DependencyExtensionData.cs
@@ -0,0 +1,29 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Dependency
4{
5 using WixToolset.Data;
6 using WixToolset.Extensibility;
7
8 /// <summary>
9 /// The WiX Toolset Dependency Extension.
10 /// </summary>
11 public sealed class DependencyExtensionData : BaseExtensionData
12 {
13 /// <summary>
14 /// Gets the default culture.
15 /// </summary>
16 /// <value>The default culture.</value>
17 public override string DefaultCulture => "en-US";
18
19 /// <summary>
20 /// Gets the contained .wixlib content.
21 /// </summary>
22 /// <param name="symbolDefinitions">Strong typed symbold definitions.</param>
23 /// <returns>The .wixlib.</returns>
24 public override Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions)
25 {
26 return Intermediate.Load(typeof(DependencyExtensionData).Assembly, "WixToolset.Dependency.dependency.wixlib", symbolDefinitions);
27 }
28 }
29}
diff --git a/src/ext/Dependency/wixext/DependencyExtensionFactory.cs b/src/ext/Dependency/wixext/DependencyExtensionFactory.cs
new file mode 100644
index 00000000..413f99ae
--- /dev/null
+++ b/src/ext/Dependency/wixext/DependencyExtensionFactory.cs
@@ -0,0 +1,17 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Dependency
4{
5 using System;
6 using System.Collections.Generic;
7 using WixToolset.Extensibility;
8
9 public class DependencyExtensionFactory : BaseExtensionFactory
10 {
11 protected override IReadOnlyCollection<Type> ExtensionTypes => new[]
12 {
13 typeof(DependencyCompiler),
14 typeof(DependencyExtensionData),
15 };
16 }
17}
diff --git a/src/ext/Dependency/wixext/WixToolset.Dependency.wixext.csproj b/src/ext/Dependency/wixext/WixToolset.Dependency.wixext.csproj
new file mode 100644
index 00000000..b2663231
--- /dev/null
+++ b/src/ext/Dependency/wixext/WixToolset.Dependency.wixext.csproj
@@ -0,0 +1,32 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup>
6 <TargetFramework>netstandard2.0</TargetFramework>
7 <DebugType>embedded</DebugType>
8 <RootNamespace>WixToolset.Dependency</RootNamespace>
9 <Description>WiX Toolset Dependency Extension</Description>
10 <Title>WiX Toolset Dependency Extension</Title>
11 <IsTool>true</IsTool>
12 <IncludeSymbols>true</IncludeSymbols>
13 </PropertyGroup>
14
15 <ItemGroup>
16 <EmbeddedResource Include="$(OutputPath)..\dependency.wixlib" />
17 </ItemGroup>
18
19 <ItemGroup>
20 <ProjectReference Include="..\wixlib\dependency.wixproj" ReferenceOutputAssembly="false" Condition=" '$(NCrunch)'=='' " />
21 </ItemGroup>
22
23 <ItemGroup>
24 <PackageReference Include="WixToolset.Data" Version="4.0.*" PrivateAssets="all" />
25 <PackageReference Include="WixToolset.Extensibility" Version="4.0.*" PrivateAssets="all" />
26 </ItemGroup>
27
28 <ItemGroup>
29 <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="all" />
30 <PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37" PrivateAssets="all" />
31 </ItemGroup>
32</Project>
diff --git a/src/ext/Dependency/wixext/WixToolset.Dependency.wixext.nuspec b/src/ext/Dependency/wixext/WixToolset.Dependency.wixext.nuspec
new file mode 100644
index 00000000..ba3eaade
--- /dev/null
+++ b/src/ext/Dependency/wixext/WixToolset.Dependency.wixext.nuspec
@@ -0,0 +1,25 @@
1<?xml version="1.0"?>
2<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
3 <metadata minClientVersion="4.0">
4 <id>$id$</id>
5 <version>$version$</version>
6 <title>$title$</title>
7 <description>$description$</description>
8 <authors>$authors$</authors>
9 <license type="expression">MS-RL</license>
10 <requireLicenseAcceptance>false</requireLicenseAcceptance>
11 <copyright>$copyright$</copyright>
12 <projectUrl>$projectUrl$</projectUrl>
13 <repository type="$repositorytype$" url="$repositoryurl$" commit="$repositorycommit$" />
14 </metadata>
15
16 <files>
17 <file src="$projectFolder$$id$.targets" target="build" />
18
19 <file src="netstandard2.0\$id$.dll" target="tools" />
20
21 <file src="ARM64\*.pdb" target="pdbs\ARM64" />
22 <file src="x86\*.pdb" target="pdbs\x86" />
23 <file src="x64\*.pdb" target="pdbs\x64" />
24 </files>
25</package>
diff --git a/src/ext/Dependency/wixext/WixToolset.Dependency.wixext.targets b/src/ext/Dependency/wixext/WixToolset.Dependency.wixext.targets
new file mode 100644
index 00000000..2b298736
--- /dev/null
+++ b/src/ext/Dependency/wixext/WixToolset.Dependency.wixext.targets
@@ -0,0 +1,11 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
5 <PropertyGroup>
6 <WixToolsetDependencyWixextPath Condition=" '$(WixToolsetDependencyWixextPath)' == '' ">$(MSBuildThisFileDirectory)..\tools\WixToolset.Dependency.wixext.dll</WixToolsetDependencyWixextPath>
7 </PropertyGroup>
8 <ItemGroup>
9 <WixExtension Include="$(WixToolsetDependencyWixextPath)" />
10 </ItemGroup>
11</Project>
diff --git a/src/ext/Dependency/wixlib/DependencyExtension.wxs b/src/ext/Dependency/wixlib/DependencyExtension.wxs
new file mode 100644
index 00000000..0516b18c
--- /dev/null
+++ b/src/ext/Dependency/wixlib/DependencyExtension.wxs
@@ -0,0 +1,21 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <?include caerr.wxi ?>
6
7 <Fragment>
8 <UI Id="WixDependencyErrors">
9 <Error Id="$(var.msierrDependencyMissingDependencies)" Message="!(loc.msierrDependencyMissingDependencies)" />
10 <Error Id="$(var.msierrDependencyHasDependents)" Message="!(loc.msierrDependencyHasDependents)" />
11 </UI>
12 </Fragment>
13
14 <Fragment>
15 <Property Id="DISABLEDEPENDENCYCHECK" Secure="yes" SuppressModularization="yes" />
16 </Fragment>
17
18 <Fragment>
19 <Property Id="IGNOREDEPENDENCIES" Secure="yes" SuppressModularization="yes" />
20 </Fragment>
21</Wix>
diff --git a/src/ext/Dependency/wixlib/DependencyExtension_Platform.wxi b/src/ext/Dependency/wixlib/DependencyExtension_Platform.wxi
new file mode 100644
index 00000000..9ab28ef3
--- /dev/null
+++ b/src/ext/Dependency/wixlib/DependencyExtension_Platform.wxi
@@ -0,0 +1,28 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2
3
4<Include xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <?include caDecor.wxi ?>
6
7 <Fragment>
8 <CustomAction Id="$(var.Prefix)DependencyRequire$(var.Suffix)" DllEntry="WixDependencyRequire" Execute="immediate" Return="check" SuppressModularization="yes" BinaryRef="DependencyCA$(var.Suffix)" />
9 <InstallExecuteSequence>
10 <Custom Action="$(var.Prefix)DependencyRequire$(var.Suffix)" Before="$(var.Prefix)DependencyCheck$(var.Suffix)" Overridable="yes" Condition="NOT DISABLEDEPENDENCYCHECK" />
11 </InstallExecuteSequence>
12 <UIRef Id="WixDependencyErrors" />
13 <PropertyRef Id="DISABLEDEPENDENCYCHECK" />
14 </Fragment>
15
16 <Fragment>
17 <CustomAction Id="$(var.Prefix)DependencyCheck$(var.Suffix)" DllEntry="WixDependencyCheck" Execute="immediate" Return="check" SuppressModularization="yes" BinaryRef="DependencyCA$(var.Suffix)" />
18 <InstallExecuteSequence>
19 <Custom Action="$(var.Prefix)DependencyCheck$(var.Suffix)" Before="InstallInitialize" Overridable="yes" Condition="(REMOVE OR MsiPatchRemovalList) AND NOT (UPGRADINGPRODUCTCODE OR IGNOREDEPENDENCIES=&quot;ALL&quot;)" />
20 </InstallExecuteSequence>
21 <UIRef Id="WixDependencyErrors" />
22 <PropertyRef Id="IGNOREDEPENDENCIES" />
23 </Fragment>
24
25 <Fragment>
26 <Binary Id="DependencyCA$(var.Suffix)" SourceFile="!(bindpath.$(var.platform))dependencyca.dll" />
27 </Fragment>
28</Include>
diff --git a/src/ext/Dependency/wixlib/DependencyExtension_arm64.wxs b/src/ext/Dependency/wixlib/DependencyExtension_arm64.wxs
new file mode 100644
index 00000000..958650e6
--- /dev/null
+++ b/src/ext/Dependency/wixlib/DependencyExtension_arm64.wxs
@@ -0,0 +1,7 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <?define platform=arm64 ?>
6 <?include DependencyExtension_Platform.wxi ?>
7</Wix>
diff --git a/src/ext/Dependency/wixlib/DependencyExtension_x64.wxs b/src/ext/Dependency/wixlib/DependencyExtension_x64.wxs
new file mode 100644
index 00000000..4fe458e8
--- /dev/null
+++ b/src/ext/Dependency/wixlib/DependencyExtension_x64.wxs
@@ -0,0 +1,7 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <?define platform=x64 ?>
6 <?include DependencyExtension_Platform.wxi ?>
7</Wix>
diff --git a/src/ext/Dependency/wixlib/DependencyExtension_x86.wxs b/src/ext/Dependency/wixlib/DependencyExtension_x86.wxs
new file mode 100644
index 00000000..d8ac6785
--- /dev/null
+++ b/src/ext/Dependency/wixlib/DependencyExtension_x86.wxs
@@ -0,0 +1,7 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <?define platform=x86 ?>
6 <?include DependencyExtension_Platform.wxi ?>
7</Wix>
diff --git a/src/ext/Dependency/wixlib/caDecor.wxi b/src/ext/Dependency/wixlib/caDecor.wxi
new file mode 100644
index 00000000..b1711518
--- /dev/null
+++ b/src/ext/Dependency/wixlib/caDecor.wxi
@@ -0,0 +1,39 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2
3
4<Include xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <?ifdef Prefix ?>
6 <?undef Prefix ?>
7 <?endif?>
8
9 <?define Prefix="Wix4" ?>
10
11 <?ifndef platform ?>
12 <?define platform="x86" ?>
13 <?endif?>
14
15 <?if $(var.platform)="" ?>
16 <?undef platform ?>
17 <?define platform="x86" ?>
18 <?endif?>
19
20 <?ifdef Suffix ?>
21 <?undef Suffix ?>
22 <?endif?>
23
24 <?if $(var.platform)~="x86" ?>
25 <?define Suffix="_X86" ?>
26 <?endif?>
27
28 <?if $(var.platform)~="x64" ?>
29 <?define Suffix="_X64" ?>
30 <?endif?>
31
32 <?if $(var.platform)~="arm" ?>
33 <?define Suffix="_A32" ?>
34 <?endif?>
35
36 <?if $(var.platform)~="arm64" ?>
37 <?define Suffix="_A64" ?>
38 <?endif?>
39</Include>
diff --git a/src/ext/Dependency/wixlib/caerr.wxi b/src/ext/Dependency/wixlib/caerr.wxi
new file mode 100644
index 00000000..ff7ec121
--- /dev/null
+++ b/src/ext/Dependency/wixlib/caerr.wxi
@@ -0,0 +1,96 @@
1<Include xmlns="http://wixtoolset.org/schemas/v4/wxs">
2 <?define msierrSecureObjectsFailedCreateSD = 25520?>
3 <?define msierrSecureObjectsFailedSet = 25521?>
4 <?define msierrSecureObjectsUnknownType = 25522?>
5 <?define msierrXmlFileFailedRead = 25530?>
6 <?define msierrXmlFileFailedOpen = 25531?>
7 <?define msierrXmlFileFailedSelect = 25532?>
8 <?define msierrXmlFileFailedSave = 25533?>
9 <?define msierrXmlConfigFailedRead = 25540?>
10 <?define msierrXmlConfigFailedOpen = 25541?>
11 <?define msierrXmlConfigFailedSelect = 25542?>
12 <?define msierrXmlConfigFailedSave = 25543?>
13 <?define msierrFirewallCannotConnect = 25580?>
14 <?define msierrIISCannotConnect = 26001?>
15 <?define msierrIISFailedReadWebSite = 26002?>
16 <?define msierrIISFailedReadWebDirs = 26003?>
17 <?define msierrIISFailedReadVDirs = 26004?>
18 <?define msierrIISFailedReadFilters = 26005?>
19 <?define msierrIISFailedReadAppPool = 26006?>
20 <?define msierrIISFailedReadMimeMap = 26007?>
21 <?define msierrIISFailedReadProp = 26008?>
22 <?define msierrIISFailedReadWebSvcExt = 26009?>
23 <?define msierrIISFailedReadWebError = 26010?>
24 <?define msierrIISFailedReadHttpHeader = 26011?>
25 <?define msierrIISFailedSchedTransaction = 26031?>
26 <?define msierrIISFailedSchedInstallWebs = 26032?>
27 <?define msierrIISFailedSchedInstallWebDirs = 26033?>
28 <?define msierrIISFailedSchedInstallVDirs = 26034?>
29 <?define msierrIISFailedSchedInstallFilters = 26035?>
30 <?define msierrIISFailedSchedInstallAppPool = 26036?>
31 <?define msierrIISFailedSchedInstallProp = 26037?>
32 <?define msierrIISFailedSchedInstallWebSvcExt = 26038?>
33 <?define msierrIISFailedSchedUninstallWebs = 26051?>
34 <?define msierrIISFailedSchedUninstallWebDirs = 26052?>
35 <?define msierrIISFailedSchedUninstallVDirs = 26053?>
36 <?define msierrIISFailedSchedUninstallFilters = 26054?>
37 <?define msierrIISFailedSchedUninstallAppPool = 26055?>
38 <?define msierrIISFailedSchedUninstallProp = 26056?>
39 <?define msierrIISFailedSchedUninstallWebSvcExt = 26057?>
40 <?define msierrIISFailedStartTransaction = 26101?>
41 <?define msierrIISFailedOpenKey = 26102?>
42 <?define msierrIISFailedCreateKey = 26103?>
43 <?define msierrIISFailedWriteData = 26104?>
44 <?define msierrIISFailedCreateApp = 26105?>
45 <?define msierrIISFailedDeleteKey = 26106?>
46 <?define msierrIISFailedDeleteApp = 26107?>
47 <?define msierrIISFailedDeleteValue = 26108?>
48 <?define msierrIISFailedCommitInUse = 26109?>
49 <?define msierrSQLFailedCreateDatabase = 26201?>
50 <?define msierrSQLFailedDropDatabase = 26202?>
51 <?define msierrSQLFailedConnectDatabase = 26203?>
52 <?define msierrSQLFailedExecString = 26204?>
53 <?define msierrSQLDatabaseAlreadyExists = 26205?>
54 <?define msierrPERFMONFailedRegisterDLL = 26251?>
55 <?define msierrPERFMONFailedUnregisterDLL = 26252?>
56 <?define msierrInstallPerfCounterData = 26253?>
57 <?define msierrUninstallPerfCounterData = 26254?>
58 <?define msierrSMBFailedCreate = 26301?>
59 <?define msierrSMBFailedDrop = 26302?>
60 <?define msierrCERTFailedOpen = 26351?>
61 <?define msierrCERTFailedAdd = 26352?>
62 <?define msierrUSRFailedUserCreate = 26401?>
63 <?define msierrUSRFailedUserCreatePswd = 26402?>
64 <?define msierrUSRFailedUserGroupAdd = 26403?>
65 <?define msierrUSRFailedUserCreateExists = 26404?>
66 <?define msierrUSRFailedGrantLogonAsService = 26405?>
67 <?define msierrDependencyMissingDependencies = 26451?>
68 <?define msierrDependencyHasDependents = 26452?>
69 <?define msierrDotNetRuntimeRequired = 27000?>
70 <?define msierrComPlusCannotConnect = 28001?>
71 <?define msierrComPlusPartitionReadFailed = 28002?>
72 <?define msierrComPlusPartitionRoleReadFailed = 28003?>
73 <?define msierrComPlusUserInPartitionRoleReadFailed = 28004?>
74 <?define msierrComPlusPartitionUserReadFailed = 28005?>
75 <?define msierrComPlusApplicationReadFailed = 28006?>
76 <?define msierrComPlusApplicationRoleReadFailed = 28007?>
77 <?define msierrComPlusUserInApplicationRoleReadFailed = 28008?>
78 <?define msierrComPlusAssembliesReadFailed = 28009?>
79 <?define msierrComPlusSubscriptionReadFailed = 28010?>
80 <?define msierrComPlusPartitionDependency = 28011?>
81 <?define msierrComPlusPartitionNotFound = 28012?>
82 <?define msierrComPlusPartitionIdConflict = 28013?>
83 <?define msierrComPlusPartitionNameConflict = 28014?>
84 <?define msierrComPlusApplicationDependency = 28015?>
85 <?define msierrComPlusApplicationNotFound = 28016?>
86 <?define msierrComPlusApplicationIdConflict = 28017?>
87 <?define msierrComPlusApplicationNameConflict = 28018?>
88 <?define msierrComPlusApplicationRoleDependency = 28019?>
89 <?define msierrComPlusApplicationRoleNotFound = 28020?>
90 <?define msierrComPlusApplicationRoleConflict = 28021?>
91 <?define msierrComPlusAssemblyDependency = 28022?>
92 <?define msierrComPlusSubscriptionIdConflict = 28023?>
93 <?define msierrComPlusSubscriptionNameConflict = 28024?>
94 <?define msierrComPlusFailedLookupNames = 28025?>
95 <?define msierrMsmqCannotConnect = 28101?>
96</Include> \ No newline at end of file
diff --git a/src/ext/Dependency/wixlib/dependency.wixproj b/src/ext/Dependency/wixlib/dependency.wixproj
new file mode 100644
index 00000000..76e3ecd3
--- /dev/null
+++ b/src/ext/Dependency/wixlib/dependency.wixproj
@@ -0,0 +1,30 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project Sdk="WixToolset.Sdk">
5
6 <PropertyGroup>
7 <OutputType>Library</OutputType>
8 <BindFiles>true</BindFiles>
9 <!-- PropertyModularizationSuppressed -->
10 <SuppressSpecificWarnings>1086</SuppressSpecificWarnings>
11 <Cultures>en-us</Cultures>
12 </PropertyGroup>
13
14 <ItemGroup>
15 <BindInputPaths Include="$(OutputPath)x86" BindName='x86' />
16 <BindInputPaths Include="$(OutputPath)x64" BindName='x64' />
17 <BindInputPaths Include="$(OutputPath)arm64" BindName='arm64' />
18 </ItemGroup>
19
20 <ItemGroup>
21 <ProjectReference Include="..\ca\dependencyca.vcxproj" Properties="Platform=ARM64" ReferenceOutputAssembly="false" />
22 <ProjectReference Include="..\ca\dependencyca.vcxproj" Properties="Platform=x86" ReferenceOutputAssembly="false" />
23 <ProjectReference Include="..\ca\dependencyca.vcxproj" Properties="Platform=x64" ReferenceOutputAssembly="false" />
24 </ItemGroup>
25
26 <ItemGroup>
27 <PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37" PrivateAssets="All" />
28 </ItemGroup>
29
30</Project>
diff --git a/src/ext/Dependency/wixlib/en-us.wxl b/src/ext/Dependency/wixlib/en-us.wxl
new file mode 100644
index 00000000..6ad7d63d
--- /dev/null
+++ b/src/ext/Dependency/wixlib/en-us.wxl
@@ -0,0 +1,7 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2
3
4<WixLocalization Culture="en-US" xmlns="http://wixtoolset.org/schemas/v4/wxl">
5 <String Id="msierrDependencyMissingDependencies" Overridable="yes">If you continue with this install, the product may not work properly because [2] or more dependencies are missing. Do you want to continue with this install anyway?</String>
6 <String Id="msierrDependencyHasDependents" Overridable="yes">If you continue with this uninstall, [2] or more products may stop working properly. Do you want to continue with this uninstall anyway?</String>
7</WixLocalization>