diff --git a/PInvoke/Shared/WinError/Win32Error.cs b/PInvoke/Shared/WinError/Win32Error.cs
index 3967c53f..1ea738fc 100644
--- a/PInvoke/Shared/WinError/Win32Error.cs
+++ b/PInvoke/Shared/WinError/Win32Error.cs
@@ -4,297 +4,283 @@ using System.Globalization;
using System.Runtime.InteropServices;
using System.Security;
-namespace Vanara.PInvoke
+namespace Vanara.PInvoke;
+
+/// Represents a Win32 Error Code. This can be used in place of a return value.
+[StructLayout(LayoutKind.Sequential, Pack = 4)]
+[TypeConverter(typeof(Win32ErrorTypeConverter))]
+[PInvokeData("winerr.h")]
+public partial struct Win32Error : IEquatable, IEquatable, IConvertible, IComparable, IComparable, IErrorProvider
{
- /// Represents a Win32 Error Code. This can be used in place of a return value.
- [StructLayout(LayoutKind.Sequential, Pack = 4)]
- [TypeConverter(typeof(Win32ErrorTypeConverter))]
- [PInvokeData("winerr.h")]
- public partial struct Win32Error : IEquatable, IEquatable, IConvertible, IComparable, IComparable, IErrorProvider
+ internal readonly uint value;
+
+ /// Initializes a new instance of the struct with an error value.
+ /// The error value.
+ public Win32Error(uint i) => value = i;
+
+ /// Gets a value indicating whether this is a failure.
+ /// if failed; otherwise, .
+ public bool Failed => !Succeeded;
+
+ /// Gets a value indicating whether this is a success.
+ /// if succeeded; otherwise, .
+ public bool Succeeded => value == ERROR_SUCCESS;
+
+ /// Performs an explicit conversion from to .
+ /// The error.
+ /// The result of the conversion.
+ 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);
+
+ /// Performs an explicit conversion from to .
+ /// The value.
+ /// The result of the conversion.
+ public static explicit operator uint(Win32Error value) => value.value;
+
+ /// Tries to extract a Win32Error from an exception.
+ /// The exception.
+ /// The error. If undecipherable, ERROR_UNIDENTIFIED_ERROR is returned.
+ public static Win32Error FromException(Exception exception)
{
- internal readonly uint value;
-
- /// Initializes a new instance of the struct with an error value.
- /// The i.
- public Win32Error(uint i) => value = i;
-
- /// Gets a value indicating whether this is a failure.
- /// true if failed; otherwise, false.
- public bool Failed => !Succeeded;
-
- /// Gets a value indicating whether this is a success.
- /// true if succeeded; otherwise, false.
- public bool Succeeded => value == ERROR_SUCCESS;
-
- /// Performs an explicit conversion from to .
- /// The error.
- /// The result of the conversion.
- 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);
-
- /// Performs an explicit conversion from to .
- /// The value.
- /// The result of the conversion.
- public static explicit operator uint(Win32Error value) => value.value;
-
- /// Tries to extract a Win32Error from an exception.
- /// The exception.
- /// The error. If undecipherable, ERROR_UNIDENTIFIED_ERROR is returned.
- public static Win32Error FromException(Exception exception)
- {
- if (exception is Win32Exception we)
- return unchecked((uint)we.NativeErrorCode);
- if (exception.InnerException is Win32Exception iwe)
- return unchecked((uint)iwe.NativeErrorCode);
- var hr = new HRESULT(exception.HResult);
- if (hr.Facility == HRESULT.FacilityCode.FACILITY_WIN32)
- return unchecked((uint)hr.Code);
- return ERROR_UNIDENTIFIED_ERROR;
- }
-
- /// Gets the last error.
- ///
- [SecurityCritical]
- [System.Diagnostics.DebuggerStepThrough]
- public static Win32Error GetLastError() => new Win32Error(ExtGetLastError());
-
- /// Performs an explicit conversion from to .
- /// The value.
- /// The result of the conversion.
- public static implicit operator Win32Error(uint value) => new Win32Error(value);
-
- /// Implements the operator !=.
- /// The error left.
- /// The error right.
- /// The result of the operator.
- public static bool operator !=(Win32Error errLeft, Win32Error errRight) => errLeft.value != errRight.value;
-
- /// Implements the operator !=.
- /// The error left.
- /// The error right.
- /// The result of the operator.
- public static bool operator !=(Win32Error errLeft, uint errRight) => errLeft.value != errRight;
-
- /// Implements the operator ==.
- /// The error left.
- /// The error right.
- /// The result of the operator.
- public static bool operator ==(Win32Error errLeft, Win32Error errRight) => errLeft.value == errRight.value;
-
- /// Implements the operator ==.
- /// The error left.
- /// The error right.
- /// The result of the operator.
- public static bool operator ==(Win32Error errLeft, uint errRight) => errLeft.value == errRight;
-
- /// Throws if failed.
- /// The error.
- /// The message.
- [System.Diagnostics.DebuggerStepThrough]
- public static void ThrowIfFailed(Win32Error err, string message = null) => err.ThrowIfFailed(message);
-
- /// Throws the last error.
- /// The message to associate with the exception.
- [System.Diagnostics.DebuggerStepThrough]
- public static void ThrowLastError(string message = null) => GetLastError().ThrowIfFailed(message);
-
- /// Throws the last error if the predicate delegate returns .
- ///
- /// The value to check.
- /// The delegate which returns on failure.
- /// The message.
- /// The passed in on success.
- public static T ThrowLastErrorIf(T value, Func valueIsFailure, string message = null)
- {
- if (valueIsFailure(value))
- GetLastError().ThrowIfFailed(message);
- return value;
- }
-
- /// Throws the last error if the function returns .
- /// The value to check.
- /// The message.
- public static bool ThrowLastErrorIfFalse(bool value, string message = null) => ThrowLastErrorIf(value, v => !v, message);
-
- /// Throws the last error if the value is an invalid handle.
- /// The SafeHandle to check.
- /// The message.
- public static T ThrowLastErrorIfInvalid(T value, string message = null) where T : SafeHandle => ThrowLastErrorIf(value, v => v.IsInvalid, message);
-
- /// Throws the last error if the value is a NULL pointer (IntPtr.Zero).
- /// The pointer to check.
- /// The message.
- public static IntPtr ThrowLastErrorIfNull(IntPtr value, string message = null) => ThrowLastErrorIf(value, v => v == IntPtr.Zero, message);
-
- /// Throws if the last error failed, unless the error is the specified value.
- /// The failure code to ignore.
- /// The message to associate with the exception.
- [System.Diagnostics.DebuggerStepThrough]
- public static void ThrowLastErrorUnless(Win32Error exception, string message = null) => GetLastError().ThrowUnless(exception, message);
-
- /// Compares the current object with another object of the same type.
- /// An object to compare with this object.
- ///
- /// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value
- /// Meaning Less than zero This object is less than the parameter.Zero This object is equal to . Greater than zero This object is greater than .
- ///
- public int CompareTo(Win32Error other) => value.CompareTo(other.value);
-
- ///
- /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current
- /// instance precedes, follows, or occurs in the same position in the sort order as the other object.
- ///
- /// An object to compare with this instance.
- ///
- /// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less
- /// than zero This instance precedes in the sort order. Zero This instance occurs in the same position in the
- /// sort order as . Greater than zero This instance follows in the sort order.
- ///
- public int CompareTo(object obj)
- {
- var v = ValueFromObj(obj);
- return v.HasValue
- ? value.CompareTo(v.Value)
- : throw new ArgumentException(@"Object cannot be converted to a Int32 value for comparison.", nameof(obj));
- }
-
- /// Indicates whether the current object is equal to another object of the same type.
- /// An object to compare with this object.
- /// true if the current object is equal to the parameter; otherwise, false.
- ///
- public bool Equals(uint other) => other == value;
-
- /// Determines whether the specified , is equal to this instance.
- /// The to compare with this instance.
- /// true if the specified is equal to this instance; otherwise, false.
- public override bool Equals(object obj) => Equals(value, ValueFromObj(obj));
-
- /// Indicates whether the current object is equal to another object of the same type.
- /// An object to compare with this object.
- /// true if the current object is equal to the parameter; otherwise, false.
- ///
- public bool Equals(Win32Error other) => other.value == value;
-
- /// Gets the .NET associated with the HRESULT value and optionally adds the supplied message.
- /// The optional message to assign to the .
- /// The associated or null if this HRESULT is not a failure.
- [SecurityCritical, SecuritySafeCritical]
- public Exception GetException(string message = null) => Succeeded ? null : ToHRESULT().GetException(message);
-
- /// Returns a hash code for this instance.
- /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
- public override int GetHashCode() => unchecked((int)value);
-
- /// Throws if failed.
- /// The message.
- ///
- [System.Diagnostics.DebuggerStepThrough]
- public void ThrowIfFailed(string message = null)
- {
- if (value != ERROR_SUCCESS) throw GetException(message);
- }
-
- /// Throws if failed, unless the error is the specified value.
- /// The failure code to ignore.
- /// The message.
- [System.Diagnostics.DebuggerStepThrough]
- public void ThrowUnless(Win32Error exception, string message = null)
- {
- if (value != ERROR_SUCCESS && value != (uint)exception) throw GetException(message);
- }
-
- /// Converts this error to an .
- /// The equivalent of this error.
- public HRESULT ToHRESULT() => (HRESULT)this;
-
- /// Returns a that represents this instance.
- /// A that represents this instance.
- public override string ToString()
- {
- StaticFieldValueHash.TryGetFieldName(value, out var err);
- var msg = HRESULT.FormatMessage(value);
- return (err ?? string.Format(CultureInfo.InvariantCulture, "0x{0:X8}", value)) + (msg == null ? "" : ": " + msg);
- }
-
- TypeCode IConvertible.GetTypeCode() => value.GetTypeCode();
-
- bool IConvertible.ToBoolean(IFormatProvider provider) => Succeeded;
-
- byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)value).ToByte(provider);
-
- char IConvertible.ToChar(IFormatProvider provider) => throw new NotSupportedException();
-
- DateTime IConvertible.ToDateTime(IFormatProvider provider) => throw new NotSupportedException();
-
- decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)value).ToDecimal(provider);
-
- double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)value).ToDouble(provider);
-
- short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)value).ToInt16(provider);
-
- int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)value).ToInt32(provider);
-
- long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)value).ToInt64(provider);
-
- sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)value).ToSByte(provider);
-
- float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)value).ToSingle(provider);
-
- string IConvertible.ToString(IFormatProvider provider) => ToString();
-
- object IConvertible.ToType(Type conversionType, IFormatProvider provider) =>
- ((IConvertible)value).ToType(conversionType, provider);
-
- ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)value).ToUInt16(provider);
-
- uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)value).ToUInt32(provider);
-
- ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)value).ToUInt64(provider);
-
- [DllImport(Lib.Kernel32, SetLastError = false, EntryPoint = "GetLastError")]
- private static extern uint ExtGetLastError();
-
- private static uint? ValueFromObj(object obj)
- {
- if (obj == null) return null;
- var c = TypeDescriptor.GetConverter(obj);
- return c.CanConvertTo(typeof(uint)) ? (uint?)c.ConvertTo(obj, typeof(uint)) : null;
- }
+ if (exception is Win32Exception we)
+ return unchecked((uint)we.NativeErrorCode);
+ if (exception.InnerException is Win32Exception iwe)
+ return unchecked((uint)iwe.NativeErrorCode);
+ var hr = new HRESULT(exception.HResult);
+ return hr.Facility == HRESULT.FacilityCode.FACILITY_WIN32 ? (Win32Error)(uint)hr.Code : (Win32Error)ERROR_UNIDENTIFIED_ERROR;
}
- internal class Win32ErrorTypeConverter : TypeConverter
+ /// Gets the last error.
+ /// The last error.
+ [SecurityCritical]
+ [System.Diagnostics.DebuggerStepThrough]
+ public static Win32Error GetLastError() => new(ExtGetLastError());
+
+ /// Performs an explicit conversion from to .
+ /// The value.
+ /// The result of the conversion.
+ public static implicit operator Win32Error(uint value) => new(value);
+
+ /// Implements the operator !=.
+ /// The error left.
+ /// The error right.
+ /// The result of the operator.
+ public static bool operator !=(Win32Error errLeft, Win32Error errRight) => errLeft.value != errRight.value;
+
+ /// Implements the operator !=.
+ /// The error left.
+ /// The error right.
+ /// The result of the operator.
+ public static bool operator !=(Win32Error errLeft, uint errRight) => errLeft.value != errRight;
+
+ /// Implements the operator ==.
+ /// The error left.
+ /// The error right.
+ /// The result of the operator.
+ public static bool operator ==(Win32Error errLeft, Win32Error errRight) => errLeft.value == errRight.value;
+
+ /// Implements the operator ==.
+ /// The error left.
+ /// The error right.
+ /// The result of the operator.
+ public static bool operator ==(Win32Error errLeft, uint errRight) => errLeft.value == errRight;
+
+ /// Throws if failed.
+ /// The error.
+ /// The message.
+ [System.Diagnostics.DebuggerStepThrough]
+ public static void ThrowIfFailed(Win32Error err, string message = null) => err.ThrowIfFailed(message);
+
+ /// Throws the last error.
+ /// The message to associate with the exception.
+ [System.Diagnostics.DebuggerStepThrough]
+ public static void ThrowLastError(string message = null) => GetLastError().ThrowIfFailed(message);
+
+ /// Throws the last error if the predicate delegate returns .
+ /// The type of the value to evaluate.
+ /// The value to check.
+ /// The delegate which returns on failure.
+ /// The message.
+ /// The passed in on success.
+ public static T ThrowLastErrorIf(T value, Func valueIsFailure, string message = null)
{
- public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
- {
- if (sourceType.IsPrimitive && sourceType != typeof(bool) && sourceType != typeof(char))
- return true;
- return base.CanConvertFrom(context, sourceType);
- }
+ if (valueIsFailure(value))
+ GetLastError().ThrowIfFailed(message);
+ return value;
+ }
- public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
- {
- if (destinationType == typeof(string) || destinationType.IsPrimitive && destinationType != typeof(char))
- return true;
- return base.CanConvertTo(context, destinationType);
- }
+ /// Throws the last error if the function returns .
+ /// The value to check.
+ /// The message.
+ public static bool ThrowLastErrorIfFalse(bool value, string message = null) => ThrowLastErrorIf(value, v => !v, message);
- public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
- {
- if (value != null && value.GetType().IsPrimitive && !(value is char) && !(value is bool))
- return new Win32Error((uint)Convert.ChangeType(value, TypeCode.UInt32));
- return base.ConvertFrom(context, culture, value);
- }
+ /// Throws the last error if the value is an invalid handle.
+ /// The SafeHandle to check.
+ /// The message.
+ public static T ThrowLastErrorIfInvalid(T value, string message = null) where T : SafeHandle => ThrowLastErrorIf(value, v => v.IsInvalid, message);
- public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value,
- Type destinationType)
- {
- if (!(value is Win32Error err)) throw new NotSupportedException();
- if (destinationType.IsPrimitive && destinationType != typeof(char))
- return Convert.ChangeType(err, destinationType);
- if (destinationType == typeof(string))
- return err.ToString();
- return base.ConvertTo(context, culture, value, destinationType);
- }
+ /// Throws the last error if the value is a NULL pointer (IntPtr.Zero).
+ /// The pointer to check.
+ /// The message.
+ public static IntPtr ThrowLastErrorIfNull(IntPtr value, string message = null) => ThrowLastErrorIf(value, v => v == IntPtr.Zero, message);
+
+ /// Throws if the last error failed, unless the error is the specified value.
+ /// The failure code to ignore.
+ /// The message to associate with the exception.
+ [System.Diagnostics.DebuggerStepThrough]
+ public static void ThrowLastErrorUnless(Win32Error exception, string message = null) => GetLastError().ThrowUnless(exception, message);
+
+ /// Compares the current object with another object of the same type.
+ /// An object to compare with this object.
+ ///
+ /// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value Meaning
+ /// Less than zero This object is less than the parameter.Zero This object is equal to .
+ /// Greater than zero This object is greater than .
+ ///
+ public int CompareTo(Win32Error other) => value.CompareTo(other.value);
+
+ ///
+ /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance
+ /// precedes, follows, or occurs in the same position in the sort order as the other object.
+ ///
+ /// An object to compare with this instance.
+ ///
+ /// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than
+ /// zero This instance precedes in the sort order. Zero This instance occurs in the same position in the sort
+ /// order as . Greater than zero This instance follows in the sort order.
+ ///
+ public int CompareTo(object obj)
+ {
+ var v = ValueFromObj(obj);
+ return v.HasValue
+ ? value.CompareTo(v.Value)
+ : throw new ArgumentException(@"Object cannot be converted to a Int32 value for comparison.", nameof(obj));
+ }
+
+ /// Indicates whether the current object is equal to another object of the same type.
+ /// An object to compare with this object.
+ /// true if the current object is equal to the parameter; otherwise, false.
+ ///
+ public bool Equals(uint other) => other == value;
+
+ /// Determines whether the specified , is equal to this instance.
+ /// The to compare with this instance.
+ /// if the specified is equal to this instance; otherwise, .
+ public override bool Equals(object obj) => Equals(value, ValueFromObj(obj));
+
+ /// Indicates whether the current object is equal to another object of the same type.
+ /// An object to compare with this object.
+ /// true if the current object is equal to the parameter; otherwise, false.
+ ///
+ public bool Equals(Win32Error other) => other.value == value;
+
+ ///
+ /// Gets the .NET associated with the value and optionally adds the supplied message.
+ ///
+ /// The optional message to assign to the .
+ /// The associated or if this is not a failure.
+ [SecurityCritical, SecuritySafeCritical]
+ public Exception GetException(string message = null) => Succeeded ? null : ToHRESULT().GetException(message);
+
+ /// Returns a hash code for this instance.
+ /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
+ public override int GetHashCode() => unchecked((int)value);
+
+ /// Throws if failed.
+ /// The message.
+ ///
+ [System.Diagnostics.DebuggerStepThrough]
+ public void ThrowIfFailed(string message = null)
+ {
+ if (value != ERROR_SUCCESS) throw GetException(message);
+ }
+
+ /// Throws if failed, unless the error is the specified value.
+ /// The failure code to ignore.
+ /// The message.
+ [System.Diagnostics.DebuggerStepThrough]
+ public void ThrowUnless(Win32Error exception, string message = null)
+ {
+ if (value != ERROR_SUCCESS && value != (uint)exception) throw GetException(message);
+ }
+
+ /// Converts this error to an .
+ /// The equivalent of this error.
+ public HRESULT ToHRESULT() => (HRESULT)this;
+
+ /// Returns a that represents this instance.
+ /// A that represents this instance.
+ public override string ToString()
+ {
+ _=StaticFieldValueHash.TryGetFieldName(value, out var err);
+ var msg = HRESULT.FormatMessage(value);
+ return (err ?? string.Format(CultureInfo.InvariantCulture, "0x{0:X8}", value)) + (msg == null ? "" : ": " + msg);
+ }
+
+ TypeCode IConvertible.GetTypeCode() => value.GetTypeCode();
+
+ bool IConvertible.ToBoolean(IFormatProvider provider) => Succeeded;
+
+ byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)value).ToByte(provider);
+
+ char IConvertible.ToChar(IFormatProvider provider) => throw new NotSupportedException();
+
+ DateTime IConvertible.ToDateTime(IFormatProvider provider) => throw new NotSupportedException();
+
+ decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)value).ToDecimal(provider);
+
+ double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)value).ToDouble(provider);
+
+ short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)value).ToInt16(provider);
+
+ int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)value).ToInt32(provider);
+
+ long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)value).ToInt64(provider);
+
+ sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)value).ToSByte(provider);
+
+ float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)value).ToSingle(provider);
+
+ string IConvertible.ToString(IFormatProvider provider) => ToString();
+
+ object IConvertible.ToType(Type conversionType, IFormatProvider provider) =>
+ ((IConvertible)value).ToType(conversionType, provider);
+
+ ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)value).ToUInt16(provider);
+
+ uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)value).ToUInt32(provider);
+
+ ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)value).ToUInt64(provider);
+
+ [DllImport(Lib.Kernel32, SetLastError = false, EntryPoint = "GetLastError")]
+ private static extern uint ExtGetLastError();
+
+ private static uint? ValueFromObj(object obj)
+ {
+ if (obj == null) return null;
+ TypeConverter c = TypeDescriptor.GetConverter(obj);
+ return c.CanConvertTo(typeof(uint)) ? (uint?)c.ConvertTo(obj, typeof(uint)) : null;
+ }
+}
+
+internal class Win32ErrorTypeConverter : TypeConverter
+{
+ public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) =>
+ sourceType.IsPrimitive && sourceType != typeof(bool) && sourceType != typeof(char) || base.CanConvertFrom(context, sourceType);
+
+ public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) =>
+ destinationType == typeof(string) || destinationType.IsPrimitive && destinationType != typeof(char) || base.CanConvertTo(context, destinationType);
+
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) =>
+ value != null && value.GetType().IsPrimitive && value is not char && value is not bool
+ ? new Win32Error((uint)Convert.ChangeType(value, TypeCode.UInt32))
+ : base.ConvertFrom(context, culture, value);
+
+ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
+ {
+ if (value is not Win32Error err) throw new NotSupportedException();
+ if (destinationType.IsPrimitive && destinationType != typeof(char))
+ return Convert.ChangeType(err, destinationType);
+ return destinationType == typeof(string) ? err.ToString() : base.ConvertTo(context, culture, value, destinationType);
}
}
\ No newline at end of file