Example #1
0
 // Finish the initialization, and ensure this type is a valid component
 // for use in the add-in model.  On failure, log a message & return false.
 // Derived classes should do their own validation and then call this one.
 internal virtual bool Validate(TypeInfo type, Collection <String> warnings)
 {
     if (type.IsGeneric)
     {
         warnings.Add(String.Format(System.Globalization.CultureInfo.CurrentCulture, Res.ComponentUnusableBecauseItIsGeneric, type.Name));
         return(false);
     }
     return(true);
 }
Example #2
0
        internal AddIn(TypeInfo typeInfo, String assemblyLocation, String fullPathToAddin, String assemblyName)
            : base(typeInfo, assemblyLocation)
        {
            System.Diagnostics.Contracts.Contract.Requires(Path.IsPathRooted(fullPathToAddin));

            _fullPathToAddIn = fullPathToAddin;
            _assemblyName = assemblyName;

            _unlocalized = new ResourceState();
        }
Example #3
0
        internal AddIn(TypeInfo typeInfo, String assemblyLocation, String fullPathToAddin, String assemblyName)
            : base(typeInfo, assemblyLocation)
        {
            System.Diagnostics.Contracts.Contract.Requires(Path.IsPathRooted(fullPathToAddin));

            _fullPathToAddIn = fullPathToAddin;
            _assemblyName    = assemblyName;

            _unlocalized = new ResourceState();
        }
        internal PipelineComponent(TypeInfo typeInfo, String assemblyLocation)
        {
            if (typeInfo == null)
                throw new ArgumentNullException("typeInfo");
            if (assemblyLocation == null)
                throw new ArgumentNullException("assemblyLocation");
            System.Diagnostics.Contracts.Contract.EndContractBlock();
            
            _typeInfo = typeInfo;
            if (Path.IsPathRooted(assemblyLocation)) {
                // For FindAddIn case, we know the full location;
                _location = assemblyLocation;
                _haveSetRootDirectory = true;
            }
            else {
                _relativeLocation = assemblyLocation;
            }

            // load the qualification data, either from reflection or minireflection, as appropriate
            if (_typeInfo.HasReflectionType)
            {
                IList<CustomAttributeData> cas =CustomAttributeData.GetCustomAttributes(_typeInfo.ReflectionType); 
                Dictionary<String, String> dictionary = new Dictionary<String, String>();
                foreach (CustomAttributeData ca in cas)
                {
                    if (Object.ReferenceEquals(ca.Constructor.DeclaringType, s_QualificationDataAttrInReflectionLoaderContext))
                    {
                        IList<CustomAttributeTypedArgument> args = ca.ConstructorArguments;
                        String key = (String)args[0].Value;
                        String val = (String)args[1].Value;
                        dictionary[key] = val;
                    }
                }
                _qualificationData = dictionary.Count == 0 ? s_emptyDictionary : 
                    new ReadOnlyDictionary<String, String>(dictionary);
            }
            else
            {
                Type qualificationDataAttribute = typeof (QualificationDataAttribute);
                MiniCustomAttributeInfo[] cas = typeInfo.GetCustomAttributeInfos(qualificationDataAttribute);
                Dictionary<String, String> dictionary = new Dictionary<String, String>();
                if (cas != null && cas.Length > 0)
                {
                    foreach (MiniCustomAttributeInfo ca in cas)
                    {
                        MiniCustomAttributeFixedArgInfo[] fai = ca.FixedArgs;
                        String key = (String)fai[0].Value;
                        String val = (String)fai[1].Value;
                        dictionary[key] = val;
                    }
                }
                _qualificationData = dictionary.Count == 0 ? s_emptyDictionary : 
                    new ReadOnlyDictionary<String, String>(dictionary);
            }
        }
        private static TView ContractToViewAdapterImpl <TView>(ContractHandle contract, String pipelineRoot, bool demand)
        {
            if (contract == null)
            {
                throw new ArgumentNullException("contract");
            }
            if (pipelineRoot == null)
            {
                throw new ArgumentNullException("pipelineRoot");
            }
            if (String.IsNullOrEmpty(pipelineRoot))
            {
                throw new ArgumentException(Res.PathCantBeEmpty);
            }
            System.Diagnostics.Contracts.Contract.EndContractBlock();

            if (demand)
            {
                new FileIOPermission(FileIOPermissionAccess.Read, pipelineRoot).Demand();
            }

            Type     havType     = typeof(TView);
            TypeInfo havTypeInfo = new TypeInfo(havType);

            List <PartialToken> partialTokens = AddInStore.GetPartialTokens(pipelineRoot);

            foreach (PartialToken partialToken in partialTokens)
            {
                if (AddInStore.Contains(partialToken.HostAdapter.HostAddinViews, havTypeInfo))
                {
                    partialToken.PipelineRootDirectory = pipelineRoot;

                    //Ask for something that can implement the contract in this partial token.  The result will
                    //either be null, the addin adapter itself, or another addin adapter
                    IContract subcontract = contract.Contract.QueryContract(partialToken._contract.TypeInfo.AssemblyQualifiedName);
                    if (subcontract != null)
                    {
                        //Instantiate the adapter and pass in the addin to its constructor
                        TView hav = AddInActivator.ActivateHostAdapter <TView>(partialToken, subcontract);
                        return(hav);
                    }
                }
            }

            // Don't let the ref count go to zero too soon, before we increment it in ActivateHostAdapter
            // This is important when QueryContract returns the addIn adapter itself.  A GC at that point
            // may collect the ContractHandle and decrement the ref count to zero before we have a chance to increment it
            System.GC.KeepAlive(contract);

            // return null.  Compiler makes us return default(TView), which will be null
            return(default(TView));
        }
        internal override bool Validate(TypeInfo type, Collection<String> warnings)
        {
            _potentialHAVs = FindBaseTypesAndInterfaces(type);
            
            if (_potentialHAVs.Length == 0)
            {
                return false;
            }

            foreach (MiniConstructorInfo ci in type.GetConstructors(true))
            {
                MiniParameterInfo[] pars = ci.GetParameters();
                if (pars.Length != 1)
                {
                    warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.HostAdapterUnusableCtorMultipleParams, type.AssemblyQualifiedName));
                    continue;
                }

                TypeInfo paramType = pars[0].ParameterType;
                bool success = false;
                try
                {
                    if (paramType.IsInterface && (paramType.Implements(typeofIContract)))
                    {
                        _constructors.Add(paramType);
                        success = true;
                    }
                }
                catch (FileNotFoundException) { }
                catch (FileLoadException)
                {
                    // Can happen for a constructor taking a type that isn't in mscorlib nor System.AddIn.Contract, and
                    // also isn't in any of the directories that we would probe.
                }
                if (!success)
                {
                    warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.HostAdapterUnusableCtorBadParam, type.AssemblyQualifiedName, paramType.FullName));
                    continue;
                }
            }
            if (_constructors.Count == 0)
            {
                warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.HostAdapterNoValidCtors, type.AssemblyQualifiedName));
                return false;
            }

            return base.Validate(type, warnings);
        }
        internal override bool Validate(TypeInfo type, Collection <String> warnings)
        {
            _potentialHAVs = FindBaseTypesAndInterfaces(type);

            if (_potentialHAVs.Length == 0)
            {
                return(false);
            }

            foreach (MiniConstructorInfo ci in type.GetConstructors(true))
            {
                MiniParameterInfo[] pars = ci.GetParameters();
                if (pars.Length != 1)
                {
                    warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.HostAdapterUnusableCtorMultipleParams, type.AssemblyQualifiedName));
                    continue;
                }

                TypeInfo paramType = pars[0].ParameterType;
                bool     success   = false;
                try
                {
                    if (paramType.IsInterface && (paramType.Implements(typeofIContract)))
                    {
                        _constructors.Add(paramType);
                        success = true;
                    }
                }
                catch (FileNotFoundException) { }
                catch (FileLoadException)
                {
                    // Can happen for a constructor taking a type that isn't in mscorlib nor System.AddIn.Contract, and
                    // also isn't in any of the directories that we would probe.
                }
                if (!success)
                {
                    warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.HostAdapterUnusableCtorBadParam, type.AssemblyQualifiedName, paramType.FullName));
                    continue;
                }
            }
            if (_constructors.Count == 0)
            {
                warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.HostAdapterNoValidCtors, type.AssemblyQualifiedName));
                return(false);
            }

            return(base.Validate(type, warnings));
        }
Example #8
0
        internal static TypeInfo[] FindBaseTypesAndInterfaces(TypeInfo type)
        {
            TypeInfo        currentTypeInfo = type;
            TypeInfo        objectType      = new TypeInfo(typeof(Object));
            List <TypeInfo> infos           = new List <TypeInfo>();

            try
            {
                //we walk up the hierarchy as far as we can until we can't
                //get the types anymore...
                while (!currentTypeInfo.Equals(objectType))
                {
                    // To get the base type and interfaces, we will need to resolve a TypeRef to a TypeDef first
                    currentTypeInfo = currentTypeInfo.TryGetTypeDef();
                    if (currentTypeInfo != null)
                    {
                        TypeInfo[] interfaces = currentTypeInfo.GetInterfaces();
                        if (interfaces != null)
                        {
                            infos.AddRange(interfaces);
                        }

                        TypeInfo baseType = currentTypeInfo.BaseType;
                        infos.Add(baseType);
                        currentTypeInfo = baseType;
                    }
                    else
                    {
                        // we have reached the limit of what we can resolve in the addin/hostadapter's folder
                        break;
                    }
                }
            }
            catch (GenericsNotImplementedException)
            {
                // Since GetInterfaces() ignores all generic interfaces, we'll only come here if we encounter a generic base class.
                // We'll ignore the generic base class and return whatever bases we found earlier.
            }

            return(infos.ToArray());
        }
 internal bool CanDirectConnectTo(TypeInfo havTypeInfo)
 {
     bool result = false;
     
     if(havTypeInfo.Equals(TypeInfo))
     {
         // Check the add-in base's type info.
         result = true;
     }
     else if(_activatableAs != null)  
     {
         // Check the ActivatableAs types.
         for(int i = 0; i < _activatableAs.Length && result == false; i++)
         {
             if(_activatableAs[i].Equals(havTypeInfo))
             {
                 result = true;
             }
         }
     }
     
     return result;
 }
Example #10
0
        internal bool CanDirectConnectTo(TypeInfo havTypeInfo)
        {
            bool result = false;

            if (havTypeInfo.Equals(TypeInfo))
            {
                // Check the add-in base's type info.
                result = true;
            }
            else if (_activatableAs != null)
            {
                // Check the ActivatableAs types.
                for (int i = 0; i < _activatableAs.Length && result == false; i++)
                {
                    if (_activatableAs[i].Equals(havTypeInfo))
                    {
                        result = true;
                    }
                }
            }

            return(result);
        }
 public HostAdapter(TypeInfo typeInfo, String assemblyLocation)
     : base(typeInfo, assemblyLocation)
 {
     _constructors = new List<TypeInfo>();
 }
        internal static TypeInfo[] FindBaseTypesAndInterfaces(TypeInfo type)
        {
            TypeInfo currentTypeInfo = type;
            TypeInfo objectType = new TypeInfo(typeof(Object));
            List<TypeInfo> infos = new List<TypeInfo>();

            try
            {
                //we walk up the hierarchy as far as we can until we can't
                //get the types anymore...
                while (!currentTypeInfo.Equals(objectType))
                {
                    // To get the base type and interfaces, we will need to resolve a TypeRef to a TypeDef first
                    currentTypeInfo = currentTypeInfo.TryGetTypeDef();
                    if (currentTypeInfo != null)
                    {
                        TypeInfo[] interfaces = currentTypeInfo.GetInterfaces();
                        if (interfaces != null)
                            infos.AddRange(interfaces);

                        TypeInfo baseType = currentTypeInfo.BaseType;
                        infos.Add(baseType);
                        currentTypeInfo = baseType;
                    }
                    else
                    {
                        // we have reached the limit of what we can resolve in the addin/hostadapter's folder
                        break;
                    }
                }
            }
            catch (GenericsNotImplementedException) 
            {
                // Since GetInterfaces() ignores all generic interfaces, we'll only come here if we encounter a generic base class.
                // We'll ignore the generic base class and return whatever bases we found earlier.
            }

            return infos.ToArray();
        }
Example #13
0
 public AddInBase(TypeInfo typeInfo, TypeInfo[] activatableAs, String assemblyLocation, String assemblyName) : base(typeInfo, assemblyLocation)
 {
     _activatableAs = activatableAs;
     _assemblyName = assemblyName;
 }
        internal InspectionResults Inspect(PipelineComponentType componentType, string assemblyFileName, string pipelineRootDirectory)
        {
            System.Diagnostics.Contracts.Contract.Requires(assemblyFileName != null);
            System.Diagnostics.Contracts.Contract.Requires(pipelineRootDirectory != null);

            _assemblyFileName      = assemblyFileName;
            _pipelineRootDirectory = pipelineRootDirectory;

            // Set up the assembly resolve event.
            _currentComponentType = componentType;
            ResolveEventHandler assemblyResolver = new ResolveEventHandler(ResolveAssembly);

            AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += assemblyResolver;

            InspectionResults retval = new InspectionResults();

            retval.Components = new List <PipelineComponent>();
            retval.Warnings   = new Collection <String>();
            Type[] publicTypes;
            String assemblyName = null;

            // Need to assert again here because we are in a new appdomain
            FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.PathDiscovery |
                                                               FileIOPermissionAccess.Read, _pipelineRootDirectory);

            permission.Assert();

            try
            {
                // We want to load the assembly WITHOUT REGARD OF PUBLISHER POLICY.
                // If the directory structure contains v1.0 of a component and v1.1
                // exists in the GAC and is a security fix to v1.0, we still want to
                // inspect v1.0.  (The reason is we have other parts of the
                // pipeline that were likely compiled against v1.0, not v1.1, and
                // we do type comparisons by comparing the fully qualified assembly
                // name.)  LoadFrom unfortunately respects policy.  Assembly's
                // ReflectionOnlyLoad(byte[]) doesn't.  ReflectionOnlyLoadFrom(String)
                // does respect policy if you've set DEVPATH, but only as a bug.
                // We don't think setting DEVPATH is interesting.
                Assembly a = Assembly.ReflectionOnlyLoadFrom(_assemblyFileName);
                publicTypes  = a.GetTypes();
                assemblyName = a.FullName;
            }
            catch (FileNotFoundException fnf)
            {
                retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.AssemblyLoadFileNotFound, fnf.Message, fnf.FileName));
                return(retval);
            }
            catch (Exception e)
            {
                retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.AssemblyLoadThrew, e.GetType().Name, e.Message, _assemblyFileName));
                return(retval);
            }
            PipelineComponent component = null;

            String relativeFileName = Utils.MakeRelativePath(_assemblyFileName, _pipelineRootDirectory);
            Type   lastType         = null;

            try
            {
                // Iterate over public types, looking for the appropriate custom attributes.
                foreach (Type type in publicTypes)
                {
                    component = null;
                    lastType  = type;
                    switch (componentType)
                    {
                    case PipelineComponentType.Contract:
                        if (!Utils.HasCustomAttribute(PipelineComponent.ContractAttributeInReflectionLoaderContext, type))
                        {
                            continue;
                        }

                        component = new ContractComponent(new TypeInfo(type), relativeFileName);
                        break;

                    case PipelineComponentType.AddInAdapter:
                        if (!Utils.HasCustomAttribute(PipelineComponent.AddInAdapterAttributeInReflectionLoaderContext, type))
                        {
                            continue;
                        }

                        component = new AddInAdapter(new TypeInfo(type), relativeFileName);
                        break;

                    case PipelineComponentType.AddInBase:
                        if (Utils.HasCustomAttribute(PipelineComponent.AddInAttributeInReflectionLoaderContext, type))
                        {
                            retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.AddInInAddInViewFolder, type.Name, _assemblyFileName));
                        }

                        if (!Utils.HasCustomAttribute(PipelineComponent.AddInBaseAttributeInReflectionLoaderContext, type))
                        {
                            continue;
                        }

                        TypeInfo[]          activatableAs = null;
                        CustomAttributeData cad           = Utils.GetCustomAttributeData(PipelineComponent.AddInBaseAttributeInReflectionLoaderContext, type);
                        foreach (CustomAttributeNamedArgument cana in cad.NamedArguments)
                        {
                            if (cana.MemberInfo.Name == "ActivatableAs")
                            {
                                CustomAttributeTypedArgument arg = cana.TypedValue;
                                ReadOnlyCollection <CustomAttributeTypedArgument> types = (ReadOnlyCollection <CustomAttributeTypedArgument>)arg.Value;
                                activatableAs = new TypeInfo[types.Count];
                                int i = 0;
                                foreach (CustomAttributeTypedArgument subArg in types)
                                {
                                    activatableAs[i++] = new TypeInfo((Type)subArg.Value);
                                }
                            }
                        }

                        component = new AddInBase(new TypeInfo(type), activatableAs, relativeFileName, assemblyName);

                        break;

                    default:
                        System.Diagnostics.Contracts.Contract.Assert(false, "Fell through switch - unrecognized componentType in InspectionWorker.Inspect");
                        break;
                    }  // switch

                    // If we found a component, make sure it satisfies all of its constraints, and give our
                    // PipelineComponents a chance to initialize state.
                    if (component != null)
                    {
                        if (component.Validate(type, retval.Warnings))
                        {
                            retval.Components.Add(component);
                        }
                    }
                } // foreach type in the assembly
            }     // try
            catch (FileNotFoundException fnf)
            {
                retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.AssemblyLoadFileNotFound, fnf.Message, fnf.FileName));
                return(retval);
            }
            catch (NotImplementedException)
            {
                retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.NotImplementedFeatureBadCtorParamOrAssembly,
                                                  _assemblyFileName, (lastType == null) ? "" : lastType.FullName));
                return(retval);
            }
            catch (Exception e)
            {
                retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.InspectingAssemblyThrew, e.GetType().Name, e.Message, _assemblyFileName));
                return(retval);
            }

            AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve -= assemblyResolver;

            if (retval.Components.Count == 0 && _currentComponentType != PipelineComponentType.AddIn && _currentComponentType != PipelineComponentType.AddInBase)
            {
                retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.NoAddInModelPartsFound, componentType, _assemblyFileName));
            }
#if ADDIN_VERBOSE_WARNINGS
            foreach (PipelineComponent c in retval.Components)
            {
                retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, "Found a {0}.  Name: {1}  Assembly: {2}", componentType, c.SimpleName, c.AssemblySimpleName));
            }
#endif
            return(retval);
        }
Example #15
0
        //Validate the addin. Also fill in the base class and interfaces.
        internal override bool Validate(TypeInfo type, Collection<String> warnings)
        {
            Type addInAttributeType = typeof(AddInAttribute);
            // Get the AddInAttribute, if available.  It is not required in the FindAddIn case.
            MiniCustomAttributeInfo[] attributes = type.GetCustomAttributeInfos(addInAttributeType);
            if (attributes.Length > 0)
            {
                MiniCustomAttributeInfo addInAttribute = attributes[0];

                _unlocalized.Name = (String)addInAttribute.FixedArgs[0].Value;
                foreach (MiniCustomAttributeNamedArgInfo namedArg in addInAttribute.NamedArgs)
                {
                    switch (namedArg.Name)
                    {
                        case "Description":
                            _unlocalized.Description = (String)namedArg.Value;
                        break;
                        case "Version":
                            _version = (String)namedArg.Value;
                        break;
                        case "Publisher":
                            _unlocalized.Publisher = (String)namedArg.Value;
                        break;
                        default:
                            warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.UnknownNamedAddInAttributeParameter, namedArg.Name, type.FullName, type.Assembly.ModuleName));
                        break;
                    }
                }
            }
            
            if (String.IsNullOrEmpty(_unlocalized.Name))
            {
                warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.AddInMustSpecifyName, type.FullName, type.Assembly.ModuleName));
                return false;
            }

            /* 
            // Parse and validate the custom attribute on this type.
            foreach (CustomAttributeData attr in CustomAttributeData.GetCustomAttributes(type)) {
                if (attr.Constructor.DeclaringType == PipelineComponent.AddInAttributeInReflectionLoaderContext) {
                    if (attr.ConstructorArguments.Count == 1) {
                        _unlocalized.Name = (String)attr.ConstructorArguments[0].Value;
                        if (String.IsNullOrEmpty(_unlocalized.Name)) {
                            warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.AddInMustSpecifyName, type.FullName, type.Assembly.Location));
                            return false;
                        }
                    }
#if LOCALIZABLE_ADDIN_ATTRIBUTE
                    else if (attr.ConstructorArguments.Count == 2) {
                        _resMgrBaseName = (String)attr.ConstructorArguments[0].Value;
                        _nameResource = (String)attr.ConstructorArguments[1].Value;
                        if (String.IsNullOrEmpty(_resMgrBaseName)) {
                            warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.MustSpecifyResMgrBaseName, type.FullName, type.Assembly.Location));
                            return false;
                        }
                        if (String.IsNullOrEmpty(_nameResource)) {
                            warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.MustSpecifyResourceName, type.FullName, type.Assembly.Location));
                            return false;
                        }
                    }
#endif  // LOCALIZABLE_ADDIN_ATTRIBUTE
                    else {
                        System.Diagnostics.Contracts.Contract.Assert(false, "Unknown number of custom attribute constructor parameters");
                    }
                    foreach (CustomAttributeNamedArgument arg in attr.NamedArguments) {
                        if (arg.MemberInfo.Name == "Publisher")
                            _unlocalized.Publisher = (String)arg.TypedValue.Value;
                        else if (arg.MemberInfo.Name == "Version")
                            _version = (String)arg.TypedValue.Value;
                        else if (arg.MemberInfo.Name == "Description")
                            _unlocalized.Description = (String)arg.TypedValue.Value;
#if LOCALIZABLE_ADDIN_ATTRIBUTE
                        else if (arg.MemberInfo.Name == "PublisherResourceName")
                            _publisherResource = (String)arg.TypedValue.Value;
                        else if (arg.MemberInfo.Name == "DescriptionResourceName")
                            _descriptionResource = (String)arg.TypedValue.Value;
#endif
                        else {
                            System.Diagnostics.Contracts.Contract.Assert(false, "Unknown named parameter to AddInAttribute: " + arg.MemberInfo.Name);
                            warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.UnknownNamedAddInAttributeParameter, arg.MemberInfo.Name, type.FullName, type.Assembly.Location));
                            // Let's ignore this - this shouldn't be fatal.
                        }
                    }
                    break;
                }
            }
            */

            // Check for a public default constructor
            bool found = false;
            foreach (MiniConstructorInfo ci in type.GetConstructors()) {
                MiniParameterInfo[] pars = ci.GetParameters();
                if (pars.Length == 0) {
                    found = true;
                    break;
                }
            }
            
            if (!found)
            {
                warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.NoDefaultConstructor, type.FullName, type.Assembly.ModuleName));
                return false;
            }

            _potentialAddinBases = FindBaseTypesAndInterfaces(type);
            
            if(_potentialAddinBases.Length == 0)
            {
                return false;
            }


#if LOCALIZABLE_ADDIN_ATTRIBUTE
            if (ContainsLocalizableStrings) {
                _localizedResources = ResourceProvider.LookupResourcesInCurrentDomain(_fullPathToAddIn,
                    _resMgrBaseName, _nameResource, _publisherResource, _descriptionResource);
            }
#endif
            return base.Validate(type, warnings);
        }
 public HostAdapter(TypeInfo typeInfo, String assemblyLocation)
     : base(typeInfo, assemblyLocation)
 {
     _constructors = new List <TypeInfo>();
 }
Example #17
0
 public AddInBase(TypeInfo typeInfo, TypeInfo[] activatableAs, String assemblyLocation, String assemblyName) : base(typeInfo, assemblyLocation)
 {
     _activatableAs = activatableAs;
     _assemblyName  = assemblyName;
 }
Example #18
0
        internal PipelineComponent(TypeInfo typeInfo, String assemblyLocation)
        {
            if (typeInfo == null)
            {
                throw new ArgumentNullException("typeInfo");
            }
            if (assemblyLocation == null)
            {
                throw new ArgumentNullException("assemblyLocation");
            }
            System.Diagnostics.Contracts.Contract.EndContractBlock();

            _typeInfo = typeInfo;
            if (Path.IsPathRooted(assemblyLocation))
            {
                // For FindAddIn case, we know the full location;
                _location             = assemblyLocation;
                _haveSetRootDirectory = true;
            }
            else
            {
                _relativeLocation = assemblyLocation;
            }

            // load the qualification data, either from reflection or minireflection, as appropriate
            if (_typeInfo.HasReflectionType)
            {
                IList <CustomAttributeData> cas        = CustomAttributeData.GetCustomAttributes(_typeInfo.ReflectionType);
                Dictionary <String, String> dictionary = new Dictionary <String, String>();
                foreach (CustomAttributeData ca in cas)
                {
                    if (Object.ReferenceEquals(ca.Constructor.DeclaringType, s_QualificationDataAttrInReflectionLoaderContext))
                    {
                        IList <CustomAttributeTypedArgument> args = ca.ConstructorArguments;
                        String key = (String)args[0].Value;
                        String val = (String)args[1].Value;
                        dictionary[key] = val;
                    }
                }
                _qualificationData = dictionary.Count == 0 ? s_emptyDictionary :
                                     new ReadOnlyDictionary <String, String>(dictionary);
            }
            else
            {
                Type qualificationDataAttribute        = typeof(QualificationDataAttribute);
                MiniCustomAttributeInfo[]   cas        = typeInfo.GetCustomAttributeInfos(qualificationDataAttribute);
                Dictionary <String, String> dictionary = new Dictionary <String, String>();
                if (cas != null && cas.Length > 0)
                {
                    foreach (MiniCustomAttributeInfo ca in cas)
                    {
                        MiniCustomAttributeFixedArgInfo[] fai = ca.FixedArgs;
                        String key = (String)fai[0].Value;
                        String val = (String)fai[1].Value;
                        dictionary[key] = val;
                    }
                }
                _qualificationData = dictionary.Count == 0 ? s_emptyDictionary :
                                     new ReadOnlyDictionary <String, String>(dictionary);
            }
        }
Example #19
0
        private static T ActivateInAppDomain <T>(AddInToken pipeline, AppDomain domain, AddInControllerImpl controller, bool weOwn)
        {
            ContractComponent contract    = pipeline._contract;
            HostAdapter       hostAdapter = pipeline._hostAdapter;

            bool usingHostAppDomain = domain == AppDomain.CurrentDomain;

            //begin direct connect code
            if (AddInToken.EnableDirectConnect && !weOwn && usingHostAppDomain)
            {
                Type     havType     = typeof(T);
                TypeInfo havTypeInfo = new TypeInfo(havType);

                if (pipeline._addinBase.CanDirectConnectTo(havTypeInfo))
                {
                    // Connect directly for best performance.
                    // Assert permission to the specific Addin directory only.
                    PermissionSet permissionSet = new PermissionSet(PermissionState.None);
                    permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery,
                                                                     Path.GetDirectoryName(pipeline._addin.Location)));
                    permissionSet.Assert();

                    Assembly addInAssembly = Assembly.LoadFrom(pipeline._addin.Location);
                    //
                    Type   addinType = addInAssembly.GetType(pipeline._addin.TypeInfo.FullName, true);
                    Object addIn     = addinType.GetConstructor(new Type[0]).Invoke(new Object[0]);
                    System.Diagnostics.Contracts.Contract.Assert(addIn != null, "Bypass couldn't create the add-in");

                    // remember the addin directly as the HAV.  Set the contract to null.
                    controller.AssociateWithHostAddinView(addIn, null);

                    return((T)addIn);
                }
            }
            //end direct connect code

            // Use Activator.CreateInstance instead of AppDomain.CreateInstanceAndUnwrap
            // because Activator will do the appropriate security asserts in the
            // remote appdomain.
            Type t = typeof(ActivationWorker);

            Object[]     args      = new Object[] { pipeline };
            ObjectHandle objHandle = Activator.CreateInstance(domain, t.Assembly.FullName, t.FullName,
                                                              false, BindingFlags.Instance | BindingFlags.NonPublic, null,
                                                              args, null, null);
            ActivationWorker activationWorker = (ActivationWorker)objHandle.Unwrap();

            activationWorker.UsingHostAppDomain = usingHostAppDomain;

            System.AddIn.Contract.IContract addInContract = null;
            try
            {
                addInContract = activationWorker.Activate();
            }
            catch (Exception ex)
            {
                CheckForDuplicateAssemblyProblems(pipeline, ex);
                throw;
            }

            if (weOwn)
            {
                domain.SetData(ContractHandle.s_appDomainOwner, addInContract);
            }

            controller.ActivationWorker = activationWorker;
            T hav = AdaptToHost <T>(pipeline, addInContract);

            controller.AssociateWithHostAddinView(hav, addInContract);

            return(hav);
        }
 // Finish the initialization, and ensure this type is a valid component
 // for use in the add-in model.  On failure, log a message & return false.
 // Derived classes should do their own validation and then call this one.
 internal virtual bool Validate(TypeInfo type, Collection<String> warnings)
 {
     if (type.IsGeneric)
     {
         warnings.Add(String.Format(System.Globalization.CultureInfo.CurrentCulture, Res.ComponentUnusableBecauseItIsGeneric, type.Name));
         return false;
     }
     return true;
 }
        internal InspectionResults Inspect(PipelineComponentType componentType, string assemblyFileName, string pipelineRootDirectory)
        {
            System.Diagnostics.Contracts.Contract.Requires(assemblyFileName != null);
            System.Diagnostics.Contracts.Contract.Requires(pipelineRootDirectory != null);

            _assemblyFileName = assemblyFileName;
            _pipelineRootDirectory = pipelineRootDirectory;

            // Set up the assembly resolve event.
            _currentComponentType = componentType;
            ResolveEventHandler assemblyResolver = new ResolveEventHandler(ResolveAssembly);
            AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += assemblyResolver;

            InspectionResults retval = new InspectionResults();
            retval.Components = new List<PipelineComponent>();
            retval.Warnings = new Collection<String>();
            Type[] publicTypes;
            String assemblyName = null;

            // Need to assert again here because we are in a new appdomain
            FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.PathDiscovery |
                    FileIOPermissionAccess.Read, _pipelineRootDirectory);
            permission.Assert();

            try
            {
                // We want to load the assembly WITHOUT REGARD OF PUBLISHER POLICY.
                // If the directory structure contains v1.0 of a component and v1.1
                // exists in the GAC and is a security fix to v1.0, we still want to
                // inspect v1.0.  (The reason is we have other parts of the 
                // pipeline that were likely compiled against v1.0, not v1.1, and
                // we do type comparisons by comparing the fully qualified assembly 
                // name.)  LoadFrom unfortunately respects policy.  Assembly's
                // ReflectionOnlyLoad(byte[]) doesn't.  ReflectionOnlyLoadFrom(String)
                // does respect policy if you've set DEVPATH, but only as a bug.
                // We don't think setting DEVPATH is interesting.
                Assembly a = Assembly.ReflectionOnlyLoadFrom(_assemblyFileName);
                publicTypes = a.GetTypes();
                assemblyName = a.FullName;
            }
            catch (FileNotFoundException fnf)
            {
                retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.AssemblyLoadFileNotFound, fnf.Message, fnf.FileName));
                return retval;
            }
            catch (Exception e)
            {
                retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.AssemblyLoadThrew, e.GetType().Name, e.Message, _assemblyFileName));
                return retval;
            }
            PipelineComponent component = null;

            String relativeFileName = Utils.MakeRelativePath(_assemblyFileName, _pipelineRootDirectory);
            Type lastType = null;
            try
            {
                // Iterate over public types, looking for the appropriate custom attributes.
                foreach (Type type in publicTypes)
                {
                    component = null;
                    lastType = type;
                    switch (componentType)
                    {
                        case PipelineComponentType.Contract:
                            if (!Utils.HasCustomAttribute(PipelineComponent.ContractAttributeInReflectionLoaderContext, type))
                                continue;

                            component = new ContractComponent(new TypeInfo(type), relativeFileName);
                            break;

                        case PipelineComponentType.AddInAdapter:
                            if (!Utils.HasCustomAttribute(PipelineComponent.AddInAdapterAttributeInReflectionLoaderContext, type))
                                continue;

                            component = new AddInAdapter(new TypeInfo(type), relativeFileName);
                            break;

                        case PipelineComponentType.AddInBase:
                            if (Utils.HasCustomAttribute(PipelineComponent.AddInAttributeInReflectionLoaderContext, type))
                                retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.AddInInAddInViewFolder, type.Name, _assemblyFileName));

                            if (!Utils.HasCustomAttribute(PipelineComponent.AddInBaseAttributeInReflectionLoaderContext, type))
                                continue;

                            TypeInfo[] activatableAs = null;
                            CustomAttributeData cad = Utils.GetCustomAttributeData(PipelineComponent.AddInBaseAttributeInReflectionLoaderContext, type);
                            foreach(CustomAttributeNamedArgument cana in cad.NamedArguments)
                            {
                                if (cana.MemberInfo.Name == "ActivatableAs")
                                {
                                    CustomAttributeTypedArgument arg = cana.TypedValue;
                                    ReadOnlyCollection<CustomAttributeTypedArgument> types = (ReadOnlyCollection<CustomAttributeTypedArgument>)arg.Value;
                                    activatableAs = new TypeInfo[types.Count];
                                    int i = 0;
                                    foreach (CustomAttributeTypedArgument subArg in types)
                                    {
                                        activatableAs[i++] = new TypeInfo((Type)subArg.Value);
                                    }
                                }
                            }

                            component = new AddInBase(new TypeInfo(type), activatableAs, relativeFileName, assemblyName);

                            break;

                        default:
                            System.Diagnostics.Contracts.Contract.Assert(false, "Fell through switch - unrecognized componentType in InspectionWorker.Inspect");
                            break;
                    }  // switch

                    // If we found a component, make sure it satisfies all of its constraints, and give our
                    // PipelineComponents a chance to initialize state.
                    if (component != null)
                    {
                        if (component.Validate(type, retval.Warnings))
                            retval.Components.Add(component);
                    }
                } // foreach type in the assembly
            } // try
            catch (FileNotFoundException fnf)
            {
                retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.AssemblyLoadFileNotFound, fnf.Message, fnf.FileName));
                return retval;
            }
            catch (NotImplementedException)
            {
                retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.NotImplementedFeatureBadCtorParamOrAssembly, 
                    _assemblyFileName, (lastType == null) ? "" : lastType.FullName));
                return retval;
            }
            catch (Exception e)
            {
                retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.InspectingAssemblyThrew, e.GetType().Name, e.Message, _assemblyFileName));
                return retval;
            }

            AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve -= assemblyResolver;

            if (retval.Components.Count == 0 && _currentComponentType != PipelineComponentType.AddIn && _currentComponentType != PipelineComponentType.AddInBase)
            {
                retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.NoAddInModelPartsFound, componentType, _assemblyFileName));
            }
#if ADDIN_VERBOSE_WARNINGS
            foreach (PipelineComponent c in retval.Components)
                retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, "Found a {0}.  Name: {1}  Assembly: {2}", componentType, c.SimpleName, c.AssemblySimpleName));
#endif
            return retval;
        }
Example #22
0
        //Validate the addin. Also fill in the base class and interfaces.
        internal override bool Validate(TypeInfo type, Collection <String> warnings)
        {
            Type addInAttributeType = typeof(AddInAttribute);

            // Get the AddInAttribute, if available.  It is not required in the FindAddIn case.
            MiniCustomAttributeInfo[] attributes = type.GetCustomAttributeInfos(addInAttributeType);
            if (attributes.Length > 0)
            {
                MiniCustomAttributeInfo addInAttribute = attributes[0];

                _unlocalized.Name = (String)addInAttribute.FixedArgs[0].Value;
                foreach (MiniCustomAttributeNamedArgInfo namedArg in addInAttribute.NamedArgs)
                {
                    switch (namedArg.Name)
                    {
                    case "Description":
                        _unlocalized.Description = (String)namedArg.Value;
                        break;

                    case "Version":
                        _version = (String)namedArg.Value;
                        break;

                    case "Publisher":
                        _unlocalized.Publisher = (String)namedArg.Value;
                        break;

                    default:
                        warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.UnknownNamedAddInAttributeParameter, namedArg.Name, type.FullName, type.Assembly.ModuleName));
                        break;
                    }
                }
            }

            if (String.IsNullOrEmpty(_unlocalized.Name))
            {
                warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.AddInMustSpecifyName, type.FullName, type.Assembly.ModuleName));
                return(false);
            }

            /*
             * // Parse and validate the custom attribute on this type.
             * foreach (CustomAttributeData attr in CustomAttributeData.GetCustomAttributes(type)) {
             *  if (attr.Constructor.DeclaringType == PipelineComponent.AddInAttributeInReflectionLoaderContext) {
             *      if (attr.ConstructorArguments.Count == 1) {
             *          _unlocalized.Name = (String)attr.ConstructorArguments[0].Value;
             *          if (String.IsNullOrEmpty(_unlocalized.Name)) {
             *              warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.AddInMustSpecifyName, type.FullName, type.Assembly.Location));
             *              return false;
             *          }
             *      }
             #if LOCALIZABLE_ADDIN_ATTRIBUTE
             *      else if (attr.ConstructorArguments.Count == 2) {
             *          _resMgrBaseName = (String)attr.ConstructorArguments[0].Value;
             *          _nameResource = (String)attr.ConstructorArguments[1].Value;
             *          if (String.IsNullOrEmpty(_resMgrBaseName)) {
             *              warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.MustSpecifyResMgrBaseName, type.FullName, type.Assembly.Location));
             *              return false;
             *          }
             *          if (String.IsNullOrEmpty(_nameResource)) {
             *              warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.MustSpecifyResourceName, type.FullName, type.Assembly.Location));
             *              return false;
             *          }
             *      }
             #endif  // LOCALIZABLE_ADDIN_ATTRIBUTE
             *      else {
             *          System.Diagnostics.Contracts.Contract.Assert(false, "Unknown number of custom attribute constructor parameters");
             *      }
             *      foreach (CustomAttributeNamedArgument arg in attr.NamedArguments) {
             *          if (arg.MemberInfo.Name == "Publisher")
             *              _unlocalized.Publisher = (String)arg.TypedValue.Value;
             *          else if (arg.MemberInfo.Name == "Version")
             *              _version = (String)arg.TypedValue.Value;
             *          else if (arg.MemberInfo.Name == "Description")
             *              _unlocalized.Description = (String)arg.TypedValue.Value;
             #if LOCALIZABLE_ADDIN_ATTRIBUTE
             *          else if (arg.MemberInfo.Name == "PublisherResourceName")
             *              _publisherResource = (String)arg.TypedValue.Value;
             *          else if (arg.MemberInfo.Name == "DescriptionResourceName")
             *              _descriptionResource = (String)arg.TypedValue.Value;
             #endif
             *          else {
             *              System.Diagnostics.Contracts.Contract.Assert(false, "Unknown named parameter to AddInAttribute: " + arg.MemberInfo.Name);
             *              warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.UnknownNamedAddInAttributeParameter, arg.MemberInfo.Name, type.FullName, type.Assembly.Location));
             *              // Let's ignore this - this shouldn't be fatal.
             *          }
             *      }
             *      break;
             *  }
             * }
             */

            // Check for a public default constructor
            bool found = false;

            foreach (MiniConstructorInfo ci in type.GetConstructors())
            {
                MiniParameterInfo[] pars = ci.GetParameters();
                if (pars.Length == 0)
                {
                    found = true;
                    break;
                }
            }

            if (!found)
            {
                warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.NoDefaultConstructor, type.FullName, type.Assembly.ModuleName));
                return(false);
            }

            _potentialAddinBases = FindBaseTypesAndInterfaces(type);

            if (_potentialAddinBases.Length == 0)
            {
                return(false);
            }


#if LOCALIZABLE_ADDIN_ATTRIBUTE
            if (ContainsLocalizableStrings)
            {
                _localizedResources = ResourceProvider.LookupResourcesInCurrentDomain(_fullPathToAddIn,
                                                                                      _resMgrBaseName, _nameResource, _publisherResource, _descriptionResource);
            }
#endif
            return(base.Validate(type, warnings));
        }
 public AddInAdapter(TypeInfo typeInfo, String assemblyLocation) : base(typeInfo, assemblyLocation)
 {
     _contracts    = new List <TypeInfo>();
     _constructors = new List <TypeInfo>();
 }
 public AddInAdapter(TypeInfo typeInfo, String assemblyLocation) : base(typeInfo, assemblyLocation)
 {
     _contracts = new List<TypeInfo>();
     _constructors = new List<TypeInfo>();
 }