aboutsummaryrefslogtreecommitdiff
path: root/src/ext
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-05-11 08:02:58 -0700
committerRob Mensching <rob@firegiant.com>2021-05-11 08:02:58 -0700
commite835776f17056097559c13f25b4c875c7361bd5b (patch)
tree8b1c3af05e44e55cf61318474d90dcb53a2e3bb6 /src/ext
parent52868c16c483776d0c55ab7f2a0828a0ee55c39d (diff)
parent4194343c39fa66778a8de9804c88789bd41dae48 (diff)
downloadwix-e835776f17056097559c13f25b4c875c7361bd5b.tar.gz
wix-e835776f17056097559c13f25b4c875c7361bd5b.tar.bz2
wix-e835776f17056097559c13f25b4c875c7361bd5b.zip
Merge Http.wixext
Diffstat (limited to 'src/ext')
-rw-r--r--src/ext/Http/CSharp.Build.props11
-rw-r--r--src/ext/Http/Cpp.Build.props86
-rw-r--r--src/ext/Http/Directory.Build.props29
-rw-r--r--src/ext/Http/Directory.Build.targets48
-rw-r--r--src/ext/Http/FindLocalWix.props8
-rw-r--r--src/ext/Http/Http.wixext.sln61
-rw-r--r--src/ext/Http/README.md2
-rw-r--r--src/ext/Http/appveyor.cmd14
-rw-r--r--src/ext/Http/appveyor.yml40
-rw-r--r--src/ext/Http/ca/caDecor.h13
-rw-r--r--src/ext/Http/ca/cost.h6
-rw-r--r--src/ext/Http/ca/dllmain.cpp26
-rw-r--r--src/ext/Http/ca/httpca.vcxproj72
-rw-r--r--src/ext/Http/ca/httpca.vcxproj.filters42
-rw-r--r--src/ext/Http/ca/packages.config5
-rw-r--r--src/ext/Http/ca/precomp.h25
-rw-r--r--src/ext/Http/ca/snisslcert.cpp704
-rw-r--r--src/ext/Http/ca/wixhttpca.cpp530
-rw-r--r--src/ext/Http/ca/wixhttpca.def12
-rw-r--r--src/ext/Http/nuget.config17
-rw-r--r--src/ext/Http/test/WixToolsetTest.Http/HttpExtensionFixture.cs57
-rw-r--r--src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.en-us.wxl11
-rw-r--r--src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.wxs15
-rw-r--r--src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/PackageComponents.wxs12
-rw-r--r--src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/example.txt1
-rw-r--r--src/ext/Http/test/WixToolsetTest.Http/TestData/UsingUrlReservation/Package.en-us.wxl11
-rw-r--r--src/ext/Http/test/WixToolsetTest.Http/TestData/UsingUrlReservation/Package.wxs15
-rw-r--r--src/ext/Http/test/WixToolsetTest.Http/TestData/UsingUrlReservation/PackageComponents.wxs16
-rw-r--r--src/ext/Http/test/WixToolsetTest.Http/TestData/UsingUrlReservation/example.txt1
-rw-r--r--src/ext/Http/test/WixToolsetTest.Http/WixToolsetTest.Http.csproj38
-rw-r--r--src/ext/Http/wix.snkbin0 -> 596 bytes
-rw-r--r--src/ext/Http/wixext/HttpCompiler.cs383
-rw-r--r--src/ext/Http/wixext/HttpConstants.cs15
-rw-r--r--src/ext/Http/wixext/HttpDecompiler.cs137
-rw-r--r--src/ext/Http/wixext/HttpErrors.cs31
-rw-r--r--src/ext/Http/wixext/HttpExtensionData.cs30
-rw-r--r--src/ext/Http/wixext/HttpExtensionFactory.cs18
-rw-r--r--src/ext/Http/wixext/HttpTableDefinitions.cs60
-rw-r--r--src/ext/Http/wixext/HttpWindowsInstallerBackendBinderExtension.cs13
-rw-r--r--src/ext/Http/wixext/Symbols/HandleExisting.cs14
-rw-r--r--src/ext/Http/wixext/Symbols/HttpSymbolDefinitions.cs47
-rw-r--r--src/ext/Http/wixext/Symbols/WixHttpSniSslCertSymbol.cs95
-rw-r--r--src/ext/Http/wixext/Symbols/WixHttpUrlAceSymbol.cs63
-rw-r--r--src/ext/Http/wixext/Symbols/WixHttpUrlReservationSymbol.cs71
-rw-r--r--src/ext/Http/wixext/WixToolset.Http.wixext.csproj31
-rw-r--r--src/ext/Http/wixext/WixToolset.Http.wixext.targets11
-rw-r--r--src/ext/Http/wixlib/HttpExtension.wxs10
-rw-r--r--src/ext/Http/wixlib/HttpExtension_Platform.wxi64
-rw-r--r--src/ext/Http/wixlib/HttpExtension_arm64.wxs7
-rw-r--r--src/ext/Http/wixlib/HttpExtension_x64.wxs7
-rw-r--r--src/ext/Http/wixlib/HttpExtension_x86.wxs7
-rw-r--r--src/ext/Http/wixlib/caDecor.wxi39
-rw-r--r--src/ext/Http/wixlib/caerr.wxi96
-rw-r--r--src/ext/Http/wixlib/en-us.wxl17
-rw-r--r--src/ext/Http/wixlib/http.wixproj24
55 files changed, 3218 insertions, 0 deletions
diff --git a/src/ext/Http/CSharp.Build.props b/src/ext/Http/CSharp.Build.props
new file mode 100644
index 00000000..b12f4c6e
--- /dev/null
+++ b/src/ext/Http/CSharp.Build.props
@@ -0,0 +1,11 @@
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 <SignAssembly>true</SignAssembly>
9 <AssemblyOriginatorKeyFile>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)wix.snk))</AssemblyOriginatorKeyFile>
10 </PropertyGroup>
11</Project>
diff --git a/src/ext/Http/Cpp.Build.props b/src/ext/Http/Cpp.Build.props
new file mode 100644
index 00000000..9b7a1bb5
--- /dev/null
+++ b/src/ext/Http/Cpp.Build.props
@@ -0,0 +1,86 @@
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 </PropertyGroup>
10
11 <PropertyGroup Condition="'$(WindowsTargetPlatformVersion)'=='' AND '$(VisualStudioVersion)'>='15.0'">
12 <WindowsTargetPlatformVersion>$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0'))</WindowsTargetPlatformVersion>
13 </PropertyGroup>
14
15 <ItemDefinitionGroup>
16 <ClCompile>
17 <DisableSpecificWarnings>$(DisableSpecificCompilerWarnings)</DisableSpecificWarnings>
18 <WarningLevel>Level4</WarningLevel>
19 <AdditionalIncludeDirectories>$(ProjectDir)inc;$(MSBuildProjectDirectory);$(IntDir);$(SqlCESdkIncludePath);$(ProjectAdditionalIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
20 <PreprocessorDefinitions>WIN32;_WINDOWS;_WIN32_MSI=500;_WIN32_WINNT=0x0501;$(ArmPreprocessorDefinitions);$(UnicodePreprocessorDefinitions);_CRT_STDIO_LEGACY_WIDE_SPECIFIERS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
21 <PrecompiledHeader>Use</PrecompiledHeader>
22 <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
23 <CallingConvention Condition="'$(Platform)'=='Win32'">StdCall</CallingConvention>
24 <TreatWarningAsError>true</TreatWarningAsError>
25 <ExceptionHandling>false</ExceptionHandling>
26 <AdditionalOptions>-YlprecompDefine</AdditionalOptions>
27 <AdditionalOptions Condition=" $(PlatformToolset.StartsWith('v14')) ">/Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
28 <MultiProcessorCompilation Condition=" $(NUMBER_OF_PROCESSORS) &gt; 4 ">true</MultiProcessorCompilation>
29 </ClCompile>
30 <ResourceCompile>
31 <PreprocessorDefinitions>$(ArmPreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
32 <AdditionalIncludeDirectories>$(ProjectAdditionalResourceIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
33 </ResourceCompile>
34 <Lib>
35 <AdditionalLibraryDirectories>$(OutDir);$(AdditionalMultiTargetLibraryPath);$(ProjectAdditionalLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
36 </Lib>
37 <Link>
38 <SubSystem>$(ProjectSubSystem)</SubSystem>
39 <ModuleDefinitionFile>$(ProjectModuleDefinitionFile)</ModuleDefinitionFile>
40 <NoEntryPoint>$(ResourceOnlyDll)</NoEntryPoint>
41 <GenerateDebugInformation>true</GenerateDebugInformation>
42 <AdditionalDependencies>$(ProjectAdditionalLinkLibraries);advapi32.lib;comdlg32.lib;user32.lib;oleaut32.lib;gdi32.lib;shell32.lib;ole32.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
43 <AdditionalLibraryDirectories>$(OutDir);$(AdditionalMultiTargetLibraryPath);$(ArmLibraryDirectories);$(ProjectAdditionalLinkLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
44 <AdditionalOptions Condition=" $(PlatformToolset.StartsWith('v14')) ">/IGNORE:4099 %(AdditionalOptions)</AdditionalOptions>
45 </Link>
46 </ItemDefinitionGroup>
47
48 <ItemDefinitionGroup Condition=" '$(Platform)'=='Win32' and '$(PlatformToolset)'!='v100'">
49 <ClCompile>
50 <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
51 </ClCompile>
52 </ItemDefinitionGroup>
53 <ItemDefinitionGroup Condition=" '$(Platform)'=='arm' ">
54 <ClCompile>
55 <CallingConvention>CDecl</CallingConvention>
56 </ClCompile>
57 </ItemDefinitionGroup>
58 <ItemDefinitionGroup Condition=" '$(ConfigurationType)'=='StaticLibrary' ">
59 <ClCompile>
60 <DebugInformationFormat>OldStyle</DebugInformationFormat>
61 <OmitDefaultLibName>true</OmitDefaultLibName>
62 <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
63 </ClCompile>
64 </ItemDefinitionGroup>
65 <ItemDefinitionGroup Condition=" '$(Configuration)'=='Debug' ">
66 <ClCompile>
67 <Optimization>Disabled</Optimization>
68 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
69 <PreprocessorDefinitions>_DEBUG;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
70 <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
71 </ClCompile>
72 </ItemDefinitionGroup>
73 <ItemDefinitionGroup Condition=" '$(Configuration)'=='Release' ">
74 <ClCompile>
75 <Optimization>MinSpace</Optimization>
76 <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
77 <FunctionLevelLinking>true</FunctionLevelLinking>
78 <IntrinsicFunctions>true</IntrinsicFunctions>
79 <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
80 </ClCompile>
81 <Link>
82 <EnableCOMDATFolding>true</EnableCOMDATFolding>
83 <OptimizeReferences>true</OptimizeReferences>
84 </Link>
85 </ItemDefinitionGroup>
86</Project>
diff --git a/src/ext/Http/Directory.Build.props b/src/ext/Http/Directory.Build.props
new file mode 100644
index 00000000..f83cc154
--- /dev/null
+++ b/src/ext/Http/Directory.Build.props
@@ -0,0 +1,29 @@
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="CSharp.Build.props" Condition=" '$(MSBuildProjectExtension)'=='.csproj' and Exists('CSharp.Build.props') " />
26 <Import Project="Cpp.Build.props" Condition=" Exists('Cpp.Build.props') And '$(MSBuildProjectExtension)'=='.vcxproj' " />
27 <Import Project="Wix.Build.props" Condition=" Exists('Wix.Build.props') And '$(MSBuildProjectExtension)'=='.wixproj' " />
28 <Import Project="Custom.Build.props" Condition=" Exists('Custom.Build.props') " />
29</Project>
diff --git a/src/ext/Http/Directory.Build.targets b/src/ext/Http/Directory.Build.targets
new file mode 100644
index 00000000..dac7452a
--- /dev/null
+++ b/src/ext/Http/Directory.Build.targets
@@ -0,0 +1,48 @@
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</Project>
diff --git a/src/ext/Http/FindLocalWix.props b/src/ext/Http/FindLocalWix.props
new file mode 100644
index 00000000..1666e4fe
--- /dev/null
+++ b/src/ext/Http/FindLocalWix.props
@@ -0,0 +1,8 @@
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">
5 <PropertyGroup>
6 <WixTargetsPath Condition=" '$(Configuration)' == 'Debug' And Exists('$(MSBuildThisFileDirectory)..\..\Tools\README.md') And Exists('$(MSBuildThisFileDirectory)..\..\Tools\build\Debug\net461\wix.targets') ">$(MSBuildThisFileDirectory)..\..\Tools\build\Debug\net461\wix.targets</WixTargetsPath>
7 </PropertyGroup>
8</Project>
diff --git a/src/ext/Http/Http.wixext.sln b/src/ext/Http/Http.wixext.sln
new file mode 100644
index 00000000..fe5c52e9
--- /dev/null
+++ b/src/ext/Http/Http.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}") = "httpca", "src\ca\httpca.vcxproj", "{90743805-C043-47C7-B5FF-8F5EE5C8A2DE}"
7EndProject
8Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "http", "src\wixlib\http.wixproj", "{055C1517-4CED-4199-BCDE-A383E5C4EF78}"
9EndProject
10Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Http.wixext", "src\wixext\WixToolset.Http.wixext.csproj", "{AAFC3C7F-D818-4B1D-AF3F-A331EA917F3F}"
11EndProject
12Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.Http", "src\test\WixToolsetTest.Http\WixToolsetTest.Http.csproj", "{6379EBAA-B5FE-4468-89A3-EF0B5D30B87E}"
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 {90743805-C043-47C7-B5FF-8F5EE5C8A2DE}.Debug|Any CPU.ActiveCfg = Debug|Win32
23 {90743805-C043-47C7-B5FF-8F5EE5C8A2DE}.Debug|Any CPU.Build.0 = Debug|Win32
24 {90743805-C043-47C7-B5FF-8F5EE5C8A2DE}.Debug|x86.ActiveCfg = Debug|Win32
25 {90743805-C043-47C7-B5FF-8F5EE5C8A2DE}.Debug|x86.Build.0 = Debug|Win32
26 {90743805-C043-47C7-B5FF-8F5EE5C8A2DE}.Release|Any CPU.ActiveCfg = Release|Win32
27 {90743805-C043-47C7-B5FF-8F5EE5C8A2DE}.Release|Any CPU.Build.0 = Release|Win32
28 {90743805-C043-47C7-B5FF-8F5EE5C8A2DE}.Release|x86.ActiveCfg = Release|Win32
29 {90743805-C043-47C7-B5FF-8F5EE5C8A2DE}.Release|x86.Build.0 = Release|Win32
30 {055C1517-4CED-4199-BCDE-A383E5C4EF78}.Debug|Any CPU.ActiveCfg = Debug|x86
31 {055C1517-4CED-4199-BCDE-A383E5C4EF78}.Debug|Any CPU.Build.0 = Debug|x86
32 {055C1517-4CED-4199-BCDE-A383E5C4EF78}.Debug|x86.ActiveCfg = Debug|x86
33 {055C1517-4CED-4199-BCDE-A383E5C4EF78}.Debug|x86.Build.0 = Debug|x86
34 {055C1517-4CED-4199-BCDE-A383E5C4EF78}.Release|Any CPU.ActiveCfg = Release|x86
35 {055C1517-4CED-4199-BCDE-A383E5C4EF78}.Release|Any CPU.Build.0 = Release|x86
36 {055C1517-4CED-4199-BCDE-A383E5C4EF78}.Release|x86.ActiveCfg = Release|x86
37 {055C1517-4CED-4199-BCDE-A383E5C4EF78}.Release|x86.Build.0 = Release|x86
38 {AAFC3C7F-D818-4B1D-AF3F-A331EA917F3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39 {AAFC3C7F-D818-4B1D-AF3F-A331EA917F3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
40 {AAFC3C7F-D818-4B1D-AF3F-A331EA917F3F}.Debug|x86.ActiveCfg = Debug|Any CPU
41 {AAFC3C7F-D818-4B1D-AF3F-A331EA917F3F}.Debug|x86.Build.0 = Debug|Any CPU
42 {AAFC3C7F-D818-4B1D-AF3F-A331EA917F3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
43 {AAFC3C7F-D818-4B1D-AF3F-A331EA917F3F}.Release|Any CPU.Build.0 = Release|Any CPU
44 {AAFC3C7F-D818-4B1D-AF3F-A331EA917F3F}.Release|x86.ActiveCfg = Release|Any CPU
45 {AAFC3C7F-D818-4B1D-AF3F-A331EA917F3F}.Release|x86.Build.0 = Release|Any CPU
46 {6379EBAA-B5FE-4468-89A3-EF0B5D30B87E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
47 {6379EBAA-B5FE-4468-89A3-EF0B5D30B87E}.Debug|Any CPU.Build.0 = Debug|Any CPU
48 {6379EBAA-B5FE-4468-89A3-EF0B5D30B87E}.Debug|x86.ActiveCfg = Debug|Any CPU
49 {6379EBAA-B5FE-4468-89A3-EF0B5D30B87E}.Debug|x86.Build.0 = Debug|Any CPU
50 {6379EBAA-B5FE-4468-89A3-EF0B5D30B87E}.Release|Any CPU.ActiveCfg = Release|Any CPU
51 {6379EBAA-B5FE-4468-89A3-EF0B5D30B87E}.Release|Any CPU.Build.0 = Release|Any CPU
52 {6379EBAA-B5FE-4468-89A3-EF0B5D30B87E}.Release|x86.ActiveCfg = Release|Any CPU
53 {6379EBAA-B5FE-4468-89A3-EF0B5D30B87E}.Release|x86.Build.0 = Release|Any CPU
54 EndGlobalSection
55 GlobalSection(SolutionProperties) = preSolution
56 HideSolutionNode = FALSE
57 EndGlobalSection
58 GlobalSection(ExtensibilityGlobals) = postSolution
59 SolutionGuid = {570B1B57-B310-4493-A3A3-B40D7374EFC3}
60 EndGlobalSection
61EndGlobal
diff --git a/src/ext/Http/README.md b/src/ext/Http/README.md
new file mode 100644
index 00000000..2d9f1895
--- /dev/null
+++ b/src/ext/Http/README.md
@@ -0,0 +1,2 @@
1# Http.wixext
2WixToolset.Http.wixext - Http WiX Toolset Extension
diff --git a/src/ext/Http/appveyor.cmd b/src/ext/Http/appveyor.cmd
new file mode 100644
index 00000000..16a34ff9
--- /dev/null
+++ b/src/ext/Http/appveyor.cmd
@@ -0,0 +1,14 @@
1@setlocal
2@pushd %~dp0
3
4nuget restore || exit /b
5
6msbuild -p:Configuration=Release -t:Restore || exit /b
7
8msbuild -p:Configuration=Release src\test\WixToolsetTest.Http\WixToolsetTest.Http.csproj || exit /b
9dotnet test -c Release --no-build src\test\WixToolsetTest.Http || exit /b
10
11msbuild -p:Configuration=Release -t:Pack src\wixext\WixToolset.Http.wixext.csproj || exit /b
12
13@popd
14@endlocal \ No newline at end of file
diff --git a/src/ext/Http/appveyor.yml b/src/ext/Http/appveyor.yml
new file mode 100644
index 00000000..7c686b04
--- /dev/null
+++ b/src/ext/Http/appveyor.yml
@@ -0,0 +1,40 @@
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
37notifications:
38- provider: Slack
39 incoming_webhook:
40 secure: p5xuu+4x2JHfwGDMDe5KcG1k7gZxqYc4jWVwvyNZv5cvkubPD2waJs5yXMAXZNN7Z63/3PWHb7q4KoY/99AjauYa1nZ4c5qYqRPFRBKTHfA=
diff --git a/src/ext/Http/ca/caDecor.h b/src/ext/Http/ca/caDecor.h
new file mode 100644
index 00000000..da274650
--- /dev/null
+++ b/src/ext/Http/ca/caDecor.h
@@ -0,0 +1,13 @@
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#if defined(_M_ARM64)
6#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_A64"
7#elif defined(_M_AMD64)
8#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_X64"
9#elif defined(_M_ARM)
10#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_ARM"
11#else
12#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_X86"
13#endif
diff --git a/src/ext/Http/ca/cost.h b/src/ext/Http/ca/cost.h
new file mode 100644
index 00000000..9677e7e8
--- /dev/null
+++ b/src/ext/Http/ca/cost.h
@@ -0,0 +1,6 @@
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
5const UINT COST_HTTP_URL_ACL = 2000;
6const UINT COST_HTTP_SNI_SSL = 2000;
diff --git a/src/ext/Http/ca/dllmain.cpp b/src/ext/Http/ca/dllmain.cpp
new file mode 100644
index 00000000..b4c8c037
--- /dev/null
+++ b/src/ext/Http/ca/dllmain.cpp
@@ -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#include "precomp.h"
4
5/********************************************************************
6DllMain - standard entry point for all WiX CustomActions
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 break;
19
20 case DLL_PROCESS_DETACH:
21 WcaGlobalFinalize();
22 break;
23 }
24
25 return TRUE;
26}
diff --git a/src/ext/Http/ca/httpca.vcxproj b/src/ext/Http/ca/httpca.vcxproj
new file mode 100644
index 00000000..fde00ff4
--- /dev/null
+++ b/src/ext/Http/ca/httpca.vcxproj
@@ -0,0 +1,72 @@
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<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
4 <Import Project="..\..\packages\WixToolset.DUtil.4.0.56\build\WixToolset.DUtil.props" Condition="Exists('..\..\packages\WixToolset.DUtil.4.0.56\build\WixToolset.DUtil.props')" />
5 <Import Project="..\..\packages\WixToolset.WcaUtil.4.0.17\build\WixToolset.WcaUtil.props" Condition="Exists('..\..\packages\WixToolset.WcaUtil.4.0.17\build\WixToolset.WcaUtil.props')" />
6
7 <ItemGroup Label="ProjectConfigurations">
8 <ProjectConfiguration Include="Debug|Win32">
9 <Configuration>Debug</Configuration>
10 <Platform>Win32</Platform>
11 </ProjectConfiguration>
12 <ProjectConfiguration Include="Release|Win32">
13 <Configuration>Release</Configuration>
14 <Platform>Win32</Platform>
15 </ProjectConfiguration>
16 <ProjectConfiguration Include="Debug|x64">
17 <Configuration>Debug</Configuration>
18 <Platform>x64</Platform>
19 </ProjectConfiguration>
20 <ProjectConfiguration Include="Release|x64">
21 <Configuration>Release</Configuration>
22 <Platform>x64</Platform>
23 </ProjectConfiguration>
24 <ProjectConfiguration Include="Debug|ARM64">
25 <Configuration>Debug</Configuration>
26 <Platform>ARM64</Platform>
27 </ProjectConfiguration>
28 <ProjectConfiguration Include="Release|ARM64">
29 <Configuration>Release</Configuration>
30 <Platform>ARM64</Platform>
31 </ProjectConfiguration>
32 </ItemGroup>
33
34 <PropertyGroup Label="Globals">
35 <ProjectGuid>{90743805-C043-47C7-B5FF-8F5EE5C8A2DE}</ProjectGuid>
36 <ConfigurationType>DynamicLibrary</ConfigurationType>
37 <PlatformToolset>v142</PlatformToolset>
38 <CharacterSet>Unicode</CharacterSet>
39 <TargetName>httpca</TargetName>
40 <ProjectModuleDefinitionFile>wixhttpca.def</ProjectModuleDefinitionFile>
41 <Description>WiX Toolset Http CustomAction</Description>
42 </PropertyGroup>
43
44 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
45 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
46
47 <PropertyGroup>
48 <ProjectAdditionalLinkLibraries>crypt32.lib;httpapi.lib;msi.lib;rpcrt4.lib;ws2_32.lib</ProjectAdditionalLinkLibraries>
49 </PropertyGroup>
50
51 <ItemGroup>
52 <ClCompile Include="dllmain.cpp">
53 <PrecompiledHeader>Create</PrecompiledHeader>
54 </ClCompile>
55 <ClCompile Include="snisslcert.cpp" />
56 <ClCompile Include="wixhttpca.cpp" />
57 <ClInclude Include="cost.h" />
58 <ClInclude Include="precomp.h" />
59 <None Include="packages.config" />
60 <None Include="wixhttpca.def" />
61 </ItemGroup>
62
63 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
64
65 <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
66 <PropertyGroup>
67 <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
68 </PropertyGroup>
69 <Error Condition="!Exists('..\..\packages\WixToolset.DUtil.4.0.56\build\WixToolset.DUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.DUtil.4.0.56\build\WixToolset.DUtil.props'))" />
70 <Error Condition="!Exists('..\..\packages\WixToolset.WcaUtil.4.0.17\build\WixToolset.WcaUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.WcaUtil.4.0.17\build\WixToolset.WcaUtil.props'))" />
71 </Target>
72</Project>
diff --git a/src/ext/Http/ca/httpca.vcxproj.filters b/src/ext/Http/ca/httpca.vcxproj.filters
new file mode 100644
index 00000000..2ccd604d
--- /dev/null
+++ b/src/ext/Http/ca/httpca.vcxproj.filters
@@ -0,0 +1,42 @@
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;hh;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="wixhttpca.cpp">
19 <Filter>Source Files</Filter>
20 </ClCompile>
21 <ClCompile Include="dllmain.cpp">
22 <Filter>Source Files</Filter>
23 </ClCompile>
24 <ClCompile Include="snisslcert.cpp">
25 <Filter>Source Files</Filter>
26 </ClCompile>
27 </ItemGroup>
28 <ItemGroup>
29 <ClInclude Include="precomp.h">
30 <Filter>Header Files</Filter>
31 </ClInclude>
32 <ClInclude Include="cost.h">
33 <Filter>Header Files</Filter>
34 </ClInclude>
35 </ItemGroup>
36 <ItemGroup>
37 <None Include="wixhttpca.def">
38 <Filter>Source Files</Filter>
39 </None>
40 <None Include="packages.config" />
41 </ItemGroup>
42</Project> \ No newline at end of file
diff --git a/src/ext/Http/ca/packages.config b/src/ext/Http/ca/packages.config
new file mode 100644
index 00000000..9d88f529
--- /dev/null
+++ b/src/ext/Http/ca/packages.config
@@ -0,0 +1,5 @@
1<?xml version="1.0" encoding="utf-8"?>
2<packages>
3 <package id="WixToolset.DUtil" version="4.0.56" targetFramework="native" />
4 <package id="WixToolset.WcaUtil" version="4.0.17" targetFramework="native" />
5</packages> \ No newline at end of file
diff --git a/src/ext/Http/ca/precomp.h b/src/ext/Http/ca/precomp.h
new file mode 100644
index 00000000..c78d78c1
--- /dev/null
+++ b/src/ext/Http/ca/precomp.h
@@ -0,0 +1,25 @@
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 <http.h>
6#include <msiquery.h>
7#include <strsafe.h>
8
9#include "wcautil.h"
10#include "cryputil.h"
11#include "dutil.h"
12#include "memutil.h"
13#include "strutil.h"
14#include "aclutil.h"
15
16#include "cost.h"
17
18#include "caDecor.h"
19
20enum eHandleExisting
21{
22 heReplace = 0,
23 heIgnore = 1,
24 heFail = 2
25};
diff --git a/src/ext/Http/ca/snisslcert.cpp b/src/ext/Http/ca/snisslcert.cpp
new file mode 100644
index 00000000..3a7336af
--- /dev/null
+++ b/src/ext/Http/ca/snisslcert.cpp
@@ -0,0 +1,704 @@
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#if _WIN32_WINNT < 0x0602
6
7typedef struct _HTTP_SERVICE_CONFIG_SSL_SNI_KEY
8{
9 SOCKADDR_STORAGE IpPort;
10 PWSTR Host;
11} HTTP_SERVICE_CONFIG_SSL_SNI_KEY, * PHTTP_SERVICE_CONFIG_SSL_SNI_KEY;
12
13typedef struct _HTTP_SERVICE_CONFIG_SSL_SNI_SET
14{
15 HTTP_SERVICE_CONFIG_SSL_SNI_KEY KeyDesc;
16 HTTP_SERVICE_CONFIG_SSL_PARAM ParamDesc;
17} HTTP_SERVICE_CONFIG_SSL_SNI_SET, * PHTTP_SERVICE_CONFIG_SSL_SNI_SET;
18
19typedef struct _HTTP_SERVICE_CONFIG_SSL_SNI_QUERY
20{
21 HTTP_SERVICE_CONFIG_QUERY_TYPE QueryDesc;
22 HTTP_SERVICE_CONFIG_SSL_SNI_KEY KeyDesc;
23 DWORD dwToken;
24} HTTP_SERVICE_CONFIG_SSL_SNI_QUERY, * PHTTP_SERVICE_CONFIG_SSL_SNI_QUERY;
25
26#define HttpServiceConfigSslSniCertInfo static_cast<HTTP_SERVICE_CONFIG_ID>(HttpServiceConfigCache + 1)
27
28#endif
29
30static UINT SchedHttpSniSslCerts(
31 __in WCA_TODO todoSched
32);
33static HRESULT WriteExistingSniSslCert(
34 __in WCA_TODO action,
35 __in_z LPCWSTR wzId,
36 __in_z LPCWSTR wzHost,
37 __in int iPort,
38 __in int iHandleExisting,
39 __in HTTP_SERVICE_CONFIG_SSL_SNI_SET* pSniSslSet,
40 __inout_z LPWSTR* psczCustomActionData
41);
42static HRESULT WriteSniSslCert(
43 __in WCA_TODO action,
44 __in_z LPCWSTR wzId,
45 __in_z LPCWSTR wzHost,
46 __in int iPort,
47 __in int iHandleExisting,
48 __in_z LPCWSTR wzCertificateThumbprint,
49 __in_z LPCWSTR wzAppId,
50 __in_z_opt LPCWSTR wzCertificateStore,
51 __inout_z LPWSTR* psczCustomActionData
52);
53static HRESULT EnsureAppId(
54 __inout_z LPWSTR* psczAppId,
55 __in_opt HTTP_SERVICE_CONFIG_SSL_SNI_SET* pExistingSniSslSet
56);
57static HRESULT StringFromGuid(
58 __in REFGUID rguid,
59 __inout_z LPWSTR* psczGuid
60);
61static HRESULT AddSniSslCert(
62 __in_z LPCWSTR wzId,
63 __in_z LPWSTR wzHost,
64 __in int iPort,
65 __in BYTE rgbCertificateThumbprint[],
66 __in DWORD cbCertificateThumbprint,
67 __in GUID* pAppId,
68 __in_z LPWSTR wzSslCertStore
69);
70static HRESULT GetSniSslCert(
71 __in_z LPWSTR wzHost,
72 __in int nPort,
73 __out HTTP_SERVICE_CONFIG_SSL_SNI_SET** ppSet
74);
75static HRESULT RemoveSniSslCert(
76 __in_z LPCWSTR wzId,
77 __in_z LPWSTR wzHost,
78 __in int iPort
79);
80static void SetSniSslCertSetKey(
81 __in HTTP_SERVICE_CONFIG_SSL_SNI_KEY* pKey,
82 __in_z LPWSTR wzHost,
83 __in int iPort
84);
85
86
87LPCWSTR vcsWixHttpSniSslCertQuery =
88L"SELECT `Wix4HttpSniSslCert`.`Wix4HttpSniSslCert`, `Wix4HttpSniSslCert`.`Host`, `Wix4HttpSniSslCert`.`Port`, `Wix4HttpSniSslCert`.`Thumbprint`, `Wix4HttpSniSslCert`.`AppId`, `Wix4HttpSniSslCert`.`Store`, `Wix4HttpSniSslCert`.`HandleExisting`, `Wix4HttpSniSslCert`.`Component_` "
89L"FROM `Wix4HttpSniSslCert`";
90enum eWixHttpSniSslCertQuery { hurqId = 1, hurqHost, hurqPort, hurqCertificateThumbprint, hurqAppId, hurqCertificateStore, hurqHandleExisting, hurqComponent };
91
92/******************************************************************
93 SchedWixHttpSniSslCertsInstall - immediate custom action entry
94 point to prepare adding URL reservations.
95
96********************************************************************/
97extern "C" UINT __stdcall SchedHttpSniSslCertsInstall(
98 __in MSIHANDLE hInstall
99)
100{
101 HRESULT hr = S_OK;
102
103 hr = WcaInitialize(hInstall, "SchedHttpSniSslCertsInstall");
104 ExitOnFailure(hr, "Failed to initialize");
105
106 hr = SchedHttpSniSslCerts(WCA_TODO_INSTALL);
107
108LExit:
109 return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS);
110}
111
112/******************************************************************
113 SchedWixHttpSniSslCertsUninstall - immediate custom action entry
114 point to prepare removing URL reservations.
115
116********************************************************************/
117extern "C" UINT __stdcall SchedHttpSniSslCertsUninstall(
118 __in MSIHANDLE hInstall
119)
120{
121 HRESULT hr = S_OK;
122
123 hr = WcaInitialize(hInstall, "SchedHttpSniSslCertsUninstall");
124 ExitOnFailure(hr, "Failed to initialize");
125
126 hr = SchedHttpSniSslCerts(WCA_TODO_UNINSTALL);
127
128LExit:
129 return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS);
130}
131
132/******************************************************************
133 ExecHttpSniSslCerts - deferred custom action entry point to
134 register and remove URL reservations.
135
136********************************************************************/
137extern "C" UINT __stdcall ExecHttpSniSslCerts(
138 __in MSIHANDLE hInstall
139)
140{
141 HRESULT hr = S_OK;
142 BOOL fHttpInitialized = FALSE;
143 LPWSTR sczCustomActionData = NULL;
144 LPWSTR wz = NULL;
145 int iTodo = WCA_TODO_UNKNOWN;
146 LPWSTR sczId = NULL;
147 LPWSTR sczHost = NULL;
148 int iPort = 0;
149 eHandleExisting handleExisting = heIgnore;
150 LPWSTR sczCertificateThumbprint = NULL;
151 LPWSTR sczAppId = NULL;
152 LPWSTR sczCertificateStore = NULL;
153
154 BOOL fRollback = ::MsiGetMode(hInstall, MSIRUNMODE_ROLLBACK);
155 BOOL fRemove = FALSE;
156 BOOL fAdd = FALSE;
157 BOOL fFailOnExisting = FALSE;
158
159 GUID guidAppId = { };
160 BYTE* pbCertificateThumbprint = NULL;
161 DWORD cbCertificateThumbprint = 0;
162
163 // Initialize.
164 hr = WcaInitialize(hInstall, "ExecHttpSniSslCerts");
165 ExitOnFailure(hr, "Failed to initialize");
166
167 hr = HRESULT_FROM_WIN32(::HttpInitialize(HTTPAPI_VERSION_1, HTTP_INITIALIZE_CONFIG, NULL));
168 ExitOnFailure(hr, "Failed to initialize HTTP Server configuration");
169
170 fHttpInitialized = TRUE;
171
172 hr = WcaGetProperty(L"CustomActionData", &sczCustomActionData);
173 ExitOnFailure(hr, "Failed to get CustomActionData");
174 WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", sczCustomActionData);
175
176 wz = sczCustomActionData;
177 while (wz && *wz)
178 {
179 // Extract the custom action data and if rolling back, swap INSTALL and UNINSTALL.
180 hr = WcaReadIntegerFromCaData(&wz, &iTodo);
181 ExitOnFailure(hr, "Failed to read todo from custom action data");
182
183 hr = WcaReadStringFromCaData(&wz, &sczId);
184 ExitOnFailure(hr, "Failed to read Id from custom action data");
185
186 hr = WcaReadStringFromCaData(&wz, &sczHost);
187 ExitOnFailure(hr, "Failed to read Host from custom action data");
188
189 hr = WcaReadIntegerFromCaData(&wz, &iPort);
190 ExitOnFailure(hr, "Failed to read Port from custom action data");
191
192 hr = WcaReadIntegerFromCaData(&wz, reinterpret_cast<int*>(&handleExisting));
193 ExitOnFailure(hr, "Failed to read HandleExisting from custom action data");
194
195 hr = WcaReadStringFromCaData(&wz, &sczCertificateThumbprint);
196 ExitOnFailure(hr, "Failed to read CertificateThumbprint from custom action data");
197
198 hr = WcaReadStringFromCaData(&wz, &sczAppId);
199 ExitOnFailure(hr, "Failed to read AppId from custom action data");
200
201 hr = WcaReadStringFromCaData(&wz, &sczCertificateStore);
202 ExitOnFailure(hr, "Failed to read CertificateStore from custom action data");
203
204 switch (iTodo)
205 {
206 case WCA_TODO_INSTALL:
207 case WCA_TODO_REINSTALL:
208 fRemove = heReplace == handleExisting || fRollback;
209 fAdd = !fRollback || *sczCertificateThumbprint;
210 fFailOnExisting = heFail == handleExisting && !fRollback;
211 break;
212
213 case WCA_TODO_UNINSTALL:
214 fRemove = !fRollback;
215 fAdd = fRollback && *sczCertificateThumbprint;
216 fFailOnExisting = FALSE;
217 break;
218 }
219
220 if (fRemove)
221 {
222 hr = RemoveSniSslCert(sczId, sczHost, iPort);
223 if (S_OK == hr)
224 {
225 WcaLog(LOGMSG_STANDARD, "Removed SNI SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort);
226 }
227 else if (FAILED(hr))
228 {
229 if (fRollback)
230 {
231 WcaLogError(hr, "Failed to remove SNI SSL certificate to rollback '%ls' for hostname: %ls:%d", sczId, sczHost, iPort);
232 }
233 else
234 {
235 ExitOnFailure(hr, "Failed to remove SNI SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort);
236 }
237 }
238 }
239
240 if (fAdd)
241 {
242 WcaLog(LOGMSG_STANDARD, "Adding SNI SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort);
243
244 hr = StrAllocHexDecode(sczCertificateThumbprint, &pbCertificateThumbprint, &cbCertificateThumbprint);
245 ExitOnFailure(hr, "Failed to convert thumbprint to bytes for SNI SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort);
246
247 hr = ::IIDFromString(sczAppId, &guidAppId);
248 ExitOnFailure(hr, "Failed to convert AppId '%ls' back to GUID for SNI SSL certificate '%ls' for hostname: %ls:%d", sczAppId, sczId, sczHost, iPort);
249
250 hr = AddSniSslCert(sczId, sczHost, iPort, pbCertificateThumbprint, cbCertificateThumbprint, &guidAppId, sczCertificateStore && *sczCertificateStore ? sczCertificateStore : L"MY");
251 if (S_FALSE == hr && fFailOnExisting)
252 {
253 hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS);
254 }
255
256 if (S_OK == hr)
257 {
258 WcaLog(LOGMSG_STANDARD, "Added SNI SSL certificate '%ls' for hostname: %ls:%d with thumbprint: %ls", sczId, sczHost, iPort, sczCertificateThumbprint);
259 }
260 else if (FAILED(hr))
261 {
262 if (fRollback)
263 {
264 WcaLogError(hr, "Failed to add SNI SSL certificate to rollback '%ls' for hostname: %ls:%d", sczId, sczHost, iPort);
265 }
266 else
267 {
268 ExitOnFailure(hr, "Failed to add SNI SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort);
269 }
270 }
271
272 ReleaseNullMem(pbCertificateThumbprint);
273 }
274 }
275
276LExit:
277 ReleaseMem(pbCertificateThumbprint);
278 ReleaseStr(sczCertificateStore);
279 ReleaseStr(sczAppId);
280 ReleaseStr(sczCertificateThumbprint);
281 ReleaseStr(sczHost);
282 ReleaseStr(sczId);
283 ReleaseStr(sczCustomActionData);
284
285 if (fHttpInitialized)
286 {
287 ::HttpTerminate(HTTP_INITIALIZE_CONFIG, NULL);
288 }
289
290 return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS);
291}
292
293static UINT SchedHttpSniSslCerts(
294 __in WCA_TODO todoSched
295)
296{
297 HRESULT hr = S_OK;
298 UINT er = ERROR_SUCCESS;
299 BOOL fHttpInitialized = FALSE;
300 DWORD cCertificates = 0;
301
302 PMSIHANDLE hView = NULL;
303 PMSIHANDLE hRec = NULL;
304 PMSIHANDLE hQueryReq = NULL;
305 PMSIHANDLE hAceView = NULL;
306
307 LPWSTR sczCustomActionData = NULL;
308 LPWSTR sczRollbackCustomActionData = NULL;
309
310 LPWSTR sczId = NULL;
311 LPWSTR sczComponent = NULL;
312 WCA_TODO todoComponent = WCA_TODO_UNKNOWN;
313 LPWSTR sczHost = NULL;
314 int iPort = 0;
315 LPWSTR sczCertificateThumbprint = NULL;
316 LPWSTR sczAppId = NULL;
317 LPWSTR sczCertificateStore = NULL;
318 int iHandleExisting = 0;
319
320 HTTP_SERVICE_CONFIG_SSL_SNI_SET* pExistingSniSslSet = NULL;
321
322 // Anything to do?
323 hr = WcaTableExists(L"Wix4HttpSniSslCert");
324 ExitOnFailure(hr, "Failed to check if the Wix4HttpSniSslCert table exists");
325 if (S_FALSE == hr)
326 {
327 WcaLog(LOGMSG_STANDARD, "Wix4HttpSniSslCert table doesn't exist, so there are no URL reservations to configure");
328 ExitFunction();
329 }
330
331 // Query and loop through all the SNI SSL certificates.
332 hr = WcaOpenExecuteView(vcsWixHttpSniSslCertQuery, &hView);
333 ExitOnFailure(hr, "Failed to open view on the Wix4HttpSniSslCert table");
334
335 hr = HRESULT_FROM_WIN32(::HttpInitialize(HTTPAPI_VERSION_1, HTTP_INITIALIZE_CONFIG, NULL));
336 ExitOnFailure(hr, "Failed to initialize HTTP Server configuration");
337
338 fHttpInitialized = TRUE;
339
340 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
341 {
342 hr = WcaGetRecordString(hRec, hurqId, &sczId);
343 ExitOnFailure(hr, "Failed to get Wix4HttpSniSslCert.Wix4HttpSniSslCert");
344
345 hr = WcaGetRecordString(hRec, hurqComponent, &sczComponent);
346 ExitOnFailure(hr, "Failed to get Wix4HttpSniSslCert.Component_");
347
348 // Figure out what we're doing for this reservation, treating reinstall the same as install.
349 todoComponent = WcaGetComponentToDo(sczComponent);
350 if ((WCA_TODO_REINSTALL == todoComponent ? WCA_TODO_INSTALL : todoComponent) != todoSched)
351 {
352 WcaLog(LOGMSG_STANDARD, "Component '%ls' action state (%d) doesn't match request (%d) for Wix4HttpSniSslCert '%ls'", sczComponent, todoComponent, todoSched, sczId);
353 continue;
354 }
355
356 hr = WcaGetRecordFormattedString(hRec, hurqHost, &sczHost);
357 ExitOnFailure(hr, "Failed to get Wix4HttpSniSslCert.Host");
358
359 hr = WcaGetRecordFormattedInteger(hRec, hurqPort, &iPort);
360 ExitOnFailure(hr, "Failed to get Wix4HttpSniSslCert.Port");
361
362 hr = WcaGetRecordFormattedString(hRec, hurqCertificateThumbprint, &sczCertificateThumbprint);
363 ExitOnFailure(hr, "Failed to get Wix4HttpSniSslCert.CertificateThumbprint");
364
365 if (!sczHost || !*sczHost)
366 {
367 hr = E_INVALIDARG;
368 ExitOnFailure(hr, "Require a Host value for Wix4HttpSniSslCert '%ls'", sczId);
369 }
370
371 if (!iPort)
372 {
373 hr = E_INVALIDARG;
374 ExitOnFailure(hr, "Require a Port value for Wix4HttpSniSslCert '%ls'", sczId);
375 }
376
377 if (!sczCertificateThumbprint || !*sczCertificateThumbprint)
378 {
379 hr = E_INVALIDARG;
380 ExitOnFailure(hr, "Require a CertificateThumbprint value for Wix4HttpSniSslCert '%ls'", sczId);
381 }
382
383 hr = WcaGetRecordFormattedString(hRec, hurqAppId, &sczAppId);
384 ExitOnFailure(hr, "Failed to get AppId for Wix4HttpSniSslCert '%ls'", sczId);
385
386 hr = WcaGetRecordFormattedString(hRec, hurqCertificateStore, &sczCertificateStore);
387 ExitOnFailure(hr, "Failed to get CertificateStore for Wix4HttpSniSslCert '%ls'", sczId);
388
389 hr = WcaGetRecordInteger(hRec, hurqHandleExisting, &iHandleExisting);
390 ExitOnFailure(hr, "Failed to get HandleExisting for Wix4HttpSniSslCert '%ls'", sczId);
391
392 hr = GetSniSslCert(sczHost, iPort, &pExistingSniSslSet);
393 ExitOnFailure(hr, "Failed to get the existing SNI SSL certificate for Wix4HttpSniSslCert '%ls'", sczId);
394
395 hr = EnsureAppId(&sczAppId, pExistingSniSslSet);
396 ExitOnFailure(hr, "Failed to ensure AppId for Wix4HttpSniSslCert '%ls'", sczId);
397
398 hr = WriteExistingSniSslCert(todoComponent, sczId, sczHost, iPort, iHandleExisting, pExistingSniSslSet, &sczRollbackCustomActionData);
399 ExitOnFailure(hr, "Failed to write rollback custom action data for Wix4HttpSniSslCert '%ls'", sczId);
400
401 hr = WriteSniSslCert(todoComponent, sczId, sczHost, iPort, iHandleExisting, sczCertificateThumbprint, sczAppId, sczCertificateStore, &sczCustomActionData);
402 ExitOnFailure(hr, "Failed to write custom action data for Wix4HttpSniSslCert '%ls'", sczId);
403 ++cCertificates;
404
405 ReleaseNullMem(pExistingSniSslSet);
406 }
407
408 // Reaching the end of the list is not an error.
409 if (E_NOMOREITEMS == hr)
410 {
411 hr = S_OK;
412 }
413 ExitOnFailure(hr, "Failure occurred while processing Wix4HttpSniSslCert table");
414
415 // Schedule ExecHttpSniSslCerts if there's anything to do.
416 if (cCertificates)
417 {
418 WcaLog(LOGMSG_STANDARD, "Scheduling SNI SSL certificate (%ls)", sczCustomActionData);
419 WcaLog(LOGMSG_STANDARD, "Scheduling rollback SNI SSL certificate (%ls)", sczRollbackCustomActionData);
420
421 if (WCA_TODO_INSTALL == todoSched)
422 {
423 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"WixRollbackHttpSniSslCertsInstall"), sczRollbackCustomActionData, cCertificates * COST_HTTP_SNI_SSL);
424 ExitOnFailure(hr, "Failed to schedule install SNI SSL certificate rollback");
425 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"WixExecHttpSniSslCertsInstall"), sczCustomActionData, cCertificates * COST_HTTP_SNI_SSL);
426 ExitOnFailure(hr, "Failed to schedule install SNI SSL certificate execution");
427 }
428 else
429 {
430 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"WixRollbackHttpSniSslCertsUninstall"), sczRollbackCustomActionData, cCertificates * COST_HTTP_SNI_SSL);
431 ExitOnFailure(hr, "Failed to schedule uninstall SNI SSL certificate rollback");
432 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"WixExecHttpSniSslCertsUninstall"), sczCustomActionData, cCertificates * COST_HTTP_SNI_SSL);
433 ExitOnFailure(hr, "Failed to schedule uninstall SNI SSL certificate execution");
434 }
435 }
436 else
437 {
438 WcaLog(LOGMSG_STANDARD, "No SNI SSL certificates scheduled");
439 }
440
441LExit:
442 ReleaseMem(pExistingSniSslSet);
443 ReleaseStr(sczCertificateStore);
444 ReleaseStr(sczAppId);
445 ReleaseStr(sczCertificateThumbprint);
446 ReleaseStr(sczHost);
447 ReleaseStr(sczComponent);
448 ReleaseStr(sczId);
449 ReleaseStr(sczRollbackCustomActionData);
450 ReleaseStr(sczCustomActionData);
451
452 if (fHttpInitialized)
453 {
454 ::HttpTerminate(HTTP_INITIALIZE_CONFIG, NULL);
455 }
456
457 return WcaFinalize(er = FAILED(hr) ? ERROR_INSTALL_FAILURE : er);
458}
459
460static HRESULT WriteExistingSniSslCert(
461 __in WCA_TODO action,
462 __in_z LPCWSTR wzId,
463 __in_z LPCWSTR wzHost,
464 __in int iPort,
465 __in int iHandleExisting,
466 __in HTTP_SERVICE_CONFIG_SSL_SNI_SET* pSniSslSet,
467 __inout_z LPWSTR* psczCustomActionData
468)
469{
470 HRESULT hr = S_OK;
471 LPWSTR sczCertificateThumbprint = NULL;
472 LPWSTR sczAppId = NULL;
473 LPCWSTR wzCertificateStore = NULL;
474
475 if (pSniSslSet)
476 {
477 hr = StrAllocHexEncode(reinterpret_cast<BYTE*>(pSniSslSet->ParamDesc.pSslHash), pSniSslSet->ParamDesc.SslHashLength, &sczCertificateThumbprint);
478 ExitOnFailure(hr, "Failed to convert existing certificate thumbprint to hex for Wix4HttpSniSslCert '%ls'", wzId);
479
480 hr = StringFromGuid(pSniSslSet->ParamDesc.AppId, &sczAppId);
481 ExitOnFailure(hr, "Failed to copy existing AppId for Wix4HttpSniSslCert '%ls'", wzId);
482
483 wzCertificateStore = pSniSslSet->ParamDesc.pSslCertStoreName;
484 }
485
486 hr = WriteSniSslCert(action, wzId, wzHost, iPort, iHandleExisting, sczCertificateThumbprint ? sczCertificateThumbprint : L"", sczAppId ? sczAppId : L"", wzCertificateStore ? wzCertificateStore : L"", psczCustomActionData);
487 ExitOnFailure(hr, "Failed to write custom action data for Wix4HttpSniSslCert '%ls'", wzId);
488
489LExit:
490 ReleaseStr(sczAppId);
491 ReleaseStr(sczCertificateThumbprint);
492
493 return hr;
494}
495
496static HRESULT WriteSniSslCert(
497 __in WCA_TODO action,
498 __in_z LPCWSTR wzId,
499 __in_z LPCWSTR wzHost,
500 __in int iPort,
501 __in int iHandleExisting,
502 __in_z LPCWSTR wzCertificateThumbprint,
503 __in_z LPCWSTR wzAppId,
504 __in_z_opt LPCWSTR wzCertificateStore,
505 __inout_z LPWSTR* psczCustomActionData
506)
507{
508 HRESULT hr = S_OK;
509
510 hr = WcaWriteIntegerToCaData(action, psczCustomActionData);
511 ExitOnFailure(hr, "Failed to write action to custom action data");
512
513 hr = WcaWriteStringToCaData(wzId, psczCustomActionData);
514 ExitOnFailure(hr, "Failed to write id to custom action data");
515
516 hr = WcaWriteStringToCaData(wzHost, psczCustomActionData);
517 ExitOnFailure(hr, "Failed to write Host to custom action data");
518
519 hr = WcaWriteIntegerToCaData(iPort, psczCustomActionData);
520 ExitOnFailure(hr, "Failed to write Port to custom action data");
521
522 hr = WcaWriteIntegerToCaData(iHandleExisting, psczCustomActionData);
523 ExitOnFailure(hr, "Failed to write HandleExisting to custom action data");
524
525 hr = WcaWriteStringToCaData(wzCertificateThumbprint, psczCustomActionData);
526 ExitOnFailure(hr, "Failed to write CertificateThumbprint to custom action data");
527
528 hr = WcaWriteStringToCaData(wzAppId, psczCustomActionData);
529 ExitOnFailure(hr, "Failed to write AppId to custom action data");
530
531 hr = WcaWriteStringToCaData(wzCertificateStore ? wzCertificateStore : L"", psczCustomActionData);
532 ExitOnFailure(hr, "Failed to write CertificateStore to custom action data");
533
534LExit:
535 return hr;
536}
537
538static HRESULT EnsureAppId(
539 __inout_z LPWSTR* psczAppId,
540 __in_opt HTTP_SERVICE_CONFIG_SSL_SNI_SET* pExistingSniSslSet
541)
542{
543 HRESULT hr = S_OK;
544 RPC_STATUS rs = RPC_S_OK;
545 GUID guid = { };
546
547 if (!psczAppId || !*psczAppId || !**psczAppId)
548 {
549 if (pExistingSniSslSet)
550 {
551 hr = StringFromGuid(pExistingSniSslSet->ParamDesc.AppId, psczAppId);
552 ExitOnFailure(hr, "Failed to ensure AppId guid");
553 }
554 else
555 {
556 rs = ::UuidCreate(&guid);
557 hr = HRESULT_FROM_RPC(rs);
558 ExitOnRootFailure(hr, "Failed to create guid for AppId");
559
560 hr = StringFromGuid(guid, psczAppId);
561 ExitOnFailure(hr, "Failed to ensure AppId guid");
562 }
563 }
564
565LExit:
566 return hr;
567}
568
569static HRESULT StringFromGuid(
570 __in REFGUID rguid,
571 __inout_z LPWSTR* psczGuid
572)
573{
574 HRESULT hr = S_OK;
575 WCHAR wzGuid[39];
576
577 if (!::StringFromGUID2(rguid, wzGuid, countof(wzGuid)))
578 {
579 hr = E_OUTOFMEMORY;
580 ExitOnRootFailure(hr, "Failed to convert guid into string");
581 }
582
583 hr = StrAllocString(psczGuid, wzGuid, 0);
584 ExitOnFailure(hr, "Failed to copy guid");
585
586LExit:
587 return hr;
588}
589
590static HRESULT AddSniSslCert(
591 __in_z LPCWSTR /*wzId*/,
592 __in_z LPWSTR wzHost,
593 __in int iPort,
594 __in BYTE rgbCertificateThumbprint[],
595 __in DWORD cbCertificateThumbprint,
596 __in GUID* pAppId,
597 __in_z LPWSTR wzSslCertStore
598)
599{
600 HRESULT hr = S_OK;
601 DWORD er = ERROR_SUCCESS;
602 HTTP_SERVICE_CONFIG_SSL_SNI_SET set = { };
603
604 SetSniSslCertSetKey(&set.KeyDesc, wzHost, iPort);
605 set.ParamDesc.SslHashLength = cbCertificateThumbprint;
606 set.ParamDesc.pSslHash = rgbCertificateThumbprint;
607 set.ParamDesc.AppId = *pAppId;
608 set.ParamDesc.pSslCertStoreName = wzSslCertStore;
609
610 er = ::HttpSetServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &set, sizeof(set), NULL);
611 if (ERROR_ALREADY_EXISTS == er)
612 {
613 hr = S_FALSE;
614 }
615 else
616 {
617 hr = HRESULT_FROM_WIN32(er);
618 }
619
620 return hr;
621}
622
623static HRESULT GetSniSslCert(
624 __in_z LPWSTR wzHost,
625 __in int nPort,
626 __out HTTP_SERVICE_CONFIG_SSL_SNI_SET** ppSet
627)
628{
629 HRESULT hr = S_OK;
630 DWORD er = ERROR_SUCCESS;
631 HTTP_SERVICE_CONFIG_SSL_SNI_QUERY query = { };
632 HTTP_SERVICE_CONFIG_SSL_SNI_SET* pSet = NULL;
633 ULONG cbSet = 0;
634
635 *ppSet = NULL;
636
637 query.QueryDesc = HttpServiceConfigQueryExact;
638 SetSniSslCertSetKey(&query.KeyDesc, wzHost, nPort);
639
640 er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL);
641 if (ERROR_INSUFFICIENT_BUFFER == er)
642 {
643 pSet = reinterpret_cast<HTTP_SERVICE_CONFIG_SSL_SNI_SET*>(MemAlloc(cbSet, TRUE));
644 ExitOnNull(pSet, hr, E_OUTOFMEMORY, "Failed to allocate query SN SSL certificate buffer");
645
646 er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL);
647 }
648
649 if (ERROR_SUCCESS == er)
650 {
651 *ppSet = pSet;
652 pSet = NULL;
653 }
654 else if (ERROR_FILE_NOT_FOUND == er)
655 {
656 hr = S_FALSE;
657 }
658 else
659 {
660 hr = HRESULT_FROM_WIN32(er);
661 }
662
663LExit:
664 ReleaseMem(pSet);
665
666 return hr;
667}
668
669static HRESULT RemoveSniSslCert(
670 __in_z LPCWSTR /*wzId*/,
671 __in_z LPWSTR wzHost,
672 __in int iPort
673)
674{
675 HRESULT hr = S_OK;
676 DWORD er = ERROR_SUCCESS;
677 HTTP_SERVICE_CONFIG_SSL_SNI_SET set = { };
678
679 SetSniSslCertSetKey(&set.KeyDesc, wzHost, iPort);
680
681 er = ::HttpDeleteServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &set, sizeof(set), NULL);
682 if (ERROR_FILE_NOT_FOUND == er)
683 {
684 hr = S_FALSE;
685 }
686 else
687 {
688 hr = HRESULT_FROM_WIN32(er);
689 }
690
691 return hr;
692}
693
694static void SetSniSslCertSetKey(
695 __in HTTP_SERVICE_CONFIG_SSL_SNI_KEY* pKey,
696 __in_z LPWSTR wzHost,
697 __in int iPort
698)
699{
700 pKey->Host = wzHost;
701 SOCKADDR_IN* pss = reinterpret_cast<SOCKADDR_IN*>(&pKey->IpPort);
702 pss->sin_family = AF_INET;
703 pss->sin_port = htons(static_cast<USHORT>(iPort));
704}
diff --git a/src/ext/Http/ca/wixhttpca.cpp b/src/ext/Http/ca/wixhttpca.cpp
new file mode 100644
index 00000000..8c846ffc
--- /dev/null
+++ b/src/ext/Http/ca/wixhttpca.cpp
@@ -0,0 +1,530 @@
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
5static HRESULT AppendUrlAce(
6 __in LPWSTR wzSecurityPrincipal,
7 __in int iRights,
8 __in LPWSTR* psczSDDL
9 );
10static HRESULT WriteHttpUrlReservation(
11 __in WCA_TODO action,
12 __in LPWSTR wzUrl,
13 __in LPWSTR wzSDDL,
14 __in int iHandleExisting,
15 __in LPWSTR* psczCustomActionData
16 );
17static HRESULT AddUrlReservation(
18 __in LPWSTR wzUrl,
19 __in LPWSTR wzSddl
20 );
21static HRESULT GetUrlReservation(
22 __in LPWSTR wzUrl,
23 __deref_out_z LPWSTR* psczSddl
24 );
25static HRESULT RemoveUrlReservation(
26 __in LPWSTR wzUrl
27 );
28
29HTTPAPI_VERSION vcHttpVersion = HTTPAPI_VERSION_1;
30ULONG vcHttpFlags = HTTP_INITIALIZE_CONFIG;
31
32LPCWSTR vcsHttpUrlReservationQuery =
33 L"SELECT `Wix4HttpUrlReservation`.`Wix4HttpUrlReservation`, `Wix4HttpUrlReservation`.`HandleExisting`, `Wix4HttpUrlReservation`.`Sddl`, `Wix4HttpUrlReservation`.`Url`, `Wix4HttpUrlReservation`.`Component_` "
34 L"FROM `Wix4HttpUrlReservation`";
35enum eHttpUrlReservationQuery { hurqId = 1, hurqHandleExisting, hurqSDDL, hurqUrl, hurqComponent };
36
37LPCWSTR vcsHttpUrlAceQuery =
38 L"SELECT `Wix4HttpUrlAce`.`SecurityPrincipal`, `Wix4HttpUrlAce`.`Rights` "
39 L"FROM `Wix4HttpUrlAce` "
40 L"WHERE `Wix4HttpUrlAce`.`Wix4HttpUrlReservation_`=?";
41enum eHttpUrlAceQuery { huaqSecurityPrincipal = 1, huaqRights };
42
43/******************************************************************
44 SchedHttpUrlReservations - immediate custom action worker to
45 prepare configuring URL reservations.
46
47********************************************************************/
48static UINT SchedHttpUrlReservations(
49 __in MSIHANDLE hInstall,
50 __in WCA_TODO todoSched
51 )
52{
53 HRESULT hr = S_OK;
54 UINT er = ERROR_SUCCESS;
55 BOOL fAceTableExists = FALSE;
56 BOOL fHttpInitialized = FALSE;
57 DWORD cUrlReservations = 0;
58
59 PMSIHANDLE hView = NULL;
60 PMSIHANDLE hRec = NULL;
61 PMSIHANDLE hQueryReq = NULL;
62 PMSIHANDLE hAceView = NULL;
63
64 LPWSTR sczCustomActionData = NULL;
65 LPWSTR sczRollbackCustomActionData = NULL;
66
67 LPWSTR sczId = NULL;
68 LPWSTR sczComponent = NULL;
69 WCA_TODO todoComponent = WCA_TODO_UNKNOWN;
70 LPWSTR sczUrl = NULL;
71 LPWSTR sczSecurityPrincipal = NULL;
72 int iRights = 0;
73 int iHandleExisting = 0;
74
75 LPWSTR sczExistingSDDL = NULL;
76 LPWSTR sczSDDL = NULL;
77
78 // Initialize.
79 hr = WcaInitialize(hInstall, "SchedHttpUrlReservations");
80 ExitOnFailure(hr, "Failed to initialize.");
81
82 // Anything to do?
83 hr = WcaTableExists(L"Wix4HttpUrlReservation");
84 ExitOnFailure(hr, "Failed to check if the Wix4HttpUrlReservation table exists.");
85 if (S_FALSE == hr)
86 {
87 WcaLog(LOGMSG_STANDARD, "Wix4HttpUrlReservation table doesn't exist, so there are no URL reservations to configure.");
88 ExitFunction();
89 }
90
91 hr = WcaTableExists(L"Wix4HttpUrlAce");
92 ExitOnFailure(hr, "Failed to check if the Wix4HttpUrlAce table exists.");
93 fAceTableExists = S_OK == hr;
94
95 // Query and loop through all the URL reservations.
96 hr = WcaOpenExecuteView(vcsHttpUrlReservationQuery, &hView);
97 ExitOnFailure(hr, "Failed to open view on the Wix4HttpUrlReservation table.");
98
99 hr = HRESULT_FROM_WIN32(::HttpInitialize(vcHttpVersion, vcHttpFlags, NULL));
100 ExitOnFailure(hr, "Failed to initialize HTTP Server configuration.");
101
102 fHttpInitialized = TRUE;
103
104 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
105 {
106 hr = WcaGetRecordString(hRec, hurqId, &sczId);
107 ExitOnFailure(hr, "Failed to get Wix4HttpUrlReservation.Wix4HttpUrlReservation");
108
109 hr = WcaGetRecordString(hRec, hurqComponent, &sczComponent);
110 ExitOnFailure(hr, "Failed to get Wix4HttpUrlReservation.Component_");
111
112 // Figure out what we're doing for this reservation, treating reinstall the same as install.
113 todoComponent = WcaGetComponentToDo(sczComponent);
114 if ((WCA_TODO_REINSTALL == todoComponent ? WCA_TODO_INSTALL : todoComponent) != todoSched)
115 {
116 WcaLog(LOGMSG_STANDARD, "Component '%ls' action state (%d) doesn't match request (%d) for UrlReservation '%ls'.", sczComponent, todoComponent, todoSched, sczId);
117 continue;
118 }
119
120 hr = WcaGetRecordFormattedString(hRec, hurqUrl, &sczUrl);
121 ExitOnFailure(hr, "Failed to get Wix4HttpUrlReservation.Url");
122
123 hr = WcaGetRecordInteger(hRec, hurqHandleExisting, &iHandleExisting);
124 ExitOnFailure(hr, "Failed to get Wix4HttpUrlReservation.HandleExisting");
125
126 if (::MsiRecordIsNull(hRec, hurqSDDL))
127 {
128 hr = StrAllocString(&sczSDDL, L"D:", 2);
129 ExitOnFailure(hr, "Failed to allocate SDDL string.");
130
131 // Skip creating the SDDL on uninstall, since it's never used and the lookup(s) could fail.
132 if (fAceTableExists && WCA_TODO_UNINSTALL != todoComponent)
133 {
134 hQueryReq = ::MsiCreateRecord(1);
135 hr = WcaSetRecordString(hQueryReq, 1, sczId);
136 ExitOnFailure(hr, "Failed to create record for querying Wix4HttpUrlAce table for reservation %ls", sczId);
137
138 hr = WcaOpenView(vcsHttpUrlAceQuery, &hAceView);
139 ExitOnFailure(hr, "Failed to open view on Wix4HttpUrlAce table for reservation %ls", sczId);
140 hr = WcaExecuteView(hAceView, hQueryReq);
141 ExitOnFailure(hr, "Failed to execute view on Wix4HttpUrlAce table for reservation %ls", sczId);
142
143 while (S_OK == (hr = WcaFetchRecord(hAceView, &hRec)))
144 {
145 hr = WcaGetRecordFormattedString(hRec, huaqSecurityPrincipal, &sczSecurityPrincipal);
146 ExitOnFailure(hr, "Failed to get Wix4HttpUrlAce.SecurityPrincipal");
147
148 hr = WcaGetRecordInteger(hRec, huaqRights, &iRights);
149 ExitOnFailure(hr, "Failed to get Wix4HttpUrlAce.Rights");
150
151 hr = AppendUrlAce(sczSecurityPrincipal, iRights, &sczSDDL);
152 ExitOnFailure(hr, "Failed to append URL ACE.");
153 }
154
155 if (E_NOMOREITEMS == hr)
156 {
157 hr = S_OK;
158 }
159 ExitOnFailure(hr, "Failed to enumerate selected rows from Wix4HttpUrlAce table.");
160 }
161 }
162 else
163 {
164 hr = WcaGetRecordFormattedString(hRec, hurqSDDL, &sczSDDL);
165 ExitOnFailure(hr, "Failed to get Wix4HttpUrlReservation.SDDL");
166 }
167
168 hr = GetUrlReservation(sczUrl, &sczExistingSDDL);
169 ExitOnFailure(hr, "Failed to get the existing SDDL for %ls", sczUrl);
170
171 hr = WriteHttpUrlReservation(todoComponent, sczUrl, sczExistingSDDL ? sczExistingSDDL : L"", iHandleExisting, &sczRollbackCustomActionData);
172 ExitOnFailure(hr, "Failed to write URL Reservation to rollback custom action data.");
173
174 hr = WriteHttpUrlReservation(todoComponent, sczUrl, sczSDDL, iHandleExisting, &sczCustomActionData);
175 ExitOnFailure(hr, "Failed to write URL reservation to custom action data.");
176 ++cUrlReservations;
177 }
178
179 // Reaching the end of the list is not an error.
180 if (E_NOMOREITEMS == hr)
181 {
182 hr = S_OK;
183 }
184 ExitOnFailure(hr, "Failure occurred while processing Wix4HttpUrlReservation table.");
185
186 // Schedule ExecHttpUrlReservations if there's anything to do.
187 if (cUrlReservations)
188 {
189 WcaLog(LOGMSG_STANDARD, "Scheduling URL reservations (%ls)", sczCustomActionData);
190 WcaLog(LOGMSG_STANDARD, "Scheduling rollback URL reservations (%ls)", sczRollbackCustomActionData);
191
192 if (WCA_TODO_INSTALL == todoSched)
193 {
194 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"WixRollbackHttpUrlReservationsInstall"), sczRollbackCustomActionData, cUrlReservations * COST_HTTP_URL_ACL);
195 ExitOnFailure(hr, "Failed to schedule install URL reservations rollback.");
196 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"WixExecHttpUrlReservationsInstall"), sczCustomActionData, cUrlReservations * COST_HTTP_URL_ACL);
197 ExitOnFailure(hr, "Failed to schedule install URL reservations execution.");
198 }
199 else
200 {
201 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"WixRollbackHttpUrlReservationsUninstall"), sczRollbackCustomActionData, cUrlReservations * COST_HTTP_URL_ACL);
202 ExitOnFailure(hr, "Failed to schedule uninstall URL reservations rollback.");
203 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"WixExecHttpUrlReservationsUninstall"), sczCustomActionData, cUrlReservations * COST_HTTP_URL_ACL);
204 ExitOnFailure(hr, "Failed to schedule uninstall URL reservations execution.");
205 }
206 }
207 else
208 {
209 WcaLog(LOGMSG_STANDARD, "No URL reservations scheduled.");
210 }
211
212LExit:
213 ReleaseStr(sczSDDL);
214 ReleaseStr(sczExistingSDDL);
215 ReleaseStr(sczSecurityPrincipal);
216 ReleaseStr(sczUrl)
217 ReleaseStr(sczComponent);
218 ReleaseStr(sczId);
219 ReleaseStr(sczRollbackCustomActionData);
220 ReleaseStr(sczCustomActionData);
221
222 if (fHttpInitialized)
223 {
224 ::HttpTerminate(vcHttpFlags, NULL);
225 }
226
227 return WcaFinalize(er = FAILED(hr) ? ERROR_INSTALL_FAILURE : er);
228}
229
230static HRESULT AppendUrlAce(
231 __in LPWSTR wzSecurityPrincipal,
232 __in int iRights,
233 __in LPWSTR* psczSDDL
234 )
235{
236 HRESULT hr = S_OK;
237 LPCWSTR wzSid = NULL;
238 LPWSTR sczSid = NULL;
239
240 Assert(wzSecurityPrincipal && *wzSecurityPrincipal);
241 Assert(psczSDDL && *psczSDDL);
242
243 // As documented in the xsd, if the first char is '*', then the rest of the string is a SID string, e.g. *S-1-5-18.
244 if (L'*' == wzSecurityPrincipal[0])
245 {
246 wzSid = &wzSecurityPrincipal[1];
247 }
248 else
249 {
250 hr = AclGetAccountSidStringEx(NULL, wzSecurityPrincipal, &sczSid);
251 ExitOnFailure(hr, "Failed to lookup the SID for account %ls", wzSecurityPrincipal);
252
253 wzSid = sczSid;
254 }
255
256 hr = StrAllocFormatted(psczSDDL, L"%ls(A;;%#x;;;%ls)", *psczSDDL, iRights, wzSid);
257
258LExit:
259 ReleaseStr(sczSid);
260
261 return hr;
262}
263
264static HRESULT WriteHttpUrlReservation(
265 __in WCA_TODO action,
266 __in LPWSTR wzUrl,
267 __in LPWSTR wzSDDL,
268 __in int iHandleExisting,
269 __in LPWSTR* psczCustomActionData
270 )
271{
272 HRESULT hr = S_OK;
273
274 hr = WcaWriteIntegerToCaData(action, psczCustomActionData);
275 ExitOnFailure(hr, "Failed to write action to custom action data.");
276
277 hr = WcaWriteStringToCaData(wzUrl, psczCustomActionData);
278 ExitOnFailure(hr, "Failed to write URL to custom action data.");
279
280 hr = WcaWriteStringToCaData(wzSDDL, psczCustomActionData);
281 ExitOnFailure(hr, "Failed to write SDDL to custom action data.");
282
283 hr = WcaWriteIntegerToCaData(iHandleExisting, psczCustomActionData);
284 ExitOnFailure(hr, "Failed to write HandleExisting to custom action data.")
285
286LExit:
287 return hr;
288}
289
290/******************************************************************
291 SchedHttpUrlReservationsInstall - immediate custom action entry
292 point to prepare adding URL reservations.
293
294********************************************************************/
295extern "C" UINT __stdcall SchedHttpUrlReservationsInstall(
296 __in MSIHANDLE hInstall
297 )
298{
299 return SchedHttpUrlReservations(hInstall, WCA_TODO_INSTALL);
300}
301
302/******************************************************************
303 SchedHttpUrlReservationsUninstall - immediate custom action entry
304 point to prepare removing URL reservations.
305
306********************************************************************/
307extern "C" UINT __stdcall SchedHttpUrlReservationsUninstall(
308 __in MSIHANDLE hInstall
309 )
310{
311 return SchedHttpUrlReservations(hInstall, WCA_TODO_UNINSTALL);
312}
313
314/******************************************************************
315 ExecHttpUrlReservations - deferred custom action entry point to
316 register and remove URL reservations.
317
318********************************************************************/
319extern "C" UINT __stdcall ExecHttpUrlReservations(
320 __in MSIHANDLE hInstall
321 )
322{
323 HRESULT hr = S_OK;
324 BOOL fHttpInitialized = FALSE;
325 LPWSTR sczCustomActionData = NULL;
326 LPWSTR wz = NULL;
327 int iTodo = WCA_TODO_UNKNOWN;
328 LPWSTR sczUrl = NULL;
329 LPWSTR sczSDDL = NULL;
330 eHandleExisting handleExisting = heIgnore;
331 BOOL fRollback = ::MsiGetMode(hInstall, MSIRUNMODE_ROLLBACK);
332 BOOL fRemove = FALSE;
333 BOOL fAdd = FALSE;
334 BOOL fFailOnExisting = FALSE;
335
336 // Initialize.
337 hr = WcaInitialize(hInstall, "ExecHttpUrlReservations");
338 ExitOnFailure(hr, "Failed to initialize.");
339
340 hr = HRESULT_FROM_WIN32(::HttpInitialize(vcHttpVersion, vcHttpFlags, NULL));
341 ExitOnFailure(hr, "Failed to initialize HTTP Server configuration.");
342
343 fHttpInitialized = TRUE;
344
345 hr = WcaGetProperty(L"CustomActionData", &sczCustomActionData);
346 ExitOnFailure(hr, "Failed to get CustomActionData.");
347 WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", sczCustomActionData);
348
349 if (!sczCustomActionData || !*sczCustomActionData)
350 {
351 WcaLog(LOGMSG_STANDARD, "No URL reservations to be executed.");
352 }
353
354 wz = sczCustomActionData;
355 while (wz && *wz)
356 {
357 // Extract the custom action data and if rolling back, swap INSTALL and UNINSTALL.
358 hr = WcaReadIntegerFromCaData(&wz, &iTodo);
359 ExitOnFailure(hr, "Failed to read todo from custom action data.");
360
361 hr = WcaReadStringFromCaData(&wz, &sczUrl);
362 ExitOnFailure(hr, "Failed to read Url from custom action data.");
363
364 hr = WcaReadStringFromCaData(&wz, &sczSDDL);
365 ExitOnFailure(hr, "Failed to read SDDL from custom action data.");
366
367 hr = WcaReadIntegerFromCaData(&wz, reinterpret_cast<int*>(&handleExisting));
368 ExitOnFailure(hr, "Failed to read HandleExisting from custom action data.");
369
370 switch (iTodo)
371 {
372 case WCA_TODO_INSTALL:
373 case WCA_TODO_REINSTALL:
374 fRemove = heReplace == handleExisting || fRollback;
375 fAdd = !fRollback || *sczSDDL;
376 fFailOnExisting = heFail == handleExisting && !fRollback;
377 break;
378
379 case WCA_TODO_UNINSTALL:
380 fRemove = !fRollback;
381 fAdd = fRollback && *sczSDDL;
382 fFailOnExisting = FALSE;
383 break;
384 }
385
386 if (fRemove)
387 {
388 WcaLog(LOGMSG_STANDARD, "Removing reservation for URL '%ls'", sczUrl);
389 hr = RemoveUrlReservation(sczUrl);
390 if (FAILED(hr))
391 {
392 if (fRollback)
393 {
394 WcaLogError(hr, "Failed to remove reservation for rollback for URL '%ls'", sczUrl);
395 }
396 else
397 {
398 ExitOnFailure(hr, "Failed to remove reservation for URL '%ls'", sczUrl);
399 }
400 }
401 }
402
403 if (fAdd)
404 {
405 WcaLog(LOGMSG_STANDARD, "Adding reservation for URL '%ls' with SDDL '%ls'", sczUrl, sczSDDL);
406 hr = AddUrlReservation(sczUrl, sczSDDL);
407 if (S_FALSE == hr && fFailOnExisting)
408 {
409 hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS);
410 }
411 if (FAILED(hr))
412 {
413 if (fRollback)
414 {
415 WcaLogError(hr, "Failed to add reservation for rollback for URL '%ls' with SDDL '%ls'", sczUrl, sczSDDL);
416 }
417 else
418 {
419 ExitOnFailure(hr, "Failed to add reservation for URL '%ls' with SDDL '%ls'", sczUrl, sczSDDL);
420 }
421 }
422 }
423 }
424
425LExit:
426 ReleaseStr(sczSDDL);
427 ReleaseStr(sczUrl);
428 ReleaseStr(sczCustomActionData);
429
430 if (fHttpInitialized)
431 {
432 ::HttpTerminate(vcHttpFlags, NULL);
433 }
434
435 return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS);
436}
437
438static HRESULT AddUrlReservation(
439 __in LPWSTR wzUrl,
440 __in LPWSTR wzSddl
441 )
442{
443 HRESULT hr = S_OK;
444 DWORD er = ERROR_SUCCESS;
445 HTTP_SERVICE_CONFIG_URLACL_SET set = { };
446
447 set.KeyDesc.pUrlPrefix = wzUrl;
448 set.ParamDesc.pStringSecurityDescriptor = wzSddl;
449
450 er = ::HttpSetServiceConfiguration(NULL, HttpServiceConfigUrlAclInfo, &set, sizeof(set), NULL);
451 if (ERROR_ALREADY_EXISTS == er)
452 {
453 hr = S_FALSE;
454 }
455 else
456 {
457 hr = HRESULT_FROM_WIN32(er);
458 }
459 ExitOnFailure(hr, "Failed to add URL reservation: %ls, ACL: %ls", wzUrl, wzSddl);
460
461LExit:
462 return hr;
463}
464
465static HRESULT GetUrlReservation(
466 __in LPWSTR wzUrl,
467 __deref_out_z LPWSTR* psczSddl
468 )
469{
470 HRESULT hr = S_OK;
471 DWORD er = ERROR_SUCCESS;
472 HTTP_SERVICE_CONFIG_URLACL_QUERY query = { };
473 HTTP_SERVICE_CONFIG_URLACL_SET* pSet = NULL;
474 ULONG cbSet = 0;
475
476 query.QueryDesc = HttpServiceConfigQueryExact;
477 query.KeyDesc.pUrlPrefix = wzUrl;
478
479 er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigUrlAclInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL);
480 if (ERROR_INSUFFICIENT_BUFFER == er)
481 {
482 pSet = reinterpret_cast<HTTP_SERVICE_CONFIG_URLACL_SET*>(MemAlloc(cbSet, TRUE));
483 ExitOnNull(pSet, hr, E_OUTOFMEMORY, "Failed to allocate query URLACL buffer.");
484
485 er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigUrlAclInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL);
486 }
487
488 if (ERROR_SUCCESS == er)
489 {
490 hr = StrAllocString(psczSddl, pSet->ParamDesc.pStringSecurityDescriptor, 0);
491 }
492 else if (ERROR_FILE_NOT_FOUND == er)
493 {
494 hr = S_FALSE;
495 }
496 else
497 {
498 hr = HRESULT_FROM_WIN32(er);
499 }
500
501LExit:
502 ReleaseMem(pSet);
503
504 return hr;
505}
506
507static HRESULT RemoveUrlReservation(
508 __in LPWSTR wzUrl
509 )
510{
511 HRESULT hr = S_OK;
512 DWORD er = ERROR_SUCCESS;
513 HTTP_SERVICE_CONFIG_URLACL_SET set = { };
514
515 set.KeyDesc.pUrlPrefix = wzUrl;
516
517 er = ::HttpDeleteServiceConfiguration(NULL, HttpServiceConfigUrlAclInfo, &set, sizeof(set), NULL);
518 if (ERROR_FILE_NOT_FOUND == er)
519 {
520 hr = S_FALSE;
521 }
522 else
523 {
524 hr = HRESULT_FROM_WIN32(er);
525 }
526 ExitOnFailure(hr, "Failed to remove URL reservation: %ls", wzUrl);
527
528LExit:
529 return hr;
530}
diff --git a/src/ext/Http/ca/wixhttpca.def b/src/ext/Http/ca/wixhttpca.def
new file mode 100644
index 00000000..281c5631
--- /dev/null
+++ b/src/ext/Http/ca/wixhttpca.def
@@ -0,0 +1,12 @@
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 "httpca"
5
6EXPORTS
7 SchedHttpUrlReservationsInstall
8 SchedHttpUrlReservationsUninstall
9 ExecHttpUrlReservations
10 SchedHttpSniSslCertsInstall
11 SchedHttpSniSslCertsUninstall
12 ExecHttpSniSslCerts
diff --git a/src/ext/Http/nuget.config b/src/ext/Http/nuget.config
new file mode 100644
index 00000000..db7aba29
--- /dev/null
+++ b/src/ext/Http/nuget.config
@@ -0,0 +1,17 @@
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-dtf" value="https://ci.appveyor.com/nuget/wixtoolset-dtf" />
11 <add key="wixtoolset-dutil" value="https://ci.appveyor.com/nuget/wixtoolset-dutil" />
12 <add key="wixtoolset-wcautil" value="https://ci.appveyor.com/nuget/wixtoolset-wcautil" />
13 <add key="wixtoolset-tools" value="https://ci.appveyor.com/nuget/wixtoolset-tools" />
14 <add key="wixbuildtools" value="https://ci.appveyor.com/nuget/wixbuildtools" />
15 <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
16 </packageSources>
17</configuration> \ No newline at end of file
diff --git a/src/ext/Http/test/WixToolsetTest.Http/HttpExtensionFixture.cs b/src/ext/Http/test/WixToolsetTest.Http/HttpExtensionFixture.cs
new file mode 100644
index 00000000..40b49327
--- /dev/null
+++ b/src/ext/Http/test/WixToolsetTest.Http/HttpExtensionFixture.cs
@@ -0,0 +1,57 @@
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.Http
4{
5 using WixBuildTools.TestSupport;
6 using WixToolset.Core.TestPackage;
7 using WixToolset.Http;
8 using Xunit;
9
10 public class HttpExtensionFixture
11 {
12 [Fact]
13 public void CanBuildUsingSniSssl()
14 {
15 var folder = TestData.Get("TestData", "SniSsl");
16 var build = new Builder(folder, typeof(HttpExtensionFactory), new[] { folder });
17
18 var results = build.BuildAndQuery(Build, "CustomAction", "Wix4HttpSniSslCert");
19 WixAssert.CompareLineByLine(new[]
20 {
21 "CustomAction:Wix4ExecHttpSniSslCertsInstall_X86\t3073\tWix4HttpCA_X86\tExecHttpSniSslCerts\t",
22 "CustomAction:Wix4ExecHttpSniSslCertsUninstall_X86\t3073\tWix4HttpCA_X86\tExecHttpSniSslCerts\t",
23 "CustomAction:Wix4RollbackHttpSniSslCertsInstall_X86\t3329\tWix4HttpCA_X86\tExecHttpSniSslCerts\t",
24 "CustomAction:Wix4RollbackHttpSniSslCertsUninstall_X86\t3329\tWix4HttpCA_X86\tExecHttpSniSslCerts\t",
25 "CustomAction:Wix4SchedHttpSniSslCertsInstall_X86\t1\tWix4HttpCA_X86\tSchedHttpSniSslCertsInstall\t",
26 "CustomAction:Wix4SchedHttpSniSslCertsUninstall_X86\t1\tWix4HttpCA_X86\tSchedHttpSniSslCertsUninstall\t",
27 "Wix4HttpSniSslCert:sslC9YX6_H7UL_WGBx4DoDGI.Sj.D0\texample.com\t8080\t[SOME_THUMBPRINT]\t\t\t2\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo",
28 }, results);
29 }
30
31 [Fact]
32 public void CanBuildUsingUrlReservation()
33 {
34 var folder = TestData.Get(@"TestData\UsingUrlReservation");
35 var build = new Builder(folder, typeof(HttpExtensionFactory), new[] { folder });
36
37 var results = build.BuildAndQuery(Build, "CustomAction", "Wix4HttpUrlAce", "Wix4HttpUrlReservation");
38 WixAssert.CompareLineByLine(new[]
39 {
40 "CustomAction:Wix4ExecHttpUrlReservationsInstall_X86\t3073\tWix4HttpCA_X86\tExecHttpUrlReservations\t",
41 "CustomAction:Wix4ExecHttpUrlReservationsUninstall_X86\t3073\tWix4HttpCA_X86\tExecHttpUrlReservations\t",
42 "CustomAction:Wix4RollbackHttpUrlReservationsInstall_X86\t3329\tWix4HttpCA_X86\tExecHttpUrlReservations\t",
43 "CustomAction:Wix4RollbackHttpUrlReservationsUninstall_X86\t3329\tWix4HttpCA_X86\tExecHttpUrlReservations\t",
44 "CustomAction:Wix4SchedHttpUrlReservationsInstall_X86\t1\tWix4HttpCA_X86\tSchedHttpUrlReservationsInstall\t",
45 "CustomAction:Wix4SchedHttpUrlReservationsUninstall_X86\t1\tWix4HttpCA_X86\tSchedHttpUrlReservationsUninstall\t",
46 "Wix4HttpUrlAce:aceu5os2gQoblRmzwjt85LQf997uD4\turlO23FkY2xzEY54lY6E6sXFW6glXc\tNT SERVICE\\TestService\t268435456",
47 "Wix4HttpUrlReservation:urlO23FkY2xzEY54lY6E6sXFW6glXc\t0\t\thttp://+:80/vroot/\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo",
48 }, results);
49 }
50
51 private static void Build(string[] args)
52 {
53 var result = WixRunner.Execute(args)
54 .AssertSuccess();
55 }
56 }
57}
diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.en-us.wxl b/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.en-us.wxl
new file mode 100644
index 00000000..38c12ac1
--- /dev/null
+++ b/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/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/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.wxs b/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.wxs
new file mode 100644
index 00000000..c85e9bba
--- /dev/null
+++ b/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.wxs
@@ -0,0 +1,15 @@
1<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
2 <Package Name="MsiPackage" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a">
3 <MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" />
4
5 <Feature Id="ProductFeature" Title="!(loc.FeatureTitle)">
6 <ComponentGroupRef Id="ProductComponents" />
7 </Feature>
8 </Package>
9
10 <Fragment>
11 <StandardDirectory Id="ProgramFilesFolder">
12 <Directory Id="INSTALLFOLDER" Name="MsiPackage" />
13 </StandardDirectory>
14 </Fragment>
15</Wix>
diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/PackageComponents.wxs b/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/PackageComponents.wxs
new file mode 100644
index 00000000..f0aae485
--- /dev/null
+++ b/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/PackageComponents.wxs
@@ -0,0 +1,12 @@
1<?xml version="1.0" encoding="utf-8"?>
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
3 xmlns:http="http://wixtoolset.org/schemas/v4/wxs/http">
4 <Fragment>
5 <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
6 <Component>
7 <File Source="example.txt" />
8 <http:SniSslCertificate Host="example.com" Port="8080" Thumbprint="[SOME_THUMBPRINT]" HandleExisting="fail" />
9 </Component>
10 </ComponentGroup>
11 </Fragment>
12</Wix>
diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/example.txt b/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/example.txt
new file mode 100644
index 00000000..1b4ffe8a
--- /dev/null
+++ b/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/example.txt
@@ -0,0 +1 @@
This is example.txt. \ No newline at end of file
diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/UsingUrlReservation/Package.en-us.wxl b/src/ext/Http/test/WixToolsetTest.Http/TestData/UsingUrlReservation/Package.en-us.wxl
new file mode 100644
index 00000000..38c12ac1
--- /dev/null
+++ b/src/ext/Http/test/WixToolsetTest.Http/TestData/UsingUrlReservation/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/Http/test/WixToolsetTest.Http/TestData/UsingUrlReservation/Package.wxs b/src/ext/Http/test/WixToolsetTest.Http/TestData/UsingUrlReservation/Package.wxs
new file mode 100644
index 00000000..bd31e81f
--- /dev/null
+++ b/src/ext/Http/test/WixToolsetTest.Http/TestData/UsingUrlReservation/Package.wxs
@@ -0,0 +1,15 @@
1<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
2 <Package Name="MsiPackage" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a" InstallerVersion="200">
3 <MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" />
4
5 <Feature Id="ProductFeature" Title="!(loc.FeatureTitle)">
6 <ComponentGroupRef Id="ProductComponents" />
7 </Feature>
8 </Package>
9
10 <Fragment>
11 <StandardDirectory Id="ProgramFilesFolder">
12 <Directory Id="INSTALLFOLDER" Name="MsiPackage" />
13 </StandardDirectory>
14 </Fragment>
15</Wix>
diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/UsingUrlReservation/PackageComponents.wxs b/src/ext/Http/test/WixToolsetTest.Http/TestData/UsingUrlReservation/PackageComponents.wxs
new file mode 100644
index 00000000..780d598b
--- /dev/null
+++ b/src/ext/Http/test/WixToolsetTest.Http/TestData/UsingUrlReservation/PackageComponents.wxs
@@ -0,0 +1,16 @@
1<?xml version="1.0" encoding="utf-8"?>
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
3 xmlns:http="http://wixtoolset.org/schemas/v4/wxs/http">
4 <Fragment>
5 <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
6 <Component>
7 <File Source="example.txt" />
8 <ServiceInstall Name="TestService" Type="ownProcess" Start="auto" ErrorControl="ignore">
9 <http:UrlReservation Url="http://+:80/vroot/">
10 <http:UrlAce Rights="all" />
11 </http:UrlReservation>
12 </ServiceInstall>
13 </Component>
14 </ComponentGroup>
15 </Fragment>
16</Wix>
diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/UsingUrlReservation/example.txt b/src/ext/Http/test/WixToolsetTest.Http/TestData/UsingUrlReservation/example.txt
new file mode 100644
index 00000000..1b4ffe8a
--- /dev/null
+++ b/src/ext/Http/test/WixToolsetTest.Http/TestData/UsingUrlReservation/example.txt
@@ -0,0 +1 @@
This is example.txt. \ No newline at end of file
diff --git a/src/ext/Http/test/WixToolsetTest.Http/WixToolsetTest.Http.csproj b/src/ext/Http/test/WixToolsetTest.Http/WixToolsetTest.Http.csproj
new file mode 100644
index 00000000..7e60e426
--- /dev/null
+++ b/src/ext/Http/test/WixToolsetTest.Http/WixToolsetTest.Http.csproj
@@ -0,0 +1,38 @@
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 <IsPackable>false</IsPackable>
8 </PropertyGroup>
9
10 <PropertyGroup>
11 <NoWarn>NU1701</NoWarn>
12 </PropertyGroup>
13
14 <ItemGroup>
15 <Content Include="TestData\**" CopyToOutputDirectory="PreserveNewest" />
16 </ItemGroup>
17
18 <ItemGroup>
19 <ProjectReference Include="..\..\wixext\WixToolset.Http.wixext.csproj" />
20 </ItemGroup>
21
22 <ItemGroup>
23 <PackageReference Include="WixToolset.Core" Version="4.0.*" />
24 <PackageReference Include="WixToolset.Core.Burn" Version="4.0.*" />
25 <PackageReference Include="WixToolset.Core.WindowsInstaller" Version="4.0.*" />
26 <PackageReference Include="WixToolset.Core.TestPackage" Version="4.0.*" />
27 </ItemGroup>
28
29 <ItemGroup>
30 <PackageReference Include="WixBuildTools.TestSupport" Version="4.0.*" />
31 </ItemGroup>
32
33 <ItemGroup>
34 <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
35 <PackageReference Include="xunit" Version="2.4.1" />
36 <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" PrivateAssets="All" />
37 </ItemGroup>
38</Project>
diff --git a/src/ext/Http/wix.snk b/src/ext/Http/wix.snk
new file mode 100644
index 00000000..3908a66a
--- /dev/null
+++ b/src/ext/Http/wix.snk
Binary files differ
diff --git a/src/ext/Http/wixext/HttpCompiler.cs b/src/ext/Http/wixext/HttpCompiler.cs
new file mode 100644
index 00000000..6c572470
--- /dev/null
+++ b/src/ext/Http/wixext/HttpCompiler.cs
@@ -0,0 +1,383 @@
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.Http
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Xml.Linq;
8 using WixToolset.Data;
9 using WixToolset.Extensibility;
10 using WixToolset.Extensibility.Data;
11 using WixToolset.Http.Symbols;
12
13 /// <summary>
14 /// The compiler for the WiX Toolset Http Extension.
15 /// </summary>
16 public sealed class HttpCompiler : BaseCompilerExtension
17 {
18 public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/http";
19
20 /// <summary>
21 /// Processes an element for the Compiler.
22 /// </summary>
23 /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
24 /// <param name="parentElement">Parent element of element to process.</param>
25 /// <param name="element">Element to process.</param>
26 /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param>
27 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
28 {
29 switch (parentElement.Name.LocalName)
30 {
31 case "ServiceInstall":
32 var serviceInstallName = context["ServiceInstallName"];
33 var serviceUser = String.IsNullOrEmpty(serviceInstallName) ? null : String.Concat("NT SERVICE\\", serviceInstallName);
34 var serviceComponentId = context["ServiceInstallComponentId"];
35
36 switch (element.Name.LocalName)
37 {
38 case "UrlReservation":
39 this.ParseUrlReservationElement(intermediate, section, element, serviceComponentId, serviceUser);
40 break;
41 default:
42 this.ParseHelper.UnexpectedElement(parentElement, element);
43 break;
44 }
45 break;
46 case "Component":
47 string componentId = context["ComponentId"];
48
49 switch (element.Name.LocalName)
50 {
51 case "SniSslCertificate":
52 this.ParseSniSslCertificateElement(intermediate, section, element, componentId);
53 break;
54
55 case "UrlReservation":
56 this.ParseUrlReservationElement(intermediate, section, element, componentId, null);
57 break;
58 default:
59 this.ParseHelper.UnexpectedElement(parentElement, element);
60 break;
61 }
62 break;
63 default:
64 this.ParseHelper.UnexpectedElement(parentElement, element);
65 break;
66 }
67 }
68
69 /// <summary>
70 /// Parses a SniSsl element.
71 /// </summary>
72 /// <param name="node">The element to parse.</param>
73 /// <param name="componentId">Identifier of the component that owns this SNI SSL Certificate.</param>
74 private void ParseSniSslCertificateElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentId)
75 {
76 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
77 Identifier id = null;
78 string host = null;
79 string port = null;
80 string appId = null;
81 string store = null;
82 string thumbprint = null;
83 var handleExisting = HandleExisting.Replace;
84 string handleExistingValue = null;
85
86 foreach (var attrib in node.Attributes())
87 {
88 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
89 {
90 switch (attrib.Name.LocalName)
91 {
92 case "Id":
93 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
94 break;
95 case "AppId":
96 appId = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
97 break;
98 case "HandleExisting":
99 handleExistingValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
100 switch (handleExistingValue)
101 {
102 case "replace":
103 handleExisting = HandleExisting.Replace;
104 break;
105 case "ignore":
106 handleExisting = HandleExisting.Ignore;
107 break;
108 case "fail":
109 handleExisting = HandleExisting.Fail;
110 break;
111 default:
112 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "HandleExisting", handleExistingValue, "replace", "ignore", "fail"));
113 break;
114 }
115 break;
116 case "Host":
117 host = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
118 break;
119 case "Port":
120 port = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
121 break;
122 case "Store":
123 store = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
124 break;
125 case "Thumbprint":
126 thumbprint = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
127 break;
128 default:
129 this.ParseHelper.UnexpectedAttribute(node, attrib);
130 break;
131 }
132 }
133 else
134 {
135 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
136 }
137 }
138
139 // Need the element ID for child element processing, so generate now if not authored.
140 if (null == id)
141 {
142 id = this.ParseHelper.CreateIdentifier("ssl", componentId, host, port);
143 }
144
145 // Required attributes.
146 if (null == host)
147 {
148 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Host"));
149 }
150
151 if (null == port)
152 {
153 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Port"));
154 }
155
156 if (null == thumbprint)
157 {
158 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Thumbprint"));
159 }
160
161 // Parse unknown children.
162 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
163
164 if (!this.Messaging.EncounteredError)
165 {
166 section.AddSymbol(new WixHttpSniSslCertSymbol(sourceLineNumbers, id)
167 {
168 Host = host,
169 Port = port,
170 Thumbprint = thumbprint,
171 AppId = appId,
172 Store = store,
173 HandleExisting = handleExisting,
174 ComponentRef = componentId,
175 });
176
177 this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4SchedHttpSniSslCertsInstall", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64);
178 this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4SchedHttpSniSslCertsUninstall", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64);
179 }
180 }
181
182 /// <summary>
183 /// Parses a UrlReservation element.
184 /// </summary>
185 /// <param name="node">The element to parse.</param>
186 /// <param name="componentId">Identifier of the component that owns this URL reservation.</param>
187 /// <param name="securityPrincipal">The security principal of the parent element (null if nested under Component).</param>
188 private void ParseUrlReservationElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentId, string securityPrincipal)
189 {
190 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
191 Identifier id = null;
192 var handleExisting = HandleExisting.Replace;
193 string sddl = null;
194 string url = null;
195 var foundACE = false;
196
197 foreach (var attrib in node.Attributes())
198 {
199 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
200 {
201 switch (attrib.Name.LocalName)
202 {
203 case "Id":
204 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
205 break;
206 case "HandleExisting":
207 var handleExistingValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
208 switch (handleExistingValue)
209 {
210 case "replace":
211 handleExisting = HandleExisting.Replace;
212 break;
213 case "ignore":
214 handleExisting = HandleExisting.Ignore;
215 break;
216 case "fail":
217 handleExisting = HandleExisting.Fail;
218 break;
219 default:
220 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "HandleExisting", handleExistingValue, "replace", "ignore", "fail"));
221 break;
222 }
223 break;
224 case "Sddl":
225 sddl = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
226 break;
227 case "Url":
228 url = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
229 break;
230 default:
231 this.ParseHelper.UnexpectedAttribute(node, attrib);
232 break;
233 }
234 }
235 else
236 {
237 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
238 }
239 }
240
241 // Need the element ID for child element processing, so generate now if not authored.
242 if (null == id)
243 {
244 id = this.ParseHelper.CreateIdentifier("url", componentId, securityPrincipal, url);
245 }
246
247 // Parse UrlAce children.
248 foreach (var child in node.Elements())
249 {
250 if (this.Namespace == child.Name.Namespace)
251 {
252 switch (child.Name.LocalName)
253 {
254 case "UrlAce":
255 if (null != sddl)
256 {
257 this.Messaging.Write(ErrorMessages.IllegalParentAttributeWhenNested(sourceLineNumbers, "UrlReservation", "Sddl", "UrlAce"));
258 }
259 else
260 {
261 foundACE = true;
262 this.ParseUrlAceElement(intermediate, section, child, id.Id, securityPrincipal);
263 }
264 break;
265 default:
266 this.ParseHelper.UnexpectedElement(node, child);
267 break;
268 }
269 }
270 else
271 {
272 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
273 }
274 }
275
276 // Url is required.
277 if (null == url)
278 {
279 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Url"));
280 }
281
282 // Security is required.
283 if (null == sddl && !foundACE)
284 {
285 this.Messaging.Write(HttpErrors.NoSecuritySpecified(sourceLineNumbers));
286 }
287
288 if (!this.Messaging.EncounteredError)
289 {
290 section.AddSymbol(new WixHttpUrlReservationSymbol(sourceLineNumbers, id)
291 {
292 HandleExisting = handleExisting,
293 Sddl = sddl,
294 Url = url,
295 ComponentRef = componentId,
296 });
297
298 this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4SchedHttpUrlReservationsInstall", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64);
299 this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4SchedHttpUrlReservationsUninstall", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64);
300 }
301 }
302
303 /// <summary>
304 /// Parses a UrlAce element.
305 /// </summary>
306 /// <param name="node">The element to parse.</param>
307 /// <param name="urlReservationId">The URL reservation ID.</param>
308 /// <param name="defaultSecurityPrincipal">The default security principal.</param>
309 private void ParseUrlAceElement(Intermediate intermediate, IntermediateSection section, XElement node, string urlReservationId, string defaultSecurityPrincipal)
310 {
311 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
312 Identifier id = null;
313 var securityPrincipal = defaultSecurityPrincipal;
314 var rights = HttpConstants.GENERIC_ALL;
315 string rightsValue = null;
316
317 foreach (var attrib in node.Attributes())
318 {
319 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
320 {
321 switch (attrib.Name.LocalName)
322 {
323 case "Id":
324 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
325 break;
326 case "SecurityPrincipal":
327 securityPrincipal = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
328 break;
329 case "Rights":
330 rightsValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
331 switch (rightsValue)
332 {
333 case "all":
334 rights = HttpConstants.GENERIC_ALL;
335 break;
336 case "delegate":
337 rights = HttpConstants.GENERIC_WRITE;
338 break;
339 case "register":
340 rights = HttpConstants.GENERIC_EXECUTE;
341 break;
342 default:
343 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Rights", rightsValue, "all", "delegate", "register"));
344 break;
345 }
346 break;
347 default:
348 this.ParseHelper.UnexpectedAttribute(node, attrib);
349 break;
350 }
351 }
352 else
353 {
354 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
355 }
356 }
357
358 // Generate Id now if not authored.
359 if (null == id)
360 {
361 id = this.ParseHelper.CreateIdentifier("ace", urlReservationId, securityPrincipal, rightsValue);
362 }
363
364 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
365
366 // SecurityPrincipal is required.
367 if (null == securityPrincipal)
368 {
369 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SecurityPrincipal"));
370 }
371
372 if (!this.Messaging.EncounteredError)
373 {
374 section.AddSymbol(new WixHttpUrlAceSymbol(sourceLineNumbers, id)
375 {
376 WixHttpUrlReservationRef = urlReservationId,
377 SecurityPrincipal = securityPrincipal,
378 Rights = rights,
379 });
380 }
381 }
382 }
383}
diff --git a/src/ext/Http/wixext/HttpConstants.cs b/src/ext/Http/wixext/HttpConstants.cs
new file mode 100644
index 00000000..5fb42d86
--- /dev/null
+++ b/src/ext/Http/wixext/HttpConstants.cs
@@ -0,0 +1,15 @@
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.Http
4{
5 using System;
6
7 internal static class HttpConstants
8 {
9 // from winnt.h
10 public const int GENERIC_ALL = 0x10000000;
11 public const int GENERIC_EXECUTE = 0x20000000;
12 public const int GENERIC_WRITE = 0x40000000;
13
14 }
15}
diff --git a/src/ext/Http/wixext/HttpDecompiler.cs b/src/ext/Http/wixext/HttpDecompiler.cs
new file mode 100644
index 00000000..8991ec2f
--- /dev/null
+++ b/src/ext/Http/wixext/HttpDecompiler.cs
@@ -0,0 +1,137 @@
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.Http
4{
5#if TODO_CONSIDER_DECOMPILER
6 using System;
7 using System.Collections;
8 using System.Diagnostics;
9 using System.Globalization;
10 using WixToolset.Data;
11 using WixToolset.Extensibility;
12 using Http = WixToolset.Extensions.Serialize.Http;
13 using Wix = WixToolset.Data.Serialize;
14
15 /// <summary>
16 /// The decompiler for the WiX Toolset Http Extension.
17 /// </summary>
18 public sealed class HttpDecompiler : DecompilerExtension
19 {
20 /// <summary>
21 /// Creates a decompiler for Http Extension.
22 /// </summary>
23 public HttpDecompiler()
24 {
25 this.TableDefinitions = HttpExtensionData.GetExtensionTableDefinitions();
26 }
27
28 /// <summary>
29 /// Get the extensions library to be removed.
30 /// </summary>
31 /// <param name="tableDefinitions">Table definitions for library.</param>
32 /// <returns>Library to remove from decompiled output.</returns>
33 public override Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions)
34 {
35 return HttpExtensionData.GetExtensionLibrary(tableDefinitions);
36 }
37
38 /// <summary>
39 /// Decompiles an extension table.
40 /// </summary>
41 /// <param name="table">The table to decompile.</param>
42 public override void DecompileTable(Table table)
43 {
44 switch (table.Name)
45 {
46 case "WixHttpUrlReservation":
47 this.DecompileWixHttpUrlReservationTable(table);
48 break;
49 case "WixHttpUrlAce":
50 this.DecompileWixHttpUrlAceTable(table);
51 break;
52 default:
53 base.DecompileTable(table);
54 break;
55 }
56 }
57
58 /// <summary>
59 /// Decompile the WixHttpUrlReservation table.
60 /// </summary>
61 /// <param name="table">The table to decompile.</param>
62 private void DecompileWixHttpUrlReservationTable(Table table)
63 {
64 foreach (Row row in table.Rows)
65 {
66 Http.UrlReservation urlReservation = new Http.UrlReservation();
67 urlReservation.Id = (string)row[0];
68 switch((int)row[1])
69 {
70 case HttpConstants.heReplace:
71 default:
72 urlReservation.HandleExisting = Http.UrlReservation.HandleExistingType.replace;
73 break;
74 case HttpConstants.heIgnore:
75 urlReservation.HandleExisting = Http.UrlReservation.HandleExistingType.ignore;
76 break;
77 case HttpConstants.heFail:
78 urlReservation.HandleExisting = Http.UrlReservation.HandleExistingType.fail;
79 break;
80 }
81 urlReservation.Sddl = (string)row[2];
82 urlReservation.Url = (string)row[3];
83
84 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[4]);
85 if (null != component)
86 {
87 component.AddChild(urlReservation);
88 }
89 else
90 {
91 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
92 }
93 this.Core.IndexElement(row, urlReservation);
94 }
95 }
96
97
98 /// <summary>
99 /// Decompile the WixHttpUrlAce table.
100 /// </summary>
101 /// <param name="table">The table to decompile.</param>
102 private void DecompileWixHttpUrlAceTable(Table table)
103 {
104 foreach (Row row in table.Rows)
105 {
106 Http.UrlAce urlace = new Http.UrlAce();
107 urlace.Id = (string)row[0];
108 urlace.SecurityPrincipal = (string)row[2];
109 switch (Convert.ToInt32(row[3]))
110 {
111 case HttpConstants.GENERIC_ALL:
112 default:
113 urlace.Rights = Http.UrlAce.RightsType.all;
114 break;
115 case HttpConstants.GENERIC_EXECUTE:
116 urlace.Rights = Http.UrlAce.RightsType.register;
117 break;
118 case HttpConstants.GENERIC_WRITE:
119 urlace.Rights = Http.UrlAce.RightsType.@delegate;
120 break;
121 }
122
123 string reservationId = (string)row[1];
124 Http.UrlReservation urlReservation = (Http.UrlReservation)this.Core.GetIndexedElement("WixHttpUrlReservation", reservationId);
125 if (null != urlReservation)
126 {
127 urlReservation.AddChild(urlace);
128 }
129 else
130 {
131 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, urlace.Id, "WixHttpUrlReservation_", reservationId, "WixHttpUrlReservation"));
132 }
133 }
134 }
135 }
136#endif
137}
diff --git a/src/ext/Http/wixext/HttpErrors.cs b/src/ext/Http/wixext/HttpErrors.cs
new file mode 100644
index 00000000..e87adf54
--- /dev/null
+++ b/src/ext/Http/wixext/HttpErrors.cs
@@ -0,0 +1,31 @@
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.Http
4{
5 using System;
6 using System.Resources;
7 using WixToolset.Data;
8
9 public static class HttpErrors
10 {
11 public static Message NoSecuritySpecified(SourceLineNumber sourceLineNumbers)
12 {
13 return Message(sourceLineNumbers, Ids.NoSecuritySpecified, "The UrlReservation element doesn't identify the security for the reservation. You must either specify the Sddl attribute, or provide child UrlAce elements.");
14 }
15
16 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args)
17 {
18 return new Message(sourceLineNumber, MessageLevel.Error, (int)id, format, args);
19 }
20
21 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, ResourceManager resourceManager, string resourceName, params object[] args)
22 {
23 return new Message(sourceLineNumber, MessageLevel.Error, (int)id, resourceManager, resourceName, args);
24 }
25
26 public enum Ids
27 {
28 NoSecuritySpecified = 6701,
29 }
30 }
31}
diff --git a/src/ext/Http/wixext/HttpExtensionData.cs b/src/ext/Http/wixext/HttpExtensionData.cs
new file mode 100644
index 00000000..04e3dcee
--- /dev/null
+++ b/src/ext/Http/wixext/HttpExtensionData.cs
@@ -0,0 +1,30 @@
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.Http
4{
5 using WixToolset.Data;
6 using WixToolset.Extensibility;
7
8 /// <summary>
9 /// The WiX Toolset Http Extension.
10 /// </summary>
11 public sealed class HttpExtensionData : 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 public override bool TryGetSymbolDefinitionByName(string name, out IntermediateSymbolDefinition symbolDefinition)
20 {
21 symbolDefinition = HttpSymbolDefinitions.ByName(name);
22 return symbolDefinition != null;
23 }
24
25 public override Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions)
26 {
27 return Intermediate.Load(typeof(HttpExtensionData).Assembly, "WixToolset.Http.http.wixlib", symbolDefinitions);
28 }
29 }
30}
diff --git a/src/ext/Http/wixext/HttpExtensionFactory.cs b/src/ext/Http/wixext/HttpExtensionFactory.cs
new file mode 100644
index 00000000..ad7d84d0
--- /dev/null
+++ b/src/ext/Http/wixext/HttpExtensionFactory.cs
@@ -0,0 +1,18 @@
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.Http
4{
5 using System;
6 using System.Collections.Generic;
7 using WixToolset.Extensibility;
8
9 public class HttpExtensionFactory : BaseExtensionFactory
10 {
11 protected override IReadOnlyCollection<Type> ExtensionTypes => new[]
12 {
13 typeof(HttpCompiler),
14 typeof(HttpExtensionData),
15 typeof(HttpWindowsInstallerBackendBinderExtension),
16 };
17 }
18}
diff --git a/src/ext/Http/wixext/HttpTableDefinitions.cs b/src/ext/Http/wixext/HttpTableDefinitions.cs
new file mode 100644
index 00000000..431b9a33
--- /dev/null
+++ b/src/ext/Http/wixext/HttpTableDefinitions.cs
@@ -0,0 +1,60 @@
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.Http
4{
5 using WixToolset.Data.WindowsInstaller;
6
7 public static class HttpTableDefinitions
8 {
9 public static readonly TableDefinition WixHttpSniSslCert = new TableDefinition(
10 "Wix4HttpSniSslCert",
11 HttpSymbolDefinitions.WixHttpSniSslCert,
12 new[]
13 {
14 new ColumnDefinition("Wix4HttpSniSslCert", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "The non-localized primary key for the table.", modularizeType: ColumnModularizeType.Column),
15 new ColumnDefinition("Host", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Host for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property),
16 new ColumnDefinition("Port", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Port for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property),
17 new ColumnDefinition("Thumbprint", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "humbprint of the SNI SSL certificate to find.", modularizeType: ColumnModularizeType.Property),
18 new ColumnDefinition("AppId", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Optional application id for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property),
19 new ColumnDefinition("Store", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Optional application id for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property),
20 new ColumnDefinition("HandleExisting", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 0, maxValue: 2, description: "The behavior when trying to install a SNI SSL certificate and it already exists."),
21 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key into the Component table referencing the component that controls the URL reservation.", modularizeType: ColumnModularizeType.Column),
22 },
23 symbolIdIsPrimaryKey: true
24 );
25
26 public static readonly TableDefinition WixHttpUrlReservation = new TableDefinition(
27 "Wix4HttpUrlReservation",
28 HttpSymbolDefinitions.WixHttpUrlReservation,
29 new[]
30 {
31 new ColumnDefinition("Wix4HttpUrlReservation", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "The non-localized primary key for the table.", modularizeType: ColumnModularizeType.Column),
32 new ColumnDefinition("HandleExisting", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 0, maxValue: 2, description: "The behavior when trying to install a URL reservation and it already exists."),
33 new ColumnDefinition("Sddl", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Security descriptor for the URL reservation.", modularizeType: ColumnModularizeType.Property),
34 new ColumnDefinition("Url", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "URL to be reserved.", modularizeType: ColumnModularizeType.Property),
35 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key into the Component table referencing the component that controls the URL reservation.", modularizeType: ColumnModularizeType.Column),
36 },
37 symbolIdIsPrimaryKey: true
38 );
39
40 public static readonly TableDefinition WixHttpUrlAce = new TableDefinition(
41 "Wix4HttpUrlAce",
42 HttpSymbolDefinitions.WixHttpUrlAce,
43 new[]
44 {
45 new ColumnDefinition("Wix4HttpUrlAce", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "The non-localized primary key for the table.", modularizeType: ColumnModularizeType.Column),
46 new ColumnDefinition("WixHttpUrlReservation_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "WixHttpUrlReservation", keyColumn: 1, description: "Foreign key into the WixHttpUrlReservation table.", modularizeType: ColumnModularizeType.Column),
47 new ColumnDefinition("SecurityPrincipal", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "The security principal for this ACE.", modularizeType: ColumnModularizeType.Property),
48 new ColumnDefinition("Rights", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 0, maxValue: 1073741824, description: "The rights for this ACE."),
49 },
50 symbolIdIsPrimaryKey: true
51 );
52
53 public static readonly TableDefinition[] All = new[]
54 {
55 WixHttpSniSslCert,
56 WixHttpUrlReservation,
57 WixHttpUrlAce,
58 };
59 }
60}
diff --git a/src/ext/Http/wixext/HttpWindowsInstallerBackendBinderExtension.cs b/src/ext/Http/wixext/HttpWindowsInstallerBackendBinderExtension.cs
new file mode 100644
index 00000000..8e4f1a96
--- /dev/null
+++ b/src/ext/Http/wixext/HttpWindowsInstallerBackendBinderExtension.cs
@@ -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
3namespace WixToolset.Http
4{
5 using System.Collections.Generic;
6 using WixToolset.Data.WindowsInstaller;
7 using WixToolset.Extensibility;
8
9 public class HttpWindowsInstallerBackendBinderExtension : BaseWindowsInstallerBackendBinderExtension
10 {
11 public override IReadOnlyCollection<TableDefinition> TableDefinitions => HttpTableDefinitions.All;
12 }
13}
diff --git a/src/ext/Http/wixext/Symbols/HandleExisting.cs b/src/ext/Http/wixext/Symbols/HandleExisting.cs
new file mode 100644
index 00000000..0d70cebc
--- /dev/null
+++ b/src/ext/Http/wixext/Symbols/HandleExisting.cs
@@ -0,0 +1,14 @@
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.Http.Symbols
4{
5 /// <summary>
6 /// Must match constants in wixhttpca.cpp
7 /// </summary>
8 public enum HandleExisting
9 {
10 Replace = 0,
11 Ignore = 1,
12 Fail = 2,
13 }
14}
diff --git a/src/ext/Http/wixext/Symbols/HttpSymbolDefinitions.cs b/src/ext/Http/wixext/Symbols/HttpSymbolDefinitions.cs
new file mode 100644
index 00000000..2aa03468
--- /dev/null
+++ b/src/ext/Http/wixext/Symbols/HttpSymbolDefinitions.cs
@@ -0,0 +1,47 @@
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.Http
4{
5 using System;
6 using WixToolset.Data;
7
8 public enum HttpSymbolDefinitionType
9 {
10 WixHttpSniSslCert,
11 WixHttpUrlAce,
12 WixHttpUrlReservation,
13 }
14
15 public static partial class HttpSymbolDefinitions
16 {
17 public static readonly Version Version = new Version("4.0.0");
18
19 public static IntermediateSymbolDefinition ByName(string name)
20 {
21 if (!Enum.TryParse(name, out HttpSymbolDefinitionType type))
22 {
23 return null;
24 }
25
26 return ByType(type);
27 }
28
29 public static IntermediateSymbolDefinition ByType(HttpSymbolDefinitionType type)
30 {
31 switch (type)
32 {
33 case HttpSymbolDefinitionType.WixHttpSniSslCert:
34 return HttpSymbolDefinitions.WixHttpSniSslCert;
35
36 case HttpSymbolDefinitionType.WixHttpUrlAce:
37 return HttpSymbolDefinitions.WixHttpUrlAce;
38
39 case HttpSymbolDefinitionType.WixHttpUrlReservation:
40 return HttpSymbolDefinitions.WixHttpUrlReservation;
41
42 default:
43 throw new ArgumentOutOfRangeException(nameof(type));
44 }
45 }
46 }
47}
diff --git a/src/ext/Http/wixext/Symbols/WixHttpSniSslCertSymbol.cs b/src/ext/Http/wixext/Symbols/WixHttpSniSslCertSymbol.cs
new file mode 100644
index 00000000..ec67a089
--- /dev/null
+++ b/src/ext/Http/wixext/Symbols/WixHttpSniSslCertSymbol.cs
@@ -0,0 +1,95 @@
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.Http
4{
5 using WixToolset.Data;
6 using WixToolset.Http.Symbols;
7
8 public static partial class HttpSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition WixHttpSniSslCert = new IntermediateSymbolDefinition(
11 HttpSymbolDefinitionType.WixHttpSniSslCert.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.Host), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.Port), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.Thumbprint), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.AppId), IntermediateFieldType.String),
18 new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.Store), IntermediateFieldType.String),
19 new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.HandleExisting), IntermediateFieldType.Number),
20 new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.ComponentRef), IntermediateFieldType.String),
21 },
22 typeof(WixHttpSniSslCertSymbol));
23 }
24}
25
26namespace WixToolset.Http.Symbols
27{
28 using WixToolset.Data;
29
30 public enum WixHttpSniSslCertSymbolFields
31 {
32 Host,
33 Port,
34 Thumbprint,
35 AppId,
36 Store,
37 HandleExisting,
38 ComponentRef,
39 }
40
41 public class WixHttpSniSslCertSymbol : IntermediateSymbol
42 {
43 public WixHttpSniSslCertSymbol() : base(HttpSymbolDefinitions.WixHttpSniSslCert, null, null)
44 {
45 }
46
47 public WixHttpSniSslCertSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(HttpSymbolDefinitions.WixHttpSniSslCert, sourceLineNumber, id)
48 {
49 }
50
51 public IntermediateField this[WixHttpSniSslCertSymbolFields index] => this.Fields[(int)index];
52
53 public string Host
54 {
55 get => this.Fields[(int)WixHttpSniSslCertSymbolFields.Host].AsString();
56 set => this.Set((int)WixHttpSniSslCertSymbolFields.Host, value);
57 }
58
59 public string Port
60 {
61 get => this.Fields[(int)WixHttpSniSslCertSymbolFields.Port].AsString();
62 set => this.Set((int)WixHttpSniSslCertSymbolFields.Port, value);
63 }
64
65 public string Thumbprint
66 {
67 get => this.Fields[(int)WixHttpSniSslCertSymbolFields.Thumbprint].AsString();
68 set => this.Set((int)WixHttpSniSslCertSymbolFields.Thumbprint, value);
69 }
70
71 public string AppId
72 {
73 get => this.Fields[(int)WixHttpSniSslCertSymbolFields.AppId].AsString();
74 set => this.Set((int)WixHttpSniSslCertSymbolFields.AppId, value);
75 }
76
77 public string Store
78 {
79 get => this.Fields[(int)WixHttpSniSslCertSymbolFields.Store].AsString();
80 set => this.Set((int)WixHttpSniSslCertSymbolFields.Store, value);
81 }
82
83 public HandleExisting HandleExisting
84 {
85 get => (HandleExisting)this.Fields[(int)WixHttpSniSslCertSymbolFields.HandleExisting].AsNumber();
86 set => this.Set((int)WixHttpSniSslCertSymbolFields.HandleExisting, (int)value);
87 }
88
89 public string ComponentRef
90 {
91 get => this.Fields[(int)WixHttpSniSslCertSymbolFields.ComponentRef].AsString();
92 set => this.Set((int)WixHttpSniSslCertSymbolFields.ComponentRef, value);
93 }
94 }
95}
diff --git a/src/ext/Http/wixext/Symbols/WixHttpUrlAceSymbol.cs b/src/ext/Http/wixext/Symbols/WixHttpUrlAceSymbol.cs
new file mode 100644
index 00000000..1d57bd52
--- /dev/null
+++ b/src/ext/Http/wixext/Symbols/WixHttpUrlAceSymbol.cs
@@ -0,0 +1,63 @@
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.Http
4{
5 using WixToolset.Data;
6 using WixToolset.Http.Symbols;
7
8 public static partial class HttpSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition WixHttpUrlAce = new IntermediateSymbolDefinition(
11 HttpSymbolDefinitionType.WixHttpUrlAce.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(WixHttpUrlAceSymbolFields.WixHttpUrlReservationRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(WixHttpUrlAceSymbolFields.SecurityPrincipal), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(WixHttpUrlAceSymbolFields.Rights), IntermediateFieldType.Number),
17 },
18 typeof(WixHttpUrlAceSymbol));
19 }
20}
21
22namespace WixToolset.Http.Symbols
23{
24 using WixToolset.Data;
25
26 public enum WixHttpUrlAceSymbolFields
27 {
28 WixHttpUrlReservationRef,
29 SecurityPrincipal,
30 Rights,
31 }
32
33 public class WixHttpUrlAceSymbol : IntermediateSymbol
34 {
35 public WixHttpUrlAceSymbol() : base(HttpSymbolDefinitions.WixHttpUrlAce, null, null)
36 {
37 }
38
39 public WixHttpUrlAceSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(HttpSymbolDefinitions.WixHttpUrlAce, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[WixHttpUrlAceSymbolFields index] => this.Fields[(int)index];
44
45 public string WixHttpUrlReservationRef
46 {
47 get => this.Fields[(int)WixHttpUrlAceSymbolFields.WixHttpUrlReservationRef].AsString();
48 set => this.Set((int)WixHttpUrlAceSymbolFields.WixHttpUrlReservationRef, value);
49 }
50
51 public string SecurityPrincipal
52 {
53 get => this.Fields[(int)WixHttpUrlAceSymbolFields.SecurityPrincipal].AsString();
54 set => this.Set((int)WixHttpUrlAceSymbolFields.SecurityPrincipal, value);
55 }
56
57 public int Rights
58 {
59 get => this.Fields[(int)WixHttpUrlAceSymbolFields.Rights].AsNumber();
60 set => this.Set((int)WixHttpUrlAceSymbolFields.Rights, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/Http/wixext/Symbols/WixHttpUrlReservationSymbol.cs b/src/ext/Http/wixext/Symbols/WixHttpUrlReservationSymbol.cs
new file mode 100644
index 00000000..4aa4a5da
--- /dev/null
+++ b/src/ext/Http/wixext/Symbols/WixHttpUrlReservationSymbol.cs
@@ -0,0 +1,71 @@
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.Http
4{
5 using WixToolset.Data;
6 using WixToolset.Http.Symbols;
7
8 public static partial class HttpSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition WixHttpUrlReservation = new IntermediateSymbolDefinition(
11 HttpSymbolDefinitionType.WixHttpUrlReservation.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(WixHttpUrlReservationSymbolFields.HandleExisting), IntermediateFieldType.Number),
15 new IntermediateFieldDefinition(nameof(WixHttpUrlReservationSymbolFields.Sddl), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(WixHttpUrlReservationSymbolFields.Url), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(WixHttpUrlReservationSymbolFields.ComponentRef), IntermediateFieldType.String),
18 },
19 typeof(WixHttpUrlReservationSymbol));
20 }
21}
22
23namespace WixToolset.Http.Symbols
24{
25 using WixToolset.Data;
26
27 public enum WixHttpUrlReservationSymbolFields
28 {
29 HandleExisting,
30 Sddl,
31 Url,
32 ComponentRef,
33 }
34
35 public class WixHttpUrlReservationSymbol : IntermediateSymbol
36 {
37 public WixHttpUrlReservationSymbol() : base(HttpSymbolDefinitions.WixHttpUrlReservation, null, null)
38 {
39 }
40
41 public WixHttpUrlReservationSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(HttpSymbolDefinitions.WixHttpUrlReservation, sourceLineNumber, id)
42 {
43 }
44
45 public IntermediateField this[WixHttpUrlReservationSymbolFields index] => this.Fields[(int)index];
46
47 public HandleExisting HandleExisting
48 {
49 get => (HandleExisting)this.Fields[(int)WixHttpUrlReservationSymbolFields.HandleExisting].AsNumber();
50 set => this.Set((int)WixHttpUrlReservationSymbolFields.HandleExisting, (int)value);
51 }
52
53 public string Sddl
54 {
55 get => this.Fields[(int)WixHttpUrlReservationSymbolFields.Sddl].AsString();
56 set => this.Set((int)WixHttpUrlReservationSymbolFields.Sddl, value);
57 }
58
59 public string Url
60 {
61 get => this.Fields[(int)WixHttpUrlReservationSymbolFields.Url].AsString();
62 set => this.Set((int)WixHttpUrlReservationSymbolFields.Url, value);
63 }
64
65 public string ComponentRef
66 {
67 get => this.Fields[(int)WixHttpUrlReservationSymbolFields.ComponentRef].AsString();
68 set => this.Set((int)WixHttpUrlReservationSymbolFields.ComponentRef, value);
69 }
70 }
71} \ No newline at end of file
diff --git a/src/ext/Http/wixext/WixToolset.Http.wixext.csproj b/src/ext/Http/wixext/WixToolset.Http.wixext.csproj
new file mode 100644
index 00000000..089a51d0
--- /dev/null
+++ b/src/ext/Http/wixext/WixToolset.Http.wixext.csproj
@@ -0,0 +1,31 @@
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 <RootNamespace>WixToolset.Http</RootNamespace>
8 <Description>WiX Toolset Http Extension</Description>
9 <Title>WiX Toolset Http Extension</Title>
10 <IsTool>true</IsTool>
11 <ContentTargetFolders>build</ContentTargetFolders>
12 </PropertyGroup>
13
14 <ItemGroup>
15 <Content Include="$(MSBuildThisFileName).targets" />
16 <EmbeddedResource Include="$(OutputPath)..\http.wixlib" />
17 </ItemGroup>
18
19 <ItemGroup>
20 <PackageReference Include="WixToolset.Data" Version="4.0.*" PrivateAssets="all" />
21 <PackageReference Include="WixToolset.Extensibility" Version="4.0.*" PrivateAssets="all" />
22 </ItemGroup>
23
24 <ItemGroup>
25 <ProjectReference Include="..\wixlib\http.wixproj" ReferenceOutputAssembly="false" Condition=" '$(NCrunch)'=='' " />
26 </ItemGroup>
27
28 <ItemGroup>
29 <PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37" PrivateAssets="all" />
30 </ItemGroup>
31</Project>
diff --git a/src/ext/Http/wixext/WixToolset.Http.wixext.targets b/src/ext/Http/wixext/WixToolset.Http.wixext.targets
new file mode 100644
index 00000000..254b0010
--- /dev/null
+++ b/src/ext/Http/wixext/WixToolset.Http.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 <WixToolsetHttpWixextPath Condition=" '$(WixToolsetHttpWixextPath)' == '' ">$(MSBuildThisFileDirectory)..\tools\WixToolset.Http.wixext.dll</WixToolsetHttpWixextPath>
7 </PropertyGroup>
8 <ItemGroup>
9 <WixExtension Include="$(WixToolsetHttpWixextPath)" />
10 </ItemGroup>
11</Project>
diff --git a/src/ext/Http/wixlib/HttpExtension.wxs b/src/ext/Http/wixlib/HttpExtension.wxs
new file mode 100644
index 00000000..e9717fc1
--- /dev/null
+++ b/src/ext/Http/wixlib/HttpExtension.wxs
@@ -0,0 +1,10 @@
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 <Fragment>
7 <UI Id="WixHttpErrors">
8 </UI>
9 </Fragment>
10</Wix>
diff --git a/src/ext/Http/wixlib/HttpExtension_Platform.wxi b/src/ext/Http/wixlib/HttpExtension_Platform.wxi
new file mode 100644
index 00000000..4f4a9e23
--- /dev/null
+++ b/src/ext/Http/wixlib/HttpExtension_Platform.wxi
@@ -0,0 +1,64 @@
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 <UIRef Id="WixHttpErrors" />
9 <UI>
10 <ProgressText Action="$(var.Prefix)SchedHttpUrlReservationsInstall$(var.Suffix)" Message="!(loc.WixSchedHttpUrlReservationsInstall)" />
11 <ProgressText Action="$(var.Prefix)SchedHttpUrlReservationsUninstall$(var.Suffix)" Message="!(loc.WixSchedHttpUrlReservationsUninstall)" />
12 <ProgressText Action="$(var.Prefix)RollbackHttpUrlReservationsInstall$(var.Suffix)" Message="!(loc.WixRollbackHttpUrlReservationsInstall)" />
13 <ProgressText Action="$(var.Prefix)ExecHttpUrlReservationsInstall$(var.Suffix)" Message="!(loc.WixExecHttpUrlReservationsInstall)" />
14 <ProgressText Action="$(var.Prefix)RollbackHttpUrlReservationsUninstall$(var.Suffix)" Message="!(loc.WixRollbackHttpUrlReservationsUninstall)" />
15 <ProgressText Action="$(var.Prefix)ExecHttpUrlReservationsUninstall$(var.Suffix)" Message="!(loc.WixExecHttpUrlReservationsUninstall)" />
16 </UI>
17
18 <CustomAction Id="$(var.Prefix)SchedHttpUrlReservationsInstall$(var.Suffix)" DllEntry="SchedHttpUrlReservationsInstall" Execute="immediate" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" />
19 <CustomAction Id="$(var.Prefix)SchedHttpUrlReservationsUninstall$(var.Suffix)" DllEntry="SchedHttpUrlReservationsUninstall" Execute="immediate" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" />
20 <CustomAction Id="$(var.Prefix)RollbackHttpUrlReservationsInstall$(var.Suffix)" DllEntry="ExecHttpUrlReservations" Execute="rollback" Impersonate="no" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" />
21 <CustomAction Id="$(var.Prefix)ExecHttpUrlReservationsInstall$(var.Suffix)" DllEntry="ExecHttpUrlReservations" Execute="deferred" Impersonate="no" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" />
22 <CustomAction Id="$(var.Prefix)RollbackHttpUrlReservationsUninstall$(var.Suffix)" DllEntry="ExecHttpUrlReservations" Execute="rollback" Impersonate="no" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" />
23 <CustomAction Id="$(var.Prefix)ExecHttpUrlReservationsUninstall$(var.Suffix)" DllEntry="ExecHttpUrlReservations" Execute="deferred" Impersonate="no" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" />
24
25 <!--
26 We need the HTTP server on Windows XP SP2 or later.
27 -->
28 <InstallExecuteSequence>
29 <Custom Action="$(var.Prefix)SchedHttpUrlReservationsUninstall$(var.Suffix)" Before="RemoveFiles" Overridable="yes" Condition="VersionNT &gt;= 600 OR (VersionNT &gt;= 501 AND ((MsiNTProductType = 1 AND ServicePackLevel &gt;= 2) OR (MsiNTProductType &gt; 1)))" />
30 <Custom Action="$(var.Prefix)SchedHttpUrlReservationsInstall$(var.Suffix)" After="InstallFiles" Overridable="yes" Condition="VersionNT &gt;= 600 OR (VersionNT &gt;= 501 AND ((MsiNTProductType = 1 AND ServicePackLevel &gt;= 2) OR (MsiNTProductType &gt; 1)))" />
31 </InstallExecuteSequence>
32 </Fragment>
33
34 <Fragment>
35 <UIRef Id="WixHttpErrors" />
36 <UI>
37 <ProgressText Action="$(var.Prefix)SchedHttpSniSslCertsInstall$(var.Suffix)" Message="!(loc.WixSchedHttpSniSslCertsInstall)" />
38 <ProgressText Action="$(var.Prefix)SchedHttpSniSslCertsUninstall$(var.Suffix)" Message="!(loc.WixSchedHttpSniSslCertsUninstall)" />
39 <ProgressText Action="$(var.Prefix)RollbackHttpSniSslCertsInstall$(var.Suffix)" Message="!(loc.WixRollbackHttpSniSslCertsInstall)" />
40 <ProgressText Action="$(var.Prefix)ExecHttpSniSslCertsInstall$(var.Suffix)" Message="!(loc.WixExecHttpSniSslCertsInstall)" />
41 <ProgressText Action="$(var.Prefix)RollbackHttpSniSslCertsUninstall$(var.Suffix)" Message="!(loc.WixRollbackHttpSniSslCertsUninstall)" />
42 <ProgressText Action="$(var.Prefix)ExecHttpSniSslCertsUninstall$(var.Suffix)" Message="!(loc.WixExecHttpSniSslCertsUninstall)" />
43 </UI>
44
45 <CustomAction Id="$(var.Prefix)SchedHttpSniSslCertsInstall$(var.Suffix)" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" DllEntry="SchedHttpSniSslCertsInstall" Execute="immediate" Return="check" SuppressModularization="yes" />
46 <CustomAction Id="$(var.Prefix)SchedHttpSniSslCertsUninstall$(var.Suffix)" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" DllEntry="SchedHttpSniSslCertsUninstall" Execute="immediate" Return="check" SuppressModularization="yes" />
47 <CustomAction Id="$(var.Prefix)RollbackHttpSniSslCertsInstall$(var.Suffix)" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" DllEntry="ExecHttpSniSslCerts" Execute="rollback" Impersonate="no" Return="check" SuppressModularization="yes" />
48 <CustomAction Id="$(var.Prefix)ExecHttpSniSslCertsInstall$(var.Suffix)" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" DllEntry="ExecHttpSniSslCerts" Execute="deferred" Impersonate="no" Return="check" SuppressModularization="yes" />
49 <CustomAction Id="$(var.Prefix)RollbackHttpSniSslCertsUninstall$(var.Suffix)" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" DllEntry="ExecHttpSniSslCerts" Execute="rollback" Impersonate="no" Return="check" SuppressModularization="yes" />
50 <CustomAction Id="$(var.Prefix)ExecHttpSniSslCertsUninstall$(var.Suffix)" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" DllEntry="ExecHttpSniSslCerts" Execute="deferred" Impersonate="no" Return="check" SuppressModularization="yes" />
51
52 <!--
53 We need HTTP.SYS on Windows 8 or later for SNI SSL support.
54 -->
55 <InstallExecuteSequence>
56 <Custom Action="$(var.Prefix)SchedHttpSniSslCertsUninstall$(var.Suffix)" Before="RemoveFiles" Overridable="yes" Condition="VersionNT >= 602" />
57 <Custom Action="$(var.Prefix)SchedHttpSniSslCertsInstall$(var.Suffix)" After="InstallFiles" Overridable="yes" Condition="VersionNT >= 602" />
58 </InstallExecuteSequence>
59 </Fragment>
60
61 <Fragment>
62 <Binary Id="$(var.Prefix)HttpCA$(var.Suffix)" SourceFile="!(bindpath.$(var.platform))httpca.dll" />
63 </Fragment>
64</Include>
diff --git a/src/ext/Http/wixlib/HttpExtension_arm64.wxs b/src/ext/Http/wixlib/HttpExtension_arm64.wxs
new file mode 100644
index 00000000..3c69a644
--- /dev/null
+++ b/src/ext/Http/wixlib/HttpExtension_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 HttpExtension_Platform.wxi ?>
7</Wix>
diff --git a/src/ext/Http/wixlib/HttpExtension_x64.wxs b/src/ext/Http/wixlib/HttpExtension_x64.wxs
new file mode 100644
index 00000000..f66f0d6f
--- /dev/null
+++ b/src/ext/Http/wixlib/HttpExtension_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 HttpExtension_Platform.wxi ?>
7</Wix>
diff --git a/src/ext/Http/wixlib/HttpExtension_x86.wxs b/src/ext/Http/wixlib/HttpExtension_x86.wxs
new file mode 100644
index 00000000..f76df25f
--- /dev/null
+++ b/src/ext/Http/wixlib/HttpExtension_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 HttpExtension_Platform.wxi ?>
7</Wix>
diff --git a/src/ext/Http/wixlib/caDecor.wxi b/src/ext/Http/wixlib/caDecor.wxi
new file mode 100644
index 00000000..b1711518
--- /dev/null
+++ b/src/ext/Http/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/Http/wixlib/caerr.wxi b/src/ext/Http/wixlib/caerr.wxi
new file mode 100644
index 00000000..ff7ec121
--- /dev/null
+++ b/src/ext/Http/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/Http/wixlib/en-us.wxl b/src/ext/Http/wixlib/en-us.wxl
new file mode 100644
index 00000000..22d74f78
--- /dev/null
+++ b/src/ext/Http/wixlib/en-us.wxl
@@ -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
3<WixLocalization Culture="en-us" xmlns="http://wixtoolset.org/schemas/v4/wxl">
4 <String Id="WixSchedHttpUrlReservationsInstall" Overridable="yes">Preparing to configure Windows HTTP Server</String>
5 <String Id="WixSchedHttpUrlReservationsUninstall" Overridable="yes">Preparing to configure Windows HTTP Server</String>
6 <String Id="WixRollbackHttpUrlReservationsInstall" Overridable="yes">Rolling back Windows HTTP Server configuration</String>
7 <String Id="WixExecHttpUrlReservationsInstall" Overridable="yes">Configuring Windows HTTP Server</String>
8 <String Id="WixRollbackHttpUrlReservationsUninstall" Overridable="yes">Rolling back Windows HTTP Server configuration</String>
9 <String Id="WixExecHttpUrlReservationsUninstall" Overridable="yes">Configuring Windows HTTP Server</String>
10
11 <String Id="WixSchedHttpSniSslCertsInstall" Overridable="yes">Preparing to configure Windows HTTP Server SSL</String>
12 <String Id="WixSchedHttpSniSslCertsUninstall" Overridable="yes">Preparing to configure Windows HTTP Server SSL</String>
13 <String Id="WixRollbackHttpSniSslCertsInstall" Overridable="yes">Rolling back Windows HTTP Server SSL configuration</String>
14 <String Id="WixExecHttpSniSslCertsInstall" Overridable="yes">Configuring Windows HTTP Server SSL</String>
15 <String Id="WixRollbackHttpSniSslCertsUninstall" Overridable="yes">Rolling back Windows HTTP Server SSL configuration</String>
16 <String Id="WixExecHttpSniSslCertsUninstall" Overridable="yes">Configuring Windows HTTP Server SSL</String>
17</WixLocalization>
diff --git a/src/ext/Http/wixlib/http.wixproj b/src/ext/Http/wixlib/http.wixproj
new file mode 100644
index 00000000..999b7334
--- /dev/null
+++ b/src/ext/Http/wixlib/http.wixproj
@@ -0,0 +1,24 @@
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<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Library</OutputType>
5 <BindFiles>true</BindFiles>
6 <Cultures>en-us</Cultures>
7 </PropertyGroup>
8
9 <ItemGroup>
10 <BindInputPaths Include="$(OutputPath)x86" BindName='x86' />
11 <BindInputPaths Include="$(OutputPath)x64" BindName='x64' />
12 <BindInputPaths Include="$(OutputPath)arm64" BindName='arm64' />
13 </ItemGroup>
14
15 <ItemGroup>
16 <ProjectReference Include="..\ca\httpca.vcxproj" Properties="Platform=ARM64" />
17 <ProjectReference Include="..\ca\httpca.vcxproj" Properties="Platform=x86" />
18 <ProjectReference Include="..\ca\httpca.vcxproj" Properties="Platform=x64" />
19 </ItemGroup>
20
21 <ItemGroup>
22 <PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37" PrivateAssets="All" />
23 </ItemGroup>
24</Project> \ No newline at end of file