aboutsummaryrefslogtreecommitdiff
path: root/src/samples/Dtf/Inventory/patches.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/samples/Dtf/Inventory/patches.cs')
-rw-r--r--src/samples/Dtf/Inventory/patches.cs227
1 files changed, 227 insertions, 0 deletions
diff --git a/src/samples/Dtf/Inventory/patches.cs b/src/samples/Dtf/Inventory/patches.cs
new file mode 100644
index 00000000..f01a4798
--- /dev/null
+++ b/src/samples/Dtf/Inventory/patches.cs
@@ -0,0 +1,227 @@
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
3using System;
4using System.IO;
5using System.Security;
6using System.Data;
7using System.Collections;
8using System.Globalization;
9using System.Windows.Forms;
10using WixToolset.Dtf.WindowsInstaller;
11
12namespace WixToolset.Dtf.Samples.Inventory
13{
14 /// <summary>
15 /// Provides inventory data about patches installed on the system.
16 /// </summary>
17 public class PatchesInventory : IInventoryDataProvider
18 {
19 public PatchesInventory()
20 {
21 }
22
23 public string Description
24 {
25 get { return "Installed patches"; }
26 }
27
28 public string[] GetNodes(InventoryDataLoadStatusCallback statusCallback)
29 {
30 ArrayList nodes = new ArrayList();
31 statusCallback(nodes.Count, @"Products\...\Patches");
32 foreach (ProductInstallation product in ProductInstallation.AllProducts)
33 {
34 string productName = MsiUtils.GetProductName(product.ProductCode);
35
36 bool addedRoot = false;
37 foreach (PatchInstallation productPatch in PatchInstallation.GetPatches(null, product.ProductCode, null, UserContexts.All, PatchStates.Applied))
38 {
39 if (!addedRoot) nodes.Add(String.Format(@"Products\{0}\Patches", productName));
40 nodes.Add(String.Format(@"Products\{0}\Patches\{1}", productName, productPatch.PatchCode));
41 }
42 }
43
44 statusCallback(nodes.Count, "Patches");
45
46 string[] allPatches = GetAllPatchesList();
47 if(allPatches.Length > 0)
48 {
49 nodes.Add("Patches");
50 foreach(string patchCode in allPatches)
51 {
52 nodes.Add(String.Format(@"Patches\{0}", patchCode));
53 nodes.Add(String.Format(@"Patches\{0}\Patched Products", patchCode));
54 }
55 statusCallback(nodes.Count, String.Empty);
56 }
57 return (string[]) nodes.ToArray(typeof(string));
58 }
59
60 public bool IsNodeSearchable(string searchRoot, string searchNode)
61 {
62 return true;
63 }
64
65 public DataView GetData(string nodePath)
66 {
67 string[] path = nodePath.Split('\\');
68
69 if(path.Length == 3 && path[0] == "Products" && path[2] == "Patches")
70 {
71 return this.GetProductPatchData(path[1]);
72 }
73 else if(path.Length == 4 && path[0] == "Products" && path[2] == "Patches")
74 {
75 return this.GetPatchData(path[3]);
76 }
77 else if(path.Length == 1 && path[0] == "Patches")
78 {
79 return this.GetAllPatchesData();
80 }
81 else if(path.Length == 2 && path[0] == "Patches")
82 {
83 return this.GetPatchData(path[1]);
84 }
85 else if(path.Length == 3 && path[0] == "Patches" && path[2] == "Patched Products")
86 {
87 return this.GetPatchTargetData(path[1]);
88 }
89 return null;
90 }
91
92 private string[] GetAllPatchesList()
93 {
94 ArrayList patchList = new ArrayList();
95 foreach(PatchInstallation patch in PatchInstallation.AllPatches)
96 {
97 if(!patchList.Contains(patch.PatchCode))
98 {
99 patchList.Add(patch.PatchCode);
100 }
101 }
102 string[] patchArray = (string[]) patchList.ToArray(typeof(string));
103 Array.Sort(patchArray, 0, patchArray.Length, StringComparer.Ordinal);
104 return patchArray;
105 }
106
107 private DataView GetAllPatchesData()
108 {
109 DataTable table = new DataTable("Patches");
110 table.Locale = CultureInfo.InvariantCulture;
111 table.Columns.Add("PatchesPatchCode", typeof(string));
112
113 foreach(string patchCode in GetAllPatchesList())
114 {
115 table.Rows.Add(new object[] { patchCode });
116 }
117 return new DataView(table, "", "PatchesPatchCode ASC", DataViewRowState.CurrentRows);
118 }
119
120 private DataView GetProductPatchData(string productCode)
121 {
122 DataTable table = new DataTable("ProductPatches");
123 table.Locale = CultureInfo.InvariantCulture;
124 table.Columns.Add("ProductPatchesPatchCode", typeof(string));
125
126 foreach(PatchInstallation patch in PatchInstallation.GetPatches(null, productCode, null, UserContexts.All, PatchStates.Applied))
127 {
128 table.Rows.Add(new object[] { patch.PatchCode });
129 }
130 return new DataView(table, "", "ProductPatchesPatchCode ASC", DataViewRowState.CurrentRows);
131 }
132
133 private DataView GetPatchData(string patchCode)
134 {
135 DataTable table = new DataTable("PatchProperties");
136 table.Locale = CultureInfo.InvariantCulture;
137 table.Columns.Add("PatchPropertiesProperty", typeof(string));
138 table.Columns.Add("PatchPropertiesValue", typeof(string));
139
140 table.Rows.Add(new object[] { "PatchCode", patchCode });
141
142 PatchInstallation patch = new PatchInstallation(patchCode, null);
143
144 string localPackage = null;
145 foreach(string property in new string[]
146 {
147 "InstallDate",
148 "LocalPackage",
149 "State",
150 "Transforms",
151 "Uninstallable",
152 })
153 {
154 try
155 {
156 string value = patch[property];
157 table.Rows.Add(new object[] { property, (value != null ? value : "") });
158 if(property == "LocalPackage") localPackage = value;
159 }
160 catch(InstallerException iex)
161 {
162 table.Rows.Add(new object[] { property, iex.Message });
163 }
164 catch(ArgumentException) { }
165 }
166
167 if(localPackage != null)
168 {
169 try
170 {
171 using(SummaryInfo patchSummaryInfo = new SummaryInfo(localPackage, false))
172 {
173 table.Rows.Add(new object[] { "Title", patchSummaryInfo.Title });
174 table.Rows.Add(new object[] { "Subject", patchSummaryInfo.Subject });
175 table.Rows.Add(new object[] { "Author", patchSummaryInfo.Author });
176 table.Rows.Add(new object[] { "Comments", patchSummaryInfo.Comments });
177 table.Rows.Add(new object[] { "TargetProductCodes", patchSummaryInfo.Template });
178 string obsoletedPatchCodes = patchSummaryInfo.RevisionNumber.Substring(patchSummaryInfo.RevisionNumber.IndexOf('}') + 1);
179 table.Rows.Add(new object[] { "ObsoletedPatchCodes", obsoletedPatchCodes });
180 table.Rows.Add(new object[] { "TransformNames", patchSummaryInfo.LastSavedBy });
181 }
182 }
183 catch(InstallerException) { }
184 catch(IOException) { }
185 catch(SecurityException) { }
186 }
187 return new DataView(table, "", "PatchPropertiesProperty ASC", DataViewRowState.CurrentRows);
188 }
189
190 private DataView GetPatchTargetData(string patchCode)
191 {
192 DataTable table = new DataTable("PatchTargets");
193 table.Locale = CultureInfo.InvariantCulture;
194 table.Columns.Add("PatchTargetsProductName", typeof(string));
195 table.Columns.Add("PatchTargetsProductCode", typeof(string));
196
197 foreach (PatchInstallation patch in PatchInstallation.GetPatches(patchCode, null, null, UserContexts.All, PatchStates.Applied))
198 {
199 if(patch.PatchCode == patchCode)
200 {
201 string productName = MsiUtils.GetProductName(patch.ProductCode);
202 table.Rows.Add(new object[] { productName, patch.ProductCode });
203 }
204 }
205 return new DataView(table, "", "PatchTargetsProductName ASC", DataViewRowState.CurrentRows);
206 }
207
208 public string GetLink(string nodePath, DataRow row)
209 {
210 string[] path = nodePath.Split('\\');
211
212 if(path.Length == 3 && path[0] == "Products" && path[2] == "Patches")
213 {
214 return String.Format(@"Patches\{0}", row["ProductPatchesPatchCode"]);
215 }
216 else if(path.Length == 1 && path[0] == "Patches")
217 {
218 return String.Format(@"Patches\{0}", row["PatchesPatchCode"]);
219 }
220 else if(path.Length == 3 && path[0] == "Patches" && path[2] == "Patched Products")
221 {
222 return String.Format(@"Products\{0}", MsiUtils.GetProductCode((string) row["PatchTargetsProductCode"]));
223 }
224 return null;
225 }
226 }
227}