public void Revert()
{
int error = 0;
if (!this.currentThread.Equals(Thread.CurrentThread))
{
throw new InvalidOperationException(SR.InvalidOperation_MustBeSameThread);
}
if (!this.NeedToRevert)
{
return;
}
//
// This code must be eagerly prepared and non-interruptible.
//
try
{
//
// The payload is entirely in the finally block
// This is how we ensure that the code will not be
// interrupted by catastrophic exceptions
//
}
finally
{
bool success = true;
try
{
//
// Only call AdjustTokenPrivileges if we're not going to be reverting to self,
// on this Revert, since doing the latter obliterates the thread token anyway
//
if (this.stateWasChanged &&
(this.tlsContents.ReferenceCountValue > 1 ||
!this.tlsContents.IsImpersonating))
{
Interop.Advapi32.LUID_AND_ATTRIBUTES luidAndAttrs = new Interop.Advapi32.LUID_AND_ATTRIBUTES();
luidAndAttrs.Luid = this.luid;
luidAndAttrs.Attributes = (this.initialState ? Interop.Advapi32.SEPrivileges.SE_PRIVILEGE_ENABLED : Interop.Advapi32.SEPrivileges.SE_PRIVILEGE_DISABLED);
Interop.Advapi32.TOKEN_PRIVILEGE newState = new Interop.Advapi32.TOKEN_PRIVILEGE();
newState.PrivilegeCount = 1;
newState.Privileges[0] = luidAndAttrs;
Interop.Advapi32.TOKEN_PRIVILEGE previousState = new Interop.Advapi32.TOKEN_PRIVILEGE();
uint previousSize = 0;
if (false == Interop.Advapi32.AdjustTokenPrivileges(
this.tlsContents.ThreadHandle,
false,
ref newState,
(uint)Marshal.SizeOf(previousState),
ref previousState,
ref previousSize))
{
error = Marshal.GetLastWin32Error();
success = false;
}
}
}
finally
{
if (success)
{
this.Reset();
}
}
}
if (error == Interop.Errors.ERROR_NOT_ENOUGH_MEMORY)
{
throw new OutOfMemoryException();
}
else if (error == Interop.Errors.ERROR_ACCESS_DENIED)
{
throw new UnauthorizedAccessException();
}
else if (error != 0)
{
System.Diagnostics.Debug.Assert(false, string.Format(CultureInfo.InvariantCulture, "AdjustTokenPrivileges() failed with unrecognized error code {0}", error));
throw new InvalidOperationException();
}
}
#if false