/Microsoft.Windows.Shell/Standard/ErrorCodes.cs
C# | 508 lines | 313 code | 41 blank | 154 comment | 28 complexity | 71e4db4d1dc63046cf15294da5fc9852 MD5 | raw file
- /**************************************************************************\
- Copyright Microsoft Corporation. All Rights Reserved.
- \**************************************************************************/
- namespace Standard
- {
- using System;
- using System.ComponentModel;
- using System.Diagnostics.CodeAnalysis;
- using System.Globalization;
- using System.Reflection;
- using System.Runtime.InteropServices;
- /// <summary>
- /// Wrapper for common Win32 status codes.
- /// </summary>
- [StructLayout(LayoutKind.Explicit)]
- internal struct Win32Error
- {
- [FieldOffset(0)]
- private readonly int _value;
- // NOTE: These public static field declarations are automatically
- // picked up by (HRESULT's) ToString through reflection.
- /// <summary>The operation completed successfully.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_SUCCESS = new Win32Error(0);
- /// <summary>Incorrect function.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_INVALID_FUNCTION = new Win32Error(1);
- /// <summary>The system cannot find the file specified.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_FILE_NOT_FOUND = new Win32Error(2);
- /// <summary>The system cannot find the path specified.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_PATH_NOT_FOUND = new Win32Error(3);
- /// <summary>The system cannot open the file.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_TOO_MANY_OPEN_FILES = new Win32Error(4);
- /// <summary>Access is denied.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_ACCESS_DENIED = new Win32Error(5);
- /// <summary>The handle is invalid.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_INVALID_HANDLE = new Win32Error(6);
- /// <summary>Not enough storage is available to complete this operation.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_OUTOFMEMORY = new Win32Error(14);
- /// <summary>There are no more files.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_NO_MORE_FILES = new Win32Error(18);
- /// <summary>The process cannot access the file because it is being used by another process.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_SHARING_VIOLATION = new Win32Error(32);
- /// <summary>The parameter is incorrect.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_INVALID_PARAMETER = new Win32Error(87);
- /// <summary>The data area passed to a system call is too small.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_INSUFFICIENT_BUFFER = new Win32Error(122);
- /// <summary>Cannot nest calls to LoadModule.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_NESTING_NOT_ALLOWED = new Win32Error(215);
- /// <summary>Illegal operation attempted on a registry key that has been marked for deletion.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_KEY_DELETED = new Win32Error(1018);
- /// <summary>Element not found.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_NOT_FOUND = new Win32Error(1168);
- /// <summary>There was no match for the specified key in the index.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_NO_MATCH = new Win32Error(1169);
- /// <summary>An invalid device was specified.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_BAD_DEVICE = new Win32Error(1200);
- /// <summary>The operation was canceled by the user.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_CANCELLED = new Win32Error(1223);
- /// <summary>The window class was already registered.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_CLASS_ALREADY_EXISTS = new Win32Error(1410);
- /// <summary>The specified datatype is invalid.</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly Win32Error ERROR_INVALID_DATATYPE = new Win32Error(1804);
- /// <summary>
- /// Create a new Win32 error.
- /// </summary>
- /// <param name="i">The integer value of the error.</param>
- public Win32Error(int i)
- {
- _value = i;
- }
- /// <summary>Performs HRESULT_FROM_WIN32 conversion.</summary>
- /// <param name="error">The Win32 error being converted to an HRESULT.</param>
- /// <returns>The equivilent HRESULT value.</returns>
- public static explicit operator HRESULT(Win32Error error)
- {
- // #define __HRESULT_FROM_WIN32(x)
- // ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)))
- if (error._value <= 0)
- {
- return new HRESULT((uint)error._value);
- }
- return HRESULT.Make(true, Facility.Win32, error._value & 0x0000FFFF);
- }
- // Method version of the cast operation
- /// <summary>Performs HRESULT_FROM_WIN32 conversion.</summary>
- /// <param name="error">The Win32 error being converted to an HRESULT.</param>
- /// <returns>The equivilent HRESULT value.</returns>
- public HRESULT ToHRESULT()
- {
- return (HRESULT)this;
- }
- /// <summary>Performs the equivalent of Win32's GetLastError()</summary>
- /// <returns>A Win32Error instance with the result of the native GetLastError</returns>
- [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
- public static Win32Error GetLastError()
- {
- return new Win32Error(Marshal.GetLastWin32Error());
- }
- public override bool Equals(object obj)
- {
- try
- {
- return ((Win32Error)obj)._value == _value;
- }
- catch (InvalidCastException)
- {
- return false;
- }
- }
- public override int GetHashCode()
- {
- return _value.GetHashCode();
- }
- /// <summary>
- /// Compare two Win32 error codes for equality.
- /// </summary>
- /// <param name="errLeft">The first error code to compare.</param>
- /// <param name="errRight">The second error code to compare.</param>
- /// <returns>Whether the two error codes are the same.</returns>
- public static bool operator ==(Win32Error errLeft, Win32Error errRight)
- {
- return errLeft._value == errRight._value;
- }
- /// <summary>
- /// Compare two Win32 error codes for inequality.
- /// </summary>
- /// <param name="errLeft">The first error code to compare.</param>
- /// <param name="errRight">The second error code to compare.</param>
- /// <returns>Whether the two error codes are not the same.</returns>
- public static bool operator !=(Win32Error errLeft, Win32Error errRight)
- {
- return !(errLeft == errRight);
- }
- }
- internal enum Facility
- {
- /// <summary>FACILITY_NULL</summary>
- Null = 0,
- /// <summary>FACILITY_RPC</summary>
- Rpc = 1,
- /// <summary>FACILITY_DISPATCH</summary>
- Dispatch = 2,
- /// <summary>FACILITY_STORAGE</summary>
- Storage = 3,
- /// <summary>FACILITY_ITF</summary>
- Itf = 4,
- /// <summary>FACILITY_WIN32</summary>
- Win32 = 7,
- /// <summary>FACILITY_WINDOWS</summary>
- Windows = 8,
- /// <summary>FACILITY_CONTROL</summary>
- Control = 10,
- /// <summary>MSDN doced facility code for ESE errors.</summary>
- Ese = 0xE5E,
- /// <summary>FACILITY_WINCODEC (WIC)</summary>
- WinCodec = 0x898,
- }
- /// <summary>Wrapper for HRESULT status codes.</summary>
- [StructLayout(LayoutKind.Explicit)]
- internal struct HRESULT
- {
- [FieldOffset(0)]
- private readonly uint _value;
- // NOTE: These public static field declarations are automatically
- // picked up by ToString through reflection.
- /// <summary>S_OK</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT S_OK = new HRESULT(0x00000000);
- /// <summary>S_FALSE</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT S_FALSE = new HRESULT(0x00000001);
- /// <summary>E_PENDING</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT E_PENDING = new HRESULT(0x8000000A);
- /// <summary>E_NOTIMPL</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT E_NOTIMPL = new HRESULT(0x80004001);
- /// <summary>E_NOINTERFACE</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT E_NOINTERFACE = new HRESULT(0x80004002);
- /// <summary>E_POINTER</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT E_POINTER = new HRESULT(0x80004003);
- /// <summary>E_ABORT</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT E_ABORT = new HRESULT(0x80004004);
- /// <summary>E_FAIL</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT E_FAIL = new HRESULT(0x80004005);
- /// <summary>E_UNEXPECTED</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT E_UNEXPECTED = new HRESULT(0x8000FFFF);
- /// <summary>STG_E_INVALIDFUNCTION</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT STG_E_INVALIDFUNCTION = new HRESULT(0x80030001);
- /// <summary>REGDB_E_CLASSNOTREG</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT REGDB_E_CLASSNOTREG = new HRESULT(0x80040154);
- /// <summary>DESTS_E_NO_MATCHING_ASSOC_HANDLER. Win7 internal error code for Jump Lists.</summary>
- /// <remarks>There is no Assoc Handler for the given item registered by the specified application.</remarks>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT DESTS_E_NO_MATCHING_ASSOC_HANDLER = new HRESULT(0x80040F03);
- /// <summary>DESTS_E_NORECDOCS. Win7 internal error code for Jump Lists.</summary>
- /// <remarks>The given item is excluded from the recent docs folder by the NoRecDocs bit on its registration.</remarks>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT DESTS_E_NORECDOCS = new HRESULT(0x80040F04);
- /// <summary>DESTS_E_NOTALLCLEARED. Win7 internal error code for Jump Lists.</summary>
- /// <remarks>Not all of the items were successfully cleared</remarks>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT DESTS_E_NOTALLCLEARED = new HRESULT(0x80040F05);
- /// <summary>E_ACCESSDENIED</summary>
- /// <remarks>Win32Error ERROR_ACCESS_DENIED.</remarks>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT E_ACCESSDENIED = new HRESULT(0x80070005);
- /// <summary>E_OUTOFMEMORY</summary>
- /// <remarks>Win32Error ERROR_OUTOFMEMORY.</remarks>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT E_OUTOFMEMORY = new HRESULT(0x8007000E);
- /// <summary>E_INVALIDARG</summary>
- /// <remarks>Win32Error ERROR_INVALID_PARAMETER.</remarks>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT E_INVALIDARG = new HRESULT(0x80070057);
- /// <summary>INTSAFE_E_ARITHMETIC_OVERFLOW</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT INTSAFE_E_ARITHMETIC_OVERFLOW = new HRESULT(0x80070216);
- /// <summary>COR_E_OBJECTDISPOSED</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT COR_E_OBJECTDISPOSED = new HRESULT(0x80131622);
- /// <summary>WC_E_GREATERTHAN</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT WC_E_GREATERTHAN = new HRESULT(0xC00CEE23);
- /// <summary>WC_E_SYNTAX</summary>
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public static readonly HRESULT WC_E_SYNTAX = new HRESULT(0xC00CEE2D);
- /// <summary>
- /// Create an HRESULT from an integer value.
- /// </summary>
- /// <param name="i"></param>
- public HRESULT(uint i)
- {
- _value = i;
- }
- public static HRESULT Make(bool severe, Facility facility, int code)
- {
- //#define MAKE_HRESULT(sev,fac,code) \
- // ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) )
- // Severity has 1 bit reserved.
- // bitness is enforced by the boolean parameter.
- // Facility has 11 bits reserved (different than SCODES, which have 4 bits reserved)
- // MSDN documentation incorrectly uses 12 bits for the ESE facility (e5e), so go ahead and let that one slide.
- // And WIC also ignores it the documented size...
- Assert.Implies((int)facility != (int)((int)facility & 0x1FF), facility == Facility.Ese || facility == Facility.WinCodec);
- // Code has 4 bits reserved.
- Assert.AreEqual(code, code & 0xFFFF);
- return new HRESULT((uint)((severe ? (1 << 31) : 0) | ((int)facility << 16) | code));
- }
- /// <summary>
- /// retrieve HRESULT_FACILITY
- /// </summary>
- public Facility Facility
- {
- get
- {
- return GetFacility((int)_value);
- }
- }
- public static Facility GetFacility(int errorCode)
- {
- // #define HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1fff)
- return (Facility)((errorCode >> 16) & 0x1fff);
- }
- /// <summary>
- /// retrieve HRESULT_CODE
- /// </summary>
- public int Code
- {
- get
- {
- return GetCode((int)_value);
- }
- }
- public static int GetCode(int error)
- {
- // #define HRESULT_CODE(hr) ((hr) & 0xFFFF)
- return (int)(error & 0xFFFF);
- }
- #region Object class override members
- /// <summary>
- /// Get a string representation of this HRESULT.
- /// </summary>
- /// <returns></returns>
- public override string ToString()
- {
- // Use reflection to try to name this HRESULT.
- // This is expensive, but if someone's ever printing HRESULT strings then
- // I think it's a fair guess that they're not in a performance critical area
- // (e.g. printing exception strings).
- // This is less error prone than trying to keep the list in the function.
- // To properly add an HRESULT's name to the ToString table, just add the HRESULT
- // like all the others above.
- //
- // CONSIDER: This data is static. It could be cached
- // after first usage for fast lookup since the keys are unique.
- //
- foreach (FieldInfo publicStaticField in typeof(HRESULT).GetFields(BindingFlags.Static | BindingFlags.Public))
- {
- if (publicStaticField.FieldType == typeof(HRESULT))
- {
- var hr = (HRESULT)publicStaticField.GetValue(null);
- if (hr == this)
- {
- return publicStaticField.Name;
- }
- }
- }
- // Try Win32 error codes also
- if (Facility == Facility.Win32)
- {
- foreach (FieldInfo publicStaticField in typeof(Win32Error).GetFields(BindingFlags.Static | BindingFlags.Public))
- {
- if (publicStaticField.FieldType == typeof(Win32Error))
- {
- var error = (Win32Error)publicStaticField.GetValue(null);
- if ((HRESULT)error == this)
- {
- return "HRESULT_FROM_WIN32(" + publicStaticField.Name + ")";
- }
- }
- }
- }
- // If there's no good name for this HRESULT,
- // return the string as readable hex (0x########) format.
- return string.Format(CultureInfo.InvariantCulture, "0x{0:X8}", _value);
- }
- public override bool Equals(object obj)
- {
- try
- {
- return ((HRESULT)obj)._value == _value;
- }
- catch (InvalidCastException)
- {
- return false;
- }
- }
- public override int GetHashCode()
- {
- return _value.GetHashCode();
- }
- #endregion
- public static bool operator ==(HRESULT hrLeft, HRESULT hrRight)
- {
- return hrLeft._value == hrRight._value;
- }
- public static bool operator !=(HRESULT hrLeft, HRESULT hrRight)
- {
- return !(hrLeft == hrRight);
- }
- public bool Succeeded
- {
- get { return (int)_value >= 0; }
- }
- public bool Failed
- {
- get { return (int)_value < 0; }
- }
- public void ThrowIfFailed()
- {
- ThrowIfFailed(null);
- }
- [
- SuppressMessage(
- "Microsoft.Usage",
- "CA2201:DoNotRaiseReservedExceptionTypes",
- Justification="Only recreating Exceptions that were already raised."),
- SuppressMessage(
- "Microsoft.Security",
- "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")
- ]
- public void ThrowIfFailed(string message)
- {
- if (Failed)
- {
- if (string.IsNullOrEmpty(message))
- {
- message = ToString();
- }
- #if DEBUG
- else
- {
- message += " (" + ToString() + ")";
- }
- #endif
- // Wow. Reflection in a throw call. Later on this may turn out to have been a bad idea.
- // If you're throwing an exception I assume it's OK for me to take some time to give it back.
- // I want to convert the HRESULT to a more appropriate exception type than COMException.
- // Marshal.ThrowExceptionForHR does this for me, but the general call uses GetErrorInfo
- // if it's set, and then ignores the HRESULT that I've provided. This makes it so this
- // call works the first time but you get burned on the second. To avoid this, I use
- // the overload that explicitly ignores the IErrorInfo.
- // In addition, the function doesn't allow me to set the Message unless I go through
- // the process of implementing an IErrorInfo and then use that. There's no stock
- // implementations of IErrorInfo available and I don't think it's worth the maintenance
- // overhead of doing it, nor would it have significant value over this approach.
- Exception e = Marshal.GetExceptionForHR((int)_value, new IntPtr(-1));
- Assert.IsNotNull(e);
- // ArgumentNullException doesn't have the right constructor parameters,
- // (nor does Win32Exception...)
- // but E_POINTER gets mapped to NullReferenceException,
- // so I don't think it will ever matter.
- Assert.IsFalse(e is ArgumentNullException);
- // If we're not getting anything better than a COMException from Marshal,
- // then at least check the facility and attempt to do better ourselves.
- if (e.GetType() == typeof(COMException))
- {
- switch (Facility)
- {
- case Facility.Win32:
- e = new Win32Exception(Code, message);
- break;
- default:
- e = new COMException(message, (int)_value);
- break;
- }
- }
- else
- {
- ConstructorInfo cons = e.GetType().GetConstructor(new[] { typeof(string) });
- if (null != cons)
- {
- e = cons.Invoke(new object[] { message }) as Exception;
- Assert.IsNotNull(e);
- }
- }
- throw e;
- }
- }
- /// <summary>
- /// Convert the result of Win32 GetLastError() into a raised exception.
- /// </summary>
- public static void ThrowLastError()
- {
- ((HRESULT)Win32Error.GetLastError()).ThrowIfFailed();
- // Only expecting to call this when we're expecting a failed GetLastError()
- Assert.Fail();
- }
- }
- }