Created
September 30, 2018 17:09
-
-
Save abfo/4d556a2c9b8251914856f4128da35df9 to your computer and use it in GitHub Desktop.
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
static class NativeMethods | |
{ | |
/// | |
/// Reboot the computer | |
/// | |
public static void Reboot() | |
{ | |
IntPtr tokenHandle = IntPtr.Zero; | |
try | |
{ | |
// get process token | |
if (!OpenProcessToken(Process.GetCurrentProcess().Handle, | |
TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, | |
out tokenHandle)) | |
{ | |
throw new Win32Exception(Marshal.GetLastWin32Error(), | |
"Failed to open process token handle"); | |
} | |
// lookup the shutdown privilege | |
TOKEN_PRIVILEGES tokenPrivs = new TOKEN_PRIVILEGES(); | |
tokenPrivs.PrivilegeCount = 1; | |
tokenPrivs.Privileges = new LUID_AND_ATTRIBUTES[1]; | |
tokenPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; | |
if (!LookupPrivilegeValue(null, | |
SE_SHUTDOWN_NAME, | |
out tokenPrivs.Privileges[0].Luid)) | |
{ | |
throw new Win32Exception(Marshal.GetLastWin32Error(), | |
"Failed to open lookup shutdown privilege"); | |
} | |
// add the shutdown privilege to the process token | |
if (!AdjustTokenPrivileges(tokenHandle, | |
false, | |
ref tokenPrivs, | |
0, | |
IntPtr.Zero, | |
IntPtr.Zero)) | |
{ | |
throw new Win32Exception(Marshal.GetLastWin32Error(), | |
"Failed to adjust process token privileges"); | |
} | |
// reboot | |
if (!ExitWindowsEx(ExitWindows.Reboot, | |
ShutdownReason.MajorApplication | | |
ShutdownReason.MinorInstallation | | |
ShutdownReason.FlagPlanned)) | |
{ | |
throw new Win32Exception(Marshal.GetLastWin32Error(), | |
"Failed to reboot system"); | |
} | |
} | |
finally | |
{ | |
// close the process token | |
if (tokenHandle != IntPtr.Zero) | |
{ | |
CloseHandle(tokenHandle); | |
} | |
} | |
} | |
// everything from here on is from pinvoke.net | |
[Flags] | |
private enum ExitWindows : uint | |
{ | |
// ONE of the following five: | |
LogOff = 0x00, | |
ShutDown = 0x01, | |
Reboot = 0x02, | |
PowerOff = 0x08, | |
RestartApps = 0x40, | |
// plus AT MOST ONE of the following two: | |
Force = 0x04, | |
ForceIfHung = 0x10, | |
} | |
[Flags] | |
private enum ShutdownReason : uint | |
{ | |
MajorApplication = 0x00040000, | |
MajorHardware = 0x00010000, | |
MajorLegacyApi = 0x00070000, | |
MajorOperatingSystem = 0x00020000, | |
MajorOther = 0x00000000, | |
MajorPower = 0x00060000, | |
MajorSoftware = 0x00030000, | |
MajorSystem = 0x00050000, | |
MinorBlueScreen = 0x0000000F, | |
MinorCordUnplugged = 0x0000000b, | |
MinorDisk = 0x00000007, | |
MinorEnvironment = 0x0000000c, | |
MinorHardwareDriver = 0x0000000d, | |
MinorHotfix = 0x00000011, | |
MinorHung = 0x00000005, | |
MinorInstallation = 0x00000002, | |
MinorMaintenance = 0x00000001, | |
MinorMMC = 0x00000019, | |
MinorNetworkConnectivity = 0x00000014, | |
MinorNetworkCard = 0x00000009, | |
MinorOther = 0x00000000, | |
MinorOtherDriver = 0x0000000e, | |
MinorPowerSupply = 0x0000000a, | |
MinorProcessor = 0x00000008, | |
MinorReconfig = 0x00000004, | |
MinorSecurity = 0x00000013, | |
MinorSecurityFix = 0x00000012, | |
MinorSecurityFixUninstall = 0x00000018, | |
MinorServicePack = 0x00000010, | |
MinorServicePackUninstall = 0x00000016, | |
MinorTermSrv = 0x00000020, | |
MinorUnstable = 0x00000006, | |
MinorUpgrade = 0x00000003, | |
MinorWMI = 0x00000015, | |
FlagUserDefined = 0x40000000, | |
FlagPlanned = 0x80000000 | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
private struct LUID | |
{ | |
public uint LowPart; | |
public int HighPart; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
private struct LUID_AND_ATTRIBUTES | |
{ | |
public LUID Luid; | |
public UInt32 Attributes; | |
} | |
private struct TOKEN_PRIVILEGES | |
{ | |
public UInt32 PrivilegeCount; | |
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] | |
public LUID_AND_ATTRIBUTES[] Privileges; | |
} | |
private const UInt32 TOKEN_QUERY = 0x0008; | |
private const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020; | |
private const UInt32 SE_PRIVILEGE_ENABLED = 0x00000002; | |
private const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege"; | |
[DllImport("user32.dll", SetLastError = true)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
private static extern bool ExitWindowsEx(ExitWindows uFlags, | |
ShutdownReason dwReason); | |
[DllImport("advapi32.dll", SetLastError = true)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
private static extern bool OpenProcessToken(IntPtr ProcessHandle, | |
UInt32 DesiredAccess, | |
out IntPtr TokenHandle); | |
[DllImport("advapi32.dll", SetLastError = true, CharSet=CharSet.Unicode)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
private static extern bool LookupPrivilegeValue(string lpSystemName, | |
string lpName, | |
out LUID lpLuid); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
private static extern bool CloseHandle(IntPtr hObject); | |
[DllImport("advapi32.dll", SetLastError = true)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
private static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, | |
[MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges, | |
ref TOKEN_PRIVILEGES NewState, | |
UInt32 Zero, | |
IntPtr Null1, | |
IntPtr Null2); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment