1 #include <windows.h>
2 #include <powrprof.h>
3 #include "screensaver_win.h"
4 
ScreenSaverWin(QObject * parent)5 ScreenSaverWin::ScreenSaverWin(QObject *parent) : ScreenSaver(parent)
6 {
7 
8 }
9 
abilities()10 QSet<ScreenSaverWin::Ability> ScreenSaverWin::abilities()
11 {
12     QSet<Ability> capabilities;
13     capabilities << Inhibit << Uninhibit << LockScreen;
14     if (canShutdown())
15         capabilities << Shutdown << Hibernate << Suspend << LogOff;
16     return capabilities;
17 }
18 
inhibitSaver(const QString & reason)19 void ScreenSaverWin::inhibitSaver(const QString &reason)
20 {
21     Q_UNUSED(reason);
22     if (isInhibiting)
23         return;
24 
25     SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED |
26                             ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED);
27     isInhibiting = true;
28     emit inhibitedSaver();
29 }
30 
uninhibitSaver()31 void ScreenSaverWin::uninhibitSaver()
32 {
33     if (!isInhibiting)
34         return;
35 
36     SetThreadExecutionState(ES_CONTINUOUS);
37     isInhibiting = false;
38     emit uninhibitedSaver();
39 }
40 
launchSaver()41 void ScreenSaverWin::launchSaver()
42 {
43     emit failed(LaunchSaver);
44 }
45 
lockScreen()46 void ScreenSaverWin::lockScreen()
47 {
48     if (LockWorkStation())
49         emit screenLocked();
50     else
51         emit failed(LockScreen);
52 }
53 
hibernateSystem()54 void ScreenSaverWin::hibernateSystem()
55 {
56     if (SetSuspendState(TRUE, FALSE, FALSE))
57         emit systemHibernated();
58     else
59         emit failed(Hibernate);
60 }
61 
suspendSystem()62 void ScreenSaverWin::suspendSystem()
63 {
64     if(SetSuspendState(FALSE, FALSE, FALSE))
65         emit systemSuspended();
66     else
67         emit failed(Suspend);
68 }
69 
shutdownSystem()70 void ScreenSaverWin::shutdownSystem()
71 {
72     if (ExitWindowsEx(EWX_SHUTDOWN, 0))
73         emit systemShutdown();
74     else
75         emit failed(Shutdown);
76 }
77 
logOff()78 void ScreenSaverWin::logOff()
79 {
80     if (ExitWindowsEx(EWX_LOGOFF, 0))
81         emit loggedOff();
82     else
83         emit failed(LogOff);
84 }
85 
canShutdown()86 bool ScreenSaverWin::canShutdown()
87 {
88     HANDLE hToken;
89     TOKEN_PRIVILEGES tkp;
90 
91     // Get a token for this process.
92     if (!OpenProcessToken(GetCurrentProcess(),
93          TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
94        return false;
95 
96     // Get the LUID for the shutdown privilege.
97     LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
98          &tkp.Privileges[0].Luid);
99 
100     tkp.PrivilegeCount = 1;  // one privilege to set
101     tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
102     // Get the shutdown privilege for this process.
103 
104     AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
105          (PTOKEN_PRIVILEGES)NULL, 0);
106 
107     return GetLastError() == ERROR_SUCCESS;
108 }
109 
110