Files
ZuneModdingHelper/ZuneModCore/Win32/TokenManipulator.cs
T

120 lines
3.5 KiB
C#

using System;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
using Vanara.PInvoke;
namespace ZuneModCore.Win32;
public class TokenManipulator
{
public static bool AddPrivilege(string privilege)
{
try
{
bool retVal;
var hproc = Kernel32.GetCurrentProcess();
retVal = AdvApi32.OpenProcessToken(hproc,
AdvApi32.TokenAccess.TOKEN_ADJUST_PRIVILEGES | AdvApi32.TokenAccess.TOKEN_QUERY, out var htok);
retVal = AdvApi32.LookupPrivilegeValue(null, privilege, out var tpLuid);
AdvApi32.TOKEN_PRIVILEGES tp = new(tpLuid, AdvApi32.PrivilegeAttributes.SE_PRIVILEGE_ENABLED);
AdvApi32.AdjustTokenPrivileges(htok, false, in tp, out _).ThrowIfFailed();
return retVal;
}
catch
{
throw;
}
}
public static bool RemovePrivilege(string privilege)
{
try
{
bool retVal;
var hproc = Kernel32.GetCurrentProcess();
retVal = AdvApi32.OpenProcessToken(hproc,
AdvApi32.TokenAccess.TOKEN_ADJUST_PRIVILEGES | AdvApi32.TokenAccess.TOKEN_QUERY, out var htok);
retVal = AdvApi32.LookupPrivilegeValue(null, privilege, out var tpLuid);
AdvApi32.TOKEN_PRIVILEGES tp = new(tpLuid, AdvApi32.PrivilegeAttributes.SE_PRIVILEGE_DISABLED);
AdvApi32.AdjustTokenPrivileges(htok, false, in tp, out _).ThrowIfFailed();
return retVal;
}
catch
{
throw;
}
}
public static void TakeOwnership(FileInfo file)
{
EscalateToAdmin();
// Get access control
FileSecurity security = file.GetAccessControl();
SecurityIdentifier? cu = WindowsIdentity.GetCurrent().User;
// Set owner to current user
security.SetOwner(cu);
security.SetAccessRule(new FileSystemAccessRule(cu, FileSystemRights.Modify, AccessControlType.Allow));
// Update the Access Control on the original file
file.SetAccessControl(security);
}
public static void TakeOwnership(DirectoryInfo dir)
{
EscalateToAdmin();
// Get access control
DirectorySecurity security = dir.GetAccessControl();
SecurityIdentifier? cu = WindowsIdentity.GetCurrent().User;
// Set owner to current user
security.SetOwner(cu);
security.SetAccessRule(new FileSystemAccessRule(cu, FileSystemRights.Modify, AccessControlType.Allow));
// Update the Access Control on the original file
dir.SetAccessControl(security);
}
public static void TakeOwnership(FileSystemInfo info)
{
if (info is FileInfo file)
TakeOwnership(file);
else if (info is DirectoryInfo dir)
TakeOwnership(dir);
}
public static bool TryTakeOwnership(FileInfo file, out Exception? exception)
{
try
{
TakeOwnership(file);
exception = null;
return true;
}
catch (Exception ex)
{
exception = ex;
return false;
}
}
public static void EscalateToAdmin()
{
// Activate necessary admin privileges to make changes without NTFS perms
AddPrivilege("SeRestorePrivilege"); // Necessary to set Owner Permissions
AddPrivilege("SeBackupPrivilege"); // Necessary to bypass Traverse Checking
AddPrivilege("SeTakeOwnershipPrivilege"); // Necessary to override FilePermissions
}
}