Initial code commit
Rob Mensching committed
Jan 2, 2018 at 23:14 UTC
97b80191048b23f2e870c9d6a27e368ebaaf594d
46 files changed
+3080
Firewall.wixext.sln
new
+73
@@ -0,0 +1,73 @@
1
+
2
+Microsoft Visual Studio Solution File, Format Version 12.00
3
+# Visual Studio 15
4
+VisualStudioVersion = 15.0.27130.2003
5
+MinimumVisualStudioVersion = 15.0.26124.0
6
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fwca", "src\ca\fwca.vcxproj", "{076018F7-19BD-423A-ABBF-229273DA08D8}"
7
+EndProject
8
+Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "firewall", "src\wixlib\firewall.wixproj", "{1ACFFEFD-505A-41A5-ACBF-A02B7B473AA2}"
9
+EndProject
10
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Firewall.wixext", "src\wixext\WixToolset.Firewall.wixext.csproj", "{6CF033EB-0A39-4AC6-9D41-9BD506352045}"
11
+EndProject
12
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.Firewall", "src\test\WixToolsetTest.Firewall\WixToolsetTest.Firewall.csproj", "{D5D34EC4-AF91-4B11-AC0A-FA5242AE924B}"
13
+EndProject
14
+Global
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
73
+EndGlobal
appveyor.cmd
new
+13
@@ -0,0 +1,13 @@
1
+@setlocal
2
+@pushd %~dp0
3
+
4
+nuget restore
5
+
6
+msbuild -p:Configuration=Release -t:Restore
7
+
8
+msbuild -p:Configuration=Release src\test\WixToolsetTest.Firewall\WixToolsetTest.Firewall.csproj
9
+
10
+msbuild -p:Configuration=Release -t:Pack src\wixext\WixToolset.Firewall.wixext.csproj
11
+
12
+@popd
13
+@endlocal
\ No newline at end of file
appveyor.yml
new
+29
@@ -0,0 +1,29 @@
1
+image: Visual Studio 2017
2
+
3
+version: 0.0.0.{build}
4
+configuration: Release
5
+
6
+environment:
7
+ DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
8
+ DOTNET_CLI_TELEMETRY_OPTOUT: 1
9
+ NUGET_XMLDOC_MODE: skip
10
+
11
+build_script:
12
+ - appveyor.cmd
13
+
14
+pull_requests:
15
+ do_not_increment_build_number: true
16
+
17
+nuget:
18
+ disable_publish_on_pr: true
19
+
20
+skip_tags: true
21
+
22
+artifacts:
23
+- path: build\Release\**\*.nupkg
24
+ name: nuget
25
+
26
+notifications:
27
+- provider: Slack
28
+ incoming_webhook:
29
+ secure: p5xuu+4x2JHfwGDMDe5KcG1k7gZxqYc4jWVwvyNZv5cvkubPD2waJs5yXMAXZNN7Z63/3PWHb7q4KoY/99AjauYa1nZ4c5qYqRPFRBKTHfA=
nuget.config
new
+15
@@ -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
src/Cpp.Build.props
new
+101
@@ -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) > 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>
src/Directory.Build.props
new
+22
@@ -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>
src/FindLocalWix.props
new
+8
@@ -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>
src/ca/CustomMsiErrors.h
new
+130
@@ -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
src/ca/cost.h
new
+5
@@ -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
+
5
+const UINT COST_FIREWALL_EXCEPTION = 2000;
src/ca/dllmain.cpp
new
+26
@@ -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
+/********************************************************************
6
+DllMain - standard entry point for all WiX CustomActions
7
+
8
+********************************************************************/
9
+extern "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
+}
src/ca/firewall.cpp
new
+1067
@@ -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
+
5
+LPCWSTR vcsFirewallExceptionQuery =
6
+ L"SELECT `Name`, `RemoteAddresses`, `Port`, `Protocol`, `Program`, `Attributes`, `Profile`, `Component_`, `Description` FROM `WixFirewallException`";
7
+enum eFirewallExceptionQuery { feqName = 1, feqRemoteAddresses, feqPort, feqProtocol, feqProgram, feqAttributes, feqProfile, feqComponent, feqDescription };
8
+enum eFirewallExceptionTarget { fetPort = 1, fetApplication, fetUnknown };
9
+enum eFirewallExceptionAttributes { feaIgnoreFailures = 1 };
10
+
11
+/******************************************************************
12
+ SchedFirewallExceptions - immediate custom action worker to
13
+ register and remove firewall exceptions.
14
+
15
+********************************************************************/
16
+static 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
+
167
+LExit:
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
+********************************************************************/
185
+extern "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
+********************************************************************/
197
+extern "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
+********************************************************************/
208
+static 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
+
254
+LExit:
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
+********************************************************************/
266
+static 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
+
327
+LExit:
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
+********************************************************************/
341
+static 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
+********************************************************************/
363
+static 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
+
412
+LExit:
413
+ ReleaseObject(pfwPolicy);
414
+ ReleaseObject(pfwMgr);
415
+ ReleaseObject(pfwProfile);
416
+
417
+ return hr;
418
+}
419
+
420
+/******************************************************************
421
+ AddApplicationException
422
+
423
+********************************************************************/
424
+static 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
+
487
+LExit:
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
+********************************************************************/
500
+static 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
+
571
+LExit:
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
+********************************************************************/
586
+static 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
+
637
+LExit:
638
+ ReleaseBSTR(bstrName);
639
+ ReleaseObject(pNetFwRules);
640
+ ReleaseObject(pNetFwRule);
641
+
642
+ return fIgnoreFailures ? S_OK : hr;
643
+}
644
+
645
+/******************************************************************
646
+ AddPortExceptionOnCurrentProfile
647
+
648
+********************************************************************/
649
+static 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
+
703
+LExit:
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
+********************************************************************/
717
+static 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
+
740
+LExit:
741
+ ReleaseBSTR(bstrName);
742
+ ReleaseObject(pNetFwRules);
743
+
744
+ return fIgnoreFailures ? S_OK : hr;
745
+}
746
+
747
+/******************************************************************
748
+ RemoveApplicationExceptionFromCurrentProfile
749
+
750
+********************************************************************/
751
+static 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
+
779
+LExit:
780
+ ReleaseBSTR(bstrFile);
781
+ ReleaseObject(pfwApps);
782
+ ReleaseObject(pfwProfile);
783
+
784
+ return fIgnoreFailures ? S_OK : hr;
785
+}
786
+
787
+/******************************************************************
788
+ RemovePortExceptionFromCurrentProfile
789
+
790
+********************************************************************/
791
+static 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
+
815
+LExit:
816
+ return fIgnoreFailures ? S_OK : hr;
817
+}
818
+
819
+static 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
+
855
+static 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
+
880
+static 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
+
909
+static 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
+********************************************************************/
936
+extern "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
+
1057
+LExit:
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
+}
src/ca/fwca.def
new
+9
@@ -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
+
4
+LIBRARY "fwca"
5
+
6
+EXPORTS
7
+ SchedFirewallExceptionsInstall
8
+ SchedFirewallExceptionsUninstall
9
+ ExecFirewallExceptions
src/ca/fwca.vcxproj
new
+72
@@ -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
+
src/ca/packages.config
new
+6
@@ -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
src/ca/precomp.h
new
+17
@@ -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"
src/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs
new
+33
@@ -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
+
3
+namespace 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
+}
src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/Package.en-us.wxl
new
+11
@@ -0,0 +1,11 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+
3
+<!--
4
+This 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>
src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/Package.wxs
new
+22
@@ -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>
src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/PackageComponents.wxs
new
+14
@@ -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>
src/test/WixToolsetTest.Firewall/TestData/UsingFirewall/example.txt
new
+1
@@ -0,0 +1 @@
1
+This is example.txt.
\ No newline at end of file
src/test/WixToolsetTest.Firewall/WixToolsetTest.Firewall.csproj
new
+40
@@ -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>
src/wixext/FirewallCompiler.cs
new
+356
@@ -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
+
3
+namespace 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
+}
src/wixext/FirewallConstants.cs
new
+21
@@ -0,0 +1,21 @@
1
+// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
+
3
+namespace 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
+}
src/wixext/FirewallDecompiler.cs
new
+169
@@ -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
+
3
+namespace 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
+}
src/wixext/FirewallErrors.cs
new
+42
@@ -0,0 +1,42 @@
1
+// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
+
3
+namespace 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
+}
src/wixext/FirewallExtensionData.cs
new
+24
@@ -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
+
3
+namespace 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
+}
src/wixext/FirewallExtensionFactory.cs
new
+18
@@ -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
+
3
+namespace 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
+}
src/wixext/FirewallWindowsInstallerBackendExtension.cs
new
+26
@@ -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
+namespace 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
+}
src/wixext/Tuples/FirewallTupleDefinitions.cs
new
+31
@@ -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
+
3
+namespace 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
+}
src/wixext/Tuples/WixFirewallExceptionTuple.cs
new
+93
@@ -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
+
3
+namespace 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
src/wixext/WixToolset.Firewall.wixext.csproj
new
+36
@@ -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>
src/wixext/WixToolset.Firewall.wixext.targets
new
+11
@@ -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>
src/wixext/firewall.xsd
new
+211
@@ -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>
src/wixext/tables.xml
new
+28
@@ -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>
src/wixlib/FirewallExtension.wxs
new
+12
@@ -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>
src/wixlib/FirewallExtension_Platform.wxi
new
+41
@@ -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>
src/wixlib/FirewallExtension_x86.wxs
new
+8
@@ -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>
src/wixlib/caSuffix.wxi
new
+28
@@ -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>
src/wixlib/caerr.wxi
new
+96
@@ -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
src/wixlib/en-us.wxl
new
+14
@@ -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>
src/wixlib/es-es.wxl
new
+13
@@ -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>
src/wixlib/firewall.wixproj
new
+44
@@ -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
src/wixlib/ja-jp.wxl
new
+14
@@ -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>
src/wixlib/packages.config
new
+5
@@ -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
src/wixlib/pl-pl.wxl
new
+14
@@ -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>
version.json
new
+11
@@ -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
+}