1 /* 2 * PROJECT: ReactOS Task Manager 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: System Shutdown. 5 * COPYRIGHT: Copyright 1999-2001 Brian Palmer <brianp@reactos.org> 6 * Copyright 2011 Mário Kacmár /Mario Kacmar/ aka Kario <kario@szm.sk> 7 * Copyright 2014 Robert Naumann <gonzomdx@gmail.com> 8 */ 9 10 #include "precomp.h" 11 #include <ndk/exfuncs.h> 12 #include <ndk/pofuncs.h> 13 #include <ndk/rtlfuncs.h> 14 15 // Uncomment when NtInitiatePowerAction() is implemented 16 // #define NT_INITIATE_POWERACTION_IMPLEMENTED 17 18 static BOOL 19 EnablePrivilege(LPCWSTR lpszPrivilegeName, BOOL bEnablePrivilege) 20 { 21 BOOL Success; 22 HANDLE hToken; 23 TOKEN_PRIVILEGES tp; 24 25 Success = OpenProcessToken(GetCurrentProcess(), 26 TOKEN_ADJUST_PRIVILEGES, 27 &hToken); 28 if (!Success) return Success; 29 30 Success = LookupPrivilegeValueW(NULL, 31 lpszPrivilegeName, 32 &tp.Privileges[0].Luid); 33 if (!Success) goto Quit; 34 35 tp.PrivilegeCount = 1; 36 tp.Privileges[0].Attributes = (bEnablePrivilege ? SE_PRIVILEGE_ENABLED : 0); 37 38 Success = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL); 39 40 Quit: 41 CloseHandle(hToken); 42 return Success; 43 } 44 45 VOID 46 ShutDown_StandBy(VOID) 47 { 48 NTSTATUS Status; 49 50 if (!EnablePrivilege(SE_SHUTDOWN_NAME, TRUE)) 51 { 52 ShowWin32Error(GetLastError()); 53 return; 54 } 55 56 #ifdef NT_INITIATE_POWERACTION_IMPLEMENTED 57 Status = NtInitiatePowerAction(PowerActionSleep, 58 PowerSystemSleeping1, 59 0, FALSE); 60 #else 61 Status = NtSetSystemPowerState(PowerActionSleep, 62 PowerSystemSleeping1, 63 0); 64 #endif 65 66 if (!NT_SUCCESS(Status)) 67 ShowWin32Error(RtlNtStatusToDosError(Status)); 68 69 EnablePrivilege(SE_SHUTDOWN_NAME, FALSE); 70 } 71 72 VOID 73 ShutDown_Hibernate(VOID) 74 { 75 NTSTATUS Status; 76 77 if (!EnablePrivilege(SE_SHUTDOWN_NAME, TRUE)) 78 { 79 ShowWin32Error(GetLastError()); 80 return; 81 } 82 83 #ifdef NT_INITIATE_POWERACTION_IMPLEMENTED 84 Status = NtInitiatePowerAction(PowerActionHibernate, 85 PowerSystemHibernate, 86 0, FALSE); 87 #else 88 Status = NtSetSystemPowerState(PowerActionHibernate, 89 PowerSystemHibernate, 90 0); 91 #endif 92 93 if (!NT_SUCCESS(Status)) 94 ShowWin32Error(RtlNtStatusToDosError(Status)); 95 96 EnablePrivilege(SE_SHUTDOWN_NAME, FALSE); 97 } 98 99 VOID 100 ShutDown_PowerOff(VOID) 101 { 102 /* Trick: on Windows, pressing the CTRL key forces shutdown via NT API */ 103 BOOL ForceShutdown = !!(GetKeyState(VK_CONTROL) & 0x8000); 104 105 if (!EnablePrivilege(SE_SHUTDOWN_NAME, TRUE)) 106 { 107 ShowWin32Error(GetLastError()); 108 return; 109 } 110 111 if (ForceShutdown) 112 { 113 NTSTATUS Status = NtShutdownSystem(ShutdownPowerOff); 114 if (!NT_SUCCESS(Status)) 115 ShowWin32Error(RtlNtStatusToDosError(Status)); 116 } 117 else 118 { 119 // The choice of EWX_SHUTDOWN or EWX_POWEROFF may be done with NtPowerInformation 120 if (!ExitWindowsEx(EWX_POWEROFF /* EWX_SHUTDOWN */, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER)) 121 ShowWin32Error(GetLastError()); 122 } 123 124 EnablePrivilege(SE_SHUTDOWN_NAME, FALSE); 125 } 126 127 VOID 128 ShutDown_Reboot(VOID) 129 { 130 /* Trick: on Windows, pressing the CTRL key forces reboot via NT API */ 131 BOOL ForceReboot = !!(GetKeyState(VK_CONTROL) & 0x8000); 132 133 if (!EnablePrivilege(SE_SHUTDOWN_NAME, TRUE)) 134 { 135 ShowWin32Error(GetLastError()); 136 return; 137 } 138 139 if (ForceReboot) 140 { 141 NTSTATUS Status = NtShutdownSystem(ShutdownReboot); 142 if (!NT_SUCCESS(Status)) 143 ShowWin32Error(RtlNtStatusToDosError(Status)); 144 } 145 else 146 { 147 if (!ExitWindowsEx(EWX_REBOOT, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER)) 148 ShowWin32Error(GetLastError()); 149 } 150 151 EnablePrivilege(SE_SHUTDOWN_NAME, FALSE); 152 } 153 154 VOID 155 ShutDown_LogOffUser(VOID) 156 { 157 if (!ExitWindowsEx(EWX_LOGOFF, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER)) 158 ShowWin32Error(GetLastError()); 159 } 160 161 VOID 162 ShutDown_SwitchUser(VOID) 163 { 164 } 165 166 VOID 167 ShutDown_LockComputer(VOID) 168 { 169 if (!LockWorkStation()) 170 ShowWin32Error(GetLastError()); 171 } 172 173 VOID 174 ShutDown_Disconnect(VOID) 175 { 176 } 177 178 VOID 179 ShutDown_EjectComputer(VOID) 180 { 181 } 182