1 /* 2 * ReactOS Task Manager 3 * 4 * shutdown.c 5 * 6 * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org> 7 * 2011 M�rio Kacm�r /Mario Kacmar/ aka Kario (kario@szm.sk) 8 * 2014 Robert Naumann <gonzomdx@gmail.com> 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2.1 of the License, or (at your option) any later version. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 */ 24 25 #include "precomp.h" 26 #include <ndk/exfuncs.h> 27 #include <ndk/pofuncs.h> 28 #include <ndk/rtlfuncs.h> 29 30 // Uncomment when NtInitiatePowerAction() is implemented 31 // #define NT_INITIATE_POWERACTION_IMPLEMENTED 32 33 static BOOL 34 EnablePrivilege(LPCWSTR lpszPrivilegeName, BOOL bEnablePrivilege) 35 { 36 BOOL Success; 37 HANDLE hToken; 38 TOKEN_PRIVILEGES tp; 39 40 Success = OpenProcessToken(GetCurrentProcess(), 41 TOKEN_ADJUST_PRIVILEGES, 42 &hToken); 43 if (!Success) return Success; 44 45 Success = LookupPrivilegeValueW(NULL, 46 lpszPrivilegeName, 47 &tp.Privileges[0].Luid); 48 if (!Success) goto Quit; 49 50 tp.PrivilegeCount = 1; 51 tp.Privileges[0].Attributes = (bEnablePrivilege ? SE_PRIVILEGE_ENABLED : 0); 52 53 Success = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL); 54 55 Quit: 56 CloseHandle(hToken); 57 return Success; 58 } 59 60 VOID 61 ShutDown_StandBy(VOID) 62 { 63 NTSTATUS Status; 64 65 if (!EnablePrivilege(SE_SHUTDOWN_NAME, TRUE)) 66 { 67 ShowWin32Error(GetLastError()); 68 return; 69 } 70 71 #ifdef NT_INITIATE_POWERACTION_IMPLEMENTED 72 Status = NtInitiatePowerAction(PowerActionSleep, 73 PowerSystemSleeping1, 74 0, FALSE); 75 #else 76 Status = NtSetSystemPowerState(PowerActionSleep, 77 PowerSystemSleeping1, 78 0); 79 #endif 80 81 if (!NT_SUCCESS(Status)) 82 ShowWin32Error(RtlNtStatusToDosError(Status)); 83 84 EnablePrivilege(SE_SHUTDOWN_NAME, FALSE); 85 } 86 87 VOID 88 ShutDown_Hibernate(VOID) 89 { 90 NTSTATUS Status; 91 92 if (!EnablePrivilege(SE_SHUTDOWN_NAME, TRUE)) 93 { 94 ShowWin32Error(GetLastError()); 95 return; 96 } 97 98 #ifdef NT_INITIATE_POWERACTION_IMPLEMENTED 99 Status = NtInitiatePowerAction(PowerActionHibernate, 100 PowerSystemHibernate, 101 0, FALSE); 102 #else 103 Status = NtSetSystemPowerState(PowerActionHibernate, 104 PowerSystemHibernate, 105 0); 106 #endif 107 108 if (!NT_SUCCESS(Status)) 109 ShowWin32Error(RtlNtStatusToDosError(Status)); 110 111 EnablePrivilege(SE_SHUTDOWN_NAME, FALSE); 112 } 113 114 VOID 115 ShutDown_PowerOff(VOID) 116 { 117 /* Trick: on Windows, pressing the CTRL key forces shutdown via NT API */ 118 BOOL ForceShutdown = !!(GetKeyState(VK_CONTROL) & 0x8000); 119 120 if (!EnablePrivilege(SE_SHUTDOWN_NAME, TRUE)) 121 { 122 ShowWin32Error(GetLastError()); 123 return; 124 } 125 126 if (ForceShutdown) 127 { 128 NTSTATUS Status = NtShutdownSystem(ShutdownPowerOff); 129 if (!NT_SUCCESS(Status)) 130 ShowWin32Error(RtlNtStatusToDosError(Status)); 131 } 132 else 133 { 134 // The choice of EWX_SHUTDOWN or EWX_POWEROFF may be done with NtPowerInformation 135 if (!ExitWindowsEx(EWX_POWEROFF /* EWX_SHUTDOWN */, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER)) 136 ShowWin32Error(GetLastError()); 137 } 138 139 EnablePrivilege(SE_SHUTDOWN_NAME, FALSE); 140 } 141 142 VOID 143 ShutDown_Reboot(VOID) 144 { 145 /* Trick: on Windows, pressing the CTRL key forces reboot via NT API */ 146 BOOL ForceReboot = !!(GetKeyState(VK_CONTROL) & 0x8000); 147 148 if (!EnablePrivilege(SE_SHUTDOWN_NAME, TRUE)) 149 { 150 ShowWin32Error(GetLastError()); 151 return; 152 } 153 154 if (ForceReboot) 155 { 156 NTSTATUS Status = NtShutdownSystem(ShutdownReboot); 157 if (!NT_SUCCESS(Status)) 158 ShowWin32Error(RtlNtStatusToDosError(Status)); 159 } 160 else 161 { 162 if (!ExitWindowsEx(EWX_REBOOT, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER)) 163 ShowWin32Error(GetLastError()); 164 } 165 166 EnablePrivilege(SE_SHUTDOWN_NAME, FALSE); 167 } 168 169 VOID 170 ShutDown_LogOffUser(VOID) 171 { 172 if (!ExitWindowsEx(EWX_LOGOFF, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER)) 173 ShowWin32Error(GetLastError()); 174 } 175 176 VOID 177 ShutDown_SwitchUser(VOID) 178 { 179 } 180 181 VOID 182 ShutDown_LockComputer(VOID) 183 { 184 if (!LockWorkStation()) 185 ShowWin32Error(GetLastError()); 186 } 187 188 VOID 189 ShutDown_Disconnect(VOID) 190 { 191 } 192 193 VOID 194 ShutDown_EjectComputer(VOID) 195 { 196 } 197