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
24 #define WIN32_NO_STATUS
31 #include "wine/debug.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
[] = L
"Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\PowerCfg";
49 static HANDLE PPRegSemaphore
= NULL
;
51 NTSTATUS WINAPI
CallNtPowerInformation(
52 POWER_INFORMATION_LEVEL InformationLevel
,
53 PVOID lpInputBuffer
, ULONG nInputBufferSize
,
54 PVOID lpOutputBuffer
, ULONG nOutputBufferSize
)
56 return NtPowerInformation(InformationLevel
, lpInputBuffer
,
57 nInputBufferSize
, lpOutputBuffer
, nOutputBufferSize
);
60 BOOLEAN WINAPI
CanUserWritePwrScheme(VOID
)
64 BOOLEAN bSuccess
= TRUE
;
68 r
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
| KEY_WRITE
, &hKey
);
70 if (r
!= ERROR_SUCCESS
) {
71 TRACE("RegOpenKeyEx failed: %d\n", r
);
80 BOOLEAN WINAPI
DeletePwrScheme(UINT uiIndex
)
82 /* FIXME: See note #1 */
83 FIXME("(%d) stub!\n", uiIndex
);
84 SetLastError(ERROR_FILE_NOT_FOUND
);
88 BOOLEAN WINAPI
EnumPwrSchemes(PWRSCHEMESENUMPROC lpfnPwrSchemesEnumProc
,
91 /* FIXME: See note #1 */
92 FIXME("(%p, %ld) stub!\n", lpfnPwrSchemesEnumProc
, lParam
);
93 SetLastError(ERROR_FILE_NOT_FOUND
);
97 BOOLEAN WINAPI
GetActivePwrScheme(PUINT puiID
)
99 /* FIXME: See note #1 */
100 FIXME("(%p) stub!\n", puiID
);
101 SetLastError(ERROR_FILE_NOT_FOUND
);
105 BOOLEAN WINAPI
GetCurrentPowerPolicies(
106 PGLOBAL_POWER_POLICY pGlobalPowerPolicy
,
107 PPOWER_POLICY pPowerPolicy
)
109 /* FIXME: See note #2 */
110 SYSTEM_POWER_POLICY ACPower
, DCPower
;
112 FIXME("(%p, %p) stub!\n", pGlobalPowerPolicy
, pPowerPolicy
);
114 NtPowerInformation(SystemPowerPolicyAc
, 0, 0, &ACPower
, sizeof(SYSTEM_POWER_POLICY
));
115 NtPowerInformation(SystemPowerPolicyDc
, 0, 0, &DCPower
, sizeof(SYSTEM_POWER_POLICY
));
120 BOOLEAN WINAPI
GetPwrCapabilities(
121 PSYSTEM_POWER_CAPABILITIES lpSystemPowerCapabilities
)
125 TRACE("(%p)\n", lpSystemPowerCapabilities
);
127 r
= NtPowerInformation(SystemPowerCapabilities
, 0, 0, lpSystemPowerCapabilities
, sizeof(SYSTEM_POWER_CAPABILITIES
));
129 SetLastError(RtlNtStatusToDosError(r
));
131 return r
== STATUS_SUCCESS
;
134 BOOLEAN WINAPI
GetPwrDiskSpindownRange(PUINT RangeMax
, PUINT RangeMin
)
139 DWORD cbValue
= sizeof(lpValue
);
141 TRACE("(%p, %p)\n", RangeMax
, RangeMin
);
143 if (RangeMax
== NULL
|| RangeMin
== NULL
) {
144 SetLastError(ERROR_INVALID_PARAMETER
);
148 SetLastError(ERROR_SUCCESS
);
150 WaitForSingleObject(PPRegSemaphore
, INFINITE
);
152 r
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
, &hKey
);
153 if (r
!= ERROR_SUCCESS
) {
154 TRACE("RegOpenKeyEx failed: %d\n", r
);
155 TRACE("Using defaults: 3600, 3\n");
158 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
162 r
= RegQueryValueExW(hKey
, L
"DiskSpindownMax", 0, 0, lpValue
, &cbValue
);
163 if (r
!= ERROR_SUCCESS
) {
164 TRACE("Couldn't open DiskSpinDownMax: %d\n", r
);
165 TRACE("Using default: 3600\n");
168 *RangeMax
= wcstol((LPCWSTR
)lpValue
, NULL
, 10);
171 cbValue
= sizeof(lpValue
);
173 r
= RegQueryValueExW(hKey
, L
"DiskSpindownMin", 0, 0, lpValue
, &cbValue
);
174 if (r
!= ERROR_SUCCESS
) {
175 TRACE("Couldn't open DiskSpinDownMin: %d\n", r
);
176 TRACE("Using default: 3\n");
179 *RangeMin
= wcstol((LPCWSTR
)lpValue
, NULL
, 10);
184 ReleaseSemaphore(PPRegSemaphore
, 1, NULL
);
189 BOOLEAN WINAPI
IsAdminOverrideActive(PADMINISTRATOR_POWER_POLICY p
)
191 FIXME("( %p) stub!\n", p
);
195 BOOLEAN WINAPI
IsPwrHibernateAllowed(VOID
)
197 SYSTEM_POWER_CAPABILITIES PowerCaps
;
198 NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
199 return PowerCaps
.SystemS4
&& PowerCaps
.HiberFilePresent
;
202 BOOLEAN WINAPI
IsPwrShutdownAllowed(VOID
)
204 SYSTEM_POWER_CAPABILITIES PowerCaps
;
205 NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
206 return PowerCaps
.SystemS5
;
209 BOOLEAN WINAPI
IsPwrSuspendAllowed(VOID
)
211 SYSTEM_POWER_CAPABILITIES PowerCaps
;
212 NtPowerInformation(SystemPowerCapabilities
, NULL
, 0, &PowerCaps
, sizeof(PowerCaps
));
213 return PowerCaps
.SystemS1
&& PowerCaps
.SystemS2
&& PowerCaps
.SystemS3
;
216 BOOLEAN WINAPI
ReadGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
)
218 /* FIXME: See note #1 */
219 FIXME("(%p) stub!\n", pGlobalPowerPolicy
);
220 SetLastError(ERROR_FILE_NOT_FOUND
);
224 BOOLEAN WINAPI
ReadProcessorPwrScheme(UINT uiID
,
225 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy
)
227 /* FIXME: See note #1 */
228 FIXME("(%d, %p) stub!\n", uiID
, pMachineProcessorPowerPolicy
);
229 SetLastError(ERROR_FILE_NOT_FOUND
);
233 BOOLEAN WINAPI
ReadPwrScheme(UINT uiID
,
234 PPOWER_POLICY pPowerPolicy
)
236 /* FIXME: See note #1 */
237 FIXME("(%d, %p) stub!\n", uiID
, pPowerPolicy
);
238 SetLastError(ERROR_FILE_NOT_FOUND
);
242 BOOLEAN WINAPI
SetActivePwrScheme(UINT uiID
,
243 PGLOBAL_POWER_POLICY lpGlobalPowerPolicy
,
244 PPOWER_POLICY lpPowerPolicy
)
246 /* FIXME: See note #1 */
247 FIXME("(%d, %p, %p) stub!\n", uiID
, lpGlobalPowerPolicy
, lpPowerPolicy
);
248 SetLastError(ERROR_FILE_NOT_FOUND
);
252 BOOLEAN WINAPI
SetSuspendState(BOOLEAN Hibernate
, BOOLEAN ForceCritical
,
253 BOOLEAN DisableWakeEvent
)
255 /* FIXME: I have NO idea how you're supposed to call NtInitiatePowerAction
256 * here, because it's not a documented function that I can find */
257 FIXME("(%d, %d, %d) stub!\n", Hibernate
, ForceCritical
, DisableWakeEvent
);
261 BOOLEAN WINAPI
WriteGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy
)
263 /* FIXME: See note #3 */
264 FIXME("(%p) stub!\n", pGlobalPowerPolicy
);
265 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
269 BOOLEAN WINAPI
WriteProcessorPwrScheme(UINT ID
,
270 PMACHINE_PROCESSOR_POWER_POLICY pMachineProcessorPowerPolicy
)
272 /* FIXME: See note #3 */
273 FIXME("(%d, %p) stub!\n", ID
, pMachineProcessorPowerPolicy
);
274 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
278 BOOLEAN WINAPI
WritePwrScheme(PUINT puiID
, LPWSTR lpszName
, LPWSTR lpszDescription
,
279 PPOWER_POLICY pPowerPolicy
)
281 /* FIXME: See note #3 */
282 FIXME("(%p, %s, %s, %p) stub!\n", puiID
, debugstr_w(lpszName
), debugstr_w(lpszDescription
), pPowerPolicy
);
283 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
287 DWORD WINAPI
PowerGetActiveScheme(HKEY UserRootPowerKey
, GUID
**polguid
)
289 FIXME("(%p,%p) stub!\n", UserRootPowerKey
, polguid
);
290 return ERROR_CALL_NOT_IMPLEMENTED
;
293 DWORD WINAPI
PowerSetActiveScheme(HKEY UserRootPowerKey
, GUID
*polguid
)
295 FIXME("(%p,%s) stub!\n", UserRootPowerKey
, wine_dbgstr_guid(polguid
));
296 return ERROR_SUCCESS
;
299 DWORD WINAPI
PowerReadDCValue(HKEY RootPowerKey
, const GUID
*Scheme
, const GUID
*SubGroup
, const GUID
*PowerSettings
, PULONG Type
, PUCHAR Buffer
, DWORD
*BufferSize
)
301 FIXME("(%p,%s,%s,%s,%p,%p,%p) stub!\n", RootPowerKey
, debugstr_guid(Scheme
), debugstr_guid(SubGroup
), debugstr_guid(PowerSettings
), Type
, Buffer
, BufferSize
);
302 return ERROR_CALL_NOT_IMPLEMENTED
;
305 DWORD WINAPI
PowerReadFriendlyName(HKEY RootPowerKey
, const GUID
*Scheme
,
306 const GUID
*SubGroup
, const GUID
*PowerSettings
, UCHAR
*Buffer
,
309 FIXME("(%p,%s,%s,%s,%p,%p) stub!\n", RootPowerKey
, debugstr_guid(Scheme
), debugstr_guid(SubGroup
), debugstr_guid(PowerSettings
), Buffer
, BufferSize
);
310 return ERROR_CALL_NOT_IMPLEMENTED
;
313 POWER_PLATFORM_ROLE WINAPI
PowerDeterminePlatformRole(void)
316 return PlatformRoleDesktop
;
319 POWER_PLATFORM_ROLE WINAPI
PowerDeterminePlatformRoleEx(ULONG version
)
321 FIXME("%u stub.\n", version
);
322 return PlatformRoleDesktop
;
325 DWORD WINAPI
PowerEnumerate(HKEY key
, const GUID
*scheme
, const GUID
*subgroup
, POWER_DATA_ACCESSOR flags
,
326 ULONG index
, UCHAR
*buffer
, DWORD
*buffer_size
)
328 FIXME("(%p,%s,%s,%d,%d,%p,%p) stub!\n", key
, debugstr_guid(scheme
), debugstr_guid(subgroup
),
329 flags
, index
, buffer
, buffer_size
);
330 return ERROR_CALL_NOT_IMPLEMENTED
;
333 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
336 case DLL_PROCESS_ATTACH
: {
341 DisableThreadLibraryCalls(hinstDLL
);
343 r
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szPowerCfgSubKey
, 0, KEY_READ
| KEY_WRITE
, &hKey
);
345 if (r
!= ERROR_SUCCESS
) {
346 TRACE("Couldn't open registry key HKLM\\%s, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey
));
349 DWORD cbValue
= sizeof(lpValue
);
350 r
= RegQueryValueExW(hKey
, L
"LastID", 0, 0, lpValue
, &cbValue
);
351 if (r
!= ERROR_SUCCESS
) {
352 TRACE("Couldn't open registry entry HKLM\\%s\\LastID, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey
));
357 PPRegSemaphore
= CreateSemaphoreW(NULL
, 1, 1, L
"PowerProfileRegistrySemaphore");
358 if (PPRegSemaphore
== NULL
) {
359 ERR("Couldn't create Semaphore: %d\n", GetLastError());
364 case DLL_PROCESS_DETACH
:
365 if (lpvReserved
) break;
366 CloseHandle(PPRegSemaphore
);