aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core.WindowsInstaller/PatchTransform.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core.WindowsInstaller/PatchTransform.cs')
-rw-r--r--src/WixToolset.Core.WindowsInstaller/PatchTransform.cs271
1 files changed, 0 insertions, 271 deletions
diff --git a/src/WixToolset.Core.WindowsInstaller/PatchTransform.cs b/src/WixToolset.Core.WindowsInstaller/PatchTransform.cs
deleted file mode 100644
index f58ca53f..00000000
--- a/src/WixToolset.Core.WindowsInstaller/PatchTransform.cs
+++ /dev/null
@@ -1,271 +0,0 @@
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#if DELETE
4
5namespace WixToolset
6{
7 using System;
8 using System.Collections;
9 using System.Globalization;
10 using System.Text;
11 using System.Text.RegularExpressions;
12 using WixToolset.Data;
13 using WixToolset.Extensibility;
14
15 public class PatchTransform
16 {
17 private string baseline;
18 private Intermediate transform;
19 private string transformPath;
20
21 public string Baseline
22 {
23 get { return this.baseline; }
24 }
25
26 public Intermediate Transform
27 {
28 get
29 {
30 if (null == this.transform)
31 {
32 this.transform = Intermediate.Load(this.transformPath, false);
33 }
34
35 return this.transform;
36 }
37 }
38
39 public string TransformPath
40 {
41 get { return this.transformPath; }
42 }
43
44 public PatchTransform(string transformPath, string baseline)
45 {
46 this.transformPath = transformPath;
47 this.baseline = baseline;
48 }
49
50 /// <summary>
51 /// Validates that the differences in the transform are valid for patch transforms.
52 /// </summary>
53 public void Validate()
54 {
55 // Changing the ProdocutCode in a patch transform is not recommended.
56 Table propertyTable = this.Transform.Tables["Property"];
57 if (null != propertyTable)
58 {
59 foreach (Row row in propertyTable.Rows)
60 {
61 // Only interested in modified rows; fast check.
62 if (RowOperation.Modify == row.Operation)
63 {
64 if (0 == String.CompareOrdinal("ProductCode", (string)row[0]))
65 {
66 this.OnMessage(WixWarnings.MajorUpgradePatchNotRecommended());
67 }
68 }
69 }
70 }
71
72 // If there is nothing in the component table we can return early because the remaining checks are component based.
73 Table componentTable = this.Transform.Tables["Component"];
74 if (null == componentTable)
75 {
76 return;
77 }
78
79 // Index Feature table row operations
80 Table featureTable = this.Transform.Tables["Feature"];
81 Table featureComponentsTable = this.Transform.Tables["FeatureComponents"];
82 Hashtable featureOps = null;
83 if (null != featureTable)
84 {
85 int capacity = featureTable.Rows.Count;
86 featureOps = new Hashtable(capacity);
87
88 foreach (Row row in featureTable.Rows)
89 {
90 featureOps[(string)row[0]] = row.Operation;
91 }
92 }
93 else
94 {
95 featureOps = new Hashtable();
96 }
97
98 // Index Component table and check for keypath modifications
99 Hashtable deletedComponent = new Hashtable();
100 Hashtable componentKeyPath = new Hashtable();
101 foreach (Row row in componentTable.Rows)
102 {
103 string id = row.Fields[0].Data.ToString();
104 string keypath = (null == row.Fields[5].Data) ? String.Empty : row.Fields[5].Data.ToString();
105
106 componentKeyPath.Add(id, keypath);
107 if (RowOperation.Delete == row.Operation)
108 {
109 deletedComponent.Add(id, row);
110 }
111 else if (RowOperation.Modify == row.Operation)
112 {
113 if (row.Fields[1].Modified)
114 {
115 // Changing the guid of a component is equal to deleting the old one and adding a new one.
116 deletedComponent.Add(id, row);
117 }
118
119 // If the keypath is modified its an error
120 if (row.Fields[5].Modified)
121 {
122 this.OnMessage(WixErrors.InvalidKeypathChange(row.SourceLineNumbers, id, this.transformPath));
123 }
124 }
125 }
126
127 // Verify changes in the file table
128 Table fileTable = this.Transform.Tables["File"];
129 if (null != fileTable)
130 {
131 Hashtable componentWithChangedKeyPath = new Hashtable();
132 foreach (Row row in fileTable.Rows)
133 {
134 if (RowOperation.None != row.Operation)
135 {
136 string fileId = row.Fields[0].Data.ToString();
137 string componentId = row.Fields[1].Data.ToString();
138
139 // If this file is the keypath of a component
140 if (String.Equals((string)componentKeyPath[componentId], fileId, StringComparison.Ordinal))
141 {
142 if (row.Fields[2].Modified)
143 {
144 // You cant change the filename of a file that is the keypath of a component.
145 this.OnMessage(WixErrors.InvalidKeypathChange(row.SourceLineNumbers, componentId, this.transformPath));
146 }
147
148 if (!componentWithChangedKeyPath.ContainsKey(componentId))
149 {
150 componentWithChangedKeyPath.Add(componentId, fileId);
151 }
152 }
153
154 if (RowOperation.Delete == row.Operation)
155 {
156 // If the file is removed from a component that is not deleted.
157 if (!deletedComponent.ContainsKey(componentId))
158 {
159 bool foundRemoveFileEntry = false;
160 string filename = Common.GetName((string)row[2], false, true);
161
162 Table removeFileTable = this.Transform.Tables["RemoveFile"];
163 if (null != removeFileTable)
164 {
165 foreach (Row removeFileRow in removeFileTable.Rows)
166 {
167 if (RowOperation.Delete == removeFileRow.Operation)
168 {
169 continue;
170 }
171
172 if (componentId == (string)removeFileRow[1])
173 {
174 // Check if there is a RemoveFile entry for this file
175 if (null != removeFileRow[2])
176 {
177 string removeFileName = Common.GetName((string)removeFileRow[2], false, true);
178
179 // Convert the MSI format for a wildcard string to Regex format.
180 removeFileName = removeFileName.Replace('.', '|').Replace('?', '.').Replace("*", ".*").Replace("|", "\\.");
181
182 Regex regex = new Regex(removeFileName, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
183 if (regex.IsMatch(filename))
184 {
185 foundRemoveFileEntry = true;
186 break;
187 }
188 }
189 }
190 }
191 }
192
193 if (!foundRemoveFileEntry)
194 {
195 this.OnMessage(WixWarnings.InvalidRemoveFile(row.SourceLineNumbers, fileId, componentId));
196 }
197 }
198 }
199 }
200 }
201 }
202
203 if (0 < deletedComponent.Count)
204 {
205 // Index FeatureComponents table.
206 Hashtable featureComponents = new Hashtable();
207
208 if (null != featureComponentsTable)
209 {
210 foreach (Row row in featureComponentsTable.Rows)
211 {
212 ArrayList features;
213 string componentId = row.Fields[1].Data.ToString();
214
215 if (featureComponents.Contains(componentId))
216 {
217 features = (ArrayList)featureComponents[componentId];
218 }
219 else
220 {
221 features = new ArrayList();
222 featureComponents.Add(componentId, features);
223 }
224 features.Add(row.Fields[0].Data.ToString());
225 }
226 }
227
228 // Check to make sure if a component was deleted, the feature was too.
229 foreach (DictionaryEntry entry in deletedComponent)
230 {
231 if (featureComponents.Contains(entry.Key.ToString()))
232 {
233 ArrayList features = (ArrayList)featureComponents[entry.Key.ToString()];
234 foreach (string featureId in features)
235 {
236 if (!featureOps.ContainsKey(featureId) || RowOperation.Delete != (RowOperation)featureOps[featureId])
237 {
238 // The feature was not deleted.
239 this.OnMessage(WixErrors.InvalidRemoveComponent(((Row)entry.Value).SourceLineNumbers, entry.Key.ToString(), featureId, this.transformPath));
240 }
241 }
242 }
243 }
244 }
245
246 // Warn if new components are added to existing features
247 if (null != featureComponentsTable)
248 {
249 foreach (Row row in featureComponentsTable.Rows)
250 {
251 if (RowOperation.Add == row.Operation)
252 {
253 // Check if the feature is in the Feature table
254 string feature_ = (string)row[0];
255 string component_ = (string)row[1];
256
257 // Features may not be present if not referenced
258 if (!featureOps.ContainsKey(feature_) || RowOperation.Add != (RowOperation)featureOps[feature_])
259 {
260 this.OnMessage(WixWarnings.NewComponentAddedToExistingFeature(row.SourceLineNumbers, component_, feature_, this.transformPath));
261 }
262 }
263 }
264 }
265
266 throw new NotImplementedException();
267 }
268 }
269}
270
271#endif \ No newline at end of file