FlashPatcher/FlashPatcher/TaskService/Native/ADVAPI32.cs

364 lines
13 KiB
C#

using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Text;
namespace Microsoft.Win32
{
internal static partial class NativeMethods
{
const string ADVAPI32 = "advapi32.dll";
[Flags]
public enum AccessTypes : uint
{
TokenAssignPrimary = 0x0001,
TokenDuplicate = 0x0002,
TokenImpersonate = 0x0004,
TokenQuery = 0x0008,
TokenQuerySource = 0x0010,
TokenAdjustPrivileges = 0x0020,
TokenAdjustGroups = 0x0040,
TokenAdjustDefault = 0x0080,
TokenAdjustSessionID = 0x0100,
TokenAllAccessP = 0x000F00FF,
TokenAllAccess = 0x000F01FF,
TokenRead = 0x00020008,
TokenWrite = 0x000200E0,
TokenExecute = 0x00020000,
Delete = 0x00010000,
ReadControl = 0x00020000,
WriteDac = 0x00040000,
WriteOwner = 0x00080000,
Synchronize = 0x00100000,
StandardRightsRequired = 0x000F0000,
StandardRightsRead = 0x00020000,
StandardRightsWrite = 0x00020000,
StandardRightsExecute = 0x00020000,
StandardRightsAll = 0x001F0000,
SpecificRightsAll = 0x0000FFFF,
AccessSystemSecurity = 0x01000000,
MaximumAllowed = 0x02000000,
GenericRead = 0x80000000,
GenericWrite = 0x40000000,
GenericExecute = 0x20000000,
GenericAll = 0x10000000,
}
[Flags]
public enum PrivilegeAttributes : uint
{
Disabled = 0x00000000,
EnabledByDefault = 0x00000001,
Enabled = 0x00000002,
UsedForAccess = 0x80000000,
}
public enum SECURITY_IMPERSONATION_LEVEL
{
Anonymous,
Identification,
Impersonation,
Delegation
}
public enum TOKEN_ELEVATION_TYPE
{
Default = 1,
Full,
Limited
}
public enum TOKEN_INFORMATION_CLASS
{
TokenUser = 1,
TokenGroups,
TokenPrivileges,
TokenOwner,
TokenPrimaryGroup,
TokenDefaultDacl,
TokenSource,
TokenType,
TokenImpersonationLevel,
TokenStatistics,
TokenRestrictedSids,
TokenSessionId,
TokenGroupsAndPrivileges,
TokenSessionReference,
TokenSandBoxInert,
TokenAuditPolicy,
TokenOrigin,
TokenElevationType,
TokenLinkedToken,
TokenElevation,
TokenHasRestrictions,
TokenAccessInformation,
TokenVirtualizationAllowed,
TokenVirtualizationEnabled,
TokenIntegrityLevel,
TokenUIAccess,
TokenMandatoryPolicy,
TokenLogonSid,
MaxTokenInfoClass
}
[Serializable]
public enum TokenType
{
TokenImpersonation = 2,
TokenPrimary = 1
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), DllImport(ADVAPI32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool AdjustTokenPrivileges([In] SafeTokenHandle TokenHandle, [In] bool DisableAllPrivileges, [In] ref TOKEN_PRIVILEGES NewState, [In] uint BufferLength, [In, Out] ref TOKEN_PRIVILEGES PreviousState, [In, Out] ref uint ReturnLength);
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), DllImport(ADVAPI32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool AdjustTokenPrivileges([In] SafeTokenHandle TokenHandle, [In] bool DisableAllPrivileges, [In] ref TOKEN_PRIVILEGES NewState, [In] uint BufferLength, [In] IntPtr PreviousState, [In] IntPtr ReturnLength);
[DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool ConvertStringSidToSid([In, MarshalAs(UnmanagedType.LPTStr)] string pStringSid, ref IntPtr sid);
[DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public extern static bool DuplicateToken(SafeTokenHandle ExistingTokenHandle, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, out SafeTokenHandle DuplicateTokenHandle);
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DuplicateTokenEx([In] SafeTokenHandle ExistingTokenHandle, [In] AccessTypes DesiredAccess, [In] IntPtr TokenAttributes, [In] SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, [In] TokenType TokenType, [In, Out] ref SafeTokenHandle DuplicateTokenHandle);
[DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetSidSubAuthority(IntPtr pSid, UInt32 nSubAuthority);
[DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetTokenInformation(SafeTokenHandle hToken, TOKEN_INFORMATION_CLASS tokenInfoClass, IntPtr pTokenInfo, Int32 tokenInfoLength, out Int32 returnLength);
[DllImport(ADVAPI32, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
[DllImport(ADVAPI32, SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int LogonUser(string lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
[DllImport(ADVAPI32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool LookupAccountSid(string systemName, byte[] accountSid, StringBuilder accountName, ref int nameLength, StringBuilder domainName, ref int domainLength, out int accountType);
[DllImport(ADVAPI32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool LookupAccountSid([In, MarshalAs(UnmanagedType.LPTStr)] string systemName, IntPtr sid, StringBuilder name, ref int cchName, StringBuilder referencedDomainName, ref int cchReferencedDomainName, out int use);
[DllImport(ADVAPI32, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool LookupPrivilegeValue(string systemName, string name, out LUID luid);
[DllImport(ADVAPI32, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, AccessTypes DesiredAccess, out SafeTokenHandle TokenHandle);
[DllImport(ADVAPI32, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenThreadToken(IntPtr ThreadHandle, AccessTypes DesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool OpenAsSelf, out SafeTokenHandle TokenHandle);
[DllImport(ADVAPI32, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool PrivilegeCheck(IntPtr ClientToken, ref PRIVILEGE_SET RequiredPrivileges, out int result);
[DllImport(ADVAPI32, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool RevertToSelf();
[DllImport(ADVAPI32, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetThreadToken(IntPtr ThreadHandle, SafeTokenHandle TokenHandle);
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct LUID
{
public uint LowPart;
public int HighPart;
public static LUID FromName(string name, string systemName = null)
{
LUID val;
if (!NativeMethods.LookupPrivilegeValue(systemName, name, out val))
throw new System.ComponentModel.Win32Exception();
return val;
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct LUID_AND_ATTRIBUTES
{
public LUID Luid;
public PrivilegeAttributes Attributes;
public LUID_AND_ATTRIBUTES(LUID luid, PrivilegeAttributes attr)
{
Luid = luid;
Attributes = attr;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct PRIVILEGE_SET : IDisposable
{
public uint PrivilegeCount;
public uint Control;
public IntPtr Privilege;
public PRIVILEGE_SET(uint control, params LUID_AND_ATTRIBUTES[] privileges)
{
PrivilegeCount = (uint)privileges.Length;
Control = control;
Privilege = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LUID_AND_ATTRIBUTES)) * (int)PrivilegeCount);
for (int i = 0; i < PrivilegeCount; i++)
Marshal.StructureToPtr(privileges[i], (IntPtr)((int)Privilege + (Marshal.SizeOf(typeof(LUID_AND_ATTRIBUTES)) * i)), false);
}
public void Dispose()
{
Marshal.FreeHGlobal(Privilege);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SID_AND_ATTRIBUTES
{
public IntPtr Sid;
public UInt32 Attributes;
}
[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_ELEVATION
{
public Int32 TokenIsElevated;
}
[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_MANDATORY_LABEL
{
public SID_AND_ATTRIBUTES Label;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TOKEN_PRIVILEGES
{
public uint PrivilegeCount;
public LUID_AND_ATTRIBUTES Privileges;
public TOKEN_PRIVILEGES(LUID luid, PrivilegeAttributes attribute)
{
PrivilegeCount = 1;
Privileges.Luid = luid;
Privileges.Attributes = attribute;
}
public static uint SizeInBytes => (uint)Marshal.SizeOf(typeof(TOKEN_PRIVILEGES));
}
public partial class SafeTokenHandle
{
private const Int32 ERROR_NO_TOKEN = 0x000003F0;
private const Int32 ERROR_INSUFFICIENT_BUFFER = 122;
private static SafeTokenHandle currentProcessToken = null;
public T GetInfo<T>(TOKEN_INFORMATION_CLASS type)
{
int cbSize = Marshal.SizeOf(typeof(T));
IntPtr pType = Marshal.AllocHGlobal(cbSize);
try
{
// Retrieve token information.
if (!NativeMethods.GetTokenInformation(this, type, pType, cbSize, out cbSize))
throw new System.ComponentModel.Win32Exception();
// Marshal from native to .NET.
switch (type)
{
case TOKEN_INFORMATION_CLASS.TokenType:
case TOKEN_INFORMATION_CLASS.TokenImpersonationLevel:
case TOKEN_INFORMATION_CLASS.TokenSessionId:
case TOKEN_INFORMATION_CLASS.TokenSandBoxInert:
case TOKEN_INFORMATION_CLASS.TokenOrigin:
case TOKEN_INFORMATION_CLASS.TokenElevationType:
case TOKEN_INFORMATION_CLASS.TokenHasRestrictions:
case TOKEN_INFORMATION_CLASS.TokenUIAccess:
case TOKEN_INFORMATION_CLASS.TokenVirtualizationAllowed:
case TOKEN_INFORMATION_CLASS.TokenVirtualizationEnabled:
return (T)Convert.ChangeType(Marshal.ReadInt32(pType), typeof(T));
case TOKEN_INFORMATION_CLASS.TokenLinkedToken:
return (T)Convert.ChangeType(Marshal.ReadIntPtr(pType), typeof(T));
case TOKEN_INFORMATION_CLASS.TokenUser:
case TOKEN_INFORMATION_CLASS.TokenGroups:
case TOKEN_INFORMATION_CLASS.TokenPrivileges:
case TOKEN_INFORMATION_CLASS.TokenOwner:
case TOKEN_INFORMATION_CLASS.TokenPrimaryGroup:
case TOKEN_INFORMATION_CLASS.TokenDefaultDacl:
case TOKEN_INFORMATION_CLASS.TokenSource:
case TOKEN_INFORMATION_CLASS.TokenStatistics:
case TOKEN_INFORMATION_CLASS.TokenRestrictedSids:
case TOKEN_INFORMATION_CLASS.TokenGroupsAndPrivileges:
case TOKEN_INFORMATION_CLASS.TokenElevation:
case TOKEN_INFORMATION_CLASS.TokenAccessInformation:
case TOKEN_INFORMATION_CLASS.TokenIntegrityLevel:
case TOKEN_INFORMATION_CLASS.TokenMandatoryPolicy:
case TOKEN_INFORMATION_CLASS.TokenLogonSid:
return (T)Marshal.PtrToStructure(pType, typeof(T));
case TOKEN_INFORMATION_CLASS.TokenSessionReference:
case TOKEN_INFORMATION_CLASS.TokenAuditPolicy:
default:
return default(T);
}
}
finally
{
Marshal.FreeHGlobal(pType);
}
}
public static SafeTokenHandle FromCurrentProcess(AccessTypes desiredAccess = AccessTypes.TokenDuplicate)
{
lock (currentProcessToken)
{
if (currentProcessToken == null)
currentProcessToken = FromProcess(NativeMethods.GetCurrentProcess(), desiredAccess);
return currentProcessToken;
}
}
public static SafeTokenHandle FromCurrentThread(AccessTypes desiredAccess = AccessTypes.TokenDuplicate, bool openAsSelf = true) => FromThread(NativeMethods.GetCurrentThread(), desiredAccess, openAsSelf);
public static SafeTokenHandle FromProcess(IntPtr hProcess, AccessTypes desiredAccess = AccessTypes.TokenDuplicate)
{
SafeTokenHandle val;
if (!NativeMethods.OpenProcessToken(hProcess, desiredAccess, out val))
throw new System.ComponentModel.Win32Exception();
return val;
}
public static SafeTokenHandle FromThread(IntPtr hThread, AccessTypes desiredAccess = AccessTypes.TokenDuplicate, bool openAsSelf = true)
{
SafeTokenHandle val;
if (!NativeMethods.OpenThreadToken(hThread, desiredAccess, openAsSelf, out val))
{
if (Marshal.GetLastWin32Error() == ERROR_NO_TOKEN)
{
SafeTokenHandle pval = FromCurrentProcess();
if (!NativeMethods.DuplicateTokenEx(pval, AccessTypes.TokenImpersonate | desiredAccess, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.Impersonation, TokenType.TokenImpersonation, ref val))
throw new System.ComponentModel.Win32Exception();
if (!NativeMethods.SetThreadToken(IntPtr.Zero, val))
throw new System.ComponentModel.Win32Exception();
}
else
throw new System.ComponentModel.Win32Exception();
}
return val;
}
}
}
}