From a645cabc7a46adaa8f26d913bbb3cc5f9cd07820 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Fri, 7 May 2021 16:37:19 -0500 Subject: Use balutil methods in Engine.cs to avoid size_t ugliness. --- src/api/burn/WixToolset.Mba.Core/Engine.cs | 229 +++++++---------------------- 1 file changed, 50 insertions(+), 179 deletions(-) (limited to 'src/api/burn/WixToolset.Mba.Core/Engine.cs') diff --git a/src/api/burn/WixToolset.Mba.Core/Engine.cs b/src/api/burn/WixToolset.Mba.Core/Engine.cs index aed420d5..5ebada36 100644 --- a/src/api/burn/WixToolset.Mba.Core/Engine.cs +++ b/src/api/burn/WixToolset.Mba.Core/Engine.cs @@ -13,8 +13,6 @@ namespace WixToolset.Mba.Core /// public sealed class Engine : IEngine { - // Burn errs on empty strings, so declare initial buffer size. - private const int InitialBufferSize = 80; private static readonly string normalizeVersionFormatString = "{0} must be less than or equal to " + UInt16.MaxValue; private IBootstrapperEngine engine; @@ -62,9 +60,7 @@ namespace WixToolset.Mba.Core /// public bool ContainsVariable(string name) { - IntPtr capacity = new IntPtr(0); - int ret = this.engine.GetVariableString(name, IntPtr.Zero, ref capacity); - return NativeMethods.E_NOTFOUND != ret; + return BalUtil.BalVariableExistsFromEngine(this.engine, name); } /// @@ -101,24 +97,21 @@ namespace WixToolset.Mba.Core /// public string EscapeString(string input) { - IntPtr capacity = new IntPtr(InitialBufferSize); - StringBuilder sb = new StringBuilder(capacity.ToInt32()); - - // Get the size of the buffer. - int ret = this.engine.EscapeString(input, sb, ref capacity); - if (NativeMethods.E_INSUFFICIENT_BUFFER == ret || NativeMethods.E_MOREDATA == ret) + StrUtil.StrHandle handle = new StrUtil.StrHandle(); + try { - capacity = new IntPtr(capacity.ToInt32() + 1); // Add one for the null terminator. - sb.Capacity = capacity.ToInt32(); - ret = this.engine.EscapeString(input, sb, ref capacity); - } + int ret = BalUtil.BalEscapeStringFromEngine(this.engine, input, ref handle); + if (ret != NativeMethods.S_OK) + { + throw new Win32Exception(ret); + } - if (NativeMethods.S_OK != ret) + return handle.ToUniString(); + } + finally { - throw new Win32Exception(ret); + handle.Dispose(); } - - return sb.ToString(); } /// @@ -133,24 +126,21 @@ namespace WixToolset.Mba.Core /// public string FormatString(string format) { - IntPtr capacity = new IntPtr(InitialBufferSize); - StringBuilder sb = new StringBuilder(capacity.ToInt32()); - - // Get the size of the buffer. - int ret = this.engine.FormatString(format, sb, ref capacity); - if (NativeMethods.E_INSUFFICIENT_BUFFER == ret || NativeMethods.E_MOREDATA == ret) + StrUtil.StrHandle handle = new StrUtil.StrHandle(); + try { - capacity = new IntPtr(capacity.ToInt32() + 1); // Add one for the null terminator. - sb.Capacity = capacity.ToInt32(); - ret = this.engine.FormatString(format, sb, ref capacity); - } + int ret = BalUtil.BalFormatStringFromEngine(this.engine, format, ref handle); + if (ret != NativeMethods.S_OK) + { + throw new Win32Exception(ret); + } - if (NativeMethods.S_OK != ret) + return handle.ToUniString(); + } + finally { - throw new Win32Exception(ret); + handle.Dispose(); } - - return sb.ToString(); } /// @@ -168,53 +158,60 @@ namespace WixToolset.Mba.Core /// public SecureString GetVariableSecureString(string name) { - var pUniString = this.getStringVariable(name, out var length); + StrUtil.StrHandle handle = new StrUtil.StrHandle(); try { - return this.convertToSecureString(pUniString, length); + int ret = BalUtil.BalGetStringVariableFromEngine(this.engine, name, ref handle); + if (ret != NativeMethods.S_OK) + { + throw new Win32Exception(ret); + } + + return handle.ToSecureString(); } finally { - if (IntPtr.Zero != pUniString) - { - Marshal.FreeCoTaskMem(pUniString); - } + handle.Dispose(); } } /// public string GetVariableString(string name) { - int length; - IntPtr pUniString = this.getStringVariable(name, out length); + StrUtil.StrHandle handle = new StrUtil.StrHandle(); try { - return Marshal.PtrToStringUni(pUniString, length); + int ret = BalUtil.BalGetStringVariableFromEngine(this.engine, name, ref handle); + if (ret != NativeMethods.S_OK) + { + throw new Win32Exception(ret); + } + + return handle.ToUniString(); } finally { - if (IntPtr.Zero != pUniString) - { - Marshal.FreeCoTaskMem(pUniString); - } + handle.Dispose(); } } /// public string GetVariableVersion(string name) { - int length; - IntPtr pUniString = this.getVersionVariable(name, out length); + StrUtil.StrHandle handle = new StrUtil.StrHandle(); try { - return Marshal.PtrToStringUni(pUniString, length); + int ret = BalUtil.BalGetVersionVariableFromEngine(this.engine, name, ref handle); + if (ret != NativeMethods.S_OK) + { + throw new Win32Exception(ret); + } + + return handle.ToUniString(); } finally { - if (IntPtr.Zero != pUniString) - { - Marshal.FreeCoTaskMem(pUniString); - } + handle.Dispose(); } } @@ -336,132 +333,6 @@ namespace WixToolset.Mba.Core this.engine.Quit(exitCode); } - /// - /// Gets the variable given by as a string. - /// - /// The name of the variable to get. - /// The length of the Unicode string. - /// The value by a pointer to a Unicode string. Must be freed by Marshal.FreeCoTaskMem. - /// An error occurred getting the variable. - internal IntPtr getStringVariable(string name, out int length) - { - IntPtr capacity = new IntPtr(InitialBufferSize); - bool success = false; - IntPtr pValue = Marshal.AllocCoTaskMem(capacity.ToInt32() * UnicodeEncoding.CharSize); - try - { - // Get the size of the buffer. - int ret = this.engine.GetVariableString(name, pValue, ref capacity); - if (NativeMethods.E_INSUFFICIENT_BUFFER == ret || NativeMethods.E_MOREDATA == ret) - { - // Don't need to add 1 for the null terminator, the engine already includes that. - pValue = Marshal.ReAllocCoTaskMem(pValue, capacity.ToInt32() * UnicodeEncoding.CharSize); - ret = this.engine.GetVariableString(name, pValue, ref capacity); - } - - if (NativeMethods.S_OK != ret) - { - throw Marshal.GetExceptionForHR(ret); - } - - // The engine only returns the exact length of the string if the buffer was too small, so calculate it ourselves. - int maxLength = capacity.ToInt32(); - for (length = 0; length < maxLength; ++length) - { - if (0 == Marshal.ReadInt16(pValue, length * UnicodeEncoding.CharSize)) - { - break; - } - } - - success = true; - return pValue; - } - finally - { - if (!success && IntPtr.Zero != pValue) - { - Marshal.FreeCoTaskMem(pValue); - } - } - } - - /// - /// Gets the variable given by as a version string. - /// - /// The name of the variable to get. - /// The length of the Unicode string. - /// The value by a pointer to a Unicode string. Must be freed by Marshal.FreeCoTaskMem. - /// An error occurred getting the variable. - internal IntPtr getVersionVariable(string name, out int length) - { - IntPtr capacity = new IntPtr(InitialBufferSize); - bool success = false; - IntPtr pValue = Marshal.AllocCoTaskMem(capacity.ToInt32() * UnicodeEncoding.CharSize); - try - { - // Get the size of the buffer. - int ret = this.engine.GetVariableVersion(name, pValue, ref capacity); - if (NativeMethods.E_INSUFFICIENT_BUFFER == ret || NativeMethods.E_MOREDATA == ret) - { - // Don't need to add 1 for the null terminator, the engine already includes that. - pValue = Marshal.ReAllocCoTaskMem(pValue, capacity.ToInt32() * UnicodeEncoding.CharSize); - ret = this.engine.GetVariableVersion(name, pValue, ref capacity); - } - - if (NativeMethods.S_OK != ret) - { - throw Marshal.GetExceptionForHR(ret); - } - - // The engine only returns the exact length of the string if the buffer was too small, so calculate it ourselves. - int maxLength = capacity.ToInt32(); - for (length = 0; length < maxLength; ++length) - { - if (0 == Marshal.ReadInt16(pValue, length * UnicodeEncoding.CharSize)) - { - break; - } - } - - success = true; - return pValue; - } - finally - { - if (!success && IntPtr.Zero != pValue) - { - Marshal.FreeCoTaskMem(pValue); - } - } - } - - /// - /// Initialize a SecureString with the given Unicode string. - /// - /// Pointer to Unicode string. - /// The string's length. - internal SecureString convertToSecureString(IntPtr pUniString, int length) - { - if (IntPtr.Zero == pUniString) - { - return null; - } - - SecureString value = new SecureString(); - short s; - char c; - for (int charIndex = 0; charIndex < length; charIndex++) - { - s = Marshal.ReadInt16(pUniString, charIndex * UnicodeEncoding.CharSize); - c = (char)s; - value.AppendChar(c); - s = 0; - c = (char)0; - } - return value; - } - /// /// Utility method for converting a into a . /// -- cgit v1.2.3-55-g6feb