public void Revert() { int error = 0; if ( !this.currentThread.Equals( Thread.CurrentThread )) { throw new InvalidOperationException( Environment.GetResourceString( "InvalidOperation_MustBeSameThread" )); } if ( !this.NeedToRevert ) { return; } // // This code must be eagerly prepared and non-interruptible. // RuntimeHelpers.PrepareConstrainedRegions(); 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 )) { Win32Native.TOKEN_PRIVILEGE newState = new Win32Native.TOKEN_PRIVILEGE(); newState.PrivilegeCount = 1; newState.Privilege.Luid = this.luid; newState.Privilege.Attributes = ( this.initialState ? Win32Native.SE_PRIVILEGE_ENABLED : Win32Native.SE_PRIVILEGE_DISABLED ); Win32Native.TOKEN_PRIVILEGE previousState = new Win32Native.TOKEN_PRIVILEGE(); uint previousSize = 0; if ( false == Win32Native.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 == Win32Native.ERROR_NOT_ENOUGH_MEMORY ) { throw new OutOfMemoryException(); } else if ( error == Win32Native.ERROR_ACCESS_DENIED ) { throw new UnauthorizedAccessException(); } else if ( error != 0 ) { Contract.Assert( false, string.Format( CultureInfo.InvariantCulture, "AdjustTokenPrivileges() failed with unrecognized error code {0}", error )); throw new InvalidOperationException(); } }
private void ToggleState(bool enable) { int num = 0; if (!this.currentThread.Equals(Thread.CurrentThread)) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MustBeSameThread")); } if (this.needToRevert) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MustRevertPrivilege")); } RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { try { this.tlsContents = Thread.GetData(tlsSlot) as TlsContents; if (this.tlsContents == null) { this.tlsContents = new TlsContents(); Thread.SetData(tlsSlot, this.tlsContents); } else { this.tlsContents.IncrementReferenceCount(); } Win32Native.TOKEN_PRIVILEGE newState = new Win32Native.TOKEN_PRIVILEGE { PrivilegeCount = 1 }; newState.Privilege.Luid = this.luid; newState.Privilege.Attributes = enable ? 2 : 0; Win32Native.TOKEN_PRIVILEGE structure = new Win32Native.TOKEN_PRIVILEGE(); uint returnLength = 0; int introduced4 = Marshal.SizeOf(structure); if (!Win32Native.AdjustTokenPrivileges(this.tlsContents.ThreadHandle, false, ref newState, (uint) introduced4, ref structure, ref returnLength)) { num = Marshal.GetLastWin32Error(); } else if (0x514 == Marshal.GetLastWin32Error()) { num = 0x514; } else { this.initialState = (structure.Privilege.Attributes & 2) != 0; this.stateWasChanged = this.initialState != enable; this.needToRevert = this.tlsContents.IsImpersonating || this.stateWasChanged; } } finally { if (!this.needToRevert) { this.Reset(); } } } switch (num) { case 0x514: throw new PrivilegeNotHeldException(privileges[this.luid] as string); case 8: throw new OutOfMemoryException(); case 5: case 0x543: throw new UnauthorizedAccessException(); } if (num != 0) { throw new InvalidOperationException(); } }
private void ToggleState( bool enable ) { int error = 0; // // All privilege operations must take place on the same thread // if ( !this.currentThread.Equals( Thread.CurrentThread )) { throw new InvalidOperationException( Environment.GetResourceString( "InvalidOperation_MustBeSameThread" )); } // // This privilege was already altered and needs to be reverted before it can be altered again // if ( this.needToRevert ) { throw new InvalidOperationException( Environment.GetResourceString( "InvalidOperation_MustRevertPrivilege" )); } // // Need to make this block of code non-interruptible so that it would preserve // consistency of thread oken state even in the face of catastrophic exceptions // RuntimeHelpers.PrepareConstrainedRegions(); 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 { try { // // Retrieve TLS state // this.tlsContents = Thread.GetData( tlsSlot ) as TlsContents; if ( this.tlsContents == null ) { this.tlsContents = new TlsContents(); Thread.SetData( tlsSlot, this.tlsContents ); } else { this.tlsContents.IncrementReferenceCount(); } Win32Native.TOKEN_PRIVILEGE newState = new Win32Native.TOKEN_PRIVILEGE(); newState.PrivilegeCount = 1; newState.Privilege.Luid = this.luid; newState.Privilege.Attributes = enable ? Win32Native.SE_PRIVILEGE_ENABLED : Win32Native.SE_PRIVILEGE_DISABLED; Win32Native.TOKEN_PRIVILEGE previousState = new Win32Native.TOKEN_PRIVILEGE(); uint previousSize = 0; // // Place the new privilege on the thread token and remember the previous state. // if ( false == Win32Native.AdjustTokenPrivileges( this.tlsContents.ThreadHandle, false, ref newState, ( uint )Marshal.SizeOf( previousState ), ref previousState, ref previousSize )) { error = Marshal.GetLastWin32Error(); } else if ( Win32Native.ERROR_NOT_ALL_ASSIGNED == Marshal.GetLastWin32Error()) { error = Win32Native.ERROR_NOT_ALL_ASSIGNED; } else { // // This is the initial state that revert will have to go back to // this.initialState = (( previousState.Privilege.Attributes & Win32Native.SE_PRIVILEGE_ENABLED ) != 0 ); // // Remember whether state has changed at all // this.stateWasChanged = ( this.initialState != enable ); // // If we had to impersonate, or if the privilege state changed we'll need to revert // this.needToRevert = this.tlsContents.IsImpersonating || this.stateWasChanged; } } finally { if ( !this.needToRevert ) { this.Reset(); } } } if ( error == Win32Native.ERROR_NOT_ALL_ASSIGNED ) { throw new PrivilegeNotHeldException( privileges[this.luid] as string ); } if ( error == Win32Native.ERROR_NOT_ENOUGH_MEMORY ) { throw new OutOfMemoryException(); } else if ( error == Win32Native.ERROR_ACCESS_DENIED || error == Win32Native.ERROR_CANT_OPEN_ANONYMOUS ) { throw new UnauthorizedAccessException(); } else if ( error != 0 ) { Contract.Assert( false, string.Format( CultureInfo.InvariantCulture, "AdjustTokenPrivileges() failed with unrecognized error code {0}", error )); throw new InvalidOperationException(); } }
public void Revert() { int num = 0; if (!this.currentThread.Equals(Thread.CurrentThread)) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MustBeSameThread")); } if (this.NeedToRevert) { RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { bool flag = true; try { if (this.stateWasChanged && ((this.tlsContents.ReferenceCountValue > 1) || !this.tlsContents.IsImpersonating)) { Win32Native.TOKEN_PRIVILEGE newState = new Win32Native.TOKEN_PRIVILEGE { PrivilegeCount = 1 }; newState.Privilege.Luid = this.luid; newState.Privilege.Attributes = this.initialState ? 2 : 0; Win32Native.TOKEN_PRIVILEGE structure = new Win32Native.TOKEN_PRIVILEGE(); uint returnLength = 0; int introduced5 = Marshal.SizeOf(structure); if (!Win32Native.AdjustTokenPrivileges(this.tlsContents.ThreadHandle, false, ref newState, (uint) introduced5, ref structure, ref returnLength)) { num = Marshal.GetLastWin32Error(); flag = false; } } } finally { if (flag) { this.Reset(); } } } switch (num) { case 8: throw new OutOfMemoryException(); case 5: throw new UnauthorizedAccessException(); } if (num != 0) { throw new InvalidOperationException(); } } }