Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
Privilege.cs
Go to the documentation of this file.
7
9
10internal sealed class Privilege
11{
12 private sealed class TlsContents : IDisposable
13 {
14 private bool disposed;
15
16 private int referenceCount = 1;
17
19
20 private readonly bool isImpersonating;
21
23
24 private static readonly object syncRoot = new object();
25
27
29
31
32 public TlsContents()
33 {
34 int num = 0;
35 int num2 = 0;
36 bool flag = true;
37 if (processHandle.IsInvalid)
38 {
40 {
41 if (processHandle.IsInvalid)
42 {
43 if (!global::Interop.Advapi32.OpenProcessToken(global::Interop.Kernel32.GetCurrentProcess(), TokenAccessLevels.Duplicate, out var TokenHandle))
44 {
46 flag = false;
47 }
49 }
50 }
51 }
52 try
53 {
55 num = System.Security.Principal.Win32.OpenThreadToken(TokenAccessLevels.Query | TokenAccessLevels.AdjustPrivileges, System.Security.Principal.WinSecurityContext.Process, out threadHandle);
56 num &= 0x7FF8FFFF;
57 if (num != 0)
58 {
59 if (flag)
60 {
62 if (num != 1008)
63 {
64 flag = false;
65 }
66 if (flag)
67 {
68 num = 0;
69 if (!global::Interop.Advapi32.DuplicateTokenEx(processHandle, TokenAccessLevels.Impersonate | TokenAccessLevels.Query | TokenAccessLevels.AdjustPrivileges, IntPtr.Zero, global::Interop.Advapi32.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, System.Security.Principal.TokenType.TokenImpersonation, ref threadHandle))
70 {
72 flag = false;
73 }
74 }
75 if (flag)
76 {
78 num &= 0x7FF8FFFF;
79 if (num != 0)
80 {
81 flag = false;
82 }
83 }
84 if (flag)
85 {
86 isImpersonating = true;
87 }
88 }
89 else
90 {
91 num = num2;
92 }
93 }
94 else
95 {
96 flag = true;
97 }
98 }
99 finally
100 {
101 if (!flag)
102 {
103 Dispose();
104 }
105 }
106 switch (num)
107 {
108 case 8:
109 throw new OutOfMemoryException();
110 case 5:
111 case 1347:
112 throw new UnauthorizedAccessException();
113 default:
114 throw new InvalidOperationException();
115 case 0:
116 break;
117 }
118 }
119
121 {
122 if (!disposed)
123 {
124 Dispose(disposing: false);
125 }
126 }
127
128 public void Dispose()
129 {
130 Dispose(disposing: true);
131 GC.SuppressFinalize(this);
132 }
133
134 private void Dispose(bool disposing)
135 {
136 if (!disposed)
137 {
138 if (disposing && threadHandle != null)
139 {
141 threadHandle = null;
142 }
143 if (isImpersonating)
144 {
145 global::Interop.Advapi32.RevertToSelf();
146 }
147 disposed = true;
148 }
149 }
150
152 {
154 }
155
157 {
158 int num = --referenceCount;
159 if (num == 0)
160 {
161 Dispose();
162 }
163 return num;
164 }
165 }
166
169
170 private static readonly Dictionary<global::Interop.Advapi32.LUID, string> privileges = new Dictionary<global::Interop.Advapi32.LUID, string>();
171
172 private static readonly Dictionary<string, global::Interop.Advapi32.LUID> luids = new Dictionary<string, global::Interop.Advapi32.LUID>();
173
174 private static readonly ReaderWriterLockSlim privilegeLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
175
176 private bool needToRevert;
177
178 private bool initialState;
179
180 private bool stateWasChanged;
181
182 private global::Interop.Advapi32.LUID luid;
183
185
187
189
190 private static global::Interop.Advapi32.LUID LuidFromPrivilege(string privilege)
191 {
192 Unsafe.SkipInit(out global::Interop.Advapi32.LUID lpLuid);
193 lpLuid.LowPart = 0;
194 lpLuid.HighPart = 0;
195 try
196 {
197 privilegeLock.EnterReadLock();
198 if (luids.ContainsKey(privilege))
199 {
201 privilegeLock.ExitReadLock();
202 }
203 else
204 {
205 privilegeLock.ExitReadLock();
206 if (!global::Interop.Advapi32.LookupPrivilegeValue(null, privilege, out lpLuid))
207 {
208 switch (Marshal.GetLastWin32Error())
209 {
210 case 8:
211 throw new OutOfMemoryException();
212 case 5:
213 throw new UnauthorizedAccessException();
214 case 1313:
216 default:
217 throw new InvalidOperationException();
218 }
219 }
220 privilegeLock.EnterWriteLock();
221 }
222 }
223 finally
224 {
225 if (privilegeLock.IsReadLockHeld)
226 {
227 privilegeLock.ExitReadLock();
228 }
229 if (privilegeLock.IsWriteLockHeld)
230 {
231 if (!luids.ContainsKey(privilege))
232 {
235 }
236 privilegeLock.ExitWriteLock();
237 }
238 }
239 return lpLuid;
240 }
241
243 {
244 if (privilegeName == null)
245 {
246 throw new ArgumentNullException("privilegeName");
247 }
249 }
250
252 {
253 if (needToRevert)
254 {
255 Revert();
256 }
257 }
258
259 public void Enable()
260 {
261 ToggleState(enable: true);
262 }
263
264 private unsafe void ToggleState(bool enable)
265 {
266 int num = 0;
268 {
270 }
271 if (needToRevert)
272 {
274 }
275 try
276 {
278 if (tlsContents == null)
279 {
280 tlsContents = new TlsContents();
282 }
283 else
284 {
286 }
287 Unsafe.SkipInit(out global::Interop.Advapi32.TOKEN_PRIVILEGE tOKEN_PRIVILEGE);
288 tOKEN_PRIVILEGE.PrivilegeCount = 1u;
289 tOKEN_PRIVILEGE.Privileges.Luid = luid;
290 tOKEN_PRIVILEGE.Privileges.Attributes = (enable ? 2u : 0u);
291 global::Interop.Advapi32.TOKEN_PRIVILEGE tOKEN_PRIVILEGE2 = default(global::Interop.Advapi32.TOKEN_PRIVILEGE);
292 uint num2 = 0u;
293 if (!global::Interop.Advapi32.AdjustTokenPrivileges(tlsContents.ThreadHandle, DisableAllPrivileges: false, &tOKEN_PRIVILEGE, (uint)sizeof(global::Interop.Advapi32.TOKEN_PRIVILEGE), &tOKEN_PRIVILEGE2, &num2))
294 {
296 }
297 else if (1300 == Marshal.GetLastWin32Error())
298 {
299 num = 1300;
300 }
301 else
302 {
303 initialState = (tOKEN_PRIVILEGE2.Privileges.Attributes & 2) != 0;
304 stateWasChanged = initialState != enable;
305 needToRevert = tlsContents.IsImpersonating || stateWasChanged;
306 }
307 }
308 finally
309 {
310 if (!needToRevert)
311 {
312 Reset();
313 }
314 }
315 switch (num)
316 {
317 case 1300:
319 case 8:
320 throw new OutOfMemoryException();
321 case 5:
322 case 1347:
323 throw new UnauthorizedAccessException();
324 default:
325 throw new InvalidOperationException();
326 case 0:
327 break;
328 }
329 }
330
331 public unsafe void Revert()
332 {
333 int num = 0;
335 {
337 }
338 if (!NeedToRevert)
339 {
340 return;
341 }
342 bool flag = true;
343 try
344 {
346 {
347 Unsafe.SkipInit(out global::Interop.Advapi32.TOKEN_PRIVILEGE tOKEN_PRIVILEGE);
348 tOKEN_PRIVILEGE.PrivilegeCount = 1u;
349 tOKEN_PRIVILEGE.Privileges.Luid = luid;
350 tOKEN_PRIVILEGE.Privileges.Attributes = (initialState ? 2u : 0u);
351 if (!global::Interop.Advapi32.AdjustTokenPrivileges(tlsContents.ThreadHandle, DisableAllPrivileges: false, &tOKEN_PRIVILEGE, 0u, null, null))
352 {
354 flag = false;
355 }
356 }
357 }
358 finally
359 {
360 if (flag)
361 {
362 Reset();
363 }
364 }
365 switch (num)
366 {
367 case 8:
368 throw new OutOfMemoryException();
369 case 5:
370 throw new UnauthorizedAccessException();
371 default:
372 throw new InvalidOperationException();
373 case 0:
374 break;
375 }
376 }
377
378 private void Reset()
379 {
380 stateWasChanged = false;
381 initialState = false;
382 needToRevert = false;
383 if (tlsContents != null && tlsContents.DecrementReferenceCount() == 0)
384 {
385 tlsContents = null;
386 t_tlsSlotData = null;
387 }
388 }
389}
static void SuppressFinalize(object obj)
Definition GC.cs:202
Definition GC.cs:8
static string Argument_InvalidPrivilegeName
Definition SR.cs:60
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string InvalidOperation_MustBeSameThread
Definition SR.cs:84
static string InvalidOperation_MustRevertPrivilege
Definition SR.cs:90
Definition SR.cs:7
static volatile SafeTokenHandle processHandle
Definition Privilege.cs:22
static readonly ReaderWriterLockSlim privilegeLock
Definition Privilege.cs:174
unsafe void ToggleState(bool enable)
Definition Privilege.cs:264
static readonly Dictionary< global::Interop.Advapi32.LUID, string > privileges
Definition Privilege.cs:170
static global::Interop.Advapi32.LUID LuidFromPrivilege(string privilege)
Definition Privilege.cs:190
global::Interop.Advapi32.LUID luid
Definition Privilege.cs:182
static readonly Dictionary< string, global::Interop.Advapi32.LUID > luids
Definition Privilege.cs:172
static int SetThreadToken(SafeTokenHandle hToken)
Definition Win32.cs:39
static int OpenThreadToken(TokenAccessLevels dwDesiredAccess, System.Security.Principal.WinSecurityContext dwOpenAs, out SafeTokenHandle phThreadToken)
Definition Win32.cs:8
static Thread CurrentThread
Definition Thread.cs:312
static readonly IntPtr Zero
Definition IntPtr.cs:18