コード例 #1
0
        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("Operation must take place on the thread that created the object");
            }

            //
            // This privilege was already altered and needs to be reverted before it can be altered again
            //

            if (this.NeedToRevert)
            {
                throw new InvalidOperationException("Must revert the privilege prior to attempting this operation");
            }

            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();
                }

                NativeMethods.TOKEN_PRIVILEGE newState = new NativeMethods.TOKEN_PRIVILEGE();
                newState.PrivilegeCount       = 1;
                newState.Privilege.Luid       = this.luid;
                newState.Privilege.Attributes = enable ? NativeMethods.SE_PRIVILEGE_ENABLED : NativeMethods.SE_PRIVILEGE_DISABLED;

                NativeMethods.TOKEN_PRIVILEGE previousState = new NativeMethods.TOKEN_PRIVILEGE();
                uint previousSize = 0;

                //
                // Place the new privilege on the thread token and remember the previous state.
                //

                if (false == NativeMethods.AdjustTokenPrivileges(
                        this.tlsContents.ThreadHandle,
                        false,
                        ref newState,
                        (uint)Marshal.SizeOf(previousState),
                        ref previousState,
                        ref previousSize))
                {
                    error = Marshal.GetLastWin32Error();
                }
                else if (NativeMethods.ERROR_NOT_ALL_ASSIGNED == Marshal.GetLastWin32Error())
                {
                    error = NativeMethods.ERROR_NOT_ALL_ASSIGNED;
                }
                else
                {
                    //
                    // This is the initial state that revert will have to go back to
                    //

                    this.initialState = ((previousState.Privilege.Attributes & NativeMethods.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 == NativeMethods.ERROR_NOT_ALL_ASSIGNED)
            {
                throw new PrivilegeNotHeldException(privileges[this.luid] as string);
            }
            if (error == NativeMethods.ERROR_NOT_ENOUGH_MEMORY)
            {
                throw new OutOfMemoryException();
            }
            else if (error == NativeMethods.ERROR_ACCESS_DENIED ||
                     error == NativeMethods.ERROR_CANT_OPEN_ANONYMOUS)
            {
                throw new UnauthorizedAccessException("The caller does not have the right to change the privilege");
            }
            else if (error != 0)
            {
                throw new Win32Exception(error);
            }
        }
コード例 #2
0
        public void Revert()
        {
            int error = 0;

            //
            // All privilege operations must take place on the same thread
            //

            if (!this.currentThread.Equals(Thread.CurrentThread))
            {
                throw new InvalidOperationException("Operation must take place on the thread that created the object");
            }

            if (!this.NeedToRevert)
            {
                return;
            }

            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))
                {
                    NativeMethods.TOKEN_PRIVILEGE newState = new NativeMethods.TOKEN_PRIVILEGE();
                    newState.PrivilegeCount       = 1;
                    newState.Privilege.Luid       = this.luid;
                    newState.Privilege.Attributes = (this.initialState ? NativeMethods.SE_PRIVILEGE_ENABLED : NativeMethods.SE_PRIVILEGE_DISABLED);
                    NativeMethods.TOKEN_PRIVILEGE previousState = new NativeMethods.TOKEN_PRIVILEGE();
                    uint previousSize = 0;

                    if (false == NativeMethods.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 == NativeMethods.ERROR_NOT_ENOUGH_MEMORY)
            {
                throw new OutOfMemoryException();
            }
            else if (error == NativeMethods.ERROR_ACCESS_DENIED)
            {
                throw new UnauthorizedAccessException("Caller does not have the permission to change the privilege");
            }
            else if (error != 0)
            {
                throw new Win32Exception(error);
            }
        }