aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs')
-rw-r--r--src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs161
1 files changed, 161 insertions, 0 deletions
diff --git a/src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs b/src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs
new file mode 100644
index 00000000..5dbd6aaa
--- /dev/null
+++ b/src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs
@@ -0,0 +1,161 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Core.Burn.Bundles
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Diagnostics;
8 using System.IO;
9 using System.Security.Cryptography;
10 using System.Security.Cryptography.X509Certificates;
11 using System.Text;
12 using WixToolset.Bind;
13 using WixToolset.Data;
14 using WixToolset.Data.Bind;
15 using WixToolset.Data.Rows;
16
17 internal class ProcessPayloadsCommand
18 {
19 private static readonly Version EmptyVersion = new Version(0, 0, 0, 0);
20
21 public IEnumerable<WixBundlePayloadRow> Payloads { private get; set; }
22
23 public PackagingType DefaultPackaging { private get; set; }
24
25 public string LayoutDirectory { private get; set; }
26
27 public IEnumerable<FileTransfer> FileTransfers { get; private set; }
28
29 public void Execute()
30 {
31 List<FileTransfer> fileTransfers = new List<FileTransfer>();
32
33 foreach (WixBundlePayloadRow payload in this.Payloads)
34 {
35 string normalizedPath = payload.Name.Replace('\\', '/');
36 if (normalizedPath.StartsWith("../", StringComparison.Ordinal) || normalizedPath.Contains("/../"))
37 {
38 Messaging.Instance.OnMessage(WixErrors.PayloadMustBeRelativeToCache(payload.SourceLineNumbers, "Payload", "Name", payload.Name));
39 }
40
41 // Embedded files (aka: files from binary .wixlibs) are not content files (because they are hidden
42 // in the .wixlib).
43 ObjectField field = (ObjectField)payload.Fields[2];
44 payload.ContentFile = !field.EmbeddedFileIndex.HasValue;
45
46 this.UpdatePayloadPackagingType(payload);
47
48 if (String.IsNullOrEmpty(payload.SourceFile))
49 {
50 // Remote payloads obviously cannot be embedded.
51 Debug.Assert(PackagingType.Embedded != payload.Packaging);
52 }
53 else // not a remote payload so we have a lot more to update.
54 {
55 this.UpdatePayloadFileInformation(payload);
56
57 this.UpdatePayloadVersionInformation(payload);
58
59 // External payloads need to be transfered.
60 if (PackagingType.External == payload.Packaging)
61 {
62 FileTransfer transfer;
63 if (FileTransfer.TryCreate(payload.FullFileName, Path.Combine(this.LayoutDirectory, payload.Name), false, "Payload", payload.SourceLineNumbers, out transfer))
64 {
65 fileTransfers.Add(transfer);
66 }
67 }
68 }
69 }
70
71 this.FileTransfers = fileTransfers;
72 }
73
74 private void UpdatePayloadPackagingType(WixBundlePayloadRow payload)
75 {
76 if (PackagingType.Unknown == payload.Packaging)
77 {
78 if (YesNoDefaultType.Yes == payload.Compressed)
79 {
80 payload.Packaging = PackagingType.Embedded;
81 }
82 else if (YesNoDefaultType.No == payload.Compressed)
83 {
84 payload.Packaging = PackagingType.External;
85 }
86 else
87 {
88 payload.Packaging = this.DefaultPackaging;
89 }
90 }
91
92 // Embedded payloads that are not assigned a container already are placed in the default attached
93 // container.
94 if (PackagingType.Embedded == payload.Packaging && String.IsNullOrEmpty(payload.Container))
95 {
96 payload.Container = Compiler.BurnDefaultAttachedContainerId;
97 }
98 }
99
100 private void UpdatePayloadFileInformation(WixBundlePayloadRow payload)
101 {
102 FileInfo fileInfo = new FileInfo(payload.SourceFile);
103
104 if (null != fileInfo)
105 {
106 payload.FileSize = (int)fileInfo.Length;
107
108 payload.Hash = Common.GetFileHash(fileInfo.FullName);
109
110 // Try to get the certificate if the payload is a signed file and we're not suppressing signature validation.
111 if (payload.EnableSignatureValidation)
112 {
113 X509Certificate2 certificate = null;
114 try
115 {
116 certificate = new X509Certificate2(fileInfo.FullName);
117 }
118 catch (CryptographicException) // we don't care about non-signed files.
119 {
120 }
121
122 // If there is a certificate, remember its hashed public key identifier and thumbprint.
123 if (null != certificate)
124 {
125 byte[] publicKeyIdentifierHash = new byte[128];
126 uint publicKeyIdentifierHashSize = (uint)publicKeyIdentifierHash.Length;
127
128 WixToolset.Core.Native.NativeMethods.HashPublicKeyInfo(certificate.Handle, publicKeyIdentifierHash, ref publicKeyIdentifierHashSize);
129 StringBuilder sb = new StringBuilder(((int)publicKeyIdentifierHashSize + 1) * 2);
130 for (int i = 0; i < publicKeyIdentifierHashSize; ++i)
131 {
132 sb.AppendFormat("{0:X2}", publicKeyIdentifierHash[i]);
133 }
134
135 payload.PublicKey = sb.ToString();
136 payload.Thumbprint = certificate.Thumbprint;
137 }
138 }
139 }
140 }
141
142 private void UpdatePayloadVersionInformation(WixBundlePayloadRow payload)
143 {
144 FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(payload.SourceFile);
145
146 if (null != versionInfo)
147 {
148 // Use the fixed version info block for the file since the resource text may not be a dotted quad.
149 Version version = new Version(versionInfo.ProductMajorPart, versionInfo.ProductMinorPart, versionInfo.ProductBuildPart, versionInfo.ProductPrivatePart);
150
151 if (ProcessPayloadsCommand.EmptyVersion != version)
152 {
153 payload.Version = version.ToString();
154 }
155
156 payload.Description = versionInfo.FileDescription;
157 payload.DisplayName = versionInfo.ProductName;
158 }
159 }
160 }
161}