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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define WIN32_NO_STATUS
30 #include "wine/debug.h"
31 #include "wine/unicode.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(powrprof
);
35 /* Notes to implementors:
36 * #1: The native implementation of these functions attempted to read in
37 * registry entries that I was unable to locate on any of the Windows
38 * machines I checked, but I only had desktops available, so maybe
39 * laptop users will have better luck. They return FNF errors because
40 * that's what the native DLL was returning during my tests.
41 * #2: These functions call NtPowerInformation but I don't know what they
42 * do with the results, and NtPowerInformation doesn't do much in WINE yet
44 * #3: Since I can't get several other functions working (see note #1),
45 * implementing these functions is going to have to wait until somebody can
46 * cobble together some sane test input. */
48 static const WCHAR szPowerCfgSubKey
[] = { 'S', 'o', 'f', 't', 'w', 'a', 'r', 'e',
49 '\\', 'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', '\\', 'W', 'i',
50 'n', 'd', 'o', 'w', 's', '\\', 'C', 'u', 'r', 'r', 'e', 'n', 't',
51 'V', 'e', 'r', 's', 'i', 'o', 'n', '\\', 'C', 'o', 'n', 't', 'r',
52 'o', 'l', 's', ' ', 'F', 'o', 'l', 'd', 'e', 'r', '\\', 'P', 'o',
53 'w', 'e', 'r', 'C', 'f', 'g', 0 };
54 static const WCHAR szSemaphoreName
[] = { 'P', 'o', 'w', 'e', 'r', 'P', 'r', 'o',
55 'f', 'i', 'l', 'e', 'R', 'e', 'g', 'i', 's', 't', 'r', 'y', 'S',
56 'e', 'm', 'a', 'p', 'h', 'o', 'r', 'e', 0 };
57 static const WCHAR szDiskMax
[] = { 'D', 'i', 's', 'k', 'S', 'p', 'i', 'n', 'd',
58 'o', 'w', 'n', 'M', 'a', 'x', 0 };
59 static const WCHAR szDiskMin
[] = { 'D', 'i', 's', 'k', 'S', 'p', 'i', 'n', 'd',
60 'o', 'w', 'n', 'M', 'i', 'n', 0 };
61 static const WCHAR szLastID
[] = { 'L', 'a', 's', 't', 'I', 'D', 0 };
62 static HANDLE PPRegSemaphore
= NULL
;
64 NTSTATUS WINAPI
CallNtPowerInformation(
65 POWER_INFORMATION_LEVEL InformationLevel
,
66 PVOID lpInputBuffer
, ULONG nInputBufferSize
,
67 PVOID lpOutputBuffer
, ULONG nOutputBufferSize
)
69 return NtPowerInformation(InformationLevel
, lpInputBuffer
,
70 nInputBufferSize
, lpOutputBuffer
, nOutputBufferSize
);
73 BOOLEAN WINAPI
CanUserWritePwrScheme(VOID
)
77 BOOLEAN bSuccess
= TRUE
;
81 r
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
| KEY_WRITE
, &hKey
);
83 if (r
!= ERROR_SUCCESS
) {
84 TRACE("RegOpenKeyEx failed: %d\n", r
);
93 BOOLEAN WINAPI
DeletePwrScheme(UINT uiIndex
)
95 /* FIXME: See note #1 */
96 FIXME("(%d) stub!\n", uiIndex
);
97 SetLastError(ERROR_FILE_NOT_FOUND
);
101 BOOLEAN WINAPI
EnumPwrSchemes(PWRSCHEMESENUMPROC lpfnPwrSchemesEnumProc
,
104 /* FIXME: See note #1 */
105 FIXME("(%p, %ld) stub!\n", lpfnPwrSchemesEnumProc
, lParam
);
106 SetLastError(ERROR_FILE_NOT_FOUND
);
110 BOOLEAN WINAPI
GetActivePwrScheme(PUINT puiID
)
112 /* FIXME: See note #1 */
113 FIXME("(%p) stub!\n", puiID
);
114 SetLastError(ERROR_FILE_NOT_FOUND
);
118 BOOLEAN WINAPI
GetCurrentPowerPolicies(
119 PGLOBAL_POWER_POLICY pGlobalPowerPolicy
,
120 PPOWER_POLICY pPowerPolicy
)
122 /* FIXME: See note #2 */
123 SYSTEM_POWER_POLICY ACPower
, DCPower
;
125 FIXME("(%p, %p) stub!\n", pGlobalPowerPolicy
, pPowerPolicy
);
127 NtPowerInformation(SystemPowerPolicyAc
, 0, 0, &ACPower
, sizeof(SYSTEM_POWER_POLICY
));
128 NtPowerInformation(SystemPowerPolicyDc
, 0, 0, &DCPower
, sizeof(SYSTEM_POWER_POLICY
));
133 BOOLEAN WINAPI
GetPwrCapabilities(
134 PSYSTEM_POWER_CAPABILITIES lpSystemPowerCapabilities
)
138 TRACE("(%p)\n", lpSystemPowerCapabilities
);
140 r
= NtPowerInformation(SystemPowerCapabilities
, 0, 0, lpSystemPowerCapabilities
, sizeof(SYSTEM_POWER_CAPABILITIES
));
142 SetLastError(RtlNtStatusToDosError(r
));
144 return r
== STATUS_SUCCESS
;
147 BOOLEAN WINAPI
GetPwrDiskSpindownRange(PUINT RangeMax
, PUINT RangeMin
)
152 DWORD cbValue
= sizeof(lpValue
);
154 TRACE("(%p, %p)\n", RangeMax
, RangeMin
);
156 if (RangeMax
== NULL
|| RangeMin
== NULL
) {
157 SetLastError(ERROR_INVALID_PARAMETER
);
161 SetLastError(ERROR_SUCCESS
);
163 WaitForSingleObject(PPRegSemaphore
, INFINITE
);
165 r
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
, &hKey
);
166 if (r
!= ERROR_SUCCESS
) {
167 TRACE("RegOpenKeyEx failed: %d\n", r
);
168 TRACE("Using defaults: 3600, 3\n");
171 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
175 r
= RegQueryValueExW(hKey
, szDiskMax
, 0, 0, lpValue
, &cbValue
);
176 if (r
!= ERROR_SUCCESS
) {
177 TRACE("Couldn't open DiskSpinDownMax: %d\n", r
);
178 TRACE("Using default: 3600\n");
181 *RangeMax
= atoiW((LPCWSTR
)lpValue
);
184 cbValue
= sizeof(lpValue
);
186 r
= RegQueryValueExW(hKey
, szDiskMin
, 0, 0, lpValue
, &cbValue
);
187 if (r
!= ERROR_SUCCESS
) {
188 TRACE("Couldn't open DiskSpinDownMin: %d\n", r
);
189 TRACE("Using default: 3\n");
192 *RangeMin
= atoiW((LPCWSTR
)lpValue
);
197 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
202 BOOLEAN WINAPI
IsAdminOverrideActive(PADMINISTRATOR_POWER_POLICY p
)
204 FIXME("( %p) stub!\n", p
);
208 BOOLEAN WINAPI
IsPwrHibernateAllowed(VOID
)
210 SYSTEM_POWER_CAPABILITIES PowerCaps
;
211 NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
212 return PowerCaps
.SystemS4
&& PowerCaps
.HiberFilePresent
;
215 BOOLEAN WINAPI
IsPwrShutdownAllowed(VOID
)
217 SYSTEM_POWER_CAPABILITIES PowerCaps
;
218 NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
219 return PowerCaps
.SystemS5
;
222 BOOLEAN WINAPI
IsPwrSuspendAllowed(VOID
)
224 SYSTEM_POWER_CAPABILITIES PowerCaps
;
225 NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
226 return PowerCaps
.SystemS1
&& PowerCaps
.SystemS2
&& PowerCaps
.SystemS3
;
229 BOOLEAN WINAPI
ReadGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
)
231 /* FIXME: See note #1 */
232 FIXME("(%p) stub!\n", pGlobalPowerPolicy
);
233 SetLastError(ERROR_FILE_NOT_FOUND
);
237 BOOLEAN WINAPI
ReadProcessorPwrScheme(UINT uiID
,
238 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy
)
240 /* FIXME: See note #1 */
241 FIXME("(%d, %p) stub!\n", uiID
, pMachineProcessorPowerPolicy
);
242 SetLastError(ERROR_FILE_NOT_FOUND
);
246 BOOLEAN WINAPI
ReadPwrScheme(UINT uiID
,
247 PPOWER_POLICY pPowerPolicy
)
249 /* FIXME: See note #1 */
250 FIXME("(%d, %p) stub!\n", uiID
, pPowerPolicy
);
251 SetLastError(ERROR_FILE_NOT_FOUND
);
255 BOOLEAN WINAPI
SetActivePwrScheme(UINT uiID
,
256 PGLOBAL_POWER_POLICY lpGlobalPowerPolicy
,
257 PPOWER_POLICY lpPowerPolicy
)
259 /* FIXME: See note #1 */
260 FIXME("(%d, %p, %p) stub!\n", uiID
, lpGlobalPowerPolicy
, lpPowerPolicy
);
261 SetLastError(ERROR_FILE_NOT_FOUND
);
265 BOOLEAN WINAPI
SetSuspendState(BOOLEAN Hibernate
, BOOLEAN ForceCritical
,
266 BOOLEAN DisableWakeEvent
)
268 /* FIXME: I have NO idea how you're supposed to call NtInitiatePowerAction
269 * here, because it's not a documented function that I can find */
270 FIXME("(%d, %d, %d) stub!\n", Hibernate
, ForceCritical
, DisableWakeEvent
);
274 BOOLEAN WINAPI
WriteGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
)
276 /* FIXME: See note #3 */
277 FIXME("(%p) stub!\n", pGlobalPowerPolicy
);
278 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
282 BOOLEAN WINAPI
WriteProcessorPwrScheme(UINT ID
,
283 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy
)
285 /* FIXME: See note #3 */
286 FIXME("(%d, %p) stub!\n", ID
, pMachineProcessorPowerPolicy
);
287 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
291 BOOLEAN WINAPI
WritePwrScheme(PUINT puiID
, LPWSTR lpszName
, LPWSTR lpszDescription
,
292 PPOWER_POLICY pPowerPolicy
)
294 /* FIXME: See note #3 */
295 FIXME("(%p, %s, %s, %p) stub!\n", puiID
, debugstr_w(lpszName
), debugstr_w(lpszDescription
), pPowerPolicy
);
296 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
300 DWORD WINAPI
PowerGetActiveScheme(HKEY UserRootPowerKey
, GUID
**polguid
)
302 FIXME("(%p,%p) stub!\n", UserRootPowerKey
, polguid
);
303 return ERROR_CALL_NOT_IMPLEMENTED
;
306 DWORD WINAPI
PowerSetActiveScheme(HKEY UserRootPowerKey
, GUID
*polguid
)
308 FIXME("(%p,%s) stub!\n", UserRootPowerKey
, wine_dbgstr_guid(polguid
));
309 return ERROR_SUCCESS
;
312 DWORD WINAPI
PowerReadDCValue(HKEY RootPowerKey
, const GUID
*Scheme
, const GUID
*SubGroup
, const GUID
*PowerSettings
, PULONG Type
, PUCHAR Buffer
, DWORD
*BufferSize
)
314 FIXME("(%p,%s,%s,%s,%p,%p,%p) stub!\n", RootPowerKey
, debugstr_guid(Scheme
), debugstr_guid(SubGroup
), debugstr_guid(PowerSettings
), Type
, Buffer
, BufferSize
);
315 return ERROR_CALL_NOT_IMPLEMENTED
;
318 POWER_PLATFORM_ROLE WINAPI
PowerDeterminePlatformRole(void)
321 return PlatformRoleDesktop
;
324 POWER_PLATFORM_ROLE WINAPI
PowerDeterminePlatformRoleEx(ULONG version
)
326 FIXME("%u stub.\n", version
);
327 return PlatformRoleDesktop
;
330 DWORD WINAPI
PowerEnumerate(HKEY key
, const GUID
*scheme
, const GUID
*subgroup
, POWER_DATA_ACCESSOR flags
,
331 ULONG index
, UCHAR
*buffer
, DWORD
*buffer_size
)
333 FIXME("(%p,%s,%s,%d,%d,%p,%p) stub!\n", key
, debugstr_guid(scheme
), debugstr_guid(subgroup
),
334 flags
, index
, buffer
, buffer_size
);
335 return ERROR_CALL_NOT_IMPLEMENTED
;
338 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
341 case DLL_PROCESS_ATTACH
: {
346 DisableThreadLibraryCalls(hinstDLL
);
348 r
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
| KEY_WRITE
, &hKey
);
350 if (r
!= ERROR_SUCCESS
) {
351 TRACE("Couldn't open registry key HKLM\\%s, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey
));
354 DWORD cbValue
= sizeof(lpValue
);
355 r
= RegQueryValueExW(hKey
, szLastID
, 0, 0, lpValue
, &cbValue
);
356 if (r
!= ERROR_SUCCESS
) {
357 TRACE("Couldn't open registry entry HKLM\\%s\\LastID, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey
));
362 PPRegSemaphore
= CreateSemaphoreW(NULL
, 1, 1, szSemaphoreName
);
363 if (PPRegSemaphore
== NULL
) {
364 ERR("Couldn't create Semaphore: %d\n", GetLastError());
369 case DLL_PROCESS_DETACH
:
370 if (lpvReserved
) break;
371 CloseHandle(PPRegSemaphore
);