diff options
Diffstat (limited to 'src/ext')
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 | | ||
2 | Microsoft Visual Studio Solution File, Format Version 12.00 | ||
3 | # Visual Studio Version 16 | ||
4 | VisualStudioVersion = 16.0.30611.23 | ||
5 | MinimumVisualStudioVersion = 10.0.40219.1 | ||
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "complusca", "src\ca\complusca.vcxproj", "{BDEF51ED-E242-4FA2-801A-01B127DF851A}" | ||
7 | EndProject | ||
8 | Project("{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 | ||
12 | EndProject | ||
13 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.ComPlus.wixext", "src\wixext\WixToolset.ComPlus.wixext.csproj", "{1497B777-330B-4CFE-927A-22850CD24D64}" | ||
14 | EndProject | ||
15 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.ComPlus", "src\test\WixToolsetTest.ComPlus\WixToolsetTest.ComPlus.csproj", "{2FC5F039-EACF-428B-BA87-8CDE1D25E121}" | ||
16 | EndProject | ||
17 | Global | ||
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 | ||
64 | EndGlobal | ||
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) > 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>(?<="[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) > 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 | ||
2 | WixToolset.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 | ||
7 | msbuild -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 | ||
13 | msbuild -p:Configuration=%_C% src\test\WixToolsetTest.ComPlus\WixToolsetTest.ComPlus.csproj || exit /b | ||
14 | |||
15 | :: Test | ||
16 | dotnet test -c %_C% --no-build src\test\WixToolsetTest.ComPlus || exit /b | ||
17 | |||
18 | :: Pack | ||
19 | msbuild -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 | |||
6 | branches: | ||
7 | only: | ||
8 | - master | ||
9 | - develop | ||
10 | |||
11 | image: Visual Studio 2019 | ||
12 | |||
13 | version: 0.0.0.{build} | ||
14 | configuration: Release | ||
15 | |||
16 | environment: | ||
17 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true | ||
18 | DOTNET_CLI_TELEMETRY_OPTOUT: 1 | ||
19 | NUGET_XMLDOC_MODE: skip | ||
20 | |||
21 | build_script: | ||
22 | - appveyor.cmd | ||
23 | |||
24 | pull_requests: | ||
25 | do_not_increment_build_number: true | ||
26 | |||
27 | nuget: | ||
28 | disable_publish_on_pr: true | ||
29 | |||
30 | skip_branch_with_pr: true | ||
31 | skip_tags: true | ||
32 | |||
33 | artifacts: | ||
34 | - path: build\Release\**\*.nupkg | ||
35 | name: nuget | ||
36 | - path: build\Release\**\*.snupkg | ||
37 | name: snupkg | ||
38 | |||
39 | notifications: | ||
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 | |||
4 | LIBRARY "complusca" | ||
5 | |||
6 | EXPORTS | ||
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 | |||
8 | struct 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 | |||
22 | static HRESULT ReadApplicationAttributes( | ||
23 | LPWSTR* ppwzData, | ||
24 | CPI_APPLICATION_ATTRIBUTES* pAttrs | ||
25 | ); | ||
26 | static void FreeApplicationAttributes( | ||
27 | CPI_APPLICATION_ATTRIBUTES* pAttrs | ||
28 | ); | ||
29 | static HRESULT CreateApplication( | ||
30 | CPI_APPLICATION_ATTRIBUTES* pAttrs | ||
31 | ); | ||
32 | static HRESULT RemoveApplication( | ||
33 | CPI_APPLICATION_ATTRIBUTES* pAttrs | ||
34 | ); | ||
35 | |||
36 | |||
37 | // function definitions | ||
38 | |||
39 | HRESULT 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 | |||
103 | LExit: | ||
104 | // clean up | ||
105 | FreeApplicationAttributes(&attrs); | ||
106 | |||
107 | return hr; | ||
108 | } | ||
109 | |||
110 | HRESULT 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 | |||
176 | LExit: | ||
177 | // clean up | ||
178 | FreeApplicationAttributes(&attrs); | ||
179 | |||
180 | return hr; | ||
181 | } | ||
182 | |||
183 | |||
184 | // helper function definitions | ||
185 | |||
186 | static 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 | |||
210 | LExit: | ||
211 | return hr; | ||
212 | } | ||
213 | |||
214 | static 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 | |||
227 | static 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 | |||
285 | LExit: | ||
286 | // clean up | ||
287 | ReleaseObject(piAppColl); | ||
288 | ReleaseObject(piAppObj); | ||
289 | |||
290 | return hr; | ||
291 | } | ||
292 | |||
293 | static 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 | |||
339 | LExit: | ||
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 | |||
5 | HRESULT CpiConfigureApplications( | ||
6 | LPWSTR* ppwzData, | ||
7 | HANDLE hRollbackFile | ||
8 | ); | ||
9 | HRESULT 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 | |||
8 | struct 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 | |||
19 | struct 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 | |||
33 | static HRESULT ReadApplicationRoleAttributes( | ||
34 | LPWSTR* ppwzData, | ||
35 | CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs | ||
36 | ); | ||
37 | static void FreeApplicationRoleAttributes( | ||
38 | CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs | ||
39 | ); | ||
40 | static HRESULT CreateApplicationRole( | ||
41 | CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs | ||
42 | ); | ||
43 | static HRESULT RemoveApplicationRole( | ||
44 | CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs | ||
45 | ); | ||
46 | static HRESULT ReadUsersInApplicationRoleAttributes( | ||
47 | LPWSTR* ppwzData, | ||
48 | CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs | ||
49 | ); | ||
50 | static void FreeUsersInApplicationRoleAttributes( | ||
51 | CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs | ||
52 | ); | ||
53 | static HRESULT CreateUsersInApplicationRole( | ||
54 | CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs | ||
55 | ); | ||
56 | static HRESULT RemoveUsersInApplicationRole( | ||
57 | CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs | ||
58 | ); | ||
59 | |||
60 | |||
61 | // function definitions | ||
62 | |||
63 | HRESULT 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 | |||
127 | LExit: | ||
128 | // clean up | ||
129 | FreeApplicationRoleAttributes(&attrs); | ||
130 | |||
131 | return hr; | ||
132 | } | ||
133 | |||
134 | HRESULT 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 | |||
200 | LExit: | ||
201 | // clean up | ||
202 | FreeApplicationRoleAttributes(&attrs); | ||
203 | |||
204 | return hr; | ||
205 | } | ||
206 | |||
207 | HRESULT 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 | |||
271 | LExit: | ||
272 | // clean up | ||
273 | FreeUsersInApplicationRoleAttributes(&attrs); | ||
274 | |||
275 | return hr; | ||
276 | } | ||
277 | |||
278 | HRESULT 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 | |||
344 | LExit: | ||
345 | // clean up | ||
346 | FreeUsersInApplicationRoleAttributes(&attrs); | ||
347 | |||
348 | return hr; | ||
349 | } | ||
350 | |||
351 | |||
352 | // helper function definitions | ||
353 | |||
354 | static 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 | |||
378 | LExit: | ||
379 | return hr; | ||
380 | } | ||
381 | |||
382 | static 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 | |||
395 | static 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 | |||
444 | LExit: | ||
445 | // clean up | ||
446 | ReleaseObject(piRolesColl); | ||
447 | ReleaseObject(piRoleObj); | ||
448 | |||
449 | return hr; | ||
450 | } | ||
451 | |||
452 | static 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 | |||
498 | LExit: | ||
499 | // clean up | ||
500 | ReleaseObject(piRolesColl); | ||
501 | |||
502 | return hr; | ||
503 | } | ||
504 | |||
505 | static 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 | |||
529 | LExit: | ||
530 | return hr; | ||
531 | } | ||
532 | |||
533 | static 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 | |||
544 | static 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 | |||
624 | LExit: | ||
625 | // clean up | ||
626 | ReleaseObject(piUsrInRoleColl); | ||
627 | ReleaseObject(piUsrInRoleObj); | ||
628 | |||
629 | if (pSid) | ||
630 | ::HeapFree(::GetProcessHeap(), 0, pSid); | ||
631 | |||
632 | return hr; | ||
633 | } | ||
634 | |||
635 | static 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 | |||
712 | LExit: | ||
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 | |||
5 | HRESULT CpiConfigureApplicationRoles( | ||
6 | LPWSTR* ppwzData, | ||
7 | HANDLE hRollbackFile | ||
8 | ); | ||
9 | HRESULT CpiRollbackConfigureApplicationRoles( | ||
10 | LPWSTR* ppwzData, | ||
11 | CPI_ROLLBACK_DATA* pRollbackDataList | ||
12 | ); | ||
13 | HRESULT CpiConfigureUsersInApplicationRoles( | ||
14 | LPWSTR* ppwzData, | ||
15 | HANDLE hRollbackFile | ||
16 | ); | ||
17 | HRESULT 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 | |||
8 | LPCWSTR vcsApplicationRoleQuery = | ||
9 | L"SELECT `ApplicationRole`, `Application_`, `Component_`, `Name` FROM `ComPlusApplicationRole`"; | ||
10 | enum eApplicationRoleQuery { arqApplicationRole = 1, arqApplication, arqComponent, arqName }; | ||
11 | |||
12 | LPCWSTR vcsUserInApplicationRoleQuery = | ||
13 | L"SELECT `UserInApplicationRole`, `ApplicationRole_`, `ComPlusUserInApplicationRole`.`Component_`, `Domain`, `Name` FROM `ComPlusUserInApplicationRole`, `User` WHERE `User_` = `User`"; | ||
14 | LPCWSTR vcsGroupInApplicationRoleQuery = | ||
15 | L"SELECT `GroupInApplicationRole`, `ApplicationRole_`, `ComPlusGroupInApplicationRole`.`Component_`, `Domain`, `Name` FROM `ComPlusGroupInApplicationRole`, `Group` WHERE `Group_` = `Group`"; | ||
16 | enum eTrusteeInApplicationRoleQuery { tiarqUserInApplicationRole = 1, tiarqApplicationRole, tiarqComponent, tiarqDomain, tiarqName }; | ||
17 | |||
18 | LPCWSTR vcsApplicationRolePropertyQuery = | ||
19 | L"SELECT `Name`, `Value` FROM `ComPlusApplicationRoleProperty` WHERE `ApplicationRole_` = ?"; | ||
20 | |||
21 | |||
22 | // property definitions | ||
23 | |||
24 | CPI_PROPERTY_DEFINITION pdlApplicationRoleProperties[] = | ||
25 | { | ||
26 | {L"Description", cpptString, 500}, | ||
27 | {NULL, cpptNone, 0} | ||
28 | }; | ||
29 | |||
30 | |||
31 | // prototypes for private helper functions | ||
32 | |||
33 | static HRESULT TrusteesInApplicationRolesRead( | ||
34 | LPCWSTR pwzQuery, | ||
35 | CPI_APPLICATION_ROLE_LIST* pAppRoleList, | ||
36 | CPI_USER_IN_APPLICATION_ROLE_LIST* pUsrInAppRoleList | ||
37 | ); | ||
38 | static void FreeApplicationRole( | ||
39 | CPI_APPLICATION_ROLE* pItm | ||
40 | ); | ||
41 | static void FreeUserInApplicationRole( | ||
42 | CPI_USER_IN_APPLICATION_ROLE* pItm | ||
43 | ); | ||
44 | //static HRESULT GetUsersCollForApplicationRole( | ||
45 | // CPI_APPLICATION_ROLE* pAppRole, | ||
46 | // ICatalogCollection** ppiUsersColl | ||
47 | // ); | ||
48 | static HRESULT FindObjectForApplicationRole( | ||
49 | CPI_APPLICATION_ROLE* pItm, | ||
50 | ICatalogObject** ppiRoleObj | ||
51 | ); | ||
52 | static HRESULT AddApplicationRoleToActionData( | ||
53 | CPI_APPLICATION_ROLE* pItm, | ||
54 | int iActionType, | ||
55 | int iActionCost, | ||
56 | LPWSTR* ppwzActionData | ||
57 | ); | ||
58 | static 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 | |||
68 | void 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 | |||
82 | HRESULT 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 | |||
183 | LExit: | ||
184 | // clean up | ||
185 | if (pItm) | ||
186 | FreeApplicationRole(pItm); | ||
187 | |||
188 | ReleaseStr(pwzData); | ||
189 | |||
190 | return hr; | ||
191 | } | ||
192 | |||
193 | HRESULT 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 | |||
256 | LExit: | ||
257 | // clean up | ||
258 | ReleaseObject(piRoleObj); | ||
259 | |||
260 | return hr; | ||
261 | } | ||
262 | |||
263 | HRESULT 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 | |||
290 | LExit: | ||
291 | return hr; | ||
292 | } | ||
293 | |||
294 | void CpiApplicationRoleAddReferenceInstall( | ||
295 | CPI_APPLICATION_ROLE* pItm | ||
296 | ) | ||
297 | { | ||
298 | pItm->fReferencedForInstall = TRUE; | ||
299 | CpiApplicationAddReferenceInstall(pItm->pApplication); | ||
300 | } | ||
301 | |||
302 | void CpiApplicationRoleAddReferenceUninstall( | ||
303 | CPI_APPLICATION_ROLE* pItm | ||
304 | ) | ||
305 | { | ||
306 | pItm->fReferencedForUninstall = TRUE; | ||
307 | CpiApplicationAddReferenceUninstall(pItm->pApplication); | ||
308 | } | ||
309 | |||
310 | HRESULT 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 | |||
358 | LExit: | ||
359 | return hr; | ||
360 | } | ||
361 | |||
362 | HRESULT 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 | |||
405 | LExit: | ||
406 | return hr; | ||
407 | } | ||
408 | |||
409 | HRESULT 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 | |||
427 | void 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 | |||
441 | HRESULT 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 | |||
464 | LExit: | ||
465 | return hr; | ||
466 | } | ||
467 | |||
468 | HRESULT 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 | |||
516 | LExit: | ||
517 | return hr; | ||
518 | } | ||
519 | |||
520 | HRESULT 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 | |||
563 | LExit: | ||
564 | return hr; | ||
565 | } | ||
566 | |||
567 | |||
568 | // helper function definitions | ||
569 | |||
570 | static 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 | |||
663 | LExit: | ||
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 | |||
675 | static 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 | |||
687 | static 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 | |||
739 | static 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 | |||
761 | LExit: | ||
762 | // clean up | ||
763 | ReleaseObject(piRoleColl); | ||
764 | |||
765 | return hr; | ||
766 | } | ||
767 | |||
768 | static 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 | |||
803 | LExit: | ||
804 | return hr; | ||
805 | } | ||
806 | |||
807 | static 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 | |||
841 | LExit: | ||
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 | |||
5 | struct 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 | |||
27 | struct CPI_APPLICATION_ROLE_LIST | ||
28 | { | ||
29 | CPI_APPLICATION_ROLE* pFirst; | ||
30 | |||
31 | int iInstallCount; | ||
32 | int iUninstallCount; | ||
33 | }; | ||
34 | |||
35 | struct 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 | |||
47 | struct 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 | |||
58 | void CpiApplicationRoleListFree( | ||
59 | CPI_APPLICATION_ROLE_LIST* pList | ||
60 | ); | ||
61 | HRESULT CpiApplicationRolesRead( | ||
62 | CPI_APPLICATION_LIST* pAppList, | ||
63 | CPI_APPLICATION_ROLE_LIST* pAppRoleList | ||
64 | ); | ||
65 | HRESULT CpiApplicationRolesVerifyInstall( | ||
66 | CPI_APPLICATION_ROLE_LIST* pList | ||
67 | ); | ||
68 | HRESULT CpiApplicationRolesVerifyUninstall( | ||
69 | CPI_APPLICATION_ROLE_LIST* pList | ||
70 | ); | ||
71 | void CpiApplicationRoleAddReferenceInstall( | ||
72 | CPI_APPLICATION_ROLE* pItm | ||
73 | ); | ||
74 | void CpiApplicationRoleAddReferenceUninstall( | ||
75 | CPI_APPLICATION_ROLE* pItm | ||
76 | ); | ||
77 | HRESULT CpiApplicationRolesInstall( | ||
78 | CPI_APPLICATION_ROLE_LIST* pList, | ||
79 | int iRunMode, | ||
80 | LPWSTR* ppwzActionData, | ||
81 | int* piProgress | ||
82 | ); | ||
83 | HRESULT CpiApplicationRolesUninstall( | ||
84 | CPI_APPLICATION_ROLE_LIST* pList, | ||
85 | int iRunMode, | ||
86 | LPWSTR* ppwzActionData, | ||
87 | int* piProgress | ||
88 | ); | ||
89 | HRESULT CpiApplicationRoleFindByKey( | ||
90 | CPI_APPLICATION_ROLE_LIST* pList, | ||
91 | LPCWSTR pwzKey, | ||
92 | CPI_APPLICATION_ROLE** ppAppRole | ||
93 | ); | ||
94 | void CpiUserInApplicationRoleListFree( | ||
95 | CPI_USER_IN_APPLICATION_ROLE_LIST* pList | ||
96 | ); | ||
97 | HRESULT CpiUsersInApplicationRolesRead( | ||
98 | CPI_APPLICATION_ROLE_LIST* pAppRoleList, | ||
99 | CPI_USER_IN_APPLICATION_ROLE_LIST* pUsrInAppRoleList | ||
100 | ); | ||
101 | HRESULT CpiUsersInApplicationRolesInstall( | ||
102 | CPI_USER_IN_APPLICATION_ROLE_LIST* pList, | ||
103 | int iRunMode, | ||
104 | LPWSTR* ppwzActionData, | ||
105 | int* piProgress | ||
106 | ); | ||
107 | HRESULT 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 | |||
8 | LPCWSTR vcsApplicationQuery = | ||
9 | L"SELECT `Application`, `Component_`, `Partition_`, `Id`, `Name` FROM `ComPlusApplication`"; | ||
10 | enum eApplicationQuery { aqApplication = 1, aqComponent, aqPartition, aqID, aqName }; | ||
11 | |||
12 | LPCWSTR vcsApplicationPropertyQuery = | ||
13 | L"SELECT `Name`, `Value` FROM `ComPlusApplicationProperty` WHERE `Application_` = ?"; | ||
14 | |||
15 | |||
16 | // property definitions | ||
17 | |||
18 | CPI_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 | |||
69 | static void FreeApplication( | ||
70 | CPI_APPLICATION* pItm | ||
71 | ); | ||
72 | static HRESULT FindObjectForApplication( | ||
73 | CPI_APPLICATION* pItm, | ||
74 | BOOL fFindId, | ||
75 | BOOL fFindName, | ||
76 | ICatalogObject** ppiAppObj | ||
77 | ); | ||
78 | static HRESULT AddApplicationToActionData( | ||
79 | CPI_APPLICATION* pItm, | ||
80 | int iActionType, | ||
81 | int iActionCost, | ||
82 | LPWSTR* ppwzActionData | ||
83 | ); | ||
84 | |||
85 | |||
86 | // function definitions | ||
87 | |||
88 | void 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 | |||
102 | HRESULT 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 | |||
233 | LExit: | ||
234 | // clean up | ||
235 | if (pItm) | ||
236 | FreeApplication(pItm); | ||
237 | |||
238 | ReleaseStr(pwzData); | ||
239 | |||
240 | return hr; | ||
241 | } | ||
242 | |||
243 | HRESULT 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 | |||
370 | LExit: | ||
371 | // clean up | ||
372 | ReleaseObject(piAppObj); | ||
373 | |||
374 | return hr; | ||
375 | } | ||
376 | |||
377 | HRESULT 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 | |||
419 | LExit: | ||
420 | // clean up | ||
421 | ReleaseObject(piAppObj); | ||
422 | |||
423 | return hr; | ||
424 | } | ||
425 | |||
426 | void CpiApplicationAddReferenceInstall( | ||
427 | CPI_APPLICATION* pItm | ||
428 | ) | ||
429 | { | ||
430 | pItm->fReferencedForInstall = TRUE; | ||
431 | if (pItm->pPartition) | ||
432 | CpiPartitionAddReferenceInstall(pItm->pPartition); | ||
433 | } | ||
434 | |||
435 | void CpiApplicationAddReferenceUninstall( | ||
436 | CPI_APPLICATION* pItm | ||
437 | ) | ||
438 | { | ||
439 | pItm->fReferencedForUninstall = TRUE; | ||
440 | if (pItm->pPartition) | ||
441 | CpiPartitionAddReferenceUninstall(pItm->pPartition); | ||
442 | } | ||
443 | |||
444 | HRESULT 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 | |||
492 | LExit: | ||
493 | return hr; | ||
494 | } | ||
495 | |||
496 | HRESULT 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 | |||
539 | LExit: | ||
540 | return hr; | ||
541 | } | ||
542 | |||
543 | HRESULT 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 | |||
561 | HRESULT 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 | |||
606 | LExit: | ||
607 | // clean up | ||
608 | ReleaseObject(piAppColl); | ||
609 | ReleaseObject(piAppObj); | ||
610 | |||
611 | return hr; | ||
612 | } | ||
613 | |||
614 | HRESULT 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 | |||
659 | LExit: | ||
660 | // clean up | ||
661 | ReleaseObject(piAppColl); | ||
662 | ReleaseObject(piAppObj); | ||
663 | |||
664 | return hr; | ||
665 | } | ||
666 | |||
667 | |||
668 | // helper function definitions | ||
669 | |||
670 | static 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 | |||
683 | static 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 | |||
710 | LExit: | ||
711 | // clean up | ||
712 | ReleaseObject(piAppColl); | ||
713 | |||
714 | return hr; | ||
715 | } | ||
716 | |||
717 | static 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 | |||
750 | LExit: | ||
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 | |||
5 | struct 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 | |||
29 | struct CPI_APPLICATION_LIST | ||
30 | { | ||
31 | CPI_APPLICATION* pFirst; | ||
32 | |||
33 | int iInstallCount; | ||
34 | int iUninstallCount; | ||
35 | }; | ||
36 | |||
37 | |||
38 | // function prototypes | ||
39 | |||
40 | void CpiApplicationListFree( | ||
41 | CPI_APPLICATION_LIST* pList | ||
42 | ); | ||
43 | HRESULT CpiApplicationsRead( | ||
44 | CPI_PARTITION_LIST* pPartList, | ||
45 | CPI_APPLICATION_LIST* pAppList | ||
46 | ); | ||
47 | HRESULT CpiApplicationsVerifyInstall( | ||
48 | CPI_APPLICATION_LIST* pList | ||
49 | ); | ||
50 | HRESULT CpiApplicationsVerifyUninstall( | ||
51 | CPI_APPLICATION_LIST* pList | ||
52 | ); | ||
53 | void CpiApplicationAddReferenceInstall( | ||
54 | CPI_APPLICATION* pItm | ||
55 | ); | ||
56 | void CpiApplicationAddReferenceUninstall( | ||
57 | CPI_APPLICATION* pItm | ||
58 | ); | ||
59 | HRESULT CpiApplicationsInstall( | ||
60 | CPI_APPLICATION_LIST* pList, | ||
61 | int iRunMode, | ||
62 | LPWSTR* ppwzActionData, | ||
63 | int* piProgress | ||
64 | ); | ||
65 | HRESULT CpiApplicationsUninstall( | ||
66 | CPI_APPLICATION_LIST* pList, | ||
67 | int iRunMode, | ||
68 | LPWSTR* ppwzActionData, | ||
69 | int* piProgress | ||
70 | ); | ||
71 | HRESULT CpiApplicationFindByKey( | ||
72 | CPI_APPLICATION_LIST* pList, | ||
73 | LPCWSTR pwzKey, | ||
74 | CPI_APPLICATION** ppApp | ||
75 | ); | ||
76 | HRESULT CpiGetRolesCollForApplication( | ||
77 | CPI_APPLICATION* pApp, | ||
78 | ICatalogCollection** ppiRolesColl | ||
79 | ); | ||
80 | HRESULT 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 | |||
8 | typedef 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 | |||
17 | typedef struct _FUSION_INSTALL_REFERENCE_ *LPFUSION_INSTALL_REFERENCE; | ||
18 | |||
19 | typedef const FUSION_INSTALL_REFERENCE *LPCFUSION_INSTALL_REFERENCE; | ||
20 | |||
21 | typedef struct _ASSEMBLY_INFO | ||
22 | { | ||
23 | ULONG cbAssemblyInfo; | ||
24 | DWORD dwAssemblyFlags; | ||
25 | ULARGE_INTEGER uliAssemblySizeInKB; | ||
26 | LPWSTR pszCurrentAssemblyPathBuf; | ||
27 | ULONG cchBuf; | ||
28 | } ASSEMBLY_INFO; | ||
29 | |||
30 | typedef interface IAssemblyCacheItem IAssemblyCacheItem; | ||
31 | |||
32 | MIDL_INTERFACE("e707dcde-d1cd-11d2-bab9-00c04f8eceae") | ||
33 | IAssemblyCache : public IUnknown | ||
34 | { | ||
35 | public: | ||
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 | |||
62 | typedef HRESULT (__stdcall *LoadLibraryShimFunc)(LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE *phModDll); | ||
63 | typedef HRESULT (__stdcall *CreateAssemblyCacheFunc)(IAssemblyCache **ppAsmCache, DWORD dwReserved); | ||
64 | |||
65 | |||
66 | // RegistrationHelper related declarations | ||
67 | |||
68 | static const GUID CLSID_RegistrationHelper = | ||
69 | { 0x89a86e7b, 0xc229, 0x4008, { 0x9b, 0xaa, 0x2f, 0x5c, 0x84, 0x11, 0xd7, 0xe0 } }; | ||
70 | |||
71 | enum eInstallationFlags { | ||
72 | ifConfigureComponentsOnly = 16, | ||
73 | ifFindOrCreateTargetApplication = 4, | ||
74 | ifExpectExistingTypeLib = 1 | ||
75 | }; | ||
76 | |||
77 | |||
78 | // private structs | ||
79 | |||
80 | struct 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 | |||
88 | struct 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 | |||
99 | struct 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 | |||
110 | struct 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 | |||
121 | struct 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 | |||
136 | struct 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 | |||
150 | static HRESULT RegisterAssembly( | ||
151 | CPI_ASSEMBLY_ATTRIBUTES* pAttrs | ||
152 | ); | ||
153 | static HRESULT UnregisterAssembly( | ||
154 | CPI_ASSEMBLY_ATTRIBUTES* pAttrs | ||
155 | ); | ||
156 | static void InitAssemblyExec(); | ||
157 | static void UninitAssemblyExec(); | ||
158 | static HRESULT GetRegistrationHelper( | ||
159 | IDispatch** ppiRegHlp | ||
160 | ); | ||
161 | static HRESULT GetAssemblyCacheObject( | ||
162 | IAssemblyCache** ppAssemblyCache | ||
163 | ); | ||
164 | static HRESULT GetAssemblyPathFromGAC( | ||
165 | LPCWSTR pwzAssemblyName, | ||
166 | LPWSTR* ppwzAssemblyPath | ||
167 | ); | ||
168 | static HRESULT RegisterDotNetAssembly( | ||
169 | CPI_ASSEMBLY_ATTRIBUTES* pAttrs | ||
170 | ); | ||
171 | static HRESULT RegisterNativeAssembly( | ||
172 | CPI_ASSEMBLY_ATTRIBUTES* pAttrs | ||
173 | ); | ||
174 | static HRESULT UnregisterDotNetAssembly( | ||
175 | CPI_ASSEMBLY_ATTRIBUTES* pAttrs | ||
176 | ); | ||
177 | static HRESULT RemoveComponents( | ||
178 | ICatalogCollection* piCompColl, | ||
179 | CPIEXEC_COMPONENT* pCompList | ||
180 | ); | ||
181 | static HRESULT ReadAssemblyAttributes( | ||
182 | LPWSTR* ppwzData, | ||
183 | CPI_ASSEMBLY_ATTRIBUTES* pAttrs | ||
184 | ); | ||
185 | static void FreeAssemblyAttributes( | ||
186 | CPI_ASSEMBLY_ATTRIBUTES* pAttrs | ||
187 | ); | ||
188 | static HRESULT ReadRoleAssignmentsAttributes( | ||
189 | LPWSTR* ppwzData, | ||
190 | CPI_ROLE_ASSIGNMENTS_ATTRIBUTES* pAttrs | ||
191 | ); | ||
192 | static void FreeRoleAssignmentsAttributes( | ||
193 | CPI_ROLE_ASSIGNMENTS_ATTRIBUTES* pAttrs | ||
194 | ); | ||
195 | static HRESULT ConfigureComponents( | ||
196 | LPCWSTR pwzPartID, | ||
197 | LPCWSTR pwzAppID, | ||
198 | CPIEXEC_COMPONENT* pCompList, | ||
199 | BOOL fCreate, | ||
200 | BOOL fProgress | ||
201 | ); | ||
202 | static HRESULT ConfigureInterfaces( | ||
203 | ICatalogCollection* piCompColl, | ||
204 | ICatalogObject* piCompObj, | ||
205 | CPIEXEC_INTERFACE* pIntfList, | ||
206 | BOOL fCreate | ||
207 | ); | ||
208 | static HRESULT ConfigureMethods( | ||
209 | ICatalogCollection* piIntfColl, | ||
210 | ICatalogObject* piIntfObj, | ||
211 | CPIEXEC_METHOD* pMethList, | ||
212 | BOOL fCreate | ||
213 | ); | ||
214 | static HRESULT ConfigureRoleAssignments( | ||
215 | LPCWSTR pwzCollName, | ||
216 | ICatalogCollection* piCompColl, | ||
217 | ICatalogObject* piCompObj, | ||
218 | CPIEXEC_ROLE_ASSIGNMENT* pRoleList, | ||
219 | BOOL fCreate | ||
220 | ); | ||
221 | static HRESULT ReadComponentList( | ||
222 | LPWSTR* ppwzData, | ||
223 | CPIEXEC_COMPONENT** ppCompList | ||
224 | ); | ||
225 | static HRESULT ReadInterfaceList( | ||
226 | LPWSTR* ppwzData, | ||
227 | CPIEXEC_INTERFACE** ppIntfList | ||
228 | ); | ||
229 | static HRESULT ReadMethodList( | ||
230 | LPWSTR* ppwzData, | ||
231 | CPIEXEC_METHOD** ppMethList | ||
232 | ); | ||
233 | static HRESULT ReadRoleAssignmentList( | ||
234 | LPWSTR* ppwzData, | ||
235 | CPIEXEC_ROLE_ASSIGNMENT** ppRoleList | ||
236 | ); | ||
237 | static void FreeComponentList( | ||
238 | CPIEXEC_COMPONENT* pList | ||
239 | ); | ||
240 | static void FreeInterfaceList( | ||
241 | CPIEXEC_INTERFACE* pList | ||
242 | ); | ||
243 | static void FreeMethodList( | ||
244 | CPIEXEC_METHOD* pList | ||
245 | ); | ||
246 | static void FreeRoleAssignmentList( | ||
247 | CPIEXEC_ROLE_ASSIGNMENT* pList | ||
248 | ); | ||
249 | |||
250 | |||
251 | // variables | ||
252 | |||
253 | static IDispatch* gpiRegHlp; | ||
254 | static IAssemblyCache* gpAssemblyCache; | ||
255 | static HMODULE ghMscoree; | ||
256 | static HMODULE ghFusion; | ||
257 | |||
258 | |||
259 | // function definitions | ||
260 | |||
261 | HRESULT 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 | |||
327 | LExit: | ||
328 | // clean up | ||
329 | FreeAssemblyAttributes(&attrs); | ||
330 | |||
331 | // uninitialize | ||
332 | UninitAssemblyExec(); | ||
333 | |||
334 | return hr; | ||
335 | } | ||
336 | |||
337 | HRESULT 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 | |||
399 | LExit: | ||
400 | // clean up | ||
401 | FreeAssemblyAttributes(&attrs); | ||
402 | |||
403 | // uninitialize | ||
404 | UninitAssemblyExec(); | ||
405 | |||
406 | return hr; | ||
407 | } | ||
408 | |||
409 | HRESULT 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 | |||
463 | LExit: | ||
464 | // clean up | ||
465 | FreeRoleAssignmentsAttributes(&attrs); | ||
466 | |||
467 | return hr; | ||
468 | } | ||
469 | |||
470 | HRESULT 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 | |||
524 | LExit: | ||
525 | // clean up | ||
526 | FreeRoleAssignmentsAttributes(&attrs); | ||
527 | |||
528 | return hr; | ||
529 | } | ||
530 | |||
531 | |||
532 | // helper function definitions | ||
533 | |||
534 | static 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 | |||
585 | LExit: | ||
586 | return hr; | ||
587 | } | ||
588 | |||
589 | static 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 | |||
698 | LExit: | ||
699 | // clean up | ||
700 | ReleaseObject(piColl); | ||
701 | ReleaseObject(piObj); | ||
702 | |||
703 | return hr; | ||
704 | } | ||
705 | |||
706 | static void InitAssemblyExec() | ||
707 | { | ||
708 | gpiRegHlp = NULL; | ||
709 | gpAssemblyCache = NULL; | ||
710 | ghMscoree = NULL; | ||
711 | ghFusion = NULL; | ||
712 | } | ||
713 | |||
714 | static void UninitAssemblyExec() | ||
715 | { | ||
716 | ReleaseObject(gpiRegHlp); | ||
717 | ReleaseObject(gpAssemblyCache); | ||
718 | if (ghFusion) | ||
719 | ::FreeLibrary(ghFusion); | ||
720 | if (ghMscoree) | ||
721 | ::FreeLibrary(ghMscoree); | ||
722 | } | ||
723 | |||
724 | static 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 | |||
742 | LExit: | ||
743 | return hr; | ||
744 | } | ||
745 | |||
746 | static 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 | |||
788 | LExit: | ||
789 | return hr; | ||
790 | } | ||
791 | |||
792 | static 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 | |||
827 | LExit: | ||
828 | // clean up | ||
829 | ReleaseObject(pAssemblyCache); | ||
830 | |||
831 | return hr; | ||
832 | } | ||
833 | |||
834 | static 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 | |||
931 | LExit: | ||
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 | |||
949 | static 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 | |||
1037 | LExit: | ||
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 | |||
1052 | static 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 | |||
1127 | LExit: | ||
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 | |||
1144 | static 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 | |||
1163 | LExit: | ||
1164 | return hr; | ||
1165 | } | ||
1166 | |||
1167 | static 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 | |||
1209 | LExit: | ||
1210 | return hr; | ||
1211 | } | ||
1212 | |||
1213 | static 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 | |||
1229 | static 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 | |||
1263 | LExit: | ||
1264 | return hr; | ||
1265 | } | ||
1266 | |||
1267 | static 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 | |||
1280 | static 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 | |||
1356 | LExit: | ||
1357 | // clean up | ||
1358 | ReleaseObject(piCompColl); | ||
1359 | ReleaseObject(piCompObj); | ||
1360 | |||
1361 | return hr; | ||
1362 | } | ||
1363 | |||
1364 | static 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 | |||
1429 | LExit: | ||
1430 | // clean up | ||
1431 | ReleaseObject(piIntfColl); | ||
1432 | ReleaseObject(piIntfObj); | ||
1433 | |||
1434 | return hr; | ||
1435 | } | ||
1436 | |||
1437 | static 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 | |||
1499 | LExit: | ||
1500 | // clean up | ||
1501 | ReleaseObject(piMethColl); | ||
1502 | ReleaseObject(piMethObj); | ||
1503 | |||
1504 | return hr; | ||
1505 | } | ||
1506 | |||
1507 | static 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 | |||
1570 | LExit: | ||
1571 | // clean up | ||
1572 | ReleaseObject(piRoleColl); | ||
1573 | ReleaseObject(piRoleObj); | ||
1574 | |||
1575 | return hr; | ||
1576 | } | ||
1577 | |||
1578 | static 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 | |||
1628 | LExit: | ||
1629 | // clean up | ||
1630 | ReleaseStr(pwzData); | ||
1631 | |||
1632 | if (pItm) | ||
1633 | FreeComponentList(pItm); | ||
1634 | |||
1635 | return hr; | ||
1636 | } | ||
1637 | |||
1638 | static 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 | |||
1688 | LExit: | ||
1689 | // clean up | ||
1690 | ReleaseStr(pwzData); | ||
1691 | |||
1692 | if (pItm) | ||
1693 | FreeInterfaceList(pItm); | ||
1694 | |||
1695 | return hr; | ||
1696 | } | ||
1697 | |||
1698 | static 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 | |||
1749 | LExit: | ||
1750 | // clean up | ||
1751 | ReleaseStr(pwzData); | ||
1752 | |||
1753 | if (pItm) | ||
1754 | FreeMethodList(pItm); | ||
1755 | |||
1756 | return hr; | ||
1757 | } | ||
1758 | |||
1759 | static 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 | |||
1802 | LExit: | ||
1803 | // clean up | ||
1804 | ReleaseStr(pwzData); | ||
1805 | |||
1806 | if (pItm) | ||
1807 | FreeRoleAssignmentList(pItm); | ||
1808 | |||
1809 | return hr; | ||
1810 | } | ||
1811 | |||
1812 | static 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 | |||
1831 | static 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 | |||
1850 | static 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 | |||
1867 | static 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 | |||
5 | HRESULT CpiConfigureAssemblies( | ||
6 | LPWSTR* ppwzData, | ||
7 | HANDLE hRollbackFile | ||
8 | ); | ||
9 | HRESULT CpiRollbackConfigureAssemblies( | ||
10 | LPWSTR* ppwzData, | ||
11 | CPI_ROLLBACK_DATA* pRollbackDataList | ||
12 | ); | ||
13 | HRESULT CpiConfigureRoleAssignments( | ||
14 | LPWSTR* ppwzData, | ||
15 | HANDLE hRollbackFile | ||
16 | ); | ||
17 | HRESULT 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 | |||
8 | LPCWSTR vcsMsiAssemblyNameQuery = | ||
9 | L"SELECT `Name`, `Value` FROM `MsiAssemblyName` WHERE `Component_` = ?"; | ||
10 | enum eMsiAssemblyNameQuery { manqName = 1, manqValue }; | ||
11 | |||
12 | LPCWSTR vcsModuleQuery = | ||
13 | L"SELECT `ModuleID` FROM `ModuleSignature`"; | ||
14 | enum eModuleQuery { mqModule = 1 }; | ||
15 | |||
16 | LPCWSTR vcsAssemblyQuery = | ||
17 | L"SELECT `Assembly`, `Component_`, `Application_`, `AssemblyName`, `DllPath`, `TlbPath`, `PSDllPath`, `Attributes` FROM `ComPlusAssembly`"; | ||
18 | enum eAssemblyQuery { aqAssembly = 1, aqComponent, aqApplication, aqAssemblyName, aqDllPath, aqTlbPath, aqPSDllPath, aqAttributes }; | ||
19 | |||
20 | LPCWSTR vcsComponentQuery = | ||
21 | L"SELECT `ComPlusComponent`, `CLSID` FROM `ComPlusComponent` WHERE `Assembly_` = ?"; | ||
22 | enum eComponentQuery { cqComponent = 1, cqCLSID }; | ||
23 | |||
24 | LPCWSTR vcsComponentPropertyQuery = | ||
25 | L"SELECT `Name`, `Value` FROM `ComPlusComponentProperty` WHERE `ComPlusComponent_` = ?"; | ||
26 | |||
27 | LPCWSTR vcsInterfaceQuery = | ||
28 | L"SELECT `Interface`, `IID` FROM `ComPlusInterface` WHERE `ComPlusComponent_` = ?"; | ||
29 | enum eInterfaceQuery { iqInterface = 1, iqIID }; | ||
30 | |||
31 | LPCWSTR vcsInterfacePropertyQuery = | ||
32 | L"SELECT `Name`, `Value` FROM `ComPlusInterfaceProperty` WHERE `Interface_` = ?"; | ||
33 | |||
34 | LPCWSTR vcsMethodQuery = | ||
35 | L"SELECT `Method`, `Index`, `Name` FROM `ComPlusMethod` WHERE `Interface_` = ?"; | ||
36 | enum eMethodQuery { mqMethod = 1, mqIndex, mqName }; | ||
37 | |||
38 | LPCWSTR vcsMethodPropertyQuery = | ||
39 | L"SELECT `Name`, `Value` FROM `ComPlusMethodProperty` WHERE `Method_` = ?"; | ||
40 | |||
41 | LPCWSTR vcsRoleForComponentQuery = | ||
42 | L"SELECT `RoleForComponent`, `ApplicationRole_`, `Component_` FROM `ComPlusRoleForComponent` WHERE `ComPlusComponent_` = ?"; | ||
43 | LPCWSTR vcsRoleForInterfaceQuery = | ||
44 | L"SELECT `RoleForInterface`, `ApplicationRole_`, `Component_` FROM `ComPlusRoleForInterface` WHERE `Interface_` = ?"; | ||
45 | LPCWSTR vcsRoleForMethodQuery = | ||
46 | L"SELECT `RoleForMethod`, `ApplicationRole_`, `Component_` FROM `ComPlusRoleForMethod` WHERE `Method_` = ?"; | ||
47 | |||
48 | enum eRoleAssignmentQuery { raqKey = 1, raqApplicationRole, raqComponent }; | ||
49 | |||
50 | LPCWSTR vcsModuleComponentsQuery = | ||
51 | L"SELECT `Component`, `ModuleID` FROM `ModuleComponents`"; | ||
52 | LPCWSTR vcsModuleDependencyQuery = | ||
53 | L"SELECT `ModuleID`, `RequiredID` FROM `ModuleDependency`"; | ||
54 | LPCWSTR vcsAssemblyDependencyQuery = | ||
55 | L"SELECT `Assembly_`, `RequiredAssembly_` FROM `ComPlusAssemblyDependency`"; | ||
56 | |||
57 | enum eKeyPairQuery { kpqFirstKey = 1, kpqSecondKey }; | ||
58 | |||
59 | |||
60 | // private structs | ||
61 | |||
62 | struct 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 | |||
70 | struct CPI_DEPENDENCY_CHAIN | ||
71 | { | ||
72 | LPCWSTR pwzKey; | ||
73 | |||
74 | CPI_DEPENDENCY_CHAIN* pPrev; | ||
75 | }; | ||
76 | |||
77 | struct CPI_MODULE | ||
78 | { | ||
79 | WCHAR wzKey[MAX_DARWIN_KEY + 1]; | ||
80 | |||
81 | CPI_MODULE* pPrev; | ||
82 | CPI_MODULE* pNext; | ||
83 | }; | ||
84 | |||
85 | struct CPI_MODULE_LIST | ||
86 | { | ||
87 | CPI_MODULE* pFirst; | ||
88 | CPI_MODULE* pLast; | ||
89 | }; | ||
90 | |||
91 | |||
92 | // property definitions | ||
93 | |||
94 | CPI_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 | |||
129 | CPI_PROPERTY_DEFINITION pdlInterfaceProperties[] = | ||
130 | { | ||
131 | {L"Description", cpptString, 500}, | ||
132 | {L"QueuingEnabled", cpptBoolean, 500}, | ||
133 | {NULL, cpptNone, 0} | ||
134 | }; | ||
135 | |||
136 | CPI_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 | |||
146 | static HRESULT GetAssemblyName( | ||
147 | LPCWSTR pwzComponent, | ||
148 | LPWSTR* ppwzAssemblyName | ||
149 | ); | ||
150 | static HRESULT KeyPairsRead( | ||
151 | LPCWSTR pwzQuery, | ||
152 | CPI_KEY_PAIR** ppKeyPairList | ||
153 | ); | ||
154 | static HRESULT ModulesRead( | ||
155 | CPI_MODULE_LIST* pModList | ||
156 | ); | ||
157 | static HRESULT AssembliesRead( | ||
158 | CPI_KEY_PAIR* pModCompList, | ||
159 | CPI_APPLICATION_LIST* pAppList, | ||
160 | CPI_APPLICATION_ROLE_LIST* pAppRoleList, | ||
161 | CPI_ASSEMBLY_LIST* pAsmList | ||
162 | ); | ||
163 | static HRESULT ComponentsRead( | ||
164 | LPCWSTR pwzAsmKey, | ||
165 | CPI_APPLICATION_ROLE_LIST* pAppRoleList, | ||
166 | CPI_ASSEMBLY* pAsm | ||
167 | ); | ||
168 | static HRESULT InterfacesRead( | ||
169 | LPCWSTR pwzCompKey, | ||
170 | CPI_APPLICATION_ROLE_LIST* pAppRoleList, | ||
171 | CPI_ASSEMBLY* pAsm, | ||
172 | CPISCHED_COMPONENT* pComp | ||
173 | ); | ||
174 | static HRESULT MethodsRead( | ||
175 | LPCWSTR pwzIntfKey, | ||
176 | CPI_APPLICATION_ROLE_LIST* pAppRoleList, | ||
177 | CPI_ASSEMBLY* pAsm, | ||
178 | CPISCHED_INTERFACE* pIntf | ||
179 | ); | ||
180 | static 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 | ); | ||
188 | static HRESULT TopSortModuleList( | ||
189 | CPI_KEY_PAIR* pDepList, | ||
190 | CPI_MODULE_LIST* pList | ||
191 | ); | ||
192 | static 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 | ); | ||
199 | static HRESULT ModuleFindByKey( | ||
200 | CPI_MODULE* pItm, | ||
201 | LPCWSTR pwzKey, | ||
202 | BOOL fReverse, | ||
203 | CPI_MODULE** ppItm | ||
204 | ); | ||
205 | static void SortAssemblyListByModule( | ||
206 | CPI_MODULE_LIST* pModList, | ||
207 | CPI_ASSEMBLY_LIST* pAsmList | ||
208 | ); | ||
209 | static HRESULT TopSortAssemblyList( | ||
210 | CPI_KEY_PAIR* pDepList, | ||
211 | CPI_ASSEMBLY_LIST* pList | ||
212 | ); | ||
213 | static 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 | ); | ||
220 | static HRESULT AssemblyFindByKey( | ||
221 | CPI_ASSEMBLY* pItm, | ||
222 | LPCWSTR pwzKey, | ||
223 | BOOL fReverse, | ||
224 | CPI_ASSEMBLY** ppItm | ||
225 | ); | ||
226 | static HRESULT AddAssemblyToActionData( | ||
227 | CPI_ASSEMBLY* pItm, | ||
228 | BOOL fInstall, | ||
229 | int iActionType, | ||
230 | int iActionCost, | ||
231 | LPWSTR* ppwzActionData | ||
232 | ); | ||
233 | static HRESULT AddRoleAssignmentsToActionData( | ||
234 | CPI_ASSEMBLY* pItm, | ||
235 | BOOL fInstall, | ||
236 | int iActionType, | ||
237 | int iActionCost, | ||
238 | LPWSTR* ppwzActionData | ||
239 | ); | ||
240 | static HRESULT AddComponentToActionData( | ||
241 | CPISCHED_COMPONENT* pItm, | ||
242 | BOOL fInstall, | ||
243 | BOOL fProps, | ||
244 | BOOL fRoles, | ||
245 | LPWSTR* ppwzActionData | ||
246 | ); | ||
247 | static HRESULT AddInterfaceToActionData( | ||
248 | CPISCHED_INTERFACE* pItm, | ||
249 | BOOL fInstall, | ||
250 | BOOL fProps, | ||
251 | BOOL fRoles, | ||
252 | LPWSTR* ppwzActionData | ||
253 | ); | ||
254 | static HRESULT AddMethodToActionData( | ||
255 | CPISCHED_METHOD* pItm, | ||
256 | BOOL fInstall, | ||
257 | BOOL fProps, | ||
258 | BOOL fRoles, | ||
259 | LPWSTR* ppwzActionData | ||
260 | ); | ||
261 | static HRESULT AddRolesToActionData( | ||
262 | int iRoleInstallCount, | ||
263 | int iRoleUninstallCount, | ||
264 | CPISCHED_ROLE_ASSIGNMENT* pRoleList, | ||
265 | BOOL fInstall, | ||
266 | BOOL fRoles, | ||
267 | LPWSTR* ppwzActionData | ||
268 | ); | ||
269 | static HRESULT KeyPairFindByFirstKey( | ||
270 | CPI_KEY_PAIR* pList, | ||
271 | LPCWSTR pwzKey, | ||
272 | CPI_KEY_PAIR** ppItm | ||
273 | ); | ||
274 | static void AssemblyFree( | ||
275 | CPI_ASSEMBLY* pItm | ||
276 | ); | ||
277 | static void KeyPairsFreeList( | ||
278 | CPI_KEY_PAIR* pList | ||
279 | ); | ||
280 | void ModuleListFree( | ||
281 | CPI_MODULE_LIST* pList | ||
282 | ); | ||
283 | static void ModuleFree( | ||
284 | CPI_MODULE* pItm | ||
285 | ); | ||
286 | static void ComponentsFreeList( | ||
287 | CPISCHED_COMPONENT* pList | ||
288 | ); | ||
289 | static void InterfacesFreeList( | ||
290 | CPISCHED_INTERFACE* pList | ||
291 | ); | ||
292 | static void MethodsFreeList( | ||
293 | CPISCHED_METHOD* pList | ||
294 | ); | ||
295 | static void RoleAssignmentsFreeList( | ||
296 | CPISCHED_ROLE_ASSIGNMENT* pList | ||
297 | ); | ||
298 | |||
299 | |||
300 | // function definitions | ||
301 | |||
302 | void 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 | |||
316 | HRESULT 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 | |||
386 | LExit: | ||
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 | |||
399 | HRESULT 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 | |||
418 | LExit: | ||
419 | return hr; | ||
420 | } | ||
421 | |||
422 | HRESULT 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 | |||
449 | HRESULT 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 | |||
517 | LExit: | ||
518 | return hr; | ||
519 | } | ||
520 | |||
521 | HRESULT 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 | |||
564 | LExit: | ||
565 | return hr; | ||
566 | } | ||
567 | |||
568 | HRESULT 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 | |||
636 | LExit: | ||
637 | return hr; | ||
638 | } | ||
639 | |||
640 | HRESULT 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 | |||
683 | LExit: | ||
684 | return hr; | ||
685 | } | ||
686 | |||
687 | HRESULT 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 | |||
726 | LExit: | ||
727 | // clean up | ||
728 | ReleaseObject(piCompColl); | ||
729 | ReleaseObject(piCompObj); | ||
730 | |||
731 | return hr; | ||
732 | } | ||
733 | |||
734 | |||
735 | // helper function definitions | ||
736 | |||
737 | static 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 | |||
805 | LExit: | ||
806 | // clean up | ||
807 | ReleaseStr(pwzKey); | ||
808 | ReleaseStr(pwzName); | ||
809 | ReleaseStr(pwzVersion); | ||
810 | ReleaseStr(pwzCulture); | ||
811 | ReleaseStr(pwzPublicKeyToken); | ||
812 | |||
813 | return hr; | ||
814 | } | ||
815 | |||
816 | static 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 | |||
859 | LExit: | ||
860 | // clean up | ||
861 | if (pItm) | ||
862 | KeyPairsFreeList(pItm); | ||
863 | |||
864 | ReleaseStr(pwzData); | ||
865 | |||
866 | return hr; | ||
867 | } | ||
868 | |||
869 | static 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 | |||
911 | LExit: | ||
912 | // clean up | ||
913 | if (pItm) | ||
914 | ModuleFree(pItm); | ||
915 | |||
916 | ReleaseStr(pwzData); | ||
917 | |||
918 | return hr; | ||
919 | } | ||
920 | |||
921 | static 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 | |||
1067 | LExit: | ||
1068 | // clean up | ||
1069 | if (pItm) | ||
1070 | AssemblyFree(pItm); | ||
1071 | |||
1072 | ReleaseStr(pwzData); | ||
1073 | ReleaseStr(pwzComponent); | ||
1074 | |||
1075 | return hr; | ||
1076 | } | ||
1077 | |||
1078 | static 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 | |||
1095 | LExit: | ||
1096 | return hr; | ||
1097 | } | ||
1098 | |||
1099 | static 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 | |||
1172 | LExit: | ||
1173 | return hr; | ||
1174 | } | ||
1175 | |||
1176 | static 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 | |||
1195 | static 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 | |||
1241 | static 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 | |||
1258 | LExit: | ||
1259 | return hr; | ||
1260 | } | ||
1261 | |||
1262 | static 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 | |||
1342 | LExit: | ||
1343 | return hr; | ||
1344 | } | ||
1345 | |||
1346 | static 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 | |||
1365 | static 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 | |||
1444 | LExit: | ||
1445 | // clean up | ||
1446 | if (pItm) | ||
1447 | ComponentsFreeList(pItm); | ||
1448 | |||
1449 | ReleaseStr(pwzData); | ||
1450 | |||
1451 | return hr; | ||
1452 | } | ||
1453 | |||
1454 | static 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 | |||
1534 | LExit: | ||
1535 | // clean up | ||
1536 | if (pItm) | ||
1537 | InterfacesFreeList(pItm); | ||
1538 | |||
1539 | ReleaseStr(pwzData); | ||
1540 | |||
1541 | return hr; | ||
1542 | } | ||
1543 | |||
1544 | static 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 | |||
1624 | LExit: | ||
1625 | // clean up | ||
1626 | if (pItm) | ||
1627 | MethodsFreeList(pItm); | ||
1628 | |||
1629 | ReleaseStr(pwzData); | ||
1630 | |||
1631 | return hr; | ||
1632 | } | ||
1633 | |||
1634 | static 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 | |||
1724 | LExit: | ||
1725 | // clean up | ||
1726 | if (pItm) | ||
1727 | RoleAssignmentsFreeList(pItm); | ||
1728 | |||
1729 | ReleaseStr(pwzData); | ||
1730 | |||
1731 | return hr; | ||
1732 | } | ||
1733 | |||
1734 | static 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 | |||
1798 | LExit: | ||
1799 | return hr; | ||
1800 | } | ||
1801 | |||
1802 | static 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 | |||
1845 | LExit: | ||
1846 | return hr; | ||
1847 | } | ||
1848 | |||
1849 | static 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 | |||
1887 | LExit: | ||
1888 | return hr; | ||
1889 | } | ||
1890 | |||
1891 | static 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 | |||
1925 | LExit: | ||
1926 | return hr; | ||
1927 | } | ||
1928 | |||
1929 | static 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 | |||
1956 | LExit: | ||
1957 | return hr; | ||
1958 | } | ||
1959 | |||
1960 | static 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 | |||
1993 | LExit: | ||
1994 | return hr; | ||
1995 | } | ||
1996 | |||
1997 | static 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 | |||
2015 | static 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 | |||
2030 | static 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 | |||
2042 | void 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 | |||
2056 | static void ModuleFree( | ||
2057 | CPI_MODULE* pItm | ||
2058 | ) | ||
2059 | { | ||
2060 | ::HeapFree(::GetProcessHeap(), 0, pItm); | ||
2061 | } | ||
2062 | |||
2063 | static 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 | |||
2086 | static 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 | |||
2107 | static 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 | |||
2125 | static 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 | |||
5 | enum eAssemblyAttributes | ||
6 | { | ||
7 | aaEventClass = (1 << 0), | ||
8 | aaDotNetAssembly = (1 << 1), | ||
9 | aaPathFromGAC = (1 << 2), | ||
10 | aaRunInCommit = (1 << 3) | ||
11 | }; | ||
12 | |||
13 | |||
14 | // structs | ||
15 | |||
16 | struct 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 | |||
27 | struct 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 | |||
43 | struct 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 | |||
61 | struct 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 | |||
81 | struct 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 | |||
109 | struct 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 | |||
126 | void CpiAssemblyListFree( | ||
127 | CPI_ASSEMBLY_LIST* pList | ||
128 | ); | ||
129 | HRESULT CpiAssembliesRead( | ||
130 | CPI_APPLICATION_LIST* pAppList, | ||
131 | CPI_APPLICATION_ROLE_LIST* pAppRoleList, | ||
132 | CPI_ASSEMBLY_LIST* pAsmList | ||
133 | ); | ||
134 | HRESULT CpiAssembliesVerifyInstall( | ||
135 | CPI_ASSEMBLY_LIST* pList | ||
136 | ); | ||
137 | HRESULT CpiAssembliesVerifyUninstall( | ||
138 | CPI_ASSEMBLY_LIST* pList | ||
139 | ); | ||
140 | HRESULT CpiAssembliesInstall( | ||
141 | CPI_ASSEMBLY_LIST* pList, | ||
142 | int iRunMode, | ||
143 | LPWSTR* ppwzActionData, | ||
144 | int* piProgress | ||
145 | ); | ||
146 | HRESULT CpiAssembliesUninstall( | ||
147 | CPI_ASSEMBLY_LIST* pList, | ||
148 | int iRunMode, | ||
149 | LPWSTR* ppwzActionData, | ||
150 | int* piProgress | ||
151 | ); | ||
152 | HRESULT CpiRoleAssignmentsInstall( | ||
153 | CPI_ASSEMBLY_LIST* pList, | ||
154 | int iRunMode, | ||
155 | LPWSTR* ppwzActionData, | ||
156 | int* piProgress | ||
157 | ); | ||
158 | HRESULT CpiRoleAssignmentsUninstall( | ||
159 | CPI_ASSEMBLY_LIST* pList, | ||
160 | int iRunMode, | ||
161 | LPWSTR* ppwzActionData, | ||
162 | int* piProgress | ||
163 | ); | ||
164 | HRESULT 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 | ********************************************************************/ | ||
10 | extern "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 | |||
36 | LExit: | ||
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 | ********************************************************************/ | ||
52 | extern "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 | |||
79 | LExit: | ||
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 | ********************************************************************/ | ||
92 | extern "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 | |||
175 | LExit: | ||
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 | ********************************************************************/ | ||
198 | extern "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 | |||
254 | LExit: | ||
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 | ********************************************************************/ | ||
276 | extern "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 | |||
391 | LExit: | ||
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 | ********************************************************************/ | ||
433 | extern "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 | |||
516 | LExit: | ||
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 | ********************************************************************/ | ||
539 | extern "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 | |||
646 | LExit: | ||
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 | |||
8 | struct 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 | |||
18 | struct 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 | |||
30 | static HRESULT ReadPartitionAttributes( | ||
31 | LPWSTR* ppwzData, | ||
32 | CPI_PARTITION_ATTRIBUTES* pAttrs | ||
33 | ); | ||
34 | static void FreePartitionAttributes( | ||
35 | CPI_PARTITION_ATTRIBUTES* pAttrs | ||
36 | ); | ||
37 | static HRESULT CreatePartition( | ||
38 | CPI_PARTITION_ATTRIBUTES* pAttrs | ||
39 | ); | ||
40 | static HRESULT RemovePartition( | ||
41 | CPI_PARTITION_ATTRIBUTES* pAttrs | ||
42 | ); | ||
43 | static HRESULT ReadPartitionUserAttributes( | ||
44 | LPWSTR* ppwzData, | ||
45 | CPI_PARTITION_USER_ATTRIBUTES* pAttrs | ||
46 | ); | ||
47 | static void FreePartitionUserAttributes( | ||
48 | CPI_PARTITION_USER_ATTRIBUTES* pAttrs | ||
49 | ); | ||
50 | static HRESULT CreatePartitionUser( | ||
51 | CPI_PARTITION_USER_ATTRIBUTES* pAttrs | ||
52 | ); | ||
53 | static HRESULT RemovePartitionUser( | ||
54 | CPI_PARTITION_USER_ATTRIBUTES* pAttrs | ||
55 | ); | ||
56 | |||
57 | |||
58 | // function definitions | ||
59 | |||
60 | HRESULT 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 | |||
124 | LExit: | ||
125 | // clean up | ||
126 | FreePartitionAttributes(&attrs); | ||
127 | |||
128 | return hr; | ||
129 | } | ||
130 | |||
131 | HRESULT 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 | |||
197 | LExit: | ||
198 | // clean up | ||
199 | FreePartitionAttributes(&attrs); | ||
200 | |||
201 | return hr; | ||
202 | } | ||
203 | |||
204 | HRESULT 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 | |||
268 | LExit: | ||
269 | // clean up | ||
270 | FreePartitionUserAttributes(&attrs); | ||
271 | |||
272 | return hr; | ||
273 | } | ||
274 | |||
275 | HRESULT 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 | |||
339 | LExit: | ||
340 | // clean up | ||
341 | FreePartitionUserAttributes(&attrs); | ||
342 | |||
343 | return hr; | ||
344 | } | ||
345 | |||
346 | |||
347 | // helper function definitions | ||
348 | |||
349 | static 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 | |||
371 | LExit: | ||
372 | return hr; | ||
373 | } | ||
374 | |||
375 | static 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 | |||
387 | static 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 | |||
437 | LExit: | ||
438 | // clean up | ||
439 | ReleaseObject(piPartColl); | ||
440 | ReleaseObject(piPartObj); | ||
441 | |||
442 | return hr; | ||
443 | } | ||
444 | |||
445 | static 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 | |||
484 | LExit: | ||
485 | // clean up | ||
486 | ReleaseObject(piPartColl); | ||
487 | |||
488 | return hr; | ||
489 | } | ||
490 | |||
491 | static 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 | |||
511 | LExit: | ||
512 | return hr; | ||
513 | } | ||
514 | |||
515 | static void FreePartitionUserAttributes( | ||
516 | CPI_PARTITION_USER_ATTRIBUTES* pAttrs | ||
517 | ) | ||
518 | { | ||
519 | ReleaseStr(pAttrs->pwzKey); | ||
520 | ReleaseStr(pAttrs->pwzAccount); | ||
521 | ReleaseStr(pAttrs->pwzPartID); | ||
522 | } | ||
523 | |||
524 | static 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 | |||
601 | LExit: | ||
602 | // clean up | ||
603 | ReleaseObject(piUserColl); | ||
604 | ReleaseObject(piUserObj); | ||
605 | |||
606 | if (pSid) | ||
607 | ::HeapFree(::GetProcessHeap(), 0, pSid); | ||
608 | |||
609 | return hr; | ||
610 | } | ||
611 | |||
612 | static 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 | |||
682 | LExit: | ||
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 | |||
5 | HRESULT CpiConfigurePartitions( | ||
6 | LPWSTR* ppwzData, | ||
7 | HANDLE hRollbackFile | ||
8 | ); | ||
9 | HRESULT CpiRollbackConfigurePartitions( | ||
10 | LPWSTR* ppwzData, | ||
11 | CPI_ROLLBACK_DATA* pRollbackDataList | ||
12 | ); | ||
13 | HRESULT CpiConfigurePartitionUsers( | ||
14 | LPWSTR* ppwzData, | ||
15 | HANDLE hRollbackFile | ||
16 | ); | ||
17 | HRESULT 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 | |||
8 | struct 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 | |||
21 | static HRESULT ReadUserInPartitionRoleAttributes( | ||
22 | LPWSTR* ppwzData, | ||
23 | CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs | ||
24 | ); | ||
25 | static void FreeUserInPartitionRoleAttributes( | ||
26 | CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs | ||
27 | ); | ||
28 | static HRESULT CreateUserInPartitionRole( | ||
29 | CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs | ||
30 | ); | ||
31 | static HRESULT RemoveUserInPartitionRole( | ||
32 | CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs | ||
33 | ); | ||
34 | |||
35 | |||
36 | // function definitions | ||
37 | |||
38 | HRESULT 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 | |||
102 | LExit: | ||
103 | // clean up | ||
104 | FreeUserInPartitionRoleAttributes(&attrs); | ||
105 | |||
106 | return hr; | ||
107 | } | ||
108 | |||
109 | HRESULT 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 | |||
175 | LExit: | ||
176 | // clean up | ||
177 | FreeUserInPartitionRoleAttributes(&attrs); | ||
178 | |||
179 | return hr; | ||
180 | } | ||
181 | |||
182 | |||
183 | // helper function definitions | ||
184 | |||
185 | static 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 | |||
207 | LExit: | ||
208 | return hr; | ||
209 | } | ||
210 | |||
211 | static 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 | |||
221 | static 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 | |||
301 | LExit: | ||
302 | // clean up | ||
303 | ReleaseObject(piUsrInRoleColl); | ||
304 | ReleaseObject(piUsrInRoleObj); | ||
305 | |||
306 | if (pSid) | ||
307 | ::HeapFree(::GetProcessHeap(), 0, pSid); | ||
308 | |||
309 | return hr; | ||
310 | } | ||
311 | |||
312 | static 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 | |||
389 | LExit: | ||
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 | |||
5 | HRESULT CpiConfigureUsersInPartitionRoles( | ||
6 | LPWSTR* ppwzData, | ||
7 | HANDLE hRollbackFile | ||
8 | ); | ||
9 | HRESULT 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 | |||
8 | LPCWSTR vcsPartitionRoleQuery = | ||
9 | L"SELECT `PartitionRole`, `Partition_`, `Component_`, `Name` FROM `ComPlusPartitionRole`"; | ||
10 | enum ePartitionRoleQuery { prqPartitionRole = 1, prqPartition, prqComponent, prqName }; | ||
11 | |||
12 | LPCWSTR vcsUserInPartitionRoleQuery = | ||
13 | L"SELECT `UserInPartitionRole`, `PartitionRole_`, `ComPlusUserInPartitionRole`.`Component_`, `Domain`, `Name` FROM `ComPlusUserInPartitionRole`, `User` WHERE `User_` = `User`"; | ||
14 | LPCWSTR vcsGroupInPartitionRoleQuery = | ||
15 | L"SELECT `GroupInPartitionRole`, `PartitionRole_`, `ComPlusGroupInPartitionRole`.`Component_`, `Domain`, `Name` FROM `ComPlusGroupInPartitionRole`, `Group` WHERE `Group_` = `Group`"; | ||
16 | enum eTrusteeInPartitionRoleQuery { tiprqUserInPartitionRole = 1, tiprqPartitionRole, tiprqComponent, tiprqDomain, tiprqName }; | ||
17 | |||
18 | |||
19 | // prototypes for private helper functions | ||
20 | |||
21 | static HRESULT TrusteesInPartitionRolesRead( | ||
22 | LPCWSTR pwzQuery, | ||
23 | CPI_PARTITION_ROLE_LIST* pPartRoleList, | ||
24 | CPI_USER_IN_PARTITION_ROLE_LIST* pUsrInPartRoleList | ||
25 | ); | ||
26 | static void FreePartitionRole( | ||
27 | CPI_PARTITION_ROLE* pItm | ||
28 | ); | ||
29 | static void FreeUserInPartitionRole( | ||
30 | CPI_USER_IN_PARTITION_ROLE* pItm | ||
31 | ); | ||
32 | static 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 | |||
42 | void 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 | |||
56 | HRESULT 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 | |||
106 | LExit: | ||
107 | // clean up | ||
108 | if (pItm) | ||
109 | FreePartitionRole(pItm); | ||
110 | |||
111 | ReleaseStr(pwzData); | ||
112 | |||
113 | return hr; | ||
114 | } | ||
115 | |||
116 | HRESULT 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 | |||
134 | void 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 | |||
148 | HRESULT 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 | |||
171 | LExit: | ||
172 | return hr; | ||
173 | } | ||
174 | |||
175 | HRESULT 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 | |||
223 | LExit: | ||
224 | return hr; | ||
225 | } | ||
226 | |||
227 | HRESULT 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 | |||
270 | LExit: | ||
271 | return hr; | ||
272 | } | ||
273 | |||
274 | |||
275 | // helper function definitions | ||
276 | |||
277 | static 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 | |||
362 | LExit: | ||
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 | |||
374 | static void FreePartitionRole( | ||
375 | CPI_PARTITION_ROLE* pItm | ||
376 | ) | ||
377 | { | ||
378 | ::HeapFree(::GetProcessHeap(), 0, pItm); | ||
379 | } | ||
380 | |||
381 | static void FreeUserInPartitionRole( | ||
382 | CPI_USER_IN_PARTITION_ROLE* pItm | ||
383 | ) | ||
384 | { | ||
385 | ReleaseStr(pItm->pwzAccount); | ||
386 | |||
387 | ::HeapFree(::GetProcessHeap(), 0, pItm); | ||
388 | } | ||
389 | |||
390 | static 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 | |||
419 | LExit: | ||
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 | |||
5 | struct 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 | |||
17 | struct CPI_PARTITION_ROLE_LIST | ||
18 | { | ||
19 | CPI_PARTITION_ROLE* pFirst; | ||
20 | }; | ||
21 | |||
22 | struct 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 | |||
34 | struct 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 | |||
45 | void CpiPartitionRoleListFree( | ||
46 | CPI_PARTITION_ROLE_LIST* pList | ||
47 | ); | ||
48 | HRESULT CpiPartitionRolesRead( | ||
49 | CPI_PARTITION_LIST* pPartList, | ||
50 | CPI_PARTITION_ROLE_LIST* pPartRoleList | ||
51 | ); | ||
52 | HRESULT CpiPartitionRoleFindByKey( | ||
53 | CPI_PARTITION_ROLE_LIST* pList, | ||
54 | LPCWSTR pwzKey, | ||
55 | CPI_PARTITION_ROLE** ppPartRole | ||
56 | ); | ||
57 | |||
58 | void CpiUserInPartitionRoleListFree( | ||
59 | CPI_USER_IN_PARTITION_ROLE_LIST* pList | ||
60 | ); | ||
61 | HRESULT CpiUsersInPartitionRolesRead( | ||
62 | CPI_PARTITION_ROLE_LIST* pPartRoleList, | ||
63 | CPI_USER_IN_PARTITION_ROLE_LIST* pUsrInPartRoleList | ||
64 | ); | ||
65 | HRESULT CpiUsersInPartitionRolesInstall( | ||
66 | CPI_USER_IN_PARTITION_ROLE_LIST* pList, | ||
67 | int iRunMode, | ||
68 | LPWSTR* ppwzActionData, | ||
69 | int* piProgress | ||
70 | ); | ||
71 | HRESULT 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 | |||
8 | LPCWSTR vcsPartitionQuery = | ||
9 | L"SELECT `Partition`, `Component_`, `Id`, `Name` FROM `ComPlusPartition`"; | ||
10 | enum ePartitionQuery { pqPartition = 1, pqComponent, pqID, pqName }; | ||
11 | |||
12 | LPCWSTR vcsPartitionPropertyQuery = | ||
13 | L"SELECT `Name`, `Value` FROM `ComPlusPartitionProperty` WHERE `Partition_` = ?"; | ||
14 | |||
15 | LPCWSTR vcsPartitionUserQuery = | ||
16 | L"SELECT `PartitionUser`, `Partition_`, `ComPlusPartitionUser`.`Component_`, `Domain`, `Name` FROM `ComPlusPartitionUser`, `User` WHERE `User_` = `User`"; | ||
17 | enum ePartitionUserQuery { puqPartitionUser = 1, puqPartition, puqComponent, puqDomain, puqName }; | ||
18 | |||
19 | |||
20 | // property definitions | ||
21 | |||
22 | CPI_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 | |||
33 | static void FreePartition( | ||
34 | CPI_PARTITION* pItm | ||
35 | ); | ||
36 | static void FreePartitionUser( | ||
37 | CPI_PARTITION_USER* pItm | ||
38 | ); | ||
39 | static HRESULT AddPartitionToActionData( | ||
40 | CPI_PARTITION* pItm, | ||
41 | int iActionType, | ||
42 | int iActionCost, | ||
43 | LPWSTR* ppwzActionData | ||
44 | ); | ||
45 | static HRESULT AddPartitionUserToActionData( | ||
46 | CPI_PARTITION_USER* pItm, | ||
47 | int iActionType, | ||
48 | int iActionCost, | ||
49 | LPWSTR* ppwzActionData | ||
50 | ); | ||
51 | |||
52 | |||
53 | // function definitions | ||
54 | |||
55 | void 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 | |||
69 | HRESULT 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 | |||
169 | LExit: | ||
170 | // clean up | ||
171 | if (pItm) | ||
172 | FreePartition(pItm); | ||
173 | |||
174 | ReleaseStr(pwzData); | ||
175 | |||
176 | return hr; | ||
177 | } | ||
178 | |||
179 | HRESULT 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 | |||
314 | LExit: | ||
315 | // clean up | ||
316 | ReleaseObject(piPartColl); | ||
317 | ReleaseObject(piPartObj); | ||
318 | |||
319 | return hr; | ||
320 | } | ||
321 | |||
322 | HRESULT 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 | |||
372 | LExit: | ||
373 | // clean up | ||
374 | ReleaseObject(piPartColl); | ||
375 | ReleaseObject(piPartObj); | ||
376 | |||
377 | return hr; | ||
378 | } | ||
379 | |||
380 | void CpiPartitionAddReferenceInstall( | ||
381 | CPI_PARTITION* pItm | ||
382 | ) | ||
383 | { | ||
384 | pItm->fReferencedForInstall = TRUE; | ||
385 | } | ||
386 | |||
387 | void CpiPartitionAddReferenceUninstall( | ||
388 | CPI_PARTITION* pItm | ||
389 | ) | ||
390 | { | ||
391 | pItm->fReferencedForUninstall = TRUE; | ||
392 | } | ||
393 | |||
394 | HRESULT 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 | |||
442 | LExit: | ||
443 | return hr; | ||
444 | } | ||
445 | |||
446 | HRESULT 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 | |||
489 | LExit: | ||
490 | return hr; | ||
491 | } | ||
492 | |||
493 | HRESULT 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 | |||
511 | HRESULT 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 | |||
553 | LExit: | ||
554 | // clean up | ||
555 | ReleaseObject(piPartColl); | ||
556 | ReleaseObject(piPartObj); | ||
557 | |||
558 | return hr; | ||
559 | } | ||
560 | |||
561 | HRESULT 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 | |||
600 | LExit: | ||
601 | // clean up | ||
602 | ReleaseObject(piPartColl); | ||
603 | ReleaseObject(piPartObj); | ||
604 | |||
605 | return hr; | ||
606 | } | ||
607 | |||
608 | void 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 | |||
622 | HRESULT 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 | |||
714 | LExit: | ||
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 | |||
726 | HRESULT 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 | |||
774 | LExit: | ||
775 | return hr; | ||
776 | } | ||
777 | |||
778 | HRESULT 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 | |||
821 | LExit: | ||
822 | return hr; | ||
823 | } | ||
824 | |||
825 | |||
826 | // helper function definitions | ||
827 | |||
828 | static 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 | |||
841 | static void FreePartitionUser( | ||
842 | CPI_PARTITION_USER* pItm | ||
843 | ) | ||
844 | { | ||
845 | ReleaseStr(pItm->pwzAccount); | ||
846 | |||
847 | ::HeapFree(::GetProcessHeap(), 0, pItm); | ||
848 | } | ||
849 | |||
850 | static 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 | |||
879 | LExit: | ||
880 | return hr; | ||
881 | } | ||
882 | |||
883 | static 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 | |||
910 | LExit: | ||
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 | |||
5 | struct 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 | |||
27 | struct CPI_PARTITION_LIST | ||
28 | { | ||
29 | CPI_PARTITION* pFirst; | ||
30 | |||
31 | int iInstallCount; | ||
32 | int iUninstallCount; | ||
33 | }; | ||
34 | |||
35 | struct 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 | |||
49 | struct CPI_PARTITION_USER_LIST | ||
50 | { | ||
51 | CPI_PARTITION_USER* pFirst; | ||
52 | |||
53 | int iInstallCount; | ||
54 | int iUninstallCount; | ||
55 | }; | ||
56 | |||
57 | |||
58 | // function prototypes | ||
59 | |||
60 | void CpiPartitionListFree( | ||
61 | CPI_PARTITION_LIST* pList | ||
62 | ); | ||
63 | HRESULT CpiPartitionsRead( | ||
64 | CPI_PARTITION_LIST* pPartList | ||
65 | ); | ||
66 | HRESULT CpiPartitionsVerifyInstall( | ||
67 | CPI_PARTITION_LIST* pList | ||
68 | ); | ||
69 | HRESULT CpiPartitionsVerifyUninstall( | ||
70 | CPI_PARTITION_LIST* pList | ||
71 | ); | ||
72 | void CpiPartitionAddReferenceInstall( | ||
73 | CPI_PARTITION* pItm | ||
74 | ); | ||
75 | void CpiPartitionAddReferenceUninstall( | ||
76 | CPI_PARTITION* pItm | ||
77 | ); | ||
78 | HRESULT CpiPartitionsInstall( | ||
79 | CPI_PARTITION_LIST* pList, | ||
80 | int iRunMode, | ||
81 | LPWSTR* ppwzActionData, | ||
82 | int* piProgress | ||
83 | ); | ||
84 | HRESULT CpiPartitionsUninstall( | ||
85 | CPI_PARTITION_LIST* pList, | ||
86 | int iRunMode, | ||
87 | LPWSTR* ppwzActionData, | ||
88 | int* piProgress | ||
89 | ); | ||
90 | HRESULT CpiPartitionFindByKey( | ||
91 | CPI_PARTITION_LIST* pList, | ||
92 | LPCWSTR wzKey, | ||
93 | CPI_PARTITION** ppItm | ||
94 | ); | ||
95 | HRESULT CpiGetApplicationsCollForPartition( | ||
96 | CPI_PARTITION* pPart, | ||
97 | ICatalogCollection** ppiAppColl | ||
98 | ); | ||
99 | HRESULT CpiGetPartitionUsersCollection( | ||
100 | CPI_PARTITION* pPart, | ||
101 | ICatalogCollection** ppiPartUsrColl | ||
102 | ); | ||
103 | HRESULT CpiGetRolesCollForPartition( | ||
104 | CPI_PARTITION* pPart, | ||
105 | ICatalogCollection** ppiRolesColl | ||
106 | ); | ||
107 | void CpiPartitionUserListFree( | ||
108 | CPI_PARTITION_USER_LIST* pList | ||
109 | ); | ||
110 | HRESULT CpiPartitionUsersRead( | ||
111 | CPI_PARTITION_LIST* pPartList, | ||
112 | CPI_PARTITION_USER_LIST* pPartUsrList | ||
113 | ); | ||
114 | HRESULT CpiPartitionUsersInstall( | ||
115 | CPI_PARTITION_USER_LIST* pList, | ||
116 | int iRunMode, | ||
117 | LPWSTR* ppwzActionData, | ||
118 | int* piProgress | ||
119 | ); | ||
120 | HRESULT 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 | ********************************************************************/ | ||
36 | extern "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 | |||
279 | LExit: | ||
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 | ********************************************************************/ | ||
313 | extern "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 | |||
540 | LExit: | ||
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 | |||
8 | struct 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 | |||
26 | static HRESULT ReadSubscriptionAttributes( | ||
27 | LPWSTR* ppwzData, | ||
28 | CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs | ||
29 | ); | ||
30 | static void FreeSubscriptionAttributes( | ||
31 | CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs | ||
32 | ); | ||
33 | static HRESULT CreateSubscription( | ||
34 | CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs | ||
35 | ); | ||
36 | static HRESULT RemoveSubscription( | ||
37 | CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs | ||
38 | ); | ||
39 | |||
40 | |||
41 | // function definitions | ||
42 | |||
43 | HRESULT 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 | |||
107 | LExit: | ||
108 | // clean up | ||
109 | FreeSubscriptionAttributes(&attrs); | ||
110 | |||
111 | return hr; | ||
112 | } | ||
113 | |||
114 | HRESULT 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 | |||
180 | LExit: | ||
181 | // clean up | ||
182 | FreeSubscriptionAttributes(&attrs); | ||
183 | |||
184 | return hr; | ||
185 | } | ||
186 | |||
187 | |||
188 | // helper function definitions | ||
189 | |||
190 | static 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 | |||
223 | LExit: | ||
224 | return hr; | ||
225 | } | ||
226 | |||
227 | static 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 | |||
244 | static 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 | |||
356 | LExit: | ||
357 | // clean up | ||
358 | ReleaseObject(piSubsColl); | ||
359 | ReleaseObject(piSubsObj); | ||
360 | |||
361 | if (pSid) | ||
362 | ::HeapFree(::GetProcessHeap(), 0, pSid); | ||
363 | |||
364 | return hr; | ||
365 | } | ||
366 | |||
367 | static 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 | |||
406 | LExit: | ||
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 | |||
5 | HRESULT CpiConfigureSubscriptions( | ||
6 | LPWSTR* ppwzData, | ||
7 | HANDLE hRollbackFile | ||
8 | ); | ||
9 | HRESULT 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 | |||
8 | LPCWSTR vcsSubscriptionQuery = | ||
9 | L"SELECT `Subscription`, `ComPlusComponent_`, `Component_`, `Id`, `Name`, `EventCLSID`, `PublisherID` FROM `ComPlusSubscription`"; | ||
10 | enum eSubscriptionQuery { sqSubscription = 1, sqComPlusComponent, sqComponent, sqID, sqName, sqEventCLSID, sqPublisherID }; | ||
11 | |||
12 | LPCWSTR vcsSubscriptionPropertyQuery = | ||
13 | L"SELECT `Name`, `Value` FROM `ComPlusSubscriptionProperty` WHERE `Subscription_` = ?"; | ||
14 | |||
15 | |||
16 | // property definitions | ||
17 | |||
18 | CPI_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 | |||
37 | static void FreeSubscription( | ||
38 | CPI_SUBSCRIPTION* pItm | ||
39 | ); | ||
40 | static HRESULT FindObjectForSubscription( | ||
41 | CPI_SUBSCRIPTION* pItm, | ||
42 | BOOL fFindId, | ||
43 | BOOL fFindName, | ||
44 | ICatalogObject** ppiSubsObj | ||
45 | ); | ||
46 | static HRESULT AddSubscriptionToActionData( | ||
47 | CPI_SUBSCRIPTION* pItm, | ||
48 | int iActionType, | ||
49 | int iActionCost, | ||
50 | LPWSTR* ppwzActionData | ||
51 | ); | ||
52 | static 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 | |||
62 | void 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 | |||
76 | HRESULT 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 | |||
193 | LExit: | ||
194 | // clean up | ||
195 | if (pItm) | ||
196 | FreeSubscription(pItm); | ||
197 | |||
198 | ReleaseStr(pwzData); | ||
199 | |||
200 | return hr; | ||
201 | } | ||
202 | |||
203 | HRESULT 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 | |||
320 | LExit: | ||
321 | // clean up | ||
322 | ReleaseObject(piSubsObj); | ||
323 | |||
324 | return hr; | ||
325 | } | ||
326 | |||
327 | HRESULT 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 | |||
368 | LExit: | ||
369 | // clean up | ||
370 | ReleaseObject(piSubsObj); | ||
371 | |||
372 | return hr; | ||
373 | } | ||
374 | |||
375 | HRESULT 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 | |||
440 | LExit: | ||
441 | return hr; | ||
442 | } | ||
443 | |||
444 | HRESULT 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 | |||
487 | LExit: | ||
488 | return hr; | ||
489 | } | ||
490 | |||
491 | |||
492 | // helper function definitions | ||
493 | |||
494 | static void FreeSubscription( | ||
495 | CPI_SUBSCRIPTION* pItm | ||
496 | ) | ||
497 | { | ||
498 | if (pItm->pProperties) | ||
499 | CpiPropertiesFreeList(pItm->pProperties); | ||
500 | |||
501 | ::HeapFree(::GetProcessHeap(), 0, pItm); | ||
502 | } | ||
503 | |||
504 | static 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 | |||
528 | LExit: | ||
529 | // clean up | ||
530 | ReleaseObject(piSubsColl); | ||
531 | |||
532 | return hr; | ||
533 | } | ||
534 | |||
535 | static 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 | |||
581 | LExit: | ||
582 | return hr; | ||
583 | } | ||
584 | |||
585 | static 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 | |||
5 | struct 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 | |||
26 | struct 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 | |||
38 | void CpiSubscriptionListFree( | ||
39 | CPI_SUBSCRIPTION_LIST* pList | ||
40 | ); | ||
41 | HRESULT CpiSubscriptionsRead( | ||
42 | CPI_ASSEMBLY_LIST* pAsmList, | ||
43 | CPI_SUBSCRIPTION_LIST* pSubList | ||
44 | ); | ||
45 | HRESULT CpiSubscriptionsVerifyInstall( | ||
46 | CPI_SUBSCRIPTION_LIST* pList | ||
47 | ); | ||
48 | HRESULT CpiSubscriptionsVerifyUninstall( | ||
49 | CPI_SUBSCRIPTION_LIST* pList | ||
50 | ); | ||
51 | HRESULT CpiSubscriptionsInstall( | ||
52 | CPI_SUBSCRIPTION_LIST* pList, | ||
53 | int iRunMode, | ||
54 | LPWSTR* ppwzActionData, | ||
55 | int* piProgress | ||
56 | ); | ||
57 | HRESULT 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 | |||
8 | struct 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 | |||
19 | CPI_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 | |||
35 | static HRESULT FindUserCollectionObjectIndex( | ||
36 | ICatalogCollection* piColl, | ||
37 | PSID pSid, | ||
38 | int* pi | ||
39 | ); | ||
40 | static HRESULT CreateSidFromDomainRidPair( | ||
41 | PSID pDomainSid, | ||
42 | DWORD dwRid, | ||
43 | PSID* ppSid | ||
44 | ); | ||
45 | static HRESULT InitLsaUnicodeString( | ||
46 | PLSA_UNICODE_STRING plusStr, | ||
47 | LPCWSTR pwzStr, | ||
48 | DWORD dwLen | ||
49 | ); | ||
50 | static void FreeLsaUnicodeString( | ||
51 | PLSA_UNICODE_STRING plusStr | ||
52 | ); | ||
53 | static HRESULT WriteFileAll( | ||
54 | HANDLE hFile, | ||
55 | PBYTE pbBuffer, | ||
56 | DWORD dwBufferLength | ||
57 | ); | ||
58 | static HRESULT ReadFileAll( | ||
59 | HANDLE hFile, | ||
60 | PBYTE pbBuffer, | ||
61 | DWORD dwBufferLength | ||
62 | ); | ||
63 | |||
64 | |||
65 | // variables | ||
66 | |||
67 | static ICOMAdminCatalog* gpiCatalog; | ||
68 | |||
69 | |||
70 | // function definitions | ||
71 | |||
72 | void CpiExecInitialize() | ||
73 | { | ||
74 | // collections | ||
75 | gpiCatalog = NULL; | ||
76 | } | ||
77 | |||
78 | void CpiExecFinalize() | ||
79 | { | ||
80 | // collections | ||
81 | ReleaseObject(gpiCatalog); | ||
82 | } | ||
83 | |||
84 | HRESULT 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 | |||
138 | LExit: | ||
139 | // clean up | ||
140 | ReleaseStr(pwzData); | ||
141 | |||
142 | return hr; | ||
143 | } | ||
144 | |||
145 | HRESULT 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 | |||
186 | LExit: | ||
187 | return hr; | ||
188 | } | ||
189 | |||
190 | HRESULT 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 | |||
209 | LExit: | ||
210 | return hr; | ||
211 | } | ||
212 | |||
213 | HRESULT 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 | |||
270 | LExit: | ||
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 | |||
285 | HRESULT 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 | |||
320 | LExit: | ||
321 | // clean up | ||
322 | ReleaseObject(piCatalog); | ||
323 | ReleaseObject(piDisp); | ||
324 | ReleaseBSTR(bstrName); | ||
325 | |||
326 | return hr; | ||
327 | } | ||
328 | |||
329 | HRESULT 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 | |||
373 | LExit: | ||
374 | // clean up | ||
375 | ReleaseObject(piCatalog); | ||
376 | ReleaseObject(piDisp); | ||
377 | ReleaseBSTR(bstrName); | ||
378 | ::VariantClear(&vtKey); | ||
379 | |||
380 | return hr; | ||
381 | } | ||
382 | |||
383 | HRESULT 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 | |||
400 | LExit: | ||
401 | // clean up | ||
402 | ReleaseObject(piDisp); | ||
403 | |||
404 | return hr; | ||
405 | } | ||
406 | |||
407 | HRESULT 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 | |||
435 | LExit: | ||
436 | // clean up | ||
437 | ReleaseBSTR(bstrPropName); | ||
438 | ::VariantClear(&vtVal); | ||
439 | |||
440 | return hr; | ||
441 | } | ||
442 | |||
443 | HRESULT 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 | |||
459 | LExit: | ||
460 | return hr; | ||
461 | } | ||
462 | |||
463 | HRESULT 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 | |||
492 | LExit: | ||
493 | // clean up | ||
494 | ReleaseBSTR(bstrPropName); | ||
495 | ::VariantClear(&vtVal); | ||
496 | |||
497 | return hr; | ||
498 | } | ||
499 | |||
500 | HRESULT 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 | |||
544 | LExit: | ||
545 | // clean up | ||
546 | ReleaseBSTR(bstrPropName); | ||
547 | ::VariantClear(&vtVal); | ||
548 | |||
549 | return hr; | ||
550 | } | ||
551 | |||
552 | HRESULT 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 | |||
634 | LExit: | ||
635 | // clean up | ||
636 | ReleaseObject(piDisp); | ||
637 | ReleaseObject(piObj); | ||
638 | |||
639 | ::VariantClear(&vtVal); | ||
640 | |||
641 | return hr; | ||
642 | } | ||
643 | |||
644 | HRESULT 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 | |||
666 | LExit: | ||
667 | return hr; | ||
668 | } | ||
669 | |||
670 | HRESULT 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 | |||
723 | LExit: | ||
724 | // clean up | ||
725 | ReleaseObject(piDisp); | ||
726 | ReleaseObject(piObj); | ||
727 | |||
728 | ::VariantClear(&vtVal); | ||
729 | |||
730 | return hr; | ||
731 | } | ||
732 | |||
733 | HRESULT 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 | |||
786 | LExit: | ||
787 | // clean up | ||
788 | ReleaseObject(piDisp); | ||
789 | ReleaseObject(piObj); | ||
790 | |||
791 | ::VariantClear(&vtVal); | ||
792 | |||
793 | return hr; | ||
794 | } | ||
795 | |||
796 | HRESULT 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 | |||
849 | LExit: | ||
850 | // clean up | ||
851 | ReleaseObject(piDisp); | ||
852 | ReleaseObject(piObj); | ||
853 | |||
854 | ::VariantClear(&vtVal); | ||
855 | |||
856 | return hr; | ||
857 | } | ||
858 | |||
859 | HRESULT 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 | |||
890 | LExit: | ||
891 | // clean up | ||
892 | ReleaseObject(piDisp); | ||
893 | |||
894 | return hr; | ||
895 | } | ||
896 | |||
897 | HRESULT 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 | |||
909 | LExit: | ||
910 | return hr; | ||
911 | } | ||
912 | |||
913 | HRESULT 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 | |||
943 | LExit: | ||
944 | // clean up | ||
945 | ReleaseObject(piPartColl); | ||
946 | ReleaseObject(piPartObj); | ||
947 | |||
948 | return hr; | ||
949 | } | ||
950 | |||
951 | HRESULT 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 | |||
982 | LExit: | ||
983 | // clean up | ||
984 | ReleaseObject(piRoleColl); | ||
985 | ReleaseObject(piRoleObj); | ||
986 | |||
987 | return hr; | ||
988 | } | ||
989 | |||
990 | HRESULT 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 | |||
1002 | LExit: | ||
1003 | return hr; | ||
1004 | } | ||
1005 | |||
1006 | HRESULT 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 | |||
1070 | LExit: | ||
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 | |||
1082 | HRESULT 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 | |||
1113 | LExit: | ||
1114 | // clean up | ||
1115 | ReleaseObject(piAppColl); | ||
1116 | ReleaseObject(piAppObj); | ||
1117 | |||
1118 | return hr; | ||
1119 | } | ||
1120 | |||
1121 | HRESULT 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 | |||
1153 | LExit: | ||
1154 | // clean up | ||
1155 | ReleaseObject(piRoleColl); | ||
1156 | ReleaseObject(piRoleObj); | ||
1157 | |||
1158 | return hr; | ||
1159 | } | ||
1160 | |||
1161 | HRESULT 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 | |||
1192 | LExit: | ||
1193 | // clean up | ||
1194 | ReleaseObject(piAppColl); | ||
1195 | ReleaseObject(piAppObj); | ||
1196 | |||
1197 | return hr; | ||
1198 | } | ||
1199 | |||
1200 | HRESULT 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 | |||
1214 | LExit: | ||
1215 | return hr; | ||
1216 | } | ||
1217 | |||
1218 | HRESULT 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 | |||
1232 | LExit: | ||
1233 | return hr; | ||
1234 | } | ||
1235 | |||
1236 | HRESULT 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 | |||
1268 | LExit: | ||
1269 | // clean up | ||
1270 | ReleaseObject(piCompColl); | ||
1271 | ReleaseObject(piCompObj); | ||
1272 | |||
1273 | return hr; | ||
1274 | } | ||
1275 | |||
1276 | HRESULT 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 | |||
1321 | LExit: | ||
1322 | // clean up | ||
1323 | ReleaseStr(pwzName); | ||
1324 | |||
1325 | if (pItm) | ||
1326 | CpiFreePropertyList(pItm); | ||
1327 | |||
1328 | return hr; | ||
1329 | } | ||
1330 | |||
1331 | void 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 | |||
1345 | HRESULT 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 | |||
1364 | LExit: | ||
1365 | return hr; | ||
1366 | } | ||
1367 | |||
1368 | HRESULT 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 | |||
1382 | LExit: | ||
1383 | return hr; | ||
1384 | } | ||
1385 | |||
1386 | HRESULT 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 | |||
1431 | LExit: | ||
1432 | // clean up | ||
1433 | if (pItm) | ||
1434 | CpiFreeRollbackDataList(pItm); | ||
1435 | |||
1436 | return hr; | ||
1437 | } | ||
1438 | |||
1439 | void 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 | |||
1451 | HRESULT 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 | |||
1470 | LExit: | ||
1471 | return hr; | ||
1472 | } | ||
1473 | |||
1474 | HRESULT 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 | |||
1543 | LExit: | ||
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 | |||
1558 | HRESULT 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 | |||
1606 | LExit: | ||
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 | |||
1623 | static 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 | |||
1726 | LExit: | ||
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 | |||
1752 | static 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 | |||
1795 | LExit: | ||
1796 | return hr; | ||
1797 | } | ||
1798 | |||
1799 | static 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 | |||
1818 | LExit: | ||
1819 | return hr; | ||
1820 | } | ||
1821 | |||
1822 | static void FreeLsaUnicodeString( | ||
1823 | PLSA_UNICODE_STRING plusStr | ||
1824 | ) | ||
1825 | { | ||
1826 | if (plusStr->Buffer) | ||
1827 | ::HeapFree(::GetProcessHeap(), 0, plusStr->Buffer); | ||
1828 | } | ||
1829 | |||
1830 | static 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 | |||
1851 | LExit: | ||
1852 | return hr; | ||
1853 | } | ||
1854 | |||
1855 | static 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 | |||
1879 | LExit: | ||
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 | |||
7 | enum eActionType { atNoOp = 0, atCreate, atRemove }; | ||
8 | |||
9 | |||
10 | // structs | ||
11 | |||
12 | struct CPI_PROPERTY | ||
13 | { | ||
14 | WCHAR wzName[MAX_DARWIN_KEY + 1]; | ||
15 | LPWSTR pwzValue; | ||
16 | |||
17 | CPI_PROPERTY* pNext; | ||
18 | }; | ||
19 | |||
20 | struct 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 | |||
31 | void CpiExecInitialize(); | ||
32 | void CpiExecFinalize(); | ||
33 | HRESULT CpiActionStartMessage( | ||
34 | LPWSTR* ppwzActionData, | ||
35 | BOOL fSuppress | ||
36 | ); | ||
37 | HRESULT CpiActionDataMessage( | ||
38 | DWORD cArgs, | ||
39 | ... | ||
40 | ); | ||
41 | HRESULT CpiExecGetAdminCatalog( | ||
42 | ICOMAdminCatalog** ppiCatalog | ||
43 | ); | ||
44 | HRESULT CpiLogCatalogErrorInfo(); | ||
45 | HRESULT CpiExecGetCatalogCollection( | ||
46 | LPCWSTR pwzName, | ||
47 | ICatalogCollection** ppiColl | ||
48 | ); | ||
49 | HRESULT CpiExecGetCatalogCollection( | ||
50 | ICatalogCollection* piColl, | ||
51 | ICatalogObject* piObj, | ||
52 | LPCWSTR pwzName, | ||
53 | ICatalogCollection** ppiColl | ||
54 | ); | ||
55 | HRESULT CpiAddCollectionObject( | ||
56 | ICatalogCollection* piColl, | ||
57 | ICatalogObject** ppiObj | ||
58 | ); | ||
59 | HRESULT CpiPutCollectionObjectValue( | ||
60 | ICatalogObject* piObj, | ||
61 | LPCWSTR pwzPropName, | ||
62 | LPCWSTR pwzValue | ||
63 | ); | ||
64 | HRESULT CpiPutCollectionObjectValues( | ||
65 | ICatalogObject* piObj, | ||
66 | CPI_PROPERTY* pPropList | ||
67 | ); | ||
68 | HRESULT CpiGetCollectionObjectValue( | ||
69 | ICatalogObject* piObj, | ||
70 | LPCWSTR szPropName, | ||
71 | LPWSTR* ppwzValue | ||
72 | ); | ||
73 | HRESULT CpiResetObjectProperty( | ||
74 | ICatalogCollection* piColl, | ||
75 | ICatalogObject* piObj, | ||
76 | LPCWSTR pwzPropName | ||
77 | ); | ||
78 | HRESULT CpiRemoveCollectionObject( | ||
79 | ICatalogCollection* piColl, | ||
80 | LPCWSTR pwzID, | ||
81 | LPCWSTR pwzName, | ||
82 | BOOL fResetDeleteable | ||
83 | ); | ||
84 | HRESULT CpiRemoveUserCollectionObject( | ||
85 | ICatalogCollection* piColl, | ||
86 | PSID pSid | ||
87 | ); | ||
88 | HRESULT CpiFindCollectionObjectByStringKey( | ||
89 | ICatalogCollection* piColl, | ||
90 | LPCWSTR pwzKey, | ||
91 | ICatalogObject** ppiObj | ||
92 | ); | ||
93 | HRESULT CpiFindCollectionObjectByIntegerKey( | ||
94 | ICatalogCollection* piColl, | ||
95 | long lKey, | ||
96 | ICatalogObject** ppiObj | ||
97 | ); | ||
98 | HRESULT CpiFindCollectionObjectByName( | ||
99 | ICatalogCollection* piColl, | ||
100 | LPCWSTR pwzName, | ||
101 | ICatalogObject** ppiObj | ||
102 | ); | ||
103 | HRESULT CpiFindUserCollectionObject( | ||
104 | ICatalogCollection* piColl, | ||
105 | PSID pSid, | ||
106 | ICatalogObject** ppiObj | ||
107 | ); | ||
108 | HRESULT CpiExecGetPartitionsCollection( | ||
109 | ICatalogCollection** ppiPartColl | ||
110 | ); | ||
111 | HRESULT CpiGetPartitionRolesCollection( | ||
112 | LPCWSTR pwzPartID, | ||
113 | ICatalogCollection** ppiRolesColl | ||
114 | ); | ||
115 | HRESULT CpiGetUsersInPartitionRoleCollection( | ||
116 | LPCWSTR pwzPartID, | ||
117 | LPCWSTR pwzRoleName, | ||
118 | ICatalogCollection** ppiUsrInRoleColl | ||
119 | ); | ||
120 | HRESULT CpiGetPartitionUsersCollection( | ||
121 | ICatalogCollection** ppiUserColl | ||
122 | ); | ||
123 | HRESULT CpiExecGetApplicationsCollection( | ||
124 | LPCWSTR pwzPartID, | ||
125 | ICatalogCollection** ppiAppColl | ||
126 | ); | ||
127 | HRESULT CpiGetRolesCollection( | ||
128 | LPCWSTR pwzPartID, | ||
129 | LPCWSTR pwzAppID, | ||
130 | ICatalogCollection** ppiRolesColl | ||
131 | ); | ||
132 | HRESULT CpiGetUsersInRoleCollection( | ||
133 | LPCWSTR pwzPartID, | ||
134 | LPCWSTR pwzAppID, | ||
135 | LPCWSTR pwzRoleName, | ||
136 | ICatalogCollection** ppiUsrInRoleColl | ||
137 | ); | ||
138 | HRESULT CpiGetComponentsCollection( | ||
139 | LPCWSTR pwzPartID, | ||
140 | LPCWSTR pwzAppID, | ||
141 | ICatalogCollection** ppiCompsColl | ||
142 | ); | ||
143 | HRESULT CpiGetInterfacesCollection( | ||
144 | ICatalogCollection* piCompColl, | ||
145 | ICatalogObject* piCompObj, | ||
146 | ICatalogCollection** ppiIntfColl | ||
147 | ); | ||
148 | HRESULT CpiGetMethodsCollection( | ||
149 | ICatalogCollection* piIntfColl, | ||
150 | ICatalogObject* piIntfObj, | ||
151 | ICatalogCollection** ppiMethColl | ||
152 | ); | ||
153 | HRESULT CpiGetSubscriptionsCollection( | ||
154 | LPCWSTR pwzPartID, | ||
155 | LPCWSTR pwzAppID, | ||
156 | LPCWSTR pwzCompCLSID, | ||
157 | ICatalogCollection** ppiCompsColl | ||
158 | ); | ||
159 | HRESULT CpiReadPropertyList( | ||
160 | LPWSTR* ppwzData, | ||
161 | CPI_PROPERTY** ppPropList | ||
162 | ); | ||
163 | void CpiFreePropertyList( | ||
164 | CPI_PROPERTY* pList | ||
165 | ); | ||
166 | HRESULT CpiWriteKeyToRollbackFile( | ||
167 | HANDLE hFile, | ||
168 | LPCWSTR pwzKey | ||
169 | ); | ||
170 | HRESULT CpiWriteIntegerToRollbackFile( | ||
171 | HANDLE hFile, | ||
172 | int i | ||
173 | ); | ||
174 | HRESULT CpiReadRollbackDataList( | ||
175 | HANDLE hFile, | ||
176 | CPI_ROLLBACK_DATA** pprdList | ||
177 | ); | ||
178 | void CpiFreeRollbackDataList( | ||
179 | CPI_ROLLBACK_DATA* pList | ||
180 | ); | ||
181 | HRESULT CpiFindRollbackStatus( | ||
182 | CPI_ROLLBACK_DATA* pList, | ||
183 | LPCWSTR pwzKey, | ||
184 | int* piStatus | ||
185 | ); | ||
186 | HRESULT CpiAccountNameToSid( | ||
187 | LPCWSTR pwzAccountName, | ||
188 | PSID* ppSid | ||
189 | ); | ||
190 | HRESULT 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 | |||
8 | LPCWSTR vcsActionTextQuery = | ||
9 | L"SELECT `Description`, `Template` FROM `ActionText` WHERE `Action` = ?"; | ||
10 | enum eActionTextQuery { atqDescription = 1, atqTemplate }; | ||
11 | |||
12 | LPCWSTR vcsComponentAttributesQuery = | ||
13 | L"SELECT `Attributes` FROM `Component` WHERE `Component` = ?"; | ||
14 | enum eComponentAttributesQuery { caqAttributes = 1 }; | ||
15 | |||
16 | LPCWSTR vcsUserQuery = L"SELECT `Domain`, `Name` FROM `User` WHERE `User` = ?"; | ||
17 | enum eUserQuery { uqDomain = 1, uqName }; | ||
18 | |||
19 | enum ePropertyQuery { pqName = 1, pqValue }; | ||
20 | |||
21 | |||
22 | // prototypes for private helper functions | ||
23 | |||
24 | static HRESULT FindPropertyDefinition( | ||
25 | CPI_PROPERTY_DEFINITION* pPropDefList, | ||
26 | LPCWSTR pwzName, | ||
27 | CPI_PROPERTY_DEFINITION** ppPropDef | ||
28 | ); | ||
29 | static HRESULT GetUserAccountName( | ||
30 | LPCWSTR pwzKey, | ||
31 | LPWSTR* ppwzAccount | ||
32 | ); | ||
33 | |||
34 | |||
35 | // variables | ||
36 | |||
37 | static ICOMAdminCatalog* gpiCatalog; | ||
38 | static ICatalogCollection* gpiPartColl; | ||
39 | static ICatalogCollection* gpiAppColl; | ||
40 | |||
41 | static int giTables; | ||
42 | |||
43 | |||
44 | // function definitions | ||
45 | |||
46 | void 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 | |||
83 | void CpiSchedFinalize() | ||
84 | { | ||
85 | // collections | ||
86 | ReleaseObject(gpiCatalog); | ||
87 | ReleaseObject(gpiPartColl); | ||
88 | ReleaseObject(gpiAppColl); | ||
89 | } | ||
90 | |||
91 | BOOL CpiTableExists( | ||
92 | int iTable | ||
93 | ) | ||
94 | { | ||
95 | return (giTables & iTable) == iTable; | ||
96 | } | ||
97 | |||
98 | HRESULT 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 | |||
117 | LExit: | ||
118 | return hr; | ||
119 | } | ||
120 | |||
121 | HRESULT 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 | |||
153 | LExit: | ||
154 | // clean up | ||
155 | ReleaseObject(piCatalog); | ||
156 | ReleaseObject(piDisp); | ||
157 | ReleaseBSTR(bstrName); | ||
158 | |||
159 | return hr; | ||
160 | } | ||
161 | |||
162 | HRESULT 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 | |||
203 | LExit: | ||
204 | // clean up | ||
205 | ReleaseObject(piCatalog); | ||
206 | ReleaseObject(piDisp); | ||
207 | ReleaseBSTR(bstrName); | ||
208 | ::VariantClear(&vtKey); | ||
209 | |||
210 | return hr; | ||
211 | } | ||
212 | |||
213 | HRESULT 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 | |||
238 | LExit: | ||
239 | // clean up | ||
240 | ::VariantClear(&vtKey); | ||
241 | |||
242 | return hr; | ||
243 | } | ||
244 | |||
245 | HRESULT 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 | |||
324 | LExit: | ||
325 | // clean up | ||
326 | ReleaseObject(piDisp); | ||
327 | ReleaseObject(piObj); | ||
328 | |||
329 | ::VariantClear(&vtVal); | ||
330 | |||
331 | return hr; | ||
332 | } | ||
333 | |||
334 | HRESULT 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 | |||
353 | LExit: | ||
354 | return hr; | ||
355 | } | ||
356 | |||
357 | HRESULT 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 | |||
418 | LExit: | ||
419 | // clean up | ||
420 | ReleaseObject(piCatalog); | ||
421 | ReleaseObject(piCatalog2); | ||
422 | ReleaseObject(piPartColl); | ||
423 | ReleaseObject(piPartObj); | ||
424 | ReleaseBSTR(bstrGlobPartID); | ||
425 | |||
426 | return hr; | ||
427 | } | ||
428 | |||
429 | HRESULT 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 | |||
485 | LExit: | ||
486 | // clean up | ||
487 | ReleaseStr(pwzDescription); | ||
488 | ReleaseStr(pwzTemplate); | ||
489 | |||
490 | return hr; | ||
491 | } | ||
492 | |||
493 | HRESULT 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 | |||
538 | LExit: | ||
539 | return hr; | ||
540 | } | ||
541 | |||
542 | HRESULT 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 | |||
629 | LExit: | ||
630 | // clean up | ||
631 | if (pItm) | ||
632 | CpiPropertiesFreeList(pItm); | ||
633 | |||
634 | ReleaseStr(pwzData); | ||
635 | |||
636 | return hr; | ||
637 | } | ||
638 | |||
639 | void 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 | |||
653 | HRESULT 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 | |||
678 | LExit: | ||
679 | return hr; | ||
680 | } | ||
681 | |||
682 | HRESULT 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 | |||
707 | LExit: | ||
708 | return hr; | ||
709 | } | ||
710 | |||
711 | HRESULT 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 | |||
734 | LExit: | ||
735 | return hr; | ||
736 | } | ||
737 | |||
738 | HRESULT 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 | |||
757 | LExit: | ||
758 | return hr; | ||
759 | } | ||
760 | |||
761 | BOOL CpiIsInstalled( | ||
762 | INSTALLSTATE isInstalled | ||
763 | ) | ||
764 | { | ||
765 | return INSTALLSTATE_LOCAL == isInstalled || INSTALLSTATE_SOURCE == isInstalled; | ||
766 | } | ||
767 | |||
768 | BOOL CpiWillBeInstalled( | ||
769 | INSTALLSTATE isInstalled, | ||
770 | INSTALLSTATE isAction | ||
771 | ) | ||
772 | { | ||
773 | return WcaIsInstalling(isInstalled, isAction) || | ||
774 | (CpiIsInstalled(isInstalled) && !WcaIsUninstalling(isInstalled, isAction)); | ||
775 | } | ||
776 | |||
777 | HRESULT 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 | |||
810 | LExit: | ||
811 | return hr; | ||
812 | } | ||
813 | |||
814 | |||
815 | // helper function definitions | ||
816 | |||
817 | static 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 | |||
835 | static 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 | |||
879 | LExit: | ||
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 | |||
5 | enum eRunMode { rmDeferred = 1, rmCommit, rmRollback }; | ||
6 | |||
7 | enum eComPlusPropertyType { cpptNone = 0, cpptBoolean, cpptInteger, cpptString, cpptUser }; | ||
8 | |||
9 | enum 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 | |||
41 | struct CPI_PROPERTY_DEFINITION | ||
42 | { | ||
43 | LPCWSTR pwzName; | ||
44 | int iType; | ||
45 | int iMinVersionNT; | ||
46 | }; | ||
47 | |||
48 | |||
49 | // function prototypes | ||
50 | |||
51 | void CpiSchedInitialize(); | ||
52 | void CpiSchedFinalize(); | ||
53 | BOOL CpiTableExists( | ||
54 | int iTable | ||
55 | ); | ||
56 | HRESULT CpiSchedGetAdminCatalog( | ||
57 | ICOMAdminCatalog** ppiCatalog | ||
58 | ); | ||
59 | HRESULT CpiSchedGetCatalogCollection( | ||
60 | LPCWSTR pwzName, | ||
61 | ICatalogCollection** ppiColl | ||
62 | ); | ||
63 | HRESULT CpiSchedGetCatalogCollection( | ||
64 | ICatalogCollection* piColl, | ||
65 | ICatalogObject* piObj, | ||
66 | LPCWSTR pwzName, | ||
67 | ICatalogCollection** ppiColl | ||
68 | ); | ||
69 | HRESULT CpiGetKeyForObject( | ||
70 | ICatalogObject* piObj, | ||
71 | LPWSTR pwzKey, | ||
72 | SIZE_T cchKey | ||
73 | ); | ||
74 | HRESULT CpiFindCollectionObject( | ||
75 | ICatalogCollection* piColl, | ||
76 | LPCWSTR pwzID, | ||
77 | LPCWSTR pwzName, | ||
78 | ICatalogObject** ppiObj | ||
79 | ); | ||
80 | HRESULT CpiSchedGetPartitionsCollection( | ||
81 | ICatalogCollection** ppiPartColl | ||
82 | ); | ||
83 | HRESULT CpiSchedGetApplicationsCollection( | ||
84 | ICatalogCollection** ppiAppColl | ||
85 | ); | ||
86 | HRESULT CpiAddActionTextToActionData( | ||
87 | LPCWSTR pwzAction, | ||
88 | LPWSTR* ppwzActionData | ||
89 | ); | ||
90 | HRESULT CpiVerifyComponentArchitecure( | ||
91 | LPCWSTR pwzComponent, | ||
92 | BOOL* pfMatchingArchitecture | ||
93 | ); | ||
94 | HRESULT CpiPropertiesRead( | ||
95 | LPCWSTR pwzQuery, | ||
96 | LPCWSTR pwzKey, | ||
97 | CPI_PROPERTY_DEFINITION* pPropDefList, | ||
98 | CPI_PROPERTY** ppPropList, | ||
99 | int* piCount | ||
100 | ); | ||
101 | void CpiPropertiesFreeList( | ||
102 | CPI_PROPERTY* pList | ||
103 | ); | ||
104 | HRESULT CpiAddPropertiesToActionData( | ||
105 | int iPropCount, | ||
106 | CPI_PROPERTY* pPropList, | ||
107 | LPWSTR* ppwzActionData | ||
108 | ); | ||
109 | HRESULT CpiBuildAccountName( | ||
110 | LPCWSTR pwzDomain, | ||
111 | LPCWSTR pwzName, | ||
112 | LPWSTR* ppwzAccount | ||
113 | ); | ||
114 | HRESULT CpiGetTempFileName( | ||
115 | LPWSTR* ppwzTempFile | ||
116 | ); | ||
117 | HRESULT CpiCreateId( | ||
118 | LPWSTR pwzDest, | ||
119 | SIZE_T cchDest | ||
120 | ); | ||
121 | BOOL CpiIsInstalled( | ||
122 | INSTALLSTATE isInstalled | ||
123 | ); | ||
124 | BOOL CpiWillBeInstalled( | ||
125 | INSTALLSTATE isInstalled, | ||
126 | INSTALLSTATE isAction | ||
127 | ); | ||
128 | HRESULT 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 | /******************************************************************** | ||
6 | DllMain - standard entry point for all WiX custom actions. | ||
7 | |||
8 | ********************************************************************/ | ||
9 | extern "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 | |||
3 | namespace 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 | <!-- | ||
4 | This file contains the declaration of all the localizable strings. | ||
5 | --> | ||
6 | <WixLocalization xmlns="http://wixtoolset.org/schemas/v4/wxl" Culture="en-US"> | ||
7 | |||
8 | <String Id="DowngradeError">A newer version of [ProductName] is already installed.</String> | ||
9 | <String Id="FeatureTitle">MsiPackage</String> | ||
10 | |||
11 | </WixLocalization> | ||
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 | |||
3 | namespace 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 | |||
3 | namespace 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 | |||
3 | namespace 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 | |||
3 | namespace 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 | |||
3 | namespace 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 | |||
3 | namespace 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 | |||
3 | namespace 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 | |||
3 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
23 | namespace 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 | |||
3 | namespace 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 | |||
21 | namespace 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 | |||
3 | namespace 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 | |||
26 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
21 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
21 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
26 | namespace 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 | |||
3 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 | |||
3 | namespace 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 | |||
22 | namespace 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 >= 500" /> | ||
89 | <Custom Action="ConfigureComPlusInstall" Before="InstallServices" Overridable="yes" Condition="VersionNT >= 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 >= 500" /> | ||
124 | <Custom Action="ConfigureComPlusInstall_x64" Before="InstallServices" Overridable="yes" Condition="VersionNT >= 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 | } | ||