Last active
December 23, 2021 02:49
-
-
Save AlphaModder/be65deb4af490051b7c1b1c573ba9916 to your computer and use it in GitHub Desktop.
P/Invoke definitions for PTOKEN_PRIVILEGES, for use in GetTokenInformation or AdjustTokenPrivileges
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[StructLayout(LayoutKind.Sequential)] | |
public struct LUID | |
{ | |
public int LowPart; | |
public int HighPart; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct LUID_AND_ATTRIBUTES | |
{ | |
public LUID Luid; | |
public int Attr; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct PTOKEN_PRIVILEGES : IDisposable, IEnumerable<LUID_AND_ATTRIBUTES> | |
{ | |
IntPtr value; | |
public PTOKEN_PRIVILEGES(IntPtr value) | |
{ | |
this.value = value; | |
} | |
public int Count | |
{ | |
get => this.value == IntPtr.Zero ? 0 : Marshal.ReadInt32(this.value); | |
private set => Marshal.WriteInt32(this.value, value); | |
} | |
private IntPtr GetIndexPtr(int index) | |
{ | |
if (index < 0 || index >= this.Count) throw new IndexOutOfRangeException($"Index {index} out of range for Privileges with Count = {this.Count}!"); | |
return this.value + 4 + Marshal.SizeOf<LUID_AND_ATTRIBUTES>() * index; | |
} | |
public LUID_AND_ATTRIBUTES this[int index] | |
{ | |
get => Marshal.PtrToStructure<LUID_AND_ATTRIBUTES>(this.GetIndexPtr(index)); | |
set => Marshal.StructureToPtr(value, this.GetIndexPtr(index), false); | |
} | |
public PTOKEN_PRIVILEGES(int count) | |
{ | |
this.value = Marshal.AllocHGlobal(4 + count * Marshal.SizeOf<LUID_AND_ATTRIBUTES>()); | |
this.Count = count; | |
} | |
public PTOKEN_PRIVILEGES(LUID_AND_ATTRIBUTES[] data) : this(data.Length) | |
{ | |
for (int i = 0; i < this.Count; ++i) this[i] = data[i]; | |
} | |
private struct Enumerator : IEnumerator<LUID_AND_ATTRIBUTES> | |
{ | |
public PTOKEN_PRIVILEGES privileges; | |
public int index; | |
public LUID_AND_ATTRIBUTES Current => privileges[index]; | |
object System.Collections.IEnumerator.Current => this.Current; | |
public bool MoveNext() | |
{ | |
if (this.index + 1 >= privileges.Count) { return false; } | |
this.index += 1; | |
return true; | |
} | |
public void Reset() | |
{ | |
this.index = -1; | |
} | |
public void Dispose() | |
{ | |
this.privileges = default; | |
} | |
} | |
public IEnumerator<LUID_AND_ATTRIBUTES> GetEnumerator() => new Enumerator { privileges = this, index = -1 }; | |
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); | |
public void Dispose() | |
{ | |
Marshal.FreeHGlobal(this.value); | |
this.value = IntPtr.Zero; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment