The Labs \ Source Viewer \ SSCLI \ System.Security \ SpecialPermissionSetFlag

  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. namespace System.Security
  16. {
  17.     using System;
  18.     using System.Threading;
  19.     using System.Security.Util;
  20.     using System.Collections;
  21.     using System.IO;
  22.     using System.Security.Permissions;
  23.     using System.Security.Policy;
  24.     using System.Runtime.Serialization.Formatters.Binary;
  25.     using BindingFlags = System.Reflection.BindingFlags;
  26.     using System.Runtime.Serialization;
  27.     using System.Text;
  28.     using System.Runtime.Remoting.Activation;
  29.     using System.Globalization;
  30.     using System.Runtime.Versioning;
  31.    
  32.     [Serializable()]
  33.     internal enum SpecialPermissionSetFlag
  34.     {
  35.         // These also appear in clr/src/vm/permset.h
  36.         Regular = 0,
  37.         NoSet = 1,
  38.         EmptySet = 2,
  39.         SkipVerification = 3
  40.     }
  41.    
  42.     [Serializable()]
  43.     [StrongNameIdentityPermissionAttribute(SecurityAction.InheritanceDemand, Name = "mscorlib", PublicKey = "0x" + AssemblyRef.EcmaPublicKeyFull)]
  44.     [System.Runtime.InteropServices.ComVisible(true)]
  45.     public class PermissionSet : ISecurityEncodable, ICollection, IStackWalk, IDeserializationCallback
  46.     {
  47.         #if _DEBUG
  48.         static internal readonly bool debug;
  49.         #endif
  50.        
  51.         [System.Diagnostics.Conditional("_DEBUG")]
  52.         [ResourceExposure(ResourceScope.None)]
  53.         [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
  54.         private static void DEBUG_WRITE(string str)
  55.         {
  56.             #if _DEBUG
  57.             if (debug)
  58.                 Console.WriteLine(str);
  59.             #endif
  60.         }
  61.        
  62.         [System.Diagnostics.Conditional("_DEBUG")]
  63.         [ResourceExposure(ResourceScope.None)]
  64.         [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
  65.         private static void DEBUG_COND_WRITE(bool exp, string str)
  66.         {
  67.             #if _DEBUG
  68.             if (debug && (exp))
  69.                 Console.WriteLine(str);
  70.             #endif
  71.         }
  72.        
  73.         [System.Diagnostics.Conditional("_DEBUG")]
  74.         [ResourceExposure(ResourceScope.None)]
  75.         [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
  76.         private static void DEBUG_PRINTSTACK(Exception e)
  77.         {
  78.             #if _DEBUG
  79.             if (debug)
  80.                 Console.Error.WriteLine((e).StackTrace);
  81.             #endif
  82.         }
  83.        
  84.         // These members are accessed from EE using their hardcoded offset.
  85.         // Please update the PermissionSetObject in object.h if you make any changes
  86.         // to the fields here. !dumpobj will show the field layout
  87.        
  88.         // First the fields that are serialized x-appdomain (for perf reasons)
  89.         private bool m_Unrestricted;
  90.         [OptionalField(VersionAdded = 2)]
  91.         private bool m_allPermissionsDecoded = false;
  92.         [OptionalField(VersionAdded = 2)]
  93.         private bool m_canUnrestrictedOverride = false;
  94.        
  95.         [OptionalField(VersionAdded = 2)]
  96.         internal TokenBasedSet m_permSet = null;
  97.        
  98.         [OptionalField(VersionAdded = 2)]
  99.         private bool m_ignoreTypeLoadFailures = false;
  100.        
  101.         // This field will be populated only for non X-AD scenarios where we create a XML-ised string of the PermissionSet
  102.         [OptionalField(VersionAdded = 2)]
  103.         private string m_serializedPermissionSet;
  104.        
  105.         [NonSerialized()]
  106.         private bool m_CheckedForNonCas;
  107.         [NonSerialized()]
  108.         private bool m_ContainsCas;
  109.         [NonSerialized()]
  110.         private bool m_ContainsNonCas;
  111.        
  112.         // only used during non X-AD serialization to save the m_permSet value (which we dont want serialized)
  113.         [NonSerialized()]
  114.         private TokenBasedSet m_permSetSaved;
  115.        
  116.         // Following 3 fields are used only for serialization compat purposes: DO NOT USE THESE EVER!
  117.         #pragma warning disable 169
  118.         private bool readableonly;
  119.         private TokenBasedSet m_unrestrictedPermSet;
  120.         private TokenBasedSet m_normalPermSet;
  121.         #pragma warning restore 169
  122.         // END: Serialization-only fields
  123.        
  124.         static internal readonly PermissionSet s_fullTrust = new PermissionSet(true);
  125.        
  126.         [OnDeserializing()]
  127.         private void OnDeserializing(StreamingContext ctx)
  128.         {
  129.             Reset();
  130.         }
  131.        
  132.         [OnDeserialized()]
  133.         private void OnDeserialized(StreamingContext ctx)
  134.         {
  135.             if (m_serializedPermissionSet != null) {
  136.                 FromXml(SecurityElement.FromString(m_serializedPermissionSet));
  137.             }
  138.             else if (m_normalPermSet != null) {
  139.                 m_permSet = m_normalPermSet.SpecialUnion(m_unrestrictedPermSet, ref m_canUnrestrictedOverride);
  140.             }
  141.             else if (m_unrestrictedPermSet != null) {
  142.                 m_permSet = m_unrestrictedPermSet.SpecialUnion(m_normalPermSet, ref m_canUnrestrictedOverride);
  143.             }
  144.            
  145.             m_serializedPermissionSet = null;
  146.             m_normalPermSet = null;
  147.             m_unrestrictedPermSet = null;
  148.            
  149.         }
  150.        
  151.         [OnSerializing()]
  152.         private void OnSerializing(StreamingContext ctx)
  153.         {
  154.            
  155.             if ((ctx.State & ~(StreamingContextStates.Clone | StreamingContextStates.CrossAppDomain)) != 0) {
  156.                 m_serializedPermissionSet = ToString();
  157.                 // For v2.x and beyond
  158.                 if (m_permSet != null)
  159.                     m_permSet.SpecialSplit(ref m_unrestrictedPermSet, ref m_normalPermSet, m_ignoreTypeLoadFailures);
  160.                 m_permSetSaved = m_permSet;
  161.                 m_permSet = null;
  162.             }
  163.         }
  164.         [OnSerialized()]
  165.         private void OnSerialized(StreamingContext context)
  166.         {
  167.             if ((context.State & ~(StreamingContextStates.Clone | StreamingContextStates.CrossAppDomain)) != 0) {
  168.                 m_serializedPermissionSet = null;
  169.                 m_permSet = m_permSetSaved;
  170.                 m_permSetSaved = null;
  171.                 m_unrestrictedPermSet = null;
  172.                 m_normalPermSet = null;
  173.             }
  174.         }
  175.        
  176.         internal PermissionSet()
  177.         {
  178.             Reset();
  179.             m_Unrestricted = true;
  180.         }
  181.        
  182.         internal PermissionSet(bool fUnrestricted) : this()
  183.         {
  184.             SetUnrestricted(fUnrestricted);
  185.         }
  186.        
  187.         public PermissionSet(PermissionState state) : this()
  188.         {
  189.             if (state == PermissionState.Unrestricted) {
  190.                 SetUnrestricted(true);
  191.             }
  192.             else if (state == PermissionState.None) {
  193.                 SetUnrestricted(false);
  194.             }
  195.             else {
  196.                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPermissionState"));
  197.             }
  198.         }
  199.        
  200.         public PermissionSet(PermissionSet permSet) : this()
  201.         {
  202.             if (permSet == null) {
  203.                 Reset();
  204.                 return;
  205.             }
  206.            
  207.             m_Unrestricted = permSet.m_Unrestricted;
  208.             m_CheckedForNonCas = permSet.m_CheckedForNonCas;
  209.             m_ContainsCas = permSet.m_ContainsCas;
  210.             m_ContainsNonCas = permSet.m_ContainsNonCas;
  211.             m_canUnrestrictedOverride = permSet.m_canUnrestrictedOverride;
  212.             m_ignoreTypeLoadFailures = permSet.m_ignoreTypeLoadFailures;
  213.            
  214.             if (permSet.m_permSet != null) {
  215.                 m_permSet = new TokenBasedSet(permSet.m_permSet);
  216.                
  217.                 // now deep copy all permissions in set
  218.                 for (int i = m_permSet.GetStartingIndex(); i <= m_permSet.GetMaxUsedIndex(); i++) {
  219.                     object obj = m_permSet.GetItem(i);
  220.                     IPermission perm = obj as IPermission;
  221.                     ISecurityElementFactory elem = obj as ISecurityElementFactory;
  222.                     if (perm != null) {
  223.                         m_permSet.SetItem(i, perm.Copy());
  224.                     }
  225.                     else if (elem != null) {
  226.                         m_permSet.SetItem(i, elem.Copy());
  227.                     }
  228.                 }
  229.             }
  230.         }
  231.        
  232.         public virtual void CopyTo(Array array, int index)
  233.         {
  234.             if (array == null)
  235.                 throw new ArgumentNullException("array");
  236.            
  237.             PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);
  238.            
  239.             while (enumerator.MoveNext()) {
  240.                 array.SetValue(enumerator.Current, index++);
  241.             }
  242.         }
  243.        
  244.        
  245.         // private constructor that doesn't create any token based sets
  246.         private PermissionSet(object trash, object junk)
  247.         {
  248.             m_Unrestricted = false;
  249.         }
  250.        
  251.        
  252.         // Returns an object appropriate for synchronizing access to this
  253.         // Array.
  254.         public virtual object SyncRoot {
  255.             get { return this; }
  256.         }
  257.        
  258.         // Is this Array synchronized (i.e., thread-safe)? If you want a synchronized
  259.         // collection, you can use SyncRoot as an object to synchronize your
  260.         // collection with. You could also call GetSynchronized()
  261.         // to get a synchronized wrapper around the Array.
  262.         public virtual bool IsSynchronized {
  263.             get { return false; }
  264.         }
  265.        
  266.         // Is this Collection ReadOnly?
  267.         public virtual bool IsReadOnly {
  268.             get { return false; }
  269.         }
  270.        
  271.         // Reinitializes all state in PermissionSet - DO NOT null-out m_serializedPermissionSet
  272.         internal void Reset()
  273.         {
  274.             m_Unrestricted = false;
  275.             m_allPermissionsDecoded = true;
  276.             m_canUnrestrictedOverride = true;
  277.             m_permSet = null;
  278.            
  279.             m_ignoreTypeLoadFailures = false;
  280.            
  281.             m_CheckedForNonCas = false;
  282.             m_ContainsCas = false;
  283.             m_ContainsNonCas = false;
  284.             m_permSetSaved = null;
  285.            
  286.            
  287.         }
  288.        
  289.         internal void CheckSet()
  290.         {
  291.             if (this.m_permSet == null)
  292.                 this.m_permSet = new TokenBasedSet();
  293.         }
  294.        
  295.         public bool IsEmpty()
  296.         {
  297.             if (m_Unrestricted)
  298.                 return false;
  299.            
  300.             if (m_permSet == null || m_permSet.FastIsEmpty())
  301.                 return true;
  302.            
  303.             PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);
  304.            
  305.             while (enumerator.MoveNext()) {
  306.                 IPermission perm = (IPermission)enumerator.Current;
  307.                
  308.                 if (!perm.IsSubsetOf(null)) {
  309.                     return false;
  310.                 }
  311.             }
  312.            
  313.             return true;
  314.         }
  315.        
  316.         internal bool FastIsEmpty()
  317.         {
  318.             if (m_Unrestricted)
  319.                 return false;
  320.            
  321.             if (m_permSet == null || m_permSet.FastIsEmpty())
  322.                 return true;
  323.            
  324.             return false;
  325.         }
  326.        
  327.         public virtual int Count {
  328.             get {
  329.                 int count = 0;
  330.                
  331.                 if (m_permSet != null)
  332.                     count += m_permSet.GetCount();
  333.                
  334.                 return count;
  335.             }
  336.         }
  337.        
  338.        
  339.         internal IPermission GetPermission(int index)
  340.         {
  341.             if (m_permSet == null)
  342.                 return null;
  343.             object obj = m_permSet.GetItem(index);
  344.             if (obj == null)
  345.                 return null;
  346.             IPermission perm = obj as IPermission;
  347.             if (perm != null)
  348.                 return perm;
  349.             perm = CreatePermission(obj, index);
  350.             if (perm == null)
  351.                 return null;
  352.             BCLDebug.Assert(PermissionToken.IsTokenProperlyAssigned(perm, PermissionToken.GetToken(perm)), "PermissionToken was improperly assigned");
  353.             BCLDebug.Assert(PermissionToken.GetToken(perm).m_index == index, "Assigning permission to incorrect index in tokenbasedset");
  354.             return perm;
  355.         }
  356.        
  357.        
  358.         internal IPermission GetPermission(PermissionToken permToken)
  359.         {
  360.             if (permToken == null)
  361.                 return null;
  362.            
  363.             return GetPermission(permToken.m_index);
  364.         }
  365.        
  366.         internal IPermission GetPermission(IPermission perm)
  367.         {
  368.             if (perm == null)
  369.                 return null;
  370.            
  371.             return GetPermission(PermissionToken.GetToken(perm));
  372.         }
  373.        
  374.         public IPermission GetPermission(Type permClass)
  375.         {
  376.             if (permClass == null)
  377.                 return null;
  378.            
  379.             return GetPermission(PermissionToken.FindToken(permClass));
  380.         }
  381.        
  382.         public IPermission SetPermission(IPermission perm)
  383.         {
  384.             return (SetPermission(perm, true));
  385.         }
  386.        
  387.         // SetPermission adds a permission to a permissionset.
  388.         // if fReplace is true, then force an override of current slot contents
  389.         // otherwise, don't replace current slot contents.
  390.         internal IPermission SetPermission(IPermission perm, bool fReplace)
  391.         {
  392.             // can't get token if perm is null
  393.             if (perm == null)
  394.                 return null;
  395.            
  396.             if (!CodeAccessPermission.CanUnrestrictedOverride(perm))
  397.                 this.m_canUnrestrictedOverride = false;
  398.            
  399.             PermissionToken permToken = PermissionToken.GetToken(perm);
  400.            
  401.             if ((permToken.m_type & PermissionTokenType.IUnrestricted) != 0) {
  402.                 // SetPermission Makes the Permission "Restricted"
  403.                 m_Unrestricted = false;
  404.             }
  405.            
  406.             CheckSet();
  407.            
  408.             IPermission currPerm = GetPermission(permToken.m_index);
  409.            
  410.             // If a Permission exists in this slot, then our behavior
  411.             // is defined by the value of fReplace. Don't replace if
  412.             // fReplace is false, just return what was found. The caller of this function
  413.             // should compare the references of the added permission
  414.             // to the one returned. If they are equal, then the permission
  415.             // was added successfully, otherwise it was not.
  416.             if ((currPerm != null) && !fReplace)
  417.                 return currPerm;
  418.            
  419.             // OK, either we were told to always override (fReplace == true) or
  420.             // there wasn't anything in the slot. In either case, set the slot contents
  421.             // to perm and return.
  422.            
  423.             m_CheckedForNonCas = false;
  424.            
  425.             // Should we copy here?
  426.             m_permSet.SetItem(permToken.m_index, perm);
  427.             return perm;
  428.         }
  429.        
  430.         public IPermission AddPermission(IPermission perm)
  431.         {
  432.             // can't get token if perm is null
  433.             if (perm == null)
  434.                 return null;
  435.            
  436.             if (!CodeAccessPermission.CanUnrestrictedOverride(perm))
  437.                 this.m_canUnrestrictedOverride = false;
  438.            
  439.             m_CheckedForNonCas = false;
  440.            
  441.             // If the permission set is unrestricted, then return an unrestricted instance
  442.             // of perm.
  443.            
  444.             PermissionToken permToken = PermissionToken.GetToken(perm);
  445.            
  446.             if (this.IsUnrestricted() && ((permToken.m_type & PermissionTokenType.IUnrestricted) != 0)) {
  447.                 Type perm_type = perm.GetType();
  448.                 object[] objs = new object[1];
  449.                 objs[0] = PermissionState.Unrestricted;
  450.                 return (IPermission)Activator.CreateInstance(perm_type, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, objs, null);
  451.             }
  452.            
  453.             CheckSet();
  454.             IPermission currPerm = GetPermission(permToken.m_index);
  455.            
  456.             // If a Permission exists in this slot, then union it with perm
  457.             // Otherwise, just add perm.
  458.            
  459.             if (currPerm != null) {
  460.                 IPermission ip_union = currPerm.Union(perm);
  461.                 m_permSet.SetItem(permToken.m_index, ip_union);
  462.                 return ip_union;
  463.             }
  464.             else {
  465.                 // Should we copy here?
  466.                 m_permSet.SetItem(permToken.m_index, perm);
  467.                 return perm;
  468.             }
  469.            
  470.         }
  471.        
  472.         internal IPermission RemovePermission(int index)
  473.         {
  474.             IPermission perm = GetPermission(index);
  475.             if (perm == null)
  476.                 return null;
  477.             return (IPermission)m_permSet.RemoveItem(index);
  478.             // this cast is safe because the call to GetPermission will guarantee it is an IPermission
  479.         }
  480.        
  481.         internal IPermission RemovePermission(PermissionToken permToken)
  482.         {
  483.             if (permToken == null)
  484.                 return null;
  485.            
  486.             return RemovePermission(permToken.m_index);
  487.         }
  488.        
  489.         public IPermission RemovePermission(Type permClass)
  490.         {
  491.             if (permClass == null)
  492.                 return null;
  493.            
  494.             return RemovePermission(PermissionToken.FindToken(permClass));
  495.         }
  496.        
  497.         // Make this internal soon.
  498.         internal void SetUnrestricted(bool unrestricted)
  499.         {
  500.             m_Unrestricted = unrestricted;
  501.         }
  502.        
  503.         public bool IsUnrestricted()
  504.         {
  505.             return m_Unrestricted;
  506.         }
  507.        
  508.         internal bool CanUnrestrictedOverride()
  509.         {
  510.             return m_canUnrestrictedOverride;
  511.         }
  512.        
  513.         internal enum IsSubsetOfType
  514.         {
  515.             Normal,
  516.             CheckDemand,
  517.             CheckPermitOnly,
  518.             CheckAssertion
  519.         }
  520.        
  521.         internal bool IsSubsetOfHelper(PermissionSet target, IsSubsetOfType type, out IPermission firstPermThatFailed, bool ignoreNonCas)
  522.         {
  523.             #if _DEBUG
  524.             if (debug)
  525.                 DEBUG_WRITE("IsSubsetOf\n" + "Other:\n" + (target == null ? "<null>" : target.ToString()) + "\nMe:\n" + ToString());
  526.             #endif
  527.            
  528.             firstPermThatFailed = null;
  529.             if (target == null || target.FastIsEmpty()) {
  530.                 if (this.IsEmpty())
  531.                     return true;
  532.                 else {
  533.                     firstPermThatFailed = GetFirstPerm();
  534.                     return false;
  535.                 }
  536.             }
  537.             else if (this.IsUnrestricted() && !target.IsUnrestricted())
  538.                 return false;
  539.             else if (this.m_permSet == null)
  540.                 return true;
  541.             else {
  542.                 target.CheckSet();
  543.                
  544.                 for (int i = m_permSet.GetStartingIndex(); i <= this.m_permSet.GetMaxUsedIndex(); ++i) {
  545.                     IPermission thisPerm = this.GetPermission(i);
  546.                     if (thisPerm == null || thisPerm.IsSubsetOf(null))
  547.                         continue;
  548.                    
  549.                     IPermission targetPerm = target.GetPermission(i);
  550.                     #if _DEBUG
  551.                     PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem(i);
  552.                     BCLDebug.Assert(targetPerm == null || (token.m_type & PermissionTokenType.DontKnow) == 0, "Token not properly initialized");
  553.                     #endif
  554.                    
  555.                     if (target.m_Unrestricted && CodeAccessPermission.CanUnrestrictedOverride(thisPerm))
  556.                         continue;
  557.                    
  558.                     // targetPerm can be null here, but that is fine since it thisPerm is a subset
  559.                     // of empty/null then we can continue in the loop.
  560.                     CodeAccessPermission cap = thisPerm as CodeAccessPermission;
  561.                     if (cap == null) {
  562.                         if (!ignoreNonCas && !thisPerm.IsSubsetOf(targetPerm)) {
  563.                             firstPermThatFailed = thisPerm;
  564.                             return false;
  565.                         }
  566.                     }
  567.                     else {
  568.                         firstPermThatFailed = thisPerm;
  569.                         switch (type) {
  570.                             case IsSubsetOfType.Normal:
  571.                                 if (!thisPerm.IsSubsetOf(targetPerm))
  572.                                     return false;
  573.                                 break;
  574.                             case IsSubsetOfType.CheckDemand:
  575.                                 if (!cap.CheckDemand((CodeAccessPermission)targetPerm))
  576.                                     return false;
  577.                                 break;
  578.                             case IsSubsetOfType.CheckPermitOnly:
  579.                                 if (!cap.CheckPermitOnly((CodeAccessPermission)targetPerm))
  580.                                     return false;
  581.                                 break;
  582.                             case IsSubsetOfType.CheckAssertion:
  583.                                 if (!cap.CheckAssert((CodeAccessPermission)targetPerm))
  584.                                     return false;
  585.                                 break;
  586.                         }
  587.                         firstPermThatFailed = null;
  588.                     }
  589.                 }
  590.             }
  591.            
  592.             return true;
  593.         }
  594.        
  595.         public bool IsSubsetOf(PermissionSet target)
  596.         {
  597.             IPermission perm;
  598.             return IsSubsetOfHelper(target, IsSubsetOfType.Normal, out perm, false);
  599.         }
  600.        
  601.         internal bool CheckDemand(PermissionSet target, out IPermission firstPermThatFailed)
  602.         {
  603.             return IsSubsetOfHelper(target, IsSubsetOfType.CheckDemand, out firstPermThatFailed, true);
  604.         }
  605.        
  606.         internal bool CheckPermitOnly(PermissionSet target, out IPermission firstPermThatFailed)
  607.         {
  608.             return IsSubsetOfHelper(target, IsSubsetOfType.CheckPermitOnly, out firstPermThatFailed, true);
  609.         }
  610.        
  611.         internal bool CheckAssertion(PermissionSet target)
  612.         {
  613.             IPermission perm;
  614.             return IsSubsetOfHelper(target, IsSubsetOfType.CheckAssertion, out perm, true);
  615.         }
  616.        
  617.         internal bool CheckDeny(PermissionSet deniedSet, out IPermission firstPermThatFailed)
  618.         {
  619.             firstPermThatFailed = null;
  620.             if (deniedSet == null || deniedSet.FastIsEmpty() || this.FastIsEmpty())
  621.                 return true;
  622.            
  623.             if (this.m_Unrestricted && deniedSet.m_Unrestricted)
  624.                 return false;
  625.            
  626.             CodeAccessPermission permThis;
  627.             CodeAccessPermission permThat;
  628.             PermissionSetEnumeratorInternal enumThis = new PermissionSetEnumeratorInternal(this);
  629.            
  630.             while (enumThis.MoveNext()) {
  631.                 permThis = enumThis.Current as CodeAccessPermission;
  632.                 if (permThis == null || permThis.IsSubsetOf(null))
  633.                     continue;
  634.                 // ignore non-CAS permissions in the grant set.
  635.                 if (deniedSet.m_Unrestricted) {
  636.                     if (permThis.CanUnrestrictedOverride()) {
  637.                         firstPermThatFailed = permThis;
  638.                         return false;
  639.                     }
  640.                 }
  641.                 permThat = (CodeAccessPermission)deniedSet.GetPermission(enumThis.GetCurrentIndex());
  642.                 if (!permThis.CheckDeny(permThat)) {
  643.                     firstPermThatFailed = permThis;
  644.                     return false;
  645.                 }
  646.             }
  647.             if (this.m_Unrestricted) {
  648.                 PermissionSetEnumeratorInternal enumThat = new PermissionSetEnumeratorInternal(deniedSet);
  649.                 while (enumThat.MoveNext()) {
  650.                     if (enumThat.Current is IPermission && CodeAccessPermission.CanUnrestrictedOverride((IPermission)enumThat.Current))
  651.                         return false;
  652.                 }
  653.             }
  654.             return true;
  655.         }
  656.        
  657.         internal void CheckDecoded(CodeAccessPermission demandedPerm, PermissionToken tokenDemandedPerm)
  658.         {
  659.             BCLDebug.Assert(demandedPerm != null, "Expected non-null value");
  660.            
  661.             if (this.m_allPermissionsDecoded || this.m_permSet == null)
  662.                 return;
  663.            
  664.             if (tokenDemandedPerm == null)
  665.                 tokenDemandedPerm = PermissionToken.GetToken(demandedPerm);
  666.            
  667.             BCLDebug.Assert(tokenDemandedPerm != null, "Unable to find token for demanded permission");
  668.            
  669.             CheckDecoded(tokenDemandedPerm.m_index);
  670.         }
  671.        
  672.         internal void CheckDecoded(int index)
  673.         {
  674.             if (this.m_allPermissionsDecoded || this.m_permSet == null)
  675.                 return;
  676.            
  677.             GetPermission(index);
  678.         }
  679.        
  680.         internal void CheckDecoded(PermissionSet demandedSet)
  681.         {
  682.             BCLDebug.Assert(demandedSet != null, "Expected non-null value");
  683.            
  684.             if (this.m_allPermissionsDecoded || this.m_permSet == null)
  685.                 return;
  686.            
  687.             PermissionSetEnumeratorInternal enumerator = demandedSet.GetEnumeratorInternal();
  688.            
  689.             while (enumerator.MoveNext()) {
  690.                 CheckDecoded(enumerator.GetCurrentIndex());
  691.             }
  692.         }
  693.        
  694.         static internal void SafeChildAdd(SecurityElement parent, ISecurityElementFactory child, bool copy)
  695.         {
  696.             if (child == parent)
  697.                 return;
  698.             if (child.GetTag().Equals("IPermission") || child.GetTag().Equals("Permission")) {
  699.                 parent.AddChild(child);
  700.             }
  701.             else if (parent.Tag.Equals(child.GetTag())) {
  702.                 BCLDebug.Assert(child is SecurityElement, "SecurityElement expected");
  703.                 SecurityElement elChild = (SecurityElement)child;
  704.                 BCLDebug.Assert(elChild.InternalChildren != null, "Non-permission elements should have children");
  705.                
  706.                 for (int i = 0; i < elChild.InternalChildren.Count; ++i) {
  707.                     ISecurityElementFactory current = (ISecurityElementFactory)elChild.InternalChildren[i];
  708.                     BCLDebug.Assert(!current.GetTag().Equals(parent.Tag), "Illegal to insert a like-typed element");
  709.                     parent.AddChildNoDuplicates(current);
  710.                 }
  711.             }
  712.             else {
  713.                 parent.AddChild((ISecurityElementFactory)(copy ? child.Copy() : child));
  714.             }
  715.         }
  716.        
  717.         internal void InplaceIntersect(PermissionSet other)
  718.         {
  719.             Exception savedException = null;
  720.            
  721.             m_CheckedForNonCas = false;
  722.            
  723.             if (this == other)
  724.                 return;
  725.            
  726.             if (other == null || other.FastIsEmpty()) {
  727.                 // If the other is empty or null, make this empty.
  728.                 Reset();
  729.                 return;
  730.             }
  731.            
  732.             if (this.FastIsEmpty())
  733.                 return;
  734.            
  735.             int maxMax = this.m_permSet == null ? -1 : this.m_permSet.GetMaxUsedIndex();
  736.             int otherMax = other.m_permSet == null ? -1 : other.m_permSet.GetMaxUsedIndex();
  737.            
  738.             if (this.IsUnrestricted() && maxMax < otherMax) {
  739.                 maxMax = otherMax;
  740.                 this.CheckSet();
  741.             }
  742.            
  743.             if (other.IsUnrestricted()) {
  744.                 other.CheckSet();
  745.             }
  746.            
  747.             for (int i = 0; i <= maxMax; ++i) {
  748.                 object thisObj = this.m_permSet.GetItem(i);
  749.                 IPermission thisPerm = thisObj as IPermission;
  750.                 ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
  751.                
  752.                 object otherObj = other.m_permSet.GetItem(i);
  753.                 IPermission otherPerm = otherObj as IPermission;
  754.                 ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
  755.                
  756.                 if (thisObj == null && otherObj == null)
  757.                     continue;
  758.                
  759.                 if (thisElem != null && otherElem != null) {
  760.                     // If we already have an intersection node, just add another child
  761.                     if (thisElem.GetTag().Equals(s_str_PermissionIntersection) || thisElem.GetTag().Equals(s_str_PermissionUnrestrictedIntersection)) {
  762.                         BCLDebug.Assert(thisElem is SecurityElement, "SecurityElement expected");
  763.                         SafeChildAdd((SecurityElement)thisElem, otherElem, true);
  764.                     }
  765.                     // If either set is unrestricted, intersect the nodes unrestricted
  766.                     else {
  767.                         bool copyOther = true;
  768.                         if (this.IsUnrestricted()) {
  769.                             SecurityElement newElemUU = new SecurityElement(s_str_PermissionUnrestrictedUnion);
  770.                             newElemUU.AddAttribute("class", thisElem.Attribute("class"));
  771.                             SafeChildAdd(newElemUU, thisElem, false);
  772.                             thisElem = newElemUU;
  773.                         }
  774.                         if (other.IsUnrestricted()) {
  775.                             SecurityElement newElemUU = new SecurityElement(s_str_PermissionUnrestrictedUnion);
  776.                             newElemUU.AddAttribute("class", otherElem.Attribute("class"));
  777.                             SafeChildAdd(newElemUU, otherElem, true);
  778.                             otherElem = newElemUU;
  779.                             copyOther = false;
  780.                         }
  781.                        
  782.                         SecurityElement newElem = new SecurityElement(s_str_PermissionIntersection);
  783.                         newElem.AddAttribute("class", thisElem.Attribute("class"));
  784.                        
  785.                         SafeChildAdd(newElem, thisElem, false);
  786.                         SafeChildAdd(newElem, otherElem, copyOther);
  787.                         this.m_permSet.SetItem(i, newElem);
  788.                     }
  789.                 }
  790.                 else if (thisObj == null) {
  791.                     // There is no object in <this>, so intersection is empty except for IUnrestrictedPermissions
  792.                     if (this.IsUnrestricted()) {
  793.                         if (otherElem != null) {
  794.                             SecurityElement newElem = new SecurityElement(s_str_PermissionUnrestrictedIntersection);
  795.                             newElem.AddAttribute("class", otherElem.Attribute("class"));
  796.                             SafeChildAdd(newElem, otherElem, true);
  797.                             this.m_permSet.SetItem(i, newElem);
  798.                             BCLDebug.Assert(PermissionToken.s_tokenSet.GetItem(i) != null, "PermissionToken should already be assigned");
  799.                         }
  800.                         else {
  801.                             PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem(i);
  802.                             if ((token.m_type & PermissionTokenType.IUnrestricted) != 0) {
  803.                                 this.m_permSet.SetItem(i, otherPerm.Copy());
  804.                                 BCLDebug.Assert(PermissionToken.s_tokenSet.GetItem(i) != null, "PermissionToken should already be assigned");
  805.                             }
  806.                         }
  807.                     }
  808.                 }
  809.                 else if (otherObj == null) {
  810.                     if (other.IsUnrestricted()) {
  811.                         if (thisElem != null) {
  812.                             SecurityElement newElem = new SecurityElement(s_str_PermissionUnrestrictedIntersection);
  813.                             newElem.AddAttribute("class", thisElem.Attribute("class"));
  814.                             SafeChildAdd(newElem, thisElem, false);
  815.                             this.m_permSet.SetItem(i, newElem);
  816.                         }
  817.                         else {
  818.                             PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem(i);
  819.                             if ((token.m_type & PermissionTokenType.IUnrestricted) == 0)
  820.                                 this.m_permSet.SetItem(i, null);
  821.                         }
  822.                     }
  823.                     else {
  824.                         this.m_permSet.SetItem(i, null);
  825.                     }
  826.                 }
  827.                 else {
  828.                     if (thisElem != null)
  829.                         thisPerm = this.CreatePermission(thisElem, i);
  830.                     if (otherElem != null)
  831.                         otherPerm = other.CreatePermission(otherElem, i);
  832.                    
  833.                     try {
  834.                         IPermission intersectPerm;
  835.                         if (thisPerm == null)
  836.                             intersectPerm = otherPerm;
  837.                         else if (otherPerm == null)
  838.                             intersectPerm = thisPerm;
  839.                         else
  840.                             intersectPerm = thisPerm.Intersect(otherPerm);
  841.                         this.m_permSet.SetItem(i, intersectPerm);
  842.                     }
  843.                     catch (Exception e) {
  844.                         if (savedException == null)
  845.                             savedException = e;
  846.                     }
  847.                 }
  848.             }
  849.            
  850.             this.m_Unrestricted = this.m_Unrestricted && other.m_Unrestricted;
  851.            
  852.             if (savedException != null)
  853.                 throw savedException;
  854.         }
  855.        
  856.         public PermissionSet Intersect(PermissionSet other)
  857.         {
  858.             if (other == null || other.FastIsEmpty() || this.FastIsEmpty()) {
  859.                 return null;
  860.             }
  861.            
  862.             int thisMax = this.m_permSet == null ? -1 : this.m_permSet.GetMaxUsedIndex();
  863.             int otherMax = other.m_permSet == null ? -1 : other.m_permSet.GetMaxUsedIndex();
  864.             int minMax = thisMax < otherMax ? thisMax : otherMax;
  865.            
  866.             if (this.IsUnrestricted() && minMax < otherMax) {
  867.                 minMax = otherMax;
  868.                 this.CheckSet();
  869.             }
  870.            
  871.             if (other.IsUnrestricted() && minMax < thisMax) {
  872.                 minMax = thisMax;
  873.                 other.CheckSet();
  874.             }
  875.            
  876.             PermissionSet pset = new PermissionSet(false);
  877.            
  878.             if (minMax > -1) {
  879.                 pset.m_permSet = new TokenBasedSet();
  880.             }
  881.            
  882.             for (int i = 0; i <= minMax; ++i) {
  883.                 object thisObj = this.m_permSet.GetItem(i);
  884.                 IPermission thisPerm = thisObj as IPermission;
  885.                 ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
  886.                
  887.                 object otherObj = other.m_permSet.GetItem(i);
  888.                 IPermission otherPerm = otherObj as IPermission;
  889.                 ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
  890.                
  891.                 if (thisObj == null && otherObj == null)
  892.                     continue;
  893.                
  894.                 if (thisElem != null && otherElem != null) {
  895.                     bool copyOther = true;
  896.                     bool copyThis = true;
  897.                     SecurityElement newElem = new SecurityElement(s_str_PermissionIntersection);
  898.                     newElem.AddAttribute("class", otherElem.Attribute("class"));
  899.                     if (this.IsUnrestricted()) {
  900.                         SecurityElement newElemUU = new SecurityElement(s_str_PermissionUnrestrictedUnion);
  901.                         newElemUU.AddAttribute("class", thisElem.Attribute("class"));
  902.                         SafeChildAdd(newElemUU, thisElem, true);
  903.                         copyThis = false;
  904.                         thisElem = newElemUU;
  905.                     }
  906.                     if (other.IsUnrestricted()) {
  907.                         SecurityElement newElemUU = new SecurityElement(s_str_PermissionUnrestrictedUnion);
  908.                         newElemUU.AddAttribute("class", otherElem.Attribute("class"));
  909.                         SafeChildAdd(newElemUU, otherElem, true);
  910.                         copyOther = false;
  911.                         otherElem = newElemUU;
  912.                     }
  913.                    
  914.                     SafeChildAdd(newElem, otherElem, copyOther);
  915.                     SafeChildAdd(newElem, thisElem, copyThis);
  916.                     pset.m_permSet.SetItem(i, newElem);
  917.                 }
  918.                 else if (thisObj == null) {
  919.                     if (this.m_Unrestricted) {
  920.                         if (otherElem != null) {
  921.                             SecurityElement newElem = new SecurityElement(s_str_PermissionUnrestrictedIntersection);
  922.                             newElem.AddAttribute("class", otherElem.Attribute("class"));
  923.                             SafeChildAdd(newElem, otherElem, true);
  924.                             pset.m_permSet.SetItem(i, newElem);
  925.                             BCLDebug.Assert(PermissionToken.s_tokenSet.GetItem(i) != null, "PermissionToken should already be assigned");
  926.                         }
  927.                         else if (otherPerm != null) {
  928.                             PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem(i);
  929.                             if ((token.m_type & PermissionTokenType.IUnrestricted) != 0) {
  930.                                 pset.m_permSet.SetItem(i, otherPerm.Copy());
  931.                                 BCLDebug.Assert(PermissionToken.s_tokenSet.GetItem(i) != null, "PermissionToken should already be assigned");
  932.                             }
  933.                         }
  934.                     }
  935.                 }
  936.                 else if (otherObj == null) {
  937.                     if (other.m_Unrestricted) {
  938.                         if (thisElem != null) {
  939.                             SecurityElement newElem = new SecurityElement(s_str_PermissionUnrestrictedIntersection);
  940.                             newElem.AddAttribute("class", thisElem.Attribute("class"));
  941.                             SafeChildAdd(newElem, thisElem, true);
  942.                             pset.m_permSet.SetItem(i, newElem);
  943.                             BCLDebug.Assert(PermissionToken.s_tokenSet.GetItem(i) != null, "PermissionToken should already be assigned");
  944.                         }
  945.                         else if (thisPerm != null) {
  946.                             PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem(i);
  947.                             if ((token.m_type & PermissionTokenType.IUnrestricted) != 0) {
  948.                                 pset.m_permSet.SetItem(i, thisPerm.Copy());
  949.                                 BCLDebug.Assert(PermissionToken.s_tokenSet.GetItem(i) != null, "PermissionToken should already be assigned");
  950.                             }
  951.                         }
  952.                     }
  953.                 }
  954.                 else {
  955.                     if (thisElem != null)
  956.                         thisPerm = this.CreatePermission(thisElem, i);
  957.                     if (otherElem != null)
  958.                         otherPerm = other.CreatePermission(otherElem, i);
  959.                    
  960.                     IPermission intersectPerm;
  961.                     if (thisPerm == null)
  962.                         intersectPerm = otherPerm;
  963.                     else if (otherPerm == null)
  964.                         intersectPerm = thisPerm;
  965.                     else
  966.                         intersectPerm = thisPerm.Intersect(otherPerm);
  967.                     pset.m_permSet.SetItem(i, intersectPerm);
  968.                     BCLDebug.Assert(intersectPerm == null || PermissionToken.s_tokenSet.GetItem(i) != null, "PermissionToken should already be assigned");
  969.                 }
  970.             }
  971.            
  972.             pset.m_Unrestricted = this.m_Unrestricted && other.m_Unrestricted;
  973.             if (pset.FastIsEmpty())
  974.                 return null;
  975.             else
  976.                 return pset;
  977.         }
  978.        
  979.         internal void InplaceUnion(PermissionSet other)
  980.         {
  981.             // Unions the "other" PermissionSet into this one. It can be optimized to do less copies than
  982.             // need be done by the traditional union (and we don't have to create a new PermissionSet).
  983.            
  984.             if (this == other)
  985.                 return;
  986.            
  987.             // Quick out conditions, union doesn't change this PermissionSet
  988.             if (other == null || other.FastIsEmpty())
  989.                 return;
  990.            
  991.            
  992.             m_CheckedForNonCas = false;
  993.            
  994.            
  995.            
  996.            
  997.             this.m_Unrestricted = this.m_Unrestricted || other.m_Unrestricted;
  998.            
  999.             if (this.m_Unrestricted) {
  1000.                 if (CodeAccessSecurityEngine.DoesFullTrustMeanFullTrust()) {
  1001.                     // FullTrustMeansFullTrust is on...so if the result of Union is unrestricted permset, null the m_permSet member
  1002.                     this.m_permSet = null;
  1003.                     return;
  1004.                 }
  1005.                 if (this.m_canUnrestrictedOverride && other.m_canUnrestrictedOverride) {
  1006.                     // Only unrestricted override-able permissions in both this and other ...again, we can null the m_permSet member
  1007.                     this.m_permSet = null;
  1008.                     return;
  1009.                 }
  1010.                 if (other.m_canUnrestrictedOverride) {
  1011.                     // Only unrestricted override-able permissions in other...cannot null m_permSet, but don't look at other.m_permSet
  1012.                     return;
  1013.                 }
  1014.             }
  1015.            
  1016.            
  1017.             // If we reach here, result of Union is not unrestricted
  1018.             // We have to union "normal" permission no matter what now.
  1019.             int maxMax = -1;
  1020.             if (other.m_permSet != null) {
  1021.                 maxMax = other.m_permSet.GetMaxUsedIndex();
  1022.                 this.CheckSet();
  1023.             }
  1024.             // Save exceptions until the end
  1025.             Exception savedException = null;
  1026.            
  1027.             for (int i = 0; i <= maxMax; ++i) {
  1028.                 object thisObj = this.m_permSet.GetItem(i);
  1029.                 IPermission thisPerm = thisObj as IPermission;
  1030.                 ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
  1031.                
  1032.                 object otherObj = other.m_permSet.GetItem(i);
  1033.                 IPermission otherPerm = otherObj as IPermission;
  1034.                 ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
  1035.                
  1036.                 if (thisObj == null && otherObj == null)
  1037.                     continue;
  1038.                
  1039.                 if (thisElem != null && otherElem != null) {
  1040.                     if (thisElem.GetTag().Equals(s_str_PermissionUnion) || thisElem.GetTag().Equals(s_str_PermissionUnrestrictedUnion)) {
  1041.                         BCLDebug.Assert(thisElem is SecurityElement, "SecurityElement expected");
  1042.                         SafeChildAdd((SecurityElement)thisElem, otherElem, true);
  1043.                     }
  1044.                     else {
  1045.                         SecurityElement newElem;
  1046.                         if (this.IsUnrestricted() || other.IsUnrestricted())
  1047.                             newElem = new SecurityElement(s_str_PermissionUnrestrictedUnion);
  1048.                         else
  1049.                             newElem = new SecurityElement(s_str_PermissionUnion);
  1050.                         newElem.AddAttribute("class", thisElem.Attribute("class"));
  1051.                         SafeChildAdd(newElem, thisElem, false);
  1052.                         SafeChildAdd(newElem, otherElem, true);
  1053.                         this.m_permSet.SetItem(i, newElem);
  1054.                     }
  1055.                 }
  1056.                 else if (thisObj == null) {
  1057.                     if (otherElem != null) {
  1058.                         this.m_permSet.SetItem(i, otherElem.Copy());
  1059.                     }
  1060.                     else if (otherPerm != null) {
  1061.                         PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem(i);
  1062.                         if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !this.m_Unrestricted) {
  1063.                             this.m_permSet.SetItem(i, otherPerm.Copy());
  1064.                         }
  1065.                     }
  1066.                 }
  1067.                 else if (otherObj == null) {
  1068.                     continue;
  1069.                 }
  1070.                 else {
  1071.                     if (thisElem != null)
  1072.                         thisPerm = this.CreatePermission(thisElem, i);
  1073.                     if (otherElem != null)
  1074.                         otherPerm = other.CreatePermission(otherElem, i);
  1075.                    
  1076.                     try {
  1077.                         IPermission unionPerm;
  1078.                         if (thisPerm == null)
  1079.                             unionPerm = otherPerm;
  1080.                         else if (otherPerm == null)
  1081.                             unionPerm = thisPerm;
  1082.                         else
  1083.                             unionPerm = thisPerm.Union(otherPerm);
  1084.                         this.m_permSet.SetItem(i, unionPerm);
  1085.                     }
  1086.                     catch (Exception e) {
  1087.                         if (savedException == null)
  1088.                             savedException = e;
  1089.                     }
  1090.                 }
  1091.             }
  1092.            
  1093.             if (savedException != null)
  1094.                 throw savedException;
  1095.         }
  1096.        
  1097.         public PermissionSet Union(PermissionSet other)
  1098.         {
  1099.             // if other is null or empty, return a clone of myself
  1100.             if (other == null || other.FastIsEmpty()) {
  1101.                 return this.Copy();
  1102.             }
  1103.            
  1104.             if (this.FastIsEmpty()) {
  1105.                 return other.Copy();
  1106.             }
  1107.            
  1108.             int maxMax = -1;
  1109.            
  1110.             PermissionSet pset = new PermissionSet();
  1111.             pset.m_Unrestricted = this.m_Unrestricted || other.m_Unrestricted;
  1112.             if (pset.m_Unrestricted) {
  1113.                 if (CodeAccessSecurityEngine.DoesFullTrustMeanFullTrust()) {
  1114.                     // FullTrustMeansFullTrust is on...so if the result of Union is unrestricted permset, just return
  1115.                     return pset;
  1116.                 }
  1117.                 if (this.m_canUnrestrictedOverride && other.m_canUnrestrictedOverride) {
  1118.                     // Only unrestricted override-able permissions in both this and other ...again, we can return just an unrestricted pset
  1119.                     return pset;
  1120.                 }
  1121.                 if (other.m_canUnrestrictedOverride) {
  1122.                     // Only unrestricted override-able permissions in other...cannot null pset.m_permSet, but don't look at other.m_permSet
  1123.                     // just copy over this.m_permSet
  1124.                     pset.m_permSet = (this.m_permSet != null) ? new TokenBasedSet(this.m_permSet) : null;
  1125.                     return pset;
  1126.                 }
  1127.             }
  1128.            
  1129.             // degenerate case where we look at both this.m_permSet and other.m_permSet
  1130.             this.CheckSet();
  1131.             other.CheckSet();
  1132.             maxMax = this.m_permSet.GetMaxUsedIndex() > other.m_permSet.GetMaxUsedIndex() ? this.m_permSet.GetMaxUsedIndex() : other.m_permSet.GetMaxUsedIndex();
  1133.             pset.m_permSet = new TokenBasedSet();
  1134.            
  1135.            
  1136.            
  1137.             for (int i = 0; i <= maxMax; ++i) {
  1138.                 object thisObj = this.m_permSet.GetItem(i);
  1139.                 IPermission thisPerm = thisObj as IPermission;
  1140.                 ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
  1141.                
  1142.                 object otherObj = other.m_permSet.GetItem(i);
  1143.                 IPermission otherPerm = otherObj as IPermission;
  1144.                 ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
  1145.                
  1146.                 if (thisObj == null && otherObj == null)
  1147.                     continue;
  1148.                
  1149.                 if (thisElem != null && otherElem != null) {
  1150.                     SecurityElement newElem;
  1151.                     if (this.IsUnrestricted() || other.IsUnrestricted())
  1152.                         newElem = new SecurityElement(s_str_PermissionUnrestrictedUnion);
  1153.                     else
  1154.                         newElem = new SecurityElement(s_str_PermissionUnion);
  1155.                     newElem.AddAttribute("class", thisElem.Attribute("class"));
  1156.                     SafeChildAdd(newElem, thisElem, true);
  1157.                     SafeChildAdd(newElem, otherElem, true);
  1158.                     pset.m_permSet.SetItem(i, newElem);
  1159.                 }
  1160.                 else if (thisObj == null) {
  1161.                     if (otherElem != null) {
  1162.                         pset.m_permSet.SetItem(i, otherElem.Copy());
  1163.                         BCLDebug.Assert(PermissionToken.s_tokenSet.GetItem(i) != null, "PermissionToken should already be assigned");
  1164.                     }
  1165.                     else if (otherPerm != null) {
  1166.                         PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem(i);
  1167.                         if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !pset.m_Unrestricted) {
  1168.                             pset.m_permSet.SetItem(i, otherPerm.Copy());
  1169.                             BCLDebug.Assert(PermissionToken.s_tokenSet.GetItem(i) != null, "PermissionToken should already be assigned");
  1170.                         }
  1171.                     }
  1172.                 }
  1173.                 else if (otherObj == null) {
  1174.                     if (thisElem != null) {
  1175.                         pset.m_permSet.SetItem(i, thisElem.Copy());
  1176.                     }
  1177.                     else if (thisPerm != null) {
  1178.                         PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem(i);
  1179.                         if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !pset.m_Unrestricted) {
  1180.                             pset.m_permSet.SetItem(i, thisPerm.Copy());
  1181.                             BCLDebug.Assert(PermissionToken.s_tokenSet.GetItem(i) != null, "PermissionToken should already be assigned");
  1182.                         }
  1183.                     }
  1184.                 }
  1185.                 else {
  1186.                     if (thisElem != null)
  1187.                         thisPerm = this.CreatePermission(thisElem, i);
  1188.                     if (otherElem != null)
  1189.                         otherPerm = other.CreatePermission(otherElem, i);
  1190.                    
  1191.                     IPermission unionPerm;
  1192.                     if (thisPerm == null)
  1193.                         unionPerm = otherPerm;
  1194.                     else if (otherPerm == null)
  1195.                         unionPerm = thisPerm;
  1196.                     else
  1197.                         unionPerm = thisPerm.Union(otherPerm);
  1198.                     pset.m_permSet.SetItem(i, unionPerm);
  1199.                     BCLDebug.Assert(unionPerm == null || PermissionToken.s_tokenSet.GetItem(i) != null, "PermissionToken should already be assigned");
  1200.                 }
  1201.             }
  1202.            
  1203.             return pset;
  1204.         }
  1205.        
  1206.         // Treating the current permission set as a grant set, and the input set as
  1207.         // a set of permissions to be denied, try to cancel out as many permissions
  1208.         // from both sets as possible. For a first cut, any granted permission that
  1209.         // is a safe subset of the corresponding denied permission can result in
  1210.         // that permission being removed from both sides.
  1211.        
  1212.         internal void MergeDeniedSet(PermissionSet denied)
  1213.         {
  1214.             if (denied == null || denied.FastIsEmpty() || this.FastIsEmpty())
  1215.                 return;
  1216.            
  1217.             m_CheckedForNonCas = false;
  1218.            
  1219.             // Check for the unrestricted case: FastIsEmpty() will return false if the PSet is unrestricted, but has no items
  1220.             if (this.m_permSet == null || denied.m_permSet == null)
  1221.                 return;
  1222.             //nothing can be removed
  1223.             int maxIndex = denied.m_permSet.GetMaxUsedIndex() > this.m_permSet.GetMaxUsedIndex() ? this.m_permSet.GetMaxUsedIndex() : denied.m_permSet.GetMaxUsedIndex();
  1224.             for (int i = 0; i <= maxIndex; ++i) {
  1225.                 IPermission deniedPerm = denied.m_permSet.GetItem(i) as IPermission;
  1226.                 if (deniedPerm == null)
  1227.                     continue;
  1228.                
  1229.                 IPermission thisPerm = this.m_permSet.GetItem(i) as IPermission;
  1230.                
  1231.                 if (thisPerm == null && !this.m_Unrestricted) {
  1232.                     denied.m_permSet.SetItem(i, null);
  1233.                     continue;
  1234.                 }
  1235.                
  1236.                 if (thisPerm != null && deniedPerm != null) {
  1237.                     if (thisPerm.IsSubsetOf(deniedPerm)) {
  1238.                         this.m_permSet.SetItem(i, null);
  1239.                         denied.m_permSet.SetItem(i, null);
  1240.                     }
  1241.                 }
  1242.             }
  1243.         }
  1244.        
  1245.         // Returns true if perm is contained in this
  1246.         internal bool Contains(IPermission perm)
  1247.         {
  1248.             if (perm == null)
  1249.                 return true;
  1250.             if (m_Unrestricted && CodeAccessPermission.CanUnrestrictedOverride(perm))
  1251.                 return true;
  1252.             if (FastIsEmpty())
  1253.                 return false;
  1254.            
  1255.             PermissionToken token = PermissionToken.GetToken(perm);
  1256.             object thisObj = this.m_permSet.GetItem(token.m_index);
  1257.             if (thisObj == null)
  1258.                 return perm.IsSubsetOf(null);
  1259.            
  1260.             IPermission thisPerm = GetPermission(token.m_index);
  1261.             if (thisPerm != null)
  1262.                 return perm.IsSubsetOf(thisPerm);
  1263.             else
  1264.                 return perm.IsSubsetOf(null);
  1265.         }
  1266.        
  1267.         [System.Runtime.InteropServices.ComVisible(false)]
  1268.         public override bool Equals(object obj)
  1269.         {
  1270.             // Note: this method is designed to accept both PermissionSet and NamedPermissionSets.
  1271.             // It will compare them based on the values in the base type, thereby ignoring the
  1272.             // name and description of the named permission set.
  1273.            
  1274.             PermissionSet other = obj as PermissionSet;
  1275.            
  1276.             if (other == null)
  1277.                 return false;
  1278.            
  1279.             if (this.m_Unrestricted != other.m_Unrestricted)
  1280.                 return false;
  1281.            
  1282.             CheckSet();
  1283.             other.CheckSet();
  1284.            
  1285.             DecodeAllPermissions();
  1286.             other.DecodeAllPermissions();
  1287.            
  1288.             int maxIndex = Math.Max(this.m_permSet.GetMaxUsedIndex(), other.m_permSet.GetMaxUsedIndex());
  1289.            
  1290.             for (int i = 0; i <= maxIndex; ++i) {
  1291.                 IPermission thisPerm = (IPermission)this.m_permSet.GetItem(i);
  1292.                 IPermission otherPerm = (IPermission)other.m_permSet.GetItem(i);
  1293.                
  1294.                 if (thisPerm == null && otherPerm == null) {
  1295.                     continue;
  1296.                 }
  1297.                 else if (thisPerm == null) {
  1298.                     if (!otherPerm.IsSubsetOf(null))
  1299.                         return false;
  1300.                 }
  1301.                 else if (otherPerm == null) {
  1302.                     if (!thisPerm.IsSubsetOf(null))
  1303.                         return false;
  1304.                 }
  1305.                 else {
  1306.                     if (!thisPerm.Equals(otherPerm))
  1307.                         return false;
  1308.                 }
  1309.             }
  1310.            
  1311.             return true;
  1312.         }
  1313.        
  1314.         [System.Runtime.InteropServices.ComVisible(false)]
  1315.         public override int GetHashCode()
  1316.         {
  1317.             int accumulator;
  1318.            
  1319.             accumulator = this.m_Unrestricted ? -1 : 0;
  1320.            
  1321.             if (this.m_permSet != null) {
  1322.                 DecodeAllPermissions();
  1323.                
  1324.                 int maxIndex = this.m_permSet.GetMaxUsedIndex();
  1325.                
  1326.                 for (int i = m_permSet.GetStartingIndex(); i <= maxIndex; ++i) {
  1327.                     IPermission perm = (IPermission)this.m_permSet.GetItem(i);
  1328.                     if (perm != null) {
  1329.                         accumulator = accumulator ^ perm.GetHashCode();
  1330.                     }
  1331.                 }
  1332.             }
  1333.            
  1334.             return accumulator;
  1335.         }
  1336.        
  1337.         // Mark this method as requiring a security object on the caller's frame
  1338.         // so the caller won't be inlined (which would mess up stack crawling).
  1339.         [DynamicSecurityMethodAttribute()]
  1340.         public void Demand()
  1341.         {
  1342.             if (this.FastIsEmpty())
  1343.                 return;
  1344.             // demanding the empty set always passes.
  1345.             ContainsNonCodeAccessPermissions();
  1346.            
  1347.             if (m_ContainsCas) {
  1348.                 StackCrawlMark stackMark = StackCrawlMark.LookForMyCallersCaller;
  1349.                 CodeAccessSecurityEngine.Check(GetCasOnlySet(), ref stackMark);
  1350.             }
  1351.             if (m_ContainsNonCas) {
  1352.                 DemandNonCAS();
  1353.             }
  1354.         }
  1355.        
  1356.         internal void DemandNonCAS()
  1357.         {
  1358.             ContainsNonCodeAccessPermissions();
  1359.            
  1360.             if (m_ContainsNonCas) {
  1361.                 if (this.m_permSet != null) {
  1362.                     CheckSet();
  1363.                     for (int i = m_permSet.GetStartingIndex(); i <= this.m_permSet.GetMaxUsedIndex(); ++i) {
  1364.                         IPermission currPerm = GetPermission(i);
  1365.                         if (currPerm != null && !(currPerm is CodeAccessPermission))
  1366.                             currPerm.Demand();
  1367.                     }
  1368.                 }
  1369.             }
  1370.         }
  1371.        
  1372.         // Metadata for this method should be flaged with REQ_SQ so that
  1373.         // EE can allocate space on the stack frame for FrameSecurityDescriptor
  1374.        
  1375.         [DynamicSecurityMethodAttribute()]
  1376.         public void Assert()
  1377.         {
  1378.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  1379.             SecurityRuntime.Assert(this, ref stackMark);
  1380.         }
  1381.        
  1382.         // Metadata for this method should be flaged with REQ_SQ so that
  1383.         // EE can allocate space on the stack frame for FrameSecurityDescriptor
  1384.        
  1385.         [DynamicSecurityMethodAttribute()]
  1386.         public void Deny()
  1387.         {
  1388.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  1389.             SecurityRuntime.Deny(this, ref stackMark);
  1390.         }
  1391.        
  1392.         // Metadata for this method should be flaged with REQ_SQ so that
  1393.         // EE can allocate space on the stack frame for FrameSecurityDescriptor
  1394.        
  1395.         [DynamicSecurityMethodAttribute()]
  1396.         public void PermitOnly()
  1397.         {
  1398.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  1399.             SecurityRuntime.PermitOnly(this, ref stackMark);
  1400.         }
  1401.        
  1402.         internal IPermission GetFirstPerm()
  1403.         {
  1404.             IEnumerator enumerator = GetEnumerator();
  1405.             if (!enumerator.MoveNext())
  1406.                 return null;
  1407.             return enumerator.Current as IPermission;
  1408.         }
  1409.        
  1410.         // Returns a deep copy
  1411.         public virtual PermissionSet Copy()
  1412.         {
  1413.             return new PermissionSet(this);
  1414.         }
  1415.        
  1416.         public IEnumerator GetEnumerator()
  1417.         {
  1418.             return new PermissionSetEnumerator(this);
  1419.         }
  1420.        
  1421.         internal PermissionSetEnumeratorInternal GetEnumeratorInternal()
  1422.         {
  1423.             return new PermissionSetEnumeratorInternal(this);
  1424.         }
  1425.        
  1426.         public override string ToString()
  1427.         {
  1428.             return ToXml().ToString();
  1429.         }
  1430.        
  1431.         private void NormalizePermissionSet()
  1432.         {
  1433.             // This function guarantees that all the permissions are placed at
  1434.             // the proper index within the token based sets. This becomes necessary
  1435.             // since these indices are dynamically allocated based on usage order.
  1436.            
  1437.             PermissionSet permSetTemp = new PermissionSet(false);
  1438.            
  1439.             permSetTemp.m_Unrestricted = this.m_Unrestricted;
  1440.            
  1441.             // Move all the normal permissions to the new permission set
  1442.            
  1443.             if (this.m_permSet != null) {
  1444.                 for (int i = m_permSet.GetStartingIndex(); i <= this.m_permSet.GetMaxUsedIndex(); ++i) {
  1445.                     object obj = this.m_permSet.GetItem(i);
  1446.                     IPermission perm = obj as IPermission;
  1447.                     ISecurityElementFactory elem = obj as ISecurityElementFactory;
  1448.                    
  1449.                     if (elem != null)
  1450.                         perm = CreatePerm(elem);
  1451.                     if (perm != null)
  1452.                         permSetTemp.SetPermission(perm);
  1453.                 }
  1454.             }
  1455.            
  1456.             this.m_permSet = permSetTemp.m_permSet;
  1457.         }
  1458.        
  1459.         private bool DecodeXml(byte[] data, HostProtectionResource fullTrustOnlyResources, HostProtectionResource inaccessibleResources)
  1460.         {
  1461.             if (data != null && data.Length > 0) {
  1462.                 FromXml(new Parser(data, Tokenizer.ByteTokenEncoding.UnicodeTokens).GetTopElement());
  1463.             }
  1464.            
  1465.             FilterHostProtectionPermissions(fullTrustOnlyResources, inaccessibleResources);
  1466.            
  1467.             // We call this method from unmanaged to code a set we are going to use declaratively. In
  1468.             // this case, all the lazy evaluation for partial policy resolution is wasted since we'll
  1469.             // need to decode all of these shortly to make the demand for whatever. Therefore, we
  1470.             // pay that price now so that we can calculate whether all the permissions in the set
  1471.             // implement the IUnrestrictedPermission interface (the common case) for use in some
  1472.             // unmanaged optimizations.
  1473.            
  1474.             DecodeAllPermissions();
  1475.            
  1476.             return true;
  1477.         }
  1478.        
  1479.         private void DecodeAllPermissions()
  1480.         {
  1481.             if (m_permSet == null) {
  1482.                 m_allPermissionsDecoded = true;
  1483.                 return;
  1484.             }
  1485.            
  1486.             m_canUnrestrictedOverride = true;
  1487.            
  1488.             int maxIndex = m_permSet.GetMaxUsedIndex();
  1489.             for (int i = m_permSet.GetStartingIndex(); i <= maxIndex; ++i) {
  1490.                 IPermission perm = GetPermission(i);
  1491.                 if (perm != null && !CodeAccessPermission.CanUnrestrictedOverride(perm))
  1492.                     m_canUnrestrictedOverride = false;
  1493.             }
  1494.            
  1495.             #if _DEBUG
  1496.             for (int i = 0; i <= maxIndex; ++i) {
  1497.                 object obj = m_permSet.GetItem(i);
  1498.                 BCLDebug.Assert(obj == null || obj is IPermission || obj is SecurityElement, "After DecodeAllPermissions, everything in m_permSet should be an IPermission");
  1499.             }
  1500.             #endif
  1501.             m_allPermissionsDecoded = true;
  1502.         }
  1503.        
  1504.         internal void FilterHostProtectionPermissions(HostProtectionResource fullTrustOnly, HostProtectionResource inaccessible)
  1505.         {
  1506.             HostProtectionPermission.protectedResources = fullTrustOnly;
  1507.             HostProtectionPermission hpp = (HostProtectionPermission)GetPermission(HostProtectionPermission.GetTokenIndex());
  1508.             if (hpp == null)
  1509.                 return;
  1510.             HostProtectionPermission newHpp = (HostProtectionPermission)hpp.Intersect(new HostProtectionPermission(fullTrustOnly));
  1511.             if (newHpp == null)
  1512.                 RemovePermission(PermissionToken.FindTokenByIndex(HostProtectionPermission.GetTokenIndex()));
  1513.             else if (newHpp.Resources != hpp.Resources)
  1514.                 SetPermission(newHpp);
  1515.         }
  1516.        
  1517.         private bool DecodeUsingSerialization(byte[] data)
  1518.         {
  1519.             MemoryStream ms = new MemoryStream(data);
  1520.             BinaryFormatter formatter = new BinaryFormatter();
  1521.            
  1522.             PermissionSet ps = null;
  1523.            
  1524.             object obj = formatter.Deserialize(ms);
  1525.            
  1526.             if (obj != null) {
  1527.                 ps = (PermissionSet)obj;
  1528.                 this.m_Unrestricted = ps.m_Unrestricted;
  1529.                 this.m_permSet = ps.m_permSet;
  1530.                 this.m_CheckedForNonCas = false;
  1531.                 BCLDebug.Trace("SER", ps.ToString());
  1532.                 return true;
  1533.             }
  1534.             else {
  1535.                 return false;
  1536.             }
  1537.         }
  1538.        
  1539.         public virtual void FromXml(SecurityElement et)
  1540.         {
  1541.             FromXml(et, false, false);
  1542.         }
  1543.        
  1544.         static internal bool IsPermissionTag(string tag, bool allowInternalOnly)
  1545.         {
  1546.             if (tag.Equals(s_str_Permission) || tag.Equals(s_str_IPermission)) {
  1547.                 return true;
  1548.             }
  1549.            
  1550.             if (allowInternalOnly && (tag.Equals(s_str_PermissionUnion) || tag.Equals(s_str_PermissionIntersection) || tag.Equals(s_str_PermissionUnrestrictedIntersection) || tag.Equals(s_str_PermissionUnrestrictedUnion))) {
  1551.                 return true;
  1552.             }
  1553.            
  1554.             return false;
  1555.         }
  1556.        
  1557.         internal virtual void FromXml(SecurityElement et, bool allowInternalOnly, bool ignoreTypeLoadFailures)
  1558.         {
  1559.             if (et == null)
  1560.                 throw new ArgumentNullException("et");
  1561.            
  1562.             if (!et.Tag.Equals(s_str_PermissionSet))
  1563.                 throw new ArgumentException(String.Format(null, Environment.GetResourceString("Argument_InvalidXMLElement"), "PermissionSet", this.GetType().FullName));
  1564.            
  1565.             Reset();
  1566.             m_ignoreTypeLoadFailures = ignoreTypeLoadFailures;
  1567.             m_allPermissionsDecoded = false;
  1568.             m_Unrestricted = XMLUtil.IsUnrestricted(et);
  1569.            
  1570.             if (et.InternalChildren != null) {
  1571.                 int childCount = et.InternalChildren.Count;
  1572.                 for (int i = 0; i < childCount; ++i) {
  1573.                     SecurityElement elem = (SecurityElement)et.Children[i];
  1574.                    
  1575.                     if (IsPermissionTag(elem.Tag, allowInternalOnly)) {
  1576.                         string className = elem.Attribute("class");
  1577.                        
  1578.                         PermissionToken token;
  1579.                         object objectToInsert;
  1580.                        
  1581.                         if (className != null) {
  1582.                             token = PermissionToken.GetToken(className);
  1583.                             if (token == null) {
  1584.                                 objectToInsert = CreatePerm(elem);
  1585.                                 #if _DEBUG
  1586.                                 PermissionToken tokenDebug = PermissionToken.GetToken((IPermission)objectToInsert);
  1587.                                 BCLDebug.Assert(tokenDebug != null && (tokenDebug.m_type & PermissionTokenType.BuiltIn) != 0, "This should only be called for built-ins");
  1588.                                 #endif
  1589.                                 if (objectToInsert != null) {
  1590.                                     BCLDebug.Assert(objectToInsert.GetType().Module.Assembly == System.Reflection.Assembly.GetExecutingAssembly(), "PermissionToken.GetToken returned null for non-mscorlib permission");
  1591.                                     token = PermissionToken.GetToken((IPermission)objectToInsert);
  1592.                                     BCLDebug.Assert((token.m_type & PermissionTokenType.DontKnow) == 0, "We should always know the permission type when getting a token from an instance");
  1593.                                 }
  1594.                             }
  1595.                             else {
  1596.                                 objectToInsert = elem;
  1597.                             }
  1598.                         }
  1599.                         else {
  1600.                             IPermission ip = CreatePerm(elem);
  1601.                             if (ip == null) {
  1602.                                 token = null;
  1603.                                 objectToInsert = null;
  1604.                             }
  1605.                             else {
  1606.                                 token = PermissionToken.GetToken(ip);
  1607.                                 BCLDebug.Assert(PermissionToken.IsTokenProperlyAssigned(ip, token), "PermissionToken was improperly assigned");
  1608.                                 objectToInsert = ip;
  1609.                             }
  1610.                         }
  1611.                        
  1612.                         if (token != null && objectToInsert != null) {
  1613.                             if (m_permSet == null)
  1614.                                 m_permSet = new TokenBasedSet();
  1615.                            
  1616.                             if (this.m_permSet.GetItem(token.m_index) != null) {
  1617.                                 // If there is already something in that slot, let's union them
  1618.                                 // together.
  1619.                                
  1620.                                 IPermission permInSlot;
  1621.                                
  1622.                                 if (this.m_permSet.GetItem(token.m_index) is IPermission)
  1623.                                     permInSlot = (IPermission)this.m_permSet.GetItem(token.m_index);
  1624.                                 else
  1625.                                     permInSlot = CreatePerm((SecurityElement)this.m_permSet.GetItem(token.m_index));
  1626.                                
  1627.                                 if (objectToInsert is IPermission)
  1628.                                     objectToInsert = ((IPermission)objectToInsert).Union(permInSlot);
  1629.                                 else
  1630.                                     objectToInsert = CreatePerm((SecurityElement)objectToInsert).Union(permInSlot);
  1631.                             }
  1632.                            
  1633.                             if (m_Unrestricted && objectToInsert is IPermission && CodeAccessPermission.CanUnrestrictedOverride((IPermission)objectToInsert))
  1634.                                 objectToInsert = null;
  1635.                            
  1636.                             this.m_permSet.SetItem(token.m_index, objectToInsert);
  1637.                         }
  1638.                     }
  1639.                 }
  1640.             }
  1641.         }
  1642.        
  1643.        
  1644.        
  1645.         internal virtual void FromXml(SecurityDocument doc, int position, bool allowInternalOnly)
  1646.         {
  1647.             if (doc == null)
  1648.                 throw new ArgumentNullException("doc");
  1649.            
  1650.             if (!doc.GetTagForElement(position).Equals(s_str_PermissionSet))
  1651.                 throw new ArgumentException(String.Format(null, Environment.GetResourceString("Argument_InvalidXMLElement"), "PermissionSet", this.GetType().FullName));
  1652.            
  1653.             Reset();
  1654.             m_allPermissionsDecoded = false;
  1655.             Exception savedException = null;
  1656.             string strUnrestricted = doc.GetAttributeForElement(position, "Unrestricted");
  1657.             if (strUnrestricted != null)
  1658.                 m_Unrestricted = strUnrestricted.Equals("True") || strUnrestricted.Equals("true") || strUnrestricted.Equals("TRUE");
  1659.             else
  1660.                 m_Unrestricted = false;
  1661.            
  1662.             ArrayList childrenIndices = doc.GetChildrenPositionForElement(position);
  1663.             int childCount = childrenIndices.Count;
  1664.             for (int i = 0; i < childCount; ++i) {
  1665.                 int childIndex = (int)childrenIndices[i];
  1666.                 if (IsPermissionTag(doc.GetTagForElement(childIndex), allowInternalOnly)) {
  1667.                     try {
  1668.                         string className = doc.GetAttributeForElement(childIndex, "class");
  1669.                        
  1670.                         PermissionToken token;
  1671.                         object objectToInsert;
  1672.                        
  1673.                         if (className != null) {
  1674.                             token = PermissionToken.GetToken(className);
  1675.                             if (token == null) {
  1676.                                 objectToInsert = CreatePerm(doc.GetElement(childIndex, true));
  1677.                                
  1678.                                 if (objectToInsert != null) {
  1679.                                     #if _DEBUG
  1680.                                     PermissionToken tokenDebug = PermissionToken.GetToken((IPermission)objectToInsert);
  1681.                                     BCLDebug.Assert((tokenDebug != null), "PermissionToken.GetToken returned null ");
  1682.                                     BCLDebug.Assert((tokenDebug.m_type & PermissionTokenType.BuiltIn) != 0, "This should only be called for built-ins");
  1683.                                     #endif
  1684.                                     BCLDebug.Assert(objectToInsert.GetType().Module.Assembly == System.Reflection.Assembly.GetExecutingAssembly(), "PermissionToken.GetToken returned null for non-mscorlib permission");
  1685.                                     token = PermissionToken.GetToken((IPermission)objectToInsert);
  1686.                                     BCLDebug.Assert((token != null), "PermissionToken.GetToken returned null ");
  1687.                                     BCLDebug.Assert((token.m_type & PermissionTokenType.DontKnow) == 0, "We should always know the permission type when getting a token from an instance");
  1688.                                 }
  1689.                             }
  1690.                             else {
  1691.                                 objectToInsert = ((ISecurityElementFactory)new SecurityDocumentElement(doc, childIndex)).CreateSecurityElement();
  1692.                             }
  1693.                         }
  1694.                         else {
  1695.                             IPermission ip = CreatePerm(doc.GetElement(childIndex, true));
  1696.                             if (ip == null) {
  1697.                                 token = null;
  1698.                                 objectToInsert = null;
  1699.                             }
  1700.                             else {
  1701.                                 token = PermissionToken.GetToken(ip);
  1702.                                 BCLDebug.Assert(PermissionToken.IsTokenProperlyAssigned(ip, token), "PermissionToken was improperly assigned");
  1703.                                 objectToInsert = ip;
  1704.                             }
  1705.                         }
  1706.                        
  1707.                         if (token != null && objectToInsert != null) {
  1708.                             if (m_permSet == null)
  1709.                                 m_permSet = new TokenBasedSet();
  1710.                            
  1711.                             IPermission permInSlot = null;
  1712.                             if (this.m_permSet.GetItem(token.m_index) != null) {
  1713.                                 // If there is already something in that slot, let's union them
  1714.                                 // together.
  1715.                                
  1716.                                 if (this.m_permSet.GetItem(token.m_index) is IPermission)
  1717.                                     permInSlot = (IPermission)this.m_permSet.GetItem(token.m_index);
  1718.                                 else
  1719.                                     permInSlot = CreatePerm(this.m_permSet.GetItem(token.m_index));
  1720.                             }
  1721.                            
  1722.                             if (permInSlot != null) {
  1723.                                 if (objectToInsert is IPermission)
  1724.                                     objectToInsert = permInSlot.Union((IPermission)objectToInsert);
  1725.                                 else
  1726.                                     objectToInsert = permInSlot.Union(CreatePerm(objectToInsert));
  1727.                             }
  1728.                            
  1729.                             if (m_Unrestricted && objectToInsert is IPermission && CodeAccessPermission.CanUnrestrictedOverride((IPermission)objectToInsert))
  1730.                                 objectToInsert = null;
  1731.                            
  1732.                             this.m_permSet.SetItem(token.m_index, objectToInsert);
  1733.                         }
  1734.                     }
  1735.                     catch (Exception e) {
  1736.                         #if _DEBUG
  1737.                         if (debug)
  1738.                             DEBUG_WRITE("error while decoding permission set =\n" + e.ToString());
  1739.                         #endif
  1740.                         if (savedException == null)
  1741.                             savedException = e;
  1742.                        
  1743.                     }
  1744.                 }
  1745.             }
  1746.            
  1747.             if (savedException != null)
  1748.                 throw savedException;
  1749.            
  1750.         }
  1751.        
  1752.         private IPermission CreatePerm(object obj)
  1753.         {
  1754.             return CreatePerm(obj, m_ignoreTypeLoadFailures);
  1755.         }
  1756.         static internal IPermission CreatePerm(object obj, bool ignoreTypeLoadFailures)
  1757.         {
  1758.             SecurityElement el = obj as SecurityElement;
  1759.             ISecurityElementFactory isf = obj as ISecurityElementFactory;
  1760.             if (el == null && isf != null) {
  1761.                 el = isf.CreateSecurityElement();
  1762.             }
  1763.            
  1764.             IEnumerator enumerator;
  1765.             IPermission finalPerm = null;
  1766.            
  1767.             switch (el.Tag) {
  1768.                 case s_str_PermissionUnion:
  1769.                     enumerator = el.Children.GetEnumerator();
  1770.                     while (enumerator.MoveNext()) {
  1771.                         IPermission tempPerm = CreatePerm((SecurityElement)enumerator.Current, ignoreTypeLoadFailures);
  1772.                        
  1773.                         if (finalPerm != null)
  1774.                             finalPerm = finalPerm.Union(tempPerm);
  1775.                         else
  1776.                             finalPerm = tempPerm;
  1777.                     }
  1778.                     break;
  1779.                 case s_str_PermissionIntersection:
  1780.                    
  1781.                     enumerator = el.Children.GetEnumerator();
  1782.                     while (enumerator.MoveNext()) {
  1783.                         IPermission tempPerm = CreatePerm((SecurityElement)enumerator.Current, ignoreTypeLoadFailures);
  1784.                        
  1785.                         if (finalPerm != null)
  1786.                             finalPerm = finalPerm.Intersect(tempPerm);
  1787.                         else
  1788.                             finalPerm = tempPerm;
  1789.                        
  1790.                         if (finalPerm == null)
  1791.                             return null;
  1792.                     }
  1793.                     break;
  1794.                 case s_str_PermissionUnrestrictedUnion:
  1795.                    
  1796.                     enumerator = el.Children.GetEnumerator();
  1797.                     bool first = true;
  1798.                     while (enumerator.MoveNext()) {
  1799.                         IPermission tempPerm = CreatePerm((SecurityElement)enumerator.Current, ignoreTypeLoadFailures);
  1800.                        
  1801.                         if (tempPerm == null)
  1802.                             continue;
  1803.                        
  1804.                         PermissionToken token = PermissionToken.GetToken(tempPerm);
  1805.                        
  1806.                         BCLDebug.Assert((token.m_type & PermissionTokenType.DontKnow) == 0, "We should know the permission type already");
  1807.                        
  1808.                         if ((token.m_type & PermissionTokenType.IUnrestricted) != 0) {
  1809.                             finalPerm = XMLUtil.CreatePermission(GetPermissionElement((SecurityElement)enumerator.Current), PermissionState.Unrestricted, ignoreTypeLoadFailures);
  1810.                             first = false;
  1811.                             break;
  1812.                         }
  1813.                         else {
  1814.                             BCLDebug.Assert(tempPerm != null, "We should only come here if we have a real permission");
  1815.                             if (first)
  1816.                                 finalPerm = tempPerm;
  1817.                             else
  1818.                                 finalPerm = tempPerm.Union(finalPerm);
  1819.                             first = false;
  1820.                         }
  1821.                     }
  1822.                     break;
  1823.                 case s_str_PermissionUnrestrictedIntersection:
  1824.                    
  1825.                     enumerator = el.Children.GetEnumerator();
  1826.                     while (enumerator.MoveNext()) {
  1827.                         IPermission tempPerm = CreatePerm((SecurityElement)enumerator.Current, ignoreTypeLoadFailures);
  1828.                        
  1829.                         if (tempPerm == null)
  1830.                             return null;
  1831.                        
  1832.                         PermissionToken token = PermissionToken.GetToken(tempPerm);
  1833.                        
  1834.                         BCLDebug.Assert((token.m_type & PermissionTokenType.DontKnow) == 0, "We should know the permission type already");
  1835.                        
  1836.                         if ((token.m_type & PermissionTokenType.IUnrestricted) != 0) {
  1837.                             if (finalPerm != null)
  1838.                                 finalPerm = tempPerm.Intersect(finalPerm);
  1839.                             else
  1840.                                 finalPerm = tempPerm;
  1841.                         }
  1842.                         else {
  1843.                             finalPerm = null;
  1844.                         }
  1845.                        
  1846.                         if (finalPerm == null)
  1847.                             return null;
  1848.                     }
  1849.                     break;
  1850.                 case "IPermission":
  1851.                 case "Permission":
  1852.                    
  1853.                     finalPerm = el.ToPermission(ignoreTypeLoadFailures);
  1854.                     break;
  1855.                 default:
  1856.                    
  1857.                     BCLDebug.Assert(false, "Unrecognized case found during permission creation");
  1858.                     break;
  1859.             }
  1860.            
  1861.             #if FALSE
  1862.             // This is useful to enable to detect when we load permissions outside of mscorlib
  1863.            
  1864.             if (finalPerm != null) {
  1865.                 System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
  1866.                 if (asm != finalPerm.GetType().Module.Assembly)
  1867.                     System.Diagnostics.Debugger.Break();
  1868.             }
  1869.             #endif
  1870.             return finalPerm;
  1871.         }
  1872.        
  1873.         internal IPermission CreatePermission(object obj, int index)
  1874.         {
  1875.             IPermission perm = CreatePerm(obj);
  1876.             if (perm == null)
  1877.                 return null;
  1878.            
  1879.             // See if the PermissionSet.m_Unrestricted flag covers this permission
  1880.             if (m_Unrestricted && CodeAccessPermission.CanUnrestrictedOverride(perm))
  1881.                 perm = null;
  1882.            
  1883.             // Store the decoded result
  1884.             CheckSet();
  1885.             m_permSet.SetItem(index, perm);
  1886.            
  1887.             // Do some consistency checks
  1888.             BCLDebug.Assert(perm == null || PermissionToken.IsTokenProperlyAssigned(perm, PermissionToken.GetToken(perm)), "PermissionToken was improperly assigned");
  1889.             if (perm != null) {
  1890.                 PermissionToken permToken = PermissionToken.GetToken(perm);
  1891.                 if (permToken != null && permToken.m_index != index)
  1892.                     throw new ArgumentException(Environment.GetResourceString("Argument_UnableToGeneratePermissionSet"));
  1893.             }
  1894.            
  1895.            
  1896.             return perm;
  1897.         }
  1898.        
  1899.         private static SecurityElement GetPermissionElement(SecurityElement el)
  1900.         {
  1901.             switch (el.Tag) {
  1902.                 case "IPermission":
  1903.                 case "Permission":
  1904.                     return el;
  1905.             }
  1906.             IEnumerator enumerator = el.Children.GetEnumerator();
  1907.             if (enumerator.MoveNext())
  1908.                 return GetPermissionElement((SecurityElement)enumerator.Current);
  1909.             BCLDebug.Assert(false, "No Permission or IPermission tag found");
  1910.             return null;
  1911.         }
  1912.        
  1913.         // internal helper which takes in the hardcoded permission name to avoid lookup at runtime
  1914.         // can be called from classes that derive from PermissionSet
  1915.         internal SecurityElement ToXml(string permName)
  1916.         {
  1917.             SecurityElement elTrunk = new SecurityElement("PermissionSet");
  1918.             elTrunk.AddAttribute("class", permName);
  1919.            
  1920.             elTrunk.AddAttribute("version", "1");
  1921.            
  1922.             PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);
  1923.            
  1924.             if (m_Unrestricted) {
  1925.                 elTrunk.AddAttribute(s_str_Unrestricted, "true");
  1926.             }
  1927.            
  1928.             while (enumerator.MoveNext()) {
  1929.                 IPermission perm = (IPermission)enumerator.Current;
  1930.                
  1931.                 if (!m_Unrestricted || !CodeAccessPermission.CanUnrestrictedOverride(perm))
  1932.                     elTrunk.AddChild(perm.ToXml());
  1933.             }
  1934.             return elTrunk;
  1935.         }
  1936.        
  1937.         internal SecurityElement InternalToXml()
  1938.         {
  1939.             SecurityElement elTrunk = new SecurityElement("PermissionSet");
  1940.             elTrunk.AddAttribute("class", this.GetType().FullName);
  1941.             elTrunk.AddAttribute("version", "1");
  1942.            
  1943.             if (m_Unrestricted) {
  1944.                 elTrunk.AddAttribute(s_str_Unrestricted, "true");
  1945.             }
  1946.            
  1947.             if (this.m_permSet != null) {
  1948.                 int maxIndex = this.m_permSet.GetMaxUsedIndex();
  1949.                
  1950.                 for (int i = m_permSet.GetStartingIndex(); i <= maxIndex; ++i) {
  1951.                     object obj = this.m_permSet.GetItem(i);
  1952.                     if (obj != null) {
  1953.                         if (obj is IPermission) {
  1954.                             if (!m_Unrestricted || !CodeAccessPermission.CanUnrestrictedOverride((IPermission)obj))
  1955.                                 elTrunk.AddChild(((IPermission)obj).ToXml());
  1956.                         }
  1957.                         else {
  1958.                             elTrunk.AddChild((SecurityElement)obj);
  1959.                         }
  1960.                     }
  1961.                    
  1962.                 }
  1963.             }
  1964.             return elTrunk;
  1965.         }
  1966.        
  1967.         public virtual SecurityElement ToXml()
  1968.         {
  1969.             // If you hit this assert then most likely you are trying to change the name of this class.
  1970.             // This is ok as long as you change the hard coded string above and change the assert below.
  1971.             BCLDebug.Assert(this.GetType().FullName.Equals("System.Security.PermissionSet"), "Class name changed! Was: System.Security.PermissionSet Should be:" + this.GetType().FullName);
  1972.            
  1973.             return ToXml("System.Security.PermissionSet");
  1974.         }
  1975.        
  1976.         internal byte[] EncodeUsingSerialization()
  1977.         {
  1978.             MemoryStream ms = new MemoryStream();
  1979.             new BinaryFormatter().Serialize(ms, this);
  1980.             return ms.ToArray();
  1981.         }
  1982.        
  1983.         internal byte[] EncodeXml()
  1984.         {
  1985.             MemoryStream ms = new MemoryStream();
  1986.             BinaryWriter writer = new BinaryWriter(ms, Encoding.Unicode);
  1987.             writer.Write(this.ToXml().ToString());
  1988.             writer.Flush();
  1989.            
  1990.             // The BinaryWriter is going to place
  1991.             // two bytes indicating a Unicode stream.
  1992.             // We want to chop those off before returning
  1993.             // the bytes out.
  1994.            
  1995.             ms.Position = 2;
  1996.             int countBytes = (int)ms.Length - 2;
  1997.             byte[] retval = new byte[countBytes];
  1998.             ms.Read(retval, 0, retval.Length);
  1999.             return retval;
  2000.         }
  2001.        
  2002.        
  2003.         /// <internalonly/>
  2004.         public static byte[] ConvertPermissionSet(string inFormat, byte[] inData, string outFormat)
  2005.         {
  2006.             if (inData == null)
  2007.                 return null;
  2008.             if (inFormat == null)
  2009.                 throw new ArgumentNullException("inFormat");
  2010.             if (outFormat == null)
  2011.                 throw new ArgumentNullException("outFormat");
  2012.            
  2013.             PermissionSet permSet = new PermissionSet(false);
  2014.            
  2015.             inFormat = String.SmallCharToUpper(inFormat);
  2016.             outFormat = String.SmallCharToUpper(outFormat);
  2017.            
  2018.             if (inFormat.Equals("XMLASCII") || inFormat.Equals("XML")) {
  2019.                 permSet.FromXml(new Parser(inData, Tokenizer.ByteTokenEncoding.ByteTokens).GetTopElement());
  2020.             }
  2021.             else if (inFormat.Equals("XMLUNICODE")) {
  2022.                 permSet.FromXml(new Parser(inData, Tokenizer.ByteTokenEncoding.UnicodeTokens).GetTopElement());
  2023.             }
  2024.             else if (inFormat.Equals("BINARY")) {
  2025.                 permSet.DecodeUsingSerialization(inData);
  2026.             }
  2027.             else {
  2028.                 return null;
  2029.             }
  2030.            
  2031.             if (outFormat.Equals("XMLASCII") || outFormat.Equals("XML")) {
  2032.                 MemoryStream ms = new MemoryStream();
  2033.                 StreamWriter writer = new StreamWriter(ms, Encoding.ASCII);
  2034.                 writer.Write(permSet.ToXml().ToString());
  2035.                 writer.Flush();
  2036.                 return ms.ToArray();
  2037.             }
  2038.             else if (outFormat.Equals("XMLUNICODE")) {
  2039.                 MemoryStream ms = new MemoryStream();
  2040.                 StreamWriter writer = new StreamWriter(ms, Encoding.Unicode);
  2041.                 writer.Write(permSet.ToXml().ToString());
  2042.                 writer.Flush();
  2043.                
  2044.                 ms.Position = 2;
  2045.                 int countBytes = (int)ms.Length - 2;
  2046.                 byte[] retval = new byte[countBytes];
  2047.                 ms.Read(retval, 0, retval.Length);
  2048.                 return retval;
  2049.             }
  2050.             else if (outFormat.Equals("BINARY")) {
  2051.                 return permSet.EncodeUsingSerialization();
  2052.             }
  2053.             else {
  2054.                 return null;
  2055.             }
  2056.         }
  2057.        
  2058.        
  2059.         // Determines whether the permission set contains any non-code access
  2060.         // security permissions.
  2061.         public bool ContainsNonCodeAccessPermissions()
  2062.         {
  2063.             if (m_CheckedForNonCas)
  2064.                 return m_ContainsNonCas;
  2065.            
  2066.             lock (this) {
  2067.                 if (m_CheckedForNonCas)
  2068.                     return m_ContainsNonCas;
  2069.                
  2070.                 m_ContainsCas = false;
  2071.                 m_ContainsNonCas = false;
  2072.                
  2073.                 if (IsUnrestricted())
  2074.                     m_ContainsCas = true;
  2075.                
  2076.                 if (this.m_permSet != null) {
  2077.                     PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);
  2078.                    
  2079.                     while (enumerator.MoveNext() && (!m_ContainsCas || !m_ContainsNonCas)) {
  2080.                         IPermission perm = enumerator.Current as IPermission;
  2081.                        
  2082.                         if (perm != null) {
  2083.                             if (perm is CodeAccessPermission)
  2084.                                 m_ContainsCas = true;
  2085.                             else
  2086.                                 m_ContainsNonCas = true;
  2087.                         }
  2088.                     }
  2089.                 }
  2090.                
  2091.                 m_CheckedForNonCas = true;
  2092.             }
  2093.            
  2094.             return m_ContainsNonCas;
  2095.         }
  2096.        
  2097.         // Returns a permission set containing only CAS-permissions. If possible
  2098.         // this is just the input set, otherwise a new set is allocated.
  2099.         private PermissionSet GetCasOnlySet()
  2100.         {
  2101.             if (!m_ContainsNonCas)
  2102.                 return this;
  2103.            
  2104.             if (IsUnrestricted())
  2105.                 return this;
  2106.            
  2107.             PermissionSet pset = new PermissionSet(false);
  2108.            
  2109.             PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);
  2110.            
  2111.             while (enumerator.MoveNext()) {
  2112.                 IPermission perm = (IPermission)enumerator.Current;
  2113.                
  2114.                 if (perm is CodeAccessPermission)
  2115.                     pset.AddPermission(perm);
  2116.             }
  2117.            
  2118.             pset.m_CheckedForNonCas = true;
  2119.             pset.m_ContainsCas = !pset.IsEmpty();
  2120.             pset.m_ContainsNonCas = false;
  2121.            
  2122.             return pset;
  2123.         }
  2124.        
  2125.         private const string s_str_PermissionSet = "PermissionSet";
  2126.         private const string s_str_Permission = "Permission";
  2127.         private const string s_str_IPermission = "IPermission";
  2128.         private const string s_str_Unrestricted = "Unrestricted";
  2129.         private const string s_str_PermissionUnion = "PermissionUnion";
  2130.         private const string s_str_PermissionIntersection = "PermissionIntersection";
  2131.         private const string s_str_PermissionUnrestrictedUnion = "PermissionUnrestrictedUnion";
  2132.         private const string s_str_PermissionUnrestrictedIntersection = "PermissionUnrestrictedIntersection";
  2133.        
  2134.         // Internal routine used to setup a special security context
  2135.         // for creating and manipulated security custom attributes
  2136.         // that we use when the Runtime is hosted.
  2137.        
  2138.         private static void SetupSecurity()
  2139.         {
  2140.             PolicyLevel level = PolicyLevel.CreateAppDomainLevel();
  2141.            
  2142.             CodeGroup rootGroup = new UnionCodeGroup(new AllMembershipCondition(), level.GetNamedPermissionSet("Execution"));
  2143.            
  2144.             StrongNamePublicKeyBlob microsoftBlob = new StrongNamePublicKeyBlob(AssemblyRef.MicrosoftPublicKeyFull);
  2145.             CodeGroup microsoftGroup = new UnionCodeGroup(new StrongNameMembershipCondition(microsoftBlob, null, null), level.GetNamedPermissionSet("FullTrust"));
  2146.            
  2147.             StrongNamePublicKeyBlob ecmaBlob = new StrongNamePublicKeyBlob(AssemblyRef.EcmaPublicKeyFull);
  2148.             CodeGroup ecmaGroup = new UnionCodeGroup(new StrongNameMembershipCondition(ecmaBlob, null, null), level.GetNamedPermissionSet("FullTrust"));
  2149.            
  2150.             CodeGroup gacGroup = new UnionCodeGroup(new GacMembershipCondition(), level.GetNamedPermissionSet("FullTrust"));
  2151.            
  2152.             rootGroup.AddChild(microsoftGroup);
  2153.             rootGroup.AddChild(ecmaGroup);
  2154.             rootGroup.AddChild(gacGroup);
  2155.            
  2156.             level.RootCodeGroup = rootGroup;
  2157.            
  2158.             try {
  2159.                 AppDomain.CurrentDomain.SetAppDomainPolicy(level);
  2160.             }
  2161.             catch (PolicyException) {
  2162.             }
  2163.         }
  2164.        
  2165.         // Internal routine used by CreateSerialized to add a permission to the set
  2166.         private static void MergePermission(IPermission perm, bool separateCasFromNonCas, ref PermissionSet casPset, ref PermissionSet nonCasPset)
  2167.         {
  2168.             if (perm == null)
  2169.                 return;
  2170.            
  2171.             if (!separateCasFromNonCas || perm is CodeAccessPermission) {
  2172.                 if (casPset == null)
  2173.                     casPset = new PermissionSet(false);
  2174.                 IPermission oldPerm = casPset.GetPermission(perm);
  2175.                 IPermission unionPerm = casPset.AddPermission(perm);
  2176.                 if (oldPerm != null && !oldPerm.IsSubsetOf(unionPerm))
  2177.                     throw new NotSupportedException(Environment.GetResourceString("NotSupported_DeclarativeUnion"));
  2178.             }
  2179.             else {
  2180.                 if (nonCasPset == null)
  2181.                     nonCasPset = new PermissionSet(false);
  2182.                 IPermission oldPerm = nonCasPset.GetPermission(perm);
  2183.                 IPermission unionPerm = nonCasPset.AddPermission(perm);
  2184.                 if (oldPerm != null && !oldPerm.IsSubsetOf(unionPerm))
  2185.                     throw new NotSupportedException(Environment.GetResourceString("NotSupported_DeclarativeUnion"));
  2186.             }
  2187.         }
  2188.        
  2189.         // Converts an array of SecurityAttributes to a PermissionSet
  2190.         [ResourceExposure(ResourceScope.Machine)]
  2191.         // Reading these attributes can load files.
  2192.         [ResourceConsumption(ResourceScope.Machine)]
  2193.         private static byte[] CreateSerialized(object[] attrs, bool serialize, ref byte[] nonCasBlob, out PermissionSet casPset, HostProtectionResource fullTrustOnlyResources)
  2194.         {
  2195.             // Create two new (empty) sets.
  2196.             casPset = null;
  2197.             PermissionSet nonCasPset = null;
  2198.            
  2199.             // Most security attributes generate a single permission. The
  2200.             // PermissionSetAttribute class generates an entire permission set we
  2201.             // need to merge, however.
  2202.             for (int i = 0; i < attrs.Length; i++) {
  2203.                 BCLDebug.Assert(i == 0 || ((SecurityAttribute)attrs[i]).m_action == ((SecurityAttribute)attrs[i - 1]).m_action, "Mixed SecurityActions");
  2204.                 if (attrs[i] is PermissionSetAttribute) {
  2205.                     PermissionSet pset = ((PermissionSetAttribute)attrs[i]).CreatePermissionSet();
  2206.                     if (pset == null)
  2207.                         throw new ArgumentException(Environment.GetResourceString("Argument_UnableToGeneratePermissionSet"));
  2208.                    
  2209.                     PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(pset);
  2210.                    
  2211.                     while (enumerator.MoveNext()) {
  2212.                         IPermission perm = (IPermission)enumerator.Current;
  2213.                         MergePermission(perm, serialize, ref casPset, ref nonCasPset);
  2214.                     }
  2215.                    
  2216.                     if (casPset == null)
  2217.                         casPset = new PermissionSet(false);
  2218.                     if (pset.IsUnrestricted())
  2219.                         casPset.SetUnrestricted(true);
  2220.                 }
  2221.                 else {
  2222.                     IPermission perm = ((SecurityAttribute)attrs[i]).CreatePermission();
  2223.                     MergePermission(perm, serialize, ref casPset, ref nonCasPset);
  2224.                 }
  2225.             }
  2226.             BCLDebug.Assert(serialize || nonCasPset == null, "We shouldn't separate nonCAS permissions unless fSerialize is true");
  2227.            
  2228.             // Filter HostProtection permission
  2229.             if (casPset != null) {
  2230.                 casPset.FilterHostProtectionPermissions(fullTrustOnlyResources, HostProtectionResource.None);
  2231.                 casPset.ContainsNonCodeAccessPermissions();
  2232.                 // make sure all declarative PermissionSets are checked for non-CAS so we can just check the flag from native code
  2233.             }
  2234.             if (nonCasPset != null) {
  2235.                 nonCasPset.FilterHostProtectionPermissions(fullTrustOnlyResources, HostProtectionResource.None);
  2236.                 nonCasPset.ContainsNonCodeAccessPermissions();
  2237.                 // make sure all declarative PermissionSets are checked for non-CAS so we can just check the flag from native code
  2238.             }
  2239.            
  2240.             // Serialize the set(s).
  2241.             byte[] casBlob = null;
  2242.             nonCasBlob = null;
  2243.             if (serialize) {
  2244.                 if (casPset != null)
  2245.                     casBlob = casPset.EncodeXml();
  2246.                 if (nonCasPset != null)
  2247.                     nonCasBlob = nonCasPset.EncodeXml();
  2248.             }
  2249.             return casBlob;
  2250.         }
  2251.        
  2252.         /// <internalonly/>
  2253.         void IDeserializationCallback.OnDeserialization(object sender)
  2254.         {
  2255.             NormalizePermissionSet();
  2256.             m_CheckedForNonCas = false;
  2257.         }
  2258.        
  2259.         public static void RevertAssert()
  2260.         {
  2261.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  2262.             SecurityRuntime.RevertAssert(ref stackMark);
  2263.         }
  2264.        
  2265.        
  2266.         static internal PermissionSet RemoveRefusedPermissionSet(PermissionSet assertSet, PermissionSet refusedSet, out bool bFailedToCompress)
  2267.         {
  2268.             BCLDebug.Assert((assertSet == null || !assertSet.IsUnrestricted()), "Cannot be unrestricted here");
  2269.             PermissionSet retPs = null;
  2270.             bFailedToCompress = false;
  2271.             if (assertSet == null)
  2272.                 return null;
  2273.             if (refusedSet != null) {
  2274.                 if (refusedSet.IsUnrestricted())
  2275.                     return null;
  2276.                 // we're refusing everything...cannot assert anything now.
  2277.                 PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(refusedSet);
  2278.                 while (enumerator.MoveNext()) {
  2279.                     CodeAccessPermission refusedPerm = (CodeAccessPermission)enumerator.Current;
  2280.                     int i = enumerator.GetCurrentIndex();
  2281.                     if (refusedPerm != null) {
  2282.                         CodeAccessPermission perm = (CodeAccessPermission)assertSet.GetPermission(i);
  2283.                         try {
  2284.                             if (refusedPerm.Intersect(perm) != null) {
  2285.                                 if (refusedPerm.Equals(perm)) {
  2286.                                     if (retPs == null)
  2287.                                         retPs = assertSet.Copy();
  2288.                                    
  2289.                                     retPs.RemovePermission(i);
  2290.                                 }
  2291.                                 else {
  2292.                                     // Asserting a permission, part of which is already denied/refused
  2293.                                     // cannot compress this assert
  2294.                                     bFailedToCompress = true;
  2295.                                     return assertSet;
  2296.                                 }
  2297.                             }
  2298.                         }
  2299.                         catch (ArgumentException) {
  2300.                             // Any exception during removing a refused set from assert set => we play it safe and not assert that perm
  2301.                             if (retPs == null)
  2302.                                 retPs = assertSet.Copy();
  2303.                             retPs.RemovePermission(i);
  2304.                         }
  2305.                     }
  2306.                 }
  2307.             }
  2308.             if (retPs != null)
  2309.                 return retPs;
  2310.             return assertSet;
  2311.         }
  2312.        
  2313.         static internal void RemoveAssertedPermissionSet(PermissionSet demandSet, PermissionSet assertSet, out PermissionSet alteredDemandSet)
  2314.         {
  2315.             BCLDebug.Assert(!assertSet.IsUnrestricted(), "Cannot call this function if assertSet is unrestricted");
  2316.             alteredDemandSet = null;
  2317.            
  2318.             PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(demandSet);
  2319.             while (enumerator.MoveNext()) {
  2320.                 CodeAccessPermission demandDerm = (CodeAccessPermission)enumerator.Current;
  2321.                 int i = enumerator.GetCurrentIndex();
  2322.                 if (demandDerm != null) {
  2323.                     CodeAccessPermission assertPerm = (CodeAccessPermission)assertSet.GetPermission(i);
  2324.                     try {
  2325.                         if (demandDerm.CheckAssert(assertPerm)) {
  2326.                             if (alteredDemandSet == null)
  2327.                                 alteredDemandSet = demandSet.Copy();
  2328.                            
  2329.                             alteredDemandSet.RemovePermission(i);
  2330.                         }
  2331.                     }
  2332.                     catch (ArgumentException) {
  2333.                     }
  2334.                 }
  2335.             }
  2336.             return;
  2337.         }
  2338.         static internal bool IsIntersectingAssertedPermissions(PermissionSet assertSet1, PermissionSet assertSet2)
  2339.         {
  2340.             bool isIntersecting = false;
  2341.             if (assertSet1 != null && assertSet2 != null) {
  2342.                 PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(assertSet2);
  2343.                 while (enumerator.MoveNext()) {
  2344.                     CodeAccessPermission perm2 = (CodeAccessPermission)enumerator.Current;
  2345.                     int i = enumerator.GetCurrentIndex();
  2346.                     if (perm2 != null) {
  2347.                         CodeAccessPermission perm1 = (CodeAccessPermission)assertSet1.GetPermission(i);
  2348.                         try {
  2349.                             if (perm1 != null && !perm1.Equals(perm2)) {
  2350.                                 isIntersecting = true;
  2351.                                 // Same type of permission, but with different flags or something - cannot union them
  2352.                             }
  2353.                         }
  2354.                         catch (ArgumentException) {
  2355.                             isIntersecting = true;
  2356.                             //assume worst case
  2357.                         }
  2358.                     }
  2359.                 }
  2360.             }
  2361.             return isIntersecting;
  2362.            
  2363.         }
  2364.        
  2365.         internal bool IgnoreTypeLoadFailures {
  2366.             set { m_ignoreTypeLoadFailures = value; }
  2367.         }
  2368.     }
  2369. }

Developer Fusion