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