public static IntegrityLevel GetProcessIntegrityLevel(IntPtr processHandle)
{
IntegrityLevel il;
SafeTokenHandle hToken = null;
IntPtr pTokenIL = IntPtr.Zero;
try
{
// Open the access token of the current process with TOKEN_QUERY.
if (!NativeMethods.OpenProcessToken(processHandle, NativeMethods.TOKEN_QUERY, out hToken))
{
throw new Win32Exception();
}
// Then we must query the size of the integrity level information
// associated with the token. Note that we expect GetTokenInformation
// to return false with the ERROR_INSUFFICIENT_BUFFER error code
// because we've given it a null buffer. On exit cbTokenIL will tell
// the size of the group information.
int cbTokenIL;
if (!NativeMethods.GetTokenInformation(hToken,
TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, IntPtr.Zero, 0,
out cbTokenIL))
{
int error = Marshal.GetLastWin32Error();
if (error != NativeMethods.ERROR_INSUFFICIENT_BUFFER)
{
// When the process is run on operating systems prior to
// Windows Vista, GetTokenInformation returns false with the
// ERROR_INVALID_PARAMETER error code because
// TokenIntegrityLevel is not supported on those OS's.
throw new Win32Exception(error);
}
}
// Now we allocate a buffer for the integrity level information.
pTokenIL = Marshal.AllocHGlobal(cbTokenIL);
if (pTokenIL == IntPtr.Zero)
{
throw new Win32Exception();
}
// Now we ask for the integrity level information again. This may fail
// if an administrator has added this account to an additional group
// between our first call to GetTokenInformation and this one.
if (!NativeMethods.GetTokenInformation(hToken,
TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, pTokenIL, cbTokenIL,
out cbTokenIL))
{
throw new Win32Exception();
}
// Marshal the TOKEN_MANDATORY_LABEL struct from native to .NET object.
var tokenIL = (TOKEN_MANDATORY_LABEL)Marshal.PtrToStructure(pTokenIL, typeof(TOKEN_MANDATORY_LABEL));
// Integrity Level SIDs are in the form of S-1-16-0xXXXX. (e.g.
// S-1-16-0x1000 stands for low integrity level SID). There is one
// and only one subauthority.
IntPtr pIL = NativeMethods.GetSidSubAuthority(tokenIL.Label.Sid, 0);
switch (Marshal.ReadInt32(pIL))
{
case NativeMethods.SECURITY_MANDATORY_UNTRUSTED_RID:
il = IntegrityLevel.Untrusted; break;
case NativeMethods.SECURITY_MANDATORY_LOW_RID:
il = IntegrityLevel.Low; break;
case NativeMethods.SECURITY_MANDATORY_MEDIUM_RID:
il = IntegrityLevel.Medium; break;
case NativeMethods.SECURITY_MANDATORY_HIGH_RID:
il = IntegrityLevel.High; break;
case NativeMethods.SECURITY_MANDATORY_SYSTEM_RID:
il = IntegrityLevel.System; break;
default:
il = IntegrityLevel.Unknown; break;
}
}
finally
{
// Очищаем неуправляемые ресурсы
if (hToken != null)
{
hToken.Close();
}
if (pTokenIL != IntPtr.Zero)
{
Marshal.FreeHGlobal(pTokenIL);
}
}
return il;
}