xref: /reactos/dll/win32/kernel32/client/power.c (revision afca8367)
1 /*
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS system libraries
5  * FILE:            dll/win32/kernel32/client/power.c
6  * PURPOSE:         Power Management Functions
7  * PROGRAMMER:      Dmitry Chapyshev <dmitry@reactos.org>
8  *
9  * UPDATE HISTORY:
10  *                  01/15/2009 Created
11  */
12 
13 #include <k32.h>
14 
15 #include <ndk/pofuncs.h>
16 
17 #define NDEBUG
18 #include <debug.h>
19 
20 /* PUBLIC FUNCTIONS ***********************************************************/
21 
22 /*
23  * @implemented
24  */
25 BOOL
26 WINAPI
GetSystemPowerStatus(IN LPSYSTEM_POWER_STATUS PowerStatus)27 GetSystemPowerStatus(IN LPSYSTEM_POWER_STATUS PowerStatus)
28 {
29     NTSTATUS Status;
30     SYSTEM_BATTERY_STATE BattState;
31     ULONG Max, Current;
32 
33     Status = NtPowerInformation(SystemBatteryState,
34                                 NULL,
35                                 0,
36                                 &BattState,
37                                 sizeof(SYSTEM_BATTERY_STATE));
38     if (!NT_SUCCESS(Status))
39     {
40         BaseSetLastNTError(Status);
41         return FALSE;
42     }
43 
44     RtlZeroMemory(PowerStatus, sizeof(SYSTEM_POWER_STATUS));
45 
46     PowerStatus->BatteryLifeTime = BATTERY_LIFE_UNKNOWN;
47     PowerStatus->BatteryFullLifeTime = BATTERY_LIFE_UNKNOWN;
48     PowerStatus->BatteryLifePercent = BATTERY_PERCENTAGE_UNKNOWN;
49     PowerStatus->ACLineStatus = AC_LINE_ONLINE;
50 
51     Max = BattState.MaxCapacity;
52     Current = BattState.RemainingCapacity;
53     if (Max)
54     {
55         if (Current <= Max)
56         {
57             PowerStatus->BatteryLifePercent = (UCHAR)((100 * Current + Max / 2) / Max);
58         }
59         else
60         {
61             PowerStatus->BatteryLifePercent = 100;
62         }
63 
64         if (PowerStatus->BatteryLifePercent <= 4)
65             PowerStatus->BatteryFlag |= BATTERY_FLAG_CRITICAL;
66 
67         if (PowerStatus->BatteryLifePercent <= 32)
68             PowerStatus->BatteryFlag |= BATTERY_FLAG_LOW;
69 
70         if (PowerStatus->BatteryLifePercent >= 67)
71             PowerStatus->BatteryFlag |= BATTERY_FLAG_HIGH;
72     }
73 
74     if (!BattState.BatteryPresent)
75         PowerStatus->BatteryFlag |= BATTERY_FLAG_NO_BATTERY;
76 
77     if (BattState.Charging)
78         PowerStatus->BatteryFlag |= BATTERY_FLAG_CHARGING;
79 
80     if (!(BattState.AcOnLine) && (BattState.BatteryPresent))
81         PowerStatus->ACLineStatus = AC_LINE_OFFLINE;
82 
83     if (BattState.EstimatedTime)
84         PowerStatus->BatteryLifeTime = BattState.EstimatedTime;
85 
86     return TRUE;
87 }
88 
89 /*
90  * @implemented
91  */
92 BOOL
93 WINAPI
SetSystemPowerState(IN BOOL fSuspend,IN BOOL fForce)94 SetSystemPowerState(IN BOOL fSuspend,
95                     IN BOOL fForce)
96 {
97     NTSTATUS Status;
98 
99     Status = NtInitiatePowerAction((fSuspend != FALSE) ? PowerActionSleep     : PowerActionHibernate,
100                                    (fSuspend != FALSE) ? PowerSystemSleeping1 : PowerSystemHibernate,
101                                    (fForce == FALSE),
102                                    FALSE);
103     if (!NT_SUCCESS(Status))
104     {
105         BaseSetLastNTError(Status);
106         return FALSE;
107     }
108 
109     return TRUE;
110 }
111 
112 /*
113  * @implemented
114  */
115 BOOL
116 WINAPI
GetDevicePowerState(IN HANDLE hDevice,OUT BOOL * pfOn)117 GetDevicePowerState(IN HANDLE hDevice,
118                     OUT BOOL *pfOn)
119 {
120     DEVICE_POWER_STATE DevicePowerState;
121     NTSTATUS Status;
122 
123     Status = NtGetDevicePowerState(hDevice, &DevicePowerState);
124     if (NT_SUCCESS(Status))
125     {
126         *pfOn = (DevicePowerState == PowerDeviceUnspecified) ||
127                 (DevicePowerState == PowerDeviceD0);
128         return TRUE;
129     }
130 
131     BaseSetLastNTError(Status);
132     return FALSE;
133 }
134 
135 /*
136  * @implemented
137  */
138 BOOL
139 WINAPI
RequestDeviceWakeup(IN HANDLE hDevice)140 RequestDeviceWakeup(IN HANDLE hDevice)
141 {
142     NTSTATUS Status;
143 
144     Status = NtRequestDeviceWakeup(hDevice);
145     if (!NT_SUCCESS(Status))
146     {
147         BaseSetLastNTError(Status);
148         return FALSE;
149     }
150 
151     return TRUE;
152 }
153 
154 /*
155  * @implemented
156  */
157 BOOL
158 WINAPI
RequestWakeupLatency(IN LATENCY_TIME latency)159 RequestWakeupLatency(IN LATENCY_TIME latency)
160 {
161     NTSTATUS Status;
162 
163     Status = NtRequestWakeupLatency(latency);
164     if (!NT_SUCCESS(Status))
165     {
166         BaseSetLastNTError(Status);
167         return FALSE;
168     }
169 
170     return TRUE;
171 }
172 
173 /*
174  * @implemented
175  */
176 BOOL
177 WINAPI
CancelDeviceWakeupRequest(IN HANDLE hDevice)178 CancelDeviceWakeupRequest(IN HANDLE hDevice)
179 {
180     NTSTATUS Status;
181 
182     Status = NtCancelDeviceWakeupRequest(hDevice);
183     if (!NT_SUCCESS(Status))
184     {
185         BaseSetLastNTError(Status);
186         return FALSE;
187     }
188 
189     return TRUE;
190 }
191 
192 /*
193  * @implemented
194  */
195 BOOL
196 WINAPI
IsSystemResumeAutomatic(VOID)197 IsSystemResumeAutomatic(VOID)
198 {
199     return (BOOL)NtIsSystemResumeAutomatic();
200 }
201 
202 /*
203  * @implemented
204  */
205 BOOL
206 WINAPI
SetMessageWaitingIndicator(IN HANDLE hMsgIndicator,IN ULONG ulMsgCount)207 SetMessageWaitingIndicator(IN HANDLE hMsgIndicator,
208                            IN ULONG ulMsgCount)
209 {
210     /* This is the correct Windows implementation */
211     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
212     return 0;
213 }
214 
215 /*
216  * @implemented
217  */
218 EXECUTION_STATE
219 WINAPI
SetThreadExecutionState(EXECUTION_STATE esFlags)220 SetThreadExecutionState(EXECUTION_STATE esFlags)
221 {
222     NTSTATUS Status;
223 
224     Status = NtSetThreadExecutionState(esFlags, &esFlags);
225     if (!NT_SUCCESS(Status))
226     {
227         BaseSetLastNTError(Status);
228         return 0;
229     }
230 
231     return esFlags;
232 }
233