mirror of https://github.com/dahall/Vanara.git
Fixed issues when converting from UInt32 and FormatMessage when no message was found.
parent
d90581309f
commit
0b4032473b
|
@ -41,7 +41,7 @@ namespace Vanara.PInvoke
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
[TypeConverter(typeof(HRESULTTypeConverter))]
|
||||
[PInvokeData("winerr.h")]
|
||||
public partial struct HRESULT : IComparable, IComparable<HRESULT>, IEquatable<HRESULT>, IEquatable<int>, IConvertible, IErrorProvider
|
||||
public partial struct HRESULT : IComparable, IComparable<HRESULT>, IEquatable<HRESULT>, IEquatable<int>, IEquatable<uint>, IConvertible, IErrorProvider
|
||||
{
|
||||
internal readonly int _value;
|
||||
|
||||
|
@ -261,6 +261,11 @@ namespace Vanara.PInvoke
|
|||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator int(HRESULT value) => value._value;
|
||||
|
||||
/// <summary>Performs an explicit conversion from <see cref="HRESULT"/> to <see cref="System.UInt32"/>.</summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator uint(HRESULT value) => unchecked((uint)value._value);
|
||||
|
||||
/// <summary>Tries to extract a HRESULT from an exception.</summary>
|
||||
/// <param name="exception">The exception.</param>
|
||||
/// <returns>The error. If undecipherable, E_FAIL is returned.</returns>
|
||||
|
@ -352,19 +357,19 @@ namespace Vanara.PInvoke
|
|||
/// <param name="hrLeft">The first <see cref="HRESULT"/>.</param>
|
||||
/// <param name="hrRight">The second <see cref="HRESULT"/>.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator ==(HRESULT hrLeft, HRESULT hrRight) => hrLeft._value == hrRight._value;
|
||||
public static bool operator ==(HRESULT hrLeft, HRESULT hrRight) => hrLeft.Equals(hrRight);
|
||||
|
||||
/// <summary>Implements the operator ==.</summary>
|
||||
/// <param name="hrLeft">The first <see cref="HRESULT"/>.</param>
|
||||
/// <param name="hrRight">The second <see cref="int"/>.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator ==(HRESULT hrLeft, int hrRight) => hrLeft._value == hrRight;
|
||||
public static bool operator ==(HRESULT hrLeft, int hrRight) => hrLeft.Equals(hrRight);
|
||||
|
||||
/// <summary>Implements the operator ==.</summary>
|
||||
/// <param name="hrLeft">The first <see cref="HRESULT"/>.</param>
|
||||
/// <param name="hrRight">The second <see cref="uint"/>.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator ==(HRESULT hrLeft, uint hrRight) => hrLeft._value == unchecked((int)hrRight);
|
||||
public static bool operator ==(HRESULT hrLeft, uint hrRight) => hrLeft.Equals(hrRight);
|
||||
|
||||
/// <summary>
|
||||
/// If the supplied raw HRESULT value represents a failure, throw the associated <see cref="Exception"/> with the optionally
|
||||
|
@ -407,10 +412,22 @@ namespace Vanara.PInvoke
|
|||
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
|
||||
public bool Equals(int other) => other == _value;
|
||||
|
||||
/// <summary>Indicates whether the current object is equal to an <see cref="uint"/>.</summary>
|
||||
/// <param name="other">An object to compare with this object.</param>
|
||||
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
|
||||
public bool Equals(uint other) => unchecked((int)other) == _value;
|
||||
|
||||
/// <summary>Determines whether the specified <see cref="object"/>, is equal to this instance.</summary>
|
||||
/// <param name="obj">The <see cref="object"/> to compare with this instance.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object obj) => Equals(_value, ValueFromObj(obj));
|
||||
public override bool Equals(object obj) => obj switch
|
||||
{
|
||||
null => false,
|
||||
HRESULT h => Equals(h),
|
||||
int i => Equals(i),
|
||||
uint u => Equals(u),
|
||||
_ => Equals(_value, ValueFromObj(obj)),
|
||||
};
|
||||
|
||||
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
|
||||
/// <param name="other">An object to compare with this object.</param>
|
||||
|
@ -503,7 +520,7 @@ namespace Vanara.PInvoke
|
|||
|
||||
short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)_value).ToInt16(provider);
|
||||
|
||||
int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)_value).ToInt32(provider);
|
||||
int IConvertible.ToInt32(IFormatProvider provider) => _value;
|
||||
|
||||
long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)_value).ToInt64(provider);
|
||||
|
||||
|
@ -516,11 +533,11 @@ namespace Vanara.PInvoke
|
|||
object IConvertible.ToType(Type conversionType, IFormatProvider provider) =>
|
||||
((IConvertible)_value).ToType(conversionType, provider);
|
||||
|
||||
ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)_value).ToUInt16(provider);
|
||||
ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)unchecked((uint)_value)).ToUInt16(provider);
|
||||
|
||||
uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)_value).ToUInt32(provider);
|
||||
uint IConvertible.ToUInt32(IFormatProvider provider) => unchecked((uint)_value);
|
||||
|
||||
ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)_value).ToUInt64(provider);
|
||||
ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)unchecked((uint)_value)).ToUInt64(provider);
|
||||
|
||||
/// <summary>Formats the message.</summary>
|
||||
/// <param name="id">The error.</param>
|
||||
|
@ -528,17 +545,19 @@ namespace Vanara.PInvoke
|
|||
internal static string FormatMessage(uint id)
|
||||
{
|
||||
var flags = 0x1200U; // FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM
|
||||
Win32Error lastError;
|
||||
var buf = new System.Text.StringBuilder(1024);
|
||||
do
|
||||
{
|
||||
if (0 != FormatMessage(flags, default, id, 0, buf, (uint)buf.Capacity, default))
|
||||
return buf.ToString();
|
||||
else if (Win32Error.ERROR_INSUFFICIENT_BUFFER != (lastError = Win32Error.GetLastError()))
|
||||
var lastError = Win32Error.GetLastError();
|
||||
if (lastError == Win32Error.ERROR_MR_MID_NOT_FOUND)
|
||||
break;
|
||||
if (lastError != Win32Error.ERROR_INSUFFICIENT_BUFFER)
|
||||
lastError.ThrowIfFailed();
|
||||
buf.Capacity = buf.Capacity * 2;
|
||||
} while (true && buf.Capacity < 1024 * 16); // Don't go crazy
|
||||
throw lastError.GetException();
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
|
||||
|
@ -546,11 +565,20 @@ namespace Vanara.PInvoke
|
|||
|
||||
private static int? ValueFromObj(object obj)
|
||||
{
|
||||
if (obj == null) return null;
|
||||
switch (obj)
|
||||
{
|
||||
case null:
|
||||
return null;
|
||||
case int i:
|
||||
return i;
|
||||
case uint u:
|
||||
return unchecked((int)u);
|
||||
default:
|
||||
var c = TypeDescriptor.GetConverter(obj);
|
||||
return c.CanConvertTo(typeof(int)) ? (int?)c.ConvertTo(obj, typeof(int)) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class HRESULTTypeConverter : TypeConverter
|
||||
{
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace Vanara.PInvoke
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
[TypeConverter(typeof(NTStatusTypeConverter))]
|
||||
[PInvokeData("winerr.h")]
|
||||
public partial struct NTStatus : IComparable, IComparable<NTStatus>, IEquatable<NTStatus>, IEquatable<int>, IConvertible, IErrorProvider
|
||||
public partial struct NTStatus : IComparable, IComparable<NTStatus>, IEquatable<NTStatus>, IEquatable<int>, IEquatable<uint>, IConvertible, IErrorProvider
|
||||
{
|
||||
internal readonly int _value;
|
||||
|
||||
|
@ -52,6 +52,10 @@ namespace Vanara.PInvoke
|
|||
/// <param name="rawValue">The raw NTStatus value.</param>
|
||||
public NTStatus(int rawValue) => _value = rawValue;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="NTStatus"/> structure.</summary>
|
||||
/// <param name="rawValue">The raw NTStatus value.</param>
|
||||
public NTStatus(uint rawValue) => _value = unchecked((int)rawValue);
|
||||
|
||||
/// <summary>Enumeration of facility codes</summary>
|
||||
[PInvokeData("winerr.h")]
|
||||
public enum FacilityCode : ushort
|
||||
|
@ -272,6 +276,11 @@ namespace Vanara.PInvoke
|
|||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator int(NTStatus value) => value._value;
|
||||
|
||||
/// <summary>Performs an explicit conversion from <see cref="NTStatus"/> to <see cref="System.UInt32"/>.</summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator uint(NTStatus value) => unchecked((uint)value._value);
|
||||
|
||||
/// <summary>Gets the code value from a 32-bit value.</summary>
|
||||
/// <param name="ntstatus">The 32-bit raw NTStatus value.</param>
|
||||
/// <returns>The code value (bits 0-15).</returns>
|
||||
|
@ -292,6 +301,11 @@ namespace Vanara.PInvoke
|
|||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator NTStatus(int value) => new NTStatus(value);
|
||||
|
||||
/// <summary>Performs an implicit conversion from <see cref="System.UInt32"/> to <see cref="NTStatus"/>.</summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator NTStatus(uint value) => new NTStatus(value);
|
||||
|
||||
/// <summary>Performs an implicit conversion from <see cref="Win32Error"/> to <see cref="NTStatus"/>.</summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The resulting <see cref="NTStatus"/> instance from the conversion.</returns>
|
||||
|
@ -336,17 +350,29 @@ namespace Vanara.PInvoke
|
|||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator !=(NTStatus hrLeft, int hrRight) => !(hrLeft == hrRight);
|
||||
|
||||
/// <summary>Implements the operator !=.</summary>
|
||||
/// <param name="hrLeft">The first <see cref="NTStatus"/>.</param>
|
||||
/// <param name="hrRight">The second <see cref="uint"/>.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator !=(NTStatus hrLeft, uint hrRight) => !(hrLeft == hrRight);
|
||||
|
||||
/// <summary>Implements the operator ==.</summary>
|
||||
/// <param name="hrLeft">The first <see cref="NTStatus"/>.</param>
|
||||
/// <param name="hrRight">The second <see cref="NTStatus"/>.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator ==(NTStatus hrLeft, NTStatus hrRight) => hrLeft._value == hrRight._value;
|
||||
public static bool operator ==(NTStatus hrLeft, NTStatus hrRight) => hrLeft.Equals(hrRight);
|
||||
|
||||
/// <summary>Implements the operator ==.</summary>
|
||||
/// <param name="hrLeft">The first <see cref="NTStatus"/>.</param>
|
||||
/// <param name="hrRight">The second <see cref="int"/>.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator ==(NTStatus hrLeft, int hrRight) => hrLeft._value == hrRight;
|
||||
public static bool operator ==(NTStatus hrLeft, int hrRight) => hrLeft.Equals(hrRight);
|
||||
|
||||
/// <summary>Implements the operator ==.</summary>
|
||||
/// <param name="hrLeft">The first <see cref="NTStatus"/>.</param>
|
||||
/// <param name="hrRight">The second <see cref="uint"/>.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator ==(NTStatus hrLeft, uint hrRight) => hrLeft.Equals(hrRight);
|
||||
|
||||
/// <summary>Converts the specified NTSTATUS code to its equivalent system error code.</summary>
|
||||
/// <param name="status">The NTSTATUS code to be converted.</param>
|
||||
|
@ -398,10 +424,22 @@ namespace Vanara.PInvoke
|
|||
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
|
||||
public bool Equals(int other) => other == _value;
|
||||
|
||||
/// <summary>Indicates whether the current object is equal to an <see cref="uint"/>.</summary>
|
||||
/// <param name="other">An object to compare with this object.</param>
|
||||
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
|
||||
public bool Equals(uint other) => unchecked((int)other) == _value;
|
||||
|
||||
/// <summary>Determines whether the specified <see cref="object"/>, is equal to this instance.</summary>
|
||||
/// <param name="obj">The <see cref="object"/> to compare with this instance.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object obj) => Equals(_value, ValueFromObj(obj));
|
||||
public override bool Equals(object obj) => obj switch
|
||||
{
|
||||
null => false,
|
||||
NTStatus n => Equals(n),
|
||||
int i => Equals(i),
|
||||
uint u => Equals(u),
|
||||
_ => Equals(_value, ValueFromObj(obj)),
|
||||
};
|
||||
|
||||
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
|
||||
/// <param name="other">An object to compare with this object.</param>
|
||||
|
@ -413,7 +451,7 @@ namespace Vanara.PInvoke
|
|||
/// <returns>The associated <see cref="Exception"/> or <c>null</c> if this NTStatus is not a failure.</returns>
|
||||
[SecurityCritical]
|
||||
[SecuritySafeCritical]
|
||||
public Exception GetException(string message = null) => !Failed ? null : ToHRESULT().GetException();
|
||||
public Exception GetException(string message = null) => !Failed ? null : ToHRESULT().GetException(message);
|
||||
|
||||
/// <summary>Returns a hash code for this instance.</summary>
|
||||
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
|
||||
|
@ -466,7 +504,7 @@ namespace Vanara.PInvoke
|
|||
|
||||
short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)_value).ToInt16(provider);
|
||||
|
||||
int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)_value).ToInt32(provider);
|
||||
int IConvertible.ToInt32(IFormatProvider provider) => _value;
|
||||
|
||||
long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)_value).ToInt64(provider);
|
||||
|
||||
|
@ -476,24 +514,34 @@ namespace Vanara.PInvoke
|
|||
|
||||
string IConvertible.ToString(IFormatProvider provider) => ToString();
|
||||
|
||||
object IConvertible.ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)_value).ToType(conversionType, provider);
|
||||
object IConvertible.ToType(Type conversionType, IFormatProvider provider) =>
|
||||
((IConvertible)_value).ToType(conversionType, provider);
|
||||
|
||||
ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)_value).ToUInt16(provider);
|
||||
ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)unchecked((uint)_value)).ToUInt16(provider);
|
||||
|
||||
uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)_value).ToUInt32(provider);
|
||||
uint IConvertible.ToUInt32(IFormatProvider provider) => unchecked((uint)_value);
|
||||
|
||||
ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)_value).ToUInt64(provider);
|
||||
ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)unchecked((uint)_value)).ToUInt64(provider);
|
||||
|
||||
[ExcludeFromCodeCoverage]
|
||||
private static HRESULT HRESULT_FROM_NT(int ntStatus) => ntStatus | FACILITY_NT_BIT;
|
||||
|
||||
private static int? ValueFromObj(object obj)
|
||||
{
|
||||
if (obj == null) return null;
|
||||
switch (obj)
|
||||
{
|
||||
case null:
|
||||
return null;
|
||||
case int i:
|
||||
return i;
|
||||
case uint u:
|
||||
return unchecked((int)u);
|
||||
default:
|
||||
var c = TypeDescriptor.GetConverter(obj);
|
||||
return c.CanConvertTo(typeof(int)) ? (int?)c.ConvertTo(obj, typeof(int)) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class NTStatusTypeConverter : TypeConverter
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue