Utils.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / AddIn / AddIn / System / Addin / Hosting / Utils.cs / 1305376 / Utils.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
/*============================================================
** 
** Class:  Utils 
**
** Purpose: Random functionality that is useful for the 
**    Add-In model
**
===========================================================*/
using System; 
using System.Collections.Generic;
using System.Collections; 
using System.Collections.ObjectModel; 
using System.IO;
using System.Reflection; 
using System.Security;
using System.Security.Permissions;
using System.Security.Policy;
using System.Text; 
using System.Diagnostics;
using System.AddIn.MiniReflection; 
using System.Diagnostics.Contracts; 

namespace System.AddIn.Hosting 
{
    [Serializable]
    internal static class Utils
    { 
        // This method requires that the types passed in are from the same CLR
        // loader context.  The V2 loader defines 4 loader contexts, and only 2 of 
        // them will exist in the CLR V3.  A type from an assembly loaded in one 
        // loader context is not assignable to the same type in a different loader
        // context.  This applies for normal assignment, but also shows up in 
        // Reflection, as getting different System.Type instances.  This method
        // wants to be relatively fast, so instead of doing string comparisons on
        // type names, we leverage Reflection's guarantees about singleton Type
        // instances for assemblies loaded in the same loader context.  That's why 
        // the loop below can do a reference equality test.
        internal static bool HasCustomAttribute(Type attributeType, Type inspectType) 
        { 
            return GetCustomAttributeData(attributeType, inspectType) != null;
        } 


        internal static CustomAttributeData GetCustomAttributeData(Type attributeType, Type inspectType)
        { 
            // Spec#: Should this be a DebugRequires or RequiresExpensive?
            System.Diagnostics.Contracts.Contract.Requires(typeof(Attribute).IsAssignableFrom(attributeType)); 
            // The following precondition isn't strictly sufficient for the V2 CLR 
            // because we define 4 loader contexts and expose only one boolean
            // predicate for testing which loader context an assembly is loaded in. 
            // But it is still very useful - our types must be in the same loader context.
            //
            // Removed because sometimes we look for attributes on a type's Base type which may be Object
            // System.Diagnostics.Contracts.Contract.Requires(attributeType.Assembly.ReflectionOnly == inspectType.Assembly.ReflectionOnly); 

            foreach (CustomAttributeData ca in CustomAttributeData.GetCustomAttributes(inspectType)) 
            { 
                if (Object.ReferenceEquals(ca.Constructor.DeclaringType, attributeType))
                    return ca; 
            }
            return null;
        }
 
        /*
        internal static bool PublicKeyTokensEqual(String token1, byte[] token2) 
        { 
            if (token2 == null || token2.Length == 0)
                return token1 == "null"; 
            if (token1 == "null")
                return false;
            Contract.Assert(token1.Length == 2 * token2.Length, "Lengths didn't match");
            for (int i = 0; i < token2.Length; i++) 
            {
                int firstPart = (token1[2 * i] <= '9') ? token1[2 * i] - '0' : token1[2 * i] - 'a' + 10; 
                int secondPart = (token1[2 * i + 1] <= '9') ? token1[2 * i + 1] - '0' : token1[2 * i + 1] - 'a' + 10; 
                byte b1 = (byte)((firstPart << 4) + secondPart);
                if (b1 != token2[i]) 
                    return false;
            }
            return true;
        } 
         */
 
        /* 
        internal static bool PublicKeyTokensEqual(byte[] token1, byte[] token2)
        { 
            if (token2 == null || token2.Length == 0)
                return token1 == null || token1.Length == 0;
            if (token1 == null)
                return false; 
            System.Diagnostics.Contracts.Contract.Assert(token1.Length == token2.Length, "Lengths didn't match");
            for (int i = 0; i < token1.Length; i++) 
                if (token1[i] != token2[i]) 
                    return false;
            return true; 
        }
        */

        internal static bool PublicKeyMatches(AssemblyName a1, AssemblyName a2) 
        {
            byte[] key = a2.GetPublicKey(); 
            return PublicKeyMatches(a1, key); 
        }
 
        internal static bool PublicKeyMatches(System.Reflection.AssemblyName a1, byte[] publicKeyOrToken)
        {
            if (publicKeyOrToken == null)
                return a1.GetPublicKey() == null; 
            byte[] publicKey = a1.GetPublicKey();
            if (publicKey != null && publicKeyOrToken.Length == publicKey.Length) 
            { 
                for (int i = 0; i < publicKey.Length; i++)
                    if (publicKey[i] != publicKeyOrToken[i]) 
                        return false;
                return true;
            }
            byte[] publicKeyToken = a1.GetPublicKeyToken(); 
            if (publicKeyOrToken.Length == publicKeyToken.Length)
            { 
                for (int i = 0; i < publicKeyToken.Length; i++) 
                    if (publicKeyToken[i] != publicKeyOrToken[i])
                        return false; 
                return true;
            }
            return false;
        } 

        internal static String PublicKeyToString(byte[] key) 
        { 
            if (key == null || key.Length == 0)
                return "null"; 

            StringBuilder sb = new StringBuilder(key.Length);
            foreach (byte b in key)
            { 
                sb.Append(b.ToString("x2", System.Globalization.CultureInfo.InvariantCulture));
            } 
            return sb.ToString(); 
        }
 
        // You must have already normalized the paths!
        internal static String MakeRelativePath(String path, String root)
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(path)); 
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(root));
            if (!path.StartsWith(root, StringComparison.OrdinalIgnoreCase)) 
                throw new ArgumentException(Res.MakeRelativePathArgs); 
            System.Diagnostics.Contracts.Contract.Requires(String.Equals(path, Path.GetFullPath(path)));
            System.Diagnostics.Contracts.Contract.Requires(String.Equals(root, Path.GetFullPath(root))); 
            System.Diagnostics.Contracts.Contract.Ensures(!Path.IsPathRooted(System.Diagnostics.Contracts.Contract.Result()));
            System.Diagnostics.Contracts.Contract.EndContractBlock();

            int skip = 0; 
            char lastChar = root[root.Length - 1];
            if (lastChar != Path.DirectorySeparatorChar && lastChar != Path.AltDirectorySeparatorChar) 
                skip++; 

            String relPath = path.Substring(root.Length + skip); 
            return relPath;
        }

        // Pass in fully qualified names.  We've factored out our assembly names 
        // comparisons so that we can handle policy if necessary, and also deal with
        // potentially mal-formed assembly refs, or assembly refs that include 
        // processor architecture, etc.  (I haven't implemented that, but it could be done.) 
        internal static bool AssemblyRefEqualsDef(String assemblyRef, String assemblyDef)
        { 
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(assemblyRef));
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(assemblyDef));

            return String.Equals(assemblyRef, assemblyDef); 
        }
 
        // Pass in fully qualified names.  We've factored out our assembly names 
        // comparisons so that we can handle policy if necessary.
        internal static bool AssemblyDefEqualsDef(String assemblyDef1, String assemblyDef2) 
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(assemblyDef1));
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(assemblyDef2));
 
            return String.Equals(assemblyDef1, assemblyDef2);
        } 
 
        // Pass in fully qualified type names.  We've factored out our assembly names
        // comparisons so that we can handle policy if necessary. 
        internal static bool FullTypeNameDefEqualsDef(String typeAndAssemblyName1, String typeAndAssemblyName2)
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(typeAndAssemblyName1));
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(typeAndAssemblyName2)); 

            return String.Equals(typeAndAssemblyName1, typeAndAssemblyName2); 
        } 

        // If you're calling this method, you suspect that you've already loaded this 
        // assembly, but you need to upgrade the assembly from the LoadFrom loader
        // context to the default loader context.  However, we'll have to call it
        // for an unbound set of assemblies.
        internal static Assembly FindLoadedAssemblyRef(String assemblyRef) 
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(assemblyRef)); 
 
            foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) {
                if (Utils.AssemblyRefEqualsDef(assemblyRef, a.FullName)) { 
                    //Console.WriteLine("FindLoadedAssemblyRef found its target (probably in the LoadFrom context).  Returning, in hopes of upgrading to default loader context.  Code base: {0}", a.CodeBase);
                    return a;
                }
            } 
            return null;
        } 
 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom", Justification="LoadFrom was designed for addins")]
        internal static Assembly LoadAssemblyFrom(List dirsToLookIn, String assemblyRef) 
        {
            int firstComma = assemblyRef.IndexOf(',');
            if (firstComma == -1)
                return null; 
            String simpleName = assemblyRef.Substring(0, firstComma);
 
            List potentialFileNames = new List(dirsToLookIn.Count * 2); 
            foreach (String path in dirsToLookIn)
            { 
                String simpleFileName = Path.Combine(path, simpleName);
                String dllName = simpleFileName + ".dll";
                if (File.Exists(dllName))
                    potentialFileNames.Add(dllName); 
                else if (File.Exists(simpleFileName + ".exe"))
                    potentialFileNames.Add(simpleFileName + ".exe"); 
            } 

            foreach (String fileName in potentialFileNames) 
            {
                try
                {
                    Assembly assembly = Assembly.LoadFrom(fileName); 
                    // We should at least be comparing the public key token
                    // for the two assemblies here.  The version numbers may 
                    // potentially be different, dependent on publisher policy. 
                    if (Utils.AssemblyRefEqualsDef(assemblyRef, assembly.FullName))
                    { 
                        return assembly;
                    }
                }
                catch (BadImageFormatException) 
                {
                } 
            } 
            return null;
        } 

        // If they have full trust, give a good error message.  Otherwise, prevent information disclosure.
        internal static bool HasFullTrust()
        { 
            try
            { 
                new PermissionSet(PermissionState.Unrestricted).Demand(); 
                return true;
            } 
            catch(SecurityException)
            {
                return false;
            } 
        }
 
        //Utility method to assert permission and unload the appdomain 
        [System.Security.SecurityCritical]
        [SecurityPermission(SecurityAction.Assert, ControlAppDomain = true)] 
        internal static void UnloadAppDomain(AppDomain domain)
        {
            AppDomain.Unload(domain);
        } 
    }
} 
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
/*============================================================
** 
** Class:  Utils 
**
** Purpose: Random functionality that is useful for the 
**    Add-In model
**
===========================================================*/
using System; 
using System.Collections.Generic;
using System.Collections; 
using System.Collections.ObjectModel; 
using System.IO;
using System.Reflection; 
using System.Security;
using System.Security.Permissions;
using System.Security.Policy;
using System.Text; 
using System.Diagnostics;
using System.AddIn.MiniReflection; 
using System.Diagnostics.Contracts; 

namespace System.AddIn.Hosting 
{
    [Serializable]
    internal static class Utils
    { 
        // This method requires that the types passed in are from the same CLR
        // loader context.  The V2 loader defines 4 loader contexts, and only 2 of 
        // them will exist in the CLR V3.  A type from an assembly loaded in one 
        // loader context is not assignable to the same type in a different loader
        // context.  This applies for normal assignment, but also shows up in 
        // Reflection, as getting different System.Type instances.  This method
        // wants to be relatively fast, so instead of doing string comparisons on
        // type names, we leverage Reflection's guarantees about singleton Type
        // instances for assemblies loaded in the same loader context.  That's why 
        // the loop below can do a reference equality test.
        internal static bool HasCustomAttribute(Type attributeType, Type inspectType) 
        { 
            return GetCustomAttributeData(attributeType, inspectType) != null;
        } 


        internal static CustomAttributeData GetCustomAttributeData(Type attributeType, Type inspectType)
        { 
            // Spec#: Should this be a DebugRequires or RequiresExpensive?
            System.Diagnostics.Contracts.Contract.Requires(typeof(Attribute).IsAssignableFrom(attributeType)); 
            // The following precondition isn't strictly sufficient for the V2 CLR 
            // because we define 4 loader contexts and expose only one boolean
            // predicate for testing which loader context an assembly is loaded in. 
            // But it is still very useful - our types must be in the same loader context.
            //
            // Removed because sometimes we look for attributes on a type's Base type which may be Object
            // System.Diagnostics.Contracts.Contract.Requires(attributeType.Assembly.ReflectionOnly == inspectType.Assembly.ReflectionOnly); 

            foreach (CustomAttributeData ca in CustomAttributeData.GetCustomAttributes(inspectType)) 
            { 
                if (Object.ReferenceEquals(ca.Constructor.DeclaringType, attributeType))
                    return ca; 
            }
            return null;
        }
 
        /*
        internal static bool PublicKeyTokensEqual(String token1, byte[] token2) 
        { 
            if (token2 == null || token2.Length == 0)
                return token1 == "null"; 
            if (token1 == "null")
                return false;
            Contract.Assert(token1.Length == 2 * token2.Length, "Lengths didn't match");
            for (int i = 0; i < token2.Length; i++) 
            {
                int firstPart = (token1[2 * i] <= '9') ? token1[2 * i] - '0' : token1[2 * i] - 'a' + 10; 
                int secondPart = (token1[2 * i + 1] <= '9') ? token1[2 * i + 1] - '0' : token1[2 * i + 1] - 'a' + 10; 
                byte b1 = (byte)((firstPart << 4) + secondPart);
                if (b1 != token2[i]) 
                    return false;
            }
            return true;
        } 
         */
 
        /* 
        internal static bool PublicKeyTokensEqual(byte[] token1, byte[] token2)
        { 
            if (token2 == null || token2.Length == 0)
                return token1 == null || token1.Length == 0;
            if (token1 == null)
                return false; 
            System.Diagnostics.Contracts.Contract.Assert(token1.Length == token2.Length, "Lengths didn't match");
            for (int i = 0; i < token1.Length; i++) 
                if (token1[i] != token2[i]) 
                    return false;
            return true; 
        }
        */

        internal static bool PublicKeyMatches(AssemblyName a1, AssemblyName a2) 
        {
            byte[] key = a2.GetPublicKey(); 
            return PublicKeyMatches(a1, key); 
        }
 
        internal static bool PublicKeyMatches(System.Reflection.AssemblyName a1, byte[] publicKeyOrToken)
        {
            if (publicKeyOrToken == null)
                return a1.GetPublicKey() == null; 
            byte[] publicKey = a1.GetPublicKey();
            if (publicKey != null && publicKeyOrToken.Length == publicKey.Length) 
            { 
                for (int i = 0; i < publicKey.Length; i++)
                    if (publicKey[i] != publicKeyOrToken[i]) 
                        return false;
                return true;
            }
            byte[] publicKeyToken = a1.GetPublicKeyToken(); 
            if (publicKeyOrToken.Length == publicKeyToken.Length)
            { 
                for (int i = 0; i < publicKeyToken.Length; i++) 
                    if (publicKeyToken[i] != publicKeyOrToken[i])
                        return false; 
                return true;
            }
            return false;
        } 

        internal static String PublicKeyToString(byte[] key) 
        { 
            if (key == null || key.Length == 0)
                return "null"; 

            StringBuilder sb = new StringBuilder(key.Length);
            foreach (byte b in key)
            { 
                sb.Append(b.ToString("x2", System.Globalization.CultureInfo.InvariantCulture));
            } 
            return sb.ToString(); 
        }
 
        // You must have already normalized the paths!
        internal static String MakeRelativePath(String path, String root)
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(path)); 
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(root));
            if (!path.StartsWith(root, StringComparison.OrdinalIgnoreCase)) 
                throw new ArgumentException(Res.MakeRelativePathArgs); 
            System.Diagnostics.Contracts.Contract.Requires(String.Equals(path, Path.GetFullPath(path)));
            System.Diagnostics.Contracts.Contract.Requires(String.Equals(root, Path.GetFullPath(root))); 
            System.Diagnostics.Contracts.Contract.Ensures(!Path.IsPathRooted(System.Diagnostics.Contracts.Contract.Result()));
            System.Diagnostics.Contracts.Contract.EndContractBlock();

            int skip = 0; 
            char lastChar = root[root.Length - 1];
            if (lastChar != Path.DirectorySeparatorChar && lastChar != Path.AltDirectorySeparatorChar) 
                skip++; 

            String relPath = path.Substring(root.Length + skip); 
            return relPath;
        }

        // Pass in fully qualified names.  We've factored out our assembly names 
        // comparisons so that we can handle policy if necessary, and also deal with
        // potentially mal-formed assembly refs, or assembly refs that include 
        // processor architecture, etc.  (I haven't implemented that, but it could be done.) 
        internal static bool AssemblyRefEqualsDef(String assemblyRef, String assemblyDef)
        { 
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(assemblyRef));
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(assemblyDef));

            return String.Equals(assemblyRef, assemblyDef); 
        }
 
        // Pass in fully qualified names.  We've factored out our assembly names 
        // comparisons so that we can handle policy if necessary.
        internal static bool AssemblyDefEqualsDef(String assemblyDef1, String assemblyDef2) 
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(assemblyDef1));
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(assemblyDef2));
 
            return String.Equals(assemblyDef1, assemblyDef2);
        } 
 
        // Pass in fully qualified type names.  We've factored out our assembly names
        // comparisons so that we can handle policy if necessary. 
        internal static bool FullTypeNameDefEqualsDef(String typeAndAssemblyName1, String typeAndAssemblyName2)
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(typeAndAssemblyName1));
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(typeAndAssemblyName2)); 

            return String.Equals(typeAndAssemblyName1, typeAndAssemblyName2); 
        } 

        // If you're calling this method, you suspect that you've already loaded this 
        // assembly, but you need to upgrade the assembly from the LoadFrom loader
        // context to the default loader context.  However, we'll have to call it
        // for an unbound set of assemblies.
        internal static Assembly FindLoadedAssemblyRef(String assemblyRef) 
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(assemblyRef)); 
 
            foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) {
                if (Utils.AssemblyRefEqualsDef(assemblyRef, a.FullName)) { 
                    //Console.WriteLine("FindLoadedAssemblyRef found its target (probably in the LoadFrom context).  Returning, in hopes of upgrading to default loader context.  Code base: {0}", a.CodeBase);
                    return a;
                }
            } 
            return null;
        } 
 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom", Justification="LoadFrom was designed for addins")]
        internal static Assembly LoadAssemblyFrom(List dirsToLookIn, String assemblyRef) 
        {
            int firstComma = assemblyRef.IndexOf(',');
            if (firstComma == -1)
                return null; 
            String simpleName = assemblyRef.Substring(0, firstComma);
 
            List potentialFileNames = new List(dirsToLookIn.Count * 2); 
            foreach (String path in dirsToLookIn)
            { 
                String simpleFileName = Path.Combine(path, simpleName);
                String dllName = simpleFileName + ".dll";
                if (File.Exists(dllName))
                    potentialFileNames.Add(dllName); 
                else if (File.Exists(simpleFileName + ".exe"))
                    potentialFileNames.Add(simpleFileName + ".exe"); 
            } 

            foreach (String fileName in potentialFileNames) 
            {
                try
                {
                    Assembly assembly = Assembly.LoadFrom(fileName); 
                    // We should at least be comparing the public key token
                    // for the two assemblies here.  The version numbers may 
                    // potentially be different, dependent on publisher policy. 
                    if (Utils.AssemblyRefEqualsDef(assemblyRef, assembly.FullName))
                    { 
                        return assembly;
                    }
                }
                catch (BadImageFormatException) 
                {
                } 
            } 
            return null;
        } 

        // If they have full trust, give a good error message.  Otherwise, prevent information disclosure.
        internal static bool HasFullTrust()
        { 
            try
            { 
                new PermissionSet(PermissionState.Unrestricted).Demand(); 
                return true;
            } 
            catch(SecurityException)
            {
                return false;
            } 
        }
 
        //Utility method to assert permission and unload the appdomain 
        [System.Security.SecurityCritical]
        [SecurityPermission(SecurityAction.Assert, ControlAppDomain = true)] 
        internal static void UnloadAppDomain(AppDomain domain)
        {
            AppDomain.Unload(domain);
        } 
    }
} 
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK