internal AddInControllerImpl(AddInEnvironment environment, bool unloadDomainOnExit, AddInToken token) { System.Diagnostics.Contracts.Contract.Requires(environment != null); System.Diagnostics.Contracts.Contract.Requires(token != null); _unloadDomainOnExit = unloadDomainOnExit; _token = token; _addInEnvironment = environment; }
private static T Activate <T>(AddInToken token, PermissionSet permissionSet, String appDomainName) { // Make a copy of the permission set to prevent the permissions from being modified after we demand permissionSet = permissionSet.Copy(); // // Breaking security fix: (B#499362): Making a copy isn't sufficient protection if the // permission object comes from an untrusted source as the permission object itself // can interfere with the copy process. We simply can't safely pass an untrusted permission // down to CreateDomain(), so if there any untrusted permissions in the set, demand full trust before // allowing the operation to proceed. // if (!permissionSet.IsUnrestricted()) { foreach (Object permission in permissionSet) { Assembly a = permission.GetType().Assembly; if (!a.GlobalAssemblyCache) { new PermissionSet(PermissionState.Unrestricted).Demand(); break; } } } // Don't let them create an appdomain that elevates privileges permissionSet.Demand(); AppDomain domain = null; try { domain = CreateDomain(token, permissionSet, appDomainName); AddInEnvironment environment = new AddInEnvironment(domain, true); AddInControllerImpl controller = new AddInControllerImpl(environment, true, token); return(ActivateInAppDomain <T>(token, domain, controller, true)); } catch { // Don't leak the domain. if (domain != null) { try { Utils.UnloadAppDomain(domain); } catch (AppDomainUnloadedException) {} } throw; } }
internal static T Activate <T>(AddInToken token, AppDomain target) { if (token == null) { throw new ArgumentNullException("token"); } if (target == null) { throw new ArgumentNullException("target"); } System.Diagnostics.Contracts.Contract.EndContractBlock(); AddInEnvironment environment = new AddInEnvironment(target); AddInControllerImpl controller = new AddInControllerImpl(environment, false, token); return(ActivateInAppDomain <T>(token, target, controller, false)); }
// Activation in an existing appdomain, either in-process or out-of-process internal static T Activate <T>(AddInToken token, AddInEnvironment environment) { if (environment == null) { throw new ArgumentNullException("environment"); } System.Diagnostics.Contracts.Contract.EndContractBlock(); if (environment.Process.IsCurrentProcess) { AddInControllerImpl controller = new AddInControllerImpl(environment, false, token); return(ActivateInAppDomain <T>(token, environment.AppDomain, controller, false)); } else { return(ActivateOutOfProcess <T>(token, environment, false)); } }
// helper method // private static T ActivateOutOfProcess <T>(AddInToken token, AddInEnvironment environment, bool weOwn) { ActivationWorker worker; IContract contract = environment.AddInServerWorker.Activate(token, out worker); AddInControllerImpl controller = new AddInControllerImpl(environment, weOwn, token); controller.ActivationWorker = worker; T hav = AdaptToHost <T>(token, contract); if (weOwn) { environment.AddInServerWorker.SetAppDomainOwner(contract); } // Add this HAV and add-in controller to our list of currently // non-disposed add-ins. controller.AssociateWithHostAddinView(hav, contract); return(hav); }
internal static T Activate <T>(AddInToken token, AddInProcess process, PermissionSet permissionSet) { if (token == null) { throw new ArgumentNullException("token"); } if (permissionSet == null) { throw new ArgumentNullException("permissionSet"); } if (process == null) { throw new ArgumentNullException("process"); } System.Diagnostics.Contracts.Contract.EndContractBlock(); // check that they have ExecutionPermission. Otherwise OOP remoting fails // by shutting down the pipe, leaving the user scratching his head. if (!permissionSet.IsUnrestricted()) { SecurityPermission p = (SecurityPermission)permissionSet.GetPermission(typeof(SecurityPermission)); SecurityPermissionFlag requiredFlags = SecurityPermissionFlag.Execution; if (p == null || (p.Flags & requiredFlags) != requiredFlags) { throw new ArgumentException(Res.NeedSecurityFlags); } } RemotingHelper.InitializeClientChannel(); AddInServer addInServer = process.GetAddInServer(); AddInServerWorker addInServerWorker = addInServer.CreateDomain(token, permissionSet); AddInEnvironment fullEnvironment = new AddInEnvironment(process, addInServerWorker); return(ActivateOutOfProcess <T>(token, fullEnvironment, true)); }
public void Shutdown() { // Disables usage of the add-in, by breaking the pipeline. // Also, if we own the appdomain, we unload it. lock (this) // Ensure multiple threads racing on Shutdown don't collide. { AddInEnvironment environment = _addInEnvironment; if (environment != null) { try { if (_contract != null) { Object hav = _havReference.Target; IDisposable disposableHAV = hav as IDisposable; if (disposableHAV != null) { try { disposableHAV.Dispose(); } catch (AppDomainUnloadedException e) { Log(e.ToString()); } catch (RemotingException re) { Log(re.ToString()); } catch (SerializationException se) { Log(se.ToString()); } } IDisposable disposableContract = _contract as IDisposable; if (disposableContract != null) { try { disposableContract.Dispose(); } catch (AppDomainUnloadedException e) { Log(e.ToString()); } catch (RemotingException re) { Log(re.ToString()); } catch (SerializationException se) { Log(se.ToString()); } } _contract = null; } if (_activationWorker != null) { // Unhook an assembly resolve event in the target appdomain. // However, if one of the adapters implemented IDisposable and cleaned // up the appropriate lifetime tokens, this appdomain may be unloading // already (we launch another thread to do this, so we are guaranteed // to have a benign race condition). We should catch an // AppDomainUnloadedException here. try { _activationWorker.Dispose(); } catch (AppDomainUnloadedException) { } catch (RemotingException) { } catch (SerializationException) { } _activationWorker = null; } } finally { if (_unloadDomainOnExit) { // AppDomain.Unload will block until we have finalized all // objects within the appdomain. Also, this may already // have been unloaded. try { environment.UnloadAppDomain(); } catch (AppDomainUnloadedException) { } catch (RemotingException) { } // Using the transparent proxy will now cause exceptions, // as managed threads are not allowed to enter this appdomain. } } _addInEnvironment = null; // eagerly remove from list lock (_havLock) { Object addin = _havReference.Target; if (addin != null) FindController(addin, true); } // The perf team recommends doing a GC after a large amount of memory has // been dereferenced. We wait for the finalizers to complete first // becase some references in the addin are not released until finalization. // Also, if an addin is buggy and causes the finalizer thread to hang, // waiting here makes it fail deterministically. System.GC.WaitForPendingFinalizers(); System.GC.Collect(); } // end if domain != null else { throw new InvalidOperationException(Res.AppDomainNull); } } }
public T Activate <T>(AddInEnvironment environment) { return(AddInActivator.Activate <T>(this, environment)); }
public void Shutdown() { // Disables usage of the add-in, by breaking the pipeline. // Also, if we own the appdomain, we unload it. lock (this) // Ensure multiple threads racing on Shutdown don't collide. { AddInEnvironment environment = _addInEnvironment; if (environment != null) { try { if (_contract != null) { Object hav = _havReference.Target; IDisposable disposableHAV = hav as IDisposable; if (disposableHAV != null) { try { disposableHAV.Dispose(); } catch (AppDomainUnloadedException e) { Log(e.ToString()); } catch (RemotingException re) { Log(re.ToString()); } catch (SerializationException se) { Log(se.ToString()); } } IDisposable disposableContract = _contract as IDisposable; if (disposableContract != null) { try { disposableContract.Dispose(); } catch (AppDomainUnloadedException e) { Log(e.ToString()); } catch (RemotingException re) { Log(re.ToString()); } catch (SerializationException se) { Log(se.ToString()); } } _contract = null; } if (_activationWorker != null) { // Unhook an assembly resolve event in the target appdomain. // However, if one of the adapters implemented IDisposable and cleaned // up the appropriate lifetime tokens, this appdomain may be unloading // already (we launch another thread to do this, so we are guaranteed // to have a benign race condition). We should catch an // AppDomainUnloadedException here. try { _activationWorker.Dispose(); } catch (AppDomainUnloadedException) { } catch (RemotingException) { } catch (SerializationException) { } _activationWorker = null; } } finally { if (_unloadDomainOnExit) { // AppDomain.Unload will block until we have finalized all // objects within the appdomain. Also, this may already // have been unloaded. try { environment.UnloadAppDomain(); } catch (AppDomainUnloadedException) { } catch (RemotingException) { } // Using the transparent proxy will now cause exceptions, // as managed threads are not allowed to enter this appdomain. } } _addInEnvironment = null; // eagerly remove from list lock (_havLock) { Object addin = _havReference.Target; if (addin != null) { FindController(addin, true); } } // The perf team recommends doing a GC after a large amount of memory has // been dereferenced. We wait for the finalizers to complete first // becase some references in the addin are not released until finalization. // Also, if an addin is buggy and causes the finalizer thread to hang, // waiting here makes it fail deterministically. System.GC.WaitForPendingFinalizers(); System.GC.Collect(); } // end if domain != null else { throw new InvalidOperationException(Res.AppDomainNull); } } }