aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core.WindowsInstaller/Msi/SummaryInformation.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core.WindowsInstaller/Msi/SummaryInformation.cs')
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Msi/SummaryInformation.cs245
1 files changed, 245 insertions, 0 deletions
diff --git a/src/WixToolset.Core.WindowsInstaller/Msi/SummaryInformation.cs b/src/WixToolset.Core.WindowsInstaller/Msi/SummaryInformation.cs
new file mode 100644
index 00000000..26831731
--- /dev/null
+++ b/src/WixToolset.Core.WindowsInstaller/Msi/SummaryInformation.cs
@@ -0,0 +1,245 @@
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.Msi
4{
5 using System;
6 using System.Globalization;
7 using System.Text;
8 using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
9 using WixToolset.Core.Native;
10
11 /// <summary>
12 /// Summary information for the MSI files.
13 /// </summary>
14 internal sealed class SummaryInformation : MsiHandle
15 {
16 /// <summary>
17 /// Summary information properties for transforms.
18 /// </summary>
19 public enum Transform
20 {
21 /// <summary>PID_CODEPAGE = code page for the summary information stream</summary>
22 CodePage = 1,
23
24 /// <summary>PID_TITLE = typically just "Transform"</summary>
25 Title = 2,
26
27 /// <summary>PID_SUBJECT = original subject of target</summary>
28 TargetSubject = 3,
29
30 /// <summary>PID_AUTHOR = original manufacturer of target</summary>
31 TargetManufacturer = 4,
32
33 /// <summary>PID_KEYWORDS = keywords for the transform, typically including at least "Installer"</summary>
34 Keywords = 5,
35
36 /// <summary>PID_COMMENTS = describes what this package does</summary>
37 Comments = 6,
38
39 /// <summary>PID_TEMPLATE = target platform;language</summary>
40 TargetPlatformAndLanguage = 7,
41
42 /// <summary>PID_LASTAUTHOR = updated platform;language</summary>
43 UpdatedPlatformAndLanguage = 8,
44
45 /// <summary>PID_REVNUMBER = {productcode}version;{newproductcode}newversion;upgradecode</summary>
46 ProductCodes = 9,
47
48 /// <summary>PID_LASTPRINTED should be null for transforms</summary>
49 Reserved11 = 11,
50
51 ///.<summary>PID_CREATE_DTM = the timestamp when the transform was created</summary>
52 CreationTime = 12,
53
54 /// <summary>PID_PAGECOUNT = minimum installer version</summary>
55 InstallerRequirement = 14,
56
57 /// <summary>PID_CHARCOUNT = validation and error flags</summary>
58 ValidationFlags = 16,
59
60 /// <summary>PID_APPNAME = the application that created the transform</summary>
61 CreatingApplication = 18,
62
63 /// <summary>PID_SECURITY = whether read-only is enforced; should always be 4 for transforms</summary>
64 Security = 19,
65 }
66
67 /// <summary>
68 /// Summary information properties for patches.
69 /// </summary>
70 public enum Patch
71 {
72 /// <summary>PID_CODEPAGE = code page of the summary information stream</summary>
73 CodePage = 1,
74
75 /// <summary>PID_TITLE = a brief description of the package type</summary>
76 Title = 2,
77
78 /// <summary>PID_SUBJECT = package name</summary>
79 PackageName = 3,
80
81 /// <summary>PID_AUTHOR = manufacturer of the patch package</summary>
82 Manufacturer = 4,
83
84 /// <summary>PID_KEYWORDS = alternate sources for the patch package</summary>
85 Sources = 5,
86
87 /// <summary>PID_COMMENTS = general purpose of the patch package</summary>
88 Comments = 6,
89
90 /// <summary>PID_TEMPLATE = semicolon delimited list of ProductCodes</summary>
91 ProductCodes = 7,
92
93 /// <summary>PID_LASTAUTHOR = semicolon delimited list of transform names</summary>
94 TransformNames = 8,
95
96 /// <summary>PID_REVNUMBER = GUID patch code</summary>
97 PatchCode = 9,
98
99 /// <summary>PID_LASTPRINTED should be null for patches</summary>
100 Reserved11 = 11,
101
102 /// <summary>PID_PAGECOUNT should be null for patches</summary>
103 Reserved14 = 14,
104
105 /// <summary>PID_WORDCOUNT = minimum installer version</summary>
106 InstallerRequirement = 15,
107
108 /// <summary>PID_CHARCOUNT should be null for patches</summary>
109 Reserved16 = 16,
110
111 /// <summary>PID_SECURITY = read-only attribute of the patch package</summary>
112 Security = 19,
113 }
114
115 /// <summary>
116 /// Summary information values for the InstallerRequirement property.
117 /// </summary>
118 public enum InstallerRequirement
119 {
120 /// <summary>Any version of the installer will do</summary>
121 Version10 = 1,
122
123 /// <summary>At least 1.2</summary>
124 Version12 = 2,
125
126 /// <summary>At least 2.0</summary>
127 Version20 = 3,
128
129 /// <summary>At least 3.0</summary>
130 Version30 = 4,
131
132 /// <summary>At least 3.1</summary>
133 Version31 = 5,
134 }
135
136 /// <summary>
137 /// Instantiate a new SummaryInformation class from an open database.
138 /// </summary>
139 /// <param name="db">Database to retrieve summary information from.</param>
140 public SummaryInformation(Database db)
141 {
142 if (null == db)
143 {
144 throw new ArgumentNullException("db");
145 }
146
147 uint handle = 0;
148 int error = MsiInterop.MsiGetSummaryInformation(db.Handle, null, 0, ref handle);
149 if (0 != error)
150 {
151 throw new MsiException(error);
152 }
153 this.Handle = handle;
154 }
155
156 /// <summary>
157 /// Instantiate a new SummaryInformation class from a database file.
158 /// </summary>
159 /// <param name="databaseFile">The database file.</param>
160 public SummaryInformation(string databaseFile)
161 {
162 if (null == databaseFile)
163 {
164 throw new ArgumentNullException("databaseFile");
165 }
166
167 uint handle = 0;
168 int error = MsiInterop.MsiGetSummaryInformation(0, databaseFile, 0, ref handle);
169 if (0 != error)
170 {
171 throw new MsiException(error);
172 }
173 this.Handle = handle;
174 }
175
176 /// <summary>
177 /// Variant types in the summary information table.
178 /// </summary>
179 private enum VT : uint
180 {
181 /// <summary>Variant has not been assigned.</summary>
182 EMPTY = 0,
183
184 /// <summary>Null variant type.</summary>
185 NULL = 1,
186
187 /// <summary>16-bit integer variant type.</summary>
188 I2 = 2,
189
190 /// <summary>32-bit integer variant type.</summary>
191 I4 = 3,
192
193 /// <summary>String variant type.</summary>
194 LPSTR = 30,
195
196 /// <summary>Date time (FILETIME, converted to Variant time) variant type.</summary>
197 FILETIME = 64,
198 }
199
200 /// <summary>
201 /// Gets a summary information property.
202 /// </summary>
203 /// <param name="index">Index of the summary information property.</param>
204 /// <returns>The summary information property.</returns>
205 public string GetProperty(int index)
206 {
207 uint dataType;
208 StringBuilder stringValue = new StringBuilder("");
209 int bufSize = 0;
210 int intValue;
211 FILETIME timeValue;
212 timeValue.dwHighDateTime = 0;
213 timeValue.dwLowDateTime = 0;
214
215 int error = MsiInterop.MsiSummaryInfoGetProperty(this.Handle, index, out dataType, out intValue, ref timeValue, stringValue, ref bufSize);
216 if (234 == error)
217 {
218 stringValue.EnsureCapacity(++bufSize);
219 error = MsiInterop.MsiSummaryInfoGetProperty(this.Handle, index, out dataType, out intValue, ref timeValue, stringValue, ref bufSize);
220 }
221
222 if (0 != error)
223 {
224 throw new MsiException(error);
225 }
226
227 switch ((VT)dataType)
228 {
229 case VT.EMPTY:
230 return String.Empty;
231 case VT.LPSTR:
232 return stringValue.ToString();
233 case VT.I2:
234 case VT.I4:
235 return Convert.ToString(intValue, CultureInfo.InvariantCulture);
236 case VT.FILETIME:
237 long longFileTime = (((long)timeValue.dwHighDateTime) << 32) | unchecked((uint)timeValue.dwLowDateTime);
238 DateTime dateTime = DateTime.FromFileTime(longFileTime);
239 return dateTime.ToString("yyyy/MM/dd HH:mm:ss", CultureInfo.InvariantCulture);
240 default:
241 throw new InvalidOperationException();
242 }
243 }
244 }
245}