internal static void RunInternal(ExecutionContext executionContext, ContextCallback callback, object state, bool preserveSyncCtx) { if (!executionContext.IsPreAllocatedDefault) { executionContext.isNewCapture = false; } Thread currentThread = Thread.CurrentThread; ExecutionContextSwitcher ecsw = new ExecutionContextSwitcher(); RuntimeHelpers.PrepareConstrainedRegions(); try { ExecutionContext.Reader executionContextReader = currentThread.GetExecutionContextReader(); if ((executionContextReader.IsNull || executionContextReader.IsDefaultFTContext(preserveSyncCtx)) && (SecurityContext.CurrentlyInDefaultFTSecurityContext(executionContextReader) && executionContext.IsDefaultFTContext(preserveSyncCtx)) && executionContextReader.HasSameLocalValues(executionContext)) { ExecutionContext.EstablishCopyOnWriteScope(currentThread, true, ref ecsw); } else { if (executionContext.IsPreAllocatedDefault) { executionContext = new ExecutionContext(); } ecsw = ExecutionContext.SetExecutionContext(executionContext, preserveSyncCtx); } callback(state); } finally { ecsw.Undo(); } }
internal static void SetCompressedStackThread(CompressedStack cs) { Thread currentThread = Thread.CurrentThread; if (currentThread.GetExecutionContextReader().SecurityContext.CompressedStack == cs) { return; } ExecutionContext executionContext = currentThread.GetMutableExecutionContext(); if (executionContext.SecurityContext != null) { executionContext.SecurityContext.CompressedStack = cs; } else { if (cs == null) { return; } executionContext.SecurityContext = new SecurityContext() { CompressedStack = cs }; } }
internal void Undo() { if (this.thread == null) { return; } Thread thread = this.thread; if (this.hecsw != null) { HostExecutionContextSwitcher.Undo(this.hecsw); } ExecutionContext.Reader executionContextReader = thread.GetExecutionContextReader(); ExecutionContext.Reader reader = this.outerEC; int num = this.outerECBelongsToScope ? 1 : 0; thread.SetExecutionContext(reader, num != 0); if (this.scsw.currSC != null) { this.scsw.Undo(); } if (this.wiIsValid) { SecurityContext.RestoreCurrentWI(this.outerEC, executionContextReader, this.wi, this.cachedAlwaysFlowImpersonationPolicy); } this.thread = (Thread)null; ExecutionContext.OnAsyncLocalContextChanged(executionContextReader.DangerousGetRawExecutionContext(), this.outerEC.DangerousGetRawExecutionContext()); }
internal static void RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, bool preserveSyncCtx) { Contract.Assert(executionContext != null); if (executionContext.IsPreAllocatedDefault) { Contract.Assert(executionContext.IsDefaultFTContext(preserveSyncCtx)); } else { Contract.Assert(executionContext.isNewCapture); executionContext.isNewCapture = false; } Thread currentThread = Thread.CurrentThread; ExecutionContextSwitcher ecsw = default(ExecutionContextSwitcher); RuntimeHelpers.PrepareConstrainedRegions(); try { ExecutionContext.Reader ec = currentThread.GetExecutionContextReader(); if ((ec.IsNull || ec.IsDefaultFTContext(preserveSyncCtx)) && #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK SecurityContext.CurrentlyInDefaultFTSecurityContext(ec) && #endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK executionContext.IsDefaultFTContext(preserveSyncCtx)) { // Neither context is interesting, so we don't need to set the context. // We do need to reset any changes made by the user's callback, // so here we establish a "copy-on-write scope". Any changes will // result in a copy of the context being made, preserving the original // context. EstablishCopyOnWriteScope(currentThread, true, ref ecsw); } else { if (executionContext.IsPreAllocatedDefault) { executionContext = executionContext.CreateCopy(); } ecsw = SetExecutionContext(executionContext, preserveSyncCtx); } // // Call the user's callback // callback(state); } finally { ecsw.Undo(currentThread); } }
private static void EstablishCopyOnWriteScope(Thread currentThread, bool knownNullWindowsIdentity, ref ExecutionContextSwitcher ecsw) { ecsw.outerEC = currentThread.GetExecutionContextReader(); ecsw.outerECBelongsToScope = currentThread.ExecutionContextBelongsToCurrentScope; ecsw.cachedAlwaysFlowImpersonationPolicy = SecurityContext.AlwaysFlowImpersonationPolicy; if (!knownNullWindowsIdentity) { ecsw.wi = SecurityContext.GetCurrentWI(ecsw.outerEC, ecsw.cachedAlwaysFlowImpersonationPolicy); } ecsw.wiIsValid = true; currentThread.ExecutionContextBelongsToCurrentScope = false; ecsw.thread = currentThread; }
internal static ExecutionContextSwitcher SetExecutionContext(ExecutionContext executionContext, bool preserveSyncCtx) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; ExecutionContextSwitcher executionContextSwitcher = new ExecutionContextSwitcher(); Thread currentThread = Thread.CurrentThread; ExecutionContext.Reader executionContextReader = currentThread.GetExecutionContextReader(); executionContextSwitcher.thread = currentThread; executionContextSwitcher.outerEC = executionContextReader; executionContextSwitcher.outerECBelongsToScope = currentThread.ExecutionContextBelongsToCurrentScope; if (preserveSyncCtx) { executionContext.SynchronizationContext = executionContextReader.SynchronizationContext; } executionContext.SynchronizationContextNoFlow = executionContextReader.SynchronizationContextNoFlow; currentThread.SetExecutionContext(executionContext, true); RuntimeHelpers.PrepareConstrainedRegions(); try { ExecutionContext.OnAsyncLocalContextChanged(executionContextReader.DangerousGetRawExecutionContext(), executionContext); SecurityContext securityContext1 = executionContext.SecurityContext; if (securityContext1 != null) { SecurityContext.Reader securityContext2 = executionContextReader.SecurityContext; executionContextSwitcher.scsw = SecurityContext.SetSecurityContext(securityContext1, securityContext2, false, ref stackMark); } else if (!SecurityContext.CurrentlyInDefaultFTSecurityContext(executionContextSwitcher.outerEC)) { SecurityContext.Reader securityContext2 = executionContextReader.SecurityContext; executionContextSwitcher.scsw = SecurityContext.SetSecurityContext(SecurityContext.FullTrustSecurityContext, securityContext2, false, ref stackMark); } HostExecutionContext executionContext1 = executionContext.HostExecutionContext; if (executionContext1 != null) { executionContextSwitcher.hecsw = HostExecutionContextManager.SetHostExecutionContextInternal(executionContext1); } } catch { executionContextSwitcher.UndoNoThrow(); throw; } return(executionContextSwitcher); }
internal static void SetCompressedStackThread(CompressedStack cs) { Thread currentThread = Thread.CurrentThread; if (currentThread.GetExecutionContextReader().SecurityContext.CompressedStack != cs) { ExecutionContext ec = currentThread.GetMutableExecutionContext(); if (ec.SecurityContext != null) { ec.SecurityContext.CompressedStack = cs; } else if (cs != null) { SecurityContext sc = new SecurityContext(); sc.CompressedStack = cs; ec.SecurityContext = sc; } } }
internal static void SetCompressedStackThread(CompressedStack cs) { Thread currentThread = Thread.CurrentThread; if (currentThread.GetExecutionContextReader().SecurityContext.CompressedStack != cs) { ExecutionContext mutableExecutionContext = currentThread.GetMutableExecutionContext(); if (mutableExecutionContext.SecurityContext != null) { mutableExecutionContext.SecurityContext.CompressedStack = cs; return; } if (cs != null) { mutableExecutionContext.SecurityContext = new SecurityContext { CompressedStack = cs }; } } }
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; }
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 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 DEBUG } finally { currentThread.ForbidExecutionContextMutation = false; } #endif }
[HandleProcessCorruptedStateExceptions] // #endif // FEATURE_CORRUPTING_EXCEPTIONS internal static ExecutionContextSwitcher SetExecutionContext(ExecutionContext executionContext, bool preserveSyncCtx) { #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; #endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK Contract.Assert(executionContext != null); Contract.Assert(executionContext != s_dummyDefaultEC); // Set up the switcher object to return; ExecutionContextSwitcher ecsw = new ExecutionContextSwitcher(); Thread currentThread = Thread.CurrentThread; ExecutionContext.Reader outerEC = currentThread.GetExecutionContextReader(); ecsw.thread = currentThread; ecsw.outerEC = outerEC; ecsw.outerECBelongsToScope = currentThread.ExecutionContextBelongsToCurrentScope; if (preserveSyncCtx) { executionContext.SynchronizationContext = outerEC.SynchronizationContext; } executionContext.SynchronizationContextNoFlow = outerEC.SynchronizationContextNoFlow; currentThread.SetExecutionContext(executionContext, belongsToCurrentScope: true); RuntimeHelpers.PrepareConstrainedRegions(); try { #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK //set the security context SecurityContext sc = executionContext.SecurityContext; if (sc != null) { // non-null SC: needs to be set SecurityContext.Reader prevSeC = outerEC.SecurityContext; ecsw.scsw = SecurityContext.SetSecurityContext(sc, prevSeC, false, ref stackMark); } else if (!SecurityContext.CurrentlyInDefaultFTSecurityContext(ecsw.outerEC)) { // null incoming SC, but we're currently not in FT: use static FTSC to set SecurityContext.Reader prevSeC = outerEC.SecurityContext; ecsw.scsw = SecurityContext.SetSecurityContext(SecurityContext.FullTrustSecurityContext, prevSeC, false, ref stackMark); } #endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK #if FEATURE_CAS_POLICY // set the Host Context HostExecutionContext hostContext = executionContext.HostExecutionContext; if (hostContext != null) { ecsw.hecsw = HostExecutionContextManager.SetHostExecutionContextInternal(hostContext); } #endif // FEATURE_CAS_POLICY } catch { ecsw.UndoNoThrow(); throw; } return(ecsw); }