|
|
- using System;
- using System.Runtime.InteropServices;
-
- namespace Microsoft.Win32.Security
- {
- using DWORD = UInt32;
- using BOOL = Int32;
-
-
- /// <summary>
- /// Encapsulation of a Win32 token handle.
- /// The object is disposable because it maintains the Win32 handle.
- /// </summary>
- public abstract class AccessToken : DisposableObject
- {
- /// The win32 token handle.
- private IntPtr _handle;
-
- protected internal AccessToken(IntPtr handle)
- {
- _handle = handle;
- }
-
-
- protected override void Dispose(bool disposing)
- {
- if (_handle != IntPtr.Zero)
- {
- // We don't want to throw an exception here, because there's not
- // much we can do when failing to close a handle.
- BOOL rc = Win32.CloseHandle(_handle);
- if (rc != Win32.FALSE)
- _handle = IntPtr.Zero;
- }
- }
-
-
- /// <summary>
- /// Enable a single privilege on the process.
- /// </summary>
- /// <param name="privilege"></param>
- /// <exception cref="">Throws an exception if the privilege is not present
- /// in the privilege list of the process</exception>
- public void EnablePrivilege(TokenPrivilege privilege)
- {
- var privs = new TokenPrivileges {privilege};
- EnableDisablePrivileges(privs);
- }
-
- private void EnableDisablePrivileges(TokenPrivileges privileges)
- {
- UnsafeEnableDisablePrivileges(privileges);
- }
-
- private unsafe void UnsafeEnableDisablePrivileges(TokenPrivileges privileges)
- {
- byte[] privBytes = privileges.GetNativeTokenPrivileges();
- fixed (byte* priv = privBytes)
- {
- UInt32 cbLength;
-
- Win32.SetLastError(Win32.SUCCESS);
-
- BOOL rc = Win32.AdjustTokenPrivileges(
- _handle,
- Win32.FALSE,
- (IntPtr) priv,
- 0,
- IntPtr.Zero,
- out cbLength);
- Win32.CheckCall(rc);
-
- // Additional check: privilege can't be added, and in that case,
- // rc indicates a success, but GetLastError() has a specific meaning.
- if (Marshal.GetLastWin32Error() == Win32.ERROR_NOT_ALL_ASSIGNED)
- Win32.ThrowLastError();
- }
- }
- }
-
- /// <summary>
- /// Access token for a process
- /// </summary>
- public class AccessTokenProcess : AccessToken
- {
- public AccessTokenProcess(int pid, TokenAccessType desiredAccess)
- : base(OpenProcessToken(pid, desiredAccess))
- {
- }
-
- private static IntPtr TryOpenProcessToken(int pid, TokenAccessType desiredAccess)
- {
- IntPtr processHandle = Win32.OpenProcess(
- ProcessAccessType.PROCESS_QUERY_INFORMATION,
- Win32.FALSE,
- (uint) pid);
- if (processHandle == IntPtr.Zero)
- return IntPtr.Zero;
- Win32.CheckCall(processHandle);
- try
- {
- IntPtr handle;
- BOOL rc = Win32.OpenProcessToken(processHandle, desiredAccess, out handle);
- if (rc == Win32.FALSE)
- return IntPtr.Zero;
- return handle;
- }
- finally
- {
- Win32.CloseHandle(processHandle);
- }
- }
-
- private static IntPtr OpenProcessToken(int pid, TokenAccessType desiredAccess)
- {
- IntPtr handle = TryOpenProcessToken(pid, desiredAccess);
- if (handle == IntPtr.Zero)
- Win32.ThrowLastError();
- return handle;
- }
- }
- }
|