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