main
cs 93 lines 4.42 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.Burn.Bundles
4 {
5 using System;
6 using WixToolset.Data;
7 using WixToolset.Data.Symbols;
8 using WixToolset.Extensibility.Services;
9
10 internal static class CacheIdGenerator
11 {
12 // These are "reasonable" limits to trim the very long hashes so
13 // when used in a cache id we do not overflow MAX_PATH.
14 private const int ReasonableCountOfCharsFromCertificateThumbprint = 20;
15 private const int ReasonableUpperLimitForCacheId = 64;
16
17 public static string GenerateLocalCacheId(IMessaging messaging, IntermediateSymbol harvestedPackageSymbol, WixBundlePayloadSymbol payloadSymbol, SourceLineNumber sourceLineNumbers, string elementName)
18 {
19 string cacheId = null;
20
21 // If we are validating the package via certificate,
22 // the CacheId must be specified in source code.
23 if (!String.IsNullOrEmpty(payloadSymbol.CertificatePublicKey) || !String.IsNullOrEmpty(payloadSymbol.CertificateThumbprint))
24 {
25 var oneOfCertificateAttributeNames = !String.IsNullOrEmpty(payloadSymbol.CertificatePublicKey) ? "CertificatePublicKey" : "CertificateThumbprint";
26
27 messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, elementName, "CacheId", oneOfCertificateAttributeNames));
28 }
29 else
30 {
31 cacheId = GenerateDefaultCacheId(harvestedPackageSymbol, payloadSymbol, out _);
32 }
33
34 return cacheId;
35 }
36
37 public static string GenerateRemoteCacheId(IntermediateSymbol harvestedPackageSymbol, WixBundlePayloadSymbol payloadSymbol)
38 {
39 // If we are not validating the package via certificate,
40 // the CacheId can be generated at build time.
41 if (String.IsNullOrEmpty(payloadSymbol.CertificateThumbprint))
42 {
43 return null;
44 }
45
46 var defaultCacheId = GenerateDefaultCacheId(harvestedPackageSymbol, payloadSymbol, out var canTruncate);
47 var takeFromThumbprint = Math.Min(ReasonableCountOfCharsFromCertificateThumbprint, payloadSymbol.CertificateThumbprint.Length);
48 var takeFromDefault = Math.Min(ReasonableUpperLimitForCacheId - takeFromThumbprint, defaultCacheId.Length);
49
50 var defaultPart = !canTruncate ? defaultCacheId : defaultCacheId.Substring(0, takeFromDefault);
51 var certificatePart = payloadSymbol.CertificateThumbprint.Substring(0, takeFromThumbprint);
52 return defaultPart + certificatePart;
53 }
54
55 public static string GenerateDefaultCacheId(IntermediateSymbol harvestedPackageSymbol, WixBundlePayloadSymbol payloadSymbol, out bool canTruncate)
56 {
57 string cacheId;
58 canTruncate = false;
59
60 if (harvestedPackageSymbol is WixBundleHarvestedBundlePackageSymbol harvestedBundlePackageSymbol)
61 {
62 cacheId = GenerateCacheIdFromGuidAndVersion(harvestedBundlePackageSymbol.BundleId, harvestedBundlePackageSymbol.Version);
63 }
64 else if (harvestedPackageSymbol is WixBundleHarvestedMsiPackageSymbol harvestedMsiPackageSymbol)
65 {
66 cacheId = GenerateCacheIdFromGuidAndVersion(harvestedMsiPackageSymbol.ProductCode, harvestedMsiPackageSymbol.ProductVersion);
67 }
68 else if (harvestedPackageSymbol is WixBundleHarvestedMspPackageSymbol harvestedMspPackageSymbol)
69 {
70 cacheId = harvestedMspPackageSymbol.PatchCode;
71 }
72 else
73 {
74 // No inherent id is available, so use the hash.
75 cacheId = GenerateCacheIdFromHash(payloadSymbol.Hash);
76 canTruncate = true;
77 }
78
79 return cacheId;
80 }
81
82 public static string GenerateCacheIdFromGuidAndVersion(string guid, string version)
83 {
84 return String.Format("{0}v{1}", guid, version);
85 }
86
87 public static string GenerateCacheIdFromHash(string hash)
88 {
89 // The hash needs to be truncated to a "reasonable" upper limit since the CacheId is in the cached file path.
90 return hash.Length > ReasonableUpperLimitForCacheId ? hash.Substring(0, ReasonableUpperLimitForCacheId) : hash;
91 }
92 }
93 }