diff options
Diffstat (limited to 'src/WixToolset.Mba.Core/Engine.cs')
-rw-r--r-- | src/WixToolset.Mba.Core/Engine.cs | 86 |
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> |