private static void CallShutdown(ShutdownFlags shutdownFlag, bool force)
{
if (!CheckEntryPoint("kernel32.dll", "GetCurrentProcess"))
{
throw new PlatformNotSupportedException("'GetCurrentProcess' method missing from 'kernel32.dll'!");
}
// if force append to flag
if (force)
{
shutdownFlag = shutdownFlag | ShutdownFlags.Force;
}
// open current process tokens
var currentProcess = NativeMethods.GetCurrentProcess();
var @null = IntPtr.Zero;
// request privileges
if (CheckEntryPoint("advapi32.dll", "OpenProcessToken"))
{
// open process token
if (!NativeMethods.OpenProcessToken(currentProcess, TokenAdjustPrivileges | TokenQuery, ref @null))
{
// failed...
}
// lookup privilege
NativeMethods.LuidAtt luid;
luid.Count = 1;
luid.Luid = 0;
luid.Attr = SePrivilegeEnabled;
if (!NativeMethods.LookupPrivilegeValue(null, SeShutdownName, ref luid.Luid))
{
// failed...
}
// adjust privileges and call shutdown
if (NativeMethods.AdjustTokenPrivileges(@null, false, ref luid, 0, IntPtr.Zero, IntPtr.Zero))
{
// failed...
}
}
// assume pre 2000, and call exit windows anyway
// call exitWindows api
if (NativeMethods.ExitWindowsEx((int)shutdownFlag, 0))
{
// failed...
}
}