2016-08-03 10:59:49 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								//------------------------------------------------------------------------------  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// <copyright file="Win32Exception.cs" company="Microsoft">  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//     Copyright (c) Microsoft Corporation.  All rights reserved.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// </copyright>                                                                  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//------------------------------------------------------------------------------  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  System.ComponentModel  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    using  Microsoft.Win32 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    using  System ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    using  System.Diagnostics ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    using  System.Runtime.InteropServices ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    using  System.Runtime.Remoting ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    using  System.Runtime.Serialization ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    using  System.Security ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    using  System.Security.Permissions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    using  System.Text ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /// <devdoc> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ///    <para>The exception that is thrown for a Win32 error code.</para> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /// </devdoc> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Code already shipped - safe to place link demand on derived class constructor when base doesn't have it - Suppress message. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [HostProtection(SharedState = true)]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [Serializable]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [SuppressUnmanagedCodeSecurity]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  partial  class  Win32Exception  :  ExternalException ,  ISerializable  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// <devdoc> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ///    <para>Represents the Win32 error code associated with this exception. This  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ///       field is read-only.</para> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// </devdoc> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        private  readonly  int  nativeErrorCode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// <devdoc> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// <para>Initializes a new instance of the <see cref='System.ComponentModel.Win32Exception'/> class with the last Win32 error  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ///    that occured.</para> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// </devdoc> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        public  Win32Exception ( )  :  this ( Marshal . GetLastWin32Error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// <devdoc> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// <para>Initializes a new instance of the <see cref='System.ComponentModel.Win32Exception'/> class with the specified error.</para> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// </devdoc> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        public  Win32Exception ( int  error )  :  this ( error ,  GetErrorMessage ( error ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// <devdoc> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// <para>Initializes a new instance of the <see cref='System.ComponentModel.Win32Exception'/> class with the specified error and the  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ///    specified detailed description.</para> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// </devdoc> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        public  Win32Exception ( int  error ,  string  message ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        :  base ( message )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            nativeErrorCode  =  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// <devdoc> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ///     Initializes a new instance of the Exception class with a specified error message. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ///     FxCop CA1032: Multiple constructors are required to correctly implement a custom exception. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// </devdoc> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        public  Win32Exception (  string  message  )  :  this ( Marshal . GetLastWin32Error ( ) ,  message )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// <devdoc> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ///     Initializes a new instance of the Exception class with a specified error message and a  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ///     reference to the inner exception that is the cause of this exception. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ///     FxCop CA1032: Multiple constructors are required to correctly implement a custom exception. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// </devdoc> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        public  Win32Exception (  string  message ,  Exception  innerException  )  :  base ( message ,  innerException )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            nativeErrorCode  =  Marshal . GetLastWin32Error ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        protected  Win32Exception ( SerializationInfo  info ,  StreamingContext  context )  :  base  ( info ,  context )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-10 11:41:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								#if  MONO_FEATURE_CAS  
						 
					
						
							
								
									
										
										
										
											2016-08-03 10:59:49 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            IntSecurity . UnmanagedCode . Demand ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#endif  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            nativeErrorCode  =  info . GetInt32 ( "NativeErrorCode" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// <devdoc> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ///    <para>Represents the Win32 error code associated with this exception. This  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ///       field is read-only.</para> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /// </devdoc> 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        public  int  NativeErrorCode  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            get  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  nativeErrorCode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#if  ! MONO  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        private  static  bool  TryGetErrorMessage ( int  error ,  StringBuilder  sb ,  out  string  errorMsg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            errorMsg  =  "" ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            int  result  =  SafeNativeMethods . FormatMessage ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                        SafeNativeMethods . FORMAT_MESSAGE_IGNORE_INSERTS  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                        SafeNativeMethods . FORMAT_MESSAGE_FROM_SYSTEM  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                        SafeNativeMethods . FORMAT_MESSAGE_ARGUMENT_ARRAY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                        IntPtr . Zero ,  ( uint )  error ,  0 ,  sb ,  sb . Capacity  +  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                        null ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( result  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                int  i  =  sb . Length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                while  ( i  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    char  ch  =  sb [ i  -  1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( ch  >  32  & &  ch  ! =  '.' )  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    i - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                errorMsg  =  sb . ToString ( 0 ,  i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else  if  ( Marshal . GetLastWin32Error ( )  = =  SafeNativeMethods . ERROR_INSUFFICIENT_BUFFER )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                errorMsg  = "Unknown error (0x"  +  Convert . ToString ( error ,  16 )  +  ")" ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Windows API FormatMessage lets you format a message string given an errocode. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Unlike other APIs this API does not support a way to query it for the total message size. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // So the API can only be used in one of these two ways. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. You pass a buffer of appropriate size and get the resource. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Windows creates a buffer and passes the address back and the onus of releasing the bugffer lies on the caller. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Since the error code is coming from the user, it is not possible to know the size in advance. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Unfortunately we can't use option b. since the buffer can only be freed using LocalFree and it is a private API on onecore. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Also, using option b is ugly for the manged code and could cause memory leak in situations where freeing is unsuccessful. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // As a result we use the following approach. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // We initially call the API with a buffer size of 256 and then gradually increase the size in case of failure until we reach the max allowed size of 65K bytes. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        private  const  int  MaxAllowedBufferSize  =  65  *  1024 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        private  static  string  GetErrorMessage ( int  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            string  errorMsg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            StringBuilder  sb  =  new  StringBuilder ( 256 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( TryGetErrorMessage ( error ,  sb ,  out  errorMsg ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  errorMsg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // increase the capacity of the StringBuilder by 4 times. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    sb . Capacity  * =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            while  ( sb . Capacity  <  MaxAllowedBufferSize ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // If you come here then a size as large as 65K is also not sufficient and so we give the generic errorMsg. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  "Unknown error (0x"  +  Convert . ToString ( error ,  16 )  +  ")" ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#endif  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Even though all we're exposing is the nativeErrorCode (which is also available via public property) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // it's not a bad idea to have this in place.  Later, if more fields are added to this exception,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // we won't need to worry about accidentaly exposing them through this interface. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter=true)]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        public  override  void  GetObjectData ( SerializationInfo  info ,  StreamingContext  context )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( info = = null )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                throw  new  ArgumentNullException ( "info" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            info . AddValue ( "NativeErrorCode" ,  nativeErrorCode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            base . GetObjectData ( info ,  context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}