The Labs \ Source Viewer \ SSCLI \ System.Threading \ DomainCompressedStack

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. /*=============================================================================
  16. **
  17. ** Class: CompressedStack
  18. **
  19. ** Purpose: Managed wrapper for the security stack compression implementation
  20. **
  21. =============================================================================*/
  22. namespace System.Threading
  23. {
  24.     using System.Security;
  25.     using System.Security.Permissions;
  26.     using System.Runtime.InteropServices;
  27.     using System.Runtime.CompilerServices;
  28.     using System.Runtime.ConstrainedExecution;
  29.     using System.Reflection;
  30.     using System.Collections;
  31.     using System.Threading;
  32.     using System.Runtime.Serialization;
  33.    
  34.    
  35.     internal struct CompressedStackSwitcher : IDisposable
  36.     {
  37.         internal CompressedStack curr_CS;
  38.         internal CompressedStack prev_CS;
  39.         internal IntPtr prev_ADStack;
  40.        
  41.        
  42.         public override bool Equals(object obj)
  43.         {
  44.             if (obj == null || !(obj is CompressedStackSwitcher))
  45.                 return false;
  46.             CompressedStackSwitcher sw = (CompressedStackSwitcher)obj;
  47.             return (this.curr_CS == sw.curr_CS && this.prev_CS == sw.prev_CS && this.prev_ADStack == sw.prev_ADStack);
  48.         }
  49.        
  50.         public override int GetHashCode()
  51.         {
  52.             return ToString().GetHashCode();
  53.         }
  54.        
  55.         public static bool operator ==(CompressedStackSwitcher c1, CompressedStackSwitcher c2)
  56.         {
  57.             return c1.Equals(c2);
  58.         }
  59.        
  60.         public static bool operator !=(CompressedStackSwitcher c1, CompressedStackSwitcher c2)
  61.         {
  62.             return !c1.Equals(c2);
  63.         }
  64.         /// <internalonly/>
  65.         void IDisposable.Dispose()
  66.         {
  67.             Undo();
  68.         }
  69.        
  70.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
  71.         internal bool UndoNoThrow()
  72.         {
  73.             try {
  74.                 Undo();
  75.             }
  76.             catch {
  77.                 return false;
  78.             }
  79.             return true;
  80.         }
  81.        
  82.        
  83.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
  84.         public void Undo()
  85.         {
  86.             if (curr_CS == null && prev_CS == null)
  87.                 return;
  88.             if (prev_ADStack != (IntPtr)0)
  89.                 CompressedStack.RestoreAppDomainStack(prev_ADStack);
  90.             CompressedStack.SetCompressedStackThread(prev_CS);
  91.            
  92.             prev_CS = null;
  93.             curr_CS = null;
  94.             prev_ADStack = (IntPtr)0;
  95.         }
  96.     }
  97.    
  98.     internal class SafeCompressedStackHandle : SafeHandle
  99.     {
  100.         public SafeCompressedStackHandle() : base(IntPtr.Zero, true)
  101.         {
  102.         }
  103.        
  104.         public override bool IsInvalid {
  105.             get { return handle == IntPtr.Zero; }
  106.         }
  107.        
  108.         protected override bool ReleaseHandle()
  109.         {
  110.             CompressedStack.DestroyDelayedCompressedStack(handle);
  111.             handle = IntPtr.Zero;
  112.             return true;
  113.         }
  114.     }
  115.    
  116.    
  117.    
  118.     [Serializable()]
  119.     public sealed class CompressedStack : ISerializable
  120.     {
  121.        
  122.         private PermissionListSet m_pls;
  123.         private SafeCompressedStackHandle m_csHandle;
  124.        
  125.        
  126.         internal PermissionListSet PLS {
  127.             get { return m_pls; }
  128.         }
  129.        
  130.         internal CompressedStack(SafeCompressedStackHandle csHandle)
  131.         {
  132.             m_csHandle = csHandle;
  133.         }
  134.        
  135.         private CompressedStack(SafeCompressedStackHandle csHandle, PermissionListSet pls)
  136.         {
  137.             this.m_csHandle = csHandle;
  138.             this.m_pls = pls;
  139.         }
  140.        
  141.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
  142.         public void GetObjectData(SerializationInfo info, StreamingContext context)
  143.         {
  144.             if (info == null)
  145.                 throw new ArgumentNullException("info");
  146.             CompleteConstruction(null);
  147.             info.AddValue("PLS", this.m_pls);
  148.         }
  149.        
  150.         private CompressedStack(SerializationInfo info, StreamingContext context)
  151.         {
  152.             this.m_pls = (PermissionListSet)info.GetValue("PLS", typeof(PermissionListSet));
  153.         }
  154.        
  155.         internal SafeCompressedStackHandle CompressedStackHandle {
  156.             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  157.             get { return m_csHandle; }
  158.         }
  159.        
  160.         [StrongNameIdentityPermissionAttribute(SecurityAction.LinkDemand, PublicKey = "0x00000000000000000400000000000000"), SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
  161.         public static CompressedStack GetCompressedStack()
  162.         {
  163.             // This is a Capture()
  164.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  165.             return CompressedStack.GetCompressedStack(ref stackMark);
  166.         }
  167.        
  168.         static internal CompressedStack GetCompressedStack(ref StackCrawlMark stackMark)
  169.         {
  170.             CompressedStack cs;
  171.             CompressedStack innerCS = null;
  172.             if (CodeAccessSecurityEngine.QuickCheckForAllDemands()) {
  173.                 cs = new CompressedStack(null);
  174.             }
  175.             else if (CodeAccessSecurityEngine.AllDomainsHomogeneousWithNoStackModifiers()) {
  176.                 cs = new CompressedStack(null);
  177.                 cs.m_pls = PermissionListSet.CreateCompressedState_HG();
  178.             }
  179.             else {
  180.                 // regular stackwalking case
  181.                 cs = new CompressedStack(GetDelayedCompressedStack(ref stackMark));
  182.                 if (cs.CompressedStackHandle != null && IsImmediateCompletionCandidate(cs.CompressedStackHandle, out innerCS)) {
  183.                     cs.CompleteConstruction(innerCS);
  184.                     DestroyDCSList(cs.CompressedStackHandle);
  185.                 }
  186.             }
  187.             return cs;
  188.         }
  189.        
  190.         public static CompressedStack Capture()
  191.         {
  192.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  193.             return GetCompressedStack(ref stackMark);
  194.         }
  195.        
  196.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure), DynamicSecurityMethodAttribute()]
  197.         public static void Run(CompressedStack compressedStack, ContextCallback callback, object state)
  198.         {
  199.            
  200.             if (compressedStack == null) {
  201.                 throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamNull"), "compressedStack");
  202.             }
  203.             if (cleanupCode == null) {
  204.                 tryCode = new RuntimeHelpers.TryCode(runTryCode);
  205.                 cleanupCode = new RuntimeHelpers.CleanupCode(runFinallyCode);
  206.             }
  207.            
  208.             CompressedStackRunData runData = new CompressedStackRunData(compressedStack, callback, state);
  209.             RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(tryCode, cleanupCode, runData);
  210.         }
  211.        
  212.         internal class CompressedStackRunData
  213.         {
  214.             internal CompressedStack cs;
  215.             internal ContextCallback callBack;
  216.             internal object state;
  217.             internal CompressedStackSwitcher cssw;
  218.             internal CompressedStackRunData(CompressedStack cs, ContextCallback cb, object state)
  219.             {
  220.                 this.cs = cs;
  221.                 this.callBack = cb;
  222.                 this.state = state;
  223.                 this.cssw = new CompressedStackSwitcher();
  224.             }
  225.         }
  226.         static internal void runTryCode(object userData)
  227.         {
  228.             CompressedStackRunData rData = (CompressedStackRunData)userData;
  229.             rData.cssw = SetCompressedStack(rData.cs, GetCompressedStackThread());
  230.             rData.callBack(rData.state);
  231.            
  232.         }
  233.        
  234.         [PrePrepareMethod()]
  235.         static internal void runFinallyCode(object userData, bool exceptionThrown)
  236.         {
  237.             CompressedStackRunData rData = (CompressedStackRunData)userData;
  238.             rData.cssw.Undo();
  239.         }
  240.        
  241.         static internal RuntimeHelpers.TryCode tryCode;
  242.         static internal RuntimeHelpers.CleanupCode cleanupCode;
  243.        
  244.        
  245.         static internal CompressedStackSwitcher SetCompressedStack(CompressedStack cs, CompressedStack prevCS)
  246.         {
  247.             CompressedStackSwitcher cssw = new CompressedStackSwitcher();
  248.             RuntimeHelpers.PrepareConstrainedRegions();
  249.             try {
  250.                 // Order is important in this block.
  251.                 // Also, we dont want any THreadAborts happening when we try to set it
  252.                 RuntimeHelpers.PrepareConstrainedRegions();
  253.                 try {
  254.                     // Empty try block to ensure no ThreadAborts in the finally block
  255.                 }
  256.                 finally {
  257.                     // SetCompressedStackThread can throw - only if it suceeds we shd update the switcher and overrides
  258.                     SetCompressedStackThread(cs);
  259.                     cssw.prev_CS = prevCS;
  260.                     cssw.curr_CS = cs;
  261.                     cssw.prev_ADStack = SetAppDomainStack(cs);
  262.                 }
  263.             }
  264.             catch {
  265.                 cssw.UndoNoThrow();
  266.                 throw;
  267.                 // throw the original exception
  268.             }
  269.             return cssw;
  270.         }
  271.        
  272.        
  273.         [ComVisible(false)]
  274.         public CompressedStack CreateCopy()
  275.         {
  276.             return new CompressedStack(this.m_csHandle, this.m_pls);
  277.         }
  278.        
  279.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  280.         static internal IntPtr SetAppDomainStack(CompressedStack cs)
  281.         {
  282.             //Update the AD Stack on the thread and return the previous AD Stack
  283.             return Thread.CurrentThread.SetAppDomainStack((cs == null ? null : cs.CompressedStackHandle));
  284.         }
  285.        
  286.        
  287.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  288.         static internal void RestoreAppDomainStack(IntPtr appDomainStack)
  289.         {
  290.             Thread.CurrentThread.RestoreAppDomainStack(appDomainStack);
  291.             //Restore the previous AD Stack
  292.         }
  293.         static internal CompressedStack GetCompressedStackThread()
  294.         {
  295.             ExecutionContext ec = Thread.CurrentThread.GetExecutionContextNoCreate();
  296.             if (ec != null && ec.SecurityContext != null)
  297.                 return ec.SecurityContext.CompressedStack;
  298.             return null;
  299.         }
  300.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
  301.         static internal void SetCompressedStackThread(CompressedStack cs)
  302.         {
  303.             ExecutionContext ec = Thread.CurrentThread.ExecutionContext;
  304.             if (ec.SecurityContext != null)
  305.                 ec.SecurityContext.CompressedStack = cs;
  306.             else if (cs != null) {
  307.                 SecurityContext sc = new SecurityContext();
  308.                 sc.CompressedStack = cs;
  309.                 ec.SecurityContext = sc;
  310.             }
  311.         }
  312.        
  313.        
  314.         internal bool CheckDemand(CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandle rmh)
  315.         {
  316.             CompleteConstruction(null);
  317.            
  318.             if (PLS == null)
  319.                 return SecurityRuntime.StackHalt;
  320.             else
  321.                 return PLS.CheckDemand(demand, permToken, rmh);
  322.            
  323.         }
  324.        
  325.         internal bool CheckSetDemand(PermissionSet pset, RuntimeMethodHandle rmh)
  326.         {
  327.             CompleteConstruction(null);
  328.            
  329.             if (PLS == null)
  330.                 return SecurityRuntime.StackHalt;
  331.             else
  332.                 return PLS.CheckSetDemand(pset, rmh);
  333.         }
  334.        
  335.        
  336.         internal void GetZoneAndOrigin(ArrayList zoneList, ArrayList originList, PermissionToken zoneToken, PermissionToken originToken)
  337.         {
  338.            
  339.            
  340.             CompleteConstruction(null);
  341.             if (PLS != null)
  342.                 PLS.GetZoneAndOrigin(zoneList, originList, zoneToken, originToken);
  343.             return;
  344.         }
  345.        
  346.         internal void CompleteConstruction(CompressedStack innerCS)
  347.         {
  348.             if (PLS != null)
  349.                 return;
  350.             PermissionListSet pls = PermissionListSet.CreateCompressedState(this, innerCS);
  351.             lock (this) {
  352.                 if (PLS == null)
  353.                     m_pls = pls;
  354.             }
  355.         }
  356.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  357.         static internal extern SafeCompressedStackHandle GetDelayedCompressedStack(ref StackCrawlMark stackMark);
  358.        
  359.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  360.         static internal extern void DestroyDelayedCompressedStack(IntPtr unmanagedCompressedStack);
  361.        
  362.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  363.         static internal extern void DestroyDCSList(SafeCompressedStackHandle compressedStack);
  364.        
  365.        
  366.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  367.         static internal extern int GetDCSCount(SafeCompressedStackHandle compressedStack);
  368.        
  369.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  370.         static internal extern bool IsImmediateCompletionCandidate(SafeCompressedStackHandle compressedStack, out CompressedStack innerCS);
  371.        
  372.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  373.         static internal extern DomainCompressedStack GetDomainCompressedStack(SafeCompressedStackHandle compressedStack, int index);
  374.        
  375.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  376.         static internal extern void GetHomogeneousPLS(PermissionListSet hgPLS);
  377.        
  378.        
  379.     }
  380.    
  381.     //**********************************************************
  382.     // New Implementation of CompressedStack creation/demand eval - NewCompressedStack/DomainCompressedStack
  383.     //**********************************************************
  384.     [Serializable()]
  385.     internal sealed class DomainCompressedStack
  386.     {
  387.         // Managed equivalent of DomainCompressedStack - used to perform demand evaluation
  388.         private PermissionListSet m_pls;
  389.         // Did we terminate construction on this DCS and therefore, should we terminate construction on the rest of the CS?
  390.         private bool m_bHaltConstruction;
  391.        
  392.        
  393.         // CompresedStack interacts with this class purely through the three properties marked internal
  394.         // Zone, Origin, AGRList.
  395.         internal PermissionListSet PLS {
  396.             get { return m_pls; }
  397.         }
  398.        
  399.         internal bool ConstructionHalted {
  400.             get { return m_bHaltConstruction; }
  401.         }
  402.        
  403.        
  404.        
  405.         // Called from the VM only.
  406.         private static DomainCompressedStack CreateManagedObject(IntPtr unmanagedDCS)
  407.         {
  408.             DomainCompressedStack newDCS = new DomainCompressedStack();
  409.             newDCS.m_pls = PermissionListSet.CreateCompressedState(unmanagedDCS, out newDCS.m_bHaltConstruction);
  410.             // return the created object
  411.             return newDCS;
  412.         }
  413.        
  414.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  415.         static internal extern int GetDescCount(IntPtr dcs);
  416.        
  417.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  418.         static internal extern void GetDomainPermissionSets(IntPtr dcs, out PermissionSet granted, out PermissionSet refused);
  419.        
  420.         // returns true if the descriptor is a FrameSecurityDescriptor
  421.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  422.         static internal extern bool GetDescriptorInfo(IntPtr dcs, int index, out PermissionSet granted, out PermissionSet refused, out Assembly assembly, out FrameSecurityDescriptor fsd);
  423.        
  424.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  425.         static internal extern bool IgnoreDomain(IntPtr dcs);
  426.     }
  427.    
  428. }

Developer Fusion