using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Security.Principal;
using Microsoft.Win32;
using static Vanara.PInvoke.AdvApi32;
namespace Vanara.Security
{
///
/// Provides information about the state of User Access Control for the system.
///
public static partial class UAC
{
private static bool? enabled;
///
/// Determines whether the provided process can be elevated. Effectively, this checks that UAC is available and that the process is running under an
/// account that belongs to the Administrators group.
///
/// The process. If this value is null, then the current process is used.
/// true if this process can be elevated; otherwise, false.
public static bool CanElevate(Process process = null) => IsEnabled() && IsRunningAsAdmin(process);
/// Determines whether the specified process is elevated.
/// The process. If this value is null, then the current process is used.
/// true if the specified process is elevated; otherwise, false.
public static bool IsElevated(Process process = null)
{
try
{
// Open the access token of the current process with TOKEN_QUERY.
using (var hObject = SafeHTOKEN.FromProcess(process ?? Process.GetCurrentProcess(), TokenAccess.TOKEN_QUERY | TokenAccess.TOKEN_DUPLICATE))
return hObject.IsElevated;
}
catch { }
return false;
}
/// Determines whether UAC is enabled on this system.
/// true if UAC is enabled; otherwise, false.
public static bool IsEnabled()
{
if (!enabled.HasValue)
{
if (Environment.OSVersion.Version.Major < 6)
enabled = true;
else
enabled = Registry.GetValue(
@"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System", "EnableLUA", 0).Equals(1);
}
return enabled.Value;
}
///
/// The function checks whether the primary access token of the process belongs to user account that is a member of the local Administrators group,
/// even if it currently is not elevated.
///
/// The process to check.
///
/// Returns true if the primary access token of the process belongs to user account that is a member of the local Administrators group. Returns false
/// if the token does not.
///
public static bool IsRunningAsAdmin(Process proc = null)
{
SafeHTOKEN hObjectToCheck = null;
// Open the access token of the current process for query and duplicate.
using (var hObject = SafeHTOKEN.FromProcess(proc, TokenAccess.TOKEN_QUERY | TokenAccess.TOKEN_DUPLICATE))
{
// Determine whether system is running Windows Vista or later operating systems (major version >= 6) because they support linked tokens, but
// previous versions (major version < 6) do not.
if (Environment.OSVersion.Version.Major >= 6)
{
// Marshal the TOKEN_ELEVATION_TYPE enum from native to .NET.
var elevType = hObject.GetInfo(TOKEN_INFORMATION_CLASS.TokenElevationType);
// If limited, get the linked elevated token for further check.
if (elevType == TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited)
{
// Marshal the linked token value from native to .NET.
hObjectToCheck = new SafeHTOKEN(hObject.GetInfo(TOKEN_INFORMATION_CLASS.TokenLinkedToken).LinkedToken.DangerousGetHandle());
}
}
// CheckTokenMembership requires an impersonation token. If we just got a linked token, it already is an impersonation token. If we did not get a
// linked token, duplicate the original into an impersonation token for CheckTokenMembership.
if (hObjectToCheck == null)
{
if (!DuplicateToken(hObject, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, out hObjectToCheck))
throw new Win32Exception();
}
}
if (hObjectToCheck == null || hObjectToCheck.IsInvalid) return false;
// Check if the token to be checked contains admin SID.
using (hObjectToCheck)
using (var id = new WindowsIdentity(hObjectToCheck.DangerousGetHandle()))
return id.IsAdmin();
}
/*/// Runs the current application elevated if it isn't already. This will close the current running instance.
public static void RunCurrentApplicationElevated()
{
if (!WindowsIdentity.GetCurrent().IsAdmin())
{
// Launch itself as administrator
var proc = new ProcessStartInfo(System.Windows.Forms.Application.ExecutablePath)
{
UseShellExecute = true,
WorkingDirectory = Environment.CurrentDirectory,
Verb = "runas"
};
try
{
Process.Start(proc);
System.Windows.Forms.Application.Exit();
}
catch { }
}
}*/
}
}