Exemplo n.º 1
0
        /// <summary>
        /// Calls a method with buffer for a type and gets the result or error.
        /// </summary>
        /// <typeparam name="TOut">The return type.</typeparam>
        /// <typeparam name="TSize">The type of the size result. This is usually <see cref="int" /> or <see cref="uint" />.</typeparam>
        /// <param name="getSize">Method to get the size of the buffer.</param>
        /// <param name="method">The lambda or method to call into.</param>
        /// <param name="result">The resulting value of <typeparamref name="TOut" />.</param>
        /// <param name="outConverter">An optional method to convert the pointer to the type specified by <typeparamref name="TOut" />. By default, this will marshal the pointer to the structure.</param>
        /// <param name="bufErr">The optional error <paramref name="method"/> returns when the buffer size is insufficient. If left <see langword="null"/>, then a list of well known errors will be used.</param>
        /// <returns>
        /// Resulting error or <see cref="Win32Error.ERROR_SUCCESS" /> on success.
        /// </returns>
        public static Win32Error CallMethodWithTypedBuf <TOut, TSize>(SizeFunc <TSize> getSize, PtrFunc <TSize> method, out TOut result, Func <IntPtr, TSize, TOut> outConverter = null, Win32Error?bufErr = null) where TSize : struct, IConvertible
        {
            TSize sz = default;

            result = default;
            var err = (getSize ?? GetSize)(ref sz);

            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);
                result = (outConverter ?? Conv)(buf.DangerousGetHandle(), sz);
                return(ret);
            }

            Win32Error GetSize(ref TSize sz1) => method(IntPtr.Zero, ref sz1);
            TOut Conv(IntPtr p, TSize s) => p.ToStructure <TOut>();
        }
Exemplo n.º 2
0
        public static Win32Error CallMethodWithTypedBuf <TOut, TSize>(SizeFunc <TSize> getSize, PtrFunc <TSize> method, out TOut result, Func <IntPtr, TSize, TOut> outConverter = null) where TSize : struct, IConvertible
        {
            TSize sz = default;

            result = default;
            var err = getSize(ref sz);

            if (err.Failed)
            {
                return(err);
            }
            var len = sz.ToInt32(null);

            using (var buf = new SafeHGlobalHandle(len))
            {
                var ret = method(buf.DangerousGetHandle(), ref sz);
                result = (outConverter ?? Conv)(buf.DangerousGetHandle(), sz);
                return(ret);
            }

            TOut Conv(IntPtr p, TSize s) => p.ToStructure <TOut>();
        }