607 lines
23 KiB
C#
607 lines
23 KiB
C#
// ==++==
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
// ==--==
|
|
/*=============================================================================
|
|
**
|
|
** Class: CompressedStack
|
|
**
|
|
** <OWNER>[....]</OWNER>
|
|
** <OWNER>[....]</OWNER>
|
|
**
|
|
** Purpose: Managed wrapper for the security stack compression implementation
|
|
**
|
|
=============================================================================*/
|
|
|
|
namespace System.Threading
|
|
{
|
|
using System.Security;
|
|
using System.Security.Permissions;
|
|
using System.Runtime.InteropServices;
|
|
using System.Runtime.CompilerServices;
|
|
#if FEATURE_CORRUPTING_EXCEPTIONS
|
|
using System.Runtime.ExceptionServices;
|
|
#endif // FEATURE_CORRUPTING_EXCEPTIONS
|
|
using System.Runtime.ConstrainedExecution;
|
|
using System.Runtime.Versioning;
|
|
using System.Reflection;
|
|
using System.Collections;
|
|
using System.Threading;
|
|
using System.Runtime.Serialization;
|
|
using System.Diagnostics.Contracts;
|
|
|
|
|
|
internal struct CompressedStackSwitcher: IDisposable
|
|
{
|
|
internal CompressedStack curr_CS;
|
|
internal CompressedStack prev_CS;
|
|
internal IntPtr prev_ADStack;
|
|
|
|
|
|
public override bool Equals(Object obj)
|
|
{
|
|
if (obj == null || !(obj is CompressedStackSwitcher))
|
|
return false;
|
|
CompressedStackSwitcher sw = (CompressedStackSwitcher)obj;
|
|
return (this.curr_CS == sw.curr_CS && this.prev_CS == sw.prev_CS && this.prev_ADStack == sw.prev_ADStack);
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return ToString().GetHashCode();
|
|
}
|
|
|
|
public static bool operator ==(CompressedStackSwitcher c1, CompressedStackSwitcher c2)
|
|
{
|
|
return c1.Equals(c2);
|
|
}
|
|
|
|
public static bool operator !=(CompressedStackSwitcher c1, CompressedStackSwitcher c2)
|
|
{
|
|
return !c1.Equals(c2);
|
|
}
|
|
|
|
[System.Security.SecuritySafeCritical] // overrides public transparent member
|
|
public void Dispose()
|
|
{
|
|
Undo();
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
|
#if FEATURE_CORRUPTING_EXCEPTIONS
|
|
[HandleProcessCorruptedStateExceptions] //
|
|
#endif // FEATURE_CORRUPTING_EXCEPTIONS
|
|
internal bool UndoNoThrow()
|
|
{
|
|
try
|
|
{
|
|
Undo();
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
|
public void Undo()
|
|
{
|
|
if (curr_CS == null && prev_CS == null)
|
|
return;
|
|
if (prev_ADStack != (IntPtr)0)
|
|
CompressedStack.RestoreAppDomainStack(prev_ADStack);
|
|
CompressedStack.SetCompressedStackThread(prev_CS);
|
|
|
|
prev_CS = null;
|
|
curr_CS = null;
|
|
prev_ADStack = (IntPtr)0;
|
|
}
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
internal class SafeCompressedStackHandle : SafeHandle
|
|
{
|
|
public SafeCompressedStackHandle() : base(IntPtr.Zero, true)
|
|
{
|
|
}
|
|
|
|
public override bool IsInvalid {
|
|
[System.Security.SecurityCritical]
|
|
get { return handle == IntPtr.Zero; }
|
|
}
|
|
|
|
[System.Security.SecurityCritical]
|
|
override protected bool ReleaseHandle()
|
|
{
|
|
CompressedStack.DestroyDelayedCompressedStack(handle);
|
|
handle = IntPtr.Zero;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
[Serializable]
|
|
public sealed class CompressedStack:ISerializable
|
|
{
|
|
|
|
private volatile PermissionListSet m_pls;
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
private volatile SafeCompressedStackHandle m_csHandle;
|
|
private bool m_canSkipEvaluation = false;
|
|
|
|
internal bool CanSkipEvaluation
|
|
{
|
|
get
|
|
{
|
|
return m_canSkipEvaluation;
|
|
}
|
|
private set
|
|
{
|
|
m_canSkipEvaluation = value;
|
|
}
|
|
}
|
|
|
|
internal PermissionListSet PLS
|
|
{
|
|
get
|
|
{
|
|
return m_pls;
|
|
}
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
internal CompressedStack( SafeCompressedStackHandle csHandle )
|
|
{
|
|
m_csHandle = csHandle;
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
private CompressedStack(SafeCompressedStackHandle csHandle, PermissionListSet pls)
|
|
{
|
|
this.m_csHandle = csHandle;
|
|
this.m_pls = pls;
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated_required
|
|
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
|
{
|
|
if (info==null)
|
|
throw new ArgumentNullException("info");
|
|
Contract.EndContractBlock();
|
|
CompleteConstruction(null);
|
|
info.AddValue("PLS", this.m_pls);
|
|
}
|
|
|
|
private CompressedStack(SerializationInfo info, StreamingContext context)
|
|
{
|
|
this.m_pls = (PermissionListSet)info.GetValue("PLS", typeof(PermissionListSet));
|
|
}
|
|
|
|
internal SafeCompressedStackHandle CompressedStackHandle
|
|
{
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
|
get
|
|
{
|
|
return m_csHandle;
|
|
}
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
|
private set
|
|
{
|
|
m_csHandle = value;
|
|
}
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated_required
|
|
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
|
|
public static CompressedStack GetCompressedStack()
|
|
{
|
|
// This is a Capture()
|
|
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
|
|
return CompressedStack.GetCompressedStack(ref stackMark);
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
internal static CompressedStack GetCompressedStack(ref StackCrawlMark stackMark)
|
|
{
|
|
CompressedStack cs;
|
|
CompressedStack innerCS = null;
|
|
if (CodeAccessSecurityEngine.QuickCheckForAllDemands())
|
|
{
|
|
cs = new CompressedStack(null);
|
|
cs.CanSkipEvaluation = true;
|
|
}
|
|
else if (CodeAccessSecurityEngine.AllDomainsHomogeneousWithNoStackModifiers())
|
|
{
|
|
// if all AppDomains on the stack are homogeneous, we don't need to walk the stack
|
|
// however, we do need to capture the AppDomain stack.
|
|
cs = new CompressedStack(GetDelayedCompressedStack(ref stackMark, false));
|
|
cs.m_pls = PermissionListSet.CreateCompressedState_HG();
|
|
}
|
|
else
|
|
{
|
|
// regular stackwalking case
|
|
// We want this to complete without ThreadAborts - if we're in a multiple AD callstack and an intermediate AD gets unloaded,
|
|
// preventing TAs here prevents a race condition where a SafeCompressedStackHandle is created to a DCS belonging to an AD that's
|
|
// gone away
|
|
cs = new CompressedStack(null);
|
|
RuntimeHelpers.PrepareConstrainedRegions();
|
|
try
|
|
{
|
|
// Empty try block to ensure no ThreadAborts in the finally block
|
|
}
|
|
finally
|
|
{
|
|
|
|
cs.CompressedStackHandle = GetDelayedCompressedStack(ref stackMark, true);
|
|
if (cs.CompressedStackHandle != null && IsImmediateCompletionCandidate(cs.CompressedStackHandle, out innerCS))
|
|
{
|
|
try
|
|
{
|
|
cs.CompleteConstruction(innerCS);
|
|
}
|
|
finally
|
|
{
|
|
DestroyDCSList(cs.CompressedStackHandle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return cs;
|
|
}
|
|
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
|
|
public static CompressedStack Capture()
|
|
{
|
|
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
|
|
return GetCompressedStack(ref stackMark);
|
|
}
|
|
|
|
// This method is special from a security perspective - the VM will not allow a stack walk to
|
|
// continue past the call to CompressedStack.Run. If you change the signature to this method, or
|
|
// provide an alternate way to do a CompressedStack.Run make sure to update
|
|
// SecurityStackWalk::IsSpecialRunFrame in the VM to search for the new method.
|
|
[System.Security.SecurityCritical] // auto-generated_required
|
|
[DynamicSecurityMethodAttribute()]
|
|
public static void Run(CompressedStack compressedStack, ContextCallback callback, Object state)
|
|
{
|
|
|
|
if (compressedStack == null )
|
|
{
|
|
throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamNull"),"compressedStack");
|
|
}
|
|
Contract.EndContractBlock();
|
|
if (cleanupCode == null)
|
|
{
|
|
tryCode = new RuntimeHelpers.TryCode(runTryCode);
|
|
cleanupCode = new RuntimeHelpers.CleanupCode(runFinallyCode);
|
|
}
|
|
|
|
CompressedStackRunData runData = new CompressedStackRunData(compressedStack, callback, state);
|
|
RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(tryCode, cleanupCode, runData);
|
|
}
|
|
|
|
internal class CompressedStackRunData
|
|
{
|
|
internal CompressedStack cs;
|
|
internal ContextCallback callBack;
|
|
internal Object state;
|
|
internal CompressedStackSwitcher cssw;
|
|
internal CompressedStackRunData(CompressedStack cs, ContextCallback cb, Object state)
|
|
{
|
|
this.cs = cs;
|
|
this.callBack = cb;
|
|
this.state = state;
|
|
this.cssw = new CompressedStackSwitcher();
|
|
}
|
|
}
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
static internal void runTryCode(Object userData)
|
|
{
|
|
CompressedStackRunData rData = (CompressedStackRunData) userData;
|
|
rData.cssw = SetCompressedStack(rData.cs, GetCompressedStackThread());
|
|
rData.callBack(rData.state);
|
|
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[PrePrepareMethod]
|
|
static internal void runFinallyCode(Object userData, bool exceptionThrown)
|
|
{
|
|
CompressedStackRunData rData = (CompressedStackRunData) userData;
|
|
rData.cssw.Undo();
|
|
}
|
|
|
|
static internal volatile RuntimeHelpers.TryCode tryCode;
|
|
static internal volatile RuntimeHelpers.CleanupCode cleanupCode;
|
|
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
#if FEATURE_CORRUPTING_EXCEPTIONS
|
|
[HandleProcessCorruptedStateExceptions] //
|
|
#endif // FEATURE_CORRUPTING_EXCEPTIONS
|
|
internal static CompressedStackSwitcher SetCompressedStack(CompressedStack cs, CompressedStack prevCS)
|
|
{
|
|
CompressedStackSwitcher cssw = new CompressedStackSwitcher();
|
|
RuntimeHelpers.PrepareConstrainedRegions();
|
|
try
|
|
{
|
|
// Order is important in this block.
|
|
// Also, we dont want any THreadAborts happening when we try to set it
|
|
RuntimeHelpers.PrepareConstrainedRegions();
|
|
try
|
|
{
|
|
// Empty try block to ensure no ThreadAborts in the finally block
|
|
}
|
|
finally
|
|
{
|
|
// SetCompressedStackThread can throw - only if it suceeds we shd update the switcher and overrides
|
|
SetCompressedStackThread(cs);
|
|
cssw.prev_CS = prevCS;
|
|
cssw.curr_CS = cs;
|
|
cssw.prev_ADStack = SetAppDomainStack(cs);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
cssw.UndoNoThrow();
|
|
throw; // throw the original exception
|
|
}
|
|
return cssw;
|
|
}
|
|
|
|
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
[ComVisible(false)]
|
|
public CompressedStack CreateCopy()
|
|
{
|
|
return new CompressedStack(this.m_csHandle, this.m_pls);
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
|
internal static IntPtr SetAppDomainStack(CompressedStack cs)
|
|
{
|
|
//Update the AD Stack on the thread and return the previous AD Stack
|
|
return Thread.CurrentThread.SetAppDomainStack((cs == null ? null:cs.CompressedStackHandle));
|
|
}
|
|
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
|
internal static void RestoreAppDomainStack(IntPtr appDomainStack)
|
|
{
|
|
Thread.CurrentThread.RestoreAppDomainStack(appDomainStack); //Restore the previous AD Stack
|
|
}
|
|
|
|
[SecurityCritical]
|
|
internal static CompressedStack GetCompressedStackThread()
|
|
{
|
|
return Thread.CurrentThread.GetExecutionContextReader().SecurityContext.CompressedStack;
|
|
}
|
|
|
|
[SecurityCritical]
|
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
|
internal static void SetCompressedStackThread(CompressedStack cs)
|
|
{
|
|
Thread currentThread = Thread.CurrentThread;
|
|
if (currentThread.GetExecutionContextReader().SecurityContext.CompressedStack != cs)
|
|
{
|
|
ExecutionContext ec = currentThread.GetMutableExecutionContext();
|
|
if (ec.SecurityContext != null)
|
|
ec.SecurityContext.CompressedStack = cs;
|
|
else if (cs != null)
|
|
{
|
|
SecurityContext sc = new SecurityContext();
|
|
sc.CompressedStack = cs;
|
|
ec.SecurityContext = sc;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
internal bool CheckDemand(CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh)
|
|
{
|
|
CompleteConstruction(null);
|
|
|
|
if (PLS == null)
|
|
return SecurityRuntime.StackHalt;
|
|
else
|
|
{
|
|
PLS.CheckDemand(demand, permToken, rmh);
|
|
return SecurityRuntime.StackHalt; // CS demand check always terminates the stackwalk
|
|
}
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
internal bool CheckDemandNoHalt(CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh)
|
|
{
|
|
CompleteConstruction(null);
|
|
|
|
if (PLS == null)
|
|
return SecurityRuntime.StackContinue;
|
|
else
|
|
{
|
|
return PLS.CheckDemand(demand, permToken, rmh);
|
|
}
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
internal bool CheckSetDemand(PermissionSet pset , RuntimeMethodHandleInternal rmh)
|
|
{
|
|
CompleteConstruction(null);
|
|
|
|
if (PLS == null)
|
|
return SecurityRuntime.StackHalt;
|
|
else
|
|
return PLS.CheckSetDemand(pset, rmh);
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
internal bool CheckSetDemandWithModificationNoHalt(PermissionSet pset, out PermissionSet alteredDemandSet, RuntimeMethodHandleInternal rmh)
|
|
{
|
|
alteredDemandSet = null;
|
|
CompleteConstruction(null);
|
|
|
|
if (PLS == null)
|
|
return SecurityRuntime.StackContinue;
|
|
else
|
|
return PLS.CheckSetDemandWithModification(pset, out alteredDemandSet, rmh);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Demand which succeeds if either a set of special permissions or a permission set is granted
|
|
/// to the call stack
|
|
/// </summary>
|
|
/// <param name="flags">set of flags to check (See PermissionType)</param>
|
|
/// <param name="grantSet">alternate permission set to check</param>
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
internal void DemandFlagsOrGrantSet(int flags, PermissionSet grantSet)
|
|
{
|
|
CompleteConstruction(null);
|
|
if (PLS == null)
|
|
return;
|
|
|
|
PLS.DemandFlagsOrGrantSet(flags, grantSet);
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
internal void GetZoneAndOrigin(ArrayList zoneList, ArrayList originList, PermissionToken zoneToken, PermissionToken originToken)
|
|
{
|
|
CompleteConstruction(null);
|
|
if (PLS != null)
|
|
PLS.GetZoneAndOrigin(zoneList,originList,zoneToken,originToken);
|
|
return;
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
|
internal void CompleteConstruction(CompressedStack innerCS)
|
|
{
|
|
if (PLS != null)
|
|
return;
|
|
PermissionListSet pls = PermissionListSet.CreateCompressedState(this, innerCS);
|
|
lock (this)
|
|
{
|
|
if (PLS == null)
|
|
m_pls = pls;
|
|
}
|
|
}
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ResourceExposure(ResourceScope.None)]
|
|
[MethodImplAttribute(MethodImplOptions.InternalCall)]
|
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
|
internal extern static SafeCompressedStackHandle GetDelayedCompressedStack(ref StackCrawlMark stackMark,
|
|
bool walkStack);
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ResourceExposure(ResourceScope.None)]
|
|
[MethodImplAttribute(MethodImplOptions.InternalCall)]
|
|
internal extern static void DestroyDelayedCompressedStack( IntPtr unmanagedCompressedStack );
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ResourceExposure(ResourceScope.None)]
|
|
[MethodImplAttribute(MethodImplOptions.InternalCall)]
|
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
|
internal extern static void DestroyDCSList( SafeCompressedStackHandle compressedStack );
|
|
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ResourceExposure(ResourceScope.None)]
|
|
[MethodImplAttribute(MethodImplOptions.InternalCall)]
|
|
internal extern static int GetDCSCount(SafeCompressedStackHandle compressedStack);
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ResourceExposure(ResourceScope.None)]
|
|
[MethodImplAttribute(MethodImplOptions.InternalCall)]
|
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
|
internal extern static bool IsImmediateCompletionCandidate(SafeCompressedStackHandle compressedStack, out CompressedStack innerCS);
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ResourceExposure(ResourceScope.None)]
|
|
[MethodImplAttribute(MethodImplOptions.InternalCall)]
|
|
internal extern static DomainCompressedStack GetDomainCompressedStack(SafeCompressedStackHandle compressedStack, int index);
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ResourceExposure(ResourceScope.None)]
|
|
[MethodImplAttribute(MethodImplOptions.InternalCall)]
|
|
internal extern static void GetHomogeneousPLS(PermissionListSet hgPLS);
|
|
|
|
|
|
}
|
|
|
|
//**********************************************************
|
|
// New Implementation of CompressedStack creation/demand eval - NewCompressedStack/DomainCompressedStack
|
|
//**********************************************************
|
|
[Serializable]
|
|
internal sealed class DomainCompressedStack
|
|
{
|
|
// Managed equivalent of DomainCompressedStack - used to perform demand evaluation
|
|
private PermissionListSet m_pls;
|
|
// Did we terminate construction on this DCS and therefore, should we terminate construction on the rest of the CS?
|
|
private bool m_bHaltConstruction;
|
|
|
|
|
|
// CompresedStack interacts with this class purely through the three properties marked internal
|
|
// Zone, Origin, AGRList.
|
|
internal PermissionListSet PLS
|
|
{
|
|
get
|
|
{
|
|
return m_pls;
|
|
}
|
|
}
|
|
|
|
internal bool ConstructionHalted
|
|
{
|
|
get
|
|
{
|
|
return m_bHaltConstruction;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Called from the VM only.
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
private static DomainCompressedStack CreateManagedObject(IntPtr unmanagedDCS)
|
|
{
|
|
DomainCompressedStack newDCS = new DomainCompressedStack();
|
|
newDCS.m_pls = PermissionListSet.CreateCompressedState(unmanagedDCS, out newDCS.m_bHaltConstruction);
|
|
// return the created object
|
|
return newDCS;
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ResourceExposure(ResourceScope.None)]
|
|
[MethodImplAttribute(MethodImplOptions.InternalCall)]
|
|
internal extern static int GetDescCount(IntPtr dcs);
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ResourceExposure(ResourceScope.None)]
|
|
[MethodImplAttribute(MethodImplOptions.InternalCall)]
|
|
internal extern static void GetDomainPermissionSets(IntPtr dcs, out PermissionSet granted, out PermissionSet refused);
|
|
|
|
// returns true if the descriptor is a FrameSecurityDescriptor
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ResourceExposure(ResourceScope.None)]
|
|
[MethodImplAttribute(MethodImplOptions.InternalCall)]
|
|
internal extern static bool GetDescriptorInfo(IntPtr dcs, int index, out PermissionSet granted, out PermissionSet refused, out Assembly assembly, out FrameSecurityDescriptor fsd);
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ResourceExposure(ResourceScope.None)]
|
|
[MethodImplAttribute(MethodImplOptions.InternalCall)]
|
|
internal extern static bool IgnoreDomain(IntPtr dcs);
|
|
}
|
|
|
|
}
|