aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Mba.Core/Engine.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Mba.Core/Engine.cs')
-rw-r--r--src/WixToolset.Mba.Core/Engine.cs86
1 files changed, 74 insertions, 12 deletions
diff --git a/src/WixToolset.Mba.Core/Engine.cs b/src/WixToolset.Mba.Core/Engine.cs
index 98427cfa..e3ad097a 100644
--- a/src/WixToolset.Mba.Core/Engine.cs
+++ b/src/WixToolset.Mba.Core/Engine.cs
@@ -178,15 +178,21 @@ namespace WixToolset.Mba.Core
178 } 178 }
179 } 179 }
180 180
181 public Version GetVariableVersion(string name) 181 public string GetVariableVersion(string name)
182 { 182 {
183 int ret = this.engine.GetVariableVersion(name, out long value); 183 int length;
184 if (NativeMethods.S_OK != ret) 184 IntPtr pUniString = this.getVersionVariable(name, out length);
185 try
185 { 186 {
186 throw new Win32Exception(ret); 187 return Marshal.PtrToStringUni(pUniString, length);
188 }
189 finally
190 {
191 if (IntPtr.Zero != pUniString)
192 {
193 Marshal.FreeCoTaskMem(pUniString);
194 }
187 } 195 }
188
189 return LongToVersion(value);
190 } 196 }
191 197
192 public void LaunchApprovedExe(IntPtr hwndParent, string approvedExeForElevationId, string arguments) 198 public void LaunchApprovedExe(IntPtr hwndParent, string approvedExeForElevationId, string arguments)
@@ -224,12 +230,12 @@ namespace WixToolset.Mba.Core
224 this.engine.SetDownloadSource(packageOrContainerId, payloadId, url, user, password); 230 this.engine.SetDownloadSource(packageOrContainerId, payloadId, url, user, password);
225 } 231 }
226 232
227 public void SetVariable(string name, long value) 233 public void SetVariableNumeric(string name, long value)
228 { 234 {
229 this.engine.SetVariableNumeric(name, value); 235 this.engine.SetVariableNumeric(name, value);
230 } 236 }
231 237
232 public void SetVariable(string name, SecureString value, bool formatted) 238 public void SetVariableString(string name, SecureString value, bool formatted)
233 { 239 {
234 IntPtr pValue = Marshal.SecureStringToCoTaskMemUnicode(value); 240 IntPtr pValue = Marshal.SecureStringToCoTaskMemUnicode(value);
235 try 241 try
@@ -242,7 +248,7 @@ namespace WixToolset.Mba.Core
242 } 248 }
243 } 249 }
244 250
245 public void SetVariable(string name, string value, bool formatted) 251 public void SetVariableString(string name, string value, bool formatted)
246 { 252 {
247 IntPtr pValue = Marshal.StringToCoTaskMemUni(value); 253 IntPtr pValue = Marshal.StringToCoTaskMemUni(value);
248 try 254 try
@@ -255,10 +261,17 @@ namespace WixToolset.Mba.Core
255 } 261 }
256 } 262 }
257 263
258 public void SetVariable(string name, Version value) 264 public void SetVariableVersion(string name, string value)
259 { 265 {
260 long version = VersionToLong(value); 266 IntPtr pValue = Marshal.StringToCoTaskMemUni(value);
261 this.engine.SetVariableVersion(name, version); 267 try
268 {
269 this.engine.SetVariableVersion(name, pValue);
270 }
271 finally
272 {
273 Marshal.FreeCoTaskMem(pValue);
274 }
262 } 275 }
263 276
264 public int SendEmbeddedError(int errorCode, string message, int uiHint) 277 public int SendEmbeddedError(int errorCode, string message, int uiHint)
@@ -330,6 +343,55 @@ namespace WixToolset.Mba.Core
330 } 343 }
331 344
332 /// <summary> 345 /// <summary>
346 /// Gets the variable given by <paramref name="name"/> as a version string.
347 /// </summary>
348 /// <param name="name">The name of the variable to get.</param>
349 /// <param name="length">The length of the Unicode string.</param>
350 /// <returns>The value by a pointer to a Unicode string. Must be freed by Marshal.FreeCoTaskMem.</returns>
351 /// <exception cref="Exception">An error occurred getting the variable.</exception>
352 internal IntPtr getVersionVariable(string name, out int length)
353 {
354 int capacity = InitialBufferSize;
355 bool success = false;
356 IntPtr pValue = Marshal.AllocCoTaskMem(capacity * UnicodeEncoding.CharSize);
357 try
358 {
359 // Get the size of the buffer.
360 int ret = this.engine.GetVariableVersion(name, pValue, ref capacity);
361 if (NativeMethods.E_INSUFFICIENT_BUFFER == ret || NativeMethods.E_MOREDATA == ret)
362 {
363 // Don't need to add 1 for the null terminator, the engine already includes that.
364 pValue = Marshal.ReAllocCoTaskMem(pValue, capacity * UnicodeEncoding.CharSize);
365 ret = this.engine.GetVariableVersion(name, pValue, ref capacity);
366 }
367
368 if (NativeMethods.S_OK != ret)
369 {
370 throw Marshal.GetExceptionForHR(ret);
371 }
372
373 // The engine only returns the exact length of the string if the buffer was too small, so calculate it ourselves.
374 for (length = 0; length < capacity; ++length)
375 {
376 if (0 == Marshal.ReadInt16(pValue, length * UnicodeEncoding.CharSize))
377 {
378 break;
379 }
380 }
381
382 success = true;
383 return pValue;
384 }
385 finally
386 {
387 if (!success && IntPtr.Zero != pValue)
388 {
389 Marshal.FreeCoTaskMem(pValue);
390 }
391 }
392 }
393
394 /// <summary>
333 /// Initialize a SecureString with the given Unicode string. 395 /// Initialize a SecureString with the given Unicode string.
334 /// </summary> 396 /// </summary>
335 /// <param name="pUniString">Pointer to Unicode string.</param> 397 /// <param name="pUniString">Pointer to Unicode string.</param>