diff options
Diffstat (limited to 'src')
100 files changed, 22827 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> | ||
