|
|
/*******************************************************************************
* * (C) COPYRIGHT MICROSOFT CORP., 1996 * * TITLE: POWRPROF.C * * VERSION: 2.0 * * AUTHOR: ReedB * * DATE: 17 Oct, 1996 * * DESCRIPTION: * User power management profile maintenance library. Implements persistent * power mamagement data storage. To minimize registry storage and simplify * user power profile management, power scheme's are divided into two parts, * GLOBAL_POWER_POLICY and POWER_POLICY: * * User Level Registry Storage * GLOBAL_POWER_POLICY = - Common scheme data. * GLOBAL_MACHINE_POWER_POLICY - Per machine data. * + GLOBAL_USER_POWER_POLICY - Per user data. * * POWER_POLICY = - Unique scheme data. * MACHINE_POWER_POLICY - Per machine data. * + USER_POWER_POLICY - Per user data. * * The interface to the power policy manager is by AC and DC * SYSTEM_POWER_POLICY which is formed by merging the above structures. * *******************************************************************************/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <tchar.h>
#include <initguid.h>
#include <devguid.h>
#include <string.h>
#include <regstr.h>
#include <commctrl.h>
#include <ntpoapi.h>
#include <setupapi.h>
#include <syssetup.h>
#include <setupbat.h>
#include "powrprofp.h"
#include "reghelp.h"
/*******************************************************************************
* * G L O B A L D A T A * *******************************************************************************/
HINSTANCE g_hInstance; // Global instance handle of this DLL.
HANDLE g_hSemRegistry; // Registry semaphore.
UINT g_uiLastID; // The last ID value used, per machine.
// Variables and definitions to manage dynamic link to NtPowerInformation.
typedef NTSTATUS (NTAPI *PFNNTPOWERINFORMATION)(POWER_INFORMATION_LEVEL, PVOID, ULONG, PVOID, ULONG);
#ifdef WINNT
// Global administrator power policy variables. Initialize to allow everything.
BOOLEAN g_bAdminOverrideActive = FALSE; ADMINISTRATOR_POWER_POLICY g_app = { // Meaning of power action "sleep" Min, Max.
PowerSystemSleeping1, PowerSystemHibernate,
// Video policies Min, Max.
0, -1,
// Disk spindown policies Min, Max.
0, -1 }; #endif
// Debug strings for Power Policy Manager POWER_INFORMATION_LEVEL:
#ifdef DEBUG
LPTSTR lpszInfoLevel[] = { TEXT("SystemPowerPolicyAc"), TEXT("SystemPowerPolicyDc"), TEXT("VerifySystemPolicyAc"), TEXT("VerifySystemPolicyDc"), TEXT("SystemPowerCapabilities"), TEXT("SystemBatteryState"), TEXT("SystemPowerStateHandler"), TEXT("ProcessorStateHandler"), TEXT("SystemPowerPolicyCurrent"), TEXT("AdministratorPowerPolicy"), TEXT("SystemReserveHiberFile"), TEXT("ProcessorInformation"), TEXT("SystemPowerInformation"), TEXT("ProcessorStateHandler2"), TEXT("LastWakeTime"), TEXT("LastSleepTime"), TEXT("SystemExecutionState"), TEXT("SystemPowerStateNotifyHandler"), TEXT("ProcessorPowerPolicyAc"), TEXT("ProcessorPowerPolicyDc"), TEXT("VerifyProcessorPowerPolicyAc"), TEXT("VerifyProcessorPowerPolicyDc"), TEXT("ProcessorPowerPolicyCurrent") };
int g_iShowValidationChanges; int g_iShowCapabilities; int g_iShowSetPPM; #endif
// Global value for storing a single registry value name/path. Multithread
// protection is provided by the Registry semaphore.
TCHAR g_szRegValue[REGSTR_MAX_VALUE_LENGTH];
// Strings used to access the registry. REGSTR_* string constants can be
// found in sdk\inc\regstr.h, USER strings are under HKEY_CURRENT_USER,
// MACHINE strings are under HKEY_LOCAL_MACHINE.
TCHAR c_szREGSTR_PATH_MACHINE_POWERCFG[] = REGSTR_PATH_CONTROLSFOLDER TEXT("\\PowerCfg"); TCHAR c_szREGSTR_PATH_USER_POWERCFG[] = REGSTR_PATH_CONTROLPANEL TEXT("\\PowerCfg");
TCHAR c_szREGSTR_PATH_MACHINE_POWERCFG_POLICIES[] = REGSTR_PATH_CONTROLSFOLDER TEXT("\\PowerCfg\\PowerPolicies"); TCHAR c_szREGSTR_PATH_MACHINE_PROCESSOR_POLICIES[] = REGSTR_PATH_CONTROLSFOLDER TEXT("\\PowerCfg\\ProcessorPolicies"); TCHAR c_szREGSTR_PATH_USER_POWERCFG_POLICIES[] = REGSTR_PATH_CONTROLPANEL TEXT("\\PowerCfg\\PowerPolicies");
TCHAR c_szREGSTR_VAL_GLOBALPOWERPOLICY[] = TEXT("GlobalPowerPolicy"); TCHAR c_szREGSTR_VAL_CURRENTPOWERPOLICY[] = TEXT("CurrentPowerPolicy");
// These values are provided to help OEM's meet disk drive warranty requirements.
TCHAR c_szREGSTR_VAL_SPINDOWNMAX[] = TEXT("DiskSpinDownMax"); TCHAR c_szREGSTR_VAL_SPINDOWNMIN[] = TEXT("DiskSpinDownMin");
// These values are provided to support administrator power policies.
TCHAR c_szREGSTR_VAL_ADMINMAXVIDEOTIMEOUT[] = TEXT("AdminMaxVideoTimeout"); TCHAR c_szREGSTR_VAL_ADMINMAXSLEEP[] = TEXT("AdminMaxSleep");
// This value manages the policy ID's.
TCHAR c_szREGSTR_VAL_LASTID[] = TEXT("LastID");
// This value turns on debug logging of PPM Validation Changes
#ifdef DEBUG
TCHAR c_szREGSTR_VAL_SHOWVALCHANGES[] = TEXT("ShowValidationChanges"); TCHAR c_szREGSTR_VAL_SHOWCAPABILITIES[] = TEXT("ShowCapabilities"); TCHAR c_szREGSTR_VAL_SHOWSETPPM[] = TEXT("ShowSetPPM"); #endif
/*******************************************************************************
* * P U B L I C E N T R Y P O I N T S * *******************************************************************************/
/*******************************************************************************
* * DllInitialize * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
BOOLEAN DllInitialize(IN PVOID hmod, IN ULONG ulReason, IN PCONTEXT pctx OPTIONAL) {
UNREFERENCED_PARAMETER(pctx);
switch (ulReason) {
case DLL_PROCESS_ATTACH: { DisableThreadLibraryCalls(hmod); g_hInstance = hmod;
#ifdef DEBUG
// Get the debug optional settings from HKCU.
ReadOptionalDebugSettings(); #endif
#ifdef WINNT
// Initialize an administrator power policy.
InitAdmin(&g_app); #endif
// One time registry related initialization.
if (!RegistryInit(&g_uiLastID)) { return FALSE; } break; } case DLL_PROCESS_DETACH: if (g_hSemRegistry) { CloseHandle(g_hSemRegistry); g_hSemRegistry = NULL; } break; } return TRUE; }
/*******************************************************************************
* * IsAdminOverrideActive * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
BOOLEAN IsAdminOverrideActive(PADMINISTRATOR_POWER_POLICY papp) { #ifdef WINNT
if ((g_bAdminOverrideActive) && (papp)) { memcpy(papp, &g_app, sizeof(g_app)); } return g_bAdminOverrideActive; #else
return FALSE; #endif
}
/*******************************************************************************
* * IsPwrSuspendAllowed * * DESCRIPTION: * Called by Explorer to determine whether suspend is supported. * * PARAMETERS: * *******************************************************************************/
BOOLEAN IsPwrSuspendAllowed(VOID) { SYSTEM_POWER_CAPABILITIES spc;
if (GetPwrCapabilities(&spc)) { if (spc.SystemS1 || spc.SystemS2 || spc.SystemS3) { return TRUE; } } return FALSE; }
/*******************************************************************************
* * IsPwrHibernateAllowed * * DESCRIPTION: * Called by Explorer to determine whether hibernate is supported. * * PARAMETERS: * *******************************************************************************/
BOOLEAN IsPwrHibernateAllowed(VOID) { SYSTEM_POWER_CAPABILITIES spc;
if (GetPwrCapabilities(&spc)) { if (spc.SystemS4 && spc.HiberFilePresent) { return TRUE; } } return FALSE; }
/*******************************************************************************
* * IsPwrShutdownAllowed * * DESCRIPTION: * Called by Explorer to determine whether shutdown is supported. * * PARAMETERS: * *******************************************************************************/
BOOLEAN IsPwrShutdownAllowed(VOID) { SYSTEM_POWER_CAPABILITIES spc;
if (GetPwrCapabilities(&spc)) { if (spc.SystemS5) { return TRUE; } } return FALSE; }
/*******************************************************************************
* * CanUserWritePwrScheme * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
BOOLEAN CanUserWritePwrScheme(VOID) { DWORD dwSize; TCHAR szNum[NUM_DEC_DIGITS]; LONG lErr;
// Read in the last ID this value must be present.
dwSize = sizeof(szNum);
// ReadWritePowerValue will set last error
if (ReadWritePowerValue(HKEY_LOCAL_MACHINE, c_szREGSTR_PATH_MACHINE_POWERCFG, c_szREGSTR_VAL_LASTID, szNum, &dwSize, FALSE, TRUE)) { // Write the value back out, this may fail if user doesn't have write access.
if (ReadWritePowerValue(HKEY_LOCAL_MACHINE, c_szREGSTR_PATH_MACHINE_POWERCFG, c_szREGSTR_VAL_LASTID, szNum, &dwSize, TRUE, TRUE)) { return TRUE; } else { lErr = GetLastError(); if (lErr != ERROR_ACCESS_DENIED) { MYDBGPRINT(( "CanUserWritePwrScheme, Unable to write last ID, Error: %d", lErr)); } } } else { lErr = GetLastError(); MYDBGPRINT(( "CanUserWritePwrScheme, Unable to fetch last ID, Error: %d", lErr)); }
return FALSE; }
/*******************************************************************************
* * GetPwrDiskSpindownRange * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
BOOLEAN GetPwrDiskSpindownRange(PUINT puiMax, PUINT puiMin) { if (!puiMax || !puiMin) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
if (ReadPowerIntOptional(HKEY_LOCAL_MACHINE, c_szREGSTR_PATH_MACHINE_POWERCFG, c_szREGSTR_VAL_SPINDOWNMAX, puiMax) && ReadPowerIntOptional(HKEY_LOCAL_MACHINE, c_szREGSTR_PATH_MACHINE_POWERCFG, c_szREGSTR_VAL_SPINDOWNMIN, puiMin)) { return TRUE; } return FALSE; }
/*******************************************************************************
* * EnumPwrSchemes * * DESCRIPTION: * Calls back the PWRSCHEMESENUMPROC with the ID, a pointer to the name, * the size in bytes of the name, a pointer to the description, the size in * bytes of the description, a pointer to the power policies and a user * defined value. Returns ERROR_SUCCESS on success, else error code. Callback * data is not allocated and is only valid during the scope of the callback. * * Note: No calls to any other API's in this library should be made during * the call back to PWRSCHEMESENUMPROC. The registry semaphore is held at * this time and a deadlock will result. * * PARAMETERS: * *******************************************************************************/
BOOLEAN EnumPwrSchemes( PWRSCHEMESENUMPROC lpfn, LPARAM lParam ) { HKEY hKeyPolicyUser, hKeyPolicyMachine; HKEY hKeyUser = INVALID_HANDLE_VALUE; HKEY hKeyMachine = INVALID_HANDLE_VALUE; DWORD dwDescSize; DWORD dwSize, dwNameSize, dwIndex = 0; BOOLEAN bOneCallBackOk = FALSE; LONG lRet = ERROR_SUCCESS; LPTSTR lpszDescBuf, lpszDesc; TCHAR szNameBuf[MAX_NAME_LEN+1]; FILETIME ft; UINT uiID;
MACHINE_POWER_POLICY mpp; USER_POWER_POLICY upp; POWER_POLICY pp;
if (!lpfn) { SetLastError(ERROR_INVALID_PARAMETER); goto WESPSP_exit; }
// Wait on/take the registry semaphore.
if (!TakeRegSemaphore()) { return FALSE; }
// Allocate a description buffer.
lpszDescBuf = LocalAlloc(0, (MAX_DESC_LEN + 1) * sizeof(TCHAR)); if (!lpszDescBuf) { goto WESPSP_exit; }
if (ERROR_SUCCESS != OpenMachineUserKeys2( c_szREGSTR_PATH_USER_POWERCFG_POLICIES, KEY_READ, c_szREGSTR_PATH_MACHINE_POWERCFG_POLICIES, KEY_READ, &hKeyUser, &hKeyMachine)) { ReleaseSemaphore(g_hSemRegistry, 1, NULL); return FALSE; }
// Enumerate the schemes
while (lRet == ERROR_SUCCESS) { dwSize = REGSTR_MAX_VALUE_LENGTH - 1; if ((lRet = RegEnumKeyEx(hKeyUser, dwIndex, g_szRegValue, &dwSize, NULL, NULL, NULL, &ft)) == ERROR_SUCCESS) {
// Open the Policies Key. The key name is the policies ID.
lpszDesc = NULL; if (MyStrToInt(g_szRegValue, &uiID)) { if ((lRet = RegOpenKeyEx(hKeyUser, g_szRegValue, 0, KEY_READ, &hKeyPolicyUser)) == ERROR_SUCCESS) {
if ((lRet = RegOpenKeyEx(hKeyMachine, g_szRegValue, 0, KEY_READ, &hKeyPolicyMachine)) == ERROR_SUCCESS) {
// Get the friendly name..
dwNameSize = MAX_NAME_SIZE; if ((lRet = RegQueryValueEx(hKeyPolicyUser, TEXT("Name"), NULL, NULL, (PBYTE) szNameBuf, &dwNameSize)) == ERROR_SUCCESS) {
// Descriptions are optional.
dwDescSize = MAX_DESC_SIZE; if ((lRet = RegQueryValueEx(hKeyPolicyUser, TEXT("Description"), NULL, NULL, (PBYTE) lpszDescBuf, &dwDescSize)) == ERROR_SUCCESS) { lpszDesc = lpszDescBuf; }
// Read the user and machine policies.
dwSize = sizeof(upp); if ((lRet = RegQueryValueEx(hKeyPolicyUser, TEXT("Policies"), NULL, NULL, (PBYTE) &upp, &dwSize)) == ERROR_SUCCESS) {
dwSize = sizeof(mpp); if ((lRet = RegQueryValueEx(hKeyPolicyMachine, TEXT("Policies"), NULL, NULL, (PBYTE) &mpp, &dwSize)) == ERROR_SUCCESS) {
// Merge the user and machine policies.
if (MergePolicies(&upp, &mpp, &pp)) {
// Call the enumerate proc.
if (!lpfn(uiID, dwNameSize, szNameBuf, dwDescSize, lpszDesc, &pp, lParam)) { RegCloseKey(hKeyPolicyMachine); RegCloseKey(hKeyPolicyUser); SetLastError(ERROR_NOT_ENOUGH_MEMORY); break; } else { bOneCallBackOk = TRUE; } } } } } RegCloseKey(hKeyPolicyMachine); } RegCloseKey(hKeyPolicyUser); } } } dwIndex++; }
RegCloseKey(hKeyUser); RegCloseKey(hKeyMachine); ReleaseSemaphore(g_hSemRegistry, 1, NULL); if (lpszDescBuf) { LocalFree(lpszDescBuf); }
WESPSP_exit: if (lRet != ERROR_NO_MORE_ITEMS) { MYDBGPRINT(( "EnumPwrSchemes, failed, LastError: 0x%08X", (lRet == ERROR_SUCCESS) ? GetLastError():lRet)); } return bOneCallBackOk; }
/*******************************************************************************
* * ReadGlobalPwrPolicy * * DESCRIPTION: * Function reads the users global power policy profile and returns it. * If there is no such profile FALSE is returned. A global power policy * profile is per user, and contains values which apply to all of a users * power policies. * * PARAMETERS: * *******************************************************************************/
BOOLEAN ReadGlobalPwrPolicy( PGLOBAL_POWER_POLICY pgpp ) { GLOBAL_MACHINE_POWER_POLICY gmpp; GLOBAL_USER_POWER_POLICY gupp; DWORD dwError = ReadPwrPolicyEx2(c_szREGSTR_PATH_USER_POWERCFG, c_szREGSTR_PATH_MACHINE_POWERCFG, c_szREGSTR_VAL_GLOBALPOWERPOLICY, NULL, NULL, &gupp, sizeof(gupp), &gmpp, sizeof(gmpp));
if (ERROR_SUCCESS == dwError) { return MergeGlobalPolicies(&gupp, &gmpp, pgpp); // Sets Last Error
} else { SetLastError(dwError); }
return FALSE; }
/*******************************************************************************
* * WritePwrScheme * * DESCRIPTION: * Function to write a users power policy profile. If the profile already * exists it is replaced. Otherwise a new profile is created. * * PARAMETERS: * * puiID - Index of the power scheme to be written. * * lpszSchemeName - String that specifies the name of the power scheme. * * lpszDescription - Pointer to a string that specifies the description * of the power scheme. * * lpScheme - Pointer to a POWER_POLICY structure that contains * the power policy settings to be written. * *******************************************************************************/
BOOLEAN WritePwrScheme( PUINT puiID, LPTSTR lpszSchemeName, LPTSTR lpszDescription OPTIONAL, PPOWER_POLICY lpScheme ) { MACHINE_POWER_POLICY mpp; USER_POWER_POLICY upp;
if( (!puiID && !lpszSchemeName) || !lpScheme ) {
SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
if (SplitPolicies(lpScheme, &upp, &mpp)) { // WritePwrPolicyEx will set the last error on failure.
return WritePwrPolicyEx(c_szREGSTR_PATH_USER_POWERCFG_POLICIES, c_szREGSTR_PATH_MACHINE_POWERCFG_POLICIES, puiID, lpszSchemeName, lpszDescription, &upp, sizeof(upp), &mpp, sizeof(mpp)); } return FALSE; }
/*******************************************************************************
* * WriteGlobalPwrPolicy * * DESCRIPTION: * Function to write a users global power policy profile. If the profile * already exists it is replaced. Otherwise a new profile is created. * A global power policy profile is per user, and contains values which * apply to all of a users power policies. Otherwise a new profile is created. * * PARAMETERS: * *******************************************************************************/
BOOLEAN WriteGlobalPwrPolicy ( PGLOBAL_POWER_POLICY pgpp ) { GLOBAL_MACHINE_POWER_POLICY gmpp; GLOBAL_USER_POWER_POLICY gupp;
if (SplitGlobalPolicies(pgpp, &gupp, &gmpp)) // Will set last error
{ // WritePwrPolicyEx will set the last error on failure.
return WritePwrPolicyEx(c_szREGSTR_PATH_USER_POWERCFG, c_szREGSTR_PATH_MACHINE_POWERCFG, NULL, c_szREGSTR_VAL_GLOBALPOWERPOLICY, NULL, &gupp, sizeof(gupp), &gmpp, sizeof(gmpp)); } return FALSE; }
/*******************************************************************************
* * DeletePwrScheme * * DESCRIPTION: * Function to delete a users power policy profile. An attempt to delete the * currently active power policy profile will fail with last error set to * ERROR_ACCESS_DENIED. * * PARAMETERS: * *******************************************************************************/
BOOLEAN DeletePwrScheme(UINT uiID) { HKEY hKeyUser; DWORD dwSize = REGSTR_MAX_VALUE_LENGTH * sizeof(TCHAR); BOOLEAN bRet = FALSE; LONG lRet = ERROR_SUCCESS; TCHAR szNum[NUM_DEC_DIGITS]; int iCurrent; HKEY hKeyCurrentUser;
// Wait on/take the registry semaphore.
if (!TakeRegSemaphore()) { return FALSE; }
if (ERROR_SUCCESS == OpenCurrentUser2(&hKeyCurrentUser, KEY_WRITE)) { // Don't allow the currently active power policy profile to be deleted.
// ReadWritePowerValue will set last error
if (ReadWritePowerValue(hKeyCurrentUser, c_szREGSTR_PATH_USER_POWERCFG, c_szREGSTR_VAL_CURRENTPOWERPOLICY, g_szRegValue, &dwSize, FALSE, FALSE) && MyStrToInt(g_szRegValue, &iCurrent)) { if (uiID != (UINT) iCurrent) { // For now we only delete the user portion of a policy. We may
// want a ref count on the machine portion which allows deletion
// of the machine portion when no user portion references it.
lRet = RegOpenKeyEx(hKeyCurrentUser,c_szREGSTR_PATH_USER_POWERCFG_POLICIES,0,KEY_WRITE,&hKeyUser); if (lRet == ERROR_SUCCESS) { _itot(uiID, szNum, 10 );
lRet = RegDeleteKey(hKeyUser, szNum); if (lRet == ERROR_SUCCESS) { bRet = TRUE; } RegCloseKey(hKeyUser); } } else { SetLastError(ERROR_ACCESS_DENIED); } } CloseCurrentUser(hKeyCurrentUser); }
ReleaseSemaphore(g_hSemRegistry, 1, NULL); if (!bRet) { MYDBGPRINT(( "DeletePwrScheme, failed, LastError: 0x%08X", (lRet == ERROR_SUCCESS) ? GetLastError():lRet)); } return bRet; }
/*******************************************************************************
* * GetActivePwrScheme * * DESCRIPTION: * Retrieves the ID of the currently active power policy profile. This value * is set by SetActivePwrScheme. * * PARAMETERS: * *******************************************************************************/
BOOLEAN GetActivePwrScheme(PUINT puiID) { BOOLEAN bRet = FALSE; TCHAR szNum[NUM_DEC_DIGITS]; DWORD dwSize = SIZE_DEC_DIGITS; HKEY hKey;
if (ERROR_SUCCESS == OpenCurrentUser2(&hKey, KEY_READ)) { // ReadWritePowerValue will set last error
if (ReadWritePowerValue(hKey, c_szREGSTR_PATH_USER_POWERCFG, c_szREGSTR_VAL_CURRENTPOWERPOLICY, szNum, &dwSize, FALSE, TRUE) && MyStrToInt(szNum, puiID)) { bRet = TRUE; } CloseCurrentUser(hKey); } return bRet; }
/*******************************************************************************
* * SetActivePwrScheme * * DESCRIPTION: * Set the currently active power policy profile. * * PARAMETERS: * uiID - ID of the new active power scheme. * lpGlobalPolicy - Optional global policies to merge with active power scheme. * lpPowerPolicy - Optional power policies to merge with active power scheme. * *******************************************************************************/
BOOLEAN SetActivePwrScheme( UINT uiID, PGLOBAL_POWER_POLICY pgpp, PPOWER_POLICY ppp ) { DWORD dwSize; NTSTATUS ntsRetVal, status; TCHAR szNum[NUM_DEC_DIGITS]; POWER_POLICY pp; GLOBAL_POWER_POLICY gpp; MACHINE_POWER_POLICY mpp; USER_POWER_POLICY upp; GLOBAL_MACHINE_POWER_POLICY gmpp; GLOBAL_USER_POWER_POLICY gupp; SYSTEM_POWER_POLICY sppAc, sppDc; MACHINE_PROCESSOR_POWER_POLICY mppp;
HKEY hKeyCurrentUser; DWORD dwError; BOOLEAN bRet = FALSE;
// If a new scheme is not passed, fetch the target scheme.
if (!ppp) { if (!ReadPwrScheme(uiID, &pp)) // Will SetLastError
{ return FALSE; } ppp = &pp; }
// If a new global policy is not passed, fetch the target global policy.
if (!pgpp) { if (!ReadGlobalPwrPolicy(&gpp)) // Sets last error
{ return FALSE; } pgpp = &gpp; }
if (!ReadProcessorPwrScheme(uiID, &mppp)) { return FALSE; }
// Merge global policy and user scheme if a global policy was passed.
if (!MergeToSystemPowerPolicies(pgpp, ppp, &sppAc, &sppDc)) // Sets last error
{ return FALSE; }
// Write out what was requested to the registry.
SplitPolicies(ppp, &upp, &mpp); // Will set last error
if (!WritePwrPolicyEx(c_szREGSTR_PATH_USER_POWERCFG_POLICIES, c_szREGSTR_PATH_MACHINE_POWERCFG_POLICIES, &uiID, NULL, NULL, &upp, sizeof(upp), &mpp, sizeof(mpp))) { // WritePwrPolicyEx will set the last error on failure.
return FALSE; }
SplitGlobalPolicies(pgpp, &gupp, &gmpp); // Will set last error
if (!WritePwrPolicyEx(c_szREGSTR_PATH_USER_POWERCFG, c_szREGSTR_PATH_MACHINE_POWERCFG, NULL, c_szREGSTR_VAL_GLOBALPOWERPOLICY, NULL, &gupp, sizeof(gupp), &gmpp, sizeof(gmpp))) { // WritePwrPolicyEx will set the last error on failure.
return FALSE; }
// Call down to the power policy manager to set the scheme.
// I'm working under the assumption that CallNtSetValidateAcDc will call SetLastError() with any
// error values.
status = CallNtSetValidateAcDc(FALSE, FALSE, &(mppp.ProcessorPolicyAc), &(mppp.ProcessorPolicyAc), &(mppp.ProcessorPolicyDc), &(mppp.ProcessorPolicyDc)); ntsRetVal = CallNtSetValidateAcDc(FALSE, TRUE, &sppAc, &sppAc, &sppDc, &sppDc); //if ((ntsRetVal == STATUS_SUCCESS) && (status = STATUS_SUCCESS))
if ((ntsRetVal == STATUS_SUCCESS)) { dwError = OpenCurrentUser2(&hKeyCurrentUser, KEY_WRITE); if (ERROR_SUCCESS == dwError) { // On success, set the current active power scheme in the registry.
_itot(uiID, szNum, 10 );
// ReadWritePowerValue will set last error
bRet = ReadWritePowerValue(hKeyCurrentUser, c_szREGSTR_PATH_USER_POWERCFG, c_szREGSTR_VAL_CURRENTPOWERPOLICY, szNum, NULL, TRUE, TRUE);
dwError = GetLastError(); CloseCurrentUser(hKeyCurrentUser); SetLastError(dwError); } else { SetLastError(dwError); } }
return bRet; }
/*******************************************************************************
* * LoadCurrentPwrScheme * * DESCRIPTION: * A Memphis only cover to call SetActivePwrScheme using RunDLL32 calling * convention. Do not change parameter list. * * PARAMETERS: * * NOTE: THIS API HAS BEEN DEPRECATED ON WINNT *******************************************************************************/
void WINAPI LoadCurrentPwrScheme( HWND hwnd, HINSTANCE hAppInstance, LPSTR lpszCmdLine, int nCmdShow) { #ifndef WINNT
UINT uiID;
if (GetActivePwrScheme(&uiID)) { SetActivePwrScheme(uiID, NULL, NULL); } #else
UNREFERENCED_PARAMETER(hwnd); UNREFERENCED_PARAMETER(hAppInstance); UNREFERENCED_PARAMETER(lpszCmdLine); UNREFERENCED_PARAMETER(nCmdShow);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
#endif
}
/*******************************************************************************
* * MergeLegacyPwrScheme * * DESCRIPTION: * A Memphis only call to merge legacy power management registry info into the * currently active power scheme. * Called using the RunDLL32 calling convention. Do not change parameter list. * * PARAMETERS: * *******************************************************************************/
void WINAPI MergeLegacyPwrScheme( HWND hwnd, HINSTANCE hAppInstance, LPSTR lpszCmdLine, int nCmdShow) { #ifndef WINNT
DWORD dwSize, dwLegacy; POWER_POLICY pp; GLOBAL_POWER_POLICY gpp; UINT uiID; HKEY hKeyCurrentUser;
// Get the active power scheme from the registry.
if (!GetActivePwrScheme(&uiID)) { return; } if (!ReadPwrScheme(uiID, &pp)) { return; } if (!ReadGlobalPwrPolicy(&gpp)) { return; }
if (ERROR_SUCCESS == OpenCurrentUser2(&hKeyCurrentUser)) { // Get the legacy video monitor power down information.
if (ReadPowerIntOptional(hKeyCurrentUser, REGSTR_PATH_SCREENSAVE, REGSTR_VALUE_POWEROFFACTIVE, &pp.user.VideoTimeoutAc)) { MYDBGPRINT(( "MergeLegacyPwrScheme, found legacy %s: %d", REGSTR_VALUE_POWEROFFACTIVE, pp.user.VideoTimeoutAc)); pp.user.VideoTimeoutDc = pp.user.VideoTimeoutAc; } CloseCurrentUser(hKeyCurrentUser); }
// Get the legacy disk spin down information.
if (ReadPowerIntOptional(HKEY_LOCAL_MACHINE, REGSTR_PATH_FILESYSTEM, REGSTR_VAL_ACDRIVESPINDOWN, &pp.user.SpindownTimeoutAc)) { MYDBGPRINT(( "MergeLegacyPwrScheme, found legacy %s: %d", REGSTR_VAL_ACDRIVESPINDOWN, pp.user.SpindownTimeoutAc)); }
if (ReadPowerIntOptional(HKEY_LOCAL_MACHINE, REGSTR_PATH_FILESYSTEM, REGSTR_VAL_BATDRIVESPINDOWN, &pp.user.SpindownTimeoutDc)) { MYDBGPRINT(( "MergeLegacyPwrScheme, found legacy %s: %d", REGSTR_VAL_BATDRIVESPINDOWN, pp.user.SpindownTimeoutDc)); }
// Get the legacy battery meter information.
dwSize = sizeof(dwLegacy); if (ReadPowerValueOptional(HKEY_LOCAL_MACHINE, REGSTR_PATH_VPOWERD, REGSTR_VAL_VPOWERDFLAGS, (LPTSTR)&dwLegacy, &dwSize)) { if (dwLegacy & VPDF_SHOWMULTIBATT) { gpp.user.GlobalFlags |= EnableSysTrayBatteryMeter; } else { gpp.user.GlobalFlags &= ~EnableSysTrayBatteryMeter; } MYDBGPRINT(( "MergeLegacyPwrScheme, found legacy %s: %X", REGSTR_VAL_VPOWERDFLAGS, dwLegacy)); }
// Write out the modified active power scheme.
if (!WriteGlobalPwrPolicy(&gpp)) { return; }
WritePwrScheme(&uiID, NULL, NULL, &pp); #else
UNREFERENCED_PARAMETER(hwnd); UNREFERENCED_PARAMETER(hAppInstance); UNREFERENCED_PARAMETER(lpszCmdLine); UNREFERENCED_PARAMETER(nCmdShow);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
#endif
}
/*******************************************************************************
* * GetPwrCapabilities * * DESCRIPTION: * Get the system power capabilities from the Power Policy Manager. * * PARAMETERS: * *******************************************************************************/
BOOLEAN GetPwrCapabilities(PSYSTEM_POWER_CAPABILITIES lpspc) { NTSTATUS ntsRetVal = STATUS_SUCCESS;
if (!lpspc) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
ntsRetVal = CallNtPowerInformation(SystemPowerCapabilities, NULL, 0, lpspc, sizeof(SYSTEM_POWER_CAPABILITIES));
if (ntsRetVal == STATUS_SUCCESS) { #ifdef DEBUG
if (g_iShowCapabilities) { DumpSystemPowerCapabilities("GetPwrCapabilities, returned:", lpspc); } #ifdef SIM_BATTERY
lpspc->SystemBatteriesPresent = TRUE; #endif
#endif
return TRUE; } else { return FALSE; } }
/*******************************************************************************
* * CallNtPowerInformation * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
NTSTATUS CallNtPowerInformation( POWER_INFORMATION_LEVEL InformationLevel, PVOID InputBuffer OPTIONAL, ULONG InputBufferLength, PVOID OutputBuffer OPTIONAL, ULONG OutputBufferLength ) { NTSTATUS ntsRetVal; DWORD dwOldState, dwStatus; DWORD dwErrorSave; LPCTSTR PrivilegeName;
if (InformationLevel == SystemReserveHiberFile) { PrivilegeName = SE_CREATE_PAGEFILE_NAME; } else { PrivilegeName = SE_SHUTDOWN_NAME; }
SetLastError(0); dwStatus = SetPrivilegeAttribute(PrivilegeName, SE_PRIVILEGE_ENABLED, &dwOldState); dwErrorSave = GetLastError();
ntsRetVal = NtPowerInformation(InformationLevel, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength);
//
// If we were able to set the privilege, then reset it.
//
if (NT_SUCCESS(dwStatus) && dwErrorSave == 0) { SetPrivilegeAttribute(PrivilegeName, dwOldState, NULL); } else { MYDBGPRINT(( "CallNtPowerInformation, SetPrivilegeAttribute failed: 0x%08X", GetLastError())); }
#ifdef DEBUG
if ((ntsRetVal != STATUS_SUCCESS) && (InformationLevel <= ProcessorPowerPolicyCurrent)) { MYDBGPRINT(( "NtPowerInformation, %s, failed: 0x%08X", lpszInfoLevel[InformationLevel], ntsRetVal)); } else { if (g_iShowSetPPM && InputBuffer) { if ((InformationLevel == SystemPowerPolicyAc) || (InformationLevel == SystemPowerPolicyDc)) { DumpSystemPowerPolicy("NtPowerInformation, Set to PPM, InputBuffer", InputBuffer); } } } #endif
return ntsRetVal; }
/*******************************************************************************
* * SetSuspendState * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
BOOLEAN SetSuspendState( BOOLEAN bHibernate, BOOLEAN bForce, BOOLEAN bWakeupEventsDisabled) { NTSTATUS ntsRetVal; POWER_ACTION pa; ULONG Flags; DWORD dwOldState, dwStatus; DWORD dwErrorSave;
SetLastError(0); dwStatus = SetPrivilegeAttribute(SE_SHUTDOWN_NAME, SE_PRIVILEGE_ENABLED, &dwOldState); dwErrorSave = GetLastError();
if (bHibernate) { pa = PowerActionHibernate; } else { pa = PowerActionSleep; }
Flags = POWER_ACTION_QUERY_ALLOWED | POWER_ACTION_UI_ALLOWED;
if (bForce) { Flags |= POWER_ACTION_CRITICAL; }
if (bWakeupEventsDisabled) { Flags |= POWER_ACTION_DISABLE_WAKES; }
ntsRetVal = NtInitiatePowerAction(pa, PowerSystemSleeping1, Flags, FALSE);
//
// If we were able to set the privilege, then reset it.
//
if (NT_SUCCESS(dwStatus) && dwErrorSave == 0) { SetPrivilegeAttribute(SE_SHUTDOWN_NAME, dwOldState, NULL); } else { MYDBGPRINT(( "SetSuspendState, SetPrivilegeAttribute failed: 0x%08X", GetLastError())); }
if (ntsRetVal == STATUS_SUCCESS) { return TRUE; } else { MYDBGPRINT(( "NtInitiatePowerAction, failed: 0x%08X", ntsRetVal)); return FALSE; } }
/*******************************************************************************
* * P R I V A T E F U N C T I O N S * *******************************************************************************/
/*******************************************************************************
* * ValidatePowerPolicies * * DESCRIPTION: * Call down to the power policy manager to validate power policies. * * PARAMETERS: * *******************************************************************************/
BOOLEAN ValidatePowerPolicies( PGLOBAL_POWER_POLICY pgpp, PPOWER_POLICY ppp ) { POWER_POLICY ppValid; GLOBAL_POWER_POLICY gppValid; SYSTEM_POWER_POLICY sppAc, sppDc;
// Get current power policy data from the PPM.
if (!GetCurrentPowerPolicies(&gppValid, &ppValid)) { return FALSE; }
if (!pgpp) { pgpp = &gppValid; }
if (!ppp) { ppp = &ppValid; }
// Merge policy and global policy data.
if (!MergeToSystemPowerPolicies(pgpp, ppp, &sppAc, &sppDc)) { return FALSE; }
if (!ValidateSystemPolicies(&sppAc, &sppDc)) { return FALSE; }
return SplitFromSystemPowerPolicies(&sppAc, &sppDc, pgpp, ppp); }
/*******************************************************************************
* * ValidateSystemPolicies * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
BOOLEAN ValidateSystemPolicies( PSYSTEM_POWER_POLICY psppAc, PSYSTEM_POWER_POLICY psppDc ) { DWORD dwLastErr; NTSTATUS ntsRetVal;
// Call down to the power policy manager to validate the scheme.
ntsRetVal = CallNtSetValidateAcDc(TRUE, TRUE, psppAc, psppAc, psppDc, psppDc);
// Map any PPM errors to winerror.h values
switch (ntsRetVal) { case STATUS_SUCCESS: return TRUE;
case STATUS_PRIVILEGE_NOT_HELD: dwLastErr = ERROR_ACCESS_DENIED; break;
case STATUS_INVALID_PARAMETER: dwLastErr = ERROR_INVALID_DATA; break;
default: dwLastErr = ERROR_GEN_FAILURE; break; } SetLastError(dwLastErr); return FALSE; }
/*******************************************************************************
* * GetCurrentPowerPolicies * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
BOOLEAN GetCurrentPowerPolicies(PGLOBAL_POWER_POLICY pgpp, PPOWER_POLICY ppp) { SYSTEM_POWER_POLICY sppAc, sppDc;
if (!GetCurrentSystemPowerPolicies(&sppAc, &sppDc)) { return FALSE; }
return SplitFromSystemPowerPolicies(&sppAc, &sppDc, pgpp, ppp); }
/*******************************************************************************
* * GetCurrentSystemPowerPolicies * * DESCRIPTION: * Call down to the power policy manager to get the current system power * policies. * * PARAMETERS: * *******************************************************************************/
BOOLEAN GetCurrentSystemPowerPolicies( PSYSTEM_POWER_POLICY psppAc, PSYSTEM_POWER_POLICY psppDc ) { NTSTATUS ntsRetVal;
// Call down to the power policy manager to get system power policies.
ntsRetVal = CallNtSetValidateAcDc(FALSE, TRUE, NULL, psppAc, NULL, psppDc);
if (ntsRetVal == STATUS_SUCCESS) { return TRUE; } else { return FALSE; } }
#ifdef WINNT
/*******************************************************************************
* * SetPrivilegeAttribute * * DESCRIPTION: * This routine sets the security attributes for a given privilege. * * PARAMETERS: * PrivilegeName - Name of the privilege we are manipulating. * NewPrivilegeAttribute - The new attribute value to use. * OldPrivilegeAttribute - Pointer to receive the old privilege value. * OPTIONAL. * *******************************************************************************/
DWORD SetPrivilegeAttribute( LPCTSTR PrivilegeName, DWORD NewPrivilegeAttribute, DWORD *OldPrivilegeAttribute ) { LUID PrivilegeValue; TOKEN_PRIVILEGES TokenPrivileges, OldTokenPrivileges; DWORD ReturnLength; HANDLE TokenHandle;
// First, find out the LUID Value of the privilege
if(!LookupPrivilegeValue(NULL, PrivilegeName, &PrivilegeValue)) { return GetLastError(); }
// Get the token handle
if (!OpenThreadToken (GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &TokenHandle)) { if (!OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle)) { return GetLastError(); } }
// Set up the privilege set we will need
TokenPrivileges.PrivilegeCount = 1; TokenPrivileges.Privileges[0].Luid = PrivilegeValue; TokenPrivileges.Privileges[0].Attributes = NewPrivilegeAttribute;
ReturnLength = sizeof(TOKEN_PRIVILEGES); if (!AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), &OldTokenPrivileges, &ReturnLength)) { CloseHandle(TokenHandle); return GetLastError(); } else { if (OldPrivilegeAttribute != NULL) {
//
// If the privilege changed, store the old value. If it did
// not change, store the value passed in.
//
if( OldTokenPrivileges.PrivilegeCount != 0 ) {
*OldPrivilegeAttribute = OldTokenPrivileges.Privileges[0].Attributes;
} else {
*OldPrivilegeAttribute = NewPrivilegeAttribute; } } CloseHandle(TokenHandle); return NO_ERROR; } } #endif
/*******************************************************************************
* * CallNtSetValidateAcDc * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
NTSTATUS CallNtSetValidateAcDc( BOOLEAN bValidate, BOOLEAN bSystem, PVOID InputBufferAc OPTIONAL, PVOID OutputBufferAc OPTIONAL, PVOID InputBufferDc OPTIONAL, PVOID OutputBufferDc OPTIONAL ) { NTSTATUS ntsRetVal; POWER_INFORMATION_LEVEL pil, pilAc, pilDc; ULONG policyLength;
#ifdef DEBUG
SYSTEM_POWER_POLICY sppOrgAc, sppOrgDc; #endif
#ifdef WINNT
DWORD dwOldState, dwStatus; DWORD dwErrorSave;
SetLastError(0); dwStatus = SetPrivilegeAttribute(SE_SHUTDOWN_NAME, SE_PRIVILEGE_ENABLED, &dwOldState); dwErrorSave = GetLastError(); #endif
if (bSystem) {
if (bValidate) { pil = pilAc = VerifySystemPolicyAc; pilDc = VerifySystemPolicyDc; } else { pil = pilAc = SystemPowerPolicyAc; pilDc = SystemPowerPolicyDc; } policyLength = sizeof(SYSTEM_POWER_POLICY);
} else { if (bValidate) { pil = pilAc = VerifyProcessorPowerPolicyAc; pilDc = VerifyProcessorPowerPolicyDc; } else { pil = pilAc = ProcessorPowerPolicyAc; pilDc = ProcessorPowerPolicyDc; } policyLength = sizeof(PROCESSOR_POWER_POLICY); } #ifdef DEBUG
if (InputBufferAc) { memcpy(&sppOrgAc, InputBufferAc, policyLength); } if (InputBufferDc) { memcpy(&sppOrgDc, InputBufferDc, policyLength); } #endif
ntsRetVal = NtPowerInformation(pilAc, InputBufferAc, policyLength, OutputBufferAc, policyLength);
if (ntsRetVal == STATUS_SUCCESS) { pil = pilDc; ntsRetVal = NtPowerInformation(pilDc, InputBufferDc, policyLength, OutputBufferDc, policyLength); }
#ifdef WINNT
// If we were able to set the privilege, then reset it.
if (NT_SUCCESS(dwStatus) && (dwErrorSave == ERROR_SUCCESS)) { SetPrivilegeAttribute(SE_SHUTDOWN_NAME, dwOldState, NULL);
#ifdef DEBUG
if (InputBufferAc && OutputBufferAc) { DifSystemPowerPolicies("PPM modified AC policies", &sppOrgAc, OutputBufferAc); } if (InputBufferDc && OutputBufferDc) { DifSystemPowerPolicies("PPM modified DC policies", &sppOrgDc, OutputBufferDc); } #endif
} else { MYDBGPRINT(( "SetSuspendState, SetPrivilegeAttribute failed: 0x%08X", GetLastError())); } #endif
#ifdef DEBUG
if (ntsRetVal != STATUS_SUCCESS) { MYDBGPRINT(( "NtPowerInformation, %s, failed: 0x%08X", lpszInfoLevel[pil], ntsRetVal)); switch (pil) { case SystemPowerPolicyAc: case VerifySystemPolicyAc: DumpSystemPowerPolicy("InputBufferAc", InputBufferAc); break;
case SystemPowerPolicyDc: case VerifySystemPolicyDc: DumpSystemPowerPolicy("InputBufferDc", InputBufferDc); break; } } else { if (g_iShowSetPPM && InputBufferAc && InputBufferDc && !bValidate) { DumpSystemPowerPolicy("CallNtSetValidateAcDc, Set AC to PPM", InputBufferAc); DumpSystemPowerPolicy("CallNtSetValidateAcDc, Set DC to PPM", InputBufferDc); } } #endif
return ntsRetVal; }
/*******************************************************************************
* * ReadPwrScheme * * DESCRIPTION: * Function reads the specified user power policy profile and returns * it. If there is no such profile FALSE is returned. * * PARAMETERS: * *******************************************************************************/
BOOLEAN ReadPwrScheme( UINT uiID, PPOWER_POLICY ppp ) { MACHINE_POWER_POLICY mpp; USER_POWER_POLICY upp; TCHAR szNum[NUM_DEC_DIGITS]; DWORD dwError;
_itot(uiID, szNum, 10 );
dwError = ReadPwrPolicyEx2(c_szREGSTR_PATH_USER_POWERCFG_POLICIES, c_szREGSTR_PATH_MACHINE_POWERCFG_POLICIES, szNum, NULL, 0, &upp, sizeof(upp), &mpp, sizeof(mpp));
if (ERROR_SUCCESS == dwError) { return MergePolicies(&upp, &mpp, ppp); } else { SetLastError(dwError); }
return FALSE; }
/*******************************************************************************
* * ReadProcessorPwrScheme * * DESCRIPTION: * Function reads the specified processor power policy profile and returns * it. If there is no such profile FALSE is returned. * * PARAMETERS: * *******************************************************************************/
BOOLEAN ReadProcessorPwrScheme( UINT uiID, PMACHINE_PROCESSOR_POWER_POLICY pmppp ) { TCHAR szNum[NUM_DEC_DIGITS]; DWORD dwError;
_itot(uiID, szNum, 10 );
dwError = ReadProcessorPwrPolicy(c_szREGSTR_PATH_MACHINE_PROCESSOR_POLICIES, szNum, pmppp, sizeof(MACHINE_PROCESSOR_POWER_POLICY));
//
// It's legal for there to be no Processor Power Scheme that corresponds with
// uiID, as long as uiID is non-zero. If this is the case, just use a
// default scheme. (We use '1' as a default because this will be the
// default laptop scheme. Non-laptops probably won't have power controls
// on the processor, so it won't matter if we get a scheme that is too aggressive.)
//
if ((ERROR_SUCCESS != dwError) && (uiID != 0)) {
szNum[0] = TEXT('1'); szNum[1] = TEXT('\0');
dwError = ReadProcessorPwrPolicy(c_szREGSTR_PATH_MACHINE_PROCESSOR_POLICIES, szNum, pmppp, sizeof(MACHINE_PROCESSOR_POWER_POLICY)); } if (ERROR_SUCCESS == dwError) { return TRUE; } else { SetLastError(dwError); return FALSE; } }
/*******************************************************************************
* * WriteProcessorPwrScheme * * DESCRIPTION: * Function writes the specified processor power policy profile * * PARAMETERS: * *******************************************************************************/
BOOLEAN WriteProcessorPwrScheme( UINT uiID, PMACHINE_PROCESSOR_POWER_POLICY pmppp ) { TCHAR szNum[NUM_DEC_DIGITS]; DWORD dwError;
_itot(uiID, szNum, 10 );
dwError = WriteProcessorPwrPolicy(c_szREGSTR_PATH_MACHINE_PROCESSOR_POLICIES, szNum, pmppp, sizeof(MACHINE_PROCESSOR_POWER_POLICY)); if (ERROR_SUCCESS == dwError) { return TRUE; } else { SetLastError(dwError); return FALSE; } }
/*******************************************************************************
* * MyStrToInt * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
BOOLEAN MyStrToInt(LPCTSTR lpSrc, PINT pi) {
#define ISDIGIT(c) ((c) >= TEXT('0') && (c) <= TEXT('9'))
int n = 0; BOOL bNeg = FALSE;
if (*lpSrc == TEXT('-')) { bNeg = TRUE; lpSrc++; }
if (!ISDIGIT(*lpSrc)) { MYDBGPRINT(( "MyStrToInt, non-integer string: %s", lpSrc)); return FALSE; }
while (ISDIGIT(*lpSrc)) { n *= 10; n += *lpSrc - TEXT('0'); lpSrc++; }
if (bNeg) { *pi = -n; } else { *pi = n; } return TRUE; }
/*******************************************************************************
* * RegistryInit * * DESCRIPTION: * Do DLL load time registry related initialization. * * PARAMETERS: * *******************************************************************************/
BOOLEAN RegistryInit(PUINT puiLastId) { DWORD dwSize; TCHAR szNum[NUM_DEC_DIGITS]; UINT uiCurPwrScheme;
// Read in the last ID this value must be present.
dwSize = sizeof(szNum);
// ReadWritePowerValue will set last error
if (!ReadWritePowerValue(HKEY_LOCAL_MACHINE, c_szREGSTR_PATH_MACHINE_POWERCFG, c_szREGSTR_VAL_LASTID, szNum, &dwSize, FALSE, FALSE) || !MyStrToInt(szNum, &g_uiLastID)) { MYDBGPRINT(( "RegistryInit, Unable to fetch last ID, registry is corrupt")); return FALSE; }
return TRUE; }
#ifdef DEBUG
/*******************************************************************************
* * ReadOptionalDebugSettings * * DESCRIPTION: * Debug only. Get the debug settings from HKCU registry entries into globals. * * PARAMETERS: * *******************************************************************************/
VOID ReadOptionalDebugSettings(VOID) { HKEY hKeyCurrentUser;
if (ERROR_SUCCESS == OpenCurrentUser2(&hKeyCurrentUser,KEY_READ)) { // Optional debug logging of PPM policy validation changes.
ReadPowerIntOptional(hKeyCurrentUser, c_szREGSTR_PATH_USER_POWERCFG, c_szREGSTR_VAL_SHOWVALCHANGES, &g_iShowValidationChanges);
// Optional debug logging of PPM capabilities.
ReadPowerIntOptional(hKeyCurrentUser, c_szREGSTR_PATH_USER_POWERCFG, c_szREGSTR_VAL_SHOWCAPABILITIES, &g_iShowCapabilities);
// Optional debug logging of setting new policy to PPM.
ReadPowerIntOptional(hKeyCurrentUser, c_szREGSTR_PATH_USER_POWERCFG, c_szREGSTR_VAL_SHOWSETPPM, &g_iShowSetPPM);
CloseCurrentUser(hKeyCurrentUser); } } #endif
#ifdef WINNT
/*******************************************************************************
* * InitAdmin * * DESCRIPTION: * For NT only, initialize an administrator power policy which * supports an optional administrative override of certain * power policy settings. The PowerCfg.Cpl and PPM will use these * override values during validation. * * PARAMETERS: * *******************************************************************************/
VOID InitAdmin(PADMINISTRATOR_POWER_POLICY papp) { INT i; NTSTATUS ntsRetVal; HKEY hKeyCurrentUser;
if (ERROR_SUCCESS == OpenCurrentUser2(&hKeyCurrentUser, KEY_READ)) { if (ReadPowerIntOptional(hKeyCurrentUser, c_szREGSTR_PATH_USER_POWERCFG, c_szREGSTR_VAL_ADMINMAXSLEEP, &i)) { g_app.MaxSleep = (SYSTEM_POWER_STATE) i; g_bAdminOverrideActive = TRUE; }
if (ReadPowerIntOptional(hKeyCurrentUser, c_szREGSTR_PATH_USER_POWERCFG, c_szREGSTR_VAL_ADMINMAXVIDEOTIMEOUT, &i)) { g_app.MaxVideoTimeout = i; g_bAdminOverrideActive = TRUE; }
CloseCurrentUser(hKeyCurrentUser); }
// If an administration override was set, call down to the power
// policy manager to set the administrator policy.
if (g_bAdminOverrideActive) { ntsRetVal = CallNtPowerInformation(AdministratorPowerPolicy, &g_app, sizeof(ADMINISTRATOR_POWER_POLICY), &g_app, sizeof(ADMINISTRATOR_POWER_POLICY)); if (ntsRetVal != STATUS_SUCCESS) { MYDBGPRINT(( "DllInitialize, Set AdministratorPowerPolicy failed: 0x%08X", ntsRetVal)); } } } #endif
|