mirror of
https://github.com/ZuneDev/ZuneModdingHelper.git
synced 2026-07-27 13:12:21 -07:00
120 lines
3.5 KiB
C#
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
|
|
}
|
|
}
|