diff --git a/PInvoke/Shared/FunctionHelper.cs b/PInvoke/Shared/FunctionHelper.cs
index 4a4977aa..a77fcc96 100644
--- a/PInvoke/Shared/FunctionHelper.cs
+++ b/PInvoke/Shared/FunctionHelper.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Text;
using Vanara.Extensions;
using Vanara.InteropServices;
@@ -8,6 +9,8 @@ namespace Vanara.PInvoke
/// Generic functions to help with standard function patterns like getting a string from a method.
public static class FunctionHelper
{
+ private static readonly List buffErrs = new List { Win32Error.ERROR_MORE_DATA, Win32Error.ERROR_INSUFFICIENT_BUFFER, Win32Error.ERROR_BUFFER_OVERFLOW };
+
/// Delegate to get the size of memory allocated to a pointer.
/// The type of the size result. This is usually or .
/// The pointer to the memory in question.
@@ -44,7 +47,7 @@ namespace Vanara.PInvoke
/// On input, the size of the capacity. On output, the number of characters written.
/// The error.
/// true if buffer size is good; otherwise false.
- public static bool ChkGoodBuf(TSize sz, TRet err) where TSize : struct where TRet : IErrorProvider, IConvertible => !sz.Equals(default(TSize)) && (err.ToHRESULT() == (HRESULT)(Win32Error)Win32Error.ERROR_MORE_DATA || err.ToHRESULT() == (HRESULT)(Win32Error)Win32Error.ERROR_INSUFFICIENT_BUFFER);
+ public static bool ChkGoodBuf(TSize sz, TRet err) where TSize : struct where TRet : IErrorProvider, IConvertible => !sz.Equals(default(TSize)) && buffErrs.ConvertAll(e => (HRESULT)e).Contains(err.ToHRESULT());
/// Calls a method with and gets the resulting string or error.
/// The type of the size result. This is usually or .
@@ -87,20 +90,25 @@ namespace Vanara.PInvoke
return ret;
}
- /// Calls a method with buffer for a type and gets the result or error.
+ ///
+ /// Calls a method with buffer for a type and gets the result or error.
+ ///
/// The return type.
- /// The type of the size result. This is usually or .
+ /// The type of the size result. This is usually or .
/// Method to get the size of the buffer.
/// The lambda or method to call into.
- /// The resulting value of .
- /// An optional method to convert the pointer to the type specified by . By default, this will marshal the pointer to the structure.
- /// Resulting error or on success.
- public static Win32Error CallMethodWithTypedBuf(SizeFunc getSize, PtrFunc method, out TOut result, Func outConverter = null) where TSize : struct, IConvertible
+ /// The resulting value of .
+ /// An optional method to convert the pointer to the type specified by . By default, this will marshal the pointer to the structure.
+ /// The optional error returns when the buffer size is insufficient. If left , then a list of well known errors will be used.
+ ///
+ /// Resulting error or on success.
+ ///
+ public static Win32Error CallMethodWithTypedBuf(SizeFunc getSize, PtrFunc method, out TOut result, Func outConverter = null, Win32Error? bufErr = null) where TSize : struct, IConvertible
{
TSize sz = default;
result = default;
var err = (getSize ?? GetSize)(ref sz);
- if (err.Failed) return err;
+ if (err.Failed && (bufErr == null || bufErr.Value != err) && !buffErrs.Contains(err)) return err;
using (var buf = new SafeHGlobalHandle(sz.ToInt32(null)))
{
var ret = method(buf.DangerousGetHandle(), ref sz);
@@ -108,7 +116,7 @@ namespace Vanara.PInvoke
return ret;
}
- Win32Error GetSize(ref TSize sz1) { var serr = method(IntPtr.Zero, ref sz1); return serr == Win32Error.ERROR_INSUFFICIENT_BUFFER || serr == Win32Error.ERROR_MORE_DATA ? Win32Error.ERROR_SUCCESS : serr; }
+ Win32Error GetSize(ref TSize sz1) => method(IntPtr.Zero, ref sz1);
TOut Conv(IntPtr p, TSize s) => p.ToStructure();
}
@@ -118,10 +126,11 @@ namespace Vanara.PInvoke
/// The lambda or method to call into.
/// Method to get the size of the buffer.
/// An optional method to convert the pointer to the type specified by . By default, this will marshal the pointer to the structure.
+ /// The optional error returns when the buffer size is insufficient. If left , then a list of well known errors will be used.
/// The resulting value of .
- public static TOut CallMethodWithTypedBuf(PtrFunc method, SizeFunc getSize = null, Func outConverter = null) where TSize : struct, IConvertible
+ public static TOut CallMethodWithTypedBuf(PtrFunc method, SizeFunc getSize = null, Func outConverter = null, Win32Error? bufErr = null) where TSize : struct, IConvertible
{
- CallMethodWithTypedBuf(getSize, method, out var res, outConverter).ThrowIfFailed();
+ CallMethodWithTypedBuf(getSize, method, out var res, outConverter, bufErr).ThrowIfFailed();
return res;
}
}