aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2020-08-01 11:49:05 -0600
committerSean Hall <r.sean.hall@gmail.com>2020-08-09 10:47:30 -0600
commit522458420df786eb653009d616127e1060b3ab9b (patch)
tree0a705ac7397f1fcce05f0dcc4aa9fb78a173f25e
parenta37013d41f0702cbdf2aee6dce95d26dafc069b4 (diff)
downloadwix-522458420df786eb653009d616127e1060b3ab9b.tar.gz
wix-522458420df786eb653009d616127e1060b3ab9b.tar.bz2
wix-522458420df786eb653009d616127e1060b3ab9b.zip
WIXFEAT:5319 Remove IVariables since they were a leaky abstraction.
-rw-r--r--src/WixToolset.Mba.Core/Engine.cs290
-rw-r--r--src/WixToolset.Mba.Core/IEngine.cs95
-rw-r--r--src/WixToolset.Mba.Core/IVariables.cs27
-rw-r--r--src/balutil/balutil.cpp4
-rw-r--r--src/balutil/inc/balutil.h4
5 files changed, 171 insertions, 249 deletions
diff --git a/src/WixToolset.Mba.Core/Engine.cs b/src/WixToolset.Mba.Core/Engine.cs
index 2c544f29..98427cfa 100644
--- a/src/WixToolset.Mba.Core/Engine.cs
+++ b/src/WixToolset.Mba.Core/Engine.cs
@@ -18,10 +18,6 @@ namespace WixToolset.Mba.Core
18 private static readonly string normalizeVersionFormatString = "{0} must be less than or equal to " + UInt16.MaxValue; 18 private static readonly string normalizeVersionFormatString = "{0} must be less than or equal to " + UInt16.MaxValue;
19 19
20 private IBootstrapperEngine engine; 20 private IBootstrapperEngine engine;
21 private Variables<long> numericVariables;
22 private Variables<SecureString> secureStringVariables;
23 private Variables<string> stringVariables;
24 private Variables<Version> versionVariables;
25 21
26 /// <summary> 22 /// <summary>
27 /// Creates a new instance of the <see cref="Engine"/> container class. 23 /// Creates a new instance of the <see cref="Engine"/> container class.
@@ -30,135 +26,6 @@ namespace WixToolset.Mba.Core
30 internal Engine(IBootstrapperEngine engine) 26 internal Engine(IBootstrapperEngine engine)
31 { 27 {
32 this.engine = engine; 28 this.engine = engine;
33
34 // Wrap the calls to get and set numeric variables.
35 this.numericVariables = new Variables<long>(
36 delegate(string name)
37 {
38 long value;
39 int ret = this.engine.GetVariableNumeric(name, out value);
40 if (NativeMethods.S_OK != ret)
41 {
42 throw new Win32Exception(ret);
43 }
44
45 return value;
46 },
47 delegate(string name, long value)
48 {
49 this.engine.SetVariableNumeric(name, value);
50 },
51 delegate(string name)
52 {
53 long value;
54 int ret = this.engine.GetVariableNumeric(name, out value);
55
56 return NativeMethods.E_NOTFOUND != ret;
57 }
58 );
59
60 // Wrap the calls to get and set string variables using SecureStrings.
61 this.secureStringVariables = new Variables<SecureString>(
62 delegate(string name)
63 {
64 var pUniString = this.getStringVariable(name, out var length);
65 try
66 {
67 return this.convertToSecureString(pUniString, length);
68 }
69 finally
70 {
71 if (IntPtr.Zero != pUniString)
72 {
73 Marshal.FreeCoTaskMem(pUniString);
74 }
75 }
76 },
77 delegate(string name, SecureString value)
78 {
79 IntPtr pValue = Marshal.SecureStringToCoTaskMemUnicode(value);
80 try
81 {
82 this.engine.SetVariableString(name, pValue, true);
83 }
84 finally
85 {
86 Marshal.FreeCoTaskMem(pValue);
87 }
88 },
89 delegate(string name)
90 {
91 return this.containsVariable(name);
92 }
93 );
94
95 // Wrap the calls to get and set string variables.
96 this.stringVariables = new Variables<string>(
97 delegate(string name)
98 {
99 int length;
100 IntPtr pUniString = this.getStringVariable(name, out length);
101 try
102 {
103 return Marshal.PtrToStringUni(pUniString, length);
104 }
105 finally
106 {
107 if (IntPtr.Zero != pUniString)
108 {
109 Marshal.FreeCoTaskMem(pUniString);
110 }
111 }
112 },
113 delegate(string name, string value)
114 {
115 IntPtr pValue = Marshal.StringToCoTaskMemUni(value);
116 try
117 {
118 this.engine.SetVariableString(name, pValue, true);
119 }
120 finally
121 {
122 Marshal.FreeCoTaskMem(pValue);
123 }
124 },
125 delegate(string name)
126 {
127 return this.containsVariable(name);
128 }
129 );
130
131 // Wrap the calls to get and set version variables.
132 this.versionVariables = new Variables<Version>(
133 delegate(string name)
134 {
135 long value;
136 int ret = this.engine.GetVariableVersion(name, out value);
137 if (NativeMethods.S_OK != ret)
138 {
139 throw new Win32Exception(ret);
140 }
141
142 return LongToVersion(value);
143 },
144 delegate(string name, Version value)
145 {
146 long version = VersionToLong(value);
147 this.engine.SetVariableVersion(name, version);
148 },
149 delegate(string name)
150 {
151 long value;
152 int ret = this.engine.GetVariableVersion(name, out value);
153
154 return NativeMethods.E_NOTFOUND != ret;
155 }
156 );
157 }
158
159 public IVariables<long> NumericVariables
160 {
161 get { return this.numericVariables; }
162 } 29 }
163 30
164 public int PackageCount 31 public int PackageCount
@@ -172,21 +39,6 @@ namespace WixToolset.Mba.Core
172 } 39 }
173 } 40 }
174 41
175 public IVariables<SecureString> SecureStringVariables
176 {
177 get { return this.secureStringVariables; }
178 }
179
180 public IVariables<string> StringVariables
181 {
182 get { return this.stringVariables; }
183 }
184
185 public IVariables<Version> VersionVariables
186 {
187 get { return this.versionVariables; }
188 }
189
190 public void Apply(IntPtr hwndParent) 42 public void Apply(IntPtr hwndParent)
191 { 43 {
192 this.engine.Apply(hwndParent); 44 this.engine.Apply(hwndParent);
@@ -197,6 +49,13 @@ namespace WixToolset.Mba.Core
197 this.engine.CloseSplashScreen(); 49 this.engine.CloseSplashScreen();
198 } 50 }
199 51
52 public bool ContainsVariable(string name)
53 {
54 int capacity = 0;
55 int ret = this.engine.GetVariableString(name, IntPtr.Zero, ref capacity);
56 return NativeMethods.E_NOTFOUND != ret;
57 }
58
200 public void Detect() 59 public void Detect()
201 { 60 {
202 this.Detect(IntPtr.Zero); 61 this.Detect(IntPtr.Zero);
@@ -275,6 +134,61 @@ namespace WixToolset.Mba.Core
275 return sb.ToString(); 134 return sb.ToString();
276 } 135 }
277 136
137 public long GetVariableNumeric(string name)
138 {
139 int ret = this.engine.GetVariableNumeric(name, out long value);
140 if (NativeMethods.S_OK != ret)
141 {
142 throw new Win32Exception(ret);
143 }
144
145 return value;
146 }
147
148 public SecureString GetVariableSecureString(string name)
149 {
150 var pUniString = this.getStringVariable(name, out var length);
151 try
152 {
153 return this.convertToSecureString(pUniString, length);
154 }
155 finally
156 {
157 if (IntPtr.Zero != pUniString)
158 {
159 Marshal.FreeCoTaskMem(pUniString);
160 }
161 }
162 }
163
164 public string GetVariableString(string name)
165 {
166 int length;
167 IntPtr pUniString = this.getStringVariable(name, out length);
168 try
169 {
170 return Marshal.PtrToStringUni(pUniString, length);
171 }
172 finally
173 {
174 if (IntPtr.Zero != pUniString)
175 {
176 Marshal.FreeCoTaskMem(pUniString);
177 }
178 }
179 }
180
181 public Version GetVariableVersion(string name)
182 {
183 int ret = this.engine.GetVariableVersion(name, out long value);
184 if (NativeMethods.S_OK != ret)
185 {
186 throw new Win32Exception(ret);
187 }
188
189 return LongToVersion(value);
190 }
191
278 public void LaunchApprovedExe(IntPtr hwndParent, string approvedExeForElevationId, string arguments) 192 public void LaunchApprovedExe(IntPtr hwndParent, string approvedExeForElevationId, string arguments)
279 { 193 {
280 this.LaunchApprovedExe(hwndParent, approvedExeForElevationId, arguments, 0); 194 this.LaunchApprovedExe(hwndParent, approvedExeForElevationId, arguments, 0);
@@ -310,6 +224,43 @@ namespace WixToolset.Mba.Core
310 this.engine.SetDownloadSource(packageOrContainerId, payloadId, url, user, password); 224 this.engine.SetDownloadSource(packageOrContainerId, payloadId, url, user, password);
311 } 225 }
312 226
227 public void SetVariable(string name, long value)
228 {
229 this.engine.SetVariableNumeric(name, value);
230 }
231
232 public void SetVariable(string name, SecureString value, bool formatted)
233 {
234 IntPtr pValue = Marshal.SecureStringToCoTaskMemUnicode(value);
235 try
236 {
237 this.engine.SetVariableString(name, pValue, formatted);
238 }
239 finally
240 {
241 Marshal.FreeCoTaskMem(pValue);
242 }
243 }
244
245 public void SetVariable(string name, string value, bool formatted)
246 {
247 IntPtr pValue = Marshal.StringToCoTaskMemUni(value);
248 try
249 {
250 this.engine.SetVariableString(name, pValue, formatted);
251 }
252 finally
253 {
254 Marshal.FreeCoTaskMem(pValue);
255 }
256 }
257
258 public void SetVariable(string name, Version value)
259 {
260 long version = VersionToLong(value);
261 this.engine.SetVariableVersion(name, version);
262 }
263
313 public int SendEmbeddedError(int errorCode, string message, int uiHint) 264 public int SendEmbeddedError(int errorCode, string message, int uiHint)
314 { 265 {
315 int result = 0; 266 int result = 0;
@@ -329,49 +280,6 @@ namespace WixToolset.Mba.Core
329 this.engine.Quit(exitCode); 280 this.engine.Quit(exitCode);
330 } 281 }
331 282
332 internal sealed class Variables<T> : IVariables<T>
333 {
334 // .NET 2.0 does not support Func<T, TResult> or Action<T1, T2>.
335 internal delegate T Getter(string name);
336 internal delegate void Setter(string name, T value);
337
338 private Getter getter;
339 private Setter setter;
340 private Predicate<string> contains;
341
342 internal Variables(Getter getter, Setter setter, Predicate<string> contains)
343 {
344 this.getter = getter;
345 this.setter = setter;
346 this.contains = contains;
347 }
348
349 public T this[string name]
350 {
351 get { return this.getter(name); }
352 set { this.setter(name, value); }
353 }
354
355 public bool Contains(string name)
356 {
357 return this.contains(name);
358 }
359 }
360
361 /// <summary>
362 /// Gets whether the variable given by <paramref name="name"/> exists.
363 /// </summary>
364 /// <param name="name">The name of the variable to check.</param>
365 /// <returns>True if the variable given by <paramref name="name"/> exists; otherwise, false.</returns>
366 internal bool containsVariable(string name)
367 {
368 int capacity = 0;
369 IntPtr pValue = IntPtr.Zero;
370 int ret = this.engine.GetVariableString(name, pValue, ref capacity);
371
372 return NativeMethods.E_NOTFOUND != ret;
373 }
374
375 /// <summary> 283 /// <summary>
376 /// Gets the variable given by <paramref name="name"/> as a string. 284 /// Gets the variable given by <paramref name="name"/> as a string.
377 /// </summary> 285 /// </summary>
diff --git a/src/WixToolset.Mba.Core/IEngine.cs b/src/WixToolset.Mba.Core/IEngine.cs
index 5ddc4176..84d93bb0 100644
--- a/src/WixToolset.Mba.Core/IEngine.cs
+++ b/src/WixToolset.Mba.Core/IEngine.cs
@@ -9,38 +9,11 @@ namespace WixToolset.Mba.Core
9 public interface IEngine 9 public interface IEngine
10 { 10 {
11 /// <summary> 11 /// <summary>
12 /// Gets or sets numeric variables for the engine.
13 /// </summary>
14 IVariables<long> NumericVariables { get; }
15
16 /// <summary>
17 /// Gets the number of packages in the bundle. 12 /// Gets the number of packages in the bundle.
18 /// </summary> 13 /// </summary>
19 int PackageCount { get; } 14 int PackageCount { get; }
20 15
21 /// <summary> 16 /// <summary>
22 /// Gets or sets string variables for the engine using SecureStrings.
23 /// </summary>
24 IVariables<SecureString> SecureStringVariables { get; }
25
26 /// <summary>
27 /// Gets or sets string variables for the engine.
28 /// </summary>
29 IVariables<string> StringVariables { get; }
30
31 /// <summary>
32 /// Gets or sets <see cref="Version"/> variables for the engine.
33 ///
34 /// The <see cref="Version"/> class can keep track of when the build and revision fields are undefined, but the engine can't.
35 /// Therefore, the build and revision fields must be defined when setting a <see cref="Version"/> variable.
36 /// Use the NormalizeVersion method to make sure the engine can accept the Version.
37 ///
38 /// To keep track of versions without build or revision fields, use StringVariables instead.
39 /// </summary>
40 /// <exception cref="OverflowException">The given <see cref="Version"/> was invalid.</exception>
41 IVariables<Version> VersionVariables { get; }
42
43 /// <summary>
44 /// Install the packages. 17 /// Install the packages.
45 /// </summary> 18 /// </summary>
46 /// <param name="hwndParent">The parent window for the installation user interface.</param> 19 /// <param name="hwndParent">The parent window for the installation user interface.</param>
@@ -53,6 +26,13 @@ namespace WixToolset.Mba.Core
53 void CloseSplashScreen(); 26 void CloseSplashScreen();
54 27
55 /// <summary> 28 /// <summary>
29 /// Checks if a variable exists in the engine.
30 /// </summary>
31 /// <param name="name">The name of the variable.</param>
32 /// <returns>Whether the variable exists.</returns>
33 bool ContainsVariable(string name);
34
35 /// <summary>
56 /// Determine if all installation conditions are fulfilled. 36 /// Determine if all installation conditions are fulfilled.
57 /// </summary> 37 /// </summary>
58 void Detect(); 38 void Detect();
@@ -95,6 +75,30 @@ namespace WixToolset.Mba.Core
95 string FormatString(string format); 75 string FormatString(string format);
96 76
97 /// <summary> 77 /// <summary>
78 /// Gets numeric variables for the engine.
79 /// </summary>
80 /// <param name="name">The name of the variable.</param>
81 long GetVariableNumeric(string name);
82
83 /// <summary>
84 /// Gets string variables for the engine using SecureStrings.
85 /// </summary>
86 /// <param name="name">The name of the variable.</param>
87 SecureString GetVariableSecureString(string name);
88
89 /// <summary>
90 /// Gets string variables for the engine.
91 /// </summary>
92 /// <param name="name">The name of the variable.</param>
93 string GetVariableString(string name);
94
95 /// <summary>
96 /// Gets <see cref="Version"/> variables for the engine.
97 /// </summary>
98 /// <param name="name">The name of the variable.</param>
99 Version GetVariableVersion(string name);
100
101 /// <summary>
98 /// Launches a preapproved executable elevated. As long as the engine already elevated, there will be no UAC prompt. 102 /// Launches a preapproved executable elevated. As long as the engine already elevated, there will be no UAC prompt.
99 /// </summary> 103 /// </summary>
100 /// <param name="hwndParent">The parent window of the elevation dialog (if the engine hasn't elevated yet).</param> 104 /// <param name="hwndParent">The parent window of the elevation dialog (if the engine hasn't elevated yet).</param>
@@ -153,6 +157,43 @@ namespace WixToolset.Mba.Core
153 void SetDownloadSource(string packageOrContainerId, string payloadId, string url, string user, string password); 157 void SetDownloadSource(string packageOrContainerId, string payloadId, string url, string user, string password);
154 158
155 /// <summary> 159 /// <summary>
160 /// Sets numeric variables for the engine.
161 /// </summary>
162 /// <param name="name">The name of the variable.</param>
163 /// <param name="value">The value to set.</param>
164 void SetVariable(string name, long value);
165
166 /// <summary>
167 /// Sets string variables for the engine using SecureStrings.
168 /// </summary>
169 /// <param name="name">The name of the variable.</param>
170 /// <param name="value">The value to set.</param>
171 /// <param name="formatted">False if the value is a literal string.</param>
172 void SetVariable(string name, SecureString value, bool formatted);
173
174 /// <summary>
175 /// Sets string variables for the engine.
176 /// </summary>
177 /// <param name="name">The name of the variable.</param>
178 /// <param name="value">The value to set.</param>
179 /// <param name="formatted">False if the value is a literal string.</param>
180 void SetVariable(string name, string value, bool formatted);
181
182 /// <summary>
183 /// Sets <see cref="Version"/> variables for the engine.
184 ///
185 /// The <see cref="Version"/> class can keep track of when the build and revision fields are undefined, but the engine can't.
186 /// Therefore, the build and revision fields must be defined when setting a <see cref="Version"/> variable.
187 /// Use the NormalizeVersion method to make sure the engine can accept the Version.
188 ///
189 /// To keep track of versions without build or revision fields, use StringVariables instead.
190 /// </summary>
191 /// <param name="name">The name of the variable.</param>
192 /// <param name="value">The value to set.</param>
193 /// <exception cref="OverflowException">The given <see cref="Version"/> was invalid.</exception>
194 void SetVariable(string name, Version value);
195
196 /// <summary>
156 /// Sends error message when embedded. 197 /// Sends error message when embedded.
157 /// </summary> 198 /// </summary>
158 /// <param name="errorCode">Error code.</param> 199 /// <param name="errorCode">Error code.</param>
diff --git a/src/WixToolset.Mba.Core/IVariables.cs b/src/WixToolset.Mba.Core/IVariables.cs
deleted file mode 100644
index c7994f0b..00000000
--- a/src/WixToolset.Mba.Core/IVariables.cs
+++ /dev/null
@@ -1,27 +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
3namespace WixToolset.Mba.Core
4{
5 using System;
6
7 /// <summary>
8 /// An accessor for numeric, string, and version variables for the engine.
9 /// </summary>
10 public interface IVariables<T>
11 {
12 /// <summary>
13 /// Gets or sets the variable given by <paramref name="name"/>.
14 /// </summary>
15 /// <param name="name">The name of the variable to get/set.</param>
16 /// <returns>The value of the given variable.</returns>
17 /// <exception cref="Exception">An error occurred getting the variable.</exception>
18 T this[string name] { get; set; }
19
20 /// <summary>
21 /// Gets whether the variable given by <paramref name="name"/> exists.
22 /// </summary>
23 /// <param name="name">The name of the variable to check.</param>
24 /// <returns>True if the variable given by <paramref name="name"/> exists; otherwise, false.</returns>
25 bool Contains(string name);
26 }
27}
diff --git a/src/balutil/balutil.cpp b/src/balutil/balutil.cpp
index ebfaede4..faca70f5 100644
--- a/src/balutil/balutil.cpp
+++ b/src/balutil/balutil.cpp
@@ -167,7 +167,7 @@ LExit:
167} 167}
168 168
169 169
170DAPI_(BOOL) BalStringVariableExists( 170DAPI_(BOOL) BalVariableExists(
171 __in_z LPCWSTR wzVariable 171 __in_z LPCWSTR wzVariable
172 ) 172 )
173{ 173{
@@ -183,7 +183,7 @@ DAPI_(BOOL) BalStringVariableExists(
183 hr = vpEngine->GetVariableString(wzVariable, NULL, &cch); 183 hr = vpEngine->GetVariableString(wzVariable, NULL, &cch);
184 184
185LExit: 185LExit:
186 return E_MOREDATA == hr; // string exists only if there are more than zero characters in the variable. 186 return E_NOTFOUND != hr;
187} 187}
188 188
189 189
diff --git a/src/balutil/inc/balutil.h b/src/balutil/inc/balutil.h
index b718e48b..affa4925 100644
--- a/src/balutil/inc/balutil.h
+++ b/src/balutil/inc/balutil.h
@@ -108,10 +108,10 @@ DAPI_(HRESULT) BalSetNumericVariable(
108 ); 108 );
109 109
110/******************************************************************* 110/*******************************************************************
111BalStringVariableExists - checks if a string variable exists in the engine. 111BalVariableExists - checks if a variable exists in the engine.
112 112
113********************************************************************/ 113********************************************************************/
114DAPI_(BOOL) BalStringVariableExists( 114DAPI_(BOOL) BalVariableExists(
115 __in_z LPCWSTR wzVariable 115 __in_z LPCWSTR wzVariable
116 ); 116 );
117 117