main
cs 78 lines 2.98 KB
Raw
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.Core.WindowsInstaller.Bind
4 {
5 using System;
6 using System.Collections.Generic;
7 using System.IO;
8 using System.Linq;
9 using WixToolset.Data;
10 using WixToolset.Data.Symbols;
11 using WixToolset.Extensibility.Data;
12 using WixToolset.Extensibility.Services;
13
14 /// <summary>
15 /// Set the guids for components with generatable guids and validate all are appropriately unique.
16 /// </summary>
17 internal class ValidateWindowsInstallerProductConstraints
18 {
19 private const int MaximumAllowedComponentsInMsi = 65536;
20 private const int MaximumAllowedFeatureDepthInMsi = 16;
21
22 internal ValidateWindowsInstallerProductConstraints(IMessaging messaging, IntermediateSection section)
23 {
24 this.Messaging = messaging;
25 this.Section = section;
26 }
27
28 private IMessaging Messaging { get; }
29
30 private IntermediateSection Section { get; }
31
32 public void Execute()
33 {
34 var componentCount = this.Section.Symbols.OfType<ComponentSymbol>().Count();
35 var featuresWithParent = this.Section.Symbols.OfType<FeatureSymbol>().ToDictionary(f => f.Id.Id, f => f.ParentFeatureRef);
36 var featuresWithDepth = new Dictionary<string, int>();
37
38 if (componentCount > MaximumAllowedComponentsInMsi)
39 {
40 this.Messaging.Write(WindowsInstallerBackendErrors.ExceededMaximumAllowedComponentsInMsi(MaximumAllowedComponentsInMsi, componentCount));
41 }
42
43 foreach (var featureSymbol in this.Section.Symbols.OfType<FeatureSymbol>())
44 {
45 var featureDepth = CalculateFeaturesDepth(featureSymbol.Id.Id, featuresWithParent, featuresWithDepth);
46
47 if (featureDepth > MaximumAllowedFeatureDepthInMsi)
48 {
49 this.Messaging.Write(WindowsInstallerBackendErrors.ExceededMaximumAllowedFeatureDepthInMsi(featureSymbol.SourceLineNumbers, MaximumAllowedFeatureDepthInMsi, featureSymbol.Id.Id, featureDepth));
50 }
51 }
52 }
53
54 private static int CalculateFeaturesDepth(string id, Dictionary<string, string> featuresWithParent, Dictionary<string, int> featuresWithDepth)
55 {
56 if (featuresWithDepth.TryGetValue(id, out var featureDepth))
57 {
58 return featureDepth;
59 }
60
61 var parentId = featuresWithParent[id];
62 if (!String.IsNullOrEmpty(parentId))
63 {
64 var parentDepth = CalculateFeaturesDepth(parentId, featuresWithParent, featuresWithDepth);
65
66 featureDepth = parentDepth + 1;
67 }
68 else
69 {
70 featureDepth = 1;
71 }
72
73 featuresWithDepth.Add(id, featureDepth);
74
75 return featureDepth;
76 }
77 }
78 }