internal void Undo(Thread currentThread) { // // Don't use an uninitialized switcher, or one that's already been used. // if (thread == null) return; // Don't do anything Contract.Assert(currentThread == this.thread); // // Restore the HostExecutionContext before restoring the ExecutionContext. // #if FEATURE_CAS_POLICY if (hecsw != null) HostExecutionContextSwitcher.Undo(hecsw); #endif // FEATURE_CAS_POLICY // // restore the saved Execution Context. Note that this will also restore the // SynchronizationContext, Logical/IllogicalCallContext, etc. // #if !FEATURE_PAL && FEATURE_IMPERSONATION ExecutionContext.Reader innerEC = currentThread.GetExecutionContextReader(); #endif currentThread.SetExecutionContext(outerEC, outerECBelongsToScope); #if !MONO && DEBUG try { currentThread.ForbidExecutionContextMutation = true; #endif // // Tell the SecurityContext to do the side-effects of restoration. // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK if (scsw.currSC != null) { // Any critical failure inside scsw will cause FailFast scsw.Undo(); } #endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK #if !FEATURE_PAL && FEATURE_IMPERSONATION if (wiIsValid) SecurityContext.RestoreCurrentWI(outerEC, innerEC, wi, cachedAlwaysFlowImpersonationPolicy); #endif thread = null; // this will prevent the switcher object being used again #if !MONO && DEBUG } finally { currentThread.ForbidExecutionContextMutation = false; } #endif }
static internal void EstablishCopyOnWriteScope(Thread currentThread, bool knownNullWindowsIdentity, ref ExecutionContextSwitcher ecsw) { Contract.Assert(currentThread == Thread.CurrentThread); ecsw.outerEC = currentThread.GetExecutionContextReader(); ecsw.outerECBelongsToScope = currentThread.ExecutionContextBelongsToCurrentScope; #if !FEATURE_PAL && FEATURE_IMPERSONATION ecsw.cachedAlwaysFlowImpersonationPolicy = SecurityContext.AlwaysFlowImpersonationPolicy; if (knownNullWindowsIdentity) Contract.Assert(SecurityContext.GetCurrentWI(ecsw.outerEC, ecsw.cachedAlwaysFlowImpersonationPolicy) == null); else ecsw.wi = SecurityContext.GetCurrentWI(ecsw.outerEC, ecsw.cachedAlwaysFlowImpersonationPolicy); ecsw.wiIsValid = true; #endif currentThread.ExecutionContextBelongsToCurrentScope = false; ecsw.thread = currentThread; }