aboutsummaryrefslogtreecommitdiff
path: root/src/ext
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext')
-rw-r--r--src/ext/ComPlus/CSharp.Build.props11
-rw-r--r--src/ext/ComPlus/ComPlus.wixext.sln64
-rw-r--r--src/ext/ComPlus/Cpp.Build.props88
-rw-r--r--src/ext/ComPlus/Directory.Build.props27
-rw-r--r--src/ext/ComPlus/Directory.Build.targets51
-rw-r--r--src/ext/ComPlus/Directory.csproj.props13
-rw-r--r--src/ext/ComPlus/Directory.csproj.targets26
-rw-r--r--src/ext/ComPlus/Directory.vcxproj.props93
-rw-r--r--src/ext/ComPlus/README.md2
-rw-r--r--src/ext/ComPlus/Wix.Build.props31
-rw-r--r--src/ext/ComPlus/appveyor.cmd22
-rw-r--r--src/ext/ComPlus/appveyor.yml42
-rw-r--r--src/ext/ComPlus/ca/complusca.def15
-rw-r--r--src/ext/ComPlus/ca/complusca.vcxproj95
-rw-r--r--src/ext/ComPlus/ca/cpappexec.cpp344
-rw-r--r--src/ext/ComPlus/ca/cpappexec.h12
-rw-r--r--src/ext/ComPlus/ca/cpapproleexec.cpp720
-rw-r--r--src/ext/ComPlus/ca/cpapproleexec.h20
-rw-r--r--src/ext/ComPlus/ca/cpapprolesched.cpp843
-rw-r--r--src/ext/ComPlus/ca/cpapprolesched.h112
-rw-r--r--src/ext/ComPlus/ca/cpappsched.cpp752
-rw-r--r--src/ext/ComPlus/ca/cpappsched.h83
-rw-r--r--src/ext/ComPlus/ca/cpasmexec.cpp1877
-rw-r--r--src/ext/ComPlus/ca/cpasmexec.h20
-rw-r--r--src/ext/ComPlus/ca/cpasmsched.cpp2135
-rw-r--r--src/ext/ComPlus/ca/cpasmsched.h168
-rw-r--r--src/ext/ComPlus/ca/cpcost.h30
-rw-r--r--src/ext/ComPlus/ca/cpexec.cpp681
-rw-r--r--src/ext/ComPlus/ca/cppartexec.cpp690
-rw-r--r--src/ext/ComPlus/ca/cppartexec.h20
-rw-r--r--src/ext/ComPlus/ca/cppartroleexec.cpp397
-rw-r--r--src/ext/ComPlus/ca/cppartroleexec.h12
-rw-r--r--src/ext/ComPlus/ca/cppartrolesched.cpp421
-rw-r--r--src/ext/ComPlus/ca/cppartrolesched.h76
-rw-r--r--src/ext/ComPlus/ca/cppartsched.cpp912
-rw-r--r--src/ext/ComPlus/ca/cppartsched.h125
-rw-r--r--src/ext/ComPlus/ca/cpsched.cpp566
-rw-r--r--src/ext/ComPlus/ca/cpsubsexec.cpp411
-rw-r--r--src/ext/ComPlus/ca/cpsubsexec.h12
-rw-r--r--src/ext/ComPlus/ca/cpsubssched.cpp606
-rw-r--r--src/ext/ComPlus/ca/cpsubssched.h62
-rw-r--r--src/ext/ComPlus/ca/cputilexec.cpp1881
-rw-r--r--src/ext/ComPlus/ca/cputilexec.h193
-rw-r--r--src/ext/ComPlus/ca/cputilsched.cpp885
-rw-r--r--src/ext/ComPlus/ca/cputilsched.h132
-rw-r--r--src/ext/ComPlus/ca/custommsierrors.h29
-rw-r--r--src/ext/ComPlus/ca/dllmain.cpp27
-rw-r--r--src/ext/ComPlus/ca/packages.config5
-rw-r--r--src/ext/ComPlus/ca/precomp.h33
-rw-r--r--src/ext/ComPlus/nuget.config17
-rw-r--r--src/ext/ComPlus/test/WixToolsetTest.ComPlus/ComPlusExtensionFixture.cs32
-rw-r--r--src/ext/ComPlus/test/WixToolsetTest.ComPlus/TestData/UsingComPlusPartition/Package.en-us.wxl11
-rw-r--r--src/ext/ComPlus/test/WixToolsetTest.ComPlus/TestData/UsingComPlusPartition/Package.wxs15
-rw-r--r--src/ext/ComPlus/test/WixToolsetTest.ComPlus/TestData/UsingComPlusPartition/PackageComponents.wxs12
-rw-r--r--src/ext/ComPlus/test/WixToolsetTest.ComPlus/TestData/UsingComPlusPartition/example.txt1
-rw-r--r--src/ext/ComPlus/test/WixToolsetTest.ComPlus/WixToolsetTest.ComPlus.csproj38
-rw-r--r--src/ext/ComPlus/wix.snkbin0 -> 596 bytes
-rw-r--r--src/ext/ComPlus/wixext/ComPlusCompiler.cs2164
-rw-r--r--src/ext/ComPlus/wixext/ComPlusDecompiler.cs1845
-rw-r--r--src/ext/ComPlus/wixext/ComPlusErrors.cs72
-rw-r--r--src/ext/ComPlus/wixext/ComPlusExtensionData.cs30
-rw-r--r--src/ext/ComPlus/wixext/ComPlusExtensionFactory.cs18
-rw-r--r--src/ext/ComPlus/wixext/ComPlusTableDefinitions.cs360
-rw-r--r--src/ext/ComPlus/wixext/ComPlusWarnings.cs31
-rw-r--r--src/ext/ComPlus/wixext/ComPlusWindowsInstallerBackendBinderExtension.cs13
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusApplicationPropertySymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusApplicationRolePropertySymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusApplicationRoleSymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusApplicationSymbol.cs71
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusAssemblyDependencySymbol.cs55
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusAssemblySymbol.cs95
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusComponentPropertySymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusComponentSymbol.cs55
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusGroupInApplicationRoleSymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusGroupInPartitionRoleSymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusInterfacePropertySymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusInterfaceSymbol.cs55
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusMethodPropertySymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusMethodSymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusPartitionPropertySymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusPartitionRoleSymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusPartitionSymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusPartitionUserSymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusRoleForComponentSymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusRoleForInterfaceSymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusRoleForMethodSymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusSubscriptionPropertySymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusSubscriptionSymbol.cs95
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusSymbolDefinitions.cs135
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusUserInApplicationRoleSymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/Symbols/ComPlusUserInPartitionRoleSymbol.cs63
-rw-r--r--src/ext/ComPlus/wixext/WixToolset.ComPlus.wixext.csproj32
-rw-r--r--src/ext/ComPlus/wixext/WixToolset.ComPlus.wixext.nuspec24
-rw-r--r--src/ext/ComPlus/wixext/WixToolset.ComPlus.wixext.targets11
-rw-r--r--src/ext/ComPlus/wixlib/ComPlusExtension.wxs135
-rw-r--r--src/ext/ComPlus/wixlib/caerr.wxi96
-rw-r--r--src/ext/ComPlus/wixlib/complus.wixproj26
-rw-r--r--src/ext/ComPlus/wixlib/en-us.wxl71
-rw-r--r--src/ext/ComPlus/wixlib/es-es.wxl72
-rw-r--r--src/ext/ComPlus/wixlib/ja-jp.wxl71
-rw-r--r--src/ext/global.json5
101 files changed, 22832 insertions, 0 deletions
diff --git a/src/ext/ComPlus/CSharp.Build.props b/src/ext/ComPlus/CSharp.Build.props
new file mode 100644
index 00000000..b12f4c6e
--- /dev/null
+++ b/src/ext/ComPlus/CSharp.Build.props
@@ -0,0 +1,11 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2<!--
3 Do NOT modify this file. Update the canonical version in Home\repo-template\src\CSharp.Build.props
4 then update all of the repos.
5-->
6<Project>
7 <PropertyGroup>
8 <SignAssembly>true</SignAssembly>
9 <AssemblyOriginatorKeyFile>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)wix.snk))</AssemblyOriginatorKeyFile>
10 </PropertyGroup>
11</Project>
diff --git a/src/ext/ComPlus/ComPlus.wixext.sln b/src/ext/ComPlus/ComPlus.wixext.sln
new file mode 100644
index 00000000..9fab25f2
--- /dev/null
+++ b/src/ext/ComPlus/ComPlus.wixext.sln
@@ -0,0 +1,64 @@
1
2Microsoft Visual Studio Solution File, Format Version 12.00
3# Visual Studio Version 16
4VisualStudioVersion = 16.0.30611.23
5MinimumVisualStudioVersion = 10.0.40219.1
6Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "complusca", "src\ca\complusca.vcxproj", "{BDEF51ED-E242-4FA2-801A-01B127DF851A}"
7EndProject
8Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "complus", "src\wixlib\complus.wixproj", "{E191E61E-E098-4F71-888F-51A79F952022}"
9 ProjectSection(ProjectDependencies) = postProject
10 {BDEF51ED-E242-4FA2-801A-01B127DF851A} = {BDEF51ED-E242-4FA2-801A-01B127DF851A}
11 EndProjectSection
12EndProject
13Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.ComPlus.wixext", "src\wixext\WixToolset.ComPlus.wixext.csproj", "{1497B777-330B-4CFE-927A-22850CD24D64}"
14EndProject
15Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.ComPlus", "src\test\WixToolsetTest.ComPlus\WixToolsetTest.ComPlus.csproj", "{2FC5F039-EACF-428B-BA87-8CDE1D25E121}"
16EndProject
17Global
18 GlobalSection(SolutionConfigurationPlatforms) = preSolution
19 Debug|Any CPU = Debug|Any CPU
20 Debug|x86 = Debug|x86
21 Release|Any CPU = Release|Any CPU
22 Release|x86 = Release|x86
23 EndGlobalSection
24 GlobalSection(ProjectConfigurationPlatforms) = postSolution
25 {BDEF51ED-E242-4FA2-801A-01B127DF851A}.Debug|Any CPU.ActiveCfg = Debug|Win32
26 {BDEF51ED-E242-4FA2-801A-01B127DF851A}.Debug|Any CPU.Build.0 = Debug|Win32
27 {BDEF51ED-E242-4FA2-801A-01B127DF851A}.Debug|x86.ActiveCfg = Debug|Win32
28 {BDEF51ED-E242-4FA2-801A-01B127DF851A}.Debug|x86.Build.0 = Debug|Win32
29 {BDEF51ED-E242-4FA2-801A-01B127DF851A}.Release|Any CPU.ActiveCfg = Release|Win32
30 {BDEF51ED-E242-4FA2-801A-01B127DF851A}.Release|Any CPU.Build.0 = Release|Win32
31 {BDEF51ED-E242-4FA2-801A-01B127DF851A}.Release|x86.ActiveCfg = Release|Win32
32 {BDEF51ED-E242-4FA2-801A-01B127DF851A}.Release|x86.Build.0 = Release|Win32
33 {E191E61E-E098-4F71-888F-51A79F952022}.Debug|Any CPU.ActiveCfg = Debug|x86
34 {E191E61E-E098-4F71-888F-51A79F952022}.Debug|Any CPU.Build.0 = Debug|x86
35 {E191E61E-E098-4F71-888F-51A79F952022}.Debug|x86.ActiveCfg = Debug|x86
36 {E191E61E-E098-4F71-888F-51A79F952022}.Debug|x86.Build.0 = Debug|x86
37 {E191E61E-E098-4F71-888F-51A79F952022}.Release|Any CPU.ActiveCfg = Release|x86
38 {E191E61E-E098-4F71-888F-51A79F952022}.Release|Any CPU.Build.0 = Release|x86
39 {E191E61E-E098-4F71-888F-51A79F952022}.Release|x86.ActiveCfg = Release|x86
40 {E191E61E-E098-4F71-888F-51A79F952022}.Release|x86.Build.0 = Release|x86
41 {1497B777-330B-4CFE-927A-22850CD24D64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
42 {1497B777-330B-4CFE-927A-22850CD24D64}.Debug|Any CPU.Build.0 = Debug|Any CPU
43 {1497B777-330B-4CFE-927A-22850CD24D64}.Debug|x86.ActiveCfg = Debug|Any CPU
44 {1497B777-330B-4CFE-927A-22850CD24D64}.Debug|x86.Build.0 = Debug|Any CPU
45 {1497B777-330B-4CFE-927A-22850CD24D64}.Release|Any CPU.ActiveCfg = Release|Any CPU
46 {1497B777-330B-4CFE-927A-22850CD24D64}.Release|Any CPU.Build.0 = Release|Any CPU
47 {1497B777-330B-4CFE-927A-22850CD24D64}.Release|x86.ActiveCfg = Release|Any CPU
48 {1497B777-330B-4CFE-927A-22850CD24D64}.Release|x86.Build.0 = Release|Any CPU
49 {2FC5F039-EACF-428B-BA87-8CDE1D25E121}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
50 {2FC5F039-EACF-428B-BA87-8CDE1D25E121}.Debug|Any CPU.Build.0 = Debug|Any CPU
51 {2FC5F039-EACF-428B-BA87-8CDE1D25E121}.Debug|x86.ActiveCfg = Debug|Any CPU
52 {2FC5F039-EACF-428B-BA87-8CDE1D25E121}.Debug|x86.Build.0 = Debug|Any CPU
53 {2FC5F039-EACF-428B-BA87-8CDE1D25E121}.Release|Any CPU.ActiveCfg = Release|Any CPU
54 {2FC5F039-EACF-428B-BA87-8CDE1D25E121}.Release|Any CPU.Build.0 = Release|Any CPU
55 {2FC5F039-EACF-428B-BA87-8CDE1D25E121}.Release|x86.ActiveCfg = Release|Any CPU
56 {2FC5F039-EACF-428B-BA87-8CDE1D25E121}.Release|x86.Build.0 = Release|Any CPU
57 EndGlobalSection
58 GlobalSection(SolutionProperties) = preSolution
59 HideSolutionNode = FALSE
60 EndGlobalSection
61 GlobalSection(ExtensibilityGlobals) = postSolution
62 SolutionGuid = {3E1857C4-5EE1-4C9E-9390-9954E041546D}
63 EndGlobalSection
64EndGlobal
diff --git a/src/ext/ComPlus/Cpp.Build.props b/src/ext/ComPlus/Cpp.Build.props
new file mode 100644
index 00000000..9551e76f
--- /dev/null
+++ b/src/ext/ComPlus/Cpp.Build.props
@@ -0,0 +1,88 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project>
5 <PropertyGroup>
6 <Platform Condition=" '$(Platform)' == '' OR '$(Platform)' == 'AnyCPU' OR '$(Platform)' == 'x86' ">Win32</Platform>
7 <NormalizedPlatform Condition=" '$(Platform)'=='Win32' ">x86</NormalizedPlatform>
8 <NormalizedPlatform Condition=" '$(NormalizedPlatform)'=='' ">$(Platform)</NormalizedPlatform>
9 <IntDir>$(BaseIntermediateOutputPath)$(Configuration)\$(NormalizedPlatform)\</IntDir>
10 <OutDir>$(OutputPath)$(NormalizedPlatform)\</OutDir>
11 </PropertyGroup>
12
13 <PropertyGroup Condition="'$(WindowsTargetPlatformVersion)'=='' AND '$(VisualStudioVersion)'>='15.0'">
14 <WindowsTargetPlatformVersion>$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0'))</WindowsTargetPlatformVersion>
15 </PropertyGroup>
16
17 <ItemDefinitionGroup>
18 <ClCompile>
19 <DisableSpecificWarnings>$(DisableSpecificCompilerWarnings)</DisableSpecificWarnings>
20 <WarningLevel>Level4</WarningLevel>
21 <AdditionalIncludeDirectories>$(ProjectDir)inc;$(MSBuildProjectDirectory);$(IntDir);$(SqlCESdkIncludePath);$(ProjectAdditionalIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
22 <PreprocessorDefinitions>WIN32;_WINDOWS;_WIN32_MSI=500;_WIN32_WINNT=0x0501;$(ArmPreprocessorDefinitions);$(UnicodePreprocessorDefinitions);_CRT_STDIO_LEGACY_WIDE_SPECIFIERS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
23 <PrecompiledHeader>Use</PrecompiledHeader>
24 <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
25 <CallingConvention Condition="'$(Platform)'=='Win32'">StdCall</CallingConvention>
26 <TreatWarningAsError>true</TreatWarningAsError>
27 <ExceptionHandling>false</ExceptionHandling>
28 <AdditionalOptions>-YlprecompDefine</AdditionalOptions>
29 <AdditionalOptions Condition=" $(PlatformToolset.StartsWith('v14')) ">/Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
30 <MultiProcessorCompilation Condition=" $(NUMBER_OF_PROCESSORS) &gt; 4 ">true</MultiProcessorCompilation>
31 </ClCompile>
32 <ResourceCompile>
33 <PreprocessorDefinitions>$(ArmPreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
34 <AdditionalIncludeDirectories>$(ProjectAdditionalResourceIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
35 </ResourceCompile>
36 <Lib>
37 <AdditionalLibraryDirectories>$(OutDir);$(AdditionalMultiTargetLibraryPath);$(ProjectAdditionalLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
38 </Lib>
39 <Link>
40 <SubSystem>$(ProjectSubSystem)</SubSystem>
41 <ModuleDefinitionFile>$(ProjectModuleDefinitionFile)</ModuleDefinitionFile>
42 <NoEntryPoint>$(ResourceOnlyDll)</NoEntryPoint>
43 <GenerateDebugInformation>true</GenerateDebugInformation>
44 <AdditionalDependencies>$(ProjectAdditionalLinkLibraries);advapi32.lib;comdlg32.lib;user32.lib;oleaut32.lib;gdi32.lib;shell32.lib;ole32.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
45 <AdditionalLibraryDirectories>$(OutDir);$(AdditionalMultiTargetLibraryPath);$(ArmLibraryDirectories);$(ProjectAdditionalLinkLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
46 <AdditionalOptions Condition=" $(PlatformToolset.StartsWith('v14')) ">/IGNORE:4099 %(AdditionalOptions)</AdditionalOptions>
47 </Link>
48 </ItemDefinitionGroup>
49
50 <ItemDefinitionGroup Condition=" '$(Platform)'=='Win32' and '$(PlatformToolset)'!='v100'">
51 <ClCompile>
52 <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
53 </ClCompile>
54 </ItemDefinitionGroup>
55 <ItemDefinitionGroup Condition=" '$(Platform)'=='arm' ">
56 <ClCompile>
57 <CallingConvention>CDecl</CallingConvention>
58 </ClCompile>
59 </ItemDefinitionGroup>
60 <ItemDefinitionGroup Condition=" '$(ConfigurationType)'=='StaticLibrary' ">
61 <ClCompile>
62 <DebugInformationFormat>OldStyle</DebugInformationFormat>
63 <OmitDefaultLibName>true</OmitDefaultLibName>
64 <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
65 </ClCompile>
66 </ItemDefinitionGroup>
67 <ItemDefinitionGroup Condition=" '$(Configuration)'=='Debug' ">
68 <ClCompile>
69 <Optimization>Disabled</Optimization>
70 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
71 <PreprocessorDefinitions>_DEBUG;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
72 <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
73 </ClCompile>
74 </ItemDefinitionGroup>
75 <ItemDefinitionGroup Condition=" '$(Configuration)'=='Release' ">
76 <ClCompile>
77 <Optimization>MinSpace</Optimization>
78 <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
79 <FunctionLevelLinking>true</FunctionLevelLinking>
80 <IntrinsicFunctions>true</IntrinsicFunctions>
81 <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
82 </ClCompile>
83 <Link>
84 <EnableCOMDATFolding>true</EnableCOMDATFolding>
85 <OptimizeReferences>true</OptimizeReferences>
86 </Link>
87 </ItemDefinitionGroup>
88</Project>
diff --git a/src/ext/ComPlus/Directory.Build.props b/src/ext/ComPlus/Directory.Build.props
new file mode 100644
index 00000000..b3c6287c
--- /dev/null
+++ b/src/ext/ComPlus/Directory.Build.props
@@ -0,0 +1,27 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3<!--
4 Do NOT modify this file. Update the canonical version in Home\repo-template\src\Directory.Build.props
5 then update all of the repos.
6-->
7<Project>
8 <PropertyGroup>
9 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
10 <EnableSourceLink Condition=" '$(NCrunch)' == '1' ">false</EnableSourceLink>
11 <MSBuildWarningsAsMessages>MSB3246</MSBuildWarningsAsMessages>
12
13 <ProjectName Condition=" '$(ProjectName)' == '' ">$(MSBuildProjectName)</ProjectName>
14 <BaseOutputPath>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\build\))</BaseOutputPath>
15 <BaseIntermediateOutputPath>$(BaseOutputPath)obj\$(ProjectName)\</BaseIntermediateOutputPath>
16 <OutputPath>$(BaseOutputPath)$(Configuration)\</OutputPath>
17
18 <Authors>WiX Toolset Team</Authors>
19 <Company>WiX Toolset</Company>
20 <Copyright>Copyright (c) .NET Foundation and contributors. All rights reserved.</Copyright>
21 <PackageLicenseExpression>MS-RL</PackageLicenseExpression>
22 <Product>WiX Toolset</Product>
23 </PropertyGroup>
24
25 <Import Project="Directory$(MSBuildProjectExtension).props" Condition=" Exists('Directory$(MSBuildProjectExtension).props') " />
26 <Import Project="Custom.Build.props" Condition=" Exists('Custom.Build.props') " />
27</Project>
diff --git a/src/ext/ComPlus/Directory.Build.targets b/src/ext/ComPlus/Directory.Build.targets
new file mode 100644
index 00000000..2fcc765a
--- /dev/null
+++ b/src/ext/ComPlus/Directory.Build.targets
@@ -0,0 +1,51 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3<!--
4 Do NOT modify this file. Update the canonical version in Home\repo-template\src\Directory.Build.targets
5 then update all of the repos.
6-->
7<!--
8 Replace PackageReferences with ProjectReferences when the projects can be found in .sln.
9 See the original here: https://github.com/dotnet/sdk/issues/1151#issuecomment-385133284
10-->
11<Project>
12 <PropertyGroup>
13 <ReplacePackageReferences>true</ReplacePackageReferences>
14 <TheSolutionPath Condition=" '$(NCrunch)'=='' ">$(SolutionPath)</TheSolutionPath>
15 <TheSolutionPath Condition=" '$(NCrunch)'=='1' ">$(NCrunchOriginalSolutionPath)</TheSolutionPath>
16 </PropertyGroup>
17
18 <Choose>
19 <When Condition="$(ReplacePackageReferences) AND '$(TheSolutionPath)' != '' AND '$(TheSolutionPath)' != '*undefined*' AND Exists('$(TheSolutionPath)')">
20
21 <PropertyGroup>
22 <SolutionFileContent>$([System.IO.File]::ReadAllText($(TheSolutionPath)))</SolutionFileContent>
23 <SmartSolutionDir>$([System.IO.Path]::GetDirectoryName( $(TheSolutionPath) ))</SmartSolutionDir>
24 <RegexPattern>(?&lt;="[PackageName]", ")(.*)(?=", ")</RegexPattern>
25 </PropertyGroup>
26
27 <ItemGroup>
28 <!-- Keep the identity of the PackageReference -->
29 <SmartPackageReference Include="@(PackageReference)">
30 <PackageName>%(Identity)</PackageName>
31 <InSolution>$(SolutionFileContent.Contains('\%(Identity).csproj'))</InSolution>
32 </SmartPackageReference>
33
34 <!-- Filter them by mapping them to another ItemGroup using the WithMetadataValue item function -->
35 <PackageInSolution Include="@(SmartPackageReference->WithMetadataValue('InSolution', True))">
36 <Pattern>$(RegexPattern.Replace('[PackageName]','%(PackageName)') )</Pattern>
37 <SmartPath>$([System.Text.RegularExpressions.Regex]::Match('$(SolutionFileContent)', '%(Pattern)'))</SmartPath>
38 </PackageInSolution>
39
40 <ProjectReference Include="@(PackageInSolution->'$(SmartSolutionDir)\%(SmartPath)' )"/>
41
42 <!-- Remove the package references that are now referenced as projects -->
43 <PackageReference Remove="@(PackageInSolution->'%(PackageName)')"/>
44 </ItemGroup>
45
46 </When>
47 </Choose>
48
49 <Import Project="Directory$(MSBuildProjectExtension).targets" Condition=" Exists('Directory$(MSBuildProjectExtension).targets') " />
50 <Import Project="Custom.Build.targets" Condition=" Exists('Custom.Build.targets') " />
51</Project>
diff --git a/src/ext/ComPlus/Directory.csproj.props b/src/ext/ComPlus/Directory.csproj.props
new file mode 100644
index 00000000..81d24ad1
--- /dev/null
+++ b/src/ext/ComPlus/Directory.csproj.props
@@ -0,0 +1,13 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2<!--
3 Do NOT modify this file. Update the canonical version in Home\repo-template\src\CSharp.Build.props
4 then update all of the repos.
5-->
6<Project>
7 <PropertyGroup>
8 <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
9 <SignAssembly>true</SignAssembly>
10 <AssemblyOriginatorKeyFile>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)wix.snk))</AssemblyOriginatorKeyFile>
11 <NBGV_EmitThisAssemblyClass>false</NBGV_EmitThisAssemblyClass>
12 </PropertyGroup>
13</Project>
diff --git a/src/ext/ComPlus/Directory.csproj.targets b/src/ext/ComPlus/Directory.csproj.targets
new file mode 100644
index 00000000..c3270426
--- /dev/null
+++ b/src/ext/ComPlus/Directory.csproj.targets
@@ -0,0 +1,26 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2<!--
3 Do NOT modify this file. Update the canonical version in Home\repo-template\src\Directory.csproj.targets
4 then update all of the repos.
5-->
6<Project>
7 <PropertyGroup>
8 <CreateDocumentation Condition=" '$(CreateDocumentationFile)'!='true' ">false</CreateDocumentation>
9 <DocumentationFile Condition=" '$(CreateDocumentationFile)'=='true' ">$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
10 </PropertyGroup>
11
12 <Target Name="SetNuspecProperties" DependsOnTargets="InitializeSourceControlInformation" AfterTargets="GetBuildVersion"
13 Condition=" Exists('$(MSBuildProjectName).nuspec') ">
14 <PropertyGroup>
15 <ProjectUrl Condition=" '$(ProjectUrl)'=='' and '$(PrivateRepositoryUrl)'!='' ">$(PrivateRepositoryUrl.Replace('.git',''))</ProjectUrl>
16
17 <NuspecFile>$(MSBuildProjectName).nuspec</NuspecFile>
18 <NuspecBasePath Condition=" '$(NuspecBasePath)'=='' ">$(OutputPath)..\</NuspecBasePath>
19 <NuspecProperties>$(NuspecProperties);Id=$(PackageId);Authors=$(Authors);Copyright=$(Copyright);Description=$(Description);Title=$(Title)</NuspecProperties>
20 <NuspecProperties>$(NuspecProperties);Version=$(PackageVersion);RepositoryCommit=$(SourceRevisionId);RepositoryType=$(RepositoryType);RepositoryUrl=$(PrivateRepositoryUrl);ProjectFolder=$(MSBuildProjectDirectory)\;ProjectUrl=$(ProjectUrl)</NuspecProperties>
21 <PublishRepositoryUrl>true</PublishRepositoryUrl>
22 <SymbolPackageFormat>snupkg</SymbolPackageFormat>
23 </PropertyGroup>
24 </Target>
25
26</Project>
diff --git a/src/ext/ComPlus/Directory.vcxproj.props b/src/ext/ComPlus/Directory.vcxproj.props
new file mode 100644
index 00000000..664bc1d8
--- /dev/null
+++ b/src/ext/ComPlus/Directory.vcxproj.props
@@ -0,0 +1,93 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project>
5 <PropertyGroup>
6 <Platform Condition=" '$(Platform)' == '' OR '$(Platform)' == 'AnyCPU' ">Win32</Platform>
7 <IntDir>$(BaseIntermediateOutputPath)$(Configuration)\$(Platform)\</IntDir>
8 <OutDir>$(OutputPath)$(Platform)\</OutDir>
9
10 <!-- NBGV properties -->
11 <AssemblyCompany>$(Company)</AssemblyCompany>
12 <AssemblyCopyright>$(Copyright)</AssemblyCopyright>
13
14 <RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
15 <NuGetTargetMoniker>native,Version=v0.0</NuGetTargetMoniker>
16 </PropertyGroup>
17
18 <PropertyGroup Condition="'$(WindowsTargetPlatformVersion)'=='' AND '$(VisualStudioVersion)'>='15.0'">
19 <WindowsTargetPlatformVersion>$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0'))</WindowsTargetPlatformVersion>
20 </PropertyGroup>
21
22 <ItemDefinitionGroup>
23 <ClCompile>
24 <DisableSpecificWarnings>$(DisableSpecificCompilerWarnings)</DisableSpecificWarnings>
25 <WarningLevel>Level4</WarningLevel>
26 <AdditionalIncludeDirectories>$(ProjectDir)inc;$(MSBuildProjectDirectory);$(IntDir);$(SqlCESdkIncludePath);$(ProjectAdditionalIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
27 <PreprocessorDefinitions>WIN32;_WINDOWS;_WIN32_MSI=500;_WIN32_WINNT=0x0501;$(ArmPreprocessorDefinitions);$(UnicodePreprocessorDefinitions);_CRT_STDIO_LEGACY_WIDE_SPECIFIERS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
28 <PrecompiledHeader>Use</PrecompiledHeader>
29 <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
30 <CallingConvention Condition="'$(Platform)'=='Win32'">StdCall</CallingConvention>
31 <TreatWarningAsError>true</TreatWarningAsError>
32 <ExceptionHandling>false</ExceptionHandling>
33 <AdditionalOptions>-YlprecompDefine</AdditionalOptions>
34 <AdditionalOptions Condition=" $(PlatformToolset.StartsWith('v14')) ">/Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
35 <MultiProcessorCompilation Condition=" $(NUMBER_OF_PROCESSORS) &gt; 4 ">true</MultiProcessorCompilation>
36 </ClCompile>
37 <ResourceCompile>
38 <PreprocessorDefinitions>$(ArmPreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
39 <AdditionalIncludeDirectories>$(ProjectAdditionalResourceIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
40 </ResourceCompile>
41 <Lib>
42 <AdditionalLibraryDirectories>$(OutDir);$(AdditionalMultiTargetLibraryPath);$(ProjectAdditionalLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
43 </Lib>
44 <Link>
45 <SubSystem>$(ProjectSubSystem)</SubSystem>
46 <ModuleDefinitionFile>$(ProjectModuleDefinitionFile)</ModuleDefinitionFile>
47 <NoEntryPoint>$(ResourceOnlyDll)</NoEntryPoint>
48 <GenerateDebugInformation>true</GenerateDebugInformation>
49 <AdditionalDependencies>$(ProjectAdditionalLinkLibraries);advapi32.lib;comdlg32.lib;user32.lib;oleaut32.lib;gdi32.lib;shell32.lib;ole32.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
50 <AdditionalLibraryDirectories>$(OutDir);$(AdditionalMultiTargetLibraryPath);$(ArmLibraryDirectories);$(ProjectAdditionalLinkLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
51 <AdditionalOptions Condition=" $(PlatformToolset.StartsWith('v14')) ">/IGNORE:4099 %(AdditionalOptions)</AdditionalOptions>
52 </Link>
53 </ItemDefinitionGroup>
54
55 <ItemDefinitionGroup Condition=" '$(Platform)'=='Win32' and '$(PlatformToolset)'!='v100'">
56 <ClCompile>
57 <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
58 </ClCompile>
59 </ItemDefinitionGroup>
60 <ItemDefinitionGroup Condition=" '$(Platform)'=='arm' ">
61 <ClCompile>
62 <CallingConvention>CDecl</CallingConvention>
63 </ClCompile>
64 </ItemDefinitionGroup>
65 <ItemDefinitionGroup Condition=" '$(ConfigurationType)'=='StaticLibrary' ">
66 <ClCompile>
67 <DebugInformationFormat>OldStyle</DebugInformationFormat>
68 <OmitDefaultLibName>true</OmitDefaultLibName>
69 <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
70 </ClCompile>
71 </ItemDefinitionGroup>
72 <ItemDefinitionGroup Condition=" '$(Configuration)'=='Debug' ">
73 <ClCompile>
74 <Optimization>Disabled</Optimization>
75 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
76 <PreprocessorDefinitions>_DEBUG;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
77 <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
78 </ClCompile>
79 </ItemDefinitionGroup>
80 <ItemDefinitionGroup Condition=" '$(Configuration)'=='Release' ">
81 <ClCompile>
82 <Optimization>MinSpace</Optimization>
83 <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
84 <FunctionLevelLinking>true</FunctionLevelLinking>
85 <IntrinsicFunctions>true</IntrinsicFunctions>
86 <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
87 </ClCompile>
88 <Link>
89 <EnableCOMDATFolding>true</EnableCOMDATFolding>
90 <OptimizeReferences>true</OptimizeReferences>
91 </Link>
92 </ItemDefinitionGroup>
93</Project>
diff --git a/src/ext/ComPlus/README.md b/src/ext/ComPlus/README.md
new file mode 100644
index 00000000..8604c104
--- /dev/null
+++ b/src/ext/ComPlus/README.md
@@ -0,0 +1,2 @@
1# ComPlus.wixext
2WixToolset.ComPlus.wixext - COM+ WiX Toolset Extension
diff --git a/src/ext/ComPlus/Wix.Build.props b/src/ext/ComPlus/Wix.Build.props
new file mode 100644
index 00000000..a81c9615
--- /dev/null
+++ b/src/ext/ComPlus/Wix.Build.props
@@ -0,0 +1,31 @@
1<?xml version="1.0" encoding="utf-8" ?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project>
5 <PropertyGroup>
6 <DefineConstants>$(DefineConstants);CompanyName=$(Company)</DefineConstants>
7 <OutputPath_x86>$(OutputPath)x86\</OutputPath_x86>
8 <OutputPath_x64>$(OutputPath)x64\</OutputPath_x64>
9 <OutputPath_arm>$(OutputPath)ARM\</OutputPath_arm>
10 <OutputPath_arm64>$(OutputPath)ARM64\</OutputPath_arm64>
11 <OutputPath_win32>$(OutputPath)Win32\</OutputPath_win32>
12 </PropertyGroup>
13
14 <ItemGroup>
15 <BindInputPaths Include="$(OutputPath_x86)">
16 <BindName>x86</BindName>
17 </BindInputPaths>
18 <BindInputPaths Include="$(OutputPath_x64)">
19 <BindName>x64</BindName>
20 </BindInputPaths>
21 <BindInputPaths Include="$(OutputPath_arm)">
22 <BindName>arm</BindName>
23 </BindInputPaths>
24 <BindInputPaths Include="$(OutputPath_arm64)">
25 <BindName>arm64</BindName>
26 </BindInputPaths>
27 <BindInputPaths Include="$(OutputPath_win32)">
28 <BindName>win32</BindName>
29 </BindInputPaths>
30 </ItemGroup>
31</Project>
diff --git a/src/ext/ComPlus/appveyor.cmd b/src/ext/ComPlus/appveyor.cmd
new file mode 100644
index 00000000..17900d31
--- /dev/null
+++ b/src/ext/ComPlus/appveyor.cmd
@@ -0,0 +1,22 @@
1@setlocal
2@pushd %~dp0
3@set _C=Release
4@if /i "%1"=="debug" set _C=Debug
5
6:: Restore
7msbuild -p:Configuration=%_C% -t:Restore || exit /b
8
9::msbuild -p:Configuration=%_C% -p:Platform=Win32 src\ca\complusca.vcxproj || exit /b
10::msbuild -p:Configuration=%_C% -p:Platform=x64 src\ca\complusca.vcxproj || exit /b
11
12:: Build
13msbuild -p:Configuration=%_C% src\test\WixToolsetTest.ComPlus\WixToolsetTest.ComPlus.csproj || exit /b
14
15:: Test
16dotnet test -c %_C% --no-build src\test\WixToolsetTest.ComPlus || exit /b
17
18:: Pack
19msbuild -p:Configuration=%_C% -p:NoBuild=true -t:Pack src\wixext\WixToolset.ComPlus.wixext.csproj || exit /b
20
21@popd
22@endlocal \ No newline at end of file
diff --git a/src/ext/ComPlus/appveyor.yml b/src/ext/ComPlus/appveyor.yml
new file mode 100644
index 00000000..c53cc9cc
--- /dev/null
+++ b/src/ext/ComPlus/appveyor.yml
@@ -0,0 +1,42 @@
1# Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2#
3# Do NOT modify this file. Update the canonical version in Home\repo-template\src\appveyor.yml
4# then update all of the repos.
5
6branches:
7 only:
8 - master
9 - develop
10
11image: Visual Studio 2019
12
13version: 0.0.0.{build}
14configuration: Release
15
16environment:
17 DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
18 DOTNET_CLI_TELEMETRY_OPTOUT: 1
19 NUGET_XMLDOC_MODE: skip
20
21build_script:
22 - appveyor.cmd
23
24pull_requests:
25 do_not_increment_build_number: true
26
27nuget:
28 disable_publish_on_pr: true
29
30skip_branch_with_pr: true
31skip_tags: true
32
33artifacts:
34- path: build\Release\**\*.nupkg
35 name: nuget
36- path: build\Release\**\*.snupkg
37 name: snupkg
38
39notifications:
40- provider: Slack
41 incoming_webhook:
42 secure: p5xuu+4x2JHfwGDMDe5KcG1k7gZxqYc4jWVwvyNZv5cvkubPD2waJs5yXMAXZNN7Z63/3PWHb7q4KoY/99AjauYa1nZ4c5qYqRPFRBKTHfA=
diff --git a/src/ext/ComPlus/ca/complusca.def b/src/ext/ComPlus/ca/complusca.def
new file mode 100644
index 00000000..7c475759
--- /dev/null
+++ b/src/ext/ComPlus/ca/complusca.def
@@ -0,0 +1,15 @@
1; Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3
4LIBRARY "complusca"
5
6EXPORTS
7 ComPlusPrepare
8 ComPlusCleanup
9 ComPlusInstallExecute
10 ComPlusInstallExecuteCommit
11 ComPlusRollbackInstallExecute
12 ComPlusUninstallExecute
13 ComPlusRollbackUninstallExecute
14 ConfigureComPlusInstall
15 ConfigureComPlusUninstall
diff --git a/src/ext/ComPlus/ca/complusca.vcxproj b/src/ext/ComPlus/ca/complusca.vcxproj
new file mode 100644
index 00000000..3a7f6e64
--- /dev/null
+++ b/src/ext/ComPlus/ca/complusca.vcxproj
@@ -0,0 +1,95 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
5 <ItemGroup Label="ProjectConfigurations">
6 <ProjectConfiguration Include="Debug|Win32">
7 <Configuration>Debug</Configuration>
8 <Platform>Win32</Platform>
9 </ProjectConfiguration>
10 <ProjectConfiguration Include="Release|Win32">
11 <Configuration>Release</Configuration>
12 <Platform>Win32</Platform>
13 </ProjectConfiguration>
14 <ProjectConfiguration Include="Debug|x64">
15 <Configuration>Debug</Configuration>
16 <Platform>x64</Platform>
17 </ProjectConfiguration>
18 <ProjectConfiguration Include="Release|x64">
19 <Configuration>Release</Configuration>
20 <Platform>x64</Platform>
21 </ProjectConfiguration>
22 </ItemGroup>
23
24 <PropertyGroup Label="Globals">
25 <ProjectGuid>{BDEF51ED-E242-4FA2-801A-01B127DF851A}</ProjectGuid>
26 <ConfigurationType>DynamicLibrary</ConfigurationType>
27 <PlatformToolset>v142</PlatformToolset>
28 <CharacterSet>Unicode</CharacterSet>
29 <TargetName>complusca</TargetName>
30 <ProjectModuleDefinitionFile>complusca.def</ProjectModuleDefinitionFile>
31 <Description>WiX Toolset ComPlus CustomAction</Description>
32 <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
33 </PropertyGroup>
34
35 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
36 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
37
38 <PropertyGroup>
39 <ProjectAdditionalLinkLibraries>msi.lib</ProjectAdditionalLinkLibraries>
40 </PropertyGroup>
41
42 <ItemGroup>
43 <ClCompile Include="cpappexec.cpp" />
44 <ClCompile Include="cpapproleexec.cpp" />
45 <ClCompile Include="cpapprolesched.cpp" />
46 <ClCompile Include="cpappsched.cpp" />
47 <ClCompile Include="cpasmexec.cpp" />
48 <ClCompile Include="cpasmsched.cpp" />
49 <ClCompile Include="cpexec.cpp" />
50 <ClCompile Include="cppartexec.cpp" />
51 <ClCompile Include="cppartroleexec.cpp" />
52 <ClCompile Include="cppartrolesched.cpp" />
53 <ClCompile Include="cppartsched.cpp" />
54 <ClCompile Include="cpsched.cpp" />
55 <ClCompile Include="cpsubsexec.cpp" />
56 <ClCompile Include="cpsubssched.cpp" />
57 <ClCompile Include="cputilexec.cpp" />
58 <ClCompile Include="cputilsched.cpp" />
59 <ClCompile Include="dllmain.cpp">
60 <PrecompiledHeader>Create</PrecompiledHeader>
61 </ClCompile>
62 </ItemGroup>
63
64 <ItemGroup>
65 <ClInclude Include="cpappexec.h" />
66 <ClInclude Include="cpapproleexec.h" />
67 <ClInclude Include="cpapprolesched.h" />
68 <ClInclude Include="cpappsched.h" />
69 <ClInclude Include="cpasmexec.h" />
70 <ClInclude Include="cpasmsched.h" />
71 <ClInclude Include="cpcost.h" />
72 <ClInclude Include="cppartexec.h" />
73 <ClInclude Include="cppartroleexec.h" />
74 <ClInclude Include="cppartrolesched.h" />
75 <ClInclude Include="cppartsched.h" />
76 <ClInclude Include="cpsubsexec.h" />
77 <ClInclude Include="cpsubssched.h" />
78 <ClInclude Include="cputilexec.h" />
79 <ClInclude Include="cputilsched.h" />
80 <ClInclude Include="precomp.h" />
81 </ItemGroup>
82
83 <ItemGroup>
84 <None Include="complusca.def" />
85 </ItemGroup>
86
87 <ItemGroup>
88 <PackageReference Include="WixToolset.Dutil" Version="4.0.62" />
89 <PackageReference Include="WixToolset.WcaUtil" Version="4.0.18" />
90 <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" />
91 <PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37" />
92 </ItemGroup>
93
94 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
95</Project> \ No newline at end of file
diff --git a/src/ext/ComPlus/ca/cpappexec.cpp b/src/ext/ComPlus/ca/cpappexec.cpp
new file mode 100644
index 00000000..48948210
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpappexec.cpp
@@ -0,0 +1,344 @@
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// private structs
7
8struct CPI_APPLICATION_ATTRIBUTES
9{
10 int iActionType;
11 int iActionCost;
12 LPWSTR pwzKey;
13 LPWSTR pwzID;
14 LPWSTR pwzName;
15 LPWSTR pwzPartID;
16 CPI_PROPERTY* pPropList;
17};
18
19
20// prototypes for private helper functions
21
22static HRESULT ReadApplicationAttributes(
23 LPWSTR* ppwzData,
24 CPI_APPLICATION_ATTRIBUTES* pAttrs
25 );
26static void FreeApplicationAttributes(
27 CPI_APPLICATION_ATTRIBUTES* pAttrs
28 );
29static HRESULT CreateApplication(
30 CPI_APPLICATION_ATTRIBUTES* pAttrs
31 );
32static HRESULT RemoveApplication(
33 CPI_APPLICATION_ATTRIBUTES* pAttrs
34 );
35
36
37// function definitions
38
39HRESULT CpiConfigureApplications(
40 LPWSTR* ppwzData,
41 HANDLE hRollbackFile
42 )
43{
44 HRESULT hr = S_OK;
45
46 CPI_APPLICATION_ATTRIBUTES attrs;
47 ::ZeroMemory(&attrs, sizeof(attrs));
48
49 // read action text
50 hr = CpiActionStartMessage(ppwzData, FALSE);
51 ExitOnFailure(hr, "Failed to send action start message");
52
53 // get count
54 int iCnt = 0;
55 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
56 ExitOnFailure(hr, "Failed to read count");
57
58 // write count to rollback file
59 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
60 ExitOnFailure(hr, "Failed to write count to rollback file");
61
62 for (int i = 0; i < iCnt; i++)
63 {
64 // read attributes from CustomActionData
65 hr = ReadApplicationAttributes(ppwzData, &attrs);
66 ExitOnFailure(hr, "Failed to read attributes");
67
68 // progress message
69 hr = CpiActionDataMessage(1, attrs.pwzName);
70 ExitOnFailure(hr, "Failed to send progress messages");
71
72 if (S_FALSE == hr)
73 ExitFunction();
74
75 // write key to rollback file
76 hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
77 ExitOnFailure(hr, "Failed to write key to rollback file");
78
79 // action
80 switch (attrs.iActionType)
81 {
82 case atCreate:
83 hr = CreateApplication(&attrs);
84 ExitOnFailure(hr, "Failed to create application, key: %S", attrs.pwzKey);
85 break;
86 case atRemove:
87 hr = RemoveApplication(&attrs);
88 ExitOnFailure(hr, "Failed to remove application, key: %S", attrs.pwzKey);
89 break;
90 }
91
92 // write completion status to rollback file
93 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
94 ExitOnFailure(hr, "Failed to write completion status to rollback file");
95
96 // progress
97 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
98 ExitOnFailure(hr, "Failed to update progress");
99 }
100
101 hr = S_OK;
102
103LExit:
104 // clean up
105 FreeApplicationAttributes(&attrs);
106
107 return hr;
108}
109
110HRESULT CpiRollbackConfigureApplications(
111 LPWSTR* ppwzData,
112 CPI_ROLLBACK_DATA* pRollbackDataList
113 )
114{
115 HRESULT hr = S_OK;
116
117 int iRollbackStatus;
118
119 CPI_APPLICATION_ATTRIBUTES attrs;
120 ::ZeroMemory(&attrs, sizeof(attrs));
121
122 // read action text
123 hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
124 ExitOnFailure(hr, "Failed to send action start message");
125
126 // get count
127 int iCnt = 0;
128 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
129 ExitOnFailure(hr, "Failed to read count");
130
131 for (int i = 0; i < iCnt; i++)
132 {
133 // read attributes from CustomActionData
134 hr = ReadApplicationAttributes(ppwzData, &attrs);
135 ExitOnFailure(hr, "Failed to read attributes");
136
137 // rollback status
138 hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
139
140 if (S_FALSE == hr)
141 continue; // not found, nothing to rollback
142
143 // progress message
144 hr = CpiActionDataMessage(1, attrs.pwzName);
145 ExitOnFailure(hr, "Failed to send progress messages");
146
147 if (S_FALSE == hr)
148 ExitFunction();
149
150 // action
151 switch (attrs.iActionType)
152 {
153 case atCreate:
154 hr = CreateApplication(&attrs);
155 if (FAILED(hr))
156 WcaLog(LOGMSG_STANDARD, "Failed to create application, hr: 0x%x, key: %S", hr, attrs.pwzKey);
157 break;
158 case atRemove:
159 hr = RemoveApplication(&attrs);
160 if (FAILED(hr))
161 WcaLog(LOGMSG_STANDARD, "Failed to remove application, hr: 0x%x, key: %S", hr, attrs.pwzKey);
162 break;
163 }
164
165 // check rollback status
166 if (0 == iRollbackStatus)
167 continue; // operation did not complete, skip progress
168
169 // progress
170 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
171 ExitOnFailure(hr, "Failed to update progress");
172 }
173
174 hr = S_OK;
175
176LExit:
177 // clean up
178 FreeApplicationAttributes(&attrs);
179
180 return hr;
181}
182
183
184// helper function definitions
185
186static HRESULT ReadApplicationAttributes(
187 LPWSTR* ppwzData,
188 CPI_APPLICATION_ATTRIBUTES* pAttrs
189 )
190{
191 HRESULT hr = S_OK;
192
193 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
194 ExitOnFailure(hr, "Failed to read action type");
195 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
196 ExitOnFailure(hr, "Failed to read action cost");
197 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
198 ExitOnFailure(hr, "Failed to read key");
199 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzID);
200 ExitOnFailure(hr, "Failed to read id");
201 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzName);
202 ExitOnFailure(hr, "Failed to read name");
203 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
204 ExitOnFailure(hr, "Failed to read partition id");
205 hr = CpiReadPropertyList(ppwzData, &pAttrs->pPropList);
206 ExitOnFailure(hr, "Failed to read properties");
207
208 hr = S_OK;
209
210LExit:
211 return hr;
212}
213
214static void FreeApplicationAttributes(
215 CPI_APPLICATION_ATTRIBUTES* pAttrs
216 )
217{
218 ReleaseStr(pAttrs->pwzKey);
219 ReleaseStr(pAttrs->pwzID);
220 ReleaseStr(pAttrs->pwzName);
221 ReleaseStr(pAttrs->pwzPartID);
222
223 if (pAttrs->pPropList)
224 CpiFreePropertyList(pAttrs->pPropList);
225}
226
227static HRESULT CreateApplication(
228 CPI_APPLICATION_ATTRIBUTES* pAttrs
229 )
230{
231 HRESULT hr = S_OK;
232
233 ICatalogCollection* piAppColl = NULL;
234 ICatalogObject* piAppObj = NULL;
235
236 long lChanges = 0;
237
238 // log
239 WcaLog(LOGMSG_VERBOSE, "Creating application, key: %S", pAttrs->pwzKey);
240
241 // get applications collection
242 hr = CpiExecGetApplicationsCollection(pAttrs->pwzPartID, &piAppColl);
243 if (S_FALSE == hr)
244 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
245 ExitOnFailure(hr, "Failed to get applications collection");
246
247 // check if application exists
248 hr = CpiFindCollectionObjectByStringKey(piAppColl, pAttrs->pwzID, &piAppObj);
249 ExitOnFailure(hr, "Failed to find application");
250
251 if (S_FALSE == hr)
252 {
253 // create application
254 hr = CpiAddCollectionObject(piAppColl, &piAppObj);
255 ExitOnFailure(hr, "Failed to add application to collection");
256
257 hr = CpiPutCollectionObjectValue(piAppObj, L"ID", pAttrs->pwzID);
258 ExitOnFailure(hr, "Failed to set application id property");
259
260 hr = CpiPutCollectionObjectValue(piAppObj, L"Name", pAttrs->pwzName);
261 ExitOnFailure(hr, "Failed to set application name property");
262
263 // save changes
264 hr = piAppColl->SaveChanges(&lChanges);
265 if (COMADMIN_E_OBJECTERRORS == hr)
266 CpiLogCatalogErrorInfo();
267 ExitOnFailure(hr, "Failed to add application");
268 }
269
270 // properties
271 hr = CpiPutCollectionObjectValues(piAppObj, pAttrs->pPropList);
272 ExitOnFailure(hr, "Failed to write properties");
273
274 // save changes
275 hr = piAppColl->SaveChanges(&lChanges);
276 if (COMADMIN_E_OBJECTERRORS == hr)
277 CpiLogCatalogErrorInfo();
278 ExitOnFailure(hr, "Failed to save changes");
279
280 // log
281 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
282
283 hr = S_OK;
284
285LExit:
286 // clean up
287 ReleaseObject(piAppColl);
288 ReleaseObject(piAppObj);
289
290 return hr;
291}
292
293static HRESULT RemoveApplication(
294 CPI_APPLICATION_ATTRIBUTES* pAttrs
295 )
296{
297 HRESULT hr = S_OK;
298
299 ICatalogCollection* piAppColl = NULL;
300
301 long lChanges = 0;
302
303 // log
304 WcaLog(LOGMSG_VERBOSE, "Removing application, key: %S", pAttrs->pwzKey);
305
306 // get applications collection
307 hr = CpiExecGetApplicationsCollection(pAttrs->pwzPartID, &piAppColl);
308 ExitOnFailure(hr, "Failed to get applications collection");
309
310 if (S_FALSE == hr)
311 {
312 // applications collection not found
313 WcaLog(LOGMSG_VERBOSE, "Unable to retrieve applications collection, nothing to delete, key: %S", pAttrs->pwzKey);
314 ExitFunction1(hr = S_OK);
315 }
316
317 // remove
318 hr = CpiRemoveCollectionObject(piAppColl, pAttrs->pwzID, NULL, TRUE);
319 ExitOnFailure(hr, "Failed to remove application");
320
321 if (S_FALSE == hr)
322 {
323 // application not found
324 WcaLog(LOGMSG_VERBOSE, "Application not found, nothing to delete, key: %S", pAttrs->pwzKey);
325 ExitFunction1(hr = S_OK);
326 }
327
328 // save changes
329 hr = piAppColl->SaveChanges(&lChanges);
330 if (COMADMIN_E_OBJECTERRORS == hr)
331 CpiLogCatalogErrorInfo();
332 ExitOnFailure(hr, "Failed to save changes");
333
334 // log
335 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
336
337 hr = S_OK;
338
339LExit:
340 // clean up
341 ReleaseObject(piAppColl);
342
343 return hr;
344}
diff --git a/src/ext/ComPlus/ca/cpappexec.h b/src/ext/ComPlus/ca/cpappexec.h
new file mode 100644
index 00000000..5003b046
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpappexec.h
@@ -0,0 +1,12 @@
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
5HRESULT CpiConfigureApplications(
6 LPWSTR* ppwzData,
7 HANDLE hRollbackFile
8 );
9HRESULT CpiRollbackConfigureApplications(
10 LPWSTR* ppwzData,
11 CPI_ROLLBACK_DATA* pRollbackDataList
12 );
diff --git a/src/ext/ComPlus/ca/cpapproleexec.cpp b/src/ext/ComPlus/ca/cpapproleexec.cpp
new file mode 100644
index 00000000..e3b71e93
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpapproleexec.cpp
@@ -0,0 +1,720 @@
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// private structs
7
8struct CPI_APPLICATION_ROLE_ATTRIBUTES
9{
10 int iActionType;
11 int iActionCost;
12 LPWSTR pwzKey;
13 LPWSTR pwzName;
14 LPWSTR pwzAppID;
15 LPWSTR pwzPartID;
16 CPI_PROPERTY* pPropList;
17};
18
19struct CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES
20{
21 int iActionType;
22 int iActionCost;
23 LPWSTR pwzKey;
24 LPWSTR pwzRoleName;
25 LPWSTR pwzAccount;
26 LPWSTR pwzAppID;
27 LPWSTR pwzPartID;
28};
29
30
31// prototypes for private helper functions
32
33static HRESULT ReadApplicationRoleAttributes(
34 LPWSTR* ppwzData,
35 CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs
36 );
37static void FreeApplicationRoleAttributes(
38 CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs
39 );
40static HRESULT CreateApplicationRole(
41 CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs
42 );
43static HRESULT RemoveApplicationRole(
44 CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs
45 );
46static HRESULT ReadUsersInApplicationRoleAttributes(
47 LPWSTR* ppwzData,
48 CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs
49 );
50static void FreeUsersInApplicationRoleAttributes(
51 CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs
52 );
53static HRESULT CreateUsersInApplicationRole(
54 CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs
55 );
56static HRESULT RemoveUsersInApplicationRole(
57 CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs
58 );
59
60
61// function definitions
62
63HRESULT CpiConfigureApplicationRoles(
64 LPWSTR* ppwzData,
65 HANDLE hRollbackFile
66 )
67{
68 HRESULT hr = S_OK;
69
70 CPI_APPLICATION_ROLE_ATTRIBUTES attrs;
71 ::ZeroMemory(&attrs, sizeof(attrs));
72
73 // read action text
74 hr = CpiActionStartMessage(ppwzData, FALSE);
75 ExitOnFailure(hr, "Failed to send action start message");
76
77 // ger count
78 int iCnt = 0;
79 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
80 ExitOnFailure(hr, "Failed to read count");
81
82 // write count to rollback file
83 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
84 ExitOnFailure(hr, "Failed to write count to rollback file");
85
86 for (int i = 0; i < iCnt; i++)
87 {
88 // read attributes from CustomActionData
89 hr = ReadApplicationRoleAttributes(ppwzData, &attrs);
90 ExitOnFailure(hr, "Failed to read attributes");
91
92 // progress message
93 hr = CpiActionDataMessage(1, attrs.pwzName);
94 ExitOnFailure(hr, "Failed to send progress messages");
95
96 if (S_FALSE == hr)
97 ExitFunction();
98
99 // write key to rollback file
100 hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
101 ExitOnFailure(hr, "Failed to write key to rollback file");
102
103 // action
104 switch (attrs.iActionType)
105 {
106 case atCreate:
107 hr = CreateApplicationRole(&attrs);
108 ExitOnFailure(hr, "Failed to create application role, key: %S", attrs.pwzKey);
109 break;
110 case atRemove:
111 hr = RemoveApplicationRole(&attrs);
112 ExitOnFailure(hr, "Failed to remove application role, key: %S", attrs.pwzKey);
113 break;
114 }
115
116 // write completion status to rollback file
117 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
118 ExitOnFailure(hr, "Failed to write completion status to rollback file");
119
120 // progress
121 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
122 ExitOnFailure(hr, "Failed to update progress");
123 }
124
125 hr = S_OK;
126
127LExit:
128 // clean up
129 FreeApplicationRoleAttributes(&attrs);
130
131 return hr;
132}
133
134HRESULT CpiRollbackConfigureApplicationRoles(
135 LPWSTR* ppwzData,
136 CPI_ROLLBACK_DATA* pRollbackDataList
137 )
138{
139 HRESULT hr = S_OK;
140
141 int iRollbackStatus;
142
143 CPI_APPLICATION_ROLE_ATTRIBUTES attrs;
144 ::ZeroMemory(&attrs, sizeof(attrs));
145
146 // read action text
147 hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
148 ExitOnFailure(hr, "Failed to send action start message");
149
150 // get count
151 int iCnt = 0;
152 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
153 ExitOnFailure(hr, "Failed to read count");
154
155 for (int i = 0; i < iCnt; i++)
156 {
157 // read attributes from CustomActionData
158 hr = ReadApplicationRoleAttributes(ppwzData, &attrs);
159 ExitOnFailure(hr, "Failed to read attributes");
160
161 // rollback status
162 hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
163
164 if (S_FALSE == hr)
165 continue; // not found, nothing to rollback
166
167 // progress message
168 hr = CpiActionDataMessage(1, attrs.pwzName);
169 ExitOnFailure(hr, "Failed to send progress messages");
170
171 if (S_FALSE == hr)
172 ExitFunction();
173
174 // action
175 switch (attrs.iActionType)
176 {
177 case atCreate:
178 hr = CreateApplicationRole(&attrs);
179 if (FAILED(hr))
180 WcaLog(LOGMSG_STANDARD, "Failed to create application role, hr: 0x%x, key: %S", hr, attrs.pwzKey);
181 break;
182 case atRemove:
183 hr = RemoveApplicationRole(&attrs);
184 if (FAILED(hr))
185 WcaLog(LOGMSG_STANDARD, "Failed to remove application role, hr: 0x%x, key: %S", hr, attrs.pwzKey);
186 break;
187 }
188
189 // check rollback status
190 if (0 == iRollbackStatus)
191 continue; // operation did not complete, skip progress
192
193 // progress
194 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
195 ExitOnFailure(hr, "Failed to update progress");
196 }
197
198 hr = S_OK;
199
200LExit:
201 // clean up
202 FreeApplicationRoleAttributes(&attrs);
203
204 return hr;
205}
206
207HRESULT CpiConfigureUsersInApplicationRoles(
208 LPWSTR* ppwzData,
209 HANDLE hRollbackFile
210 )
211{
212 HRESULT hr = S_OK;
213
214 CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES attrs;
215 ::ZeroMemory(&attrs, sizeof(attrs));
216
217 // read action text
218 hr = CpiActionStartMessage(ppwzData, FALSE);
219 ExitOnFailure(hr, "Failed to send action start message");
220
221 // ger count
222 int iCnt = 0;
223 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
224 ExitOnFailure(hr, "Failed to read count");
225
226 // write count to rollback file
227 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
228 ExitOnFailure(hr, "Failed to write count to rollback file");
229
230 for (int i = 0; i < iCnt; i++)
231 {
232 // read attributes from CustomActionData
233 hr = ReadUsersInApplicationRoleAttributes(ppwzData, &attrs);
234 ExitOnFailure(hr, "Failed to read attributes");
235
236 // progress message
237 hr = CpiActionDataMessage(1, attrs.pwzRoleName);
238 ExitOnFailure(hr, "Failed to send progress messages");
239
240 if (S_FALSE == hr)
241 ExitFunction();
242
243 // write key to rollback file
244 hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
245 ExitOnFailure(hr, "Failed to write key to rollback file");
246
247 // action
248 switch (attrs.iActionType)
249 {
250 case atCreate:
251 hr = CreateUsersInApplicationRole(&attrs);
252 ExitOnFailure(hr, "Failed to create user in application role, key: %S", attrs.pwzKey);
253 break;
254 case atRemove:
255 hr = RemoveUsersInApplicationRole(&attrs);
256 ExitOnFailure(hr, "Failed to remove user from application role, key: %S", attrs.pwzKey);
257 break;
258 }
259
260 // write completion status to rollback file
261 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
262 ExitOnFailure(hr, "Failed to write completion status to rollback file");
263
264 // progress
265 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
266 ExitOnFailure(hr, "Failed to update progress");
267 }
268
269 hr = S_OK;
270
271LExit:
272 // clean up
273 FreeUsersInApplicationRoleAttributes(&attrs);
274
275 return hr;
276}
277
278HRESULT CpiRollbackConfigureUsersInApplicationRoles(
279 LPWSTR* ppwzData,
280 CPI_ROLLBACK_DATA* pRollbackDataList
281 )
282{
283 HRESULT hr = S_OK;
284
285 int iRollbackStatus;
286
287 CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES attrs;
288 ::ZeroMemory(&attrs, sizeof(attrs));
289
290 // read action text
291 hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
292 ExitOnFailure(hr, "Failed to send action start message");
293
294 // get count
295 int iCnt = 0;
296 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
297 ExitOnFailure(hr, "Failed to read count");
298
299 for (int i = 0; i < iCnt; i++)
300 {
301 // read attributes from CustomActionData
302 hr = ReadUsersInApplicationRoleAttributes(ppwzData, &attrs);
303 ExitOnFailure(hr, "Failed to read attributes");
304
305 // rollback status
306 hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
307
308 if (S_FALSE == hr)
309 continue; // not found, nothing to rollback
310
311 // progress message
312 hr = CpiActionDataMessage(1, attrs.pwzRoleName);
313 ExitOnFailure(hr, "Failed to send progress messages");
314
315 if (S_FALSE == hr)
316 ExitFunction();
317
318 // action
319 switch (attrs.iActionType)
320 {
321 case atCreate:
322 hr = CreateUsersInApplicationRole(&attrs);
323 if (FAILED(hr))
324 WcaLog(LOGMSG_STANDARD, "Failed to add user to application role, hr: 0x%x, key: %S", hr, attrs.pwzKey);
325 break;
326 case atRemove:
327 hr = RemoveUsersInApplicationRole(&attrs);
328 if (FAILED(hr))
329 WcaLog(LOGMSG_STANDARD, "Failed to remove user from application role, hr: 0x%x, key: %S", hr, attrs.pwzKey);
330 break;
331 }
332
333 // check rollback status
334 if (0 == iRollbackStatus)
335 continue; // operation did not complete, skip progress
336
337 // progress
338 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
339 ExitOnFailure(hr, "Failed to update progress");
340 }
341
342 hr = S_OK;
343
344LExit:
345 // clean up
346 FreeUsersInApplicationRoleAttributes(&attrs);
347
348 return hr;
349}
350
351
352// helper function definitions
353
354static HRESULT ReadApplicationRoleAttributes(
355 LPWSTR* ppwzData,
356 CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs
357 )
358{
359 HRESULT hr = S_OK;
360
361 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
362 ExitOnFailure(hr, "Failed to read action type");
363 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
364 ExitOnFailure(hr, "Failed to read action cost");
365 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
366 ExitOnFailure(hr, "Failed to read key");
367 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzName);
368 ExitOnFailure(hr, "Failed to read name");
369 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAppID);
370 ExitOnFailure(hr, "Failed to read application id");
371 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
372 ExitOnFailure(hr, "Failed to read partition id");
373 hr = CpiReadPropertyList(ppwzData, &pAttrs->pPropList);
374 ExitOnFailure(hr, "Failed to read properties");
375
376 hr = S_OK;
377
378LExit:
379 return hr;
380}
381
382static void FreeApplicationRoleAttributes(
383 CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs
384 )
385{
386 ReleaseStr(pAttrs->pwzKey);
387 ReleaseStr(pAttrs->pwzName);
388 ReleaseStr(pAttrs->pwzAppID);
389 ReleaseStr(pAttrs->pwzPartID);
390
391 if (pAttrs->pPropList)
392 CpiFreePropertyList(pAttrs->pPropList);
393}
394
395static HRESULT CreateApplicationRole(
396 CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs
397 )
398{
399 HRESULT hr = S_OK;
400
401 ICatalogCollection* piRolesColl = NULL;
402 ICatalogObject* piRoleObj = NULL;
403
404 long lChanges = 0;
405
406 // log
407 WcaLog(LOGMSG_VERBOSE, "Creating application role, key: %S", pAttrs->pwzKey);
408
409 // get roles collection
410 hr = CpiGetRolesCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, &piRolesColl);
411 if (S_FALSE == hr)
412 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
413 ExitOnFailure(hr, "Failed to get roles collection");
414
415 // check if role exists
416 hr = CpiFindCollectionObjectByName(piRolesColl, pAttrs->pwzName, &piRoleObj);
417 ExitOnFailure(hr, "Failed to find role");
418
419 if (S_FALSE == hr)
420 {
421 // create role
422 hr = CpiAddCollectionObject(piRolesColl, &piRoleObj);
423 ExitOnFailure(hr, "Failed to add role to collection");
424
425 hr = CpiPutCollectionObjectValue(piRoleObj, L"Name", pAttrs->pwzName);
426 ExitOnFailure(hr, "Failed to set role name property");
427 }
428
429 // properties
430 hr = CpiPutCollectionObjectValues(piRoleObj, pAttrs->pPropList);
431 ExitOnFailure(hr, "Failed to write properties");
432
433 // save changes
434 hr = piRolesColl->SaveChanges(&lChanges);
435 if (COMADMIN_E_OBJECTERRORS == hr)
436 CpiLogCatalogErrorInfo();
437 ExitOnFailure(hr, "Failed to save changes");
438
439 // log
440 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
441
442 hr = S_OK;
443
444LExit:
445 // clean up
446 ReleaseObject(piRolesColl);
447 ReleaseObject(piRoleObj);
448
449 return hr;
450}
451
452static HRESULT RemoveApplicationRole(
453 CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs
454 )
455{
456 HRESULT hr = S_OK;
457
458 ICatalogCollection* piRolesColl = NULL;
459
460 long lChanges = 0;
461
462 // log
463 WcaLog(LOGMSG_VERBOSE, "Removing application role, key: %S", pAttrs->pwzKey);
464
465 // get roles collection
466 hr = CpiGetRolesCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, &piRolesColl);
467 ExitOnFailure(hr, "Failed to get roles collection");
468
469 if (S_FALSE == hr)
470 {
471 // roles collection not found
472 WcaLog(LOGMSG_VERBOSE, "Unable to retrieve roles collection, nothing to delete, key: %S", pAttrs->pwzKey);
473 ExitFunction1(hr = S_OK);
474 }
475
476 // remove
477 hr = CpiRemoveCollectionObject(piRolesColl, NULL, pAttrs->pwzName, FALSE);
478 ExitOnFailure(hr, "Failed to remove role");
479
480 if (S_FALSE == hr)
481 {
482 // role not found
483 WcaLog(LOGMSG_VERBOSE, "Role not found, nothing to delete, key: %S", pAttrs->pwzKey);
484 ExitFunction1(hr = S_OK);
485 }
486
487 // save changes
488 hr = piRolesColl->SaveChanges(&lChanges);
489 if (COMADMIN_E_OBJECTERRORS == hr)
490 CpiLogCatalogErrorInfo();
491 ExitOnFailure(hr, "Failed to save changes");
492
493 // log
494 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
495
496 hr = S_OK;
497
498LExit:
499 // clean up
500 ReleaseObject(piRolesColl);
501
502 return hr;
503}
504
505static HRESULT ReadUsersInApplicationRoleAttributes(
506 LPWSTR* ppwzData,
507 CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs
508 )
509{
510 HRESULT hr = S_OK;
511
512 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
513 ExitOnFailure(hr, "Failed to read action type");
514 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
515 ExitOnFailure(hr, "Failed to read action cost");
516 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
517 ExitOnFailure(hr, "Failed to read key");
518 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzRoleName);
519 ExitOnFailure(hr, "Failed to read role name");
520 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAccount);
521 ExitOnFailure(hr, "Failed to read account name");
522 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAppID);
523 ExitOnFailure(hr, "Failed to read application id");
524 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
525 ExitOnFailure(hr, "Failed to read partition id");
526
527 hr = S_OK;
528
529LExit:
530 return hr;
531}
532
533static void FreeUsersInApplicationRoleAttributes(
534 CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs
535 )
536{
537 ReleaseStr(pAttrs->pwzKey);
538 ReleaseStr(pAttrs->pwzRoleName);
539 ReleaseStr(pAttrs->pwzAccount);
540 ReleaseStr(pAttrs->pwzAppID);
541 ReleaseStr(pAttrs->pwzPartID);
542}
543
544static HRESULT CreateUsersInApplicationRole(
545 CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs
546 )
547{
548 HRESULT hr = S_OK;
549 UINT er = ERROR_SUCCESS;
550
551 ICatalogCollection* piUsrInRoleColl = NULL;
552 ICatalogObject* piUsrInRoleObj = NULL;
553
554 PSID pSid = NULL;
555 long lChanges = 0;
556
557 // log
558 WcaLog(LOGMSG_VERBOSE, "Adding user to application role, key: %S", pAttrs->pwzKey);
559
560 // get users in role collection
561 hr = CpiGetUsersInRoleCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, pAttrs->pwzRoleName, &piUsrInRoleColl);
562 if (S_FALSE == hr)
563 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
564 ExitOnFailure(hr, "Failed to get users in role collection");
565
566 // get SID for account
567 do {
568 er = ERROR_SUCCESS;
569 hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid);
570 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
571 {
572 WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount);
573 er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
574 switch (er)
575 {
576 case IDABORT:
577 ExitFunction(); // exit with error code from CpiAccountNameToSid()
578 case IDRETRY:
579 break;
580 case IDIGNORE:
581 default:
582 ExitFunction1(hr = S_OK);
583 }
584 }
585 else
586 ExitOnFailure(hr, "Failed to get SID for account");
587 } while (IDRETRY == er);
588
589 // find any existing entry
590 hr = CpiFindUserCollectionObject(piUsrInRoleColl, pSid, NULL);
591 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr)
592 WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr);
593 else
594 ExitOnFailure(hr, "Failed to find user in application role");
595
596 if (S_OK == hr)
597 {
598 WcaLog(LOGMSG_VERBOSE, "User already assigned to application role, key: %S", pAttrs->pwzKey);
599 ExitFunction(); // exit with hr = S_OK
600 }
601
602 // convert SID back to account name
603 hr = CpiSidToAccountName(pSid, &pAttrs->pwzAccount);
604 ExitOnFailure(hr, "Failed to convert SID to account name");
605
606 // add user
607 hr = CpiAddCollectionObject(piUsrInRoleColl, &piUsrInRoleObj);
608 ExitOnFailure(hr, "Failed to add user in role to collection");
609
610 hr = CpiPutCollectionObjectValue(piUsrInRoleObj, L"User", pAttrs->pwzAccount);
611 ExitOnFailure(hr, "Failed to set role name property");
612
613 // save changes
614 hr = piUsrInRoleColl->SaveChanges(&lChanges);
615 if (COMADMIN_E_OBJECTERRORS == hr)
616 CpiLogCatalogErrorInfo();
617 ExitOnFailure(hr, "Failed to save changes");
618
619 // log
620 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
621
622 hr = S_OK;
623
624LExit:
625 // clean up
626 ReleaseObject(piUsrInRoleColl);
627 ReleaseObject(piUsrInRoleObj);
628
629 if (pSid)
630 ::HeapFree(::GetProcessHeap(), 0, pSid);
631
632 return hr;
633}
634
635static HRESULT RemoveUsersInApplicationRole(
636 CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs
637 )
638{
639 HRESULT hr = S_OK;
640 UINT er = ERROR_SUCCESS;
641
642 ICatalogCollection* piUsrInRoleColl = NULL;
643
644 PSID pSid = NULL;
645 long lChanges = 0;
646
647 // log
648 WcaLog(LOGMSG_VERBOSE, "Removing user from application role, key: %S", pAttrs->pwzKey);
649
650 // get users in role collection
651 hr = CpiGetUsersInRoleCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, pAttrs->pwzRoleName, &piUsrInRoleColl);
652 ExitOnFailure(hr, "Failed to get users in role collection");
653
654 if (S_FALSE == hr)
655 {
656 // users in role collection not found
657 WcaLog(LOGMSG_VERBOSE, "Unable to retrieve users in role collection, nothing to delete, key: %S", pAttrs->pwzKey);
658 ExitFunction1(hr = S_OK);
659 }
660
661 // get SID for account
662 do {
663 er = ERROR_SUCCESS;
664 hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid);
665 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
666 {
667 WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount);
668 er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
669 switch (er)
670 {
671 case IDABORT:
672 ExitFunction(); // exit with error code from CpiAccountNameToSid()
673 case IDRETRY:
674 break;
675 case IDIGNORE:
676 default:
677 ExitFunction1(hr = S_OK);
678 }
679 }
680 else
681 ExitOnFailure(hr, "Failed to get SID for account");
682 } while (IDRETRY == er);
683
684 // remove
685 hr = CpiRemoveUserCollectionObject(piUsrInRoleColl, pSid);
686 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr)
687 {
688 WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr);
689 hr = S_FALSE;
690 }
691 else
692 ExitOnFailure(hr, "Failed to remove user");
693
694 if (S_FALSE == hr)
695 {
696 // role not found
697 WcaLog(LOGMSG_VERBOSE, "User not found for application role, nothing to delete, key: %S", pAttrs->pwzKey);
698 ExitFunction1(hr = S_OK);
699 }
700
701 // save changes
702 hr = piUsrInRoleColl->SaveChanges(&lChanges);
703 if (COMADMIN_E_OBJECTERRORS == hr)
704 CpiLogCatalogErrorInfo();
705 ExitOnFailure(hr, "Failed to save changes");
706
707 // log
708 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
709
710 hr = S_OK;
711
712LExit:
713 // clean up
714 ReleaseObject(piUsrInRoleColl);
715
716 if (pSid)
717 ::HeapFree(::GetProcessHeap(), 0, pSid);
718
719 return hr;
720}
diff --git a/src/ext/ComPlus/ca/cpapproleexec.h b/src/ext/ComPlus/ca/cpapproleexec.h
new file mode 100644
index 00000000..1251cbdb
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpapproleexec.h
@@ -0,0 +1,20 @@
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
5HRESULT CpiConfigureApplicationRoles(
6 LPWSTR* ppwzData,
7 HANDLE hRollbackFile
8 );
9HRESULT CpiRollbackConfigureApplicationRoles(
10 LPWSTR* ppwzData,
11 CPI_ROLLBACK_DATA* pRollbackDataList
12 );
13HRESULT CpiConfigureUsersInApplicationRoles(
14 LPWSTR* ppwzData,
15 HANDLE hRollbackFile
16 );
17HRESULT CpiRollbackConfigureUsersInApplicationRoles(
18 LPWSTR* ppwzData,
19 CPI_ROLLBACK_DATA* pRollbackDataList
20 );
diff --git a/src/ext/ComPlus/ca/cpapprolesched.cpp b/src/ext/ComPlus/ca/cpapprolesched.cpp
new file mode 100644
index 00000000..a268d156
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpapprolesched.cpp
@@ -0,0 +1,843 @@
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// sql queries
7
8LPCWSTR vcsApplicationRoleQuery =
9 L"SELECT `ApplicationRole`, `Application_`, `Component_`, `Name` FROM `ComPlusApplicationRole`";
10enum eApplicationRoleQuery { arqApplicationRole = 1, arqApplication, arqComponent, arqName };
11
12LPCWSTR vcsUserInApplicationRoleQuery =
13 L"SELECT `UserInApplicationRole`, `ApplicationRole_`, `ComPlusUserInApplicationRole`.`Component_`, `Domain`, `Name` FROM `ComPlusUserInApplicationRole`, `User` WHERE `User_` = `User`";
14LPCWSTR vcsGroupInApplicationRoleQuery =
15 L"SELECT `GroupInApplicationRole`, `ApplicationRole_`, `ComPlusGroupInApplicationRole`.`Component_`, `Domain`, `Name` FROM `ComPlusGroupInApplicationRole`, `Group` WHERE `Group_` = `Group`";
16enum eTrusteeInApplicationRoleQuery { tiarqUserInApplicationRole = 1, tiarqApplicationRole, tiarqComponent, tiarqDomain, tiarqName };
17
18LPCWSTR vcsApplicationRolePropertyQuery =
19 L"SELECT `Name`, `Value` FROM `ComPlusApplicationRoleProperty` WHERE `ApplicationRole_` = ?";
20
21
22// property definitions
23
24CPI_PROPERTY_DEFINITION pdlApplicationRoleProperties[] =
25{
26 {L"Description", cpptString, 500},
27 {NULL, cpptNone, 0}
28};
29
30
31// prototypes for private helper functions
32
33static HRESULT TrusteesInApplicationRolesRead(
34 LPCWSTR pwzQuery,
35 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
36 CPI_USER_IN_APPLICATION_ROLE_LIST* pUsrInAppRoleList
37 );
38static void FreeApplicationRole(
39 CPI_APPLICATION_ROLE* pItm
40 );
41static void FreeUserInApplicationRole(
42 CPI_USER_IN_APPLICATION_ROLE* pItm
43 );
44//static HRESULT GetUsersCollForApplicationRole(
45// CPI_APPLICATION_ROLE* pAppRole,
46// ICatalogCollection** ppiUsersColl
47// );
48static HRESULT FindObjectForApplicationRole(
49 CPI_APPLICATION_ROLE* pItm,
50 ICatalogObject** ppiRoleObj
51 );
52static HRESULT AddApplicationRoleToActionData(
53 CPI_APPLICATION_ROLE* pItm,
54 int iActionType,
55 int iActionCost,
56 LPWSTR* ppwzActionData
57 );
58static HRESULT AddUserInApplicationRoleToActionData(
59 CPI_USER_IN_APPLICATION_ROLE* pItm,
60 int iActionType,
61 int iActionCost,
62 LPWSTR* ppwzActionData
63 );
64
65
66// function definitions
67
68void CpiApplicationRoleListFree(
69 CPI_APPLICATION_ROLE_LIST* pList
70 )
71{
72 CPI_APPLICATION_ROLE* pItm = pList->pFirst;
73
74 while (pItm)
75 {
76 CPI_APPLICATION_ROLE* pDelete = pItm;
77 pItm = pItm->pNext;
78 FreeApplicationRole(pDelete);
79 }
80}
81
82HRESULT CpiApplicationRolesRead(
83 CPI_APPLICATION_LIST* pAppList,
84 CPI_APPLICATION_ROLE_LIST* pAppRoleList
85 )
86{
87 HRESULT hr = S_OK;
88 UINT er = ERROR_SUCCESS;
89
90 PMSIHANDLE hView, hRec;
91
92 CPI_APPLICATION_ROLE* pItm = NULL;
93 LPWSTR pwzData = NULL;
94 BOOL fMatchingArchitecture = FALSE;
95
96 // loop through all application roles
97 hr = WcaOpenExecuteView(vcsApplicationRoleQuery, &hView);
98 ExitOnFailure(hr, "Failed to execute view on ComPlusApplicationRole table");
99
100 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
101 {
102 // get component
103 hr = WcaGetRecordString(hRec, arqComponent, &pwzData);
104 ExitOnFailure(hr, "Failed to get component");
105
106 // check if the component is our processor architecture
107 if (pwzData && *pwzData)
108 {
109 hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture);
110 ExitOnFailure(hr, "Failed to get component architecture.");
111
112 if (!fMatchingArchitecture)
113 {
114 continue; // not the same architecture, ignore
115 }
116 }
117
118 // create entry
119 pItm = (CPI_APPLICATION_ROLE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_APPLICATION_ROLE));
120 if (!pItm)
121 ExitFunction1(hr = E_OUTOFMEMORY);
122
123 // get component install state
124 if (pwzData && *pwzData)
125 {
126 pItm->fHasComponent = TRUE;
127
128 er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction);
129 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
130 }
131
132 // get key
133 hr = WcaGetRecordString(hRec, arqApplicationRole, &pwzData);
134 ExitOnFailure(hr, "Failed to get key");
135 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
136
137 // get application
138 hr = WcaGetRecordString(hRec, arqApplication, &pwzData);
139 ExitOnFailure(hr, "Failed to get application");
140
141 hr = CpiApplicationFindByKey(pAppList, pwzData, &pItm->pApplication);
142 if (S_FALSE == hr)
143 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
144 ExitOnFailure(hr, "Failed to find application, key: %S", pwzData);
145
146 // get name
147 hr = WcaGetRecordFormattedString(hRec, arqName, &pwzData);
148 ExitOnFailure(hr, "Failed to get name");
149 StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData);
150
151 // get properties
152 if (CpiTableExists(cptComPlusApplicationRoleProperty))
153 {
154 hr = CpiPropertiesRead(vcsApplicationRolePropertyQuery, pItm->wzKey, pdlApplicationRoleProperties, &pItm->pProperties, &pItm->iPropertyCount);
155 ExitOnFailure(hr, "Failed to get properties");
156 }
157
158 // set references & increment counters
159 if (pItm->fHasComponent)
160 {
161 if (WcaIsInstalling(pItm->isInstalled, pItm->isAction))
162 {
163 CpiApplicationAddReferenceInstall(pItm->pApplication);
164 pAppRoleList->iInstallCount++;
165 }
166 if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
167 {
168 CpiApplicationAddReferenceUninstall(pItm->pApplication);
169 pAppRoleList->iUninstallCount++;
170 }
171 }
172
173 // add entry
174 if (pAppRoleList->pFirst)
175 pItm->pNext = pAppRoleList->pFirst;
176 pAppRoleList->pFirst = pItm;
177 pItm = NULL;
178 }
179
180 if (E_NOMOREITEMS == hr)
181 hr = S_OK;
182
183LExit:
184 // clean up
185 if (pItm)
186 FreeApplicationRole(pItm);
187
188 ReleaseStr(pwzData);
189
190 return hr;
191}
192
193HRESULT CpiApplicationRolesVerifyInstall(
194 CPI_APPLICATION_ROLE_LIST* pList
195 )
196{
197 HRESULT hr = S_OK;
198 UINT er = ERROR_SUCCESS;
199
200 ICatalogObject* piRoleObj = NULL;
201
202 for (CPI_APPLICATION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
203 {
204 // referenced locaters or roles that are being installed
205 if (!pItm->fReferencedForInstall && !(pItm->fHasComponent && WcaIsInstalling(pItm->isInstalled, pItm->isAction)))
206 continue;
207
208 // if the role is referensed and is not a locater, it must be installed
209 if (pItm->fReferencedForInstall && pItm->fHasComponent && !CpiWillBeInstalled(pItm->isInstalled, pItm->isAction))
210 MessageExitOnFailure(hr = E_FAIL, msierrComPlusApplicationRoleDependency, "An application role is used by another entity being installed, but is not installed itself, key: %S", pItm->wzKey);
211
212 // role is a locater
213 if (!pItm->fHasComponent)
214 {
215 // get collection object for role
216 hr = FindObjectForApplicationRole(pItm, &piRoleObj);
217 ExitOnFailure(hr, "Failed to find collection object for role");
218
219 // if the role was not found
220 if (S_FALSE == hr)
221 MessageExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), msierrComPlusApplicationRoleNotFound, "An application role required by this installation was not found, key: %S", pItm->wzKey);
222 }
223
224 // role is supposed to be created
225 else if (!CpiIsInstalled(pItm->isInstalled))
226 {
227 do {
228 // find roles with conflicting name or id
229 hr = FindObjectForApplicationRole(pItm, NULL);
230 ExitOnFailure(hr, "Failed to find collection object for role");
231
232 if (S_OK == hr)
233 {
234 er = WcaErrorMessage(msierrComPlusApplicationRoleConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
235 switch (er)
236 {
237 case IDABORT:
238 ExitOnFailure(hr = E_FAIL, "An application with a conflictiong name exists, key: %S", pItm->wzKey);
239 break;
240 case IDRETRY:
241 break;
242 case IDIGNORE:
243 default:
244 hr = S_FALSE; // indicate that this is not a conflict
245 }
246 }
247 } while (S_OK == hr); // hr = S_FALSE if we don't have any conflicts
248 }
249
250 // clean up
251 ReleaseNullObject(piRoleObj);
252 }
253
254 hr = S_OK;
255
256LExit:
257 // clean up
258 ReleaseObject(piRoleObj);
259
260 return hr;
261}
262
263HRESULT CpiApplicationRolesVerifyUninstall(
264 CPI_APPLICATION_ROLE_LIST* pList
265 )
266{
267 HRESULT hr = S_OK;
268
269 for (CPI_APPLICATION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
270 {
271 // referenced locaters or roles that are being installed
272 if (!pItm->fReferencedForUninstall && !(pItm->fHasComponent && WcaIsUninstalling(pItm->isInstalled, pItm->isAction)))
273 continue;
274
275 // get collection object for role
276 hr = FindObjectForApplicationRole(pItm, NULL);
277 ExitOnFailure(hr, "Failed to find collection object for role");
278
279 // if the role was not found
280 if (S_FALSE == hr)
281 {
282 pItm->fObjectNotFound = TRUE;
283 if (pItm->fHasComponent)
284 pList->iUninstallCount--; // elements with the fObjectNotFound flag set will not be scheduled for uninstall
285 }
286 }
287
288 hr = S_OK;
289
290LExit:
291 return hr;
292}
293
294void CpiApplicationRoleAddReferenceInstall(
295 CPI_APPLICATION_ROLE* pItm
296 )
297{
298 pItm->fReferencedForInstall = TRUE;
299 CpiApplicationAddReferenceInstall(pItm->pApplication);
300}
301
302void CpiApplicationRoleAddReferenceUninstall(
303 CPI_APPLICATION_ROLE* pItm
304 )
305{
306 pItm->fReferencedForUninstall = TRUE;
307 CpiApplicationAddReferenceUninstall(pItm->pApplication);
308}
309
310HRESULT CpiApplicationRolesInstall(
311 CPI_APPLICATION_ROLE_LIST* pList,
312 int iRunMode,
313 LPWSTR* ppwzActionData,
314 int* piProgress
315 )
316{
317 HRESULT hr = S_OK;
318
319 int iActionType;
320
321 // add action text
322 hr = CpiAddActionTextToActionData(L"CreateComPlusApplicationRoles", ppwzActionData);
323 ExitOnFailure(hr, "Failed to add action text to custom action data");
324
325 // add count to action data
326 hr = WcaWriteIntegerToCaData(pList->iInstallCount, ppwzActionData);
327 ExitOnFailure(hr, "Failed to add count to custom action data");
328
329 // add roles to custom action data
330 for (CPI_APPLICATION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
331 {
332 // roles that are being installed only
333 if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction))
334 continue;
335
336 // action type
337 if (rmRollback == iRunMode)
338 {
339 if (CpiIsInstalled(pItm->isInstalled))
340 iActionType = atNoOp;
341 else
342 iActionType = atRemove;
343 }
344 else
345 iActionType = atCreate;
346
347 // add to action data
348 hr = AddApplicationRoleToActionData(pItm, iActionType, COST_APPLICATION_ROLE_CREATE, ppwzActionData);
349 ExitOnFailure(hr, "Failed to add application role to custom action data, key: %S", pItm->wzKey);
350 }
351
352 // add progress tics
353 if (piProgress)
354 *piProgress += COST_APPLICATION_ROLE_CREATE * pList->iInstallCount;
355
356 hr = S_OK;
357
358LExit:
359 return hr;
360}
361
362HRESULT CpiApplicationRolesUninstall(
363 CPI_APPLICATION_ROLE_LIST* pList,
364 int iRunMode,
365 LPWSTR* ppwzActionData,
366 int* piProgress
367 )
368{
369 HRESULT hr = S_OK;
370
371 int iActionType;
372
373 // add action text
374 hr = CpiAddActionTextToActionData(L"RemoveComPlusApplicationRoles", ppwzActionData);
375 ExitOnFailure(hr, "Failed to add action text to custom action data");
376
377 // add count to action data
378 hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData);
379 ExitOnFailure(hr, "Failed to add count to custom action data");
380
381 // add roles to custom action data
382 for (CPI_APPLICATION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
383 {
384 // roles that are being uninstalled only
385 if (pItm->fObjectNotFound || !WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
386 continue;
387
388 // action type
389 if (rmRollback == iRunMode)
390 iActionType = atCreate;
391 else
392 iActionType = atRemove;
393
394 // add to action data
395 hr = AddApplicationRoleToActionData(pItm, iActionType, COST_APPLICATION_ROLE_DELETE, ppwzActionData);
396 ExitOnFailure(hr, "Failed to add application role to custom action data, key: %S", pItm->wzKey);
397 }
398
399 // add progress tics
400 if (piProgress)
401 *piProgress += COST_APPLICATION_ROLE_DELETE * pList->iUninstallCount;
402
403 hr = S_OK;
404
405LExit:
406 return hr;
407}
408
409HRESULT CpiApplicationRoleFindByKey(
410 CPI_APPLICATION_ROLE_LIST* pList,
411 LPCWSTR pwzKey,
412 CPI_APPLICATION_ROLE** ppAppRole
413 )
414{
415 for (CPI_APPLICATION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
416 {
417 if (0 == lstrcmpW(pItm->wzKey, pwzKey))
418 {
419 *ppAppRole = pItm;
420 return S_OK;
421 }
422 }
423
424 return S_FALSE;
425}
426
427void CpiUserInApplicationRoleListFree(
428 CPI_USER_IN_APPLICATION_ROLE_LIST* pList
429 )
430{
431 CPI_USER_IN_APPLICATION_ROLE* pItm = pList->pFirst;
432
433 while (pItm)
434 {
435 CPI_USER_IN_APPLICATION_ROLE* pDelete = pItm;
436 pItm = pItm->pNext;
437 FreeUserInApplicationRole(pDelete);
438 }
439}
440
441HRESULT CpiUsersInApplicationRolesRead(
442 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
443 CPI_USER_IN_APPLICATION_ROLE_LIST* pUsrInAppRoleList
444 )
445{
446 HRESULT hr = S_OK;
447
448 // read users in application roles
449 if (CpiTableExists(cptComPlusUserInApplicationRole))
450 {
451 hr = TrusteesInApplicationRolesRead(vcsUserInApplicationRoleQuery, pAppRoleList, pUsrInAppRoleList);
452 ExitOnFailure(hr, "Failed to read users in application roles");
453 }
454
455 // read groups in application roles
456 if (CpiTableExists(cptComPlusGroupInApplicationRole))
457 {
458 hr = TrusteesInApplicationRolesRead(vcsGroupInApplicationRoleQuery, pAppRoleList, pUsrInAppRoleList);
459 ExitOnFailure(hr, "Failed to read groups in application roles");
460 }
461
462 hr = S_OK;
463
464LExit:
465 return hr;
466}
467
468HRESULT CpiUsersInApplicationRolesInstall(
469 CPI_USER_IN_APPLICATION_ROLE_LIST* pList,
470 int iRunMode,
471 LPWSTR* ppwzActionData,
472 int* piProgress
473 )
474{
475 HRESULT hr = S_OK;
476
477 int iActionType;
478
479 // add action text
480 hr = CpiAddActionTextToActionData(L"AddUsersToComPlusApplicationRoles", ppwzActionData);
481 ExitOnFailure(hr, "Failed to add action text to custom action data");
482
483 // add count to action data
484 hr = WcaWriteIntegerToCaData(pList->iInstallCount, ppwzActionData);
485 ExitOnFailure(hr, "Failed to add count to custom action data");
486
487 // add roles to custom action data
488 for (CPI_USER_IN_APPLICATION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
489 {
490 // roles that are being installed only
491 if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction))
492 continue;
493
494 // action type
495 if (rmRollback == iRunMode)
496 {
497 if (CpiIsInstalled(pItm->isInstalled))
498 iActionType = atNoOp;
499 else
500 iActionType = atRemove;
501 }
502 else
503 iActionType = atCreate;
504
505 // add to action data
506 hr = AddUserInApplicationRoleToActionData(pItm, iActionType, COST_USER_IN_APPLICATION_ROLE_CREATE, ppwzActionData);
507 ExitOnFailure(hr, "Failed to add user in application role to custom action data, key: %S", pItm->wzKey);
508 }
509
510 // add progress tics
511 if (piProgress)
512 *piProgress += COST_USER_IN_APPLICATION_ROLE_CREATE * pList->iInstallCount;
513
514 hr = S_OK;
515
516LExit:
517 return hr;
518}
519
520HRESULT CpiUsersInApplicationRolesUninstall(
521 CPI_USER_IN_APPLICATION_ROLE_LIST* pList,
522 int iRunMode,
523 LPWSTR* ppwzActionData,
524 int* piProgress
525 )
526{
527 HRESULT hr = S_OK;
528
529 int iActionType;
530
531 // add action text
532 hr = CpiAddActionTextToActionData(L"RemoveUsersFromComPlusAppRoles", ppwzActionData);
533 ExitOnFailure(hr, "Failed to add action text to custom action data");
534
535 // add count to action data
536 hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData);
537 ExitOnFailure(hr, "Failed to add count to custom action data");
538
539 // add roles to custom action data
540 for (CPI_USER_IN_APPLICATION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
541 {
542 // roles that are being uninstalled only
543 if (!WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
544 continue;
545
546 // action type
547 if (rmRollback == iRunMode)
548 iActionType = atCreate;
549 else
550 iActionType = atRemove;
551
552 // add to action data
553 hr = AddUserInApplicationRoleToActionData(pItm, iActionType, COST_USER_IN_APPLICATION_ROLE_DELETE, ppwzActionData);
554 ExitOnFailure(hr, "Failed to add user in application role to custom action data, key: %S", pItm->wzKey);
555 }
556
557 // add progress tics
558 if (piProgress)
559 *piProgress += COST_USER_IN_APPLICATION_ROLE_DELETE * pList->iUninstallCount;
560
561 hr = S_OK;
562
563LExit:
564 return hr;
565}
566
567
568// helper function definitions
569
570static HRESULT TrusteesInApplicationRolesRead(
571 LPCWSTR pwzQuery,
572 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
573 CPI_USER_IN_APPLICATION_ROLE_LIST* pUsrInAppRoleList
574 )
575{
576 HRESULT hr = S_OK;
577 UINT er = ERROR_SUCCESS;
578
579 PMSIHANDLE hView, hRec;
580
581 CPI_USER_IN_APPLICATION_ROLE* pItm = NULL;
582 LPWSTR pwzData = NULL;
583 LPWSTR pwzDomain = NULL;
584 LPWSTR pwzName = NULL;
585 BOOL fMatchingArchitecture = FALSE;
586
587 // loop through all application roles
588 hr = WcaOpenExecuteView(pwzQuery, &hView);
589 ExitOnFailure(hr, "Failed to execute view on table");
590
591 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
592 {
593 // get component
594 hr = WcaGetRecordString(hRec, tiarqComponent, &pwzData);
595 ExitOnFailure(hr, "Failed to get component");
596
597 // check if the component is our processor architecture
598 hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture);
599 ExitOnFailure(hr, "Failed to get component architecture.");
600
601 if (!fMatchingArchitecture)
602 {
603 continue; // not the same architecture, ignore
604 }
605
606 // create entry
607 pItm = (CPI_USER_IN_APPLICATION_ROLE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_USER_IN_APPLICATION_ROLE));
608 if (!pItm)
609 ExitFunction1(hr = E_OUTOFMEMORY);
610
611 // get component install state
612 er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction);
613 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
614
615 // get key
616 hr = WcaGetRecordString(hRec, tiarqUserInApplicationRole, &pwzData);
617 ExitOnFailure(hr, "Failed to get key");
618 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
619
620 // get application role
621 hr = WcaGetRecordString(hRec, tiarqApplicationRole, &pwzData);
622 ExitOnFailure(hr, "Failed to get application role");
623
624 hr = CpiApplicationRoleFindByKey(pAppRoleList, pwzData, &pItm->pApplicationRole);
625 if (S_FALSE == hr)
626 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
627 ExitOnFailure(hr, "Failed to find application role, key: %S", pwzData);
628
629 // get user domain
630 hr = WcaGetRecordFormattedString(hRec, tiarqDomain, &pwzDomain);
631 ExitOnFailure(hr, "Failed to get domain");
632
633 // get user name
634 hr = WcaGetRecordFormattedString(hRec, tiarqName, &pwzName);
635 ExitOnFailure(hr, "Failed to get name");
636
637 // build account name
638 hr = CpiBuildAccountName(pwzDomain, pwzName, &pItm->pwzAccount);
639 ExitOnFailure(hr, "Failed to build account name");
640
641 // set references & increment counters
642 if (WcaIsInstalling(pItm->isInstalled, pItm->isAction))
643 {
644 CpiApplicationRoleAddReferenceInstall(pItm->pApplicationRole);
645 pUsrInAppRoleList->iInstallCount++;
646 }
647 if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
648 {
649 CpiApplicationRoleAddReferenceUninstall(pItm->pApplicationRole);
650 pUsrInAppRoleList->iUninstallCount++;
651 }
652
653 // add entry
654 if (pUsrInAppRoleList->pFirst)
655 pItm->pNext = pUsrInAppRoleList->pFirst;
656 pUsrInAppRoleList->pFirst = pItm;
657 pItm = NULL;
658 }
659
660 if (E_NOMOREITEMS == hr)
661 hr = S_OK;
662
663LExit:
664 // clean up
665 if (pItm)
666 FreeUserInApplicationRole(pItm);
667
668 ReleaseStr(pwzData);
669 ReleaseStr(pwzDomain);
670 ReleaseStr(pwzName);
671
672 return hr;
673}
674
675static void FreeApplicationRole(
676 CPI_APPLICATION_ROLE* pItm
677 )
678{
679 if (pItm->pProperties)
680 CpiPropertiesFreeList(pItm->pProperties);
681
682 ReleaseObject(pItm->piUsersColl);
683
684 ::HeapFree(::GetProcessHeap(), 0, pItm);
685}
686
687static void FreeUserInApplicationRole(
688 CPI_USER_IN_APPLICATION_ROLE* pItm
689 )
690{
691 ReleaseStr(pItm->pwzAccount);
692
693 ::HeapFree(::GetProcessHeap(), 0, pItm);
694}
695
696//static HRESULT GetUsersCollForApplicationRole(
697// CPI_APPLICATION_ROLE* pAppRole,
698// ICatalogCollection** ppiUsersColl
699// )
700//{
701// HRESULT hr = S_OK;
702//
703// ICatalogCollection* piRoleColl = NULL;
704// ICatalogObject* piRoleObj = NULL;
705//
706// // if a previous attempt to locate the collection object failed
707// if (pAppRole->fObjectNotFound)
708// ExitFunction1(hr = S_FALSE);
709//
710// // get applications collection
711// if (!pAppRole->piUsersColl)
712// {
713// // get collection object for role
714// hr = FindObjectForApplicationRole(pAppRole, &piRoleObj);
715// ExitOnFailure(hr, "Failed to find collection object for role");
716//
717// if (S_FALSE == hr)
718// ExitFunction(); // exit with hr = S_FALSE
719//
720// // get users collection
721// hr = CpiGetCatalogCollection(piRoleColl, piRoleObj, L"UsersInRole", &pAppRole->piUsersColl);
722// ExitOnFailure(hr, "Failed to get users in role collection");
723// }
724//
725// // return value
726// *ppiUsersColl = pAppRole->piUsersColl;
727// (*ppiUsersColl)->AddRef();
728//
729// hr = S_OK;
730//
731//LExit:
732// // clean up
733// ReleaseObject(piRoleColl);
734// ReleaseObject(piRoleObj);
735//
736// return hr;
737//}
738
739static HRESULT FindObjectForApplicationRole(
740 CPI_APPLICATION_ROLE* pItm,
741 ICatalogObject** ppiRoleObj
742 )
743{
744 HRESULT hr = S_OK;
745
746 ICatalogCollection* piRoleColl = NULL;
747
748 // get roles collection
749 hr = CpiGetRolesCollForApplication(pItm->pApplication, &piRoleColl);
750 ExitOnFailure(hr, "Failed to get collection");
751
752 if (S_FALSE == hr)
753 ExitFunction(); // exit with hr = S_FALSE
754
755 // find role object
756 hr = CpiFindCollectionObject(piRoleColl, NULL, pItm->wzName, ppiRoleObj);
757 ExitOnFailure(hr, "Failed to find object");
758
759 // exit with hr from CpiFindCollectionObject()
760
761LExit:
762 // clean up
763 ReleaseObject(piRoleColl);
764
765 return hr;
766}
767
768static HRESULT AddApplicationRoleToActionData(
769 CPI_APPLICATION_ROLE* pItm,
770 int iActionType,
771 int iActionCost,
772 LPWSTR* ppwzActionData
773 )
774{
775 HRESULT hr = S_OK;
776
777 // add action information to custom action data
778 hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
779 ExitOnFailure(hr, "Failed to add action type to custom action data");
780 hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
781 ExitOnFailure(hr, "Failed to add action cost to custom action data");
782
783 // add application role information to custom action data
784 hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
785 ExitOnFailure(hr, "Failed to add application role key to custom action data");
786 hr = WcaWriteStringToCaData(pItm->wzName, ppwzActionData);
787 ExitOnFailure(hr, "Failed to add application role name to custom action data");
788
789 // add application information to custom action data
790 hr = WcaWriteStringToCaData(pItm->pApplication->wzID, ppwzActionData);
791 ExitOnFailure(hr, "Failed to add application id to custom action data");
792
793 // add partition information to custom action data
794 hr = WcaWriteStringToCaData(pItm->pApplication->pPartition ? pItm->pApplication->pPartition->wzID : L"", ppwzActionData);
795 ExitOnFailure(hr, "Failed to add partition id to custom action data");
796
797 // add properties to custom action data
798 hr = CpiAddPropertiesToActionData(atCreate == iActionType ? pItm->iPropertyCount : 0, pItm->pProperties, ppwzActionData);
799 ExitOnFailure(hr, "Failed to add properties to custom action data");
800
801 hr = S_OK;
802
803LExit:
804 return hr;
805}
806
807static HRESULT AddUserInApplicationRoleToActionData(
808 CPI_USER_IN_APPLICATION_ROLE* pItm,
809 int iActionType,
810 int iActionCost,
811 LPWSTR* ppwzActionData
812 )
813{
814 HRESULT hr = S_OK;
815
816 // add action information to custom action data
817 hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
818 ExitOnFailure(hr, "Failed to add action type to custom action data");
819 hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
820 ExitOnFailure(hr, "Failed to add action cost to custom action data");
821
822 // add application role information to custom action data
823 hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
824 ExitOnFailure(hr, "Failed to add key to custom action data");
825 hr = WcaWriteStringToCaData(pItm->pApplicationRole->wzName, ppwzActionData);
826 ExitOnFailure(hr, "Failed to add role name to custom action data");
827 hr = WcaWriteStringToCaData(pItm->pwzAccount, ppwzActionData);
828 ExitOnFailure(hr, "Failed to add user account to custom action data");
829
830 // add application information to custom action data
831 CPI_APPLICATION* pApplication = pItm->pApplicationRole->pApplication;
832 hr = WcaWriteStringToCaData(pApplication->wzID, ppwzActionData);
833 ExitOnFailure(hr, "Failed to add application id to custom action data");
834
835 // add partition information to custom action data
836 hr = WcaWriteStringToCaData(pApplication->pPartition ? pApplication->pPartition->wzID : L"", ppwzActionData);
837 ExitOnFailure(hr, "Failed to add partition id to custom action data");
838
839 hr = S_OK;
840
841LExit:
842 return hr;
843}
diff --git a/src/ext/ComPlus/ca/cpapprolesched.h b/src/ext/ComPlus/ca/cpapprolesched.h
new file mode 100644
index 00000000..02852eef
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpapprolesched.h
@@ -0,0 +1,112 @@
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
5struct CPI_APPLICATION_ROLE
6{
7 WCHAR wzKey[MAX_DARWIN_KEY + 1];
8 WCHAR wzName[MAX_DARWIN_COLUMN + 1];
9
10 int iPropertyCount;
11 CPI_PROPERTY* pProperties;
12
13 BOOL fHasComponent;
14 BOOL fReferencedForInstall;
15 BOOL fReferencedForUninstall;
16 BOOL fObjectNotFound;
17
18 INSTALLSTATE isInstalled, isAction;
19
20 CPI_APPLICATION* pApplication;
21
22 ICatalogCollection* piUsersColl;
23
24 CPI_APPLICATION_ROLE* pNext;
25};
26
27struct CPI_APPLICATION_ROLE_LIST
28{
29 CPI_APPLICATION_ROLE* pFirst;
30
31 int iInstallCount;
32 int iUninstallCount;
33};
34
35struct CPI_USER_IN_APPLICATION_ROLE
36{
37 WCHAR wzKey[MAX_DARWIN_KEY + 1];
38 LPWSTR pwzAccount;
39
40 INSTALLSTATE isInstalled, isAction;
41
42 CPI_APPLICATION_ROLE* pApplicationRole;
43
44 CPI_USER_IN_APPLICATION_ROLE* pNext;
45};
46
47struct CPI_USER_IN_APPLICATION_ROLE_LIST
48{
49 CPI_USER_IN_APPLICATION_ROLE* pFirst;
50
51 int iInstallCount;
52 int iUninstallCount;
53};
54
55
56// function prototypes
57
58void CpiApplicationRoleListFree(
59 CPI_APPLICATION_ROLE_LIST* pList
60 );
61HRESULT CpiApplicationRolesRead(
62 CPI_APPLICATION_LIST* pAppList,
63 CPI_APPLICATION_ROLE_LIST* pAppRoleList
64 );
65HRESULT CpiApplicationRolesVerifyInstall(
66 CPI_APPLICATION_ROLE_LIST* pList
67 );
68HRESULT CpiApplicationRolesVerifyUninstall(
69 CPI_APPLICATION_ROLE_LIST* pList
70 );
71void CpiApplicationRoleAddReferenceInstall(
72 CPI_APPLICATION_ROLE* pItm
73 );
74void CpiApplicationRoleAddReferenceUninstall(
75 CPI_APPLICATION_ROLE* pItm
76 );
77HRESULT CpiApplicationRolesInstall(
78 CPI_APPLICATION_ROLE_LIST* pList,
79 int iRunMode,
80 LPWSTR* ppwzActionData,
81 int* piProgress
82 );
83HRESULT CpiApplicationRolesUninstall(
84 CPI_APPLICATION_ROLE_LIST* pList,
85 int iRunMode,
86 LPWSTR* ppwzActionData,
87 int* piProgress
88 );
89HRESULT CpiApplicationRoleFindByKey(
90 CPI_APPLICATION_ROLE_LIST* pList,
91 LPCWSTR pwzKey,
92 CPI_APPLICATION_ROLE** ppAppRole
93 );
94void CpiUserInApplicationRoleListFree(
95 CPI_USER_IN_APPLICATION_ROLE_LIST* pList
96 );
97HRESULT CpiUsersInApplicationRolesRead(
98 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
99 CPI_USER_IN_APPLICATION_ROLE_LIST* pUsrInAppRoleList
100 );
101HRESULT CpiUsersInApplicationRolesInstall(
102 CPI_USER_IN_APPLICATION_ROLE_LIST* pList,
103 int iRunMode,
104 LPWSTR* ppwzActionData,
105 int* piProgress
106 );
107HRESULT CpiUsersInApplicationRolesUninstall(
108 CPI_USER_IN_APPLICATION_ROLE_LIST* pList,
109 int iRunMode,
110 LPWSTR* ppwzActionData,
111 int* piProgress
112 );
diff --git a/src/ext/ComPlus/ca/cpappsched.cpp b/src/ext/ComPlus/ca/cpappsched.cpp
new file mode 100644
index 00000000..1fb2203b
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpappsched.cpp
@@ -0,0 +1,752 @@
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// sql queries
7
8LPCWSTR vcsApplicationQuery =
9 L"SELECT `Application`, `Component_`, `Partition_`, `Id`, `Name` FROM `ComPlusApplication`";
10enum eApplicationQuery { aqApplication = 1, aqComponent, aqPartition, aqID, aqName };
11
12LPCWSTR vcsApplicationPropertyQuery =
13 L"SELECT `Name`, `Value` FROM `ComPlusApplicationProperty` WHERE `Application_` = ?";
14
15
16// property definitions
17
18CPI_PROPERTY_DEFINITION pdlApplicationProperties[] =
19{
20 {L"3GigSupportEnabled", cpptBoolean, 500},
21 {L"AccessChecksLevel", cpptInteger, 500},
22 {L"Activation", cpptInteger, 500},
23 {L"ApplicationAccessChecksEnabled", cpptBoolean, 500},
24 {L"ApplicationDirectory", cpptString, 501},
25 {L"Authentication", cpptInteger, 500},
26 {L"AuthenticationCapability", cpptInteger, 500},
27 {L"Changeable", cpptBoolean, 500},
28 {L"CommandLine", cpptString, 500},
29 {L"ConcurrentApps", cpptInteger, 501},
30 {L"CreatedBy", cpptString, 500},
31 {L"CRMEnabled", cpptBoolean, 500},
32 {L"CRMLogFile", cpptString, 500},
33 {L"Deleteable", cpptBoolean, 500},
34 {L"Description", cpptString, 500},
35 {L"DumpEnabled", cpptBoolean, 501},
36 {L"DumpOnException", cpptBoolean, 501},
37 {L"DumpOnFailfast", cpptBoolean, 501},
38 {L"DumpPath", cpptString, 501},
39 {L"EventsEnabled", cpptBoolean, 500},
40 {L"Identity", cpptString, 500},
41 {L"ImpersonationLevel", cpptInteger, 500},
42 {L"IsEnabled", cpptBoolean, 501},
43 {L"MaxDumpCount", cpptInteger, 501},
44 {L"Password", cpptString, 500},
45 {L"QCAuthenticateMsgs", cpptInteger, 501},
46 {L"QCListenerMaxThreads", cpptInteger, 501},
47 {L"QueueListenerEnabled", cpptBoolean, 500},
48 {L"QueuingEnabled", cpptBoolean, 500},
49 {L"RecycleActivationLimit", cpptInteger, 501},
50 {L"RecycleCallLimit", cpptInteger, 501},
51 {L"RecycleExpirationTimeout", cpptInteger, 501},
52 {L"RecycleLifetimeLimit", cpptInteger, 501},
53 {L"RecycleMemoryLimit", cpptInteger, 501},
54 {L"Replicable", cpptBoolean, 501},
55 {L"RunForever", cpptBoolean, 500},
56 {L"ShutdownAfter", cpptInteger, 500},
57 {L"SoapActivated", cpptBoolean, 502},
58 {L"SoapBaseUrl", cpptString, 502},
59 {L"SoapMailTo", cpptString, 502},
60 {L"SoapVRoot", cpptString, 502},
61 {L"SRPEnabled", cpptBoolean, 501},
62 {L"SRPTrustLevel", cpptInteger, 501},
63 {NULL, cpptNone, 0}
64};
65
66
67// prototypes for private helper functions
68
69static void FreeApplication(
70 CPI_APPLICATION* pItm
71 );
72static HRESULT FindObjectForApplication(
73 CPI_APPLICATION* pItm,
74 BOOL fFindId,
75 BOOL fFindName,
76 ICatalogObject** ppiAppObj
77 );
78static HRESULT AddApplicationToActionData(
79 CPI_APPLICATION* pItm,
80 int iActionType,
81 int iActionCost,
82 LPWSTR* ppwzActionData
83 );
84
85
86// function definitions
87
88void CpiApplicationListFree(
89 CPI_APPLICATION_LIST* pList
90 )
91{
92 CPI_APPLICATION* pItm = pList->pFirst;
93
94 while (pItm)
95 {
96 CPI_APPLICATION* pDelete = pItm;
97 pItm = pItm->pNext;
98 FreeApplication(pDelete);
99 }
100}
101
102HRESULT CpiApplicationsRead(
103 CPI_PARTITION_LIST* pPartList,
104 CPI_APPLICATION_LIST* pAppList
105 )
106{
107 HRESULT hr = S_OK;
108 UINT er = ERROR_SUCCESS;
109
110 int iVersionNT = 0;
111
112 PMSIHANDLE hView, hRec;
113
114 CPI_APPLICATION* pItm = NULL;
115 LPWSTR pwzData = NULL;
116 BOOL fMatchingArchitecture = FALSE;
117
118 // get NT version
119 hr = WcaGetIntProperty(L"VersionNT", &iVersionNT);
120 ExitOnFailure(hr, "Failed to get VersionNT property");
121
122 // loop through all applications
123 hr = WcaOpenExecuteView(vcsApplicationQuery, &hView);
124 ExitOnFailure(hr, "Failed to execute view on ComPlusApplication table");
125
126 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
127 {
128 // get component
129 hr = WcaGetRecordString(hRec, aqComponent, &pwzData);
130 ExitOnFailure(hr, "Failed to get component");
131
132 // check if the component is our processor architecture
133 if (pwzData && *pwzData)
134 {
135 hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture);
136 ExitOnFailure(hr, "Failed to get component architecture.");
137
138 if (!fMatchingArchitecture)
139 {
140 continue; // not the same architecture, ignore
141 }
142 }
143
144 // create entry
145 pItm = (CPI_APPLICATION*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_APPLICATION));
146 if (!pItm)
147 ExitFunction1(hr = E_OUTOFMEMORY);
148
149 // get component install state
150 if (pwzData && *pwzData)
151 {
152 pItm->fHasComponent = TRUE;
153
154 er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction);
155 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
156 }
157
158 // get key
159 hr = WcaGetRecordString(hRec, aqApplication, &pwzData);
160 ExitOnFailure(hr, "Failed to get key");
161 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
162
163 // get partition
164 if (502 <= iVersionNT)
165 {
166 hr = WcaGetRecordString(hRec, aqPartition, &pwzData);
167 ExitOnFailure(hr, "Failed to get partition");
168
169 if (pwzData && *pwzData)
170 {
171 hr = CpiPartitionFindByKey(pPartList, pwzData, &pItm->pPartition);
172 ExitOnFailure(hr, "Failed to find partition, key: %S", pwzData);
173 }
174 }
175
176 // get id
177 hr = WcaGetRecordFormattedString(hRec, aqID, &pwzData);
178 ExitOnFailure(hr, "Failed to get id");
179
180 if (pwzData && *pwzData)
181 {
182 hr = PcaGuidToRegFormat(pwzData, pItm->wzID, countof(pItm->wzID));
183 ExitOnFailure(hr, "Failed to parse id guid value, key: %S, value: '%S'", pItm->wzKey, pwzData);
184 }
185
186 // get name
187 hr = WcaGetRecordFormattedString(hRec, aqName, &pwzData);
188 ExitOnFailure(hr, "Failed to get name");
189 StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData);
190
191 // if application is a locater, either an id or a name must be provided
192 if (!pItm->fHasComponent && !*pItm->wzID && !*pItm->wzName)
193 ExitOnFailure(hr = E_FAIL, "An application locater must have either an id or a name associated, key: %S", pItm->wzKey);
194
195 // if application is not a locater, an name must be provided
196 if (pItm->fHasComponent && !*pItm->wzName)
197 ExitOnFailure(hr = E_FAIL, "An application must have a name associated, key: %S", pItm->wzKey);
198
199 // get properties
200 if (CpiTableExists(cptComPlusApplicationProperty) && pItm->fHasComponent)
201 {
202 hr = CpiPropertiesRead(vcsApplicationPropertyQuery, pItm->wzKey, pdlApplicationProperties, &pItm->pProperties, &pItm->iPropertyCount);
203 ExitOnFailure(hr, "Failed to get properties");
204 }
205
206 // set references & increment counters
207 if (pItm->fHasComponent)
208 {
209 if (WcaIsInstalling(pItm->isInstalled, pItm->isAction))
210 {
211 if (pItm->pPartition)
212 CpiPartitionAddReferenceInstall(pItm->pPartition);
213 pAppList->iInstallCount++;
214 }
215 if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
216 {
217 if (pItm->pPartition)
218 CpiPartitionAddReferenceUninstall(pItm->pPartition);
219 pAppList->iUninstallCount++;
220 }
221 }
222
223 // add entry
224 if (pAppList->pFirst)
225 pItm->pNext = pAppList->pFirst;
226 pAppList->pFirst = pItm;
227 pItm = NULL;
228 }
229
230 if (E_NOMOREITEMS == hr)
231 hr = S_OK;
232
233LExit:
234 // clean up
235 if (pItm)
236 FreeApplication(pItm);
237
238 ReleaseStr(pwzData);
239
240 return hr;
241}
242
243HRESULT CpiApplicationsVerifyInstall(
244 CPI_APPLICATION_LIST* pList
245 )
246{
247 HRESULT hr = S_OK;
248 UINT er = ERROR_SUCCESS;
249
250 ICatalogObject* piAppObj = NULL;
251
252 for (CPI_APPLICATION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
253 {
254 // referenced locaters or applications that are being installed
255 if (!pItm->fReferencedForInstall && !(pItm->fHasComponent && WcaIsInstalling(pItm->isInstalled, pItm->isAction)))
256 continue;
257
258 // if the application is referensed and is not a locater, it must be installed
259 if (pItm->fReferencedForInstall && pItm->fHasComponent && !CpiWillBeInstalled(pItm->isInstalled, pItm->isAction))
260 MessageExitOnFailure(hr = E_FAIL, msierrComPlusApplicationDependency, "An application is used by another entity being installed, but is not installed itself, key: %S", pItm->wzKey);
261
262 // application is supposed to exist
263 if (!pItm->fHasComponent || CpiIsInstalled(pItm->isInstalled))
264 {
265 // get collection object for application
266 hr = FindObjectForApplication(pItm, 0 != *pItm->wzID, 0 == *pItm->wzID, &piAppObj);
267 ExitOnFailure(hr, "Failed to find collection object for application");
268
269 // if the application was found
270 if (S_OK == hr)
271 {
272 // if we don't have an id, copy id from object
273 if (!*pItm->wzID)
274 {
275 hr = CpiGetKeyForObject(piAppObj, pItm->wzID, countof(pItm->wzID));
276 ExitOnFailure(hr, "Failed to get id");
277 }
278 }
279
280 // if the application was not found
281 else
282 {
283 // if the application is a locater, this is an error
284 if (!pItm->fHasComponent)
285 MessageExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), msierrComPlusApplicationNotFound, "An application required by this installation was not found, key: %S", pItm->wzKey);
286
287 // create a new id if one is missing
288 if (!*pItm->wzID)
289 {
290 hr = CpiCreateId(pItm->wzID, countof(pItm->wzID));
291 ExitOnFailure(hr, "Failed to create id");
292 }
293 }
294 }
295
296 // application is supposed to be created
297 else
298 {
299 // check for conflicts
300 do {
301 if (*pItm->wzID)
302 {
303 // find applications with conflicting id
304 hr = FindObjectForApplication(pItm, TRUE, FALSE, &piAppObj);
305 ExitOnFailure(hr, "Failed to find collection object for application");
306
307 if (S_FALSE == hr)
308 {
309 // find applications with conflicting name
310 hr = FindObjectForApplication(pItm, FALSE, TRUE, &piAppObj);
311 ExitOnFailure(hr, "Failed to find collection object for application");
312
313 if (S_OK == hr)
314 // "A application with a conflictiong name exists. retry cancel"
315 er = WcaErrorMessage(msierrComPlusApplicationNameConflict, hr, INSTALLMESSAGE_ERROR | MB_RETRYCANCEL, 0);
316 else
317 break; // no conflicting entry found, break loop
318 }
319 else
320 // "A application with a conflicting id exists. abort retry ignore"
321 er = WcaErrorMessage(msierrComPlusApplicationIdConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
322 }
323 else
324 {
325 // find applications with conflicting name
326 hr = FindObjectForApplication(pItm, FALSE, TRUE, &piAppObj);
327 ExitOnFailure(hr, "Failed to find collection object for application");
328
329 if (S_OK == hr)
330 // "A subscription with a conflictiong name exists. abort retry ignore"
331 er = WcaErrorMessage(msierrComPlusApplicationNameConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
332 else
333 break; // no conflicting entry found, break loop
334 }
335
336 switch (er)
337 {
338 case IDCANCEL:
339 case IDABORT:
340 ExitOnFailure(hr = E_FAIL, "An application with a conflictiong name or id exists, key: %S", pItm->wzKey);
341 break;
342 case IDRETRY:
343 break;
344 case IDIGNORE:
345 default:
346 // if we don't have an id, copy id from object
347 if (!*pItm->wzID)
348 {
349 hr = CpiGetKeyForObject(piAppObj, pItm->wzID, countof(pItm->wzID));
350 ExitOnFailure(hr, "Failed to get id");
351 }
352 hr = S_FALSE; // indicate that this is not a conflict
353 }
354 } while (S_OK == hr); // hr = S_FALSE if we don't have any conflicts
355
356 // create a new id if one is missing
357 if (!*pItm->wzID)
358 {
359 hr = CpiCreateId(pItm->wzID, countof(pItm->wzID));
360 ExitOnFailure(hr, "Failed to create id");
361 }
362 }
363
364 // clean up
365 ReleaseNullObject(piAppObj);
366 }
367
368 hr = S_OK;
369
370LExit:
371 // clean up
372 ReleaseObject(piAppObj);
373
374 return hr;
375}
376
377HRESULT CpiApplicationsVerifyUninstall(
378 CPI_APPLICATION_LIST* pList
379 )
380{
381 HRESULT hr = S_OK;
382 ICatalogObject* piAppObj = NULL;
383
384 for (CPI_APPLICATION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
385 {
386 // referenced locaters or applications that are being installed
387 if (!pItm->fReferencedForUninstall && !(pItm->fHasComponent && WcaIsUninstalling(pItm->isInstalled, pItm->isAction)))
388 continue;
389
390 // get collection object for application
391 hr = FindObjectForApplication(pItm, 0 != *pItm->wzID, 0 == *pItm->wzID, &piAppObj);
392 ExitOnFailure(hr, "Failed to find collection object for application");
393
394 // if the application was found
395 if (S_OK == hr)
396 {
397 // if we don't have an id, copy id from object
398 if (!*pItm->wzID)
399 {
400 hr = CpiGetKeyForObject(piAppObj, pItm->wzID, countof(pItm->wzID));
401 ExitOnFailure(hr, "Failed to get id");
402 }
403 }
404
405 // if the application was not found
406 else
407 {
408 pItm->fObjectNotFound = TRUE;
409 if (pItm->fHasComponent)
410 pList->iUninstallCount--; // elements with the fObjectNotFound flag set will not be scheduled for uninstall
411 }
412
413 // clean up
414 ReleaseNullObject(piAppObj);
415 }
416
417 hr = S_OK;
418
419LExit:
420 // clean up
421 ReleaseObject(piAppObj);
422
423 return hr;
424}
425
426void CpiApplicationAddReferenceInstall(
427 CPI_APPLICATION* pItm
428 )
429{
430 pItm->fReferencedForInstall = TRUE;
431 if (pItm->pPartition)
432 CpiPartitionAddReferenceInstall(pItm->pPartition);
433}
434
435void CpiApplicationAddReferenceUninstall(
436 CPI_APPLICATION* pItm
437 )
438{
439 pItm->fReferencedForUninstall = TRUE;
440 if (pItm->pPartition)
441 CpiPartitionAddReferenceUninstall(pItm->pPartition);
442}
443
444HRESULT CpiApplicationsInstall(
445 CPI_APPLICATION_LIST* pList,
446 int iRunMode,
447 LPWSTR* ppwzActionData,
448 int* piProgress
449 )
450{
451 HRESULT hr = S_OK;
452
453 int iActionType;
454
455 // add action text
456 hr = CpiAddActionTextToActionData(L"CreateComPlusApplications", ppwzActionData);
457 ExitOnFailure(hr, "Failed to add action text to custom action data");
458
459 // add applicaton count to action data
460 hr = WcaWriteIntegerToCaData(pList->iInstallCount, ppwzActionData);
461 ExitOnFailure(hr, "Failed to add count to custom action data");
462
463 // add applications to custom action data
464 for (CPI_APPLICATION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
465 {
466 // applications that are being installed only
467 if (!pItm->fHasComponent || !WcaIsInstalling(pItm->isInstalled, pItm->isAction))
468 continue;
469
470 // action type
471 if (rmRollback == iRunMode)
472 {
473 if (CpiIsInstalled(pItm->isInstalled))
474 iActionType = atNoOp;
475 else
476 iActionType = atRemove;
477 }
478 else
479 iActionType = atCreate;
480
481 // add to action data
482 hr = AddApplicationToActionData(pItm, iActionType, COST_APPLICATION_CREATE, ppwzActionData);
483 ExitOnFailure(hr, "Failed to add applicaton to custom action data, key: %S", pItm->wzKey);
484 }
485
486 // add progress tics
487 if (piProgress)
488 *piProgress += COST_APPLICATION_CREATE * pList->iInstallCount;
489
490 hr = S_OK;
491
492LExit:
493 return hr;
494}
495
496HRESULT CpiApplicationsUninstall(
497 CPI_APPLICATION_LIST* pList,
498 int iRunMode,
499 LPWSTR* ppwzActionData,
500 int* piProgress
501 )
502{
503 HRESULT hr = S_OK;
504
505 int iActionType;
506
507 // add action text
508 hr = CpiAddActionTextToActionData(L"RemoveComPlusApplications", ppwzActionData);
509 ExitOnFailure(hr, "Failed to add action text to custom action data");
510
511 // add applicaton count to action data
512 hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData);
513 ExitOnFailure(hr, "Failed to add count to custom action data");
514
515 // add applications to custom action data
516 for (CPI_APPLICATION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
517 {
518 // applications that are being uninstalled only
519 if (!pItm->fHasComponent || !WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
520 continue;
521
522 // action type
523 if (rmRollback == iRunMode)
524 iActionType = atCreate;
525 else
526 iActionType = atRemove;
527
528 // add to action data
529 hr = AddApplicationToActionData(pItm, iActionType, COST_APPLICATION_DELETE, ppwzActionData);
530 ExitOnFailure(hr, "Failed to add applicaton to custom action data, key: %S", pItm->wzKey);
531 }
532
533 // add progress tics
534 if (piProgress)
535 *piProgress += COST_APPLICATION_DELETE * pList->iUninstallCount;
536
537 hr = S_OK;
538
539LExit:
540 return hr;
541}
542
543HRESULT CpiApplicationFindByKey(
544 CPI_APPLICATION_LIST* pList,
545 LPCWSTR pwzKey,
546 CPI_APPLICATION** ppApp
547 )
548{
549 for (CPI_APPLICATION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
550 {
551 if (0 == lstrcmpW(pItm->wzKey, pwzKey))
552 {
553 *ppApp = pItm;
554 return S_OK;
555 }
556 }
557
558 return S_FALSE;
559}
560
561HRESULT CpiGetRolesCollForApplication(
562 CPI_APPLICATION* pApp,
563 ICatalogCollection** ppiRolesColl
564 )
565{
566 HRESULT hr = S_OK;
567
568 ICatalogCollection* piAppColl = NULL;
569 ICatalogObject* piAppObj = NULL;
570
571 // if a previous attempt to locate the collection object failed
572 if (pApp->fObjectNotFound)
573 ExitFunction1(hr = S_FALSE);
574
575 // get applications collection
576 if (!pApp->piRolesColl)
577 {
578 // get applications collection
579 if (pApp->pPartition)
580 hr = CpiGetApplicationsCollForPartition(pApp->pPartition, &piAppColl);
581 else
582 hr = CpiSchedGetApplicationsCollection(&piAppColl);
583 ExitOnFailure(hr, "Failed to get applications collection");
584
585 if (S_FALSE == hr)
586 ExitFunction(); // exit with hr = S_FALSE
587
588 // find application object
589 hr = CpiFindCollectionObject(piAppColl, pApp->wzID, *pApp->wzID ? NULL : pApp->wzName, &piAppObj);
590 ExitOnFailure(hr, "Failed to find application object");
591
592 if (S_FALSE == hr)
593 ExitFunction(); // exit with hr = S_FALSE
594
595 // get roles collection
596 hr = CpiSchedGetCatalogCollection(piAppColl, piAppObj, L"Roles", &pApp->piRolesColl);
597 ExitOnFailure(hr, "Failed to get roles collection");
598 }
599
600 // return value
601 *ppiRolesColl = pApp->piRolesColl;
602 (*ppiRolesColl)->AddRef();
603
604 hr = S_OK;
605
606LExit:
607 // clean up
608 ReleaseObject(piAppColl);
609 ReleaseObject(piAppObj);
610
611 return hr;
612}
613
614HRESULT CpiGetComponentsCollForApplication(
615 CPI_APPLICATION* pApp,
616 ICatalogCollection** ppiCompsColl
617 )
618{
619 HRESULT hr = S_OK;
620
621 ICatalogCollection* piAppColl = NULL;
622 ICatalogObject* piAppObj = NULL;
623
624 // if a previous attempt to locate the collection object failed
625 if (pApp->fObjectNotFound)
626 ExitFunction1(hr = S_FALSE);
627
628 // get applications collection
629 if (!pApp->piCompsColl)
630 {
631 // get applications collection
632 if (pApp->pPartition)
633 hr = CpiGetApplicationsCollForPartition(pApp->pPartition, &piAppColl);
634 else
635 hr = CpiSchedGetApplicationsCollection(&piAppColl);
636 ExitOnFailure(hr, "Failed to get applications collection");
637
638 if (S_FALSE == hr)
639 ExitFunction(); // exit with hr = S_FALSE
640
641 // find application object
642 hr = CpiFindCollectionObject(piAppColl, pApp->wzID, *pApp->wzID ? NULL : pApp->wzName, &piAppObj);
643 ExitOnFailure(hr, "Failed to find application object");
644
645 if (S_FALSE == hr)
646 ExitFunction(); // exit with hr = S_FALSE
647
648 // get roles collection
649 hr = CpiSchedGetCatalogCollection(piAppColl, piAppObj, L"Components", &pApp->piCompsColl);
650 ExitOnFailure(hr, "Failed to get components collection");
651 }
652
653 // return value
654 *ppiCompsColl = pApp->piCompsColl;
655 (*ppiCompsColl)->AddRef();
656
657 hr = S_OK;
658
659LExit:
660 // clean up
661 ReleaseObject(piAppColl);
662 ReleaseObject(piAppObj);
663
664 return hr;
665}
666
667
668// helper function definitions
669
670static void FreeApplication(
671 CPI_APPLICATION* pItm
672 )
673{
674 if (pItm->pProperties)
675 CpiPropertiesFreeList(pItm->pProperties);
676
677 ReleaseObject(pItm->piRolesColl);
678 ReleaseObject(pItm->piCompsColl);
679
680 ::HeapFree(::GetProcessHeap(), 0, pItm);
681}
682
683static HRESULT FindObjectForApplication(
684 CPI_APPLICATION* pItm,
685 BOOL fFindId,
686 BOOL fFindName,
687 ICatalogObject** ppiAppObj
688 )
689{
690 HRESULT hr = S_OK;
691
692 ICatalogCollection* piAppColl = NULL;
693
694 // get applications collection
695 if (pItm->pPartition)
696 hr = CpiGetApplicationsCollForPartition(pItm->pPartition, &piAppColl);
697 else
698 hr = CpiSchedGetApplicationsCollection(&piAppColl);
699 ExitOnFailure(hr, "Failed to get applications collection");
700
701 if (S_FALSE == hr)
702 ExitFunction(); // exit with hr = S_FALSE
703
704 // find application object
705 hr = CpiFindCollectionObject(piAppColl, fFindId ? pItm->wzID : NULL, fFindName ? pItm->wzName : NULL, ppiAppObj);
706 ExitOnFailure(hr, "Failed to find application object");
707
708 // exit with hr from CpiFindCollectionObject()
709
710LExit:
711 // clean up
712 ReleaseObject(piAppColl);
713
714 return hr;
715}
716
717static HRESULT AddApplicationToActionData(
718 CPI_APPLICATION* pItm,
719 int iActionType,
720 int iActionCost,
721 LPWSTR* ppwzActionData
722 )
723{
724 HRESULT hr = S_OK;
725
726 // add action information to custom action data
727 hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
728 ExitOnFailure(hr, "Failed to add action type to custom action data");
729 hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
730 ExitOnFailure(hr, "Failed to add action cost to custom action data");
731
732 // add application information to custom action data
733 hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
734 ExitOnFailure(hr, "Failed to add application key to custom action data");
735 hr = WcaWriteStringToCaData(pItm->wzID, ppwzActionData);
736 ExitOnFailure(hr, "Failed to add application id to custom action data");
737 hr = WcaWriteStringToCaData(pItm->wzName, ppwzActionData);
738 ExitOnFailure(hr, "Failed to add application name to custom action data");
739
740 // add partition information to custom action data
741 hr = WcaWriteStringToCaData(pItm->pPartition ? pItm->pPartition->wzID : L"", ppwzActionData);
742 ExitOnFailure(hr, "Failed to add partition id to custom action data");
743
744 // add properties to custom action data
745 hr = CpiAddPropertiesToActionData(atCreate == iActionType ? pItm->iPropertyCount : 0, pItm->pProperties, ppwzActionData);
746 ExitOnFailure(hr, "Failed to add properties to custom action data");
747
748 hr = S_OK;
749
750LExit:
751 return hr;
752}
diff --git a/src/ext/ComPlus/ca/cpappsched.h b/src/ext/ComPlus/ca/cpappsched.h
new file mode 100644
index 00000000..2cd6a0ee
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpappsched.h
@@ -0,0 +1,83 @@
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
5struct CPI_APPLICATION
6{
7 WCHAR wzKey[MAX_DARWIN_KEY + 1];
8 WCHAR wzID[CPI_MAX_GUID + 1];
9 WCHAR wzName[MAX_DARWIN_COLUMN + 1];
10
11 int iPropertyCount;
12 CPI_PROPERTY* pProperties;
13
14 BOOL fHasComponent;
15 BOOL fReferencedForInstall;
16 BOOL fReferencedForUninstall;
17 BOOL fObjectNotFound;
18
19 INSTALLSTATE isInstalled, isAction;
20
21 CPI_PARTITION* pPartition;
22
23 ICatalogCollection* piRolesColl;
24 ICatalogCollection* piCompsColl;
25
26 CPI_APPLICATION* pNext;
27};
28
29struct CPI_APPLICATION_LIST
30{
31 CPI_APPLICATION* pFirst;
32
33 int iInstallCount;
34 int iUninstallCount;
35};
36
37
38// function prototypes
39
40void CpiApplicationListFree(
41 CPI_APPLICATION_LIST* pList
42 );
43HRESULT CpiApplicationsRead(
44 CPI_PARTITION_LIST* pPartList,
45 CPI_APPLICATION_LIST* pAppList
46 );
47HRESULT CpiApplicationsVerifyInstall(
48 CPI_APPLICATION_LIST* pList
49 );
50HRESULT CpiApplicationsVerifyUninstall(
51 CPI_APPLICATION_LIST* pList
52 );
53void CpiApplicationAddReferenceInstall(
54 CPI_APPLICATION* pItm
55 );
56void CpiApplicationAddReferenceUninstall(
57 CPI_APPLICATION* pItm
58 );
59HRESULT CpiApplicationsInstall(
60 CPI_APPLICATION_LIST* pList,
61 int iRunMode,
62 LPWSTR* ppwzActionData,
63 int* piProgress
64 );
65HRESULT CpiApplicationsUninstall(
66 CPI_APPLICATION_LIST* pList,
67 int iRunMode,
68 LPWSTR* ppwzActionData,
69 int* piProgress
70 );
71HRESULT CpiApplicationFindByKey(
72 CPI_APPLICATION_LIST* pList,
73 LPCWSTR pwzKey,
74 CPI_APPLICATION** ppApp
75 );
76HRESULT CpiGetRolesCollForApplication(
77 CPI_APPLICATION* pApp,
78 ICatalogCollection** ppiRolesColl
79 );
80HRESULT CpiGetComponentsCollForApplication(
81 CPI_APPLICATION* pApp,
82 ICatalogCollection** ppiCompsColl
83 );
diff --git a/src/ext/ComPlus/ca/cpasmexec.cpp b/src/ext/ComPlus/ca/cpasmexec.cpp
new file mode 100644
index 00000000..3d140027
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpasmexec.cpp
@@ -0,0 +1,1877 @@
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// GAC related declarations
7
8typedef struct _FUSION_INSTALL_REFERENCE_
9{
10 DWORD cbSize;
11 DWORD dwFlags;
12 GUID guidScheme;
13 LPCWSTR szIdentifier;
14 LPCWSTR szNonCannonicalData;
15} FUSION_INSTALL_REFERENCE;
16
17typedef struct _FUSION_INSTALL_REFERENCE_ *LPFUSION_INSTALL_REFERENCE;
18
19typedef const FUSION_INSTALL_REFERENCE *LPCFUSION_INSTALL_REFERENCE;
20
21typedef struct _ASSEMBLY_INFO
22{
23 ULONG cbAssemblyInfo;
24 DWORD dwAssemblyFlags;
25 ULARGE_INTEGER uliAssemblySizeInKB;
26 LPWSTR pszCurrentAssemblyPathBuf;
27 ULONG cchBuf;
28} ASSEMBLY_INFO;
29
30typedef interface IAssemblyCacheItem IAssemblyCacheItem;
31
32MIDL_INTERFACE("e707dcde-d1cd-11d2-bab9-00c04f8eceae")
33IAssemblyCache : public IUnknown
34{
35public:
36 virtual HRESULT STDMETHODCALLTYPE UninstallAssembly(
37 /* [in] */ DWORD dwFlags,
38 /* [in] */ LPCWSTR pszAssemblyName,
39 /* [in] */ LPCFUSION_INSTALL_REFERENCE pRefData,
40 /* [optional][out] */ ULONG *pulDisposition) = 0;
41
42 virtual HRESULT STDMETHODCALLTYPE QueryAssemblyInfo(
43 /* [in] */ DWORD dwFlags,
44 /* [in] */ LPCWSTR pszAssemblyName,
45 /* [out][in] */ ASSEMBLY_INFO *pAsmInfo) = 0;
46
47 virtual HRESULT STDMETHODCALLTYPE CreateAssemblyCacheItem(
48 /* [in] */ DWORD dwFlags,
49 /* [in] */ PVOID pvReserved,
50 /* [out] */ IAssemblyCacheItem **ppAsmItem,
51 /* [optional][in] */ LPCWSTR pszAssemblyName) = 0;
52
53 virtual HRESULT STDMETHODCALLTYPE CreateAssemblyScavenger(
54 /* [out] */ IUnknown **ppUnkReserved) = 0;
55
56 virtual HRESULT STDMETHODCALLTYPE InstallAssembly(
57 /* [in] */ DWORD dwFlags,
58 /* [in] */ LPCWSTR pszManifestFilePath,
59 /* [in] */ LPCFUSION_INSTALL_REFERENCE pRefData) = 0;
60};
61
62typedef HRESULT (__stdcall *LoadLibraryShimFunc)(LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE *phModDll);
63typedef HRESULT (__stdcall *CreateAssemblyCacheFunc)(IAssemblyCache **ppAsmCache, DWORD dwReserved);
64
65
66// RegistrationHelper related declarations
67
68static const GUID CLSID_RegistrationHelper =
69 { 0x89a86e7b, 0xc229, 0x4008, { 0x9b, 0xaa, 0x2f, 0x5c, 0x84, 0x11, 0xd7, 0xe0 } };
70
71enum eInstallationFlags {
72 ifConfigureComponentsOnly = 16,
73 ifFindOrCreateTargetApplication = 4,
74 ifExpectExistingTypeLib = 1
75};
76
77
78// private structs
79
80struct CPIEXEC_ROLE_ASSIGNMENT
81{
82 WCHAR wzKey[MAX_DARWIN_KEY + 1];
83 WCHAR wzRoleName[MAX_DARWIN_COLUMN + 1];
84
85 CPIEXEC_ROLE_ASSIGNMENT* pNext;
86};
87
88struct CPIEXEC_METHOD
89{
90 WCHAR wzIndex[11 + 1];
91 WCHAR wzName[MAX_DARWIN_COLUMN + 1];
92
93 CPI_PROPERTY* pPropertyList;
94 CPIEXEC_ROLE_ASSIGNMENT* pRoleAssignmentList;
95
96 CPIEXEC_METHOD* pNext;
97};
98
99struct CPIEXEC_INTERFACE
100{
101 WCHAR wzIID[CPI_MAX_GUID + 1];
102
103 CPI_PROPERTY* pPropertyList;
104 CPIEXEC_ROLE_ASSIGNMENT* pRoleAssignmentList;
105 CPIEXEC_METHOD* pMethodList;
106
107 CPIEXEC_INTERFACE* pNext;
108};
109
110struct CPIEXEC_COMPONENT
111{
112 WCHAR wzCLSID[CPI_MAX_GUID + 1];
113
114 CPI_PROPERTY* pPropertyList;
115 CPIEXEC_ROLE_ASSIGNMENT* pRoleAssignmentList;
116 CPIEXEC_INTERFACE* pInterfaceList;
117
118 CPIEXEC_COMPONENT* pNext;
119};
120
121struct CPI_ASSEMBLY_ATTRIBUTES
122{
123 int iActionType;
124 int iActionCost;
125 LPWSTR pwzKey;
126 LPWSTR pwzAssemblyName;
127 LPWSTR pwzDllPath;
128 LPWSTR pwzTlbPath;
129 LPWSTR pwzPSDllPath;
130 LPWSTR pwzAppID;
131 LPWSTR pwzPartID;
132 int iAttributes;
133 CPIEXEC_COMPONENT* pCompList;
134};
135
136struct CPI_ROLE_ASSIGNMENTS_ATTRIBUTES
137{
138 int iActionType;
139 int iActionCost;
140 LPWSTR pwzKey;
141 LPWSTR pwzAppID;
142 LPWSTR pwzPartID;
143 int iRoleCount;
144 CPIEXEC_COMPONENT* pCompList;
145};
146
147
148// prototypes for private helper functions
149
150static HRESULT RegisterAssembly(
151 CPI_ASSEMBLY_ATTRIBUTES* pAttrs
152 );
153static HRESULT UnregisterAssembly(
154 CPI_ASSEMBLY_ATTRIBUTES* pAttrs
155 );
156static void InitAssemblyExec();
157static void UninitAssemblyExec();
158static HRESULT GetRegistrationHelper(
159 IDispatch** ppiRegHlp
160 );
161static HRESULT GetAssemblyCacheObject(
162 IAssemblyCache** ppAssemblyCache
163 );
164static HRESULT GetAssemblyPathFromGAC(
165 LPCWSTR pwzAssemblyName,
166 LPWSTR* ppwzAssemblyPath
167 );
168static HRESULT RegisterDotNetAssembly(
169 CPI_ASSEMBLY_ATTRIBUTES* pAttrs
170 );
171static HRESULT RegisterNativeAssembly(
172 CPI_ASSEMBLY_ATTRIBUTES* pAttrs
173 );
174static HRESULT UnregisterDotNetAssembly(
175 CPI_ASSEMBLY_ATTRIBUTES* pAttrs
176 );
177static HRESULT RemoveComponents(
178 ICatalogCollection* piCompColl,
179 CPIEXEC_COMPONENT* pCompList
180 );
181static HRESULT ReadAssemblyAttributes(
182 LPWSTR* ppwzData,
183 CPI_ASSEMBLY_ATTRIBUTES* pAttrs
184 );
185static void FreeAssemblyAttributes(
186 CPI_ASSEMBLY_ATTRIBUTES* pAttrs
187 );
188static HRESULT ReadRoleAssignmentsAttributes(
189 LPWSTR* ppwzData,
190 CPI_ROLE_ASSIGNMENTS_ATTRIBUTES* pAttrs
191 );
192static void FreeRoleAssignmentsAttributes(
193 CPI_ROLE_ASSIGNMENTS_ATTRIBUTES* pAttrs
194 );
195static HRESULT ConfigureComponents(
196 LPCWSTR pwzPartID,
197 LPCWSTR pwzAppID,
198 CPIEXEC_COMPONENT* pCompList,
199 BOOL fCreate,
200 BOOL fProgress
201 );
202static HRESULT ConfigureInterfaces(
203 ICatalogCollection* piCompColl,
204 ICatalogObject* piCompObj,
205 CPIEXEC_INTERFACE* pIntfList,
206 BOOL fCreate
207 );
208static HRESULT ConfigureMethods(
209 ICatalogCollection* piIntfColl,
210 ICatalogObject* piIntfObj,
211 CPIEXEC_METHOD* pMethList,
212 BOOL fCreate
213 );
214static HRESULT ConfigureRoleAssignments(
215 LPCWSTR pwzCollName,
216 ICatalogCollection* piCompColl,
217 ICatalogObject* piCompObj,
218 CPIEXEC_ROLE_ASSIGNMENT* pRoleList,
219 BOOL fCreate
220 );
221static HRESULT ReadComponentList(
222 LPWSTR* ppwzData,
223 CPIEXEC_COMPONENT** ppCompList
224 );
225static HRESULT ReadInterfaceList(
226 LPWSTR* ppwzData,
227 CPIEXEC_INTERFACE** ppIntfList
228 );
229static HRESULT ReadMethodList(
230 LPWSTR* ppwzData,
231 CPIEXEC_METHOD** ppMethList
232 );
233static HRESULT ReadRoleAssignmentList(
234 LPWSTR* ppwzData,
235 CPIEXEC_ROLE_ASSIGNMENT** ppRoleList
236 );
237static void FreeComponentList(
238 CPIEXEC_COMPONENT* pList
239 );
240static void FreeInterfaceList(
241 CPIEXEC_INTERFACE* pList
242 );
243static void FreeMethodList(
244 CPIEXEC_METHOD* pList
245 );
246static void FreeRoleAssignmentList(
247 CPIEXEC_ROLE_ASSIGNMENT* pList
248 );
249
250
251// variables
252
253static IDispatch* gpiRegHlp;
254static IAssemblyCache* gpAssemblyCache;
255static HMODULE ghMscoree;
256static HMODULE ghFusion;
257
258
259// function definitions
260
261HRESULT CpiConfigureAssemblies(
262 LPWSTR* ppwzData,
263 HANDLE hRollbackFile
264 )
265{
266 HRESULT hr = S_OK;
267
268 CPI_ASSEMBLY_ATTRIBUTES attrs;
269 ::ZeroMemory(&attrs, sizeof(attrs));
270
271 // initialize
272 InitAssemblyExec();
273
274 // read action text
275 hr = CpiActionStartMessage(ppwzData, FALSE);
276 ExitOnFailure(hr, "Failed to send action start message");
277
278 // get count
279 int iCnt = 0;
280 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
281 ExitOnFailure(hr, "Failed to read count");
282
283 // write count to rollback file
284 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
285 ExitOnFailure(hr, "Failed to write count to rollback file");
286
287 for (int i = 0; i < iCnt; i++)
288 {
289 // read attributes from CustomActionData
290 hr = ReadAssemblyAttributes(ppwzData, &attrs);
291 ExitOnFailure(hr, "Failed to read assembly attributes");
292
293 // write key to rollback file
294 hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
295 ExitOnFailure(hr, "Failed to write key to rollback file");
296
297 // action
298 switch (attrs.iActionType)
299 {
300 case atCreate:
301 hr = RegisterAssembly(&attrs);
302 ExitOnFailure(hr, "Failed to register assembly, key: %S", attrs.pwzKey);
303 break;
304 case atRemove:
305 hr = UnregisterAssembly(&attrs);
306 ExitOnFailure(hr, "Failed to unregister assembly, key: %S", attrs.pwzKey);
307 break;
308 default:
309 hr = S_OK;
310 break;
311 }
312
313 if (S_FALSE == hr)
314 ExitFunction(); // aborted by user
315
316 // write completion status to rollback file
317 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
318 ExitOnFailure(hr, "Failed to write completion status to rollback file");
319
320 // progress
321 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
322 ExitOnFailure(hr, "Failed to update progress");
323 }
324
325 hr = S_OK;
326
327LExit:
328 // clean up
329 FreeAssemblyAttributes(&attrs);
330
331 // uninitialize
332 UninitAssemblyExec();
333
334 return hr;
335}
336
337HRESULT CpiRollbackConfigureAssemblies(
338 LPWSTR* ppwzData,
339 CPI_ROLLBACK_DATA* pRollbackDataList
340 )
341{
342 HRESULT hr = S_OK;
343
344 int iRollbackStatus;
345
346 CPI_ASSEMBLY_ATTRIBUTES attrs;
347 ::ZeroMemory(&attrs, sizeof(attrs));
348
349 // initialize
350 InitAssemblyExec();
351
352 // read action text
353 hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
354 ExitOnFailure(hr, "Failed to send action start message");
355
356 // get count
357 int iCnt = 0;
358 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
359 ExitOnFailure(hr, "Failed to read count");
360
361 for (int i = 0; i < iCnt; i++)
362 {
363 // read attributes from CustomActionData
364 hr = ReadAssemblyAttributes(ppwzData, &attrs);
365 ExitOnFailure(hr, "Failed to read assembly attributes");
366
367 // rollback status
368 hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
369
370 if (S_FALSE == hr)
371 continue; // not found, nothing to rollback
372
373 // action
374 switch (attrs.iActionType)
375 {
376 case atCreate:
377 hr = RegisterAssembly(&attrs);
378 if (FAILED(hr))
379 WcaLog(LOGMSG_STANDARD, "Failed to register assembly, hr: 0x%x, key: %S", hr, attrs.pwzKey);
380 break;
381 case atRemove:
382 hr = UnregisterAssembly(&attrs);
383 if (FAILED(hr))
384 WcaLog(LOGMSG_STANDARD, "Failed to unregister assembly, hr: 0x%x, key: %S", hr, attrs.pwzKey);
385 break;
386 }
387
388 // check rollback status
389 if (0 == iRollbackStatus)
390 continue; // operation did not complete, skip progress
391
392 // progress
393 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
394 ExitOnFailure(hr, "Failed to update progress");
395 }
396
397 hr = S_OK;
398
399LExit:
400 // clean up
401 FreeAssemblyAttributes(&attrs);
402
403 // uninitialize
404 UninitAssemblyExec();
405
406 return hr;
407}
408
409HRESULT CpiConfigureRoleAssignments(
410 LPWSTR* ppwzData,
411 HANDLE hRollbackFile
412 )
413{
414 HRESULT hr = S_OK;
415
416 CPI_ROLE_ASSIGNMENTS_ATTRIBUTES attrs;
417 ::ZeroMemory(&attrs, sizeof(attrs));
418
419 // read action text
420 hr = CpiActionStartMessage(ppwzData, FALSE);
421 ExitOnFailure(hr, "Failed to send action start message");
422
423 // get count
424 int iCnt = 0;
425 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
426 ExitOnFailure(hr, "Failed to read count");
427
428 // write count to rollback file
429 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
430 ExitOnFailure(hr, "Failed to write count to rollback file");
431
432 for (int i = 0; i < iCnt; i++)
433 {
434 // read attributes from CustomActionData
435 hr = ReadRoleAssignmentsAttributes(ppwzData, &attrs);
436 ExitOnFailure(hr, "Failed to read role assignments attributes");
437
438 // write key to rollback file
439 hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
440 ExitOnFailure(hr, "Failed to write key to rollback file");
441
442 // action
443 if (atNoOp != attrs.iActionType)
444 {
445 hr = ConfigureComponents(attrs.pwzPartID, attrs.pwzAppID, attrs.pCompList, atCreate == attrs.iActionType, TRUE);
446 ExitOnFailure(hr, "Failed to configure components");
447
448 if (S_FALSE == hr)
449 ExitFunction(); // aborted by user
450 }
451
452 // write completion status to rollback file
453 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
454 ExitOnFailure(hr, "Failed to write completion status to rollback file");
455
456 // progress
457 hr = WcaProgressMessage(attrs.iActionCost * attrs.iRoleCount, FALSE);
458 ExitOnFailure(hr, "Failed to update progress");
459 }
460
461 hr = S_OK;
462
463LExit:
464 // clean up
465 FreeRoleAssignmentsAttributes(&attrs);
466
467 return hr;
468}
469
470HRESULT CpiRollbackConfigureRoleAssignments(
471 LPWSTR* ppwzData,
472 CPI_ROLLBACK_DATA* pRollbackDataList
473 )
474{
475 HRESULT hr = S_OK;
476
477 int iRollbackStatus;
478
479 CPI_ROLE_ASSIGNMENTS_ATTRIBUTES attrs;
480 ::ZeroMemory(&attrs, sizeof(attrs));
481
482 // read action text
483 hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
484 ExitOnFailure(hr, "Failed to send action start message");
485
486 // get count
487 int iCnt = 0;
488 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
489 ExitOnFailure(hr, "Failed to read count");
490
491 for (int i = 0; i < iCnt; i++)
492 {
493 // read attributes from CustomActionData
494 hr = ReadRoleAssignmentsAttributes(ppwzData, &attrs);
495 ExitOnFailure(hr, "Failed to read role assignments attributes");
496
497 // rollback status
498 hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
499
500 if (S_FALSE == hr)
501 continue; // not found, nothing to rollback
502
503 // action
504 if (atNoOp != attrs.iActionType)
505 {
506 hr = ConfigureComponents(attrs.pwzPartID, attrs.pwzAppID, attrs.pCompList, atCreate == attrs.iActionType, TRUE);
507 ExitOnFailure(hr, "Failed to configure components");
508
509 if (S_FALSE == hr)
510 ExitFunction(); // aborted by user
511 }
512
513 // check rollback status
514 if (0 == iRollbackStatus)
515 continue; // operation did not complete, skip progress
516
517 // progress
518 hr = WcaProgressMessage(attrs.iActionCost * attrs.iRoleCount, FALSE);
519 ExitOnFailure(hr, "Failed to update progress");
520 }
521
522 hr = S_OK;
523
524LExit:
525 // clean up
526 FreeRoleAssignmentsAttributes(&attrs);
527
528 return hr;
529}
530
531
532// helper function definitions
533
534static HRESULT RegisterAssembly(
535 CPI_ASSEMBLY_ATTRIBUTES* pAttrs
536 )
537{
538 HRESULT hr = S_OK;
539
540 // progress message
541 hr = CpiActionDataMessage(1, (pAttrs->iAttributes & aaPathFromGAC) ? pAttrs->pwzAssemblyName : pAttrs->pwzDllPath);
542 ExitOnFailure(hr, "Failed to send progress messages");
543
544 if (S_FALSE == hr)
545 ExitFunction(); // aborted by user
546
547 // log
548 WcaLog(LOGMSG_VERBOSE, "Registering assembly, key: %S", pAttrs->pwzKey);
549
550 // extract path from GAC
551 if (pAttrs->iAttributes & aaPathFromGAC)
552 {
553 hr = GetAssemblyPathFromGAC(pAttrs->pwzAssemblyName, &pAttrs->pwzDllPath);
554 if (S_FALSE == hr)
555 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
556 ExitOnFailure(hr, "Failed to get path for assembly from GAC");
557
558 // log
559 WcaLog(LOGMSG_VERBOSE, "Assembly path extracted from GAC, key: %S, path: '%S'", pAttrs->pwzKey, pAttrs->pwzDllPath);
560 }
561
562 // .net assembly
563 if (pAttrs->iAttributes & aaDotNetAssembly)
564 {
565 hr = RegisterDotNetAssembly(pAttrs);
566 ExitOnFailure(hr, "Failed to register .NET assembly");
567 }
568
569 // native assembly
570 else
571 {
572 hr = RegisterNativeAssembly(pAttrs);
573 ExitOnFailure(hr, "Failed to register native assembly");
574 }
575
576 // configure components
577 if (pAttrs->pCompList)
578 {
579 hr = ConfigureComponents(pAttrs->pwzPartID, pAttrs->pwzAppID, pAttrs->pCompList, TRUE, FALSE);
580 ExitOnFailure(hr, "Failed to configure components");
581 }
582
583 hr = S_OK;
584
585LExit:
586 return hr;
587}
588
589static HRESULT UnregisterAssembly(
590 CPI_ASSEMBLY_ATTRIBUTES* pAttrs
591 )
592{
593 HRESULT hr = S_OK;
594
595 long lChanges = 0;
596
597 ICatalogCollection* piColl = NULL;
598 ICatalogObject* piObj = NULL;
599
600 // progress message
601 hr = CpiActionDataMessage(1, (pAttrs->iAttributes & aaPathFromGAC) ? pAttrs->pwzAssemblyName : pAttrs->pwzDllPath);
602 ExitOnFailure(hr, "Failed to send progress messages");
603
604 if (S_FALSE == hr)
605 ExitFunction(); // aborted by user
606
607 // log
608 WcaLog(LOGMSG_VERBOSE, "Unregistering assembly, key: %S", pAttrs->pwzKey);
609
610 // extract path from GAC
611 if (pAttrs->iAttributes & aaPathFromGAC)
612 {
613 hr = GetAssemblyPathFromGAC(pAttrs->pwzAssemblyName, &pAttrs->pwzDllPath);
614 ExitOnFailure(hr, "Failed to get path for assembly from GAC");
615
616 if (S_FALSE == hr)
617 {
618 WcaLog(LOGMSG_VERBOSE, "Unable to locate assembly in GAC, assembly will not be unregistered from COM+, key: %S", pAttrs->pwzKey);
619 ExitFunction1(hr = S_OK);
620 }
621
622 // log
623 WcaLog(LOGMSG_VERBOSE, "Assembly path extracted from GAC, key: %S, path: '%S'", pAttrs->pwzKey, pAttrs->pwzDllPath);
624 }
625
626 // .NET assembly
627 if (pAttrs->iAttributes & aaDotNetAssembly)
628 {
629 if (pAttrs->pwzAppID && *pAttrs->pwzAppID)
630 {
631 // When unregistering a .net assembly using the RegistrationHelper class, and the application is
632 // left empty after all components in the assembly are removed, the RegistrationHelper class also
633 // attempts to remove the application for some reason. However, it does not handle the situation
634 // when the application has its deleteable property set to false, and will simply fail if this is
635 // the case. This is the reason we are clearing the deleatable property of the application here.
636 //
637 // TODO: handle rollbacks
638
639 // get applications collection
640 hr = CpiExecGetApplicationsCollection(pAttrs->pwzPartID, &piColl);
641 ExitOnFailure(hr, "Failed to get applications collection");
642
643 if (S_FALSE == hr)
644 {
645 // applications collection not found
646 WcaLog(LOGMSG_VERBOSE, "Unable to retrieve applications collection, nothing to delete, key: %S", pAttrs->pwzKey);
647 ExitFunction1(hr = S_OK);
648 }
649
650 // find application object
651 hr = CpiFindCollectionObjectByStringKey(piColl, pAttrs->pwzAppID, &piObj);
652 ExitOnFailure(hr, "Failed to find application object");
653
654 if (S_FALSE == hr)
655 {
656 // application not found
657 WcaLog(LOGMSG_VERBOSE, "Unable to find application object, nothing to delete, key: %S", pAttrs->pwzKey);
658 ExitFunction1(hr = S_OK);
659 }
660
661 // reset deleteable property
662 hr = CpiResetObjectProperty(piColl, piObj, L"Deleteable");
663 ExitOnFailure(hr, "Failed to reset deleteable property");
664 }
665
666 // unregister assembly
667 hr = UnregisterDotNetAssembly(pAttrs);
668 ExitOnFailure(hr, "Failed to unregister .NET assembly");
669 }
670
671 // native assembly
672 else
673 {
674 // get components collection
675 hr = CpiGetComponentsCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, &piColl);
676 ExitOnFailure(hr, "Failed to get components collection");
677
678 if (S_FALSE == hr)
679 {
680 // components collection not found
681 WcaLog(LOGMSG_VERBOSE, "Unable to retrieve components collection, nothing to delete, key: %S", pAttrs->pwzKey);
682 ExitFunction1(hr = S_OK);
683 }
684
685 // remove components
686 hr = RemoveComponents(piColl, pAttrs->pCompList);
687 ExitOnFailure(hr, "Failed to get remove components");
688
689 // save changes
690 hr = piColl->SaveChanges(&lChanges);
691 if (COMADMIN_E_OBJECTERRORS == hr)
692 CpiLogCatalogErrorInfo();
693 ExitOnFailure(hr, "Failed to save changes");
694 }
695
696 hr = S_OK;
697
698LExit:
699 // clean up
700 ReleaseObject(piColl);
701 ReleaseObject(piObj);
702
703 return hr;
704}
705
706static void InitAssemblyExec()
707{
708 gpiRegHlp = NULL;
709 gpAssemblyCache = NULL;
710 ghMscoree = NULL;
711 ghFusion = NULL;
712}
713
714static void UninitAssemblyExec()
715{
716 ReleaseObject(gpiRegHlp);
717 ReleaseObject(gpAssemblyCache);
718 if (ghFusion)
719 ::FreeLibrary(ghFusion);
720 if (ghMscoree)
721 ::FreeLibrary(ghMscoree);
722}
723
724static HRESULT GetRegistrationHelper(
725 IDispatch** ppiRegHlp
726 )
727{
728 HRESULT hr = S_OK;
729
730 if (!gpiRegHlp)
731 {
732 // create registration helper object
733 hr = ::CoCreateInstance(CLSID_RegistrationHelper, NULL, CLSCTX_ALL, IID_IDispatch, (void**)&gpiRegHlp);
734 ExitOnFailure(hr, "Failed to create registration helper object");
735 }
736
737 gpiRegHlp->AddRef();
738 *ppiRegHlp = gpiRegHlp;
739
740 hr = S_OK;
741
742LExit:
743 return hr;
744}
745
746static HRESULT GetAssemblyCacheObject(
747 IAssemblyCache** ppAssemblyCache
748 )
749{
750 HRESULT hr = S_OK;
751
752 if (!gpAssemblyCache)
753 {
754 // mscoree.dll
755 if (!ghMscoree)
756 {
757 // load mscoree.dll
758 ghMscoree = ::LoadLibraryW(L"mscoree.dll");
759 ExitOnNull(ghMscoree, hr, E_FAIL, "Failed to load mscoree.dll");
760 }
761
762 // fusion.dll
763 if (!ghFusion)
764 {
765 // get LoadLibraryShim function address
766 LoadLibraryShimFunc pfnLoadLibraryShim = (LoadLibraryShimFunc)::GetProcAddress(ghMscoree, "LoadLibraryShim");
767 ExitOnNull(pfnLoadLibraryShim, hr, HRESULT_FROM_WIN32(::GetLastError()), "Failed get address for LoadLibraryShim() function");
768
769 // load fusion.dll
770 hr = pfnLoadLibraryShim(L"fusion.dll", NULL, NULL, &ghFusion);
771 ExitOnFailure(hr, "Failed to load fusion.dll");
772 }
773
774 // get CreateAssemblyCache function address
775 CreateAssemblyCacheFunc pfnCreateAssemblyCache = (CreateAssemblyCacheFunc)::GetProcAddress(ghFusion, "CreateAssemblyCache");
776 ExitOnNull(pfnCreateAssemblyCache, hr, HRESULT_FROM_WIN32(::GetLastError()), "Failed get address for CreateAssemblyCache() function");
777
778 // create AssemblyCache object
779 hr = pfnCreateAssemblyCache(&gpAssemblyCache, 0);
780 ExitOnFailure(hr, "Failed to create AssemblyCache object");
781 }
782
783 gpAssemblyCache->AddRef();
784 *ppAssemblyCache = gpAssemblyCache;
785
786 hr = S_OK;
787
788LExit:
789 return hr;
790}
791
792static HRESULT GetAssemblyPathFromGAC(
793 LPCWSTR pwzAssemblyName,
794 LPWSTR* ppwzAssemblyPath
795 )
796{
797 HRESULT hr = S_OK;
798
799 IAssemblyCache* pAssemblyCache = NULL;
800
801 ASSEMBLY_INFO assemblyInfo;
802 WCHAR wzPathBuf[MAX_PATH];
803
804 ::ZeroMemory(&assemblyInfo, sizeof(ASSEMBLY_INFO));
805 ::ZeroMemory(wzPathBuf, countof(wzPathBuf));
806
807 // get AssemblyCache object
808 hr = GetAssemblyCacheObject(&pAssemblyCache);
809 ExitOnFailure(hr, "Failed to get AssemblyCache object");
810
811 // get assembly info
812 assemblyInfo.cbAssemblyInfo = sizeof(ASSEMBLY_INFO);
813 assemblyInfo.pszCurrentAssemblyPathBuf = wzPathBuf;
814 assemblyInfo.cchBuf = countof(wzPathBuf);
815
816 hr = pAssemblyCache->QueryAssemblyInfo(0, pwzAssemblyName, &assemblyInfo);
817 if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
818 ExitFunction1(hr = S_FALSE);
819 ExitOnFailure(hr, "Failed to get assembly info");
820
821 // copy assembly path
822 hr = StrAllocString(ppwzAssemblyPath, wzPathBuf, 0);
823 ExitOnFailure(hr, "Failed to copy assembly path");
824
825 hr = S_OK;
826
827LExit:
828 // clean up
829 ReleaseObject(pAssemblyCache);
830
831 return hr;
832}
833
834static HRESULT RegisterDotNetAssembly(
835 CPI_ASSEMBLY_ATTRIBUTES* pAttrs
836 )
837{
838 HRESULT hr = S_OK;
839
840 IDispatch* piRegHlp = NULL;
841
842 DISPID dispid;
843 BSTR bstrMember = NULL;
844
845 long lInstallationFlags = 0;
846
847 VARIANTARG rgvarg[5];
848 DISPPARAMS dispparams;
849 EXCEPINFO excepInfo;
850
851 BSTR bstrPartName = NULL;
852 BSTR bstrAppName = NULL;
853 BSTR bstrDllPath = NULL;
854 BSTR bstrTlbPath = NULL;
855
856 ::ZeroMemory(rgvarg, sizeof(rgvarg));
857 ::ZeroMemory(&dispparams, sizeof(dispparams));
858 ::ZeroMemory(&excepInfo, sizeof(excepInfo));
859
860 bstrMember = ::SysAllocString(L"InstallAssembly_2");
861 ExitOnNull(bstrMember, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for method name");
862
863 // create BSTRs for parameters
864 if (pAttrs->pwzPartID && *pAttrs->pwzPartID)
865 {
866 bstrPartName = ::SysAllocString(pAttrs->pwzPartID);
867 ExitOnNull(bstrPartName, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for partition id");
868 }
869
870 if (pAttrs->pwzAppID && *pAttrs->pwzAppID)
871 {
872 bstrAppName = ::SysAllocString(pAttrs->pwzAppID);
873 ExitOnNull(bstrAppName, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for application id");
874 }
875
876 bstrDllPath = ::SysAllocString(pAttrs->pwzDllPath);
877 ExitOnNull(bstrDllPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for dll path");
878
879 if (pAttrs->pwzTlbPath && *pAttrs->pwzTlbPath)
880 {
881 bstrTlbPath = ::SysAllocString(pAttrs->pwzTlbPath);
882 ExitOnNull(bstrTlbPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for tlb path");
883 }
884
885 // get registration helper object
886 hr = GetRegistrationHelper(&piRegHlp);
887 ExitOnFailure(hr, "Failed to get registration helper object");
888
889 // get dispatch id of InstallAssembly() method
890 hr = piRegHlp->GetIDsOfNames(IID_NULL, &bstrMember, 1, LOCALE_USER_DEFAULT, &dispid);
891 ExitOnFailure(hr, "Failed to get dispatch id of InstallAssembly() method");
892
893 // set installation flags
894 lInstallationFlags = ifExpectExistingTypeLib;
895
896 if (!bstrAppName)
897 lInstallationFlags |= ifFindOrCreateTargetApplication;
898
899 // invoke InstallAssembly() method
900 rgvarg[0].vt = VT_I4;
901 rgvarg[0].lVal = lInstallationFlags;
902 rgvarg[1].vt = VT_BYREF|VT_BSTR;
903 rgvarg[1].pbstrVal = &bstrTlbPath;
904 rgvarg[2].vt = VT_BSTR;
905 rgvarg[2].bstrVal = bstrPartName;
906 rgvarg[3].vt = VT_BYREF|VT_BSTR;
907 rgvarg[3].pbstrVal = &bstrAppName;
908 rgvarg[4].vt = VT_BSTR;
909 rgvarg[4].bstrVal = bstrDllPath;
910 dispparams.rgvarg = rgvarg;
911 dispparams.cArgs = 5;
912 dispparams.cNamedArgs = 0;
913
914 hr = piRegHlp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, NULL, &excepInfo, NULL);
915 if (DISP_E_EXCEPTION == hr)
916 {
917 // log exception information
918 if (!excepInfo.pfnDeferredFillIn || (excepInfo.pfnDeferredFillIn && SUCCEEDED(excepInfo.pfnDeferredFillIn(&excepInfo))))
919 {
920 WcaLog(LOGMSG_STANDARD, "ExceptionInfo: Code='%hu', Source='%S', Description='%S', HelpFile='%S', HelpContext='%u'",
921 excepInfo.wCode, excepInfo.bstrSource,
922 excepInfo.bstrDescription ? excepInfo.bstrDescription : L"",
923 excepInfo.bstrHelpFile ? excepInfo.bstrHelpFile : L"",
924 excepInfo.dwHelpContext);
925 }
926 }
927 ExitOnFailure(hr, "Failed to invoke RegistrationHelper.InstallAssembly() method");
928
929 hr = S_OK;
930
931LExit:
932 // clean up
933 ReleaseObject(piRegHlp);
934
935 ReleaseBSTR(bstrMember);
936
937 ReleaseBSTR(excepInfo.bstrSource);
938 ReleaseBSTR(excepInfo.bstrDescription);
939 ReleaseBSTR(excepInfo.bstrHelpFile);
940
941 ReleaseBSTR(bstrPartName);
942 ReleaseBSTR(bstrAppName);
943 ReleaseBSTR(bstrDllPath);
944 ReleaseBSTR(bstrTlbPath);
945
946 return hr;
947}
948
949static HRESULT RegisterNativeAssembly(
950 CPI_ASSEMBLY_ATTRIBUTES* pAttrs
951 )
952{
953 HRESULT hr = S_OK;
954
955 ICOMAdminCatalog* piCatalog = NULL;
956 ICOMAdminCatalog2* piCatalog2 = NULL;
957 BSTR bstrGlobPartID = NULL;
958
959 BSTR bstrPartID = NULL;
960 BSTR bstrAppID = NULL;
961 BSTR bstrDllPath = NULL;
962 BSTR bstrTlbPath = NULL;
963 BSTR bstrPSDllPath = NULL;
964
965 // create BSTRs for parameters
966 if (pAttrs->pwzPartID && *pAttrs->pwzPartID)
967 {
968 bstrPartID = ::SysAllocString(pAttrs->pwzPartID);
969 ExitOnNull(bstrPartID, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for partition id");
970 }
971
972 bstrAppID = ::SysAllocString(pAttrs->pwzAppID);
973 ExitOnNull(bstrAppID, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for application id");
974
975 bstrDllPath = ::SysAllocString(pAttrs->pwzDllPath);
976 ExitOnNull(bstrDllPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for dll path");
977
978 bstrTlbPath = ::SysAllocString(pAttrs->pwzTlbPath ? pAttrs->pwzTlbPath : L"");
979 ExitOnNull(bstrTlbPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for tlb path");
980
981 bstrPSDllPath = ::SysAllocString(pAttrs->pwzPSDllPath ? pAttrs->pwzPSDllPath : L"");
982 ExitOnNull(bstrPSDllPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for tlb path");
983
984 // get catalog
985 hr = CpiExecGetAdminCatalog(&piCatalog);
986 ExitOnFailure(hr, "Failed to get COM+ admin catalog");
987
988 // get ICOMAdminCatalog2 interface
989 hr = piCatalog->QueryInterface(IID_ICOMAdminCatalog2, (void**)&piCatalog2);
990
991 // COM+ 1.5 or later
992 if (E_NOINTERFACE != hr)
993 {
994 ExitOnFailure(hr, "Failed to get IID_ICOMAdminCatalog2 interface");
995
996 // partition id
997 if (!bstrPartID)
998 {
999 // get global partition id
1000 hr = piCatalog2->get_GlobalPartitionID(&bstrGlobPartID);
1001 ExitOnFailure(hr, "Failed to get global partition id");
1002 }
1003
1004 // set current partition
1005 hr = piCatalog2->put_CurrentPartition(bstrPartID ? bstrPartID : bstrGlobPartID);
1006 ExitOnFailure(hr, "Failed to set current partition");
1007 }
1008
1009 // COM+ pre 1.5
1010 else
1011 {
1012 // this version of COM+ does not support partitions, make sure a partition was not specified
1013 if (bstrPartID)
1014 ExitOnFailure(hr = E_FAIL, "Partitions are not supported by this version of COM+");
1015 }
1016
1017 // install event classes
1018 if (pAttrs->iAttributes & aaEventClass)
1019 {
1020 hr = piCatalog->InstallEventClass(bstrAppID, bstrDllPath, bstrTlbPath, bstrPSDllPath);
1021 if (COMADMIN_E_OBJECTERRORS == hr)
1022 CpiLogCatalogErrorInfo();
1023 ExitOnFailure(hr, "Failed to install event classes");
1024 }
1025
1026 // install components
1027 else
1028 {
1029 hr = piCatalog->InstallComponent(bstrAppID, bstrDllPath, bstrTlbPath, bstrPSDllPath);
1030 if (COMADMIN_E_OBJECTERRORS == hr)
1031 CpiLogCatalogErrorInfo();
1032 ExitOnFailure(hr, "Failed to install components");
1033 }
1034
1035 hr = S_OK;
1036
1037LExit:
1038 // clean up
1039 ReleaseObject(piCatalog);
1040 ReleaseObject(piCatalog2);
1041 ReleaseBSTR(bstrGlobPartID);
1042
1043 ReleaseBSTR(bstrPartID);
1044 ReleaseBSTR(bstrAppID);
1045 ReleaseBSTR(bstrDllPath);
1046 ReleaseBSTR(bstrTlbPath);
1047 ReleaseBSTR(bstrPSDllPath);
1048
1049 return hr;
1050}
1051
1052static HRESULT UnregisterDotNetAssembly(
1053 CPI_ASSEMBLY_ATTRIBUTES* pAttrs
1054 )
1055{
1056 HRESULT hr = S_OK;
1057
1058 IDispatch* piRegHlp = NULL;
1059
1060 DISPID dispid;
1061 BSTR bstrMember = NULL;
1062
1063 VARIANTARG rgvarg[3];
1064 DISPPARAMS dispparams;
1065 EXCEPINFO excepInfo;
1066
1067 BSTR bstrPartName = NULL;
1068 BSTR bstrAppName = NULL;
1069 BSTR bstrDllPath = NULL;
1070
1071 ::ZeroMemory(rgvarg, sizeof(rgvarg));
1072 ::ZeroMemory(&dispparams, sizeof(dispparams));
1073 ::ZeroMemory(&excepInfo, sizeof(excepInfo));
1074
1075 bstrMember = ::SysAllocString(L"UninstallAssembly_2");
1076 ExitOnNull(bstrMember, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for method name");
1077
1078 // create BSTRs for parameters
1079 if (pAttrs->pwzPartID && *pAttrs->pwzPartID)
1080 {
1081 bstrPartName = ::SysAllocString(pAttrs->pwzPartID);
1082 ExitOnNull(bstrPartName, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for partition id");
1083 }
1084
1085 bstrAppName = ::SysAllocString(pAttrs->pwzAppID);
1086 ExitOnNull(bstrAppName, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for application id");
1087
1088 bstrDllPath = ::SysAllocString(pAttrs->pwzDllPath);
1089 ExitOnNull(bstrDllPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for dll path");
1090
1091 // get registration helper object
1092 hr = GetRegistrationHelper(&piRegHlp);
1093 ExitOnFailure(hr, "Failed to get registration helper object");
1094
1095 // get dispatch id of UninstallAssembly() method
1096 hr = piRegHlp->GetIDsOfNames(IID_NULL, &bstrMember, 1, LOCALE_USER_DEFAULT, &dispid);
1097 ExitOnFailure(hr, "Failed to get dispatch id of UninstallAssembly() method");
1098
1099 // invoke UninstallAssembly() method
1100 rgvarg[0].vt = VT_BSTR;
1101 rgvarg[0].bstrVal = bstrPartName;
1102 rgvarg[1].vt = VT_BSTR;
1103 rgvarg[1].bstrVal = bstrAppName;
1104 rgvarg[2].vt = VT_BSTR;
1105 rgvarg[2].bstrVal = bstrDllPath;
1106 dispparams.rgvarg = rgvarg;
1107 dispparams.cArgs = 3;
1108 dispparams.cNamedArgs = 0;
1109
1110 hr = piRegHlp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, NULL, &excepInfo, NULL);
1111 if (DISP_E_EXCEPTION == hr)
1112 {
1113 // log exception information
1114 if (!excepInfo.pfnDeferredFillIn || (excepInfo.pfnDeferredFillIn && SUCCEEDED(excepInfo.pfnDeferredFillIn(&excepInfo))))
1115 {
1116 WcaLog(LOGMSG_STANDARD, "ExceptionInfo: Code='%hu', Source='%S', Description='%S', HelpFile='%S', HelpContext='%u'",
1117 excepInfo.wCode, excepInfo.bstrSource,
1118 excepInfo.bstrDescription ? excepInfo.bstrDescription : L"",
1119 excepInfo.bstrHelpFile ? excepInfo.bstrHelpFile : L"",
1120 excepInfo.dwHelpContext);
1121 }
1122 }
1123 ExitOnFailure(hr, "Failed to invoke RegistrationHelper.UninstallAssembly() method");
1124
1125 hr = S_OK;
1126
1127LExit:
1128 // clean up
1129 ReleaseObject(piRegHlp);
1130
1131 ReleaseBSTR(bstrMember);
1132
1133 ReleaseBSTR(excepInfo.bstrSource);
1134 ReleaseBSTR(excepInfo.bstrDescription);
1135 ReleaseBSTR(excepInfo.bstrHelpFile);
1136
1137 ReleaseBSTR(bstrPartName);
1138 ReleaseBSTR(bstrAppName);
1139 ReleaseBSTR(bstrDllPath);
1140
1141 return hr;
1142}
1143
1144static HRESULT RemoveComponents(
1145 ICatalogCollection* piCompColl,
1146 CPIEXEC_COMPONENT* pCompList
1147 )
1148{
1149 HRESULT hr = S_OK;
1150
1151 for (CPIEXEC_COMPONENT* pItm = pCompList; pItm; pItm = pItm->pNext)
1152 {
1153 // remove
1154 hr = CpiRemoveCollectionObject(piCompColl, pItm->wzCLSID, NULL, FALSE);
1155 ExitOnFailure(hr, "Failed to remove component");
1156
1157 if (S_FALSE == hr)
1158 WcaLog(LOGMSG_VERBOSE, "Component not found, nothing to delete, key: %S", pItm->wzCLSID);
1159 }
1160
1161 hr = S_OK;
1162
1163LExit:
1164 return hr;
1165}
1166
1167static HRESULT ReadAssemblyAttributes(
1168 LPWSTR* ppwzData,
1169 CPI_ASSEMBLY_ATTRIBUTES* pAttrs
1170 )
1171{
1172 HRESULT hr = S_OK;
1173
1174 // read attributes
1175 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
1176 ExitOnFailure(hr, "Failed to read action type");
1177 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
1178 ExitOnFailure(hr, "Failed to read action cost");
1179 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
1180 ExitOnFailure(hr, "Failed to read key");
1181 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAssemblyName);
1182 ExitOnFailure(hr, "Failed to read assembly name");
1183 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzDllPath);
1184 ExitOnFailure(hr, "Failed to read dll path");
1185 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzTlbPath);
1186 ExitOnFailure(hr, "Failed to read tlb path");
1187 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPSDllPath);
1188 ExitOnFailure(hr, "Failed to read proxy-stub dll path");
1189 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iAttributes);
1190 ExitOnFailure(hr, "Failed to read attributes");
1191 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAppID);
1192 ExitOnFailure(hr, "Failed to read application id");
1193 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
1194 ExitOnFailure(hr, "Failed to read partition id");
1195
1196 // free existing component list
1197 if (pAttrs->pCompList)
1198 {
1199 FreeComponentList(pAttrs->pCompList);
1200 pAttrs->pCompList = NULL;
1201 }
1202
1203 // read components
1204 hr = ReadComponentList(ppwzData, &pAttrs->pCompList);
1205 ExitOnFailure(hr, "Failed to read components");
1206
1207 hr = S_OK;
1208
1209LExit:
1210 return hr;
1211}
1212
1213static void FreeAssemblyAttributes(
1214 CPI_ASSEMBLY_ATTRIBUTES* pAttrs
1215 )
1216{
1217 ReleaseStr(pAttrs->pwzKey);
1218 ReleaseStr(pAttrs->pwzAssemblyName);
1219 ReleaseStr(pAttrs->pwzDllPath);
1220 ReleaseStr(pAttrs->pwzTlbPath);
1221 ReleaseStr(pAttrs->pwzPSDllPath);
1222 ReleaseStr(pAttrs->pwzAppID);
1223 ReleaseStr(pAttrs->pwzPartID);
1224
1225 if (pAttrs->pCompList)
1226 FreeComponentList(pAttrs->pCompList);
1227}
1228
1229static HRESULT ReadRoleAssignmentsAttributes(
1230 LPWSTR* ppwzData,
1231 CPI_ROLE_ASSIGNMENTS_ATTRIBUTES* pAttrs
1232 )
1233{
1234 HRESULT hr = S_OK;
1235
1236 // read attributes
1237 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
1238 ExitOnFailure(hr, "Failed to read action type");
1239 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
1240 ExitOnFailure(hr, "Failed to read action cost");
1241 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
1242 ExitOnFailure(hr, "Failed to read key");
1243 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iRoleCount);
1244 ExitOnFailure(hr, "Failed to read role assignments count");
1245 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAppID);
1246 ExitOnFailure(hr, "Failed to read application id");
1247 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
1248 ExitOnFailure(hr, "Failed to read partition id");
1249
1250 // free existing component list
1251 if (pAttrs->pCompList)
1252 {
1253 FreeComponentList(pAttrs->pCompList);
1254 pAttrs->pCompList = NULL;
1255 }
1256
1257 // read components
1258 hr = ReadComponentList(ppwzData, &pAttrs->pCompList);
1259 ExitOnFailure(hr, "Failed to read components");
1260
1261 hr = S_OK;
1262
1263LExit:
1264 return hr;
1265}
1266
1267static void FreeRoleAssignmentsAttributes(
1268 CPI_ROLE_ASSIGNMENTS_ATTRIBUTES* pAttrs
1269 )
1270{
1271 ReleaseStr(pAttrs->pwzKey);
1272 ReleaseStr(pAttrs->pwzAppID);
1273 ReleaseStr(pAttrs->pwzPartID);
1274
1275 if (pAttrs->pCompList)
1276 FreeComponentList(pAttrs->pCompList);
1277}
1278
1279
1280static HRESULT ConfigureComponents(
1281 LPCWSTR pwzPartID,
1282 LPCWSTR pwzAppID,
1283 CPIEXEC_COMPONENT* pCompList,
1284 BOOL fCreate,
1285 BOOL fProgress
1286 )
1287{
1288 HRESULT hr = S_OK;
1289
1290 ICatalogCollection* piCompColl = NULL;
1291 ICatalogObject* piCompObj = NULL;
1292
1293 long lChanges = 0;
1294
1295 // get components collection
1296 hr = CpiGetComponentsCollection(pwzPartID, pwzAppID, &piCompColl);
1297 if (S_FALSE == hr)
1298 if (fCreate)
1299 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1300 else
1301 ExitFunction1(hr = S_OK);
1302 ExitOnFailure(hr, "Failed to get components collection");
1303
1304 // read components
1305 for (CPIEXEC_COMPONENT* pItm = pCompList; pItm; pItm = pItm->pNext)
1306 {
1307 // progress message
1308 if (fProgress)
1309 {
1310 hr = CpiActionDataMessage(1, pItm->wzCLSID);
1311 ExitOnFailure(hr, "Failed to send progress messages");
1312
1313 if (S_FALSE == hr)
1314 ExitFunction(); // aborted by user
1315 }
1316
1317 // find component
1318 hr = CpiFindCollectionObjectByStringKey(piCompColl, pItm->wzCLSID, &piCompObj);
1319 if (S_FALSE == hr)
1320 if (fCreate)
1321 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1322 else
1323 continue;
1324 ExitOnFailure(hr, "Failed to find component object");
1325
1326 // properties
1327 hr = CpiPutCollectionObjectValues(piCompObj, pItm->pPropertyList);
1328 ExitOnFailure(hr, "Failed to write properties");
1329
1330 // read roles
1331 if (pItm->pRoleAssignmentList)
1332 {
1333 hr = ConfigureRoleAssignments(L"RolesForComponent", piCompColl, piCompObj, pItm->pRoleAssignmentList, fCreate);
1334 ExitOnFailure(hr, "Failed to read roles");
1335 }
1336
1337 // read interfaces
1338 if (pItm->pInterfaceList)
1339 {
1340 hr = ConfigureInterfaces(piCompColl, piCompObj, pItm->pInterfaceList, fCreate);
1341 ExitOnFailure(hr, "Failed to read interfaces");
1342 }
1343
1344 // clean up
1345 ReleaseNullObject(piCompObj);
1346 }
1347
1348 // save changes
1349 hr = piCompColl->SaveChanges(&lChanges);
1350 if (COMADMIN_E_OBJECTERRORS == hr)
1351 CpiLogCatalogErrorInfo();
1352 ExitOnFailure(hr, "Failed to save changes");
1353
1354 hr = S_OK;
1355
1356LExit:
1357 // clean up
1358 ReleaseObject(piCompColl);
1359 ReleaseObject(piCompObj);
1360
1361 return hr;
1362}
1363
1364static HRESULT ConfigureInterfaces(
1365 ICatalogCollection* piCompColl,
1366 ICatalogObject* piCompObj,
1367 CPIEXEC_INTERFACE* pIntfList,
1368 BOOL fCreate
1369 )
1370{
1371 HRESULT hr = S_OK;
1372
1373 ICatalogCollection* piIntfColl = NULL;
1374 ICatalogObject* piIntfObj = NULL;
1375
1376 long lChanges = 0;
1377
1378 // get interfaces collection
1379 hr = CpiGetInterfacesCollection(piCompColl, piCompObj, &piIntfColl);
1380 if (S_FALSE == hr)
1381 if (fCreate)
1382 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1383 else
1384 ExitFunction1(hr = S_OK);
1385 ExitOnFailure(hr, "Failed to get interfaces collection");
1386
1387 // read interfaces
1388 for (CPIEXEC_INTERFACE* pItm = pIntfList; pItm; pItm = pItm->pNext)
1389 {
1390 // find interface
1391 hr = CpiFindCollectionObjectByStringKey(piIntfColl, pItm->wzIID, &piIntfObj);
1392 if (S_FALSE == hr)
1393 if (fCreate)
1394 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1395 else
1396 continue;
1397 ExitOnFailure(hr, "Failed to find interface object");
1398
1399 // properties
1400 hr = CpiPutCollectionObjectValues(piIntfObj, pItm->pPropertyList);
1401 ExitOnFailure(hr, "Failed to write properties");
1402
1403 // read roles
1404 if (pItm->pRoleAssignmentList)
1405 {
1406 hr = ConfigureRoleAssignments(L"RolesForInterface", piIntfColl, piIntfObj, pItm->pRoleAssignmentList, fCreate);
1407 ExitOnFailure(hr, "Failed to read roles");
1408 }
1409
1410 // read methods
1411 if (pItm->pMethodList)
1412 {
1413 hr = ConfigureMethods(piIntfColl, piIntfObj, pItm->pMethodList, fCreate);
1414 ExitOnFailure(hr, "Failed to read methods");
1415 }
1416
1417 // clean up
1418 ReleaseNullObject(piIntfObj);
1419 }
1420
1421 // save changes
1422 hr = piIntfColl->SaveChanges(&lChanges);
1423 if (COMADMIN_E_OBJECTERRORS == hr)
1424 CpiLogCatalogErrorInfo();
1425 ExitOnFailure(hr, "Failed to save changes");
1426
1427 hr = S_OK;
1428
1429LExit:
1430 // clean up
1431 ReleaseObject(piIntfColl);
1432 ReleaseObject(piIntfObj);
1433
1434 return hr;
1435}
1436
1437static HRESULT ConfigureMethods(
1438 ICatalogCollection* piIntfColl,
1439 ICatalogObject* piIntfObj,
1440 CPIEXEC_METHOD* pMethList,
1441 BOOL fCreate
1442 )
1443{
1444 HRESULT hr = S_OK;
1445
1446 ICatalogCollection* piMethColl = NULL;
1447 ICatalogObject* piMethObj = NULL;
1448
1449 long lChanges = 0;
1450
1451 // get methods collection
1452 hr = CpiGetMethodsCollection(piIntfColl, piIntfObj, &piMethColl);
1453 if (S_FALSE == hr)
1454 if (fCreate)
1455 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1456 else
1457 ExitFunction1(hr = S_OK);
1458 ExitOnFailure(hr, "Failed to get methods collection");
1459
1460 // read methods
1461 for (CPIEXEC_METHOD* pItm = pMethList; pItm; pItm = pItm->pNext)
1462 {
1463 // find method
1464 if (*pItm->wzIndex)
1465 hr = CpiFindCollectionObjectByIntegerKey(piMethColl, _wtol(pItm->wzIndex), &piMethObj);
1466 else
1467 hr = CpiFindCollectionObjectByName(piMethColl, pItm->wzName, &piMethObj);
1468
1469 if (S_FALSE == hr)
1470 if (fCreate)
1471 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1472 else
1473 continue;
1474 ExitOnFailure(hr, "Failed to find method object");
1475
1476 // properties
1477 hr = CpiPutCollectionObjectValues(piMethObj, pItm->pPropertyList);
1478 ExitOnFailure(hr, "Failed to write properties");
1479
1480 // read roles
1481 if (pItm->pRoleAssignmentList)
1482 {
1483 hr = ConfigureRoleAssignments(L"RolesForMethod", piMethColl, piMethObj, pItm->pRoleAssignmentList, fCreate);
1484 ExitOnFailure(hr, "Failed to read roles");
1485 }
1486
1487 // clean up
1488 ReleaseNullObject(piMethObj);
1489 }
1490
1491 // save changes
1492 hr = piMethColl->SaveChanges(&lChanges);
1493 if (COMADMIN_E_OBJECTERRORS == hr)
1494 CpiLogCatalogErrorInfo();
1495 ExitOnFailure(hr, "Failed to save changes");
1496
1497 hr = S_OK;
1498
1499LExit:
1500 // clean up
1501 ReleaseObject(piMethColl);
1502 ReleaseObject(piMethObj);
1503
1504 return hr;
1505}
1506
1507static HRESULT ConfigureRoleAssignments(
1508 LPCWSTR pwzCollName,
1509 ICatalogCollection* piCompColl,
1510 ICatalogObject* piCompObj,
1511 CPIEXEC_ROLE_ASSIGNMENT* pRoleList,
1512 BOOL fCreate
1513 )
1514{
1515 HRESULT hr = S_OK;
1516
1517 ICatalogCollection* piRoleColl = NULL;
1518 ICatalogObject* piRoleObj = NULL;
1519
1520 long lChanges = 0;
1521
1522 // get roles collection
1523 hr = CpiExecGetCatalogCollection(piCompColl, piCompObj, pwzCollName, &piRoleColl);
1524 if (S_FALSE == hr)
1525 if (fCreate)
1526 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1527 else
1528 ExitFunction1(hr = S_OK);
1529 ExitOnFailure(hr, "Failed to get role assignments collection");
1530
1531 // read roles
1532 for (CPIEXEC_ROLE_ASSIGNMENT* pItm = pRoleList; pItm; pItm = pItm->pNext)
1533 {
1534 if (fCreate)
1535 {
1536 // find existing role
1537 hr = CpiFindCollectionObjectByName(piRoleColl, pItm->wzRoleName, NULL);
1538 ExitOnFailure(hr, "Failed to find role, key: %S", pItm->wzKey);
1539
1540 if (S_OK == hr)
1541 continue; // role already exists
1542
1543 // add object
1544 hr = CpiAddCollectionObject(piRoleColl, &piRoleObj);
1545 ExitOnFailure(hr, "Failed to add role assignment to collection");
1546
1547 // role name
1548 hr = CpiPutCollectionObjectValue(piRoleObj, L"Name", pItm->wzRoleName);
1549 ExitOnFailure(hr, "Failed to set role name property, key: %S", pItm->wzKey);
1550
1551 // clean up
1552 ReleaseNullObject(piRoleObj);
1553 }
1554 else
1555 {
1556 // remove role
1557 hr = CpiRemoveCollectionObject(piRoleColl, NULL, pItm->wzRoleName, FALSE);
1558 ExitOnFailure(hr, "Failed to remove role, key: %S", pItm->wzKey);
1559 }
1560 }
1561
1562 // save changes
1563 hr = piRoleColl->SaveChanges(&lChanges);
1564 if (COMADMIN_E_OBJECTERRORS == hr)
1565 CpiLogCatalogErrorInfo();
1566 ExitOnFailure(hr, "Failed to save changes");
1567
1568 hr = S_OK;
1569
1570LExit:
1571 // clean up
1572 ReleaseObject(piRoleColl);
1573 ReleaseObject(piRoleObj);
1574
1575 return hr;
1576}
1577
1578static HRESULT ReadComponentList(
1579 LPWSTR* ppwzData,
1580 CPIEXEC_COMPONENT** ppCompList
1581 )
1582{
1583 HRESULT hr = S_OK;
1584
1585 LPWSTR pwzData = NULL;
1586
1587 CPIEXEC_COMPONENT* pItm = NULL;
1588
1589 int iCnt = 0;
1590
1591 // read count
1592 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
1593 ExitOnFailure(hr, "Failed to read count");
1594
1595 // read components
1596 for (int i = 0; i < iCnt; i++)
1597 {
1598 pItm = (CPIEXEC_COMPONENT*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPIEXEC_COMPONENT));
1599 if (!pItm)
1600 ExitFunction1(hr = E_OUTOFMEMORY);
1601
1602 // read clsid
1603 hr = WcaReadStringFromCaData(ppwzData, &pwzData);
1604 ExitOnFailure(hr, "Failed to read clsid");
1605 StringCchCopyW(pItm->wzCLSID, countof(pItm->wzCLSID), pwzData);
1606
1607 // read properties
1608 hr = CpiReadPropertyList(ppwzData, &pItm->pPropertyList);
1609 ExitOnFailure(hr, "Failed to read properties");
1610
1611 // read role assignments
1612 hr = ReadRoleAssignmentList(ppwzData, &pItm->pRoleAssignmentList);
1613 ExitOnFailure(hr, "Failed to read role assignments");
1614
1615 // read interfaces
1616 hr = ReadInterfaceList(ppwzData, &pItm->pInterfaceList);
1617 ExitOnFailure(hr, "Failed to read interfaces");
1618
1619 // add to list
1620 if (*ppCompList)
1621 pItm->pNext = *ppCompList;
1622 *ppCompList = pItm;
1623 pItm = NULL;
1624 }
1625
1626 hr = S_OK;
1627
1628LExit:
1629 // clean up
1630 ReleaseStr(pwzData);
1631
1632 if (pItm)
1633 FreeComponentList(pItm);
1634
1635 return hr;
1636}
1637
1638static HRESULT ReadInterfaceList(
1639 LPWSTR* ppwzData,
1640 CPIEXEC_INTERFACE** ppIntfList
1641 )
1642{
1643 HRESULT hr = S_OK;
1644
1645 LPWSTR pwzData = NULL;
1646
1647 CPIEXEC_INTERFACE* pItm = NULL;
1648
1649 int iCnt = 0;
1650
1651 // read count
1652 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
1653 ExitOnFailure(hr, "Failed to read count");
1654
1655 // read interfaces
1656 for (int i = 0; i < iCnt; i++)
1657 {
1658 pItm = (CPIEXEC_INTERFACE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPIEXEC_INTERFACE));
1659 if (!pItm)
1660 ExitFunction1(hr = E_OUTOFMEMORY);
1661
1662 // read iid
1663 hr = WcaReadStringFromCaData(ppwzData, &pwzData);
1664 ExitOnFailure(hr, "Failed to read iid");
1665 StringCchCopyW(pItm->wzIID, countof(pItm->wzIID), pwzData);
1666
1667 // read properties
1668 hr = CpiReadPropertyList(ppwzData, &pItm->pPropertyList);
1669 ExitOnFailure(hr, "Failed to read properties");
1670
1671 // read role assignments
1672 hr = ReadRoleAssignmentList(ppwzData, &pItm->pRoleAssignmentList);
1673 ExitOnFailure(hr, "Failed to read role assignments");
1674
1675 // read methods
1676 hr = ReadMethodList(ppwzData, &pItm->pMethodList);
1677 ExitOnFailure(hr, "Failed to read methods");
1678
1679 // add to list
1680 if (*ppIntfList)
1681 pItm->pNext = *ppIntfList;
1682 *ppIntfList = pItm;
1683 pItm = NULL;
1684 }
1685
1686 hr = S_OK;
1687
1688LExit:
1689 // clean up
1690 ReleaseStr(pwzData);
1691
1692 if (pItm)
1693 FreeInterfaceList(pItm);
1694
1695 return hr;
1696}
1697
1698static HRESULT ReadMethodList(
1699 LPWSTR* ppwzData,
1700 CPIEXEC_METHOD** ppMethList
1701 )
1702{
1703 HRESULT hr = S_OK;
1704
1705 LPWSTR pwzData = NULL;
1706
1707 CPIEXEC_METHOD* pItm = NULL;
1708
1709 int iCnt = 0;
1710
1711 // read count
1712 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
1713 ExitOnFailure(hr, "Failed to read count");
1714
1715 // read methods
1716 for (int i = 0; i < iCnt; i++)
1717 {
1718 pItm = (CPIEXEC_METHOD*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPIEXEC_METHOD));
1719 if (!pItm)
1720 ExitFunction1(hr = E_OUTOFMEMORY);
1721
1722 // read index
1723 hr = WcaReadStringFromCaData(ppwzData, &pwzData);
1724 ExitOnFailure(hr, "Failed to read index");
1725 StringCchCopyW(pItm->wzIndex, countof(pItm->wzIndex), pwzData);
1726
1727 // read name
1728 hr = WcaReadStringFromCaData(ppwzData, &pwzData);
1729 ExitOnFailure(hr, "Failed to read name");
1730 StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData);
1731
1732 // read properties
1733 hr = CpiReadPropertyList(ppwzData, &pItm->pPropertyList);
1734 ExitOnFailure(hr, "Failed to read properties");
1735
1736 // read role assignments
1737 hr = ReadRoleAssignmentList(ppwzData, &pItm->pRoleAssignmentList);
1738 ExitOnFailure(hr, "Failed to read role assignments");
1739
1740 // add to list
1741 if (*ppMethList)
1742 pItm->pNext = *ppMethList;
1743 *ppMethList = pItm;
1744 pItm = NULL;
1745 }
1746
1747 hr = S_OK;
1748
1749LExit:
1750 // clean up
1751 ReleaseStr(pwzData);
1752
1753 if (pItm)
1754 FreeMethodList(pItm);
1755
1756 return hr;
1757}
1758
1759static HRESULT ReadRoleAssignmentList(
1760 LPWSTR* ppwzData,
1761 CPIEXEC_ROLE_ASSIGNMENT** ppRoleList
1762 )
1763{
1764 HRESULT hr = S_OK;
1765
1766 LPWSTR pwzData = NULL;
1767
1768 CPIEXEC_ROLE_ASSIGNMENT* pItm = NULL;
1769
1770 int iCnt = 0;
1771
1772 // read role count
1773 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
1774 ExitOnFailure(hr, "Failed to read role assignments count");
1775
1776 // read roles
1777 for (int i = 0; i < iCnt; i++)
1778 {
1779 pItm = (CPIEXEC_ROLE_ASSIGNMENT*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPIEXEC_ROLE_ASSIGNMENT));
1780 if (!pItm)
1781 ExitFunction1(hr = E_OUTOFMEMORY);
1782
1783 // read key
1784 hr = WcaReadStringFromCaData(ppwzData, &pwzData);
1785 ExitOnFailure(hr, "Failed to read key");
1786 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
1787
1788 // read role name
1789 hr = WcaReadStringFromCaData(ppwzData, &pwzData);
1790 ExitOnFailure(hr, "Failed to read role name");
1791 StringCchCopyW(pItm->wzRoleName, countof(pItm->wzRoleName), pwzData);
1792
1793 // add to list
1794 if (*ppRoleList)
1795 pItm->pNext = *ppRoleList;
1796 *ppRoleList = pItm;
1797 pItm = NULL;
1798 }
1799
1800 hr = S_OK;
1801
1802LExit:
1803 // clean up
1804 ReleaseStr(pwzData);
1805
1806 if (pItm)
1807 FreeRoleAssignmentList(pItm);
1808
1809 return hr;
1810}
1811
1812static void FreeComponentList(
1813 CPIEXEC_COMPONENT* pList
1814 )
1815{
1816 while (pList)
1817 {
1818 if (pList->pPropertyList)
1819 CpiFreePropertyList(pList->pPropertyList);
1820 if (pList->pRoleAssignmentList)
1821 FreeRoleAssignmentList(pList->pRoleAssignmentList);
1822 if (pList->pInterfaceList)
1823 FreeInterfaceList(pList->pInterfaceList);
1824
1825 CPIEXEC_COMPONENT* pDelete = pList;
1826 pList = pList->pNext;
1827 ::HeapFree(::GetProcessHeap(), 0, pDelete);
1828 }
1829}
1830
1831static void FreeInterfaceList(
1832 CPIEXEC_INTERFACE* pList
1833 )
1834{
1835 while (pList)
1836 {
1837 if (pList->pPropertyList)
1838 CpiFreePropertyList(pList->pPropertyList);
1839 if (pList->pRoleAssignmentList)
1840 FreeRoleAssignmentList(pList->pRoleAssignmentList);
1841 if (pList->pMethodList)
1842 FreeMethodList(pList->pMethodList);
1843
1844 CPIEXEC_INTERFACE* pDelete = pList;
1845 pList = pList->pNext;
1846 ::HeapFree(::GetProcessHeap(), 0, pDelete);
1847 }
1848}
1849
1850static void FreeMethodList(
1851 CPIEXEC_METHOD* pList
1852 )
1853{
1854 while (pList)
1855 {
1856 if (pList->pPropertyList)
1857 CpiFreePropertyList(pList->pPropertyList);
1858 if (pList->pRoleAssignmentList)
1859 FreeRoleAssignmentList(pList->pRoleAssignmentList);
1860
1861 CPIEXEC_METHOD* pDelete = pList;
1862 pList = pList->pNext;
1863 ::HeapFree(::GetProcessHeap(), 0, pDelete);
1864 }
1865}
1866
1867static void FreeRoleAssignmentList(
1868 CPIEXEC_ROLE_ASSIGNMENT* pList
1869 )
1870{
1871 while (pList)
1872 {
1873 CPIEXEC_ROLE_ASSIGNMENT* pDelete = pList;
1874 pList = pList->pNext;
1875 ::HeapFree(::GetProcessHeap(), 0, pDelete);
1876 }
1877}
diff --git a/src/ext/ComPlus/ca/cpasmexec.h b/src/ext/ComPlus/ca/cpasmexec.h
new file mode 100644
index 00000000..56184c01
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpasmexec.h
@@ -0,0 +1,20 @@
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
5HRESULT CpiConfigureAssemblies(
6 LPWSTR* ppwzData,
7 HANDLE hRollbackFile
8 );
9HRESULT CpiRollbackConfigureAssemblies(
10 LPWSTR* ppwzData,
11 CPI_ROLLBACK_DATA* pRollbackDataList
12 );
13HRESULT CpiConfigureRoleAssignments(
14 LPWSTR* ppwzData,
15 HANDLE hRollbackFile
16 );
17HRESULT CpiRollbackConfigureRoleAssignments(
18 LPWSTR* ppwzData,
19 CPI_ROLLBACK_DATA* pRollbackDataList
20 );
diff --git a/src/ext/ComPlus/ca/cpasmsched.cpp b/src/ext/ComPlus/ca/cpasmsched.cpp
new file mode 100644
index 00000000..2d0573a5
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpasmsched.cpp
@@ -0,0 +1,2135 @@
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// sql queries
7
8LPCWSTR vcsMsiAssemblyNameQuery =
9 L"SELECT `Name`, `Value` FROM `MsiAssemblyName` WHERE `Component_` = ?";
10enum eMsiAssemblyNameQuery { manqName = 1, manqValue };
11
12LPCWSTR vcsModuleQuery =
13 L"SELECT `ModuleID` FROM `ModuleSignature`";
14enum eModuleQuery { mqModule = 1 };
15
16LPCWSTR vcsAssemblyQuery =
17 L"SELECT `Assembly`, `Component_`, `Application_`, `AssemblyName`, `DllPath`, `TlbPath`, `PSDllPath`, `Attributes` FROM `ComPlusAssembly`";
18enum eAssemblyQuery { aqAssembly = 1, aqComponent, aqApplication, aqAssemblyName, aqDllPath, aqTlbPath, aqPSDllPath, aqAttributes };
19
20LPCWSTR vcsComponentQuery =
21 L"SELECT `ComPlusComponent`, `CLSID` FROM `ComPlusComponent` WHERE `Assembly_` = ?";
22enum eComponentQuery { cqComponent = 1, cqCLSID };
23
24LPCWSTR vcsComponentPropertyQuery =
25 L"SELECT `Name`, `Value` FROM `ComPlusComponentProperty` WHERE `ComPlusComponent_` = ?";
26
27LPCWSTR vcsInterfaceQuery =
28 L"SELECT `Interface`, `IID` FROM `ComPlusInterface` WHERE `ComPlusComponent_` = ?";
29enum eInterfaceQuery { iqInterface = 1, iqIID };
30
31LPCWSTR vcsInterfacePropertyQuery =
32 L"SELECT `Name`, `Value` FROM `ComPlusInterfaceProperty` WHERE `Interface_` = ?";
33
34LPCWSTR vcsMethodQuery =
35 L"SELECT `Method`, `Index`, `Name` FROM `ComPlusMethod` WHERE `Interface_` = ?";
36enum eMethodQuery { mqMethod = 1, mqIndex, mqName };
37
38LPCWSTR vcsMethodPropertyQuery =
39 L"SELECT `Name`, `Value` FROM `ComPlusMethodProperty` WHERE `Method_` = ?";
40
41LPCWSTR vcsRoleForComponentQuery =
42 L"SELECT `RoleForComponent`, `ApplicationRole_`, `Component_` FROM `ComPlusRoleForComponent` WHERE `ComPlusComponent_` = ?";
43LPCWSTR vcsRoleForInterfaceQuery =
44 L"SELECT `RoleForInterface`, `ApplicationRole_`, `Component_` FROM `ComPlusRoleForInterface` WHERE `Interface_` = ?";
45LPCWSTR vcsRoleForMethodQuery =
46 L"SELECT `RoleForMethod`, `ApplicationRole_`, `Component_` FROM `ComPlusRoleForMethod` WHERE `Method_` = ?";
47
48enum eRoleAssignmentQuery { raqKey = 1, raqApplicationRole, raqComponent };
49
50LPCWSTR vcsModuleComponentsQuery =
51 L"SELECT `Component`, `ModuleID` FROM `ModuleComponents`";
52LPCWSTR vcsModuleDependencyQuery =
53 L"SELECT `ModuleID`, `RequiredID` FROM `ModuleDependency`";
54LPCWSTR vcsAssemblyDependencyQuery =
55 L"SELECT `Assembly_`, `RequiredAssembly_` FROM `ComPlusAssemblyDependency`";
56
57enum eKeyPairQuery { kpqFirstKey = 1, kpqSecondKey };
58
59
60// private structs
61
62struct CPI_KEY_PAIR
63{
64 WCHAR wzFirstKey[MAX_DARWIN_KEY + 1];
65 WCHAR wzSecondKey[MAX_DARWIN_KEY + 1];
66
67 CPI_KEY_PAIR* pNext;
68};
69
70struct CPI_DEPENDENCY_CHAIN
71{
72 LPCWSTR pwzKey;
73
74 CPI_DEPENDENCY_CHAIN* pPrev;
75};
76
77struct CPI_MODULE
78{
79 WCHAR wzKey[MAX_DARWIN_KEY + 1];
80
81 CPI_MODULE* pPrev;
82 CPI_MODULE* pNext;
83};
84
85struct CPI_MODULE_LIST
86{
87 CPI_MODULE* pFirst;
88 CPI_MODULE* pLast;
89};
90
91
92// property definitions
93
94CPI_PROPERTY_DEFINITION pdlComponentProperties[] =
95{
96 {L"AllowInprocSubscribers", cpptBoolean, 500},
97 {L"ComponentAccessChecksEnabled", cpptBoolean, 500},
98 {L"ComponentTransactionTimeout", cpptInteger, 500},
99 {L"ComponentTransactionTimeoutEnabled", cpptBoolean, 500},
100 {L"COMTIIntrinsics", cpptBoolean, 500},
101 {L"ConstructionEnabled", cpptBoolean, 500},
102 {L"ConstructorString", cpptString, 500},
103 {L"CreationTimeout", cpptInteger, 500},
104 {L"Description", cpptString, 500},
105 {L"EventTrackingEnabled", cpptBoolean, 500},
106 {L"ExceptionClass", cpptString, 500},
107 {L"FireInParallel", cpptBoolean, 500},
108 {L"IISIntrinsics", cpptBoolean, 500},
109 {L"InitializesServerApplication", cpptBoolean, 500},
110 {L"IsEnabled", cpptBoolean, 501},
111 {L"IsPrivateComponent", cpptBoolean, 501},
112 {L"JustInTimeActivation", cpptBoolean, 500},
113 {L"LoadBalancingSupported", cpptBoolean, 500},
114 {L"MaxPoolSize", cpptInteger, 500},
115 {L"MinPoolSize", cpptInteger, 500},
116 {L"MultiInterfacePublisherFilterCLSID", cpptString, 500},
117 {L"MustRunInClientContext", cpptBoolean, 500},
118 {L"MustRunInDefaultContext", cpptBoolean, 501},
119 {L"ObjectPoolingEnabled", cpptBoolean, 500},
120 {L"PublisherID", cpptString, 500},
121 {L"SoapAssemblyName", cpptString, 502},
122 {L"SoapTypeName", cpptString, 502},
123 {L"Synchronization", cpptInteger, 500},
124 {L"Transaction", cpptInteger, 500},
125 {L"TxIsolationLevel", cpptInteger, 501},
126 {NULL, cpptNone, 0}
127};
128
129CPI_PROPERTY_DEFINITION pdlInterfaceProperties[] =
130{
131 {L"Description", cpptString, 500},
132 {L"QueuingEnabled", cpptBoolean, 500},
133 {NULL, cpptNone, 0}
134};
135
136CPI_PROPERTY_DEFINITION pdlMethodProperties[] =
137{
138 {L"AutoComplete", cpptBoolean, 500},
139 {L"Description", cpptString, 500},
140 {NULL, cpptNone, 0}
141};
142
143
144// prototypes for private helper functions
145
146static HRESULT GetAssemblyName(
147 LPCWSTR pwzComponent,
148 LPWSTR* ppwzAssemblyName
149 );
150static HRESULT KeyPairsRead(
151 LPCWSTR pwzQuery,
152 CPI_KEY_PAIR** ppKeyPairList
153 );
154static HRESULT ModulesRead(
155 CPI_MODULE_LIST* pModList
156 );
157static HRESULT AssembliesRead(
158 CPI_KEY_PAIR* pModCompList,
159 CPI_APPLICATION_LIST* pAppList,
160 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
161 CPI_ASSEMBLY_LIST* pAsmList
162 );
163static HRESULT ComponentsRead(
164 LPCWSTR pwzAsmKey,
165 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
166 CPI_ASSEMBLY* pAsm
167 );
168static HRESULT InterfacesRead(
169 LPCWSTR pwzCompKey,
170 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
171 CPI_ASSEMBLY* pAsm,
172 CPISCHED_COMPONENT* pComp
173 );
174static HRESULT MethodsRead(
175 LPCWSTR pwzIntfKey,
176 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
177 CPI_ASSEMBLY* pAsm,
178 CPISCHED_INTERFACE* pIntf
179 );
180static HRESULT RoleAssignmentsRead(
181 LPCWSTR pwzQuery,
182 LPCWSTR pwzKey,
183 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
184 CPISCHED_ROLE_ASSIGNMENT** ppRoleList,
185 int* piInstallCount,
186 int* piUninstallCount
187 );
188static HRESULT TopSortModuleList(
189 CPI_KEY_PAIR* pDepList,
190 CPI_MODULE_LIST* pList
191 );
192static HRESULT SwapDependentModules(
193 CPI_DEPENDENCY_CHAIN* pdcPrev,
194 CPI_KEY_PAIR* pDepList,
195 CPI_MODULE_LIST* pList,
196 CPI_MODULE* pRoot,
197 CPI_MODULE* pItm
198 );
199static HRESULT ModuleFindByKey(
200 CPI_MODULE* pItm,
201 LPCWSTR pwzKey,
202 BOOL fReverse,
203 CPI_MODULE** ppItm
204 );
205static void SortAssemblyListByModule(
206 CPI_MODULE_LIST* pModList,
207 CPI_ASSEMBLY_LIST* pAsmList
208 );
209static HRESULT TopSortAssemblyList(
210 CPI_KEY_PAIR* pDepList,
211 CPI_ASSEMBLY_LIST* pList
212 );
213static HRESULT SwapDependentAssemblies(
214 CPI_DEPENDENCY_CHAIN* pdcPrev,
215 CPI_KEY_PAIR* pDepList,
216 CPI_ASSEMBLY_LIST* pList,
217 CPI_ASSEMBLY* pRoot,
218 CPI_ASSEMBLY* pItm
219 );
220static HRESULT AssemblyFindByKey(
221 CPI_ASSEMBLY* pItm,
222 LPCWSTR pwzKey,
223 BOOL fReverse,
224 CPI_ASSEMBLY** ppItm
225 );
226static HRESULT AddAssemblyToActionData(
227 CPI_ASSEMBLY* pItm,
228 BOOL fInstall,
229 int iActionType,
230 int iActionCost,
231 LPWSTR* ppwzActionData
232 );
233static HRESULT AddRoleAssignmentsToActionData(
234 CPI_ASSEMBLY* pItm,
235 BOOL fInstall,
236 int iActionType,
237 int iActionCost,
238 LPWSTR* ppwzActionData
239 );
240static HRESULT AddComponentToActionData(
241 CPISCHED_COMPONENT* pItm,
242 BOOL fInstall,
243 BOOL fProps,
244 BOOL fRoles,
245 LPWSTR* ppwzActionData
246 );
247static HRESULT AddInterfaceToActionData(
248 CPISCHED_INTERFACE* pItm,
249 BOOL fInstall,
250 BOOL fProps,
251 BOOL fRoles,
252 LPWSTR* ppwzActionData
253 );
254static HRESULT AddMethodToActionData(
255 CPISCHED_METHOD* pItm,
256 BOOL fInstall,
257 BOOL fProps,
258 BOOL fRoles,
259 LPWSTR* ppwzActionData
260 );
261static HRESULT AddRolesToActionData(
262 int iRoleInstallCount,
263 int iRoleUninstallCount,
264 CPISCHED_ROLE_ASSIGNMENT* pRoleList,
265 BOOL fInstall,
266 BOOL fRoles,
267 LPWSTR* ppwzActionData
268 );
269static HRESULT KeyPairFindByFirstKey(
270 CPI_KEY_PAIR* pList,
271 LPCWSTR pwzKey,
272 CPI_KEY_PAIR** ppItm
273 );
274static void AssemblyFree(
275 CPI_ASSEMBLY* pItm
276 );
277static void KeyPairsFreeList(
278 CPI_KEY_PAIR* pList
279 );
280void ModuleListFree(
281 CPI_MODULE_LIST* pList
282 );
283static void ModuleFree(
284 CPI_MODULE* pItm
285 );
286static void ComponentsFreeList(
287 CPISCHED_COMPONENT* pList
288 );
289static void InterfacesFreeList(
290 CPISCHED_INTERFACE* pList
291 );
292static void MethodsFreeList(
293 CPISCHED_METHOD* pList
294 );
295static void RoleAssignmentsFreeList(
296 CPISCHED_ROLE_ASSIGNMENT* pList
297 );
298
299
300// function definitions
301
302void CpiAssemblyListFree(
303 CPI_ASSEMBLY_LIST* pList
304 )
305{
306 CPI_ASSEMBLY* pItm = pList->pFirst;
307
308 while (pItm)
309 {
310 CPI_ASSEMBLY* pDelete = pItm;
311 pItm = pItm->pNext;
312 AssemblyFree(pDelete);
313 }
314}
315
316HRESULT CpiAssembliesRead(
317 CPI_APPLICATION_LIST* pAppList,
318 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
319 CPI_ASSEMBLY_LIST* pAsmList
320 )
321{
322 HRESULT hr = S_OK;
323 CPI_MODULE_LIST modList;
324 CPI_KEY_PAIR* pModCompList = NULL;
325 CPI_KEY_PAIR* pModDepList = NULL;
326 CPI_KEY_PAIR* pAsmDepList = NULL;
327
328 ::ZeroMemory(&modList, sizeof(CPI_MODULE_LIST));
329
330 BOOL fModuleSignatureTable = (S_OK == WcaTableExists(L"ModuleSignature"));
331 BOOL fModuleComponentsTable = (S_OK == WcaTableExists(L"ModuleComponents"));
332 BOOL fModuleDependencyTable = (S_OK == WcaTableExists(L"ModuleDependency"));
333
334 // read modules
335 if (fModuleSignatureTable)
336 {
337 hr = ModulesRead(&modList);
338 ExitOnFailure(hr, "Failed to read ModuleSignature table");
339 }
340
341 // read module components
342 if (fModuleComponentsTable)
343 {
344 hr = KeyPairsRead(vcsModuleComponentsQuery, &pModCompList);
345 ExitOnFailure(hr, "Failed to read ModuleComponents table");
346 }
347
348 // read module dependencies
349 if (fModuleDependencyTable)
350 {
351 hr = KeyPairsRead(vcsModuleDependencyQuery, &pModDepList);
352 ExitOnFailure(hr, "Failed to read ModuleDependency table");
353 }
354
355 // read assemblies
356 hr = AssembliesRead(pModCompList, pAppList, pAppRoleList, pAsmList);
357 ExitOnFailure(hr, "Failed to read ComPlusAssembly table");
358
359 // read assembly dependencies
360 if (CpiTableExists(cptComPlusAssemblyDependency))
361 {
362 hr = KeyPairsRead(vcsAssemblyDependencyQuery, &pAsmDepList);
363 ExitOnFailure(hr, "Failed to read ComPlusAssemblyDependency table");
364 }
365
366 // sort modules
367 if (modList.pFirst && pModDepList)
368 {
369 hr = TopSortModuleList(pModDepList, &modList);
370 ExitOnFailure(hr, "Failed to sort modules");
371 }
372
373 // sort assemblies by module
374 if (pAsmList->pFirst && modList.pFirst && pModDepList)
375 SortAssemblyListByModule(&modList, pAsmList);
376
377 // sort assemblies by dependency
378 if (pAsmList->pFirst && pAsmDepList)
379 {
380 hr = TopSortAssemblyList(pAsmDepList, pAsmList);
381 ExitOnFailure(hr, "Failed to sort assemblies");
382 }
383
384 hr = S_OK;
385
386LExit:
387 // clean up
388 ModuleListFree(&modList);
389 if (pModCompList)
390 KeyPairsFreeList(pModCompList);
391 if (pModDepList)
392 KeyPairsFreeList(pModDepList);
393 if (pAsmDepList)
394 KeyPairsFreeList(pAsmDepList);
395
396 return hr;
397}
398
399HRESULT CpiAssembliesVerifyInstall(
400 CPI_ASSEMBLY_LIST* pList
401 )
402{
403 HRESULT hr = S_OK;
404
405 for (CPI_ASSEMBLY* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
406 {
407 // assemblies that are being installed
408 if (!pItm->fReferencedForInstall && !pItm->iRoleAssignmentsInstallCount && !WcaIsInstalling(pItm->isInstalled, pItm->isAction))
409 continue;
410
411 // if the assembly is referensed, it must be installed
412 if ((pItm->fReferencedForInstall || pItm->iRoleAssignmentsInstallCount) && !CpiWillBeInstalled(pItm->isInstalled, pItm->isAction))
413 MessageExitOnFailure(hr = E_FAIL, msierrComPlusAssemblyDependency, "An assembly is used by another entity being installed, but is not installed itself, key: %S", pItm->wzKey);
414 }
415
416 hr = S_OK;
417
418LExit:
419 return hr;
420}
421
422HRESULT CpiAssembliesVerifyUninstall(
423 CPI_ASSEMBLY_LIST* pList
424 )
425{
426 HRESULT hr = S_OK;
427
428 for (CPI_ASSEMBLY* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
429 {
430 // assemblies that are being uninstalled
431 if (!pItm->fReferencedForUninstall && !pItm->iRoleAssignmentsUninstallCount && (!WcaIsUninstalling(pItm->isInstalled, pItm->isAction) && !WcaIsReInstalling(pItm->isInstalled, pItm->isAction)))
432 continue;
433
434 // if the application is not present, there is no need to remove the components
435 if (pItm->pApplication && pItm->pApplication->fObjectNotFound)
436 {
437 pItm->fIgnore = TRUE;
438 pList->iUninstallCount--; // elements with the fIgnore flag set will not be scheduled for uninstall
439 pList->iRoleUninstallCount--;
440 }
441 }
442
443 hr = S_OK;
444
445//LExit:
446 return hr;
447}
448
449HRESULT CpiAssembliesInstall(
450 CPI_ASSEMBLY_LIST* pList,
451 int iRunMode,
452 LPWSTR* ppwzActionData,
453 int* piProgress
454 )
455{
456 HRESULT hr = S_OK;
457
458 int iActionType;
459 int iCount = 0;
460
461 // add action text
462 hr = CpiAddActionTextToActionData(L"RegisterComPlusAssemblies", ppwzActionData);
463 ExitOnFailure(hr, "Failed to add action text to custom action data");
464
465 // assembly count
466 switch (iRunMode)
467 {
468 case rmDeferred:
469 iCount = pList->iInstallCount - pList->iCommitCount;
470 break;
471 case rmCommit:
472 iCount = pList->iCommitCount;
473 break;
474 case rmRollback:
475 iCount = pList->iInstallCount;
476 break;
477 }
478
479 // add assembly count to action data
480 hr = WcaWriteIntegerToCaData(iCount, ppwzActionData);
481 ExitOnFailure(hr, "Failed to add count to custom action data");
482
483 // add assemblies to custom action data in forward order
484 for (CPI_ASSEMBLY* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
485 {
486 // assemblies that are being installed, or contains roll assignments to install
487 if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction))
488 continue;
489
490 // assemblies that are being installed must be scheduled during the right type of action
491 BOOL fRunInCommit = 0 != (pItm->iAttributes & aaRunInCommit);
492 if (((rmCommit == iRunMode && !fRunInCommit) || (rmDeferred == iRunMode && fRunInCommit)))
493 continue;
494
495 // action type
496 if (rmRollback == iRunMode)
497 {
498 if (CpiIsInstalled(pItm->isInstalled))
499 iActionType = atNoOp;
500 else
501 iActionType = atRemove;
502 }
503 else
504 iActionType = atCreate;
505
506 // add to action data
507 hr = AddAssemblyToActionData(pItm, TRUE, iActionType, COST_ASSEMBLY_REGISTER, ppwzActionData);
508 ExitOnFailure(hr, "Failed to add assembly to custom action data, key: %S", pItm->wzKey);
509 }
510
511 // add progress tics
512 if (piProgress)
513 *piProgress += COST_ASSEMBLY_REGISTER * iCount;
514
515 hr = S_OK;
516
517LExit:
518 return hr;
519}
520
521HRESULT CpiAssembliesUninstall(
522 CPI_ASSEMBLY_LIST* pList,
523 int iRunMode,
524 LPWSTR* ppwzActionData,
525 int* piProgress
526 )
527{
528 HRESULT hr = S_OK;
529
530 int iActionType;
531
532 // add action text
533 hr = CpiAddActionTextToActionData(L"UnregisterComPlusAssemblies", ppwzActionData);
534 ExitOnFailure(hr, "Failed to add action text to custom action data");
535
536 // add assembly count to action data
537 hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData);
538 ExitOnFailure(hr, "Failed to add count to custom action data");
539
540 // add assemblies to custom action data in reverse order
541 for (CPI_ASSEMBLY* pItm = pList->pLast; pItm; pItm = pItm->pPrev)
542 {
543 // assemblies that are being uninstalled
544 if (pItm->fIgnore || (!WcaIsUninstalling(pItm->isInstalled, pItm->isAction) && !WcaIsReInstalling(pItm->isInstalled, pItm->isAction)))
545 continue;
546
547 // action type
548 if (rmRollback == iRunMode)
549 iActionType = atCreate;
550 else
551 iActionType = atRemove;
552
553 // add to action data
554 hr = AddAssemblyToActionData(pItm, FALSE, iActionType, COST_ASSEMBLY_UNREGISTER, ppwzActionData);
555 ExitOnFailure(hr, "Failed to add assembly to custom action data, key: %S", pItm->wzKey);
556 }
557
558 // add progress tics
559 if (piProgress)
560 *piProgress += COST_ASSEMBLY_UNREGISTER * pList->iUninstallCount;
561
562 hr = S_OK;
563
564LExit:
565 return hr;
566}
567
568HRESULT CpiRoleAssignmentsInstall(
569 CPI_ASSEMBLY_LIST* pList,
570 int iRunMode,
571 LPWSTR* ppwzActionData,
572 int* piProgress
573 )
574{
575 HRESULT hr = S_OK;
576
577 int iActionType;
578 int iCount = 0;
579
580 // add action text
581 hr = CpiAddActionTextToActionData(L"AddComPlusRoleAssignments", ppwzActionData);
582 ExitOnFailure(hr, "Failed to add action text to custom action data");
583
584 // assembly count
585 switch (iRunMode)
586 {
587 case rmDeferred:
588 iCount = pList->iRoleInstallCount - pList->iRoleCommitCount;
589 break;
590 case rmCommit:
591 iCount = pList->iRoleCommitCount;
592 break;
593 case rmRollback:
594 iCount = pList->iRoleInstallCount;
595 break;
596 }
597
598 // add assembly count to action data
599 hr = WcaWriteIntegerToCaData(iCount, ppwzActionData);
600 ExitOnFailure(hr, "Failed to add count to custom action data");
601
602 // add assemblies to custom action data in forward order
603 for (CPI_ASSEMBLY* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
604 {
605 // assemblies that are being installed, or contains roll assignments to install
606 if (!pItm->iRoleAssignmentsInstallCount)
607 continue;
608
609 // assemblies that are being installed must be scheduled during the right type of action
610 BOOL fRunInCommit = 0 != (pItm->iAttributes & aaRunInCommit);
611 if (((rmCommit == iRunMode && !fRunInCommit) || (rmDeferred == iRunMode && fRunInCommit)))
612 continue;
613
614 // action type
615 if (rmRollback == iRunMode)
616 {
617 if (CpiIsInstalled(pItm->isInstalled))
618 iActionType = atNoOp;
619 else
620 iActionType = atRemove;
621 }
622 else
623 iActionType = atCreate;
624
625 // add to action data
626 hr = AddRoleAssignmentsToActionData(pItm, TRUE, iActionType, COST_ROLLASSIGNMENT_CREATE, ppwzActionData);
627 ExitOnFailure(hr, "Failed to add assembly to custom action data, key: %S", pItm->wzKey);
628
629 // add progress tics
630 if (piProgress)
631 *piProgress += COST_ROLLASSIGNMENT_CREATE * pItm->iRoleAssignmentsInstallCount;
632 }
633
634 hr = S_OK;
635
636LExit:
637 return hr;
638}
639
640HRESULT CpiRoleAssignmentsUninstall(
641 CPI_ASSEMBLY_LIST* pList,
642 int iRunMode,
643 LPWSTR* ppwzActionData,
644 int* piProgress
645 )
646{
647 HRESULT hr = S_OK;
648
649 int iActionType;
650
651 // add action text
652 hr = CpiAddActionTextToActionData(L"RemoveComPlusRoleAssignments", ppwzActionData);
653 ExitOnFailure(hr, "Failed to add action text to custom action data");
654
655 // add assembly count to action data
656 hr = WcaWriteIntegerToCaData(pList->iRoleUninstallCount, ppwzActionData);
657 ExitOnFailure(hr, "Failed to add count to custom action data");
658
659 // add assemblies to custom action data in reverse order
660 for (CPI_ASSEMBLY* pItm = pList->pLast; pItm; pItm = pItm->pPrev)
661 {
662 // assemblies that are being uninstalled
663 if (pItm->fIgnore || !pItm->iRoleAssignmentsUninstallCount)
664 continue;
665
666 // action type
667 if (rmRollback == iRunMode)
668 iActionType = atCreate;
669 else
670 iActionType = atRemove;
671
672 // add to action data
673 hr = AddRoleAssignmentsToActionData(pItm, FALSE, iActionType, COST_ROLLASSIGNMENT_DELETE, ppwzActionData);
674 ExitOnFailure(hr, "Failed to add assembly to custom action data, key: %S", pItm->wzKey);
675
676 // add progress tics
677 if (piProgress)
678 *piProgress += COST_ROLLASSIGNMENT_DELETE * pItm->iRoleAssignmentsUninstallCount;
679 }
680
681 hr = S_OK;
682
683LExit:
684 return hr;
685}
686
687HRESULT CpiGetSubscriptionsCollForComponent(
688 CPI_ASSEMBLY* pAsm,
689 CPISCHED_COMPONENT* pComp,
690 ICatalogCollection** ppiSubsColl
691 )
692{
693 HRESULT hr = S_OK;
694
695 ICatalogCollection* piCompColl = NULL;
696 ICatalogObject* piCompObj = NULL;
697
698 // get applications collection
699 if (!pComp->piSubsColl)
700 {
701 // get components collection for application
702 hr = CpiGetComponentsCollForApplication(pAsm->pApplication, &piCompColl);
703 ExitOnFailure(hr, "Failed to get components collection for application");
704
705 if (S_FALSE == hr)
706 ExitFunction(); // exit with hr = S_FALSE
707
708 // find component object
709 hr = CpiFindCollectionObject(piCompColl, pComp->wzCLSID, NULL, &piCompObj);
710 ExitOnFailure(hr, "Failed to find component object");
711
712 if (S_FALSE == hr)
713 ExitFunction(); // exit with hr = S_FALSE
714
715 // get roles collection
716 hr = CpiSchedGetCatalogCollection(piCompColl, piCompObj, L"SubscriptionsForComponent", &pComp->piSubsColl);
717 ExitOnFailure(hr, "Failed to get subscriptions collection");
718 }
719
720 // return value
721 *ppiSubsColl = pComp->piSubsColl;
722 (*ppiSubsColl)->AddRef();
723
724 hr = S_OK;
725
726LExit:
727 // clean up
728 ReleaseObject(piCompColl);
729 ReleaseObject(piCompObj);
730
731 return hr;
732}
733
734
735// helper function definitions
736
737static HRESULT GetAssemblyName(
738 LPCWSTR pwzComponent,
739 LPWSTR* ppwzAssemblyName
740 )
741{
742 HRESULT hr = S_OK;
743
744 PMSIHANDLE hView, hRecKey, hRec;
745
746 LPWSTR pwzKey = NULL;
747
748 LPWSTR pwzName = NULL;
749 LPWSTR pwzVersion = NULL;
750 LPWSTR pwzCulture = NULL;
751 LPWSTR pwzPublicKeyToken = NULL;
752
753 // create parameter record
754 hRecKey = ::MsiCreateRecord(1);
755 ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
756 hr = WcaSetRecordString(hRecKey, 1, pwzComponent);
757 ExitOnFailure(hr, "Failed to set record string");
758
759 // open view
760 hr = WcaOpenView(vcsMsiAssemblyNameQuery, &hView);
761 ExitOnFailure(hr, "Failed to open view on MsiAssemblyName table");
762 hr = WcaExecuteView(hView, hRecKey);
763 ExitOnFailure(hr, "Failed to execute view on MsiAssemblyName table");
764
765 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
766 {
767 // read key
768 hr = WcaGetRecordString(hRec, manqName, &pwzKey);
769 ExitOnFailure(hr, "Failed to get name");
770
771 // read value
772 if (0 == lstrcmpiW(L"name", pwzKey))
773 hr = WcaGetRecordString(hRec, manqValue, &pwzName);
774 else if (0 == lstrcmpiW(L"version", pwzKey))
775 hr = WcaGetRecordString(hRec, manqValue, &pwzVersion);
776 else if (0 == lstrcmpiW(L"culture", pwzKey))
777 hr = WcaGetRecordString(hRec, manqValue, &pwzCulture);
778 else if (0 == lstrcmpiW(L"publicKeyToken", pwzKey))
779 hr = WcaGetRecordString(hRec, manqValue, &pwzPublicKeyToken);
780 else
781 {
782 WcaLog(LOGMSG_VERBOSE, "Unknown name in MsiAssemblyName table: %S, %S", pwzComponent, pwzKey);
783 hr = S_OK;
784 }
785
786 ExitOnFailure(hr, "Failed to get value");
787 }
788
789 if (E_NOMOREITEMS != hr)
790 ExitOnFailure(hr, "Failed to fetch record");
791
792 // verify
793 if (!(pwzName && *pwzName) || !(pwzVersion && *pwzVersion))
794 ExitOnFailure(hr = E_FAIL, "Incomplete assembly name");
795
796 // build name string
797 hr = StrAllocFormatted(ppwzAssemblyName, L"%s, Version=%s, Culture=%s, PublicKeyToken=%s",
798 pwzName, pwzVersion,
799 pwzCulture && *pwzCulture ? pwzCulture : L"Neutral",
800 pwzPublicKeyToken && *pwzPublicKeyToken ? pwzPublicKeyToken : L"null");
801 ExitOnFailure(hr, "Failed to build assembly name string");
802
803 hr = S_OK;
804
805LExit:
806 // clean up
807 ReleaseStr(pwzKey);
808 ReleaseStr(pwzName);
809 ReleaseStr(pwzVersion);
810 ReleaseStr(pwzCulture);
811 ReleaseStr(pwzPublicKeyToken);
812
813 return hr;
814}
815
816static HRESULT KeyPairsRead(
817 LPCWSTR pwzQuery,
818 CPI_KEY_PAIR** ppKeyPairList
819 )
820{
821 HRESULT hr = S_OK;
822
823 PMSIHANDLE hView, hRec;
824
825 CPI_KEY_PAIR* pItm = NULL;
826 LPWSTR pwzData = NULL;
827
828 // loop through all dependencies
829 hr = WcaOpenExecuteView(pwzQuery, &hView);
830 ExitOnFailure(hr, "Failed to execute view on table");
831
832 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
833 {
834 // create entry
835 pItm = (CPI_KEY_PAIR*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_KEY_PAIR));
836 if (!pItm)
837 ExitFunction1(hr = E_OUTOFMEMORY);
838
839 // get key
840 hr = WcaGetRecordString(hRec, kpqFirstKey, &pwzData);
841 ExitOnFailure(hr, "Failed to get first key");
842 StringCchCopyW(pItm->wzFirstKey, countof(pItm->wzFirstKey), pwzData);
843
844 // get key
845 hr = WcaGetRecordString(hRec, kpqSecondKey, &pwzData);
846 ExitOnFailure(hr, "Failed to get second key");
847 StringCchCopyW(pItm->wzSecondKey, countof(pItm->wzSecondKey), pwzData);
848
849 // add entry
850 if (*ppKeyPairList)
851 pItm->pNext = *ppKeyPairList;
852 *ppKeyPairList = pItm;
853 pItm = NULL;
854 }
855
856 if (E_NOMOREITEMS == hr)
857 hr = S_OK;
858
859LExit:
860 // clean up
861 if (pItm)
862 KeyPairsFreeList(pItm);
863
864 ReleaseStr(pwzData);
865
866 return hr;
867}
868
869static HRESULT ModulesRead(
870 CPI_MODULE_LIST* pModList
871 )
872{
873 HRESULT hr = S_OK;
874
875 PMSIHANDLE hView, hRec;
876
877 CPI_MODULE* pItm = NULL;
878 LPWSTR pwzData = NULL;
879
880 // loop through all modules
881 hr = WcaOpenExecuteView(vcsModuleQuery, &hView);
882 ExitOnFailure(hr, "Failed to execute view on ModuleSignature table");
883
884 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
885 {
886 // create entry
887 pItm = (CPI_MODULE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_MODULE));
888 if (!pItm)
889 ExitFunction1(hr = E_OUTOFMEMORY);
890
891 // get key
892 hr = WcaGetRecordString(hRec, mqModule, &pwzData);
893 ExitOnFailure(hr, "Failed to get key");
894 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
895
896 // add entry
897 if (pModList->pLast)
898 {
899 pModList->pLast->pNext = pItm;
900 pItm->pPrev = pModList->pLast;
901 }
902 else
903 pModList->pFirst = pItm;
904 pModList->pLast = pItm;
905 pItm = NULL;
906 }
907
908 if (E_NOMOREITEMS == hr)
909 hr = S_OK;
910
911LExit:
912 // clean up
913 if (pItm)
914 ModuleFree(pItm);
915
916 ReleaseStr(pwzData);
917
918 return hr;
919}
920
921static HRESULT AssembliesRead(
922 CPI_KEY_PAIR* pModCompList,
923 CPI_APPLICATION_LIST* pAppList,
924 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
925 CPI_ASSEMBLY_LIST* pAsmList
926 )
927{
928 HRESULT hr = S_OK;
929 UINT er = ERROR_SUCCESS;
930
931 PMSIHANDLE hView, hRec;
932
933 CPI_ASSEMBLY* pItm = NULL;
934 CPI_KEY_PAIR* pModComp;
935 LPWSTR pwzData = NULL;
936 LPWSTR pwzComponent = NULL;
937 BOOL fMatchingArchitecture = FALSE;
938
939 // loop through all assemblies
940 hr = WcaOpenExecuteView(vcsAssemblyQuery, &hView);
941 ExitOnFailure(hr, "Failed to execute view on ComPlusAssembly table");
942
943 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
944 {
945 // get component
946 hr = WcaGetRecordString(hRec, aqComponent, &pwzComponent);
947 ExitOnFailure(hr, "Failed to get component");
948
949 // check if the component is our processor architecture
950 hr = CpiVerifyComponentArchitecure(pwzComponent, &fMatchingArchitecture);
951 ExitOnFailure(hr, "Failed to get component architecture.");
952
953 if (!fMatchingArchitecture)
954 {
955 continue; // not the same architecture, ignore
956 }
957
958 // create entry
959 pItm = (CPI_ASSEMBLY*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_ASSEMBLY));
960 if (!pItm)
961 ExitFunction1(hr = E_OUTOFMEMORY);
962
963 // get component install state
964 er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzComponent, &pItm->isInstalled, &pItm->isAction);
965 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
966
967 // get key
968 hr = WcaGetRecordString(hRec, aqAssembly, &pwzData);
969 ExitOnFailure(hr, "Failed to get key");
970 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
971
972 // get attributes
973 hr = WcaGetRecordInteger(hRec, aqAttributes, &pItm->iAttributes);
974 ExitOnFailure(hr, "Failed to get attributes");
975
976 // get assembly name
977 hr = WcaGetRecordFormattedString(hRec, aqAssemblyName, &pItm->pwzAssemblyName);
978 ExitOnFailure(hr, "Failed to get assembly name");
979
980 if (!*pItm->pwzAssemblyName && (pItm->iAttributes & aaPathFromGAC))
981 {
982 // get assembly name for component
983 hr = GetAssemblyName(pwzComponent, &pItm->pwzAssemblyName);
984 ExitOnFailure(hr, "Failed to get assembly name for component");
985 }
986
987 // get dll path
988 hr = WcaGetRecordFormattedString(hRec, aqDllPath, &pItm->pwzDllPath);
989 ExitOnFailure(hr, "Failed to get assembly dll path");
990
991 // get module
992 // TODO: if there is a very large number of components belonging to modules, this search might be slow
993 hr = KeyPairFindByFirstKey(pModCompList, pwzData, &pModComp);
994
995 if (S_OK == hr)
996 StringCchCopyW(pItm->wzModule, countof(pItm->wzModule), pModComp->wzSecondKey);
997
998 // get application
999 hr = WcaGetRecordString(hRec, aqApplication, &pwzData);
1000 ExitOnFailure(hr, "Failed to get application");
1001
1002 if (pwzData && *pwzData)
1003 {
1004 hr = CpiApplicationFindByKey(pAppList, pwzData, &pItm->pApplication);
1005 if (S_FALSE == hr)
1006 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1007 ExitOnFailure(hr, "Failed to find application, key: %S", pwzData);
1008 }
1009
1010 // get tlb path
1011 hr = WcaGetRecordFormattedString(hRec, aqTlbPath, &pItm->pwzTlbPath);
1012 ExitOnFailure(hr, "Failed to get assembly tlb path");
1013
1014 // get proxy-stub dll path
1015 hr = WcaGetRecordFormattedString(hRec, aqPSDllPath, &pItm->pwzPSDllPath);
1016 ExitOnFailure(hr, "Failed to get assembly proxy-stub DLL path");
1017
1018 // read components
1019 if (CpiTableExists(cptComPlusComponent))
1020 {
1021 hr = ComponentsRead(pItm->wzKey, pAppRoleList, pItm);
1022 ExitOnFailure(hr, "Failed to read components for assembly");
1023 }
1024
1025 // set references & increment counters
1026 if (WcaIsInstalling(pItm->isInstalled, pItm->isAction))
1027 {
1028 pAsmList->iInstallCount++;
1029 if (pItm->iAttributes & aaRunInCommit)
1030 pAsmList->iCommitCount++;
1031 }
1032 if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction) || WcaIsReInstalling(pItm->isInstalled, pItm->isAction))
1033 pAsmList->iUninstallCount++;
1034
1035 if (pItm->iRoleAssignmentsInstallCount)
1036 {
1037 pAsmList->iRoleInstallCount++;
1038 if (pItm->iAttributes & aaRunInCommit)
1039 pAsmList->iRoleCommitCount++;
1040 }
1041 if (pItm->iRoleAssignmentsUninstallCount)
1042 pAsmList->iRoleUninstallCount++;
1043
1044 if (pItm->pApplication)
1045 {
1046 if (pItm->iRoleAssignmentsInstallCount || WcaIsInstalling(pItm->isInstalled, pItm->isAction))
1047 CpiApplicationAddReferenceInstall(pItm->pApplication);
1048 if (pItm->iRoleAssignmentsUninstallCount || WcaIsUninstalling(pItm->isInstalled, pItm->isAction) || WcaIsReInstalling(pItm->isInstalled, pItm->isAction))
1049 CpiApplicationAddReferenceUninstall(pItm->pApplication);
1050 }
1051
1052 // add entry
1053 if (pAsmList->pLast)
1054 {
1055 pAsmList->pLast->pNext = pItm;
1056 pItm->pPrev = pAsmList->pLast;
1057 }
1058 else
1059 pAsmList->pFirst = pItm;
1060 pAsmList->pLast = pItm;
1061 pItm = NULL;
1062 }
1063
1064 if (E_NOMOREITEMS == hr)
1065 hr = S_OK;
1066
1067LExit:
1068 // clean up
1069 if (pItm)
1070 AssemblyFree(pItm);
1071
1072 ReleaseStr(pwzData);
1073 ReleaseStr(pwzComponent);
1074
1075 return hr;
1076}
1077
1078static HRESULT TopSortModuleList(
1079 CPI_KEY_PAIR* pDepList,
1080 CPI_MODULE_LIST* pList
1081 )
1082{
1083 HRESULT hr = S_OK;
1084
1085 // top sort list
1086 for (CPI_MODULE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
1087 {
1088 // append module
1089 hr = SwapDependentModules(NULL, pDepList, pList, pItm, pItm);
1090 ExitOnFailure(hr, "Failed to swap dependent modules");
1091 }
1092
1093 hr = S_OK;
1094
1095LExit:
1096 return hr;
1097}
1098
1099static HRESULT SwapDependentModules(
1100 CPI_DEPENDENCY_CHAIN* pdcPrev, // list containing the entire dependency chain
1101 CPI_KEY_PAIR* pDepList, // module dependency list
1102 CPI_MODULE_LIST* pList, // module list being sorted
1103 CPI_MODULE* pRoot, // first module in the chain
1104 CPI_MODULE* pItm // current module to test for dependencies
1105 )
1106{
1107 HRESULT hr = S_OK;
1108
1109 CPI_MODULE* pDepItm;
1110
1111 // find dependencies
1112 for (CPI_KEY_PAIR* pDep = pDepList; pDep; pDep = pDep->pNext)
1113 {
1114 if (0 == lstrcmpW(pItm->wzKey, pDep->wzFirstKey))
1115 {
1116 CPI_DEPENDENCY_CHAIN dcItm;
1117 dcItm.pwzKey = pItm->wzKey;
1118 dcItm.pPrev = pdcPrev;
1119
1120 // check for circular dependencies
1121 for (CPI_DEPENDENCY_CHAIN* pdcItm = &dcItm; pdcItm; pdcItm = pdcItm->pPrev)
1122 {
1123 if (0 == lstrcmpW(pdcItm->pwzKey, pDep->wzSecondKey))
1124 {
1125 // circular dependency found
1126 ExitOnFailure(hr = E_FAIL, "Circular module dependency found, key: %S", pDep->wzSecondKey);
1127 }
1128 }
1129
1130 // make sure the item is not already in the list
1131 hr = ModuleFindByKey(pRoot->pPrev, pDep->wzSecondKey, TRUE, &pDepItm); // find in reverse order
1132
1133 if (S_OK == hr)
1134 continue; // item found, move on
1135
1136 // find item in the list
1137 hr = ModuleFindByKey(pRoot->pNext, pDep->wzSecondKey, FALSE, &pDepItm); // find in forward order
1138
1139 if (S_FALSE == hr)
1140 {
1141 // not found
1142 ExitOnFailure(hr = E_FAIL, "Module dependency not found, key: %S", pDep->wzSecondKey);
1143 }
1144
1145 // if this item in turn has dependencies, they have to be swaped first
1146 hr = SwapDependentModules(&dcItm, pDepList, pList, pRoot, pDepItm);
1147 ExitOnFailure(hr, "Failed to swap dependent module");
1148
1149 // remove item from its current position
1150 pDepItm->pPrev->pNext = pDepItm->pNext; // pDepItm can never be the first item, no need to check pPrev
1151 if (pDepItm->pNext)
1152 pDepItm->pNext->pPrev = pDepItm->pPrev;
1153 else
1154 {
1155 pList->pLast = pDepItm->pPrev;
1156 pList->pLast->pNext = NULL;
1157 }
1158
1159 // insert before the current item
1160 if (pRoot->pPrev)
1161 pRoot->pPrev->pNext = pDepItm;
1162 else
1163 pList->pFirst = pDepItm;
1164 pDepItm->pPrev = pRoot->pPrev;
1165 pRoot->pPrev = pDepItm;
1166 pDepItm->pNext = pRoot;
1167 }
1168 }
1169
1170 hr = S_OK;
1171
1172LExit:
1173 return hr;
1174}
1175
1176static HRESULT ModuleFindByKey(
1177 CPI_MODULE* pItm,
1178 LPCWSTR pwzKey,
1179 BOOL fReverse,
1180 CPI_MODULE** ppItm
1181 )
1182{
1183 for (; pItm; pItm = fReverse ? pItm->pPrev : pItm->pNext)
1184 {
1185 if (0 == lstrcmpW(pItm->wzKey, pwzKey))
1186 {
1187 *ppItm = pItm;
1188 return S_OK;
1189 }
1190 }
1191
1192 return S_FALSE;
1193}
1194
1195static void SortAssemblyListByModule(
1196 CPI_MODULE_LIST* pModList,
1197 CPI_ASSEMBLY_LIST* pAsmList
1198 )
1199{
1200 CPI_ASSEMBLY* pMoved = NULL; // first moved item
1201
1202 // loop modules in reverse order
1203 for (CPI_MODULE* pMod = pModList->pLast; pMod; pMod = pMod->pPrev)
1204 {
1205 // loop assemblies in forward order, starting with the first unmoved item
1206 CPI_ASSEMBLY* pAsm = pMoved ? pMoved->pNext : pAsmList->pFirst;
1207 while (pAsm)
1208 {
1209 CPI_ASSEMBLY* pNext = pAsm->pNext;
1210
1211 // check if assembly belongs to the current module
1212 if (0 == lstrcmpW(pMod->wzKey, pAsm->wzModule))
1213 {
1214 // if the item is not already first in the list
1215 if (pAsm->pPrev)
1216 {
1217 // remove item from it's current position
1218 pAsm->pPrev->pNext = pAsm->pNext;
1219 if (pAsm->pNext)
1220 pAsm->pNext->pPrev = pAsm->pPrev;
1221 else
1222 pAsmList->pLast = pAsm->pPrev;
1223
1224 // insert item first in the list
1225 pAsmList->pFirst->pPrev = pAsm;
1226 pAsm->pNext = pAsmList->pFirst;
1227 pAsm->pPrev = NULL;
1228 pAsmList->pFirst = pAsm;
1229 }
1230
1231 // if we haven't moved any items yet, this is the first moved item
1232 if (!pMoved)
1233 pMoved = pAsm;
1234 }
1235
1236 pAsm = pNext;
1237 }
1238 }
1239}
1240
1241static HRESULT TopSortAssemblyList(
1242 CPI_KEY_PAIR* pDepList,
1243 CPI_ASSEMBLY_LIST* pList
1244 )
1245{
1246 HRESULT hr = S_OK;
1247
1248 // top sort list
1249 for (CPI_ASSEMBLY* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
1250 {
1251 // append module
1252 hr = SwapDependentAssemblies(NULL, pDepList, pList, pItm, pItm);
1253 ExitOnFailure(hr, "Failed to swap dependent assemblies");
1254 }
1255
1256 hr = S_OK;
1257
1258LExit:
1259 return hr;
1260}
1261
1262static HRESULT SwapDependentAssemblies(
1263 CPI_DEPENDENCY_CHAIN* pdcPrev, // list containing the entire dependency chain
1264 CPI_KEY_PAIR* pDepList, // assembly dependency list
1265 CPI_ASSEMBLY_LIST* pList, // assembly list being sorted
1266 CPI_ASSEMBLY* pRoot, // first assembly in the chain
1267 CPI_ASSEMBLY* pItm // current assembly to test for dependencies
1268 )
1269{
1270 HRESULT hr = S_OK;
1271
1272 CPI_ASSEMBLY* pDepItm;
1273
1274 // find dependencies
1275 for (CPI_KEY_PAIR* pDep = pDepList; pDep; pDep = pDep->pNext)
1276 {
1277 if (0 == lstrcmpW(pItm->wzKey, pDep->wzFirstKey))
1278 {
1279 CPI_DEPENDENCY_CHAIN dcItm;
1280 dcItm.pwzKey = pItm->wzKey;
1281 dcItm.pPrev = pdcPrev;
1282
1283 // check for circular dependencies
1284 for (CPI_DEPENDENCY_CHAIN* pdcItm = &dcItm; pdcItm; pdcItm = pdcItm->pPrev)
1285 {
1286 if (0 == lstrcmpW(pdcItm->pwzKey, pDep->wzSecondKey))
1287 {
1288 // circular dependency found
1289 ExitOnFailure(hr = E_FAIL, "Circular assembly dependency found, key: %S", pDep->wzSecondKey);
1290 }
1291 }
1292
1293 // make sure the item is not already in the list
1294 hr = AssemblyFindByKey(pRoot->pPrev, pDep->wzSecondKey, TRUE, &pDepItm); // find in reverse order
1295
1296 if (S_OK == hr)
1297 continue; // item found, move on
1298
1299 // find item in the list
1300 hr = AssemblyFindByKey(pRoot->pNext, pDep->wzSecondKey, FALSE, &pDepItm); // find in forward order
1301
1302 if (S_FALSE == hr)
1303 {
1304 // not found
1305 ExitOnFailure(hr = E_FAIL, "Assembly dependency not found, key: %S", pDep->wzSecondKey);
1306 }
1307
1308 // if the root item belongs to a module, this item must also belong to the same module
1309 if (*pItm->wzModule)
1310 {
1311 if (0 != lstrcmpW(pDepItm->wzModule, pItm->wzModule))
1312 ExitOnFailure(hr = E_FAIL, "An assembly dependency can only exist between two assemblies not belonging to modules, or belonging to the same module. assembly: %S, required assembly: %S", pItm->wzKey, pDepItm->wzKey);
1313 }
1314
1315 // if this item in turn has dependencies, they have to be swaped first
1316 hr = SwapDependentAssemblies(&dcItm, pDepList, pList, pRoot, pDepItm);
1317 ExitOnFailure(hr, "Failed to swap dependent assemblies");
1318
1319 // remove item from its current position
1320 pDepItm->pPrev->pNext = pDepItm->pNext; // pDepItm can never be the first item, no need to check pPrev
1321 if (pDepItm->pNext)
1322 pDepItm->pNext->pPrev = pDepItm->pPrev;
1323 else
1324 {
1325 pList->pLast = pDepItm->pPrev;
1326 pList->pLast->pNext = NULL;
1327 }
1328
1329 // insert before the current item
1330 if (pRoot->pPrev)
1331 pRoot->pPrev->pNext = pDepItm;
1332 else
1333 pList->pFirst = pDepItm;
1334 pDepItm->pPrev = pRoot->pPrev;
1335 pRoot->pPrev = pDepItm;
1336 pDepItm->pNext = pRoot;
1337 }
1338 }
1339
1340 hr = S_OK;
1341
1342LExit:
1343 return hr;
1344}
1345
1346static HRESULT AssemblyFindByKey(
1347 CPI_ASSEMBLY* pItm,
1348 LPCWSTR pwzKey,
1349 BOOL fReverse,
1350 CPI_ASSEMBLY** ppItm
1351 )
1352{
1353 for (; pItm; pItm = fReverse ? pItm->pPrev : pItm->pNext)
1354 {
1355 if (0 == lstrcmpW(pItm->wzKey, pwzKey))
1356 {
1357 *ppItm = pItm;
1358 return S_OK;
1359 }
1360 }
1361
1362 return S_FALSE;
1363}
1364
1365static HRESULT ComponentsRead(
1366 LPCWSTR pwzAsmKey,
1367 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
1368 CPI_ASSEMBLY* pAsm
1369 )
1370{
1371 HRESULT hr = S_OK;
1372 PMSIHANDLE hView;
1373 PMSIHANDLE hRec;
1374 PMSIHANDLE hRecKey;
1375 CPISCHED_COMPONENT* pItm = NULL;
1376 LPWSTR pwzData = NULL;
1377
1378 // create parameter record
1379 hRecKey = ::MsiCreateRecord(1);
1380 ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
1381 hr = WcaSetRecordString(hRecKey, 1, pwzAsmKey);
1382 ExitOnFailure(hr, "Failed to set record string");
1383
1384 // open view
1385 hr = WcaOpenView(vcsComponentQuery, &hView);
1386 ExitOnFailure(hr, "Failed to open view on ComPlusComponent table");
1387 hr = WcaExecuteView(hView, hRecKey);
1388 ExitOnFailure(hr, "Failed to execute view on ComPlusComponent table");
1389
1390 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
1391 {
1392 // create entry
1393 pItm = (CPISCHED_COMPONENT*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPISCHED_COMPONENT));
1394 if (!pItm)
1395 ExitFunction1(hr = E_OUTOFMEMORY);
1396
1397 // get key
1398 hr = WcaGetRecordString(hRec, cqComponent, &pwzData);
1399 ExitOnFailure(hr, "Failed to get key");
1400 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
1401
1402 // get clsid
1403 hr = WcaGetRecordFormattedString(hRec, cqCLSID, &pwzData);
1404 ExitOnFailure(hr, "Failed to get clsid");
1405 StringCchCopyW(pItm->wzCLSID, countof(pItm->wzCLSID), pwzData);
1406
1407 // read properties
1408 if (CpiTableExists(cptComPlusComponentProperty))
1409 {
1410 hr = CpiPropertiesRead(vcsComponentPropertyQuery, pItm->wzKey, pdlComponentProperties, &pItm->pProperties, &pItm->iPropertyCount);
1411 ExitOnFailure(hr, "Failed to get component properties");
1412 }
1413
1414 // read roles
1415 if (CpiTableExists(cptComPlusRoleForComponent))
1416 {
1417 hr = RoleAssignmentsRead(vcsRoleForComponentQuery, pItm->wzKey, pAppRoleList, &pItm->pRoles, &pItm->iRoleInstallCount, &pItm->iRoleUninstallCount);
1418 ExitOnFailure(hr, "Failed to get roles for component");
1419 }
1420
1421 if (pItm->iRoleInstallCount)
1422 pAsm->iRoleAssignmentsInstallCount++;
1423 if (pItm->iRoleUninstallCount)
1424 pAsm->iRoleAssignmentsUninstallCount++;
1425
1426 // read interfaces
1427 if (CpiTableExists(cptComPlusInterface))
1428 {
1429 hr = InterfacesRead(pItm->wzKey, pAppRoleList, pAsm, pItm);
1430 ExitOnFailure(hr, "Failed to get interfaces for component");
1431 }
1432
1433 // add entry
1434 pAsm->iComponentCount++;
1435 if (pAsm->pComponents)
1436 pItm->pNext = pAsm->pComponents;
1437 pAsm->pComponents = pItm;
1438 pItm = NULL;
1439 }
1440
1441 if (E_NOMOREITEMS == hr)
1442 hr = S_OK;
1443
1444LExit:
1445 // clean up
1446 if (pItm)
1447 ComponentsFreeList(pItm);
1448
1449 ReleaseStr(pwzData);
1450
1451 return hr;
1452}
1453
1454static HRESULT InterfacesRead(
1455 LPCWSTR pwzCompKey,
1456 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
1457 CPI_ASSEMBLY* pAsm,
1458 CPISCHED_COMPONENT* pComp
1459 )
1460{
1461 HRESULT hr = S_OK;
1462 PMSIHANDLE hView;
1463 PMSIHANDLE hRec;
1464 PMSIHANDLE hRecKey;
1465 CPISCHED_INTERFACE* pItm = NULL;
1466 LPWSTR pwzData = NULL;
1467
1468 // create parameter record
1469 hRecKey = ::MsiCreateRecord(1);
1470 ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
1471 hr = WcaSetRecordString(hRecKey, 1, pwzCompKey);
1472 ExitOnFailure(hr, "Failed to set record string");
1473
1474 // open view
1475 hr = WcaOpenView(vcsInterfaceQuery, &hView);
1476 ExitOnFailure(hr, "Failed to open view on ComPlusInterface table");
1477 hr = WcaExecuteView(hView, hRecKey);
1478 ExitOnFailure(hr, "Failed to execute view on ComPlusInterface table");
1479
1480 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
1481 {
1482 // create entry
1483 pItm = (CPISCHED_INTERFACE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPISCHED_INTERFACE));
1484 if (!pItm)
1485 ExitFunction1(hr = E_OUTOFMEMORY);
1486
1487 // get key
1488 hr = WcaGetRecordString(hRec, iqInterface, &pwzData);
1489 ExitOnFailure(hr, "Failed to get key");
1490 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
1491
1492 // get iid
1493 hr = WcaGetRecordFormattedString(hRec, iqIID, &pwzData);
1494 ExitOnFailure(hr, "Failed to get iid");
1495 StringCchCopyW(pItm->wzIID, countof(pItm->wzIID), pwzData);
1496
1497 // read properties
1498 if (CpiTableExists(cptComPlusInterfaceProperty))
1499 {
1500 hr = CpiPropertiesRead(vcsInterfacePropertyQuery, pItm->wzKey, pdlInterfaceProperties, &pItm->pProperties, &pItm->iPropertyCount);
1501 ExitOnFailure(hr, "Failed to get interface properties");
1502 }
1503
1504 // read roles
1505 if (CpiTableExists(cptComPlusRoleForInterface))
1506 {
1507 hr = RoleAssignmentsRead(vcsRoleForInterfaceQuery, pItm->wzKey, pAppRoleList, &pItm->pRoles, &pItm->iRoleInstallCount, &pItm->iRoleUninstallCount);
1508 ExitOnFailure(hr, "Failed to get roles for interface");
1509 }
1510
1511 if (pItm->iRoleInstallCount)
1512 pAsm->iRoleAssignmentsInstallCount++;
1513 if (pItm->iRoleUninstallCount)
1514 pAsm->iRoleAssignmentsUninstallCount++;
1515
1516 // read methods
1517 if (CpiTableExists(cptComPlusMethod))
1518 {
1519 hr = MethodsRead(pItm->wzKey, pAppRoleList, pAsm, pItm);
1520 ExitOnFailure(hr, "Failed to get methods for interface");
1521 }
1522
1523 // add entry
1524 pComp->iInterfaceCount++;
1525 if (pComp->pInterfaces)
1526 pItm->pNext = pComp->pInterfaces;
1527 pComp->pInterfaces = pItm;
1528 pItm = NULL;
1529 }
1530
1531 if (E_NOMOREITEMS == hr)
1532 hr = S_OK;
1533
1534LExit:
1535 // clean up
1536 if (pItm)
1537 InterfacesFreeList(pItm);
1538
1539 ReleaseStr(pwzData);
1540
1541 return hr;
1542}
1543
1544static HRESULT MethodsRead(
1545 LPCWSTR pwzIntfKey,
1546 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
1547 CPI_ASSEMBLY* pAsm,
1548 CPISCHED_INTERFACE* pIntf
1549 )
1550{
1551 HRESULT hr = S_OK;
1552 PMSIHANDLE hView, hRec, hRecKey;
1553 CPISCHED_METHOD* pItm = NULL;
1554 LPWSTR pwzData = NULL;
1555
1556 // create parameter record
1557 hRecKey = ::MsiCreateRecord(1);
1558 ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
1559 hr = WcaSetRecordString(hRecKey, 1, pwzIntfKey);
1560 ExitOnFailure(hr, "Failed to set record string");
1561
1562 // open view
1563 hr = WcaOpenView(vcsMethodQuery, &hView);
1564 ExitOnFailure(hr, "Failed to open view on ComPlusMethod table");
1565 hr = WcaExecuteView(hView, hRecKey);
1566 ExitOnFailure(hr, "Failed to execute view on ComPlusMethod table");
1567
1568 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
1569 {
1570 // create entry
1571 pItm = (CPISCHED_METHOD*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPISCHED_METHOD));
1572 if (!pItm)
1573 ExitFunction1(hr = E_OUTOFMEMORY);
1574
1575 // get key
1576 hr = WcaGetRecordString(hRec, iqInterface, &pwzData);
1577 ExitOnFailure(hr, "Failed to get key");
1578 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
1579
1580 // get index
1581 hr = WcaGetRecordFormattedString(hRec, mqIndex, &pwzData);
1582 ExitOnFailure(hr, "Failed to get index");
1583 StringCchCopyW(pItm->wzIndex, countof(pItm->wzIndex), pwzData);
1584
1585 // get name
1586 hr = WcaGetRecordFormattedString(hRec, mqName, &pwzData);
1587 ExitOnFailure(hr, "Failed to get name");
1588 StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData);
1589
1590 // either an index or a name must be provided
1591 if (!*pItm->wzIndex && !*pItm->wzName)
1592 ExitOnFailure(hr = E_FAIL, "A method must have either an index or a name associated, key: %S", pItm->wzKey);
1593
1594 // read properties
1595 if (CpiTableExists(cptComPlusMethodProperty))
1596 {
1597 hr = CpiPropertiesRead(vcsMethodPropertyQuery, pItm->wzKey, pdlMethodProperties, &pItm->pProperties, &pItm->iPropertyCount);
1598 ExitOnFailure(hr, "Failed to get method properties");
1599 }
1600
1601 // read roles
1602 if (CpiTableExists(cptComPlusRoleForMethod))
1603 {
1604 hr = RoleAssignmentsRead(vcsRoleForMethodQuery, pItm->wzKey, pAppRoleList, &pItm->pRoles, &pItm->iRoleInstallCount, &pItm->iRoleUninstallCount);
1605 ExitOnFailure(hr, "Failed to get roles for method");
1606 }
1607
1608 if (pItm->iRoleInstallCount)
1609 pAsm->iRoleAssignmentsInstallCount++;
1610 if (pItm->iRoleUninstallCount)
1611 pAsm->iRoleAssignmentsUninstallCount++;
1612
1613 // add entry
1614 pIntf->iMethodCount++;
1615 if (pIntf->pMethods)
1616 pItm->pNext = pIntf->pMethods;
1617 pIntf->pMethods = pItm;
1618 pItm = NULL;
1619 }
1620
1621 if (E_NOMOREITEMS == hr)
1622 hr = S_OK;
1623
1624LExit:
1625 // clean up
1626 if (pItm)
1627 MethodsFreeList(pItm);
1628
1629 ReleaseStr(pwzData);
1630
1631 return hr;
1632}
1633
1634static HRESULT RoleAssignmentsRead(
1635 LPCWSTR pwzQuery,
1636 LPCWSTR pwzKey,
1637 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
1638 CPISCHED_ROLE_ASSIGNMENT** ppRoleList,
1639 int* piInstallCount,
1640 int* piUninstallCount
1641 )
1642{
1643 HRESULT hr = S_OK;
1644 UINT er = ERROR_SUCCESS;
1645
1646 PMSIHANDLE hView, hRec, hRecKey;
1647
1648 CPISCHED_ROLE_ASSIGNMENT* pItm = NULL;
1649 LPWSTR pwzData = NULL;
1650 BOOL fMatchingArchitecture = FALSE;
1651
1652 // create parameter record
1653 hRecKey = ::MsiCreateRecord(1);
1654 ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
1655 hr = WcaSetRecordString(hRecKey, 1, pwzKey);
1656 ExitOnFailure(hr, "Failed to set record string");
1657
1658 // open view
1659 hr = WcaOpenView(pwzQuery, &hView);
1660 ExitOnFailure(hr, "Failed to open view on role assignment table");
1661 hr = WcaExecuteView(hView, hRecKey);
1662 ExitOnFailure(hr, "Failed to execute view on role assignment table");
1663
1664 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
1665 {
1666 // get component
1667 hr = WcaGetRecordString(hRec, raqComponent, &pwzData);
1668 ExitOnFailure(hr, "Failed to get assembly component");
1669
1670 // check if the component is our processor architecture
1671 hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture);
1672 ExitOnFailure(hr, "Failed to get component architecture.");
1673
1674 if (!fMatchingArchitecture)
1675 {
1676 continue; // not the same architecture, ignore
1677 }
1678
1679 // create entry
1680 pItm = (CPISCHED_ROLE_ASSIGNMENT*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPISCHED_ROLE_ASSIGNMENT));
1681 if (!pItm)
1682 ExitFunction1(hr = E_OUTOFMEMORY);
1683
1684 // get component install state
1685 er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction);
1686 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
1687
1688 // get key
1689 hr = WcaGetRecordString(hRec, raqKey, &pwzData);
1690 ExitOnFailure(hr, "Failed to get key");
1691 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
1692
1693 // get application role
1694 hr = WcaGetRecordString(hRec, raqApplicationRole, &pwzData);
1695 ExitOnFailure(hr, "Failed to get application role");
1696
1697 hr = CpiApplicationRoleFindByKey(pAppRoleList, pwzData, &pItm->pApplicationRole);
1698 if (S_FALSE == hr)
1699 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1700 ExitOnFailure(hr, "Failed to find application, key: %S", pwzData);
1701
1702 // set references & increment counters
1703 if (WcaIsInstalling(pItm->isInstalled, pItm->isAction))
1704 {
1705 CpiApplicationRoleAddReferenceInstall(pItm->pApplicationRole);
1706 ++*piInstallCount;
1707 }
1708 if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
1709 {
1710 CpiApplicationRoleAddReferenceUninstall(pItm->pApplicationRole);
1711 ++*piUninstallCount;
1712 }
1713
1714 // add entry
1715 if (*ppRoleList)
1716 pItm->pNext = *ppRoleList;
1717 *ppRoleList = pItm;
1718 pItm = NULL;
1719 }
1720
1721 if (E_NOMOREITEMS == hr)
1722 hr = S_OK;
1723
1724LExit:
1725 // clean up
1726 if (pItm)
1727 RoleAssignmentsFreeList(pItm);
1728
1729 ReleaseStr(pwzData);
1730
1731 return hr;
1732}
1733
1734static HRESULT AddAssemblyToActionData(
1735 CPI_ASSEMBLY* pItm,
1736 BOOL fInstall,
1737 int iActionType,
1738 int iActionCost,
1739 LPWSTR* ppwzActionData
1740 )
1741{
1742 HRESULT hr = S_OK;
1743
1744 // add action information to custom action data
1745 hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
1746 ExitOnFailure(hr, "Failed to add action type to custom action data");
1747 hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
1748 ExitOnFailure(hr, "Failed to add action cost to custom action data");
1749
1750 // add assembly information to custom action data
1751 hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
1752 ExitOnFailure(hr, "Failed to add assembly key to custom action data");
1753 hr = WcaWriteStringToCaData(pItm->pwzAssemblyName, ppwzActionData);
1754 ExitOnFailure(hr, "Failed to add assembly name to custom action data");
1755 hr = WcaWriteStringToCaData(pItm->pwzDllPath, ppwzActionData);
1756 ExitOnFailure(hr, "Failed to add assembly dll path to custom action data");
1757 hr = WcaWriteStringToCaData(atCreate == iActionType ? pItm->pwzTlbPath : L"", ppwzActionData);
1758 ExitOnFailure(hr, "Failed to add assembly tlb path to custom action data");
1759 hr = WcaWriteStringToCaData(atCreate == iActionType ? pItm->pwzPSDllPath : L"", ppwzActionData);
1760 ExitOnFailure(hr, "Failed to add assembly proxy-stub dll path to custom action data");
1761 hr = WcaWriteIntegerToCaData(pItm->iAttributes, ppwzActionData);
1762 ExitOnFailure(hr, "Failed to add assembly attributes to custom action data");
1763
1764 // add application information to custom action data
1765 hr = WcaWriteStringToCaData(pItm->pApplication ? pItm->pApplication->wzID : L"", ppwzActionData);
1766 ExitOnFailure(hr, "Failed to add application id to custom action data");
1767
1768 // add partition information to custom action data
1769 LPCWSTR pwzPartID = pItm->pApplication && pItm->pApplication->pPartition ? pItm->pApplication->pPartition->wzID : L"";
1770 hr = WcaWriteStringToCaData(pwzPartID, ppwzActionData);
1771 ExitOnFailure(hr, "Failed to add partition id to custom action data");
1772
1773 // add components to custom action data
1774 //
1775 // components are needed acording to the following table:
1776 //
1777 // Native .NET
1778 // --------------------------------------------
1779 // NoOp | No | No
1780 // Create | Yes | Yes
1781 // Remove | Yes | No
1782 //
1783 int iCompCount = (atCreate == iActionType || (atRemove == iActionType && 0 == (pItm->iAttributes & aaDotNetAssembly))) ? pItm->iComponentCount : 0;
1784 hr = WcaWriteIntegerToCaData(iCompCount, ppwzActionData);
1785 ExitOnFailure(hr, "Failed to add component count to custom action data, key: %S", pItm->wzKey);
1786
1787 if (iCompCount)
1788 {
1789 for (CPISCHED_COMPONENT* pComp = pItm->pComponents; pComp; pComp = pComp->pNext)
1790 {
1791 hr = AddComponentToActionData(pComp, fInstall, atCreate == iActionType, FALSE, ppwzActionData);
1792 ExitOnFailure(hr, "Failed to add component to custom action data, component: %S", pComp->wzKey);
1793 }
1794 }
1795
1796 hr = S_OK;
1797
1798LExit:
1799 return hr;
1800}
1801
1802static HRESULT AddRoleAssignmentsToActionData(
1803 CPI_ASSEMBLY* pItm,
1804 BOOL fInstall,
1805 int iActionType,
1806 int iActionCost,
1807 LPWSTR* ppwzActionData
1808 )
1809{
1810 HRESULT hr = S_OK;
1811
1812 // add action information to custom action data
1813 hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
1814 ExitOnFailure(hr, "Failed to add action type to custom action data");
1815 hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
1816 ExitOnFailure(hr, "Failed to add action cost to custom action data");
1817
1818 // add assembly information to custom action data
1819 hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
1820 ExitOnFailure(hr, "Failed to add assembly key to custom action data");
1821 hr = WcaWriteIntegerToCaData(fInstall ? pItm->iRoleAssignmentsInstallCount : pItm->iRoleAssignmentsUninstallCount, ppwzActionData);
1822 ExitOnFailure(hr, "Failed to add role assignments count to custom action data");
1823
1824 // add application information to custom action data
1825 hr = WcaWriteStringToCaData(pItm->pApplication ? pItm->pApplication->wzID : L"", ppwzActionData);
1826 ExitOnFailure(hr, "Failed to add application id to custom action data");
1827
1828 // add partition information to custom action data
1829 LPCWSTR pwzPartID = pItm->pApplication && pItm->pApplication->pPartition ? pItm->pApplication->pPartition->wzID : L"";
1830 hr = WcaWriteStringToCaData(pwzPartID, ppwzActionData);
1831 ExitOnFailure(hr, "Failed to add partition id to custom action data");
1832
1833 // add components to custom action data
1834 hr = WcaWriteIntegerToCaData(pItm->iComponentCount, ppwzActionData);
1835 ExitOnFailure(hr, "Failed to add component count to custom action data");
1836
1837 for (CPISCHED_COMPONENT* pComp = pItm->pComponents; pComp; pComp = pComp->pNext)
1838 {
1839 hr = AddComponentToActionData(pComp, fInstall, FALSE, TRUE, ppwzActionData);
1840 ExitOnFailure(hr, "Failed to add component to custom action data, component: %S", pComp->wzKey);
1841 }
1842
1843 hr = S_OK;
1844
1845LExit:
1846 return hr;
1847}
1848
1849static HRESULT AddComponentToActionData(
1850 CPISCHED_COMPONENT* pItm,
1851 BOOL fInstall,
1852 BOOL fProps,
1853 BOOL fRoles,
1854 LPWSTR* ppwzActionData
1855 )
1856{
1857 HRESULT hr = S_OK;
1858
1859 // add component information to custom action data
1860 hr = WcaWriteStringToCaData(pItm->wzCLSID, ppwzActionData);
1861 ExitOnFailure(hr, "Failed to add component CLSID to custom action data");
1862
1863 // add properties to custom action data
1864 hr = CpiAddPropertiesToActionData(fProps ? pItm->iPropertyCount : 0, pItm->pProperties, ppwzActionData);
1865 ExitOnFailure(hr, "Failed to add properties to custom action data");
1866
1867 // add roles to custom action data
1868 hr = AddRolesToActionData(pItm->iRoleInstallCount, pItm->iRoleUninstallCount, pItm->pRoles, fInstall, fRoles, ppwzActionData);
1869 ExitOnFailure(hr, "Failed to add roles to custom action data");
1870
1871 // add interfaces to custom action data
1872 int iIntfCount = (fProps || fRoles) ? pItm->iInterfaceCount : 0;
1873 hr = WcaWriteIntegerToCaData(iIntfCount, ppwzActionData);
1874 ExitOnFailure(hr, "Failed to add interface count to custom action data");
1875
1876 if (iIntfCount)
1877 {
1878 for (CPISCHED_INTERFACE* pIntf = pItm->pInterfaces; pIntf; pIntf = pIntf->pNext)
1879 {
1880 hr = AddInterfaceToActionData(pIntf, fInstall, fProps, fRoles, ppwzActionData);
1881 ExitOnFailure(hr, "Failed to add interface custom action data, interface: %S", pIntf->wzKey);
1882 }
1883 }
1884
1885 hr = S_OK;
1886
1887LExit:
1888 return hr;
1889}
1890
1891static HRESULT AddInterfaceToActionData(
1892 CPISCHED_INTERFACE* pItm,
1893 BOOL fInstall,
1894 BOOL fProps,
1895 BOOL fRoles,
1896 LPWSTR* ppwzActionData
1897 )
1898{
1899 HRESULT hr = S_OK;
1900
1901 // add interface information to custom action data
1902 hr = WcaWriteStringToCaData(pItm->wzIID, ppwzActionData);
1903 ExitOnFailure(hr, "Failed to add interface IID to custom action data");
1904
1905 // add properties to custom action data
1906 hr = CpiAddPropertiesToActionData(fProps ? pItm->iPropertyCount : 0, pItm->pProperties, ppwzActionData);
1907 ExitOnFailure(hr, "Failed to add properties to custom action data");
1908
1909 // add roles to custom action data
1910 hr = AddRolesToActionData(pItm->iRoleInstallCount, pItm->iRoleUninstallCount, pItm->pRoles, fInstall, fRoles, ppwzActionData);
1911 ExitOnFailure(hr, "Failed to add roles to custom action data");
1912
1913 // add methods to custom action data
1914 hr = WcaWriteIntegerToCaData(pItm->iMethodCount, ppwzActionData);
1915 ExitOnFailure(hr, "Failed to add method count to custom action data");
1916
1917 for (CPISCHED_METHOD* pMeth = pItm->pMethods; pMeth; pMeth = pMeth->pNext)
1918 {
1919 hr = AddMethodToActionData(pMeth, fInstall, fProps, fRoles, ppwzActionData);
1920 ExitOnFailure(hr, "Failed to add method custom action data, method: %S", pMeth->wzKey);
1921 }
1922
1923 hr = S_OK;
1924
1925LExit:
1926 return hr;
1927}
1928
1929static HRESULT AddMethodToActionData(
1930 CPISCHED_METHOD* pItm,
1931 BOOL fInstall,
1932 BOOL fProps,
1933 BOOL fRoles,
1934 LPWSTR* ppwzActionData
1935 )
1936{
1937 HRESULT hr = S_OK;
1938
1939 // add interface information to custom action data
1940 hr = WcaWriteStringToCaData(pItm->wzIndex, ppwzActionData);
1941 ExitOnFailure(hr, "Failed to add method index to custom action data");
1942
1943 hr = WcaWriteStringToCaData(pItm->wzName, ppwzActionData);
1944 ExitOnFailure(hr, "Failed to add method name to custom action data");
1945
1946 // add properties to custom action data
1947 hr = CpiAddPropertiesToActionData(fProps ? pItm->iPropertyCount : 0, pItm->pProperties, ppwzActionData);
1948 ExitOnFailure(hr, "Failed to add properties to custom action data");
1949
1950 // add roles to custom action data
1951 hr = AddRolesToActionData(pItm->iRoleInstallCount, pItm->iRoleUninstallCount, pItm->pRoles, fInstall, fRoles, ppwzActionData);
1952 ExitOnFailure(hr, "Failed to add roles to custom action data");
1953
1954 hr = S_OK;
1955
1956LExit:
1957 return hr;
1958}
1959
1960static HRESULT AddRolesToActionData(
1961 int iRoleInstallCount,
1962 int iRoleUninstallCount,
1963 CPISCHED_ROLE_ASSIGNMENT* pRoleList,
1964 BOOL fInstall,
1965 BOOL fRoles,
1966 LPWSTR* ppwzActionData
1967 )
1968{
1969 HRESULT hr = S_OK;
1970
1971 int iRoleCount = fRoles ? (fInstall ? iRoleInstallCount : iRoleUninstallCount) : 0;
1972 hr = WcaWriteIntegerToCaData(iRoleCount, ppwzActionData);
1973 ExitOnFailure(hr, "Failed to add role count to custom action data");
1974
1975 if (iRoleCount)
1976 {
1977 for (CPISCHED_ROLE_ASSIGNMENT* pRole = pRoleList; pRole; pRole = pRole->pNext)
1978 {
1979 // make sure the install state matches the create flag
1980 if (fInstall ? !WcaIsInstalling(pRole->isInstalled, pRole->isAction) : !WcaIsUninstalling(pRole->isInstalled, pRole->isAction))
1981 continue;
1982
1983 hr = WcaWriteStringToCaData(pRole->pApplicationRole->wzKey, ppwzActionData);
1984 ExitOnFailure(hr, "Failed to add key to custom action data, role: %S", pRole->wzKey);
1985
1986 hr = WcaWriteStringToCaData(pRole->pApplicationRole->wzName, ppwzActionData);
1987 ExitOnFailure(hr, "Failed to add role name to custom action data, role: %S", pRole->wzKey);
1988 }
1989 }
1990
1991 hr = S_OK;
1992
1993LExit:
1994 return hr;
1995}
1996
1997static HRESULT KeyPairFindByFirstKey(
1998 CPI_KEY_PAIR* pList,
1999 LPCWSTR pwzKey,
2000 CPI_KEY_PAIR** ppItm
2001 )
2002{
2003 for (; pList; pList = pList->pNext)
2004 {
2005 if (0 == lstrcmpW(pList->wzFirstKey, pwzKey))
2006 {
2007 *ppItm = pList;
2008 return S_OK;
2009 }
2010 }
2011
2012 return S_FALSE;
2013}
2014
2015static void AssemblyFree(
2016 CPI_ASSEMBLY* pItm
2017 )
2018{
2019 ReleaseStr(pItm->pwzAssemblyName);
2020 ReleaseStr(pItm->pwzDllPath);
2021 ReleaseStr(pItm->pwzTlbPath);
2022 ReleaseStr(pItm->pwzPSDllPath);
2023
2024 if (pItm->pComponents)
2025 ComponentsFreeList(pItm->pComponents);
2026
2027 ::HeapFree(::GetProcessHeap(), 0, pItm);
2028}
2029
2030static void KeyPairsFreeList(
2031 CPI_KEY_PAIR* pList
2032 )
2033{
2034 while (pList)
2035 {
2036 CPI_KEY_PAIR* pDelete = pList;
2037 pList = pList->pNext;
2038 ::HeapFree(::GetProcessHeap(), 0, pDelete);
2039 }
2040}
2041
2042void ModuleListFree(
2043 CPI_MODULE_LIST* pList
2044 )
2045{
2046 CPI_MODULE* pItm = pList->pFirst;
2047
2048 while (pItm)
2049 {
2050 CPI_MODULE* pDelete = pItm;
2051 pItm = pItm->pNext;
2052 ModuleFree(pDelete);
2053 }
2054}
2055
2056static void ModuleFree(
2057 CPI_MODULE* pItm
2058 )
2059{
2060 ::HeapFree(::GetProcessHeap(), 0, pItm);
2061}
2062
2063static void ComponentsFreeList(
2064 CPISCHED_COMPONENT* pList
2065 )
2066{
2067 while (pList)
2068 {
2069 if (pList->pProperties)
2070 CpiPropertiesFreeList(pList->pProperties);
2071
2072 if (pList->pRoles)
2073 RoleAssignmentsFreeList(pList->pRoles);
2074
2075 if (pList->pInterfaces)
2076 InterfacesFreeList(pList->pInterfaces);
2077
2078 ReleaseObject(pList->piSubsColl);
2079
2080 CPISCHED_COMPONENT* pDelete = pList;
2081 pList = pList->pNext;
2082 ::HeapFree(::GetProcessHeap(), 0, pDelete);
2083 }
2084}
2085
2086static void InterfacesFreeList(
2087 CPISCHED_INTERFACE* pList
2088 )
2089{
2090 while (pList)
2091 {
2092 if (pList->pProperties)
2093 CpiPropertiesFreeList(pList->pProperties);
2094
2095 if (pList->pRoles)
2096 RoleAssignmentsFreeList(pList->pRoles);
2097
2098 if (pList->pMethods)
2099 MethodsFreeList(pList->pMethods);
2100
2101 CPISCHED_INTERFACE* pDelete = pList;
2102 pList = pList->pNext;
2103 ::HeapFree(::GetProcessHeap(), 0, pDelete);
2104 }
2105}
2106
2107static void MethodsFreeList(
2108 CPISCHED_METHOD* pList
2109 )
2110{
2111 while (pList)
2112 {
2113 if (pList->pProperties)
2114 CpiPropertiesFreeList(pList->pProperties);
2115
2116 if (pList->pRoles)
2117 RoleAssignmentsFreeList(pList->pRoles);
2118
2119 CPISCHED_METHOD* pDelete = pList;
2120 pList = pList->pNext;
2121 ::HeapFree(::GetProcessHeap(), 0, pDelete);
2122 }
2123}
2124
2125static void RoleAssignmentsFreeList(
2126 CPISCHED_ROLE_ASSIGNMENT* pList
2127 )
2128{
2129 while (pList)
2130 {
2131 CPISCHED_ROLE_ASSIGNMENT* pDelete = pList;
2132 pList = pList->pNext;
2133 ::HeapFree(::GetProcessHeap(), 0, pDelete);
2134 }
2135}
diff --git a/src/ext/ComPlus/ca/cpasmsched.h b/src/ext/ComPlus/ca/cpasmsched.h
new file mode 100644
index 00000000..ddf4b6c0
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpasmsched.h
@@ -0,0 +1,168 @@
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
5enum eAssemblyAttributes
6{
7 aaEventClass = (1 << 0),
8 aaDotNetAssembly = (1 << 1),
9 aaPathFromGAC = (1 << 2),
10 aaRunInCommit = (1 << 3)
11};
12
13
14// structs
15
16struct CPISCHED_ROLE_ASSIGNMENT
17{
18 WCHAR wzKey[MAX_DARWIN_KEY + 1];
19
20 INSTALLSTATE isInstalled, isAction;
21
22 CPI_APPLICATION_ROLE* pApplicationRole;
23
24 CPISCHED_ROLE_ASSIGNMENT* pNext;
25};
26
27struct CPISCHED_METHOD
28{
29 WCHAR wzKey[MAX_DARWIN_KEY + 1];
30 WCHAR wzIndex[11 + 1];
31 WCHAR wzName[MAX_DARWIN_COLUMN + 1];
32
33 int iPropertyCount;
34 CPI_PROPERTY* pProperties;
35
36 int iRoleInstallCount;
37 int iRoleUninstallCount;
38 CPISCHED_ROLE_ASSIGNMENT* pRoles;
39
40 CPISCHED_METHOD* pNext;
41};
42
43struct CPISCHED_INTERFACE
44{
45 WCHAR wzKey[MAX_DARWIN_KEY + 1];
46 WCHAR wzIID[CPI_MAX_GUID + 1];
47
48 int iPropertyCount;
49 CPI_PROPERTY* pProperties;
50
51 int iRoleInstallCount;
52 int iRoleUninstallCount;
53 CPISCHED_ROLE_ASSIGNMENT* pRoles;
54
55 int iMethodCount;
56 CPISCHED_METHOD* pMethods;
57
58 CPISCHED_INTERFACE* pNext;
59};
60
61struct CPISCHED_COMPONENT
62{
63 WCHAR wzKey[MAX_DARWIN_KEY + 1];
64 WCHAR wzCLSID[CPI_MAX_GUID + 1];
65
66 int iPropertyCount;
67 CPI_PROPERTY* pProperties;
68
69 int iRoleInstallCount;
70 int iRoleUninstallCount;
71 CPISCHED_ROLE_ASSIGNMENT* pRoles;
72
73 int iInterfaceCount;
74 CPISCHED_INTERFACE* pInterfaces;
75
76 ICatalogCollection* piSubsColl;
77
78 CPISCHED_COMPONENT* pNext;
79};
80
81struct CPI_ASSEMBLY
82{
83 WCHAR wzKey[MAX_DARWIN_KEY + 1];
84 WCHAR wzModule[MAX_DARWIN_KEY + 1];
85 LPWSTR pwzAssemblyName;
86 LPWSTR pwzDllPath;
87 LPWSTR pwzTlbPath;
88 LPWSTR pwzPSDllPath;
89 int iAttributes;
90
91 int iComponentCount;
92 CPISCHED_COMPONENT* pComponents;
93
94 BOOL fReferencedForInstall;
95 BOOL fReferencedForUninstall;
96 BOOL fIgnore;
97
98 int iRoleAssignmentsInstallCount;
99 int iRoleAssignmentsUninstallCount;
100
101 INSTALLSTATE isInstalled, isAction;
102
103 CPI_APPLICATION* pApplication;
104
105 CPI_ASSEMBLY* pPrev;
106 CPI_ASSEMBLY* pNext;
107};
108
109struct CPI_ASSEMBLY_LIST
110{
111 CPI_ASSEMBLY* pFirst;
112 CPI_ASSEMBLY* pLast;
113
114 int iInstallCount;
115 int iCommitCount;
116 int iUninstallCount;
117
118 int iRoleInstallCount;
119 int iRoleCommitCount;
120 int iRoleUninstallCount;
121};
122
123
124// function prototypes
125
126void CpiAssemblyListFree(
127 CPI_ASSEMBLY_LIST* pList
128 );
129HRESULT CpiAssembliesRead(
130 CPI_APPLICATION_LIST* pAppList,
131 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
132 CPI_ASSEMBLY_LIST* pAsmList
133 );
134HRESULT CpiAssembliesVerifyInstall(
135 CPI_ASSEMBLY_LIST* pList
136 );
137HRESULT CpiAssembliesVerifyUninstall(
138 CPI_ASSEMBLY_LIST* pList
139 );
140HRESULT CpiAssembliesInstall(
141 CPI_ASSEMBLY_LIST* pList,
142 int iRunMode,
143 LPWSTR* ppwzActionData,
144 int* piProgress
145 );
146HRESULT CpiAssembliesUninstall(
147 CPI_ASSEMBLY_LIST* pList,
148 int iRunMode,
149 LPWSTR* ppwzActionData,
150 int* piProgress
151 );
152HRESULT CpiRoleAssignmentsInstall(
153 CPI_ASSEMBLY_LIST* pList,
154 int iRunMode,
155 LPWSTR* ppwzActionData,
156 int* piProgress
157 );
158HRESULT CpiRoleAssignmentsUninstall(
159 CPI_ASSEMBLY_LIST* pList,
160 int iRunMode,
161 LPWSTR* ppwzActionData,
162 int* piProgress
163 );
164HRESULT CpiGetSubscriptionsCollForComponent(
165 CPI_ASSEMBLY* pAsm,
166 CPISCHED_COMPONENT* pComp,
167 ICatalogCollection** ppiSubsColl
168 );
diff --git a/src/ext/ComPlus/ca/cpcost.h b/src/ext/ComPlus/ca/cpcost.h
new file mode 100644
index 00000000..7a23e03b
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpcost.h
@@ -0,0 +1,30 @@
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 COST_PARTITION_CREATE 10000
6#define COST_PARTITION_DELETE 10000
7
8#define COST_PARTITION_USER_CREATE 10000
9#define COST_PARTITION_USER_DELETE 10000
10
11#define COST_USER_IN_PARTITION_ROLE_CREATE 10000
12#define COST_USER_IN_PARTITION_ROLE_DELETE 10000
13
14#define COST_APPLICATION_CREATE 10000
15#define COST_APPLICATION_DELETE 10000
16
17#define COST_APPLICATION_ROLE_CREATE 10000
18#define COST_APPLICATION_ROLE_DELETE 10000
19
20#define COST_USER_IN_APPLICATION_ROLE_CREATE 10000
21#define COST_USER_IN_APPLICATION_ROLE_DELETE 10000
22
23#define COST_ASSEMBLY_REGISTER 50000
24#define COST_ASSEMBLY_UNREGISTER 10000
25
26#define COST_ROLLASSIGNMENT_CREATE 10000
27#define COST_ROLLASSIGNMENT_DELETE 10000
28
29#define COST_SUBSCRIPTION_CREATE 10000
30#define COST_SUBSCRIPTION_DELETE 10000
diff --git a/src/ext/ComPlus/ca/cpexec.cpp b/src/ext/ComPlus/ca/cpexec.cpp
new file mode 100644
index 00000000..9b1691fc
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpexec.cpp
@@ -0,0 +1,681 @@
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 ComPlusPrepare - CUSTOM ACTION ENTRY POINT
7
8 Input: deferred CustomActionData - ComPlusPrepare
9********************************************************************/
10extern "C" UINT __stdcall ComPlusPrepare(MSIHANDLE hInstall)
11{
12 HRESULT hr = S_OK;
13 UINT er = ERROR_SUCCESS;
14
15 LPWSTR pwzCustomActionData = NULL;
16 LPWSTR pwzData = NULL;
17
18 HANDLE hRollbackFile = INVALID_HANDLE_VALUE;
19
20 // initialize
21 hr = WcaInitialize(hInstall, "ComPlusPrepare");
22 ExitOnFailure(hr, "Failed to initialize ComPlusPrepare");
23
24 // get custom action data
25 hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
26 ExitOnFailure(hr, "Failed to get CustomActionData");
27 pwzData = pwzCustomActionData;
28
29 // create rollback file
30 hRollbackFile = ::CreateFileW(pwzData, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY, NULL);
31 if (INVALID_HANDLE_VALUE == hRollbackFile)
32 ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to create rollback file, name: %S", pwzData);
33
34 hr = S_OK;
35
36LExit:
37 // clean up
38 ReleaseStr(pwzCustomActionData);
39
40 if (INVALID_HANDLE_VALUE != hRollbackFile)
41 ::CloseHandle(hRollbackFile);
42
43 er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
44 return WcaFinalize(er);
45}
46
47/********************************************************************
48 ComPlusCleanup - CUSTOM ACTION ENTRY POINT
49
50 Input: deferred CustomActionData - ComPlusCleanup
51********************************************************************/
52extern "C" UINT __stdcall ComPlusCleanup(MSIHANDLE hInstall)
53{
54 HRESULT hr = S_OK;
55 UINT er = ERROR_SUCCESS;
56
57 LPWSTR pwzCustomActionData = NULL;
58 LPWSTR pwzData = NULL;
59
60 // initialize
61 hr = WcaInitialize(hInstall, "ComPlusCleanup");
62 ExitOnFailure(hr, "Failed to initialize ComPlusCleanup");
63
64 // get custom action data
65 hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
66 ExitOnFailure(hr, "Failed to get CustomActionData");
67 pwzData = pwzCustomActionData;
68
69 // delete rollback file
70 if (!::DeleteFileW(pwzData))
71 {
72 // error, but not a showstopper
73 hr = HRESULT_FROM_WIN32(::GetLastError());
74 WcaLog(LOGMSG_STANDARD, "Failed to delete rollback file, hr: 0x%x, name: %S", hr, pwzData);
75 }
76
77 hr = S_OK;
78
79LExit:
80 // clean up
81 ReleaseStr(pwzCustomActionData);
82
83 er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
84 return WcaFinalize(er);
85}
86
87/********************************************************************
88 ComPlusInstallExecute - CUSTOM ACTION ENTRY POINT
89
90 Input: deferred CustomActionData - ComPlusInstallExecute
91********************************************************************/
92extern "C" UINT __stdcall ComPlusInstallExecute(MSIHANDLE hInstall)
93{
94 HRESULT hr = S_OK;
95 UINT er = ERROR_SUCCESS;
96
97 LPWSTR pwzCustomActionData = NULL;
98 LPWSTR pwzData = NULL;
99 LPWSTR pwzRollbackFileName = NULL;
100
101 HANDLE hRollbackFile = INVALID_HANDLE_VALUE;
102
103 BOOL fInitializedCom = FALSE;
104
105 // initialize
106 hr = WcaInitialize(hInstall, "ComPlusInstallExecute");
107 ExitOnFailure(hr, "Failed to initialize ComPlusInstallExecute");
108
109 hr = ::CoInitialize(NULL);
110 ExitOnFailure(hr, "Failed to initialize COM");
111 fInitializedCom = TRUE;
112
113 CpiExecInitialize();
114
115 // get custom action data
116 hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
117 ExitOnFailure(hr, "Failed to get CustomActionData");
118 pwzData = pwzCustomActionData;
119
120 // open rollback file
121 hr = WcaReadStringFromCaData(&pwzData, &pwzRollbackFileName);
122 ExitOnFailure(hr, "Failed to read rollback file name");
123
124 hRollbackFile = ::CreateFileW(pwzRollbackFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
125 if (INVALID_HANDLE_VALUE == hRollbackFile)
126 ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to open rollback file, name: %S", pwzRollbackFileName);
127
128 // create partitions
129 hr = CpiConfigurePartitions(&pwzData, hRollbackFile);
130 ExitOnFailure(hr, "Failed to create partitions");
131 if (S_FALSE == hr) ExitFunction();
132
133 // create users in partition roles
134 hr = CpiConfigureUsersInPartitionRoles(&pwzData, hRollbackFile);
135 ExitOnFailure(hr, "Failed to create users in partition roles");
136 if (S_FALSE == hr) ExitFunction();
137
138 // create partition users
139 hr = CpiConfigurePartitionUsers(&pwzData, hRollbackFile);
140 ExitOnFailure(hr, "Failed to add partition users");
141 if (S_FALSE == hr) ExitFunction();
142
143 // create applications
144 hr = CpiConfigureApplications(&pwzData, hRollbackFile);
145 ExitOnFailure(hr, "Failed to create applications");
146 if (S_FALSE == hr) ExitFunction();
147
148 // create application roles
149 hr = CpiConfigureApplicationRoles(&pwzData, hRollbackFile);
150 ExitOnFailure(hr, "Failed to create application roles");
151 if (S_FALSE == hr) ExitFunction();
152
153 // create users in application roles
154 hr = CpiConfigureUsersInApplicationRoles(&pwzData, hRollbackFile);
155 ExitOnFailure(hr, "Failed to create users in application roles");
156 if (S_FALSE == hr) ExitFunction();
157
158 // register assemblies
159 hr = CpiConfigureAssemblies(&pwzData, hRollbackFile);
160 ExitOnFailure(hr, "Failed to register assemblies");
161 if (S_FALSE == hr) ExitFunction();
162
163 // create role assignments
164 hr = CpiConfigureRoleAssignments(&pwzData, hRollbackFile);
165 ExitOnFailure(hr, "Failed to create role assignments");
166 if (S_FALSE == hr) ExitFunction();
167
168 // create subscriptions
169 hr = CpiConfigureSubscriptions(&pwzData, hRollbackFile);
170 ExitOnFailure(hr, "Failed to create subscriptions");
171 if (S_FALSE == hr) ExitFunction();
172
173 hr = S_OK;
174
175LExit:
176 // clean up
177 ReleaseStr(pwzCustomActionData);
178 ReleaseStr(pwzRollbackFileName);
179
180 if (INVALID_HANDLE_VALUE != hRollbackFile)
181 ::CloseHandle(hRollbackFile);
182
183 // unitialize
184 CpiExecFinalize();
185
186 if (fInitializedCom)
187 ::CoUninitialize();
188
189 er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
190 return WcaFinalize(er);
191}
192
193/********************************************************************
194 ComPlusInstallExecuteCommit - CUSTOM ACTION ENTRY POINT
195
196 Input: deferred CustomActionData - ComPlusInstallExecuteCommit
197********************************************************************/
198extern "C" UINT __stdcall ComPlusInstallExecuteCommit(MSIHANDLE hInstall)
199{
200 HRESULT hr = S_OK;
201 UINT er = ERROR_SUCCESS;
202
203 LPWSTR pwzCustomActionData = NULL;
204 LPWSTR pwzData = NULL;
205 LPWSTR pwzRollbackFileName = NULL;
206
207 HANDLE hRollbackFile = INVALID_HANDLE_VALUE;
208
209 BOOL fInitializedCom = FALSE;
210
211 // initialize
212 hr = WcaInitialize(hInstall, "ComPlusInstallExecuteCommit");
213 ExitOnFailure(hr, "Failed to initialize ComPlusInstallExecuteCommit");
214
215 hr = ::CoInitialize(NULL);
216 ExitOnFailure(hr, "Failed to initialize COM");
217 fInitializedCom = TRUE;
218
219 CpiExecInitialize();
220
221 // get custom action data
222 hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
223 ExitOnFailure(hr, "Failed to get CustomActionData");
224 pwzData = pwzCustomActionData;
225
226 // open rollback file
227 hr = WcaReadStringFromCaData(&pwzData, &pwzRollbackFileName);
228 ExitOnFailure(hr, "Failed to read rollback file name");
229
230 hRollbackFile = ::CreateFileW(pwzRollbackFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
231 if (INVALID_HANDLE_VALUE == hRollbackFile)
232 ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to open rollback file, name: %S", pwzRollbackFileName);
233
234 if (INVALID_SET_FILE_POINTER == ::SetFilePointer(hRollbackFile, 0, NULL, FILE_END))
235 ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to set file pointer");
236
237 // register assemblies
238 hr = CpiConfigureAssemblies(&pwzData, hRollbackFile);
239 ExitOnFailure(hr, "Failed to register assemblies");
240 if (S_FALSE == hr) ExitFunction();
241
242 // create role assignments
243 hr = CpiConfigureRoleAssignments(&pwzData, hRollbackFile);
244 ExitOnFailure(hr, "Failed to create role assignments");
245 if (S_FALSE == hr) ExitFunction();
246
247 // create subscriptions
248 hr = CpiConfigureSubscriptions(&pwzData, hRollbackFile);
249 ExitOnFailure(hr, "Failed to create subscriptions");
250 if (S_FALSE == hr) ExitFunction();
251
252 hr = S_OK;
253
254LExit:
255 // clean up
256 ReleaseStr(pwzCustomActionData);
257
258 if (INVALID_HANDLE_VALUE != hRollbackFile)
259 ::CloseHandle(hRollbackFile);
260
261 // unitialize
262 CpiExecFinalize();
263
264 if (fInitializedCom)
265 ::CoUninitialize();
266
267 er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
268 return WcaFinalize(er);
269}
270
271/********************************************************************
272 ComPlusRollbackInstallExecute - CUSTOM ACTION ENTRY POINT
273
274 Input: deferred CustomActionData - ComPlusRollbackInstallExecute
275********************************************************************/
276extern "C" UINT __stdcall ComPlusRollbackInstallExecute(MSIHANDLE hInstall)
277{
278 HRESULT hr = S_OK;
279 UINT er = ERROR_SUCCESS;
280
281 LPWSTR pwzCustomActionData = NULL;
282 LPWSTR pwzData = NULL;
283 LPWSTR pwzRollbackFileName = NULL;
284
285 HANDLE hRollbackFile = INVALID_HANDLE_VALUE;
286
287 CPI_ROLLBACK_DATA* prdPartitions = NULL;
288 CPI_ROLLBACK_DATA* prdUsersInPartitionRoles = NULL;
289 CPI_ROLLBACK_DATA* prdPartitionUsers = NULL;
290 CPI_ROLLBACK_DATA* prdApplications = NULL;
291 CPI_ROLLBACK_DATA* prdApplicationRoles = NULL;
292 CPI_ROLLBACK_DATA* prdUsersApplicationRoles = NULL;
293 CPI_ROLLBACK_DATA* prdAssemblies = NULL;
294 CPI_ROLLBACK_DATA* prdRoleAssignments = NULL;
295 CPI_ROLLBACK_DATA* prdSubscriptions = NULL;
296
297 BOOL fInitializedCom = FALSE;
298
299 // initialize
300 hr = WcaInitialize(hInstall, "ComPlusRollbackInstallExecute");
301 ExitOnFailure(hr, "Failed to initialize ComPlusRollbackInstallExecute");
302
303 hr = ::CoInitialize(NULL);
304 ExitOnFailure(hr, "Failed to initialize COM");
305 fInitializedCom = TRUE;
306
307 CpiExecInitialize();
308
309 // get custom action data
310 hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
311 ExitOnFailure(hr, "Failed to get CustomActionData");
312 pwzData = pwzCustomActionData;
313
314 // open rollback file
315 hr = WcaReadStringFromCaData(&pwzData, &pwzRollbackFileName);
316 ExitOnFailure(hr, "Failed to read rollback file name");
317
318 hRollbackFile = ::CreateFileW(pwzRollbackFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
319 if (INVALID_HANDLE_VALUE == hRollbackFile)
320 ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to open rollback file, name: %S", pwzRollbackFileName);
321
322 // read rollback data (execute)
323 hr = CpiReadRollbackDataList(hRollbackFile, &prdPartitions);
324 ExitOnFailure(hr, "Failed to read partitions rollback data");
325 hr = CpiReadRollbackDataList(hRollbackFile, &prdUsersInPartitionRoles);
326 ExitOnFailure(hr, "Failed to read users in partition roles rollback data");
327 hr = CpiReadRollbackDataList(hRollbackFile, &prdPartitionUsers);
328 ExitOnFailure(hr, "Failed to read partition users rollback data");
329 hr = CpiReadRollbackDataList(hRollbackFile, &prdApplications);
330 ExitOnFailure(hr, "Failed to read applications rollback data");
331 hr = CpiReadRollbackDataList(hRollbackFile, &prdApplicationRoles);
332 ExitOnFailure(hr, "Failed to read application roles rollback data");
333 hr = CpiReadRollbackDataList(hRollbackFile, &prdUsersApplicationRoles);
334 ExitOnFailure(hr, "Failed to read users in application roles rollback data");
335 hr = CpiReadRollbackDataList(hRollbackFile, &prdAssemblies);
336 ExitOnFailure(hr, "Failed to read assemblies rollback data");
337 hr = CpiReadRollbackDataList(hRollbackFile, &prdRoleAssignments);
338 ExitOnFailure(hr, "Failed to read role assignments rollback data");
339 hr = CpiReadRollbackDataList(hRollbackFile, &prdSubscriptions);
340 ExitOnFailure(hr, "Failed to read subscription rollback data");
341
342 // read rollback data (commit)
343 hr = CpiReadRollbackDataList(hRollbackFile, &prdAssemblies);
344 ExitOnFailure(hr, "Failed to read assemblies rollback data (commit)");
345 hr = CpiReadRollbackDataList(hRollbackFile, &prdRoleAssignments);
346 ExitOnFailure(hr, "Failed to read role assignments rollback data");
347 hr = CpiReadRollbackDataList(hRollbackFile, &prdSubscriptions);
348 ExitOnFailure(hr, "Failed to read subscription rollback data (commit)");
349
350 ::CloseHandle(hRollbackFile);
351 hRollbackFile = INVALID_HANDLE_VALUE;
352
353 // rollback create subscriptions
354 hr = CpiRollbackConfigureSubscriptions(&pwzData, prdSubscriptions);
355 ExitOnFailure(hr, "Failed to rollback create subscriptions");
356
357 // rollback create role assignments
358 hr = CpiRollbackConfigureRoleAssignments(&pwzData, prdRoleAssignments);
359 ExitOnFailure(hr, "Failed to rollback create role assignments");
360
361 // rollback register assemblies
362 hr = CpiRollbackConfigureAssemblies(&pwzData, prdAssemblies);
363 ExitOnFailure(hr, "Failed to rollback register assemblies");
364
365 // rollback create users in application roles
366 hr = CpiRollbackConfigureUsersInApplicationRoles(&pwzData, prdUsersApplicationRoles);
367 ExitOnFailure(hr, "Failed to rollback create users in application roles");
368
369 // rollback create application roles
370 hr = CpiRollbackConfigureApplicationRoles(&pwzData, prdApplicationRoles);
371 ExitOnFailure(hr, "Failed to rollback create application roles");
372
373 // rollback create applications
374 hr = CpiRollbackConfigureApplications(&pwzData, prdApplications);
375 ExitOnFailure(hr, "Failed to rollback create applications");
376
377 // rollback create partition users
378 hr = CpiRollbackConfigurePartitionUsers(&pwzData, prdPartitionUsers);
379 ExitOnFailure(hr, "Failed to rollback create partition users");
380
381 // rollback create users in partition roles
382 hr = CpiRollbackConfigureUsersInPartitionRoles(&pwzData, prdUsersInPartitionRoles);
383 ExitOnFailure(hr, "Failed to rollback create users in partition roles");
384
385 // rollback create partitions
386 hr = CpiRollbackConfigurePartitions(&pwzData, prdPartitions);
387 ExitOnFailure(hr, "Failed to rollback create partitions");
388
389 hr = S_OK;
390
391LExit:
392 // clean up
393 ReleaseStr(pwzCustomActionData);
394 ReleaseStr(pwzRollbackFileName);
395
396 if (INVALID_HANDLE_VALUE != hRollbackFile)
397 ::CloseHandle(hRollbackFile);
398
399 if (prdPartitions)
400 CpiFreeRollbackDataList(prdPartitions);
401 if (prdUsersInPartitionRoles)
402 CpiFreeRollbackDataList(prdUsersInPartitionRoles);
403 if (prdPartitionUsers)
404 CpiFreeRollbackDataList(prdPartitionUsers);
405 if (prdApplications)
406 CpiFreeRollbackDataList(prdApplications);
407 if (prdApplicationRoles)
408 CpiFreeRollbackDataList(prdApplicationRoles);
409 if (prdUsersApplicationRoles)
410 CpiFreeRollbackDataList(prdUsersApplicationRoles);
411 if (prdAssemblies)
412 CpiFreeRollbackDataList(prdAssemblies);
413 if (prdRoleAssignments)
414 CpiFreeRollbackDataList(prdRoleAssignments);
415 if (prdSubscriptions)
416 CpiFreeRollbackDataList(prdSubscriptions);
417
418 // unitialize
419 CpiExecFinalize();
420
421 if (fInitializedCom)
422 ::CoUninitialize();
423
424 er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
425 return WcaFinalize(er);
426}
427
428/********************************************************************
429 ComPlusUninstallExecute - CUSTOM ACTION ENTRY POINT
430
431 Input: deferred CustomActionData - ComPlusUninstallExecute
432********************************************************************/
433extern "C" UINT __stdcall ComPlusUninstallExecute(MSIHANDLE hInstall)
434{
435 HRESULT hr = S_OK;
436 UINT er = ERROR_SUCCESS;
437
438 LPWSTR pwzCustomActionData = NULL;
439 LPWSTR pwzData = NULL;
440 LPWSTR pwzRollbackFileName = NULL;
441
442 HANDLE hRollbackFile = INVALID_HANDLE_VALUE;
443
444 BOOL fInitializedCom = FALSE;
445
446 // initialize
447 hr = WcaInitialize(hInstall, "ComPlusUninstallExecute");
448 ExitOnFailure(hr, "Failed to initialize ComPlusUninstallExecute");
449
450 hr = ::CoInitialize(NULL);
451 ExitOnFailure(hr, "Failed to initialize COM");
452 fInitializedCom = TRUE;
453
454 CpiExecInitialize();
455
456 // get custom action data
457 hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
458 ExitOnFailure(hr, "Failed to get CustomActionData");
459 pwzData = pwzCustomActionData;
460
461 // open rollback file
462 hr = WcaReadStringFromCaData(&pwzData, &pwzRollbackFileName);
463 ExitOnFailure(hr, "Failed to read rollback file name");
464
465 hRollbackFile = ::CreateFileW(pwzRollbackFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
466 if (INVALID_HANDLE_VALUE == hRollbackFile)
467 ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to open rollback file, name: %S", pwzRollbackFileName);
468
469 // delete subscriptions
470 hr = CpiConfigureSubscriptions(&pwzData, hRollbackFile);
471 ExitOnFailure(hr, "Failed to delete subscriptions");
472 if (S_FALSE == hr) ExitFunction();
473
474 // delete role assignments
475 hr = CpiConfigureRoleAssignments(&pwzData, hRollbackFile);
476 ExitOnFailure(hr, "Failed to delete role assignments");
477 if (S_FALSE == hr) ExitFunction();
478
479 // unregister assemblies
480 hr = CpiConfigureAssemblies(&pwzData, hRollbackFile);
481 ExitOnFailure(hr, "Failed to unregister assemblies");
482 if (S_FALSE == hr) ExitFunction();
483
484 // remove users in application roles
485 hr = CpiConfigureUsersInApplicationRoles(&pwzData, hRollbackFile);
486 ExitOnFailure(hr, "Failed to delete users in application roles");
487 if (S_FALSE == hr) ExitFunction();
488
489 // remove application roles
490 hr = CpiConfigureApplicationRoles(&pwzData, hRollbackFile);
491 ExitOnFailure(hr, "Failed to delete application roles");
492 if (S_FALSE == hr) ExitFunction();
493
494 // remove applications
495 hr = CpiConfigureApplications(&pwzData, hRollbackFile);
496 ExitOnFailure(hr, "Failed to remove applications");
497 if (S_FALSE == hr) ExitFunction();
498
499 // remove partition users
500 hr = CpiConfigurePartitionUsers(&pwzData, hRollbackFile);
501 ExitOnFailure(hr, "Failed to remove partition users");
502 if (S_FALSE == hr) ExitFunction();
503
504 // remove users in partition roles
505 hr = CpiConfigureUsersInPartitionRoles(&pwzData, hRollbackFile);
506 ExitOnFailure(hr, "Failed to delete users in partition roles");
507 if (S_FALSE == hr) ExitFunction();
508
509 // remove partitions
510 hr = CpiConfigurePartitions(&pwzData, hRollbackFile);
511 ExitOnFailure(hr, "Failed to delete partitions");
512 if (S_FALSE == hr) ExitFunction();
513
514 hr = S_OK;
515
516LExit:
517 // clean up
518 ReleaseStr(pwzCustomActionData);
519 ReleaseStr(pwzRollbackFileName);
520
521 if (INVALID_HANDLE_VALUE != hRollbackFile)
522 ::CloseHandle(hRollbackFile);
523
524 // unitialize
525 CpiExecFinalize();
526
527 if (fInitializedCom)
528 ::CoUninitialize();
529
530 er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
531 return WcaFinalize(er);
532}
533
534/********************************************************************
535 ComPlusRollbackUninstallExecute - CUSTOM ACTION ENTRY POINT
536
537 Input: deferred CustomActionData - ComPlusRollbackUninstallExecute
538********************************************************************/
539extern "C" UINT __stdcall ComPlusRollbackUninstallExecute(MSIHANDLE hInstall)
540{
541 HRESULT hr = S_OK;
542 UINT er = ERROR_SUCCESS;
543
544 LPWSTR pwzCustomActionData = NULL;
545 LPWSTR pwzData = NULL;
546 LPWSTR pwzRollbackFileName = NULL;
547
548 HANDLE hRollbackFile = INVALID_HANDLE_VALUE;
549
550 CPI_ROLLBACK_DATA* prdPartitions = NULL;
551 CPI_ROLLBACK_DATA* prdUsersInPartitionRoles = NULL;
552 CPI_ROLLBACK_DATA* prdPartitionUsers = NULL;
553 CPI_ROLLBACK_DATA* prdApplications = NULL;
554 CPI_ROLLBACK_DATA* prdApplicationRoles = NULL;
555 CPI_ROLLBACK_DATA* prdUsersApplicationRoles = NULL;
556 CPI_ROLLBACK_DATA* prdAssemblies = NULL;
557 CPI_ROLLBACK_DATA* prdRoleAssignments = NULL;
558 CPI_ROLLBACK_DATA* prdSubscriptions = NULL;
559
560 BOOL fInitializedCom = FALSE;
561
562 // initialize
563 hr = WcaInitialize(hInstall, "ComPlusRollbackUninstallExecute");
564 ExitOnFailure(hr, "Failed to initialize ComPlusRollbackUninstallExecute");
565
566 hr = ::CoInitialize(NULL);
567 ExitOnFailure(hr, "Failed to initialize COM");
568 fInitializedCom = TRUE;
569
570 CpiExecInitialize();
571
572 // get custom action data
573 hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
574 ExitOnFailure(hr, "Failed to get CustomActionData");
575 pwzData = pwzCustomActionData;
576
577 // open rollback file
578 hr = WcaReadStringFromCaData(&pwzData, &pwzRollbackFileName);
579 ExitOnFailure(hr, "Failed to read rollback file name");
580
581 hRollbackFile = ::CreateFileW(pwzRollbackFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
582 if (INVALID_HANDLE_VALUE == hRollbackFile)
583 ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to open rollback file, name: %S", pwzRollbackFileName);
584
585 // read rollback data
586 hr = CpiReadRollbackDataList(hRollbackFile, &prdSubscriptions);
587 ExitOnFailure(hr, "Failed to read subscription rollback data");
588 hr = CpiReadRollbackDataList(hRollbackFile, &prdRoleAssignments);
589 ExitOnFailure(hr, "Failed to read role assignments rollback data");
590 hr = CpiReadRollbackDataList(hRollbackFile, &prdAssemblies);
591 ExitOnFailure(hr, "Failed to read assemblies rollback data");
592 hr = CpiReadRollbackDataList(hRollbackFile, &prdUsersApplicationRoles);
593 ExitOnFailure(hr, "Failed to read users in application roles rollback data");
594 hr = CpiReadRollbackDataList(hRollbackFile, &prdApplicationRoles);
595 ExitOnFailure(hr, "Failed to read application roles rollback data");
596 hr = CpiReadRollbackDataList(hRollbackFile, &prdApplications);
597 ExitOnFailure(hr, "Failed to read applications rollback data");
598 hr = CpiReadRollbackDataList(hRollbackFile, &prdPartitionUsers);
599 ExitOnFailure(hr, "Failed to read partition users rollback data");
600 hr = CpiReadRollbackDataList(hRollbackFile, &prdUsersInPartitionRoles);
601 ExitOnFailure(hr, "Failed to read users in partition roles rollback data");
602 hr = CpiReadRollbackDataList(hRollbackFile, &prdPartitions);
603 ExitOnFailure(hr, "Failed to read partitions rollback data");
604
605 ::CloseHandle(hRollbackFile);
606 hRollbackFile = INVALID_HANDLE_VALUE;
607
608 // rollback remove partitions
609 hr = CpiRollbackConfigurePartitions(&pwzData, prdPartitions);
610 ExitOnFailure(hr, "Failed to rollback delete partitions");
611
612 // rollback remove users in partition roles
613 hr = CpiRollbackConfigureUsersInPartitionRoles(&pwzData, prdUsersInPartitionRoles);
614 ExitOnFailure(hr, "Failed to rollback delete users in partition roles");
615
616 // rollback remove partition users
617 hr = CpiRollbackConfigurePartitionUsers(&pwzData, prdPartitionUsers);
618 ExitOnFailure(hr, "Failed to rollback delete partition users");
619
620 // rollback remove applications
621 hr = CpiRollbackConfigureApplications(&pwzData, prdApplications);
622 ExitOnFailure(hr, "Failed to rollback delete applications");
623
624 // rollback remove application roles
625 hr = CpiRollbackConfigureApplicationRoles(&pwzData, prdApplicationRoles);
626 ExitOnFailure(hr, "Failed to rollback delete application roles");
627
628 // rollback remove users in application roles
629 hr = CpiRollbackConfigureUsersInApplicationRoles(&pwzData, prdUsersApplicationRoles);
630 ExitOnFailure(hr, "Failed to rollback delete users in application roles");
631
632 // rollback unregister assemblies
633 hr = CpiRollbackConfigureAssemblies(&pwzData, prdAssemblies);
634 ExitOnFailure(hr, "Failed to rollback unregister assemblies");
635
636 // rollback delete role assignments
637 hr = CpiRollbackConfigureRoleAssignments(&pwzData, prdAssemblies);
638 ExitOnFailure(hr, "Failed to rollback delete role assignments");
639
640 // rollback delete subscriptions
641 hr = CpiRollbackConfigureSubscriptions(&pwzData, prdSubscriptions);
642 ExitOnFailure(hr, "Failed to rollback delete subscriptions");
643
644 hr = S_OK;
645
646LExit:
647 // clean up
648 ReleaseStr(pwzCustomActionData);
649 ReleaseStr(pwzRollbackFileName);
650
651 if (INVALID_HANDLE_VALUE != hRollbackFile)
652 ::CloseHandle(hRollbackFile);
653
654 if (prdPartitions)
655 CpiFreeRollbackDataList(prdPartitions);
656 if (prdUsersInPartitionRoles)
657 CpiFreeRollbackDataList(prdUsersInPartitionRoles);
658 if (prdPartitionUsers)
659 CpiFreeRollbackDataList(prdPartitionUsers);
660 if (prdApplications)
661 CpiFreeRollbackDataList(prdApplications);
662 if (prdApplicationRoles)
663 CpiFreeRollbackDataList(prdApplicationRoles);
664 if (prdUsersApplicationRoles)
665 CpiFreeRollbackDataList(prdUsersApplicationRoles);
666 if (prdAssemblies)
667 CpiFreeRollbackDataList(prdAssemblies);
668 if (prdRoleAssignments)
669 CpiFreeRollbackDataList(prdRoleAssignments);
670 if (prdSubscriptions)
671 CpiFreeRollbackDataList(prdSubscriptions);
672
673 // unitialize
674 CpiExecFinalize();
675
676 if (fInitializedCom)
677 ::CoUninitialize();
678
679 er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
680 return WcaFinalize(er);
681}
diff --git a/src/ext/ComPlus/ca/cppartexec.cpp b/src/ext/ComPlus/ca/cppartexec.cpp
new file mode 100644
index 00000000..673bdaf9
--- /dev/null
+++ b/src/ext/ComPlus/ca/cppartexec.cpp
@@ -0,0 +1,690 @@
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// private structs
7
8struct CPI_PARTITION_ATTRIBUTES
9{
10 int iActionType;
11 int iActionCost;
12 LPWSTR pwzKey;
13 LPWSTR pwzID;
14 LPWSTR pwzName;
15 CPI_PROPERTY* pPropList;
16};
17
18struct CPI_PARTITION_USER_ATTRIBUTES
19{
20 int iActionType;
21 int iActionCost;
22 LPWSTR pwzKey;
23 LPWSTR pwzAccount;
24 LPWSTR pwzPartID;
25};
26
27
28// prototypes for private helper functions
29
30static HRESULT ReadPartitionAttributes(
31 LPWSTR* ppwzData,
32 CPI_PARTITION_ATTRIBUTES* pAttrs
33 );
34static void FreePartitionAttributes(
35 CPI_PARTITION_ATTRIBUTES* pAttrs
36 );
37static HRESULT CreatePartition(
38 CPI_PARTITION_ATTRIBUTES* pAttrs
39 );
40static HRESULT RemovePartition(
41 CPI_PARTITION_ATTRIBUTES* pAttrs
42 );
43static HRESULT ReadPartitionUserAttributes(
44 LPWSTR* ppwzData,
45 CPI_PARTITION_USER_ATTRIBUTES* pAttrs
46 );
47static void FreePartitionUserAttributes(
48 CPI_PARTITION_USER_ATTRIBUTES* pAttrs
49 );
50static HRESULT CreatePartitionUser(
51 CPI_PARTITION_USER_ATTRIBUTES* pAttrs
52 );
53static HRESULT RemovePartitionUser(
54 CPI_PARTITION_USER_ATTRIBUTES* pAttrs
55 );
56
57
58// function definitions
59
60HRESULT CpiConfigurePartitions(
61 LPWSTR* ppwzData,
62 HANDLE hRollbackFile
63 )
64{
65 HRESULT hr = S_OK;
66
67 CPI_PARTITION_ATTRIBUTES attrs;
68 ::ZeroMemory(&attrs, sizeof(attrs));
69
70 // read action text
71 hr = CpiActionStartMessage(ppwzData, FALSE);
72 ExitOnFailure(hr, "Failed to send action start message");
73
74 // ger partition count
75 int iCnt = 0;
76 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
77 ExitOnFailure(hr, "Failed to read count");
78
79 // write count to rollback file
80 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
81 ExitOnFailure(hr, "Failed to write count to rollback file");
82
83 for (int i = 0; i < iCnt; i++)
84 {
85 // read partition attributes from CustomActionData
86 hr = ReadPartitionAttributes(ppwzData, &attrs);
87 ExitOnFailure(hr, "Failed to read attributes");
88
89 // progress message
90 hr = CpiActionDataMessage(1, attrs.pwzName);
91 ExitOnFailure(hr, "Failed to send progress messages");
92
93 if (S_FALSE == hr)
94 ExitFunction();
95
96 // write key to rollback file
97 hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
98 ExitOnFailure(hr, "Failed to write key to rollback file");
99
100 // action
101 switch (attrs.iActionType)
102 {
103 case atCreate:
104 hr = CreatePartition(&attrs);
105 ExitOnFailure(hr, "Failed to create partition, key: %S", attrs.pwzKey);
106 break;
107 case atRemove:
108 hr = RemovePartition(&attrs);
109 ExitOnFailure(hr, "Failed to remove partition, key: %S", attrs.pwzKey);
110 break;
111 }
112
113 // write completion status to rollback file
114 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
115 ExitOnFailure(hr, "Failed to write completion status to rollback file");
116
117 // progress
118 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
119 ExitOnFailure(hr, "Failed to update progress");
120 }
121
122 hr = S_OK;
123
124LExit:
125 // clean up
126 FreePartitionAttributes(&attrs);
127
128 return hr;
129}
130
131HRESULT CpiRollbackConfigurePartitions(
132 LPWSTR* ppwzData,
133 CPI_ROLLBACK_DATA* pRollbackDataList
134 )
135{
136 HRESULT hr = S_OK;
137
138 int iRollbackStatus;
139
140 CPI_PARTITION_ATTRIBUTES attrs;
141 ::ZeroMemory(&attrs, sizeof(attrs));
142
143 // read action text
144 hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
145 ExitOnFailure(hr, "Failed to send action start message");
146
147 // get count
148 int iCnt = 0;
149 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
150 ExitOnFailure(hr, "Failed to read count");
151
152 for (int i = 0; i < iCnt; i++)
153 {
154 // read partition attributes from CustomActionData
155 hr = ReadPartitionAttributes(ppwzData, &attrs);
156 ExitOnFailure(hr, "Failed to read attributes");
157
158 // rollback status
159 hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
160
161 if (S_FALSE == hr)
162 continue; // not found, nothing to rollback
163
164 // progress message
165 hr = CpiActionDataMessage(1, attrs.pwzName);
166 ExitOnFailure(hr, "Failed to send progress messages");
167
168 if (S_FALSE == hr)
169 ExitFunction();
170
171 // action
172 switch (attrs.iActionType)
173 {
174 case atCreate:
175 hr = CreatePartition(&attrs);
176 if (FAILED(hr))
177 WcaLog(LOGMSG_STANDARD, "Failed to create partition, hr: 0x%x, key: %S", hr, attrs.pwzKey);
178 break;
179 case atRemove:
180 hr = RemovePartition(&attrs);
181 if (FAILED(hr))
182 WcaLog(LOGMSG_STANDARD, "Failed to remove partition, hr: 0x%x, key: %S", hr, attrs.pwzKey);
183 break;
184 }
185
186 // check rollback status
187 if (0 == iRollbackStatus)
188 continue; // operation did not complete, skip progress
189
190 // progress
191 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
192 ExitOnFailure(hr, "Failed to update progress");
193 }
194
195 hr = S_OK;
196
197LExit:
198 // clean up
199 FreePartitionAttributes(&attrs);
200
201 return hr;
202}
203
204HRESULT CpiConfigurePartitionUsers(
205 LPWSTR* ppwzData,
206 HANDLE hRollbackFile
207 )
208{
209 HRESULT hr = S_OK;
210
211 CPI_PARTITION_USER_ATTRIBUTES attrs;
212 ::ZeroMemory(&attrs, sizeof(attrs));
213
214 // read action text
215 hr = CpiActionStartMessage(ppwzData, FALSE);
216 ExitOnFailure(hr, "Failed to send action start message");
217
218 // ger partition count
219 int iCnt = 0;
220 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
221 ExitOnFailure(hr, "Failed to read count");
222
223 // write count to rollback file
224 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
225 ExitOnFailure(hr, "Failed to write count to rollback file");
226
227 for (int i = 0; i < iCnt; i++)
228 {
229 // read partition attributes from CustomActionData
230 hr = ReadPartitionUserAttributes(ppwzData, &attrs);
231 ExitOnFailure(hr, "Failed to read attributes");
232
233 // progress message
234 hr = CpiActionDataMessage(1, attrs.pwzAccount);
235 ExitOnFailure(hr, "Failed to send progress messages");
236
237 if (S_FALSE == hr)
238 ExitFunction();
239
240 // write key to rollback file
241 hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
242 ExitOnFailure(hr, "Failed to write key to rollback file");
243
244 // action
245 switch (attrs.iActionType)
246 {
247 case atCreate:
248 hr = CreatePartitionUser(&attrs);
249 ExitOnFailure(hr, "Failed to create partition user, key: %S", attrs.pwzKey);
250 break;
251 case atRemove:
252 hr = RemovePartitionUser(&attrs);
253 ExitOnFailure(hr, "Failed to remove partition user, key: %S", attrs.pwzKey);
254 break;
255 }
256
257 // write completion status to rollback file
258 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
259 ExitOnFailure(hr, "Failed to write completion status to rollback file");
260
261 // progress
262 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
263 ExitOnFailure(hr, "Failed to update progress");
264 }
265
266 hr = S_OK;
267
268LExit:
269 // clean up
270 FreePartitionUserAttributes(&attrs);
271
272 return hr;
273}
274
275HRESULT CpiRollbackConfigurePartitionUsers(
276 LPWSTR* ppwzData,
277 CPI_ROLLBACK_DATA* pRollbackDataList
278 )
279{
280 HRESULT hr = S_OK;
281
282 int iRollbackStatus;
283
284 CPI_PARTITION_USER_ATTRIBUTES attrs;
285 ::ZeroMemory(&attrs, sizeof(attrs));
286
287 // read action text
288 hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
289 ExitOnFailure(hr, "Failed to send action start message");
290
291 // get count
292 int iCnt = 0;
293 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
294 ExitOnFailure(hr, "Failed to read count");
295
296 for (int i = 0; i < iCnt; i++)
297 {
298 // read partition attributes from CustomActionData
299 hr = ReadPartitionUserAttributes(ppwzData, &attrs);
300 ExitOnFailure(hr, "Failed to read attributes");
301
302 // rollback status
303 hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
304
305 if (S_FALSE == hr)
306 continue; // not found, nothing to rollback
307
308 // progress message
309 hr = CpiActionDataMessage(1, attrs.pwzAccount);
310 ExitOnFailure(hr, "Failed to send progress messages");
311
312 if (S_FALSE == hr)
313 ExitFunction();
314
315 // action
316 switch (attrs.iActionType)
317 {
318 case atCreate:
319 hr = CreatePartitionUser(&attrs);
320 ExitOnFailure(hr, "Failed to create partition user, key: %S", attrs.pwzKey);
321 break;
322 case atRemove:
323 hr = RemovePartitionUser(&attrs);
324 ExitOnFailure(hr, "Failed to remove partition user, key: %S", attrs.pwzKey);
325 break;
326 }
327
328 // check rollback status
329 if (0 == iRollbackStatus)
330 continue; // operation did not complete, skip progress
331
332 // progress
333 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
334 ExitOnFailure(hr, "Failed to update progress");
335 }
336
337 hr = S_OK;
338
339LExit:
340 // clean up
341 FreePartitionUserAttributes(&attrs);
342
343 return hr;
344}
345
346
347// helper function definitions
348
349static HRESULT ReadPartitionAttributes(
350 LPWSTR* ppwzData,
351 CPI_PARTITION_ATTRIBUTES* pAttrs
352 )
353{
354 HRESULT hr = S_OK;
355
356 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
357 ExitOnFailure(hr, "Failed to read action type");
358 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
359 ExitOnFailure(hr, "Failed to read action cost");
360 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
361 ExitOnFailure(hr, "Failed to read key");
362 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzID);
363 ExitOnFailure(hr, "Failed to read id");
364 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzName);
365 ExitOnFailure(hr, "Failed to read name");
366 hr = CpiReadPropertyList(ppwzData, &pAttrs->pPropList);
367 ExitOnFailure(hr, "Failed to read properties");
368
369 hr = S_OK;
370
371LExit:
372 return hr;
373}
374
375static void FreePartitionAttributes(
376 CPI_PARTITION_ATTRIBUTES* pAttrs
377 )
378{
379 ReleaseStr(pAttrs->pwzKey);
380 ReleaseStr(pAttrs->pwzID);
381 ReleaseStr(pAttrs->pwzName);
382
383 if (pAttrs->pPropList)
384 CpiFreePropertyList(pAttrs->pPropList);
385}
386
387static HRESULT CreatePartition(
388 CPI_PARTITION_ATTRIBUTES* pAttrs
389 )
390{
391 HRESULT hr = S_OK;
392
393 ICatalogCollection* piPartColl = NULL;
394 ICatalogObject* piPartObj = NULL;
395
396 long lChanges = 0;
397
398 // log
399 WcaLog(LOGMSG_VERBOSE, "Creating partition, key: %S", pAttrs->pwzKey);
400
401 // get partitions collection
402 hr = CpiExecGetPartitionsCollection(&piPartColl);
403 ExitOnFailure(hr, "Failed to get partitions collection");
404
405 // check if partition exists
406 hr = CpiFindCollectionObjectByStringKey(piPartColl, pAttrs->pwzID, &piPartObj);
407 ExitOnFailure(hr, "Failed to find partition");
408
409 if (S_FALSE == hr)
410 {
411 // create partition
412 hr = CpiAddCollectionObject(piPartColl, &piPartObj);
413 ExitOnFailure(hr, "Failed to add partition to collection");
414
415 hr = CpiPutCollectionObjectValue(piPartObj, L"ID", pAttrs->pwzID);
416 ExitOnFailure(hr, "Failed to set partition id property");
417
418 hr = CpiPutCollectionObjectValue(piPartObj, L"Name", pAttrs->pwzName);
419 ExitOnFailure(hr, "Failed to set partition name property");
420 }
421
422 // properties
423 hr = CpiPutCollectionObjectValues(piPartObj, pAttrs->pPropList);
424 ExitOnFailure(hr, "Failed to write properties");
425
426 // save changes
427 hr = piPartColl->SaveChanges(&lChanges);
428 if (COMADMIN_E_OBJECTERRORS == hr)
429 CpiLogCatalogErrorInfo();
430 ExitOnFailure(hr, "Failed to save changes");
431
432 // log
433 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
434
435 hr = S_OK;
436
437LExit:
438 // clean up
439 ReleaseObject(piPartColl);
440 ReleaseObject(piPartObj);
441
442 return hr;
443}
444
445static HRESULT RemovePartition(
446 CPI_PARTITION_ATTRIBUTES* pAttrs
447 )
448{
449 HRESULT hr = S_OK;
450
451 ICatalogCollection* piPartColl = NULL;
452
453 long lChanges = 0;
454
455 // log
456 WcaLog(LOGMSG_VERBOSE, "Removing partition, key: %S", pAttrs->pwzKey);
457
458 // get partitions collection
459 hr = CpiExecGetPartitionsCollection(&piPartColl);
460 ExitOnFailure(hr, "Failed to get partitions collection");
461
462 // remove
463 hr = CpiRemoveCollectionObject(piPartColl, pAttrs->pwzID, NULL, TRUE);
464 ExitOnFailure(hr, "Failed to remove partition");
465
466 if (S_FALSE == hr)
467 {
468 // partition not found
469 WcaLog(LOGMSG_VERBOSE, "Partition not found, nothing to delete, key: %S", pAttrs->pwzKey);
470 ExitFunction1(hr = S_OK);
471 }
472
473 // save changes
474 hr = piPartColl->SaveChanges(&lChanges);
475 if (COMADMIN_E_OBJECTERRORS == hr)
476 CpiLogCatalogErrorInfo();
477 ExitOnFailure(hr, "Failed to save changes");
478
479 // log
480 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
481
482 hr = S_OK;
483
484LExit:
485 // clean up
486 ReleaseObject(piPartColl);
487
488 return hr;
489}
490
491static HRESULT ReadPartitionUserAttributes(
492 LPWSTR* ppwzData,
493 CPI_PARTITION_USER_ATTRIBUTES* pAttrs
494 )
495{
496 HRESULT hr = S_OK;
497
498 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
499 ExitOnFailure(hr, "Failed to read action type");
500 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
501 ExitOnFailure(hr, "Failed to read action cost");
502 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
503 ExitOnFailure(hr, "Failed to read key");
504 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAccount);
505 ExitOnFailure(hr, "Failed to read account name");
506 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
507 ExitOnFailure(hr, "Failed to read partition id");
508
509 hr = S_OK;
510
511LExit:
512 return hr;
513}
514
515static void FreePartitionUserAttributes(
516 CPI_PARTITION_USER_ATTRIBUTES* pAttrs
517 )
518{
519 ReleaseStr(pAttrs->pwzKey);
520 ReleaseStr(pAttrs->pwzAccount);
521 ReleaseStr(pAttrs->pwzPartID);
522}
523
524static HRESULT CreatePartitionUser(
525 CPI_PARTITION_USER_ATTRIBUTES* pAttrs
526 )
527{
528 HRESULT hr = S_OK;
529 UINT er = ERROR_SUCCESS;
530
531 ICatalogCollection* piUserColl = NULL;
532 ICatalogObject* piUserObj = NULL;
533
534 PSID pSid = NULL;
535 long lChanges = 0;
536
537 // log
538 WcaLog(LOGMSG_VERBOSE, "Setting default partition for user, key: %S", pAttrs->pwzKey);
539
540 // get partition users collection
541 hr = CpiGetPartitionUsersCollection(&piUserColl);
542 ExitOnFailure(hr, "Failed to get partition users collection");
543
544 // get SID for account
545 do {
546 er = ERROR_SUCCESS;
547 hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid);
548 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
549 {
550 WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount);
551 er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
552 switch (er)
553 {
554 case IDABORT:
555 ExitFunction(); // exit with error code from CpiAccountNameToSid()
556 case IDRETRY:
557 break;
558 case IDIGNORE:
559 default:
560 ExitFunction1(hr = S_OK);
561 }
562 }
563 else
564 ExitOnFailure(hr, "Failed to get SID for account");
565 } while (IDRETRY == er);
566
567 // remove any existing entry
568 hr = CpiRemoveUserCollectionObject(piUserColl, pSid);
569 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr)
570 {
571 WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr);
572 hr = S_FALSE;
573 }
574 else
575 ExitOnFailure(hr, "Failed to remove user");
576
577 if (S_OK == hr)
578 WcaLog(LOGMSG_VERBOSE, "Existing default partition for user was removed, key: %S", pAttrs->pwzKey);
579
580 // add partition user
581 hr = CpiAddCollectionObject(piUserColl, &piUserObj);
582 ExitOnFailure(hr, "Failed to add partition to collection");
583
584 hr = CpiPutCollectionObjectValue(piUserObj, L"AccountName", pAttrs->pwzAccount);
585 ExitOnFailure(hr, "Failed to set account name property");
586
587 hr = CpiPutCollectionObjectValue(piUserObj, L"DefaultPartitionID", pAttrs->pwzPartID);
588 ExitOnFailure(hr, "Failed to set default partition id property");
589
590 // save changes
591 hr = piUserColl->SaveChanges(&lChanges);
592 if (COMADMIN_E_OBJECTERRORS == hr)
593 CpiLogCatalogErrorInfo();
594 ExitOnFailure(hr, "Failed to save changes");
595
596 // log
597 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
598
599 hr = S_OK;
600
601LExit:
602 // clean up
603 ReleaseObject(piUserColl);
604 ReleaseObject(piUserObj);
605
606 if (pSid)
607 ::HeapFree(::GetProcessHeap(), 0, pSid);
608
609 return hr;
610}
611
612static HRESULT RemovePartitionUser(
613 CPI_PARTITION_USER_ATTRIBUTES* pAttrs
614 )
615{
616 HRESULT hr = S_OK;
617 UINT er = ERROR_SUCCESS;
618
619 ICatalogCollection* piUserColl = NULL;
620
621 PSID pSid = NULL;
622 long lChanges = 0;
623
624 // log
625 WcaLog(LOGMSG_VERBOSE, "Removing default partition for user, key: %S", pAttrs->pwzKey);
626
627 // get partition users collection
628 hr = CpiGetPartitionUsersCollection(&piUserColl);
629 ExitOnFailure(hr, "Failed to get partition users collection");
630
631 // get SID for account
632 do {
633 er = ERROR_SUCCESS;
634 hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid);
635 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
636 {
637 WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount);
638 er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
639 switch (er)
640 {
641 case IDABORT:
642 ExitFunction(); // exit with error code from CpiAccountNameToSid()
643 case IDRETRY:
644 break;
645 case IDIGNORE:
646 default:
647 ExitFunction1(hr = S_OK);
648 }
649 }
650 else
651 ExitOnFailure(hr, "Failed to get SID for account");
652 } while (IDRETRY == er);
653
654 // remove
655 hr = CpiRemoveUserCollectionObject(piUserColl, pSid);
656 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr)
657 {
658 WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr);
659 hr = S_FALSE;
660 }
661 else
662 ExitOnFailure(hr, "Failed to remove user");
663
664 if (S_FALSE == hr)
665 {
666 // user not found
667 WcaLog(LOGMSG_VERBOSE, "Default partition for user not found, nothing to delete, key: %S", pAttrs->pwzKey);
668 ExitFunction1(hr = S_OK);
669 }
670
671 // save changes
672 hr = piUserColl->SaveChanges(&lChanges);
673 if (COMADMIN_E_OBJECTERRORS == hr)
674 CpiLogCatalogErrorInfo();
675 ExitOnFailure(hr, "Failed to save changes");
676
677 // log
678 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
679
680 hr = S_OK;
681
682LExit:
683 // clean up
684 ReleaseObject(piUserColl);
685
686 if (pSid)
687 ::HeapFree(::GetProcessHeap(), 0, pSid);
688
689 return hr;
690}
diff --git a/src/ext/ComPlus/ca/cppartexec.h b/src/ext/ComPlus/ca/cppartexec.h
new file mode 100644
index 00000000..132a9f5a
--- /dev/null
+++ b/src/ext/ComPlus/ca/cppartexec.h
@@ -0,0 +1,20 @@
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
5HRESULT CpiConfigurePartitions(
6 LPWSTR* ppwzData,
7 HANDLE hRollbackFile
8 );
9HRESULT CpiRollbackConfigurePartitions(
10 LPWSTR* ppwzData,
11 CPI_ROLLBACK_DATA* pRollbackDataList
12 );
13HRESULT CpiConfigurePartitionUsers(
14 LPWSTR* ppwzData,
15 HANDLE hRollbackFile
16 );
17HRESULT CpiRollbackConfigurePartitionUsers(
18 LPWSTR* ppwzData,
19 CPI_ROLLBACK_DATA* pRollbackDataList
20 );
diff --git a/src/ext/ComPlus/ca/cppartroleexec.cpp b/src/ext/ComPlus/ca/cppartroleexec.cpp
new file mode 100644
index 00000000..4a503c79
--- /dev/null
+++ b/src/ext/ComPlus/ca/cppartroleexec.cpp
@@ -0,0 +1,397 @@
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// private structs
7
8struct CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES
9{
10 int iActionType;
11 int iActionCost;
12 LPWSTR pwzKey;
13 LPWSTR pwzRoleName;
14 LPWSTR pwzAccount;
15 LPWSTR pwzPartID;
16};
17
18
19// prototypes for private helper functions
20
21static HRESULT ReadUserInPartitionRoleAttributes(
22 LPWSTR* ppwzData,
23 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
24 );
25static void FreeUserInPartitionRoleAttributes(
26 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
27 );
28static HRESULT CreateUserInPartitionRole(
29 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
30 );
31static HRESULT RemoveUserInPartitionRole(
32 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
33 );
34
35
36// function definitions
37
38HRESULT CpiConfigureUsersInPartitionRoles(
39 LPWSTR* ppwzData,
40 HANDLE hRollbackFile
41 )
42{
43 HRESULT hr = S_OK;
44
45 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES attrs;
46 ::ZeroMemory(&attrs, sizeof(attrs));
47
48 // read action text
49 hr = CpiActionStartMessage(ppwzData, FALSE);
50 ExitOnFailure(hr, "Failed to send action start message");
51
52 // ger count
53 int iCnt = 0;
54 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
55 ExitOnFailure(hr, "Failed to read count");
56
57 // write count to rollback file
58 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
59 ExitOnFailure(hr, "Failed to write count to rollback file");
60
61 for (int i = 0; i < iCnt; i++)
62 {
63 // read attributes from CustomActionData
64 hr = ReadUserInPartitionRoleAttributes(ppwzData, &attrs);
65 ExitOnFailure(hr, "Failed to read attributes");
66
67 // progress message
68 hr = CpiActionDataMessage(1, attrs.pwzRoleName);
69 ExitOnFailure(hr, "Failed to send progress messages");
70
71 if (S_FALSE == hr)
72 ExitFunction();
73
74 // write key to rollback file
75 hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
76 ExitOnFailure(hr, "Failed to write key to rollback file");
77
78 // action
79 switch (attrs.iActionType)
80 {
81 case atCreate:
82 hr = CreateUserInPartitionRole(&attrs);
83 ExitOnFailure(hr, "Failed to add user to partition role, key: %S", attrs.pwzKey);
84 break;
85 case atRemove:
86 hr = RemoveUserInPartitionRole(&attrs);
87 ExitOnFailure(hr, "Failed to remove user from partition role, key: %S", attrs.pwzKey);
88 break;
89 }
90
91 // write completion status to rollback file
92 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
93 ExitOnFailure(hr, "Failed to write completion status to rollback file");
94
95 // progress
96 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
97 ExitOnFailure(hr, "Failed to update progress");
98 }
99
100 hr = S_OK;
101
102LExit:
103 // clean up
104 FreeUserInPartitionRoleAttributes(&attrs);
105
106 return hr;
107}
108
109HRESULT CpiRollbackConfigureUsersInPartitionRoles(
110 LPWSTR* ppwzData,
111 CPI_ROLLBACK_DATA* pRollbackDataList
112 )
113{
114 HRESULT hr = S_OK;
115
116 int iRollbackStatus;
117
118 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES attrs;
119 ::ZeroMemory(&attrs, sizeof(attrs));
120
121 // read action text
122 hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
123 ExitOnFailure(hr, "Failed to send action start message");
124
125 // get count
126 int iCnt = 0;
127 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
128 ExitOnFailure(hr, "Failed to read count");
129
130 for (int i = 0; i < iCnt; i++)
131 {
132 // read attributes from CustomActionData
133 hr = ReadUserInPartitionRoleAttributes(ppwzData, &attrs);
134 ExitOnFailure(hr, "Failed to read attributes");
135
136 // rollback status
137 hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
138
139 if (S_FALSE == hr)
140 continue; // not found, nothing to rollback
141
142 // progress message
143 hr = CpiActionDataMessage(1, attrs.pwzRoleName);
144 ExitOnFailure(hr, "Failed to send progress messages");
145
146 if (S_FALSE == hr)
147 ExitFunction();
148
149 // action
150 switch (attrs.iActionType)
151 {
152 case atCreate:
153 hr = CreateUserInPartitionRole(&attrs);
154 if (FAILED(hr))
155 WcaLog(LOGMSG_STANDARD, "Failed to add user to partition role, hr: 0x%x, key: %S", hr, attrs.pwzKey);
156 break;
157 case atRemove:
158 hr = RemoveUserInPartitionRole(&attrs);
159 if (FAILED(hr))
160 WcaLog(LOGMSG_STANDARD, "Failed to remove user from partition role, hr: 0x%x, key: %S", hr, attrs.pwzKey);
161 break;
162 }
163
164 // check rollback status
165 if (0 == iRollbackStatus)
166 continue; // operation did not complete, skip progress
167
168 // progress
169 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
170 ExitOnFailure(hr, "Failed to update progress");
171 }
172
173 hr = S_OK;
174
175LExit:
176 // clean up
177 FreeUserInPartitionRoleAttributes(&attrs);
178
179 return hr;
180}
181
182
183// helper function definitions
184
185static HRESULT ReadUserInPartitionRoleAttributes(
186 LPWSTR* ppwzData,
187 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
188 )
189{
190 HRESULT hr = S_OK;
191
192 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
193 ExitOnFailure(hr, "Failed to read action type");
194 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
195 ExitOnFailure(hr, "Failed to read action cost");
196 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
197 ExitOnFailure(hr, "Failed to read key");
198 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzRoleName);
199 ExitOnFailure(hr, "Failed to read role name");
200 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAccount);
201 ExitOnFailure(hr, "Failed to read account name");
202 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
203 ExitOnFailure(hr, "Failed to read partition id");
204
205 hr = S_OK;
206
207LExit:
208 return hr;
209}
210
211static void FreeUserInPartitionRoleAttributes(
212 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
213 )
214{
215 ReleaseStr(pAttrs->pwzKey);
216 ReleaseStr(pAttrs->pwzRoleName);
217 ReleaseStr(pAttrs->pwzAccount);
218 ReleaseStr(pAttrs->pwzPartID);
219}
220
221static HRESULT CreateUserInPartitionRole(
222 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
223 )
224{
225 HRESULT hr = S_OK;
226 UINT er = ERROR_SUCCESS;
227
228 ICatalogCollection* piUsrInRoleColl = NULL;
229 ICatalogObject* piUsrInRoleObj = NULL;
230
231 PSID pSid = NULL;
232 long lChanges = 0;
233
234 // log
235 WcaLog(LOGMSG_VERBOSE, "Adding user to partition role, key: %S", pAttrs->pwzKey);
236
237 // get users in partition role collection
238 hr = CpiGetUsersInPartitionRoleCollection(pAttrs->pwzPartID, pAttrs->pwzRoleName, &piUsrInRoleColl);
239 if (S_FALSE == hr)
240 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
241 ExitOnFailure(hr, "Failed to get users in partition role collection");
242
243 // get SID for account
244 do {
245 er = ERROR_SUCCESS;
246 hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid);
247 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
248 {
249 WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount);
250 er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
251 switch (er)
252 {
253 case IDABORT:
254 ExitFunction(); // exit with error code from CpiAccountNameToSid()
255 case IDRETRY:
256 break;
257 case IDIGNORE:
258 default:
259 ExitFunction1(hr = S_OK);
260 }
261 }
262 else
263 ExitOnFailure(hr, "Failed to get SID for account");
264 } while (IDRETRY == er);
265
266 // find any existing entry
267 hr = CpiFindUserCollectionObject(piUsrInRoleColl, pSid, NULL);
268 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr)
269 WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr);
270 else
271 ExitOnFailure(hr, "Failed to find user in partition role");
272
273 if (S_OK == hr)
274 {
275 WcaLog(LOGMSG_VERBOSE, "User already assigned to partition role, key: %S", pAttrs->pwzKey);
276 ExitFunction(); // exit with hr = S_OK
277 }
278
279 // convert SID back to account name
280 hr = CpiSidToAccountName(pSid, &pAttrs->pwzAccount);
281 ExitOnFailure(hr, "Failed to convert SID to account name");
282
283 // add user
284 hr = CpiAddCollectionObject(piUsrInRoleColl, &piUsrInRoleObj);
285 ExitOnFailure(hr, "Failed to add user in role to collection");
286
287 hr = CpiPutCollectionObjectValue(piUsrInRoleObj, L"User", pAttrs->pwzAccount);
288 ExitOnFailure(hr, "Failed to set role name property");
289
290 // save changes
291 hr = piUsrInRoleColl->SaveChanges(&lChanges);
292 if (COMADMIN_E_OBJECTERRORS == hr)
293 CpiLogCatalogErrorInfo();
294 ExitOnFailure(hr, "Failed to save changes");
295
296 // log
297 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
298
299 hr = S_OK;
300
301LExit:
302 // clean up
303 ReleaseObject(piUsrInRoleColl);
304 ReleaseObject(piUsrInRoleObj);
305
306 if (pSid)
307 ::HeapFree(::GetProcessHeap(), 0, pSid);
308
309 return hr;
310}
311
312static HRESULT RemoveUserInPartitionRole(
313 CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
314 )
315{
316 HRESULT hr = S_OK;
317 UINT er = ERROR_SUCCESS;
318
319 ICatalogCollection* piUsrInRoleColl = NULL;
320
321 PSID pSid = NULL;
322 long lChanges = 0;
323
324 // log
325 WcaLog(LOGMSG_VERBOSE, "Removing user from partition role, key: %S", pAttrs->pwzKey);
326
327 // get users in partition role collection
328 hr = CpiGetUsersInPartitionRoleCollection(pAttrs->pwzPartID, pAttrs->pwzRoleName, &piUsrInRoleColl);
329 ExitOnFailure(hr, "Failed to get users in partition role collection");
330
331 if (S_FALSE == hr)
332 {
333 // users in role collection not found
334 WcaLog(LOGMSG_VERBOSE, "Unable to retrieve users in partition role collection, nothing to delete, key: %S", pAttrs->pwzKey);
335 ExitFunction1(hr = S_OK);
336 }
337
338 // get SID for account
339 do {
340 er = ERROR_SUCCESS;
341 hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid);
342 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
343 {
344 WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount);
345 er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
346 switch (er)
347 {
348 case IDABORT:
349 ExitFunction(); // exit with error code from CpiAccountNameToSid()
350 case IDRETRY:
351 break;
352 case IDIGNORE:
353 default:
354 ExitFunction1(hr = S_OK);
355 }
356 }
357 else
358 ExitOnFailure(hr, "Failed to get SID for account");
359 } while (IDRETRY == er);
360
361 // remove
362 hr = CpiRemoveUserCollectionObject(piUsrInRoleColl, pSid);
363 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr)
364 {
365 WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr);
366 hr = S_FALSE;
367 }
368 else
369 ExitOnFailure(hr, "Failed to remove user");
370
371 if (S_FALSE == hr)
372 {
373 // role not found
374 WcaLog(LOGMSG_VERBOSE, "User not found for partition role, nothing to delete, key: %S", pAttrs->pwzKey);
375 ExitFunction1(hr = S_OK);
376 }
377
378 // save changes
379 hr = piUsrInRoleColl->SaveChanges(&lChanges);
380 if (COMADMIN_E_OBJECTERRORS == hr)
381 CpiLogCatalogErrorInfo();
382 ExitOnFailure(hr, "Failed to save changes");
383
384 // log
385 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
386
387 hr = S_OK;
388
389LExit:
390 // clean up
391 ReleaseObject(piUsrInRoleColl);
392
393 if (pSid)
394 ::HeapFree(::GetProcessHeap(), 0, pSid);
395
396 return hr;
397}
diff --git a/src/ext/ComPlus/ca/cppartroleexec.h b/src/ext/ComPlus/ca/cppartroleexec.h
new file mode 100644
index 00000000..0ec47dad
--- /dev/null
+++ b/src/ext/ComPlus/ca/cppartroleexec.h
@@ -0,0 +1,12 @@
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
5HRESULT CpiConfigureUsersInPartitionRoles(
6 LPWSTR* ppwzData,
7 HANDLE hRollbackFile
8 );
9HRESULT CpiRollbackConfigureUsersInPartitionRoles(
10 LPWSTR* ppwzData,
11 CPI_ROLLBACK_DATA* pRollbackDataList
12 );
diff --git a/src/ext/ComPlus/ca/cppartrolesched.cpp b/src/ext/ComPlus/ca/cppartrolesched.cpp
new file mode 100644
index 00000000..a988f8e3
--- /dev/null
+++ b/src/ext/ComPlus/ca/cppartrolesched.cpp
@@ -0,0 +1,421 @@
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// sql queries
7
8LPCWSTR vcsPartitionRoleQuery =
9 L"SELECT `PartitionRole`, `Partition_`, `Component_`, `Name` FROM `ComPlusPartitionRole`";
10enum ePartitionRoleQuery { prqPartitionRole = 1, prqPartition, prqComponent, prqName };
11
12LPCWSTR vcsUserInPartitionRoleQuery =
13 L"SELECT `UserInPartitionRole`, `PartitionRole_`, `ComPlusUserInPartitionRole`.`Component_`, `Domain`, `Name` FROM `ComPlusUserInPartitionRole`, `User` WHERE `User_` = `User`";
14LPCWSTR vcsGroupInPartitionRoleQuery =
15 L"SELECT `GroupInPartitionRole`, `PartitionRole_`, `ComPlusGroupInPartitionRole`.`Component_`, `Domain`, `Name` FROM `ComPlusGroupInPartitionRole`, `Group` WHERE `Group_` = `Group`";
16enum eTrusteeInPartitionRoleQuery { tiprqUserInPartitionRole = 1, tiprqPartitionRole, tiprqComponent, tiprqDomain, tiprqName };
17
18
19// prototypes for private helper functions
20
21static HRESULT TrusteesInPartitionRolesRead(
22 LPCWSTR pwzQuery,
23 CPI_PARTITION_ROLE_LIST* pPartRoleList,
24 CPI_USER_IN_PARTITION_ROLE_LIST* pUsrInPartRoleList
25 );
26static void FreePartitionRole(
27 CPI_PARTITION_ROLE* pItm
28 );
29static void FreeUserInPartitionRole(
30 CPI_USER_IN_PARTITION_ROLE* pItm
31 );
32static HRESULT AddUserInPartitionRoleToActionData(
33 CPI_USER_IN_PARTITION_ROLE* pItm,
34 int iActionType,
35 int iActionCost,
36 LPWSTR* ppwzActionData
37 );
38
39
40// function definitions
41
42void CpiPartitionRoleListFree(
43 CPI_PARTITION_ROLE_LIST* pList
44 )
45{
46 CPI_PARTITION_ROLE* pItm = pList->pFirst;
47
48 while (pItm)
49 {
50 CPI_PARTITION_ROLE* pDelete = pItm;
51 pItm = pItm->pNext;
52 FreePartitionRole(pDelete);
53 }
54}
55
56HRESULT CpiPartitionRolesRead(
57 CPI_PARTITION_LIST* pPartList,
58 CPI_PARTITION_ROLE_LIST* pPartRoleList
59 )
60{
61 HRESULT hr = S_OK;
62 PMSIHANDLE hView, hRec;
63 CPI_PARTITION_ROLE* pItm = NULL;
64 LPWSTR pwzData = NULL;
65
66 // loop through all application roles
67 hr = WcaOpenExecuteView(vcsPartitionRoleQuery, &hView);
68 ExitOnFailure(hr, "Failed to execute view on ComPlusPartitionRole table");
69
70 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
71 {
72 // create entry
73 pItm = (CPI_PARTITION_ROLE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_PARTITION_ROLE));
74 if (!pItm)
75 ExitFunction1(hr = E_OUTOFMEMORY);
76
77 // get key
78 hr = WcaGetRecordString(hRec, prqPartitionRole, &pwzData);
79 ExitOnFailure(hr, "Failed to get key");
80 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
81
82 // get partition
83 hr = WcaGetRecordString(hRec, prqPartition, &pwzData);
84 ExitOnFailure(hr, "Failed to get application");
85
86 hr = CpiPartitionFindByKey(pPartList, pwzData, &pItm->pPartition);
87 if (S_FALSE == hr)
88 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
89 ExitOnFailure(hr, "Failed to find partition, key: %S", pwzData);
90
91 // get name
92 hr = WcaGetRecordFormattedString(hRec, prqName, &pwzData);
93 ExitOnFailure(hr, "Failed to get name");
94 StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData);
95
96 // add entry
97 if (pPartRoleList->pFirst)
98 pItm->pNext = pPartRoleList->pFirst;
99 pPartRoleList->pFirst = pItm;
100 pItm = NULL;
101 }
102
103 if (E_NOMOREITEMS == hr)
104 hr = S_OK;
105
106LExit:
107 // clean up
108 if (pItm)
109 FreePartitionRole(pItm);
110
111 ReleaseStr(pwzData);
112
113 return hr;
114}
115
116HRESULT CpiPartitionRoleFindByKey(
117 CPI_PARTITION_ROLE_LIST* pList,
118 LPCWSTR pwzKey,
119 CPI_PARTITION_ROLE** ppPartRole
120 )
121{
122 for (CPI_PARTITION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
123 {
124 if (0 == lstrcmpW(pItm->wzKey, pwzKey))
125 {
126 *ppPartRole = pItm;
127 return S_OK;
128 }
129 }
130
131 return E_FAIL;
132}
133
134void CpiUserInPartitionRoleListFree(
135 CPI_USER_IN_PARTITION_ROLE_LIST* pList
136 )
137{
138 CPI_USER_IN_PARTITION_ROLE* pItm = pList->pFirst;
139
140 while (pItm)
141 {
142 CPI_USER_IN_PARTITION_ROLE* pDelete = pItm;
143 pItm = pItm->pNext;
144 FreeUserInPartitionRole(pDelete);
145 }
146}
147
148HRESULT CpiUsersInPartitionRolesRead(
149 CPI_PARTITION_ROLE_LIST* pPartRoleList,
150 CPI_USER_IN_PARTITION_ROLE_LIST* pUsrInPartRoleList
151 )
152{
153 HRESULT hr = S_OK;
154
155 // read users in partition roles
156 if (CpiTableExists(cptComPlusUserInPartitionRole))
157 {
158 hr = TrusteesInPartitionRolesRead(vcsUserInPartitionRoleQuery, pPartRoleList, pUsrInPartRoleList);
159 ExitOnFailure(hr, "Failed to read users in partition roles");
160 }
161
162 // read groups in partition roles
163 if (CpiTableExists(cptComPlusGroupInPartitionRole))
164 {
165 hr = TrusteesInPartitionRolesRead(vcsGroupInPartitionRoleQuery, pPartRoleList, pUsrInPartRoleList);
166 ExitOnFailure(hr, "Failed to read groups in partition roles");
167 }
168
169 hr = S_OK;
170
171LExit:
172 return hr;
173}
174
175HRESULT CpiUsersInPartitionRolesInstall(
176 CPI_USER_IN_PARTITION_ROLE_LIST* pList,
177 int iRunMode,
178 LPWSTR* ppwzActionData,
179 int* piProgress
180 )
181{
182 HRESULT hr = S_OK;
183
184 int iActionType;
185
186 // add action text
187 hr = CpiAddActionTextToActionData(L"AddUsersToComPlusPartitionRoles", ppwzActionData);
188 ExitOnFailure(hr, "Failed to add action text to custom action data");
189
190 // add count to action data
191 hr = WcaWriteIntegerToCaData(pList->iInstallCount, ppwzActionData);
192 ExitOnFailure(hr, "Failed to add count to custom action data");
193
194 // add roles to custom action data
195 for (CPI_USER_IN_PARTITION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
196 {
197 // roles that are being installed only
198 if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction))
199 continue;
200
201 // action type
202 if (rmRollback == iRunMode)
203 {
204 if (CpiIsInstalled(pItm->isInstalled))
205 iActionType = atNoOp;
206 else
207 iActionType = atRemove;
208 }
209 else
210 iActionType = atCreate;
211
212 // add to action data
213 hr = AddUserInPartitionRoleToActionData(pItm, iActionType, COST_USER_IN_APPLICATION_ROLE_CREATE, ppwzActionData);
214 ExitOnFailure(hr, "Failed to add user in partition role to custom action data, key: %S", pItm->wzKey);
215 }
216
217 // add progress tics
218 if (piProgress)
219 *piProgress += COST_USER_IN_APPLICATION_ROLE_CREATE * pList->iInstallCount;
220
221 hr = S_OK;
222
223LExit:
224 return hr;
225}
226
227HRESULT CpiUsersInPartitionRolesUninstall(
228 CPI_USER_IN_PARTITION_ROLE_LIST* pList,
229 int iRunMode,
230 LPWSTR* ppwzActionData,
231 int* piProgress
232 )
233{
234 HRESULT hr = S_OK;
235
236 int iActionType;
237
238 // add action text
239 hr = CpiAddActionTextToActionData(L"RemoveUsersFromComPlusPartRoles", ppwzActionData);
240 ExitOnFailure(hr, "Failed to add action text to custom action data");
241
242 // add count to action data
243 hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData);
244 ExitOnFailure(hr, "Failed to add count to custom action data");
245
246 // add roles to custom action data
247 for (CPI_USER_IN_PARTITION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
248 {
249 // roles that are being uninstalled only
250 if (!WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
251 continue;
252
253 // action type
254 if (rmRollback == iRunMode)
255 iActionType = atCreate;
256 else
257 iActionType = atRemove;
258
259 // add to action data
260 hr = AddUserInPartitionRoleToActionData(pItm, iActionType, COST_USER_IN_APPLICATION_ROLE_DELETE, ppwzActionData);
261 ExitOnFailure(hr, "Failed to add user in partition role to custom action data, key: %S", pItm->wzKey);
262 }
263
264 // add progress tics
265 if (piProgress)
266 *piProgress += COST_USER_IN_APPLICATION_ROLE_DELETE * pList->iUninstallCount;
267
268 hr = S_OK;
269
270LExit:
271 return hr;
272}
273
274
275// helper function definitions
276
277static HRESULT TrusteesInPartitionRolesRead(
278 LPCWSTR pwzQuery,
279 CPI_PARTITION_ROLE_LIST* pPartRoleList,
280 CPI_USER_IN_PARTITION_ROLE_LIST* pUsrInPartRoleList
281 )
282{
283 HRESULT hr = S_OK;
284 UINT er = ERROR_SUCCESS;
285
286 PMSIHANDLE hView, hRec;
287
288 CPI_USER_IN_PARTITION_ROLE* pItm = NULL;
289 LPWSTR pwzData = NULL;
290 LPWSTR pwzDomain = NULL;
291 LPWSTR pwzName = NULL;
292 BOOL fMatchingArchitecture = FALSE;
293
294 // loop through all application roles
295 hr = WcaOpenExecuteView(pwzQuery, &hView);
296 ExitOnFailure(hr, "Failed to execute view on table");
297
298 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
299 {
300 // get component
301 hr = WcaGetRecordString(hRec, tiprqComponent, &pwzData);
302 ExitOnFailure(hr, "Failed to get component");
303
304 // check if the component is our processor architecture
305 hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture);
306 ExitOnFailure(hr, "Failed to get component architecture.");
307
308 if (!fMatchingArchitecture)
309 {
310 continue; // not the same architecture, ignore
311 }
312
313 // create entry
314 pItm = (CPI_USER_IN_PARTITION_ROLE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_USER_IN_PARTITION_ROLE));
315 if (!pItm)
316 ExitFunction1(hr = E_OUTOFMEMORY);
317
318 // get component install state
319 er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction);
320 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
321
322 // get key
323 hr = WcaGetRecordString(hRec, tiprqUserInPartitionRole, &pwzData);
324 ExitOnFailure(hr, "Failed to get key");
325 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
326
327 // get partition role
328 hr = WcaGetRecordString(hRec, tiprqPartitionRole, &pwzData);
329 ExitOnFailure(hr, "Failed to get partition role");
330
331 hr = CpiPartitionRoleFindByKey(pPartRoleList, pwzData, &pItm->pPartitionRole);
332 ExitOnFailure(hr, "Failed to find partition role, key: %S", pwzData);
333
334 // get user domain
335 hr = WcaGetRecordFormattedString(hRec, tiprqDomain, &pwzDomain);
336 ExitOnFailure(hr, "Failed to get domain");
337
338 // get user name
339 hr = WcaGetRecordFormattedString(hRec, tiprqName, &pwzName);
340 ExitOnFailure(hr, "Failed to get name");
341
342 // build account name
343 hr = CpiBuildAccountName(pwzDomain, pwzName, &pItm->pwzAccount);
344 ExitOnFailure(hr, "Failed to build account name");
345
346 // increment counters
347 if (WcaIsInstalling(pItm->isInstalled, pItm->isAction))
348 pUsrInPartRoleList->iInstallCount++;
349 if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
350 pUsrInPartRoleList->iUninstallCount++;
351
352 // add entry
353 if (pUsrInPartRoleList->pFirst)
354 pItm->pNext = pUsrInPartRoleList->pFirst;
355 pUsrInPartRoleList->pFirst = pItm;
356 pItm = NULL;
357 }
358
359 if (E_NOMOREITEMS == hr)
360 hr = S_OK;
361
362LExit:
363 // clean up
364 if (pItm)
365 FreeUserInPartitionRole(pItm);
366
367 ReleaseStr(pwzData);
368 ReleaseStr(pwzDomain);
369 ReleaseStr(pwzName);
370
371 return hr;
372}
373
374static void FreePartitionRole(
375 CPI_PARTITION_ROLE* pItm
376 )
377{
378 ::HeapFree(::GetProcessHeap(), 0, pItm);
379}
380
381static void FreeUserInPartitionRole(
382 CPI_USER_IN_PARTITION_ROLE* pItm
383 )
384{
385 ReleaseStr(pItm->pwzAccount);
386
387 ::HeapFree(::GetProcessHeap(), 0, pItm);
388}
389
390static HRESULT AddUserInPartitionRoleToActionData(
391 CPI_USER_IN_PARTITION_ROLE* pItm,
392 int iActionType,
393 int iActionCost,
394 LPWSTR* ppwzActionData
395 )
396{
397 HRESULT hr = S_OK;
398
399 // add action information to custom action data
400 hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
401 ExitOnFailure(hr, "Failed to add action type to custom action data");
402 hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
403 ExitOnFailure(hr, "Failed to add action cost to custom action data");
404
405 // add application role information to custom action data
406 hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
407 ExitOnFailure(hr, "Failed to add key to custom action data");
408 hr = WcaWriteStringToCaData(pItm->pPartitionRole->wzName, ppwzActionData);
409 ExitOnFailure(hr, "Failed to add role name to custom action data");
410 hr = WcaWriteStringToCaData(pItm->pwzAccount, ppwzActionData);
411 ExitOnFailure(hr, "Failed to add user account to custom action data");
412
413 // add partition information to custom action data
414 hr = WcaWriteStringToCaData(pItm->pPartitionRole->pPartition->wzID, ppwzActionData);
415 ExitOnFailure(hr, "Failed to add partition id to custom action data");
416
417 hr = S_OK;
418
419LExit:
420 return hr;
421}
diff --git a/src/ext/ComPlus/ca/cppartrolesched.h b/src/ext/ComPlus/ca/cppartrolesched.h
new file mode 100644
index 00000000..ff1275d9
--- /dev/null
+++ b/src/ext/ComPlus/ca/cppartrolesched.h
@@ -0,0 +1,76 @@
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
5struct CPI_PARTITION_ROLE
6{
7 WCHAR wzKey[MAX_DARWIN_KEY + 1];
8 WCHAR wzName[MAX_DARWIN_COLUMN + 1];
9
10 CPI_PARTITION* pPartition;
11
12 ICatalogCollection* piUsersColl;
13
14 CPI_PARTITION_ROLE* pNext;
15};
16
17struct CPI_PARTITION_ROLE_LIST
18{
19 CPI_PARTITION_ROLE* pFirst;
20};
21
22struct CPI_USER_IN_PARTITION_ROLE
23{
24 WCHAR wzKey[MAX_DARWIN_KEY + 1];
25 LPWSTR pwzAccount;
26
27 INSTALLSTATE isInstalled, isAction;
28
29 CPI_PARTITION_ROLE* pPartitionRole;
30
31 CPI_USER_IN_PARTITION_ROLE* pNext;
32};
33
34struct CPI_USER_IN_PARTITION_ROLE_LIST
35{
36 CPI_USER_IN_PARTITION_ROLE* pFirst;
37
38 int iInstallCount;
39 int iUninstallCount;
40};
41
42
43// function prototypes
44
45void CpiPartitionRoleListFree(
46 CPI_PARTITION_ROLE_LIST* pList
47 );
48HRESULT CpiPartitionRolesRead(
49 CPI_PARTITION_LIST* pPartList,
50 CPI_PARTITION_ROLE_LIST* pPartRoleList
51 );
52HRESULT CpiPartitionRoleFindByKey(
53 CPI_PARTITION_ROLE_LIST* pList,
54 LPCWSTR pwzKey,
55 CPI_PARTITION_ROLE** ppPartRole
56 );
57
58void CpiUserInPartitionRoleListFree(
59 CPI_USER_IN_PARTITION_ROLE_LIST* pList
60 );
61HRESULT CpiUsersInPartitionRolesRead(
62 CPI_PARTITION_ROLE_LIST* pPartRoleList,
63 CPI_USER_IN_PARTITION_ROLE_LIST* pUsrInPartRoleList
64 );
65HRESULT CpiUsersInPartitionRolesInstall(
66 CPI_USER_IN_PARTITION_ROLE_LIST* pList,
67 int iRunMode,
68 LPWSTR* ppwzActionData,
69 int* piProgress
70 );
71HRESULT CpiUsersInPartitionRolesUninstall(
72 CPI_USER_IN_PARTITION_ROLE_LIST* pList,
73 int iRunMode,
74 LPWSTR* ppwzActionData,
75 int* piProgress
76 );
diff --git a/src/ext/ComPlus/ca/cppartsched.cpp b/src/ext/ComPlus/ca/cppartsched.cpp
new file mode 100644
index 00000000..7cd98791
--- /dev/null
+++ b/src/ext/ComPlus/ca/cppartsched.cpp
@@ -0,0 +1,912 @@
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// sql queries
7
8LPCWSTR vcsPartitionQuery =
9 L"SELECT `Partition`, `Component_`, `Id`, `Name` FROM `ComPlusPartition`";
10enum ePartitionQuery { pqPartition = 1, pqComponent, pqID, pqName };
11
12LPCWSTR vcsPartitionPropertyQuery =
13 L"SELECT `Name`, `Value` FROM `ComPlusPartitionProperty` WHERE `Partition_` = ?";
14
15LPCWSTR vcsPartitionUserQuery =
16 L"SELECT `PartitionUser`, `Partition_`, `ComPlusPartitionUser`.`Component_`, `Domain`, `Name` FROM `ComPlusPartitionUser`, `User` WHERE `User_` = `User`";
17enum ePartitionUserQuery { puqPartitionUser = 1, puqPartition, puqComponent, puqDomain, puqName };
18
19
20// property definitions
21
22CPI_PROPERTY_DEFINITION pdlPartitionProperties[] =
23{
24 {L"Changeable", cpptBoolean, 502},
25 {L"Deleteable", cpptBoolean, 502},
26 {L"Description", cpptString, 502},
27 {NULL, cpptNone, 0}
28};
29
30
31// prototypes for private helper functions
32
33static void FreePartition(
34 CPI_PARTITION* pItm
35 );
36static void FreePartitionUser(
37 CPI_PARTITION_USER* pItm
38 );
39static HRESULT AddPartitionToActionData(
40 CPI_PARTITION* pItm,
41 int iActionType,
42 int iActionCost,
43 LPWSTR* ppwzActionData
44 );
45static HRESULT AddPartitionUserToActionData(
46 CPI_PARTITION_USER* pItm,
47 int iActionType,
48 int iActionCost,
49 LPWSTR* ppwzActionData
50 );
51
52
53// function definitions
54
55void CpiPartitionListFree(
56 CPI_PARTITION_LIST* pList
57 )
58{
59 CPI_PARTITION* pItm = pList->pFirst;
60
61 while (pItm)
62 {
63 CPI_PARTITION* pDelete = pItm;
64 pItm = pItm->pNext;
65 FreePartition(pDelete);
66 }
67}
68
69HRESULT CpiPartitionsRead(
70 CPI_PARTITION_LIST* pPartList
71 )
72{
73 HRESULT hr = S_OK;
74 UINT er = ERROR_SUCCESS;
75
76 PMSIHANDLE hView, hRec;
77
78 CPI_PARTITION* pItm = NULL;
79 LPWSTR pwzData = NULL;
80 BOOL fMatchingArchitecture = FALSE;
81
82 // loop through all partitions
83 hr = WcaOpenExecuteView(vcsPartitionQuery, &hView);
84 ExitOnFailure(hr, "Failed to execute view on ComPlusPartition table");
85
86 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
87 {
88 // get component
89 hr = WcaGetRecordString(hRec, pqComponent, &pwzData);
90 ExitOnFailure(hr, "Failed to get component");
91
92 // check if the component is our processor architecture
93 if (pwzData && *pwzData)
94 {
95 hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture);
96 ExitOnFailure(hr, "Failed to get component architecture.");
97
98 if (!fMatchingArchitecture)
99 {
100 continue; // not the same architecture, ignore
101 }
102 }
103
104 // create entry
105 pItm = (CPI_PARTITION*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_PARTITION));
106 if (!pItm)
107 ExitFunction1(hr = E_OUTOFMEMORY);
108
109 // get component install state
110 if (pwzData && *pwzData)
111 {
112 pItm->fHasComponent = TRUE;
113
114 er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction);
115 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
116 }
117
118 // get key
119 hr = WcaGetRecordString(hRec, pqPartition, &pwzData);
120 ExitOnFailure(hr, "Failed to get key");
121 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
122
123 // get id
124 hr = WcaGetRecordFormattedString(hRec, pqID, &pwzData);
125 ExitOnFailure(hr, "Failed to get id");
126
127 if (pwzData && *pwzData)
128 {
129 hr = PcaGuidToRegFormat(pwzData, pItm->wzID, countof(pItm->wzID));
130 ExitOnFailure(hr, "Failed to parse id guid value, key: %S, value: '%S'", pItm->wzKey, pwzData);
131 }
132
133 // get name
134 hr = WcaGetRecordFormattedString(hRec, pqName, &pwzData);
135 ExitOnFailure(hr, "Failed to get name");
136 StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData);
137
138 // if partition is a locater, either an id or a name must be provided
139 if (!pItm->fHasComponent && !*pItm->wzID && !*pItm->wzName)
140 ExitOnFailure(hr = E_FAIL, "A partition locater must have either an id or a name associated, key: %S", pItm->wzKey);
141
142 // if partition is not a locater, an name must be provided
143 if (pItm->fHasComponent && !*pItm->wzName)
144 ExitOnFailure(hr = E_FAIL, "A partition must have a name associated, key: %S", pItm->wzKey);
145
146 // get properties
147 if (CpiTableExists(cptComPlusPartitionProperty) && pItm->fHasComponent)
148 {
149 hr = CpiPropertiesRead(vcsPartitionPropertyQuery, pItm->wzKey, pdlPartitionProperties, &pItm->pProperties, &pItm->iPropertyCount);
150 ExitOnFailure(hr, "Failed to get properties");
151 }
152
153 // increment counters
154 if (pItm->fHasComponent && WcaIsInstalling(pItm->isInstalled, pItm->isAction))
155 pPartList->iInstallCount++;
156 if (pItm->fHasComponent && WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
157 pPartList->iUninstallCount++;
158
159 // add entry
160 if (pPartList->pFirst)
161 pItm->pNext = pPartList->pFirst;
162 pPartList->pFirst = pItm;
163 pItm = NULL;
164 }
165
166 if (E_NOMOREITEMS == hr)
167 hr = S_OK;
168
169LExit:
170 // clean up
171 if (pItm)
172 FreePartition(pItm);
173
174 ReleaseStr(pwzData);
175
176 return hr;
177}
178
179HRESULT CpiPartitionsVerifyInstall(
180 CPI_PARTITION_LIST* pList
181 )
182{
183 HRESULT hr = S_OK;
184 UINT er = ERROR_SUCCESS;
185
186 ICatalogCollection* piPartColl = NULL;
187 ICatalogObject* piPartObj = NULL;
188
189 for (CPI_PARTITION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
190 {
191 // referenced locaters or partitions that are being installed
192 if (!pItm->fReferencedForInstall && !(pItm->fHasComponent && WcaIsInstalling(pItm->isInstalled, pItm->isAction)))
193 continue;
194
195 // if the partition is referensed and is not a locater, it must be installed
196 if (pItm->fReferencedForInstall && pItm->fHasComponent && !CpiWillBeInstalled(pItm->isInstalled, pItm->isAction))
197 MessageExitOnFailure(hr = E_FAIL, msierrComPlusPartitionDependency, "A partition is used by another entity being installed, but is not installed itself, key: %S", pItm->wzKey);
198
199 // get partitions collection
200 if (!piPartColl)
201 {
202 hr = CpiSchedGetPartitionsCollection(&piPartColl);
203 ExitOnFailure(hr, "Failed to get partitions collection");
204 }
205
206 // partition is supposed to exist
207 if (!pItm->fHasComponent || CpiIsInstalled(pItm->isInstalled))
208 {
209 // get collection object for partition
210 hr = CpiFindCollectionObject(piPartColl, pItm->wzID, *pItm->wzID ? NULL : pItm->wzName, &piPartObj);
211 ExitOnFailure(hr, "Failed to find collection object for partition");
212
213 // if the partition was found
214 if (S_OK == hr)
215 {
216 // if we don't have an id, copy id from object
217 if (!*pItm->wzID)
218 {
219 hr = CpiGetKeyForObject(piPartObj, pItm->wzID, countof(pItm->wzID));
220 ExitOnFailure(hr, "Failed to get id");
221 }
222 }
223
224 // if the partition was not found
225 else
226 {
227 // if the application is a locater, this is an error
228 if (!pItm->fHasComponent)
229 MessageExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), msierrComPlusPartitionNotFound, "A partition required by this installation was not found, key: %S", pItm->wzKey);
230
231 // create a new id if one is missing
232 if (!*pItm->wzID)
233 {
234 hr = CpiCreateId(pItm->wzID, countof(pItm->wzID));
235 ExitOnFailure(hr, "Failed to create id");
236 }
237 }
238 }
239
240 // partition is supposed to be created
241 else
242 {
243 // check for conflicts
244 do {
245 if (*pItm->wzID)
246 {
247 // find partitions with conflicting id
248 hr = CpiFindCollectionObject(piPartColl, pItm->wzID, NULL, &piPartObj);
249 ExitOnFailure(hr, "Failed to find collection object for partition");
250
251 if (S_FALSE == hr)
252 {
253 // find partitions with conflicting name
254 hr = CpiFindCollectionObject(piPartColl, NULL, pItm->wzName, &piPartObj);
255 ExitOnFailure(hr, "Failed to find collection object for partition");
256
257 if (S_OK == hr)
258 // "A partition with a conflictiong name exists. retry cancel"
259 er = WcaErrorMessage(msierrComPlusPartitionNameConflict, hr, INSTALLMESSAGE_ERROR | MB_RETRYCANCEL, 0);
260 else
261 break; // no conflicting entry found, break loop
262 }
263 else
264 // "A partition with a conflicting id exists. abort retry ignore"
265 er = WcaErrorMessage(msierrComPlusPartitionIdConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
266 }
267 else
268 {
269 // find partitions with conflicting name
270 hr = CpiFindCollectionObject(piPartColl, NULL, pItm->wzName, &piPartObj);
271 ExitOnFailure(hr, "Failed to find collection object for partition");
272
273 if (S_OK == hr)
274 // "A partition with a conflictiong name exists. abort retry ignore"
275 er = WcaErrorMessage(msierrComPlusPartitionNameConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
276 else
277 break; // no conflicting entry found, break loop
278 }
279
280 switch (er)
281 {
282 case IDCANCEL:
283 case IDABORT:
284 ExitOnFailure(hr = E_FAIL, "A partition with a conflictiong name or id exists, key: %S", pItm->wzKey);
285 break;
286 case IDRETRY:
287 break;
288 case IDIGNORE:
289 default:
290 // if we don't have an id, copy id from object
291 if (!*pItm->wzID)
292 {
293 hr = CpiGetKeyForObject(piPartObj, pItm->wzID, countof(pItm->wzID));
294 ExitOnFailure(hr, "Failed to get id");
295 }
296 hr = S_FALSE; // indicate that this is not a conflict
297 }
298 } while (S_OK == hr); // hr = S_FALSE if we don't have any conflicts
299
300 // create a new id if one is missing
301 if (!*pItm->wzID)
302 {
303 hr = CpiCreateId(pItm->wzID, countof(pItm->wzID));
304 ExitOnFailure(hr, "Failed to create id");
305 }
306 }
307
308 // clean up
309 ReleaseNullObject(piPartObj);
310 }
311
312 hr = S_OK;
313
314LExit:
315 // clean up
316 ReleaseObject(piPartColl);
317 ReleaseObject(piPartObj);
318
319 return hr;
320}
321
322HRESULT CpiPartitionsVerifyUninstall(
323 CPI_PARTITION_LIST* pList
324 )
325{
326 HRESULT hr = S_OK;
327 ICatalogCollection* piPartColl = NULL;
328 ICatalogObject* piPartObj = NULL;
329
330 for (CPI_PARTITION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
331 {
332 // referenced locaters or partitions that are being uninstalled
333 if (!pItm->fReferencedForUninstall && !(pItm->fHasComponent && WcaIsUninstalling(pItm->isInstalled, pItm->isAction)))
334 continue;
335
336 // get partitions collection
337 if (!piPartColl)
338 {
339 hr = CpiSchedGetPartitionsCollection(&piPartColl);
340 ExitOnFailure(hr, "Failed to get partitions collection");
341 }
342
343 // get collection object for partition
344 hr = CpiFindCollectionObject(piPartColl, pItm->wzID, *pItm->wzID ? NULL : pItm->wzName, &piPartObj);
345 ExitOnFailure(hr, "Failed to find collection object for partition");
346
347 // if the partition was found
348 if (S_OK == hr)
349 {
350 // if we don't have an id, copy id from object
351 if (!*pItm->wzID)
352 {
353 hr = CpiGetKeyForObject(piPartObj, pItm->wzID, countof(pItm->wzID));
354 ExitOnFailure(hr, "Failed to get id");
355 }
356 }
357
358 // if the partition was not found
359 else
360 {
361 pItm->fObjectNotFound = TRUE;
362 if (pItm->fHasComponent)
363 pList->iUninstallCount--; // elements with the fObjectNotFound flag set will not be scheduled for uninstall
364 }
365
366 // clean up
367 ReleaseNullObject(piPartObj);
368 }
369
370 hr = S_OK;
371
372LExit:
373 // clean up
374 ReleaseObject(piPartColl);
375 ReleaseObject(piPartObj);
376
377 return hr;
378}
379
380void CpiPartitionAddReferenceInstall(
381 CPI_PARTITION* pItm
382 )
383{
384 pItm->fReferencedForInstall = TRUE;
385}
386
387void CpiPartitionAddReferenceUninstall(
388 CPI_PARTITION* pItm
389 )
390{
391 pItm->fReferencedForUninstall = TRUE;
392}
393
394HRESULT CpiPartitionsInstall(
395 CPI_PARTITION_LIST* pList,
396 int iRunMode,
397 LPWSTR* ppwzActionData,
398 int* piProgress
399 )
400{
401 HRESULT hr = S_OK;
402
403 int iActionType;
404
405 // add action text
406 hr = CpiAddActionTextToActionData(L"CreateComPlusPartitions", ppwzActionData);
407 ExitOnFailure(hr, "Failed to add action text to custom action data");
408
409 // add partition count to action data
410 hr = WcaWriteIntegerToCaData(pList->iInstallCount, ppwzActionData);
411 ExitOnFailure(hr, "Failed to add count to custom action data");
412
413 // add applications to custom action data
414 for (CPI_PARTITION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
415 {
416 // partitions that are being installed only
417 if (!pItm->fHasComponent || !WcaIsInstalling(pItm->isInstalled, pItm->isAction))
418 continue;
419
420 // action type
421 if (rmRollback == iRunMode)
422 {
423 if (CpiIsInstalled(pItm->isInstalled))
424 iActionType = atNoOp;
425 else
426 iActionType = atRemove;
427 }
428 else
429 iActionType = atCreate;
430
431 // add to action data
432 hr = AddPartitionToActionData(pItm, iActionType, COST_PARTITION_CREATE, ppwzActionData);
433 ExitOnFailure(hr, "Failed to add partition to custom action data, key: %S", pItm->wzKey);
434 }
435
436 // add progress tics
437 if (piProgress)
438 *piProgress += COST_PARTITION_CREATE * pList->iInstallCount;
439
440 hr = S_OK;
441
442LExit:
443 return hr;
444}
445
446HRESULT CpiPartitionsUninstall(
447 CPI_PARTITION_LIST* pList,
448 int iRunMode,
449 LPWSTR* ppwzActionData,
450 int* piProgress
451 )
452{
453 HRESULT hr = S_OK;
454
455 int iActionType;
456
457 // add action text
458 hr = CpiAddActionTextToActionData(L"RemoveComPlusPartitions", ppwzActionData);
459 ExitOnFailure(hr, "Failed to add action text to custom action data");
460
461 // add partition count to action data
462 hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData);
463 ExitOnFailure(hr, "Failed to add count to custom action data");
464
465 // add partitions to custom action data
466 for (CPI_PARTITION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
467 {
468 // partitions that are being uninstalled only
469 if (!pItm->fHasComponent || pItm->fObjectNotFound || !WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
470 continue;
471
472 // action type
473 if (rmRollback == iRunMode)
474 iActionType = atCreate;
475 else
476 iActionType = atRemove;
477
478 // add to action data
479 hr = AddPartitionToActionData(pItm, iActionType, COST_PARTITION_DELETE, ppwzActionData);
480 ExitOnFailure(hr, "Failed to add partition to custom action data, key:", pItm->wzKey);
481 }
482
483 // add progress tics
484 if (piProgress)
485 *piProgress += COST_PARTITION_DELETE * pList->iUninstallCount;
486
487 hr = S_OK;
488
489LExit:
490 return hr;
491}
492
493HRESULT CpiPartitionFindByKey(
494 CPI_PARTITION_LIST* pList,
495 LPCWSTR wzKey,
496 CPI_PARTITION** ppItm
497 )
498{
499 for (CPI_PARTITION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
500 {
501 if (0 == lstrcmpW(pItm->wzKey, wzKey))
502 {
503 *ppItm = pItm;
504 return S_OK;
505 }
506 }
507
508 return S_FALSE;
509}
510
511HRESULT CpiGetApplicationsCollForPartition(
512 CPI_PARTITION* pPart,
513 ICatalogCollection** ppiAppColl
514 )
515{
516 HRESULT hr = S_OK;
517
518 ICatalogCollection* piPartColl = NULL;
519 ICatalogObject* piPartObj = NULL;
520
521 // if a previous attempt to locate the collection object failed
522 if (pPart->fObjectNotFound)
523 ExitFunction1(hr = S_FALSE);
524
525 // get applications collection
526 if (!pPart->piApplicationsColl)
527 {
528 // get partitions collection from catalog
529 hr = CpiSchedGetPartitionsCollection(&piPartColl);
530 ExitOnFailure(hr, "Failed to get partitions collection");
531
532 // find application object
533 hr = CpiFindCollectionObject(piPartColl, pPart->wzID, *pPart->wzID ? NULL : pPart->wzName, &piPartObj);
534 ExitOnFailure(hr, "Failed to find partition object");
535
536 if (S_FALSE == hr)
537 {
538 pPart->fObjectNotFound = TRUE;
539 ExitFunction(); // exit with hr = S_FALSE
540 }
541
542 // get roles collection
543 hr = CpiSchedGetCatalogCollection(piPartColl, piPartObj, L"Applications", &pPart->piApplicationsColl);
544 ExitOnFailure(hr, "Failed to get applications collection");
545 }
546
547 // return value
548 *ppiAppColl = pPart->piApplicationsColl;
549 (*ppiAppColl)->AddRef();
550
551 hr = S_OK;
552
553LExit:
554 // clean up
555 ReleaseObject(piPartColl);
556 ReleaseObject(piPartObj);
557
558 return hr;
559}
560
561HRESULT CpiGetRolesCollForPartition(
562 CPI_PARTITION* pPart,
563 ICatalogCollection** ppiRolesColl
564 )
565{
566 HRESULT hr = S_OK;
567
568 ICatalogCollection* piPartColl = NULL;
569 ICatalogObject* piPartObj = NULL;
570
571 // if a previous attempt to locate the collection object failed
572 if (pPart->fObjectNotFound)
573 ExitFunction1(hr = S_FALSE);
574
575 // get applications collection
576 if (!pPart->piRolesColl)
577 {
578 // get partitions collection from catalog
579 hr = CpiSchedGetPartitionsCollection(&piPartColl);
580 ExitOnFailure(hr, "Failed to get partitions collection");
581
582 // find partition object
583 hr = CpiFindCollectionObject(piPartColl, pPart->wzID, *pPart->wzID ? NULL : pPart->wzName, &piPartObj);
584 ExitOnFailure(hr, "Failed to find partition object");
585
586 if (S_FALSE == hr)
587 ExitFunction(); // exit with hr = S_FALSE
588
589 // get roles collection
590 hr = CpiSchedGetCatalogCollection(piPartColl, piPartObj, L"RolesForPartition", &pPart->piRolesColl);
591 ExitOnFailure(hr, "Failed to get roles collection");
592 }
593
594 // return value
595 *ppiRolesColl = pPart->piRolesColl;
596 (*ppiRolesColl)->AddRef();
597
598 hr = S_OK;
599
600LExit:
601 // clean up
602 ReleaseObject(piPartColl);
603 ReleaseObject(piPartObj);
604
605 return hr;
606}
607
608void CpiPartitionUserListFree(
609 CPI_PARTITION_USER_LIST* pList
610 )
611{
612 CPI_PARTITION_USER* pItm = pList->pFirst;
613
614 while (pItm)
615 {
616 CPI_PARTITION_USER* pDelete = pItm;
617 pItm = pItm->pNext;
618 FreePartitionUser(pDelete);
619 }
620}
621
622HRESULT CpiPartitionUsersRead(
623 CPI_PARTITION_LIST* pPartList,
624 CPI_PARTITION_USER_LIST* pPartUsrList
625 )
626{
627 HRESULT hr = S_OK;
628 UINT er = ERROR_SUCCESS;
629
630 PMSIHANDLE hView, hRec;
631
632 CPI_PARTITION_USER* pItm = NULL;
633 LPWSTR pwzData = NULL;
634 LPWSTR pwzDomain = NULL;
635 LPWSTR pwzName = NULL;
636 BOOL fMatchingArchitecture = FALSE;
637
638 // loop through all partition users
639 hr = WcaOpenExecuteView(vcsPartitionUserQuery, &hView);
640 ExitOnFailure(hr, "Failed to execute view on ComPlusPartitionUser table");
641
642 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
643 {
644 // get component
645 hr = WcaGetRecordString(hRec, puqComponent, &pwzData);
646 ExitOnFailure(hr, "Failed to get component");
647
648 // check if the component is our processor architecture
649 hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture);
650 ExitOnFailure(hr, "Failed to get component architecture.");
651
652 if (!fMatchingArchitecture)
653 {
654 continue; // not the same architecture, ignore
655 }
656
657 // create entry
658 pItm = (CPI_PARTITION_USER*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_PARTITION_USER));
659 if (!pItm)
660 ExitFunction1(hr = E_OUTOFMEMORY);
661
662 // get component install state
663 er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction);
664 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
665
666 // get key
667 hr = WcaGetRecordString(hRec, puqPartitionUser, &pwzData);
668 ExitOnFailure(hr, "Failed to get key");
669 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
670
671 // get partition
672 hr = WcaGetRecordString(hRec, puqPartition, &pwzData);
673 ExitOnFailure(hr, "Failed to get partition");
674
675 hr = CpiPartitionFindByKey(pPartList, pwzData, &pItm->pPartition);
676 if (S_FALSE == hr)
677 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
678 ExitOnFailure(hr, "Failed to find partition, key: %S", pwzData);
679
680 // get user domain
681 hr = WcaGetRecordFormattedString(hRec, puqDomain, &pwzDomain);
682 ExitOnFailure(hr, "Failed to get user domain");
683
684 // get user name
685 hr = WcaGetRecordFormattedString(hRec, puqName, &pwzName);
686 ExitOnFailure(hr, "Failed to get user name");
687
688 // build account name
689 hr = CpiBuildAccountName(pwzDomain, pwzName, &pItm->pwzAccount);
690 ExitOnFailure(hr, "Failed to build account name");
691
692 // set references & increment counters
693 if (WcaIsInstalling(pItm->isInstalled, pItm->isAction))
694 {
695 pItm->pPartition->fReferencedForInstall = TRUE;
696 pPartUsrList->iInstallCount++;
697 }
698 if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
699 {
700 pItm->pPartition->fReferencedForUninstall = TRUE;
701 pPartUsrList->iUninstallCount++;
702 }
703
704 // add entry
705 if (pPartUsrList->pFirst)
706 pItm->pNext = pPartUsrList->pFirst;
707 pPartUsrList->pFirst = pItm;
708 pItm = NULL;
709 }
710
711 if (E_NOMOREITEMS == hr)
712 hr = S_OK;
713
714LExit:
715 // clean up
716 if (pItm)
717 FreePartitionUser(pItm);
718
719 ReleaseStr(pwzData);
720 ReleaseStr(pwzDomain);
721 ReleaseStr(pwzName);
722
723 return hr;
724}
725
726HRESULT CpiPartitionUsersInstall(
727 CPI_PARTITION_USER_LIST* pList,
728 int iRunMode,
729 LPWSTR* ppwzActionData,
730 int* piProgress
731 )
732{
733 HRESULT hr = S_OK;
734
735 int iActionType;
736
737 // add action text
738 hr = CpiAddActionTextToActionData(L"AddComPlusPartitionUsers", ppwzActionData);
739 ExitOnFailure(hr, "Failed to add action text to custom action data");
740
741 // add partition count to action data
742 hr = WcaWriteIntegerToCaData(pList->iInstallCount, ppwzActionData);
743 ExitOnFailure(hr, "Failed to add count to custom action data");
744
745 // add applications to custom action data
746 for (CPI_PARTITION_USER* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
747 {
748 // partitions that are being installed only
749 if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction))
750 continue;
751
752 // action type
753 if (rmRollback == iRunMode)
754 {
755 if (CpiIsInstalled(pItm->isInstalled))
756 iActionType = atNoOp;
757 else
758 iActionType = atRemove;
759 }
760 else
761 iActionType = atCreate;
762
763 // add to action data
764 hr = AddPartitionUserToActionData(pItm, iActionType, COST_PARTITION_USER_CREATE, ppwzActionData);
765 ExitOnFailure(hr, "Failed to add partition user to custom action data, key: %S", pItm->wzKey);
766 }
767
768 // add progress tics
769 if (piProgress)
770 *piProgress += COST_PARTITION_USER_CREATE * pList->iInstallCount;
771
772 hr = S_OK;
773
774LExit:
775 return hr;
776}
777
778HRESULT CpiPartitionUsersUninstall(
779 CPI_PARTITION_USER_LIST* pList,
780 int iRunMode,
781 LPWSTR* ppwzActionData,
782 int* piProgress
783 )
784{
785 HRESULT hr = S_OK;
786
787 int iActionType;
788
789 // add action text
790 hr = CpiAddActionTextToActionData(L"RemoveComPlusPartitionUsers", ppwzActionData);
791 ExitOnFailure(hr, "Failed to add action text to custom action data");
792
793 // add partition count to action data
794 hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData);
795 ExitOnFailure(hr, "Failed to add count to custom action data");
796
797 // add partitions to custom action data
798 for (CPI_PARTITION_USER* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
799 {
800 // partitions that are being uninstalled only
801 if (!WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
802 continue;
803
804 // action type
805 if (rmRollback == iRunMode)
806 iActionType = atCreate;
807 else
808 iActionType = atRemove;
809
810 // add to action data
811 hr = AddPartitionUserToActionData(pItm, iActionType, COST_PARTITION_USER_DELETE, ppwzActionData);
812 ExitOnFailure(hr, "Failed to add partition user to custom action data, key: %S", pItm->wzKey);
813 }
814
815 // add progress tics
816 if (piProgress)
817 *piProgress += COST_PARTITION_USER_DELETE * pList->iUninstallCount;
818
819 hr = S_OK;
820
821LExit:
822 return hr;
823}
824
825
826// helper function definitions
827
828static void FreePartition(
829 CPI_PARTITION* pItm
830 )
831{
832 if (pItm->pProperties)
833 CpiPropertiesFreeList(pItm->pProperties);
834
835 ReleaseObject(pItm->piApplicationsColl);
836 ReleaseObject(pItm->piRolesColl);
837
838 ::HeapFree(::GetProcessHeap(), 0, pItm);
839}
840
841static void FreePartitionUser(
842 CPI_PARTITION_USER* pItm
843 )
844{
845 ReleaseStr(pItm->pwzAccount);
846
847 ::HeapFree(::GetProcessHeap(), 0, pItm);
848}
849
850static HRESULT AddPartitionToActionData(
851 CPI_PARTITION* pItm,
852 int iActionType,
853 int iActionCost,
854 LPWSTR* ppwzActionData
855 )
856{
857 HRESULT hr = S_OK;
858
859 // add action information to custom action data
860 hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
861 ExitOnFailure(hr, "Failed to add action type to custom action data");
862 hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
863 ExitOnFailure(hr, "Failed to add action cost to custom action data");
864
865 // add partition information to custom action data
866 hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
867 ExitOnFailure(hr, "Failed to add partition key to custom action data");
868 hr = WcaWriteStringToCaData(pItm->wzID, ppwzActionData);
869 ExitOnFailure(hr, "Failed to add partition id to custom action data");
870 hr = WcaWriteStringToCaData(pItm->wzName, ppwzActionData);
871 ExitOnFailure(hr, "Failed to add partition name to custom action data");
872
873 // add properties to custom action data
874 hr = CpiAddPropertiesToActionData(atCreate == iActionType ? pItm->iPropertyCount : 0, pItm->pProperties, ppwzActionData);
875 ExitOnFailure(hr, "Failed to add properties to custom action data");
876
877 hr = S_OK;
878
879LExit:
880 return hr;
881}
882
883static HRESULT AddPartitionUserToActionData(
884 CPI_PARTITION_USER* pItm,
885 int iActionType,
886 int iActionCost,
887 LPWSTR* ppwzActionData
888 )
889{
890 HRESULT hr = S_OK;
891
892 // add action information to custom action data
893 hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
894 ExitOnFailure(hr, "Failed to add action type to custom action data");
895 hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
896 ExitOnFailure(hr, "Failed to add action cost to custom action data");
897
898 // add partition user information to custom action data
899 hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
900 ExitOnFailure(hr, "Failed to add partition user key to custom action data");
901 hr = WcaWriteStringToCaData(pItm->pwzAccount, ppwzActionData);
902 ExitOnFailure(hr, "Failed to add user account to custom action data");
903
904 // add partition information to custom action data
905 hr = WcaWriteStringToCaData(atCreate == iActionType ? pItm->pPartition->wzID : L"", ppwzActionData);
906 ExitOnFailure(hr, "Failed to add partition id to custom action data");
907
908 hr = S_OK;
909
910LExit:
911 return hr;
912}
diff --git a/src/ext/ComPlus/ca/cppartsched.h b/src/ext/ComPlus/ca/cppartsched.h
new file mode 100644
index 00000000..55085912
--- /dev/null
+++ b/src/ext/ComPlus/ca/cppartsched.h
@@ -0,0 +1,125 @@
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
5struct CPI_PARTITION
6{
7 WCHAR wzKey[MAX_DARWIN_KEY + 1];
8 WCHAR wzID[CPI_MAX_GUID + 1];
9 WCHAR wzName[MAX_DARWIN_COLUMN + 1];
10
11 int iPropertyCount;
12 CPI_PROPERTY* pProperties;
13
14 BOOL fHasComponent;
15 BOOL fReferencedForInstall;
16 BOOL fReferencedForUninstall;
17 BOOL fObjectNotFound;
18
19 INSTALLSTATE isInstalled, isAction;
20
21 ICatalogCollection* piApplicationsColl;
22 ICatalogCollection* piRolesColl;
23
24 CPI_PARTITION* pNext;
25};
26
27struct CPI_PARTITION_LIST
28{
29 CPI_PARTITION* pFirst;
30
31 int iInstallCount;
32 int iUninstallCount;
33};
34
35struct CPI_PARTITION_USER
36{
37 WCHAR wzKey[MAX_DARWIN_KEY + 1];
38 LPWSTR pwzAccount;
39
40 BOOL fNoFind;
41
42 INSTALLSTATE isInstalled, isAction;
43
44 CPI_PARTITION* pPartition;
45
46 CPI_PARTITION_USER* pNext;
47};
48
49struct CPI_PARTITION_USER_LIST
50{
51 CPI_PARTITION_USER* pFirst;
52
53 int iInstallCount;
54 int iUninstallCount;
55};
56
57
58// function prototypes
59
60void CpiPartitionListFree(
61 CPI_PARTITION_LIST* pList
62 );
63HRESULT CpiPartitionsRead(
64 CPI_PARTITION_LIST* pPartList
65 );
66HRESULT CpiPartitionsVerifyInstall(
67 CPI_PARTITION_LIST* pList
68 );
69HRESULT CpiPartitionsVerifyUninstall(
70 CPI_PARTITION_LIST* pList
71 );
72void CpiPartitionAddReferenceInstall(
73 CPI_PARTITION* pItm
74 );
75void CpiPartitionAddReferenceUninstall(
76 CPI_PARTITION* pItm
77 );
78HRESULT CpiPartitionsInstall(
79 CPI_PARTITION_LIST* pList,
80 int iRunMode,
81 LPWSTR* ppwzActionData,
82 int* piProgress
83 );
84HRESULT CpiPartitionsUninstall(
85 CPI_PARTITION_LIST* pList,
86 int iRunMode,
87 LPWSTR* ppwzActionData,
88 int* piProgress
89 );
90HRESULT CpiPartitionFindByKey(
91 CPI_PARTITION_LIST* pList,
92 LPCWSTR wzKey,
93 CPI_PARTITION** ppItm
94 );
95HRESULT CpiGetApplicationsCollForPartition(
96 CPI_PARTITION* pPart,
97 ICatalogCollection** ppiAppColl
98 );
99HRESULT CpiGetPartitionUsersCollection(
100 CPI_PARTITION* pPart,
101 ICatalogCollection** ppiPartUsrColl
102 );
103HRESULT CpiGetRolesCollForPartition(
104 CPI_PARTITION* pPart,
105 ICatalogCollection** ppiRolesColl
106 );
107void CpiPartitionUserListFree(
108 CPI_PARTITION_USER_LIST* pList
109 );
110HRESULT CpiPartitionUsersRead(
111 CPI_PARTITION_LIST* pPartList,
112 CPI_PARTITION_USER_LIST* pPartUsrList
113 );
114HRESULT CpiPartitionUsersInstall(
115 CPI_PARTITION_USER_LIST* pList,
116 int iRunMode,
117 LPWSTR* ppwzActionData,
118 int* piProgress
119 );
120HRESULT CpiPartitionUsersUninstall(
121 CPI_PARTITION_USER_LIST* pList,
122 int iRunMode,
123 LPWSTR* ppwzActionData,
124 int* piProgress
125 );
diff --git a/src/ext/ComPlus/ca/cpsched.cpp b/src/ext/ComPlus/ca/cpsched.cpp
new file mode 100644
index 00000000..ebc547ae
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpsched.cpp
@@ -0,0 +1,566 @@
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#ifdef _WIN64
7#define CP_COMPLUSROLLBACKINSTALLPREPARE L"ComPlusRollbackInstallPrepare_64"
8#define CP_COMPLUSINSTALLPREPARE L"ComPlusInstallPrepare_64"
9#define CP_COMPLUSROLLBACKINSTALLEXECUTE L"ComPlusRollbackInstallExecute_64"
10#define CP_COMPLUSINSTALLEXECUTE L"ComPlusInstallExecute_64"
11#define CP_COMPLUSINSTALLEXECUTECOMMIT L"ComPlusInstallExecuteCommit_64"
12#define CP_COMPLUSINSTALLCOMMIT L"ComPlusInstallCommit_64"
13#define CP_COMPLUSROLLBACKINSTALLPREPARE L"ComPlusRollbackInstallPrepare_64"
14#define CP_COMPLUSINSTALLPREPARE L"ComPlusInstallPrepare_64"
15#define CP_COMPLUSROLLBACKUNINSTALLEXECUTE L"ComPlusRollbackUninstallExecute_64"
16#define CP_COMPLUSUNINSTALLEXECUTE L"ComPlusUninstallExecute_64"
17#define CP_COMPLUSINSTALLCOMMIT L"ComPlusInstallCommit_64"
18#else
19#define CP_COMPLUSROLLBACKINSTALLPREPARE L"ComPlusRollbackInstallPrepare"
20#define CP_COMPLUSINSTALLPREPARE L"ComPlusInstallPrepare"
21#define CP_COMPLUSROLLBACKINSTALLEXECUTE L"ComPlusRollbackInstallExecute"
22#define CP_COMPLUSINSTALLEXECUTE L"ComPlusInstallExecute"
23#define CP_COMPLUSINSTALLEXECUTECOMMIT L"ComPlusInstallExecuteCommit"
24#define CP_COMPLUSINSTALLCOMMIT L"ComPlusInstallCommit"
25#define CP_COMPLUSROLLBACKINSTALLPREPARE L"ComPlusRollbackInstallPrepare"
26#define CP_COMPLUSINSTALLPREPARE L"ComPlusInstallPrepare"
27#define CP_COMPLUSROLLBACKUNINSTALLEXECUTE L"ComPlusRollbackUninstallExecute"
28#define CP_COMPLUSUNINSTALLEXECUTE L"ComPlusUninstallExecute"
29#define CP_COMPLUSINSTALLCOMMIT L"ComPlusInstallCommit"
30#endif
31
32/********************************************************************
33 ConfigureComPlusInstall - CUSTOM ACTION ENTRY POINT for installing COM+ components
34
35********************************************************************/
36extern "C" UINT __stdcall ConfigureComPlusInstall(MSIHANDLE hInstall)
37{
38 HRESULT hr = S_OK;
39 UINT er = ERROR_SUCCESS;
40
41 BOOL fInitializedCom = FALSE;
42
43 ICOMAdminCatalog* piCatalog = NULL;
44
45 CPI_PARTITION_LIST partList;
46 CPI_PARTITION_ROLE_LIST partRoleList;
47 CPI_USER_IN_PARTITION_ROLE_LIST usrInPartRoleList;
48 CPI_PARTITION_USER_LIST partUsrList;
49 CPI_APPLICATION_LIST appList;
50 CPI_APPLICATION_ROLE_LIST appRoleList;
51 CPI_USER_IN_APPLICATION_ROLE_LIST usrInAppRoleList;
52 CPI_ASSEMBLY_LIST asmList;
53 CPI_SUBSCRIPTION_LIST subList;
54
55 LPWSTR pwzRollbackFileName = NULL;
56 LPWSTR pwzActionData = NULL;
57 LPWSTR pwzRollbackActionData = NULL;
58 LPWSTR pwzCommitActionData = NULL;
59
60 int iVersionNT = 0;
61 int iProgress = 0;
62 int iCommitProgress = 0;
63
64 ::ZeroMemory(&partList, sizeof(CPI_PARTITION_LIST));
65 ::ZeroMemory(&partRoleList, sizeof(CPI_PARTITION_ROLE_LIST));
66 ::ZeroMemory(&usrInPartRoleList, sizeof(CPI_USER_IN_PARTITION_ROLE_LIST));
67 ::ZeroMemory(&partUsrList, sizeof(CPI_PARTITION_USER_LIST));
68 ::ZeroMemory(&appList, sizeof(CPI_APPLICATION_LIST));
69 ::ZeroMemory(&appRoleList, sizeof(CPI_APPLICATION_ROLE_LIST));
70 ::ZeroMemory(&usrInAppRoleList, sizeof(CPI_USER_IN_APPLICATION_ROLE_LIST));
71 ::ZeroMemory(&asmList, sizeof(CPI_ASSEMBLY_LIST));
72 ::ZeroMemory(&subList, sizeof(CPI_SUBSCRIPTION_LIST));
73
74 // initialize
75 hr = WcaInitialize(hInstall, "ConfigureComPlusInstall");
76 ExitOnFailure(hr, "Failed to initialize");
77
78 hr = ::CoInitialize(NULL);
79 ExitOnFailure(hr, "Failed to initialize COM");
80 fInitializedCom = TRUE;
81
82 CpiSchedInitialize();
83
84 // check for the prerequsite tables
85 if (!CpiTableExists(cptComPlusPartition) && !CpiTableExists(cptComPlusApplication) && !CpiTableExists(cptComPlusAssembly))
86 {
87 WcaLog(LOGMSG_VERBOSE, "skipping install COM+ CustomAction, no ComPlusPartition, ComPlusApplication or ComPlusAssembly table present");
88 ExitFunction1(hr = S_FALSE);
89 }
90
91 // make sure we can access the COM+ admin catalog
92 do {
93 hr = CpiSchedGetAdminCatalog(&piCatalog);
94 if (FAILED(hr))
95 {
96 WcaLog(LOGMSG_STANDARD, "Failed to get COM+ admin catalog");
97 er = WcaErrorMessage(msierrComPlusCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
98 switch (er)
99 {
100 case IDABORT:
101 ExitFunction(); // exit with hr from CpiGetAdminCatalog() to kick off a rollback
102 case IDRETRY:
103 hr = S_FALSE;
104 break;
105 case IDIGNORE:
106 default:
107 ExitFunction1(hr = S_OK); // pretend everything is okay and bail
108 }
109 }
110 } while (S_FALSE == hr);
111
112 // get NT version
113 hr = WcaGetIntProperty(L"VersionNT", &iVersionNT);
114 ExitOnFailure(hr, "Failed to get VersionNT property");
115
116 // read elements
117 if (502 <= iVersionNT && CpiTableExists(cptComPlusPartition))
118 {
119 hr = CpiPartitionsRead(&partList);
120 MessageExitOnFailure(hr, msierrComPlusPartitionReadFailed, "Failed to read ComPlusPartitions table");
121 }
122
123 if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionRole))
124 {
125 hr = CpiPartitionRolesRead(&partList, &partRoleList);
126 MessageExitOnFailure(hr, msierrComPlusPartitionRoleReadFailed, "Failed to read ComPlusPartitionRole table");
127 }
128
129 if (502 <= iVersionNT && (CpiTableExists(cptComPlusUserInPartitionRole) || CpiTableExists(cptComPlusGroupInPartitionRole)))
130 {
131 hr = CpiUsersInPartitionRolesRead(&partRoleList, &usrInPartRoleList);
132 MessageExitOnFailure(hr, msierrComPlusUserInPartitionRoleReadFailed, "Failed to read ComPlusUserInPartitionRole table");
133 }
134
135 if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionUser))
136 {
137 hr = CpiPartitionUsersRead(&partList, &partUsrList);
138 MessageExitOnFailure(hr, msierrComPlusPartitionUserReadFailed, "Failed to read ComPlusPartitionUser table");
139 }
140
141 if (CpiTableExists(cptComPlusApplication))
142 {
143 hr = CpiApplicationsRead(&partList, &appList);
144 MessageExitOnFailure(hr, msierrComPlusApplicationReadFailed, "Failed to read ComPlusApplication table");
145 }
146
147 if (CpiTableExists(cptComPlusApplicationRole))
148 {
149 hr = CpiApplicationRolesRead(&appList, &appRoleList);
150 MessageExitOnFailure(hr, msierrComPlusApplicationRoleReadFailed, "Failed to read ComPlusApplicationRole table");
151 }
152
153 if (CpiTableExists(cptComPlusUserInApplicationRole) || CpiTableExists(cptComPlusGroupInApplicationRole))
154 {
155 hr = CpiUsersInApplicationRolesRead(&appRoleList, &usrInAppRoleList);
156 MessageExitOnFailure(hr, msierrComPlusUserInApplicationRoleReadFailed, "Failed to read ComPlusUserInApplicationRole table");
157 }
158
159 if (CpiTableExists(cptComPlusAssembly))
160 {
161 hr = CpiAssembliesRead(&appList, &appRoleList, &asmList);
162 MessageExitOnFailure(hr, msierrComPlusAssembliesReadFailed, "Failed to read ComPlusAssembly table");
163 }
164
165 if (CpiTableExists(cptComPlusSubscription))
166 {
167 hr = CpiSubscriptionsRead(&asmList, &subList);
168 MessageExitOnFailure(hr, msierrComPlusSubscriptionReadFailed, "Failed to read ComPlusSubscription table");
169 }
170
171 // verify elements
172 hr = CpiPartitionsVerifyInstall(&partList);
173 ExitOnFailure(hr, "Failed to verify partitions");
174
175 hr = CpiApplicationsVerifyInstall(&appList);
176 ExitOnFailure(hr, "Failed to verify applications");
177
178 hr = CpiApplicationRolesVerifyInstall(&appRoleList);
179 ExitOnFailure(hr, "Failed to verify application roles");
180
181 hr = CpiAssembliesVerifyInstall(&asmList);
182 ExitOnFailure(hr, "Failed to verify assemblies");
183
184 if (subList.iInstallCount)
185 {
186 hr = CpiSubscriptionsVerifyInstall(&subList);
187 ExitOnFailure(hr, "Failed to verify subscriptions");
188 }
189
190 // schedule
191 if (partList.iInstallCount || appList.iInstallCount || usrInAppRoleList.iInstallCount ||
192 appRoleList.iInstallCount || asmList.iInstallCount || asmList.iRoleInstallCount || subList.iInstallCount)
193 {
194 // create rollback file name
195 hr = CpiGetTempFileName(&pwzRollbackFileName);
196 ExitOnFailure(hr, "Failed to get rollback file name");
197
198 // schedule rollback prepare custom action
199 hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKINSTALLPREPARE, pwzRollbackFileName, 0);
200 ExitOnFailure(hr, "Failed to schedule ComPlusRollbackInstallPrepare");
201
202 // schedule prepare custom action
203 hr = WcaDoDeferredAction(CP_COMPLUSINSTALLPREPARE, pwzRollbackFileName, 0);
204 ExitOnFailure(hr, "Failed to schedule ComPlusInstallPrepare");
205
206 // schedule rollback custom action
207 hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzRollbackActionData);
208 ExitOnFailure(hr, "Failed to add rollback file name to rollback custom action data");
209
210 hr = CpiSubscriptionsInstall(&subList, rmRollback, &pwzRollbackActionData, NULL);
211 ExitOnFailure(hr, "Failed to install subscriptions");
212 hr = CpiRoleAssignmentsInstall(&asmList, rmRollback, &pwzRollbackActionData, NULL);
213 ExitOnFailure(hr, "Failed to install assemblies");
214 hr = CpiAssembliesInstall(&asmList, rmRollback, &pwzRollbackActionData, NULL);
215 ExitOnFailure(hr, "Failed to install assemblies");
216 hr = CpiUsersInApplicationRolesInstall(&usrInAppRoleList, rmRollback, &pwzRollbackActionData, NULL);
217 ExitOnFailure(hr, "Failed to install users in application roles");
218 hr = CpiApplicationRolesInstall(&appRoleList, rmRollback, &pwzRollbackActionData, NULL);
219 ExitOnFailure(hr, "Failed to install application roles");
220 hr = CpiApplicationsInstall(&appList, rmRollback, &pwzRollbackActionData, NULL);
221 ExitOnFailure(hr, "Failed to install applications");
222 hr = CpiPartitionUsersInstall(&partUsrList, rmRollback, &pwzRollbackActionData, NULL);
223 ExitOnFailure(hr, "Failed to install partition users");
224 hr = CpiUsersInPartitionRolesInstall(&usrInPartRoleList, rmRollback, &pwzRollbackActionData, NULL);
225 ExitOnFailure(hr, "Failed to install users in partition roles");
226 hr = CpiPartitionsInstall(&partList, rmRollback, &pwzRollbackActionData, NULL);
227 ExitOnFailure(hr, "Failed to install partitions");
228
229 hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKINSTALLEXECUTE, pwzRollbackActionData, 0);
230 ExitOnFailure(hr, "Failed to schedule ComPlusRollbackInstallExecute");
231
232 // schedule install custom action
233 hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzActionData);
234 ExitOnFailure(hr, "Failed to add rollback file name to custom action data");
235
236 hr = CpiPartitionsInstall(&partList, rmDeferred, &pwzActionData, &iProgress);
237 ExitOnFailure(hr, "Failed to install partitions");
238 hr = CpiUsersInPartitionRolesInstall(&usrInPartRoleList, rmDeferred, &pwzActionData, &iProgress);
239 ExitOnFailure(hr, "Failed to install users in partition roles");
240 hr = CpiPartitionUsersInstall(&partUsrList, rmDeferred, &pwzActionData, &iProgress);
241 ExitOnFailure(hr, "Failed to install partition users");
242 hr = CpiApplicationsInstall(&appList, rmDeferred, &pwzActionData, &iProgress);
243 ExitOnFailure(hr, "Failed to install applications");
244 hr = CpiApplicationRolesInstall(&appRoleList, rmDeferred, &pwzActionData, &iProgress);
245 ExitOnFailure(hr, "Failed to install application roles");
246 hr = CpiUsersInApplicationRolesInstall(&usrInAppRoleList, rmDeferred, &pwzActionData, &iProgress);
247 ExitOnFailure(hr, "Failed to install users in application roles");
248 hr = CpiAssembliesInstall(&asmList, rmDeferred, &pwzActionData, &iProgress);
249 ExitOnFailure(hr, "Failed to install assemblies");
250 hr = CpiRoleAssignmentsInstall(&asmList, rmDeferred, &pwzActionData, &iProgress);
251 ExitOnFailure(hr, "Failed to install assemblies");
252 hr = CpiSubscriptionsInstall(&subList, rmDeferred, &pwzActionData, &iProgress);
253 ExitOnFailure(hr, "Failed to install subscriptions");
254
255 hr = WcaDoDeferredAction(CP_COMPLUSINSTALLEXECUTE, pwzActionData, iProgress);
256 ExitOnFailure(hr, "Failed to schedule ComPlusInstallExecute");
257
258 // schedule install commit custom action
259 hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzCommitActionData);
260 ExitOnFailure(hr, "Failed to add rollback file name to commit custom action data");
261
262 hr = CpiAssembliesInstall(&asmList, rmCommit, &pwzCommitActionData, &iCommitProgress);
263 ExitOnFailure(hr, "Failed to install assemblies");
264 hr = CpiRoleAssignmentsInstall(&asmList, rmCommit, &pwzCommitActionData, &iCommitProgress);
265 ExitOnFailure(hr, "Failed to install assemblies");
266 hr = CpiSubscriptionsInstall(&subList, rmCommit, &pwzCommitActionData, &iCommitProgress);
267 ExitOnFailure(hr, "Failed to install subscriptions");
268
269 hr = WcaDoDeferredAction(CP_COMPLUSINSTALLEXECUTECOMMIT, pwzCommitActionData, iCommitProgress);
270 ExitOnFailure(hr, "Failed to schedule ComPlusInstallExecuteCommit");
271
272 // schedule commit custom action
273 hr = WcaDoDeferredAction(CP_COMPLUSINSTALLCOMMIT, pwzRollbackFileName, 0);
274 ExitOnFailure(hr, "Failed to schedule ComPlusInstallCommit");
275 }
276
277 hr = S_OK;
278
279LExit:
280 // clean up
281 ReleaseObject(piCatalog);
282
283 ReleaseStr(pwzRollbackFileName);
284 ReleaseStr(pwzActionData);
285 ReleaseStr(pwzRollbackActionData);
286 ReleaseStr(pwzCommitActionData);
287
288 CpiPartitionListFree(&partList);
289 CpiPartitionRoleListFree(&partRoleList);
290 CpiUserInPartitionRoleListFree(&usrInPartRoleList);
291 CpiPartitionUserListFree(&partUsrList);
292 CpiApplicationListFree(&appList);
293 CpiApplicationRoleListFree(&appRoleList);
294 CpiUserInApplicationRoleListFree(&usrInAppRoleList);
295 CpiAssemblyListFree(&asmList);
296 CpiSubscriptionListFree(&subList);
297
298 // unitialize
299 CpiSchedFinalize();
300
301 if (fInitializedCom)
302 ::CoUninitialize();
303
304 er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
305 return WcaFinalize(er);
306}
307
308
309/********************************************************************
310 ConfigureComPlusUninstall - CUSTOM ACTION ENTRY POINT for uninstalling COM+ components
311
312********************************************************************/
313extern "C" UINT __stdcall ConfigureComPlusUninstall(MSIHANDLE hInstall)
314{
315 HRESULT hr = S_OK;
316 UINT er = ERROR_SUCCESS;
317
318 BOOL fInitializedCom = FALSE;
319
320 ICOMAdminCatalog* piCatalog = NULL;
321
322 CPI_PARTITION_LIST partList;
323 CPI_PARTITION_ROLE_LIST partRoleList;
324 CPI_USER_IN_PARTITION_ROLE_LIST usrInPartRoleList;
325 CPI_PARTITION_USER_LIST partUsrList;
326 CPI_APPLICATION_LIST appList;
327 CPI_APPLICATION_ROLE_LIST appRoleList;
328 CPI_USER_IN_APPLICATION_ROLE_LIST usrInAppRoleList;
329 CPI_ASSEMBLY_LIST asmList;
330 CPI_SUBSCRIPTION_LIST subList;
331
332 LPWSTR pwzRollbackFileName = NULL;
333 LPWSTR pwzActionData = NULL;
334 LPWSTR pwzRollbackActionData = NULL;
335
336 int iVersionNT = 0;
337 int iProgress = 0;
338
339 ::ZeroMemory(&partList, sizeof(CPI_PARTITION_LIST));
340 ::ZeroMemory(&partRoleList, sizeof(CPI_PARTITION_ROLE_LIST));
341 ::ZeroMemory(&usrInPartRoleList, sizeof(CPI_USER_IN_PARTITION_ROLE_LIST));
342 ::ZeroMemory(&partUsrList, sizeof(CPI_PARTITION_USER_LIST));
343 ::ZeroMemory(&appList, sizeof(CPI_APPLICATION_LIST));
344 ::ZeroMemory(&appRoleList, sizeof(CPI_APPLICATION_ROLE_LIST));
345 ::ZeroMemory(&usrInAppRoleList, sizeof(CPI_USER_IN_APPLICATION_ROLE_LIST));
346 ::ZeroMemory(&asmList, sizeof(CPI_ASSEMBLY_LIST));
347 ::ZeroMemory(&subList, sizeof(CPI_SUBSCRIPTION_LIST));
348
349 // initialize
350 hr = WcaInitialize(hInstall, "ConfigureComPlusUninstall");
351 ExitOnFailure(hr, "Failed to initialize");
352
353 hr = ::CoInitialize(NULL);
354 ExitOnFailure(hr, "Failed to initialize COM");
355 fInitializedCom = TRUE;
356
357 CpiSchedInitialize();
358
359 // check for the prerequsite tables
360 if (!CpiTableExists(cptComPlusPartition) && !CpiTableExists(cptComPlusApplication) && !CpiTableExists(cptComPlusAssembly))
361 {
362 WcaLog(LOGMSG_VERBOSE, "skipping uninstall COM+ CustomAction, no ComPlusPartition, ComPlusApplication or ComPlusAssembly table present");
363 ExitFunction1(hr = S_FALSE);
364 }
365
366 // make sure we can access the COM+ admin catalog
367 do {
368 hr = CpiSchedGetAdminCatalog(&piCatalog);
369 if (FAILED(hr))
370 {
371 WcaLog(LOGMSG_STANDARD, "Failed to get COM+ admin catalog");
372 er = WcaErrorMessage(msierrComPlusCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
373 switch (er)
374 {
375 case IDABORT:
376 ExitFunction(); // exit with hr from CpiGetAdminCatalog() to kick off a rollback
377 case IDRETRY:
378 hr = S_FALSE;
379 break;
380 case IDIGNORE:
381 default:
382 ExitFunction1(hr = S_OK); // pretend everything is okay and bail
383 }
384 }
385 } while (S_FALSE == hr);
386
387 // get NT version
388 hr = WcaGetIntProperty(L"VersionNT", &iVersionNT);
389 ExitOnFailure(hr, "Failed to get VersionNT property");
390
391 // read elements
392 if (502 <= iVersionNT && CpiTableExists(cptComPlusPartition))
393 {
394 hr = CpiPartitionsRead(&partList);
395 MessageExitOnFailure(hr, msierrComPlusPartitionReadFailed, "Failed to read ComPlusPartitions table");
396 }
397
398 if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionRole))
399 {
400 hr = CpiPartitionRolesRead(&partList, &partRoleList);
401 MessageExitOnFailure(hr, msierrComPlusPartitionRoleReadFailed, "Failed to read ComPlusPartitionRole table");
402 }
403
404 if (502 <= iVersionNT && (CpiTableExists(cptComPlusUserInPartitionRole) || CpiTableExists(cptComPlusGroupInPartitionRole)))
405 {
406 hr = CpiUsersInPartitionRolesRead(&partRoleList, &usrInPartRoleList);
407 MessageExitOnFailure(hr, msierrComPlusUserInPartitionRoleReadFailed, "Failed to read ComPlusUserInPartitionRole table");
408 }
409
410 if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionUser))
411 {
412 hr = CpiPartitionUsersRead(&partList, &partUsrList);
413 MessageExitOnFailure(hr, msierrComPlusPartitionUserReadFailed, "Failed to read ComPlusPartitionUser table");
414 }
415
416 if (CpiTableExists(cptComPlusApplication))
417 {
418 hr = CpiApplicationsRead(&partList, &appList);
419 MessageExitOnFailure(hr, msierrComPlusApplicationReadFailed, "Failed to read ComPlusApplication table");
420 }
421
422 if (CpiTableExists(cptComPlusApplicationRole))
423 {
424 hr = CpiApplicationRolesRead(&appList, &appRoleList);
425 MessageExitOnFailure(hr, msierrComPlusApplicationRoleReadFailed, "Failed to read ComPlusApplicationRole table");
426 }
427
428 if (CpiTableExists(cptComPlusUserInApplicationRole) || CpiTableExists(cptComPlusGroupInApplicationRole))
429 {
430 hr = CpiUsersInApplicationRolesRead(&appRoleList, &usrInAppRoleList);
431 MessageExitOnFailure(hr, msierrComPlusUserInApplicationRoleReadFailed, "Failed to read ComPlusUserInApplicationRole table");
432 }
433
434 if (CpiTableExists(cptComPlusAssembly))
435 {
436 hr = CpiAssembliesRead(&appList, &appRoleList, &asmList);
437 MessageExitOnFailure(hr, msierrComPlusAssembliesReadFailed, "Failed to read ComPlusAssembly table");
438 }
439
440 if (CpiTableExists(cptComPlusSubscription))
441 {
442 hr = CpiSubscriptionsRead(&asmList, &subList);
443 MessageExitOnFailure(hr, msierrComPlusSubscriptionReadFailed, "Failed to read ComPlusSubscription table");
444 }
445
446 // verify elements
447 hr = CpiPartitionsVerifyUninstall(&partList);
448 ExitOnFailure(hr, "Failed to verify partitions");
449
450 hr = CpiApplicationsVerifyUninstall(&appList);
451 ExitOnFailure(hr, "Failed to verify applications");
452
453 hr = CpiApplicationRolesVerifyUninstall(&appRoleList);
454 ExitOnFailure(hr, "Failed to verify application roles");
455
456 hr = CpiAssembliesVerifyUninstall(&asmList);
457 ExitOnFailure(hr, "Failed to verify assemblies");
458
459 if (subList.iUninstallCount)
460 {
461 hr = CpiSubscriptionsVerifyUninstall(&subList);
462 ExitOnFailure(hr, "Failed to verify subscriptions");
463 }
464
465 // schedule
466 if (partList.iUninstallCount || appList.iUninstallCount || appRoleList.iUninstallCount ||
467 usrInAppRoleList.iUninstallCount || asmList.iUninstallCount || asmList.iRoleUninstallCount || subList.iUninstallCount)
468 {
469 // create rollback file name
470 hr = CpiGetTempFileName(&pwzRollbackFileName);
471 ExitOnFailure(hr, "Failed to get rollback file name");
472
473 // schedule rollback prepare custom action
474 hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKINSTALLPREPARE, pwzRollbackFileName, 0);
475 ExitOnFailure(hr, "Failed to schedule ComPlusRollbackInstallPrepare");
476
477 // schedule prepare custom action
478 hr = WcaDoDeferredAction(CP_COMPLUSINSTALLPREPARE, pwzRollbackFileName, 0);
479 ExitOnFailure(hr, "Failed to schedule ComPlusInstallPrepare");
480
481 // schedule rollback custom action
482 hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzRollbackActionData);
483 ExitOnFailure(hr, "Failed to add rollback file name to rollback custom action data");
484
485 hr = CpiPartitionsUninstall(&partList, rmRollback, &pwzRollbackActionData, NULL);
486 ExitOnFailure(hr, "Failed to uninstall partitions");
487 hr = CpiUsersInPartitionRolesUninstall(&usrInPartRoleList, rmRollback, &pwzRollbackActionData, NULL);
488 ExitOnFailure(hr, "Failed to uninstall users in partition roles");
489 hr = CpiPartitionUsersUninstall(&partUsrList, rmRollback, &pwzRollbackActionData, NULL);
490 ExitOnFailure(hr, "Failed to uninstall partition users");
491 hr = CpiApplicationsUninstall(&appList, rmRollback, &pwzRollbackActionData, NULL);
492 ExitOnFailure(hr, "Failed to uninstall applications");
493 hr = CpiApplicationRolesUninstall(&appRoleList, rmRollback, &pwzRollbackActionData, NULL);
494 ExitOnFailure(hr, "Failed to uninstall application roles");
495 hr = CpiUsersInApplicationRolesUninstall(&usrInAppRoleList, rmRollback, &pwzRollbackActionData, NULL);
496 ExitOnFailure(hr, "Failed to uninstall users in application roles");
497 hr = CpiAssembliesUninstall(&asmList, rmRollback, &pwzRollbackActionData, NULL);
498 ExitOnFailure(hr, "Failed to uninstall assemblies");
499 hr = CpiRoleAssignmentsUninstall(&asmList, rmRollback, &pwzRollbackActionData, NULL);
500 ExitOnFailure(hr, "Failed to uninstall assemblies");
501 hr = CpiSubscriptionsUninstall(&subList, rmRollback, &pwzRollbackActionData, NULL);
502 ExitOnFailure(hr, "Failed to uninstall subscriptions");
503
504 hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKUNINSTALLEXECUTE, pwzRollbackActionData, 0);
505 ExitOnFailure(hr, "Failed to schedule ComPlusRollbackUninstallExecute");
506
507 // schedule install custom action
508 hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzActionData);
509 ExitOnFailure(hr, "Failed to add rollback file name to custom action data");
510
511 hr = CpiSubscriptionsUninstall(&subList, rmDeferred, &pwzActionData, &iProgress);
512 ExitOnFailure(hr, "Failed to uninstall subscriptions");
513 hr = CpiRoleAssignmentsUninstall(&asmList, rmDeferred, &pwzActionData, &iProgress);
514 ExitOnFailure(hr, "Failed to uninstall assemblies");
515 hr = CpiAssembliesUninstall(&asmList, rmDeferred, &pwzActionData, &iProgress);
516 ExitOnFailure(hr, "Failed to uninstall assemblies");
517 hr = CpiUsersInApplicationRolesUninstall(&usrInAppRoleList, rmDeferred, &pwzActionData, &iProgress);
518 ExitOnFailure(hr, "Failed to uninstall users in application roles");
519 hr = CpiApplicationRolesUninstall(&appRoleList, rmDeferred, &pwzActionData, &iProgress);
520 ExitOnFailure(hr, "Failed to uninstall application roles");
521 hr = CpiApplicationsUninstall(&appList, rmDeferred, &pwzActionData, &iProgress);
522 ExitOnFailure(hr, "Failed to uninstall applications");
523 hr = CpiPartitionUsersUninstall(&partUsrList, rmDeferred, &pwzActionData, &iProgress);
524 ExitOnFailure(hr, "Failed to uninstall partition users");
525 hr = CpiUsersInPartitionRolesUninstall(&usrInPartRoleList, rmDeferred, &pwzActionData, &iProgress);
526 ExitOnFailure(hr, "Failed to uninstall users in partition roles");
527 hr = CpiPartitionsUninstall(&partList, rmDeferred, &pwzActionData, &iProgress);
528 ExitOnFailure(hr, "Failed to uninstall partitions");
529
530 hr = WcaDoDeferredAction(CP_COMPLUSUNINSTALLEXECUTE, pwzActionData, iProgress);
531 ExitOnFailure(hr, "Failed to schedule ComPlusUninstallExecute");
532
533 // schedule commit custom action
534 hr = WcaDoDeferredAction(CP_COMPLUSINSTALLCOMMIT, pwzRollbackFileName, 0);
535 ExitOnFailure(hr, "Failed to schedule ComPlusInstallCommit");
536 }
537
538 hr = S_OK;
539
540LExit:
541 // clean up
542 ReleaseObject(piCatalog);
543
544 ReleaseStr(pwzRollbackFileName);
545 ReleaseStr(pwzActionData);
546 ReleaseStr(pwzRollbackActionData);
547
548 CpiPartitionListFree(&partList);
549 CpiPartitionRoleListFree(&partRoleList);
550 CpiUserInPartitionRoleListFree(&usrInPartRoleList);
551 CpiPartitionUserListFree(&partUsrList);
552 CpiApplicationListFree(&appList);
553 CpiApplicationRoleListFree(&appRoleList);
554 CpiUserInApplicationRoleListFree(&usrInAppRoleList);
555 CpiAssemblyListFree(&asmList);
556 CpiSubscriptionListFree(&subList);
557
558 // unitialize
559 CpiSchedFinalize();
560
561 if (fInitializedCom)
562 ::CoUninitialize();
563
564 er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
565 return WcaFinalize(er);
566}
diff --git a/src/ext/ComPlus/ca/cpsubsexec.cpp b/src/ext/ComPlus/ca/cpsubsexec.cpp
new file mode 100644
index 00000000..bbcf9853
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpsubsexec.cpp
@@ -0,0 +1,411 @@
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// private structs
7
8struct CPI_SUBSCRIPTION_ATTRIBUTES
9{
10 int iActionType;
11 int iActionCost;
12 LPWSTR pwzKey;
13 LPWSTR pwzID;
14 LPWSTR pwzName;
15 LPWSTR pwzEventCLSID;
16 LPWSTR pwzPublisherID;
17 LPWSTR pwzCompCLSID;
18 LPWSTR pwzAppID;
19 LPWSTR pwzPartID;
20 CPI_PROPERTY* pPropList;
21};
22
23
24// prototypes for private helper functions
25
26static HRESULT ReadSubscriptionAttributes(
27 LPWSTR* ppwzData,
28 CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
29 );
30static void FreeSubscriptionAttributes(
31 CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
32 );
33static HRESULT CreateSubscription(
34 CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
35 );
36static HRESULT RemoveSubscription(
37 CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
38 );
39
40
41// function definitions
42
43HRESULT CpiConfigureSubscriptions(
44 LPWSTR* ppwzData,
45 HANDLE hRollbackFile
46 )
47{
48 HRESULT hr = S_OK;
49
50 CPI_SUBSCRIPTION_ATTRIBUTES attrs;
51 ::ZeroMemory(&attrs, sizeof(attrs));
52
53 // read action text
54 hr = CpiActionStartMessage(ppwzData, FALSE);
55 ExitOnFailure(hr, "Failed to send action start message");
56
57 // ger count
58 int iCnt = 0;
59 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
60 ExitOnFailure(hr, "Failed to read count");
61
62 // write count to rollback file
63 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
64 ExitOnFailure(hr, "Failed to write count to rollback file");
65
66 for (int i = 0; i < iCnt; i++)
67 {
68 // read attributes from CustomActionData
69 hr = ReadSubscriptionAttributes(ppwzData, &attrs);
70 ExitOnFailure(hr, "Failed to read attributes");
71
72 // progress message
73 hr = CpiActionDataMessage(1, attrs.pwzName);
74 ExitOnFailure(hr, "Failed to send progress messages");
75
76 if (S_FALSE == hr)
77 ExitFunction();
78
79 // write key to rollback file
80 hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
81 ExitOnFailure(hr, "Failed to write key to rollback file");
82
83 // action
84 switch (attrs.iActionType)
85 {
86 case atCreate:
87 hr = CreateSubscription(&attrs);
88 ExitOnFailure(hr, "Failed to create subscription, key: %S", attrs.pwzKey);
89 break;
90 case atRemove:
91 hr = RemoveSubscription(&attrs);
92 ExitOnFailure(hr, "Failed to remove subscription, key: %S", attrs.pwzKey);
93 break;
94 }
95
96 // write completion status to rollback file
97 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
98 ExitOnFailure(hr, "Failed to write completion status to rollback file");
99
100 // progress
101 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
102 ExitOnFailure(hr, "Failed to update progress");
103 }
104
105 hr = S_OK;
106
107LExit:
108 // clean up
109 FreeSubscriptionAttributes(&attrs);
110
111 return hr;
112}
113
114HRESULT CpiRollbackConfigureSubscriptions(
115 LPWSTR* ppwzData,
116 CPI_ROLLBACK_DATA* pRollbackDataList
117 )
118{
119 HRESULT hr = S_OK;
120
121 int iRollbackStatus;
122
123 CPI_SUBSCRIPTION_ATTRIBUTES attrs;
124 ::ZeroMemory(&attrs, sizeof(attrs));
125
126 // read action text
127 hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
128 ExitOnFailure(hr, "Failed to send action start message");
129
130 // ger count
131 int iCnt = 0;
132 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
133 ExitOnFailure(hr, "Failed to read count");
134
135 for (int i = 0; i < iCnt; i++)
136 {
137 // read attributes from CustomActionData
138 hr = ReadSubscriptionAttributes(ppwzData, &attrs);
139 ExitOnFailure(hr, "Failed to read attributes");
140
141 // rollback status
142 hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
143
144 if (S_FALSE == hr)
145 continue; // not found, nothing to rollback
146
147 // progress message
148 hr = CpiActionDataMessage(1, attrs.pwzName);
149 ExitOnFailure(hr, "Failed to send progress messages");
150
151 if (S_FALSE == hr)
152 ExitFunction();
153
154 // action
155 switch (attrs.iActionType)
156 {
157 case atCreate:
158 hr = CreateSubscription(&attrs);
159 if (FAILED(hr))
160 WcaLog(LOGMSG_STANDARD, "Failed to create subscription, hr: 0x%x, key: %S", hr, attrs.pwzKey);
161 break;
162 case atRemove:
163 hr = RemoveSubscription(&attrs);
164 if (FAILED(hr))
165 WcaLog(LOGMSG_STANDARD, "Failed to remove subscription, hr: 0x%x, key: %S", hr, attrs.pwzKey);
166 break;
167 }
168
169 // check rollback status
170 if (0 == iRollbackStatus)
171 continue; // operation did not complete, skip progress
172
173 // progress
174 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
175 ExitOnFailure(hr, "Failed to update progress");
176 }
177
178 hr = S_OK;
179
180LExit:
181 // clean up
182 FreeSubscriptionAttributes(&attrs);
183
184 return hr;
185}
186
187
188// helper function definitions
189
190static HRESULT ReadSubscriptionAttributes(
191 LPWSTR* ppwzData,
192 CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
193 )
194{
195 HRESULT hr = S_OK;
196
197 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
198 ExitOnFailure(hr, "Failed to read action type");
199 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
200 ExitOnFailure(hr, "Failed to read action cost");
201 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
202 ExitOnFailure(hr, "Failed to read key");
203 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzID);
204 ExitOnFailure(hr, "Failed to read id");
205 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzName);
206 ExitOnFailure(hr, "Failed to read name");
207 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzEventCLSID);
208 ExitOnFailure(hr, "Failed to read event clsid");
209 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPublisherID);
210 ExitOnFailure(hr, "Failed to read publisher id");
211 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzCompCLSID);
212 ExitOnFailure(hr, "Failed to read component clsid");
213 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAppID);
214 ExitOnFailure(hr, "Failed to read application id");
215 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
216 ExitOnFailure(hr, "Failed to read partition id");
217
218 hr = CpiReadPropertyList(ppwzData, &pAttrs->pPropList);
219 ExitOnFailure(hr, "Failed to read properties");
220
221 hr = S_OK;
222
223LExit:
224 return hr;
225}
226
227static void FreeSubscriptionAttributes(
228 CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
229 )
230{
231 ReleaseStr(pAttrs->pwzKey);
232 ReleaseStr(pAttrs->pwzID);
233 ReleaseStr(pAttrs->pwzName);
234 ReleaseStr(pAttrs->pwzEventCLSID);
235 ReleaseStr(pAttrs->pwzPublisherID);
236 ReleaseStr(pAttrs->pwzCompCLSID);
237 ReleaseStr(pAttrs->pwzAppID);
238 ReleaseStr(pAttrs->pwzPartID);
239
240 if (pAttrs->pPropList)
241 CpiFreePropertyList(pAttrs->pPropList);
242}
243
244static HRESULT CreateSubscription(
245 CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
246 )
247{
248 HRESULT hr = S_OK;
249 UINT er = ERROR_SUCCESS;
250
251 ICatalogCollection* piSubsColl = NULL;
252 ICatalogObject* piSubsObj = NULL;
253
254 PSID pSid = NULL;
255 long lChanges = 0;
256
257 // log
258 WcaLog(LOGMSG_VERBOSE, "Creating subscription, key: %S", pAttrs->pwzKey);
259
260 // get subscriptions collection
261 hr = CpiGetSubscriptionsCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, pAttrs->pwzCompCLSID, &piSubsColl);
262 if (S_FALSE == hr)
263 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
264 ExitOnFailure(hr, "Failed to get subscriptions collection");
265
266 // check if subscription exists
267 hr = CpiFindCollectionObjectByStringKey(piSubsColl, pAttrs->pwzID, &piSubsObj);
268 ExitOnFailure(hr, "Failed to find subscription");
269
270 if (S_FALSE == hr)
271 {
272 // create subscription
273 hr = CpiAddCollectionObject(piSubsColl, &piSubsObj);
274 ExitOnFailure(hr, "Failed to add subscription to collection");
275
276 hr = CpiPutCollectionObjectValue(piSubsObj, L"ID", pAttrs->pwzID);
277 ExitOnFailure(hr, "Failed to set subscription id property");
278
279 hr = CpiPutCollectionObjectValue(piSubsObj, L"Name", pAttrs->pwzName);
280 ExitOnFailure(hr, "Failed to set subscription name property");
281
282 if (pAttrs->pwzEventCLSID && *pAttrs->pwzEventCLSID)
283 {
284 hr = CpiPutCollectionObjectValue(piSubsObj, L"EventCLSID", pAttrs->pwzEventCLSID);
285 ExitOnFailure(hr, "Failed to set role event clsid property");
286 }
287
288 if (pAttrs->pwzPublisherID && *pAttrs->pwzPublisherID)
289 {
290 hr = CpiPutCollectionObjectValue(piSubsObj, L"PublisherID", pAttrs->pwzPublisherID);
291 ExitOnFailure(hr, "Failed to set role publisher id property");
292 }
293 }
294
295 // properties
296 for (CPI_PROPERTY* pItm = pAttrs->pPropList; pItm; pItm = pItm->pNext)
297 {
298 // UserName property
299 if (0 == lstrcmpW(pItm->wzName, L"UserName"))
300 {
301 // get SID for account
302 do {
303 er = ERROR_SUCCESS;
304 hr = CpiAccountNameToSid(pItm->pwzValue, &pSid);
305 if (!::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
306 {
307 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr)
308 {
309 WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pItm->pwzValue);
310 er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
311 switch (er)
312 {
313 case IDABORT:
314 ExitFunction(); // exit with error code from CpiAccountNameToSid()
315 case IDRETRY:
316 break;
317 case IDIGNORE:
318 default:
319 hr = S_FALSE;
320 }
321 }
322 else
323 ExitOnFailure(hr, "Failed to get SID for account, account: '%S'", pItm->pwzValue);
324 }
325 else if (FAILED(hr))
326 {
327 WcaLog(LOGMSG_STANDARD, "Failed to get SID for account, hr: 0x%x, account: '%S'", hr, pItm->pwzValue);
328 hr = S_FALSE;
329 }
330 } while (IDRETRY == er);
331
332 if (S_FALSE == hr)
333 continue;
334
335 // convert SID back to account name
336 hr = CpiSidToAccountName(pSid, &pItm->pwzValue);
337 ExitOnFailure(hr, "Failed to convert SID to account name");
338 }
339
340 // set property
341 hr = CpiPutCollectionObjectValue(piSubsObj, pItm->wzName, pItm->pwzValue);
342 ExitOnFailure(hr, "Failed to set object property value, name: %S", pItm->wzName);
343 }
344
345 // save changes
346 hr = piSubsColl->SaveChanges(&lChanges);
347 if (COMADMIN_E_OBJECTERRORS == hr)
348 CpiLogCatalogErrorInfo();
349 ExitOnFailure(hr, "Failed to save changes");
350
351 // log
352 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
353
354 hr = S_OK;
355
356LExit:
357 // clean up
358 ReleaseObject(piSubsColl);
359 ReleaseObject(piSubsObj);
360
361 if (pSid)
362 ::HeapFree(::GetProcessHeap(), 0, pSid);
363
364 return hr;
365}
366
367static HRESULT RemoveSubscription(
368 CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
369 )
370{
371 HRESULT hr = S_OK;
372
373 ICatalogCollection* piSubsColl = NULL;
374
375 long lChanges = 0;
376
377 // log
378 WcaLog(LOGMSG_VERBOSE, "Removing subscription, key: %S", pAttrs->pwzKey);
379
380 // get subscriptions collection
381 hr = CpiGetSubscriptionsCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, pAttrs->pwzCompCLSID, &piSubsColl);
382 ExitOnFailure(hr, "Failed to get subscriptions collection");
383
384 if (S_FALSE == hr)
385 {
386 // subscription not found
387 WcaLog(LOGMSG_VERBOSE, "Unable to retrieve subscriptions collection, nothing to delete, key: %S", pAttrs->pwzKey);
388 ExitFunction1(hr = S_OK);
389 }
390
391 // remove
392 hr = CpiRemoveCollectionObject(piSubsColl, pAttrs->pwzID, NULL, FALSE);
393 ExitOnFailure(hr, "Failed to remove subscriptions");
394
395 // save changes
396 hr = piSubsColl->SaveChanges(&lChanges);
397 if (COMADMIN_E_OBJECTERRORS == hr)
398 CpiLogCatalogErrorInfo();
399 ExitOnFailure(hr, "Failed to save changes");
400
401 // log
402 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
403
404 hr = S_OK;
405
406LExit:
407 // clean up
408 ReleaseObject(piSubsColl);
409
410 return hr;
411}
diff --git a/src/ext/ComPlus/ca/cpsubsexec.h b/src/ext/ComPlus/ca/cpsubsexec.h
new file mode 100644
index 00000000..2f4d3c75
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpsubsexec.h
@@ -0,0 +1,12 @@
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
5HRESULT CpiConfigureSubscriptions(
6 LPWSTR* ppwzData,
7 HANDLE hRollbackFile
8 );
9HRESULT CpiRollbackConfigureSubscriptions(
10 LPWSTR* ppwzData,
11 CPI_ROLLBACK_DATA* pRollbackDataList
12 );
diff --git a/src/ext/ComPlus/ca/cpsubssched.cpp b/src/ext/ComPlus/ca/cpsubssched.cpp
new file mode 100644
index 00000000..df15fd03
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpsubssched.cpp
@@ -0,0 +1,606 @@
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// sql queries
7
8LPCWSTR vcsSubscriptionQuery =
9 L"SELECT `Subscription`, `ComPlusComponent_`, `Component_`, `Id`, `Name`, `EventCLSID`, `PublisherID` FROM `ComPlusSubscription`";
10enum eSubscriptionQuery { sqSubscription = 1, sqComPlusComponent, sqComponent, sqID, sqName, sqEventCLSID, sqPublisherID };
11
12LPCWSTR vcsSubscriptionPropertyQuery =
13 L"SELECT `Name`, `Value` FROM `ComPlusSubscriptionProperty` WHERE `Subscription_` = ?";
14
15
16// property definitions
17
18CPI_PROPERTY_DEFINITION pdlSubscriptionProperties[] =
19{
20 {L"Description", cpptString, 500},
21 {L"Enabled", cpptBoolean, 500},
22 {L"EventClassPartitionID", cpptString, 502},
23 {L"FilterCriteria", cpptString, 500},
24 {L"InterfaceID", cpptString, 500},
25 {L"MachineName", cpptString, 500},
26 {L"MethodName", cpptString, 500},
27 {L"PerUser", cpptBoolean, 500},
28 {L"Queued", cpptBoolean, 500},
29 {L"SubscriberMoniker", cpptString, 500},
30 {L"UserName", cpptUser, 500},
31 {NULL, cpptNone, 0}
32};
33
34
35// prototypes for private helper functions
36
37static void FreeSubscription(
38 CPI_SUBSCRIPTION* pItm
39 );
40static HRESULT FindObjectForSubscription(
41 CPI_SUBSCRIPTION* pItm,
42 BOOL fFindId,
43 BOOL fFindName,
44 ICatalogObject** ppiSubsObj
45 );
46static HRESULT AddSubscriptionToActionData(
47 CPI_SUBSCRIPTION* pItm,
48 int iActionType,
49 int iActionCost,
50 LPWSTR* ppwzActionData
51 );
52static HRESULT ComponentFindByKey(
53 CPI_ASSEMBLY_LIST* pAsmList,
54 LPCWSTR pwzKey,
55 CPI_ASSEMBLY** ppAsmItm,
56 CPISCHED_COMPONENT** ppCompItm
57 );
58
59
60// function definitions
61
62void CpiSubscriptionListFree(
63 CPI_SUBSCRIPTION_LIST* pList
64 )
65{
66 CPI_SUBSCRIPTION* pItm = pList->pFirst;
67
68 while (pItm)
69 {
70 CPI_SUBSCRIPTION* pDelete = pItm;
71 pItm = pItm->pNext;
72 FreeSubscription(pDelete);
73 }
74}
75
76HRESULT CpiSubscriptionsRead(
77 CPI_ASSEMBLY_LIST* pAsmList,
78 CPI_SUBSCRIPTION_LIST* pSubList
79 )
80{
81 HRESULT hr = S_OK;
82 UINT er = ERROR_SUCCESS;
83
84 PMSIHANDLE hView, hRec;
85
86 CPI_SUBSCRIPTION* pItm = NULL;
87 LPWSTR pwzData = NULL;
88 BOOL fMatchingArchitecture = FALSE;
89
90 // loop through all applications
91 hr = WcaOpenExecuteView(vcsSubscriptionQuery, &hView);
92 ExitOnFailure(hr, "Failed to execute view on ComPlusSubscription table");
93
94 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
95 {
96 // get component
97 hr = WcaGetRecordString(hRec, sqComponent, &pwzData);
98 ExitOnFailure(hr, "Failed to get component");
99
100 // check if the component is our processor architecture
101 hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture);
102 ExitOnFailure(hr, "Failed to get component architecture.");
103
104 if (!fMatchingArchitecture)
105 {
106 continue; // not the same architecture, ignore
107 }
108
109 // create entry
110 pItm = (CPI_SUBSCRIPTION*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_SUBSCRIPTION));
111 if (!pItm)
112 ExitFunction1(hr = E_OUTOFMEMORY);
113
114 // get component install state
115 er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction);
116 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
117
118 // get key
119 hr = WcaGetRecordString(hRec, sqSubscription, &pwzData);
120 ExitOnFailure(hr, "Failed to get key");
121 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
122
123 // get com+ component
124 hr = WcaGetRecordString(hRec, sqComPlusComponent, &pwzData);
125 ExitOnFailure(hr, "Failed to get COM+ component");
126
127 hr = ComponentFindByKey(pAsmList, pwzData, &pItm->pAssembly, &pItm->pComponent);
128
129 if (S_FALSE == hr)
130 {
131 // component not found
132 ExitOnFailure(hr = E_FAIL, "Failed to find component, key: %S", pwzData);
133 }
134
135 // get id
136 hr = WcaGetRecordFormattedString(hRec, sqID, &pwzData);
137 ExitOnFailure(hr, "Failed to get id");
138
139 if (pwzData && *pwzData)
140 {
141 hr = PcaGuidToRegFormat(pwzData, pItm->wzID, countof(pItm->wzID));
142 ExitOnFailure(hr, "Failed to parse id guid value, key: %S, value: '%S'", pItm->wzKey, pwzData);
143 }
144
145 // get name
146 hr = WcaGetRecordFormattedString(hRec, sqName, &pwzData);
147 ExitOnFailure(hr, "Failed to get name");
148 StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData);
149
150 // get event clsid
151 hr = WcaGetRecordFormattedString(hRec, sqEventCLSID, &pwzData);
152 ExitOnFailure(hr, "Failed to get event clsid");
153 StringCchCopyW(pItm->wzEventCLSID, countof(pItm->wzEventCLSID), pwzData);
154
155 // get publisher id
156 hr = WcaGetRecordFormattedString(hRec, sqPublisherID, &pwzData);
157 ExitOnFailure(hr, "Failed to get publisher id");
158 StringCchCopyW(pItm->wzPublisherID, countof(pItm->wzPublisherID), pwzData);
159
160 // get properties
161 if (CpiTableExists(cptComPlusSubscriptionProperty))
162 {
163 hr = CpiPropertiesRead(vcsSubscriptionPropertyQuery, pItm->wzKey, pdlSubscriptionProperties, &pItm->pProperties, &pItm->iPropertyCount);
164 ExitOnFailure(hr, "Failed to get subscription properties");
165 }
166
167 // set references & increment counters
168 if (WcaIsInstalling(pItm->isInstalled, pItm->isAction))
169 {
170 CpiApplicationAddReferenceInstall(pItm->pAssembly->pApplication);
171 pItm->pAssembly->fReferencedForInstall = TRUE;
172 pSubList->iInstallCount++;
173 if (pItm->pAssembly->iAttributes & aaRunInCommit)
174 pSubList->iCommitCount++;
175 }
176 if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
177 {
178 CpiApplicationAddReferenceUninstall(pItm->pAssembly->pApplication);
179 pItm->pAssembly->fReferencedForUninstall = TRUE;
180 pSubList->iUninstallCount++;
181 }
182
183 // add entry
184 if (pSubList->pFirst)
185 pItm->pNext = pSubList->pFirst;
186 pSubList->pFirst = pItm;
187 pItm = NULL;
188 }
189
190 if (E_NOMOREITEMS == hr)
191 hr = S_OK;
192
193LExit:
194 // clean up
195 if (pItm)
196 FreeSubscription(pItm);
197
198 ReleaseStr(pwzData);
199
200 return hr;
201}
202
203HRESULT CpiSubscriptionsVerifyInstall(
204 CPI_SUBSCRIPTION_LIST* pList
205 )
206{
207 HRESULT hr = S_OK;
208 UINT er = ERROR_SUCCESS;
209
210 ICatalogObject* piSubsObj = NULL;
211
212 for (CPI_SUBSCRIPTION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
213 {
214 // subscriptions that are being installed
215 if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction))
216 continue;
217
218 // subscription is supposed to exist
219 if (CpiIsInstalled(pItm->isInstalled))
220 {
221 // if we don't have an id
222 if (!*pItm->wzID)
223 {
224 // find subscriptions with conflicting name
225 hr = FindObjectForSubscription(pItm, FALSE, TRUE, &piSubsObj);
226 ExitOnFailure(hr, "Failed to find collection object for subscription");
227
228 // if the subscription was found
229 if (S_OK == hr)
230 {
231 // get id from subscription object
232 hr = CpiGetKeyForObject(piSubsObj, pItm->wzID, countof(pItm->wzID));
233 ExitOnFailure(hr, "Failed to get id");
234 }
235
236 // if the subscription was not found
237 else
238 {
239 // create a new id
240 hr = CpiCreateId(pItm->wzID, countof(pItm->wzID));
241 ExitOnFailure(hr, "Failed to create id");
242 }
243 }
244 }
245
246 // subscription is supposed to be created
247 else
248 {
249 // check for conflicts
250 do {
251 if (*pItm->wzID)
252 {
253 // find subscriptions with conflicting id
254 hr = FindObjectForSubscription(pItm, TRUE, FALSE, &piSubsObj);
255 ExitOnFailure(hr, "Failed to find collection object for subscription");
256
257 if (S_FALSE == hr)
258 {
259 // find subscriptions with conflicting name
260 hr = FindObjectForSubscription(pItm, FALSE, TRUE, &piSubsObj);
261 ExitOnFailure(hr, "Failed to find collection object for subscription");
262
263 if (S_OK == hr)
264 // "A subscription with a conflictiong name exists. retry cancel"
265 er = WcaErrorMessage(msierrComPlusSubscriptionNameConflict, hr, INSTALLMESSAGE_ERROR | MB_RETRYCANCEL, 0);
266 else
267 break; // no conflicting entry found, break loop
268 }
269 else
270 // "A subscription with a conflicting id exists. abort retry ignore"
271 er = WcaErrorMessage(msierrComPlusSubscriptionIdConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
272 }
273 else
274 {
275 // find subscriptions with conflicting name
276 hr = FindObjectForSubscription(pItm, FALSE, TRUE, &piSubsObj);
277 ExitOnFailure(hr, "Failed to find collection object for subscription");
278
279 if (S_OK == hr)
280 // "A subscription with a conflictiong name exists. abort retry ignore"
281 er = WcaErrorMessage(msierrComPlusSubscriptionNameConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
282 else
283 break; // no conflicting entry found, break loop
284 }
285
286 switch (er)
287 {
288 case IDCANCEL:
289 case IDABORT:
290 ExitOnFailure(hr = E_FAIL, "A subscription with a conflictiong name or id exists, key: %S", pItm->wzKey);
291 break;
292 case IDRETRY:
293 break;
294 case IDIGNORE:
295 default:
296 // if we don't have an id, copy id from object
297 if (!*pItm->wzID)
298 {
299 hr = CpiGetKeyForObject(piSubsObj, pItm->wzID, countof(pItm->wzID));
300 ExitOnFailure(hr, "Failed to get id");
301 }
302 hr = S_FALSE; // indicate that this is not a conflict
303 }
304 } while (S_OK == hr); // hr = S_FALSE if we don't have any conflicts
305
306 // create a new id if one is missing
307 if (!*pItm->wzID)
308 {
309 hr = CpiCreateId(pItm->wzID, countof(pItm->wzID));
310 ExitOnFailure(hr, "Failed to create id");
311 }
312 }
313
314 // clean up
315 ReleaseNullObject(piSubsObj);
316 }
317
318 hr = S_OK;
319
320LExit:
321 // clean up
322 ReleaseObject(piSubsObj);
323
324 return hr;
325}
326
327HRESULT CpiSubscriptionsVerifyUninstall(
328 CPI_SUBSCRIPTION_LIST* pList
329 )
330{
331 HRESULT hr = S_OK;
332 ICatalogObject* piSubsObj = NULL;
333
334 for (CPI_SUBSCRIPTION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
335 {
336 // subscriptions that are being installed
337 if (!WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
338 continue;
339
340 // find subscriptions with conflicting name
341 hr = FindObjectForSubscription(pItm, 0 != *pItm->wzID, 0 == *pItm->wzID, &piSubsObj);
342 ExitOnFailure(hr, "Failed to find collection object for subscription");
343
344 // if the subscription was found
345 if (S_OK == hr)
346 {
347 // if we don't have an id, copy id from object
348 if (!*pItm->wzID)
349 {
350 hr = CpiGetKeyForObject(piSubsObj, pItm->wzID, countof(pItm->wzID));
351 ExitOnFailure(hr, "Failed to get id");
352 }
353 }
354
355 // if the subscription was not found
356 else
357 {
358 pItm->fObjectNotFound = TRUE;
359 pList->iUninstallCount--; // elements with the fObjectNotFound flag set will not be scheduled for uninstall
360 }
361
362 // clean up
363 ReleaseNullObject(piSubsObj);
364 }
365
366 hr = S_OK;
367
368LExit:
369 // clean up
370 ReleaseObject(piSubsObj);
371
372 return hr;
373}
374
375HRESULT CpiSubscriptionsInstall(
376 CPI_SUBSCRIPTION_LIST* pList,
377 int iRunMode,
378 LPWSTR* ppwzActionData,
379 int* piProgress
380 )
381{
382 HRESULT hr = S_OK;
383
384 int iActionType;
385 int iCount = 0;
386
387 // add action text
388 hr = CpiAddActionTextToActionData(L"CreateSubscrComPlusComponents", ppwzActionData);
389 ExitOnFailure(hr, "Failed to add action text to custom action data");
390
391 // subscription count
392 switch (iRunMode)
393 {
394 case rmDeferred:
395 iCount = pList->iInstallCount - pList->iCommitCount;
396 break;
397 case rmCommit:
398 iCount = pList->iCommitCount;
399 break;
400 case rmRollback:
401 iCount = pList->iInstallCount;
402 break;
403 }
404
405 // add subscription count to action data
406 hr = WcaWriteIntegerToCaData(iCount, ppwzActionData);
407 ExitOnFailure(hr, "Failed to add count to custom action data");
408
409 // add assemblies to custom action data in forward order
410 for (CPI_SUBSCRIPTION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
411 {
412 // roles that are being installed only
413 if ((rmCommit == iRunMode && !(pItm->pAssembly->iAttributes & aaRunInCommit)) ||
414 (rmDeferred == iRunMode && (pItm->pAssembly->iAttributes & aaRunInCommit)) ||
415 !WcaIsInstalling(pItm->isInstalled, pItm->isAction))
416 continue;
417
418 // action type
419 if (rmRollback == iRunMode)
420 {
421 if (CpiIsInstalled(pItm->isInstalled))
422 iActionType = atNoOp;
423 else
424 iActionType = atRemove;
425 }
426 else
427 iActionType = atCreate;
428
429 // add to action data
430 hr = AddSubscriptionToActionData(pItm, iActionType, COST_SUBSCRIPTION_CREATE, ppwzActionData);
431 ExitOnFailure(hr, "Failed to add subscription to custom action data, key: %S", pItm->wzKey);
432 }
433
434 // add progress tics
435 if (piProgress)
436 *piProgress += COST_SUBSCRIPTION_CREATE * pList->iInstallCount;
437
438 hr = S_OK;
439
440LExit:
441 return hr;
442}
443
444HRESULT CpiSubscriptionsUninstall(
445 CPI_SUBSCRIPTION_LIST* pList,
446 int iRunMode,
447 LPWSTR* ppwzActionData,
448 int* piProgress
449 )
450{
451 HRESULT hr = S_OK;
452
453 int iActionType;
454
455 // add action text
456 hr = CpiAddActionTextToActionData(L"RemoveSubscrComPlusComponents", ppwzActionData);
457 ExitOnFailure(hr, "Failed to add action text to custom action data");
458
459 // add subscription count to action data
460 hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData);
461 ExitOnFailure(hr, "Failed to add count to custom action data");
462
463 // add assemblies to custom action data in reverse order
464 for (CPI_SUBSCRIPTION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
465 {
466 // roles that are being uninstalled only
467 if (pItm->fObjectNotFound || !WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
468 continue;
469
470 // action type
471 if (rmRollback == iRunMode)
472 iActionType = atCreate;
473 else
474 iActionType = atRemove;
475
476 // add to action data
477 hr = AddSubscriptionToActionData(pItm, iActionType, COST_SUBSCRIPTION_DELETE, ppwzActionData);
478 ExitOnFailure(hr, "Failed to add subscription to custom action data, key: %S", pItm->wzKey);
479 }
480
481 // add progress tics
482 if (piProgress)
483 *piProgress += COST_SUBSCRIPTION_DELETE * pList->iUninstallCount;
484
485 hr = S_OK;
486
487LExit:
488 return hr;
489}
490
491
492// helper function definitions
493
494static void FreeSubscription(
495 CPI_SUBSCRIPTION* pItm
496 )
497{
498 if (pItm->pProperties)
499 CpiPropertiesFreeList(pItm->pProperties);
500
501 ::HeapFree(::GetProcessHeap(), 0, pItm);
502}
503
504static HRESULT FindObjectForSubscription(
505 CPI_SUBSCRIPTION* pItm,
506 BOOL fFindId,
507 BOOL fFindName,
508 ICatalogObject** ppiSubsObj
509 )
510{
511 HRESULT hr = S_OK;
512
513 ICatalogCollection* piSubsColl = NULL;
514
515 // get applications collection
516 hr = CpiGetSubscriptionsCollForComponent(pItm->pAssembly, pItm->pComponent, &piSubsColl);
517 ExitOnFailure(hr, "Failed to get collection");
518
519 if (S_FALSE == hr)
520 ExitFunction(); // exit with hr = S_FALSE
521
522 // find application object
523 hr = CpiFindCollectionObject(piSubsColl, fFindId ? pItm->wzID : NULL, fFindName ? pItm->wzName : NULL, ppiSubsObj);
524 ExitOnFailure(hr, "Failed to find object");
525
526 // exit with hr from CpiFindCollectionObject()
527
528LExit:
529 // clean up
530 ReleaseObject(piSubsColl);
531
532 return hr;
533}
534
535static HRESULT AddSubscriptionToActionData(
536 CPI_SUBSCRIPTION* pItm,
537 int iActionType,
538 int iActionCost,
539 LPWSTR* ppwzActionData
540 )
541{
542 HRESULT hr = S_OK;
543
544 // add action information to custom action data
545 hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
546 ExitOnFailure(hr, "Failed to add action type to custom action data");
547 hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
548 ExitOnFailure(hr, "Failed to add action cost to custom action data");
549
550 // add application role information to custom action data
551 hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
552 ExitOnFailure(hr, "Failed to add subscription key to custom action data");
553 hr = WcaWriteStringToCaData(pItm->wzID, ppwzActionData);
554 ExitOnFailure(hr, "Failed to add subscription id to custom action data");
555 hr = WcaWriteStringToCaData(pItm->wzName, ppwzActionData);
556 ExitOnFailure(hr, "Failed to add subscription name to custom action data");
557 hr = WcaWriteStringToCaData(atCreate == iActionType ? pItm->wzEventCLSID : L"", ppwzActionData);
558 ExitOnFailure(hr, "Failed to add assembly tlb path to custom action data");
559 hr = WcaWriteStringToCaData(atCreate == iActionType ? pItm->wzPublisherID : L"", ppwzActionData);
560 ExitOnFailure(hr, "Failed to add assembly proxy-stub dll path to custom action data");
561
562 // add component information to custom action data
563 hr = WcaWriteStringToCaData(pItm->pComponent->wzCLSID, ppwzActionData);
564 ExitOnFailure(hr, "Failed to add application id to custom action data");
565
566 // add application information to custom action data
567 hr = WcaWriteStringToCaData(pItm->pAssembly->pApplication->wzID, ppwzActionData);
568 ExitOnFailure(hr, "Failed to add application id to custom action data");
569
570 // add partition information to custom action data
571 LPCWSTR pwzPartID = pItm->pAssembly->pApplication->pPartition ? pItm->pAssembly->pApplication->pPartition->wzID : L"";
572 hr = WcaWriteStringToCaData(pwzPartID, ppwzActionData);
573 ExitOnFailure(hr, "Failed to add partition id to custom action data");
574
575 // add properties to custom action data
576 hr = CpiAddPropertiesToActionData(atCreate == iActionType ? pItm->iPropertyCount : 0, pItm->pProperties, ppwzActionData);
577 ExitOnFailure(hr, "Failed to add properties to custom action data");
578
579 hr = S_OK;
580
581LExit:
582 return hr;
583}
584
585static HRESULT ComponentFindByKey(
586 CPI_ASSEMBLY_LIST* pAsmList,
587 LPCWSTR pwzKey,
588 CPI_ASSEMBLY** ppAsmItm,
589 CPISCHED_COMPONENT** ppCompItm
590 )
591{
592 for (CPI_ASSEMBLY* pAsmItm = pAsmList->pFirst; pAsmItm; pAsmItm = pAsmItm->pNext)
593 {
594 for (CPISCHED_COMPONENT* pCompItm = pAsmItm->pComponents; pCompItm; pCompItm = pCompItm->pNext)
595 {
596 if (0 == lstrcmpW(pCompItm->wzKey, pwzKey))
597 {
598 *ppAsmItm = pAsmItm;
599 *ppCompItm = pCompItm;
600 return S_OK;
601 }
602 }
603 }
604
605 return S_FALSE;
606}
diff --git a/src/ext/ComPlus/ca/cpsubssched.h b/src/ext/ComPlus/ca/cpsubssched.h
new file mode 100644
index 00000000..83ff1af8
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpsubssched.h
@@ -0,0 +1,62 @@
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
5struct CPI_SUBSCRIPTION
6{
7 WCHAR wzKey[MAX_DARWIN_KEY + 1];
8 WCHAR wzID[CPI_MAX_GUID + 1];
9 WCHAR wzName[MAX_DARWIN_COLUMN + 1];
10 WCHAR wzEventCLSID[CPI_MAX_GUID + 1];
11 WCHAR wzPublisherID[CPI_MAX_GUID + 1];
12
13 BOOL fObjectNotFound;
14
15 int iPropertyCount;
16 CPI_PROPERTY* pProperties;
17
18 INSTALLSTATE isInstalled, isAction;
19
20 CPI_ASSEMBLY* pAssembly;
21 CPISCHED_COMPONENT* pComponent;
22
23 CPI_SUBSCRIPTION* pNext;
24};
25
26struct CPI_SUBSCRIPTION_LIST
27{
28 CPI_SUBSCRIPTION* pFirst;
29
30 int iInstallCount;
31 int iCommitCount;
32 int iUninstallCount;
33};
34
35
36// function prototypes
37
38void CpiSubscriptionListFree(
39 CPI_SUBSCRIPTION_LIST* pList
40 );
41HRESULT CpiSubscriptionsRead(
42 CPI_ASSEMBLY_LIST* pAsmList,
43 CPI_SUBSCRIPTION_LIST* pSubList
44 );
45HRESULT CpiSubscriptionsVerifyInstall(
46 CPI_SUBSCRIPTION_LIST* pList
47 );
48HRESULT CpiSubscriptionsVerifyUninstall(
49 CPI_SUBSCRIPTION_LIST* pList
50 );
51HRESULT CpiSubscriptionsInstall(
52 CPI_SUBSCRIPTION_LIST* pList,
53 int iRunMode,
54 LPWSTR* ppwzActionData,
55 int* piProgress
56 );
57HRESULT CpiSubscriptionsUninstall(
58 CPI_SUBSCRIPTION_LIST* pList,
59 int iRunMode,
60 LPWSTR* ppwzActionData,
61 int* piProgress
62 );
diff --git a/src/ext/ComPlus/ca/cputilexec.cpp b/src/ext/ComPlus/ca/cputilexec.cpp
new file mode 100644
index 00000000..1c2c8b93
--- /dev/null
+++ b/src/ext/ComPlus/ca/cputilexec.cpp
@@ -0,0 +1,1881 @@
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// private structs
7
8struct CPI_WELLKNOWN_SID
9{
10 LPCWSTR pwzName;
11 SID_IDENTIFIER_AUTHORITY iaIdentifierAuthority;
12 BYTE nSubAuthorityCount;
13 DWORD dwSubAuthority[8];
14};
15
16
17// well known SIDs
18
19CPI_WELLKNOWN_SID wsWellKnownSids[] = {
20 {L"\\Everyone", SECURITY_WORLD_SID_AUTHORITY, 1, {SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0}},
21 {L"\\Administrators", SECURITY_NT_AUTHORITY, 2, {SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0}},
22 {L"\\LocalSystem", SECURITY_NT_AUTHORITY, 1, {SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0}},
23 {L"\\LocalService", SECURITY_NT_AUTHORITY, 1, {SECURITY_LOCAL_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0}},
24 {L"\\NetworkService", SECURITY_NT_AUTHORITY, 1, {SECURITY_NETWORK_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0}},
25 {L"\\AuthenticatedUser", SECURITY_NT_AUTHORITY, 1, {SECURITY_AUTHENTICATED_USER_RID, 0, 0, 0, 0, 0, 0, 0}},
26 {L"\\Guests", SECURITY_NT_AUTHORITY, 2, {SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS, 0, 0, 0, 0, 0, 0}},
27 {L"\\Users", SECURITY_NT_AUTHORITY, 2, {SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0}},
28 {L"\\CREATOR OWNER", SECURITY_NT_AUTHORITY, 1, {SECURITY_CREATOR_OWNER_RID, 0, 0, 0, 0, 0, 0, 0}},
29 {NULL, SECURITY_NULL_SID_AUTHORITY, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
30};
31
32
33// prototypes for private helper functions
34
35static HRESULT FindUserCollectionObjectIndex(
36 ICatalogCollection* piColl,
37 PSID pSid,
38 int* pi
39 );
40static HRESULT CreateSidFromDomainRidPair(
41 PSID pDomainSid,
42 DWORD dwRid,
43 PSID* ppSid
44 );
45static HRESULT InitLsaUnicodeString(
46 PLSA_UNICODE_STRING plusStr,
47 LPCWSTR pwzStr,
48 DWORD dwLen
49 );
50static void FreeLsaUnicodeString(
51 PLSA_UNICODE_STRING plusStr
52 );
53static HRESULT WriteFileAll(
54 HANDLE hFile,
55 PBYTE pbBuffer,
56 DWORD dwBufferLength
57 );
58static HRESULT ReadFileAll(
59 HANDLE hFile,
60 PBYTE pbBuffer,
61 DWORD dwBufferLength
62 );
63
64
65// variables
66
67static ICOMAdminCatalog* gpiCatalog;
68
69
70// function definitions
71
72void CpiExecInitialize()
73{
74 // collections
75 gpiCatalog = NULL;
76}
77
78void CpiExecFinalize()
79{
80 // collections
81 ReleaseObject(gpiCatalog);
82}
83
84HRESULT CpiActionStartMessage(
85 LPWSTR* ppwzActionData,
86 BOOL fSuppress
87 )
88{
89 HRESULT hr = S_OK;
90 UINT er = ERROR_SUCCESS;
91
92 PMSIHANDLE hRec;
93
94 LPWSTR pwzData = NULL;
95
96 // create record
97 hRec = ::MsiCreateRecord(3);
98 ExitOnNull(hRec, hr, E_OUTOFMEMORY, "Failed to create record");
99
100 // action name
101 hr = WcaReadStringFromCaData(ppwzActionData, &pwzData);
102 ExitOnFailure(hr, "Failed to action name");
103
104 er = ::MsiRecordSetStringW(hRec, 1, pwzData);
105 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set action name");
106
107 // description
108 hr = WcaReadStringFromCaData(ppwzActionData, &pwzData);
109 ExitOnFailure(hr, "Failed to description");
110
111 er = ::MsiRecordSetStringW(hRec, 2, pwzData);
112 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set description");
113
114 // template
115 hr = WcaReadStringFromCaData(ppwzActionData, &pwzData);
116 ExitOnFailure(hr, "Failed to template");
117
118 er = ::MsiRecordSetStringW(hRec, 3, pwzData);
119 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set template");
120
121 // message
122 if (!fSuppress)
123 {
124 er = WcaProcessMessage(INSTALLMESSAGE_ACTIONSTART, hRec);
125 if (0 == er || IDOK == er || IDYES == er)
126 {
127 hr = S_OK;
128 }
129 else if (IDABORT == er || IDCANCEL == er)
130 {
131 WcaSetReturnValue(ERROR_INSTALL_USEREXIT); // note that the user said exit
132 hr = S_FALSE;
133 }
134 else
135 hr = E_UNEXPECTED;
136 }
137
138LExit:
139 // clean up
140 ReleaseStr(pwzData);
141
142 return hr;
143}
144
145HRESULT CpiActionDataMessage(
146 DWORD cArgs,
147 ...
148 )
149{
150 HRESULT hr = S_OK;
151 UINT er = ERROR_SUCCESS;
152
153 PMSIHANDLE hRec;
154 va_list args;
155
156 // record
157 hRec = ::MsiCreateRecord(cArgs);
158 ExitOnNull(hRec, hr, E_OUTOFMEMORY, "Failed to create record");
159
160 va_start(args, cArgs);
161 for (DWORD i = 1; i <= cArgs; i++)
162 {
163 LPCWSTR pwzArg = va_arg(args, WCHAR*);
164 if (pwzArg && *pwzArg)
165 {
166 er = ::MsiRecordSetStringW(hRec, i, pwzArg);
167 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set record field string");
168 }
169 }
170 va_end(args);
171
172 // message
173 er = WcaProcessMessage(INSTALLMESSAGE_ACTIONDATA, hRec);
174 if (0 == er || IDOK == er || IDYES == er)
175 {
176 hr = S_OK;
177 }
178 else if (IDABORT == er || IDCANCEL == er)
179 {
180 WcaSetReturnValue(ERROR_INSTALL_USEREXIT); // note that the user said exit
181 hr = S_FALSE;
182 }
183 else
184 hr = E_UNEXPECTED;
185
186LExit:
187 return hr;
188}
189
190HRESULT CpiExecGetAdminCatalog(
191 ICOMAdminCatalog** ppiCatalog
192 )
193{
194 HRESULT hr = S_OK;
195
196 if (!gpiCatalog)
197 {
198 // get collection
199 hr = ::CoCreateInstance(CLSID_COMAdminCatalog, NULL, CLSCTX_ALL, IID_ICOMAdminCatalog, (void**)&gpiCatalog);
200 ExitOnFailure(hr, "Failed to create COM+ admin catalog object");
201 }
202
203 // return value
204 gpiCatalog->AddRef();
205 *ppiCatalog = gpiCatalog;
206
207 hr = S_OK;
208
209LExit:
210 return hr;
211}
212
213HRESULT CpiLogCatalogErrorInfo()
214{
215 HRESULT hr = S_OK;
216
217 ICOMAdminCatalog* piCatalog = NULL;
218 ICatalogCollection* piErrColl = NULL;
219 IDispatch* piDisp = NULL;
220 ICatalogObject* piObj = NULL;
221
222 LPWSTR pwzName = NULL;
223 LPWSTR pwzErrorCode = NULL;
224 LPWSTR pwzMajorRef = NULL;
225 LPWSTR pwzMinorRef = NULL;
226
227 // get catalog
228 hr = CpiExecGetAdminCatalog(&piCatalog);
229 ExitOnFailure(hr, "Failed to get COM+ admin catalog");
230
231 // get error info collection
232 hr = CpiExecGetCatalogCollection(L"ErrorInfo", &piErrColl);
233 ExitOnFailure(hr, "Failed to get error info collection");
234
235 // loop objects
236 long lCnt;
237 hr = piErrColl->get_Count(&lCnt);
238 ExitOnFailure(hr, "Failed to get to number of items in collection");
239
240 for (long i = 0; i < lCnt; i++)
241 {
242 // get ICatalogObject interface
243 hr = piErrColl->get_Item(i, &piDisp);
244 ExitOnFailure(hr, "Failed to get item from partitions collection");
245
246 hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj);
247 ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
248
249 // get properties
250 hr = CpiGetCollectionObjectValue(piObj, L"Name", &pwzName);
251 ExitOnFailure(hr, "Failed to get name");
252 hr = CpiGetCollectionObjectValue(piObj, L"ErrorCode", &pwzErrorCode);
253 ExitOnFailure(hr, "Failed to get error code");
254 hr = CpiGetCollectionObjectValue(piObj, L"MajorRef", &pwzMajorRef);
255 ExitOnFailure(hr, "Failed to get major ref");
256 hr = CpiGetCollectionObjectValue(piObj, L"MinorRef", &pwzMinorRef);
257 ExitOnFailure(hr, "Failed to get minor ref");
258
259 // write to log
260 WcaLog(LOGMSG_STANDARD, "ErrorInfo: Name='%S', ErrorCode='%S', MajorRef='%S', MinorRef='%S'",
261 pwzName, pwzErrorCode, pwzMajorRef, pwzMinorRef);
262
263 // clean up
264 ReleaseNullObject(piDisp);
265 ReleaseNullObject(piObj);
266 }
267
268 hr = S_OK;
269
270LExit:
271 // clean up
272 ReleaseObject(piCatalog);
273 ReleaseObject(piErrColl);
274 ReleaseObject(piDisp);
275 ReleaseObject(piObj);
276
277 ReleaseStr(pwzName);
278 ReleaseStr(pwzErrorCode);
279 ReleaseStr(pwzMajorRef);
280 ReleaseStr(pwzMinorRef);
281
282 return hr;
283}
284
285HRESULT CpiExecGetCatalogCollection(
286 LPCWSTR pwzName,
287 ICatalogCollection** ppiColl
288 )
289{
290 HRESULT hr = S_OK;
291
292 ICOMAdminCatalog* piCatalog = NULL;
293 IDispatch* piDisp = NULL;
294
295 BSTR bstrName = NULL;
296
297 // copy name string
298 bstrName = ::SysAllocString(pwzName);
299 ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for collection name");
300
301 // get catalog
302 hr = CpiExecGetAdminCatalog(&piCatalog);
303 ExitOnFailure(hr, "Failed to get COM+ admin catalog");
304
305 // get collecton from catalog
306 hr = piCatalog->GetCollection(bstrName, &piDisp);
307 ExitOnFailure(hr, "Failed to get collection");
308
309 hr = piDisp->QueryInterface(IID_ICatalogCollection, (void**)ppiColl);
310 ExitOnFailure(hr, "Failed to get IID_ICatalogCollection interface");
311
312 // populate collection
313 hr = (*ppiColl)->Populate();
314 if (COMADMIN_E_OBJECTERRORS == hr)
315 CpiLogCatalogErrorInfo();
316 ExitOnFailure(hr, "Failed to populate collection");
317
318 hr = S_OK;
319
320LExit:
321 // clean up
322 ReleaseObject(piCatalog);
323 ReleaseObject(piDisp);
324 ReleaseBSTR(bstrName);
325
326 return hr;
327}
328
329HRESULT CpiExecGetCatalogCollection(
330 ICatalogCollection* piColl,
331 ICatalogObject* piObj,
332 LPCWSTR pwzName,
333 ICatalogCollection** ppiColl
334 )
335{
336 HRESULT hr = S_OK;
337
338 ICOMAdminCatalog* piCatalog = NULL;
339 IDispatch* piDisp = NULL;
340
341 BSTR bstrName = NULL;
342
343 VARIANT vtKey;
344 ::VariantInit(&vtKey);
345
346 // copy name string
347 bstrName = ::SysAllocString(pwzName);
348 ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for collection name");
349
350 // get catalog
351 hr = CpiExecGetAdminCatalog(&piCatalog);
352 ExitOnFailure(hr, "Failed to get COM+ admin catalog");
353
354 // get key
355 hr = piObj->get_Key(&vtKey);
356 ExitOnFailure(hr, "Failed to get object key");
357
358 // get collecton from catalog
359 hr = piColl->GetCollection(bstrName, vtKey, &piDisp);
360 ExitOnFailure(hr, "Failed to get collection");
361
362 hr = piDisp->QueryInterface(IID_ICatalogCollection, (void**)ppiColl);
363 ExitOnFailure(hr, "Failed to get IID_ICatalogCollection interface");
364
365 // populate collection
366 hr = (*ppiColl)->Populate();
367 if (COMADMIN_E_OBJECTERRORS == hr)
368 CpiLogCatalogErrorInfo();
369 ExitOnFailure(hr, "Failed to populate collection");
370
371 hr = S_OK;
372
373LExit:
374 // clean up
375 ReleaseObject(piCatalog);
376 ReleaseObject(piDisp);
377 ReleaseBSTR(bstrName);
378 ::VariantClear(&vtKey);
379
380 return hr;
381}
382
383HRESULT CpiAddCollectionObject(
384 ICatalogCollection* piColl,
385 ICatalogObject** ppiObj
386 )
387{
388 HRESULT hr = S_OK;
389
390 IDispatch* piDisp = NULL;
391
392 hr = piColl->Add(&piDisp);
393 ExitOnFailure(hr, "Failed to add object to collection");
394
395 hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)ppiObj);
396 ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
397
398 hr = S_OK;
399
400LExit:
401 // clean up
402 ReleaseObject(piDisp);
403
404 return hr;
405}
406
407HRESULT CpiPutCollectionObjectValue(
408 ICatalogObject* piObj,
409 LPCWSTR pwzPropName,
410 LPCWSTR pwzValue
411 )
412{
413 HRESULT hr = S_OK;
414
415 BSTR bstrPropName = NULL;
416
417 VARIANT vtVal;
418 ::VariantInit(&vtVal);
419
420 // allocate property name string
421 bstrPropName = ::SysAllocString(pwzPropName);
422 ExitOnNull(bstrPropName, hr, E_OUTOFMEMORY, "Failed to allocate property name string");
423
424 // prepare value variant
425 vtVal.vt = VT_BSTR;
426 vtVal.bstrVal = ::SysAllocString(pwzValue);
427 ExitOnNull(vtVal.bstrVal, hr, E_OUTOFMEMORY, "Failed to allocate property value string");
428
429 // put value
430 hr = piObj->put_Value(bstrPropName, vtVal);
431 ExitOnFailure(hr, "Failed to put property value");
432
433 hr = S_OK;
434
435LExit:
436 // clean up
437 ReleaseBSTR(bstrPropName);
438 ::VariantClear(&vtVal);
439
440 return hr;
441}
442
443HRESULT CpiPutCollectionObjectValues(
444 ICatalogObject* piObj,
445 CPI_PROPERTY* pPropList
446 )
447{
448 HRESULT hr = S_OK;
449
450 for (CPI_PROPERTY* pItm = pPropList; pItm; pItm = pItm->pNext)
451 {
452 // set property
453 hr = CpiPutCollectionObjectValue(piObj, pItm->wzName, pItm->pwzValue);
454 ExitOnFailure(hr, "Failed to set object property value, name: %S", pItm->wzName);
455 }
456
457 hr = S_OK;
458
459LExit:
460 return hr;
461}
462
463HRESULT CpiGetCollectionObjectValue(
464 ICatalogObject* piObj,
465 LPCWSTR szPropName,
466 LPWSTR* ppwzValue
467 )
468{
469 HRESULT hr = S_OK;
470
471 BSTR bstrPropName = NULL;
472
473 VARIANT vtVal;
474 ::VariantInit(&vtVal);
475
476 // allocate property name string
477 bstrPropName = ::SysAllocString(szPropName);
478 ExitOnNull(bstrPropName, hr, E_OUTOFMEMORY, "Failed to allocate property name string");
479
480 // get value
481 hr = piObj->get_Value(bstrPropName, &vtVal);
482 ExitOnFailure(hr, "Failed to get property value");
483
484 hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR);
485 ExitOnFailure(hr, "Failed to change variant type");
486
487 hr = StrAllocString(ppwzValue, vtVal.bstrVal, ::SysStringLen(vtVal.bstrVal));
488 ExitOnFailure(hr, "Failed to allocate memory for value string");
489
490 hr = S_OK;
491
492LExit:
493 // clean up
494 ReleaseBSTR(bstrPropName);
495 ::VariantClear(&vtVal);
496
497 return hr;
498}
499
500HRESULT CpiResetObjectProperty(
501 ICatalogCollection* piColl,
502 ICatalogObject* piObj,
503 LPCWSTR pwzPropName
504 )
505{
506 HRESULT hr = S_OK;
507
508 BSTR bstrPropName = NULL;
509
510 long lChanges = 0;
511
512 VARIANT vtVal;
513 ::VariantInit(&vtVal);
514
515 // allocate property name string
516 bstrPropName = ::SysAllocString(pwzPropName);
517 ExitOnNull(bstrPropName, hr, E_OUTOFMEMORY, "Failed to allocate deleteable property name string");
518
519 // get value
520 hr = piObj->get_Value(bstrPropName, &vtVal);
521 ExitOnFailure(hr, "Failed to get deleteable property value");
522
523 hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BOOL);
524 ExitOnFailure(hr, "Failed to change variant type");
525
526 // if the deleteable property is set
527 if (VARIANT_FALSE == vtVal.boolVal)
528 {
529 // clear property
530 vtVal.boolVal = VARIANT_TRUE;
531
532 hr = piObj->put_Value(bstrPropName, vtVal);
533 ExitOnFailure(hr, "Failed to get property value");
534
535 // save changes
536 hr = piColl->SaveChanges(&lChanges);
537 if (COMADMIN_E_OBJECTERRORS == hr)
538 CpiLogCatalogErrorInfo();
539 ExitOnFailure(hr, "Failed to save changes");
540 }
541
542 hr = S_OK;
543
544LExit:
545 // clean up
546 ReleaseBSTR(bstrPropName);
547 ::VariantClear(&vtVal);
548
549 return hr;
550}
551
552HRESULT CpiRemoveCollectionObject(
553 ICatalogCollection* piColl,
554 LPCWSTR pwzID,
555 LPCWSTR pwzName,
556 BOOL fResetDeleteable
557 )
558{
559 HRESULT hr = S_OK;
560
561 IDispatch* piDisp = NULL;
562 ICatalogObject* piObj = NULL;
563
564 BOOL fMatch = FALSE;
565
566 VARIANT vtVal;
567 ::VariantInit(&vtVal);
568
569 long lCnt;
570 hr = piColl->get_Count(&lCnt);
571 ExitOnFailure(hr, "Failed to get to number of items in collection");
572
573 for (long i = 0; i < lCnt; i++)
574 {
575 // get ICatalogObject interface
576 hr = piColl->get_Item(i, &piDisp);
577 ExitOnFailure(hr, "Failed to get object from collection");
578
579 hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj);
580 ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
581
582 // compare id
583 if (pwzID && *pwzID)
584 {
585 hr = piObj->get_Key(&vtVal);
586 ExitOnFailure(hr, "Failed to get key");
587
588 hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR);
589 ExitOnFailure(hr, "Failed to change variant type");
590
591 if (0 == lstrcmpiW(vtVal.bstrVal, pwzID))
592 fMatch = TRUE;
593
594 ::VariantClear(&vtVal);
595 }
596
597 // compare name
598 if (pwzName && *pwzName)
599 {
600 hr = piObj->get_Name(&vtVal);
601 ExitOnFailure(hr, "Failed to get name");
602
603 hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR);
604 ExitOnFailure(hr, "Failed to change variant type");
605
606 if (0 == lstrcmpW(vtVal.bstrVal, pwzName))
607 fMatch = TRUE;
608
609 ::VariantClear(&vtVal);
610 }
611
612 // if it's a match, remove it
613 if (fMatch)
614 {
615 if (fResetDeleteable)
616 {
617 // reset deleteable property, if set
618 hr = CpiResetObjectProperty(piColl, piObj, L"Deleteable");
619 ExitOnFailure(hr, "Failed to reset deleteable property");
620 }
621
622 hr = piColl->Remove(i);
623 ExitOnFailure(hr, "Failed to remove item from collection");
624 break;
625 }
626
627 // release interface pointers
628 ReleaseNullObject(piDisp);
629 ReleaseNullObject(piObj);
630 }
631
632 hr = S_OK;
633
634LExit:
635 // clean up
636 ReleaseObject(piDisp);
637 ReleaseObject(piObj);
638
639 ::VariantClear(&vtVal);
640
641 return hr;
642}
643
644HRESULT CpiRemoveUserCollectionObject(
645 ICatalogCollection* piColl,
646 PSID pSid
647 )
648{
649 HRESULT hr = S_OK;
650
651 int i = 0;
652
653 // find index
654 hr = FindUserCollectionObjectIndex(piColl, pSid, &i);
655 ExitOnFailure(hr, "Failed to find user collection index");
656
657 if (S_FALSE == hr)
658 ExitFunction(); // not found, exit with hr = S_FALSE
659
660 // remove object
661 hr = piColl->Remove(i);
662 ExitOnFailure(hr, "Failed to remove object from collection");
663
664 hr = S_OK;
665
666LExit:
667 return hr;
668}
669
670HRESULT CpiFindCollectionObjectByStringKey(
671 ICatalogCollection* piColl,
672 LPCWSTR pwzKey,
673 ICatalogObject** ppiObj
674 )
675{
676 HRESULT hr = S_OK;
677
678 IDispatch* piDisp = NULL;
679 ICatalogObject* piObj = NULL;
680
681 VARIANT vtVal;
682 ::VariantInit(&vtVal);
683
684 long lCnt;
685 hr = piColl->get_Count(&lCnt);
686 ExitOnFailure(hr, "Failed to get to number of items in collection");
687
688 for (long i = 0; i < lCnt; i++)
689 {
690 // get ICatalogObject interface
691 hr = piColl->get_Item(i, &piDisp);
692 ExitOnFailure(hr, "Failed to get object from collection");
693
694 hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj);
695 ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
696
697 // compare key
698 hr = piObj->get_Key(&vtVal);
699 ExitOnFailure(hr, "Failed to get key");
700
701 hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR);
702 ExitOnFailure(hr, "Failed to change variant type");
703
704 if (0 == lstrcmpiW(vtVal.bstrVal, pwzKey))
705 {
706 if (ppiObj)
707 {
708 *ppiObj = piObj;
709 piObj = NULL;
710 }
711 ExitFunction1(hr = S_OK);
712 }
713
714 // clean up
715 ReleaseNullObject(piDisp);
716 ReleaseNullObject(piObj);
717
718 ::VariantClear(&vtVal);
719 }
720
721 hr = S_FALSE;
722
723LExit:
724 // clean up
725 ReleaseObject(piDisp);
726 ReleaseObject(piObj);
727
728 ::VariantClear(&vtVal);
729
730 return hr;
731}
732
733HRESULT CpiFindCollectionObjectByIntegerKey(
734 ICatalogCollection* piColl,
735 long lKey,
736 ICatalogObject** ppiObj
737 )
738{
739 HRESULT hr = S_OK;
740
741 IDispatch* piDisp = NULL;
742 ICatalogObject* piObj = NULL;
743
744 VARIANT vtVal;
745 ::VariantInit(&vtVal);
746
747 long lCnt;
748 hr = piColl->get_Count(&lCnt);
749 ExitOnFailure(hr, "Failed to get to number of items in collection");
750
751 for (long i = 0; i < lCnt; i++)
752 {
753 // get ICatalogObject interface
754 hr = piColl->get_Item(i, &piDisp);
755 ExitOnFailure(hr, "Failed to get object from collection");
756
757 hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj);
758 ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
759
760 // compare key
761 hr = piObj->get_Key(&vtVal);
762 ExitOnFailure(hr, "Failed to get key");
763
764 hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_I4);
765 ExitOnFailure(hr, "Failed to change variant type");
766
767 if (vtVal.lVal == lKey)
768 {
769 if (ppiObj)
770 {
771 *ppiObj = piObj;
772 piObj = NULL;
773 }
774 ExitFunction1(hr = S_OK);
775 }
776
777 // clean up
778 ReleaseNullObject(piDisp);
779 ReleaseNullObject(piObj);
780
781 ::VariantClear(&vtVal);
782 }
783
784 hr = S_FALSE;
785
786LExit:
787 // clean up
788 ReleaseObject(piDisp);
789 ReleaseObject(piObj);
790
791 ::VariantClear(&vtVal);
792
793 return hr;
794}
795
796HRESULT CpiFindCollectionObjectByName(
797 ICatalogCollection* piColl,
798 LPCWSTR pwzName,
799 ICatalogObject** ppiObj
800 )
801{
802 HRESULT hr = S_OK;
803
804 IDispatch* piDisp = NULL;
805 ICatalogObject* piObj = NULL;
806
807 VARIANT vtVal;
808 ::VariantInit(&vtVal);
809
810 long lCnt;
811 hr = piColl->get_Count(&lCnt);
812 ExitOnFailure(hr, "Failed to get to number of items in collection");
813
814 for (long i = 0; i < lCnt; i++)
815 {
816 // get ICatalogObject interface
817 hr = piColl->get_Item(i, &piDisp);
818 ExitOnFailure(hr, "Failed to get object from collection");
819
820 hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj);
821 ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
822
823 // compare key
824 hr = piObj->get_Name(&vtVal);
825 ExitOnFailure(hr, "Failed to get key");
826
827 hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR);
828 ExitOnFailure(hr, "Failed to change variant type");
829
830 if (0 == lstrcmpW(vtVal.bstrVal, pwzName))
831 {
832 if (ppiObj)
833 {
834 *ppiObj = piObj;
835 piObj = NULL;
836 }
837 ExitFunction1(hr = S_OK);
838 }
839
840 // clean up
841 ReleaseNullObject(piDisp);
842 ReleaseNullObject(piObj);
843
844 ::VariantClear(&vtVal);
845 }
846
847 hr = S_FALSE;
848
849LExit:
850 // clean up
851 ReleaseObject(piDisp);
852 ReleaseObject(piObj);
853
854 ::VariantClear(&vtVal);
855
856 return hr;
857}
858
859HRESULT CpiFindUserCollectionObject(
860 ICatalogCollection* piColl,
861 PSID pSid,
862 ICatalogObject** ppiObj
863 )
864{
865 HRESULT hr = S_OK;
866
867 int i = 0;
868
869 IDispatch* piDisp = NULL;
870
871 // find index
872 hr = FindUserCollectionObjectIndex(piColl, pSid, &i);
873 ExitOnFailure(hr, "Failed to find user collection index");
874
875 if (S_FALSE == hr)
876 ExitFunction(); // not found, exit with hr = S_FALSE
877
878 // get object
879 if (ppiObj)
880 {
881 hr = piColl->get_Item(i, &piDisp);
882 ExitOnFailure(hr, "Failed to get object from collection");
883
884 hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)ppiObj);
885 ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
886 }
887
888 hr = S_OK;
889
890LExit:
891 // clean up
892 ReleaseObject(piDisp);
893
894 return hr;
895}
896
897HRESULT CpiExecGetPartitionsCollection(
898 ICatalogCollection** ppiPartColl
899 )
900{
901 HRESULT hr = S_OK;
902
903 // get collection
904 hr = CpiExecGetCatalogCollection(L"Partitions", ppiPartColl);
905 ExitOnFailure(hr, "Failed to get catalog collection");
906
907 hr = S_OK;
908
909LExit:
910 return hr;
911}
912
913HRESULT CpiGetPartitionRolesCollection(
914 LPCWSTR pwzPartID,
915 ICatalogCollection** ppiRolesColl
916 )
917{
918 HRESULT hr = S_OK;
919
920 ICatalogCollection* piPartColl = NULL;
921 ICatalogObject* piPartObj = NULL;
922
923 // get partitions collection
924 hr = CpiExecGetPartitionsCollection(&piPartColl);
925 ExitOnFailure(hr, "Failed to get partitions collection");
926
927 if (S_FALSE == hr)
928 ExitFunction(); // partitions collection not found, exit with hr = S_FALSE
929
930 // find object
931 hr = CpiFindCollectionObjectByStringKey(piPartColl, pwzPartID, &piPartObj);
932 ExitOnFailure(hr, "Failed to find collection object");
933
934 if (S_FALSE == hr)
935 ExitFunction(); // partition not found, exit with hr = S_FALSE
936
937 // get roles collection
938 hr = CpiExecGetCatalogCollection(piPartColl, piPartObj, L"RolesForPartition", ppiRolesColl);
939 ExitOnFailure(hr, "Failed to get catalog collection");
940
941 hr = S_OK;
942
943LExit:
944 // clean up
945 ReleaseObject(piPartColl);
946 ReleaseObject(piPartObj);
947
948 return hr;
949}
950
951HRESULT CpiGetUsersInPartitionRoleCollection(
952 LPCWSTR pwzPartID,
953 LPCWSTR pwzRoleName,
954 ICatalogCollection** ppiUsrInRoleColl
955 )
956{
957 HRESULT hr = S_OK;
958
959 ICatalogCollection* piRoleColl = NULL;
960 ICatalogObject* piRoleObj = NULL;
961
962 // get roles collection
963 hr = CpiGetPartitionRolesCollection(pwzPartID, &piRoleColl);
964 ExitOnFailure(hr, "Failed to get roles collection");
965
966 if (S_FALSE == hr)
967 ExitFunction(); // partition roles collection not found, exit with hr = S_FALSE
968
969 // find object
970 hr = CpiFindCollectionObjectByName(piRoleColl, pwzRoleName, &piRoleObj);
971 ExitOnFailure(hr, "Failed to find collection object");
972
973 if (S_FALSE == hr)
974 ExitFunction(); // user not found, exit with hr = S_FALSE
975
976 // get roles collection
977 hr = CpiExecGetCatalogCollection(piRoleColl, piRoleObj, L"UsersInPartitionRole", ppiUsrInRoleColl);
978 ExitOnFailure(hr, "Failed to get catalog collection");
979
980 hr = S_OK;
981
982LExit:
983 // clean up
984 ReleaseObject(piRoleColl);
985 ReleaseObject(piRoleObj);
986
987 return hr;
988}
989
990HRESULT CpiGetPartitionUsersCollection(
991 ICatalogCollection** ppiUserColl
992 )
993{
994 HRESULT hr = S_OK;
995
996 // get roles collection
997 hr = CpiExecGetCatalogCollection(L"PartitionUsers", ppiUserColl);
998 ExitOnFailure(hr, "Failed to get catalog collection");
999
1000 hr = S_OK;
1001
1002LExit:
1003 return hr;
1004}
1005
1006HRESULT CpiExecGetApplicationsCollection(
1007 LPCWSTR pwzPartID,
1008 ICatalogCollection** ppiAppColl
1009 )
1010{
1011 HRESULT hr = S_OK;
1012
1013 ICOMAdminCatalog* piCatalog = NULL;
1014 ICOMAdminCatalog2* piCatalog2 = NULL;
1015 BSTR bstrGlobPartID = NULL;
1016
1017 ICatalogCollection* piPartColl = NULL;
1018 ICatalogObject* piPartObj = NULL;
1019
1020 // get catalog
1021 hr = CpiExecGetAdminCatalog(&piCatalog);
1022 ExitOnFailure(hr, "Failed to get COM+ admin catalog");
1023
1024 // get ICOMAdminCatalog2 interface
1025 hr = piCatalog->QueryInterface(IID_ICOMAdminCatalog2, (void**)&piCatalog2);
1026
1027 // COM+ 1.5 or later
1028 if (E_NOINTERFACE != hr)
1029 {
1030 ExitOnFailure(hr, "Failed to get IID_ICOMAdminCatalog2 interface");
1031
1032 // partition id
1033 if (!pwzPartID || !*pwzPartID)
1034 {
1035 // get global partition id
1036 hr = piCatalog2->get_GlobalPartitionID(&bstrGlobPartID);
1037 ExitOnFailure(hr, "Failed to get global partition id");
1038 }
1039
1040 // get partitions collection
1041 hr = CpiExecGetPartitionsCollection(&piPartColl);
1042 ExitOnFailure(hr, "Failed to get partitions collection");
1043
1044 // find object
1045 hr = CpiFindCollectionObjectByStringKey(piPartColl, bstrGlobPartID ? bstrGlobPartID : pwzPartID, &piPartObj);
1046 ExitOnFailure(hr, "Failed to find collection object");
1047
1048 if (S_FALSE == hr)
1049 ExitFunction(); // partition not found, exit with hr = S_FALSE
1050
1051 // get applications collection
1052 hr = CpiExecGetCatalogCollection(piPartColl, piPartObj, L"Applications", ppiAppColl);
1053 ExitOnFailure(hr, "Failed to get catalog collection for partition");
1054 }
1055
1056 // COM+ pre 1.5
1057 else
1058 {
1059 // this version of COM+ does not support partitions, make sure a partition was not specified
1060 if (pwzPartID && *pwzPartID)
1061 ExitOnFailure(hr = E_FAIL, "Partitions are not supported by this version of COM+");
1062
1063 // get applications collection
1064 hr = CpiExecGetCatalogCollection(L"Applications", ppiAppColl);
1065 ExitOnFailure(hr, "Failed to get catalog collection");
1066 }
1067
1068 hr = S_OK;
1069
1070LExit:
1071 // clean up
1072 ReleaseObject(piCatalog);
1073 ReleaseObject(piCatalog2);
1074 ReleaseBSTR(bstrGlobPartID);
1075
1076 ReleaseObject(piPartColl);
1077 ReleaseObject(piPartObj);
1078
1079 return hr;
1080}
1081
1082HRESULT CpiGetRolesCollection(
1083 LPCWSTR pwzPartID,
1084 LPCWSTR pwzAppID,
1085 ICatalogCollection** ppiRolesColl
1086 )
1087{
1088 HRESULT hr = S_OK;
1089
1090 ICatalogCollection* piAppColl = NULL;
1091 ICatalogObject* piAppObj = NULL;
1092
1093 // get applications collection
1094 hr = CpiExecGetApplicationsCollection(pwzPartID, &piAppColl);
1095 ExitOnFailure(hr, "Failed to get applications collection");
1096
1097 if (S_FALSE == hr)
1098 ExitFunction(); // applications collection not found, exit with hr = S_FALSE
1099
1100 // find object
1101 hr = CpiFindCollectionObjectByStringKey(piAppColl, pwzAppID, &piAppObj);
1102 ExitOnFailure(hr, "Failed to find collection object");
1103
1104 if (S_FALSE == hr)
1105 ExitFunction(); // application not found, exit with hr = S_FALSE
1106
1107 // get roles collection
1108 hr = CpiExecGetCatalogCollection(piAppColl, piAppObj, L"Roles", ppiRolesColl);
1109 ExitOnFailure(hr, "Failed to catalog collection");
1110
1111 hr = S_OK;
1112
1113LExit:
1114 // clean up
1115 ReleaseObject(piAppColl);
1116 ReleaseObject(piAppObj);
1117
1118 return hr;
1119}
1120
1121HRESULT CpiGetUsersInRoleCollection(
1122 LPCWSTR pwzPartID,
1123 LPCWSTR pwzAppID,
1124 LPCWSTR pwzRoleName,
1125 ICatalogCollection** ppiUsrInRoleColl
1126 )
1127{
1128 HRESULT hr = S_OK;
1129
1130 ICatalogCollection* piRoleColl = NULL;
1131 ICatalogObject* piRoleObj = NULL;
1132
1133 // get roles collection
1134 hr = CpiGetRolesCollection(pwzPartID, pwzAppID, &piRoleColl);
1135 ExitOnFailure(hr, "Failed to get roles collection");
1136
1137 if (S_FALSE == hr)
1138 ExitFunction(); // roles collection not found, exit with hr = S_FALSE
1139
1140 // find object
1141 hr = CpiFindCollectionObjectByName(piRoleColl, pwzRoleName, &piRoleObj);
1142 ExitOnFailure(hr, "Failed to find collection object");
1143
1144 if (S_FALSE == hr)
1145 ExitFunction(); // role not found, exit with hr = S_FALSE
1146
1147 // get roles collection
1148 hr = CpiExecGetCatalogCollection(piRoleColl, piRoleObj, L"UsersInRole", ppiUsrInRoleColl);
1149 ExitOnFailure(hr, "Failed to get catalog collection");
1150
1151 hr = S_OK;
1152
1153LExit:
1154 // clean up
1155 ReleaseObject(piRoleColl);
1156 ReleaseObject(piRoleObj);
1157
1158 return hr;
1159}
1160
1161HRESULT CpiGetComponentsCollection(
1162 LPCWSTR pwzPartID,
1163 LPCWSTR pwzAppID,
1164 ICatalogCollection** ppiCompsColl
1165 )
1166{
1167 HRESULT hr = S_OK;
1168
1169 ICatalogCollection* piAppColl = NULL;
1170 ICatalogObject* piAppObj = NULL;
1171
1172 // get applications collection
1173 hr = CpiExecGetApplicationsCollection(pwzPartID, &piAppColl);
1174 ExitOnFailure(hr, "Failed to get applications collection");
1175
1176 if (S_FALSE == hr)
1177 ExitFunction(); // applications collection not found, exit with hr = S_FALSE
1178
1179 // find object
1180 hr = CpiFindCollectionObjectByStringKey(piAppColl, pwzAppID, &piAppObj);
1181 ExitOnFailure(hr, "Failed to find collection object");
1182
1183 if (S_FALSE == hr)
1184 ExitFunction(); // application not found, exit with hr = S_FALSE
1185
1186 // get components collection
1187 hr = CpiExecGetCatalogCollection(piAppColl, piAppObj, L"Components", ppiCompsColl);
1188 ExitOnFailure(hr, "Failed to get catalog collection");
1189
1190 hr = S_OK;
1191
1192LExit:
1193 // clean up
1194 ReleaseObject(piAppColl);
1195 ReleaseObject(piAppObj);
1196
1197 return hr;
1198}
1199
1200HRESULT CpiGetInterfacesCollection(
1201 ICatalogCollection* piCompColl,
1202 ICatalogObject* piCompObj,
1203 ICatalogCollection** ppiIntfColl
1204 )
1205{
1206 HRESULT hr = S_OK;
1207
1208 // get interfaces collection
1209 hr = CpiExecGetCatalogCollection(piCompColl, piCompObj, L"InterfacesForComponent", ppiIntfColl);
1210 ExitOnFailure(hr, "Failed to get catalog collection");
1211
1212 hr = S_OK;
1213
1214LExit:
1215 return hr;
1216}
1217
1218HRESULT CpiGetMethodsCollection(
1219 ICatalogCollection* piIntfColl,
1220 ICatalogObject* piIntfObj,
1221 ICatalogCollection** ppiMethColl
1222 )
1223{
1224 HRESULT hr = S_OK;
1225
1226 // get interfaces collection
1227 hr = CpiExecGetCatalogCollection(piIntfColl, piIntfObj, L"MethodsForInterface", ppiMethColl);
1228 ExitOnFailure(hr, "Failed to get catalog collection");
1229
1230 hr = S_OK;
1231
1232LExit:
1233 return hr;
1234}
1235
1236HRESULT CpiGetSubscriptionsCollection(
1237 LPCWSTR pwzPartID,
1238 LPCWSTR pwzAppID,
1239 LPCWSTR pwzCompCLSID,
1240 ICatalogCollection** ppiSubsColl
1241 )
1242{
1243 HRESULT hr = S_OK;
1244
1245 ICatalogCollection* piCompColl = NULL;
1246 ICatalogObject* piCompObj = NULL;
1247
1248 // get components collection
1249 hr = CpiGetComponentsCollection(pwzPartID, pwzAppID, &piCompColl);
1250 ExitOnFailure(hr, "Failed to get components collection");
1251
1252 if (S_FALSE == hr)
1253 ExitFunction(); // components collection not found, exit with hr = S_FALSE
1254
1255 // find object
1256 hr = CpiFindCollectionObjectByStringKey(piCompColl, pwzCompCLSID, &piCompObj);
1257 ExitOnFailure(hr, "Failed to find collection object");
1258
1259 if (S_FALSE == hr)
1260 ExitFunction(); // component not found, exit with hr = S_FALSE
1261
1262 // get subscriptions collection
1263 hr = CpiExecGetCatalogCollection(piCompColl, piCompObj, L"SubscriptionsForComponent", ppiSubsColl);
1264 ExitOnFailure(hr, "Failed to get catalog collection");
1265
1266 hr = S_OK;
1267
1268LExit:
1269 // clean up
1270 ReleaseObject(piCompColl);
1271 ReleaseObject(piCompObj);
1272
1273 return hr;
1274}
1275
1276HRESULT CpiReadPropertyList(
1277 LPWSTR* ppwzData,
1278 CPI_PROPERTY** ppPropList
1279 )
1280{
1281 HRESULT hr = S_OK;
1282
1283 CPI_PROPERTY* pItm = NULL;
1284 LPWSTR pwzName = NULL;
1285
1286 // clear list if it already contains items
1287 if (*ppPropList)
1288 CpiFreePropertyList(*ppPropList);
1289 *ppPropList = NULL;
1290
1291 // read property count
1292 int iPropCnt = 0;
1293 hr = WcaReadIntegerFromCaData(ppwzData, &iPropCnt);
1294 ExitOnFailure(hr, "Failed to read property count");
1295
1296 for (int i = 0; i < iPropCnt; i++)
1297 {
1298 // allocate new element
1299 pItm = (CPI_PROPERTY*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_PROPERTY));
1300 if (!pItm)
1301 ExitFunction1(hr = E_OUTOFMEMORY);
1302
1303 // Name
1304 hr = WcaReadStringFromCaData(ppwzData, &pwzName);
1305 ExitOnFailure(hr, "Failed to read name");
1306 StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzName);
1307
1308 // Value
1309 hr = WcaReadStringFromCaData(ppwzData, &pItm->pwzValue);
1310 ExitOnFailure(hr, "Failed to read property value");
1311
1312 // add to list
1313 if (*ppPropList)
1314 pItm->pNext = *ppPropList;
1315 *ppPropList = pItm;
1316 pItm = NULL;
1317 }
1318
1319 hr = S_OK;
1320
1321LExit:
1322 // clean up
1323 ReleaseStr(pwzName);
1324
1325 if (pItm)
1326 CpiFreePropertyList(pItm);
1327
1328 return hr;
1329}
1330
1331void CpiFreePropertyList(
1332 CPI_PROPERTY* pList
1333 )
1334{
1335 while (pList)
1336 {
1337 ReleaseStr(pList->pwzValue);
1338
1339 CPI_PROPERTY* pDelete = pList;
1340 pList = pList->pNext;
1341 ::HeapFree(::GetProcessHeap(), 0, pDelete);
1342 }
1343}
1344
1345HRESULT CpiWriteKeyToRollbackFile(
1346 HANDLE hFile,
1347 LPCWSTR pwzKey
1348 )
1349{
1350 HRESULT hr = S_OK;
1351
1352 WCHAR wzKey[MAX_DARWIN_KEY + 1];
1353 ::ZeroMemory(wzKey, sizeof(wzKey));
1354 hr = StringCchCopyW(wzKey, countof(wzKey), pwzKey);
1355 ExitOnFailure(hr, "Failed to copy key");
1356
1357 hr = WriteFileAll(hFile, (PBYTE)wzKey, MAX_DARWIN_KEY * sizeof(WCHAR));
1358 ExitOnFailure(hr, "Failed to write buffer");
1359
1360 FlushFileBuffers(hFile);
1361
1362 hr = S_OK;
1363
1364LExit:
1365 return hr;
1366}
1367
1368HRESULT CpiWriteIntegerToRollbackFile(
1369 HANDLE hFile,
1370 int i
1371 )
1372{
1373 HRESULT hr = S_OK;
1374
1375 hr = WriteFileAll(hFile, (PBYTE)&i, sizeof(int));
1376 ExitOnFailure(hr, "Failed to write buffer");
1377
1378 FlushFileBuffers(hFile);
1379
1380 hr = S_OK;
1381
1382LExit:
1383 return hr;
1384}
1385
1386HRESULT CpiReadRollbackDataList(
1387 HANDLE hFile,
1388 CPI_ROLLBACK_DATA** pprdList
1389 )
1390{
1391 HRESULT hr = S_OK;
1392
1393 int iCount;
1394
1395 CPI_ROLLBACK_DATA* pItm = NULL;
1396
1397 // read count
1398 hr = ReadFileAll(hFile, (PBYTE)&iCount, sizeof(int));
1399 if (HRESULT_FROM_WIN32(ERROR_HANDLE_EOF) == hr)
1400 ExitFunction1(hr = S_OK); // EOF reached, nothing left to read
1401 ExitOnFailure(hr, "Failed to read count");
1402
1403 for (int i = 0; i < iCount; i++)
1404 {
1405 // allocate new element
1406 pItm = (CPI_ROLLBACK_DATA*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_ROLLBACK_DATA));
1407 if (!pItm)
1408 ExitFunction1(hr = E_OUTOFMEMORY);
1409
1410 // read from file
1411 hr = ReadFileAll(hFile, (PBYTE)pItm->wzKey, MAX_DARWIN_KEY * sizeof(WCHAR));
1412 if (HRESULT_FROM_WIN32(ERROR_HANDLE_EOF) == hr)
1413 break; // EOF reached, nothing left to read
1414 ExitOnFailure(hr, "Failed to read key");
1415
1416 hr = ReadFileAll(hFile, (PBYTE)&pItm->iStatus, sizeof(int));
1417 if (HRESULT_FROM_WIN32(ERROR_HANDLE_EOF) == hr)
1418 pItm->iStatus = 0; // EOF reached, the operation was interupted; set status to zero
1419 else
1420 ExitOnFailure(hr, "Failed to read status");
1421
1422 // add to list
1423 if (*pprdList)
1424 pItm->pNext = *pprdList;
1425 *pprdList = pItm;
1426 pItm = NULL;
1427 }
1428
1429 hr = S_OK;
1430
1431LExit:
1432 // clean up
1433 if (pItm)
1434 CpiFreeRollbackDataList(pItm);
1435
1436 return hr;
1437}
1438
1439void CpiFreeRollbackDataList(
1440 CPI_ROLLBACK_DATA* pList
1441 )
1442{
1443 while (pList)
1444 {
1445 CPI_ROLLBACK_DATA* pDelete = pList;
1446 pList = pList->pNext;
1447 ::HeapFree(::GetProcessHeap(), 0, pDelete);
1448 }
1449}
1450
1451HRESULT CpiFindRollbackStatus(
1452 CPI_ROLLBACK_DATA* pList,
1453 LPCWSTR pwzKey,
1454 int* piStatus
1455 )
1456{
1457 HRESULT hr = S_OK;
1458
1459 for (; pList; pList = pList->pNext)
1460 {
1461 if (0 == lstrcmpW(pList->wzKey, pwzKey))
1462 {
1463 *piStatus = pList->iStatus;
1464 ExitFunction1(hr = S_OK);
1465 }
1466 }
1467
1468 hr = S_FALSE;
1469
1470LExit:
1471 return hr;
1472}
1473
1474HRESULT CpiAccountNameToSid(
1475 LPCWSTR pwzAccountName,
1476 PSID* ppSid
1477 )
1478{
1479 HRESULT hr = S_OK;
1480 UINT er = ERROR_SUCCESS;
1481 NTSTATUS st = 0;
1482
1483 PSID pSid = NULL;
1484 LSA_OBJECT_ATTRIBUTES loaAttributes;
1485 LSA_HANDLE lsahPolicy = NULL;
1486 LSA_UNICODE_STRING lusName;
1487 PLSA_REFERENCED_DOMAIN_LIST plrdsDomains = NULL;
1488 PLSA_TRANSLATED_SID pltsSid = NULL;
1489
1490 ::ZeroMemory(&loaAttributes, sizeof(loaAttributes));
1491 ::ZeroMemory(&lusName, sizeof(lusName));
1492
1493 // identify well known SIDs
1494 for (CPI_WELLKNOWN_SID* pWS = wsWellKnownSids; pWS->pwzName; pWS++)
1495 {
1496 if (0 == lstrcmpiW(pwzAccountName, pWS->pwzName))
1497 {
1498 // allocate SID buffer
1499 pSid = (PSID)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, ::GetSidLengthRequired(pWS->nSubAuthorityCount));
1500 ExitOnNull(pSid, hr, E_OUTOFMEMORY, "Failed to allocate buffer for SID");
1501
1502 // initialize SID
1503 ::InitializeSid(pSid, &pWS->iaIdentifierAuthority, pWS->nSubAuthorityCount);
1504
1505 // copy sub autorities
1506 for (DWORD i = 0; i < pWS->nSubAuthorityCount; i++)
1507 *::GetSidSubAuthority(pSid, i) = pWS->dwSubAuthority[i];
1508
1509 break;
1510 }
1511 }
1512
1513 // lookup name
1514 if (!pSid)
1515 {
1516 // open policy handle
1517 st = ::LsaOpenPolicy(NULL, &loaAttributes, POLICY_ALL_ACCESS, &lsahPolicy);
1518 er = ::LsaNtStatusToWinError(st);
1519 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to open policy handle");
1520
1521 // create account name lsa unicode string
1522 hr = InitLsaUnicodeString(&lusName, pwzAccountName, (DWORD)wcslen(pwzAccountName));
1523 ExitOnFailure(hr, "Failed to initialize account name string");
1524
1525 // lookup name
1526 st = ::LsaLookupNames(lsahPolicy, 1, &lusName, &plrdsDomains, &pltsSid);
1527 er = ::LsaNtStatusToWinError(st);
1528 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to lookup account names");
1529
1530 if (SidTypeDomain == pltsSid->Use)
1531 ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), "Domain SIDs not supported");
1532
1533 // convert sid
1534 hr = CreateSidFromDomainRidPair(plrdsDomains->Domains[pltsSid->DomainIndex].Sid, pltsSid->RelativeId, &pSid);
1535 ExitOnFailure(hr, "Failed to convert SID");
1536 }
1537
1538 *ppSid = pSid;
1539 pSid = NULL;
1540
1541 hr = S_OK;
1542
1543LExit:
1544 // clean up
1545 if (pSid)
1546 ::HeapFree(::GetProcessHeap(), 0, pSid);
1547 if (lsahPolicy)
1548 ::LsaClose(lsahPolicy);
1549 if (plrdsDomains)
1550 ::LsaFreeMemory(plrdsDomains);
1551 if (pltsSid)
1552 ::LsaFreeMemory(pltsSid);
1553 FreeLsaUnicodeString(&lusName);
1554
1555 return hr;
1556}
1557
1558HRESULT CpiSidToAccountName(
1559 PSID pSid,
1560 LPWSTR* ppwzAccountName
1561 )
1562{
1563 HRESULT hr = S_OK;
1564 UINT er = ERROR_SUCCESS;
1565 NTSTATUS st = 0;
1566
1567 LSA_OBJECT_ATTRIBUTES loaAttributes;
1568 LSA_HANDLE lsahPolicy = NULL;
1569 PLSA_REFERENCED_DOMAIN_LIST plrdsDomains = NULL;
1570 PLSA_TRANSLATED_NAME pltnName = NULL;
1571
1572 LPWSTR pwzDomain = NULL;
1573 LPWSTR pwzName = NULL;
1574
1575 ::ZeroMemory(&loaAttributes, sizeof(loaAttributes));
1576
1577 // open policy handle
1578 st = ::LsaOpenPolicy(NULL, &loaAttributes, POLICY_ALL_ACCESS, &lsahPolicy);
1579 er = ::LsaNtStatusToWinError(st);
1580 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to open policy handle");
1581
1582 // lookup SID
1583 st = ::LsaLookupSids(lsahPolicy, 1, &pSid, &plrdsDomains, &pltnName);
1584 er = ::LsaNtStatusToWinError(st);
1585 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed lookup SID");
1586
1587 if (SidTypeDomain == pltnName->Use)
1588 ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), "Domain SIDs not supported");
1589
1590 // format account name string
1591 if (SidTypeWellKnownGroup != pltnName->Use)
1592 {
1593 PLSA_UNICODE_STRING plusDomain = &plrdsDomains->Domains[pltnName->DomainIndex].Name;
1594 hr = StrAllocString(&pwzDomain, plusDomain->Buffer, plusDomain->Length / sizeof(WCHAR));
1595 ExitOnFailure(hr, "Failed to allocate name string");
1596 }
1597
1598 hr = StrAllocString(&pwzName, pltnName->Name.Buffer, pltnName->Name.Length / sizeof(WCHAR));
1599 ExitOnFailure(hr, "Failed to allocate domain string");
1600
1601 hr = StrAllocFormatted(ppwzAccountName, L"%s\\%s", pwzDomain ? pwzDomain : L"", pwzName);
1602 ExitOnFailure(hr, "Failed to format account name string");
1603
1604 hr = S_OK;
1605
1606LExit:
1607 // clean up
1608 if (lsahPolicy)
1609 ::LsaClose(lsahPolicy);
1610 if (plrdsDomains)
1611 ::LsaFreeMemory(plrdsDomains);
1612 if (pltnName)
1613 ::LsaFreeMemory(pltnName);
1614
1615 ReleaseStr(pwzDomain);
1616 ReleaseStr(pwzName);
1617
1618 return hr;
1619}
1620
1621// helper function definitions
1622
1623static HRESULT FindUserCollectionObjectIndex(
1624 ICatalogCollection* piColl,
1625 PSID pSid,
1626 int* pi
1627 )
1628{
1629 HRESULT hr = S_OK;
1630 UINT er = ERROR_SUCCESS;
1631 NTSTATUS st = 0;
1632
1633 long i = 0;
1634 long lCollCnt = 0;
1635
1636 LSA_OBJECT_ATTRIBUTES loaAttributes;
1637 LSA_HANDLE lsahPolicy = NULL;
1638 PLSA_UNICODE_STRING plusNames = NULL;
1639 PLSA_REFERENCED_DOMAIN_LIST plrdsDomains = NULL;
1640 PLSA_TRANSLATED_SID pltsSids = NULL;
1641
1642 IDispatch* piDisp = NULL;
1643 ICatalogObject* piObj = NULL;
1644 VARIANT vtVal;
1645
1646 PSID pTmpSid = NULL;
1647
1648 PLSA_TRANSLATED_SID pltsSid;
1649
1650 ::VariantInit(&vtVal);
1651 ::ZeroMemory(&loaAttributes, sizeof(loaAttributes));
1652
1653 // open policy handle
1654 st = ::LsaOpenPolicy(NULL, &loaAttributes, POLICY_ALL_ACCESS, &lsahPolicy);
1655 er = ::LsaNtStatusToWinError(st);
1656 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to open policy handle");
1657
1658 // get number of elements in collection
1659 hr = piColl->get_Count(&lCollCnt);
1660 ExitOnFailure(hr, "Failed to get to number of objects in collection");
1661
1662 if (0 == lCollCnt)
1663 ExitFunction1(hr = S_FALSE); // not found
1664
1665 // allocate name buffer
1666 plusNames = (PLSA_UNICODE_STRING)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LSA_UNICODE_STRING) * lCollCnt);
1667 ExitOnNull(plusNames, hr, E_OUTOFMEMORY, "Failed to allocate names buffer");
1668
1669 // get accounts in collection
1670 for (i = 0; i < lCollCnt; i++)
1671 {
1672 // get ICatalogObject interface
1673 hr = piColl->get_Item(i, &piDisp);
1674 ExitOnFailure(hr, "Failed to get object from collection");
1675
1676 hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj);
1677 ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
1678
1679 // get value
1680 hr = piObj->get_Key(&vtVal);
1681 ExitOnFailure(hr, "Failed to get key");
1682
1683 hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR);
1684 ExitOnFailure(hr, "Failed to change variant type");
1685
1686 // copy account name string
1687 hr = InitLsaUnicodeString(&plusNames[i], vtVal.bstrVal, ::SysStringLen(vtVal.bstrVal));
1688 ExitOnFailure(hr, "Failed to initialize account name string");
1689
1690 // clean up
1691 ReleaseNullObject(piDisp);
1692 ReleaseNullObject(piObj);
1693 ::VariantClear(&vtVal);
1694 }
1695
1696 // lookup names
1697 st = ::LsaLookupNames(lsahPolicy, lCollCnt, plusNames, &plrdsDomains, &pltsSids);
1698 er = ::LsaNtStatusToWinError(st);
1699 if (ERROR_NONE_MAPPED != er && ERROR_SOME_NOT_MAPPED != er)
1700 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to lookup account names");
1701
1702 // compare SIDs
1703 for (i = 0; i < lCollCnt; i++)
1704 {
1705 // get SID
1706 pltsSid = &pltsSids[i];
1707 if (SidTypeDomain == pltsSid->Use || SidTypeInvalid == pltsSid->Use || SidTypeUnknown == pltsSid->Use)
1708 continue; // ignore...
1709
1710 hr = CreateSidFromDomainRidPair(plrdsDomains->Domains[pltsSid->DomainIndex].Sid, pltsSid->RelativeId, &pTmpSid);
1711 ExitOnFailure(hr, "Failed to convert SID");
1712
1713 // compare SIDs
1714 if (::EqualSid(pSid, pTmpSid))
1715 {
1716 *pi = i;
1717 ExitFunction1(hr = S_OK);
1718 }
1719 }
1720
1721 if (ERROR_NONE_MAPPED == er || ERROR_SOME_NOT_MAPPED == er)
1722 hr = HRESULT_FROM_WIN32(er);
1723 else
1724 hr = S_FALSE; // not found
1725
1726LExit:
1727 // clean up
1728 ReleaseObject(piDisp);
1729 ReleaseObject(piObj);
1730 ::VariantClear(&vtVal);
1731
1732 if (plusNames)
1733 {
1734 for (i = 0; i < lCollCnt; i++)
1735 FreeLsaUnicodeString(&plusNames[i]);
1736 ::HeapFree(::GetProcessHeap(), 0, plusNames);
1737 }
1738
1739 if (lsahPolicy)
1740 ::LsaClose(lsahPolicy);
1741 if (plrdsDomains)
1742 ::LsaFreeMemory(plrdsDomains);
1743 if (pltsSids)
1744 ::LsaFreeMemory(pltsSids);
1745
1746 if (pTmpSid)
1747 ::HeapFree(::GetProcessHeap(), 0, pTmpSid);
1748
1749 return hr;
1750}
1751
1752static HRESULT CreateSidFromDomainRidPair(
1753 PSID pDomainSid,
1754 DWORD dwRid,
1755 PSID* ppSid
1756 )
1757{
1758 HRESULT hr = S_OK;
1759 PSID pSid = NULL;
1760
1761 // get domain SID sub authority count
1762 UCHAR ucSubAuthorityCount = *::GetSidSubAuthorityCount(pDomainSid);
1763
1764 // allocate SID buffer
1765 DWORD dwLengthRequired = ::GetSidLengthRequired(ucSubAuthorityCount + (UCHAR)1);
1766 if (*ppSid)
1767 {
1768 SIZE_T ccb = ::HeapSize(::GetProcessHeap(), 0, *ppSid);
1769 if (-1 == ccb)
1770 ExitOnFailure(hr = E_FAIL, "Failed to get size of SID buffer");
1771
1772 if (ccb < dwLengthRequired)
1773 {
1774 pSid = (PSID)::HeapReAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, *ppSid, dwLengthRequired);
1775 ExitOnNull(pSid, hr, E_OUTOFMEMORY, "Failed to reallocate buffer for SID, len: %d", dwLengthRequired);
1776 *ppSid = pSid;
1777 }
1778 }
1779 else
1780 {
1781 *ppSid = (PSID)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, dwLengthRequired);
1782 ExitOnNull(*ppSid, hr, E_OUTOFMEMORY, "Failed to allocate buffer for SID, len: %d", dwLengthRequired);
1783 }
1784
1785 ::InitializeSid(*ppSid, ::GetSidIdentifierAuthority(pDomainSid), ucSubAuthorityCount + (UCHAR)1);
1786
1787 // copy sub autorities
1788 DWORD i = 0;
1789 for (; i < ucSubAuthorityCount; i++)
1790 *::GetSidSubAuthority(*ppSid, i) = *::GetSidSubAuthority(pDomainSid, i);
1791 *::GetSidSubAuthority(*ppSid, i) = dwRid;
1792
1793 hr = S_OK;
1794
1795LExit:
1796 return hr;
1797}
1798
1799static HRESULT InitLsaUnicodeString(
1800 PLSA_UNICODE_STRING plusStr,
1801 LPCWSTR pwzStr,
1802 DWORD dwLen
1803 )
1804{
1805 HRESULT hr = S_OK;
1806
1807 plusStr->Length = (USHORT)dwLen * sizeof(WCHAR);
1808 plusStr->MaximumLength = (USHORT)(dwLen + 1) * sizeof(WCHAR);
1809
1810 plusStr->Buffer = (WCHAR*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR) * (dwLen + 1));
1811 ExitOnNull(plusStr->Buffer, hr, E_OUTOFMEMORY, "Failed to allocate account name string");
1812
1813 hr = StringCchCopyW(plusStr->Buffer, dwLen + 1, pwzStr);
1814 ExitOnFailure(hr, "Failed to copy buffer");
1815
1816 hr = S_OK;
1817
1818LExit:
1819 return hr;
1820}
1821
1822static void FreeLsaUnicodeString(
1823 PLSA_UNICODE_STRING plusStr
1824 )
1825{
1826 if (plusStr->Buffer)
1827 ::HeapFree(::GetProcessHeap(), 0, plusStr->Buffer);
1828}
1829
1830static HRESULT WriteFileAll(
1831 HANDLE hFile,
1832 PBYTE pbBuffer,
1833 DWORD dwBufferLength
1834 )
1835{
1836 HRESULT hr = S_OK;
1837
1838 DWORD dwBytesWritten;
1839
1840 while (dwBufferLength)
1841 {
1842 if (!::WriteFile(hFile, pbBuffer, dwBufferLength, &dwBytesWritten, NULL))
1843 ExitFunction1(hr = HRESULT_FROM_WIN32(::GetLastError()));
1844
1845 dwBufferLength -= dwBytesWritten;
1846 pbBuffer += dwBytesWritten;
1847 }
1848
1849 hr = S_OK;
1850
1851LExit:
1852 return hr;
1853}
1854
1855static HRESULT ReadFileAll(
1856 HANDLE hFile,
1857 PBYTE pbBuffer,
1858 DWORD dwBufferLength
1859 )
1860{
1861 HRESULT hr = S_OK;
1862
1863 DWORD dwBytesRead;
1864
1865 while (dwBufferLength)
1866 {
1867 if (!::ReadFile(hFile, pbBuffer, dwBufferLength, &dwBytesRead, NULL))
1868 ExitFunction1(hr = HRESULT_FROM_WIN32(::GetLastError()));
1869
1870 if (0 == dwBytesRead)
1871 ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_HANDLE_EOF));
1872
1873 dwBufferLength -= dwBytesRead;
1874 pbBuffer += dwBytesRead;
1875 }
1876
1877 hr = S_OK;
1878
1879LExit:
1880 return hr;
1881}
diff --git a/src/ext/ComPlus/ca/cputilexec.h b/src/ext/ComPlus/ca/cputilexec.h
new file mode 100644
index 00000000..b900883d
--- /dev/null
+++ b/src/ext/ComPlus/ca/cputilexec.h
@@ -0,0 +1,193 @@
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 CPI_MAX_GUID 38
6
7enum eActionType { atNoOp = 0, atCreate, atRemove };
8
9
10// structs
11
12struct CPI_PROPERTY
13{
14 WCHAR wzName[MAX_DARWIN_KEY + 1];
15 LPWSTR pwzValue;
16
17 CPI_PROPERTY* pNext;
18};
19
20struct CPI_ROLLBACK_DATA
21{
22 WCHAR wzKey[MAX_DARWIN_KEY + 1];
23 int iStatus;
24
25 CPI_ROLLBACK_DATA* pNext;
26};
27
28
29// function prototypes
30
31void CpiExecInitialize();
32void CpiExecFinalize();
33HRESULT CpiActionStartMessage(
34 LPWSTR* ppwzActionData,
35 BOOL fSuppress
36 );
37HRESULT CpiActionDataMessage(
38 DWORD cArgs,
39 ...
40 );
41HRESULT CpiExecGetAdminCatalog(
42 ICOMAdminCatalog** ppiCatalog
43 );
44HRESULT CpiLogCatalogErrorInfo();
45HRESULT CpiExecGetCatalogCollection(
46 LPCWSTR pwzName,
47 ICatalogCollection** ppiColl
48 );
49HRESULT CpiExecGetCatalogCollection(
50 ICatalogCollection* piColl,
51 ICatalogObject* piObj,
52 LPCWSTR pwzName,
53 ICatalogCollection** ppiColl
54 );
55HRESULT CpiAddCollectionObject(
56 ICatalogCollection* piColl,
57 ICatalogObject** ppiObj
58 );
59HRESULT CpiPutCollectionObjectValue(
60 ICatalogObject* piObj,
61 LPCWSTR pwzPropName,
62 LPCWSTR pwzValue
63 );
64HRESULT CpiPutCollectionObjectValues(
65 ICatalogObject* piObj,
66 CPI_PROPERTY* pPropList
67 );
68HRESULT CpiGetCollectionObjectValue(
69 ICatalogObject* piObj,
70 LPCWSTR szPropName,
71 LPWSTR* ppwzValue
72 );
73HRESULT CpiResetObjectProperty(
74 ICatalogCollection* piColl,
75 ICatalogObject* piObj,
76 LPCWSTR pwzPropName
77 );
78HRESULT CpiRemoveCollectionObject(
79 ICatalogCollection* piColl,
80 LPCWSTR pwzID,
81 LPCWSTR pwzName,
82 BOOL fResetDeleteable
83 );
84HRESULT CpiRemoveUserCollectionObject(
85 ICatalogCollection* piColl,
86 PSID pSid
87 );
88HRESULT CpiFindCollectionObjectByStringKey(
89 ICatalogCollection* piColl,
90 LPCWSTR pwzKey,
91 ICatalogObject** ppiObj
92 );
93HRESULT CpiFindCollectionObjectByIntegerKey(
94 ICatalogCollection* piColl,
95 long lKey,
96 ICatalogObject** ppiObj
97 );
98HRESULT CpiFindCollectionObjectByName(
99 ICatalogCollection* piColl,
100 LPCWSTR pwzName,
101 ICatalogObject** ppiObj
102 );
103HRESULT CpiFindUserCollectionObject(
104 ICatalogCollection* piColl,
105 PSID pSid,
106 ICatalogObject** ppiObj
107 );
108HRESULT CpiExecGetPartitionsCollection(
109 ICatalogCollection** ppiPartColl
110 );
111HRESULT CpiGetPartitionRolesCollection(
112 LPCWSTR pwzPartID,
113 ICatalogCollection** ppiRolesColl
114 );
115HRESULT CpiGetUsersInPartitionRoleCollection(
116 LPCWSTR pwzPartID,
117 LPCWSTR pwzRoleName,
118 ICatalogCollection** ppiUsrInRoleColl
119 );
120HRESULT CpiGetPartitionUsersCollection(
121 ICatalogCollection** ppiUserColl
122 );
123HRESULT CpiExecGetApplicationsCollection(
124 LPCWSTR pwzPartID,
125 ICatalogCollection** ppiAppColl
126 );
127HRESULT CpiGetRolesCollection(
128 LPCWSTR pwzPartID,
129 LPCWSTR pwzAppID,
130 ICatalogCollection** ppiRolesColl
131 );
132HRESULT CpiGetUsersInRoleCollection(
133 LPCWSTR pwzPartID,
134 LPCWSTR pwzAppID,
135 LPCWSTR pwzRoleName,
136 ICatalogCollection** ppiUsrInRoleColl
137 );
138HRESULT CpiGetComponentsCollection(
139 LPCWSTR pwzPartID,
140 LPCWSTR pwzAppID,
141 ICatalogCollection** ppiCompsColl
142 );
143HRESULT CpiGetInterfacesCollection(
144 ICatalogCollection* piCompColl,
145 ICatalogObject* piCompObj,
146 ICatalogCollection** ppiIntfColl
147 );
148HRESULT CpiGetMethodsCollection(
149 ICatalogCollection* piIntfColl,
150 ICatalogObject* piIntfObj,
151 ICatalogCollection** ppiMethColl
152 );
153HRESULT CpiGetSubscriptionsCollection(
154 LPCWSTR pwzPartID,
155 LPCWSTR pwzAppID,
156 LPCWSTR pwzCompCLSID,
157 ICatalogCollection** ppiCompsColl
158 );
159HRESULT CpiReadPropertyList(
160 LPWSTR* ppwzData,
161 CPI_PROPERTY** ppPropList
162 );
163void CpiFreePropertyList(
164 CPI_PROPERTY* pList
165 );
166HRESULT CpiWriteKeyToRollbackFile(
167 HANDLE hFile,
168 LPCWSTR pwzKey
169 );
170HRESULT CpiWriteIntegerToRollbackFile(
171 HANDLE hFile,
172 int i
173 );
174HRESULT CpiReadRollbackDataList(
175 HANDLE hFile,
176 CPI_ROLLBACK_DATA** pprdList
177 );
178void CpiFreeRollbackDataList(
179 CPI_ROLLBACK_DATA* pList
180 );
181HRESULT CpiFindRollbackStatus(
182 CPI_ROLLBACK_DATA* pList,
183 LPCWSTR pwzKey,
184 int* piStatus
185 );
186HRESULT CpiAccountNameToSid(
187 LPCWSTR pwzAccountName,
188 PSID* ppSid
189 );
190HRESULT CpiSidToAccountName(
191 PSID pSid,
192 LPWSTR* ppwzAccountName
193 );
diff --git a/src/ext/ComPlus/ca/cputilsched.cpp b/src/ext/ComPlus/ca/cputilsched.cpp
new file mode 100644
index 00000000..1a958c56
--- /dev/null
+++ b/src/ext/ComPlus/ca/cputilsched.cpp
@@ -0,0 +1,885 @@
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// sql queries
7
8LPCWSTR vcsActionTextQuery =
9 L"SELECT `Description`, `Template` FROM `ActionText` WHERE `Action` = ?";
10enum eActionTextQuery { atqDescription = 1, atqTemplate };
11
12LPCWSTR vcsComponentAttributesQuery =
13 L"SELECT `Attributes` FROM `Component` WHERE `Component` = ?";
14enum eComponentAttributesQuery { caqAttributes = 1 };
15
16LPCWSTR vcsUserQuery = L"SELECT `Domain`, `Name` FROM `User` WHERE `User` = ?";
17enum eUserQuery { uqDomain = 1, uqName };
18
19enum ePropertyQuery { pqName = 1, pqValue };
20
21
22// prototypes for private helper functions
23
24static HRESULT FindPropertyDefinition(
25 CPI_PROPERTY_DEFINITION* pPropDefList,
26 LPCWSTR pwzName,
27 CPI_PROPERTY_DEFINITION** ppPropDef
28 );
29static HRESULT GetUserAccountName(
30 LPCWSTR pwzKey,
31 LPWSTR* ppwzAccount
32 );
33
34
35// variables
36
37static ICOMAdminCatalog* gpiCatalog;
38static ICatalogCollection* gpiPartColl;
39static ICatalogCollection* gpiAppColl;
40
41static int giTables;
42
43
44// function definitions
45
46void CpiSchedInitialize()
47{
48 // collections
49 gpiCatalog = NULL;
50 gpiPartColl = NULL;
51 gpiAppColl = NULL;
52
53 // tables
54 giTables = 0;
55
56 if (S_OK == WcaTableExists(L"ComPlusPartition")) giTables |= cptComPlusPartition;
57 if (S_OK == WcaTableExists(L"ComPlusPartitionProperty")) giTables |= cptComPlusPartitionProperty;
58 if (S_OK == WcaTableExists(L"ComPlusPartitionRole")) giTables |= cptComPlusPartitionRole;
59 if (S_OK == WcaTableExists(L"ComPlusUserInPartitionRole")) giTables |= cptComPlusUserInPartitionRole;
60 if (S_OK == WcaTableExists(L"ComPlusGroupInPartitionRole")) giTables |= cptComPlusGroupInPartitionRole;
61 if (S_OK == WcaTableExists(L"ComPlusPartitionUser")) giTables |= cptComPlusPartitionUser;
62 if (S_OK == WcaTableExists(L"ComPlusApplication")) giTables |= cptComPlusApplication;
63 if (S_OK == WcaTableExists(L"ComPlusApplicationProperty")) giTables |= cptComPlusApplicationProperty;
64 if (S_OK == WcaTableExists(L"ComPlusApplicationRole")) giTables |= cptComPlusApplicationRole;
65 if (S_OK == WcaTableExists(L"ComPlusApplicationRoleProperty")) giTables |= cptComPlusApplicationRoleProperty;
66 if (S_OK == WcaTableExists(L"ComPlusUserInApplicationRole")) giTables |= cptComPlusUserInApplicationRole;
67 if (S_OK == WcaTableExists(L"ComPlusGroupInApplicationRole")) giTables |= cptComPlusGroupInApplicationRole;
68 if (S_OK == WcaTableExists(L"ComPlusAssembly")) giTables |= cptComPlusAssembly;
69 if (S_OK == WcaTableExists(L"ComPlusAssemblyDependency")) giTables |= cptComPlusAssemblyDependency;
70 if (S_OK == WcaTableExists(L"ComPlusComponent")) giTables |= cptComPlusComponent;
71 if (S_OK == WcaTableExists(L"ComPlusComponentProperty")) giTables |= cptComPlusComponentProperty;
72 if (S_OK == WcaTableExists(L"ComPlusRoleForComponent")) giTables |= cptComPlusRoleForComponent;
73 if (S_OK == WcaTableExists(L"ComPlusInterface")) giTables |= cptComPlusInterface;
74 if (S_OK == WcaTableExists(L"ComPlusInterfaceProperty")) giTables |= cptComPlusInterfaceProperty;
75 if (S_OK == WcaTableExists(L"ComPlusRoleForInterface")) giTables |= cptComPlusRoleForInterface;
76 if (S_OK == WcaTableExists(L"ComPlusMethod")) giTables |= cptComPlusMethod;
77 if (S_OK == WcaTableExists(L"ComPlusMethodProperty")) giTables |= cptComPlusMethodProperty;
78 if (S_OK == WcaTableExists(L"ComPlusRoleForMethod")) giTables |= cptComPlusRoleForMethod;
79 if (S_OK == WcaTableExists(L"ComPlusSubscription")) giTables |= cptComPlusSubscription;
80 if (S_OK == WcaTableExists(L"ComPlusSubscriptionProperty")) giTables |= cptComPlusSubscriptionProperty;
81}
82
83void CpiSchedFinalize()
84{
85 // collections
86 ReleaseObject(gpiCatalog);
87 ReleaseObject(gpiPartColl);
88 ReleaseObject(gpiAppColl);
89}
90
91BOOL CpiTableExists(
92 int iTable
93 )
94{
95 return (giTables & iTable) == iTable;
96}
97
98HRESULT CpiSchedGetAdminCatalog(
99 ICOMAdminCatalog** ppiCatalog
100 )
101{
102 HRESULT hr = S_OK;
103
104 if (!gpiCatalog)
105 {
106 // get collection
107 hr = ::CoCreateInstance(CLSID_COMAdminCatalog, NULL, CLSCTX_ALL, IID_ICOMAdminCatalog, (void**)&gpiCatalog);
108 ExitOnFailure(hr, "Failed to create COM+ admin catalog object");
109 }
110
111 // return value
112 gpiCatalog->AddRef();
113 *ppiCatalog = gpiCatalog;
114
115 hr = S_OK;
116
117LExit:
118 return hr;
119}
120
121HRESULT CpiSchedGetCatalogCollection(
122 LPCWSTR pwzName,
123 ICatalogCollection** ppiColl
124 )
125{
126 HRESULT hr = S_OK;
127
128 ICOMAdminCatalog* piCatalog = NULL;
129 IDispatch* piDisp = NULL;
130 BSTR bstrName = NULL;
131
132 // copy name string
133 bstrName = ::SysAllocString(pwzName);
134 ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for collection name");
135
136 // get catalog
137 hr = CpiSchedGetAdminCatalog(&piCatalog);
138 ExitOnFailure(hr, "Failed to get COM+ admin catalog");
139
140 // get collecton from catalog
141 hr = piCatalog->GetCollection(bstrName, &piDisp);
142 ExitOnFailure(hr, "Failed to get collection");
143
144 hr = piDisp->QueryInterface(IID_ICatalogCollection, (void**)ppiColl);
145 ExitOnFailure(hr, "Failed to get IID_ICatalogCollection interface");
146
147 // populate collection
148 hr = (*ppiColl)->Populate();
149 ExitOnFailure(hr, "Failed to populate collection");
150
151 hr = S_OK;
152
153LExit:
154 // clean up
155 ReleaseObject(piCatalog);
156 ReleaseObject(piDisp);
157 ReleaseBSTR(bstrName);
158
159 return hr;
160}
161
162HRESULT CpiSchedGetCatalogCollection(
163 ICatalogCollection* piColl,
164 ICatalogObject* piObj,
165 LPCWSTR pwzName,
166 ICatalogCollection** ppiColl
167 )
168{
169 HRESULT hr = S_OK;
170
171 ICOMAdminCatalog* piCatalog = NULL;
172 IDispatch* piDisp = NULL;
173 BSTR bstrName = NULL;
174
175 VARIANT vtKey;
176 ::VariantInit(&vtKey);
177
178 // copy name string
179 bstrName = ::SysAllocString(pwzName);
180 ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for collection name");
181
182 // get catalog
183 hr = CpiSchedGetAdminCatalog(&piCatalog);
184 ExitOnFailure(hr, "Failed to get COM+ admin catalog");
185
186 // get key
187 hr = piObj->get_Key(&vtKey);
188 ExitOnFailure(hr, "Failed to get object key");
189
190 // get collecton from catalog
191 hr = piColl->GetCollection(bstrName, vtKey, &piDisp);
192 ExitOnFailure(hr, "Failed to get collection");
193
194 hr = piDisp->QueryInterface(IID_ICatalogCollection, (void**)ppiColl);
195 ExitOnFailure(hr, "Failed to get IID_ICatalogCollection interface");
196
197 // populate collection
198 hr = (*ppiColl)->Populate();
199 ExitOnFailure(hr, "Failed to populate collection");
200
201 hr = S_OK;
202
203LExit:
204 // clean up
205 ReleaseObject(piCatalog);
206 ReleaseObject(piDisp);
207 ReleaseBSTR(bstrName);
208 ::VariantClear(&vtKey);
209
210 return hr;
211}
212
213HRESULT CpiGetKeyForObject(
214 ICatalogObject* piObj,
215 LPWSTR pwzKey,
216 SIZE_T cchKey
217 )
218{
219 HRESULT hr = S_OK;
220
221 VARIANT vtKey;
222 ::VariantInit(&vtKey);
223
224 // get key
225 hr = piObj->get_Key(&vtKey);
226 ExitOnFailure(hr, "Failed to get key");
227
228 // change variant type
229 hr = ::VariantChangeType(&vtKey, &vtKey, 0, VT_BSTR);
230 ExitOnFailure(hr, "Failed to change variant type");
231
232 // copy key
233 hr = StringCchCopyW(pwzKey, cchKey, vtKey.bstrVal);
234 ExitOnFailure(hr, "Failed to copy key");
235
236 hr = S_OK;
237
238LExit:
239 // clean up
240 ::VariantClear(&vtKey);
241
242 return hr;
243}
244
245HRESULT CpiFindCollectionObject(
246 ICatalogCollection* piColl,
247 LPCWSTR pwzID,
248 LPCWSTR pwzName,
249 ICatalogObject** ppiObj
250 )
251{
252 HRESULT hr = S_OK;
253
254 IDispatch* piDisp = NULL;
255 ICatalogObject* piObj = NULL;
256
257 VARIANT vtVal;
258 ::VariantInit(&vtVal);
259
260 long lCnt;
261 hr = piColl->get_Count(&lCnt);
262 ExitOnFailure(hr, "Failed to get to number of items in collection");
263
264 for (long i = 0; i < lCnt; i++)
265 {
266 // get ICatalogObject interface
267 hr = piColl->get_Item(i, &piDisp);
268 ExitOnFailure(hr, "Failed to get object from collection");
269
270 hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj);
271 ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
272
273 // compare id
274 if (pwzID && *pwzID)
275 {
276 hr = piObj->get_Key(&vtVal);
277 ExitOnFailure(hr, "Failed to get key");
278
279 hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR);
280 ExitOnFailure(hr, "Failed to change variant type");
281
282 if (0 == lstrcmpiW(vtVal.bstrVal, pwzID))
283 {
284 if (ppiObj)
285 {
286 *ppiObj = piObj;
287 piObj = NULL;
288 }
289 ExitFunction1(hr = S_OK);
290 }
291
292 ::VariantClear(&vtVal);
293 }
294
295 // compare name
296 if (pwzName && *pwzName)
297 {
298 hr = piObj->get_Name(&vtVal);
299 ExitOnFailure(hr, "Failed to get name");
300
301 hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR);
302 ExitOnFailure(hr, "Failed to change variant type");
303
304 if (0 == lstrcmpW(vtVal.bstrVal, pwzName))
305 {
306 if (ppiObj)
307 {
308 *ppiObj = piObj;
309 piObj = NULL;
310 }
311 ExitFunction1(hr = S_OK);
312 }
313
314 ::VariantClear(&vtVal);
315 }
316
317 // release interface pointers
318 ReleaseNullObject(piDisp);
319 ReleaseNullObject(piObj);
320 }
321
322 hr = S_FALSE;
323
324LExit:
325 // clean up
326 ReleaseObject(piDisp);
327 ReleaseObject(piObj);
328
329 ::VariantClear(&vtVal);
330
331 return hr;
332}
333
334HRESULT CpiSchedGetPartitionsCollection(
335 ICatalogCollection** ppiPartColl
336 )
337{
338 HRESULT hr = S_OK;
339
340 if (!gpiPartColl)
341 {
342 // get collection
343 hr = CpiSchedGetCatalogCollection(L"Partitions", &gpiPartColl);
344 ExitOnFailure(hr, "Failed to get partitions collection");
345 }
346
347 // return value
348 gpiPartColl->AddRef();
349 *ppiPartColl = gpiPartColl;
350
351 hr = S_OK;
352
353LExit:
354 return hr;
355}
356
357HRESULT CpiSchedGetApplicationsCollection(
358 ICatalogCollection** ppiAppColl
359 )
360{
361 HRESULT hr = S_OK;
362
363 ICOMAdminCatalog* piCatalog = NULL;
364 ICOMAdminCatalog2* piCatalog2 = NULL;
365 ICatalogCollection* piPartColl = NULL;
366 ICatalogObject* piPartObj = NULL;
367 BSTR bstrGlobPartID = NULL;
368
369 if (!gpiAppColl)
370 {
371 // get catalog
372 hr = CpiSchedGetAdminCatalog(&piCatalog);
373 ExitOnFailure(hr, "Failed to get COM+ admin catalog");
374
375 // get ICOMAdminCatalog2 interface
376 hr = piCatalog->QueryInterface(IID_ICOMAdminCatalog2, (void**)&piCatalog2);
377
378 // COM+ 1.5 or later
379 if (E_NOINTERFACE != hr)
380 {
381 ExitOnFailure(hr, "Failed to get IID_ICOMAdminCatalog2 interface");
382
383 // get global partition id
384 hr = piCatalog2->get_GlobalPartitionID(&bstrGlobPartID);
385 ExitOnFailure(hr, "Failed to get global partition id");
386
387 // get partitions collection
388 hr = CpiSchedGetPartitionsCollection(&piPartColl);
389 ExitOnFailure(hr, "Failed to get partitions collection");
390
391 // find object
392 hr = CpiFindCollectionObject(piPartColl, bstrGlobPartID, NULL, &piPartObj);
393 ExitOnFailure(hr, "Failed to find collection object");
394
395 if (S_FALSE == hr)
396 ExitFunction(); // partition not found, exit with hr = S_FALSE
397
398 // get applications collection
399 hr = CpiSchedGetCatalogCollection(piPartColl, piPartObj, L"Applications", &gpiAppColl);
400 ExitOnFailure(hr, "Failed to get applications collection");
401 }
402
403 // COM+ pre 1.5
404 else
405 {
406 // get applications collection
407 hr = CpiSchedGetCatalogCollection(L"Applications", &gpiAppColl);
408 ExitOnFailure(hr, "Failed to get applications collection");
409 }
410 }
411
412 // return value
413 gpiAppColl->AddRef();
414 *ppiAppColl = gpiAppColl;
415
416 hr = S_OK;
417
418LExit:
419 // clean up
420 ReleaseObject(piCatalog);
421 ReleaseObject(piCatalog2);
422 ReleaseObject(piPartColl);
423 ReleaseObject(piPartObj);
424 ReleaseBSTR(bstrGlobPartID);
425
426 return hr;
427}
428
429HRESULT CpiAddActionTextToActionData(
430 LPCWSTR pwzAction,
431 LPWSTR* ppwzActionData
432 )
433{
434 HRESULT hr = S_OK;
435
436 PMSIHANDLE hView, hRecKey, hRec;
437
438 LPWSTR pwzDescription = NULL;
439 LPWSTR pwzTemplate = NULL;
440
441 if (S_OK == WcaTableExists(L"ActionText"))
442 {
443 // create parameter record
444 hRecKey = ::MsiCreateRecord(1);
445 ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
446 hr = WcaSetRecordString(hRecKey, 1, pwzAction);
447 ExitOnFailure(hr, "Failed to set record string");
448
449 // open view
450 hr = WcaOpenView(vcsActionTextQuery, &hView);
451 ExitOnFailure(hr, "Failed to open view on ActionText table");
452 hr = WcaExecuteView(hView, hRecKey);
453 ExitOnFailure(hr, "Failed to execute view on ActionText table");
454
455 // fetch record
456 hr = WcaFetchSingleRecord(hView, &hRec);
457 if (S_FALSE != hr)
458 {
459 ExitOnFailure(hr, "Failed to fetch action text record");
460
461 // get description
462 hr = WcaGetRecordString(hRec, atqDescription, &pwzDescription);
463 ExitOnFailure(hr, "Failed to get description");
464
465 // get template
466 hr = WcaGetRecordString(hRec, atqTemplate, &pwzTemplate);
467 ExitOnFailure(hr, "Failed to get template");
468 }
469 }
470
471 // add action name to action data
472 hr = WcaWriteStringToCaData(pwzAction, ppwzActionData);
473 ExitOnFailure(hr, "Failed to add action name to custom action data");
474
475 // add description to action data
476 hr = WcaWriteStringToCaData(pwzDescription ? pwzDescription : L"", ppwzActionData);
477 ExitOnFailure(hr, "Failed to add description to custom action data");
478
479 // add template to action data
480 hr = WcaWriteStringToCaData(pwzTemplate ? pwzTemplate : L"", ppwzActionData);
481 ExitOnFailure(hr, "Failed to add template to custom action data");
482
483 hr = S_OK;
484
485LExit:
486 // clean up
487 ReleaseStr(pwzDescription);
488 ReleaseStr(pwzTemplate);
489
490 return hr;
491}
492
493HRESULT CpiVerifyComponentArchitecure(
494 LPCWSTR pwzComponent,
495 BOOL* pfMatchingArchitecture
496 )
497{
498 HRESULT hr = S_OK;
499
500 PMSIHANDLE hView, hRecKey, hRec;
501
502 int iAttributes = 0;
503
504 if (S_OK == WcaTableExists(L"Component"))
505 {
506 // create parameter record
507 hRecKey = ::MsiCreateRecord(1);
508 ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
509 hr = WcaSetRecordString(hRecKey, 1, pwzComponent);
510 ExitOnFailure(hr, "Failed to set record string");
511
512 // open view
513 hr = WcaOpenView(vcsComponentAttributesQuery, &hView);
514 ExitOnFailure(hr, "Failed to open view on ActionText table");
515 hr = WcaExecuteView(hView, hRecKey);
516 ExitOnFailure(hr, "Failed to execute view on ActionText table");
517
518 // fetch record
519 hr = WcaFetchSingleRecord(hView, &hRec);
520 if (S_FALSE != hr)
521 {
522 ExitOnFailure(hr, "Failed to fetch component record");
523
524 hr = WcaGetRecordInteger(hRec, caqAttributes, &iAttributes);
525 ExitOnFailure(hr, "Failed to get component attributes");
526 }
527 }
528
529 // return values
530#ifdef _WIN64
531 *pfMatchingArchitecture = 256 == (iAttributes & 256);
532#else
533 *pfMatchingArchitecture = 256 != (iAttributes & 256);
534#endif
535
536 hr = S_OK;
537
538LExit:
539 return hr;
540}
541
542HRESULT CpiPropertiesRead(
543 LPCWSTR pwzQuery,
544 LPCWSTR pwzKey,
545 CPI_PROPERTY_DEFINITION* pPropDefList,
546 CPI_PROPERTY** ppPropList,
547 int* piCount
548 )
549{
550 HRESULT hr = S_OK;
551
552 PMSIHANDLE hView, hRecKey, hRec;
553
554 CPI_PROPERTY* pItm = NULL;
555 LPWSTR pwzData = NULL;
556
557 int iVersionNT = 0;
558
559 CPI_PROPERTY_DEFINITION* pPropDef;
560
561 *piCount = 0;
562
563 // get NT version
564 hr = WcaGetIntProperty(L"VersionNT", &iVersionNT);
565 ExitOnFailure(hr, "Failed to set record string");
566
567 // create parameter record
568 hRecKey = ::MsiCreateRecord(1);
569 ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
570 hr = WcaSetRecordString(hRecKey, 1, pwzKey);
571 ExitOnFailure(hr, "Failed to set record string");
572
573 // open view
574 hr = WcaOpenView(pwzQuery, &hView);
575 ExitOnFailure(hr, "Failed to open view on property table");
576 hr = WcaExecuteView(hView, hRecKey);
577 ExitOnFailure(hr, "Failed to execute view on property table");
578
579 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
580 {
581 // create entry
582 pItm = (CPI_PROPERTY*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_PROPERTY));
583 if (!pItm)
584 ExitFunction1(hr = E_OUTOFMEMORY);
585
586 // get name
587 hr = WcaGetRecordString(hRec, pqName, &pwzData);
588 ExitOnFailure(hr, "Failed to get name");
589 StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData);
590
591 // get value
592 hr = WcaGetRecordFormattedString(hRec, pqValue, &pItm->pwzValue);
593 ExitOnFailure(hr, "Failed to get value");
594
595 // find property definition
596 hr = FindPropertyDefinition(pPropDefList, pItm->wzName, &pPropDef);
597 ExitOnFailure(hr, "Failed to find property definition");
598
599 if (S_FALSE == hr)
600 ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unknown property, key: %S, property: %S", pwzKey, pItm->wzName);
601
602 // check version, ignore if catalog version is too low
603 if (iVersionNT < pPropDef->iMinVersionNT)
604 {
605 WcaLog(LOGMSG_VERBOSE, "Skipping property since NT version is too low, key: %S, property: %S", pwzKey, pItm->wzName);
606 CpiPropertiesFreeList(pItm);
607 pItm = NULL;
608 continue;
609 }
610
611 // if the property is a user, replace the User table key with a user account name
612 if (cpptUser == pPropDef->iType)
613 {
614 hr = GetUserAccountName(pItm->pwzValue, &pItm->pwzValue);
615 ExitOnFailure(hr, "Failed to get user account name");
616 }
617
618 // add entry
619 ++*piCount;
620 if (*ppPropList)
621 pItm->pNext = *ppPropList;
622 *ppPropList = pItm;
623 pItm = NULL;
624 }
625
626 if (E_NOMOREITEMS == hr)
627 hr = S_OK;
628
629LExit:
630 // clean up
631 if (pItm)
632 CpiPropertiesFreeList(pItm);
633
634 ReleaseStr(pwzData);
635
636 return hr;
637}
638
639void CpiPropertiesFreeList(
640 CPI_PROPERTY* pList
641 )
642{
643 while (pList)
644 {
645 ReleaseStr(pList->pwzValue);
646
647 CPI_PROPERTY* pDelete = pList;
648 pList = pList->pNext;
649 ::HeapFree(::GetProcessHeap(), 0, pDelete);
650 }
651}
652
653HRESULT CpiAddPropertiesToActionData(
654 int iPropCount,
655 CPI_PROPERTY* pPropList,
656 LPWSTR* ppwzActionData
657 )
658{
659 HRESULT hr = S_OK;
660
661 hr = WcaWriteIntegerToCaData(iPropCount, ppwzActionData);
662 ExitOnFailure(hr, "Failed to add count to custom action data");
663
664 if (iPropCount) // count might be 0 event thought there are elements in the list
665 {
666 for (CPI_PROPERTY* pProp = pPropList; pProp; pProp = pProp->pNext)
667 {
668 hr = WcaWriteStringToCaData(pProp->wzName, ppwzActionData);
669 ExitOnFailure(hr, "Failed to add property name to custom action data, name: %S", pProp->wzName);
670
671 hr = WcaWriteStringToCaData(pProp->pwzValue, ppwzActionData);
672 ExitOnFailure(hr, "Failed to add property value to custom action data, name: %S", pProp->wzName);
673 }
674 }
675
676 hr = S_OK;
677
678LExit:
679 return hr;
680}
681
682HRESULT CpiBuildAccountName(
683 LPCWSTR pwzDomain,
684 LPCWSTR pwzName,
685 LPWSTR* ppwzAccount
686 )
687{
688 HRESULT hr = S_OK;
689
690 WCHAR wzComputerName[MAX_COMPUTERNAME_LENGTH + 1];
691 ::ZeroMemory(wzComputerName, sizeof(wzComputerName));
692
693 // if domain is '.', get computer name
694 if (0 == lstrcmpW(pwzDomain, L"."))
695 {
696 DWORD dwSize = countof(wzComputerName);
697 if (!::GetComputerNameW(wzComputerName, &dwSize))
698 ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to get computer name");
699 }
700
701 // build account name
702 hr = StrAllocFormatted(ppwzAccount, L"%s\\%s", *wzComputerName ? wzComputerName : pwzDomain, pwzName);
703 ExitOnFailure(hr, "Failed to build domain user name");
704
705 hr = S_OK;
706
707LExit:
708 return hr;
709}
710
711HRESULT CpiGetTempFileName(
712 LPWSTR* ppwzTempFile
713 )
714{
715 HRESULT hr = S_OK;
716
717 // get temp path
718 WCHAR wzTempPath[MAX_PATH];
719 DWORD dw = ::GetTempPathW(countof(wzTempPath), wzTempPath);
720 if (countof(wzTempPath) <= dw)
721 ExitOnFailure(hr = E_FAIL, "TEMP directory path too long");
722
723 // get unique number
724 LARGE_INTEGER liCount;
725 if (!::QueryPerformanceCounter(&liCount))
726 ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to query performance counter");
727
728 // create temp file name
729 hr = StrAllocFormatted(ppwzTempFile, L"%sCPI%I64X.tmp", wzTempPath, liCount.QuadPart);
730 ExitOnFailure(hr, "Failed to create temp file name string");
731
732 hr = S_OK;
733
734LExit:
735 return hr;
736}
737
738HRESULT CpiCreateId(
739 LPWSTR pwzDest,
740 SIZE_T cchDest
741 )
742{
743 HRESULT hr = S_OK;
744
745 GUID guid;
746
747 // create new guid
748 hr = ::CoCreateGuid(&guid);
749 ExitOnFailure(hr, "Failed to create new guid");
750
751 // convert guid to string
752 if (0 == ::StringFromGUID2(guid, pwzDest, (int)cchDest))
753 ExitOnFailure(hr = E_FAIL, "Failed to convert guid to string");
754
755 hr = S_OK;
756
757LExit:
758 return hr;
759}
760
761BOOL CpiIsInstalled(
762 INSTALLSTATE isInstalled
763 )
764{
765 return INSTALLSTATE_LOCAL == isInstalled || INSTALLSTATE_SOURCE == isInstalled;
766}
767
768BOOL CpiWillBeInstalled(
769 INSTALLSTATE isInstalled,
770 INSTALLSTATE isAction
771 )
772{
773 return WcaIsInstalling(isInstalled, isAction) ||
774 (CpiIsInstalled(isInstalled) && !WcaIsUninstalling(isInstalled, isAction));
775}
776
777HRESULT PcaGuidToRegFormat(
778 LPWSTR pwzGuid,
779 LPWSTR pwzDest,
780 SIZE_T cchDest
781 )
782{
783 HRESULT hr = S_OK;
784
785 GUID guid = GUID_NULL;
786 int cch = 0;
787
788 WCHAR wz[39];
789 ::ZeroMemory(wz, sizeof(wz));
790
791 cch = lstrlenW(pwzGuid);
792
793 if (38 == cch && L'{' == pwzGuid[0] && L'}' == pwzGuid[37])
794 StringCchCopyW(wz, countof(wz), pwzGuid);
795 else if (36 == cch)
796 StringCchPrintfW(wz, countof(wz), L"{%s}", pwzGuid);
797 else
798 ExitFunction1(hr = E_INVALIDARG);
799
800 // convert string to guid
801 hr = ::CLSIDFromString(wz, &guid);
802 ExitOnFailure(hr, "Failed to parse guid string");
803
804 // convert guid to string
805 if (0 == ::StringFromGUID2(guid, pwzDest, (int)cchDest))
806 ExitOnFailure(hr = E_FAIL, "Failed to convert guid to string");
807
808 hr = S_OK;
809
810LExit:
811 return hr;
812}
813
814
815// helper function definitions
816
817static HRESULT FindPropertyDefinition(
818 CPI_PROPERTY_DEFINITION* pPropDefList,
819 LPCWSTR pwzName,
820 CPI_PROPERTY_DEFINITION** ppPropDef
821 )
822{
823 for (CPI_PROPERTY_DEFINITION* pItm = pPropDefList; pItm->pwzName; pItm++)
824 {
825 if (0 == lstrcmpW(pItm->pwzName, pwzName))
826 {
827 *ppPropDef = pItm;
828 return S_OK;
829 }
830 }
831
832 return S_FALSE;
833}
834
835static HRESULT GetUserAccountName(
836 LPCWSTR pwzKey,
837 LPWSTR* ppwzAccount
838 )
839{
840 HRESULT hr = S_OK;
841
842 PMSIHANDLE hView, hRecKey, hRec;
843
844 LPWSTR pwzDomain = NULL;
845 LPWSTR pwzName = NULL;
846
847 // create parameter record
848 hRecKey = ::MsiCreateRecord(1);
849 ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
850 hr = WcaSetRecordString(hRecKey, 1, pwzKey);
851 ExitOnFailure(hr, "Failed to set record string");
852
853 // open view
854 hr = WcaOpenView(vcsUserQuery, &hView);
855 ExitOnFailure(hr, "Failed to open view on User table");
856 hr = WcaExecuteView(hView, hRecKey);
857 ExitOnFailure(hr, "Failed to execute view on User table");
858
859 // fetch record
860 hr = WcaFetchSingleRecord(hView, &hRec);
861 if (S_FALSE == hr)
862 ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "User not found, key: %S", pwzKey);
863 ExitOnFailure(hr, "Failed to fetch user record");
864
865 // get user domain
866 hr = WcaGetRecordFormattedString(hRec, uqDomain, &pwzDomain);
867 ExitOnFailure(hr, "Failed to get domain");
868
869 // get user name
870 hr = WcaGetRecordFormattedString(hRec, uqName, &pwzName);
871 ExitOnFailure(hr, "Failed to get name");
872
873 // build account name
874 hr = CpiBuildAccountName(pwzDomain, pwzName, ppwzAccount);
875 ExitOnFailure(hr, "Failed to build account name");
876
877 hr = S_OK;
878
879LExit:
880 // clean up
881 ReleaseStr(pwzDomain);
882 ReleaseStr(pwzName);
883
884 return hr;
885}
diff --git a/src/ext/ComPlus/ca/cputilsched.h b/src/ext/ComPlus/ca/cputilsched.h
new file mode 100644
index 00000000..1f315576
--- /dev/null
+++ b/src/ext/ComPlus/ca/cputilsched.h
@@ -0,0 +1,132 @@
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
5enum eRunMode { rmDeferred = 1, rmCommit, rmRollback };
6
7enum eComPlusPropertyType { cpptNone = 0, cpptBoolean, cpptInteger, cpptString, cpptUser };
8
9enum eComPlusTables
10{
11 cptComPlusPartition = (1 << 0),
12 cptComPlusPartitionProperty = (1 << 1),
13 cptComPlusPartitionRole = (1 << 2),
14 cptComPlusUserInPartitionRole = (1 << 3),
15 cptComPlusGroupInPartitionRole = (1 << 4),
16 cptComPlusPartitionUser = (1 << 5),
17 cptComPlusApplication = (1 << 6),
18 cptComPlusApplicationProperty = (1 << 7),
19 cptComPlusApplicationRole = (1 << 8),
20 cptComPlusApplicationRoleProperty = (1 << 9),
21 cptComPlusUserInApplicationRole = (1 << 10),
22 cptComPlusGroupInApplicationRole = (1 << 11),
23 cptComPlusAssembly = (1 << 12),
24 cptComPlusAssemblyDependency = (1 << 13),
25 cptComPlusComponent = (1 << 14),
26 cptComPlusComponentProperty = (1 << 15),
27 cptComPlusRoleForComponent = (1 << 16),
28 cptComPlusInterface = (1 << 17),
29 cptComPlusInterfaceProperty = (1 << 18),
30 cptComPlusRoleForInterface = (1 << 19),
31 cptComPlusMethod = (1 << 20),
32 cptComPlusMethodProperty = (1 << 21),
33 cptComPlusRoleForMethod = (1 << 22),
34 cptComPlusSubscription = (1 << 23),
35 cptComPlusSubscriptionProperty = (1 << 24)
36};
37
38
39// structs
40
41struct CPI_PROPERTY_DEFINITION
42{
43 LPCWSTR pwzName;
44 int iType;
45 int iMinVersionNT;
46};
47
48
49// function prototypes
50
51void CpiSchedInitialize();
52void CpiSchedFinalize();
53BOOL CpiTableExists(
54 int iTable
55 );
56HRESULT CpiSchedGetAdminCatalog(
57 ICOMAdminCatalog** ppiCatalog
58 );
59HRESULT CpiSchedGetCatalogCollection(
60 LPCWSTR pwzName,
61 ICatalogCollection** ppiColl
62 );
63HRESULT CpiSchedGetCatalogCollection(
64 ICatalogCollection* piColl,
65 ICatalogObject* piObj,
66 LPCWSTR pwzName,
67 ICatalogCollection** ppiColl
68 );
69HRESULT CpiGetKeyForObject(
70 ICatalogObject* piObj,
71 LPWSTR pwzKey,
72 SIZE_T cchKey
73 );
74HRESULT CpiFindCollectionObject(
75 ICatalogCollection* piColl,
76 LPCWSTR pwzID,
77 LPCWSTR pwzName,
78 ICatalogObject** ppiObj
79 );
80HRESULT CpiSchedGetPartitionsCollection(
81 ICatalogCollection** ppiPartColl
82 );
83HRESULT CpiSchedGetApplicationsCollection(
84 ICatalogCollection** ppiAppColl
85 );
86HRESULT CpiAddActionTextToActionData(
87 LPCWSTR pwzAction,
88 LPWSTR* ppwzActionData
89 );
90HRESULT CpiVerifyComponentArchitecure(
91 LPCWSTR pwzComponent,
92 BOOL* pfMatchingArchitecture
93 );
94HRESULT CpiPropertiesRead(
95 LPCWSTR pwzQuery,
96 LPCWSTR pwzKey,
97 CPI_PROPERTY_DEFINITION* pPropDefList,
98 CPI_PROPERTY** ppPropList,
99 int* piCount
100 );
101void CpiPropertiesFreeList(
102 CPI_PROPERTY* pList
103 );
104HRESULT CpiAddPropertiesToActionData(
105 int iPropCount,
106 CPI_PROPERTY* pPropList,
107 LPWSTR* ppwzActionData
108 );
109HRESULT CpiBuildAccountName(
110 LPCWSTR pwzDomain,
111 LPCWSTR pwzName,
112 LPWSTR* ppwzAccount
113 );
114HRESULT CpiGetTempFileName(
115 LPWSTR* ppwzTempFile
116 );
117HRESULT CpiCreateId(
118 LPWSTR pwzDest,
119 SIZE_T cchDest
120 );
121BOOL CpiIsInstalled(
122 INSTALLSTATE isInstalled
123 );
124BOOL CpiWillBeInstalled(
125 INSTALLSTATE isInstalled,
126 INSTALLSTATE isAction
127 );
128HRESULT PcaGuidToRegFormat(
129 LPWSTR pwzGuid,
130 LPWSTR pwzDest,
131 SIZE_T cchDest
132 );
diff --git a/src/ext/ComPlus/ca/custommsierrors.h b/src/ext/ComPlus/ca/custommsierrors.h
new file mode 100644
index 00000000..219df698
--- /dev/null
+++ b/src/ext/ComPlus/ca/custommsierrors.h
@@ -0,0 +1,29 @@
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 msierrComPlusCannotConnect 28001
6#define msierrComPlusPartitionReadFailed 28002
7#define msierrComPlusPartitionRoleReadFailed 28003
8#define msierrComPlusUserInPartitionRoleReadFailed 28004
9#define msierrComPlusPartitionUserReadFailed 28005
10#define msierrComPlusApplicationReadFailed 28006
11#define msierrComPlusApplicationRoleReadFailed 28007
12#define msierrComPlusUserInApplicationRoleReadFailed 28008
13#define msierrComPlusAssembliesReadFailed 28009
14#define msierrComPlusSubscriptionReadFailed 28010
15#define msierrComPlusPartitionDependency 28011
16#define msierrComPlusPartitionNotFound 28012
17#define msierrComPlusPartitionIdConflict 28013
18#define msierrComPlusPartitionNameConflict 28014
19#define msierrComPlusApplicationDependency 28015
20#define msierrComPlusApplicationNotFound 28016
21#define msierrComPlusApplicationIdConflict 28017
22#define msierrComPlusApplicationNameConflict 28018
23#define msierrComPlusApplicationRoleDependency 28019
24#define msierrComPlusApplicationRoleNotFound 28020
25#define msierrComPlusApplicationRoleConflict 28021
26#define msierrComPlusAssemblyDependency 28022
27#define msierrComPlusSubscriptionIdConflict 28023
28#define msierrComPlusSubscriptionNameConflict 28024
29#define msierrComPlusFailedLookupNames 28025
diff --git a/src/ext/ComPlus/ca/dllmain.cpp b/src/ext/ComPlus/ca/dllmain.cpp
new file mode 100644
index 00000000..7d299feb
--- /dev/null
+++ b/src/ext/ComPlus/ca/dllmain.cpp
@@ -0,0 +1,27 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5/********************************************************************
6DllMain - standard entry point for all WiX custom actions.
7
8********************************************************************/
9extern "C" BOOL WINAPI DllMain(
10 IN HINSTANCE hInstance,
11 IN ULONG ulReason,
12 IN LPVOID)
13{
14 switch(ulReason)
15 {
16 case DLL_PROCESS_ATTACH:
17 WcaGlobalInitialize(hInstance);
18 ::DisableThreadLibraryCalls(hInstance);
19 break;
20
21 case DLL_PROCESS_DETACH:
22 WcaGlobalFinalize();
23 break;
24 }
25
26 return TRUE;
27}
diff --git a/src/ext/ComPlus/ca/packages.config b/src/ext/ComPlus/ca/packages.config
new file mode 100644
index 00000000..e3dc0e43
--- /dev/null
+++ b/src/ext/ComPlus/ca/packages.config
@@ -0,0 +1,5 @@
1<?xml version="1.0" encoding="utf-8"?>
2<packages>
3 <package id="WixToolset.DUtil" version="4.0.30" targetFramework="native" />
4 <package id="WixToolset.WcaUtil" version="4.0.16" targetFramework="native" />
5</packages> \ No newline at end of file
diff --git a/src/ext/ComPlus/ca/precomp.h b/src/ext/ComPlus/ca/precomp.h
new file mode 100644
index 00000000..74c328d2
--- /dev/null
+++ b/src/ext/ComPlus/ca/precomp.h
@@ -0,0 +1,33 @@
1#pragma once
2// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
3
4
5#include <windows.h>
6#include <msiquery.h>
7#include <strsafe.h>
8#include <comadmin.h>
9#include <ntsecapi.h>
10#include <aclapi.h>
11
12#include "wcautil.h"
13#include "memutil.h"
14#include "strutil.h"
15#include "wiutil.h"
16
17#include "CustomMsiErrors.h"
18
19#include "cpcost.h"
20#include "cputilexec.h"
21#include "cppartexec.h"
22#include "cppartroleexec.h"
23#include "cpappexec.h"
24#include "cpapproleexec.h"
25#include "cpasmexec.h"
26#include "cpsubsexec.h"
27#include "cputilsched.h"
28#include "cppartsched.h"
29#include "cppartrolesched.h"
30#include "cpappsched.h"
31#include "cpapprolesched.h"
32#include "cpasmsched.h"
33#include "cpsubssched.h"
diff --git a/src/ext/ComPlus/nuget.config b/src/ext/ComPlus/nuget.config
new file mode 100644
index 00000000..db7aba29
--- /dev/null
+++ b/src/ext/ComPlus/nuget.config
@@ -0,0 +1,17 @@
1<?xml version="1.0" encoding="utf-8"?>
2<configuration>
3 <packageSources>
4 <clear />
5 <add key="wixtoolset-burn" value="https://ci.appveyor.com/nuget/wixtoolset-burn" />
6 <add key="wixtoolset-data" value="https://ci.appveyor.com/nuget/wixtoolset-data" />
7 <add key="wixtoolset-extensibility" value="https://ci.appveyor.com/nuget/wixtoolset-extensibility" />
8 <add key="wixtoolset-core" value="https://ci.appveyor.com/nuget/wixtoolset-core" />
9 <add key="wixtoolset-core-native" value="https://ci.appveyor.com/nuget/wixtoolset-core-native" />
10 <add key="wixtoolset-dtf" value="https://ci.appveyor.com/nuget/wixtoolset-dtf" />
11 <add key="wixtoolset-dutil" value="https://ci.appveyor.com/nuget/wixtoolset-dutil" />
12 <add key="wixtoolset-wcautil" value="https://ci.appveyor.com/nuget/wixtoolset-wcautil" />
13 <add key="wixtoolset-tools" value="https://ci.appveyor.com/nuget/wixtoolset-tools" />
14 <add key="wixbuildtools" value="https://ci.appveyor.com/nuget/wixbuildtools" />
15 <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
16 </packageSources>
17</configuration> \ No newline at end of file
diff --git a/src/ext/ComPlus/test/WixToolsetTest.ComPlus/ComPlusExtensionFixture.cs b/src/ext/ComPlus/test/WixToolsetTest.ComPlus/ComPlusExtensionFixture.cs
new file mode 100644
index 00000000..ace4d6b6
--- /dev/null
+++ b/src/ext/ComPlus/test/WixToolsetTest.ComPlus/ComPlusExtensionFixture.cs
@@ -0,0 +1,32 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolsetTest.ComPlus
4{
5 using System.Linq;
6 using WixBuildTools.TestSupport;
7 using WixToolset.Core.TestPackage;
8 using WixToolset.ComPlus;
9 using Xunit;
10
11 public class ComPlusExtensionFixture
12 {
13 [Fact]
14 public void CanBuildUsingComPlusPartition()
15 {
16 var folder = TestData.Get(@"TestData\UsingComPlusPartition");
17 var build = new Builder(folder, typeof(ComPlusExtensionFactory), new[] { folder });
18
19 var results = build.BuildAndQuery(Build, "ComPlusPartition");
20 WixAssert.CompareLineByLine(new[]
21 {
22 "ComPlusPartition:MyPartition\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo\tMyPartitionId\tMyPartition",
23 }, results);
24 }
25
26 private static void Build(string[] args)
27 {
28 var result = WixRunner.Execute(args)
29 .AssertSuccess();
30 }
31 }
32}
diff --git a/src/ext/ComPlus/test/WixToolsetTest.ComPlus/TestData/UsingComPlusPartition/Package.en-us.wxl b/src/ext/ComPlus/test/WixToolsetTest.ComPlus/TestData/UsingComPlusPartition/Package.en-us.wxl
new file mode 100644
index 00000000..38c12ac1
--- /dev/null
+++ b/src/ext/ComPlus/test/WixToolsetTest.ComPlus/TestData/UsingComPlusPartition/Package.en-us.wxl
@@ -0,0 +1,11 @@
1<?xml version="1.0" encoding="utf-8"?>
2
3<!--
4This file contains the declaration of all the localizable strings.
5-->
6<WixLocalization xmlns="http://wixtoolset.org/schemas/v4/wxl" Culture="en-US">
7
8 <String Id="DowngradeError">A newer version of [ProductName] is already installed.</String>
9 <String Id="FeatureTitle">MsiPackage</String>
10
11</WixLocalization>
diff --git a/src/ext/ComPlus/test/WixToolsetTest.ComPlus/TestData/UsingComPlusPartition/Package.wxs b/src/ext/ComPlus/test/WixToolsetTest.ComPlus/TestData/UsingComPlusPartition/Package.wxs
new file mode 100644
index 00000000..bd31e81f
--- /dev/null
+++ b/src/ext/ComPlus/test/WixToolsetTest.ComPlus/TestData/UsingComPlusPartition/Package.wxs
@@ -0,0 +1,15 @@
1<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
2 <Package Name="MsiPackage" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a" InstallerVersion="200">
3 <MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" />
4
5 <Feature Id="ProductFeature" Title="!(loc.FeatureTitle)">
6 <ComponentGroupRef Id="ProductComponents" />
7 </Feature>
8 </Package>
9
10 <Fragment>
11 <StandardDirectory Id="ProgramFilesFolder">
12 <Directory Id="INSTALLFOLDER" Name="MsiPackage" />
13 </StandardDirectory>
14 </Fragment>
15</Wix>
diff --git a/src/ext/ComPlus/test/WixToolsetTest.ComPlus/TestData/UsingComPlusPartition/PackageComponents.wxs b/src/ext/ComPlus/test/WixToolsetTest.ComPlus/TestData/UsingComPlusPartition/PackageComponents.wxs
new file mode 100644
index 00000000..f61eedd6
--- /dev/null
+++ b/src/ext/ComPlus/test/WixToolsetTest.ComPlus/TestData/UsingComPlusPartition/PackageComponents.wxs
@@ -0,0 +1,12 @@
1<?xml version="1.0" encoding="utf-8"?>
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
3 xmlns:complus="http://wixtoolset.org/schemas/v4/wxs/complus">
4 <Fragment>
5 <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
6 <Component>
7 <File Source="example.txt" />
8 <complus:ComPlusPartition Id="MyPartition" Name="MyPartition" PartitionId="MyPartitionId" />
9 </Component>
10 </ComponentGroup>
11 </Fragment>
12</Wix>
diff --git a/src/ext/ComPlus/test/WixToolsetTest.ComPlus/TestData/UsingComPlusPartition/example.txt b/src/ext/ComPlus/test/WixToolsetTest.ComPlus/TestData/UsingComPlusPartition/example.txt
new file mode 100644
index 00000000..1b4ffe8a
--- /dev/null
+++ b/src/ext/ComPlus/test/WixToolsetTest.ComPlus/TestData/UsingComPlusPartition/example.txt
@@ -0,0 +1 @@
This is example.txt. \ No newline at end of file
diff --git a/src/ext/ComPlus/test/WixToolsetTest.ComPlus/WixToolsetTest.ComPlus.csproj b/src/ext/ComPlus/test/WixToolsetTest.ComPlus/WixToolsetTest.ComPlus.csproj
new file mode 100644
index 00000000..e4a529cb
--- /dev/null
+++ b/src/ext/ComPlus/test/WixToolsetTest.ComPlus/WixToolsetTest.ComPlus.csproj
@@ -0,0 +1,38 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup>
6 <TargetFramework>netcoreapp3.1</TargetFramework>
7 <IsPackable>false</IsPackable>
8 </PropertyGroup>
9
10 <PropertyGroup>
11 <NoWarn>NU1701</NoWarn>
12 </PropertyGroup>
13
14 <ItemGroup>
15 <Content Include="TestData\**" CopyToOutputDirectory="PreserveNewest" />
16 </ItemGroup>
17
18 <ItemGroup>
19 <ProjectReference Include="..\..\wixext\WixToolset.ComPlus.wixext.csproj" />
20 </ItemGroup>
21
22 <ItemGroup>
23 <PackageReference Include="WixToolset.Core" Version="4.0.*" />
24 <PackageReference Include="WixToolset.Core.Burn" Version="4.0.*" />
25 <PackageReference Include="WixToolset.Core.WindowsInstaller" Version="4.0.*" />
26 <PackageReference Include="WixToolset.Core.TestPackage" Version="4.0.*" />
27 </ItemGroup>
28
29 <ItemGroup>
30 <PackageReference Include="WixBuildTools.TestSupport" Version="4.0.*" />
31 </ItemGroup>
32
33 <ItemGroup>
34 <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
35 <PackageReference Include="xunit" Version="2.4.1" />
36 <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" PrivateAssets="All" />
37 </ItemGroup>
38</Project>
diff --git a/src/ext/ComPlus/wix.snk b/src/ext/ComPlus/wix.snk
new file mode 100644
index 00000000..3908a66a
--- /dev/null
+++ b/src/ext/ComPlus/wix.snk
Binary files differ
diff --git a/src/ext/ComPlus/wixext/ComPlusCompiler.cs b/src/ext/ComPlus/wixext/ComPlusCompiler.cs
new file mode 100644
index 00000000..4404801e
--- /dev/null
+++ b/src/ext/ComPlus/wixext/ComPlusCompiler.cs
@@ -0,0 +1,2164 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Xml.Linq;
8 using WixToolset.ComPlus.Symbols;
9 using WixToolset.Data;
10 using WixToolset.Extensibility;
11
12 /// <summary>
13 /// The compiler for the WiX Toolset COM+ Extension.
14 /// </summary>
15 public sealed class ComPlusCompiler : BaseCompilerExtension
16 {
17 /// <summary>
18 /// </summary>
19 /// <remarks></remarks>
20 public enum CpiAssemblyAttributes
21 {
22 EventClass = (1 << 0),
23 DotNetAssembly = (1 << 1),
24 DllPathFromGAC = (1 << 2),
25 RegisterInCommit = (1 << 3)
26 }
27
28 public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/complus";
29
30 /// <summary>
31 /// Processes an element for the Compiler.
32 /// </summary>
33 /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
34 /// <param name="parentElement">Parent element of element to process.</param>
35 /// <param name="element">Element to process.</param>
36 /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param>
37 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
38 {
39 switch (parentElement.Name.LocalName)
40 {
41 case "Component":
42 var componentId = context["ComponentId"];
43 var directoryId = context["DirectoryId"];
44 var win64 = Boolean.Parse(context["Win64"]);
45
46 switch (element.Name.LocalName)
47 {
48 case "ComPlusPartition":
49 this.ParseComPlusPartitionElement(intermediate, section, element, componentId, win64);
50 break;
51 case "ComPlusPartitionRole":
52 this.ParseComPlusPartitionRoleElement(intermediate, section, element, componentId, null);
53 break;
54 case "ComPlusUserInPartitionRole":
55 this.ParseComPlusUserInPartitionRoleElement(intermediate, section, element, componentId, null);
56 break;
57 case "ComPlusGroupInPartitionRole":
58 this.ParseComPlusGroupInPartitionRoleElement(intermediate, section, element, componentId, null);
59 break;
60 case "ComPlusPartitionUser":
61 this.ParseComPlusPartitionUserElement(intermediate, section, element, componentId, null);
62 break;
63 case "ComPlusApplication":
64 this.ParseComPlusApplicationElement(intermediate, section, element, componentId, win64, null);
65 break;
66 case "ComPlusApplicationRole":
67 this.ParseComPlusApplicationRoleElement(intermediate, section, element, componentId, null);
68 break;
69 case "ComPlusUserInApplicationRole":
70 this.ParseComPlusUserInApplicationRoleElement(intermediate, section, element, componentId, null);
71 break;
72 case "ComPlusGroupInApplicationRole":
73 this.ParseComPlusGroupInApplicationRoleElement(intermediate, section, element, componentId, null);
74 break;
75 case "ComPlusAssembly":
76 this.ParseComPlusAssemblyElement(intermediate, section, element, componentId, win64, null);
77 break;
78 case "ComPlusRoleForComponent":
79 this.ParseComPlusRoleForComponentElement(intermediate, section, element, componentId, null);
80 break;
81 case "ComPlusRoleForInterface":
82 this.ParseComPlusRoleForInterfaceElement(intermediate, section, element, componentId, null);
83 break;
84 case "ComPlusRoleForMethod":
85 this.ParseComPlusRoleForMethodElement(intermediate, section, element, componentId, null);
86 break;
87 case "ComPlusSubscription":
88 this.ParseComPlusSubscriptionElement(intermediate, section, element, componentId, null);
89 break;
90 default:
91 this.ParseHelper.UnexpectedElement(parentElement, element);
92 break;
93 }
94 break;
95 case "Fragment":
96 case "Module":
97 case "Package":
98 switch (element.Name.LocalName)
99 {
100 case "ComPlusPartition":
101 this.ParseComPlusPartitionElement(intermediate, section, element, null, false);
102 break;
103 case "ComPlusPartitionRole":
104 this.ParseComPlusPartitionRoleElement(intermediate, section, element, null, null);
105 break;
106 case "ComPlusApplication":
107 this.ParseComPlusApplicationElement(intermediate, section, element, null, false, null);
108 break;
109 case "ComPlusApplicationRole":
110 this.ParseComPlusApplicationRoleElement(intermediate, section, element, null, null);
111 break;
112 default:
113 this.ParseHelper.UnexpectedElement(parentElement, element);
114 break;
115 }
116 break;
117 default:
118 this.ParseHelper.UnexpectedElement(parentElement, element);
119 break;
120 }
121 }
122
123 /// <summary>
124 /// Parses a COM+ partition element.
125 /// </summary>
126 /// <param name="node">Element to parse.</param>
127 /// <param name="componentKey">Identifier of parent component.</param>
128 private void ParseComPlusPartitionElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, bool win64)
129 {
130 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
131
132 Identifier key = null;
133 string id = null;
134 string name = null;
135
136 var properties = new Dictionary<string, string>();
137
138 foreach (var attrib in node.Attributes())
139 {
140 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
141 {
142 switch (attrib.Name.LocalName)
143 {
144 case "Id":
145 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
146 break;
147 case "PartitionId":
148 id = this.TryFormatGuidValue(this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib));
149 break;
150 case "Name":
151 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
152 break;
153 case "Changeable":
154 this.Messaging.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
155 break;
156 case "Deleteable":
157 if (null == componentKey)
158 {
159 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
160 }
161 properties["Deleteable"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
162 break;
163 case "Description":
164 if (null == componentKey)
165 {
166 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
167 }
168 properties["Description"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
169 break;
170 default:
171 this.ParseHelper.UnexpectedAttribute(node, attrib);
172 break;
173 }
174 }
175 else
176 {
177 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
178 }
179 }
180
181 if (null != componentKey && null == name)
182 {
183 this.Messaging.Write(ComPlusErrors.RequiredAttributeUnderComponent(sourceLineNumbers, node.Name.LocalName, "Name"));
184 }
185 if (null == componentKey && null == id && null == name)
186 {
187 this.Messaging.Write(ComPlusErrors.RequiredAttributeNotUnderComponent(sourceLineNumbers, node.Name.LocalName, "Id", "Name"));
188 }
189
190 foreach (var child in node.Elements())
191 {
192 if (this.Namespace == child.Name.Namespace)
193 {
194 switch (child.Name.LocalName)
195 {
196 case "ComPlusPartitionRole":
197 this.ParseComPlusPartitionRoleElement(intermediate, section, child, componentKey, key?.Id);
198 break;
199 case "ComPlusPartitionUser":
200 this.ParseComPlusPartitionUserElement(intermediate, section, child, componentKey, key?.Id);
201 break;
202 case "ComPlusApplication":
203 this.ParseComPlusApplicationElement(intermediate, section, child, componentKey, win64, key?.Id);
204 break;
205 default:
206 this.ParseHelper.UnexpectedElement(node, child);
207 break;
208 }
209 }
210 else
211 {
212 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
213 }
214 }
215
216 section.AddSymbol(new ComPlusPartitionSymbol(sourceLineNumbers, key)
217 {
218 ComponentRef = componentKey,
219 PartitionId = id,
220 Name = name,
221 });
222
223 foreach (var kvp in properties)
224 {
225 section.AddSymbol(new ComPlusPartitionPropertySymbol(sourceLineNumbers)
226 {
227 PartitionRef = key?.Id,
228 Name = kvp.Key,
229 Value = kvp.Value,
230 });
231 }
232
233 if (componentKey != null)
234 {
235 this.AddReferenceToConfigureComPlus(section, sourceLineNumbers, node.Name.LocalName, win64);
236 }
237 }
238
239 /// <summary>
240 /// Parses a COM+ partition role element.
241 /// </summary>
242 /// <param name="node">Element to parse.</param>
243 /// <param name="componentKey">Identifier of parent component.</param>
244 /// <param name="applicationKey">Optional identifier of parent application.</param>
245 private void ParseComPlusPartitionRoleElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string partitionKey)
246 {
247 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
248
249 Identifier key = null;
250 string name = null;
251
252 foreach (var attrib in node.Attributes())
253 {
254 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
255 {
256 switch (attrib.Name.LocalName)
257 {
258 case "Id":
259 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
260 break;
261 case "Partition":
262 if (null != partitionKey)
263 {
264 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
265 }
266 partitionKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
267 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusPartition, partitionKey);
268 break;
269 case "Name":
270 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
271 break;
272 default:
273 this.ParseHelper.UnexpectedAttribute(node, attrib);
274 break;
275 }
276 }
277 else
278 {
279 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
280 }
281 }
282
283 if (null == partitionKey)
284 {
285 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Partition"));
286 }
287
288 foreach (var child in node.Elements())
289 {
290 if (this.Namespace == child.Name.Namespace)
291 {
292 switch (child.Name.LocalName)
293 {
294 case "ComPlusUserInPartitionRole":
295 this.ParseComPlusUserInPartitionRoleElement(intermediate, section, child, componentKey, key?.Id);
296 break;
297 case "ComPlusGroupInPartitionRole":
298 this.ParseComPlusGroupInPartitionRoleElement(intermediate, section, child, componentKey, key?.Id);
299 break;
300 default:
301 this.ParseHelper.UnexpectedElement(node, child);
302 break;
303 }
304 }
305 else
306 {
307 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
308 }
309 }
310
311 section.AddSymbol(new ComPlusPartitionRoleSymbol(sourceLineNumbers, key)
312 {
313 PartitionRef = partitionKey,
314 Name = name,
315 });
316 }
317
318 /// <summary>
319 /// Parses a COM+ partition role user element.
320 /// </summary>
321 /// <param name="node">Element to parse.</param>
322 /// <param name="componentKey">Identifier of parent component.</param>
323 /// <param name="applicationKey">Optional identifier of parent application role.</param>
324 private void ParseComPlusUserInPartitionRoleElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string partitionRoleKey)
325 {
326 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
327
328 Identifier key = null;
329 string user = null;
330
331 foreach (var attrib in node.Attributes())
332 {
333 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
334 {
335 switch (attrib.Name.LocalName)
336 {
337 case "Id":
338 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
339 break;
340 case "PartitionRole":
341 if (null != partitionRoleKey)
342 {
343 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
344 }
345 partitionRoleKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
346 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusPartitionRole, partitionRoleKey);
347 break;
348 case "User":
349 user = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
350 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user);
351 break;
352 default:
353 this.ParseHelper.UnexpectedAttribute(node, attrib);
354 break;
355 }
356 }
357 else
358 {
359 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
360 }
361 }
362
363 if (null == partitionRoleKey)
364 {
365 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "PartitionRole"));
366 }
367
368 section.AddSymbol(new ComPlusUserInPartitionRoleSymbol(sourceLineNumbers, key)
369 {
370 PartitionRoleRef = partitionRoleKey,
371 ComponentRef = componentKey,
372 UserRef = user,
373 });
374 }
375
376 /// <summary>
377 /// Parses a COM+ partition role user element.
378 /// </summary>
379 /// <param name="node">Element to parse.</param>
380 /// <param name="componentKey">Identifier of parent component.</param>
381 /// <param name="applicationKey">Optional identifier of parent application role.</param>
382 private void ParseComPlusGroupInPartitionRoleElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string partitionRoleKey)
383 {
384 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
385
386 Identifier key = null;
387 string group = null;
388
389 foreach (var attrib in node.Attributes())
390 {
391 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
392 {
393 switch (attrib.Name.LocalName)
394 {
395 case "Id":
396 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
397 break;
398 case "PartitionRole":
399 if (null != partitionRoleKey)
400 {
401 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
402 }
403 partitionRoleKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
404 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusPartitionRole, partitionRoleKey);
405 break;
406 case "Group":
407 group = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
408 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "Group", group);
409 break;
410 default:
411 this.ParseHelper.UnexpectedAttribute(node, attrib);
412 break;
413 }
414 }
415 else
416 {
417 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
418 }
419 }
420
421 if (null == partitionRoleKey)
422 {
423 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "PartitionRole"));
424 }
425
426 section.AddSymbol(new ComPlusGroupInPartitionRoleSymbol(sourceLineNumbers, key)
427 {
428 PartitionRoleRef = partitionRoleKey,
429 ComponentRef = componentKey,
430 GroupRef = group,
431 });
432 }
433
434 /// <summary>
435 /// Parses a COM+ partition element.
436 /// </summary>
437 /// <param name="node">Element to parse.</param>
438 /// <param name="componentKey">Identifier of parent component.</param>
439 private void ParseComPlusPartitionUserElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string partitionKey)
440 {
441 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
442
443 Identifier key = null;
444 string user = null;
445
446 foreach (var attrib in node.Attributes())
447 {
448 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
449 {
450 switch (attrib.Name.LocalName)
451 {
452 case "Id":
453 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
454 break;
455 case "Partition":
456 if (null != partitionKey)
457 {
458 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
459 }
460 partitionKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
461 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusPartition, partitionKey);
462 break;
463 case "User":
464 user = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
465 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user);
466 break;
467 default:
468 this.ParseHelper.UnexpectedAttribute(node, attrib);
469 break;
470 }
471 }
472 else
473 {
474 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
475 }
476 }
477
478 if (null == partitionKey)
479 {
480 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Partition"));
481 }
482
483 section.AddSymbol(new ComPlusPartitionUserSymbol(sourceLineNumbers, key)
484 {
485 PartitionRef = partitionKey,
486 ComponentRef = componentKey,
487 UserRef = user,
488 });
489 }
490
491 /// <summary>
492 /// Parses a COM+ application element.
493 /// </summary>
494 /// <param name="node">Element to parse.</param>
495 /// <param name="componentKey">Identifier of parent component.</param>
496 /// <param name="partitionKey">Optional identifier of parent partition.</param>
497 private void ParseComPlusApplicationElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, bool win64, string partitionKey)
498 {
499 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
500
501 Identifier key = null;
502 string id = null;
503 string name = null;
504
505 var properties = new Dictionary<string, string>();
506
507 foreach (XAttribute attrib in node.Attributes())
508 {
509 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
510 {
511 switch (attrib.Name.LocalName)
512 {
513 case "Id":
514 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
515 break;
516 case "Partition":
517 if (null != partitionKey)
518 {
519 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
520 }
521 partitionKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
522 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusPartition, partitionKey);
523 break;
524 case "ApplicationId":
525 id = this.TryFormatGuidValue(this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib));
526 break;
527 case "Name":
528 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
529 break;
530 case "ThreeGigSupportEnabled":
531 if (null == componentKey)
532 {
533 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
534 }
535 properties["3GigSupportEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
536 break;
537 case "AccessChecksLevel":
538 if (null == componentKey)
539 {
540 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
541 }
542 var accessChecksLevelValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
543 switch (accessChecksLevelValue)
544 {
545 case "applicationLevel":
546 properties["AccessChecksLevel"] = "0";
547 break;
548 case "applicationComponentLevel":
549 properties["AccessChecksLevel"] = "1";
550 break;
551 default:
552 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "AccessChecksLevel", accessChecksLevelValue, "applicationLevel", "applicationComponentLevel"));
553 break;
554 }
555 break;
556 case "Activation":
557 if (null == componentKey)
558 {
559 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
560 }
561 var activationValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
562 switch (activationValue)
563 {
564 case "inproc":
565 properties["Activation"] = "Inproc";
566 break;
567 case "local":
568 properties["Activation"] = "Local";
569 break;
570 default:
571 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "Activation", activationValue, "inproc", "local"));
572 break;
573 }
574 break;
575 case "ApplicationAccessChecksEnabled":
576 if (null == componentKey)
577 {
578 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
579 }
580 properties["ApplicationAccessChecksEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
581 break;
582 case "ApplicationDirectory":
583 if (null == componentKey)
584 {
585 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
586 }
587 properties["ApplicationDirectory"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
588 break;
589 case "Authentication":
590 if (null == componentKey)
591 {
592 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
593 }
594 string authenticationValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
595 switch (authenticationValue)
596 {
597 case "default":
598 properties["Authentication"] = "0";
599 break;
600 case "none":
601 properties["Authentication"] = "1";
602 break;
603 case "connect":
604 properties["Authentication"] = "2";
605 break;
606 case "call":
607 properties["Authentication"] = "3";
608 break;
609 case "packet":
610 properties["Authentication"] = "4";
611 break;
612 case "integrity":
613 properties["Authentication"] = "5";
614 break;
615 case "privacy":
616 properties["Authentication"] = "6";
617 break;
618 default:
619 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "Authentication", authenticationValue, "default", "none", "connect", "call", "packet", "integrity", "privacy"));
620 break;
621 }
622 break;
623 case "AuthenticationCapability":
624 if (null == componentKey)
625 {
626 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
627 }
628 var authenticationCapabilityValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
629 switch (authenticationCapabilityValue)
630 {
631 case "none":
632 properties["AuthenticationCapability"] = "0";
633 break;
634 case "secureReference":
635 properties["AuthenticationCapability"] = "2";
636 break;
637 case "staticCloaking":
638 properties["AuthenticationCapability"] = "32";
639 break;
640 case "dynamicCloaking":
641 properties["AuthenticationCapability"] = "64";
642 break;
643 default:
644 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "AuthenticationCapability", authenticationCapabilityValue, "none", "secureReference", "staticCloaking", "dynamicCloaking"));
645 break;
646 }
647 break;
648 case "Changeable":
649 this.Messaging.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
650 break;
651 case "CommandLine":
652 if (null == componentKey)
653 {
654 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
655 }
656 properties["CommandLine"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
657 break;
658 case "ConcurrentApps":
659 if (null == componentKey)
660 {
661 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
662 }
663 properties["ConcurrentApps"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
664 break;
665 case "CreatedBy":
666 if (null == componentKey)
667 {
668 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
669 }
670 properties["CreatedBy"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
671 break;
672 case "CRMEnabled":
673 if (null == componentKey)
674 {
675 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
676 }
677 properties["CRMEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
678 break;
679 case "CRMLogFile":
680 if (null == componentKey)
681 {
682 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
683 }
684 properties["CRMLogFile"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
685 break;
686 case "Deleteable":
687 if (null == componentKey)
688 {
689 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
690 }
691 properties["Deleteable"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
692 break;
693 case "Description":
694 if (null == componentKey)
695 {
696 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
697 }
698 properties["Description"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
699 break;
700 case "DumpEnabled":
701 if (null == componentKey)
702 {
703 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
704 }
705 properties["DumpEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
706 break;
707 case "DumpOnException":
708 if (null == componentKey)
709 {
710 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
711 }
712 properties["DumpOnException"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
713 break;
714 case "DumpOnFailfast":
715 if (null == componentKey)
716 {
717 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
718 }
719 properties["DumpOnFailfast"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
720 break;
721 case "DumpPath":
722 if (null == componentKey)
723 {
724 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
725 }
726 properties["DumpPath"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
727 break;
728 case "EventsEnabled":
729 if (null == componentKey)
730 {
731 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
732 }
733 properties["EventsEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
734 break;
735 case "Identity":
736 if (null == componentKey)
737 {
738 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
739 }
740 properties["Identity"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
741 break;
742 case "ImpersonationLevel":
743 if (null == componentKey)
744 {
745 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
746 }
747 string impersonationLevelValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
748 switch (impersonationLevelValue)
749 {
750 case "anonymous":
751 properties["ImpersonationLevel"] = "1";
752 break;
753 case "identify":
754 properties["ImpersonationLevel"] = "2";
755 break;
756 case "impersonate":
757 properties["ImpersonationLevel"] = "3";
758 break;
759 case "delegate":
760 properties["ImpersonationLevel"] = "4";
761 break;
762 default:
763 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "ImpersonationLevel", impersonationLevelValue, "anonymous", "identify", "impersonate", "delegate"));
764 break;
765 }
766 break;
767 case "IsEnabled":
768 if (null == componentKey)
769 {
770 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
771 }
772 properties["IsEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
773 break;
774 case "MaxDumpCount":
775 if (null == componentKey)
776 {
777 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
778 }
779 properties["MaxDumpCount"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
780 break;
781 case "Password":
782 if (null == componentKey)
783 {
784 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
785 }
786 properties["Password"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
787 break;
788 case "QCAuthenticateMsgs":
789 if (null == componentKey)
790 {
791 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
792 }
793 string qcAuthenticateMsgsValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
794 switch (qcAuthenticateMsgsValue)
795 {
796 case "secureApps":
797 properties["QCAuthenticateMsgs"] = "0";
798 break;
799 case "off":
800 properties["QCAuthenticateMsgs"] = "1";
801 break;
802 case "on":
803 properties["QCAuthenticateMsgs"] = "2";
804 break;
805 default:
806 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "QCAuthenticateMsgs", qcAuthenticateMsgsValue, "secureApps", "off", "on"));
807 break;
808 }
809 break;
810 case "QCListenerMaxThreads":
811 if (null == componentKey)
812 {
813 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
814 }
815 properties["QCListenerMaxThreads"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
816 break;
817 case "QueueListenerEnabled":
818 if (null == componentKey)
819 {
820 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
821 }
822 properties["QueueListenerEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
823 break;
824 case "QueuingEnabled":
825 if (null == componentKey)
826 {
827 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
828 }
829 properties["QueuingEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
830 break;
831 case "RecycleActivationLimit":
832 if (null == componentKey)
833 {
834 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
835 }
836 properties["RecycleActivationLimit"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
837 break;
838 case "RecycleCallLimit":
839 if (null == componentKey)
840 {
841 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
842 }
843 properties["RecycleCallLimit"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
844 break;
845 case "RecycleExpirationTimeout":
846 if (null == componentKey)
847 {
848 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
849 }
850 properties["RecycleExpirationTimeout"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
851 break;
852 case "RecycleLifetimeLimit":
853 if (null == componentKey)
854 {
855 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
856 }
857 properties["RecycleLifetimeLimit"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
858 break;
859 case "RecycleMemoryLimit":
860 if (null == componentKey)
861 {
862 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
863 }
864 properties["RecycleMemoryLimit"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
865 break;
866 case "Replicable":
867 if (null == componentKey)
868 {
869 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
870 }
871 properties["Replicable"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
872 break;
873 case "RunForever":
874 if (null == componentKey)
875 {
876 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
877 }
878 properties["RunForever"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
879 break;
880 case "ShutdownAfter":
881 if (null == componentKey)
882 {
883 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
884 }
885 properties["ShutdownAfter"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
886 break;
887 case "SoapActivated":
888 if (null == componentKey)
889 {
890 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
891 }
892 properties["SoapActivated"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
893 break;
894 case "SoapBaseUrl":
895 if (null == componentKey)
896 {
897 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
898 }
899 properties["SoapBaseUrl"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
900 break;
901 case "SoapMailTo":
902 if (null == componentKey)
903 {
904 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
905 }
906 properties["SoapMailTo"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
907 break;
908 case "SoapVRoot":
909 if (null == componentKey)
910 {
911 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
912 }
913 properties["SoapVRoot"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
914 break;
915 case "SRPEnabled":
916 if (null == componentKey)
917 {
918 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
919 }
920 properties["SRPEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
921 break;
922 case "SRPTrustLevel":
923 if (null == componentKey)
924 {
925 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
926 }
927 var srpTrustLevelValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
928 switch (srpTrustLevelValue)
929 {
930 case "disallowed":
931 properties["SRPTrustLevel"] = "0";
932 break;
933 case "fullyTrusted":
934 properties["SRPTrustLevel"] = "262144";
935 break;
936 default:
937 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "SRPTrustLevel", srpTrustLevelValue, "disallowed", "fullyTrusted"));
938 break;
939 }
940 break;
941 default:
942 this.ParseHelper.UnexpectedAttribute(node, attrib);
943 break;
944 }
945 }
946 else
947 {
948 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
949 }
950 }
951
952 if (null != componentKey && null == name)
953 {
954 this.Messaging.Write(ComPlusErrors.RequiredAttributeUnderComponent(sourceLineNumbers, node.Name.LocalName, "Name"));
955 }
956 if (null == componentKey && null == id && null == name)
957 {
958 this.Messaging.Write(ComPlusErrors.RequiredAttributeNotUnderComponent(sourceLineNumbers, node.Name.LocalName, "Id", "Name"));
959 }
960
961 foreach (var child in node.Elements())
962 {
963 if (this.Namespace == child.Name.Namespace)
964 {
965 switch (child.Name.LocalName)
966 {
967 case "ComPlusApplicationRole":
968 this.ParseComPlusApplicationRoleElement(intermediate, section, child, componentKey, key?.Id);
969 break;
970 case "ComPlusAssembly":
971 this.ParseComPlusAssemblyElement(intermediate, section, child, componentKey, win64, key?.Id);
972 break;
973 default:
974 this.ParseHelper.UnexpectedElement(node, child);
975 break;
976 }
977 }
978 else
979 {
980 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
981 }
982 }
983
984 section.AddSymbol(new ComPlusApplicationSymbol(sourceLineNumbers, key)
985 {
986 PartitionRef = partitionKey,
987 ComponentRef = componentKey,
988 ApplicationId = id,
989 Name = name,
990 });
991
992 foreach (var kvp in properties)
993 {
994 section.AddSymbol(new ComPlusApplicationPropertySymbol(sourceLineNumbers)
995 {
996 ApplicationRef = key?.Id,
997 Name = kvp.Key,
998 Value = kvp.Value,
999 });
1000 }
1001
1002 if (componentKey != null)
1003 {
1004 this.AddReferenceToConfigureComPlus(section, sourceLineNumbers, node.Name.LocalName, win64);
1005 }
1006 }
1007
1008 /// <summary>
1009 /// Parses a COM+ application role element.
1010 /// </summary>
1011 /// <param name="node">Element to parse.</param>
1012 /// <param name="componentKey">Identifier of parent component.</param>
1013 /// <param name="applicationKey">Optional identifier of parent application.</param>
1014 private void ParseComPlusApplicationRoleElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string applicationKey)
1015 {
1016 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1017
1018 Identifier key = null;
1019 string name = null;
1020
1021 var properties = new Dictionary<string, string>();
1022
1023 foreach (var attrib in node.Attributes())
1024 {
1025 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1026 {
1027 switch (attrib.Name.LocalName)
1028 {
1029 case "Id":
1030 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1031 break;
1032 case "Application":
1033 if (null != applicationKey)
1034 {
1035 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1036 }
1037 applicationKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1038 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusApplication, applicationKey);
1039 break;
1040 case "Name":
1041 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1042 break;
1043 case "Description":
1044 if (null == componentKey)
1045 {
1046 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
1047 }
1048 properties["Description"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1049 break;
1050 default:
1051 this.ParseHelper.UnexpectedAttribute(node, attrib);
1052 break;
1053 }
1054 }
1055 else
1056 {
1057 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1058 }
1059 }
1060
1061 if (null == applicationKey)
1062 {
1063 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Application"));
1064 }
1065
1066 foreach (var child in node.Elements())
1067 {
1068 if (this.Namespace == child.Name.Namespace)
1069 {
1070 switch (child.Name.LocalName)
1071 {
1072 case "ComPlusUserInApplicationRole":
1073 this.ParseComPlusUserInApplicationRoleElement(intermediate, section, child, componentKey, key?.Id);
1074 break;
1075 case "ComPlusGroupInApplicationRole":
1076 this.ParseComPlusGroupInApplicationRoleElement(intermediate, section, child, componentKey, key?.Id);
1077 break;
1078 default:
1079 this.ParseHelper.UnexpectedElement(node, child);
1080 break;
1081 }
1082 }
1083 else
1084 {
1085 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
1086 }
1087 }
1088
1089 section.AddSymbol(new ComPlusApplicationRoleSymbol(sourceLineNumbers, key)
1090 {
1091 ApplicationRef = applicationKey,
1092 ComponentRef = componentKey,
1093 Name = name,
1094 });
1095
1096 foreach (var kvp in properties)
1097 {
1098 section.AddSymbol(new ComPlusApplicationRolePropertySymbol(sourceLineNumbers)
1099 {
1100 ApplicationRoleRef = key?.Id,
1101 Name = kvp.Key,
1102 Value = kvp.Value,
1103 });
1104 }
1105 }
1106
1107 /// <summary>
1108 /// Parses a COM+ application role user element.
1109 /// </summary>
1110 /// <param name="node">Element to parse.</param>
1111 /// <param name="componentKey">Identifier of parent component.</param>
1112 /// <param name="applicationKey">Optional identifier of parent application role.</param>
1113 private void ParseComPlusUserInApplicationRoleElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string applicationRoleKey)
1114 {
1115 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1116
1117 Identifier key = null;
1118 string user = null;
1119
1120 foreach (var attrib in node.Attributes())
1121 {
1122 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1123 {
1124 switch (attrib.Name.LocalName)
1125 {
1126 case "Id":
1127 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1128 break;
1129 case "ApplicationRole":
1130 if (null != applicationRoleKey)
1131 {
1132 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1133 }
1134 applicationRoleKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1135 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusApplicationRole, applicationRoleKey);
1136 break;
1137 case "User":
1138 user = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1139 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user);
1140 break;
1141 default:
1142 this.ParseHelper.UnexpectedAttribute(node, attrib);
1143 break;
1144 }
1145 }
1146 else
1147 {
1148 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1149 }
1150 }
1151
1152 if (null == applicationRoleKey)
1153 {
1154 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ApplicationRole"));
1155 }
1156
1157 section.AddSymbol(new ComPlusUserInApplicationRoleSymbol(sourceLineNumbers, key)
1158 {
1159 ApplicationRoleRef = applicationRoleKey,
1160 ComponentRef = componentKey,
1161 UserRef = user,
1162 });
1163 }
1164
1165 /// <summary>
1166 /// Parses a COM+ application role group element.
1167 /// </summary>
1168 /// <param name="node">Element to parse.</param>
1169 /// <param name="componentKey">Identifier of parent component.</param>
1170 /// <param name="applicationKey">Optional identifier of parent application role.</param>
1171 private void ParseComPlusGroupInApplicationRoleElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string applicationRoleKey)
1172 {
1173 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1174
1175 Identifier key = null;
1176 string group = null;
1177
1178 foreach (var attrib in node.Attributes())
1179 {
1180 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1181 {
1182 switch (attrib.Name.LocalName)
1183 {
1184 case "Id":
1185 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1186 break;
1187 case "ApplicationRole":
1188 if (null != applicationRoleKey)
1189 {
1190 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1191 }
1192 applicationRoleKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1193 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusApplicationRole, applicationRoleKey);
1194 break;
1195 case "Group":
1196 group = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1197 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "Group", group);
1198 break;
1199 default:
1200 this.ParseHelper.UnexpectedAttribute(node, attrib);
1201 break;
1202 }
1203 }
1204 else
1205 {
1206 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1207 }
1208 }
1209
1210 if (null == applicationRoleKey)
1211 {
1212 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ApplicationRole"));
1213 }
1214
1215 section.AddSymbol(new ComPlusGroupInApplicationRoleSymbol(sourceLineNumbers, key)
1216 {
1217 ApplicationRoleRef = applicationRoleKey,
1218 ComponentRef = componentKey,
1219 GroupRef = group,
1220 });
1221 }
1222
1223 /// <summary>
1224 /// Parses a COM+ assembly element.
1225 /// </summary>
1226 /// <param name="node">Element to parse.</param>
1227 /// <param name="componentKey">Identifier of parent component.</param>
1228 /// <param name="applicationKey">Optional identifier of parent application.</param>
1229 private void ParseComPlusAssemblyElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, bool win64, string applicationKey)
1230 {
1231 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1232
1233 Identifier key = null;
1234 string assemblyName = null;
1235 string dllPath = null;
1236 string tlbPath = null;
1237 string psDllPath = null;
1238 int attributes = 0;
1239
1240 var hasComponents = false;
1241
1242 foreach (var attrib in node.Attributes())
1243 {
1244 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1245 {
1246 switch (attrib.Name.LocalName)
1247 {
1248 case "Id":
1249 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1250 break;
1251 case "Application":
1252 if (null != applicationKey)
1253 {
1254 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1255 }
1256 applicationKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1257 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusApplication, applicationKey);
1258 break;
1259 case "AssemblyName":
1260 assemblyName = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1261 break;
1262 case "DllPath":
1263 dllPath = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1264 break;
1265 case "TlbPath":
1266 tlbPath = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1267 break;
1268 case "PSDllPath":
1269 psDllPath = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1270 break;
1271 case "Type":
1272 string typeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1273 switch (typeValue)
1274 {
1275 case ".net":
1276 attributes |= (int)CpiAssemblyAttributes.DotNetAssembly;
1277 break;
1278 case "native":
1279 attributes &= ~(int)CpiAssemblyAttributes.DotNetAssembly;
1280 break;
1281 default:
1282 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusAssembly", "Type", typeValue, ".net", "native"));
1283 break;
1284 }
1285 break;
1286 case "EventClass":
1287 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
1288 {
1289 attributes |= (int)CpiAssemblyAttributes.EventClass;
1290 }
1291 else
1292 {
1293 attributes &= ~(int)CpiAssemblyAttributes.EventClass;
1294 }
1295 break;
1296 case "DllPathFromGAC":
1297 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
1298 {
1299 attributes |= (int)CpiAssemblyAttributes.DllPathFromGAC;
1300 }
1301 else
1302 {
1303 attributes &= ~(int)CpiAssemblyAttributes.DllPathFromGAC;
1304 }
1305 break;
1306 case "RegisterInCommit":
1307 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
1308 {
1309 attributes |= (int)CpiAssemblyAttributes.RegisterInCommit;
1310 }
1311 else
1312 {
1313 attributes &= ~(int)CpiAssemblyAttributes.RegisterInCommit;
1314 }
1315 break;
1316 default:
1317 this.ParseHelper.UnexpectedAttribute(node, attrib);
1318 break;
1319 }
1320 }
1321 else
1322 {
1323 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1324 }
1325 }
1326
1327 if (null == applicationKey && 0 == (attributes & (int)CpiAssemblyAttributes.DotNetAssembly))
1328 {
1329 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Application", "Type", "native"));
1330 }
1331 if (null != assemblyName && 0 == (attributes & (int)CpiAssemblyAttributes.DllPathFromGAC))
1332 {
1333 this.Messaging.Write(ComPlusErrors.UnexpectedAttributeWithoutOtherValue(sourceLineNumbers, node.Name.LocalName, "AssemblyName", "DllPathFromGAC", "no"));
1334 }
1335 if (null == tlbPath && 0 != (attributes & (int)CpiAssemblyAttributes.DotNetAssembly))
1336 {
1337 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "TlbPath", "Type", ".net"));
1338 }
1339 if (null != psDllPath && 0 != (attributes & (int)CpiAssemblyAttributes.DotNetAssembly))
1340 {
1341 this.Messaging.Write(ComPlusErrors.UnexpectedAttributeWithOtherValue(sourceLineNumbers, node.Name.LocalName, "PSDllPath", "Type", ".net"));
1342 }
1343 if (0 != (attributes & (int)CpiAssemblyAttributes.EventClass) && 0 != (attributes & (int)CpiAssemblyAttributes.DotNetAssembly))
1344 {
1345 this.Messaging.Write(ComPlusErrors.UnexpectedAttributeWithOtherValue(sourceLineNumbers, node.Name.LocalName, "EventClass", "yes", "Type", ".net"));
1346 }
1347
1348 foreach (var child in node.Elements())
1349 {
1350 if (this.Namespace == child.Name.Namespace)
1351 {
1352 switch (child.Name.LocalName)
1353 {
1354 case "ComPlusAssemblyDependency":
1355 this.ParseComPlusAssemblyDependencyElement(intermediate, section, child, key?.Id);
1356 break;
1357 case "ComPlusComponent":
1358 this.ParseComPlusComponentElement(intermediate, section, child, componentKey, key?.Id);
1359 hasComponents = true;
1360 break;
1361 default:
1362 this.ParseHelper.UnexpectedElement(node, child);
1363 break;
1364 }
1365 }
1366 else
1367 {
1368 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
1369 }
1370 }
1371
1372 if (0 == (attributes & (int)CpiAssemblyAttributes.DotNetAssembly) && !hasComponents)
1373 {
1374 this.Messaging.Write(ComPlusWarnings.MissingComponents(sourceLineNumbers));
1375 }
1376
1377 section.AddSymbol(new ComPlusAssemblySymbol(sourceLineNumbers, key)
1378 {
1379 ApplicationRef = applicationKey,
1380 ComponentRef = componentKey,
1381 AssemblyName = assemblyName,
1382 DllPath = dllPath,
1383 TlbPath = tlbPath,
1384 PSDllPath = psDllPath,
1385 Attributes = attributes,
1386 });
1387
1388 this.AddReferenceToConfigureComPlus(section, sourceLineNumbers, node.Name.LocalName, win64);
1389 }
1390
1391 /// <summary>
1392 /// Parses a COM+ assembly dependency element.
1393 /// </summary>
1394 /// <param name="node">Element to parse.</param>
1395 /// <param name="assemblyKey">Identifier of parent assembly.</param>
1396 private void ParseComPlusAssemblyDependencyElement(Intermediate intermediate, IntermediateSection section, XElement node, string assemblyKey)
1397 {
1398 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1399
1400 string requiredAssemblyKey = null;
1401
1402 foreach (var attrib in node.Attributes())
1403 {
1404 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1405 {
1406 switch (attrib.Name.LocalName)
1407 {
1408 case "RequiredAssembly":
1409 requiredAssemblyKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1410 break;
1411 default:
1412 this.ParseHelper.UnexpectedAttribute(node, attrib);
1413 break;
1414 }
1415 }
1416 else
1417 {
1418 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1419 }
1420 }
1421
1422 section.AddSymbol(new ComPlusAssemblyDependencySymbol(sourceLineNumbers)
1423 {
1424 AssemblyRef = assemblyKey,
1425 RequiredAssemblyRef = requiredAssemblyKey,
1426 });
1427 }
1428
1429 /// <summary>
1430 /// Parses a COM+ component element.
1431 /// </summary>
1432 /// <param name="node">Element to parse.</param>
1433 /// <param name="componentKey">Identifier of parent component.</param>
1434 /// <param name="assemblyKey">Identifier of parent assembly.</param>
1435 private void ParseComPlusComponentElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string assemblyKey)
1436 {
1437 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1438
1439 Identifier key = null;
1440 string clsid = null;
1441
1442 var properties = new Dictionary<string, string>();
1443
1444 foreach (var attrib in node.Attributes())
1445 {
1446 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1447 {
1448 switch (attrib.Name.LocalName)
1449 {
1450 case "Id":
1451 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1452 break;
1453 case "CLSID":
1454 clsid = "{" + this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib) + "}";
1455 break;
1456 case "AllowInprocSubscribers":
1457 properties["AllowInprocSubscribers"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1458 break;
1459 case "ComponentAccessChecksEnabled":
1460 properties["ComponentAccessChecksEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1461 break;
1462 case "ComponentTransactionTimeout":
1463 properties["ComponentTransactionTimeout"] = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 3600).ToString();
1464 break;
1465 case "ComponentTransactionTimeoutEnabled":
1466 properties["ComponentTransactionTimeoutEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1467 break;
1468 case "COMTIIntrinsics":
1469 properties["COMTIIntrinsics"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1470 break;
1471 case "ConstructionEnabled":
1472 properties["ConstructionEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1473 break;
1474 case "ConstructorString":
1475 properties["ConstructorString"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1476 break;
1477 case "CreationTimeout":
1478 properties["CreationTimeout"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1479 break;
1480 case "Description":
1481 properties["Description"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1482 break;
1483 case "EventTrackingEnabled":
1484 properties["EventTrackingEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1485 break;
1486 case "ExceptionClass":
1487 properties["ExceptionClass"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1488 break;
1489 case "FireInParallel":
1490 properties["FireInParallel"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1491 break;
1492 case "IISIntrinsics":
1493 properties["IISIntrinsics"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1494 break;
1495 case "InitializesServerApplication":
1496 properties["InitializesServerApplication"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1497 break;
1498 case "IsEnabled":
1499 properties["IsEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1500 break;
1501 case "IsPrivateComponent":
1502 properties["IsPrivateComponent"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1503 break;
1504 case "JustInTimeActivation":
1505 properties["JustInTimeActivation"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1506 break;
1507 case "LoadBalancingSupported":
1508 properties["LoadBalancingSupported"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1509 break;
1510 case "MaxPoolSize":
1511 properties["MaxPoolSize"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1512 break;
1513 case "MinPoolSize":
1514 properties["MinPoolSize"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1515 break;
1516 case "MultiInterfacePublisherFilterCLSID":
1517 properties["MultiInterfacePublisherFilterCLSID"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1518 break;
1519 case "MustRunInClientContext":
1520 properties["MustRunInClientContext"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1521 break;
1522 case "MustRunInDefaultContext":
1523 properties["MustRunInDefaultContext"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1524 break;
1525 case "ObjectPoolingEnabled":
1526 properties["ObjectPoolingEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1527 break;
1528 case "PublisherID":
1529 properties["PublisherID"] = this.TryFormatGuidValue(this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib));
1530 break;
1531 case "SoapAssemblyName":
1532 properties["SoapAssemblyName"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1533 break;
1534 case "SoapTypeName":
1535 properties["SoapTypeName"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1536 break;
1537 case "Synchronization":
1538 var synchronizationValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1539 switch (synchronizationValue)
1540 {
1541 case "ignored":
1542 properties["Synchronization"] = "0";
1543 break;
1544 case "none":
1545 properties["Synchronization"] = "1";
1546 break;
1547 case "supported":
1548 properties["Synchronization"] = "2";
1549 break;
1550 case "required":
1551 properties["Synchronization"] = "3";
1552 break;
1553 case "requiresNew":
1554 properties["Synchronization"] = "4";
1555 break;
1556 default:
1557 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusComponent", "Synchronization", synchronizationValue, "ignored", "none", "supported", "required", "requiresNew"));
1558 break;
1559 }
1560 break;
1561 case "Transaction":
1562 var transactionValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1563 switch (transactionValue)
1564 {
1565 case "ignored":
1566 properties["Transaction"] = "0";
1567 break;
1568 case "none":
1569 properties["Transaction"] = "1";
1570 break;
1571 case "supported":
1572 properties["Transaction"] = "2";
1573 break;
1574 case "required":
1575 properties["Transaction"] = "3";
1576 break;
1577 case "requiresNew":
1578 properties["Transaction"] = "4";
1579 break;
1580 default:
1581 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusComponent", "Transaction", transactionValue, "ignored", "none", "supported", "required", "requiresNew"));
1582 break;
1583 }
1584 break;
1585 case "TxIsolationLevel":
1586 var txIsolationLevelValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1587 switch (txIsolationLevelValue)
1588 {
1589 case "any":
1590 properties["TxIsolationLevel"] = "0";
1591 break;
1592 case "readUnCommitted":
1593 properties["TxIsolationLevel"] = "1";
1594 break;
1595 case "readCommitted":
1596 properties["TxIsolationLevel"] = "2";
1597 break;
1598 case "repeatableRead":
1599 properties["TxIsolationLevel"] = "3";
1600 break;
1601 case "serializable":
1602 properties["TxIsolationLevel"] = "4";
1603 break;
1604 default:
1605 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusComponent", "TxIsolationLevel", txIsolationLevelValue, "any", "readUnCommitted", "readCommitted", "repeatableRead", "serializable"));
1606 break;
1607 }
1608 break;
1609 default:
1610 this.ParseHelper.UnexpectedAttribute(node, attrib);
1611 break;
1612 }
1613 }
1614 else
1615 {
1616 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1617 }
1618 }
1619
1620 foreach (var child in node.Elements())
1621 {
1622 if (this.Namespace == child.Name.Namespace)
1623 {
1624 switch (child.Name.LocalName)
1625 {
1626 case "ComPlusRoleForComponent":
1627 this.ParseComPlusRoleForComponentElement(intermediate, section, child, componentKey, key?.Id);
1628 break;
1629 case "ComPlusInterface":
1630 this.ParseComPlusInterfaceElement(intermediate, section, child, componentKey, key?.Id);
1631 break;
1632 case "ComPlusSubscription":
1633 this.ParseComPlusSubscriptionElement(intermediate, section, child, componentKey, key?.Id);
1634 break;
1635 default:
1636 this.ParseHelper.UnexpectedElement(node, child);
1637 break;
1638 }
1639 }
1640 else
1641 {
1642 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
1643 }
1644 }
1645
1646 section.AddSymbol(new ComPlusComponentSymbol(sourceLineNumbers, key)
1647 {
1648 AssemblyRef = assemblyKey,
1649 CLSID = clsid,
1650 });
1651
1652 foreach (var kvp in properties)
1653 {
1654 section.AddSymbol(new ComPlusComponentPropertySymbol(sourceLineNumbers)
1655 {
1656 ComPlusComponentRef = key?.Id,
1657 Name = kvp.Key,
1658 Value = kvp.Value,
1659 });
1660 }
1661 }
1662
1663 /// <summary>
1664 /// Parses a COM+ application role for component element.
1665 /// </summary>
1666 /// <param name="node">Element to parse.</param>
1667 /// <param name="componentKey">Identifier of parent component.</param>
1668 /// <param name="cpcomponentKey">Identifier of parent COM+ component.</param>
1669 private void ParseComPlusRoleForComponentElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string cpcomponentKey)
1670 {
1671 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1672
1673 Identifier key = null;
1674 string applicationRoleKey = null;
1675
1676 foreach (var attrib in node.Attributes())
1677 {
1678 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1679 {
1680 switch (attrib.Name.LocalName)
1681 {
1682 case "Id":
1683 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1684 break;
1685 case "Component":
1686 if (null != cpcomponentKey)
1687 {
1688 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1689 }
1690 cpcomponentKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1691 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusComponent, cpcomponentKey);
1692 break;
1693 case "ApplicationRole":
1694 applicationRoleKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1695 break;
1696 default:
1697 this.ParseHelper.UnexpectedAttribute(node, attrib);
1698 break;
1699 }
1700 }
1701 else
1702 {
1703 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1704 }
1705 }
1706
1707 if (null == cpcomponentKey)
1708 {
1709 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Component"));
1710 }
1711
1712 section.AddSymbol(new ComPlusRoleForComponentSymbol(sourceLineNumbers, key)
1713 {
1714 ComPlusComponentRef = cpcomponentKey,
1715 ApplicationRoleRef = applicationRoleKey,
1716 ComponentRef = componentKey,
1717 });
1718 }
1719
1720 /// <summary>
1721 /// Parses a COM+ interface element.
1722 /// </summary>
1723 /// <param name="node">Element to parse.</param>
1724 /// <param name="componentKey">Identifier of parent component.</param>
1725 /// <param name="cpcomponentKey">Identifier of parent COM+ component.</param>
1726 private void ParseComPlusInterfaceElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string cpcomponentKey)
1727 {
1728 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1729
1730 // parse attributes
1731 Identifier key = null;
1732 string iid = null;
1733
1734 var properties = new Dictionary<string, string>();
1735
1736 foreach (var attrib in node.Attributes())
1737 {
1738 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1739 {
1740 switch (attrib.Name.LocalName)
1741 {
1742 case "Id":
1743 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1744 break;
1745 case "IID":
1746 iid = "{" + this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib) + "}";
1747 break;
1748 case "Description":
1749 properties["Description"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1750 break;
1751 case "QueuingEnabled":
1752 properties["QueuingEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1753 break;
1754 default:
1755 this.ParseHelper.UnexpectedAttribute(node, attrib);
1756 break;
1757 }
1758 }
1759 else
1760 {
1761 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1762 }
1763 }
1764
1765 foreach (var child in node.Elements())
1766 {
1767 if (this.Namespace == child.Name.Namespace)
1768 {
1769 switch (child.Name.LocalName)
1770 {
1771 case "ComPlusRoleForInterface":
1772 this.ParseComPlusRoleForInterfaceElement(intermediate, section, child, componentKey, key?.Id);
1773 break;
1774 case "ComPlusMethod":
1775 this.ParseComPlusMethodElement(intermediate, section, child, componentKey, key?.Id);
1776 break;
1777 default:
1778 this.ParseHelper.UnexpectedElement(node, child);
1779 break;
1780 }
1781 }
1782 else
1783 {
1784 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
1785 }
1786 }
1787
1788 section.AddSymbol(new ComPlusInterfaceSymbol(sourceLineNumbers, key)
1789 {
1790 ComPlusComponentRef = cpcomponentKey,
1791 IID = iid,
1792 });
1793
1794 foreach (var kvp in properties)
1795 {
1796 section.AddSymbol(new ComPlusInterfacePropertySymbol(sourceLineNumbers)
1797 {
1798 InterfaceRef = key?.Id,
1799 Name = kvp.Key,
1800 Value = kvp.Value,
1801 });
1802 }
1803 }
1804
1805 /// <summary>
1806 /// Parses a COM+ application role for interface element.
1807 /// </summary>
1808 /// <param name="node">Element to parse.</param>
1809 /// <param name="componentKey">Identifier of parent component.</param>
1810 /// <param name="interfaceKey">Identifier of parent interface.</param>
1811 private void ParseComPlusRoleForInterfaceElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string interfaceKey)
1812 {
1813 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1814
1815 Identifier key = null;
1816 string applicationRoleKey = null;
1817
1818 foreach (var attrib in node.Attributes())
1819 {
1820 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1821 {
1822 switch (attrib.Name.LocalName)
1823 {
1824 case "Id":
1825 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1826 break;
1827 case "Interface":
1828 if (null != interfaceKey)
1829 {
1830 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1831 }
1832 interfaceKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1833 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusInterface, interfaceKey);
1834 break;
1835 case "ApplicationRole":
1836 applicationRoleKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1837 break;
1838 default:
1839 this.ParseHelper.UnexpectedAttribute(node, attrib);
1840 break;
1841 }
1842 }
1843 else
1844 {
1845 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1846 }
1847 }
1848
1849 if (null == interfaceKey)
1850 {
1851 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Interface"));
1852 }
1853
1854 section.AddSymbol(new ComPlusRoleForInterfaceSymbol(sourceLineNumbers, key)
1855 {
1856 InterfaceRef = interfaceKey,
1857 ApplicationRoleRef = applicationRoleKey,
1858 ComponentRef = componentKey,
1859 });
1860 }
1861
1862 /// <summary>
1863 /// Parses a COM+ method element.
1864 /// </summary>
1865 /// <param name="node">Element to parse.</param>
1866 /// <param name="componentKey">Identifier of parent component.</param>
1867 /// <param name="interfaceKey">Identifier of parent interface.</param>
1868 private void ParseComPlusMethodElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string interfaceKey)
1869 {
1870 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1871
1872 Identifier key = null;
1873 var index = CompilerConstants.IntegerNotSet;
1874 string name = null;
1875
1876 var properties = new Dictionary<string, string>();
1877
1878 foreach (var attrib in node.Attributes())
1879 {
1880 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1881 {
1882 switch (attrib.Name.LocalName)
1883 {
1884 case "Id":
1885 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1886 break;
1887 case "Index":
1888 index = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
1889 break;
1890 case "Name":
1891 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1892 break;
1893 case "AutoComplete":
1894 properties["AutoComplete"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1895 break;
1896 case "Description":
1897 properties["Description"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1898 break;
1899 default:
1900 this.ParseHelper.UnexpectedAttribute(node, attrib);
1901 break;
1902 }
1903 }
1904 else
1905 {
1906 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1907 }
1908 }
1909
1910 foreach (var child in node.Elements())
1911 {
1912 if (this.Namespace == child.Name.Namespace)
1913 {
1914 switch (child.Name.LocalName)
1915 {
1916 case "ComPlusRoleForMethod":
1917 this.ParseComPlusRoleForMethodElement(intermediate, section, child, componentKey, key?.Id);
1918 break;
1919 default:
1920 this.ParseHelper.UnexpectedElement(node, child);
1921 break;
1922 }
1923 }
1924 else
1925 {
1926 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
1927 }
1928 }
1929
1930 if (CompilerConstants.IntegerNotSet == index && null == name)
1931 {
1932 this.Messaging.Write(ComPlusErrors.RequiredAttribute(sourceLineNumbers, node.Name.LocalName, "Index", "Name"));
1933 }
1934
1935 var symbol = section.AddSymbol(new ComPlusMethodSymbol(sourceLineNumbers, key)
1936 {
1937 InterfaceRef = interfaceKey,
1938 Name = name,
1939 });
1940
1941 if (CompilerConstants.IntegerNotSet != index)
1942 {
1943 symbol.Index = index;
1944 }
1945
1946 foreach (var kvp in properties)
1947 {
1948 section.AddSymbol(new ComPlusMethodPropertySymbol(sourceLineNumbers)
1949 {
1950 MethodRef = key?.Id,
1951 Name = kvp.Key,
1952 Value = kvp.Value,
1953 });
1954 }
1955 }
1956
1957 /// <summary>
1958 /// Parses a COM+ application role for method element.
1959 /// </summary>
1960 /// <param name="node">Element to parse.</param>
1961 /// <param name="componentKey">Identifier of parent component.</param>
1962 /// <param name="methodKey">Identifier of parent method.</param>
1963 private void ParseComPlusRoleForMethodElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string methodKey)
1964 {
1965 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1966
1967 Identifier key = null;
1968 string applicationRoleKey = null;
1969
1970 foreach (var attrib in node.Attributes())
1971 {
1972 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1973 {
1974 switch (attrib.Name.LocalName)
1975 {
1976 case "Id":
1977 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1978 break;
1979 case "Method":
1980 if (null != methodKey)
1981 {
1982 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1983 }
1984 methodKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1985 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusMethod, methodKey);
1986 break;
1987 case "ApplicationRole":
1988 applicationRoleKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1989 break;
1990 default:
1991 this.ParseHelper.UnexpectedAttribute(node, attrib);
1992 break;
1993 }
1994 }
1995 else
1996 {
1997 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1998 }
1999 }
2000
2001 if (null == methodKey)
2002 {
2003 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Method"));
2004 }
2005
2006 section.AddSymbol(new ComPlusRoleForMethodSymbol(sourceLineNumbers, key)
2007 {
2008 MethodRef = methodKey,
2009 ApplicationRoleRef = applicationRoleKey,
2010 ComponentRef = componentKey,
2011 });
2012 }
2013
2014 /// <summary>
2015 /// Parses a COM+ event subscription element.
2016 /// </summary>
2017 /// <param name="node">Element to parse.</param>
2018 /// <param name="componentKey">Identifier of parent component.</param>
2019 /// <param name="cpcomponentKey">Identifier of parent COM+ component.</param>
2020 private void ParseComPlusSubscriptionElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string cpcomponentKey)
2021 {
2022 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
2023
2024 Identifier key = null;
2025 string id = null;
2026 string name = null;
2027 string eventCLSID = null;
2028 string publisherID = null;
2029
2030 var properties = new Dictionary<string, string>();
2031
2032 foreach (var attrib in node.Attributes())
2033 {
2034 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
2035 {
2036 switch (attrib.Name.LocalName)
2037 {
2038 case "Id":
2039 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
2040 break;
2041 case "Component":
2042 if (null != cpcomponentKey)
2043 {
2044 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
2045 }
2046 cpcomponentKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2047 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusComponent, cpcomponentKey);
2048 break;
2049 case "SubscriptionId":
2050 id = this.TryFormatGuidValue(this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib));
2051 break;
2052 case "Name":
2053 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2054 break;
2055 case "EventCLSID":
2056 eventCLSID = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2057 break;
2058 case "PublisherID":
2059 publisherID = this.TryFormatGuidValue(this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib));
2060 break;
2061 case "Description":
2062 properties["Description"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2063 break;
2064 case "Enabled":
2065 properties["Enabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
2066 break;
2067 case "EventClassPartitionID":
2068 properties["EventClassPartitionID"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2069 break;
2070 case "FilterCriteria":
2071 properties["FilterCriteria"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2072 break;
2073 case "InterfaceID":
2074 properties["InterfaceID"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2075 break;
2076 case "MachineName":
2077 properties["MachineName"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2078 break;
2079 case "MethodName":
2080 properties["MethodName"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2081 break;
2082 case "PerUser":
2083 properties["PerUser"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
2084 break;
2085 case "Queued":
2086 properties["Queued"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
2087 break;
2088 case "SubscriberMoniker":
2089 properties["SubscriberMoniker"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2090 break;
2091 case "UserName":
2092 properties["UserName"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2093 break;
2094 default:
2095 this.ParseHelper.UnexpectedAttribute(node, attrib);
2096 break;
2097 }
2098 }
2099 else
2100 {
2101 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
2102 }
2103 }
2104
2105 if (null == cpcomponentKey)
2106 {
2107 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Component"));
2108 }
2109
2110 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
2111
2112 section.AddSymbol(new ComPlusSubscriptionSymbol(sourceLineNumbers, key)
2113 {
2114 Subscription = key?.Id,
2115 ComPlusComponentRef = cpcomponentKey,
2116 ComponentRef = componentKey,
2117 SubscriptionId = id,
2118 Name = name,
2119 EventCLSID = eventCLSID,
2120 PublisherID = publisherID,
2121 });
2122
2123 foreach (var kvp in properties)
2124 {
2125 section.AddSymbol(new ComPlusSubscriptionPropertySymbol(sourceLineNumbers)
2126 {
2127 SubscriptionRef = key?.Id,
2128 Name = kvp.Key,
2129 Value = kvp.Value,
2130 });
2131 }
2132 }
2133
2134 /// <summary>
2135 /// Attempts to parse the input value as a GUID, and in case the value is a valid
2136 /// GUID returnes it in the format "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}".
2137 /// </summary>
2138 /// <param name="val"></param>
2139 /// <returns></returns>
2140 private string TryFormatGuidValue(string val)
2141 {
2142 if (!Guid.TryParse(val, out var guid))
2143 {
2144 return val;
2145 }
2146 return guid.ToString("B").ToUpper();
2147 }
2148
2149 private void AddReferenceToConfigureComPlus(IntermediateSection section, SourceLineNumber sourceLineNumbers, string elementName, bool win64)
2150 {
2151 if (win64)
2152 {
2153 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "ConfigureComPlusInstall_x64");
2154 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "ConfigureComPlusUninstall_x64");
2155 }
2156 else
2157 {
2158 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "ConfigureComPlusInstall");
2159 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "ConfigureComPlusUninstall");
2160 }
2161
2162 }
2163 }
2164}
diff --git a/src/ext/ComPlus/wixext/ComPlusDecompiler.cs b/src/ext/ComPlus/wixext/ComPlusDecompiler.cs
new file mode 100644
index 00000000..6da2df94
--- /dev/null
+++ b/src/ext/ComPlus/wixext/ComPlusDecompiler.cs
@@ -0,0 +1,1845 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5#if TODO_CONSIDER_DECOMPILER
6 using System;
7 using System.Collections;
8 using System.Globalization;
9 using WixToolset.Data;
10 using WixToolset.Extensibility;
11 using ComPlus = WixToolset.Extensions.Serialize.ComPlus;
12 using Wix = WixToolset.Data.Serialize;
13
14 /// <summary>
15 /// The decompiler for the WiX Toolset COM+ Extension.
16 /// </summary>
17 public sealed class ComPlusDecompiler : DecompilerExtension
18 {
19 /// <summary>
20 /// Creates a decompiler for ComPlus Extension.
21 /// </summary>
22 public ComPlusDecompiler()
23 {
24 this.TableDefinitions = ComPlusExtensionData.GetExtensionTableDefinitions();
25 }
26
27 /// <summary>
28 /// Get the extensions library to be removed.
29 /// </summary>
30 /// <param name="tableDefinitions">Table definitions for library.</param>
31 /// <returns>Library to remove from decompiled output.</returns>
32 public override Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions)
33 {
34 return ComPlusExtensionData.GetExtensionLibrary(tableDefinitions);
35 }
36
37 /// <summary>
38 /// Decompiles an extension table.
39 /// </summary>
40 /// <param name="table">The table to decompile.</param>
41 public override void DecompileTable(Table table)
42 {
43 switch (table.Name)
44 {
45 case "ComPlusPartition":
46 this.DecompileComPlusPartitionTable(table);
47 break;
48 case "ComPlusPartitionProperty":
49 this.DecompileComPlusPartitionPropertyTable(table);
50 break;
51 case "ComPlusPartitionRole":
52 this.DecompileComPlusPartitionRoleTable(table);
53 break;
54 case "ComPlusUserInPartitionRole":
55 this.DecompileComPlusUserInPartitionRoleTable(table);
56 break;
57 case "ComPlusGroupInPartitionRole":
58 this.DecompileComPlusGroupInPartitionRoleTable(table);
59 break;
60 case "ComPlusPartitionUser":
61 this.DecompileComPlusPartitionUserTable(table);
62 break;
63 case "ComPlusApplication":
64 this.DecompileComPlusApplicationTable(table);
65 break;
66 case "ComPlusApplicationProperty":
67 this.DecompileComPlusApplicationPropertyTable(table);
68 break;
69 case "ComPlusApplicationRole":
70 this.DecompileComPlusApplicationRoleTable(table);
71 break;
72 case "ComPlusApplicationRoleProperty":
73 this.DecompileComPlusApplicationRolePropertyTable(table);
74 break;
75 case "ComPlusUserInApplicationRole":
76 this.DecompileComPlusUserInApplicationRoleTable(table);
77 break;
78 case "ComPlusGroupInApplicationRole":
79 this.DecompileComPlusGroupInApplicationRoleTable(table);
80 break;
81 case "ComPlusAssembly":
82 this.DecompileComPlusAssemblyTable(table);
83 break;
84 case "ComPlusComponent":
85 this.DecompileComPlusComponentTable(table);
86 break;
87 case "ComPlusComponentProperty":
88 this.DecompileComPlusComponentPropertyTable(table);
89 break;
90 case "ComPlusRoleForComponent":
91 this.DecompileComPlusRoleForComponentTable(table);
92 break;
93 case "ComPlusInterface":
94 this.DecompileComPlusInterfaceTable(table);
95 break;
96 case "ComPlusInterfaceProperty":
97 this.DecompileComPlusInterfacePropertyTable(table);
98 break;
99 case "ComPlusRoleForInterface":
100 this.DecompileComPlusRoleForInterfaceTable(table);
101 break;
102 case "ComPlusMethod":
103 this.DecompileComPlusMethodTable(table);
104 break;
105 case "ComPlusMethodProperty":
106 this.DecompileComPlusMethodPropertyTable(table);
107 break;
108 case "ComPlusRoleForMethod":
109 this.DecompileComPlusRoleForMethodTable(table);
110 break;
111 case "ComPlusSubscription":
112 this.DecompileComPlusSubscriptionTable(table);
113 break;
114 case "ComPlusSubscriptionProperty":
115 this.DecompileComPlusSubscriptionPropertyTable(table);
116 break;
117 default:
118 base.DecompileTable(table);
119 break;
120 }
121 }
122
123 /// <summary>
124 /// Decompile the ComPlusPartition table.
125 /// </summary>
126 /// <param name="table">The table to decompile.</param>
127 private void DecompileComPlusPartitionTable(Table table)
128 {
129 foreach (Row row in table.Rows)
130 {
131 ComPlus.ComPlusPartition partition = new ComPlus.ComPlusPartition();
132
133 partition.Id = (string)row[0];
134
135 if (null != row[2])
136 {
137 partition.PartitionId = (string)row[2];
138 }
139
140 if (null != row[3])
141 {
142 partition.Name = (string)row[3];
143 }
144
145 if (null != row[1])
146 {
147 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]);
148 if (null != component)
149 {
150 component.AddChild(partition);
151 }
152 else
153 {
154 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component"));
155 }
156 }
157 else
158 {
159 this.Core.RootElement.AddChild(partition);
160 }
161 this.Core.IndexElement(row, partition);
162 }
163 }
164
165 /// <summary>
166 /// Decompile the ComPlusPartitionProperty table.
167 /// </summary>
168 /// <param name="table">The table to decompile.</param>
169 private void DecompileComPlusPartitionPropertyTable(Table table)
170 {
171 foreach (Row row in table.Rows)
172 {
173 ComPlus.ComPlusPartition partition = (ComPlus.ComPlusPartition)this.Core.GetIndexedElement("ComPlusPartition", (string)row[0]);
174 if (null == partition)
175 {
176 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Partition_", (string)row[0], "ComPlusPartition"));
177 }
178
179 switch ((string)row[1])
180 {
181 case "Changeable":
182 switch ((string)row[2])
183 {
184 case "1":
185 partition.Changeable = ComPlus.YesNoType.yes;
186 break;
187 case "0":
188 partition.Changeable = ComPlus.YesNoType.no;
189 break;
190 default:
191 // TODO: Warning
192 break;
193 }
194 break;
195 case "Deleteable":
196 switch ((string)row[2])
197 {
198 case "1":
199 partition.Deleteable = ComPlus.YesNoType.yes;
200 break;
201 case "0":
202 partition.Deleteable = ComPlus.YesNoType.no;
203 break;
204 default:
205 // TODO: Warning
206 break;
207 }
208 break;
209 case "Description":
210 partition.Description = (string)row[2];
211 break;
212 default:
213 // TODO: Warning
214 break;
215 }
216 }
217 }
218
219 /// <summary>
220 /// Decompile the ComPlusPartitionRole table.
221 /// </summary>
222 /// <param name="table">The table to decompile.</param>
223 private void DecompileComPlusPartitionRoleTable(Table table)
224 {
225 foreach (Row row in table.Rows)
226 {
227 ComPlus.ComPlusPartitionRole partitionRole = new ComPlus.ComPlusPartitionRole();
228
229 partitionRole.Id = (string)row[0];
230 partitionRole.Partition = (string)row[1];
231 partitionRole.Name = (string)row[3];
232
233 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
234 if (null != component)
235 {
236 component.AddChild(partitionRole);
237 }
238 else
239 {
240 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
241 }
242 }
243 }
244
245 /// <summary>
246 /// Decompile the ComPlusUserInPartitionRole table.
247 /// </summary>
248 /// <param name="table">The table to decompile.</param>
249 private void DecompileComPlusUserInPartitionRoleTable(Table table)
250 {
251 foreach (Row row in table.Rows)
252 {
253 ComPlus.ComPlusUserInPartitionRole userInPartitionRole = new ComPlus.ComPlusUserInPartitionRole();
254
255 userInPartitionRole.Id = (string)row[0];
256 userInPartitionRole.PartitionRole = (string)row[1];
257 userInPartitionRole.User = (string)row[3];
258
259 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
260 if (null != component)
261 {
262 component.AddChild(userInPartitionRole);
263 }
264 else
265 {
266 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
267 }
268 }
269 }
270
271 /// <summary>
272 /// Decompile the ComPlusGroupInPartitionRole table.
273 /// </summary>
274 /// <param name="table">The table to decompile.</param>
275 private void DecompileComPlusGroupInPartitionRoleTable(Table table)
276 {
277 foreach (Row row in table.Rows)
278 {
279 ComPlus.ComPlusGroupInPartitionRole groupInPartitionRole = new ComPlus.ComPlusGroupInPartitionRole();
280
281 groupInPartitionRole.Id = (string)row[0];
282 groupInPartitionRole.PartitionRole = (string)row[1];
283 groupInPartitionRole.Group = (string)row[3];
284
285 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
286 if (null != component)
287 {
288 component.AddChild(groupInPartitionRole);
289 }
290 else
291 {
292 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
293 }
294 }
295 }
296
297 /// <summary>
298 /// Decompile the ComPlusPartitionUser table.
299 /// </summary>
300 /// <param name="table">The table to decompile.</param>
301 private void DecompileComPlusPartitionUserTable(Table table)
302 {
303 foreach (Row row in table.Rows)
304 {
305 ComPlus.ComPlusPartitionUser partitionUser = new ComPlus.ComPlusPartitionUser();
306
307 partitionUser.Id = (string)row[0];
308 partitionUser.Partition = (string)row[1];
309 partitionUser.User = (string)row[3];
310
311 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
312 if (null != component)
313 {
314 component.AddChild(partitionUser);
315 }
316 else
317 {
318 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
319 }
320 }
321 }
322
323 /// <summary>
324 /// Decompile the ComPlusApplication table.
325 /// </summary>
326 /// <param name="table">The table to decompile.</param>
327 private void DecompileComPlusApplicationTable(Table table)
328 {
329 foreach (Row row in table.Rows)
330 {
331 ComPlus.ComPlusApplication application = new ComPlus.ComPlusApplication();
332
333 application.Id = (string)row[0];
334 application.Partition = (string)row[1];
335
336 if (null != row[3])
337 {
338 application.ApplicationId = (string)row[3];
339 }
340
341 if (null != row[4])
342 {
343 application.Name = (string)row[4];
344 }
345
346 if (null != row[2])
347 {
348 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]);
349 if (null != component)
350 {
351 component.AddChild(application);
352 }
353 else
354 {
355 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
356 }
357 }
358 else
359 {
360 this.Core.RootElement.AddChild(application);
361 }
362 this.Core.IndexElement(row, application);
363 }
364 }
365
366 /// <summary>
367 /// Decompile the ComPlusApplicationProperty table.
368 /// </summary>
369 /// <param name="table">The table to decompile.</param>
370 private void DecompileComPlusApplicationPropertyTable(Table table)
371 {
372 foreach (Row row in table.Rows)
373 {
374 ComPlus.ComPlusApplication application = (ComPlus.ComPlusApplication)this.Core.GetIndexedElement("ComPlusApplication", (string)row[0]);
375 if (null == application)
376 {
377 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Application_", (string)row[0], "ComPlusApplication"));
378 }
379
380 switch ((string)row[1])
381 {
382 case "3GigSupportEnabled":
383 switch ((string)row[2])
384 {
385 case "1":
386 application.ThreeGigSupportEnabled = ComPlus.YesNoType.yes;
387 break;
388 case "0":
389 application.ThreeGigSupportEnabled = ComPlus.YesNoType.no;
390 break;
391 default:
392 // TODO: Warning
393 break;
394 }
395 break;
396 case "AccessChecksLevel":
397 switch ((string)row[2])
398 {
399 case "0":
400 application.AccessChecksLevel = ComPlus.ComPlusApplication.AccessChecksLevelType.applicationLevel;
401 break;
402 case "1":
403 application.AccessChecksLevel = ComPlus.ComPlusApplication.AccessChecksLevelType.applicationComponentLevel;
404 break;
405 default:
406 // TODO: Warning
407 break;
408 }
409 break;
410 case "Activation":
411 switch ((string)row[2])
412 {
413 case "Inproc":
414 application.Activation = ComPlus.ComPlusApplication.ActivationType.inproc;
415 break;
416 case "Local":
417 application.Activation = ComPlus.ComPlusApplication.ActivationType.local;
418 break;
419 default:
420 // TODO: Warning
421 break;
422 }
423 break;
424 case "ApplicationAccessChecksEnabled":
425 switch ((string)row[2])
426 {
427 case "1":
428 application.ApplicationAccessChecksEnabled = ComPlus.YesNoType.yes;
429 break;
430 case "0":
431 application.ApplicationAccessChecksEnabled = ComPlus.YesNoType.no;
432 break;
433 default:
434 // TODO: Warning
435 break;
436 }
437 break;
438 case "ApplicationDirectory":
439 application.ApplicationDirectory = (string)row[2];
440 break;
441 case "Authentication":
442 switch ((string)row[2])
443 {
444 case "0":
445 application.Authentication = ComPlus.ComPlusApplication.AuthenticationType.@default;
446 break;
447 case "1":
448 application.Authentication = ComPlus.ComPlusApplication.AuthenticationType.none;
449 break;
450 case "2":
451 application.Authentication = ComPlus.ComPlusApplication.AuthenticationType.connect;
452 break;
453 case "3":
454 application.Authentication = ComPlus.ComPlusApplication.AuthenticationType.call;
455 break;
456 case "4":
457 application.Authentication = ComPlus.ComPlusApplication.AuthenticationType.packet;
458 break;
459 case "5":
460 application.Authentication = ComPlus.ComPlusApplication.AuthenticationType.integrity;
461 break;
462 case "6":
463 application.Authentication = ComPlus.ComPlusApplication.AuthenticationType.privacy;
464 break;
465 default:
466 // TODO: Warning
467 break;
468 }
469 break;
470 case "AuthenticationCapability":
471 switch ((string)row[2])
472 {
473 case "0":
474 application.AuthenticationCapability = ComPlus.ComPlusApplication.AuthenticationCapabilityType.none;
475 break;
476 case "2":
477 application.AuthenticationCapability = ComPlus.ComPlusApplication.AuthenticationCapabilityType.secureReference;
478 break;
479 case "32":
480 application.AuthenticationCapability = ComPlus.ComPlusApplication.AuthenticationCapabilityType.staticCloaking;
481 break;
482 case "64":
483 application.AuthenticationCapability = ComPlus.ComPlusApplication.AuthenticationCapabilityType.dynamicCloaking;
484 break;
485 default:
486 // TODO: Warning
487 break;
488 }
489 break;
490 case "Changeable":
491 switch ((string)row[2])
492 {
493 case "1":
494 application.Changeable = ComPlus.YesNoType.yes;
495 break;
496 case "0":
497 application.Changeable = ComPlus.YesNoType.no;
498 break;
499 default:
500 // TODO: Warning
501 break;
502 }
503 break;
504 case "CommandLine":
505 application.CommandLine = (string)row[2];
506 break;
507 case "ConcurrentApps":
508 int concurrentApps;
509 if (Int32.TryParse((string)row[2], out concurrentApps))
510 {
511 application.ConcurrentApps = concurrentApps;
512 }
513 else
514 {
515 // TODO: Warning
516 }
517 break;
518 case "CreatedBy":
519 application.CreatedBy = (string)row[2];
520 break;
521 case "CRMEnabled":
522 switch ((string)row[2])
523 {
524 case "1":
525 application.CRMEnabled = ComPlus.YesNoType.yes;
526 break;
527 case "0":
528 application.CRMEnabled = ComPlus.YesNoType.no;
529 break;
530 default:
531 // TODO: Warning
532 break;
533 }
534 break;
535 case "CRMLogFile":
536 application.CRMLogFile = (string)row[2];
537 break;
538 case "Deleteable":
539 switch ((string)row[2])
540 {
541 case "1":
542 application.Deleteable = ComPlus.YesNoType.yes;
543 break;
544 case "0":
545 application.Deleteable = ComPlus.YesNoType.no;
546 break;
547 default:
548 // TODO: Warning
549 break;
550 }
551 break;
552 case "Description":
553 application.Description = (string)row[2];
554 break;
555 case "DumpEnabled":
556 switch ((string)row[2])
557 {
558 case "1":
559 application.DumpEnabled = ComPlus.YesNoType.yes;
560 break;
561 case "0":
562 application.DumpEnabled = ComPlus.YesNoType.no;
563 break;
564 default:
565 // TODO: Warning
566 break;
567 }
568 break;
569 case "DumpOnException":
570 switch ((string)row[2])
571 {
572 case "1":
573 application.DumpOnException = ComPlus.YesNoType.yes;
574 break;
575 case "0":
576 application.DumpOnException = ComPlus.YesNoType.no;
577 break;
578 default:
579 // TODO: Warning
580 break;
581 }
582 break;
583 case "DumpOnFailfast":
584 switch ((string)row[2])
585 {
586 case "1":
587 application.DumpOnFailfast = ComPlus.YesNoType.yes;
588 break;
589 case "0":
590 application.DumpOnFailfast = ComPlus.YesNoType.no;
591 break;
592 default:
593 // TODO: Warning
594 break;
595 }
596 break;
597 case "DumpPath":
598 application.DumpPath = (string)row[2];
599 break;
600 case "EventsEnabled":
601 switch ((string)row[2])
602 {
603 case "1":
604 application.EventsEnabled = ComPlus.YesNoType.yes;
605 break;
606 case "0":
607 application.EventsEnabled = ComPlus.YesNoType.no;
608 break;
609 default:
610 // TODO: Warning
611 break;
612 }
613 break;
614 case "Identity":
615 application.Identity = (string)row[2];
616 break;
617 case "ImpersonationLevel":
618 switch ((string)row[2])
619 {
620 case "1":
621 application.ImpersonationLevel = ComPlus.ComPlusApplication.ImpersonationLevelType.anonymous;
622 break;
623 case "2":
624 application.ImpersonationLevel = ComPlus.ComPlusApplication.ImpersonationLevelType.identify;
625 break;
626 case "3":
627 application.ImpersonationLevel = ComPlus.ComPlusApplication.ImpersonationLevelType.impersonate;
628 break;
629 case "4":
630 application.ImpersonationLevel = ComPlus.ComPlusApplication.ImpersonationLevelType.@delegate;
631 break;
632 default:
633 // TODO: Warning
634 break;
635 }
636 break;
637 case "IsEnabled":
638 switch ((string)row[2])
639 {
640 case "1":
641 application.IsEnabled = ComPlus.YesNoType.yes;
642 break;
643 case "0":
644 application.IsEnabled = ComPlus.YesNoType.no;
645 break;
646 default:
647 // TODO: Warning
648 break;
649 }
650 break;
651 case "MaxDumpCount":
652 int maxDumpCount;
653 if (Int32.TryParse((string)row[2], out maxDumpCount))
654 {
655 application.MaxDumpCount = maxDumpCount;
656 }
657 else
658 {
659 // TODO: Warning
660 }
661 break;
662 case "Password":
663 application.Password = (string)row[2];
664 break;
665 case "QCAuthenticateMsgs":
666 switch ((string)row[2])
667 {
668 case "0":
669 application.QCAuthenticateMsgs = ComPlus.ComPlusApplication.QCAuthenticateMsgsType.secureApps;
670 break;
671 case "1":
672 application.QCAuthenticateMsgs = ComPlus.ComPlusApplication.QCAuthenticateMsgsType.off;
673 break;
674 case "2":
675 application.QCAuthenticateMsgs = ComPlus.ComPlusApplication.QCAuthenticateMsgsType.on;
676 break;
677 default:
678 // TODO: Warning
679 break;
680 }
681 break;
682 case "QCListenerMaxThreads":
683 int qcListenerMaxThreads;
684 if (Int32.TryParse((string)row[2], out qcListenerMaxThreads))
685 {
686 application.QCListenerMaxThreads = qcListenerMaxThreads;
687 }
688 else
689 {
690 // TODO: Warning
691 }
692 break;
693 case "QueueListenerEnabled":
694 switch ((string)row[2])
695 {
696 case "1":
697 application.QueueListenerEnabled = ComPlus.YesNoType.yes;
698 break;
699 case "0":
700 application.QueueListenerEnabled = ComPlus.YesNoType.no;
701 break;
702 default:
703 // TODO: Warning
704 break;
705 }
706 break;
707 case "QueuingEnabled":
708 switch ((string)row[2])
709 {
710 case "1":
711 application.QueuingEnabled = ComPlus.YesNoType.yes;
712 break;
713 case "0":
714 application.QueuingEnabled = ComPlus.YesNoType.no;
715 break;
716 default:
717 // TODO: Warning
718 break;
719 }
720 break;
721 case "RecycleActivationLimit":
722 int recycleActivationLimit;
723 if (Int32.TryParse((string)row[2], out recycleActivationLimit))
724 {
725 application.RecycleActivationLimit = recycleActivationLimit;
726 }
727 else
728 {
729 // TODO: Warning
730 }
731 break;
732 case "RecycleCallLimit":
733 int recycleCallLimit;
734 if (Int32.TryParse((string)row[2], out recycleCallLimit))
735 {
736 application.RecycleCallLimit = recycleCallLimit;
737 }
738 else
739 {
740 // TODO: Warning
741 }
742 break;
743 case "RecycleExpirationTimeout":
744 int recycleExpirationTimeout;
745 if (Int32.TryParse((string)row[2], out recycleExpirationTimeout))
746 {
747 application.RecycleExpirationTimeout = recycleExpirationTimeout;
748 }
749 else
750 {
751 // TODO: Warning
752 }
753 break;
754 case "RecycleLifetimeLimit":
755 int recycleLifetimeLimit;
756 if (Int32.TryParse((string)row[2], out recycleLifetimeLimit))
757 {
758 application.RecycleLifetimeLimit = recycleLifetimeLimit;
759 }
760 else
761 {
762 // TODO: Warning
763 }
764 break;
765 case "RecycleMemoryLimit":
766 int recycleMemoryLimit;
767 if (Int32.TryParse((string)row[2], out recycleMemoryLimit))
768 {
769 application.RecycleMemoryLimit = recycleMemoryLimit;
770 }
771 else
772 {
773 // TODO: Warning
774 }
775 break;
776 case "Replicable":
777 switch ((string)row[2])
778 {
779 case "1":
780 application.Replicable = ComPlus.YesNoType.yes;
781 break;
782 case "0":
783 application.Replicable = ComPlus.YesNoType.no;
784 break;
785 default:
786 // TODO: Warning
787 break;
788 }
789 break;
790 case "RunForever":
791 switch ((string)row[2])
792 {
793 case "1":
794 application.RunForever = ComPlus.YesNoType.yes;
795 break;
796 case "0":
797 application.RunForever = ComPlus.YesNoType.no;
798 break;
799 default:
800 // TODO: Warning
801 break;
802 }
803 break;
804 case "ShutdownAfter":
805 int shutdownAfter;
806 if (Int32.TryParse((string)row[2], out shutdownAfter))
807 {
808 application.ShutdownAfter = shutdownAfter;
809 }
810 else
811 {
812 // TODO: Warning
813 }
814 break;
815 case "SoapActivated":
816 switch ((string)row[2])
817 {
818 case "1":
819 application.SoapActivated = ComPlus.YesNoType.yes;
820 break;
821 case "0":
822 application.SoapActivated = ComPlus.YesNoType.no;
823 break;
824 default:
825 // TODO: Warning
826 break;
827 }
828 break;
829 case "SoapBaseUrl":
830 application.SoapBaseUrl = (string)row[2];
831 break;
832 case "SoapMailTo":
833 application.SoapMailTo = (string)row[2];
834 break;
835 case "SoapVRoot":
836 application.SoapVRoot = (string)row[2];
837 break;
838 case "SRPEnabled":
839 switch ((string)row[2])
840 {
841 case "1":
842 application.SRPEnabled = ComPlus.YesNoType.yes;
843 break;
844 case "0":
845 application.SRPEnabled = ComPlus.YesNoType.no;
846 break;
847 default:
848 // TODO: Warning
849 break;
850 }
851 break;
852 case "SRPTrustLevel":
853 switch ((string)row[2])
854 {
855 case "0":
856 application.SRPTrustLevel = ComPlus.ComPlusApplication.SRPTrustLevelType.disallowed;
857 break;
858 case "262144":
859 application.SRPTrustLevel = ComPlus.ComPlusApplication.SRPTrustLevelType.fullyTrusted;
860 break;
861 default:
862 // TODO: Warning
863 break;
864 }
865 break;
866 default:
867 // TODO: Warning
868 break;
869 }
870 }
871 }
872
873 /// <summary>
874 /// Decompile the ComPlusApplicationRole table.
875 /// </summary>
876 /// <param name="table">The table to decompile.</param>
877 private void DecompileComPlusApplicationRoleTable(Table table)
878 {
879 foreach (Row row in table.Rows)
880 {
881 ComPlus.ComPlusApplicationRole applicationRole = new ComPlus.ComPlusApplicationRole();
882
883 applicationRole.Id = (string)row[0];
884 applicationRole.Application = (string)row[1];
885
886 if (null != row[3])
887 {
888 applicationRole.Name = (string)row[3];
889 }
890
891 if (null != row[2])
892 {
893 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
894 if (null != component)
895 {
896 component.AddChild(applicationRole);
897 }
898 else
899 {
900 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
901 }
902 }
903 else
904 {
905 this.Core.RootElement.AddChild(applicationRole);
906 }
907 this.Core.IndexElement(row, applicationRole);
908 }
909 }
910
911 /// <summary>
912 /// Decompile the ComPlusApplicationRoleProperty table.
913 /// </summary>
914 /// <param name="table">The table to decompile.</param>
915 private void DecompileComPlusApplicationRolePropertyTable(Table table)
916 {
917 foreach (Row row in table.Rows)
918 {
919 ComPlus.ComPlusApplicationRole applicationRole = (ComPlus.ComPlusApplicationRole)this.Core.GetIndexedElement("ComPlusApplicationRole", (string)row[0]);
920 if (null == applicationRole)
921 {
922 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ApplicationRole_", (string)row[0], "ComPlusApplicationRole"));
923 }
924
925 switch ((string)row[1])
926 {
927 case "Description":
928 applicationRole.Description = (string)row[2];
929 break;
930 default:
931 // TODO: Warning
932 break;
933 }
934 }
935 }
936
937 /// <summary>
938 /// Decompile the ComPlusUserInApplicationRole table.
939 /// </summary>
940 /// <param name="table">The table to decompile.</param>
941 private void DecompileComPlusUserInApplicationRoleTable(Table table)
942 {
943 foreach (Row row in table.Rows)
944 {
945 ComPlus.ComPlusUserInApplicationRole userInApplicationRole = new ComPlus.ComPlusUserInApplicationRole();
946
947 userInApplicationRole.Id = (string)row[0];
948 userInApplicationRole.ApplicationRole = (string)row[1];
949 userInApplicationRole.User = (string)row[3];
950
951 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
952 if (null != component)
953 {
954 component.AddChild(userInApplicationRole);
955 }
956 else
957 {
958 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
959 }
960 }
961 }
962
963 /// <summary>
964 /// Decompile the ComPlusGroupInApplicationRole table.
965 /// </summary>
966 /// <param name="table">The table to decompile.</param>
967 private void DecompileComPlusGroupInApplicationRoleTable(Table table)
968 {
969 foreach (Row row in table.Rows)
970 {
971 ComPlus.ComPlusGroupInApplicationRole groupInApplicationRole = new ComPlus.ComPlusGroupInApplicationRole();
972
973 groupInApplicationRole.Id = (string)row[0];
974 groupInApplicationRole.ApplicationRole = (string)row[1];
975 groupInApplicationRole.Group = (string)row[3];
976
977 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
978 if (null != component)
979 {
980 component.AddChild(groupInApplicationRole);
981 }
982 else
983 {
984 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
985 }
986 }
987 }
988
989 /// <summary>
990 /// Decompile the ComPlusAssembly table.
991 /// </summary>
992 /// <param name="table">The table to decompile.</param>
993 private void DecompileComPlusAssemblyTable(Table table)
994 {
995 foreach (Row row in table.Rows)
996 {
997 ComPlus.ComPlusAssembly assembly = new ComPlus.ComPlusAssembly();
998
999 assembly.Id = (string)row[0];
1000 assembly.Application = (string)row[1];
1001
1002 if (null != row[3])
1003 {
1004 assembly.AssemblyName = (string)row[3];
1005 }
1006
1007 if (null != row[4])
1008 {
1009 assembly.DllPath = (string)row[4];
1010 }
1011
1012 if (null != row[5])
1013 {
1014 assembly.TlbPath = (string)row[5];
1015 }
1016
1017 if (null != row[6])
1018 {
1019 assembly.PSDllPath = (string)row[6];
1020 }
1021
1022 int attributes = (int)row[7];
1023
1024 if (0 != (attributes & (int)ComPlusCompiler.CpiAssemblyAttributes.EventClass))
1025 {
1026 assembly.EventClass = ComPlus.YesNoType.yes;
1027 }
1028
1029 if (0 != (attributes & (int)ComPlusCompiler.CpiAssemblyAttributes.DotNetAssembly))
1030 {
1031 assembly.Type = ComPlus.ComPlusAssembly.TypeType.net;
1032 }
1033
1034 if (0 != (attributes & (int)ComPlusCompiler.CpiAssemblyAttributes.DllPathFromGAC))
1035 {
1036 assembly.DllPathFromGAC = ComPlus.YesNoType.yes;
1037 }
1038
1039 if (0 != (attributes & (int)ComPlusCompiler.CpiAssemblyAttributes.RegisterInCommit))
1040 {
1041 assembly.RegisterInCommit = ComPlus.YesNoType.yes;
1042 }
1043
1044 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
1045 if (null != component)
1046 {
1047 component.AddChild(assembly);
1048 }
1049 else
1050 {
1051 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
1052 }
1053 this.Core.IndexElement(row, assembly);
1054 }
1055 }
1056
1057 /// <summary>
1058 /// Decompile the ComPlusAssemblyDependency table.
1059 /// </summary>
1060 /// <param name="table">The table to decompile.</param>
1061 private void DecompileComPlusAssemblyDependencyTable(Table table)
1062 {
1063 foreach (Row row in table.Rows)
1064 {
1065 ComPlus.ComPlusAssemblyDependency assemblyDependency = new ComPlus.ComPlusAssemblyDependency();
1066
1067 assemblyDependency.RequiredAssembly = (string)row[1];
1068
1069 ComPlus.ComPlusAssembly assembly = (ComPlus.ComPlusAssembly)this.Core.GetIndexedElement("ComPlusAssembly", (string)row[0]);
1070 if (null != assembly)
1071 {
1072 assembly.AddChild(assemblyDependency);
1073 }
1074 else
1075 {
1076 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Assembly_", (string)row[0], "ComPlusAssembly"));
1077 }
1078 }
1079 }
1080
1081 /// <summary>
1082 /// Decompile the ComPlusComponent table.
1083 /// </summary>
1084 /// <param name="table">The table to decompile.</param>
1085 private void DecompileComPlusComponentTable(Table table)
1086 {
1087 foreach (Row row in table.Rows)
1088 {
1089 ComPlus.ComPlusComponent comPlusComponent = new ComPlus.ComPlusComponent();
1090
1091 comPlusComponent.Id = (string)row[0];
1092
1093 try
1094 {
1095 Guid clsid = new Guid((string)row[2]);
1096 comPlusComponent.CLSID = clsid.ToString().ToUpper();
1097 }
1098 catch
1099 {
1100 // TODO: Warning
1101 }
1102
1103 ComPlus.ComPlusAssembly assembly = (ComPlus.ComPlusAssembly)this.Core.GetIndexedElement("ComPlusAssembly", (string)row[1]);
1104 if (null != assembly)
1105 {
1106 assembly.AddChild(comPlusComponent);
1107 }
1108 else
1109 {
1110 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Assembly_", (string)row[1], "ComPlusAssembly"));
1111 }
1112 this.Core.IndexElement(row, comPlusComponent);
1113 }
1114 }
1115
1116 /// <summary>
1117 /// Decompile the ComPlusComponentProperty table.
1118 /// </summary>
1119 /// <param name="table">The table to decompile.</param>
1120 private void DecompileComPlusComponentPropertyTable(Table table)
1121 {
1122 foreach (Row row in table.Rows)
1123 {
1124 ComPlus.ComPlusComponent comPlusComponent = (ComPlus.ComPlusComponent)this.Core.GetIndexedElement("ComPlusComponent", (string)row[0]);
1125 if (null == comPlusComponent)
1126 {
1127 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ComPlusComponent_", (string)row[0], "ComPlusComponent"));
1128 }
1129
1130 switch ((string)row[1])
1131 {
1132 case "AllowInprocSubscribers":
1133 switch ((string)row[2])
1134 {
1135 case "1":
1136 comPlusComponent.AllowInprocSubscribers = ComPlus.YesNoType.yes;
1137 break;
1138 case "0":
1139 comPlusComponent.AllowInprocSubscribers = ComPlus.YesNoType.no;
1140 break;
1141 default:
1142 // TODO: Warning
1143 break;
1144 }
1145 break;
1146 case "ComponentAccessChecksEnabled":
1147 switch ((string)row[2])
1148 {
1149 case "1":
1150 comPlusComponent.ComponentAccessChecksEnabled = ComPlus.YesNoType.yes;
1151 break;
1152 case "0":
1153 comPlusComponent.ComponentAccessChecksEnabled = ComPlus.YesNoType.no;
1154 break;
1155 default:
1156 // TODO: Warning
1157 break;
1158 }
1159 break;
1160 case "ComponentTransactionTimeout":
1161 int componentTransactionTimeout;
1162 if (Int32.TryParse((string)row[2], out componentTransactionTimeout))
1163 {
1164 comPlusComponent.ComponentTransactionTimeout = componentTransactionTimeout;
1165 }
1166 else
1167 {
1168 // TODO: Warning
1169 }
1170 break;
1171 case "ComponentTransactionTimeoutEnabled":
1172 switch ((string)row[2])
1173 {
1174 case "1":
1175 comPlusComponent.ComponentTransactionTimeoutEnabled = ComPlus.YesNoType.yes;
1176 break;
1177 case "0":
1178 comPlusComponent.ComponentTransactionTimeoutEnabled = ComPlus.YesNoType.no;
1179 break;
1180 default:
1181 // TODO: Warning
1182 break;
1183 }
1184 break;
1185 case "COMTIIntrinsics":
1186 switch ((string)row[2])
1187 {
1188 case "1":
1189 comPlusComponent.COMTIIntrinsics = ComPlus.YesNoType.yes;
1190 break;
1191 case "0":
1192 comPlusComponent.COMTIIntrinsics = ComPlus.YesNoType.no;
1193 break;
1194 default:
1195 // TODO: Warning
1196 break;
1197 }
1198 break;
1199 case "ConstructionEnabled":
1200 switch ((string)row[2])
1201 {
1202 case "1":
1203 comPlusComponent.ConstructionEnabled = ComPlus.YesNoType.yes;
1204 break;
1205 case "0":
1206 comPlusComponent.ConstructionEnabled = ComPlus.YesNoType.no;
1207 break;
1208 default:
1209 // TODO: Warning
1210 break;
1211 }
1212 break;
1213 case "ConstructorString":
1214 comPlusComponent.ConstructorString = (string)row[2];
1215 break;
1216 case "CreationTimeout":
1217 int creationTimeout;
1218 if (Int32.TryParse((string)row[2], out creationTimeout))
1219 {
1220 comPlusComponent.CreationTimeout = creationTimeout;
1221 }
1222 else
1223 {
1224 // TODO: Warning
1225 }
1226 break;
1227 case "Description":
1228 comPlusComponent.Description = (string)row[2];
1229 break;
1230 case "EventTrackingEnabled":
1231 switch ((string)row[2])
1232 {
1233 case "1":
1234 comPlusComponent.EventTrackingEnabled = ComPlus.YesNoType.yes;
1235 break;
1236 case "0":
1237 comPlusComponent.EventTrackingEnabled = ComPlus.YesNoType.no;
1238 break;
1239 default:
1240 // TODO: Warning
1241 break;
1242 }
1243 break;
1244 case "ExceptionClass":
1245 comPlusComponent.ExceptionClass = (string)row[2];
1246 break;
1247 case "FireInParallel":
1248 switch ((string)row[2])
1249 {
1250 case "1":
1251 comPlusComponent.FireInParallel = ComPlus.YesNoType.yes;
1252 break;
1253 case "0":
1254 comPlusComponent.FireInParallel = ComPlus.YesNoType.no;
1255 break;
1256 default:
1257 // TODO: Warning
1258 break;
1259 }
1260 break;
1261 case "IISIntrinsics":
1262 switch ((string)row[2])
1263 {
1264 case "1":
1265 comPlusComponent.IISIntrinsics = ComPlus.YesNoType.yes;
1266 break;
1267 case "0":
1268 comPlusComponent.IISIntrinsics = ComPlus.YesNoType.no;
1269 break;
1270 default:
1271 // TODO: Warning
1272 break;
1273 }
1274 break;
1275 case "InitializesServerApplication":
1276 switch ((string)row[2])
1277 {
1278 case "1":
1279 comPlusComponent.InitializesServerApplication = ComPlus.YesNoType.yes;
1280 break;
1281 case "0":
1282 comPlusComponent.InitializesServerApplication = ComPlus.YesNoType.no;
1283 break;
1284 default:
1285 // TODO: Warning
1286 break;
1287 }
1288 break;
1289 case "IsEnabled":
1290 switch ((string)row[2])
1291 {
1292 case "1":
1293 comPlusComponent.IsEnabled = ComPlus.YesNoType.yes;
1294 break;
1295 case "0":
1296 comPlusComponent.IsEnabled = ComPlus.YesNoType.no;
1297 break;
1298 default:
1299 // TODO: Warning
1300 break;
1301 }
1302 break;
1303 case "IsPrivateComponent":
1304 switch ((string)row[2])
1305 {
1306 case "1":
1307 comPlusComponent.IsPrivateComponent = ComPlus.YesNoType.yes;
1308 break;
1309 case "0":
1310 comPlusComponent.IsPrivateComponent = ComPlus.YesNoType.no;
1311 break;
1312 default:
1313 // TODO: Warning
1314 break;
1315 }
1316 break;
1317 case "JustInTimeActivation":
1318 switch ((string)row[2])
1319 {
1320 case "1":
1321 comPlusComponent.JustInTimeActivation = ComPlus.YesNoType.yes;
1322 break;
1323 case "0":
1324 comPlusComponent.JustInTimeActivation = ComPlus.YesNoType.no;
1325 break;
1326 default:
1327 // TODO: Warning
1328 break;
1329 }
1330 break;
1331 case "LoadBalancingSupported":
1332 switch ((string)row[2])
1333 {
1334 case "1":
1335 comPlusComponent.LoadBalancingSupported = ComPlus.YesNoType.yes;
1336 break;
1337 case "0":
1338 comPlusComponent.LoadBalancingSupported = ComPlus.YesNoType.no;
1339 break;
1340 default:
1341 // TODO: Warning
1342 break;
1343 }
1344 break;
1345 case "MaxPoolSize":
1346 int maxPoolSize;
1347 if (Int32.TryParse((string)row[2], out maxPoolSize))
1348 {
1349 comPlusComponent.MaxPoolSize = maxPoolSize;
1350 }
1351 else
1352 {
1353 // TODO: Warning
1354 }
1355 break;
1356 case "MinPoolSize":
1357 int minPoolSize;
1358 if (Int32.TryParse((string)row[2], out minPoolSize))
1359 {
1360 comPlusComponent.MinPoolSize = minPoolSize;
1361 }
1362 else
1363 {
1364 // TODO: Warning
1365 }
1366 break;
1367 case "MultiInterfacePublisherFilterCLSID":
1368 comPlusComponent.MultiInterfacePublisherFilterCLSID = (string)row[2];
1369 break;
1370 case "MustRunInClientContext":
1371 switch ((string)row[2])
1372 {
1373 case "1":
1374 comPlusComponent.MustRunInClientContext = ComPlus.YesNoType.yes;
1375 break;
1376 case "0":
1377 comPlusComponent.MustRunInClientContext = ComPlus.YesNoType.no;
1378 break;
1379 default:
1380 // TODO: Warning
1381 break;
1382 }
1383 break;
1384 case "MustRunInDefaultContext":
1385 switch ((string)row[2])
1386 {
1387 case "1":
1388 comPlusComponent.MustRunInDefaultContext = ComPlus.YesNoType.yes;
1389 break;
1390 case "0":
1391 comPlusComponent.MustRunInDefaultContext = ComPlus.YesNoType.no;
1392 break;
1393 default:
1394 // TODO: Warning
1395 break;
1396 }
1397 break;
1398 case "ObjectPoolingEnabled":
1399 switch ((string)row[2])
1400 {
1401 case "1":
1402 comPlusComponent.ObjectPoolingEnabled = ComPlus.YesNoType.yes;
1403 break;
1404 case "0":
1405 comPlusComponent.ObjectPoolingEnabled = ComPlus.YesNoType.no;
1406 break;
1407 default:
1408 // TODO: Warning
1409 break;
1410 }
1411 break;
1412 case "PublisherID":
1413 comPlusComponent.PublisherID = (string)row[2];
1414 break;
1415 case "SoapAssemblyName":
1416 comPlusComponent.SoapAssemblyName = (string)row[2];
1417 break;
1418 case "SoapTypeName":
1419 comPlusComponent.SoapTypeName = (string)row[2];
1420 break;
1421 case "Synchronization":
1422 switch ((string)row[2])
1423 {
1424 case "0":
1425 comPlusComponent.Synchronization = ComPlus.ComPlusComponent.SynchronizationType.ignored;
1426 break;
1427 case "1":
1428 comPlusComponent.Synchronization = ComPlus.ComPlusComponent.SynchronizationType.none;
1429 break;
1430 case "2":
1431 comPlusComponent.Synchronization = ComPlus.ComPlusComponent.SynchronizationType.supported;
1432 break;
1433 case "3":
1434 comPlusComponent.Synchronization = ComPlus.ComPlusComponent.SynchronizationType.required;
1435 break;
1436 case "4":
1437 comPlusComponent.Synchronization = ComPlus.ComPlusComponent.SynchronizationType.requiresNew;
1438 break;
1439 default:
1440 // TODO: Warning
1441 break;
1442 }
1443 break;
1444 case "Transaction":
1445 switch ((string)row[2])
1446 {
1447 case "0":
1448 comPlusComponent.Transaction = ComPlus.ComPlusComponent.TransactionType.ignored;
1449 break;
1450 case "1":
1451 comPlusComponent.Transaction = ComPlus.ComPlusComponent.TransactionType.none;
1452 break;
1453 case "2":
1454 comPlusComponent.Transaction = ComPlus.ComPlusComponent.TransactionType.supported;
1455 break;
1456 case "3":
1457 comPlusComponent.Transaction = ComPlus.ComPlusComponent.TransactionType.required;
1458 break;
1459 case "4":
1460 comPlusComponent.Transaction = ComPlus.ComPlusComponent.TransactionType.requiresNew;
1461 break;
1462 default:
1463 // TODO: Warning
1464 break;
1465 }
1466 break;
1467 case "TxIsolationLevel":
1468 switch ((string)row[2])
1469 {
1470 case "0":
1471 comPlusComponent.TxIsolationLevel = ComPlus.ComPlusComponent.TxIsolationLevelType.any;
1472 break;
1473 case "1":
1474 comPlusComponent.TxIsolationLevel = ComPlus.ComPlusComponent.TxIsolationLevelType.readUnCommitted;
1475 break;
1476 case "2":
1477 comPlusComponent.TxIsolationLevel = ComPlus.ComPlusComponent.TxIsolationLevelType.readCommitted;
1478 break;
1479 case "3":
1480 comPlusComponent.TxIsolationLevel = ComPlus.ComPlusComponent.TxIsolationLevelType.repeatableRead;
1481 break;
1482 case "4":
1483 comPlusComponent.TxIsolationLevel = ComPlus.ComPlusComponent.TxIsolationLevelType.serializable;
1484 break;
1485 default:
1486 // TODO: Warning
1487 break;
1488 }
1489 break;
1490 default:
1491 // TODO: Warning
1492 break;
1493 }
1494 }
1495 }
1496
1497 /// <summary>
1498 /// Decompile the ComPlusRoleForComponent table.
1499 /// </summary>
1500 /// <param name="table">The table to decompile.</param>
1501 private void DecompileComPlusRoleForComponentTable(Table table)
1502 {
1503 foreach (Row row in table.Rows)
1504 {
1505 ComPlus.ComPlusRoleForComponent roleForComponent = new ComPlus.ComPlusRoleForComponent();
1506
1507 roleForComponent.Id = (string)row[0];
1508 roleForComponent.Component = (string)row[1];
1509 roleForComponent.ApplicationRole = (string)row[2];
1510
1511 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[3]);
1512 if (null != component)
1513 {
1514 component.AddChild(roleForComponent);
1515 }
1516 else
1517 {
1518 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[3], "Component"));
1519 }
1520 }
1521 }
1522
1523 /// <summary>
1524 /// Decompile the ComPlusInterface table.
1525 /// </summary>
1526 /// <param name="table">The table to decompile.</param>
1527 private void DecompileComPlusInterfaceTable(Table table)
1528 {
1529 foreach (Row row in table.Rows)
1530 {
1531 ComPlus.ComPlusInterface comPlusInterface = new ComPlus.ComPlusInterface();
1532
1533 comPlusInterface.Id = (string)row[0];
1534
1535 try
1536 {
1537 Guid iid = new Guid((string)row[2]);
1538 comPlusInterface.IID = iid.ToString().ToUpper();
1539 }
1540 catch
1541 {
1542 // TODO: Warning
1543 }
1544
1545 ComPlus.ComPlusComponent comPlusComponent = (ComPlus.ComPlusComponent)this.Core.GetIndexedElement("ComPlusComponent", (string)row[1]);
1546 if (null != comPlusComponent)
1547 {
1548 comPlusComponent.AddChild(comPlusInterface);
1549 }
1550 else
1551 {
1552 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ComPlusComponent_", (string)row[1], "ComPlusComponent"));
1553 }
1554 this.Core.IndexElement(row, comPlusInterface);
1555 }
1556 }
1557
1558 /// <summary>
1559 /// Decompile the ComPlusInterfaceProperty table.
1560 /// </summary>
1561 /// <param name="table">The table to decompile.</param>
1562 private void DecompileComPlusInterfacePropertyTable(Table table)
1563 {
1564 foreach (Row row in table.Rows)
1565 {
1566 ComPlus.ComPlusInterface comPlusInterface = (ComPlus.ComPlusInterface)this.Core.GetIndexedElement("ComPlusInterface", (string)row[0]);
1567 if (null == comPlusInterface)
1568 {
1569 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Interface_", (string)row[0], "ComPlusInterface"));
1570 }
1571
1572 switch ((string)row[1])
1573 {
1574 case "Description":
1575 comPlusInterface.Description = (string)row[2];
1576 break;
1577 case "QueuingEnabled":
1578 switch ((string)row[2])
1579 {
1580 case "1":
1581 comPlusInterface.QueuingEnabled = ComPlus.YesNoType.yes;
1582 break;
1583 case "0":
1584 comPlusInterface.QueuingEnabled = ComPlus.YesNoType.no;
1585 break;
1586 default:
1587 // TODO: Warning
1588 break;
1589 }
1590 break;
1591 default:
1592 // TODO: Warning
1593 break;
1594 }
1595 }
1596 }
1597
1598 /// <summary>
1599 /// Decompile the ComPlusRoleForInterface table.
1600 /// </summary>
1601 /// <param name="table">The table to decompile.</param>
1602 private void DecompileComPlusRoleForInterfaceTable(Table table)
1603 {
1604 foreach (Row row in table.Rows)
1605 {
1606 ComPlus.ComPlusRoleForInterface roleForInterface = new ComPlus.ComPlusRoleForInterface();
1607
1608 roleForInterface.Id = (string)row[0];
1609 roleForInterface.Interface = (string)row[1];
1610 roleForInterface.ApplicationRole = (string)row[2];
1611
1612 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[3]);
1613 if (null != component)
1614 {
1615 component.AddChild(roleForInterface);
1616 }
1617 else
1618 {
1619 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[3], "Component"));
1620 }
1621 }
1622 }
1623
1624 /// <summary>
1625 /// Decompile the ComPlusMethod table.
1626 /// </summary>
1627 /// <param name="table">The table to decompile.</param>
1628 private void DecompileComPlusMethodTable(Table table)
1629 {
1630 foreach (Row row in table.Rows)
1631 {
1632 ComPlus.ComPlusMethod comPlusMethod = new ComPlus.ComPlusMethod();
1633
1634 comPlusMethod.Id = (string)row[0];
1635
1636 if (null != row[2])
1637 {
1638 comPlusMethod.Index = (int)row[2];
1639 }
1640
1641 if (null != row[3])
1642 {
1643 comPlusMethod.Name = (string)row[3];
1644 }
1645
1646 ComPlus.ComPlusInterface comPlusInterface = (ComPlus.ComPlusInterface)this.Core.GetIndexedElement("ComPlusInterface", (string)row[1]);
1647 if (null != comPlusInterface)
1648 {
1649 comPlusInterface.AddChild(comPlusMethod);
1650 }
1651 else
1652 {
1653 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Interface_", (string)row[1], "ComPlusInterface"));
1654 }
1655 this.Core.IndexElement(row, comPlusMethod);
1656 }
1657 }
1658
1659 /// <summary>
1660 /// Decompile the ComPlusMethodProperty table.
1661 /// </summary>
1662 /// <param name="table">The table to decompile.</param>
1663 private void DecompileComPlusMethodPropertyTable(Table table)
1664 {
1665 foreach (Row row in table.Rows)
1666 {
1667 ComPlus.ComPlusMethod comPlusMethod = (ComPlus.ComPlusMethod)this.Core.GetIndexedElement("ComPlusMethod", (string)row[0]);
1668 if (null == comPlusMethod)
1669 {
1670 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Method_", (string)row[0], "ComPlusMethod"));
1671 }
1672
1673 switch ((string)row[1])
1674 {
1675 case "AutoComplete":
1676 switch ((string)row[2])
1677 {
1678 case "1":
1679 comPlusMethod.AutoComplete = ComPlus.YesNoType.yes;
1680 break;
1681 case "0":
1682 comPlusMethod.AutoComplete = ComPlus.YesNoType.no;
1683 break;
1684 default:
1685 // TODO: Warning
1686 break;
1687 }
1688 break;
1689 case "Description":
1690 comPlusMethod.Description = (string)row[2];
1691 break;
1692 default:
1693 // TODO: Warning
1694 break;
1695 }
1696 }
1697 }
1698
1699 /// <summary>
1700 /// Decompile the ComPlusRoleForMethod table.
1701 /// </summary>
1702 /// <param name="table">The table to decompile.</param>
1703 private void DecompileComPlusRoleForMethodTable(Table table)
1704 {
1705 foreach (Row row in table.Rows)
1706 {
1707 ComPlus.ComPlusRoleForMethod roleForMethod = new ComPlus.ComPlusRoleForMethod();
1708
1709 roleForMethod.Id = (string)row[0];
1710 roleForMethod.Method = (string)row[1];
1711 roleForMethod.ApplicationRole = (string)row[2];
1712
1713 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[3]);
1714 if (null != component)
1715 {
1716 component.AddChild(roleForMethod);
1717 }
1718 else
1719 {
1720 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[3], "Component"));
1721 }
1722 }
1723 }
1724
1725 /// <summary>
1726 /// Decompile the ComPlusSubscription table.
1727 /// </summary>
1728 /// <param name="table">The table to decompile.</param>
1729 private void DecompileComPlusSubscriptionTable(Table table)
1730 {
1731 foreach (Row row in table.Rows)
1732 {
1733 ComPlus.ComPlusSubscription subscription = new ComPlus.ComPlusSubscription();
1734
1735 subscription.Id = (string)row[0];
1736 subscription.Component = (string)row[1];
1737 subscription.SubscriptionId = (string)row[3];
1738 subscription.Name = (string)row[4];
1739 subscription.EventCLSID = (string)row[5];
1740 subscription.PublisherID = (string)row[6];
1741
1742 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
1743 if (null != component)
1744 {
1745 component.AddChild(subscription);
1746 }
1747 else
1748 {
1749 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
1750 }
1751 this.Core.IndexElement(row, subscription);
1752 }
1753 }
1754
1755 /// <summary>
1756 /// Decompile the ComPlusSubscriptionProperty table.
1757 /// </summary>
1758 /// <param name="table">The table to decompile.</param>
1759 private void DecompileComPlusSubscriptionPropertyTable(Table table)
1760 {
1761 foreach (Row row in table.Rows)
1762 {
1763 ComPlus.ComPlusSubscription subscription = (ComPlus.ComPlusSubscription)this.Core.GetIndexedElement("ComPlusSubscription", (string)row[0]);
1764 if (null == subscription)
1765 {
1766 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Subscription_", (string)row[0], "ComPlusSubscription"));
1767 }
1768
1769 switch ((string)row[1])
1770 {
1771 case "Description":
1772 subscription.Description = (string)row[2];
1773 break;
1774 case "Enabled":
1775 switch ((string)row[2])
1776 {
1777 case "1":
1778 subscription.Enabled = ComPlus.YesNoType.yes;
1779 break;
1780 case "0":
1781 subscription.Enabled = ComPlus.YesNoType.no;
1782 break;
1783 default:
1784 // TODO: Warning
1785 break;
1786 }
1787 break;
1788 case "EventClassPartitionID":
1789 subscription.EventClassPartitionID = (string)row[2];
1790 break;
1791 case "FilterCriteria":
1792 subscription.FilterCriteria = (string)row[2];
1793 break;
1794 case "InterfaceID":
1795 subscription.InterfaceID = (string)row[2];
1796 break;
1797 case "MachineName":
1798 subscription.MachineName = (string)row[2];
1799 break;
1800 case "MethodName":
1801 subscription.MethodName = (string)row[2];
1802 break;
1803 case "PerUser":
1804 switch ((string)row[2])
1805 {
1806 case "1":
1807 subscription.PerUser = ComPlus.YesNoType.yes;
1808 break;
1809 case "0":
1810 subscription.PerUser = ComPlus.YesNoType.no;
1811 break;
1812 default:
1813 // TODO: Warning
1814 break;
1815 }
1816 break;
1817 case "Queued":
1818 switch ((string)row[2])
1819 {
1820 case "1":
1821 subscription.Queued = ComPlus.YesNoType.yes;
1822 break;
1823 case "0":
1824 subscription.Queued = ComPlus.YesNoType.no;
1825 break;
1826 default:
1827 // TODO: Warning
1828 break;
1829 }
1830 break;
1831 case "SubscriberMoniker":
1832 subscription.SubscriberMoniker = (string)row[2];
1833 break;
1834 case "UserName":
1835 subscription.UserName = (string)row[2];
1836 break;
1837 default:
1838 // TODO: Warning
1839 break;
1840 }
1841 }
1842 }
1843 }
1844#endif
1845}
diff --git a/src/ext/ComPlus/wixext/ComPlusErrors.cs b/src/ext/ComPlus/wixext/ComPlusErrors.cs
new file mode 100644
index 00000000..91b41679
--- /dev/null
+++ b/src/ext/ComPlus/wixext/ComPlusErrors.cs
@@ -0,0 +1,72 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using System;
6 using System.Resources;
7 using WixToolset.Data;
8
9 public static class ComPlusErrors
10 {
11 public static Message IllegalAttributeWithoutComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName)
12 {
13 return Message(sourceLineNumbers, Ids.IllegalAttributeWithoutComponent, "The {0}/@{1} attribute cannot be specified unless the element has a component as an ancestor. A {0} that does not have a component ancestor is not installed.", elementName, attributeName);
14 }
15
16 public static Message IllegalElementWithoutComponent(SourceLineNumber sourceLineNumbers, string elementName)
17 {
18 return Message(sourceLineNumbers, Ids.IllegalElementWithoutComponent, "The {0} element cannot be specified unless the element has a component as an ancestor. A {0} that does not have a component ancestor is not installed.", elementName);
19 }
20
21 public static Message RequiredAttribute(SourceLineNumber sourceLineNumbers, string elementName, string attributeName1, string attributeName2)
22 {
23 return Message(sourceLineNumbers, Ids.RequiredAttribute, "A {0} element must have either a {1} attribute or a {2} attribute, or both set.", elementName, attributeName1, attributeName2);
24 }
25
26 public static Message RequiredAttributeNotUnderComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName1, string attributeName2)
27 {
28 return Message(sourceLineNumbers, Ids.RequiredAttributeNotUnderComponent, "A {0} element not nested under a component must have either a {1} attribute or a {2} attribute, or both set.", elementName, attributeName1, attributeName2);
29 }
30
31 public static Message RequiredAttributeUnderComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName)
32 {
33 return Message(sourceLineNumbers, Ids.RequiredAttributeUnderComponent, "The {0}/@{1} attribute must be provided when {0} element is nested under a component.", elementName, attributeName);
34 }
35
36 public static Message UnexpectedAttributeWithOtherValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string otherAttributeName, string otherValue)
37 {
38 return Message(sourceLineNumbers, Ids.UnexpectedAttributeWithOtherValue, "The {0}/@{1} attribute cannot coexist with the {2} attribute's value of '{3}'.", elementName, attributeName, otherAttributeName, otherValue);
39 }
40
41 public static Message UnexpectedAttributeWithOtherValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string value, string otherAttributeName, string otherValue)
42 {
43 return Message(sourceLineNumbers, Ids.UnexpectedAttributeWithOtherValue, "The {0}/@{1} attribute's value, '{2}', cannot coexist with the {3} attribute's value of '{4}'.", elementName, attributeName, value, otherAttributeName, otherValue);
44 }
45
46 public static Message UnexpectedAttributeWithoutOtherValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string otherAttributeName, string otherValue)
47 {
48 return Message(sourceLineNumbers, Ids.UnexpectedAttributeWithoutOtherValue, "The {0}/@{1} cannot be provided unless the {2} attribute is provided with a value of '{3}'.", elementName, attributeName, otherAttributeName, otherValue);
49 }
50
51 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args)
52 {
53 return new Message(sourceLineNumber, MessageLevel.Error, (int)id, format, args);
54 }
55
56 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, ResourceManager resourceManager, string resourceName, params object[] args)
57 {
58 return new Message(sourceLineNumber, MessageLevel.Error, (int)id, resourceManager, resourceName, args);
59 }
60
61 public enum Ids
62 {
63 IllegalAttributeWithoutComponent = 6000,
64 IllegalElementWithoutComponent = 6001,
65 UnexpectedAttributeWithOtherValue = 6002,
66 UnexpectedAttributeWithoutOtherValue = 6003,
67 RequiredAttributeUnderComponent = 6004,
68 RequiredAttribute = 6005,
69 RequiredAttributeNotUnderComponent = 6006,
70 }
71 }
72}
diff --git a/src/ext/ComPlus/wixext/ComPlusExtensionData.cs b/src/ext/ComPlus/wixext/ComPlusExtensionData.cs
new file mode 100644
index 00000000..9cd5341e
--- /dev/null
+++ b/src/ext/ComPlus/wixext/ComPlusExtensionData.cs
@@ -0,0 +1,30 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.Extensibility;
7
8 /// <summary>
9 /// The WiX Toolset COM+ Extension.
10 /// </summary>
11 public sealed class ComPlusExtensionData : BaseExtensionData
12 {
13 /// <summary>
14 /// Gets the default culture.
15 /// </summary>
16 /// <value>The default culture.</value>
17 public override string DefaultCulture => "en-US";
18
19 public override bool TryGetSymbolDefinitionByName(string name, out IntermediateSymbolDefinition symbolDefinition)
20 {
21 symbolDefinition = ComPlusSymbolDefinitions.ByName(name);
22 return symbolDefinition != null;
23 }
24
25 public override Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions)
26 {
27 return Intermediate.Load(typeof(ComPlusExtensionData).Assembly, "WixToolset.ComPlus.complus.wixlib", symbolDefinitions);
28 }
29 }
30}
diff --git a/src/ext/ComPlus/wixext/ComPlusExtensionFactory.cs b/src/ext/ComPlus/wixext/ComPlusExtensionFactory.cs
new file mode 100644
index 00000000..76b51bff
--- /dev/null
+++ b/src/ext/ComPlus/wixext/ComPlusExtensionFactory.cs
@@ -0,0 +1,18 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using System;
6 using System.Collections.Generic;
7 using WixToolset.Extensibility;
8
9 public class ComPlusExtensionFactory : BaseExtensionFactory
10 {
11 protected override IReadOnlyCollection<Type> ExtensionTypes => new[]
12 {
13 typeof(ComPlusCompiler),
14 typeof(ComPlusExtensionData),
15 typeof(ComPlusWindowsInstallerBackendBinderExtension),
16 };
17 }
18}
diff --git a/src/ext/ComPlus/wixext/ComPlusTableDefinitions.cs b/src/ext/ComPlus/wixext/ComPlusTableDefinitions.cs
new file mode 100644
index 00000000..565e1d44
--- /dev/null
+++ b/src/ext/ComPlus/wixext/ComPlusTableDefinitions.cs
@@ -0,0 +1,360 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data.WindowsInstaller;
6
7 public static class ComPlusTableDefinitions
8 {
9 public static readonly TableDefinition ComPlusPartition = new TableDefinition(
10 "ComPlusPartition",
11 ComPlusSymbolDefinitions.ComPlusPartition,
12 new[]
13 {
14 new ColumnDefinition("Partition", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
15 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
16 new ColumnDefinition("Id", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
17 new ColumnDefinition("Name", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
18 },
19 symbolIdIsPrimaryKey: true
20 );
21
22 public static readonly TableDefinition ComPlusPartitionProperty = new TableDefinition(
23 "ComPlusPartitionProperty",
24 ComPlusSymbolDefinitions.ComPlusPartitionProperty,
25 new[]
26 {
27 new ColumnDefinition("Partition_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusPartition", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
28 new ColumnDefinition("Name", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
29 new ColumnDefinition("Value", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
30 },
31 symbolIdIsPrimaryKey: false
32 );
33
34 public static readonly TableDefinition ComPlusPartitionRole = new TableDefinition(
35 "ComPlusPartitionRole",
36 ComPlusSymbolDefinitions.ComPlusPartitionRole,
37 new[]
38 {
39 new ColumnDefinition("PartitionRole", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
40 new ColumnDefinition("Partition_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusPartition", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
41 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
42 new ColumnDefinition("Name", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
43 },
44 symbolIdIsPrimaryKey: true
45 );
46
47 public static readonly TableDefinition ComPlusUserInPartitionRole = new TableDefinition(
48 "ComPlusUserInPartitionRole",
49 ComPlusSymbolDefinitions.ComPlusUserInPartitionRole,
50 new[]
51 {
52 new ColumnDefinition("UserInPartitionRole", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
53 new ColumnDefinition("PartitionRole_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusPartitionRole", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
54 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
55 new ColumnDefinition("User_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
56 },
57 symbolIdIsPrimaryKey: true
58 );
59
60 public static readonly TableDefinition ComPlusGroupInPartitionRole = new TableDefinition(
61 "ComPlusGroupInPartitionRole",
62 ComPlusSymbolDefinitions.ComPlusGroupInPartitionRole,
63 new[]
64 {
65 new ColumnDefinition("GroupInPartitionRole", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
66 new ColumnDefinition("PartitionRole_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusPartitionRole", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
67 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
68 new ColumnDefinition("Group_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
69 },
70 symbolIdIsPrimaryKey: true
71 );
72
73 public static readonly TableDefinition ComPlusPartitionUser = new TableDefinition(
74 "ComPlusPartitionUser",
75 ComPlusSymbolDefinitions.ComPlusPartitionUser,
76 new[]
77 {
78 new ColumnDefinition("PartitionUser", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
79 new ColumnDefinition("Partition_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusPartition", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
80 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
81 new ColumnDefinition("User_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
82 },
83 symbolIdIsPrimaryKey: true
84 );
85
86 public static readonly TableDefinition ComPlusApplication = new TableDefinition(
87 "ComPlusApplication",
88 ComPlusSymbolDefinitions.ComPlusApplication,
89 new[]
90 {
91 new ColumnDefinition("Application", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
92 new ColumnDefinition("Partition_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "ComPlusPartition", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
93 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
94 new ColumnDefinition("Id", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
95 new ColumnDefinition("Name", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
96 },
97 symbolIdIsPrimaryKey: true
98 );
99
100 public static readonly TableDefinition ComPlusApplicationProperty = new TableDefinition(
101 "ComPlusApplicationProperty",
102 ComPlusSymbolDefinitions.ComPlusApplicationProperty,
103 new[]
104 {
105 new ColumnDefinition("Application_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusApplication", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
106 new ColumnDefinition("Name", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
107 new ColumnDefinition("Value", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
108 },
109 symbolIdIsPrimaryKey: false
110 );
111
112 public static readonly TableDefinition ComPlusApplicationRole = new TableDefinition(
113 "ComPlusApplicationRole",
114 ComPlusSymbolDefinitions.ComPlusApplicationRole,
115 new[]
116 {
117 new ColumnDefinition("ApplicationRole", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
118 new ColumnDefinition("Application_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusApplication", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
119 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
120 new ColumnDefinition("Name", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
121 },
122 symbolIdIsPrimaryKey: true
123 );
124
125 public static readonly TableDefinition ComPlusApplicationRoleProperty = new TableDefinition(
126 "ComPlusApplicationRoleProperty",
127 ComPlusSymbolDefinitions.ComPlusApplicationRoleProperty,
128 new[]
129 {
130 new ColumnDefinition("ApplicationRole_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusApplicationRole", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
131 new ColumnDefinition("Name", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
132 new ColumnDefinition("Value", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
133 },
134 symbolIdIsPrimaryKey: false
135 );
136
137 public static readonly TableDefinition ComPlusUserInApplicationRole = new TableDefinition(
138 "ComPlusUserInApplicationRole",
139 ComPlusSymbolDefinitions.ComPlusUserInApplicationRole,
140 new[]
141 {
142 new ColumnDefinition("UserInApplicationRole", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
143 new ColumnDefinition("ApplicationRole_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusApplicationRole", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
144 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
145 new ColumnDefinition("User_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
146 },
147 symbolIdIsPrimaryKey: true
148 );
149
150 public static readonly TableDefinition ComPlusGroupInApplicationRole = new TableDefinition(
151 "ComPlusGroupInApplicationRole",
152 ComPlusSymbolDefinitions.ComPlusGroupInApplicationRole,
153 new[]
154 {
155 new ColumnDefinition("GroupInApplicationRole", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
156 new ColumnDefinition("ApplicationRole_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusApplicationRole", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
157 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
158 new ColumnDefinition("Group_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
159 },
160 symbolIdIsPrimaryKey: true
161 );
162
163 public static readonly TableDefinition ComPlusAssembly = new TableDefinition(
164 "ComPlusAssembly",
165 ComPlusSymbolDefinitions.ComPlusAssembly,
166 new[]
167 {
168 new ColumnDefinition("Assembly", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
169 new ColumnDefinition("Application_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "ComPlusApplication", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
170 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
171 new ColumnDefinition("AssemblyName", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
172 new ColumnDefinition("DllPath", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
173 new ColumnDefinition("TlbPath", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
174 new ColumnDefinition("PSDllPath", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
175 new ColumnDefinition("Attributes", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown),
176 },
177 symbolIdIsPrimaryKey: true
178 );
179
180 public static readonly TableDefinition ComPlusAssemblyDependency = new TableDefinition(
181 "ComPlusAssemblyDependency",
182 ComPlusSymbolDefinitions.ComPlusAssemblyDependency,
183 new[]
184 {
185 new ColumnDefinition("Assembly_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusAssembly", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
186 new ColumnDefinition("RequiredAssembly_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusAssembly", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
187 },
188 symbolIdIsPrimaryKey: false
189 );
190
191 public static readonly TableDefinition ComPlusComponent = new TableDefinition(
192 "ComPlusComponent",
193 ComPlusSymbolDefinitions.ComPlusComponent,
194 new[]
195 {
196 new ColumnDefinition("ComPlusComponent", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
197 new ColumnDefinition("Assembly_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusAssembly", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
198 new ColumnDefinition("CLSID", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
199 },
200 symbolIdIsPrimaryKey: true
201 );
202
203 public static readonly TableDefinition ComPlusComponentProperty = new TableDefinition(
204 "ComPlusComponentProperty",
205 ComPlusSymbolDefinitions.ComPlusComponentProperty,
206 new[]
207 {
208 new ColumnDefinition("ComPlusComponent_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusComponent", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
209 new ColumnDefinition("Name", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
210 new ColumnDefinition("Value", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
211 },
212 symbolIdIsPrimaryKey: false
213 );
214
215 public static readonly TableDefinition ComPlusRoleForComponent = new TableDefinition(
216 "ComPlusRoleForComponent",
217 ComPlusSymbolDefinitions.ComPlusRoleForComponent,
218 new[]
219 {
220 new ColumnDefinition("RoleForComponent", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
221 new ColumnDefinition("ComPlusComponent_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusComponent", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
222 new ColumnDefinition("ApplicationRole_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusApplicationRole", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
223 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
224 },
225 symbolIdIsPrimaryKey: true
226 );
227
228 public static readonly TableDefinition ComPlusInterface = new TableDefinition(
229 "ComPlusInterface",
230 ComPlusSymbolDefinitions.ComPlusInterface,
231 new[]
232 {
233 new ColumnDefinition("Interface", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
234 new ColumnDefinition("ComPlusComponent_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusComponent", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
235 new ColumnDefinition("IID", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
236 },
237 symbolIdIsPrimaryKey: true
238 );
239
240 public static readonly TableDefinition ComPlusInterfaceProperty = new TableDefinition(
241 "ComPlusInterfaceProperty",
242 ComPlusSymbolDefinitions.ComPlusInterfaceProperty,
243 new[]
244 {
245 new ColumnDefinition("Interface_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusInterface", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
246 new ColumnDefinition("Name", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
247 new ColumnDefinition("Value", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
248 },
249 symbolIdIsPrimaryKey: false
250 );
251
252 public static readonly TableDefinition ComPlusRoleForInterface = new TableDefinition(
253 "ComPlusRoleForInterface",
254 ComPlusSymbolDefinitions.ComPlusRoleForInterface,
255 new[]
256 {
257 new ColumnDefinition("RoleForInterface", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
258 new ColumnDefinition("Interface_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusInterface", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
259 new ColumnDefinition("ApplicationRole_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusApplicationRole", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
260 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
261 },
262 symbolIdIsPrimaryKey: true
263 );
264
265 public static readonly TableDefinition ComPlusMethod = new TableDefinition(
266 "ComPlusMethod",
267 ComPlusSymbolDefinitions.ComPlusMethod,
268 new[]
269 {
270 new ColumnDefinition("Method", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
271 new ColumnDefinition("Interface_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusInterface", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
272 new ColumnDefinition("Index", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown),
273 new ColumnDefinition("Name", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
274 },
275 symbolIdIsPrimaryKey: true
276 );
277
278 public static readonly TableDefinition ComPlusMethodProperty = new TableDefinition(
279 "ComPlusMethodProperty",
280 ComPlusSymbolDefinitions.ComPlusMethodProperty,
281 new[]
282 {
283 new ColumnDefinition("Method_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusMethod", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
284 new ColumnDefinition("Name", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
285 new ColumnDefinition("Value", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
286 },
287 symbolIdIsPrimaryKey: false
288 );
289
290 public static readonly TableDefinition ComPlusRoleForMethod = new TableDefinition(
291 "ComPlusRoleForMethod",
292 ComPlusSymbolDefinitions.ComPlusRoleForMethod,
293 new[]
294 {
295 new ColumnDefinition("RoleForMethod", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
296 new ColumnDefinition("Method_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusMethod", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
297 new ColumnDefinition("ApplicationRole_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusApplicationRole", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
298 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
299 },
300 symbolIdIsPrimaryKey: true
301 );
302
303 public static readonly TableDefinition ComPlusSubscription = new TableDefinition(
304 "ComPlusSubscription",
305 ComPlusSymbolDefinitions.ComPlusSubscription,
306 new[]
307 {
308 new ColumnDefinition("Subscription", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
309 new ColumnDefinition("ComPlusComponent_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusComponent", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
310 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
311 new ColumnDefinition("Id", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
312 new ColumnDefinition("Name", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
313 new ColumnDefinition("EventCLSID", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
314 new ColumnDefinition("PublisherID", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
315 },
316 symbolIdIsPrimaryKey: false
317 );
318
319 public static readonly TableDefinition ComPlusSubscriptionProperty = new TableDefinition(
320 "ComPlusSubscriptionProperty",
321 ComPlusSymbolDefinitions.ComPlusSubscriptionProperty,
322 new[]
323 {
324 new ColumnDefinition("Subscription_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "ComPlusSubscription", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
325 new ColumnDefinition("Name", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
326 new ColumnDefinition("Value", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
327 },
328 symbolIdIsPrimaryKey: false
329 );
330
331 public static readonly TableDefinition[] All = new[]
332 {
333 ComPlusPartition,
334 ComPlusPartitionProperty,
335 ComPlusPartitionRole,
336 ComPlusUserInPartitionRole,
337 ComPlusGroupInPartitionRole,
338 ComPlusPartitionUser,
339 ComPlusApplication,
340 ComPlusApplicationProperty,
341 ComPlusApplicationRole,
342 ComPlusApplicationRoleProperty,
343 ComPlusUserInApplicationRole,
344 ComPlusGroupInApplicationRole,
345 ComPlusAssembly,
346 ComPlusAssemblyDependency,
347 ComPlusComponent,
348 ComPlusComponentProperty,
349 ComPlusRoleForComponent,
350 ComPlusInterface,
351 ComPlusInterfaceProperty,
352 ComPlusRoleForInterface,
353 ComPlusMethod,
354 ComPlusMethodProperty,
355 ComPlusRoleForMethod,
356 ComPlusSubscription,
357 ComPlusSubscriptionProperty,
358 };
359 }
360}
diff --git a/src/ext/ComPlus/wixext/ComPlusWarnings.cs b/src/ext/ComPlus/wixext/ComPlusWarnings.cs
new file mode 100644
index 00000000..e0000918
--- /dev/null
+++ b/src/ext/ComPlus/wixext/ComPlusWarnings.cs
@@ -0,0 +1,31 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using System;
6 using System.Resources;
7 using WixToolset.Data;
8
9 public static class ComPlusWarnings
10 {
11 public static Message MissingComponents(SourceLineNumber sourceLineNumbers)
12 {
13 return Message(sourceLineNumbers, Ids.MissingComponents, "The ComPlusAssembly element has a Type attribute with a value of 'native', but the element does not contain any ComPlusComponent elements. All components contained in a native assembly must be listed, or they will not be correctly removed during uninstall.");
14 }
15
16 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args)
17 {
18 return new Message(sourceLineNumber, MessageLevel.Warning, (int)id, format, args);
19 }
20
21 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, ResourceManager resourceManager, string resourceName, params object[] args)
22 {
23 return new Message(sourceLineNumber, MessageLevel.Warning, (int)id, resourceManager, resourceName, args);
24 }
25
26 public enum Ids
27 {
28 MissingComponents = 6007,
29 }
30 }
31}
diff --git a/src/ext/ComPlus/wixext/ComPlusWindowsInstallerBackendBinderExtension.cs b/src/ext/ComPlus/wixext/ComPlusWindowsInstallerBackendBinderExtension.cs
new file mode 100644
index 00000000..cf226a3d
--- /dev/null
+++ b/src/ext/ComPlus/wixext/ComPlusWindowsInstallerBackendBinderExtension.cs
@@ -0,0 +1,13 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using System.Collections.Generic;
6 using WixToolset.Data.WindowsInstaller;
7 using WixToolset.Extensibility;
8
9 public class ComPlusWindowsInstallerBackendBinderExtension : BaseWindowsInstallerBackendBinderExtension
10 {
11 public override IReadOnlyCollection<TableDefinition> TableDefinitions => ComPlusTableDefinitions.All;
12 }
13}
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusApplicationPropertySymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusApplicationPropertySymbol.cs
new file mode 100644
index 00000000..6d1e2d28
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusApplicationPropertySymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusApplicationProperty = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusApplicationProperty.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusApplicationPropertySymbolFields.ApplicationRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusApplicationPropertySymbolFields.Name), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusApplicationPropertySymbolFields.Value), IntermediateFieldType.String),
17 },
18 typeof(ComPlusApplicationPropertySymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusApplicationPropertySymbolFields
27 {
28 ApplicationRef,
29 Name,
30 Value,
31 }
32
33 public class ComPlusApplicationPropertySymbol : IntermediateSymbol
34 {
35 public ComPlusApplicationPropertySymbol() : base(ComPlusSymbolDefinitions.ComPlusApplicationProperty, null, null)
36 {
37 }
38
39 public ComPlusApplicationPropertySymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusApplicationProperty, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusApplicationPropertySymbolFields index] => this.Fields[(int)index];
44
45 public string ApplicationRef
46 {
47 get => this.Fields[(int)ComPlusApplicationPropertySymbolFields.ApplicationRef].AsString();
48 set => this.Set((int)ComPlusApplicationPropertySymbolFields.ApplicationRef, value);
49 }
50
51 public string Name
52 {
53 get => this.Fields[(int)ComPlusApplicationPropertySymbolFields.Name].AsString();
54 set => this.Set((int)ComPlusApplicationPropertySymbolFields.Name, value);
55 }
56
57 public string Value
58 {
59 get => this.Fields[(int)ComPlusApplicationPropertySymbolFields.Value].AsString();
60 set => this.Set((int)ComPlusApplicationPropertySymbolFields.Value, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusApplicationRolePropertySymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusApplicationRolePropertySymbol.cs
new file mode 100644
index 00000000..3b957899
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusApplicationRolePropertySymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusApplicationRoleProperty = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusApplicationRoleProperty.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusApplicationRolePropertySymbolFields.ApplicationRoleRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusApplicationRolePropertySymbolFields.Name), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusApplicationRolePropertySymbolFields.Value), IntermediateFieldType.String),
17 },
18 typeof(ComPlusApplicationRolePropertySymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusApplicationRolePropertySymbolFields
27 {
28 ApplicationRoleRef,
29 Name,
30 Value,
31 }
32
33 public class ComPlusApplicationRolePropertySymbol : IntermediateSymbol
34 {
35 public ComPlusApplicationRolePropertySymbol() : base(ComPlusSymbolDefinitions.ComPlusApplicationRoleProperty, null, null)
36 {
37 }
38
39 public ComPlusApplicationRolePropertySymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusApplicationRoleProperty, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusApplicationRolePropertySymbolFields index] => this.Fields[(int)index];
44
45 public string ApplicationRoleRef
46 {
47 get => this.Fields[(int)ComPlusApplicationRolePropertySymbolFields.ApplicationRoleRef].AsString();
48 set => this.Set((int)ComPlusApplicationRolePropertySymbolFields.ApplicationRoleRef, value);
49 }
50
51 public string Name
52 {
53 get => this.Fields[(int)ComPlusApplicationRolePropertySymbolFields.Name].AsString();
54 set => this.Set((int)ComPlusApplicationRolePropertySymbolFields.Name, value);
55 }
56
57 public string Value
58 {
59 get => this.Fields[(int)ComPlusApplicationRolePropertySymbolFields.Value].AsString();
60 set => this.Set((int)ComPlusApplicationRolePropertySymbolFields.Value, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusApplicationRoleSymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusApplicationRoleSymbol.cs
new file mode 100644
index 00000000..84028ee3
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusApplicationRoleSymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusApplicationRole = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusApplicationRole.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusApplicationRoleSymbolFields.ApplicationRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusApplicationRoleSymbolFields.ComponentRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusApplicationRoleSymbolFields.Name), IntermediateFieldType.String),
17 },
18 typeof(ComPlusApplicationRoleSymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusApplicationRoleSymbolFields
27 {
28 ApplicationRef,
29 ComponentRef,
30 Name,
31 }
32
33 public class ComPlusApplicationRoleSymbol : IntermediateSymbol
34 {
35 public ComPlusApplicationRoleSymbol() : base(ComPlusSymbolDefinitions.ComPlusApplicationRole, null, null)
36 {
37 }
38
39 public ComPlusApplicationRoleSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusApplicationRole, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusApplicationRoleSymbolFields index] => this.Fields[(int)index];
44
45 public string ApplicationRef
46 {
47 get => this.Fields[(int)ComPlusApplicationRoleSymbolFields.ApplicationRef].AsString();
48 set => this.Set((int)ComPlusApplicationRoleSymbolFields.ApplicationRef, value);
49 }
50
51 public string ComponentRef
52 {
53 get => this.Fields[(int)ComPlusApplicationRoleSymbolFields.ComponentRef].AsString();
54 set => this.Set((int)ComPlusApplicationRoleSymbolFields.ComponentRef, value);
55 }
56
57 public string Name
58 {
59 get => this.Fields[(int)ComPlusApplicationRoleSymbolFields.Name].AsString();
60 set => this.Set((int)ComPlusApplicationRoleSymbolFields.Name, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusApplicationSymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusApplicationSymbol.cs
new file mode 100644
index 00000000..ce541e43
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusApplicationSymbol.cs
@@ -0,0 +1,71 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusApplication = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusApplication.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusApplicationSymbolFields.PartitionRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusApplicationSymbolFields.ComponentRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusApplicationSymbolFields.ApplicationId), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(ComPlusApplicationSymbolFields.Name), IntermediateFieldType.String),
18 },
19 typeof(ComPlusApplicationSymbol));
20 }
21}
22
23namespace WixToolset.ComPlus.Symbols
24{
25 using WixToolset.Data;
26
27 public enum ComPlusApplicationSymbolFields
28 {
29 PartitionRef,
30 ComponentRef,
31 ApplicationId,
32 Name,
33 }
34
35 public class ComPlusApplicationSymbol : IntermediateSymbol
36 {
37 public ComPlusApplicationSymbol() : base(ComPlusSymbolDefinitions.ComPlusApplication, null, null)
38 {
39 }
40
41 public ComPlusApplicationSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusApplication, sourceLineNumber, id)
42 {
43 }
44
45 public IntermediateField this[ComPlusApplicationSymbolFields index] => this.Fields[(int)index];
46
47 public string PartitionRef
48 {
49 get => this.Fields[(int)ComPlusApplicationSymbolFields.PartitionRef].AsString();
50 set => this.Set((int)ComPlusApplicationSymbolFields.PartitionRef, value);
51 }
52
53 public string ComponentRef
54 {
55 get => this.Fields[(int)ComPlusApplicationSymbolFields.ComponentRef].AsString();
56 set => this.Set((int)ComPlusApplicationSymbolFields.ComponentRef, value);
57 }
58
59 public string ApplicationId
60 {
61 get => this.Fields[(int)ComPlusApplicationSymbolFields.ApplicationId].AsString();
62 set => this.Set((int)ComPlusApplicationSymbolFields.ApplicationId, value);
63 }
64
65 public string Name
66 {
67 get => this.Fields[(int)ComPlusApplicationSymbolFields.Name].AsString();
68 set => this.Set((int)ComPlusApplicationSymbolFields.Name, value);
69 }
70 }
71} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusAssemblyDependencySymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusAssemblyDependencySymbol.cs
new file mode 100644
index 00000000..549d53e4
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusAssemblyDependencySymbol.cs
@@ -0,0 +1,55 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusAssemblyDependency = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusAssemblyDependency.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusAssemblyDependencySymbolFields.AssemblyRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusAssemblyDependencySymbolFields.RequiredAssemblyRef), IntermediateFieldType.String),
16 },
17 typeof(ComPlusAssemblyDependencySymbol));
18 }
19}
20
21namespace WixToolset.ComPlus.Symbols
22{
23 using WixToolset.Data;
24
25 public enum ComPlusAssemblyDependencySymbolFields
26 {
27 AssemblyRef,
28 RequiredAssemblyRef,
29 }
30
31 public class ComPlusAssemblyDependencySymbol : IntermediateSymbol
32 {
33 public ComPlusAssemblyDependencySymbol() : base(ComPlusSymbolDefinitions.ComPlusAssemblyDependency, null, null)
34 {
35 }
36
37 public ComPlusAssemblyDependencySymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusAssemblyDependency, sourceLineNumber, id)
38 {
39 }
40
41 public IntermediateField this[ComPlusAssemblyDependencySymbolFields index] => this.Fields[(int)index];
42
43 public string AssemblyRef
44 {
45 get => this.Fields[(int)ComPlusAssemblyDependencySymbolFields.AssemblyRef].AsString();
46 set => this.Set((int)ComPlusAssemblyDependencySymbolFields.AssemblyRef, value);
47 }
48
49 public string RequiredAssemblyRef
50 {
51 get => this.Fields[(int)ComPlusAssemblyDependencySymbolFields.RequiredAssemblyRef].AsString();
52 set => this.Set((int)ComPlusAssemblyDependencySymbolFields.RequiredAssemblyRef, value);
53 }
54 }
55} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusAssemblySymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusAssemblySymbol.cs
new file mode 100644
index 00000000..1329df30
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusAssemblySymbol.cs
@@ -0,0 +1,95 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusAssembly = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusAssembly.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusAssemblySymbolFields.ApplicationRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusAssemblySymbolFields.ComponentRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusAssemblySymbolFields.AssemblyName), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(ComPlusAssemblySymbolFields.DllPath), IntermediateFieldType.String),
18 new IntermediateFieldDefinition(nameof(ComPlusAssemblySymbolFields.TlbPath), IntermediateFieldType.String),
19 new IntermediateFieldDefinition(nameof(ComPlusAssemblySymbolFields.PSDllPath), IntermediateFieldType.String),
20 new IntermediateFieldDefinition(nameof(ComPlusAssemblySymbolFields.Attributes), IntermediateFieldType.Number),
21 },
22 typeof(ComPlusAssemblySymbol));
23 }
24}
25
26namespace WixToolset.ComPlus.Symbols
27{
28 using WixToolset.Data;
29
30 public enum ComPlusAssemblySymbolFields
31 {
32 ApplicationRef,
33 ComponentRef,
34 AssemblyName,
35 DllPath,
36 TlbPath,
37 PSDllPath,
38 Attributes,
39 }
40
41 public class ComPlusAssemblySymbol : IntermediateSymbol
42 {
43 public ComPlusAssemblySymbol() : base(ComPlusSymbolDefinitions.ComPlusAssembly, null, null)
44 {
45 }
46
47 public ComPlusAssemblySymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusAssembly, sourceLineNumber, id)
48 {
49 }
50
51 public IntermediateField this[ComPlusAssemblySymbolFields index] => this.Fields[(int)index];
52
53 public string ApplicationRef
54 {
55 get => this.Fields[(int)ComPlusAssemblySymbolFields.ApplicationRef].AsString();
56 set => this.Set((int)ComPlusAssemblySymbolFields.ApplicationRef, value);
57 }
58
59 public string ComponentRef
60 {
61 get => this.Fields[(int)ComPlusAssemblySymbolFields.ComponentRef].AsString();
62 set => this.Set((int)ComPlusAssemblySymbolFields.ComponentRef, value);
63 }
64
65 public string AssemblyName
66 {
67 get => this.Fields[(int)ComPlusAssemblySymbolFields.AssemblyName].AsString();
68 set => this.Set((int)ComPlusAssemblySymbolFields.AssemblyName, value);
69 }
70
71 public string DllPath
72 {
73 get => this.Fields[(int)ComPlusAssemblySymbolFields.DllPath].AsString();
74 set => this.Set((int)ComPlusAssemblySymbolFields.DllPath, value);
75 }
76
77 public string TlbPath
78 {
79 get => this.Fields[(int)ComPlusAssemblySymbolFields.TlbPath].AsString();
80 set => this.Set((int)ComPlusAssemblySymbolFields.TlbPath, value);
81 }
82
83 public string PSDllPath
84 {
85 get => this.Fields[(int)ComPlusAssemblySymbolFields.PSDllPath].AsString();
86 set => this.Set((int)ComPlusAssemblySymbolFields.PSDllPath, value);
87 }
88
89 public int Attributes
90 {
91 get => this.Fields[(int)ComPlusAssemblySymbolFields.Attributes].AsNumber();
92 set => this.Set((int)ComPlusAssemblySymbolFields.Attributes, value);
93 }
94 }
95} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusComponentPropertySymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusComponentPropertySymbol.cs
new file mode 100644
index 00000000..b1d85b60
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusComponentPropertySymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusComponentProperty = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusComponentProperty.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusComponentPropertySymbolFields.ComPlusComponentRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusComponentPropertySymbolFields.Name), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusComponentPropertySymbolFields.Value), IntermediateFieldType.String),
17 },
18 typeof(ComPlusComponentPropertySymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusComponentPropertySymbolFields
27 {
28 ComPlusComponentRef,
29 Name,
30 Value,
31 }
32
33 public class ComPlusComponentPropertySymbol : IntermediateSymbol
34 {
35 public ComPlusComponentPropertySymbol() : base(ComPlusSymbolDefinitions.ComPlusComponentProperty, null, null)
36 {
37 }
38
39 public ComPlusComponentPropertySymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusComponentProperty, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusComponentPropertySymbolFields index] => this.Fields[(int)index];
44
45 public string ComPlusComponentRef
46 {
47 get => this.Fields[(int)ComPlusComponentPropertySymbolFields.ComPlusComponentRef].AsString();
48 set => this.Set((int)ComPlusComponentPropertySymbolFields.ComPlusComponentRef, value);
49 }
50
51 public string Name
52 {
53 get => this.Fields[(int)ComPlusComponentPropertySymbolFields.Name].AsString();
54 set => this.Set((int)ComPlusComponentPropertySymbolFields.Name, value);
55 }
56
57 public string Value
58 {
59 get => this.Fields[(int)ComPlusComponentPropertySymbolFields.Value].AsString();
60 set => this.Set((int)ComPlusComponentPropertySymbolFields.Value, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusComponentSymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusComponentSymbol.cs
new file mode 100644
index 00000000..020b754c
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusComponentSymbol.cs
@@ -0,0 +1,55 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusComponent = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusComponent.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusComponentSymbolFields.AssemblyRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusComponentSymbolFields.CLSID), IntermediateFieldType.String),
16 },
17 typeof(ComPlusComponentSymbol));
18 }
19}
20
21namespace WixToolset.ComPlus.Symbols
22{
23 using WixToolset.Data;
24
25 public enum ComPlusComponentSymbolFields
26 {
27 AssemblyRef,
28 CLSID,
29 }
30
31 public class ComPlusComponentSymbol : IntermediateSymbol
32 {
33 public ComPlusComponentSymbol() : base(ComPlusSymbolDefinitions.ComPlusComponent, null, null)
34 {
35 }
36
37 public ComPlusComponentSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusComponent, sourceLineNumber, id)
38 {
39 }
40
41 public IntermediateField this[ComPlusComponentSymbolFields index] => this.Fields[(int)index];
42
43 public string AssemblyRef
44 {
45 get => this.Fields[(int)ComPlusComponentSymbolFields.AssemblyRef].AsString();
46 set => this.Set((int)ComPlusComponentSymbolFields.AssemblyRef, value);
47 }
48
49 public string CLSID
50 {
51 get => this.Fields[(int)ComPlusComponentSymbolFields.CLSID].AsString();
52 set => this.Set((int)ComPlusComponentSymbolFields.CLSID, value);
53 }
54 }
55} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusGroupInApplicationRoleSymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusGroupInApplicationRoleSymbol.cs
new file mode 100644
index 00000000..d6b91e99
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusGroupInApplicationRoleSymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusGroupInApplicationRole = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusGroupInApplicationRole.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusGroupInApplicationRoleSymbolFields.ApplicationRoleRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusGroupInApplicationRoleSymbolFields.ComponentRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusGroupInApplicationRoleSymbolFields.GroupRef), IntermediateFieldType.String),
17 },
18 typeof(ComPlusGroupInApplicationRoleSymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusGroupInApplicationRoleSymbolFields
27 {
28 ApplicationRoleRef,
29 ComponentRef,
30 GroupRef,
31 }
32
33 public class ComPlusGroupInApplicationRoleSymbol : IntermediateSymbol
34 {
35 public ComPlusGroupInApplicationRoleSymbol() : base(ComPlusSymbolDefinitions.ComPlusGroupInApplicationRole, null, null)
36 {
37 }
38
39 public ComPlusGroupInApplicationRoleSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusGroupInApplicationRole, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusGroupInApplicationRoleSymbolFields index] => this.Fields[(int)index];
44
45 public string ApplicationRoleRef
46 {
47 get => this.Fields[(int)ComPlusGroupInApplicationRoleSymbolFields.ApplicationRoleRef].AsString();
48 set => this.Set((int)ComPlusGroupInApplicationRoleSymbolFields.ApplicationRoleRef, value);
49 }
50
51 public string ComponentRef
52 {
53 get => this.Fields[(int)ComPlusGroupInApplicationRoleSymbolFields.ComponentRef].AsString();
54 set => this.Set((int)ComPlusGroupInApplicationRoleSymbolFields.ComponentRef, value);
55 }
56
57 public string GroupRef
58 {
59 get => this.Fields[(int)ComPlusGroupInApplicationRoleSymbolFields.GroupRef].AsString();
60 set => this.Set((int)ComPlusGroupInApplicationRoleSymbolFields.GroupRef, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusGroupInPartitionRoleSymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusGroupInPartitionRoleSymbol.cs
new file mode 100644
index 00000000..da70de9f
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusGroupInPartitionRoleSymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusGroupInPartitionRole = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusGroupInPartitionRole.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusGroupInPartitionRoleSymbolFields.PartitionRoleRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusGroupInPartitionRoleSymbolFields.ComponentRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusGroupInPartitionRoleSymbolFields.GroupRef), IntermediateFieldType.String),
17 },
18 typeof(ComPlusGroupInPartitionRoleSymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusGroupInPartitionRoleSymbolFields
27 {
28 PartitionRoleRef,
29 ComponentRef,
30 GroupRef,
31 }
32
33 public class ComPlusGroupInPartitionRoleSymbol : IntermediateSymbol
34 {
35 public ComPlusGroupInPartitionRoleSymbol() : base(ComPlusSymbolDefinitions.ComPlusGroupInPartitionRole, null, null)
36 {
37 }
38
39 public ComPlusGroupInPartitionRoleSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusGroupInPartitionRole, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusGroupInPartitionRoleSymbolFields index] => this.Fields[(int)index];
44
45 public string PartitionRoleRef
46 {
47 get => this.Fields[(int)ComPlusGroupInPartitionRoleSymbolFields.PartitionRoleRef].AsString();
48 set => this.Set((int)ComPlusGroupInPartitionRoleSymbolFields.PartitionRoleRef, value);
49 }
50
51 public string ComponentRef
52 {
53 get => this.Fields[(int)ComPlusGroupInPartitionRoleSymbolFields.ComponentRef].AsString();
54 set => this.Set((int)ComPlusGroupInPartitionRoleSymbolFields.ComponentRef, value);
55 }
56
57 public string GroupRef
58 {
59 get => this.Fields[(int)ComPlusGroupInPartitionRoleSymbolFields.GroupRef].AsString();
60 set => this.Set((int)ComPlusGroupInPartitionRoleSymbolFields.GroupRef, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusInterfacePropertySymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusInterfacePropertySymbol.cs
new file mode 100644
index 00000000..2ed4ce18
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusInterfacePropertySymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusInterfaceProperty = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusInterfaceProperty.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusInterfacePropertySymbolFields.InterfaceRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusInterfacePropertySymbolFields.Name), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusInterfacePropertySymbolFields.Value), IntermediateFieldType.String),
17 },
18 typeof(ComPlusInterfacePropertySymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusInterfacePropertySymbolFields
27 {
28 InterfaceRef,
29 Name,
30 Value,
31 }
32
33 public class ComPlusInterfacePropertySymbol : IntermediateSymbol
34 {
35 public ComPlusInterfacePropertySymbol() : base(ComPlusSymbolDefinitions.ComPlusInterfaceProperty, null, null)
36 {
37 }
38
39 public ComPlusInterfacePropertySymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusInterfaceProperty, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusInterfacePropertySymbolFields index] => this.Fields[(int)index];
44
45 public string InterfaceRef
46 {
47 get => this.Fields[(int)ComPlusInterfacePropertySymbolFields.InterfaceRef].AsString();
48 set => this.Set((int)ComPlusInterfacePropertySymbolFields.InterfaceRef, value);
49 }
50
51 public string Name
52 {
53 get => this.Fields[(int)ComPlusInterfacePropertySymbolFields.Name].AsString();
54 set => this.Set((int)ComPlusInterfacePropertySymbolFields.Name, value);
55 }
56
57 public string Value
58 {
59 get => this.Fields[(int)ComPlusInterfacePropertySymbolFields.Value].AsString();
60 set => this.Set((int)ComPlusInterfacePropertySymbolFields.Value, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusInterfaceSymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusInterfaceSymbol.cs
new file mode 100644
index 00000000..f875b424
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusInterfaceSymbol.cs
@@ -0,0 +1,55 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusInterface = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusInterface.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusInterfaceSymbolFields.ComPlusComponentRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusInterfaceSymbolFields.IID), IntermediateFieldType.String),
16 },
17 typeof(ComPlusInterfaceSymbol));
18 }
19}
20
21namespace WixToolset.ComPlus.Symbols
22{
23 using WixToolset.Data;
24
25 public enum ComPlusInterfaceSymbolFields
26 {
27 ComPlusComponentRef,
28 IID,
29 }
30
31 public class ComPlusInterfaceSymbol : IntermediateSymbol
32 {
33 public ComPlusInterfaceSymbol() : base(ComPlusSymbolDefinitions.ComPlusInterface, null, null)
34 {
35 }
36
37 public ComPlusInterfaceSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusInterface, sourceLineNumber, id)
38 {
39 }
40
41 public IntermediateField this[ComPlusInterfaceSymbolFields index] => this.Fields[(int)index];
42
43 public string ComPlusComponentRef
44 {
45 get => this.Fields[(int)ComPlusInterfaceSymbolFields.ComPlusComponentRef].AsString();
46 set => this.Set((int)ComPlusInterfaceSymbolFields.ComPlusComponentRef, value);
47 }
48
49 public string IID
50 {
51 get => this.Fields[(int)ComPlusInterfaceSymbolFields.IID].AsString();
52 set => this.Set((int)ComPlusInterfaceSymbolFields.IID, value);
53 }
54 }
55} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusMethodPropertySymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusMethodPropertySymbol.cs
new file mode 100644
index 00000000..65b17ea4
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusMethodPropertySymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusMethodProperty = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusMethodProperty.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusMethodPropertySymbolFields.MethodRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusMethodPropertySymbolFields.Name), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusMethodPropertySymbolFields.Value), IntermediateFieldType.String),
17 },
18 typeof(ComPlusMethodPropertySymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusMethodPropertySymbolFields
27 {
28 MethodRef,
29 Name,
30 Value,
31 }
32
33 public class ComPlusMethodPropertySymbol : IntermediateSymbol
34 {
35 public ComPlusMethodPropertySymbol() : base(ComPlusSymbolDefinitions.ComPlusMethodProperty, null, null)
36 {
37 }
38
39 public ComPlusMethodPropertySymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusMethodProperty, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusMethodPropertySymbolFields index] => this.Fields[(int)index];
44
45 public string MethodRef
46 {
47 get => this.Fields[(int)ComPlusMethodPropertySymbolFields.MethodRef].AsString();
48 set => this.Set((int)ComPlusMethodPropertySymbolFields.MethodRef, value);
49 }
50
51 public string Name
52 {
53 get => this.Fields[(int)ComPlusMethodPropertySymbolFields.Name].AsString();
54 set => this.Set((int)ComPlusMethodPropertySymbolFields.Name, value);
55 }
56
57 public string Value
58 {
59 get => this.Fields[(int)ComPlusMethodPropertySymbolFields.Value].AsString();
60 set => this.Set((int)ComPlusMethodPropertySymbolFields.Value, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusMethodSymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusMethodSymbol.cs
new file mode 100644
index 00000000..9959a56f
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusMethodSymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusMethod = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusMethod.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusMethodSymbolFields.InterfaceRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusMethodSymbolFields.Index), IntermediateFieldType.Number),
16 new IntermediateFieldDefinition(nameof(ComPlusMethodSymbolFields.Name), IntermediateFieldType.String),
17 },
18 typeof(ComPlusMethodSymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusMethodSymbolFields
27 {
28 InterfaceRef,
29 Index,
30 Name,
31 }
32
33 public class ComPlusMethodSymbol : IntermediateSymbol
34 {
35 public ComPlusMethodSymbol() : base(ComPlusSymbolDefinitions.ComPlusMethod, null, null)
36 {
37 }
38
39 public ComPlusMethodSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusMethod, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusMethodSymbolFields index] => this.Fields[(int)index];
44
45 public string InterfaceRef
46 {
47 get => this.Fields[(int)ComPlusMethodSymbolFields.InterfaceRef].AsString();
48 set => this.Set((int)ComPlusMethodSymbolFields.InterfaceRef, value);
49 }
50
51 public int? Index
52 {
53 get => this.Fields[(int)ComPlusMethodSymbolFields.Index].AsNullableNumber();
54 set => this.Set((int)ComPlusMethodSymbolFields.Index, value);
55 }
56
57 public string Name
58 {
59 get => this.Fields[(int)ComPlusMethodSymbolFields.Name].AsString();
60 set => this.Set((int)ComPlusMethodSymbolFields.Name, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusPartitionPropertySymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusPartitionPropertySymbol.cs
new file mode 100644
index 00000000..e42feae2
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusPartitionPropertySymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusPartitionProperty = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusPartitionProperty.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusPartitionPropertySymbolFields.PartitionRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusPartitionPropertySymbolFields.Name), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusPartitionPropertySymbolFields.Value), IntermediateFieldType.String),
17 },
18 typeof(ComPlusPartitionPropertySymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusPartitionPropertySymbolFields
27 {
28 PartitionRef,
29 Name,
30 Value,
31 }
32
33 public class ComPlusPartitionPropertySymbol : IntermediateSymbol
34 {
35 public ComPlusPartitionPropertySymbol() : base(ComPlusSymbolDefinitions.ComPlusPartitionProperty, null, null)
36 {
37 }
38
39 public ComPlusPartitionPropertySymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusPartitionProperty, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusPartitionPropertySymbolFields index] => this.Fields[(int)index];
44
45 public string PartitionRef
46 {
47 get => this.Fields[(int)ComPlusPartitionPropertySymbolFields.PartitionRef].AsString();
48 set => this.Set((int)ComPlusPartitionPropertySymbolFields.PartitionRef, value);
49 }
50
51 public string Name
52 {
53 get => this.Fields[(int)ComPlusPartitionPropertySymbolFields.Name].AsString();
54 set => this.Set((int)ComPlusPartitionPropertySymbolFields.Name, value);
55 }
56
57 public string Value
58 {
59 get => this.Fields[(int)ComPlusPartitionPropertySymbolFields.Value].AsString();
60 set => this.Set((int)ComPlusPartitionPropertySymbolFields.Value, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusPartitionRoleSymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusPartitionRoleSymbol.cs
new file mode 100644
index 00000000..23293d93
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusPartitionRoleSymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusPartitionRole = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusPartitionRole.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusPartitionRoleSymbolFields.PartitionRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusPartitionRoleSymbolFields.ComponentRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusPartitionRoleSymbolFields.Name), IntermediateFieldType.String),
17 },
18 typeof(ComPlusPartitionRoleSymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusPartitionRoleSymbolFields
27 {
28 PartitionRef,
29 ComponentRef,
30 Name,
31 }
32
33 public class ComPlusPartitionRoleSymbol : IntermediateSymbol
34 {
35 public ComPlusPartitionRoleSymbol() : base(ComPlusSymbolDefinitions.ComPlusPartitionRole, null, null)
36 {
37 }
38
39 public ComPlusPartitionRoleSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusPartitionRole, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusPartitionRoleSymbolFields index] => this.Fields[(int)index];
44
45 public string PartitionRef
46 {
47 get => this.Fields[(int)ComPlusPartitionRoleSymbolFields.PartitionRef].AsString();
48 set => this.Set((int)ComPlusPartitionRoleSymbolFields.PartitionRef, value);
49 }
50
51 public string ComponentRef
52 {
53 get => this.Fields[(int)ComPlusPartitionRoleSymbolFields.ComponentRef].AsString();
54 set => this.Set((int)ComPlusPartitionRoleSymbolFields.ComponentRef, value);
55 }
56
57 public string Name
58 {
59 get => this.Fields[(int)ComPlusPartitionRoleSymbolFields.Name].AsString();
60 set => this.Set((int)ComPlusPartitionRoleSymbolFields.Name, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusPartitionSymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusPartitionSymbol.cs
new file mode 100644
index 00000000..c60fca40
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusPartitionSymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusPartition = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusPartition.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusPartitionSymbolFields.ComponentRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusPartitionSymbolFields.PartitionId), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusPartitionSymbolFields.Name), IntermediateFieldType.String),
17 },
18 typeof(ComPlusPartitionSymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusPartitionSymbolFields
27 {
28 ComponentRef,
29 PartitionId,
30 Name,
31 }
32
33 public class ComPlusPartitionSymbol : IntermediateSymbol
34 {
35 public ComPlusPartitionSymbol() : base(ComPlusSymbolDefinitions.ComPlusPartition, null, null)
36 {
37 }
38
39 public ComPlusPartitionSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusPartition, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusPartitionSymbolFields index] => this.Fields[(int)index];
44
45 public string ComponentRef
46 {
47 get => this.Fields[(int)ComPlusPartitionSymbolFields.ComponentRef].AsString();
48 set => this.Set((int)ComPlusPartitionSymbolFields.ComponentRef, value);
49 }
50
51 public string PartitionId
52 {
53 get => this.Fields[(int)ComPlusPartitionSymbolFields.PartitionId].AsString();
54 set => this.Set((int)ComPlusPartitionSymbolFields.PartitionId, value);
55 }
56
57 public string Name
58 {
59 get => this.Fields[(int)ComPlusPartitionSymbolFields.Name].AsString();
60 set => this.Set((int)ComPlusPartitionSymbolFields.Name, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusPartitionUserSymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusPartitionUserSymbol.cs
new file mode 100644
index 00000000..c4d52f54
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusPartitionUserSymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusPartitionUser = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusPartitionUser.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusPartitionUserSymbolFields.PartitionRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusPartitionUserSymbolFields.ComponentRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusPartitionUserSymbolFields.UserRef), IntermediateFieldType.String),
17 },
18 typeof(ComPlusPartitionUserSymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusPartitionUserSymbolFields
27 {
28 PartitionRef,
29 ComponentRef,
30 UserRef,
31 }
32
33 public class ComPlusPartitionUserSymbol : IntermediateSymbol
34 {
35 public ComPlusPartitionUserSymbol() : base(ComPlusSymbolDefinitions.ComPlusPartitionUser, null, null)
36 {
37 }
38
39 public ComPlusPartitionUserSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusPartitionUser, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusPartitionUserSymbolFields index] => this.Fields[(int)index];
44
45 public string PartitionRef
46 {
47 get => this.Fields[(int)ComPlusPartitionUserSymbolFields.PartitionRef].AsString();
48 set => this.Set((int)ComPlusPartitionUserSymbolFields.PartitionRef, value);
49 }
50
51 public string ComponentRef
52 {
53 get => this.Fields[(int)ComPlusPartitionUserSymbolFields.ComponentRef].AsString();
54 set => this.Set((int)ComPlusPartitionUserSymbolFields.ComponentRef, value);
55 }
56
57 public string UserRef
58 {
59 get => this.Fields[(int)ComPlusPartitionUserSymbolFields.UserRef].AsString();
60 set => this.Set((int)ComPlusPartitionUserSymbolFields.UserRef, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusRoleForComponentSymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusRoleForComponentSymbol.cs
new file mode 100644
index 00000000..2d9968ee
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusRoleForComponentSymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusRoleForComponent = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusRoleForComponent.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusRoleForComponentSymbolFields.ComPlusComponentRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusRoleForComponentSymbolFields.ApplicationRoleRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusRoleForComponentSymbolFields.ComponentRef), IntermediateFieldType.String),
17 },
18 typeof(ComPlusRoleForComponentSymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusRoleForComponentSymbolFields
27 {
28 ComPlusComponentRef,
29 ApplicationRoleRef,
30 ComponentRef,
31 }
32
33 public class ComPlusRoleForComponentSymbol : IntermediateSymbol
34 {
35 public ComPlusRoleForComponentSymbol() : base(ComPlusSymbolDefinitions.ComPlusRoleForComponent, null, null)
36 {
37 }
38
39 public ComPlusRoleForComponentSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusRoleForComponent, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusRoleForComponentSymbolFields index] => this.Fields[(int)index];
44
45 public string ComPlusComponentRef
46 {
47 get => this.Fields[(int)ComPlusRoleForComponentSymbolFields.ComPlusComponentRef].AsString();
48 set => this.Set((int)ComPlusRoleForComponentSymbolFields.ComPlusComponentRef, value);
49 }
50
51 public string ApplicationRoleRef
52 {
53 get => this.Fields[(int)ComPlusRoleForComponentSymbolFields.ApplicationRoleRef].AsString();
54 set => this.Set((int)ComPlusRoleForComponentSymbolFields.ApplicationRoleRef, value);
55 }
56
57 public string ComponentRef
58 {
59 get => this.Fields[(int)ComPlusRoleForComponentSymbolFields.ComponentRef].AsString();
60 set => this.Set((int)ComPlusRoleForComponentSymbolFields.ComponentRef, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusRoleForInterfaceSymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusRoleForInterfaceSymbol.cs
new file mode 100644
index 00000000..b77bd215
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusRoleForInterfaceSymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusRoleForInterface = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusRoleForInterface.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusRoleForInterfaceSymbolFields.InterfaceRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusRoleForInterfaceSymbolFields.ApplicationRoleRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusRoleForInterfaceSymbolFields.ComponentRef), IntermediateFieldType.String),
17 },
18 typeof(ComPlusRoleForInterfaceSymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusRoleForInterfaceSymbolFields
27 {
28 InterfaceRef,
29 ApplicationRoleRef,
30 ComponentRef,
31 }
32
33 public class ComPlusRoleForInterfaceSymbol : IntermediateSymbol
34 {
35 public ComPlusRoleForInterfaceSymbol() : base(ComPlusSymbolDefinitions.ComPlusRoleForInterface, null, null)
36 {
37 }
38
39 public ComPlusRoleForInterfaceSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusRoleForInterface, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusRoleForInterfaceSymbolFields index] => this.Fields[(int)index];
44
45 public string InterfaceRef
46 {
47 get => this.Fields[(int)ComPlusRoleForInterfaceSymbolFields.InterfaceRef].AsString();
48 set => this.Set((int)ComPlusRoleForInterfaceSymbolFields.InterfaceRef, value);
49 }
50
51 public string ApplicationRoleRef
52 {
53 get => this.Fields[(int)ComPlusRoleForInterfaceSymbolFields.ApplicationRoleRef].AsString();
54 set => this.Set((int)ComPlusRoleForInterfaceSymbolFields.ApplicationRoleRef, value);
55 }
56
57 public string ComponentRef
58 {
59 get => this.Fields[(int)ComPlusRoleForInterfaceSymbolFields.ComponentRef].AsString();
60 set => this.Set((int)ComPlusRoleForInterfaceSymbolFields.ComponentRef, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusRoleForMethodSymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusRoleForMethodSymbol.cs
new file mode 100644
index 00000000..9ba9d03b
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusRoleForMethodSymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusRoleForMethod = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusRoleForMethod.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusRoleForMethodSymbolFields.MethodRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusRoleForMethodSymbolFields.ApplicationRoleRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusRoleForMethodSymbolFields.ComponentRef), IntermediateFieldType.String),
17 },
18 typeof(ComPlusRoleForMethodSymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusRoleForMethodSymbolFields
27 {
28 MethodRef,
29 ApplicationRoleRef,
30 ComponentRef,
31 }
32
33 public class ComPlusRoleForMethodSymbol : IntermediateSymbol
34 {
35 public ComPlusRoleForMethodSymbol() : base(ComPlusSymbolDefinitions.ComPlusRoleForMethod, null, null)
36 {
37 }
38
39 public ComPlusRoleForMethodSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusRoleForMethod, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusRoleForMethodSymbolFields index] => this.Fields[(int)index];
44
45 public string MethodRef
46 {
47 get => this.Fields[(int)ComPlusRoleForMethodSymbolFields.MethodRef].AsString();
48 set => this.Set((int)ComPlusRoleForMethodSymbolFields.MethodRef, value);
49 }
50
51 public string ApplicationRoleRef
52 {
53 get => this.Fields[(int)ComPlusRoleForMethodSymbolFields.ApplicationRoleRef].AsString();
54 set => this.Set((int)ComPlusRoleForMethodSymbolFields.ApplicationRoleRef, value);
55 }
56
57 public string ComponentRef
58 {
59 get => this.Fields[(int)ComPlusRoleForMethodSymbolFields.ComponentRef].AsString();
60 set => this.Set((int)ComPlusRoleForMethodSymbolFields.ComponentRef, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusSubscriptionPropertySymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusSubscriptionPropertySymbol.cs
new file mode 100644
index 00000000..af995c3d
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusSubscriptionPropertySymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusSubscriptionProperty = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusSubscriptionProperty.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusSubscriptionPropertySymbolFields.SubscriptionRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusSubscriptionPropertySymbolFields.Name), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusSubscriptionPropertySymbolFields.Value), IntermediateFieldType.String),
17 },
18 typeof(ComPlusSubscriptionPropertySymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusSubscriptionPropertySymbolFields
27 {
28 SubscriptionRef,
29 Name,
30 Value,
31 }
32
33 public class ComPlusSubscriptionPropertySymbol : IntermediateSymbol
34 {
35 public ComPlusSubscriptionPropertySymbol() : base(ComPlusSymbolDefinitions.ComPlusSubscriptionProperty, null, null)
36 {
37 }
38
39 public ComPlusSubscriptionPropertySymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusSubscriptionProperty, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusSubscriptionPropertySymbolFields index] => this.Fields[(int)index];
44
45 public string SubscriptionRef
46 {
47 get => this.Fields[(int)ComPlusSubscriptionPropertySymbolFields.SubscriptionRef].AsString();
48 set => this.Set((int)ComPlusSubscriptionPropertySymbolFields.SubscriptionRef, value);
49 }
50
51 public string Name
52 {
53 get => this.Fields[(int)ComPlusSubscriptionPropertySymbolFields.Name].AsString();
54 set => this.Set((int)ComPlusSubscriptionPropertySymbolFields.Name, value);
55 }
56
57 public string Value
58 {
59 get => this.Fields[(int)ComPlusSubscriptionPropertySymbolFields.Value].AsString();
60 set => this.Set((int)ComPlusSubscriptionPropertySymbolFields.Value, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusSubscriptionSymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusSubscriptionSymbol.cs
new file mode 100644
index 00000000..24d3f92e
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusSubscriptionSymbol.cs
@@ -0,0 +1,95 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusSubscription = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusSubscription.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusSubscriptionSymbolFields.Subscription), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusSubscriptionSymbolFields.ComPlusComponentRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusSubscriptionSymbolFields.ComponentRef), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(ComPlusSubscriptionSymbolFields.SubscriptionId), IntermediateFieldType.String),
18 new IntermediateFieldDefinition(nameof(ComPlusSubscriptionSymbolFields.Name), IntermediateFieldType.String),
19 new IntermediateFieldDefinition(nameof(ComPlusSubscriptionSymbolFields.EventCLSID), IntermediateFieldType.String),
20 new IntermediateFieldDefinition(nameof(ComPlusSubscriptionSymbolFields.PublisherID), IntermediateFieldType.String),
21 },
22 typeof(ComPlusSubscriptionSymbol));
23 }
24}
25
26namespace WixToolset.ComPlus.Symbols
27{
28 using WixToolset.Data;
29
30 public enum ComPlusSubscriptionSymbolFields
31 {
32 Subscription,
33 ComPlusComponentRef,
34 ComponentRef,
35 SubscriptionId,
36 Name,
37 EventCLSID,
38 PublisherID,
39 }
40
41 public class ComPlusSubscriptionSymbol : IntermediateSymbol
42 {
43 public ComPlusSubscriptionSymbol() : base(ComPlusSymbolDefinitions.ComPlusSubscription, null, null)
44 {
45 }
46
47 public ComPlusSubscriptionSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusSubscription, sourceLineNumber, id)
48 {
49 }
50
51 public IntermediateField this[ComPlusSubscriptionSymbolFields index] => this.Fields[(int)index];
52
53 public string Subscription
54 {
55 get => this.Fields[(int)ComPlusSubscriptionSymbolFields.Subscription].AsString();
56 set => this.Set((int)ComPlusSubscriptionSymbolFields.Subscription, value);
57 }
58
59 public string ComPlusComponentRef
60 {
61 get => this.Fields[(int)ComPlusSubscriptionSymbolFields.ComPlusComponentRef].AsString();
62 set => this.Set((int)ComPlusSubscriptionSymbolFields.ComPlusComponentRef, value);
63 }
64
65 public string ComponentRef
66 {
67 get => this.Fields[(int)ComPlusSubscriptionSymbolFields.ComponentRef].AsString();
68 set => this.Set((int)ComPlusSubscriptionSymbolFields.ComponentRef, value);
69 }
70
71 public string SubscriptionId
72 {
73 get => this.Fields[(int)ComPlusSubscriptionSymbolFields.SubscriptionId].AsString();
74 set => this.Set((int)ComPlusSubscriptionSymbolFields.SubscriptionId, value);
75 }
76
77 public string Name
78 {
79 get => this.Fields[(int)ComPlusSubscriptionSymbolFields.Name].AsString();
80 set => this.Set((int)ComPlusSubscriptionSymbolFields.Name, value);
81 }
82
83 public string EventCLSID
84 {
85 get => this.Fields[(int)ComPlusSubscriptionSymbolFields.EventCLSID].AsString();
86 set => this.Set((int)ComPlusSubscriptionSymbolFields.EventCLSID, value);
87 }
88
89 public string PublisherID
90 {
91 get => this.Fields[(int)ComPlusSubscriptionSymbolFields.PublisherID].AsString();
92 set => this.Set((int)ComPlusSubscriptionSymbolFields.PublisherID, value);
93 }
94 }
95} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusSymbolDefinitions.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusSymbolDefinitions.cs
new file mode 100644
index 00000000..407b9c14
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusSymbolDefinitions.cs
@@ -0,0 +1,135 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using System;
6 using WixToolset.Data;
7
8 public enum ComPlusSymbolDefinitionType
9 {
10 ComPlusApplication,
11 ComPlusApplicationProperty,
12 ComPlusApplicationRole,
13 ComPlusApplicationRoleProperty,
14 ComPlusAssembly,
15 ComPlusAssemblyDependency,
16 ComPlusComponent,
17 ComPlusComponentProperty,
18 ComPlusGroupInApplicationRole,
19 ComPlusGroupInPartitionRole,
20 ComPlusInterface,
21 ComPlusInterfaceProperty,
22 ComPlusMethod,
23 ComPlusMethodProperty,
24 ComPlusPartition,
25 ComPlusPartitionProperty,
26 ComPlusPartitionRole,
27 ComPlusPartitionUser,
28 ComPlusRoleForComponent,
29 ComPlusRoleForInterface,
30 ComPlusRoleForMethod,
31 ComPlusSubscription,
32 ComPlusSubscriptionProperty,
33 ComPlusUserInApplicationRole,
34 ComPlusUserInPartitionRole,
35 }
36
37 public static partial class ComPlusSymbolDefinitions
38 {
39 public static readonly Version Version = new Version("4.0.0");
40
41 public static IntermediateSymbolDefinition ByName(string name)
42 {
43 if (!Enum.TryParse(name, out ComPlusSymbolDefinitionType type))
44 {
45 return null;
46 }
47
48 return ByType(type);
49 }
50
51 public static IntermediateSymbolDefinition ByType(ComPlusSymbolDefinitionType type)
52 {
53 switch (type)
54 {
55 case ComPlusSymbolDefinitionType.ComPlusApplication:
56 return ComPlusSymbolDefinitions.ComPlusApplication;
57
58 case ComPlusSymbolDefinitionType.ComPlusApplicationProperty:
59 return ComPlusSymbolDefinitions.ComPlusApplicationProperty;
60
61 case ComPlusSymbolDefinitionType.ComPlusApplicationRole:
62 return ComPlusSymbolDefinitions.ComPlusApplicationRole;
63
64 case ComPlusSymbolDefinitionType.ComPlusApplicationRoleProperty:
65 return ComPlusSymbolDefinitions.ComPlusApplicationRoleProperty;
66
67 case ComPlusSymbolDefinitionType.ComPlusAssembly:
68 return ComPlusSymbolDefinitions.ComPlusAssembly;
69
70 case ComPlusSymbolDefinitionType.ComPlusAssemblyDependency:
71 return ComPlusSymbolDefinitions.ComPlusAssemblyDependency;
72
73 case ComPlusSymbolDefinitionType.ComPlusComponent:
74 return ComPlusSymbolDefinitions.ComPlusComponent;
75
76 case ComPlusSymbolDefinitionType.ComPlusComponentProperty:
77 return ComPlusSymbolDefinitions.ComPlusComponentProperty;
78
79 case ComPlusSymbolDefinitionType.ComPlusGroupInApplicationRole:
80 return ComPlusSymbolDefinitions.ComPlusGroupInApplicationRole;
81
82 case ComPlusSymbolDefinitionType.ComPlusGroupInPartitionRole:
83 return ComPlusSymbolDefinitions.ComPlusGroupInPartitionRole;
84
85 case ComPlusSymbolDefinitionType.ComPlusInterface:
86 return ComPlusSymbolDefinitions.ComPlusInterface;
87
88 case ComPlusSymbolDefinitionType.ComPlusInterfaceProperty:
89 return ComPlusSymbolDefinitions.ComPlusInterfaceProperty;
90
91 case ComPlusSymbolDefinitionType.ComPlusMethod:
92 return ComPlusSymbolDefinitions.ComPlusMethod;
93
94 case ComPlusSymbolDefinitionType.ComPlusMethodProperty:
95 return ComPlusSymbolDefinitions.ComPlusMethodProperty;
96
97 case ComPlusSymbolDefinitionType.ComPlusPartition:
98 return ComPlusSymbolDefinitions.ComPlusPartition;
99
100 case ComPlusSymbolDefinitionType.ComPlusPartitionProperty:
101 return ComPlusSymbolDefinitions.ComPlusPartitionProperty;
102
103 case ComPlusSymbolDefinitionType.ComPlusPartitionRole:
104 return ComPlusSymbolDefinitions.ComPlusPartitionRole;
105
106 case ComPlusSymbolDefinitionType.ComPlusPartitionUser:
107 return ComPlusSymbolDefinitions.ComPlusPartitionUser;
108
109 case ComPlusSymbolDefinitionType.ComPlusRoleForComponent:
110 return ComPlusSymbolDefinitions.ComPlusRoleForComponent;
111
112 case ComPlusSymbolDefinitionType.ComPlusRoleForInterface:
113 return ComPlusSymbolDefinitions.ComPlusRoleForInterface;
114
115 case ComPlusSymbolDefinitionType.ComPlusRoleForMethod:
116 return ComPlusSymbolDefinitions.ComPlusRoleForMethod;
117
118 case ComPlusSymbolDefinitionType.ComPlusSubscription:
119 return ComPlusSymbolDefinitions.ComPlusSubscription;
120
121 case ComPlusSymbolDefinitionType.ComPlusSubscriptionProperty:
122 return ComPlusSymbolDefinitions.ComPlusSubscriptionProperty;
123
124 case ComPlusSymbolDefinitionType.ComPlusUserInApplicationRole:
125 return ComPlusSymbolDefinitions.ComPlusUserInApplicationRole;
126
127 case ComPlusSymbolDefinitionType.ComPlusUserInPartitionRole:
128 return ComPlusSymbolDefinitions.ComPlusUserInPartitionRole;
129
130 default:
131 throw new ArgumentOutOfRangeException(nameof(type));
132 }
133 }
134 }
135}
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusUserInApplicationRoleSymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusUserInApplicationRoleSymbol.cs
new file mode 100644
index 00000000..1f2e01b2
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusUserInApplicationRoleSymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusUserInApplicationRole = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusUserInApplicationRole.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusUserInApplicationRoleSymbolFields.ApplicationRoleRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusUserInApplicationRoleSymbolFields.ComponentRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusUserInApplicationRoleSymbolFields.UserRef), IntermediateFieldType.String),
17 },
18 typeof(ComPlusUserInApplicationRoleSymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusUserInApplicationRoleSymbolFields
27 {
28 ApplicationRoleRef,
29 ComponentRef,
30 UserRef,
31 }
32
33 public class ComPlusUserInApplicationRoleSymbol : IntermediateSymbol
34 {
35 public ComPlusUserInApplicationRoleSymbol() : base(ComPlusSymbolDefinitions.ComPlusUserInApplicationRole, null, null)
36 {
37 }
38
39 public ComPlusUserInApplicationRoleSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusUserInApplicationRole, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusUserInApplicationRoleSymbolFields index] => this.Fields[(int)index];
44
45 public string ApplicationRoleRef
46 {
47 get => this.Fields[(int)ComPlusUserInApplicationRoleSymbolFields.ApplicationRoleRef].AsString();
48 set => this.Set((int)ComPlusUserInApplicationRoleSymbolFields.ApplicationRoleRef, value);
49 }
50
51 public string ComponentRef
52 {
53 get => this.Fields[(int)ComPlusUserInApplicationRoleSymbolFields.ComponentRef].AsString();
54 set => this.Set((int)ComPlusUserInApplicationRoleSymbolFields.ComponentRef, value);
55 }
56
57 public string UserRef
58 {
59 get => this.Fields[(int)ComPlusUserInApplicationRoleSymbolFields.UserRef].AsString();
60 set => this.Set((int)ComPlusUserInApplicationRoleSymbolFields.UserRef, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/Symbols/ComPlusUserInPartitionRoleSymbol.cs b/src/ext/ComPlus/wixext/Symbols/ComPlusUserInPartitionRoleSymbol.cs
new file mode 100644
index 00000000..10df94bf
--- /dev/null
+++ b/src/ext/ComPlus/wixext/Symbols/ComPlusUserInPartitionRoleSymbol.cs
@@ -0,0 +1,63 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.ComPlus
4{
5 using WixToolset.Data;
6 using WixToolset.ComPlus.Symbols;
7
8 public static partial class ComPlusSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition ComPlusUserInPartitionRole = new IntermediateSymbolDefinition(
11 ComPlusSymbolDefinitionType.ComPlusUserInPartitionRole.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(ComPlusUserInPartitionRoleSymbolFields.PartitionRoleRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(ComPlusUserInPartitionRoleSymbolFields.ComponentRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(ComPlusUserInPartitionRoleSymbolFields.UserRef), IntermediateFieldType.String),
17 },
18 typeof(ComPlusUserInPartitionRoleSymbol));
19 }
20}
21
22namespace WixToolset.ComPlus.Symbols
23{
24 using WixToolset.Data;
25
26 public enum ComPlusUserInPartitionRoleSymbolFields
27 {
28 PartitionRoleRef,
29 ComponentRef,
30 UserRef,
31 }
32
33 public class ComPlusUserInPartitionRoleSymbol : IntermediateSymbol
34 {
35 public ComPlusUserInPartitionRoleSymbol() : base(ComPlusSymbolDefinitions.ComPlusUserInPartitionRole, null, null)
36 {
37 }
38
39 public ComPlusUserInPartitionRoleSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(ComPlusSymbolDefinitions.ComPlusUserInPartitionRole, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[ComPlusUserInPartitionRoleSymbolFields index] => this.Fields[(int)index];
44
45 public string PartitionRoleRef
46 {
47 get => this.Fields[(int)ComPlusUserInPartitionRoleSymbolFields.PartitionRoleRef].AsString();
48 set => this.Set((int)ComPlusUserInPartitionRoleSymbolFields.PartitionRoleRef, value);
49 }
50
51 public string ComponentRef
52 {
53 get => this.Fields[(int)ComPlusUserInPartitionRoleSymbolFields.ComponentRef].AsString();
54 set => this.Set((int)ComPlusUserInPartitionRoleSymbolFields.ComponentRef, value);
55 }
56
57 public string UserRef
58 {
59 get => this.Fields[(int)ComPlusUserInPartitionRoleSymbolFields.UserRef].AsString();
60 set => this.Set((int)ComPlusUserInPartitionRoleSymbolFields.UserRef, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/ComPlus/wixext/WixToolset.ComPlus.wixext.csproj b/src/ext/ComPlus/wixext/WixToolset.ComPlus.wixext.csproj
new file mode 100644
index 00000000..11271ad3
--- /dev/null
+++ b/src/ext/ComPlus/wixext/WixToolset.ComPlus.wixext.csproj
@@ -0,0 +1,32 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup>
6 <TargetFramework>netstandard2.0</TargetFramework>
7 <DebugType>embedded</DebugType>
8 <RootNamespace>WixToolset.ComPlus</RootNamespace>
9 <Description>WiX Toolset ComPlus Extension</Description>
10 <Title>WiX Toolset ComPlus Extension</Title>
11 <IsTool>true</IsTool>
12 <IncludeSymbols>true</IncludeSymbols>
13 </PropertyGroup>
14
15 <ItemGroup>
16 <EmbeddedResource Include="$(OutputPath)..\complus.wixlib" />
17 </ItemGroup>
18
19 <ItemGroup>
20 <ProjectReference Include="..\wixlib\complus.wixproj" ReferenceOutputAssembly="false" Condition=" '$(NCrunch)'=='' " />
21 </ItemGroup>
22
23 <ItemGroup>
24 <PackageReference Include="WixToolset.Data" Version="4.0.*" PrivateAssets="all" />
25 <PackageReference Include="WixToolset.Extensibility" Version="4.0.*" PrivateAssets="all" />
26 </ItemGroup>
27
28 <ItemGroup>
29 <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="all" />
30 <PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37" PrivateAssets="all" />
31 </ItemGroup>
32</Project>
diff --git a/src/ext/ComPlus/wixext/WixToolset.ComPlus.wixext.nuspec b/src/ext/ComPlus/wixext/WixToolset.ComPlus.wixext.nuspec
new file mode 100644
index 00000000..3197250b
--- /dev/null
+++ b/src/ext/ComPlus/wixext/WixToolset.ComPlus.wixext.nuspec
@@ -0,0 +1,24 @@
1<?xml version="1.0"?>
2<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
3 <metadata minClientVersion="4.0">
4 <id>$id$</id>
5 <version>$version$</version>
6 <title>$title$</title>
7 <description>$description$</description>
8 <authors>$authors$</authors>
9 <license type="expression">MS-RL</license>
10 <requireLicenseAcceptance>false</requireLicenseAcceptance>
11 <copyright>$copyright$</copyright>
12 <projectUrl>$projectUrl$</projectUrl>
13 <repository type="$repositorytype$" url="$repositoryurl$" commit="$repositorycommit$" />
14 </metadata>
15
16 <files>
17 <file src="$projectFolder$$id$.targets" target="build" />
18
19 <file src="netstandard2.0\$id$.dll" target="tools" />
20
21 <file src="x86\*.pdb" target="pdbs\x86" />
22 <file src="x64\*.pdb" target="pdbs\x64" />
23 </files>
24</package>
diff --git a/src/ext/ComPlus/wixext/WixToolset.ComPlus.wixext.targets b/src/ext/ComPlus/wixext/WixToolset.ComPlus.wixext.targets
new file mode 100644
index 00000000..8115b715
--- /dev/null
+++ b/src/ext/ComPlus/wixext/WixToolset.ComPlus.wixext.targets
@@ -0,0 +1,11 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
5 <PropertyGroup>
6 <WixToolsetComPlusWixextPath Condition=" '$(WixToolsetComPlusWixextPath)' == '' ">$(MSBuildThisFileDirectory)..\tools\WixToolset.ComPlus.wixext.dll</WixToolsetComPlusWixextPath>
7 </PropertyGroup>
8 <ItemGroup>
9 <WixExtension Include="$(WixToolsetComPlusWixextPath)" />
10 </ItemGroup>
11</Project>
diff --git a/src/ext/ComPlus/wixlib/ComPlusExtension.wxs b/src/ext/ComPlus/wixlib/ComPlusExtension.wxs
new file mode 100644
index 00000000..fe74eeae
--- /dev/null
+++ b/src/ext/ComPlus/wixlib/ComPlusExtension.wxs
@@ -0,0 +1,135 @@
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<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <?include caerr.wxi ?>
5
6 <Fragment>
7 <UI Id="ComPlusUI">
8 <Error Id="$(var.msierrComPlusCannotConnect)" Message="!(loc.msierrComPlusCannotConnect)" />
9 <Error Id="$(var.msierrComPlusPartitionReadFailed)" Message="!(loc.msierrComPlusPartitionReadFailed)" />
10 <Error Id="$(var.msierrComPlusPartitionRoleReadFailed)" Message="!(loc.msierrComPlusPartitionRoleReadFailed)" />
11 <Error Id="$(var.msierrComPlusUserInPartitionRoleReadFailed)" Message="!(loc.msierrComPlusUserInPartitionRoleReadFailed)" />
12 <Error Id="$(var.msierrComPlusPartitionUserReadFailed)" Message="!(loc.msierrComPlusPartitionUserReadFailed)" />
13 <Error Id="$(var.msierrComPlusApplicationReadFailed)" Message="!(loc.msierrComPlusApplicationReadFailed)" />
14 <Error Id="$(var.msierrComPlusApplicationRoleReadFailed)" Message="!(loc.msierrComPlusApplicationRoleReadFailed)" />
15 <Error Id="$(var.msierrComPlusUserInApplicationRoleReadFailed)" Message="!(loc.msierrComPlusUserInApplicationRoleReadFailed)" />
16 <Error Id="$(var.msierrComPlusAssembliesReadFailed)" Message="!(loc.msierrComPlusAssembliesReadFailed)" />
17 <Error Id="$(var.msierrComPlusSubscriptionReadFailed)" Message="!(loc.msierrComPlusSubscriptionReadFailed)" />
18 <Error Id="$(var.msierrComPlusPartitionDependency)" Message="!(loc.msierrComPlusPartitionDependency)" />
19 <Error Id="$(var.msierrComPlusPartitionNotFound)" Message="!(loc.msierrComPlusPartitionNotFound)" />
20 <Error Id="$(var.msierrComPlusPartitionIdConflict)" Message="!(loc.msierrComPlusPartitionIdConflict)" />
21 <Error Id="$(var.msierrComPlusPartitionNameConflict)" Message="!(loc.msierrComPlusPartitionNameConflict)" />
22 <Error Id="$(var.msierrComPlusApplicationDependency)" Message="!(loc.msierrComPlusApplicationDependency)" />
23 <Error Id="$(var.msierrComPlusApplicationNotFound)" Message="!(loc.msierrComPlusApplicationNotFound)" />
24 <Error Id="$(var.msierrComPlusApplicationIdConflict)" Message="!(loc.msierrComPlusApplicationIdConflict)" />
25 <Error Id="$(var.msierrComPlusApplicationNameConflict)" Message="!(loc.msierrComPlusApplicationNameConflict)" />
26 <Error Id="$(var.msierrComPlusApplicationRoleDependency)" Message="!(loc.msierrComPlusApplicationRoleDependency)" />
27 <Error Id="$(var.msierrComPlusApplicationRoleNotFound)" Message="!(loc.msierrComPlusApplicationRoleNotFound)" />
28 <Error Id="$(var.msierrComPlusApplicationRoleConflict)" Message="!(loc.msierrComPlusApplicationRoleConflict)" />
29 <Error Id="$(var.msierrComPlusAssemblyDependency)" Message="!(loc.msierrComPlusAssemblyDependency)" />
30 <Error Id="$(var.msierrComPlusSubscriptionIdConflict)" Message="!(loc.msierrComPlusSubscriptionIdConflict)" />
31 <Error Id="$(var.msierrComPlusSubscriptionNameConflict)" Message="!(loc.msierrComPlusSubscriptionNameConflict)" />
32 <Error Id="$(var.msierrComPlusFailedLookupNames)" Message="!(loc.msierrComPlusFailedLookupNames)" />
33
34 <ProgressText Action="ComPlusInstallExecute" Message="!(loc.ComPlusInstallExecute)" />
35 <ProgressText Action="ComPlusUninstallExecute" Message="!(loc.ComPlusUninstallExecute)" />
36
37 <ProgressText Action="CreateComPlusPartitions" Template="!(loc.CreateComPlusPartitionsTemplate)" Message="!(loc.CreateComPlusPartitions)" />
38 <ProgressText Action="RemoveComPlusPartitions" Template="!(loc.RemoveComPlusPartitionsTemplate)" Message="!(loc.RemoveComPlusPartitions)" />
39 <ProgressText Action="AddUsersToComPlusPartitionRoles" Template="!(loc.AddUsersToComPlusPartitionRolesTemplate)" Message="!(loc.AddUsersToComPlusPartitionRoles)" />
40 <ProgressText Action="RemoveUsersFromComPlusPartRoles" Template="!(loc.RemoveUsersFromComPlusPartitionRolesTemplate)" Message="!(loc.RemoveUsersFromComPlusPartitionRoles)" />
41 <ProgressText Action="AddComPlusPartitionUsers" Template="!(loc.AddComPlusPartitionUsersTemplate)" Message="!(loc.AddComPlusPartitionUsers)" />
42 <ProgressText Action="RemoveComPlusPartitionUsers" Template="!(loc.RemoveComPlusPartitionUsersTemplate)" Message="!(loc.RemoveComPlusPartitionUsers)" />
43 <ProgressText Action="CreateComPlusApplications" Template="!(loc.CreateComPlusApplicationsTemplate)" Message="!(loc.CreateComPlusApplications)" />
44 <ProgressText Action="RemoveComPlusApplications" Template="!(loc.RemoveComPlusApplicationsTemplate)" Message="!(loc.RemoveComPlusApplications)" />
45 <ProgressText Action="CreateComPlusApplicationRoles" Template="!(loc.CreateComPlusApplicationRolesTemplate)" Message="!(loc.CreateComPlusApplicationRoles)" />
46 <ProgressText Action="RemoveComPlusApplicationRoles" Template="!(loc.RemoveComPlusApplicationRolesTemplate)" Message="!(loc.RemoveComPlusApplicationRoles)" />
47 <ProgressText Action="AddUsersToComPlusApplicationRoles" Template="!(loc.AddUsersToComPlusApplicationRolesTemplate)" Message="!(loc.AddUsersToComPlusApplicationRoles)" />
48 <ProgressText Action="RemoveUsersFromComPlusAppRoles" Template="!(loc.RemoveUsersFromComPlusApplicationRolesTemplate)" Message="!(loc.RemoveUsersFromComPlusApplicationRoles)" />
49 <ProgressText Action="RegisterComPlusAssemblies" Template="!(loc.RegisterComPlusAssembliesTemplate)" Message="!(loc.RegisterComPlusAssemblies)" />
50 <ProgressText Action="UnregisterComPlusAssemblies" Template="!(loc.UnregisterComPlusAssembliesTemplate)" Message="!(loc.UnregisterComPlusAssemblies)" />
51 <ProgressText Action="AddComPlusRoleAssignments" Template="!(loc.AddComPlusRoleAssignmentsTemplate)" Message="!(loc.AddComPlusRoleAssignments)" />
52 <ProgressText Action="RemoveComPlusRoleAssignments" Template="!(loc.RemoveComPlusRoleAssignmentsTemplate)" Message="!(loc.RemoveComPlusRoleAssignments)" />
53 <ProgressText Action="CreateSubscrComPlusComponents" Template="!(loc.CreateSubscriptionsComPlusComponentsTemplate)" Message="!(loc.CreateSubscriptionsComPlusComponents)" />
54 <ProgressText Action="RemoveSubscrComPlusComponents" Template="!(loc.RemoveSubscriptionsComPlusComponentsTemplate)" Message="!(loc.RemoveSubscriptionsComPlusComponents)" />
55 </UI>
56 </Fragment>
57
58 <Fragment>
59 <UIRef Id="ComPlusUI" />
60
61 <CustomAction Id="ConfigureComPlusInstall" DllEntry="ConfigureComPlusInstall" Execute="immediate" Return="check" SuppressModularization="yes" BinaryRef="ComPlusCA_x86" />
62 <CustomAction Id="ConfigureComPlusUninstall" DllEntry="ConfigureComPlusUninstall" Execute="immediate" Return="check" SuppressModularization="yes" BinaryRef="ComPlusCA_x86" />
63 <CustomAction Id="ComPlusInstallPrepare" DllEntry="ComPlusPrepare" Execute="deferred" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x86" />
64 <CustomAction Id="ComPlusRollbackInstallPrepare" DllEntry="ComPlusCleanup" Execute="rollback" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x86" />
65 <CustomAction Id="ComPlusInstallExecute" DllEntry="ComPlusInstallExecute" Execute="deferred" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x86" />
66 <CustomAction Id="ComPlusInstallExecuteCommit" DllEntry="ComPlusInstallExecuteCommit" Execute="commit" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x86" />
67 <CustomAction Id="ComPlusRollbackInstallExecute" DllEntry="ComPlusRollbackInstallExecute" Execute="rollback" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x86" />
68 <CustomAction Id="ComPlusInstallCommit" DllEntry="ComPlusCleanup" Execute="commit" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x86" />
69 <CustomAction Id="ComPlusUninstallPrepare" DllEntry="ComPlusPrepare" Execute="deferred" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x86" />
70 <CustomAction Id="ComPlusRollbackUninstallPrepare" DllEntry="ComPlusCleanup" Execute="rollback" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x86" />
71 <CustomAction Id="ComPlusUninstallExecute" DllEntry="ComPlusUninstallExecute" Execute="deferred" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x86" />
72 <CustomAction Id="ComPlusRollbackUninstallExecute" DllEntry="ComPlusInstallExecute" Execute="rollback" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x86" />
73 <CustomAction Id="ComPlusUninstallCommit" DllEntry="ComPlusCleanup" Execute="commit" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x86" />
74
75 <Property Id="ComPlusInstallPrepare" Hidden="yes" SuppressModularization="yes" />
76 <Property Id="ComPlusRollbackInstallPrepare" Hidden="yes" SuppressModularization="yes" />
77 <Property Id="ComPlusInstallExecute" Hidden="yes" SuppressModularization="yes" />
78 <Property Id="ComPlusInstallExecuteCommit" Hidden="yes" SuppressModularization="yes" />
79 <Property Id="ComPlusRollbackInstallExecute" Hidden="yes" SuppressModularization="yes" />
80 <Property Id="ComPlusInstallCommit" Hidden="yes" SuppressModularization="yes" />
81 <Property Id="ComPlusUninstallPrepare" Hidden="yes" SuppressModularization="yes" />
82 <Property Id="ComPlusRollbackUninstallPrepare" Hidden="yes" SuppressModularization="yes" />
83 <Property Id="ComPlusUninstallExecute" Hidden="yes" SuppressModularization="yes" />
84 <Property Id="ComPlusRollbackUninstallExecute" Hidden="yes" SuppressModularization="yes" />
85 <Property Id="ComPlusUninstallCommit" Hidden="yes" SuppressModularization="yes" />
86
87 <InstallExecuteSequence>
88 <Custom Action="ConfigureComPlusUninstall" After="DeleteServices" Overridable="yes" Condition="VersionNT &gt;= 500" />
89 <Custom Action="ConfigureComPlusInstall" Before="InstallServices" Overridable="yes" Condition="VersionNT &gt;= 500" />
90 </InstallExecuteSequence>
91 </Fragment>
92
93 <Fragment>
94 <UIRef Id="ComPlusUI" />
95
96 <CustomAction Id="ConfigureComPlusInstall_x64" DllEntry="ConfigureComPlusInstall" Execute="immediate" Return="check" SuppressModularization="yes" BinaryRef="ComPlusCA_x64" />
97 <CustomAction Id="ConfigureComPlusUninstall_x64" DllEntry="ConfigureComPlusUninstall" Execute="immediate" Return="check" SuppressModularization="yes" BinaryRef="ComPlusCA_x64" />
98 <CustomAction Id="ComPlusInstallPrepare_64" DllEntry="ComPlusPrepare" Execute="deferred" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x64" />
99 <CustomAction Id="ComPlusRollbackInstallPrepare_64" DllEntry="ComPlusCleanup" Execute="rollback" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x64" />
100 <CustomAction Id="ComPlusInstallExecute_64" DllEntry="ComPlusInstallExecute" Execute="deferred" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x64" />
101 <CustomAction Id="ComPlusInstallExecuteCommit_64" DllEntry="ComPlusInstallExecuteCommit" Execute="commit" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x64" />
102 <CustomAction Id="ComPlusRollbackInstallExecute_64" DllEntry="ComPlusRollbackInstallExecute" Execute="rollback" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x64" />
103 <CustomAction Id="ComPlusInstallCommit_64" DllEntry="ComPlusCleanup" Execute="commit" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x64" />
104 <CustomAction Id="ComPlusUninstallPrepare_64" DllEntry="ComPlusPrepare" Execute="deferred" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x64" />
105 <CustomAction Id="ComPlusRollbackUninstallPrepare_64" DllEntry="ComPlusCleanup" Execute="rollback" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x64" />
106 <CustomAction Id="ComPlusUninstallExecute_64" DllEntry="ComPlusUninstallExecute" Execute="deferred" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x64" />
107 <CustomAction Id="ComPlusRollbackUninstallExecute_64" DllEntry="ComPlusInstallExecute" Execute="rollback" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x64" />
108 <CustomAction Id="ComPlusUninstallCommit_64" DllEntry="ComPlusCleanup" Execute="commit" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" BinaryRef="ComPlusCA_x64" />
109
110 <Property Id="ComPlusInstallPrepare_64" Hidden="yes" SuppressModularization="yes" />
111 <Property Id="ComPlusRollbackInstallPrepare_64" Hidden="yes" SuppressModularization="yes" />
112 <Property Id="ComPlusInstallExecute_64" Hidden="yes" SuppressModularization="yes" />
113 <Property Id="ComPlusInstallExecuteCommit_64" Hidden="yes" SuppressModularization="yes" />
114 <Property Id="ComPlusRollbackInstallExecute_64" Hidden="yes" SuppressModularization="yes" />
115 <Property Id="ComPlusInstallCommit_64" Hidden="yes" SuppressModularization="yes" />
116 <Property Id="ComPlusUninstallPrepare_64" Hidden="yes" SuppressModularization="yes" />
117 <Property Id="ComPlusRollbackUninstallPrepare_64" Hidden="yes" SuppressModularization="yes" />
118 <Property Id="ComPlusUninstallExecute_64" Hidden="yes" SuppressModularization="yes" />
119 <Property Id="ComPlusRollbackUninstallExecute_64" Hidden="yes" SuppressModularization="yes" />
120 <Property Id="ComPlusUninstallCommit_64" Hidden="yes" SuppressModularization="yes" />
121
122 <InstallExecuteSequence>
123 <Custom Action="ConfigureComPlusUninstall_x64" After="DeleteServices" Overridable="yes" Condition="VersionNT &gt;= 500" />
124 <Custom Action="ConfigureComPlusInstall_x64" Before="InstallServices" Overridable="yes" Condition="VersionNT &gt;= 500" />
125 </InstallExecuteSequence>
126 </Fragment>
127
128 <Fragment>
129 <Binary Id="ComPlusCA_x86" SourceFile="!(bindpath.x86)complusca.dll" />
130 </Fragment>
131
132 <Fragment>
133 <Binary Id="ComPlusCA_x64" SourceFile="!(bindpath.x64)complusca.dll" />
134 </Fragment>
135</Wix>
diff --git a/src/ext/ComPlus/wixlib/caerr.wxi b/src/ext/ComPlus/wixlib/caerr.wxi
new file mode 100644
index 00000000..ff7ec121
--- /dev/null
+++ b/src/ext/ComPlus/wixlib/caerr.wxi
@@ -0,0 +1,96 @@
1<Include xmlns="http://wixtoolset.org/schemas/v4/wxs">
2 <?define msierrSecureObjectsFailedCreateSD = 25520?>
3 <?define msierrSecureObjectsFailedSet = 25521?>
4 <?define msierrSecureObjectsUnknownType = 25522?>
5 <?define msierrXmlFileFailedRead = 25530?>
6 <?define msierrXmlFileFailedOpen = 25531?>
7 <?define msierrXmlFileFailedSelect = 25532?>
8 <?define msierrXmlFileFailedSave = 25533?>
9 <?define msierrXmlConfigFailedRead = 25540?>
10 <?define msierrXmlConfigFailedOpen = 25541?>
11 <?define msierrXmlConfigFailedSelect = 25542?>
12 <?define msierrXmlConfigFailedSave = 25543?>
13 <?define msierrFirewallCannotConnect = 25580?>
14 <?define msierrIISCannotConnect = 26001?>
15 <?define msierrIISFailedReadWebSite = 26002?>
16 <?define msierrIISFailedReadWebDirs = 26003?>
17 <?define msierrIISFailedReadVDirs = 26004?>
18 <?define msierrIISFailedReadFilters = 26005?>
19 <?define msierrIISFailedReadAppPool = 26006?>
20 <?define msierrIISFailedReadMimeMap = 26007?>
21 <?define msierrIISFailedReadProp = 26008?>
22 <?define msierrIISFailedReadWebSvcExt = 26009?>
23 <?define msierrIISFailedReadWebError = 26010?>
24 <?define msierrIISFailedReadHttpHeader = 26011?>
25 <?define msierrIISFailedSchedTransaction = 26031?>
26 <?define msierrIISFailedSchedInstallWebs = 26032?>
27 <?define msierrIISFailedSchedInstallWebDirs = 26033?>
28 <?define msierrIISFailedSchedInstallVDirs = 26034?>
29 <?define msierrIISFailedSchedInstallFilters = 26035?>
30 <?define msierrIISFailedSchedInstallAppPool = 26036?>
31 <?define msierrIISFailedSchedInstallProp = 26037?>
32 <?define msierrIISFailedSchedInstallWebSvcExt = 26038?>
33 <?define msierrIISFailedSchedUninstallWebs = 26051?>
34 <?define msierrIISFailedSchedUninstallWebDirs = 26052?>
35 <?define msierrIISFailedSchedUninstallVDirs = 26053?>
36 <?define msierrIISFailedSchedUninstallFilters = 26054?>
37 <?define msierrIISFailedSchedUninstallAppPool = 26055?>
38 <?define msierrIISFailedSchedUninstallProp = 26056?>
39 <?define msierrIISFailedSchedUninstallWebSvcExt = 26057?>
40 <?define msierrIISFailedStartTransaction = 26101?>
41 <?define msierrIISFailedOpenKey = 26102?>
42 <?define msierrIISFailedCreateKey = 26103?>
43 <?define msierrIISFailedWriteData = 26104?>
44 <?define msierrIISFailedCreateApp = 26105?>
45 <?define msierrIISFailedDeleteKey = 26106?>
46 <?define msierrIISFailedDeleteApp = 26107?>
47 <?define msierrIISFailedDeleteValue = 26108?>
48 <?define msierrIISFailedCommitInUse = 26109?>
49 <?define msierrSQLFailedCreateDatabase = 26201?>
50 <?define msierrSQLFailedDropDatabase = 26202?>
51 <?define msierrSQLFailedConnectDatabase = 26203?>
52 <?define msierrSQLFailedExecString = 26204?>
53 <?define msierrSQLDatabaseAlreadyExists = 26205?>
54 <?define msierrPERFMONFailedRegisterDLL = 26251?>
55 <?define msierrPERFMONFailedUnregisterDLL = 26252?>
56 <?define msierrInstallPerfCounterData = 26253?>
57 <?define msierrUninstallPerfCounterData = 26254?>
58 <?define msierrSMBFailedCreate = 26301?>
59 <?define msierrSMBFailedDrop = 26302?>
60 <?define msierrCERTFailedOpen = 26351?>
61 <?define msierrCERTFailedAdd = 26352?>
62 <?define msierrUSRFailedUserCreate = 26401?>
63 <?define msierrUSRFailedUserCreatePswd = 26402?>
64 <?define msierrUSRFailedUserGroupAdd = 26403?>
65 <?define msierrUSRFailedUserCreateExists = 26404?>
66 <?define msierrUSRFailedGrantLogonAsService = 26405?>
67 <?define msierrDependencyMissingDependencies = 26451?>
68 <?define msierrDependencyHasDependents = 26452?>
69 <?define msierrDotNetRuntimeRequired = 27000?>
70 <?define msierrComPlusCannotConnect = 28001?>
71 <?define msierrComPlusPartitionReadFailed = 28002?>
72 <?define msierrComPlusPartitionRoleReadFailed = 28003?>
73 <?define msierrComPlusUserInPartitionRoleReadFailed = 28004?>
74 <?define msierrComPlusPartitionUserReadFailed = 28005?>
75 <?define msierrComPlusApplicationReadFailed = 28006?>
76 <?define msierrComPlusApplicationRoleReadFailed = 28007?>
77 <?define msierrComPlusUserInApplicationRoleReadFailed = 28008?>
78 <?define msierrComPlusAssembliesReadFailed = 28009?>
79 <?define msierrComPlusSubscriptionReadFailed = 28010?>
80 <?define msierrComPlusPartitionDependency = 28011?>
81 <?define msierrComPlusPartitionNotFound = 28012?>
82 <?define msierrComPlusPartitionIdConflict = 28013?>
83 <?define msierrComPlusPartitionNameConflict = 28014?>
84 <?define msierrComPlusApplicationDependency = 28015?>
85 <?define msierrComPlusApplicationNotFound = 28016?>
86 <?define msierrComPlusApplicationIdConflict = 28017?>
87 <?define msierrComPlusApplicationNameConflict = 28018?>
88 <?define msierrComPlusApplicationRoleDependency = 28019?>
89 <?define msierrComPlusApplicationRoleNotFound = 28020?>
90 <?define msierrComPlusApplicationRoleConflict = 28021?>
91 <?define msierrComPlusAssemblyDependency = 28022?>
92 <?define msierrComPlusSubscriptionIdConflict = 28023?>
93 <?define msierrComPlusSubscriptionNameConflict = 28024?>
94 <?define msierrComPlusFailedLookupNames = 28025?>
95 <?define msierrMsmqCannotConnect = 28101?>
96</Include> \ No newline at end of file
diff --git a/src/ext/ComPlus/wixlib/complus.wixproj b/src/ext/ComPlus/wixlib/complus.wixproj
new file mode 100644
index 00000000..ef792a13
--- /dev/null
+++ b/src/ext/ComPlus/wixlib/complus.wixproj
@@ -0,0 +1,26 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project Sdk="WixToolset.Sdk">
5
6 <PropertyGroup>
7 <OutputType>Library</OutputType>
8 <BindFiles>true</BindFiles>
9 <SuppressSpecificWarnings>1086</SuppressSpecificWarnings>
10 </PropertyGroup>
11
12 <ItemGroup>
13 <BindInputPaths Include="$(OutputPath)x86" BindName='x86' />
14 <BindInputPaths Include="$(OutputPath)x64" BindName='x64' />
15 </ItemGroup>
16
17 <ItemGroup>
18 <ProjectReference Include="..\ca\complusca.vcxproj" Properties="Platform=x86" ReferenceOutputAssembly="false" />
19 <ProjectReference Include="..\ca\complusca.vcxproj" Properties="Platform=x64" ReferenceOutputAssembly="false" />
20 </ItemGroup>
21
22 <ItemGroup>
23 <PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37" PrivateAssets="All" />
24 </ItemGroup>
25
26</Project>
diff --git a/src/ext/ComPlus/wixlib/en-us.wxl b/src/ext/ComPlus/wixlib/en-us.wxl
new file mode 100644
index 00000000..8f6f38fc
--- /dev/null
+++ b/src/ext/ComPlus/wixlib/en-us.wxl
@@ -0,0 +1,71 @@
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="msierrComPlusCannotConnect" Overridable="yes">Cannot connect to the COM+ admin catalog. ([2] [3] [4] [5])</String>
7 <String Id="msierrComPlusPartitionReadFailed" Overridable="yes">Failed to read COM+ partitions. ([2] [3] [4] [5])</String>
8 <String Id="msierrComPlusPartitionRoleReadFailed" Overridable="yes">Failed to read COM+ partition roles. ([2] [3] [4] [5])</String>
9 <String Id="msierrComPlusUserInPartitionRoleReadFailed" Overridable="yes">Failed to read COM+ users in partition roles. ([2] [3] [4] [5])</String>
10 <String Id="msierrComPlusPartitionUserReadFailed" Overridable="yes">Failed to read COM+ partition users. ([2] [3] [4] [5])</String>
11 <String Id="msierrComPlusApplicationReadFailed" Overridable="yes">Failed to read COM+ applications. ([2] [3] [4] [5])</String>
12 <String Id="msierrComPlusApplicationRoleReadFailed" Overridable="yes">Failed to read COM+ application roles. ([2] [3] [4] [5])</String>
13 <String Id="msierrComPlusUserInApplicationRoleReadFailed" Overridable="yes">Failed to read COM+ users in application roles. ([2] [3] [4] [5])</String>
14 <String Id="msierrComPlusAssembliesReadFailed" Overridable="yes">Failed to read COM+ assemblies. ([2] [3] [4] [5])</String>
15 <String Id="msierrComPlusSubscriptionReadFailed" Overridable="yes">Failed to read COM+ event subscriptions. ([2] [3] [4] [5])</String>
16 <String Id="msierrComPlusPartitionDependency" Overridable="yes">Another entity is dependent on a COM+ partition that is not being installed. ([2] [3] [4] [5])</String>
17 <String Id="msierrComPlusPartitionNotFound" Overridable="yes">The COM+ partition was not found. ([2] [3] [4] [5])</String>
18 <String Id="msierrComPlusPartitionIdConflict" Overridable="yes">A COM+ partition with the same id already exists. ([2] [3] [4] [5])</String>
19 <String Id="msierrComPlusPartitionNameConflict" Overridable="yes">A COM+ partition with the same name already exists. ([2] [3] [4] [5])</String>
20 <String Id="msierrComPlusApplicationDependency" Overridable="yes">Another entity is dependent on a COM+ application that is not being installed. ([2] [3] [4] [5])</String>
21 <String Id="msierrComPlusApplicationNotFound" Overridable="yes">The COM+ application was not found. ([2] [3] [4] [5])</String>
22 <String Id="msierrComPlusApplicationIdConflict" Overridable="yes">A COM+ application with the same id already exists. ([2] [3] [4] [5])</String>
23 <String Id="msierrComPlusApplicationNameConflict" Overridable="yes">A COM+ application with the same name already exists. ([2] [3] [4] [5])</String>
24 <String Id="msierrComPlusApplicationRoleDependency" Overridable="yes">Another entity is dependent on a COM+ application role that is not being installed. ([2] [3] [4] [5])</String>
25 <String Id="msierrComPlusApplicationRoleNotFound" Overridable="yes">The COM+ application role was not found. ([2] [3] [4] [5])</String>
26 <String Id="msierrComPlusApplicationRoleConflict" Overridable="yes">A COM+ application role with the same name already exists. ([2] [3] [4] [5])</String>
27 <String Id="msierrComPlusAssemblyDependency" Overridable="yes">Another entity is dependent on a COM+ assembly that is not being installed. ([2] [3] [4] [5])</String>
28 <String Id="msierrComPlusSubscriptionIdConflict" Overridable="yes">A COM+ component event subscription with the same id already exists. ([2] [3] [4] [5])</String>
29 <String Id="msierrComPlusSubscriptionNameConflict" Overridable="yes">A COM+ component event subscription with the same name already exists. ([2] [3] [4] [5])</String>
30 <String Id="msierrComPlusFailedLookupNames" Overridable="yes">Failed to lookup user account names. ([2] [3] [4] [5])</String>
31
32 <String Id="ComPlusInstallExecute" Overridable="yes">Registering COM+ components</String>
33 <String Id="ComPlusUninstallExecute" Overridable="yes">Unregistering COM+ components</String>
34
35 <String Id="CreateComPlusPartitions" Overridable="yes">Creating COM+ partitions</String>
36 <String Id="CreateComPlusPartitionsTemplate" Overridable="yes">Partition: [1]</String>
37 <String Id="RemoveComPlusPartitions" Overridable="yes">Removing COM+ partitions</String>
38 <String Id="RemoveComPlusPartitionsTemplate" Overridable="yes">Partition: [1]</String>
39 <String Id="AddUsersToComPlusPartitionRoles" Overridable="yes">Adding users to COM+ partition roles</String>
40 <String Id="AddUsersToComPlusPartitionRolesTemplate" Overridable="yes">Role: [1]</String>
41 <String Id="RemoveUsersFromComPlusPartitionRoles" Overridable="yes">Removing users from COM+ partition roles</String>
42 <String Id="RemoveUsersFromComPlusPartitionRolesTemplate" Overridable="yes">Role: [1]</String>
43 <String Id="AddComPlusPartitionUsers" Overridable="yes">Setting default COM+ partitions for users</String>
44 <String Id="AddComPlusPartitionUsersTemplate" Overridable="yes">User: [1]</String>
45 <String Id="RemoveComPlusPartitionUsers" Overridable="yes">Removing default COM+ partitions for users</String>
46 <String Id="RemoveComPlusPartitionUsersTemplate" Overridable="yes">User: [1]</String>
47 <String Id="CreateComPlusApplications" Overridable="yes">Creating COM+ applications</String>
48 <String Id="CreateComPlusApplicationsTemplate" Overridable="yes">Application: [1]</String>
49 <String Id="RemoveComPlusApplications" Overridable="yes">Removing COM+ applications</String>
50 <String Id="RemoveComPlusApplicationsTemplate" Overridable="yes">Application: [1]</String>
51 <String Id="CreateComPlusApplicationRoles" Overridable="yes">Creating COM+ application roles</String>
52 <String Id="CreateComPlusApplicationRolesTemplate" Overridable="yes">Role: [1]</String>
53 <String Id="RemoveComPlusApplicationRoles" Overridable="yes">Removing COM+ application roles</String>
54 <String Id="RemoveComPlusApplicationRolesTemplate" Overridable="yes">Role: [1]</String>
55 <String Id="AddUsersToComPlusApplicationRoles" Overridable="yes">Adding users to COM+ application roles</String>
56 <String Id="AddUsersToComPlusApplicationRolesTemplate" Overridable="yes">User: [1]</String>
57 <String Id="RemoveUsersFromComPlusApplicationRoles" Overridable="yes">Removing users from COM+ application roles</String>
58 <String Id="RemoveUsersFromComPlusApplicationRolesTemplate" Overridable="yes">User: [1]</String>
59 <String Id="RegisterComPlusAssemblies" Overridable="yes">Registering COM+ components</String>
60 <String Id="RegisterComPlusAssembliesTemplate" Overridable="yes">DLL: [1]</String>
61 <String Id="UnregisterComPlusAssemblies" Overridable="yes">Unregistering COM+ components</String>
62 <String Id="UnregisterComPlusAssembliesTemplate" Overridable="yes">DLL: [1]</String>
63 <String Id="AddComPlusRoleAssignments" Overridable="yes">Assigning roles to COM+ components</String>
64 <String Id="AddComPlusRoleAssignmentsTemplate" Overridable="yes">Component: [1]</String>
65 <String Id="RemoveComPlusRoleAssignments" Overridable="yes">Removing role assignments from COM+ components</String>
66 <String Id="RemoveComPlusRoleAssignmentsTemplate" Overridable="yes">Component: [1]</String>
67 <String Id="CreateSubscriptionsComPlusComponents" Overridable="yes">Creating subscriptions for COM+ components</String>
68 <String Id="CreateSubscriptionsComPlusComponentsTemplate" Overridable="yes">Subscription: [1]</String>
69 <String Id="RemoveSubscriptionsComPlusComponents" Overridable="yes">Removing subscriptions for COM+ components</String>
70 <String Id="RemoveSubscriptionsComPlusComponentsTemplate" Overridable="yes">Subscription: [1]</String>
71</WixLocalization>
diff --git a/src/ext/ComPlus/wixlib/es-es.wxl b/src/ext/ComPlus/wixlib/es-es.wxl
new file mode 100644
index 00000000..5e7eba66
--- /dev/null
+++ b/src/ext/ComPlus/wixlib/es-es.wxl
@@ -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
5<WixLocalization Culture="es-es" xmlns="http://wixtoolset.org/schemas/v4/wxl">
6 <String Id="msierrComPlusCannotConnect" Overridable="yes">No se puede conectar al catálogo de administración de COM+. ([2] [3] [4] [5])</String>
7 <String Id="msierrComPlusPartitionReadFailed" Overridable="yes">Falla al leer las particiones COM+. ([2] [3] [4] [5])</String>
8 <String Id="msierrComPlusPartitionRoleReadFailed" Overridable="yes">Falla al leer los roles de las particiones COM+. ([2] [3] [4] [5])</String>
9 <String Id="msierrComPlusUserInPartitionRoleReadFailed" Overridable="yes">Falla al leer los usuario en los roles de las particiones COM+. ([2] [3] [4] [5])</String>
10 <String Id="msierrComPlusPartitionUserReadFailed" Overridable="yes">Falla al leer los usuario de las particiones COM+. ([2] [3] [4] [5])</String>
11 <String Id="msierrComPlusApplicationReadFailed" Overridable="yes">Falla al leer las aplicaciones COM+. ([2] [3] [4] [5])</String>
12 <String Id="msierrComPlusApplicationRoleReadFailed" Overridable="yes">Falla al leer los roles de las aplicaciones COM+. ([2] [3] [4] [5])</String>
13 <String Id="msierrComPlusUserInApplicationRoleReadFailed" Overridable="yes">Falla al leer los usuario de las aplicaciones COM+. ([2] [3] [4] [5])</String>
14 <String Id="msierrComPlusAssembliesReadFailed" Overridable="yes">Falla al leer los ensamblados COM+. ([2] [3] [4] [5])</String>
15 <String Id="msierrComPlusSubscriptionReadFailed" Overridable="yes">Falla al leer las suscripciones a eventos COM+. ([2] [3] [4] [5])</String>
16 <String Id="msierrComPlusPartitionDependency" Overridable="yes">Otra entidad es dependiente de una partición COM+ que no está siendo instalada. ([2] [3] [4] [5])</String>
17 <String Id="msierrComPlusPartitionNotFound" Overridable="yes">La partición COM+ no pudo ser encontrada. ([2] [3] [4] [5])</String>
18 <String Id="msierrComPlusPartitionIdConflict" Overridable="yes">Ya existe otra partición COM+ con el mismo id. ([2] [3] [4] [5])</String>
19 <String Id="msierrComPlusPartitionNameConflict" Overridable="yes">Ya existe otra partición COM+ con el mismo nombre. ([2] [3] [4] [5])</String>
20 <String Id="msierrComPlusApplicationDependency" Overridable="yes">Otra entidad es dependiente de una aplicación COM+ que no está siendo instalada. ([2] [3] [4] [5])</String>
21 <String Id="msierrComPlusApplicationNotFound" Overridable="yes">La aplicación COM+ no pudo ser encontrada. ([2] [3] [4] [5])</String>
22 <String Id="msierrComPlusApplicationIdConflict" Overridable="yes">Ya existe otra aplicación COM+ con el mismo id. ([2] [3] [4] [5])</String>
23 <String Id="msierrComPlusApplicationNameConflict" Overridable="yes">Ya existe otra aplicación COM+ con el mismo nombre. ([2] [3] [4] [5])</String>
24 <String Id="msierrComPlusApplicationRoleDependency" Overridable="yes">Otra entidad es dependiente de un rol de aplicación COM+ que no está siendo instalado. ([2] [3] [4] [5])</String>
25 <String Id="msierrComPlusApplicationRoleNotFound" Overridable="yes">El rol de aplicación COM+ no pudo ser encontrado. ([2] [3] [4] [5])</String>
26 <String Id="msierrComPlusApplicationRoleConflict" Overridable="yes">Ya existe otro rol de aplicación COM+ con el mismo nombre. ([2] [3] [4] [5])</String>
27 <String Id="msierrComPlusAssemblyDependency" Overridable="yes">Otra entidad es dependiente de un ensamblado COM+ que no está siendo instalado. ([2] [3] [4] [5])</String>
28 <String Id="msierrComPlusSubscriptionIdConflict" Overridable="yes">Ya existe otra suscripción de evento al componente COM+ con el mismo id. ([2] [3] [4] [5])</String>
29 <String Id="msierrComPlusSubscriptionNameConflict" Overridable="yes">Ya existe otra suscripción de evento al componente COM+ con el mismo nombre. ([2] [3] [4] [5])</String>
30 <String Id="msierrComPlusFailedLookupNames" Overridable="yes">Falla el la búsqueda de los nombres de usuario. ([2] [3] [4] [5])</String>
31
32 <String Id="ComPlusInstallExecute" Overridable="yes">Registrando componentes COM+</String>
33 <String Id="ComPlusUninstallExecute" Overridable="yes">Anular el registro de componentes COM+</String>
34
35 <String Id="CreateComPlusPartitions" Overridable="yes">Creando particiones COM+</String>
36 <String Id="CreateComPlusPartitionsTemplate" Overridable="yes">Particiones: [1]</String>
37 <String Id="RemoveComPlusPartitions" Overridable="yes">Borrando particiones COM+</String>
38 <String Id="RemoveComPlusPartitionsTemplate" Overridable="yes">Particiones: [1]</String>
39 <String Id="AddUsersToComPlusPartitionRoles" Overridable="yes">Agregando usuarios a los roles de las particiones COM+</String>
40 <String Id="AddUsersToComPlusPartitionRolesTemplate" Overridable="yes">Rol: [1]</String>
41 <String Id="RemoveUsersFromComPlusPartitionRoles" Overridable="yes">Borrando usuarios a los roles de las particiones COM+</String>
42 <String Id="RemoveUsersFromComPlusPartitionRolesTemplate" Overridable="yes">Rol: [1]</String>
43 <String Id="AddComPlusPartitionUsers" Overridable="yes">Ajustando partición COM+ por omisión para los usuarios</String>
44 <String Id="AddComPlusPartitionUsersTemplate" Overridable="yes">Usuario: [1]</String>
45 <String Id="RemoveComPlusPartitionUsers" Overridable="yes">Borrando partición COM+ por omisión para los usuarios</String>
46 <String Id="RemoveComPlusPartitionUsersTemplate" Overridable="yes">Usuario: [1]</String>
47 <String Id="CreateComPlusApplications" Overridable="yes">Creando aplicación COM+</String>
48 <String Id="CreateComPlusApplicationsTemplate" Overridable="yes">Aplicación: [1]</String>
49 <String Id="RemoveComPlusApplications" Overridable="yes">Borrando aplicación COM+</String>
50 <String Id="RemoveComPlusApplicationsTemplate" Overridable="yes">Aplicación: [1]</String>
51 <String Id="CreateComPlusApplicationRoles" Overridable="yes">Creando roles de aplicación COM+</String>
52 <String Id="CreateComPlusApplicationRolesTemplate" Overridable="yes">Rol: [1]</String>
53 <String Id="RemoveComPlusApplicationRoles" Overridable="yes">Borrando roles de aplicación COM+</String>
54 <String Id="RemoveComPlusApplicationRolesTemplate" Overridable="yes">Rol: [1]</String>
55 <String Id="AddUsersToComPlusApplicationRoles" Overridable="yes">Agregando usuarios a los roles de aplicación COM+</String>
56 <String Id="AddUsersToComPlusApplicationRolesTemplate" Overridable="yes">Usuario: [1]</String>
57 <String Id="RemoveUsersFromComPlusApplicationRoles" Overridable="yes">Borrando usuarios a los roles de aplicación COM</String>
58 <String Id="RemoveUsersFromComPlusApplicationRolesTemplate" Overridable="yes">Usuario: [1]</String>
59 <String Id="RegisterComPlusAssemblies" Overridable="yes">Registrando componente COM+</String>
60 <String Id="RegisterComPlusAssembliesTemplate" Overridable="yes">DLL: [1]</String>
61 <String Id="UnregisterComPlusAssemblies" Overridable="yes">Anulando el registro de componentes COM+</String>
62 <String Id="UnregisterComPlusAssembliesTemplate" Overridable="yes">DLL: [1]</String>
63 <String Id="AddComPlusRoleAssignments" Overridable="yes">Asignando roles a los componentes COM+</String>
64 <String Id="AddComPlusRoleAssignmentsTemplate" Overridable="yes">Componente: [1]</String>
65 <String Id="RemoveComPlusRoleAssignments" Overridable="yes">Borrando asignación de roles a los componentes COM+</String>
66 <String Id="RemoveComPlusRoleAssignmentsTemplate" Overridable="yes">Componente: [1]</String>
67 <String Id="CreateSubscriptionsComPlusComponents" Overridable="yes">Creando suscripción a componentes COM+</String>
68 <String Id="CreateSubscriptionsComPlusComponentsTemplate" Overridable="yes">Suscripción: [1]</String>
69 <String Id="RemoveSubscriptionsComPlusComponents" Overridable="yes">Borrando suscripción a componentes COM+</String>
70 <String Id="RemoveSubscriptionsComPlusComponentsTemplate" Overridable="yes">Suscripción: [1]</String>
71</WixLocalization>
72
diff --git a/src/ext/ComPlus/wixlib/ja-jp.wxl b/src/ext/ComPlus/wixlib/ja-jp.wxl
new file mode 100644
index 00000000..03b2cf1c
--- /dev/null
+++ b/src/ext/ComPlus/wixlib/ja-jp.wxl
@@ -0,0 +1,71 @@
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="msierrComPlusCannotConnect" Overridable="yes">COM+ 管理カタログへ接続できません。 ([2] [3] [4] [5])</String>
7 <String Id="msierrComPlusPartitionReadFailed" Overridable="yes">COM+ パーティションの読み込みに失敗しました。 ([2] [3] [4] [5])</String>
8 <String Id="msierrComPlusPartitionRoleReadFailed" Overridable="yes">COM+ パーティション役割の読み込みに失敗しました。 ([2] [3] [4] [5])</String>
9 <String Id="msierrComPlusUserInPartitionRoleReadFailed" Overridable="yes">COM+ パーティション役割内ユーザーの読み込みに失敗しました。 ([2] [3] [4] [5])</String>
10 <String Id="msierrComPlusPartitionUserReadFailed" Overridable="yes">COM+ パーティション ユーザーの読み込みに失敗しました。 ([2] [3] [4] [5])</String>
11 <String Id="msierrComPlusApplicationReadFailed" Overridable="yes">COM+ アプリケーションの読み込みに失敗しました。 ([2] [3] [4] [5])</String>
12 <String Id="msierrComPlusApplicationRoleReadFailed" Overridable="yes">COM+ アプリケーション役割の読み込みに失敗しました。 ([2] [3] [4] [5])</String>
13 <String Id="msierrComPlusUserInApplicationRoleReadFailed" Overridable="yes">COM+ アプリケーション役割内ユーザーの読み込みに失敗しました。 ([2] [3] [4] [5])</String>
14 <String Id="msierrComPlusAssembliesReadFailed" Overridable="yes">COM+ アセンブリの読み込みに失敗しました。 ([2] [3] [4] [5])</String>
15 <String Id="msierrComPlusSubscriptionReadFailed" Overridable="yes">COM+ イベント登録の読み込みに失敗しました。 ([2] [3] [4] [5])</String>
16 <String Id="msierrComPlusPartitionDependency" Overridable="yes">他のエンティティはインストールされない COM+ パーティションに依存します。 ([2] [3] [4] [5])</String>
17 <String Id="msierrComPlusPartitionNotFound" Overridable="yes">COM+ パーティションは見つかりません ([2] [3] [4] [5])</String>
18 <String Id="msierrComPlusPartitionIdConflict" Overridable="yes">同一 ID を持つ COM+ パーティションが既に存在します。 ([2] [3] [4] [5])</String>
19 <String Id="msierrComPlusPartitionNameConflict" Overridable="yes">同一名称を持つ COM+ パーティションが既に存在します。 ([2] [3] [4] [5])</String>
20 <String Id="msierrComPlusApplicationDependency" Overridable="yes">他のエンティティはインストールされない COM+ アプリケーションに依存します。 ([2] [3] [4] [5])</String>
21 <String Id="msierrComPlusApplicationNotFound" Overridable="yes">COM+ アプリケーションは見つかりません。 ([2] [3] [4] [5])</String>
22 <String Id="msierrComPlusApplicationIdConflict" Overridable="yes">同一 ID を持つ COM+ アプリケーションが既に存在します。 ([2] [3] [4] [5])</String>
23 <String Id="msierrComPlusApplicationNameConflict" Overridable="yes">同一名称を持つ COM+ アプリケーションが既に存在します。 ([2] [3] [4] [5])</String>
24 <String Id="msierrComPlusApplicationRoleDependency" Overridable="yes">他のエンティティはインストールされない COM+ アプリケーション役割に依存します。 ([2] [3] [4] [5])</String>
25 <String Id="msierrComPlusApplicationRoleNotFound" Overridable="yes">COM+ アプリケーション役割は見つかりません。 ([2] [3] [4] [5])</String>
26 <String Id="msierrComPlusApplicationRoleConflict" Overridable="yes">同一名称を持つ COM+ アプリケーション役割が既に存在します。 ([2] [3] [4] [5])</String>
27 <String Id="msierrComPlusAssemblyDependency" Overridable="yes">他のエンティティはインストールされない COM+ アセンブリに依存します。 ([2] [3] [4] [5])</String>
28 <String Id="msierrComPlusSubscriptionIdConflict" Overridable="yes">同一 ID を持つ COM+ コンポーネントのイベント登録が既に存在します。 ([2] [3] [4] [5])</String>
29 <String Id="msierrComPlusSubscriptionNameConflict" Overridable="yes">同一名称を持つ COM+ コンポーネントのイベント登録が既に存在します。 ([2] [3] [4] [5])</String>
30 <String Id="msierrComPlusFailedLookupNames" Overridable="yes">ユーザー アカウント名の照合に失敗しました。 ([2] [3] [4] [5])</String>
31
32 <String Id="ComPlusInstallExecute" Overridable="yes">COM+ コンポーネントを登録しています</String>
33 <String Id="ComPlusUninstallExecute" Overridable="yes">COM+ コンポーネント登録を解除しています</String>
34
35 <String Id="CreateComPlusPartitions" Overridable="yes">COM+ パーティションを作成しています</String>
36 <String Id="CreateComPlusPartitionsTemplate" Overridable="yes">パーティション: [1]</String>
37 <String Id="RemoveComPlusPartitions" Overridable="yes">COM+ パーティションを削除しています</String>
38 <String Id="RemoveComPlusPartitionsTemplate" Overridable="yes">パーティション: [1]</String>
39 <String Id="AddUsersToComPlusPartitionRoles" Overridable="yes">ユーザーを COM+ パーティション役割に追加しています</String>
40 <String Id="AddUsersToComPlusPartitionRolesTemplate" Overridable="yes">役割: [1]</String>
41 <String Id="RemoveUsersFromComPlusPartitionRoles" Overridable="yes">ユーザを COM+ パーティション役割より削除しています</String>
42 <String Id="RemoveUsersFromComPlusPartitionRolesTemplate" Overridable="yes">役割: [1]</String>
43 <String Id="AddComPlusPartitionUsers" Overridable="yes">ユーザーのデフォルト COM+ 役割を設定しています</String>
44 <String Id="AddComPlusPartitionUsersTemplate" Overridable="yes">ユーザー: [1]</String>
45 <String Id="RemoveComPlusPartitionUsers" Overridable="yes">ユーザーのデフォルト COM+ パーティション役割を削除しています</String>
46 <String Id="RemoveComPlusPartitionUsersTemplate" Overridable="yes">ユーザー: [1]</String>
47 <String Id="CreateComPlusApplications" Overridable="yes">COM+ アプリケーションを作成しています</String>
48 <String Id="CreateComPlusApplicationsTemplate" Overridable="yes">アプリケーション: [1]</String>
49 <String Id="RemoveComPlusApplications" Overridable="yes">COM+ アプリケーションを削除しています</String>
50 <String Id="RemoveComPlusApplicationsTemplate" Overridable="yes">アプリケーション: [1]</String>
51 <String Id="CreateComPlusApplicationRoles" Overridable="yes">COM+ アプリケーション役割を作成しています</String>
52 <String Id="CreateComPlusApplicationRolesTemplate" Overridable="yes">役割: [1]</String>
53 <String Id="RemoveComPlusApplicationRoles" Overridable="yes">COM+ アプリケーション役割を削除しています</String>
54 <String Id="RemoveComPlusApplicationRolesTemplate" Overridable="yes">役割: [1]</String>
55 <String Id="AddUsersToComPlusApplicationRoles" Overridable="yes">ユーザーを COM+ アプリケーション役割に追加しています</String>
56 <String Id="AddUsersToComPlusApplicationRolesTemplate" Overridable="yes">ユーザー: [1]</String>
57 <String Id="RemoveUsersFromComPlusApplicationRoles" Overridable="yes">ユーザーを COM+ アプリケーション役割より削除しています</String>
58 <String Id="RemoveUsersFromComPlusApplicationRolesTemplate" Overridable="yes">ユーザー: [1]</String>
59 <String Id="RegisterComPlusAssemblies" Overridable="yes">COM+ コンポーネントを登録しています</String>
60 <String Id="RegisterComPlusAssembliesTemplate" Overridable="yes">DLL: [1]</String>
61 <String Id="UnregisterComPlusAssemblies" Overridable="yes">COM+ コンポーネント登録を解除しています</String>
62 <String Id="UnregisterComPlusAssembliesTemplate" Overridable="yes">DLL: [1]</String>
63 <String Id="AddComPlusRoleAssignments" Overridable="yes">COM+ コンポーネントへ役割を割り当てています</String>
64 <String Id="AddComPlusRoleAssignmentsTemplate" Overridable="yes">コンポーネント: [1]</String>
65 <String Id="RemoveComPlusRoleAssignments" Overridable="yes">COM+ コンポーネントより役割割当を削除しています</String>
66 <String Id="RemoveComPlusRoleAssignmentsTemplate" Overridable="yes">コンポーネント: [1]</String>
67 <String Id="CreateSubscriptionsComPlusComponents" Overridable="yes">COM+ コンポーネント用登録を作成しています</String>
68 <String Id="CreateSubscriptionsComPlusComponentsTemplate" Overridable="yes">登録: [1]</String>
69 <String Id="RemoveSubscriptionsComPlusComponents" Overridable="yes">COM+ コンポーネント用登録を削除しています</String>
70 <String Id="RemoveSubscriptionsComPlusComponentsTemplate" Overridable="yes">登録: [1]</String>
71</WixLocalization>
diff --git a/src/ext/global.json b/src/ext/global.json
new file mode 100644
index 00000000..23dd3fa6
--- /dev/null
+++ b/src/ext/global.json
@@ -0,0 +1,5 @@
1{
2 "msbuild-sdks": {
3 "WixToolset.Sdk": "4.0.0-build-0211"
4 }
5}