LicenseManager.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / CompMod / System / ComponentModel / LicenseManager.cs / 1 / LicenseManager.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.ComponentModel { 
    using System.Runtime.Remoting.Activation; 
    using System.Runtime.Remoting;
    using System.Runtime.InteropServices; 
    using System.Reflection;
    using System.Diagnostics;
    using System;
    using System.Text; 
    using System.Collections;
    using System.ComponentModel.Design; 
    using Microsoft.Win32; 
    using System.Security.Permissions;
 
    /// 
    /// 
    ///    Provides properties and methods to add a license
    ///       to a component and to manage a . This class cannot be inherited. 
    /// 
    [HostProtection(ExternalProcessMgmt=true)] 
    public sealed class LicenseManager { 
        private static readonly object selfLock = new object();
 
        private static LicenseContext context = null;
        private static object contextLockHolder = null;
        private static Hashtable providers;
        private static Hashtable providerInstances; 
        private static object internalSyncObject = new object();
 
        // not creatable... 
        //
        private LicenseManager() { 
        }

        /// 
        ///  
        ///    
        ///       Gets or sets the current  which specifies when the licensed object can be 
        ///       used. 
        ///    
        ///  
        public static LicenseContext CurrentContext {
            get {
                if (context == null) {
                    lock(internalSyncObject) { 
                        if (context == null) {
                            context = new System.ComponentModel.Design.RuntimeLicenseContext(); 
                        } 
                    }
                } 
                return context;
            }
            set {
                lock(internalSyncObject) { 
                    if (contextLockHolder != null) {
                        throw new InvalidOperationException(SR.GetString(SR.LicMgrContextCannotBeChanged)); 
                    } 
                    context = value;
                } 
            }
        }

        ///  
        /// 
        /// Gets the  that 
        ///    specifies when the licensed object can be used, for the . 
        /// 
        public static LicenseUsageMode UsageMode { 
            get {
                if (context != null) {
                    return context.UsageMode;
                } 
                return LicenseUsageMode.Runtime;
            } 
        } 

        ///  
        /// 
        ///     Caches the provider, both in the instance cache, and the type
        ///     cache.
        ///  
        private static void CacheProvider(Type type, LicenseProvider provider) {
            if (providers == null) { 
                providers = new Hashtable(); 
            }
            providers[type] = provider; 

            if (provider != null) {
                if (providerInstances == null) {
                    providerInstances = new Hashtable(); 
                }
                providerInstances[provider.GetType()] = provider; 
            } 
        }
 
        /// 
        /// 
        ///    Creates an instance of the specified type, using
        ///       creationContext 
        ///       as the context in which the licensed instance can be used.
        ///  
        public static object CreateWithContext(Type type, LicenseContext creationContext) { 
            return CreateWithContext(type, creationContext, new object[0]);
        } 

        /// 
        /// 
        ///    Creates an instance of the specified type with the 
        ///       specified arguments, using creationContext as the context in which the licensed
        ///       instance can be used. 
        ///  
        public static object CreateWithContext(Type type, LicenseContext creationContext, object[] args) {
            object created = null; 

            lock(internalSyncObject) {
                LicenseContext normal = CurrentContext;
                try { 
                    CurrentContext = creationContext;
                    LockContext(selfLock); 
                    try { 
                        created = SecurityUtils.SecureCreateInstance(type, args);
                    } 
                    catch (TargetInvocationException e) {
                        throw e.InnerException;
                    }
                } 
                finally {
                    UnlockContext(selfLock); 
                    CurrentContext = normal; 
                }
            } 

            return created;
        }
 
        /// 
        ///  
        ///     Determines if type was actually cached to have _no_ provider, 
        ///     as opposed to not being cached.
        ///  
        private static bool GetCachedNoLicenseProvider(Type type) {
            if (providers != null) {
                return providers.ContainsKey(type);
            } 
            return false;
        } 
 
        /// 
        ///  
        ///     Retrieves a cached instance of the provider associated with the
        ///     specified type.
        /// 
        private static LicenseProvider GetCachedProvider(Type type) { 
            if (providers != null) {
                return(LicenseProvider)providers[type]; 
            } 
            return null;
        } 

        /// 
        /// 
        ///     Retrieves a cached instance of the provider of the specified 
        ///     type.
        ///  
        private static LicenseProvider GetCachedProviderInstance(Type providerType) { 
            Debug.Assert(providerType != null, "Type cannot ever be null");
            if (providerInstances != null) { 
                return(LicenseProvider)providerInstances[providerType];
            }
            return null;
        } 

        ///  
        ///  
        ///     Retrieves the typehandle of the interop helper
        ///  
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        private static RuntimeTypeHandle GetLicenseInteropHelperType() {
            return typeof(LicenseInteropHelper).TypeHandle;
        } 

        ///  
        ///  
        ///    Determines if the given type has a valid license or not.
        ///  
        public static bool IsLicensed(Type type) {
            Debug.Assert(type != null, "IsValid Type cannot ever be null");
            License license;
            bool value = ValidateInternal(type, null, false, out license); 
            if (license != null) {
                license.Dispose(); 
                license = null; 
            }
            return value; 
        }

        /// 
        ///  
        ///    Determines if a valid license can be granted for the specified type.
        ///  
        public static bool IsValid(Type type) { 
            Debug.Assert(type != null, "IsValid Type cannot ever be null");
            License license; 
            bool value = ValidateInternal(type, null, false, out license);
            if (license != null) {
                license.Dispose();
                license = null; 
            }
            return value; 
        } 

 
        /// 
        /// 
        ///    Determines if a valid license can be granted for the
        ///       specified instance of the type. This method creates a valid .  
        /// 
        public static bool IsValid(Type type, object instance, out License license) { 
            return ValidateInternal(type, instance, false, out license); 
        }
 
        /// 
        /// 
        /// 
        public static void LockContext(object contextUser) { 
            lock(internalSyncObject) {
                if (contextLockHolder != null) { 
                    throw new InvalidOperationException(SR.GetString(SR.LicMgrAlreadyLocked)); 
                }
                contextLockHolder = contextUser; 
            }
        }

        ///  
        /// 
        ///  
        public static void UnlockContext(object contextUser) { 
            lock(internalSyncObject) {
                if (contextLockHolder != contextUser) { 
                    throw new ArgumentException(SR.GetString(SR.LicMgrDifferentUser));
                }
                contextLockHolder = null;
            } 
        }
 
        ///  
        /// 
        ///     Internal validation helper. 
        /// 
        private static bool ValidateInternal(Type type, object instance, bool allowExceptions, out License license) {
            string licenseKey;
            return ValidateInternalRecursive(CurrentContext, 
                                             type,
                                             instance, 
                                             allowExceptions, 
                                             out license,
                                             out licenseKey); 
        }

        /// 
        ///  
        ///     Since we want to walk up the entire inheritance change, when not
        ///     give an instance, we need another helper method to walk up 
        ///     the chain... 
        /// 
        private static bool ValidateInternalRecursive(LicenseContext context, Type type, object instance, bool allowExceptions, out License license, out string licenseKey) { 
            LicenseProvider provider = GetCachedProvider(type);
            if (provider == null && !GetCachedNoLicenseProvider(type)) {
                // NOTE : Must look directly at the class, we want no inheritance.
                // 
                LicenseProviderAttribute attr = (LicenseProviderAttribute)Attribute.GetCustomAttribute(type, typeof(LicenseProviderAttribute), false);
                if (attr != null) { 
                    Type providerType = attr.LicenseProvider; 
                    provider = GetCachedProviderInstance(providerType);
 
                    if (provider == null) {
                        provider = (LicenseProvider)SecurityUtils.SecureCreateInstance(providerType);
                    }
                } 

                CacheProvider(type, provider); 
            } 

            license = null; 
            bool isValid = true;

            licenseKey = null;
            if (provider != null) { 
                license = provider.GetLicense(context, type, instance, allowExceptions);
                if (license == null) { 
                    isValid = false; 
                }
                else { 
                    // For the case where a COM client is calling "RequestLicKey",
                    // we try to squirrel away the first found license key
                    //
                    licenseKey = license.LicenseKey; 
                }
            } 
 
            // When looking only at a type, we need to recurse up the inheritence
            // chain, however, we can't give out the license, since this may be 
            // from more than one provider.
            //
            if (isValid && instance == null) {
                Type baseType = type.BaseType; 
                if (baseType != typeof(object) && baseType != null) {
                    if (license != null) { 
                        license.Dispose(); 
                        license = null;
                    } 
                    string temp;
                    isValid = ValidateInternalRecursive(context, baseType, null, allowExceptions, out license, out temp);
                    if (license != null) {
                        license.Dispose(); 
                        license = null;
                    } 
                } 
            }
 
            return isValid;
        }

        ///  
        /// 
        ///    Determines if a license can be granted for the specified type. 
        ///  
        public static void Validate(Type type) {
            License lic; 

            if (!ValidateInternal(type, null, true, out lic)) {
                throw new LicenseException(type);
            } 

            if (lic != null) { 
                lic.Dispose(); 
                lic = null;
            } 
        }

        /// 
        ///  
        ///    Determines if a license can be granted for the instance of the specified type.
        ///  
        public static License Validate(Type type, object instance) { 
            License lic;
 
            if (!ValidateInternal(type, instance, true, out lic)) {
                throw new LicenseException(type, instance);
            }
 
            return lic;
        } 
 
        // FxCop complaint about uninstantiated internal classes
        // Re-activate if this class proves to be useful. 

        // This is a helper class that supports the CLR's IClassFactory2 marshaling
        // support.
        // 
        // When a managed object is exposed to COM, the CLR invokes
        // AllocateAndValidateLicense() to set up the appropriate 
        // license context and instantiate the object. 
        //
        // When the CLR consumes an unmanaged COM object, the CLR invokes 
        // GetCurrentContextInfo() to figure out the licensing context
        // and decide whether to call ICF::CreateInstance() (designtime) or
        // ICF::CreateInstanceLic() (runtime). In the former case, it also
        // requests the class factory for a runtime license key and invokes 
        // SaveKeyInCurrentContext() to stash a copy in the current licensing
        // context 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")] 
        class LicenseInteropHelper {
 
            // Define some common HRESULTs.
            const int S_OK = 0;
            const int E_NOTIMPL = unchecked((int)0x80004001);
            const int CLASS_E_NOTLICENSED = unchecked((int)0x80040112); 
            const int E_FAIL              = unchecked((int)0x80000008);
 
            DesigntimeLicenseContext helperContext; 
            LicenseContext    savedLicenseContext;
            Type              savedType; 

            // The CLR invokes this whenever a COM client invokes
            // IClassFactory::CreateInstance() or IClassFactory2::CreateInstanceLic()
            // on a managed managed that has a LicenseProvider custom attribute. 
            //
            // If we are being entered because of a call to ICF::CreateInstance(), 
            // fDesignTime will be "true". 
            //
            // If we are being entered because of a call to ICF::CreateInstanceLic(), 
            // fDesignTime will be "false" and bstrKey will point a non-null
            // license key.
            private static object AllocateAndValidateLicense(RuntimeTypeHandle rth, IntPtr bstrKey, int fDesignTime) {
                Type type = Type.GetTypeFromHandle(rth); 
                CLRLicenseContext licensecontext = new CLRLicenseContext(fDesignTime != 0 ? LicenseUsageMode.Designtime : LicenseUsageMode.Runtime, type);
                if (fDesignTime == 0 && bstrKey != (IntPtr)0) { 
                    licensecontext.SetSavedLicenseKey(type, Marshal.PtrToStringBSTR(bstrKey)); 
                }
 

                try {
                    return LicenseManager.CreateWithContext(type, licensecontext);
                } 
                catch (LicenseException lexp) {
                    throw new COMException(lexp.Message, CLASS_E_NOTLICENSED); 
                } 
            }
 
            // The CLR invokes this whenever a COM client invokes
            // IClassFactory2::RequestLicKey on a managed class.
            //
            // This method should return the appropriate HRESULT and set pbstrKey 
            // to the licensing key.
            private static int RequestLicKey(RuntimeTypeHandle rth, ref IntPtr pbstrKey) { 
                Type type = Type.GetTypeFromHandle(rth); 
                License license;
                string licenseKey; 

                // license will be null, since we passed no instance,
                // however we can still retrieve the "first" license
                // key from the file. This really will only 
                // work for simple COM-compatible license providers
                // like LicFileLicenseProvider that don't require the 
                // instance to grant a key. 
                //
                if (!LicenseManager.ValidateInternalRecursive(LicenseManager.CurrentContext, 
                                                              type,
                                                              null,
                                                              false,
                                                              out license, 
                                                              out licenseKey)) {
                    return E_FAIL; 
                } 

                if (licenseKey == null) { 
                    return E_FAIL;
                }

                pbstrKey = Marshal.StringToBSTR(licenseKey); 

                if (license != null) { 
                    license.Dispose(); 
                    license = null;
                } 

                return S_OK;

            } 

 
            // The CLR invokes this whenever a COM client invokes 
            // IClassFactory2::GetLicInfo on a managed class.
            // 
            // COM normally doesn't expect this function to fail so this method
            // should only throw in the case of a catastrophic error (stack, memory, etc.)
            private void GetLicInfo(RuntimeTypeHandle rth, ref int pRuntimeKeyAvail, ref int pLicVerified) {
                pRuntimeKeyAvail = 0; 
                pLicVerified = 0;
 
                Type type = Type.GetTypeFromHandle(rth); 
                License license;
                string licenseKey; 

                if (helperContext == null) {
                    helperContext = new DesigntimeLicenseContext();
                } 
                else {
                    helperContext.savedLicenseKeys.Clear(); 
                } 

                if (LicenseManager.ValidateInternalRecursive(helperContext, type, null, false, out license, out licenseKey)) { 

                    if (helperContext.savedLicenseKeys.Contains(type.AssemblyQualifiedName)) {
                        pRuntimeKeyAvail = 1;
                    } 

                    if (license != null) { 
                        license.Dispose(); 
                        license = null;
 
                        pLicVerified = 1;
                    }
                }
            } 

            // The CLR invokes this when instantiating an unmanaged COM 
            // object. The purpose is to decide which classfactory method to 
            // use.
            // 
            // If the current context is design time, the CLR will
            // use ICF::CreateInstance().
            //
            // If the current context is runtime and the current context 
            // exposes a non-null license key and the COM object supports
            // IClassFactory2, the CLR will use ICF2::CreateInstanceLic(). 
            // Otherwise, the CLR will use ICF::CreateInstance. 
            //
            // Arguments: 
            //    ref int fDesignTime:   on exit, this will be set to indicate
            //                           the nature of the current license context.
            //    ref int bstrKey:       on exit, this will point to the
            //                           licensekey saved inside the license context. 
            //                           (only if the license context is runtime)
            //    RuntimeTypeHandle rth: the managed type of the wrapper 
            private void GetCurrentContextInfo(ref int fDesignTime, ref IntPtr bstrKey, RuntimeTypeHandle rth) { 
                this.savedLicenseContext = LicenseManager.CurrentContext;
                this.savedType = Type.GetTypeFromHandle(rth); 
                if (this.savedLicenseContext.UsageMode == LicenseUsageMode.Designtime) {
                    fDesignTime = 1;
                    bstrKey = (IntPtr)0;
                } 
                else {
                    fDesignTime = 0; 
                    String key = this.savedLicenseContext.GetSavedLicenseKey(this.savedType, null); 
                    bstrKey = Marshal.StringToBSTR(key);
 
                }
            }

            // The CLR invokes this when instantiating a licensed COM 
            // object inside a designtime license context.
            // It's purpose is to save away the license key that the CLR 
            // retrieved using RequestLicKey(). This license key can be NULL. 
            private void SaveKeyInCurrentContext(IntPtr bstrKey) {
                if (bstrKey != (IntPtr)0) { 
                    this.savedLicenseContext.SetSavedLicenseKey(this.savedType, Marshal.PtrToStringBSTR(bstrKey));
                }
            }
 
            // A private implementation of a LicenseContext used for instantiating
            // managed objects exposed to COM. It has memory for the license key 
            // of a single Type. 
            internal class CLRLicenseContext : LicenseContext {
                LicenseUsageMode  usageMode; 
                Type              type;
                string            key;

                public CLRLicenseContext(LicenseUsageMode usageMode, Type type) { 
                    this.usageMode = usageMode;
                    this.type      = type; 
                } 

                public override LicenseUsageMode UsageMode 
                {
                    get {
                        return this.usageMode;
                    } 
                }
 
 
                public override string GetSavedLicenseKey(Type type, Assembly resourceAssembly) {
                    return type == this.type ? this.key : null; 
                }
                public override void SetSavedLicenseKey(Type type, string key) {
                    if (type == this.type) {
                        this.key = key; 
                    }
                } 
            } 
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.ComponentModel { 
    using System.Runtime.Remoting.Activation; 
    using System.Runtime.Remoting;
    using System.Runtime.InteropServices; 
    using System.Reflection;
    using System.Diagnostics;
    using System;
    using System.Text; 
    using System.Collections;
    using System.ComponentModel.Design; 
    using Microsoft.Win32; 
    using System.Security.Permissions;
 
    /// 
    /// 
    ///    Provides properties and methods to add a license
    ///       to a component and to manage a . This class cannot be inherited. 
    /// 
    [HostProtection(ExternalProcessMgmt=true)] 
    public sealed class LicenseManager { 
        private static readonly object selfLock = new object();
 
        private static LicenseContext context = null;
        private static object contextLockHolder = null;
        private static Hashtable providers;
        private static Hashtable providerInstances; 
        private static object internalSyncObject = new object();
 
        // not creatable... 
        //
        private LicenseManager() { 
        }

        /// 
        ///  
        ///    
        ///       Gets or sets the current  which specifies when the licensed object can be 
        ///       used. 
        ///    
        ///  
        public static LicenseContext CurrentContext {
            get {
                if (context == null) {
                    lock(internalSyncObject) { 
                        if (context == null) {
                            context = new System.ComponentModel.Design.RuntimeLicenseContext(); 
                        } 
                    }
                } 
                return context;
            }
            set {
                lock(internalSyncObject) { 
                    if (contextLockHolder != null) {
                        throw new InvalidOperationException(SR.GetString(SR.LicMgrContextCannotBeChanged)); 
                    } 
                    context = value;
                } 
            }
        }

        ///  
        /// 
        /// Gets the  that 
        ///    specifies when the licensed object can be used, for the . 
        /// 
        public static LicenseUsageMode UsageMode { 
            get {
                if (context != null) {
                    return context.UsageMode;
                } 
                return LicenseUsageMode.Runtime;
            } 
        } 

        ///  
        /// 
        ///     Caches the provider, both in the instance cache, and the type
        ///     cache.
        ///  
        private static void CacheProvider(Type type, LicenseProvider provider) {
            if (providers == null) { 
                providers = new Hashtable(); 
            }
            providers[type] = provider; 

            if (provider != null) {
                if (providerInstances == null) {
                    providerInstances = new Hashtable(); 
                }
                providerInstances[provider.GetType()] = provider; 
            } 
        }
 
        /// 
        /// 
        ///    Creates an instance of the specified type, using
        ///       creationContext 
        ///       as the context in which the licensed instance can be used.
        ///  
        public static object CreateWithContext(Type type, LicenseContext creationContext) { 
            return CreateWithContext(type, creationContext, new object[0]);
        } 

        /// 
        /// 
        ///    Creates an instance of the specified type with the 
        ///       specified arguments, using creationContext as the context in which the licensed
        ///       instance can be used. 
        ///  
        public static object CreateWithContext(Type type, LicenseContext creationContext, object[] args) {
            object created = null; 

            lock(internalSyncObject) {
                LicenseContext normal = CurrentContext;
                try { 
                    CurrentContext = creationContext;
                    LockContext(selfLock); 
                    try { 
                        created = SecurityUtils.SecureCreateInstance(type, args);
                    } 
                    catch (TargetInvocationException e) {
                        throw e.InnerException;
                    }
                } 
                finally {
                    UnlockContext(selfLock); 
                    CurrentContext = normal; 
                }
            } 

            return created;
        }
 
        /// 
        ///  
        ///     Determines if type was actually cached to have _no_ provider, 
        ///     as opposed to not being cached.
        ///  
        private static bool GetCachedNoLicenseProvider(Type type) {
            if (providers != null) {
                return providers.ContainsKey(type);
            } 
            return false;
        } 
 
        /// 
        ///  
        ///     Retrieves a cached instance of the provider associated with the
        ///     specified type.
        /// 
        private static LicenseProvider GetCachedProvider(Type type) { 
            if (providers != null) {
                return(LicenseProvider)providers[type]; 
            } 
            return null;
        } 

        /// 
        /// 
        ///     Retrieves a cached instance of the provider of the specified 
        ///     type.
        ///  
        private static LicenseProvider GetCachedProviderInstance(Type providerType) { 
            Debug.Assert(providerType != null, "Type cannot ever be null");
            if (providerInstances != null) { 
                return(LicenseProvider)providerInstances[providerType];
            }
            return null;
        } 

        ///  
        ///  
        ///     Retrieves the typehandle of the interop helper
        ///  
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        private static RuntimeTypeHandle GetLicenseInteropHelperType() {
            return typeof(LicenseInteropHelper).TypeHandle;
        } 

        ///  
        ///  
        ///    Determines if the given type has a valid license or not.
        ///  
        public static bool IsLicensed(Type type) {
            Debug.Assert(type != null, "IsValid Type cannot ever be null");
            License license;
            bool value = ValidateInternal(type, null, false, out license); 
            if (license != null) {
                license.Dispose(); 
                license = null; 
            }
            return value; 
        }

        /// 
        ///  
        ///    Determines if a valid license can be granted for the specified type.
        ///  
        public static bool IsValid(Type type) { 
            Debug.Assert(type != null, "IsValid Type cannot ever be null");
            License license; 
            bool value = ValidateInternal(type, null, false, out license);
            if (license != null) {
                license.Dispose();
                license = null; 
            }
            return value; 
        } 

 
        /// 
        /// 
        ///    Determines if a valid license can be granted for the
        ///       specified instance of the type. This method creates a valid .  
        /// 
        public static bool IsValid(Type type, object instance, out License license) { 
            return ValidateInternal(type, instance, false, out license); 
        }
 
        /// 
        /// 
        /// 
        public static void LockContext(object contextUser) { 
            lock(internalSyncObject) {
                if (contextLockHolder != null) { 
                    throw new InvalidOperationException(SR.GetString(SR.LicMgrAlreadyLocked)); 
                }
                contextLockHolder = contextUser; 
            }
        }

        ///  
        /// 
        ///  
        public static void UnlockContext(object contextUser) { 
            lock(internalSyncObject) {
                if (contextLockHolder != contextUser) { 
                    throw new ArgumentException(SR.GetString(SR.LicMgrDifferentUser));
                }
                contextLockHolder = null;
            } 
        }
 
        ///  
        /// 
        ///     Internal validation helper. 
        /// 
        private static bool ValidateInternal(Type type, object instance, bool allowExceptions, out License license) {
            string licenseKey;
            return ValidateInternalRecursive(CurrentContext, 
                                             type,
                                             instance, 
                                             allowExceptions, 
                                             out license,
                                             out licenseKey); 
        }

        /// 
        ///  
        ///     Since we want to walk up the entire inheritance change, when not
        ///     give an instance, we need another helper method to walk up 
        ///     the chain... 
        /// 
        private static bool ValidateInternalRecursive(LicenseContext context, Type type, object instance, bool allowExceptions, out License license, out string licenseKey) { 
            LicenseProvider provider = GetCachedProvider(type);
            if (provider == null && !GetCachedNoLicenseProvider(type)) {
                // NOTE : Must look directly at the class, we want no inheritance.
                // 
                LicenseProviderAttribute attr = (LicenseProviderAttribute)Attribute.GetCustomAttribute(type, typeof(LicenseProviderAttribute), false);
                if (attr != null) { 
                    Type providerType = attr.LicenseProvider; 
                    provider = GetCachedProviderInstance(providerType);
 
                    if (provider == null) {
                        provider = (LicenseProvider)SecurityUtils.SecureCreateInstance(providerType);
                    }
                } 

                CacheProvider(type, provider); 
            } 

            license = null; 
            bool isValid = true;

            licenseKey = null;
            if (provider != null) { 
                license = provider.GetLicense(context, type, instance, allowExceptions);
                if (license == null) { 
                    isValid = false; 
                }
                else { 
                    // For the case where a COM client is calling "RequestLicKey",
                    // we try to squirrel away the first found license key
                    //
                    licenseKey = license.LicenseKey; 
                }
            } 
 
            // When looking only at a type, we need to recurse up the inheritence
            // chain, however, we can't give out the license, since this may be 
            // from more than one provider.
            //
            if (isValid && instance == null) {
                Type baseType = type.BaseType; 
                if (baseType != typeof(object) && baseType != null) {
                    if (license != null) { 
                        license.Dispose(); 
                        license = null;
                    } 
                    string temp;
                    isValid = ValidateInternalRecursive(context, baseType, null, allowExceptions, out license, out temp);
                    if (license != null) {
                        license.Dispose(); 
                        license = null;
                    } 
                } 
            }
 
            return isValid;
        }

        ///  
        /// 
        ///    Determines if a license can be granted for the specified type. 
        ///  
        public static void Validate(Type type) {
            License lic; 

            if (!ValidateInternal(type, null, true, out lic)) {
                throw new LicenseException(type);
            } 

            if (lic != null) { 
                lic.Dispose(); 
                lic = null;
            } 
        }

        /// 
        ///  
        ///    Determines if a license can be granted for the instance of the specified type.
        ///  
        public static License Validate(Type type, object instance) { 
            License lic;
 
            if (!ValidateInternal(type, instance, true, out lic)) {
                throw new LicenseException(type, instance);
            }
 
            return lic;
        } 
 
        // FxCop complaint about uninstantiated internal classes
        // Re-activate if this class proves to be useful. 

        // This is a helper class that supports the CLR's IClassFactory2 marshaling
        // support.
        // 
        // When a managed object is exposed to COM, the CLR invokes
        // AllocateAndValidateLicense() to set up the appropriate 
        // license context and instantiate the object. 
        //
        // When the CLR consumes an unmanaged COM object, the CLR invokes 
        // GetCurrentContextInfo() to figure out the licensing context
        // and decide whether to call ICF::CreateInstance() (designtime) or
        // ICF::CreateInstanceLic() (runtime). In the former case, it also
        // requests the class factory for a runtime license key and invokes 
        // SaveKeyInCurrentContext() to stash a copy in the current licensing
        // context 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")] 
        class LicenseInteropHelper {
 
            // Define some common HRESULTs.
            const int S_OK = 0;
            const int E_NOTIMPL = unchecked((int)0x80004001);
            const int CLASS_E_NOTLICENSED = unchecked((int)0x80040112); 
            const int E_FAIL              = unchecked((int)0x80000008);
 
            DesigntimeLicenseContext helperContext; 
            LicenseContext    savedLicenseContext;
            Type              savedType; 

            // The CLR invokes this whenever a COM client invokes
            // IClassFactory::CreateInstance() or IClassFactory2::CreateInstanceLic()
            // on a managed managed that has a LicenseProvider custom attribute. 
            //
            // If we are being entered because of a call to ICF::CreateInstance(), 
            // fDesignTime will be "true". 
            //
            // If we are being entered because of a call to ICF::CreateInstanceLic(), 
            // fDesignTime will be "false" and bstrKey will point a non-null
            // license key.
            private static object AllocateAndValidateLicense(RuntimeTypeHandle rth, IntPtr bstrKey, int fDesignTime) {
                Type type = Type.GetTypeFromHandle(rth); 
                CLRLicenseContext licensecontext = new CLRLicenseContext(fDesignTime != 0 ? LicenseUsageMode.Designtime : LicenseUsageMode.Runtime, type);
                if (fDesignTime == 0 && bstrKey != (IntPtr)0) { 
                    licensecontext.SetSavedLicenseKey(type, Marshal.PtrToStringBSTR(bstrKey)); 
                }
 

                try {
                    return LicenseManager.CreateWithContext(type, licensecontext);
                } 
                catch (LicenseException lexp) {
                    throw new COMException(lexp.Message, CLASS_E_NOTLICENSED); 
                } 
            }
 
            // The CLR invokes this whenever a COM client invokes
            // IClassFactory2::RequestLicKey on a managed class.
            //
            // This method should return the appropriate HRESULT and set pbstrKey 
            // to the licensing key.
            private static int RequestLicKey(RuntimeTypeHandle rth, ref IntPtr pbstrKey) { 
                Type type = Type.GetTypeFromHandle(rth); 
                License license;
                string licenseKey; 

                // license will be null, since we passed no instance,
                // however we can still retrieve the "first" license
                // key from the file. This really will only 
                // work for simple COM-compatible license providers
                // like LicFileLicenseProvider that don't require the 
                // instance to grant a key. 
                //
                if (!LicenseManager.ValidateInternalRecursive(LicenseManager.CurrentContext, 
                                                              type,
                                                              null,
                                                              false,
                                                              out license, 
                                                              out licenseKey)) {
                    return E_FAIL; 
                } 

                if (licenseKey == null) { 
                    return E_FAIL;
                }

                pbstrKey = Marshal.StringToBSTR(licenseKey); 

                if (license != null) { 
                    license.Dispose(); 
                    license = null;
                } 

                return S_OK;

            } 

 
            // The CLR invokes this whenever a COM client invokes 
            // IClassFactory2::GetLicInfo on a managed class.
            // 
            // COM normally doesn't expect this function to fail so this method
            // should only throw in the case of a catastrophic error (stack, memory, etc.)
            private void GetLicInfo(RuntimeTypeHandle rth, ref int pRuntimeKeyAvail, ref int pLicVerified) {
                pRuntimeKeyAvail = 0; 
                pLicVerified = 0;
 
                Type type = Type.GetTypeFromHandle(rth); 
                License license;
                string licenseKey; 

                if (helperContext == null) {
                    helperContext = new DesigntimeLicenseContext();
                } 
                else {
                    helperContext.savedLicenseKeys.Clear(); 
                } 

                if (LicenseManager.ValidateInternalRecursive(helperContext, type, null, false, out license, out licenseKey)) { 

                    if (helperContext.savedLicenseKeys.Contains(type.AssemblyQualifiedName)) {
                        pRuntimeKeyAvail = 1;
                    } 

                    if (license != null) { 
                        license.Dispose(); 
                        license = null;
 
                        pLicVerified = 1;
                    }
                }
            } 

            // The CLR invokes this when instantiating an unmanaged COM 
            // object. The purpose is to decide which classfactory method to 
            // use.
            // 
            // If the current context is design time, the CLR will
            // use ICF::CreateInstance().
            //
            // If the current context is runtime and the current context 
            // exposes a non-null license key and the COM object supports
            // IClassFactory2, the CLR will use ICF2::CreateInstanceLic(). 
            // Otherwise, the CLR will use ICF::CreateInstance. 
            //
            // Arguments: 
            //    ref int fDesignTime:   on exit, this will be set to indicate
            //                           the nature of the current license context.
            //    ref int bstrKey:       on exit, this will point to the
            //                           licensekey saved inside the license context. 
            //                           (only if the license context is runtime)
            //    RuntimeTypeHandle rth: the managed type of the wrapper 
            private void GetCurrentContextInfo(ref int fDesignTime, ref IntPtr bstrKey, RuntimeTypeHandle rth) { 
                this.savedLicenseContext = LicenseManager.CurrentContext;
                this.savedType = Type.GetTypeFromHandle(rth); 
                if (this.savedLicenseContext.UsageMode == LicenseUsageMode.Designtime) {
                    fDesignTime = 1;
                    bstrKey = (IntPtr)0;
                } 
                else {
                    fDesignTime = 0; 
                    String key = this.savedLicenseContext.GetSavedLicenseKey(this.savedType, null); 
                    bstrKey = Marshal.StringToBSTR(key);
 
                }
            }

            // The CLR invokes this when instantiating a licensed COM 
            // object inside a designtime license context.
            // It's purpose is to save away the license key that the CLR 
            // retrieved using RequestLicKey(). This license key can be NULL. 
            private void SaveKeyInCurrentContext(IntPtr bstrKey) {
                if (bstrKey != (IntPtr)0) { 
                    this.savedLicenseContext.SetSavedLicenseKey(this.savedType, Marshal.PtrToStringBSTR(bstrKey));
                }
            }
 
            // A private implementation of a LicenseContext used for instantiating
            // managed objects exposed to COM. It has memory for the license key 
            // of a single Type. 
            internal class CLRLicenseContext : LicenseContext {
                LicenseUsageMode  usageMode; 
                Type              type;
                string            key;

                public CLRLicenseContext(LicenseUsageMode usageMode, Type type) { 
                    this.usageMode = usageMode;
                    this.type      = type; 
                } 

                public override LicenseUsageMode UsageMode 
                {
                    get {
                        return this.usageMode;
                    } 
                }
 
 
                public override string GetSavedLicenseKey(Type type, Assembly resourceAssembly) {
                    return type == this.type ? this.key : null; 
                }
                public override void SetSavedLicenseKey(Type type, string key) {
                    if (type == this.type) {
                        this.key = key; 
                    }
                } 
            } 
        }
    } 
}

// 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