Merge pull request #944 from ermshiperete/bug-novell-496138
authorZoltan Varga <vargaz@gmail.com>
Wed, 29 Oct 2014 23:06:05 +0000 (19:06 -0400)
committerZoltan Varga <vargaz@gmail.com>
Wed, 29 Oct 2014 23:06:05 +0000 (19:06 -0400)
Improve COM error handling

1  2 
mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs
mcs/class/corlib/corlib.dll.sources

index e339f94955ad4463ee6de55a20d018c6b0157cd2,95df86a7c8f0bf6a13854cc50d73a28be57654b9..243984706ceaaf1c27f77ccacd711eaf450bcce6
@@@ -414,9 -414,11 +414,11 @@@ namespace System.Runtime.InteropService
  #endif // !FULL_AOT_RUNTIME
  
  #if !FULL_AOT_RUNTIME
-               [MonoTODO ("SetErrorInfo")]
                public static int GetHRForException (Exception e)
                {
+                       var errorInfo = new ManagedErrorInfo(e);
+                       SetErrorInfo (0, errorInfo);
                        return e.hresult;
                }
  
                        throw new NotImplementedException ();
                }
  
 +#if NET_4_5
 +              public static Type GetTypeFromCLSID (Guid clsid)
 +              {
 +                      throw new NotImplementedException ();                   
 +              }
 +#endif
 +
  #if !FULL_AOT_RUNTIME
                [Obsolete]
                [MonoTODO]
                        throw new NotImplementedException ();
                }
  
-               public static Exception GetExceptionForHR (int errorCode) {
-                       return GetExceptionForHR (errorCode, IntPtr.Zero);
-               }
-               public static Exception GetExceptionForHR (int errorCode, IntPtr errorInfo) {
+               private static Exception ConvertHrToException (int errorCode)
+               {
+                       const int MSEE_E_APPDOMAINUNLOADED = unchecked ((int)0x80131014L);
+                       const int COR_E_APPLICATION = unchecked ((int)0x80131600L);
+                       const int E_INVALIDARG = unchecked ((int)0x80070057);
+                       const int COR_E_ARGUMENTOUTOFRANGE = unchecked ((int)0x80131502L);
+                       const int COR_E_ARITHMETIC = unchecked ((int)0x80070216);
+                       const int COR_E_ARRAYTYPEMISMATCH = unchecked ((int)0x80131503L);
+                       const int COR_E_BADIMAGEFORMAT = unchecked ((int)0x8007000BL);
+                       const int ERROR_BAD_FORMAT = unchecked ((int)0x0B);
+                       //const int COR_E_COMEMULATE_ERROR = unchecked ((int)?);
+                       const int COR_E_CONTEXTMARSHAL = unchecked ((int)0x80131504L);
+                       //const int COR_E_CORE = unchecked ((int)?);
+                       const int NTE_FAIL = unchecked ((int)0x80090020L);
+                       const int COR_E_DIRECTORYNOTFOUND = unchecked ((int)0x80070003L);
+                       const int ERROR_PATH_NOT_FOUND = unchecked ((int)0x03);
+                       const int COR_E_DIVIDEBYZERO = unchecked ((int)0x80020012L);
+                       const int COR_E_DUPLICATEWAITOBJECT = unchecked ((int)0x80131529L);
+                       const int COR_E_ENDOFSTREAM = unchecked ((int)0x80070026L);
+                       const int COR_E_TYPELOAD = unchecked ((int)0x80131522L);
+                       const int COR_E_EXCEPTION = unchecked ((int)0x80131500L);
+                       const int COR_E_EXECUTIONENGINE = unchecked ((int)0x80131506L);
+                       const int COR_E_FIELDACCESS = unchecked ((int)0x80131507L);
+                       const int COR_E_FILENOTFOUND = unchecked ((int)0x80070002L);
+                       const int ERROR_FILE_NOT_FOUND = unchecked ((int)0x02);
+                       const int COR_E_FORMAT = unchecked ((int)0x80131537L);
+                       const int COR_E_INDEXOUTOFRANGE = unchecked ((int)0x80131508L);
+                       const int COR_E_INVALIDCAST = unchecked ((int)0x80004002L);
+                       const int COR_E_INVALIDCOMOBJECT = unchecked ((int)0x80131527L);
+                       const int COR_E_INVALIDFILTERCRITERIA = unchecked ((int)0x80131601L);
+                       const int COR_E_INVALIDOLEVARIANTTYPE = unchecked ((int)0x80131531L);
+                       const int COR_E_INVALIDOPERATION = unchecked ((int)0x80131509L);
+                       const int COR_E_IO = unchecked ((int)0x80131620L);
+                       const int COR_E_MEMBERACCESS = unchecked ((int)0x8013151AL);
+                       const int COR_E_METHODACCESS = unchecked ((int)0x80131510L);
+                       const int COR_E_MISSINGFIELD = unchecked ((int)0x80131511L);
+                       const int COR_E_MISSINGMANIFESTRESOURCE = unchecked ((int)0x80131532L);
+                       const int COR_E_MISSINGMEMBER = unchecked ((int)0x80131512L);
+                       const int COR_E_MISSINGMETHOD = unchecked ((int)0x80131513L);
+                       const int COR_E_MULTICASTNOTSUPPORTED = unchecked ((int)0x80131514L);
+                       const int COR_E_NOTFINITENUMBER = unchecked ((int)0x80131528L);
+                       const int E_NOTIMPL = unchecked ((int)0x80004001L);
+                       const int COR_E_NOTSUPPORTED = unchecked ((int)0x80131515L);
+                       const int COR_E_NULLREFERENCE = unchecked ((int)0x80004003L);
                        const int E_OUTOFMEMORY = unchecked ((int)0x8007000EL);
-                       const int E_INVALIDARG = unchecked ((int)0X80070057);
-                       
-                       switch (errorCode)
-                       {
-                       case E_OUTOFMEMORY:
-                               return new OutOfMemoryException ();
-                       case E_INVALIDARG:
-                               return new ArgumentException ();
+                       const int COR_E_OVERFLOW = unchecked ((int)0x80131516L);
+                       const int COR_E_PATHTOOLONG = unchecked ((int)0x800700CEL);
+                       const int ERROR_FILENAME_EXCED_RANGE = unchecked ((int)0xCE);
+                       const int COR_E_RANK = unchecked ((int)0x80131517L);
+                       const int COR_E_REFLECTIONTYPELOAD = unchecked ((int)0x80131602L);
+                       const int COR_E_REMOTING = unchecked ((int)0x8013150BL);
+                       const int COR_E_SAFEARRAYTYPEMISMATCH = unchecked ((int)0x80131533L);
+                       const int COR_E_SECURITY = unchecked ((int)0x8013150AL);
+                       const int COR_E_SERIALIZATION = unchecked ((int)0x8013150CL);
+                       const int COR_E_STACKOVERFLOW = unchecked ((int)0x800703E9L);
+                       const int ERROR_STACK_OVERFLOW = unchecked ((int)0x03E9);
+                       const int COR_E_SYNCHRONIZATIONLOCK = unchecked ((int)0x80131518L);
+                       const int COR_E_SYSTEM = unchecked ((int)0x80131501L);
+                       const int COR_E_TARGET = unchecked ((int)0x80131603L);
+                       const int COR_E_TARGETINVOCATION = unchecked ((int)0x80131604L);
+                       const int COR_E_TARGETPARAMCOUNT = unchecked ((int)0x8002000EL);
+                       const int COR_E_THREADABORTED = unchecked ((int)0x80131530L);
+                       const int COR_E_THREADINTERRUPTED = unchecked ((int)0x80131519L);
+                       const int COR_E_THREADSTATE = unchecked ((int)0x80131520L);
+                       const int COR_E_THREADSTOP = unchecked ((int)0x80131521L);
+                       const int COR_E_TYPEINITIALIZATION = unchecked ((int)0x80131534L);
+                       const int COR_E_VERIFICATION = unchecked ((int)0x8013150DL);
+                       //const int COR_E_WEAKREFERENCE = unchecked ((int)?);
+                       //const int COR_E_VTABLECALLSNOTSUPPORTED = unchecked ((int));
+                       switch (errorCode) {
+                               case MSEE_E_APPDOMAINUNLOADED:
+                                       return new AppDomainUnloadedException ();
+                               case COR_E_APPLICATION:
+                                       return new ApplicationException ();
+                               case E_INVALIDARG:
+                                       return new ArgumentException ();
+                               case COR_E_ARGUMENTOUTOFRANGE:
+                                       return new ArgumentOutOfRangeException ();
+                               case COR_E_ARITHMETIC:
+                                       return new ArithmeticException ();
+                               case COR_E_ARRAYTYPEMISMATCH:
+                                       return new ArrayTypeMismatchException ();
+                               case COR_E_BADIMAGEFORMAT:
+                               case ERROR_BAD_FORMAT:
+                                       return new BadImageFormatException ();
+ //                            case COR_E_COMEMULATE_ERROR:
+ //                                    return new COMEmulateException ();
+                               case COR_E_CONTEXTMARSHAL:
+                                       return new ContextMarshalException ();
+ //                            case COR_E_CORE:
+ //                                    return new CoreException ();
+                               case NTE_FAIL:
+                                       return new System.Security.Cryptography.CryptographicException ();
+                               case COR_E_DIRECTORYNOTFOUND:
+                               case ERROR_PATH_NOT_FOUND:
+                                       return new System.IO.DirectoryNotFoundException ();
+                               case COR_E_DIVIDEBYZERO:
+                                       return new DivideByZeroException ();
+                               case COR_E_DUPLICATEWAITOBJECT:
+                                       return new DuplicateWaitObjectException ();
+                               case COR_E_ENDOFSTREAM:
+                                       return new System.IO.EndOfStreamException ();
+                               case COR_E_EXCEPTION:
+                                       return new Exception ();
+                               case COR_E_EXECUTIONENGINE:
+                                       return new ExecutionEngineException ();
+                               case COR_E_FIELDACCESS:
+                                       return new FieldAccessException ();
+                               case COR_E_FILENOTFOUND:
+                               case ERROR_FILE_NOT_FOUND:
+                                       return new System.IO.FileNotFoundException ();
+                               case COR_E_FORMAT:
+                                       return new FormatException ();
+                               case COR_E_INDEXOUTOFRANGE:
+                                       return new IndexOutOfRangeException ();
+                               case COR_E_INVALIDCAST:
+                               // E_NOINTERFACE has same value as COR_E_INVALIDCAST
+                                       return new InvalidCastException ();
+                               case COR_E_INVALIDCOMOBJECT:
+                                       return new InvalidComObjectException ();
+                               case COR_E_INVALIDFILTERCRITERIA:
+                                       return new InvalidFilterCriteriaException ();
+                               case COR_E_INVALIDOLEVARIANTTYPE:
+                                       return new InvalidOleVariantTypeException ();
+                               case COR_E_INVALIDOPERATION:
+                                       return new InvalidOperationException ();
+                               case COR_E_IO:
+                                       return new System.IO.IOException ();
+                               case COR_E_MEMBERACCESS:
+                                       return new MemberAccessException ();
+                               case COR_E_METHODACCESS:
+                                       return new MethodAccessException ();
+                               case COR_E_MISSINGFIELD:
+                                       return new MissingFieldException ();
+                               case COR_E_MISSINGMANIFESTRESOURCE:
+                                       return new System.Resources.MissingManifestResourceException ();
+                               case COR_E_MISSINGMEMBER:
+                                       return new MissingMemberException ();
+                               case COR_E_MISSINGMETHOD:
+                                       return new MissingMethodException ();
+                               case COR_E_MULTICASTNOTSUPPORTED:
+                                       return new MulticastNotSupportedException ();
+                               case COR_E_NOTFINITENUMBER:
+                                       return new NotFiniteNumberException ();
+                               case E_NOTIMPL:
+                                       return new NotImplementedException ();
+                               case COR_E_NOTSUPPORTED:
+                                       return new NotSupportedException ();
+                               case COR_E_NULLREFERENCE:
+                               // E_POINTER has the same value as COR_E_NULLREFERENCE
+                                       return new NullReferenceException ();
+                               case E_OUTOFMEMORY:
+                               // COR_E_OUTOFMEMORY has the same value as E_OUTOFMEMORY
+                                       return new OutOfMemoryException ();
+                               case COR_E_OVERFLOW:
+                                       return new OverflowException ();
+                               case COR_E_PATHTOOLONG:
+                               case ERROR_FILENAME_EXCED_RANGE:
+                                       return new System.IO.PathTooLongException ();
+                               case COR_E_RANK:
+                                       return new RankException ();
+                               case COR_E_REFLECTIONTYPELOAD:
+                                       return new System.Reflection.ReflectionTypeLoadException (new Type[] { }, new Exception[] { });
+                               case COR_E_REMOTING:
+                                       return new System.Runtime.Remoting.RemotingException ();
+                               case COR_E_SAFEARRAYTYPEMISMATCH:
+                                       return new SafeArrayTypeMismatchException ();
+                               case COR_E_SECURITY:
+                                       return new SecurityException ();
+                               case COR_E_SERIALIZATION:
+                                       return new System.Runtime.Serialization.SerializationException ();
+                               case COR_E_STACKOVERFLOW:
+                               case ERROR_STACK_OVERFLOW:
+                                       return new StackOverflowException ();
+                               case COR_E_SYNCHRONIZATIONLOCK:
+                                       return new SynchronizationLockException ();
+                               case COR_E_SYSTEM:
+                                       return new SystemException ();
+                               case COR_E_TARGET:
+                                       return new TargetException ();
+                               case COR_E_TARGETINVOCATION:
+                                       return new System.Reflection.TargetInvocationException (null);
+                               case COR_E_TARGETPARAMCOUNT:
+                                       return new TargetParameterCountException ();
+ //                            case COR_E_THREADABORTED:
+ //                                    ThreadAbortException c'tor is inaccessible
+ //                                    return new System.Threading.ThreadAbortException ();
+                               case COR_E_THREADINTERRUPTED:
+                                       return new ThreadInterruptedException ();
+                               case COR_E_THREADSTATE:
+                                       return new ThreadStateException ();
+ //                            case COR_E_THREADSTOP:
+ //                                    ThreadStopException does not exist
+ //                                    return new System.Threading.ThreadStopException ();
+                               case COR_E_TYPELOAD:
+                                       return new TypeLoadException ();
+                               // MSDN lists COR_E_TYPELOAD twice with different exceptions.
+                               // return new EntryPointNotFoundException ();
+                               case COR_E_TYPEINITIALIZATION:
+                                       return new TypeInitializationException("", null);
+                               case COR_E_VERIFICATION:
+                                       return new VerificationException ();
+ //                            case COR_E_WEAKREFERENCE:
+ //                                    return new WeakReferenceException ();
+ //                            case COR_E_VTABLECALLSNOTSUPPORTED:
+ //                                    return new VTableCallsNotSupportedException ();
                        }
                        if (errorCode < 0)
                                return new COMException ("", errorCode);
                        return null;
                }
  
+               [DllImport ("oleaut32.dll", CharSet=CharSet.Unicode, EntryPoint = "SetErrorInfo")]
+               static extern int _SetErrorInfo (int dwReserved,
+                       [MarshalAs(UnmanagedType.Interface)] IErrorInfo pIErrorInfo);
+               [DllImport ("oleaut32.dll", CharSet=CharSet.Unicode, EntryPoint = "GetErrorInfo")]
+               static extern int _GetErrorInfo (int dwReserved,
+                       [MarshalAs(UnmanagedType.Interface)] out IErrorInfo ppIErrorInfo);
+               static bool SetErrorInfoNotAvailable;
+               static bool GetErrorInfoNotAvailable;
+               internal static int SetErrorInfo (int dwReserved, IErrorInfo errorInfo)
+               {
+                       int retVal = 0;
+                       errorInfo = null;
+                       if (SetErrorInfoNotAvailable)
+                               return -1;
+                       try {
+                               retVal = _SetErrorInfo (dwReserved, errorInfo);
+                       }
+                       catch (Exception) {
+                               // ignore any exception - probably there's no suitable SetErrorInfo
+                               // method available.
+                               SetErrorInfoNotAvailable = true;
+                       }
+                       return retVal;
+               }
+               internal static int GetErrorInfo (int dwReserved, out IErrorInfo errorInfo)
+               {
+                       int retVal = 0;
+                       errorInfo = null;
+                       if (GetErrorInfoNotAvailable)
+                               return -1;
+                       try {
+                               retVal = _GetErrorInfo (dwReserved, out errorInfo);
+                       }
+                       catch (Exception) {
+                               // ignore any exception - probably there's no suitable GetErrorInfo
+                               // method available.
+                               GetErrorInfoNotAvailable = true;
+                       }
+                       return retVal;
+               }
+               public static Exception GetExceptionForHR (int errorCode)
+               {
+                       return GetExceptionForHR (errorCode, IntPtr.Zero);
+               }
+               public static Exception GetExceptionForHR (int errorCode, IntPtr errorInfoPtr)
+               {
+                       IErrorInfo errorInfo = null;
+                       if (errorInfoPtr != (IntPtr)(-1)) {
+                               if (errorInfoPtr == IntPtr.Zero) {
+                                       if (GetErrorInfo (0, out errorInfo) != 0) {
+                                               errorInfo = null;
+                                       }
+                               } else {
+                                       errorInfo = Marshal.GetObjectForIUnknown (errorInfoPtr) as IErrorInfo;
+                               }
+                       }
+                       if (errorInfo is ManagedErrorInfo && ((ManagedErrorInfo)errorInfo).Exception.hresult == errorCode) {
+                               return ((ManagedErrorInfo)errorInfo).Exception;
+                       }
+                       Exception e = ConvertHrToException (errorCode);
+                       if (errorInfo != null && e != null) {
+                               uint helpContext;
+                               errorInfo.GetHelpContext (out helpContext);
+                               string str;
+                               errorInfo.GetSource (out str);
+                               e.Source = str;
+                               errorInfo.GetDescription (out str);
+                               e.SetMessage (str);
+                               errorInfo.GetHelpFile (out str);
+                               if (helpContext == 0) {
+                                       e.HelpLink = str;
+                               } else {
+                                       e.HelpLink = string.Format ("{0}#{1}", str, helpContext);
+                               }
+                       }
+                       return e;
+               }
  #if !FULL_AOT_RUNTIME
                public static int FinalReleaseComObject (object o)
                {
index b1516b8bb1427aa88926bb4cc09e2924cbf10579,0bf28c2287d5b300f0730d76cb03920086fdf0c1..5268a3a9766a55efbdb9a4bf1ea874691d021764
@@@ -160,7 -160,6 +160,7 @@@ System/EventHandler.c
  System/Exception.cs
  System/ExecutionEngineException.cs
  System/FieldAccessException.cs
 +System/FirstChanceExceptionEventArgs.cs
  System/FlagsAttribute.cs
  System/FormatException.cs
  System/Funcs.cs
@@@ -265,7 -264,6 +265,7 @@@ System/TimeZone.c
  ../System.Core/System/TimeZoneInfo.AdjustmentRule.cs
  ../System.Core/System/TimeZoneInfo.Android.cs
  ../System.Core/System/TimeZoneInfo.MonoTouch.cs
 +../System.Core/System/TimeZoneInfo.Serialization.cs
  ../System.Core/System/TimeZoneInfo.TransitionTime.cs
  System/TimeZoneNotFoundException.cs
  System/TimeoutException.cs
@@@ -362,14 -360,8 +362,14 @@@ System.Diagnostics.Contracts/ContractSh
  System.Diagnostics.Contracts/ContractVerificationAttribute.cs
  System.Diagnostics.Contracts/PureAttribute.cs
  System.Diagnostics.Contracts.Internal/ContractHelper.cs
 +System.Diagnostics.Tracing/EventAttribute.cs
 +System.Diagnostics.Tracing/EventCommand.cs
 +System.Diagnostics.Tracing/EventKeywords.cs
 +System.Diagnostics.Tracing/EventLevel.cs
  System.Diagnostics.Tracing/EventSource.cs
 +System.Diagnostics.Tracing/EventSourceAttribute.cs
  System.Diagnostics.Tracing/EventCommandEventArgs.cs
 +System.Diagnostics.Tracing/NonEventAttribute.cs
  System.Diagnostics.SymbolStore/ISymbolBinder.cs
  System.Diagnostics.SymbolStore/ISymbolBinder1.cs
  System.Diagnostics.SymbolStore/ISymbolDocument.cs
@@@ -417,7 -409,6 +417,7 @@@ System.Globalization/NumberStyles.c
  System.Globalization/PersianCalendar.cs
  System.Globalization/RegionInfo.cs
  System.Globalization/RegionInfo.MonoTouch.cs
 +System.Globalization/SortVersion.cs
  System.Globalization/StringInfo.cs
  System.Globalization/TaiwanCalendar.cs
  System.Globalization/TaiwanLunisolarCalendar.cs
@@@ -635,7 -626,6 +635,7 @@@ System.Resources/SatelliteContractVersi
  System.Resources/UltimateResourceFallbackLocation.cs
  System.Resources/Win32Resources.cs
  System.Runtime/AssemblyTargetedPatchBandAttribute.cs
 +System.Runtime/GCLargeObjectHeapCompactionMode.cs
  System.Runtime/GCLatencyMode.cs
  System.Runtime/GCSettings.cs
  System.Runtime/MemoryFailPoint.cs
@@@ -811,6 -801,7 +811,7 @@@ System.Runtime.InteropServices/IDispatc
  System.Runtime.InteropServices/IDispatchImplType.cs
  System.Runtime.InteropServices/IDLDESC.cs
  System.Runtime.InteropServices/IDLFLAG.cs
+ System.Runtime.InteropServices/IErrorInfo.cs
  System.Runtime.InteropServices/IMPLTYPEFLAGS.cs
  System.Runtime.InteropServices/INVOKEKIND.cs
  System.Runtime.InteropServices/IRegistrationServices.cs
@@@ -827,6 -818,7 +828,7 @@@ System.Runtime.InteropServices/InvalidO
  System.Runtime.InteropServices/LCIDConversionAttribute.cs
  System.Runtime.InteropServices/LIBFLAGS.cs
  System.Runtime.InteropServices/LayoutKind.cs
+ System.Runtime.InteropServices/ManagedErrorInfo.cs
  System.Runtime.InteropServices/Marshal.cs
  System.Runtime.InteropServices/MarshalAsAttribute.cs
  System.Runtime.InteropServices/MarshalDirectiveException.cs
@@@ -1184,7 -1176,6 +1186,7 @@@ System.Runtime.Serialization.Formatters
  System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs
  System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs
  System.Runtime.Serialization.Formatters.Binary/MessageFormatter.cs
 +System.Runtime.Versioning/CompatibilitySwitch.cs
  System.Runtime.Versioning/ComponentGuaranteesAttribute.cs
  System.Runtime.Versioning/ComponentGuaranteesOptions.cs
  System.Runtime.Versioning/ResourceConsumptionAttribute.cs
@@@ -1296,11 -1287,6 +1298,11 @@@ System.Security.AccessControl/SddlAcces
  System.Security.AccessControl/SecurityInfos.cs
  System.Security.AccessControl/SystemAcl.cs
  ../System.Core/System.Security.Cryptography/Aes.cs
 +System.Security.Claims/Claim.cs
 +System.Security.Claims/ClaimsIdentity.cs
 +System.Security.Claims/ClaimsPrincipal.cs
 +System.Security.Claims/ClaimTypes.cs
 +System.Security.Claims/ClaimValueTypes.cs
  System.Security.Cryptography/AsymmetricAlgorithm.cs
  System.Security.Cryptography/AsymmetricKeyExchangeDeformatter.cs
  System.Security.Cryptography/AsymmetricKeyExchangeFormatter.cs
@@@ -1528,8 -1514,6 +1530,8 @@@ System.Text/EncoderFallbackException.c
  System.Text/EncoderReplacementFallback.cs
  System.Text/EncoderReplacementFallbackBuffer.cs
  System.Text/Encoding.cs
 +System.Text/EncodingEncoder.cs
 +System.Text/EncodingDecoder.cs
  System.Text/EncodingInfo.cs
  System.Text/Latin1Encoding.cs
  System.Text/MLangCodePageEncoding.cs