aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2018-01-02 23:14:58 -0800
committerRob Mensching <rob@firegiant.com>2018-01-02 23:14:58 -0800
commit97b80191048b23f2e870c9d6a27e368ebaaf594d (patch)
treeabe72531843285feb9f6e4502b5896a165219e3e
parent3fbfb758d90a52c54fc75669d9029badcbeaf251 (diff)
downloadwix-97b80191048b23f2e870c9d6a27e368ebaaf594d.tar.gz
wix-97b80191048b23f2e870c9d6a27e368ebaaf594d.tar.bz2
wix-97b80191048b23f2e870c9d6a27e368ebaaf594d.zip
Initial code commit
-rw-r--r--Firewall.wixext.sln73
-rw-r--r--appveyor.cmd13
-rw-r--r--appveyor.yml29
-rw-r--r--nuget.config15
-rw-r--r--src/Cpp.Build.props101
-rw-r--r--src/Directory.Build.props22
-rw-r--r--src/FindLocalWix.props8
-rw-r--r--src/ca/CustomMsiErrors.h130
-rw-r--r--src/ca/cost.h5
-rw-r--r--src/ca/dllmain.cpp26
-rw-r--r--src/ca/firewall.cpp1067
-rw-r--r--src/ca/fwca.def9
-rw-r--r--src/ca/fwca.vcxproj72
-rw-r--r--src/ca/packages.config6
-rw-r--r--src/ca/precomp.h17
-rw-r--r--src/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs33
-rw-r--r--src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/Package.en-us.wxl11
-rw-r--r--src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/Package.wxs22
-rw-r--r--src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/PackageComponents.wxs14
-rw-r--r--src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/example.txt1
-rw-r--r--src/test/WixToolsetTest.Firewall/WixToolsetTest.Firewall.csproj40
-rw-r--r--src/wixext/FirewallCompiler.cs356
-rw-r--r--src/wixext/FirewallConstants.cs21
-rw-r--r--src/wixext/FirewallDecompiler.cs169
-rw-r--r--src/wixext/FirewallErrors.cs42
-rw-r--r--src/wixext/FirewallExtensionData.cs24
-rw-r--r--src/wixext/FirewallExtensionFactory.cs18
-rw-r--r--src/wixext/FirewallWindowsInstallerBackendExtension.cs26
-rw-r--r--src/wixext/Tuples/FirewallTupleDefinitions.cs31
-rw-r--r--src/wixext/Tuples/WixFirewallExceptionTuple.cs93
-rw-r--r--src/wixext/WixToolset.Firewall.wixext.csproj36
-rw-r--r--src/wixext/WixToolset.Firewall.wixext.targets11
-rw-r--r--src/wixext/firewall.xsd211
-rw-r--r--src/wixext/tables.xml28
-rw-r--r--src/wixlib/FirewallExtension.wxs12
-rw-r--r--src/wixlib/FirewallExtension_Platform.wxi41
-rw-r--r--src/wixlib/FirewallExtension_x86.wxs8
-rw-r--r--src/wixlib/caSuffix.wxi28
-rw-r--r--src/wixlib/caerr.wxi96
-rw-r--r--src/wixlib/en-us.wxl14
-rw-r--r--src/wixlib/es-es.wxl13
-rw-r--r--src/wixlib/firewall.wixproj44
-rw-r--r--src/wixlib/ja-jp.wxl14
-rw-r--r--src/wixlib/packages.config5
-rw-r--r--src/wixlib/pl-pl.wxl14
-rw-r--r--version.json11
46 files changed, 3080 insertions, 0 deletions
diff --git a/Firewall.wixext.sln b/Firewall.wixext.sln
new file mode 100644
index 00000000..47e30fcd
--- /dev/null
+++ b/Firewall.wixext.sln
@@ -0,0 +1,73 @@
1
2Microsoft Visual Studio Solution File, Format Version 12.00
3# Visual Studio 15
4VisualStudioVersion = 15.0.27130.2003
5MinimumVisualStudioVersion = 15.0.26124.0
6Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fwca", "src\ca\fwca.vcxproj", "{076018F7-19BD-423A-ABBF-229273DA08D8}"
7EndProject
8Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "firewall", "src\wixlib\firewall.wixproj", "{1ACFFEFD-505A-41A5-ACBF-A02B7B473AA2}"
9EndProject
10Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Firewall.wixext", "src\wixext\WixToolset.Firewall.wixext.csproj", "{6CF033EB-0A39-4AC6-9D41-9BD506352045}"
11EndProject
12Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.Firewall", "src\test\WixToolsetTest.Firewall\WixToolsetTest.Firewall.csproj", "{D5D34EC4-AF91-4B11-AC0A-FA5242AE924B}"
13EndProject
14Global
15 GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 Debug|Any CPU = Debug|Any CPU
17 Debug|x64 = Debug|x64
18 Debug|x86 = Debug|x86
19 Release|Any CPU = Release|Any CPU
20 Release|x64 = Release|x64
21 Release|x86 = Release|x86
22 EndGlobalSection
23 GlobalSection(ProjectConfigurationPlatforms) = postSolution
24 {076018F7-19BD-423A-ABBF-229273DA08D8}.Debug|Any CPU.ActiveCfg = Debug|Win32
25 {076018F7-19BD-423A-ABBF-229273DA08D8}.Debug|x64.ActiveCfg = Debug|Win32
26 {076018F7-19BD-423A-ABBF-229273DA08D8}.Debug|x86.ActiveCfg = Debug|Win32
27 {076018F7-19BD-423A-ABBF-229273DA08D8}.Debug|x86.Build.0 = Debug|Win32
28 {076018F7-19BD-423A-ABBF-229273DA08D8}.Release|Any CPU.ActiveCfg = Release|Win32
29 {076018F7-19BD-423A-ABBF-229273DA08D8}.Release|x64.ActiveCfg = Release|Win32
30 {076018F7-19BD-423A-ABBF-229273DA08D8}.Release|x86.ActiveCfg = Release|Win32
31 {076018F7-19BD-423A-ABBF-229273DA08D8}.Release|x86.Build.0 = Release|Win32
32 {1ACFFEFD-505A-41A5-ACBF-A02B7B473AA2}.Debug|Any CPU.ActiveCfg = Debug|x86
33 {1ACFFEFD-505A-41A5-ACBF-A02B7B473AA2}.Debug|x64.ActiveCfg = Debug|x64
34 {1ACFFEFD-505A-41A5-ACBF-A02B7B473AA2}.Debug|x64.Build.0 = Debug|x64
35 {1ACFFEFD-505A-41A5-ACBF-A02B7B473AA2}.Debug|x86.ActiveCfg = Debug|x86
36 {1ACFFEFD-505A-41A5-ACBF-A02B7B473AA2}.Debug|x86.Build.0 = Debug|x86
37 {1ACFFEFD-505A-41A5-ACBF-A02B7B473AA2}.Release|Any CPU.ActiveCfg = Release|x86
38 {1ACFFEFD-505A-41A5-ACBF-A02B7B473AA2}.Release|x64.ActiveCfg = Release|x64
39 {1ACFFEFD-505A-41A5-ACBF-A02B7B473AA2}.Release|x64.Build.0 = Release|x64
40 {1ACFFEFD-505A-41A5-ACBF-A02B7B473AA2}.Release|x86.ActiveCfg = Release|x86
41 {1ACFFEFD-505A-41A5-ACBF-A02B7B473AA2}.Release|x86.Build.0 = Release|x86
42 {6CF033EB-0A39-4AC6-9D41-9BD506352045}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
43 {6CF033EB-0A39-4AC6-9D41-9BD506352045}.Debug|Any CPU.Build.0 = Debug|Any CPU
44 {6CF033EB-0A39-4AC6-9D41-9BD506352045}.Debug|x64.ActiveCfg = Debug|Any CPU
45 {6CF033EB-0A39-4AC6-9D41-9BD506352045}.Debug|x64.Build.0 = Debug|Any CPU
46 {6CF033EB-0A39-4AC6-9D41-9BD506352045}.Debug|x86.ActiveCfg = Debug|Any CPU
47 {6CF033EB-0A39-4AC6-9D41-9BD506352045}.Debug|x86.Build.0 = Debug|Any CPU
48 {6CF033EB-0A39-4AC6-9D41-9BD506352045}.Release|Any CPU.ActiveCfg = Release|Any CPU
49 {6CF033EB-0A39-4AC6-9D41-9BD506352045}.Release|Any CPU.Build.0 = Release|Any CPU
50 {6CF033EB-0A39-4AC6-9D41-9BD506352045}.Release|x64.ActiveCfg = Release|Any CPU
51 {6CF033EB-0A39-4AC6-9D41-9BD506352045}.Release|x64.Build.0 = Release|Any CPU
52 {6CF033EB-0A39-4AC6-9D41-9BD506352045}.Release|x86.ActiveCfg = Release|Any CPU
53 {6CF033EB-0A39-4AC6-9D41-9BD506352045}.Release|x86.Build.0 = Release|Any CPU
54 {D5D34EC4-AF91-4B11-AC0A-FA5242AE924B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
55 {D5D34EC4-AF91-4B11-AC0A-FA5242AE924B}.Debug|Any CPU.Build.0 = Debug|Any CPU
56 {D5D34EC4-AF91-4B11-AC0A-FA5242AE924B}.Debug|x64.ActiveCfg = Debug|Any CPU
57 {D5D34EC4-AF91-4B11-AC0A-FA5242AE924B}.Debug|x64.Build.0 = Debug|Any CPU
58 {D5D34EC4-AF91-4B11-AC0A-FA5242AE924B}.Debug|x86.ActiveCfg = Debug|Any CPU
59 {D5D34EC4-AF91-4B11-AC0A-FA5242AE924B}.Debug|x86.Build.0 = Debug|Any CPU
60 {D5D34EC4-AF91-4B11-AC0A-FA5242AE924B}.Release|Any CPU.ActiveCfg = Release|Any CPU
61 {D5D34EC4-AF91-4B11-AC0A-FA5242AE924B}.Release|Any CPU.Build.0 = Release|Any CPU
62 {D5D34EC4-AF91-4B11-AC0A-FA5242AE924B}.Release|x64.ActiveCfg = Release|Any CPU
63 {D5D34EC4-AF91-4B11-AC0A-FA5242AE924B}.Release|x64.Build.0 = Release|Any CPU
64 {D5D34EC4-AF91-4B11-AC0A-FA5242AE924B}.Release|x86.ActiveCfg = Release|Any CPU
65 {D5D34EC4-AF91-4B11-AC0A-FA5242AE924B}.Release|x86.Build.0 = Release|Any CPU
66 EndGlobalSection
67 GlobalSection(SolutionProperties) = preSolution
68 HideSolutionNode = FALSE
69 EndGlobalSection
70 GlobalSection(ExtensibilityGlobals) = postSolution
71 SolutionGuid = {E4566A6B-47D0-4EA0-989A-D763AC39105D}
72 EndGlobalSection
73EndGlobal
diff --git a/appveyor.cmd b/appveyor.cmd
new file mode 100644
index 00000000..6742048a
--- /dev/null
+++ b/appveyor.cmd
@@ -0,0 +1,13 @@
1@setlocal
2@pushd %~dp0
3
4nuget restore
5
6msbuild -p:Configuration=Release -t:Restore
7
8msbuild -p:Configuration=Release src\test\WixToolsetTest.Firewall\WixToolsetTest.Firewall.csproj
9
10msbuild -p:Configuration=Release -t:Pack src\wixext\WixToolset.Firewall.wixext.csproj
11
12@popd
13@endlocal \ No newline at end of file
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 00000000..0c74d54b
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,29 @@
1image: Visual Studio 2017
2
3version: 0.0.0.{build}
4configuration: Release
5
6environment:
7 DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
8 DOTNET_CLI_TELEMETRY_OPTOUT: 1
9 NUGET_XMLDOC_MODE: skip
10
11build_script:
12 - appveyor.cmd
13
14pull_requests:
15 do_not_increment_build_number: true
16
17nuget:
18 disable_publish_on_pr: true
19
20skip_tags: true
21
22artifacts:
23- path: build\Release\**\*.nupkg
24 name: nuget
25
26notifications:
27- provider: Slack
28 incoming_webhook:
29 secure: p5xuu+4x2JHfwGDMDe5KcG1k7gZxqYc4jWVwvyNZv5cvkubPD2waJs5yXMAXZNN7Z63/3PWHb7q4KoY/99AjauYa1nZ4c5qYqRPFRBKTHfA=
diff --git a/nuget.config b/nuget.config
new file mode 100644
index 00000000..bb8de141
--- /dev/null
+++ b/nuget.config
@@ -0,0 +1,15 @@
1<?xml version="1.0" encoding="utf-8"?>
2<configuration>
3 <packageSources>
4 <clear />
5 <add key="wixtoolset-data" value="https://ci.appveyor.com/nuget/wixtoolset-data" />
6 <add key="wixtoolset-extensibility" value="https://ci.appveyor.com/nuget/wixtoolset-extensibility" />
7 <add key="wixtoolset-core" value="https://ci.appveyor.com/nuget/wixtoolset-core" />
8 <add key="wixtoolset-core-native" value="https://ci.appveyor.com/nuget/wixtoolset-core-native" />
9 <add key="wixtoolset-dtf" value="https://ci.appveyor.com/nuget/wixtoolset-dtf" />
10 <add key="wixtoolset-dutil" value="https://ci.appveyor.com/nuget/wixtoolset-dutil" />
11 <add key="wixtoolset-wcautil" value="https://ci.appveyor.com/nuget/wixtoolset-wcautil" />
12 <add key="wixbuildtools" value="https://ci.appveyor.com/nuget/wixbuildtools" />
13 <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
14 </packageSources>
15</configuration> \ No newline at end of file
diff --git a/src/Cpp.Build.props b/src/Cpp.Build.props
new file mode 100644
index 00000000..453aa442
--- /dev/null
+++ b/src/Cpp.Build.props
@@ -0,0 +1,101 @@
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)' == 'AnyCPU' ">Win32</Platform>
7 <BaseOutputPath>$(OutputPath)</BaseOutputPath>
8 <IntDir>$(BaseIntermediateOutputPath)$(Platform)\</IntDir>
9 <OutDir>$(OutputPath)$(Platform)\</OutDir>
10 </PropertyGroup>
11
12 <ItemDefinitionGroup>
13 <ClCompile>
14 <DisableSpecificWarnings>$(DisableSpecificCompilerWarnings)</DisableSpecificWarnings>
15 <WarningLevel>Level4</WarningLevel>
16 <AdditionalIncludeDirectories>$(ProjectDir)inc;$(MSBuildProjectDirectory);$(IntDir);$(SqlCESdkIncludePath);$(ProjectAdditionalIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
17 <PreprocessorDefinitions>WIN32;_WINDOWS;_WIN32_MSI=500;_WIN32_WINNT=0x0501;$(ArmPreprocessorDefinitions);$(UnicodePreprocessorDefinitions);_CRT_STDIO_LEGACY_WIDE_SPECIFIERS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
18 <PrecompiledHeader>Use</PrecompiledHeader>
19 <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
20 <CallingConvention>StdCall</CallingConvention>
21 <TreatWarningAsError>true</TreatWarningAsError>
22 <ExceptionHandling>false</ExceptionHandling>
23 <AdditionalOptions>-YlprecompDefine</AdditionalOptions>
24 <AdditionalOptions Condition=" $(PlatformToolset.StartsWith('v14')) ">/Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
25 <MultiProcessorCompilation Condition=" $(NUMBER_OF_PROCESSORS) &gt; 4 ">true</MultiProcessorCompilation>
26 </ClCompile>
27 <ResourceCompile>
28 <PreprocessorDefinitions>$(ArmPreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
29 <AdditionalIncludeDirectories>$(ProjectAdditionalResourceIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
30 </ResourceCompile>
31 <Lib>
32 <AdditionalLibraryDirectories>$(OutDir);$(AdditionalMultiTargetLibraryPath);$(ProjectAdditionalLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
33 </Lib>
34 <Link>
35 <SubSystem>$(ProjectSubSystem)</SubSystem>
36 <ModuleDefinitionFile>$(ProjectModuleDefinitionFile)</ModuleDefinitionFile>
37 <NoEntryPoint>$(ResourceOnlyDll)</NoEntryPoint>
38 <GenerateDebugInformation>true</GenerateDebugInformation>
39 <AdditionalDependencies>$(ProjectAdditionalLinkLibraries);advapi32.lib;comdlg32.lib;user32.lib;oleaut32.lib;gdi32.lib;shell32.lib;ole32.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
40 <AdditionalLibraryDirectories>$(OutDir);$(AdditionalMultiTargetLibraryPath);$(ArmLibraryDirectories);$(ProjectAdditionalLinkLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
41 <AdditionalOptions Condition=" $(PlatformToolset.StartsWith('v14')) ">/IGNORE:4099 %(AdditionalOptions)</AdditionalOptions>
42 </Link>
43 </ItemDefinitionGroup>
44
45 <ItemDefinitionGroup Condition=" '$(Platform)'=='Win32' and '$(PlatformToolset)'!='v100'">
46 <ClCompile>
47 <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
48 </ClCompile>
49 </ItemDefinitionGroup>
50 <ItemDefinitionGroup Condition=" '$(Platform)'=='arm' ">
51 <ClCompile>
52 <CallingConvention>CDecl</CallingConvention>
53 </ClCompile>
54 </ItemDefinitionGroup>
55 <ItemDefinitionGroup Condition=" '$(ConfigurationType)'=='StaticLibrary' ">
56 <ClCompile>
57 <DebugInformationFormat>OldStyle</DebugInformationFormat>
58 <OmitDefaultLibName>true</OmitDefaultLibName>
59 <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
60 </ClCompile>
61 </ItemDefinitionGroup>
62 <ItemDefinitionGroup Condition=" '$(Configuration)'=='Debug' ">
63 <ClCompile>
64 <Optimization>Disabled</Optimization>
65 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
66 <PreprocessorDefinitions>_DEBUG;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
67 <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
68 </ClCompile>
69 </ItemDefinitionGroup>
70 <ItemDefinitionGroup Condition=" '$(Configuration)'=='Debug' and '$(CLRSupport)'=='true' ">
71 <ClCompile>
72 <BasicRuntimeChecks></BasicRuntimeChecks>
73 <RuntimeLibrary>MultiThreadedDebugDll</RuntimeLibrary>
74 </ClCompile>
75 </ItemDefinitionGroup>
76 <ItemDefinitionGroup Condition=" '$(Configuration)'=='Release' ">
77 <ClCompile>
78 <Optimization>MinSpace</Optimization>
79 <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
80 <FunctionLevelLinking>true</FunctionLevelLinking>
81 <IntrinsicFunctions>true</IntrinsicFunctions>
82 <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
83 </ClCompile>
84 <Link>
85 <EnableCOMDATFolding>true</EnableCOMDATFolding>
86 <OptimizeReferences>true</OptimizeReferences>
87 </Link>
88 </ItemDefinitionGroup>
89 <ItemDefinitionGroup Condition=" '$(Configuration)'=='Release' and '$(CLRSupport)'=='true' ">
90 <ClCompile>
91 <BasicRuntimeChecks></BasicRuntimeChecks>
92 <RuntimeLibrary>MultiThreadedDll</RuntimeLibrary>
93 </ClCompile>
94 </ItemDefinitionGroup>
95 <ItemDefinitionGroup Condition=" '$(CLRSupport)'=='true' ">
96 <Link>
97 <KeyFile>$(LinkKeyFile)</KeyFile>
98 <DelaySign>$(LinkDelaySign)</DelaySign>
99 </Link>
100 </ItemDefinitionGroup>
101</Project>
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
new file mode 100644
index 00000000..63ad5d6e
--- /dev/null
+++ b/src/Directory.Build.props
@@ -0,0 +1,22 @@
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 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
7 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
8 <BaseIntermediateOutputPath>$(MSBuildThisFileDirectory)..\build\obj\$(MSBuildProjectName)\</BaseIntermediateOutputPath>
9 <OutputPath>$(MSBuildThisFileDirectory)..\build\$(Configuration)\</OutputPath>
10
11 <Authors>WiX Toolset Team</Authors>
12 <Company>WiX Toolset</Company>
13 <Copyright>Copyright (c) .NET Foundation and contributors. All rights reserved.</Copyright>
14 </PropertyGroup>
15
16 <PropertyGroup>
17 <WixToolsetRootFolder>$(MSBuildThisFileDirectory)..\..\</WixToolsetRootFolder>
18 </PropertyGroup>
19
20 <Import Project="Cpp.Build.props" Condition=" '$(MSBuildProjectExtension)'=='.vcxproj' " />
21 <Import Project="Custom.Build.props" Condition=" Exists('Custom.Build.props') " />
22</Project>
diff --git a/src/FindLocalWix.props b/src/FindLocalWix.props
new file mode 100644
index 00000000..1301b0e5
--- /dev/null
+++ b/src/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)' != 'Release' And Exists('$(MSBuildThisFileDirectory)..\..\Core\README.md') ">$(MSBuildThisFileDirectory)..\..\Core\build\Debug\net461\wix.targets</WixTargetsPath>
7 </PropertyGroup>
8</Project>
diff --git a/src/ca/CustomMsiErrors.h b/src/ca/CustomMsiErrors.h
new file mode 100644
index 00000000..f149fb31
--- /dev/null
+++ b/src/ca/CustomMsiErrors.h
@@ -0,0 +1,130 @@
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#define GLOBAL_ERROR_BASE 25501
6
7#define msierrSecureObjectsFailedCreateSD 25520
8#define msierrSecureObjectsFailedSet 25521
9#define msierrSecureObjectsUnknownType 25522
10
11#define msierrXmlFileFailedRead 25530
12#define msierrXmlFileFailedOpen 25531
13#define msierrXmlFileFailedSelect 25532
14#define msierrXmlFileFailedSave 25533
15
16#define msierrXmlConfigFailedRead 25540
17#define msierrXmlConfigFailedOpen 25541
18#define msierrXmlConfigFailedSelect 25542
19#define msierrXmlConfigFailedSave 25543
20
21#define msierrFirewallCannotConnect 25580
22
23//---------------------------------------------------------------------------
24// Server CustomAction Errors
25// SERVER range: 26001-26100
26#define SERVER_ERROR_BASE 26000
27
28#define msierrIISCannotConnect 26001
29#define msierrIISFailedReadWebSite 26002
30#define msierrIISFailedReadWebDirs 26003
31#define msierrIISFailedReadVDirs 26004
32#define msierrIISFailedReadFilters 26005
33#define msierrIISFailedReadAppPool 26006
34#define msierrIISFailedReadMimeMap 26007
35#define msierrIISFailedReadProp 26008
36#define msierrIISFailedReadWebSvcExt 26009
37#define msierrIISFailedReadWebError 26010
38#define msierrIISFailedReadHttpHeader 26011
39
40#define msierrIISFailedSchedTransaction 26031
41#define msierrIISFailedSchedInstallWebs 26032
42#define msierrIISFailedSchedInstallWebDirs 26033
43#define msierrIISFailedSchedInstallVDirs 26034
44#define msierrIISFailedSchedInstallFilters 26035
45#define msierrIISFailedSchedInstallAppPool 26036
46#define msierrIISFailedSchedInstallProp 26037
47#define msierrIISFailedSchedInstallWebSvcExt 26038
48
49#define msierrIISFailedSchedUninstallWebs 26051
50#define msierrIISFailedSchedUninstallWebDirs 26052
51#define msierrIISFailedSchedUninstallVDirs 26053
52#define msierrIISFailedSchedUninstallFilters 26054
53#define msierrIISFailedSchedUninstallAppPool 26055
54#define msierrIISFailedSchedUninstallProp 26056
55#define msierrIISFailedSchedUninstallWebSvcExt 26057
56
57#define msierrIISFailedStartTransaction 26101
58#define msierrIISFailedOpenKey 26102
59#define msierrIISFailedCreateKey 26103
60#define msierrIISFailedWriteData 26104
61#define msierrIISFailedCreateApp 26105
62#define msierrIISFailedDeleteKey 26106
63#define msierrIISFailedDeleteApp 26107
64#define msierrIISFailedDeleteValue 26108
65#define msierrIISFailedCommitInUse 26109
66
67#define msierrSQLFailedCreateDatabase 26201
68#define msierrSQLFailedDropDatabase 26202
69#define msierrSQLFailedConnectDatabase 26203
70#define msierrSQLFailedExecString 26204
71#define msierrSQLDatabaseAlreadyExists 26205
72
73#define msierrPERFMONFailedRegisterDLL 26251
74#define msierrPERFMONFailedUnregisterDLL 26252
75#define msierrInstallPerfCounterData 26253
76#define msierrUninstallPerfCounterData 26254
77
78#define msierrSMBFailedCreate 26301
79#define msierrSMBFailedDrop 26302
80
81#define msierrCERTFailedOpen 26351
82#define msierrCERTFailedAdd 26352
83
84#define msierrUSRFailedUserCreate 26401
85#define msierrUSRFailedUserCreatePswd 26402
86#define msierrUSRFailedUserGroupAdd 26403
87#define msierrUSRFailedUserCreateExists 26404
88#define msierrUSRFailedGrantLogonAsService 26405
89
90#define msierrDependencyMissingDependencies 26451
91#define msierrDependencyHasDependents 26452
92
93//--------------------------------------------------------------------------
94// Managed code CustomAction Errors
95// MANAGED range: 27000-27100
96#define MANAGED_ERROR_BASE 27000
97
98#define msierrDotNetRuntimeRequired 27000
99//---------------------------------------------------------------------------
100// Public CustomAction Errors
101// PUBLIC range: 28001-28100
102#define PUBLIC_ERROR_BASE 28000
103
104#define msierrComPlusCannotConnect 28001
105#define msierrComPlusPartitionReadFailed 28002
106#define msierrComPlusPartitionRoleReadFailed 28003
107#define msierrComPlusUserInPartitionRoleReadFailed 28004
108#define msierrComPlusPartitionUserReadFailed 28005
109#define msierrComPlusApplicationReadFailed 28006
110#define msierrComPlusApplicationRoleReadFailed 28007
111#define msierrComPlusUserInApplicationRoleReadFailed 28008
112#define msierrComPlusAssembliesReadFailed 28009
113#define msierrComPlusSubscriptionReadFailed 28010
114#define msierrComPlusPartitionDependency 28011
115#define msierrComPlusPartitionNotFound 28012
116#define msierrComPlusPartitionIdConflict 28013
117#define msierrComPlusPartitionNameConflict 28014
118#define msierrComPlusApplicationDependency 28015
119#define msierrComPlusApplicationNotFound 28016
120#define msierrComPlusApplicationIdConflict 28017
121#define msierrComPlusApplicationNameConflict 28018
122#define msierrComPlusApplicationRoleDependency 28019
123#define msierrComPlusApplicationRoleNotFound 28020
124#define msierrComPlusApplicationRoleConflict 28021
125#define msierrComPlusAssemblyDependency 28022
126#define msierrComPlusSubscriptionIdConflict 28023
127#define msierrComPlusSubscriptionNameConflict 28024
128#define msierrComPlusFailedLookupNames 28025
129
130#define msierrMsmqCannotConnect 28101
diff --git a/src/ca/cost.h b/src/ca/cost.h
new file mode 100644
index 00000000..da68c667
--- /dev/null
+++ b/src/ca/cost.h
@@ -0,0 +1,5 @@
1#pragma once
2// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
3
4
5const UINT COST_FIREWALL_EXCEPTION = 2000;
diff --git a/src/ca/dllmain.cpp b/src/ca/dllmain.cpp
new file mode 100644
index 00000000..df53f872
--- /dev/null
+++ b/src/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 hInst,
11 IN ULONG ulReason,
12 IN LPVOID)
13{
14 switch(ulReason)
15 {
16 case DLL_PROCESS_ATTACH:
17 WcaGlobalInitialize(hInst);
18 break;
19
20 case DLL_PROCESS_DETACH:
21 WcaGlobalFinalize();
22 break;
23 }
24
25 return TRUE;
26}
diff --git a/src/ca/firewall.cpp b/src/ca/firewall.cpp
new file mode 100644
index 00000000..62a5b454
--- /dev/null
+++ b/src/ca/firewall.cpp
@@ -0,0 +1,1067 @@
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
5LPCWSTR vcsFirewallExceptionQuery =
6 L"SELECT `Name`, `RemoteAddresses`, `Port`, `Protocol`, `Program`, `Attributes`, `Profile`, `Component_`, `Description` FROM `WixFirewallException`";
7enum eFirewallExceptionQuery { feqName = 1, feqRemoteAddresses, feqPort, feqProtocol, feqProgram, feqAttributes, feqProfile, feqComponent, feqDescription };
8enum eFirewallExceptionTarget { fetPort = 1, fetApplication, fetUnknown };
9enum eFirewallExceptionAttributes { feaIgnoreFailures = 1 };
10
11/******************************************************************
12 SchedFirewallExceptions - immediate custom action worker to
13 register and remove firewall exceptions.
14
15********************************************************************/
16static UINT SchedFirewallExceptions(
17 __in MSIHANDLE hInstall,
18 WCA_TODO todoSched
19 )
20{
21 HRESULT hr = S_OK;
22 UINT er = ERROR_SUCCESS;
23 int cFirewallExceptions = 0;
24
25 PMSIHANDLE hView = NULL;
26 PMSIHANDLE hRec = NULL;
27
28 LPWSTR pwzCustomActionData = NULL;
29 LPWSTR pwzName = NULL;
30 LPWSTR pwzRemoteAddresses = NULL;
31 LPWSTR pwzPort = NULL;
32 int iProtocol = 0;
33 int iAttributes = 0;
34 int iProfile = 0;
35 LPWSTR pwzProgram = NULL;
36 LPWSTR pwzComponent = NULL;
37 LPWSTR pwzFormattedFile = NULL;
38 LPWSTR pwzDescription = NULL;
39
40 // initialize
41 hr = WcaInitialize(hInstall, "SchedFirewallExceptions");
42 ExitOnFailure(hr, "failed to initialize");
43
44 // anything to do?
45 if (S_OK != WcaTableExists(L"WixFirewallException"))
46 {
47 WcaLog(LOGMSG_STANDARD, "WixFirewallException table doesn't exist, so there are no firewall exceptions to configure.");
48 ExitFunction();
49 }
50
51 // query and loop through all the firewall exceptions
52 hr = WcaOpenExecuteView(vcsFirewallExceptionQuery, &hView);
53 ExitOnFailure(hr, "failed to open view on WixFirewallException table");
54
55 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
56 {
57 hr = WcaGetRecordFormattedString(hRec, feqName, &pwzName);
58 ExitOnFailure(hr, "failed to get firewall exception name");
59
60 hr = WcaGetRecordFormattedString(hRec, feqRemoteAddresses, &pwzRemoteAddresses);
61 ExitOnFailure(hr, "failed to get firewall exception remote addresses");
62
63 hr = WcaGetRecordFormattedString(hRec, feqPort, &pwzPort);
64 ExitOnFailure(hr, "failed to get firewall exception port");
65
66 hr = WcaGetRecordInteger(hRec, feqProtocol, &iProtocol);
67 ExitOnFailure(hr, "failed to get firewall exception protocol");
68
69 hr = WcaGetRecordFormattedString(hRec, feqProgram, &pwzProgram);
70 ExitOnFailure(hr, "failed to get firewall exception program");
71
72 hr = WcaGetRecordInteger(hRec, feqAttributes, &iAttributes);
73 ExitOnFailure(hr, "failed to get firewall exception attributes");
74
75 hr = WcaGetRecordInteger(hRec, feqProfile, &iProfile);
76 ExitOnFailure(hr, "failed to get firewall exception profile");
77
78 hr = WcaGetRecordString(hRec, feqComponent, &pwzComponent);
79 ExitOnFailure(hr, "failed to get firewall exception component");
80
81 hr = WcaGetRecordString(hRec, feqDescription, &pwzDescription);
82 ExitOnFailure(hr, "failed to get firewall description");
83
84 // figure out what we're doing for this exception, treating reinstall the same as install
85 WCA_TODO todoComponent = WcaGetComponentToDo(pwzComponent);
86 if ((WCA_TODO_REINSTALL == todoComponent ? WCA_TODO_INSTALL : todoComponent) != todoSched)
87 {
88 WcaLog(LOGMSG_STANDARD, "Component '%ls' action state (%d) doesn't match request (%d)", pwzComponent, todoComponent, todoSched);
89 continue;
90 }
91
92 // action :: name :: profile :: remoteaddresses :: attributes :: target :: {port::protocol | path}
93 ++cFirewallExceptions;
94 hr = WcaWriteIntegerToCaData(todoComponent, &pwzCustomActionData);
95 ExitOnFailure(hr, "failed to write exception action to custom action data");
96
97 hr = WcaWriteStringToCaData(pwzName, &pwzCustomActionData);
98 ExitOnFailure(hr, "failed to write exception name to custom action data");
99
100 hr = WcaWriteIntegerToCaData(iProfile, &pwzCustomActionData);
101 ExitOnFailure(hr, "failed to write exception profile to custom action data");
102
103 hr = WcaWriteStringToCaData(pwzRemoteAddresses, &pwzCustomActionData);
104 ExitOnFailure(hr, "failed to write exception remote addresses to custom action data");
105
106 hr = WcaWriteIntegerToCaData(iAttributes, &pwzCustomActionData);
107 ExitOnFailure(hr, "failed to write exception attributes to custom action data");
108
109 if (*pwzProgram)
110 {
111 // If program is defined, we have an application exception.
112 hr = WcaWriteIntegerToCaData(fetApplication, &pwzCustomActionData);
113 ExitOnFailure(hr, "failed to write exception target (application) to custom action data");
114
115 hr = WcaWriteStringToCaData(pwzProgram, &pwzCustomActionData);
116 ExitOnFailure(hr, "failed to write application path to custom action data");
117 }
118 else
119 {
120 // we have a port-only exception
121 hr = WcaWriteIntegerToCaData(fetPort, &pwzCustomActionData);
122 ExitOnFailure(hr, "failed to write exception target (port) to custom action data");
123 }
124
125 hr = WcaWriteStringToCaData(pwzPort, &pwzCustomActionData);
126 ExitOnFailure(hr, "failed to write application path to custom action data");
127
128 hr = WcaWriteIntegerToCaData(iProtocol, &pwzCustomActionData);
129 ExitOnFailure(hr, "failed to write exception protocol to custom action data");
130
131 hr = WcaWriteStringToCaData(pwzDescription, &pwzCustomActionData);
132 ExitOnFailure(hr, "failed to write firewall rule description to custom action data");
133 }
134
135 // reaching the end of the list is actually a good thing, not an error
136 if (E_NOMOREITEMS == hr)
137 {
138 hr = S_OK;
139 }
140 ExitOnFailure(hr, "failure occured while processing WixFirewallException table");
141
142 // schedule ExecFirewallExceptions if there's anything to do
143 if (pwzCustomActionData && *pwzCustomActionData)
144 {
145 WcaLog(LOGMSG_STANDARD, "Scheduling firewall exception (%ls)", pwzCustomActionData);
146
147 if (WCA_TODO_INSTALL == todoSched)
148 {
149 hr = WcaDoDeferredAction(L"WixRollbackFirewallExceptionsInstall", pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION);
150 ExitOnFailure(hr, "failed to schedule firewall install exceptions rollback");
151 hr = WcaDoDeferredAction(L"WixExecFirewallExceptionsInstall", pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION);
152 ExitOnFailure(hr, "failed to schedule firewall install exceptions execution");
153 }
154 else
155 {
156 hr = WcaDoDeferredAction(L"WixRollbackFirewallExceptionsUninstall", pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION);
157 ExitOnFailure(hr, "failed to schedule firewall uninstall exceptions rollback");
158 hr = WcaDoDeferredAction(L"WixExecFirewallExceptionsUninstall", pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION);
159 ExitOnFailure(hr, "failed to schedule firewall uninstall exceptions execution");
160 }
161 }
162 else
163 {
164 WcaLog(LOGMSG_STANDARD, "No firewall exceptions scheduled");
165 }
166
167LExit:
168 ReleaseStr(pwzCustomActionData);
169 ReleaseStr(pwzName);
170 ReleaseStr(pwzRemoteAddresses);
171 ReleaseStr(pwzPort);
172 ReleaseStr(pwzProgram);
173 ReleaseStr(pwzComponent);
174 ReleaseStr(pwzDescription);
175 ReleaseStr(pwzFormattedFile);
176
177 return WcaFinalize(er = FAILED(hr) ? ERROR_INSTALL_FAILURE : er);
178}
179
180/******************************************************************
181 SchedFirewallExceptionsInstall - immediate custom action entry
182 point to register firewall exceptions.
183
184********************************************************************/
185extern "C" UINT __stdcall SchedFirewallExceptionsInstall(
186 __in MSIHANDLE hInstall
187 )
188{
189 return SchedFirewallExceptions(hInstall, WCA_TODO_INSTALL);
190}
191
192/******************************************************************
193 SchedFirewallExceptionsUninstall - immediate custom action entry
194 point to remove firewall exceptions.
195
196********************************************************************/
197extern "C" UINT __stdcall SchedFirewallExceptionsUninstall(
198 __in MSIHANDLE hInstall
199 )
200{
201 return SchedFirewallExceptions(hInstall, WCA_TODO_UNINSTALL);
202}
203
204/******************************************************************
205 GetFirewallRules - Get the collection of firewall rules.
206
207********************************************************************/
208static HRESULT GetFirewallRules(
209 __in BOOL fIgnoreFailures,
210 __out INetFwRules** ppNetFwRules
211 )
212{
213 HRESULT hr = S_OK;
214 INetFwPolicy2* pNetFwPolicy2 = NULL;
215 INetFwRules* pNetFwRules = NULL;
216 *ppNetFwRules = NULL;
217
218 do
219 {
220 ReleaseNullObject(pNetFwPolicy2);
221 ReleaseNullObject(pNetFwRules);
222
223 if (SUCCEEDED(hr = ::CoCreateInstance(__uuidof(NetFwPolicy2), NULL, CLSCTX_ALL, __uuidof(INetFwPolicy2), (void**)&pNetFwPolicy2)) &&
224 SUCCEEDED(hr = pNetFwPolicy2->get_Rules(&pNetFwRules)))
225 {
226 break;
227 }
228 else if (fIgnoreFailures)
229 {
230 ExitFunction1(hr = S_FALSE);
231 }
232 else
233 {
234 WcaLog(LOGMSG_STANDARD, "Failed to connect to Windows Firewall");
235 UINT er = WcaErrorMessage(msierrFirewallCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
236 switch (er)
237 {
238 case IDABORT: // exit with the current HRESULT
239 ExitFunction();
240 case IDRETRY: // clean up and retry the loop
241 hr = S_FALSE;
242 break;
243 case IDIGNORE: // pass S_FALSE back to the caller, who knows how to ignore the failure
244 ExitFunction1(hr = S_FALSE);
245 default: // No UI, so default is to fail.
246 ExitFunction();
247 }
248 }
249 } while (S_FALSE == hr);
250
251 *ppNetFwRules = pNetFwRules;
252 pNetFwRules = NULL;
253
254LExit:
255 ReleaseObject(pNetFwPolicy2);
256 ReleaseObject(pNetFwRules);
257
258 return hr;
259}
260
261/******************************************************************
262 CreateFwRuleObject - CoCreate a firewall rule, and set the common set of properties which are shared
263 between port and application firewall rules
264
265********************************************************************/
266static HRESULT CreateFwRuleObject(
267 __in BSTR bstrName,
268 __in int iProfile,
269 __in_opt LPCWSTR wzRemoteAddresses,
270 __in LPCWSTR wzPort,
271 __in int iProtocol,
272 __in LPCWSTR wzDescription,
273 __out INetFwRule** ppNetFwRule
274 )
275{
276 HRESULT hr = S_OK;
277 BSTR bstrRemoteAddresses = NULL;
278 BSTR bstrPort = NULL;
279 BSTR bstrDescription = NULL;
280 INetFwRule* pNetFwRule = NULL;
281 *ppNetFwRule = NULL;
282
283 // convert to BSTRs to make COM happy
284 bstrRemoteAddresses = ::SysAllocString(wzRemoteAddresses);
285 ExitOnNull(bstrRemoteAddresses, hr, E_OUTOFMEMORY, "failed SysAllocString for remote addresses");
286 bstrPort = ::SysAllocString(wzPort);
287 ExitOnNull(bstrPort, hr, E_OUTOFMEMORY, "failed SysAllocString for port");
288 bstrDescription = ::SysAllocString(wzDescription);
289 ExitOnNull(bstrDescription, hr, E_OUTOFMEMORY, "failed SysAllocString for description");
290
291 hr = ::CoCreateInstance(__uuidof(NetFwRule), NULL, CLSCTX_ALL, __uuidof(INetFwRule), (void**)&pNetFwRule);
292 ExitOnFailure(hr, "failed to create NetFwRule object");
293
294 hr = pNetFwRule->put_Name(bstrName);
295 ExitOnFailure(hr, "failed to set exception name");
296
297 hr = pNetFwRule->put_Profiles(static_cast<NET_FW_PROFILE_TYPE2>(iProfile));
298 ExitOnFailure(hr, "failed to set exception profile");
299
300 if (MSI_NULL_INTEGER != iProtocol)
301 {
302 hr = pNetFwRule->put_Protocol(static_cast<NET_FW_IP_PROTOCOL>(iProtocol));
303 ExitOnFailure(hr, "failed to set exception protocol");
304 }
305
306 if (bstrPort && *bstrPort)
307 {
308 hr = pNetFwRule->put_LocalPorts(bstrPort);
309 ExitOnFailure(hr, "failed to set exception port");
310 }
311
312 if (bstrRemoteAddresses && *bstrRemoteAddresses)
313 {
314 hr = pNetFwRule->put_RemoteAddresses(bstrRemoteAddresses);
315 ExitOnFailure(hr, "failed to set exception remote addresses '%ls'", bstrRemoteAddresses);
316 }
317
318 if (bstrDescription && *bstrDescription)
319 {
320 hr = pNetFwRule->put_Description(bstrDescription);
321 ExitOnFailure(hr, "failed to set exception description '%ls'", bstrDescription);
322 }
323
324 *ppNetFwRule = pNetFwRule;
325 pNetFwRule = NULL;
326
327LExit:
328 ReleaseBSTR(bstrRemoteAddresses);
329 ReleaseBSTR(bstrPort);
330 ReleaseBSTR(bstrDescription);
331 ReleaseObject(pNetFwRule);
332
333 return hr;
334}
335
336/******************************************************************
337 FSupportProfiles - Returns true if we support profiles on this machine.
338 (Only on Vista or later)
339
340********************************************************************/
341static BOOL FSupportProfiles()
342{
343 BOOL fSupportProfiles = FALSE;
344 INetFwRules* pNetFwRules = NULL;
345
346 // We only support profiles if we can co-create an instance of NetFwPolicy2.
347 // This will not work on pre-vista machines.
348 if (SUCCEEDED(GetFirewallRules(TRUE, &pNetFwRules)) && pNetFwRules != NULL)
349 {
350 fSupportProfiles = TRUE;
351 ReleaseObject(pNetFwRules);
352 }
353
354 return fSupportProfiles;
355}
356
357/******************************************************************
358 GetCurrentFirewallProfile - get the active firewall profile as an
359 INetFwProfile, which owns the lists of exceptions we're
360 updating.
361
362********************************************************************/
363static HRESULT GetCurrentFirewallProfile(
364 __in BOOL fIgnoreFailures,
365 __out INetFwProfile** ppfwProfile
366 )
367{
368 HRESULT hr = S_OK;
369 INetFwMgr* pfwMgr = NULL;
370 INetFwPolicy* pfwPolicy = NULL;
371 INetFwProfile* pfwProfile = NULL;
372 *ppfwProfile = NULL;
373
374 do
375 {
376 ReleaseNullObject(pfwPolicy);
377 ReleaseNullObject(pfwMgr);
378 ReleaseNullObject(pfwProfile);
379
380 if (SUCCEEDED(hr = ::CoCreateInstance(__uuidof(NetFwMgr), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwMgr), (void**)&pfwMgr)) &&
381 SUCCEEDED(hr = pfwMgr->get_LocalPolicy(&pfwPolicy)) &&
382 SUCCEEDED(hr = pfwPolicy->get_CurrentProfile(&pfwProfile)))
383 {
384 break;
385 }
386 else if (fIgnoreFailures)
387 {
388 ExitFunction1(hr = S_FALSE);
389 }
390 else
391 {
392 WcaLog(LOGMSG_STANDARD, "Failed to connect to Windows Firewall");
393 UINT er = WcaErrorMessage(msierrFirewallCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
394 switch (er)
395 {
396 case IDABORT: // exit with the current HRESULT
397 ExitFunction();
398 case IDRETRY: // clean up and retry the loop
399 hr = S_FALSE;
400 break;
401 case IDIGNORE: // pass S_FALSE back to the caller, who knows how to ignore the failure
402 ExitFunction1(hr = S_FALSE);
403 default: // No UI, so default is to fail.
404 ExitFunction();
405 }
406 }
407 } while (S_FALSE == hr);
408
409 *ppfwProfile = pfwProfile;
410 pfwProfile = NULL;
411
412LExit:
413 ReleaseObject(pfwPolicy);
414 ReleaseObject(pfwMgr);
415 ReleaseObject(pfwProfile);
416
417 return hr;
418}
419
420/******************************************************************
421 AddApplicationException
422
423********************************************************************/
424static HRESULT AddApplicationException(
425 __in LPCWSTR wzFile,
426 __in LPCWSTR wzName,
427 __in int iProfile,
428 __in_opt LPCWSTR wzRemoteAddresses,
429 __in BOOL fIgnoreFailures,
430 __in LPCWSTR wzPort,
431 __in int iProtocol,
432 __in LPCWSTR wzDescription
433 )
434{
435 HRESULT hr = S_OK;
436 BSTR bstrFile = NULL;
437 BSTR bstrName = NULL;
438 INetFwRules* pNetFwRules = NULL;
439 INetFwRule* pNetFwRule = NULL;
440
441 // convert to BSTRs to make COM happy
442 bstrFile = ::SysAllocString(wzFile);
443 ExitOnNull(bstrFile, hr, E_OUTOFMEMORY, "failed SysAllocString for path");
444 bstrName = ::SysAllocString(wzName);
445 ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "failed SysAllocString for name");
446
447 // get the collection of firewall rules
448 hr = GetFirewallRules(fIgnoreFailures, &pNetFwRules);
449 ExitOnFailure(hr, "failed to get firewall rules object");
450 if (S_FALSE == hr) // user or package author chose to ignore missing firewall
451 {
452 ExitFunction();
453 }
454
455 // try to find it (i.e., support reinstall)
456 hr = pNetFwRules->Item(bstrName, &pNetFwRule);
457 if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
458 {
459 hr = CreateFwRuleObject(bstrName, iProfile, wzRemoteAddresses, wzPort, iProtocol, wzDescription, &pNetFwRule);
460 ExitOnFailure(hr, "failed to create FwRule object");
461
462 // set edge traversal to true
463 hr = pNetFwRule->put_EdgeTraversal(VARIANT_TRUE);
464 ExitOnFailure(hr, "failed to set application exception edgetraversal property");
465
466 // set path
467 hr = pNetFwRule->put_ApplicationName(bstrFile);
468 ExitOnFailure(hr, "failed to set application name");
469
470 // enable it
471 hr = pNetFwRule->put_Enabled(VARIANT_TRUE);
472 ExitOnFailure(hr, "failed to to enable application exception");
473
474 // add it to the list of authorized apps
475 hr = pNetFwRules->Add(pNetFwRule);
476 ExitOnFailure(hr, "failed to add app to the authorized apps list");
477 }
478 else
479 {
480 // we found an existing app exception (if we succeeded, that is)
481 ExitOnFailure(hr, "failed trying to find existing app");
482
483 // enable it (just in case it was disabled)
484 pNetFwRule->put_Enabled(VARIANT_TRUE);
485 }
486
487LExit:
488 ReleaseBSTR(bstrName);
489 ReleaseBSTR(bstrFile);
490 ReleaseObject(pNetFwRules);
491 ReleaseObject(pNetFwRule);
492
493 return fIgnoreFailures ? S_OK : hr;
494}
495
496/******************************************************************
497 AddApplicationExceptionOnCurrentProfile
498
499********************************************************************/
500static HRESULT AddApplicationExceptionOnCurrentProfile(
501 __in LPCWSTR wzFile,
502 __in LPCWSTR wzName,
503 __in_opt LPCWSTR wzRemoteAddresses,
504 __in BOOL fIgnoreFailures
505 )
506{
507 HRESULT hr = S_OK;
508 BSTR bstrFile = NULL;
509 BSTR bstrName = NULL;
510 BSTR bstrRemoteAddresses = NULL;
511 INetFwProfile* pfwProfile = NULL;
512 INetFwAuthorizedApplications* pfwApps = NULL;
513 INetFwAuthorizedApplication* pfwApp = NULL;
514
515 // convert to BSTRs to make COM happy
516 bstrFile = ::SysAllocString(wzFile);
517 ExitOnNull(bstrFile, hr, E_OUTOFMEMORY, "failed SysAllocString for path");
518 bstrName = ::SysAllocString(wzName);
519 ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "failed SysAllocString for name");
520 bstrRemoteAddresses = ::SysAllocString(wzRemoteAddresses);
521 ExitOnNull(bstrRemoteAddresses, hr, E_OUTOFMEMORY, "failed SysAllocString for remote addresses");
522
523 // get the firewall profile, which is our entry point for adding exceptions
524 hr = GetCurrentFirewallProfile(fIgnoreFailures, &pfwProfile);
525 ExitOnFailure(hr, "failed to get firewall profile");
526 if (S_FALSE == hr) // user or package author chose to ignore missing firewall
527 {
528 ExitFunction();
529 }
530
531 // first, let's see if the app is already on the exception list
532 hr = pfwProfile->get_AuthorizedApplications(&pfwApps);
533 ExitOnFailure(hr, "failed to get list of authorized apps");
534
535 // try to find it (i.e., support reinstall)
536 hr = pfwApps->Item(bstrFile, &pfwApp);
537 if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
538 {
539 // not found, so we get to add it
540 hr = ::CoCreateInstance(__uuidof(NetFwAuthorizedApplication), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwAuthorizedApplication), reinterpret_cast<void**>(&pfwApp));
541 ExitOnFailure(hr, "failed to create authorized app");
542
543 // set the display name
544 hr = pfwApp->put_Name(bstrName);
545 ExitOnFailure(hr, "failed to set authorized app name");
546
547 // set path
548 hr = pfwApp->put_ProcessImageFileName(bstrFile);
549 ExitOnFailure(hr, "failed to set authorized app path");
550
551 // set the allowed remote addresses
552 if (bstrRemoteAddresses && *bstrRemoteAddresses)
553 {
554 hr = pfwApp->put_RemoteAddresses(bstrRemoteAddresses);
555 ExitOnFailure(hr, "failed to set authorized app remote addresses");
556 }
557
558 // add it to the list of authorized apps
559 hr = pfwApps->Add(pfwApp);
560 ExitOnFailure(hr, "failed to add app to the authorized apps list");
561 }
562 else
563 {
564 // we found an existing app exception (if we succeeded, that is)
565 ExitOnFailure(hr, "failed trying to find existing app");
566
567 // enable it (just in case it was disabled)
568 pfwApp->put_Enabled(VARIANT_TRUE);
569 }
570
571LExit:
572 ReleaseBSTR(bstrRemoteAddresses);
573 ReleaseBSTR(bstrName);
574 ReleaseBSTR(bstrFile);
575 ReleaseObject(pfwApp);
576 ReleaseObject(pfwApps);
577 ReleaseObject(pfwProfile);
578
579 return fIgnoreFailures ? S_OK : hr;
580}
581
582/******************************************************************
583 AddPortException
584
585********************************************************************/
586static HRESULT AddPortException(
587 __in LPCWSTR wzName,
588 __in int iProfile,
589 __in_opt LPCWSTR wzRemoteAddresses,
590 __in BOOL fIgnoreFailures,
591 __in LPCWSTR wzPort,
592 __in int iProtocol,
593 __in LPCWSTR wzDescription
594 )
595{
596 HRESULT hr = S_OK;
597 BSTR bstrName = NULL;
598 INetFwRules* pNetFwRules = NULL;
599 INetFwRule* pNetFwRule = NULL;
600
601 // convert to BSTRs to make COM happy
602 bstrName = ::SysAllocString(wzName);
603 ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "failed SysAllocString for name");
604
605 // get the collection of firewall rules
606 hr = GetFirewallRules(fIgnoreFailures, &pNetFwRules);
607 ExitOnFailure(hr, "failed to get firewall rules object");
608 if (S_FALSE == hr) // user or package author chose to ignore missing firewall
609 {
610 ExitFunction();
611 }
612
613 // try to find it (i.e., support reinstall)
614 hr = pNetFwRules->Item(bstrName, &pNetFwRule);
615 if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
616 {
617 hr = CreateFwRuleObject(bstrName, iProfile, wzRemoteAddresses, wzPort, iProtocol, wzDescription, &pNetFwRule);
618 ExitOnFailure(hr, "failed to create FwRule object");
619
620 // enable it
621 hr = pNetFwRule->put_Enabled(VARIANT_TRUE);
622 ExitOnFailure(hr, "failed to to enable port exception");
623
624 // add it to the list of authorized ports
625 hr = pNetFwRules->Add(pNetFwRule);
626 ExitOnFailure(hr, "failed to add app to the authorized ports list");
627 }
628 else
629 {
630 // we found an existing port exception (if we succeeded, that is)
631 ExitOnFailure(hr, "failed trying to find existing port rule");
632
633 // enable it (just in case it was disabled)
634 pNetFwRule->put_Enabled(VARIANT_TRUE);
635 }
636
637LExit:
638 ReleaseBSTR(bstrName);
639 ReleaseObject(pNetFwRules);
640 ReleaseObject(pNetFwRule);
641
642 return fIgnoreFailures ? S_OK : hr;
643}
644
645/******************************************************************
646 AddPortExceptionOnCurrentProfile
647
648********************************************************************/
649static HRESULT AddPortExceptionOnCurrentProfile(
650 __in LPCWSTR wzName,
651 __in_opt LPCWSTR wzRemoteAddresses,
652 __in BOOL fIgnoreFailures,
653 __in int iPort,
654 __in int iProtocol
655 )
656{
657 HRESULT hr = S_OK;
658 BSTR bstrName = NULL;
659 BSTR bstrRemoteAddresses = NULL;
660 INetFwProfile* pfwProfile = NULL;
661 INetFwOpenPorts* pfwPorts = NULL;
662 INetFwOpenPort* pfwPort = NULL;
663
664 // convert to BSTRs to make COM happy
665 bstrName = ::SysAllocString(wzName);
666 ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "failed SysAllocString for name");
667 bstrRemoteAddresses = ::SysAllocString(wzRemoteAddresses);
668 ExitOnNull(bstrRemoteAddresses, hr, E_OUTOFMEMORY, "failed SysAllocString for remote addresses");
669
670 // create and initialize a new open port object
671 hr = ::CoCreateInstance(__uuidof(NetFwOpenPort), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwOpenPort), reinterpret_cast<void**>(&pfwPort));
672 ExitOnFailure(hr, "failed to create new open port");
673
674 hr = pfwPort->put_Port(iPort);
675 ExitOnFailure(hr, "failed to set exception port");
676
677 hr = pfwPort->put_Protocol(static_cast<NET_FW_IP_PROTOCOL>(iProtocol));
678 ExitOnFailure(hr, "failed to set exception protocol");
679
680 if (bstrRemoteAddresses && *bstrRemoteAddresses)
681 {
682 hr = pfwPort->put_RemoteAddresses(bstrRemoteAddresses);
683 ExitOnFailure(hr, "failed to set exception remote addresses '%ls'", bstrRemoteAddresses);
684 }
685
686 hr = pfwPort->put_Name(bstrName);
687 ExitOnFailure(hr, "failed to set exception name");
688
689 // get the firewall profile, its current list of open ports, and add ours
690 hr = GetCurrentFirewallProfile(fIgnoreFailures, &pfwProfile);
691 ExitOnFailure(hr, "failed to get firewall profile");
692 if (S_FALSE == hr) // user or package author chose to ignore missing firewall
693 {
694 ExitFunction();
695 }
696
697 hr = pfwProfile->get_GloballyOpenPorts(&pfwPorts);
698 ExitOnFailure(hr, "failed to get open ports");
699
700 hr = pfwPorts->Add(pfwPort);
701 ExitOnFailure(hr, "failed to add exception to global list");
702
703LExit:
704 ReleaseBSTR(bstrRemoteAddresses);
705 ReleaseBSTR(bstrName);
706 ReleaseObject(pfwProfile);
707 ReleaseObject(pfwPorts);
708 ReleaseObject(pfwPort);
709
710 return fIgnoreFailures ? S_OK : hr;
711}
712
713/******************************************************************
714 RemoveException - Removes the exception rule with the given name.
715
716********************************************************************/
717static HRESULT RemoveException(
718 __in LPCWSTR wzName,
719 __in BOOL fIgnoreFailures
720 )
721{
722 HRESULT hr = S_OK;;
723 INetFwRules* pNetFwRules = NULL;
724
725 // convert to BSTRs to make COM happy
726 BSTR bstrName = ::SysAllocString(wzName);
727 ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "failed SysAllocString for path");
728
729 // get the collection of firewall rules
730 hr = GetFirewallRules(fIgnoreFailures, &pNetFwRules);
731 ExitOnFailure(hr, "failed to get firewall rules object");
732 if (S_FALSE == hr) // user or package author chose to ignore missing firewall
733 {
734 ExitFunction();
735 }
736
737 hr = pNetFwRules->Remove(bstrName);
738 ExitOnFailure(hr, "failed to remove authorized app");
739
740LExit:
741 ReleaseBSTR(bstrName);
742 ReleaseObject(pNetFwRules);
743
744 return fIgnoreFailures ? S_OK : hr;
745}
746
747/******************************************************************
748 RemoveApplicationExceptionFromCurrentProfile
749
750********************************************************************/
751static HRESULT RemoveApplicationExceptionFromCurrentProfile(
752 __in LPCWSTR wzFile,
753 __in BOOL fIgnoreFailures
754 )
755{
756 HRESULT hr = S_OK;
757 INetFwProfile* pfwProfile = NULL;
758 INetFwAuthorizedApplications* pfwApps = NULL;
759
760 // convert to BSTRs to make COM happy
761 BSTR bstrFile = ::SysAllocString(wzFile);
762 ExitOnNull(bstrFile, hr, E_OUTOFMEMORY, "failed SysAllocString for path");
763
764 // get the firewall profile, which is our entry point for removing exceptions
765 hr = GetCurrentFirewallProfile(fIgnoreFailures, &pfwProfile);
766 ExitOnFailure(hr, "failed to get firewall profile");
767 if (S_FALSE == hr) // user or package author chose to ignore missing firewall
768 {
769 ExitFunction();
770 }
771
772 // now get the list of app exceptions and remove the one
773 hr = pfwProfile->get_AuthorizedApplications(&pfwApps);
774 ExitOnFailure(hr, "failed to get list of authorized apps");
775
776 hr = pfwApps->Remove(bstrFile);
777 ExitOnFailure(hr, "failed to remove authorized app");
778
779LExit:
780 ReleaseBSTR(bstrFile);
781 ReleaseObject(pfwApps);
782 ReleaseObject(pfwProfile);
783
784 return fIgnoreFailures ? S_OK : hr;
785}
786
787/******************************************************************
788 RemovePortExceptionFromCurrentProfile
789
790********************************************************************/
791static HRESULT RemovePortExceptionFromCurrentProfile(
792 __in int iPort,
793 __in int iProtocol,
794 __in BOOL fIgnoreFailures
795 )
796{
797 HRESULT hr = S_OK;
798 INetFwProfile* pfwProfile = NULL;
799 INetFwOpenPorts* pfwPorts = NULL;
800
801 // get the firewall profile, which is our entry point for adding exceptions
802 hr = GetCurrentFirewallProfile(fIgnoreFailures, &pfwProfile);
803 ExitOnFailure(hr, "failed to get firewall profile");
804 if (S_FALSE == hr) // user or package author chose to ignore missing firewall
805 {
806 ExitFunction();
807 }
808
809 hr = pfwProfile->get_GloballyOpenPorts(&pfwPorts);
810 ExitOnFailure(hr, "failed to get open ports");
811
812 hr = pfwPorts->Remove(iPort, static_cast<NET_FW_IP_PROTOCOL>(iProtocol));
813 ExitOnFailure(hr, "failed to remove open port %d, protocol %d", iPort, iProtocol);
814
815LExit:
816 return fIgnoreFailures ? S_OK : hr;
817}
818
819static HRESULT AddApplicationException(
820 __in BOOL fSupportProfiles,
821 __in LPCWSTR wzFile,
822 __in LPCWSTR wzName,
823 __in int iProfile,
824 __in_opt LPCWSTR wzRemoteAddresses,
825 __in BOOL fIgnoreFailures,
826 __in LPCWSTR wzPort,
827 __in int iProtocol,
828 __in LPCWSTR wzDescription
829 )
830{
831 HRESULT hr = S_OK;
832
833 if (fSupportProfiles)
834 {
835 hr = AddApplicationException(wzFile, wzName, iProfile, wzRemoteAddresses, fIgnoreFailures, wzPort, iProtocol, wzDescription);
836 }
837 else
838 {
839 if (0 != *wzPort || MSI_NULL_INTEGER != iProtocol)
840 {
841 // NOTE: This is treated as an error rather than either creating a rule based on just the application (no port), or
842 // just the port because it is unclear what is the proper fall back. For example, suppose that you have code that
843 // runs in dllhost.exe. Clearly falling back to opening all of dllhost is wrong. Because the firewall is a security
844 // feature, it seems better to require the MSI author to indicate the behavior that they want.
845 WcaLog(LOGMSG_STANDARD, "FirewallExtension: Cannot add firewall rule '%ls', which defines both an application and a port or protocol. Such a rule requires Microsoft Windows Vista or later.", wzName);
846 return fIgnoreFailures ? S_OK : E_NOTIMPL;
847 }
848
849 hr = AddApplicationExceptionOnCurrentProfile(wzFile, wzName, wzRemoteAddresses, fIgnoreFailures);
850 }
851
852 return hr;
853}
854
855static HRESULT AddPortException(
856 __in BOOL fSupportProfiles,
857 __in LPCWSTR wzName,
858 __in int iProfile,
859 __in_opt LPCWSTR wzRemoteAddresses,
860 __in BOOL fIgnoreFailures,
861 __in LPCWSTR wzPort,
862 __in int iProtocol,
863 __in LPCWSTR wzDescription
864 )
865{
866 HRESULT hr = S_OK;
867
868 if (fSupportProfiles)
869 {
870 hr = AddPortException(wzName, iProfile, wzRemoteAddresses, fIgnoreFailures, wzPort, iProtocol, wzDescription);
871 }
872 else
873 {
874 hr = AddPortExceptionOnCurrentProfile(wzName, wzRemoteAddresses, fIgnoreFailures, wcstol(wzPort, NULL, 10), iProtocol);
875 }
876
877 return hr;
878}
879
880static HRESULT RemoveApplicationException(
881 __in BOOL fSupportProfiles,
882 __in LPCWSTR wzName,
883 __in LPCWSTR wzFile,
884 __in BOOL fIgnoreFailures,
885 __in LPCWSTR wzPort,
886 __in int iProtocol
887 )
888{
889 HRESULT hr = S_OK;
890
891 if (fSupportProfiles)
892 {
893 hr = RemoveException(wzName, fIgnoreFailures);
894 }
895 else
896 {
897 if (0 != *wzPort || MSI_NULL_INTEGER != iProtocol)
898 {
899 WcaLog(LOGMSG_STANDARD, "FirewallExtension: Cannot remove firewall rule '%ls', which defines both an application and a port or protocol. Such a rule requires Microsoft Windows Vista or later.", wzName);
900 return S_OK;
901 }
902
903 hr = RemoveApplicationExceptionFromCurrentProfile(wzFile, fIgnoreFailures);
904 }
905
906 return hr;
907}
908
909static HRESULT RemovePortException(
910 __in BOOL fSupportProfiles,
911 __in LPCWSTR wzName,
912 __in LPCWSTR wzPort,
913 __in int iProtocol,
914 __in BOOL fIgnoreFailures
915 )
916{
917 HRESULT hr = S_OK;
918
919 if (fSupportProfiles)
920 {
921 hr = RemoveException(wzName, fIgnoreFailures);
922 }
923 else
924 {
925 hr = RemovePortExceptionFromCurrentProfile(wcstol(wzPort, NULL, 10), iProtocol, fIgnoreFailures);
926 }
927
928 return hr;
929}
930
931/******************************************************************
932 ExecFirewallExceptions - deferred custom action entry point to
933 register and remove firewall exceptions.
934
935********************************************************************/
936extern "C" UINT __stdcall ExecFirewallExceptions(
937 __in MSIHANDLE hInstall
938 )
939{
940 HRESULT hr = S_OK;
941 BOOL fSupportProfiles = FALSE;
942 LPWSTR pwz = NULL;
943 LPWSTR pwzCustomActionData = NULL;
944 int iTodo = WCA_TODO_UNKNOWN;
945 LPWSTR pwzName = NULL;
946 LPWSTR pwzRemoteAddresses = NULL;
947 int iAttributes = 0;
948 int iTarget = fetUnknown;
949 LPWSTR pwzFile = NULL;
950 LPWSTR pwzPort = NULL;
951 LPWSTR pwzDescription = NULL;
952 int iProtocol = 0;
953 int iProfile = 0;
954
955 // initialize
956 hr = WcaInitialize(hInstall, "ExecFirewallExceptions");
957 ExitOnFailure(hr, "failed to initialize");
958
959 hr = WcaGetProperty( L"CustomActionData", &pwzCustomActionData);
960 ExitOnFailure(hr, "failed to get CustomActionData");
961 WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzCustomActionData);
962
963 hr = ::CoInitialize(NULL);
964 ExitOnFailure(hr, "failed to initialize COM");
965
966 // Find out if we support profiles (only on Vista or later)
967 fSupportProfiles = FSupportProfiles();
968
969 // loop through all the passed in data
970 pwz = pwzCustomActionData;
971 while (pwz && *pwz)
972 {
973 // extract the custom action data and if rolling back, swap INSTALL and UNINSTALL
974 hr = WcaReadIntegerFromCaData(&pwz, &iTodo);
975 ExitOnFailure(hr, "failed to read todo from custom action data");
976 if (::MsiGetMode(hInstall, MSIRUNMODE_ROLLBACK))
977 {
978 if (WCA_TODO_INSTALL == iTodo)
979 {
980 iTodo = WCA_TODO_UNINSTALL;
981 }
982 else if (WCA_TODO_UNINSTALL == iTodo)
983 {
984 iTodo = WCA_TODO_INSTALL;
985 }
986 }
987
988 hr = WcaReadStringFromCaData(&pwz, &pwzName);
989 ExitOnFailure(hr, "failed to read name from custom action data");
990
991 hr = WcaReadIntegerFromCaData(&pwz, &iProfile);
992 ExitOnFailure(hr, "failed to read profile from custom action data");
993
994 hr = WcaReadStringFromCaData(&pwz, &pwzRemoteAddresses);
995 ExitOnFailure(hr, "failed to read remote addresses from custom action data");
996
997 hr = WcaReadIntegerFromCaData(&pwz, &iAttributes);
998 ExitOnFailure(hr, "failed to read attributes from custom action data");
999 BOOL fIgnoreFailures = feaIgnoreFailures == (iAttributes & feaIgnoreFailures);
1000
1001 hr = WcaReadIntegerFromCaData(&pwz, &iTarget);
1002 ExitOnFailure(hr, "failed to read target from custom action data");
1003
1004 if (iTarget == fetApplication)
1005 {
1006 hr = WcaReadStringFromCaData(&pwz, &pwzFile);
1007 ExitOnFailure(hr, "failed to read file path from custom action data");
1008 }
1009
1010 hr = WcaReadStringFromCaData(&pwz, &pwzPort);
1011 ExitOnFailure(hr, "failed to read port from custom action data");
1012 hr = WcaReadIntegerFromCaData(&pwz, &iProtocol);
1013 ExitOnFailure(hr, "failed to read protocol from custom action data");
1014 hr = WcaReadStringFromCaData(&pwz, &pwzDescription);
1015 ExitOnFailure(hr, "failed to read protocol from custom action data");
1016
1017 switch (iTarget)
1018 {
1019 case fetPort:
1020 switch (iTodo)
1021 {
1022 case WCA_TODO_INSTALL:
1023 case WCA_TODO_REINSTALL:
1024 WcaLog(LOGMSG_STANDARD, "Installing firewall exception2 %ls on port %ls, protocol %d", pwzName, pwzPort, iProtocol);
1025 hr = AddPortException(fSupportProfiles, pwzName, iProfile, pwzRemoteAddresses, fIgnoreFailures, pwzPort, iProtocol, pwzDescription);
1026 ExitOnFailure(hr, "failed to add/update port exception for name '%ls' on port %ls, protocol %d", pwzName, pwzPort, iProtocol);
1027 break;
1028
1029 case WCA_TODO_UNINSTALL:
1030 WcaLog(LOGMSG_STANDARD, "Uninstalling firewall exception2 %ls on port %ls, protocol %d", pwzName, pwzPort, iProtocol);
1031 hr = RemovePortException(fSupportProfiles, pwzName, pwzPort, iProtocol, fIgnoreFailures);
1032 ExitOnFailure(hr, "failed to remove port exception for name '%ls' on port %ls, protocol %d", pwzName, pwzPort, iProtocol);
1033 break;
1034 }
1035 break;
1036
1037 case fetApplication:
1038 switch (iTodo)
1039 {
1040 case WCA_TODO_INSTALL:
1041 case WCA_TODO_REINSTALL:
1042 WcaLog(LOGMSG_STANDARD, "Installing firewall exception2 %ls (%ls)", pwzName, pwzFile);
1043 hr = AddApplicationException(fSupportProfiles, pwzFile, pwzName, iProfile, pwzRemoteAddresses, fIgnoreFailures, pwzPort, iProtocol, pwzDescription);
1044 ExitOnFailure(hr, "failed to add/update application exception for name '%ls', file '%ls'", pwzName, pwzFile);
1045 break;
1046
1047 case WCA_TODO_UNINSTALL:
1048 WcaLog(LOGMSG_STANDARD, "Uninstalling firewall exception2 %ls (%ls)", pwzName, pwzFile);
1049 hr = RemoveApplicationException(fSupportProfiles, pwzName, pwzFile, fIgnoreFailures, pwzPort, iProtocol);
1050 ExitOnFailure(hr, "failed to remove application exception for name '%ls', file '%ls'", pwzName, pwzFile);
1051 break;
1052 }
1053 break;
1054 }
1055 }
1056
1057LExit:
1058 ReleaseStr(pwzCustomActionData);
1059 ReleaseStr(pwzName);
1060 ReleaseStr(pwzRemoteAddresses);
1061 ReleaseStr(pwzFile);
1062 ReleaseStr(pwzPort);
1063 ReleaseStr(pwzDescription);
1064 ::CoUninitialize();
1065
1066 return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS);
1067}
diff --git a/src/ca/fwca.def b/src/ca/fwca.def
new file mode 100644
index 00000000..d32c5379
--- /dev/null
+++ b/src/ca/fwca.def
@@ -0,0 +1,9 @@
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 "fwca"
5
6EXPORTS
7 SchedFirewallExceptionsInstall
8 SchedFirewallExceptionsUninstall
9 ExecFirewallExceptions
diff --git a/src/ca/fwca.vcxproj b/src/ca/fwca.vcxproj
new file mode 100644
index 00000000..b6075790
--- /dev/null
+++ b/src/ca/fwca.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
4<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
5 <Import Project="..\..\packages\WixToolset.DUtil.4.0.6\build\WixToolset.DUtil.props" Condition="Exists('..\..\packages\WixToolset.DUtil.4.0.6\build\WixToolset.DUtil.props')" />
6 <Import Project="..\..\packages\WixToolset.WcaUtil.4.0.2\build\WixToolset.WcaUtil.props" Condition="Exists('..\..\packages\WixToolset.WcaUtil.4.0.2\build\WixToolset.WcaUtil.props')" />
7
8 <ItemGroup Label="ProjectConfigurations">
9 <ProjectConfiguration Include="Debug|Win32">
10 <Configuration>Debug</Configuration>
11 <Platform>Win32</Platform>
12 </ProjectConfiguration>
13 <ProjectConfiguration Include="Release|Win32">
14 <Configuration>Release</Configuration>
15 <Platform>Win32</Platform>
16 </ProjectConfiguration>
17 </ItemGroup>
18
19 <PropertyGroup Label="Globals">
20 <ProjectGuid>{F72D34CA-48DA-4DFD-91A9-A0C78BEF6981}</ProjectGuid>
21 <ConfigurationType>DynamicLibrary</ConfigurationType>
22 <TargetName>fwca</TargetName>
23 <PlatformToolset>v141</PlatformToolset>
24 <CharacterSet>Unicode</CharacterSet>
25 <ProjectModuleDefinitionFile>fwca.def</ProjectModuleDefinitionFile>
26 <Description>WiX Toolset Firewall CustomAction</Description>
27 </PropertyGroup>
28
29 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
30 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
31
32 <ImportGroup Label="ExtensionSettings">
33 </ImportGroup>
34
35 <ImportGroup Label="Shared">
36 <Import Project="..\..\packages\Microsoft.VisualStudio.Setup.Configuration.Native.1.14.114\build\native\Microsoft.VisualStudio.Setup.Configuration.Native.targets" Condition="Exists('..\..\packages\Microsoft.VisualStudio.Setup.Configuration.Native.1.14.114\build\native\Microsoft.VisualStudio.Setup.Configuration.Native.targets')" />
37 </ImportGroup>
38
39 <PropertyGroup>
40 <ProjectAdditionalLinkLibraries>msi.lib</ProjectAdditionalLinkLibraries>
41 </PropertyGroup>
42
43 <ItemGroup>
44 <ClCompile Include="dllmain.cpp">
45 <PrecompiledHeader>Create</PrecompiledHeader>
46 </ClCompile>
47 <ClCompile Include="firewall.cpp" />
48 </ItemGroup>
49
50 <ItemGroup>
51 <ClInclude Include="cost.h" />
52 <ClInclude Include="CustomMsiErrors.h" />
53 <ClInclude Include="precomp.h" />
54 </ItemGroup>
55
56 <ItemGroup>
57 <None Include="packages.config" />
58 <None Include="fwca.def" />
59 </ItemGroup>
60
61 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
62
63 <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
64 <PropertyGroup>
65 <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>
66 </PropertyGroup>
67 <Error Condition="!Exists('..\..\packages\Microsoft.VisualStudio.Setup.Configuration.Native.1.14.114\build\native\Microsoft.VisualStudio.Setup.Configuration.Native.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.VisualStudio.Setup.Configuration.Native.1.14.114\build\native\Microsoft.VisualStudio.Setup.Configuration.Native.targets'))" />
68 <Error Condition="!Exists('..\..\packages\WixToolset.DUtil.4.0.6\build\WixToolset.DUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.DUtil.4.0.6\build\WixToolset.DUtil.props'))" />
69 <Error Condition="!Exists('..\..\packages\WixToolset.WcaUtil.4.0.2\build\WixToolset.WcaUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.WcaUtil.4.0.2\build\WixToolset.WcaUtil.props'))" />
70 </Target>
71</Project>
72
diff --git a/src/ca/packages.config b/src/ca/packages.config
new file mode 100644
index 00000000..b74ff5d0
--- /dev/null
+++ b/src/ca/packages.config
@@ -0,0 +1,6 @@
1<?xml version="1.0" encoding="utf-8"?>
2<packages>
3 <package id="Microsoft.VisualStudio.Setup.Configuration.Native" version="1.14.114" targetFramework="native" developmentDependency="true" />
4 <package id="WixToolset.DUtil" version="4.0.6" targetFramework="native" />
5 <package id="WixToolset.WcaUtil" version="4.0.2" targetFramework="native" />
6</packages> \ No newline at end of file
diff --git a/src/ca/precomp.h b/src/ca/precomp.h
new file mode 100644
index 00000000..a84bacff
--- /dev/null
+++ b/src/ca/precomp.h
@@ -0,0 +1,17 @@
1#pragma once
2// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
3
4
5#include <windows.h>
6#include <msidefs.h>
7#include <msiquery.h>
8#include <strsafe.h>
9#include <netfw.h>
10
11#include "wcautil.h"
12#include "fileutil.h"
13#include "pathutil.h"
14#include "strutil.h"
15
16#include "CustomMsiErrors.h"
17#include "cost.h"
diff --git a/src/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs b/src/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs
new file mode 100644
index 00000000..0d7eb6ad
--- /dev/null
+++ b/src/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs
@@ -0,0 +1,33 @@
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.Firewall
4{
5 using System.Linq;
6 using WixBuildTools.TestSupport;
7 using WixToolset.Core.TestPackage;
8 using WixToolset.Firewall;
9 using Xunit;
10
11 public class FirewallExtensionFixture
12 {
13 [Fact]
14 public void CanBuildUsingFileShare()
15 {
16 var folder = TestData.Get(@"TestData\UsingFirewall");
17 var build = new Builder(folder, typeof(FirewallExtensionFactory), new[] { folder });
18
19 var results = build.BuildAndQuery(Build, "WixFirewallException");
20 Assert.Equal(new[]
21 {
22 "WixFirewallException:ExampleFirewall\texample\t*\t42\t6\t\t0\t2147483647\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo\tAn example firewall",
23 }, results.OrderBy(s => s).ToArray());
24 }
25
26 private static void Build(string[] args)
27 {
28 var result = WixRunner.Execute(args, out var messages);
29 Assert.Equal(0, result);
30 Assert.Empty(messages);
31 }
32 }
33}
diff --git a/src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/Package.en-us.wxl b/src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/Package.en-us.wxl
new file mode 100644
index 00000000..38c12ac1
--- /dev/null
+++ b/src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/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/test/WixToolsetTest.Firewall/TestData/UsingFirewall/Package.wxs b/src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/Package.wxs
new file mode 100644
index 00000000..68ff98fd
--- /dev/null
+++ b/src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/Package.wxs
@@ -0,0 +1,22 @@
1<?xml version="1.0" encoding="utf-8"?>
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Product Id="*" Name="MsiPackage" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a">
4 <Package InstallerVersion="200" Compressed="no" InstallScope="perMachine" />
5
6 <MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" />
7 <MediaTemplate />
8
9 <Feature Id="ProductFeature" Title="!(loc.FeatureTitle)">
10 <ComponentGroupRef Id="ProductComponents" />
11 </Feature>
12
13 </Product>
14
15 <Fragment>
16 <Directory Id="TARGETDIR" Name="SourceDir">
17 <Directory Id="ProgramFilesFolder">
18 <Directory Id="INSTALLFOLDER" Name="MsiPackage" />
19 </Directory>
20 </Directory>
21 </Fragment>
22</Wix>
diff --git a/src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/PackageComponents.wxs b/src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/PackageComponents.wxs
new file mode 100644
index 00000000..910cca2d
--- /dev/null
+++ b/src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/PackageComponents.wxs
@@ -0,0 +1,14 @@
1<?xml version="1.0" encoding="utf-8"?>
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
3 xmlns:fw="http://wixtoolset.org/schemas/v4/wxs/firewall">
4 <Fragment>
5 <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
6 <Component>
7 <File Source="example.txt" />
8 <fw:FirewallException Id="ExampleFirewall" Description="An example firewall" Name="example" Port="42">
9 <fw:RemoteAddress>*</fw:RemoteAddress>
10 </fw:FirewallException>
11 </Component>
12 </ComponentGroup>
13 </Fragment>
14</Wix>
diff --git a/src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/example.txt b/src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/example.txt
new file mode 100644
index 00000000..1b4ffe8a
--- /dev/null
+++ b/src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/example.txt
@@ -0,0 +1 @@
This is example.txt. \ No newline at end of file
diff --git a/src/test/WixToolsetTest.Firewall/WixToolsetTest.Firewall.csproj b/src/test/WixToolsetTest.Firewall/WixToolsetTest.Firewall.csproj
new file mode 100644
index 00000000..8925cbc7
--- /dev/null
+++ b/src/test/WixToolsetTest.Firewall/WixToolsetTest.Firewall.csproj
@@ -0,0 +1,40 @@
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>netcoreapp2.0</TargetFramework>
7 <IsPackable>false</IsPackable>
8 </PropertyGroup>
9
10 <PropertyGroup>
11 <NoWarn>NU1701</NoWarn>
12 </PropertyGroup>
13
14 <ItemGroup>
15 <Content Include="TestData\UsingFirewall\example.txt" CopyToOutputDirectory="PreserveNewest" />
16 <Content Include="TestData\UsingFirewall\Package.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
17 <Content Include="TestData\UsingFirewall\Package.wxs" CopyToOutputDirectory="PreserveNewest" />
18 <Content Include="TestData\UsingFirewall\PackageComponents.wxs" CopyToOutputDirectory="PreserveNewest" />
19 </ItemGroup>
20
21 <ItemGroup>
22 <ProjectReference Include="..\..\wixext\WixToolset.Firewall.wixext.csproj" />
23 </ItemGroup>
24
25 <ItemGroup>
26 <ProjectReference Include="$(WixToolsetRootFolder)\Core\src\WixToolset.Core.TestPackage\WixToolset.Core.TestPackage.csproj" Condition=" '$(Configuration)' == 'Debug' And Exists('$(WixToolsetRootFolder)\Core\README.md') " />
27 <ProjectReference Include="$(WixToolsetRootFolder)\Core\src\wix\wix.csproj" Condition=" '$(Configuration)' == 'Debug' And Exists('$(WixToolsetRootFolder)\Core\README.md') " />
28 <PackageReference Include="WixToolset.Core.TestPackage" Version="4.0.*" Condition=" '$(Configuration)' == 'Release' Or !Exists('$(WixToolsetRootFolder)\Core\README.md') " PrivateAssets="all" />
29 </ItemGroup>
30
31 <ItemGroup>
32 <PackageReference Include="WixBuildTools.TestSupport" Version="4.0.*" />
33 </ItemGroup>
34
35 <ItemGroup>
36 <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170628-02" />
37 <PackageReference Include="xunit" Version="2.2.0" />
38 <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
39 </ItemGroup>
40</Project>
diff --git a/src/wixext/FirewallCompiler.cs b/src/wixext/FirewallCompiler.cs
new file mode 100644
index 00000000..0696b4b1
--- /dev/null
+++ b/src/wixext/FirewallCompiler.cs
@@ -0,0 +1,356 @@
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.Firewall
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Globalization;
8 using System.Xml.Linq;
9 using WixToolset.Data;
10 using WixToolset.Extensibility;
11
12 /// <summary>
13 /// The compiler for the WiX Toolset Firewall Extension.
14 /// </summary>
15 public sealed class FirewallCompiler : BaseCompilerExtension
16 {
17 public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/firewall";
18
19 /// <summary>
20 /// Processes an element for the Compiler.
21 /// </summary>
22 /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
23 /// <param name="parentElement">Parent element of element to process.</param>
24 /// <param name="element">Element to process.</param>
25 /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param>
26 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
27 {
28 switch (parentElement.Name.LocalName)
29 {
30 case "File":
31 string fileId = context["FileId"];
32 string fileComponentId = context["ComponentId"];
33
34 switch (element.Name.LocalName)
35 {
36 case "FirewallException":
37 this.ParseFirewallExceptionElement(intermediate, section, element, fileComponentId, fileId);
38 break;
39 default:
40 this.ParseHelper.UnexpectedElement(parentElement, element);
41 break;
42 }
43 break;
44 case "Component":
45 string componentId = context["ComponentId"];
46
47 switch (element.Name.LocalName)
48 {
49 case "FirewallException":
50 this.ParseFirewallExceptionElement(intermediate, section, element, componentId, null);
51 break;
52 default:
53 this.ParseHelper.UnexpectedElement(parentElement, element);
54 break;
55 }
56 break;
57 default:
58 this.ParseHelper.UnexpectedElement(parentElement, element);
59 break;
60 }
61 }
62
63 /// <summary>
64 /// Parses a FirewallException element.
65 /// </summary>
66 /// <param name="element">The element to parse.</param>
67 /// <param name="componentId">Identifier of the component that owns this firewall exception.</param>
68 /// <param name="fileId">The file identifier of the parent element (null if nested under Component).</param>
69 private void ParseFirewallExceptionElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string fileId)
70 {
71 SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
72 Identifier id = null;
73 string name = null;
74 int attributes = 0;
75 string file = null;
76 string program = null;
77 string port = null;
78 string protocolValue = null;
79 int? protocol = null;
80 string profileValue = null;
81 int? profile = null;
82 string scope = null;
83 string remoteAddresses = null;
84 string description = null;
85
86 foreach (XAttribute attrib in element.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 "Name":
96 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
97 break;
98 case "File":
99 if (null != fileId)
100 {
101 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, element.Name.LocalName, "File", "File"));
102 }
103 else
104 {
105 file = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
106 }
107 break;
108 case "IgnoreFailure":
109 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
110 {
111 attributes |= 0x1; // feaIgnoreFailures
112 }
113 break;
114 case "Program":
115 if (null != fileId)
116 {
117 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, element.Name.LocalName, "Program", "File"));
118 }
119 else
120 {
121 program = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
122 }
123 break;
124 case "Port":
125 port = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
126 break;
127 case "Protocol":
128 protocolValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
129 switch (protocolValue)
130 {
131 case "tcp":
132 protocol = FirewallConstants.NET_FW_IP_PROTOCOL_TCP;
133 break;
134 case "udp":
135 protocol = FirewallConstants.NET_FW_IP_PROTOCOL_UDP;
136 break;
137 default:
138 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Protocol", protocolValue, "tcp", "udp"));
139 break;
140 }
141 break;
142 case "Scope":
143 scope = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
144 switch (scope)
145 {
146 case "any":
147 remoteAddresses = "*";
148 break;
149 case "localSubnet":
150 remoteAddresses = "LocalSubnet";
151 break;
152 default:
153 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Scope", scope, "any", "localSubnet"));
154 break;
155 }
156 break;
157 case "Profile":
158 profileValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
159 switch (profileValue)
160 {
161 case "domain":
162 profile = FirewallConstants.NET_FW_PROFILE2_DOMAIN;
163 break;
164 case "private":
165 profile = FirewallConstants.NET_FW_PROFILE2_PRIVATE;
166 break;
167 case "public":
168 profile = FirewallConstants.NET_FW_PROFILE2_PUBLIC;
169 break;
170 case "all":
171 profile = FirewallConstants.NET_FW_PROFILE2_ALL;
172 break;
173 default:
174 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Profile", profileValue, "domain", "private", "public", "all"));
175 break;
176 }
177 break;
178 case "Description":
179 description = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
180 break;
181 default:
182 this.ParseHelper.UnexpectedAttribute(element, attrib);
183 break;
184 }
185 }
186 else
187 {
188 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
189 }
190 }
191
192 // parse RemoteAddress children
193 foreach (XElement child in element.Elements())
194 {
195 if (this.Namespace == child.Name.Namespace)
196 {
197 SourceLineNumber childSourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(child);
198 switch (child.Name.LocalName)
199 {
200 case "RemoteAddress":
201 if (null != scope)
202 {
203 this.Messaging.Write(FirewallErrors.IllegalRemoteAddressWithScopeAttribute(sourceLineNumbers));
204 }
205 else
206 {
207 this.ParseRemoteAddressElement(intermediate, section, child, ref remoteAddresses);
208 }
209 break;
210 default:
211 this.ParseHelper.UnexpectedElement(element, child);
212 break;
213 }
214 }
215 else
216 {
217 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, element, child);
218 }
219 }
220
221 // Id and Name are required
222 if (null == id)
223 {
224 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id"));
225 }
226
227 if (null == name)
228 {
229 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name"));
230 }
231
232 // Scope or child RemoteAddress(es) are required
233 if (null == remoteAddresses)
234 {
235 this.Messaging.Write(ErrorMessages.ExpectedAttributeOrElement(sourceLineNumbers, element.Name.LocalName, "Scope", "RemoteAddress"));
236 }
237
238 // can't have both Program and File
239 if (null != program && null != file)
240 {
241 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "File", "Program"));
242 }
243
244 // must be nested under File, have File or Program attributes, or have Port attribute
245 if (String.IsNullOrEmpty(fileId) && String.IsNullOrEmpty(file) && String.IsNullOrEmpty(program) && String.IsNullOrEmpty(port))
246 {
247 this.Messaging.Write(FirewallErrors.NoExceptionSpecified(sourceLineNumbers));
248 }
249
250 if (!this.Messaging.EncounteredError)
251 {
252 // at this point, File attribute and File parent element are treated the same
253 if (null != file)
254 {
255 fileId = file;
256 }
257
258 var row = this.ParseHelper.CreateRow(section, sourceLineNumbers, "WixFirewallException", id);
259 row.Set(1, name);
260 row.Set(2, remoteAddresses);
261
262 if (!String.IsNullOrEmpty(port))
263 {
264 row.Set(3, port);
265
266 if (!protocol.HasValue)
267 {
268 // default protocol is "TCP"
269 protocol = FirewallConstants.NET_FW_IP_PROTOCOL_TCP;
270 }
271 }
272
273 if (protocol.HasValue)
274 {
275 row.Set(4, protocol);
276 }
277
278 if (!String.IsNullOrEmpty(fileId))
279 {
280 row.Set(5, $"[#{fileId}]");
281 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "File", fileId);
282 }
283 else if (!String.IsNullOrEmpty(program))
284 {
285 row.Set(5, program);
286 }
287
288 if (CompilerConstants.IntegerNotSet != attributes)
289 {
290 row.Set(6, attributes);
291 }
292
293 // Default is "all"
294 row.Set(7, profile ?? FirewallConstants.NET_FW_PROFILE2_ALL);
295
296 row.Set(8, componentId);
297
298 row.Set(9, description);
299
300 if (this.Context.Platform == Platform.ARM)
301 {
302 // Ensure ARM version of the CA is referenced
303 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixSchedFirewallExceptionsInstall_ARM");
304 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixSchedFirewallExceptionsUninstall_ARM");
305 }
306 else
307 {
308 // All other supported platforms use x86
309 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixSchedFirewallExceptionsInstall");
310 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixSchedFirewallExceptionsUninstall");
311 }
312 }
313 }
314
315 /// <summary>
316 /// Parses a RemoteAddress element
317 /// </summary>
318 /// <param name="element">The element to parse.</param>
319 private void ParseRemoteAddressElement(Intermediate intermediate, IntermediateSection section, XElement element, ref string remoteAddresses)
320 {
321 SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
322
323 // no attributes
324 foreach (XAttribute attrib in element.Attributes())
325 {
326 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
327 {
328 this.ParseHelper.UnexpectedAttribute(element, attrib);
329 }
330 else
331 {
332 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
333 }
334 }
335
336 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
337
338 string address = this.ParseHelper.GetTrimmedInnerText(element);
339 if (String.IsNullOrEmpty(address))
340 {
341 this.Messaging.Write(FirewallErrors.IllegalEmptyRemoteAddress(sourceLineNumbers));
342 }
343 else
344 {
345 if (String.IsNullOrEmpty(remoteAddresses))
346 {
347 remoteAddresses = address;
348 }
349 else
350 {
351 remoteAddresses = String.Concat(remoteAddresses, ",", address);
352 }
353 }
354 }
355 }
356}
diff --git a/src/wixext/FirewallConstants.cs b/src/wixext/FirewallConstants.cs
new file mode 100644
index 00000000..16caa5b4
--- /dev/null
+++ b/src/wixext/FirewallConstants.cs
@@ -0,0 +1,21 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Firewall
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Text;
8
9 static class FirewallConstants
10 {
11 // from icftypes.h
12 public const int NET_FW_IP_PROTOCOL_TCP = 6;
13 public const int NET_FW_IP_PROTOCOL_UDP = 17;
14
15 // from icftypes.h
16 public const int NET_FW_PROFILE2_DOMAIN = 0x0001;
17 public const int NET_FW_PROFILE2_PRIVATE = 0x0002;
18 public const int NET_FW_PROFILE2_PUBLIC = 0x0004;
19 public const int NET_FW_PROFILE2_ALL = 0x7FFFFFFF;
20 }
21}
diff --git a/src/wixext/FirewallDecompiler.cs b/src/wixext/FirewallDecompiler.cs
new file mode 100644
index 00000000..b060f8e2
--- /dev/null
+++ b/src/wixext/FirewallDecompiler.cs
@@ -0,0 +1,169 @@
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.Firewall
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 Firewall = WixToolset.Extensions.Serialize.Firewall;
13 using Wix = WixToolset.Data.Serialize;
14
15 /// <summary>
16 /// The decompiler for the WiX Toolset Firewall Extension.
17 /// </summary>
18 public sealed class FirewallDecompiler : DecompilerExtension
19 {
20 /// <summary>
21 /// Creates a decompiler for Firewall Extension.
22 /// </summary>
23 public FirewallDecompiler()
24 {
25 this.TableDefinitions = FirewallExtensionData.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 FirewallExtensionData.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 "WixFirewallException":
47 this.DecompileWixFirewallExceptionTable(table);
48 break;
49 default:
50 base.DecompileTable(table);
51 break;
52 }
53 }
54
55 /// <summary>
56 /// Decompile the WixFirewallException table.
57 /// </summary>
58 /// <param name="table">The table to decompile.</param>
59 private void DecompileWixFirewallExceptionTable(Table table)
60 {
61 foreach (Row row in table.Rows)
62 {
63 Firewall.FirewallException fire = new Firewall.FirewallException();
64 fire.Id = (string)row[0];
65 fire.Name = (string)row[1];
66
67 string[] addresses = ((string)row[2]).Split(',');
68 if (1 == addresses.Length)
69 {
70 // special-case the Scope attribute values
71 if ("*" == addresses[0])
72 {
73 fire.Scope = Firewall.FirewallException.ScopeType.any;
74 }
75 else if ("LocalSubnet" == addresses[0])
76 {
77 fire.Scope = Firewall.FirewallException.ScopeType.localSubnet;
78 }
79 else
80 {
81 FirewallDecompiler.AddRemoteAddress(fire, addresses[0]);
82 }
83 }
84 else
85 {
86 foreach (string address in addresses)
87 {
88 FirewallDecompiler.AddRemoteAddress(fire, address);
89 }
90 }
91
92 if (!row.IsColumnEmpty(3))
93 {
94 fire.Port = (string)row[3];
95 }
96
97 if (!row.IsColumnEmpty(4))
98 {
99 switch (Convert.ToInt32(row[4]))
100 {
101 case FirewallConstants.NET_FW_IP_PROTOCOL_TCP:
102 fire.Protocol = Firewall.FirewallException.ProtocolType.tcp;
103 break;
104 case FirewallConstants.NET_FW_IP_PROTOCOL_UDP:
105 fire.Protocol = Firewall.FirewallException.ProtocolType.udp;
106 break;
107 }
108 }
109
110 if (!row.IsColumnEmpty(5))
111 {
112 fire.Program = (string)row[5];
113 }
114
115 if (!row.IsColumnEmpty(6))
116 {
117 int attr = Convert.ToInt32(row[6]);
118 if (0x1 == (attr & 0x1)) // feaIgnoreFailures
119 {
120 fire.IgnoreFailure = Firewall.YesNoType.yes;
121 }
122 }
123
124 if (!row.IsColumnEmpty(7))
125 {
126 switch (Convert.ToInt32(row[7]))
127 {
128 case FirewallConstants.NET_FW_PROFILE2_DOMAIN:
129 fire.Profile = Firewall.FirewallException.ProfileType.domain;
130 break;
131 case FirewallConstants.NET_FW_PROFILE2_PRIVATE:
132 fire.Profile = Firewall.FirewallException.ProfileType.@private;
133 break;
134 case FirewallConstants.NET_FW_PROFILE2_PUBLIC:
135 fire.Profile = Firewall.FirewallException.ProfileType.@public;
136 break;
137 case FirewallConstants.NET_FW_PROFILE2_ALL:
138 fire.Profile = Firewall.FirewallException.ProfileType.all;
139 break;
140 }
141 }
142
143 // Description column is new in v3.6
144 if (9 < row.Fields.Length && !row.IsColumnEmpty(9))
145 {
146 fire.Description = (string)row[9];
147 }
148
149 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[8]);
150 if (null != component)
151 {
152 component.AddChild(fire);
153 }
154 else
155 {
156 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[6], "Component"));
157 }
158 }
159 }
160
161 private static void AddRemoteAddress(Firewall.FirewallException fire, string address)
162 {
163 Firewall.RemoteAddress remote = new Firewall.RemoteAddress();
164 remote.Content = address;
165 fire.AddChild(remote);
166 }
167 }
168#endif
169}
diff --git a/src/wixext/FirewallErrors.cs b/src/wixext/FirewallErrors.cs
new file mode 100644
index 00000000..3fff8c8d
--- /dev/null
+++ b/src/wixext/FirewallErrors.cs
@@ -0,0 +1,42 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Firewall
4{
5 using System.Resources;
6 using WixToolset.Data;
7
8 public static class FirewallErrors
9 {
10 public static Message IllegalRemoteAddressWithScopeAttribute(SourceLineNumber sourceLineNumbers)
11 {
12 return Message(sourceLineNumbers, Ids.IllegalRemoteAddressWithScopeAttribute, "The RemoteAddress element cannot be specified because its parent FirewallException already specified the Scope attribute. To use RemoteAddress elements, omit the Scope attribute.");
13 }
14
15 public static Message IllegalEmptyRemoteAddress(SourceLineNumber sourceLineNumbers)
16 {
17 return Message(sourceLineNumbers, Ids.IllegalEmptyRemoteAddress, "The RemoteAddress element's inner text cannot be an empty string or completely whitespace.");
18 }
19
20 public static Message NoExceptionSpecified(SourceLineNumber sourceLineNumbers)
21 {
22 return Message(sourceLineNumbers, Ids.NoExceptionSpecified, "The FirewallException element doesn't identify the target of the firewall exception. To create an application exception, nest the FirewallException element under a File element or provide a value for the File or Program attributes. To create a port exception, provide a value for the Port attribute.");
23 }
24
25 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args)
26 {
27 return new Message(sourceLineNumber, MessageLevel.Error, (int)id, format, args);
28 }
29
30 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, ResourceManager resourceManager, string resourceName, params object[] args)
31 {
32 return new Message(sourceLineNumber, MessageLevel.Error, (int)id, resourceManager, resourceName, args);
33 }
34
35 public enum Ids
36 {
37 IllegalRemoteAddressWithScopeAttribute = 6401,
38 IllegalEmptyRemoteAddress = 6402,
39 NoExceptionSpecified = 6403,
40 }
41 }
42}
diff --git a/src/wixext/FirewallExtensionData.cs b/src/wixext/FirewallExtensionData.cs
new file mode 100644
index 00000000..78939c4e
--- /dev/null
+++ b/src/wixext/FirewallExtensionData.cs
@@ -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
3namespace WixToolset.Firewall
4{
5 using WixToolset.Data;
6 using WixToolset.Extensibility;
7 using WixToolset.Firewall.Tuples;
8
9 public sealed class FirewallExtensionData : BaseExtensionData
10 {
11 public override string DefaultCulture => "en-US";
12
13 public override bool TryGetTupleDefinitionByName(string name, out IntermediateTupleDefinition tupleDefinition)
14 {
15 tupleDefinition = (name == FirewallTupleDefinitionNames.WixFirewallException) ? FirewallTupleDefinitions.WixFirewallException : null;
16 return tupleDefinition != null;
17 }
18
19 public override Intermediate GetLibrary(ITupleDefinitionCreator tupleDefinitions)
20 {
21 return Intermediate.Load(typeof(FirewallExtensionData).Assembly, "WixToolset.Firewall.firewall.wixlib", tupleDefinitions);
22 }
23 }
24}
diff --git a/src/wixext/FirewallExtensionFactory.cs b/src/wixext/FirewallExtensionFactory.cs
new file mode 100644
index 00000000..4594419d
--- /dev/null
+++ b/src/wixext/FirewallExtensionFactory.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.Firewall
4{
5 using System;
6 using System.Collections.Generic;
7 using WixToolset.Extensibility;
8
9 public class FirewallExtensionFactory : BaseExtensionFactory
10 {
11 protected override IEnumerable<Type> ExtensionTypes => new[]
12 {
13 typeof(FirewallCompiler),
14 typeof(FirewallExtensionData),
15 typeof(FirewallWindowsInstallerBackendExtension),
16 };
17 }
18}
diff --git a/src/wixext/FirewallWindowsInstallerBackendExtension.cs b/src/wixext/FirewallWindowsInstallerBackendExtension.cs
new file mode 100644
index 00000000..a1c78f04
--- /dev/null
+++ b/src/wixext/FirewallWindowsInstallerBackendExtension.cs
@@ -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
3namespace WixToolset.Firewall
4{
5 using System.Linq;
6 using System.Xml;
7 using WixToolset.Data.WindowsInstaller;
8 using WixToolset.Extensibility;
9
10 public class FirewallWindowsInstallerBackendExtension : BaseWindowsInstallerBackendExtension
11 {
12 private static readonly TableDefinition[] Tables = LoadTables();
13
14 protected override TableDefinition[] TableDefinitionsForTuples => Tables;
15
16 private static TableDefinition[] LoadTables()
17 {
18 using (var resourceStream = typeof(FirewallWindowsInstallerBackendExtension).Assembly.GetManifestResourceStream("WixToolset.Firewall.tables.xml"))
19 using (var reader = XmlReader.Create(resourceStream))
20 {
21 var tables = TableDefinitionCollection.Load(reader);
22 return tables.ToArray();
23 }
24 }
25 }
26}
diff --git a/src/wixext/Tuples/FirewallTupleDefinitions.cs b/src/wixext/Tuples/FirewallTupleDefinitions.cs
new file mode 100644
index 00000000..79fc28cf
--- /dev/null
+++ b/src/wixext/Tuples/FirewallTupleDefinitions.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.Firewall.Tuples
4{
5 using WixToolset.Data;
6
7 public static class FirewallTupleDefinitionNames
8 {
9 public static string WixFirewallException { get; } = "WixFirewallException";
10 }
11
12 public static partial class FirewallTupleDefinitions
13 {
14 public static readonly IntermediateTupleDefinition WixFirewallException = new IntermediateTupleDefinition(
15 FirewallTupleDefinitionNames.WixFirewallException,
16 new[]
17 {
18 new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.WixFirewallException), IntermediateFieldType.String),
19 new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Name), IntermediateFieldType.String),
20 new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.RemoteAddresses), IntermediateFieldType.String),
21 new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Port), IntermediateFieldType.String),
22 new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Protocol), IntermediateFieldType.Number),
23 new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Program), IntermediateFieldType.String),
24 new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Attributes), IntermediateFieldType.Number),
25 new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Profile), IntermediateFieldType.Number),
26 new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Component_), IntermediateFieldType.String),
27 new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Description), IntermediateFieldType.String),
28 },
29 typeof(WixFirewallExceptionTuple));
30 }
31}
diff --git a/src/wixext/Tuples/WixFirewallExceptionTuple.cs b/src/wixext/Tuples/WixFirewallExceptionTuple.cs
new file mode 100644
index 00000000..715a4b9b
--- /dev/null
+++ b/src/wixext/Tuples/WixFirewallExceptionTuple.cs
@@ -0,0 +1,93 @@
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.Firewall.Tuples
4{
5 using WixToolset.Data;
6
7 public enum WixFirewallExceptionTupleFields
8 {
9 WixFirewallException,
10 Name,
11 RemoteAddresses,
12 Port,
13 Protocol,
14 Program,
15 Attributes,
16 Profile,
17 Component_,
18 Description,
19 }
20
21 public class WixFirewallExceptionTuple : IntermediateTuple
22 {
23 public WixFirewallExceptionTuple() : base(FirewallTupleDefinitions.WixFirewallException, null, null)
24 {
25 }
26
27 public WixFirewallExceptionTuple(SourceLineNumber sourceLineNumber, Identifier id = null) : base(FirewallTupleDefinitions.WixFirewallException, sourceLineNumber, id)
28 {
29 }
30
31 public IntermediateField this[WixFirewallExceptionTupleFields index] => this.Fields[(int)index];
32
33 public string WixFirewallException
34 {
35 get => this.Fields[(int)WixFirewallExceptionTupleFields.WixFirewallException].AsString();
36 set => this.Set((int)WixFirewallExceptionTupleFields.WixFirewallException, value);
37 }
38
39 public string Name
40 {
41 get => this.Fields[(int)WixFirewallExceptionTupleFields.Name].AsString();
42 set => this.Set((int)WixFirewallExceptionTupleFields.Name, value);
43 }
44
45 public string RemoteAddresses
46 {
47 get => this.Fields[(int)WixFirewallExceptionTupleFields.RemoteAddresses].AsString();
48 set => this.Set((int)WixFirewallExceptionTupleFields.RemoteAddresses, value);
49 }
50
51 public string Port
52 {
53 get => this.Fields[(int)WixFirewallExceptionTupleFields.Port].AsString();
54 set => this.Set((int)WixFirewallExceptionTupleFields.Port, value);
55 }
56
57 public int Protocol
58 {
59 get => this.Fields[(int)WixFirewallExceptionTupleFields.Protocol].AsNumber();
60 set => this.Set((int)WixFirewallExceptionTupleFields.Protocol, value);
61 }
62
63 public string Program
64 {
65 get => this.Fields[(int)WixFirewallExceptionTupleFields.Program].AsString();
66 set => this.Set((int)WixFirewallExceptionTupleFields.Program, value);
67 }
68
69 public int Attributes
70 {
71 get => this.Fields[(int)WixFirewallExceptionTupleFields.Attributes].AsNumber();
72 set => this.Set((int)WixFirewallExceptionTupleFields.Attributes, value);
73 }
74
75 public int Profile
76 {
77 get => this.Fields[(int)WixFirewallExceptionTupleFields.Profile].AsNumber();
78 set => this.Set((int)WixFirewallExceptionTupleFields.Profile, value);
79 }
80
81 public string Component_
82 {
83 get => this.Fields[(int)WixFirewallExceptionTupleFields.Component_].AsString();
84 set => this.Set((int)WixFirewallExceptionTupleFields.Component_, value);
85 }
86
87 public string Description
88 {
89 get => this.Fields[(int)WixFirewallExceptionTupleFields.Description].AsString();
90 set => this.Set((int)WixFirewallExceptionTupleFields.Description, value);
91 }
92 }
93} \ No newline at end of file
diff --git a/src/wixext/WixToolset.Firewall.wixext.csproj b/src/wixext/WixToolset.Firewall.wixext.csproj
new file mode 100644
index 00000000..2d89911c
--- /dev/null
+++ b/src/wixext/WixToolset.Firewall.wixext.csproj
@@ -0,0 +1,36 @@
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.Firewall</RootNamespace>
8 <Description>WiX Toolset Firewallity Extension</Description>
9 <Title>WiX Toolset Firewall Extension</Title>
10 <IsTool>true</IsTool>
11 <ContentTargetFolders>build</ContentTargetFolders>
12 </PropertyGroup>
13
14 <ItemGroup>
15 <Content Include="$(MSBuildThisFileName).targets" />
16 <Content Include="firewall.xsd" PackagePath="tools" />
17 <EmbeddedResource Include="tables.xml" />
18 <EmbeddedResource Include="$(OutputPath)..\firewall.wixlib" />
19 </ItemGroup>
20
21 <ItemGroup>
22 <ProjectReference Include="$(WixToolsetRootFolder)\Data\src\WixToolset.Data\WixToolset.Data.csproj" Condition=" '$(Configuration)' == 'Debug' And Exists('$(WixToolsetRootFolder)\Data\README.md') " />
23 <PackageReference Include="WixToolset.Data" Version="4.0.*" Condition=" '$(Configuration)' == 'Release' Or !Exists('$(WixToolsetRootFolder)\Data\README.md') " PrivateAssets="all" />
24
25 <ProjectReference Include="$(WixToolsetRootFolder)\Extensibility\src\WixToolset.Extensibility\WixToolset.Extensibility.csproj" Condition=" '$(Configuration)' == 'Debug' And Exists('$(WixToolsetRootFolder)\Extensibility\README.md') " />
26 <PackageReference Include="WixToolset.Extensibility" Version="4.0.*" Condition=" '$(Configuration)' == 'Release' Or !Exists('$(WixToolsetRootFolder)\Extensibility\README.md') " PrivateAssets="all" />
27 </ItemGroup>
28
29 <ItemGroup>
30 <ProjectReference Include="..\wixlib\firewall.wixproj" ReferenceOutputAssembly="false" />
31 </ItemGroup>
32
33 <ItemGroup>
34 <PackageReference Include="Nerdbank.GitVersioning" Version="2.1.7" PrivateAssets="all" />
35 </ItemGroup>
36</Project>
diff --git a/src/wixext/WixToolset.Firewall.wixext.targets b/src/wixext/WixToolset.Firewall.wixext.targets
new file mode 100644
index 00000000..c717450f
--- /dev/null
+++ b/src/wixext/WixToolset.Firewall.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 <WixToolsetFirewallWixextPath Condition=" '$(WixToolsetFirewallWixextPath)' == '' ">$(MSBuildThisFileDirectory)..\tools\WixToolset.Firewall.wixext.dll</WixToolsetFirewallWixextPath>
7 </PropertyGroup>
8 <ItemGroup>
9 <WixExtension Include="$(WixToolsetFirewallWixextPath)" />
10 </ItemGroup>
11</Project>
diff --git a/src/wixext/firewall.xsd b/src/wixext/firewall.xsd
new file mode 100644
index 00000000..d64aafef
--- /dev/null
+++ b/src/wixext/firewall.xsd
@@ -0,0 +1,211 @@
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
5<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
6 xmlns:xse=" http://wixtoolset.org/schemas/XmlSchemaExtension"
7 xmlns:html="http://www.w3.org/1999/xhtml"
8 targetNamespace="http://wixtoolset.org/schemas/v4/wxs/firewall"
9 xmlns="http://wixtoolset.org/schemas/v4/wxs/firewall">
10 <xs:annotation>
11 <xs:documentation>
12 The source code schema for the WiX Toolset Firewall Extension.
13 </xs:documentation>
14 </xs:annotation>
15
16 <xs:import namespace="http://wixtoolset.org/schemas/v4/wxs" />
17
18 <xs:element name="FirewallException">
19 <xs:annotation>
20 <xs:documentation>
21 Registers an exception for a program or a specific port and protocol in the Windows Firewall
22 on Windows XP SP2, Windows Server 2003 SP1, and later. For more information about the Windows
23 Firewall, see <html:a href="http://msdn.microsoft.com/en-us/library/aa364679.aspx">
24 About Windows Firewall API</html:a>.
25 </xs:documentation>
26 <xs:appinfo>
27 <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
28 <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="File" />
29 </xs:appinfo>
30 </xs:annotation>
31
32 <xs:complexType>
33 <xs:choice minOccurs="0" maxOccurs="unbounded">
34 <xs:annotation>
35 <xs:documentation>
36 Explicitly-listed remote addresses that this exception allows through the
37 firewall.
38 </xs:documentation>
39 </xs:annotation>
40 <xs:element ref="RemoteAddress" />
41 </xs:choice>
42
43 <xs:attribute name="Id" type="xs:string" use="required">
44 <xs:annotation>
45 <xs:documentation>
46 Unique ID of this firewall exception.
47 </xs:documentation>
48 </xs:annotation>
49 </xs:attribute>
50
51 <xs:attribute name="Name" type="xs:string" use="required">
52 <xs:annotation>
53 <xs:documentation>
54 Name of this firewall exception, visible to the user in the firewall
55 control panel.
56 </xs:documentation>
57 </xs:annotation>
58 </xs:attribute>
59
60 <xs:attribute name="Scope">
61 <xs:annotation>
62 <xs:documentation>
63 The scope of this firewall exception, which indicates whether incoming
64 connections can come from any computer including those on the Internet
65 or only those on the local network subnet. To more precisely specify
66 allowed remote address, specify a custom scope using RemoteAddress
67 child elements.
68 </xs:documentation>
69 </xs:annotation>
70 <xs:simpleType>
71 <xs:restriction base="xs:NMTOKEN">
72 <xs:enumeration value="any" />
73 <xs:enumeration value="localSubnet" />
74 </xs:restriction>
75 </xs:simpleType>
76 </xs:attribute>
77
78 <xs:attribute name="Port" type="xs:string">
79 <xs:annotation>
80 <xs:documentation>
81 Port to allow through the firewall for this exception.
82
83 If you use Port and also File or Program in the same
84 FirewallException element, the exception will fail to install on
85 Windows XP and Windows Server 2003. IgnoreFailure="yes" can be used to
86 ignore the resulting failure, but the exception will not be added.
87 </xs:documentation>
88 </xs:annotation>
89 </xs:attribute>
90
91 <xs:attribute name="Protocol">
92 <xs:annotation>
93 <xs:documentation>
94 IP protocol used for this firewall exception. If Port is defined,
95 "tcp" is assumed if the protocol is not specified.
96
97 If you use Protocol and also File or Program in the same
98 FirewallException element, the exception will fail to install on
99 Windows XP and Windows Server 2003. IgnoreFailure="yes" can be used to
100 ignore the resulting failure, but the exception will not be added.
101 </xs:documentation>
102 </xs:annotation>
103 <xs:simpleType>
104 <xs:restriction base="xs:NMTOKEN">
105 <xs:enumeration value="tcp" />
106 <xs:enumeration value="udp" />
107 </xs:restriction>
108 </xs:simpleType>
109 </xs:attribute>
110
111 <xs:attribute name="File" type="xs:string">
112 <xs:annotation>
113 <xs:documentation>
114 Identifier of a file to be granted access to all incoming ports and
115 protocols. If you use File, you cannot also use Program.
116
117 If you use File and also Port or Protocol in the same
118 FirewallException element, the exception will fail to install on
119 Windows XP and Windows Server 2003. IgnoreFailure="yes" can be used to
120 ignore the resulting failure, but the exception will not be added.
121 </xs:documentation>
122 </xs:annotation>
123 </xs:attribute>
124
125 <xs:attribute name="Program" type="xs:string">
126 <xs:annotation>
127 <xs:documentation>
128 Path to a target program to be granted access to all incoming ports and
129 protocols. Note that this is a formatted field, so you can use [#fileId]
130 syntax to refer to a file being installed. If you use Program, you cannot
131 also use File.
132
133 If you use Program and also Port or Protocol in the same
134 FirewallException element, the exception will fail to install on
135 Windows XP and Windows Server 2003. IgnoreFailure="yes" can be used to
136 ignore the resulting failure, but the exception will not be added.
137 </xs:documentation>
138 </xs:annotation>
139 </xs:attribute>
140
141 <xs:attribute name="IgnoreFailure" type="YesNoType">
142 <xs:annotation>
143 <xs:documentation>
144 If "yes," failures to register this firewall exception will be silently
145 ignored. If "no" (the default), failures will cause rollback.
146 </xs:documentation>
147 </xs:annotation>
148 </xs:attribute>
149
150 <xs:attribute name="Profile">
151 <xs:annotation>
152 <xs:documentation>
153 Profile type for this firewall exception. Default is "all".
154 </xs:documentation>
155 </xs:annotation>
156 <xs:simpleType>
157 <xs:restriction base="xs:NMTOKEN">
158 <xs:enumeration value="domain" />
159 <xs:enumeration value="private" />
160 <xs:enumeration value="public" />
161 <xs:enumeration value="all" />
162 </xs:restriction>
163 </xs:simpleType>
164 </xs:attribute>
165 <xs:attribute name="Description" type="xs:string">
166 <xs:annotation>
167 <xs:documentation>
168 Description for this firewall rule displayed in Windows Firewall manager in
169 Windows Vista and later.
170 </xs:documentation>
171 </xs:annotation>
172 </xs:attribute>
173 </xs:complexType>
174 </xs:element>
175
176 <xs:element name="RemoteAddress">
177 <xs:annotation>
178 <xs:documentation>
179 A remote address to which the port or program can listen. Address formats vary
180 based on the version of Windows and Windows Firewall the program is being installed
181 on. For Windows XP SP2 and Windows Server 2003 SP1, see
182 <html:a href="http://msdn.microsoft.com/en-us/library/aa365270.aspx">
183 RemoteAddresses Property</html:a>.
184 For Windows Vista and Windows Server 2008, see
185 <html:a href="http://msdn.microsoft.com/en-us/library/aa365366.aspx">
186 RemoteAddresses Property</html:a>.
187 </xs:documentation>
188 </xs:annotation>
189 <xs:complexType>
190 <xs:simpleContent>
191 <xs:extension base="xs:string">
192 <xs:annotation>
193 <xs:documentation>
194 A remote address.
195 </xs:documentation>
196 </xs:annotation>
197 </xs:extension>
198 </xs:simpleContent>
199 </xs:complexType>
200 </xs:element>
201
202 <xs:simpleType name="YesNoType">
203 <xs:annotation>
204 <xs:documentation>Values of this type will either be "yes" or "no".</xs:documentation>
205 </xs:annotation>
206 <xs:restriction base='xs:NMTOKEN'>
207 <xs:enumeration value="no"/>
208 <xs:enumeration value="yes"/>
209 </xs:restriction>
210 </xs:simpleType>
211</xs:schema>
diff --git a/src/wixext/tables.xml b/src/wixext/tables.xml
new file mode 100644
index 00000000..5b408b96
--- /dev/null
+++ b/src/wixext/tables.xml
@@ -0,0 +1,28 @@
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
5<tableDefinitions xmlns="http://wixtoolset.org/schemas/v4/wi/tables">
6 <tableDefinition name="WixFirewallException">
7 <columnDefinition name="WixFirewallException" type="string" length="72" primaryKey="yes" modularize="column"
8 category="identifier" description="The primary key, a non-localized token." />
9 <columnDefinition name="Name" type="localized" length="255" nullable="yes" modularize="property"
10 category="formatted" description="Localizable display name." />
11 <columnDefinition name="RemoteAddresses" type="string" length="0" modularize="property"
12 category="formatted" description="Remote address to accept incoming connections from." />
13 <columnDefinition name="Port" type="string" length="0" modularize="property" nullable="yes"
14 category="formatted" minValue="1" description="Port number." />
15 <columnDefinition name="Protocol" type="number" length="1" nullable="yes"
16 category="integer" minValue="6" maxValue="17" description="Protocol (6=TCP; 17=UDP)." />
17 <columnDefinition name="Program" type="string" length="255" nullable="yes" modularize="property"
18 category="formatted" description="Exception for a program (formatted path name)." />
19 <columnDefinition name="Attributes" type="number" length="4" nullable="yes"
20 minValue="0" maxValue="65536" description="Vital=1" />
21 <columnDefinition name="Profile" type="number" length="4" nullable="no"
22 category="integer" minValue="1" maxValue="2147483647" description="Profile (1=domain; 2=private; 4=public; 2147483647=all)." />
23 <columnDefinition name="Component_" type="string" length="72" modularize="column"
24 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key into the Component table referencing component that controls the firewall configuration."/>
25 <columnDefinition name="Description" type="string" length="255" nullable="yes"
26 category="formatted" description="Description displayed in Windows Firewall manager for this firewall rule."/>
27 </tableDefinition>
28</tableDefinitions>
diff --git a/src/wixlib/FirewallExtension.wxs b/src/wixlib/FirewallExtension.wxs
new file mode 100644
index 00000000..271469e4
--- /dev/null
+++ b/src/wixlib/FirewallExtension.wxs
@@ -0,0 +1,12 @@
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
5<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
6 <?include caerr.wxi ?>
7 <Fragment>
8 <UI Id="WixFirewallErrors">
9 <Error Id="$(var.msierrFirewallCannotConnect)">!(loc.msierrFirewallCannotConnect)</Error>
10 </UI>
11 </Fragment>
12</Wix>
diff --git a/src/wixlib/FirewallExtension_Platform.wxi b/src/wixlib/FirewallExtension_Platform.wxi
new file mode 100644
index 00000000..263651d2
--- /dev/null
+++ b/src/wixlib/FirewallExtension_Platform.wxi
@@ -0,0 +1,41 @@
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<Include xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <?include caSuffix.wxi ?>
6 <Fragment>
7 <UIRef Id="WixFirewallErrors" />
8 <UI>
9 <ProgressText Action="WixSchedFirewallExceptionsInstall$(var.Suffix)">!(loc.WixSchedFirewallExceptionsInstall)</ProgressText>
10 <ProgressText Action="WixSchedFirewallExceptionsUninstall$(var.Suffix)">!(loc.WixSchedFirewallExceptionsUninstall)</ProgressText>
11 <ProgressText Action="WixRollbackFirewallExceptionsInstall$(var.DeferredSuffix)">!(loc.WixRollbackFirewallExceptionsInstall)</ProgressText>
12 <ProgressText Action="WixExecFirewallExceptionsInstall$(var.DeferredSuffix)">!(loc.WixExecFirewallExceptionsInstall)</ProgressText>
13 <ProgressText Action="WixRollbackFirewallExceptionsUninstall$(var.DeferredSuffix)">!(loc.WixRollbackFirewallExceptionsUninstall)</ProgressText>
14 <ProgressText Action="WixExecFirewallExceptionsUninstall$(var.DeferredSuffix)">!(loc.WixExecFirewallExceptionsUninstall)</ProgressText>
15 </UI>
16
17 <CustomAction Id="WixSchedFirewallExceptionsInstall$(var.Suffix)" BinaryKey="WixFirewallCA$(var.Suffix)" DllEntry="SchedFirewallExceptionsInstall" Execute="immediate" Return="check" SuppressModularization="yes" />
18 <CustomAction Id="WixSchedFirewallExceptionsUninstall$(var.Suffix)" BinaryKey="WixFirewallCA$(var.Suffix)" DllEntry="SchedFirewallExceptionsUninstall" Execute="immediate" Return="check" SuppressModularization="yes" />
19 <CustomAction Id="WixRollbackFirewallExceptionsInstall$(var.DeferredSuffix)" BinaryKey="WixFirewallCA$(var.Suffix)" DllEntry="ExecFirewallExceptions" Execute="rollback" Impersonate="no" Return="check" SuppressModularization="yes" />
20 <CustomAction Id="WixExecFirewallExceptionsInstall$(var.DeferredSuffix)" BinaryKey="WixFirewallCA$(var.Suffix)" DllEntry="ExecFirewallExceptions" Execute="deferred" Impersonate="no" Return="check" SuppressModularization="yes" />
21 <CustomAction Id="WixRollbackFirewallExceptionsUninstall$(var.DeferredSuffix)" BinaryKey="WixFirewallCA$(var.Suffix)" DllEntry="ExecFirewallExceptions" Execute="rollback" Impersonate="no" Return="check" SuppressModularization="yes" />
22 <CustomAction Id="WixExecFirewallExceptionsUninstall$(var.DeferredSuffix)" BinaryKey="WixFirewallCA$(var.Suffix)" DllEntry="ExecFirewallExceptions" Execute="deferred" Impersonate="no" Return="check" SuppressModularization="yes" />
23
24 <!--
25 We need the firewall on Windows XP SP2 or later.
26 -->
27 <InstallExecuteSequence>
28 <Custom Action="WixSchedFirewallExceptionsUninstall$(var.Suffix)" Before="RemoveFiles" Overridable="yes">
29 <![CDATA[ VersionNT >= 600 OR (VersionNT >= 501 AND ((MsiNTProductType = 1 AND ServicePackLevel >= 2) OR (MsiNTProductType > 1 AND ServicePackLevel >= 1))) ]]>
30 </Custom>
31 <Custom Action="WixSchedFirewallExceptionsInstall$(var.Suffix)" After="InstallFiles" Overridable="yes">
32 <![CDATA[ VersionNT >= 600 OR (VersionNT >= 501 AND ((MsiNTProductType = 1 AND ServicePackLevel >= 2) OR (MsiNTProductType > 1 AND ServicePackLevel >= 1))) ]]>
33 </Custom>
34 </InstallExecuteSequence>
35 </Fragment>
36
37 <!-- Firewall Custom Action DLL Definitions -->
38 <Fragment>
39 <Binary Id="WixFirewallCA$(var.Suffix)" SourceFile="!(bindpath.$(var.platform))fwca.dll" />
40 </Fragment>
41</Include>
diff --git a/src/wixlib/FirewallExtension_x86.wxs b/src/wixlib/FirewallExtension_x86.wxs
new file mode 100644
index 00000000..b43a4c5f
--- /dev/null
+++ b/src/wixlib/FirewallExtension_x86.wxs
@@ -0,0 +1,8 @@
1<?xml version="1.0"?>
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<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
6 <?define platform=x86 ?>
7 <?include FirewallExtension_Platform.wxi ?>
8</Wix>
diff --git a/src/wixlib/caSuffix.wxi b/src/wixlib/caSuffix.wxi
new file mode 100644
index 00000000..a56a2393
--- /dev/null
+++ b/src/wixlib/caSuffix.wxi
@@ -0,0 +1,28 @@
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<Include xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <?ifndef platform ?>
6 <?error Required value "platform" not defined in include caSuffix.wxi ?>
7 <?endif ?>
8
9 <?ifdef Suffix ?>
10 <?undef Suffix ?>
11 <?undef DeferredSuffix ?>
12 <?endif ?>
13
14 <?if $(var.platform)="x86" ?>
15 <?define Suffix="" ?>
16 <?define DeferredSuffix="" ?>
17 <?endif ?>
18
19 <?if $(var.platform)="x64" ?>
20 <?define Suffix="_x64" ?>
21 <?define DeferredSuffix="_64" ?>
22 <?endif ?>
23
24 <?if $(var.platform)="arm" ?>
25 <?define Suffix="_ARM" ?>
26 <?define DeferredSuffix="_ARM" ?>
27 <?endif ?>
28</Include>
diff --git a/src/wixlib/caerr.wxi b/src/wixlib/caerr.wxi
new file mode 100644
index 00000000..141942f2
--- /dev/null
+++ b/src/wixlib/caerr.wxi
@@ -0,0 +1,96 @@
1<Include>
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/wixlib/en-us.wxl b/src/wixlib/en-us.wxl
new file mode 100644
index 00000000..7db8a9c2
--- /dev/null
+++ b/src/wixlib/en-us.wxl
@@ -0,0 +1,14 @@
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
5<WixLocalization Culture="en-us" xmlns="http://wixtoolset.org/schemas/v4/wxl">
6 <String Id="msierrFirewallCannotConnect" Overridable="yes">Cannot connect to Windows Firewall. ([2] [3] [4] [5])</String>
7
8 <String Id="WixSchedFirewallExceptionsInstall" Overridable="yes">Configuring Windows Firewall</String>
9 <String Id="WixSchedFirewallExceptionsUninstall" Overridable="yes">Configuring Windows Firewall</String>
10 <String Id="WixRollbackFirewallExceptionsInstall" Overridable="yes">Rolling back Windows Firewall configuration</String>
11 <String Id="WixExecFirewallExceptionsInstall" Overridable="yes">Installing Windows Firewall configuration</String>
12 <String Id="WixRollbackFirewallExceptionsUninstall" Overridable="yes">Rolling back Windows Firewall configuration</String>
13 <String Id="WixExecFirewallExceptionsUninstall" Overridable="yes">Uninstalling Windows Firewall configuration</String>
14</WixLocalization>
diff --git a/src/wixlib/es-es.wxl b/src/wixlib/es-es.wxl
new file mode 100644
index 00000000..45d5fd0e
--- /dev/null
+++ b/src/wixlib/es-es.wxl
@@ -0,0 +1,13 @@
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<WixLocalization Culture="es-es" xmlns="http://wixtoolset.org/schemas/v4/wxl">
5 <String Id="msierrFirewallCannotConnect" Overridable="yes">No se puede conectar al Firewall de Windows. ([2] [3] [4] [5])</String>
6
7 <String Id="WixSchedFirewallExceptionsInstall" Overridable="yes">Configurando el Firewall de Windows</String>
8 <String Id="WixSchedFirewallExceptionsUninstall" Overridable="yes">Configurando el Firewall de Windows</String>
9 <String Id="WixRollbackFirewallExceptionsInstall" Overridable="yes">Regresando la configuración del Firewall de Windows</String>
10 <String Id="WixExecFirewallExceptionsInstall" Overridable="yes">Instalando la configuración del Firewall de Windows</String>
11 <String Id="WixRollbackFirewallExceptionsUninstall" Overridable="yes">Regresando la configuración del Firewall de Windows</String>
12 <String Id="WixExecFirewallExceptionsUninstall" Overridable="yes">Desinstalando la configuración del Firewall de Windows</String>
13</WixLocalization>
diff --git a/src/wixlib/firewall.wixproj b/src/wixlib/firewall.wixproj
new file mode 100644
index 00000000..fc700d61
--- /dev/null
+++ b/src/wixlib/firewall.wixproj
@@ -0,0 +1,44 @@
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" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0">
4 <Import Project="..\..\packages\WixToolset.Core.InternalPackage.4.0.64\build\WixToolset.Core.InternalPackage.props" Condition="Exists('..\..\packages\WixToolset.Core.InternalPackage.4.0.64\build\WixToolset.Core.InternalPackage.props')" />
5 <Import Project="..\FindLocalWix.props" />
6 <PropertyGroup>
7 <ProjectGuid>{1acffefd-505a-41a5-acbf-a02b7b473aa2}</ProjectGuid>
8 <OutputName>firewall</OutputName>
9 <OutputType>Library</OutputType>
10 <BindFiles>true</BindFiles>
11 <Pedantic>true</Pedantic>
12 <Cultures>en-us</Cultures>
13 </PropertyGroup>
14 <ItemGroup>
15 <Compile Include="FirewallExtension.wxs" />
16 <Compile Include="FirewallExtension_x86.wxs" />
17 <EmbeddedResource Include="en-us.wxl" />
18 <EmbeddedResource Include="es-es.wxl" />
19 <EmbeddedResource Include="ja-jp.wxl" />
20 <EmbeddedResource Include="pl-pl.wxl" />
21 </ItemGroup>
22 <ItemGroup>
23 <None Include="packages.config" />
24 </ItemGroup>
25 <ItemGroup>
26 <ProjectReference Include="..\ca\fwca.vcxproj">
27 <Name>fwca</Name>
28 <Project>{F72D34CA-48DA-4DFD-91A9-A0C78BEF6981}</Project>
29 </ProjectReference>
30 </ItemGroup>
31 <Import Project="$(WixTargetsPath)" Condition=" '$(WixTargetsPath)' != '' AND Exists('$(WixTargetsPath)') " />
32 <Import Project="$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\wix.targets" Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\wix.targets') " />
33 <Target Name="EnsureWixToolsetInstalled" Condition=" '$(WixTargetsImported)' != 'true' ">
34 <Error Text="FG-WiX or WiX Toolset build tools (v3.11 or later) must be installed to build this project. To download FG-WiX, go to https://www.firegiant.com/downloads/. To download the WiX Toolset, go to http://wixtoolset.org/releases/." />
35 </Target>
36 <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
37 <PropertyGroup>
38 <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>
39 </PropertyGroup>
40 <Error Condition="!Exists('..\..\packages\Nerdbank.GitVersioning.2.1.7\build\Nerdbank.GitVersioning.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Nerdbank.GitVersioning.2.1.7\build\Nerdbank.GitVersioning.targets'))" />
41 <Error Condition="!Exists('..\..\packages\WixToolset.Core.InternalPackage.4.0.64\build\WixToolset.Core.InternalPackage.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.Core.InternalPackage.4.0.64\build\WixToolset.Core.InternalPackage.props'))" />
42 </Target>
43 <Import Project="..\..\packages\Nerdbank.GitVersioning.2.1.7\build\Nerdbank.GitVersioning.targets" Condition="Exists('..\..\packages\Nerdbank.GitVersioning.2.1.7\build\Nerdbank.GitVersioning.targets')" />
44</Project> \ No newline at end of file
diff --git a/src/wixlib/ja-jp.wxl b/src/wixlib/ja-jp.wxl
new file mode 100644
index 00000000..b6c0b96e
--- /dev/null
+++ b/src/wixlib/ja-jp.wxl
@@ -0,0 +1,14 @@
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
5<WixLocalization Culture="ja-jp" xmlns="http://wixtoolset.org/schemas/v4/wxl">
6 <String Id="msierrFirewallCannotConnect" Overridable="yes">Windows ファイアウォールへ接続できません。 ([2] [3] [4] [5])</String>
7
8 <String Id="WixSchedFirewallExceptionsInstall" Overridable="yes">Windows ファイアウォールを構成しています</String>
9 <String Id="WixSchedFirewallExceptionsUninstall" Overridable="yes">Windows ファイアウォールを構成しています</String>
10 <String Id="WixRollbackFirewallExceptionsInstall" Overridable="yes">Windows ファイアウォール構成をロールバックしています</String>
11 <String Id="WixExecFirewallExceptionsInstall" Overridable="yes">Windows ファイアウォール構成をインストールしています</String>
12 <String Id="WixRollbackFirewallExceptionsUninstall" Overridable="yes">Windows ファイアウォール構成をロールバックしています</String>
13 <String Id="WixExecFirewallExceptionsUninstall" Overridable="yes">Windows ファイアウォール構成をアンインストールしています</String>
14</WixLocalization>
diff --git a/src/wixlib/packages.config b/src/wixlib/packages.config
new file mode 100644
index 00000000..4250845c
--- /dev/null
+++ b/src/wixlib/packages.config
@@ -0,0 +1,5 @@
1<?xml version="1.0" encoding="utf-8"?>
2<packages>
3 <package id="Nerdbank.GitVersioning" version="2.1.7" developmentDependency="true" targetFramework="net40" />
4 <package id="WixToolset.Core.InternalPackage" version="4.0.64" targetFramework="net40" developmentDependency="true" />
5</packages> \ No newline at end of file
diff --git a/src/wixlib/pl-pl.wxl b/src/wixlib/pl-pl.wxl
new file mode 100644
index 00000000..a685917c
--- /dev/null
+++ b/src/wixlib/pl-pl.wxl
@@ -0,0 +1,14 @@
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
5<WixLocalization Culture="pl-pl" xmlns="http://wixtoolset.org/schemas/v4/wxl">
6 <String Id="msierrFirewallCannotConnect" Overridable="yes">Nie udało się połączyć z Zaporą systemu Windows. ([2] [3] [4] [5])</String>
7
8 <String Id="WixSchedFirewallExceptionsInstall" Overridable="yes">Dodawanie wyjątków do Zapory systemu Windows</String>
9 <String Id="WixSchedFirewallExceptionsUninstall" Overridable="yes">Usuwanie wyjątków z Zapory systemu Windows</String>
10 <String Id="WixRollbackFirewallExceptionsInstall" Overridable="yes">Cofanie zmian konfiguracji Zapory systemu Windows</String>
11 <String Id="WixExecFirewallExceptionsInstall" Overridable="yes">Konfigurowywanie Zapory systemu Windows</String>
12 <String Id="WixRollbackFirewallExceptionsUninstall" Overridable="yes">Cofanie zmian konfiguracji Zapory systemu Windows</String>
13 <String Id="WixExecFirewallExceptionsUninstall" Overridable="yes">Konfigurowywanie Zapory systemu Windows</String>
14</WixLocalization>
diff --git a/version.json b/version.json
new file mode 100644
index 00000000..5f857771
--- /dev/null
+++ b/version.json
@@ -0,0 +1,11 @@
1{
2 "version": "4.0",
3 "publicReleaseRefSpec": [
4 "^refs/heads/master$"
5 ],
6 "cloudBuild": {
7 "buildNumber": {
8 "enabled": true
9 }
10 }
11}