mscorlib(4.0.0.0) API with additions
CompressedStack.cs
1 using System.Collections;
7 using System.Security;
8 
9 namespace System.Threading
10 {
12  [Serializable]
13  public sealed class CompressedStack : ISerializable
14  {
15  internal class CompressedStackRunData
16  {
17  internal CompressedStack cs;
18 
19  internal ContextCallback callBack;
20 
21  internal object state;
22 
23  internal CompressedStackSwitcher cssw;
24 
25  internal CompressedStackRunData(CompressedStack cs, ContextCallback cb, object state)
26  {
27  this.cs = cs;
28  callBack = cb;
29  this.state = state;
30  cssw = default(CompressedStackSwitcher);
31  }
32  }
33 
34  private volatile PermissionListSet m_pls;
35 
36  [SecurityCritical]
37  private volatile SafeCompressedStackHandle m_csHandle;
38 
39  private bool m_canSkipEvaluation;
40 
41  internal static volatile RuntimeHelpers.TryCode tryCode;
42 
43  internal static volatile RuntimeHelpers.CleanupCode cleanupCode;
44 
45  internal bool CanSkipEvaluation
46  {
47  get
48  {
49  return m_canSkipEvaluation;
50  }
51  private set
52  {
53  m_canSkipEvaluation = value;
54  }
55  }
56 
57  internal PermissionListSet PLS => m_pls;
58 
59  internal SafeCompressedStackHandle CompressedStackHandle
60  {
61  [SecurityCritical]
62  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
63  get
64  {
65  return m_csHandle;
66  }
67  [SecurityCritical]
68  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
69  private set
70  {
71  m_csHandle = value;
72  }
73  }
74 
75  [SecurityCritical]
76  internal CompressedStack(SafeCompressedStackHandle csHandle)
77  {
78  m_csHandle = csHandle;
79  }
80 
81  [SecurityCritical]
82  private CompressedStack(SafeCompressedStackHandle csHandle, PermissionListSet pls)
83  {
84  m_csHandle = csHandle;
85  m_pls = pls;
86  }
87 
93  [SecurityCritical]
95  {
96  if (info == null)
97  {
98  throw new ArgumentNullException("info");
99  }
100  CompleteConstruction(null);
101  info.AddValue("PLS", m_pls);
102  }
103 
104  private CompressedStack(SerializationInfo info, StreamingContext context)
105  {
106  m_pls = (PermissionListSet)info.GetValue("PLS", typeof(PermissionListSet));
107  }
108 
112  [MethodImpl(MethodImplOptions.NoInlining)]
113  [SecurityCritical]
115  {
116  StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
117  return GetCompressedStack(ref stackMark);
118  }
119 
120  [SecurityCritical]
121  internal static CompressedStack GetCompressedStack(ref StackCrawlMark stackMark)
122  {
123  CompressedStack innerCS = null;
124  CompressedStack compressedStack;
125  if (CodeAccessSecurityEngine.QuickCheckForAllDemands())
126  {
127  compressedStack = new CompressedStack(null);
128  compressedStack.CanSkipEvaluation = true;
129  }
130  else
131  {
132  if (!CodeAccessSecurityEngine.AllDomainsHomogeneousWithNoStackModifiers())
133  {
134  compressedStack = new CompressedStack(null);
136  try
137  {
138  return compressedStack;
139  }
140  finally
141  {
142  compressedStack.CompressedStackHandle = GetDelayedCompressedStack(ref stackMark, walkStack: true);
143  if (compressedStack.CompressedStackHandle != null && IsImmediateCompletionCandidate(compressedStack.CompressedStackHandle, out innerCS))
144  {
145  try
146  {
147  compressedStack.CompleteConstruction(innerCS);
148  }
149  finally
150  {
151  DestroyDCSList(compressedStack.CompressedStackHandle);
152  }
153  }
154  }
155  }
156  compressedStack = new CompressedStack(GetDelayedCompressedStack(ref stackMark, walkStack: false));
157  compressedStack.m_pls = PermissionListSet.CreateCompressedState_HG();
158  }
159  return compressedStack;
160  }
161 
164  [MethodImpl(MethodImplOptions.NoInlining)]
165  [SecuritySafeCritical]
166  public static CompressedStack Capture()
167  {
168  StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
169  return GetCompressedStack(ref stackMark);
170  }
171 
178  [SecurityCritical]
179  public static void Run(CompressedStack compressedStack, ContextCallback callback, object state)
180  {
181  if (compressedStack == null)
182  {
183  throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamNull"), "compressedStack");
184  }
185  if (cleanupCode == null)
186  {
187  tryCode = runTryCode;
188  cleanupCode = runFinallyCode;
189  }
190  CompressedStackRunData userData = new CompressedStackRunData(compressedStack, callback, state);
191  RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(tryCode, cleanupCode, userData);
192  }
193 
194  [SecurityCritical]
195  internal static void runTryCode(object userData)
196  {
197  CompressedStackRunData compressedStackRunData = (CompressedStackRunData)userData;
198  compressedStackRunData.cssw = SetCompressedStack(compressedStackRunData.cs, GetCompressedStackThread());
199  compressedStackRunData.callBack(compressedStackRunData.state);
200  }
201 
202  [SecurityCritical]
203  [PrePrepareMethod]
204  internal static void runFinallyCode(object userData, bool exceptionThrown)
205  {
206  CompressedStackRunData compressedStackRunData = (CompressedStackRunData)userData;
207  compressedStackRunData.cssw.Undo();
208  }
209 
210  [SecurityCritical]
211  [HandleProcessCorruptedStateExceptions]
212  internal static CompressedStackSwitcher SetCompressedStack(CompressedStack cs, CompressedStack prevCS)
213  {
214  CompressedStackSwitcher result = default(CompressedStackSwitcher);
216  try
217  {
219  try
220  {
221  return result;
222  }
223  finally
224  {
225  SetCompressedStackThread(cs);
226  result.prev_CS = prevCS;
227  result.curr_CS = cs;
228  result.prev_ADStack = SetAppDomainStack(cs);
229  }
230  }
231  catch
232  {
233  result.UndoNoThrow();
234  throw;
235  }
236  }
237 
240  [SecuritySafeCritical]
241  [ComVisible(false)]
243  {
244  return new CompressedStack(m_csHandle, m_pls);
245  }
246 
247  [SecurityCritical]
248  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
249  internal static IntPtr SetAppDomainStack(CompressedStack cs)
250  {
251  return Thread.CurrentThread.SetAppDomainStack(cs?.CompressedStackHandle);
252  }
253 
254  [SecurityCritical]
255  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
256  internal static void RestoreAppDomainStack(IntPtr appDomainStack)
257  {
258  Thread.CurrentThread.RestoreAppDomainStack(appDomainStack);
259  }
260 
261  [SecurityCritical]
262  internal static CompressedStack GetCompressedStackThread()
263  {
264  return Thread.CurrentThread.GetExecutionContextReader().SecurityContext.CompressedStack;
265  }
266 
267  [SecurityCritical]
268  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
269  internal static void SetCompressedStackThread(CompressedStack cs)
270  {
271  Thread currentThread = Thread.CurrentThread;
272  if (currentThread.GetExecutionContextReader().SecurityContext.CompressedStack != cs)
273  {
274  ExecutionContext mutableExecutionContext = currentThread.GetMutableExecutionContext();
275  if (mutableExecutionContext.SecurityContext != null)
276  {
277  mutableExecutionContext.SecurityContext.CompressedStack = cs;
278  }
279  else if (cs != null)
280  {
281  SecurityContext securityContext = new SecurityContext();
282  securityContext.CompressedStack = cs;
283  mutableExecutionContext.SecurityContext = securityContext;
284  }
285  }
286  }
287 
288  [SecurityCritical]
289  internal bool CheckDemand(CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh)
290  {
291  CompleteConstruction(null);
292  if (PLS == null)
293  {
294  return false;
295  }
296  PLS.CheckDemand(demand, permToken, rmh);
297  return false;
298  }
299 
300  [SecurityCritical]
301  internal bool CheckDemandNoHalt(CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh)
302  {
303  CompleteConstruction(null);
304  if (PLS == null)
305  {
306  return true;
307  }
308  return PLS.CheckDemand(demand, permToken, rmh);
309  }
310 
311  [SecurityCritical]
312  internal bool CheckSetDemand(PermissionSet pset, RuntimeMethodHandleInternal rmh)
313  {
314  CompleteConstruction(null);
315  if (PLS == null)
316  {
317  return false;
318  }
319  return PLS.CheckSetDemand(pset, rmh);
320  }
321 
322  [SecurityCritical]
323  internal bool CheckSetDemandWithModificationNoHalt(PermissionSet pset, out PermissionSet alteredDemandSet, RuntimeMethodHandleInternal rmh)
324  {
325  alteredDemandSet = null;
326  CompleteConstruction(null);
327  if (PLS == null)
328  {
329  return true;
330  }
331  return PLS.CheckSetDemandWithModification(pset, out alteredDemandSet, rmh);
332  }
333 
334  [SecurityCritical]
335  internal void DemandFlagsOrGrantSet(int flags, PermissionSet grantSet)
336  {
337  CompleteConstruction(null);
338  if (PLS != null)
339  {
340  PLS.DemandFlagsOrGrantSet(flags, grantSet);
341  }
342  }
343 
344  [SecurityCritical]
345  internal void GetZoneAndOrigin(ArrayList zoneList, ArrayList originList, PermissionToken zoneToken, PermissionToken originToken)
346  {
347  CompleteConstruction(null);
348  if (PLS != null)
349  {
350  PLS.GetZoneAndOrigin(zoneList, originList, zoneToken, originToken);
351  }
352  }
353 
354  [SecurityCritical]
355  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
356  internal void CompleteConstruction(CompressedStack innerCS)
357  {
358  if (PLS == null)
359  {
360  PermissionListSet pls = PermissionListSet.CreateCompressedState(this, innerCS);
361  lock (this)
362  {
363  if (PLS == null)
364  {
365  m_pls = pls;
366  }
367  }
368  }
369  }
370 
371  [MethodImpl(MethodImplOptions.InternalCall)]
372  [SecurityCritical]
373  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
374  internal static extern SafeCompressedStackHandle GetDelayedCompressedStack(ref StackCrawlMark stackMark, bool walkStack);
375 
376  [MethodImpl(MethodImplOptions.InternalCall)]
377  [SecurityCritical]
378  internal static extern void DestroyDelayedCompressedStack(IntPtr unmanagedCompressedStack);
379 
380  [MethodImpl(MethodImplOptions.InternalCall)]
381  [SecurityCritical]
382  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
383  internal static extern void DestroyDCSList(SafeCompressedStackHandle compressedStack);
384 
385  [MethodImpl(MethodImplOptions.InternalCall)]
386  [SecurityCritical]
387  internal static extern int GetDCSCount(SafeCompressedStackHandle compressedStack);
388 
389  [MethodImpl(MethodImplOptions.InternalCall)]
390  [SecurityCritical]
391  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
392  internal static extern bool IsImmediateCompletionCandidate(SafeCompressedStackHandle compressedStack, out CompressedStack innerCS);
393 
394  [MethodImpl(MethodImplOptions.InternalCall)]
395  [SecurityCritical]
396  internal static extern DomainCompressedStack GetDomainCompressedStack(SafeCompressedStackHandle compressedStack, int index);
397 
398  [MethodImpl(MethodImplOptions.InternalCall)]
399  [SecurityCritical]
400  internal static extern void GetHomogeneousPLS(PermissionListSet hgPLS);
401  }
402 }
static Thread CurrentThread
Gets the currently running thread.
Definition: Thread.cs:134
delegate void TryCode(object userData)
Represents a delegate to code that should be run in a try block..
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
delegate void ContextCallback(object state)
Represents a method to be called within a new context.
static void ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, object userData)
Executes code using a T:System.Delegate while using another T:System.Delegate to execute additional c...
void GetObjectData(SerializationInfo info, StreamingContext context)
Sets the T:System.Runtime.Serialization.SerializationInfo object with the logical context information...
Definition: __Canon.cs:3
Encapsulates and propagates all security-related data for execution contexts transferred across threa...
static void Run(CompressedStack compressedStack, ContextCallback callback, object state)
Runs a method in the specified compressed stack on the current thread.
Describes the source and destination of a given serialized stream, and provides an additional caller-...
Cer
Specifies a method's behavior when called within a constrained execution region.
Definition: Cer.cs:5
Provides information about, and means to manipulate, the current environment and platform....
Definition: Environment.cs:21
static CompressedStack GetCompressedStack()
Gets the compressed stack for the current thread.
Represents a collection that can contain many different types of permissions.
Defines the underlying structure of all code access permissions.
A platform-specific type that is used to represent a pointer or a handle.
Definition: IntPtr.cs:14
static void PrepareConstrainedRegions()
Designates a body of code as a constrained execution region (CER).
MethodImplOptions
Defines the details of how a method is implemented.
Stores all the data needed to serialize or deserialize an object. This class cannot be inherited.
The exception that is thrown when one of the arguments provided to a method is not valid.
static CompressedStack Capture()
Captures the compressed stack from the current thread.
Allows an object to control its own serialization and deserialization.
Definition: ISerializable.cs:8
delegate void CleanupCode(object userData, bool exceptionThrown)
Represents a method to run when an exception occurs.
Provides methods for setting and capturing the compressed stack on the current thread....
Specifies that the class can be serialized.
Consistency
Specifies a reliability contract.
Definition: Consistency.cs:5
CompressedStack CreateCopy()
Creates a copy of the current compressed stack.
Provides a set of static methods and properties that provide support for compilers....
Implements the T:System.Collections.IList interface using an array whose size is dynamically increase...
Definition: ArrayList.cs:14
Creates and controls a thread, sets its priority, and gets its status.
Definition: Thread.cs:18