Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / AddIn / AddIn / System / Addin / Hosting / ActivationWorker.cs / 1305376 / ActivationWorker.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================ ** ** Class: ActivationWorker ** ** Purpose: Created in the remote AppDomain, this worker is ** used to start up & shut down the add-in. ** ===========================================================*/ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Security; using System.Security.Permissions; using System.Diagnostics.Contracts; namespace System.AddIn.Hosting { internal sealed class ActivationWorker : MarshalByRefObject, IDisposable { private AddInToken _pipeline; private ResolveEventHandler _assemblyResolver; private PipelineComponentType _currentComponentType; private bool _usingHostAppDomain; internal ActivationWorker(AddInToken pipeline) { System.Diagnostics.Contracts.Contract.Requires(pipeline != null); System.Diagnostics.Contracts.Contract.Requires(pipeline.PipelineRootDirectory != null); _pipeline = pipeline; } //// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification="Reviewed")] [System.Security.SecuritySafeCritical] public void Dispose() { if (_assemblyResolver != null) { AppDomain.CurrentDomain.AssemblyResolve -= _assemblyResolver; _assemblyResolver = null; } } // Don't let this object time out in Remoting. We need this object to be // alive until we clean up the appdomain, and we want to unhook our assembly // resolve event. public override Object InitializeLifetimeService() { return null; } internal bool UsingHostAppDomain { set { _usingHostAppDomain = value; } } // This method should return System.AddIn.Contract.IContract, instead of Object. This gives // Remoting half a chance at setting up the transparent proxy to contain // the appropriate interface method table. Then, hopefully Reflection // is built to check that interface method table first. (hopefully.) //// // [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification="Reviewed"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification="Reviewed"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom", Justification="LoadFrom was explicitly designed for addin loading")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2128:SecurityTransparentCodeShouldNotAssert", Justification = "This is a SecurityRules.Level1 assembly, in which this rule is being incorrectly applied")] [System.Security.SecuritySafeCritical] internal System.AddIn.Contract.IContract Activate() { // Assert permission to the contracts, AddInSideAdapters, AddInViews and specific Addin directories only. PermissionSet permissionSet = new PermissionSet(PermissionState.None); permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, Path.Combine(_pipeline.PipelineRootDirectory, AddInStore.ContractsDirName))); permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, Path.Combine(_pipeline.PipelineRootDirectory, AddInStore.AddInAdaptersDirName))); permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, Path.Combine(_pipeline.PipelineRootDirectory, AddInStore.AddInBasesDirName))); permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, Path.GetDirectoryName(_pipeline._addin.Location))); permissionSet.Assert(); // Let's be very deliberate about loading precisely the components we want, // instead of relying on an assembly resolve event. We may still need the // resolve event, but let's ensure we load the right files from the right // places in the right loader contexts. Assembly.LoadFrom(_pipeline._contract.Location); // only load the AddInBase in the LoadFrom context if there is no copy // of the assembly loaded already in the Load context. Otherwise there would be an InvalidCastException // when returning it to the host in the single appdomain, non direct-connect scenario, when // the HVA assembly is also used as the AddInBase assembly. // Since the reflection call to determine whether the assembly is loaded is expensive, only // do it when we are in the single-appdomain scenario. bool alreadyPresent = false; if (_usingHostAppDomain) alreadyPresent = IsAssemblyLoaded(_pipeline._addinBase._assemblyName); if (!alreadyPresent) Assembly.LoadFrom(_pipeline._addinBase.Location); Assembly addInAssembly = Assembly.LoadFrom(_pipeline._addin.Location); Assembly addinAdapterAssembly = Assembly.LoadFrom(_pipeline._addinAdapter.Location); CodeAccessPermission.RevertAssert(); // Create instances of all the interesting objects. // Either we don't need this here, or it may need to exist for the duration of // the add-in's lifetime. // // The assembly resolve event will be removed when the addin // controller's Shutdown method is run. _assemblyResolver = new ResolveEventHandler(ResolveAssembly); AppDomain.CurrentDomain.AssemblyResolve += _assemblyResolver; // Create the AddIn _currentComponentType = PipelineComponentType.AddIn; 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, "CreateInstance didn't create the add-in"); return CreateAddInAdapter(addIn, addinAdapterAssembly); } // Return true if the assembly of the given name has already been loaded, perhaps // from a different path. [System.Security.SecuritySafeCritical] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2128:SecurityTransparentCodeShouldNotAssert", Justification = "This is a SecurityRules.Level1 assembly, in which this rule is being incorrectly applied")] private static bool IsAssemblyLoaded(String assemblyName) { // Since there is no managed API for finding the GAC path, I // assert path discovery for all local files. FileIOPermission permission = new FileIOPermission(PermissionState.None); permission.AllLocalFiles = FileIOPermissionAccess.PathDiscovery; permission.Assert(); foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { if (assembly.FullName.Equals(assemblyName, StringComparison.OrdinalIgnoreCase)) { return true; } // Warn if they have the same assembly with different versions. If we don't do this, // they will get an InvalidCastException instead. AssemblyName name1 = new AssemblyName(assemblyName); AssemblyName name2 = assembly.GetName(); if (name1.Name == name2.Name && name1.CultureInfo.Equals(name2.CultureInfo) && Utils.PublicKeyMatches(name1, name2) && name1.Version != name2.Version) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Res.IncompatibleAddInBaseAssembly, assemblyName)); } } return false; } //// // // [System.Security.SecuritySafeCritical] internal System.AddIn.Contract.IContract CreateAddInAdapter(Object addIn, Assembly addinAdapterAssembly) { System.Diagnostics.Contracts.Contract.Ensures(System.Diagnostics.Contracts.Contract.Result// () != null); // Create the AddIn Adapter System.AddIn.Contract.IContract addInAdapter = null; _currentComponentType = PipelineComponentType.AddInAdapter; Type adapterType = addinAdapterAssembly.GetType(_pipeline._addinAdapter.TypeInfo.FullName, true); Type addInBaseType = Type.GetType(_pipeline._addinBase.TypeInfo.AssemblyQualifiedName, true); AddInActivator.InvokerDelegate myInvokerDelegate = AddInActivator.CreateConsInvoker(adapterType, addIn.GetType()); addInAdapter = (System.AddIn.Contract.IContract)myInvokerDelegate(addIn); System.Diagnostics.Contracts.Contract.Assert(addInAdapter != null, "CreateInstance didn't create the add-in adapter"); return addInAdapter; } // This is necessary if an add-in or an add-in adapter depends on other // assemblies within the same directory. // // [System.Security.SecuritySafeCritical] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2128:SecurityTransparentCodeShouldNotAssert", Justification = "This is a SecurityRules.Level1 assembly, in which this rule is being incorrectly applied")] internal Assembly ResolveAssembly(Object sender, ResolveEventArgs args) { System.Diagnostics.Contracts.Contract.Assert(_pipeline != null); String assemblyRef = args.Name; //Console.WriteLine("ResolveAssembly (in add-in's AD) called for {0}", assemblyRef); // Two purposes here: // 1) Ensure that our already-loaded pipeline components get upgraded // from the LoadFrom context to the default loader context. // 2) Any dependencies of our already-loaded pipeline components would // have been loaded in the LoadFrom context, and need to also be // manually upgraded to the default loader context. // We can do both of the above by calling LoadFrom on the appropriate // assemblies on disk, or by walking the list of already-loaded // assemblies, looking for the ones we need to upgrade. // Since we'll have multiple add-ins in the same AD, it may make the // most sense to simply look for an already-loaded assembly instead of // looking in directories on disk, to avoid conflicts. // Check to see if this assembly was already loaded in the // LoadFrom context. If so, upgrade it. Assembly a = Utils.FindLoadedAssemblyRef(assemblyRef); if (a != null) return a; // It wasn't found in memory, so look on disk String rootDir = _pipeline.PipelineRootDirectory; List// dirsToLookIn = new List (); switch (_currentComponentType) { case PipelineComponentType.AddInAdapter: // Look in contract directory and addin base directory. dirsToLookIn.Add(Path.Combine(rootDir, AddInStore.ContractsDirName)); dirsToLookIn.Add(Path.Combine(rootDir, AddInStore.AddInBasesDirName)); break; case PipelineComponentType.AddIn: dirsToLookIn.Add(Path.Combine(rootDir, AddInStore.AddInBasesDirName)); break; default: System.Diagnostics.Contracts.Contract.Assert(false); throw new InvalidOperationException("Fell through switch in assembly resolve event!"); } // ARROWHEAD START // In the LoadFrom context, assemblies we depend on in the same folder are loaded automatically. // We don't have that behavior in Arrowhead. //String addinFolder = Path.GetDirectoryName(_pipeline._addin.Location); //dirsToLookIn.Add(addinFolder); // ARROWHEAD END // Assert permission to read from addinBase folder (and maybe contracts folder). PermissionSet permissionSet = new PermissionSet(PermissionState.None); foreach (string dir in dirsToLookIn) { permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, dir)); } permissionSet.Assert(); return Utils.LoadAssemblyFrom(dirsToLookIn, assemblyRef); //Console.WriteLine("Couldn't resolve assembly {0} while loading a {1}", simpleName, _currentComponentType); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- OdbcConnectionPoolProviderInfo.cs
- CookielessHelper.cs
- CompiledQueryCacheEntry.cs
- BasicExpandProvider.cs
- ObjectRef.cs
- MessageSecurityProtocol.cs
- MatchSingleFxEngineOpcode.cs
- FixedDSBuilder.cs
- Task.cs
- GeometryValueSerializer.cs
- RequestStatusBarUpdateEventArgs.cs
- ProtocolElementCollection.cs
- SystemWebSectionGroup.cs
- IssuedTokenParametersElement.cs
- HostSecurityManager.cs
- ContainerUtilities.cs
- CodeMemberField.cs
- UserInitiatedRoutedEventPermission.cs
- Viewport2DVisual3D.cs
- MembershipValidatePasswordEventArgs.cs
- BreakRecordTable.cs
- Thickness.cs
- ControlFilterExpression.cs
- ResourceContainerWrapper.cs
- ComplexType.cs
- RawStylusActions.cs
- CriticalFinalizerObject.cs
- BamlLocalizationDictionary.cs
- DataGridClipboardHelper.cs
- FileSystemWatcher.cs
- ComponentCommands.cs
- WSFederationHttpSecurity.cs
- Intellisense.cs
- TextDecoration.cs
- WorkflowOperationContext.cs
- AsyncPostBackErrorEventArgs.cs
- WebPartCancelEventArgs.cs
- RtType.cs
- MenuItemBindingCollection.cs
- PartialCachingControl.cs
- XmlSchemaAnnotated.cs
- BulletedListDesigner.cs
- PropertyManager.cs
- XmlIlGenerator.cs
- control.ime.cs
- XsdCachingReader.cs
- DateTimeConverter.cs
- Int16AnimationUsingKeyFrames.cs
- base64Transforms.cs
- ObjectFactoryCodeDomTreeGenerator.cs
- PropagatorResult.cs
- StreamGeometry.cs
- ProxySimple.cs
- _emptywebproxy.cs
- DataGridViewAdvancedBorderStyle.cs
- WindowsSidIdentity.cs
- PopupEventArgs.cs
- TreeSet.cs
- ImportRequest.cs
- TextTreeDeleteContentUndoUnit.cs
- DataSetMappper.cs
- TextServicesManager.cs
- SpecularMaterial.cs
- EdmToObjectNamespaceMap.cs
- SafeEventLogWriteHandle.cs
- FilterableAttribute.cs
- CategoryNameCollection.cs
- DependencyObjectPropertyDescriptor.cs
- XmlNodeList.cs
- XmlMessageFormatter.cs
- EditBehavior.cs
- SortKey.cs
- InfoCardConstants.cs
- AsyncInvokeOperation.cs
- CapiSafeHandles.cs
- SQLGuidStorage.cs
- WindowsScrollBar.cs
- PropertyChangedEventArgs.cs
- XmlSerializerAssemblyAttribute.cs
- PlainXmlWriter.cs
- DataObjectCopyingEventArgs.cs
- Error.cs
- _Rfc2616CacheValidators.cs
- Transform3DCollection.cs
- ValidationErrorEventArgs.cs
- GeometryHitTestParameters.cs
- GridItemProviderWrapper.cs
- UriWriter.cs
- BrowserCapabilitiesFactory.cs
- FlowDocumentPaginator.cs
- ThumbAutomationPeer.cs
- JulianCalendar.cs
- WindowsButton.cs
- ListViewTableCell.cs
- URLString.cs
- CodeIdentifiers.cs
- NetSectionGroup.cs
- SqlBulkCopyColumnMappingCollection.cs
- xmlglyphRunInfo.cs
- DeviceContext.cs