11using System . Runtime . InteropServices ;
22using System . Security ;
3+ using Windows . Win32 ;
4+ using Windows . Win32 . Foundation ;
5+ using Windows . Win32 . Security ;
36
47namespace Win10BloatRemover . Utils ;
58
@@ -8,91 +11,46 @@ namespace Win10BloatRemover.Utils;
811 */
912class TokenPrivilege : IDisposable
1013{
11- private enum PrivilegeAction : uint
12- {
13- Disable = 0x0 ,
14- Enable = 0x2
15- }
16-
1714 public static TokenPrivilege TakeOwnership => new TokenPrivilege ( "SeTakeOwnershipPrivilege" ) ;
1815
1916 private readonly string privilegeName ;
2017
2118 private TokenPrivilege ( string privilegeName )
2219 {
2320 this . privilegeName = privilegeName ;
24- Apply ( PrivilegeAction . Enable ) ;
25- }
26-
27- private void Apply ( PrivilegeAction action )
28- {
29- OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY , out IntPtr tokenHandle ) ;
30- LookupPrivilegeValue ( null , privilegeName , out Luid luid ) ;
31- var tokenPrivilege = new TokenPrivileges ( luid , ( uint ) action ) ;
32- UpdateTokenPrivileges ( tokenHandle , tokenPrivilege ) ;
33- }
34-
35- private void UpdateTokenPrivileges ( IntPtr tokenHandle , TokenPrivileges privilegeInfo )
36- {
37- bool successful = AdjustTokenPrivileges ( tokenHandle , false , ref privilegeInfo , 0 , IntPtr . Zero , IntPtr . Zero ) ;
38- if ( ! successful || Marshal . GetLastWin32Error ( ) == ERROR_NOT_ALL_ASSIGNED )
39- throw new SecurityException ( $ "Can't adjust token privilege { privilegeName } ") ;
21+ TogglePrivilege ( Action . Enable ) ;
4022 }
41-
23+
4224 public void Dispose ( )
4325 {
44- Apply ( PrivilegeAction . Disable ) ;
26+ TogglePrivilege ( Action . Disable ) ;
4527 }
46-
47- #region P/Invoke structs and methods
48- private const int ERROR_NOT_ALL_ASSIGNED = 1300 ;
49-
50- [ StructLayout ( LayoutKind . Sequential ) ]
51- private struct TokenPrivileges ( Luid luid , uint attributes )
28+
29+ private enum Action : uint
5230 {
53- // We can use this struct only with one privilege since CLR doesn't support marshalling dynamic-sized arrays
54- private uint Count = 1 ;
55-
56- [ MarshalAs ( UnmanagedType . ByValArray , SizeConst = 1 ) ]
57- private LuidAndAttributes [ ] Privileges = [ new LuidAndAttributes ( luid , attributes ) ] ;
31+ Disable = 0x0 ,
32+ Enable = 0x2
5833 }
5934
60- [ StructLayout ( LayoutKind . Sequential ) ]
61- private readonly struct LuidAndAttributes ( Luid luid , uint attributes )
35+ private void TogglePrivilege ( Action privilegeAction )
6236 {
63- private readonly Luid Luid = luid ;
64- private readonly uint Attributes = attributes ;
37+ using var currentProcessHandle = WinAPI . GetCurrentProcess_SafeHandle ( ) ;
38+ WinAPI . OpenProcessToken ( currentProcessHandle ,
39+ TOKEN_ACCESS_MASK . TOKEN_ADJUST_PRIVILEGES | TOKEN_ACCESS_MASK . TOKEN_QUERY , out var tokenHandle ) ;
40+ WinAPI . LookupPrivilegeValue ( null , privilegeName , out var privilegeLuid ) ;
41+ UpdateTokenPrivileges ( tokenHandle , privilegeLuid , privilegeAction ) ;
6542 }
6643
67- [ StructLayout ( LayoutKind . Sequential ) ]
68- private readonly struct Luid
44+ private unsafe void UpdateTokenPrivileges ( SafeHandle tokenHandle , LUID privilegeLuid , Action privilegeAction )
6945 {
70- private readonly uint LowPart ;
71- private readonly int HighPart ;
46+ var updatedPrivileges = new TOKEN_PRIVILEGES {
47+ PrivilegeCount = 1 ,
48+ Privileges = new VariableLengthInlineArray < LUID_AND_ATTRIBUTES > {
49+ [ 0 ] = new LUID_AND_ATTRIBUTES { Luid = privilegeLuid , Attributes = ( TOKEN_PRIVILEGES_ATTRIBUTES ) privilegeAction }
50+ }
51+ } ;
52+ bool successful = WinAPI . AdjustTokenPrivileges ( tokenHandle , false , & updatedPrivileges , null ) ;
53+ if ( ! successful || Marshal . GetLastWin32Error ( ) == ( int ) WIN32_ERROR . ERROR_NOT_ALL_ASSIGNED )
54+ throw new SecurityException ( $ "Can't adjust token privilege { privilegeName } ") ;
7255 }
73-
74- private const int TOKEN_QUERY = 0x8 ;
75- private const int TOKEN_ADJUST_PRIVILEGES = 0x20 ;
76-
77- [ DllImport ( "advapi32.dll" , SetLastError = true ) ]
78- [ DefaultDllImportSearchPaths ( DllImportSearchPath . System32 ) ]
79- private static extern bool AdjustTokenPrivileges ( IntPtr tokenHandle ,
80- bool disableAllPrivileges ,
81- ref TokenPrivileges newState ,
82- int bufferLength ,
83- IntPtr previousState ,
84- IntPtr returnLength ) ;
85-
86- [ DllImport ( "kernel32.dll" ) ]
87- [ DefaultDllImportSearchPaths ( DllImportSearchPath . System32 ) ]
88- private static extern IntPtr GetCurrentProcess ( ) ;
89-
90- [ DllImport ( "advapi32.dll" , SetLastError = true ) ]
91- [ DefaultDllImportSearchPaths ( DllImportSearchPath . System32 ) ]
92- private static extern bool OpenProcessToken ( IntPtr processHandle , int desiredAccess , out IntPtr tokenHandle ) ;
93-
94- [ DllImport ( "advapi32.dll" , SetLastError = true ) ]
95- [ DefaultDllImportSearchPaths ( DllImportSearchPath . System32 ) ]
96- private static extern bool LookupPrivilegeValue ( string ? systemName , string privilegeName , out Luid privilegeLuid ) ;
97- #endregion
9856}
0 commit comments