- Implement RequestDeviceWakeup
[reactos.git] / reactos / dll / win32 / kernel32 / misc / power.c
1 /*
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: dll/win32/kernel32/misc/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 #define NDEBUG
16 #include <debug.h>
17
18
19 NTSYSAPI
20 NTSTATUS
21 NTAPI
22 NtGetDevicePowerState(
23 IN HANDLE Device,
24 IN PDEVICE_POWER_STATE PowerState
25 );
26
27 NTSYSAPI
28 NTSTATUS
29 NTAPI
30 NtRequestWakeupLatency(
31 IN LATENCY_TIME latency
32 );
33
34 NTSYSAPI
35 BOOLEAN
36 NTAPI
37 NtIsSystemResumeAutomatic(VOID);
38
39 NTSYSAPI
40 NTSTATUS
41 NTAPI
42 NtSetThreadExecutionState(
43 IN EXECUTION_STATE esFlags,
44 OUT EXECUTION_STATE *PreviousFlags
45 );
46
47 NTSYSAPI
48 NTSTATUS
49 NTAPI
50 NtInitiatePowerAction(
51 IN POWER_ACTION SystemAction,
52 IN SYSTEM_POWER_STATE MinSystemState,
53 IN ULONG Flags,
54 IN BOOLEAN Asynchronous
55 );
56
57 NTSYSAPI
58 NTSTATUS
59 NTAPI
60 NtRequestDeviceWakeup(
61 IN HANDLE Device
62 );
63
64 NTSYSAPI
65 NTSTATUS
66 NTAPI
67 NtCancelDeviceWakeupRequest(
68 IN HANDLE Device
69 );
70
71 /* PUBLIC FUNCTIONS ***********************************************************/
72
73 /*
74 * @implemented
75 */
76 BOOL
77 WINAPI
78 GetSystemPowerStatus(LPSYSTEM_POWER_STATUS PowerStatus)
79 {
80 NTSTATUS Status;
81 SYSTEM_BATTERY_STATE SysBatState;
82
83 Status = NtPowerInformation(SystemBatteryState,
84 NULL,
85 0,
86 &SysBatState,
87 sizeof(SYSTEM_BATTERY_STATE));
88
89 if (!NT_SUCCESS(Status))
90 {
91 SetLastErrorByStatus(Status);
92 return FALSE;
93 }
94
95 RtlZeroMemory(PowerStatus, sizeof(LPSYSTEM_POWER_STATUS));
96
97 PowerStatus->BatteryLifeTime = BATTERY_LIFE_UNKNOWN;
98 PowerStatus->BatteryFullLifeTime = BATTERY_LIFE_UNKNOWN;
99
100 PowerStatus->BatteryLifePercent = BATTERY_PERCENTAGE_UNKNOWN;
101 if (SysBatState.MaxCapacity)
102 {
103 if (SysBatState.MaxCapacity >= SysBatState.RemainingCapacity)
104 PowerStatus->BatteryLifePercent = (SysBatState.RemainingCapacity / SysBatState.MaxCapacity) * 100;
105 else
106 PowerStatus->BatteryLifePercent = 100; /* 100% */
107
108 if (PowerStatus->BatteryLifePercent <= 32)
109 PowerStatus->BatteryFlag |= BATTERY_FLAG_LOW;
110
111 if (PowerStatus->BatteryLifePercent >= 67)
112 PowerStatus->BatteryFlag |= BATTERY_FLAG_HIGH;
113 }
114
115 if (!SysBatState.BatteryPresent)
116 PowerStatus->BatteryFlag |= BATTERY_FLAG_NO_BATTERY;
117
118 if (SysBatState.Charging)
119 PowerStatus->BatteryFlag |= BATTERY_FLAG_CHARGING;
120
121 if (!SysBatState.AcOnLine && SysBatState.BatteryPresent)
122 PowerStatus->ACLineStatus = AC_LINE_OFFLINE;
123 else
124 PowerStatus->ACLineStatus = AC_LINE_ONLINE;
125
126 if (SysBatState.EstimatedTime)
127 PowerStatus->BatteryLifeTime = SysBatState.EstimatedTime;
128
129 return TRUE;
130 }
131
132 /*
133 * @implemented
134 */
135 BOOL WINAPI
136 SetSystemPowerState(BOOL fSuspend, BOOL fForce)
137 {
138 SYSTEM_POWER_STATE MinSystemState = (!fSuspend ? PowerSystemHibernate : PowerSystemSleeping1);
139 ULONG Flags = (!fForce ? POWER_ACTION_QUERY_ALLOWED : 0);
140 NTSTATUS Status;
141
142 Status = NtInitiatePowerAction(PowerActionSleep,
143 MinSystemState,
144 Flags,
145 FALSE);
146
147 if (!NT_SUCCESS(Status))
148 {
149 SetLastErrorByStatus(Status);
150 return FALSE;
151 }
152
153 return TRUE;
154 }
155
156 /*
157 * @implemented
158 */
159 BOOL
160 WINAPI
161 GetDevicePowerState(HANDLE hDevice, BOOL *pfOn)
162 {
163 DEVICE_POWER_STATE DevicePowerState;
164 NTSTATUS Status;
165
166 Status = NtGetDevicePowerState(hDevice, &DevicePowerState);
167
168 if (NT_SUCCESS(Status))
169 {
170 if ((DevicePowerState != PowerDeviceUnspecified) &&
171 (DevicePowerState != PowerDeviceD0))
172 *pfOn = FALSE;
173 else
174 *pfOn = TRUE;
175
176 return TRUE;
177 }
178
179 SetLastErrorByStatus(Status);
180 return FALSE;
181 }
182
183 /*
184 * @implemented
185 */
186 BOOL
187 WINAPI
188 RequestDeviceWakeup(HANDLE hDevice)
189 {
190 NTSTATUS Status;
191
192 Status = NtRequestDeviceWakeup(hDevice);
193
194 if (!NT_SUCCESS(Status))
195 {
196 SetLastErrorByStatus(Status);
197 return FALSE;
198 }
199
200 return TRUE;
201 }
202
203 /*
204 * @implemented
205 */
206 BOOL
207 WINAPI
208 RequestWakeupLatency(LATENCY_TIME latency)
209 {
210 NTSTATUS Status;
211
212 Status = NtRequestWakeupLatency(latency);
213
214 if (!NT_SUCCESS(Status))
215 {
216 SetLastErrorByStatus(Status);
217 return FALSE;
218 }
219
220 return TRUE;
221 }
222
223 /*
224 * @implemented
225 */
226 BOOL
227 WINAPI
228 CancelDeviceWakeupRequest(HANDLE hDevice)
229 {
230 NTSTATUS Status;
231
232 Status = NtCancelDeviceWakeupRequest(hDevice);
233
234 if (!NT_SUCCESS(Status))
235 {
236 SetLastErrorByStatus(Status);
237 return FALSE;
238 }
239
240 return TRUE;
241 }
242
243 /*
244 * @implemented
245 */
246 BOOL
247 WINAPI
248 IsSystemResumeAutomatic(VOID)
249 {
250 return NtIsSystemResumeAutomatic();
251 }
252
253 /*
254 * @unimplemented
255 */
256 BOOL
257 WINAPI
258 SetMessageWaitingIndicator(HANDLE hMsgIndicator,
259 ULONG ulMsgCount)
260 {
261 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
262 DPRINT1("SetMessageWaitingIndicator is UNIMPLEMENTED!\n");
263 return 0;
264 }
265
266 /*
267 * @implemented
268 */
269 EXECUTION_STATE
270 WINAPI
271 SetThreadExecutionState(EXECUTION_STATE esFlags)
272 {
273 EXECUTION_STATE OldFlags;
274 NTSTATUS Status;
275
276 Status = NtSetThreadExecutionState(esFlags, &OldFlags);
277
278 if (!NT_SUCCESS(Status))
279 {
280 SetLastErrorByStatus(Status);
281 return 0;
282 }
283
284 return OldFlags;
285 }