Cleaned Win32Error and fixed some docs

pull/303/head
dahall 2022-07-10 17:29:30 -06:00
parent dba346c0d0
commit 51bd754440
1 changed files with 270 additions and 284 deletions

View File

@ -4,8 +4,8 @@ using System.Globalization;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security; using System.Security;
namespace Vanara.PInvoke namespace Vanara.PInvoke;
{
/// <summary>Represents a Win32 Error Code. This can be used in place of a return value.</summary> /// <summary>Represents a Win32 Error Code. This can be used in place of a return value.</summary>
[StructLayout(LayoutKind.Sequential, Pack = 4)] [StructLayout(LayoutKind.Sequential, Pack = 4)]
[TypeConverter(typeof(Win32ErrorTypeConverter))] [TypeConverter(typeof(Win32ErrorTypeConverter))]
@ -15,15 +15,15 @@ namespace Vanara.PInvoke
internal readonly uint value; internal readonly uint value;
/// <summary>Initializes a new instance of the <see cref="Win32Error"/> struct with an error value.</summary> /// <summary>Initializes a new instance of the <see cref="Win32Error"/> struct with an error value.</summary>
/// <param name="i">The i.</param> /// <param name="i">The error value.</param>
public Win32Error(uint i) => value = i; public Win32Error(uint i) => value = i;
/// <summary>Gets a value indicating whether this <see cref="Win32Error"/> is a failure.</summary> /// <summary>Gets a value indicating whether this <see cref="Win32Error"/> is a failure.</summary>
/// <value><c>true</c> if failed; otherwise, <c>false</c>.</value> /// <value><see langword="true"/> if failed; otherwise, <see langword="false"/>.</value>
public bool Failed => !Succeeded; public bool Failed => !Succeeded;
/// <summary>Gets a value indicating whether this <see cref="Win32Error"/> is a success.</summary> /// <summary>Gets a value indicating whether this <see cref="Win32Error"/> is a success.</summary>
/// <value><c>true</c> if succeeded; otherwise, <c>false</c>.</value> /// <value><see langword="true"/><see langword="true"/> if succeeded; otherwise, <see langword="false"/>.</value>
public bool Succeeded => value == ERROR_SUCCESS; public bool Succeeded => value == ERROR_SUCCESS;
/// <summary>Performs an explicit conversion from <see cref="Win32Error"/> to <see cref="HRESULT"/>.</summary> /// <summary>Performs an explicit conversion from <see cref="Win32Error"/> to <see cref="HRESULT"/>.</summary>
@ -32,7 +32,7 @@ namespace Vanara.PInvoke
public static explicit operator HRESULT(Win32Error error) => public static explicit operator HRESULT(Win32Error error) =>
unchecked((int)error.value) <= 0 ? unchecked((int)error.value) : HRESULT.Make(true, HRESULT.FacilityCode.FACILITY_WIN32, error.value & 0xffff); unchecked((int)error.value) <= 0 ? unchecked((int)error.value) : HRESULT.Make(true, HRESULT.FacilityCode.FACILITY_WIN32, error.value & 0xffff);
/// <summary>Performs an explicit conversion from <see cref="Win32Error"/> to <see cref="System.Int32"/>.</summary> /// <summary>Performs an explicit conversion from <see cref="Win32Error"/> to <see cref="int"/>.</summary>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
/// <returns>The result of the conversion.</returns> /// <returns>The result of the conversion.</returns>
public static explicit operator uint(Win32Error value) => value.value; public static explicit operator uint(Win32Error value) => value.value;
@ -47,21 +47,19 @@ namespace Vanara.PInvoke
if (exception.InnerException is Win32Exception iwe) if (exception.InnerException is Win32Exception iwe)
return unchecked((uint)iwe.NativeErrorCode); return unchecked((uint)iwe.NativeErrorCode);
var hr = new HRESULT(exception.HResult); var hr = new HRESULT(exception.HResult);
if (hr.Facility == HRESULT.FacilityCode.FACILITY_WIN32) return hr.Facility == HRESULT.FacilityCode.FACILITY_WIN32 ? (Win32Error)(uint)hr.Code : (Win32Error)ERROR_UNIDENTIFIED_ERROR;
return unchecked((uint)hr.Code);
return ERROR_UNIDENTIFIED_ERROR;
} }
/// <summary>Gets the last error.</summary> /// <summary>Gets the last error.</summary>
/// <returns></returns> /// <returns>The last error.</returns>
[SecurityCritical] [SecurityCritical]
[System.Diagnostics.DebuggerStepThrough] [System.Diagnostics.DebuggerStepThrough]
public static Win32Error GetLastError() => new Win32Error(ExtGetLastError()); public static Win32Error GetLastError() => new(ExtGetLastError());
/// <summary>Performs an explicit conversion from <see cref="System.Int32"/> to <see cref="Win32Error"/>.</summary> /// <summary>Performs an explicit conversion from <see cref="int"/> to <see cref="Win32Error"/>.</summary>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
/// <returns>The result of the conversion.</returns> /// <returns>The result of the conversion.</returns>
public static implicit operator Win32Error(uint value) => new Win32Error(value); public static implicit operator Win32Error(uint value) => new(value);
/// <summary>Implements the operator !=.</summary> /// <summary>Implements the operator !=.</summary>
/// <param name="errLeft">The error left.</param> /// <param name="errLeft">The error left.</param>
@ -99,7 +97,7 @@ namespace Vanara.PInvoke
public static void ThrowLastError(string message = null) => GetLastError().ThrowIfFailed(message); public static void ThrowLastError(string message = null) => GetLastError().ThrowIfFailed(message);
/// <summary>Throws the last error if the predicate delegate returns <see langword="true"/>.</summary> /// <summary>Throws the last error if the predicate delegate returns <see langword="true"/>.</summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T">The type of the value to evaluate.</typeparam>
/// <param name="value">The value to check.</param> /// <param name="value">The value to check.</param>
/// <param name="valueIsFailure">The delegate which returns <see langword="true"/> on failure.</param> /// <param name="valueIsFailure">The delegate which returns <see langword="true"/> on failure.</param>
/// <param name="message">The message.</param> /// <param name="message">The message.</param>
@ -135,21 +133,21 @@ namespace Vanara.PInvoke
/// <summary>Compares the current object with another object of the same type.</summary> /// <summary>Compares the current object with another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param> /// <param name="other">An object to compare with this object.</param>
/// <returns> /// <returns>
/// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value /// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value Meaning
/// Meaning Less than zero This object is less than the <paramref name="other"/> parameter.Zero This object is equal to <paramref /// Less than zero This object is less than the <paramref name="other"/> parameter.Zero This object is equal to <paramref name="other"/>.
/// name="other"/>. Greater than zero This object is greater than <paramref name="other"/>. /// Greater than zero This object is greater than <paramref name="other"/>.
/// </returns> /// </returns>
public int CompareTo(Win32Error other) => value.CompareTo(other.value); public int CompareTo(Win32Error other) => value.CompareTo(other.value);
/// <summary> /// <summary>
/// Compares the current instance with another object of the same type and returns an integer that indicates whether the current /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance
/// instance precedes, follows, or occurs in the same position in the sort order as the other object. /// precedes, follows, or occurs in the same position in the sort order as the other object.
/// </summary> /// </summary>
/// <param name="obj">An object to compare with this instance.</param> /// <param name="obj">An object to compare with this instance.</param>
/// <returns> /// <returns>
/// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less /// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than
/// than zero This instance precedes <paramref name="obj"/> in the sort order. Zero This instance occurs in the same position in the /// zero This instance precedes <paramref name="obj"/> in the sort order. Zero This instance occurs in the same position in the sort
/// sort order as <paramref name="obj"/>. Greater than zero This instance follows <paramref name="obj"/> in the sort order. /// order as <paramref name="obj"/>. Greater than zero This instance follows <paramref name="obj"/> in the sort order.
/// </returns> /// </returns>
public int CompareTo(object obj) public int CompareTo(object obj)
{ {
@ -165,9 +163,9 @@ namespace Vanara.PInvoke
/// <exception cref="System.NotImplementedException"></exception> /// <exception cref="System.NotImplementedException"></exception>
public bool Equals(uint other) => other == value; public bool Equals(uint other) => other == value;
/// <summary>Determines whether the specified <see cref="System.Object"/>, is equal to this instance.</summary> /// <summary>Determines whether the specified <see cref="object"/>, is equal to this instance.</summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param> /// <param name="obj">The <see cref="object"/> to compare with this instance.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.</returns> /// <returns><see langword="true"/> if the specified <see cref="object"/> is equal to this instance; otherwise, <see langword="false"/>.</returns>
public override bool Equals(object obj) => Equals(value, ValueFromObj(obj)); public override bool Equals(object obj) => Equals(value, ValueFromObj(obj));
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary> /// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
@ -176,9 +174,11 @@ namespace Vanara.PInvoke
/// <exception cref="System.NotImplementedException"></exception> /// <exception cref="System.NotImplementedException"></exception>
public bool Equals(Win32Error other) => other.value == value; public bool Equals(Win32Error other) => other.value == value;
/// <summary>Gets the .NET <see cref="Exception"/> associated with the HRESULT value and optionally adds the supplied message.</summary> /// <summary>
/// Gets the .NET <see cref="Exception"/> associated with the <see cref="Win32Error"/> value and optionally adds the supplied message.
/// </summary>
/// <param name="message">The optional message to assign to the <see cref="Exception"/>.</param> /// <param name="message">The optional message to assign to the <see cref="Exception"/>.</param>
/// <returns>The associated <see cref="Exception"/> or <c>null</c> if this HRESULT is not a failure.</returns> /// <returns>The associated <see cref="Exception"/> or <see langword="null"/> if this <see cref="Win32Error"/> is not a failure.</returns>
[SecurityCritical, SecuritySafeCritical] [SecurityCritical, SecuritySafeCritical]
public Exception GetException(string message = null) => Succeeded ? null : ToHRESULT().GetException(message); public Exception GetException(string message = null) => Succeeded ? null : ToHRESULT().GetException(message);
@ -208,11 +208,11 @@ namespace Vanara.PInvoke
/// <returns>The <see cref="HRESULT"/> equivalent of this error.</returns> /// <returns>The <see cref="HRESULT"/> equivalent of this error.</returns>
public HRESULT ToHRESULT() => (HRESULT)this; public HRESULT ToHRESULT() => (HRESULT)this;
/// <summary>Returns a <see cref="System.String"/> that represents this instance.</summary> /// <summary>Returns a <see cref="string"/> that represents this instance.</summary>
/// <returns>A <see cref="System.String"/> that represents this instance.</returns> /// <returns>A <see cref="string"/> that represents this instance.</returns>
public override string ToString() public override string ToString()
{ {
StaticFieldValueHash.TryGetFieldName<Win32Error, uint>(value, out var err); _=StaticFieldValueHash.TryGetFieldName<Win32Error, uint>(value, out var err);
var msg = HRESULT.FormatMessage(value); var msg = HRESULT.FormatMessage(value);
return (err ?? string.Format(CultureInfo.InvariantCulture, "0x{0:X8}", value)) + (msg == null ? "" : ": " + msg); return (err ?? string.Format(CultureInfo.InvariantCulture, "0x{0:X8}", value)) + (msg == null ? "" : ": " + msg);
} }
@ -258,43 +258,29 @@ namespace Vanara.PInvoke
private static uint? ValueFromObj(object obj) private static uint? ValueFromObj(object obj)
{ {
if (obj == null) return null; if (obj == null) return null;
var c = TypeDescriptor.GetConverter(obj); TypeConverter c = TypeDescriptor.GetConverter(obj);
return c.CanConvertTo(typeof(uint)) ? (uint?)c.ConvertTo(obj, typeof(uint)) : null; return c.CanConvertTo(typeof(uint)) ? (uint?)c.ConvertTo(obj, typeof(uint)) : null;
} }
} }
internal class Win32ErrorTypeConverter : TypeConverter internal class Win32ErrorTypeConverter : TypeConverter
{ {
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) =>
{ sourceType.IsPrimitive && sourceType != typeof(bool) && sourceType != typeof(char) || base.CanConvertFrom(context, sourceType);
if (sourceType.IsPrimitive && sourceType != typeof(bool) && sourceType != typeof(char))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) =>
{ destinationType == typeof(string) || destinationType.IsPrimitive && destinationType != typeof(char) || base.CanConvertTo(context, destinationType);
if (destinationType == typeof(string) || destinationType.IsPrimitive && destinationType != typeof(char))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) =>
{ value != null && value.GetType().IsPrimitive && value is not char && value is not bool
if (value != null && value.GetType().IsPrimitive && !(value is char) && !(value is bool)) ? new Win32Error((uint)Convert.ChangeType(value, TypeCode.UInt32))
return new Win32Error((uint)Convert.ChangeType(value, TypeCode.UInt32)); : base.ConvertFrom(context, culture, value);
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
Type destinationType)
{ {
if (!(value is Win32Error err)) throw new NotSupportedException(); if (value is not Win32Error err) throw new NotSupportedException();
if (destinationType.IsPrimitive && destinationType != typeof(char)) if (destinationType.IsPrimitive && destinationType != typeof(char))
return Convert.ChangeType(err, destinationType); return Convert.ChangeType(err, destinationType);
if (destinationType == typeof(string)) return destinationType == typeof(string) ? err.ToString() : base.ConvertTo(context, culture, value, destinationType);
return err.ToString();
return base.ConvertTo(context, culture, value, destinationType);
}
} }
} }