2 * Copyright (C) 2005 Benjamin Cutler
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include "wine/debug.h"
30 #include "wine/unicode.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(powrprof
);
34 /* Notes to implementors:
35 * #1: The native implementation of these functions attempted to read in
36 * registry entries that I was unable to locate on any of the Windows
37 * machines I checked, but I only had desktops available, so maybe
38 * laptop users will have better luck. They return FNF errors because
39 * that's what the native DLL was returning during my tests.
40 * #2: These functions call NtPowerInformation but I don't know what they
41 * do with the results, and NtPowerInformation doesn't do much in WINE yet
43 * #3: Since I can't get several other functions working (see note #1),
44 * implementing these functions is going to have to wait until somebody can
45 * cobble together some sane test input. */
47 static const WCHAR szPowerCfgSubKey
[] = { 'S', 'o', 'f', 't', 'w', 'a', 'r', 'e',
48 '\\', 'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', '\\', 'W', 'i',
49 'n', 'd', 'o', 'w', 's', '\\', 'C', 'u', 'r', 'r', 'e', 'n', 't',
50 'V', 'e', 'r', 's', 'i', 'o', 'n', '\\', 'C', 'o', 'n', 't', 'r',
51 'o', 'l', 's', ' ', 'F', 'o', 'l', 'd', 'e', 'r', '\\', 'P', 'o',
52 'w', 'e', 'r', 'C', 'f', 'g', 0 };
53 static const WCHAR szSemaphoreName
[] = { 'P', 'o', 'w', 'e', 'r', 'P', 'r', 'o',
54 'f', 'i', 'l', 'e', 'R', 'e', 'g', 'i', 's', 't', 'r', 'y', 'S',
55 'e', 'm', 'a', 'p', 'h', 'o', 'r', 'e', 0 };
56 static const WCHAR szDiskMax
[] = { 'D', 'i', 's', 'k', 'S', 'p', 'i', 'n', 'd',
57 'o', 'w', 'n', 'M', 'a', 'x', 0 };
58 static const WCHAR szDiskMin
[] = { 'D', 'i', 's', 'k', 'S', 'p', 'i', 'n', 'd',
59 'o', 'w', 'n', 'M', 'i', 'n', 0 };
60 static const WCHAR szLastID
[] = { 'L', 'a', 's', 't', 'I', 'D', 0 };
61 static HANDLE PPRegSemaphore
= NULL
;
63 NTSTATUS WINAPI
CallNtPowerInformation(
64 POWER_INFORMATION_LEVEL InformationLevel
,
65 PVOID lpInputBuffer
, ULONG nInputBufferSize
,
66 PVOID lpOutputBuffer
, ULONG nOutputBufferSize
)
68 return NtPowerInformation(InformationLevel
, lpInputBuffer
,
69 nInputBufferSize
, lpOutputBuffer
, nOutputBufferSize
);
72 BOOLEAN WINAPI
CanUserWritePwrScheme(VOID
)
76 BOOLEAN bSuccess
= TRUE
;
80 r
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
| KEY_WRITE
, &hKey
);
82 if (r
!= ERROR_SUCCESS
) {
83 TRACE("RegOpenKeyEx failed: %ld\n", r
);
92 BOOLEAN WINAPI
DeletePwrScheme(UINT uiIndex
)
94 /* FIXME: See note #1 */
95 FIXME("(%d) stub!\n", uiIndex
);
96 SetLastError(ERROR_FILE_NOT_FOUND
);
100 BOOLEAN WINAPI
EnumPwrSchemes(PWRSCHEMESENUMPROC lpfnPwrSchemesEnumProc
,
103 /* FIXME: See note #1 */
104 FIXME("(%p, %ld) stub!\n", lpfnPwrSchemesEnumProc
, lParam
);
105 SetLastError(ERROR_FILE_NOT_FOUND
);
109 BOOLEAN WINAPI
GetActivePwrScheme(PUINT puiID
)
111 /* FIXME: See note #1 */
112 FIXME("(%p) stub!\n", puiID
);
113 SetLastError(ERROR_FILE_NOT_FOUND
);
117 BOOLEAN WINAPI
GetCurrentPowerPolicies(
118 PGLOBAL_POWER_POLICY pGlobalPowerPolicy
,
119 PPOWER_POLICY pPowerPolicy
)
121 /* FIXME: See note #2 */
122 SYSTEM_POWER_POLICY ACPower
, DCPower
;
124 FIXME("(%p, %p) stub!\n", pGlobalPowerPolicy
, pPowerPolicy
);
126 NtPowerInformation(SystemPowerPolicyAc
, 0, 0, &ACPower
, sizeof(SYSTEM_POWER_POLICY
));
127 NtPowerInformation(SystemPowerPolicyDc
, 0, 0, &DCPower
, sizeof(SYSTEM_POWER_POLICY
));
132 BOOLEAN WINAPI
GetPwrCapabilities(
133 PSYSTEM_POWER_CAPABILITIES lpSystemPowerCapabilities
)
137 TRACE("(%p)\n", lpSystemPowerCapabilities
);
139 r
= NtPowerInformation(SystemPowerCapabilities
, 0, 0, lpSystemPowerCapabilities
, sizeof(SYSTEM_POWER_CAPABILITIES
));
141 SetLastError(RtlNtStatusToDosError(r
));
143 return r
== STATUS_SUCCESS
;
146 BOOLEAN WINAPI
GetPwrDiskSpindownRange(PUINT RangeMax
, PUINT RangeMin
)
150 LONG cbValue
= 40, r
;
152 TRACE("(%p, %p)\n", RangeMax
, RangeMin
);
154 if (RangeMax
== NULL
|| RangeMin
== NULL
) {
155 SetLastError(ERROR_INVALID_PARAMETER
);
159 SetLastError(ERROR_SUCCESS
);
161 WaitForSingleObject(PPRegSemaphore
, INFINITE
);
163 r
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
, &hKey
);
164 if (r
!= ERROR_SUCCESS
) {
165 TRACE("RegOpenKeyEx failed: %ld\n", r
);
166 TRACE("Using defaults: 3600, 3\n");
169 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
173 r
= RegQueryValueExW(hKey
, szDiskMax
, 0, 0, lpValue
, &cbValue
);
174 if (r
!= ERROR_SUCCESS
) {
175 TRACE("Couldn't open DiskSpinDownMax: %ld\n", r
);
176 TRACE("Using default: 3600\n");
179 *RangeMax
= atoiW((LPCWSTR
)lpValue
);
184 r
= RegQueryValueExW(hKey
, szDiskMin
, 0, 0, lpValue
, &cbValue
);
185 if (r
!= ERROR_SUCCESS
) {
186 TRACE("Couldn't open DiskSpinDownMin: %ld\n", r
);
187 TRACE("Using default: 3\n");
190 *RangeMin
= atoiW((LPCWSTR
)lpValue
);
195 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
200 BOOLEAN WINAPI
IsPwrHibernateAllowed(VOID
)
202 /* FIXME: See note #2 */
203 SYSTEM_POWER_CAPABILITIES PowerCaps
;
205 NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
209 BOOLEAN WINAPI
IsPwrShutdownAllowed(VOID
)
211 /* FIXME: See note #2 */
212 SYSTEM_POWER_CAPABILITIES PowerCaps
;
214 NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
218 BOOLEAN WINAPI
IsPwrSuspendAllowed(VOID
)
220 /* FIXME: See note #2 */
221 SYSTEM_POWER_CAPABILITIES PowerCaps
;
223 NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
227 BOOLEAN WINAPI
ReadGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
)
229 /* FIXME: See note #1 */
230 FIXME("(%p) stub!\n", pGlobalPowerPolicy
);
231 SetLastError(ERROR_FILE_NOT_FOUND
);
235 BOOLEAN WINAPI
ReadProcessorPwrScheme(UINT uiID
,
236 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy
)
238 /* FIXME: See note #1 */
239 FIXME("(%d, %p) stub!\n", uiID
, pMachineProcessorPowerPolicy
);
240 SetLastError(ERROR_FILE_NOT_FOUND
);
244 BOOLEAN WINAPI
ReadPwrScheme(UINT uiID
,
245 PPOWER_POLICY pPowerPolicy
)
247 /* FIXME: See note #1 */
248 FIXME("(%d, %p) stub!\n", uiID
, pPowerPolicy
);
249 SetLastError(ERROR_FILE_NOT_FOUND
);
253 BOOLEAN WINAPI
SetActivePwrScheme(UINT uiID
,
254 PGLOBAL_POWER_POLICY lpGlobalPowerPolicy
,
255 PPOWER_POLICY lpPowerPolicy
)
257 /* FIXME: See note #1 */
258 FIXME("(%d, %p, %p) stub!\n", uiID
, lpGlobalPowerPolicy
, lpPowerPolicy
);
259 SetLastError(ERROR_FILE_NOT_FOUND
);
263 BOOLEAN WINAPI
SetSuspendState(BOOLEAN Hibernate
, BOOLEAN ForceCritical
,
264 BOOLEAN DisableWakeEvent
)
266 /* FIXME: I have NO idea how you're supposed to call NtInitiatePowerAction
267 * here, because it's not a documented function that I can find */
268 FIXME("(%d, %d, %d) stub!\n", Hibernate
, ForceCritical
, DisableWakeEvent
);
272 BOOLEAN WINAPI
WriteGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
)
274 /* FIXME: See note #3 */
275 FIXME("(%p) stub!\n", pGlobalPowerPolicy
);
276 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
280 BOOLEAN WINAPI
WriteProcessorPwrScheme(UINT ID
,
281 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy
)
283 /* FIXME: See note #3 */
284 FIXME("(%d, %p) stub!\n", ID
, pMachineProcessorPowerPolicy
);
285 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
289 BOOLEAN WINAPI
WritePwrScheme(PUINT puiID
, LPWSTR lpszName
, LPWSTR lpszDescription
,
290 PPOWER_POLICY pPowerPolicy
)
292 /* FIXME: See note #3 */
293 FIXME("(%p, %s, %s, %p) stub!\n", puiID
, debugstr_w(lpszName
), debugstr_w(lpszDescription
), pPowerPolicy
);
294 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
298 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
300 FIXME("(%p, %ld, %p) not fully implemented\n", hinstDLL
, fdwReason
, lpvReserved
);
303 case DLL_PROCESS_ATTACH
: {
308 DisableThreadLibraryCalls(hinstDLL
);
310 r
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
| KEY_WRITE
, &hKey
);
312 if (r
!= ERROR_SUCCESS
) {
313 TRACE("Couldn't open registry key HKLM\\%s, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey
));
317 r
= RegQueryValueExW(hKey
, szLastID
, 0, 0, lpValue
, &cbValue
);
318 if (r
!= ERROR_SUCCESS
) {
319 TRACE("Couldn't open registry entry HKLM\\%s\\LastID, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey
));
324 PPRegSemaphore
= CreateSemaphoreW(NULL
, 1, 1, szSemaphoreName
);
325 if (PPRegSemaphore
== NULL
) {
326 ERR("Couldn't create Semaphore: %ld\n", GetLastError());
331 case DLL_PROCESS_DETACH
:
332 CloseHandle(PPRegSemaphore
);