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 } }