|
|
/*++
Copyright (c) 2001 Microsoft Corporation Module Name: powercfg.c Abstract: Allows users to view and modify power schemes and system power settings from the command line. May be useful in unattended configuration and for headless systems. Author: Ben Hertzberg (t-benher) 1-Jun-2001 Revision History: Ben Hertzberg (t-benher) 15-Jun-2001 - CPU throttle added Ben Hertzberg (t-benher) 4-Jun-2001 - import/export added Ben Hertzberg (t-benher) 1-Jun-2001 - created it. --*/
// standard win includes
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
// app-specific includes
#include <stdio.h>
#include "cmdline.h"
#include "cmdlineres.h"
#include "powrprof.h"
#include "powercfg.h"
#include "resource.h"
// app-specific structures
// structure to manage the scheme list information.
// note that descriptions are currently not visible in the
// GUI tool (as of 6-1-2001), so they are not visible in this
// app either, although the framework is already there if
// someone decides to add the descriptions at a later date.
typedef struct _SCHEME_LIST { LIST_ENTRY le; UINT uiID; LPTSTR lpszName; LPTSTR lpszDesc; PPOWER_POLICY ppp; PMACHINE_PROCESSOR_POWER_POLICY pmppp; } SCHEME_LIST, *PSCHEME_LIST;
// structure to manage the change parameters
typedef struct _CHANGE_PARAM { BOOL bVideoTimeoutAc; ULONG ulVideoTimeoutAc; BOOL bVideoTimeoutDc; ULONG ulVideoTimeoutDc; BOOL bSpindownTimeoutAc; ULONG ulSpindownTimeoutAc; BOOL bSpindownTimeoutDc; ULONG ulSpindownTimeoutDc; BOOL bIdleTimeoutAc; ULONG ulIdleTimeoutAc; BOOL bIdleTimeoutDc; ULONG ulIdleTimeoutDc; BOOL bDozeS4TimeoutAc; ULONG ulDozeS4TimeoutAc; BOOL bDozeS4TimeoutDc; ULONG ulDozeS4TimeoutDc; BOOL bDynamicThrottleAc; LPTSTR lpszDynamicThrottleAc; BOOL bDynamicThrottleDc; LPTSTR lpszDynamicThrottleDc; } CHANGE_PARAM, *PCHANGE_PARAM;
// forward decl's
BOOL DoList();
BOOL DoQuery( LPCTSTR lpszName, BOOL bNameSpecified );
BOOL DoCreate( LPTSTR lpszName );
BOOL DoDelete( LPCTSTR lpszName );
BOOL DoSetActive( LPCTSTR lpszName );
BOOL DoChange( LPCTSTR lpszName, PCHANGE_PARAM pcp );
BOOL DoHibernate( LPCTSTR lpszBoolStr );
BOOL DoExport( LPCTSTR lpszName, LPCTSTR lpszFile );
BOOL DoImport( LPCTSTR lpszName, LPCTSTR lpszFile );
BOOL DoUsage();
// global data
LPCTSTR g_lpszErr = NULL_STRING; // string holding const error description
LPTSTR g_lpszErr2 = NULL; // string holding dyn-alloc error msg
TCHAR g_lpszBuf[256]; // formatting buffer
BOOL g_bHiberFileSupported = FALSE; // true iff hiberfile supported
BOOL g_bHiberTimerSupported = FALSE; // true iff hibertimer supported
BOOL g_bStandbySupported = FALSE; // true iff standby supported
BOOL g_bMonitorPowerSupported = FALSE; // true iff has power support
BOOL g_bDiskPowerSupported = FALSE; // true iff has power support
BOOL g_bThrottleSupported = FALSE; // true iff has throttle support
// functions
DWORD _cdecl _tmain( DWORD argc, LPCTSTR argv[] ) /*++
Routine Description: This routine is the main function. It parses parameters and takes apprpriate action. Arguments: argc - indicates the number of arguments argv - array of null terminated strings indicating arguments. See usage for actual meaning of arguments. Return Value: EXIT_SUCCESS if successful EXIT_FAILURE if something goes wrong --*/ {
// command line flags
BOOL bList = FALSE; BOOL bQuery = FALSE; BOOL bCreate = FALSE; BOOL bDelete = FALSE; BOOL bSetActive = FALSE; BOOL bChange = FALSE; BOOL bHibernate = FALSE; BOOL bImport = FALSE; BOOL bExport = FALSE; BOOL bFile = FALSE; BOOL bUsage = FALSE; // error status
BOOL bFail = FALSE; // dummy
INT iDummy = 1; // parse result value vars
LPTSTR lpszName = NULL; LPTSTR lpszBoolStr = NULL; LPTSTR lpszFile = NULL; LPTSTR lpszThrottleAcStr = NULL; LPTSTR lpszThrottleDcStr = NULL;
CHANGE_PARAM tChangeParam; // parser info struct
TCMDPARSER cmdOptions[NUM_CMDS]; // system power caps struct
SYSTEM_POWER_CAPABILITIES SysPwrCapabilities;
// determine upper bound on input string length
UINT uiMaxInLen = 0; DWORD dwIdx; for(dwIdx=1; dwIdx<argc; dwIdx++) { UINT uiCurLen = lstrlen(argv[dwIdx]); if (uiCurLen > uiMaxInLen) { uiMaxInLen = uiCurLen; } } // allocate space for scheme name and boolean string
lpszName = LocalAlloc(LPTR,(uiMaxInLen+1)*sizeof(TCHAR)); if (!lpszName) { DISPLAY_MESSAGE(stderr,GetResString(IDS_OUT_OF_MEMORY)); return EXIT_FAILURE; } lpszBoolStr = LocalAlloc(LPTR,(uiMaxInLen+1)*sizeof(TCHAR)); if (!lpszBoolStr) { LocalFree(lpszName); DISPLAY_MESSAGE(stderr,GetResString(IDS_OUT_OF_MEMORY)); return EXIT_FAILURE; } if (uiMaxInLen < (UINT)lstrlen(GetResString(IDS_DEFAULT_FILENAME))) { lpszFile = LocalAlloc(LPTR,(lstrlen(GetResString(IDS_DEFAULT_FILENAME))+1)*sizeof(TCHAR)); } else { lpszFile = LocalAlloc(LPTR,(uiMaxInLen+1)*sizeof(TCHAR)); } if (!lpszFile) { LocalFree(lpszName); LocalFree(lpszBoolStr); DISPLAY_MESSAGE(stderr,GetResString(IDS_OUT_OF_MEMORY)); return EXIT_FAILURE; } lpszThrottleAcStr = LocalAlloc(LPTR,(uiMaxInLen+1)*sizeof(TCHAR)); if (!lpszThrottleAcStr) { LocalFree(lpszName); LocalFree(lpszBoolStr); LocalFree(lpszFile); DISPLAY_MESSAGE(stderr,GetResString(IDS_OUT_OF_MEMORY)); return EXIT_FAILURE; } lpszThrottleDcStr = LocalAlloc(LPTR,(uiMaxInLen+1)*sizeof(TCHAR)); if (!lpszThrottleDcStr) { LocalFree(lpszThrottleAcStr); LocalFree(lpszName); LocalFree(lpszBoolStr); LocalFree(lpszFile); DISPLAY_MESSAGE(stderr,GetResString(IDS_OUT_OF_MEMORY)); return EXIT_FAILURE; }
// initialize the allocated strings
lstrcpy(lpszName,NULL_STRING); lstrcpy(lpszBoolStr,NULL_STRING); lstrcpy(lpszFile,GetResString(IDS_DEFAULT_FILENAME)); lstrcpy(lpszThrottleAcStr,NULL_STRING); lstrcpy(lpszThrottleDcStr,NULL_STRING);
// determine system capabilities
if (GetPwrCapabilities(&SysPwrCapabilities)) { g_bHiberFileSupported = SysPwrCapabilities.SystemS4; g_bHiberTimerSupported = (SysPwrCapabilities.RtcWake >= PowerSystemHibernate); g_bStandbySupported = SysPwrCapabilities.SystemS1 | SysPwrCapabilities.SystemS2 | SysPwrCapabilities.SystemS3; g_bDiskPowerSupported = SysPwrCapabilities.DiskSpinDown; g_bThrottleSupported = SysPwrCapabilities.ProcessorThrottle; g_bMonitorPowerSupported = SystemParametersInfo( SPI_GETLOWPOWERACTIVE, 0, &iDummy, 0 ); if (!g_bMonitorPowerSupported ) { g_bMonitorPowerSupported = SystemParametersInfo( SPI_GETPOWEROFFACTIVE, 0, &iDummy, 0 ); } } else { g_lpszErr = GetResString(IDS_UNEXPECTED_ERROR); return EXIT_FAILURE; } //fill in the TCMDPARSER array
// option 'list'
cmdOptions[CMDINDEX_LIST].dwFlags = CP_MAIN_OPTION; cmdOptions[CMDINDEX_LIST].dwCount = 1; cmdOptions[CMDINDEX_LIST].dwActuals = 0; cmdOptions[CMDINDEX_LIST].pValue = &bList; cmdOptions[CMDINDEX_LIST].pFunction = NULL; cmdOptions[CMDINDEX_LIST].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_LIST].szOption, CMDOPTION_LIST ); lstrcpy( cmdOptions[CMDINDEX_LIST].szValues, NULL_STRING ); // option 'query'
cmdOptions[CMDINDEX_QUERY].dwFlags = CP_TYPE_TEXT | CP_VALUE_OPTIONAL | CP_MAIN_OPTION; cmdOptions[CMDINDEX_QUERY].dwCount = 1; cmdOptions[CMDINDEX_QUERY].dwActuals = 0; cmdOptions[CMDINDEX_QUERY].pValue = lpszName; cmdOptions[CMDINDEX_QUERY].pFunction = NULL; cmdOptions[CMDINDEX_QUERY].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_QUERY].szOption, CMDOPTION_QUERY ); lstrcpy( cmdOptions[CMDINDEX_QUERY].szValues, NULL_STRING ); // option 'create'
cmdOptions[CMDINDEX_CREATE].dwFlags = CP_TYPE_TEXT | CP_VALUE_MANDATORY | CP_MAIN_OPTION; cmdOptions[CMDINDEX_CREATE].dwCount = 1; cmdOptions[CMDINDEX_CREATE].dwActuals = 0; cmdOptions[CMDINDEX_CREATE].pValue = lpszName; cmdOptions[CMDINDEX_CREATE].pFunction = NULL; cmdOptions[CMDINDEX_CREATE].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_CREATE].szOption, CMDOPTION_CREATE ); lstrcpy( cmdOptions[CMDINDEX_CREATE].szValues, NULL_STRING ); // option 'delete'
cmdOptions[CMDINDEX_DELETE].dwFlags = CP_TYPE_TEXT | CP_VALUE_MANDATORY | CP_MAIN_OPTION; cmdOptions[CMDINDEX_DELETE].dwCount = 1; cmdOptions[CMDINDEX_DELETE].dwActuals = 0; cmdOptions[CMDINDEX_DELETE].pValue = lpszName; cmdOptions[CMDINDEX_DELETE].pFunction = NULL; cmdOptions[CMDINDEX_DELETE].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_DELETE].szOption, CMDOPTION_DELETE ); lstrcpy( cmdOptions[CMDINDEX_DELETE].szValues, NULL_STRING ); // option 'setactive'
cmdOptions[CMDINDEX_SETACTIVE].dwFlags = CP_TYPE_TEXT | CP_VALUE_MANDATORY | CP_MAIN_OPTION; cmdOptions[CMDINDEX_SETACTIVE].dwCount = 1; cmdOptions[CMDINDEX_SETACTIVE].dwActuals = 0; cmdOptions[CMDINDEX_SETACTIVE].pValue = lpszName; cmdOptions[CMDINDEX_SETACTIVE].pFunction = NULL; cmdOptions[CMDINDEX_SETACTIVE].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_SETACTIVE].szOption, CMDOPTION_SETACTIVE ); lstrcpy( cmdOptions[CMDINDEX_SETACTIVE].szValues, NULL_STRING ); // option 'change'
cmdOptions[CMDINDEX_CHANGE].dwFlags = CP_TYPE_TEXT | CP_VALUE_MANDATORY | CP_MAIN_OPTION; cmdOptions[CMDINDEX_CHANGE].dwCount = 1; cmdOptions[CMDINDEX_CHANGE].dwActuals = 0; cmdOptions[CMDINDEX_CHANGE].pValue = lpszName; cmdOptions[CMDINDEX_CHANGE].pFunction = NULL; cmdOptions[CMDINDEX_CHANGE].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_CHANGE].szOption, CMDOPTION_CHANGE ); lstrcpy( cmdOptions[CMDINDEX_CHANGE].szValues, NULL_STRING ); // option 'hibernate'
cmdOptions[CMDINDEX_HIBERNATE].dwFlags = CP_TYPE_TEXT | CP_VALUE_MANDATORY | CP_MAIN_OPTION; cmdOptions[CMDINDEX_HIBERNATE].dwCount = 1; cmdOptions[CMDINDEX_HIBERNATE].dwActuals = 0; cmdOptions[CMDINDEX_HIBERNATE].pValue = lpszBoolStr; cmdOptions[CMDINDEX_HIBERNATE].pFunction = NULL; cmdOptions[CMDINDEX_HIBERNATE].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_HIBERNATE].szOption, CMDOPTION_HIBERNATE ); lstrcpy( cmdOptions[CMDINDEX_HIBERNATE].szValues, NULL_STRING ); // option 'export'
cmdOptions[CMDINDEX_EXPORT].dwFlags = CP_TYPE_TEXT | CP_VALUE_MANDATORY | CP_MAIN_OPTION; cmdOptions[CMDINDEX_EXPORT].dwCount = 1; cmdOptions[CMDINDEX_EXPORT].dwActuals = 0; cmdOptions[CMDINDEX_EXPORT].pValue = lpszName; cmdOptions[CMDINDEX_EXPORT].pFunction = NULL; cmdOptions[CMDINDEX_EXPORT].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_EXPORT].szOption, CMDOPTION_EXPORT ); lstrcpy( cmdOptions[CMDINDEX_EXPORT].szValues, NULL_STRING );
// option 'import'
cmdOptions[CMDINDEX_IMPORT].dwFlags = CP_TYPE_TEXT | CP_VALUE_MANDATORY | CP_MAIN_OPTION; cmdOptions[CMDINDEX_IMPORT].dwCount = 1; cmdOptions[CMDINDEX_IMPORT].dwActuals = 0; cmdOptions[CMDINDEX_IMPORT].pValue = lpszName; cmdOptions[CMDINDEX_IMPORT].pFunction = NULL; cmdOptions[CMDINDEX_IMPORT].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_IMPORT].szOption, CMDOPTION_IMPORT ); lstrcpy( cmdOptions[CMDINDEX_IMPORT].szValues, NULL_STRING );
// option 'usage'
cmdOptions[CMDINDEX_USAGE].dwFlags = CP_USAGE | CP_MAIN_OPTION; cmdOptions[CMDINDEX_USAGE].dwCount = 1; cmdOptions[CMDINDEX_USAGE].dwActuals = 0; cmdOptions[CMDINDEX_USAGE].pValue = &bUsage; cmdOptions[CMDINDEX_USAGE].pFunction = NULL; cmdOptions[CMDINDEX_USAGE].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_USAGE].szOption, CMDOPTION_USAGE ); lstrcpy( cmdOptions[CMDINDEX_USAGE].szValues, NULL_STRING ); // sub-option 'monitor-timeout-ac'
cmdOptions[CMDINDEX_MONITOR_OFF_AC].dwFlags = CP_TYPE_UNUMERIC | CP_VALUE_MANDATORY; cmdOptions[CMDINDEX_MONITOR_OFF_AC].dwCount = 1; cmdOptions[CMDINDEX_MONITOR_OFF_AC].dwActuals = 0; cmdOptions[CMDINDEX_MONITOR_OFF_AC].pValue = &tChangeParam.ulVideoTimeoutAc; cmdOptions[CMDINDEX_MONITOR_OFF_AC].pFunction = NULL; cmdOptions[CMDINDEX_MONITOR_OFF_AC].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_MONITOR_OFF_AC].szOption, CMDOPTION_MONITOR_OFF_AC ); lstrcpy( cmdOptions[CMDINDEX_MONITOR_OFF_AC].szValues, NULL_STRING ); // sub-option 'monitor-timeout-dc'
cmdOptions[CMDINDEX_MONITOR_OFF_DC].dwFlags = CP_TYPE_UNUMERIC | CP_VALUE_MANDATORY; cmdOptions[CMDINDEX_MONITOR_OFF_DC].dwCount = 1; cmdOptions[CMDINDEX_MONITOR_OFF_DC].dwActuals = 0; cmdOptions[CMDINDEX_MONITOR_OFF_DC].pValue = &tChangeParam.ulVideoTimeoutDc; cmdOptions[CMDINDEX_MONITOR_OFF_DC].pFunction = NULL; cmdOptions[CMDINDEX_MONITOR_OFF_DC].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_MONITOR_OFF_DC].szOption, CMDOPTION_MONITOR_OFF_DC ); lstrcpy( cmdOptions[CMDINDEX_MONITOR_OFF_DC].szValues, NULL_STRING ); // sub-option 'disk-timeout-ac'
cmdOptions[CMDINDEX_DISK_OFF_AC].dwFlags = CP_TYPE_UNUMERIC | CP_VALUE_MANDATORY; cmdOptions[CMDINDEX_DISK_OFF_AC].dwCount = 1; cmdOptions[CMDINDEX_DISK_OFF_AC].dwActuals = 0; cmdOptions[CMDINDEX_DISK_OFF_AC].pValue = &tChangeParam.ulSpindownTimeoutAc; cmdOptions[CMDINDEX_DISK_OFF_AC].pFunction = NULL; cmdOptions[CMDINDEX_DISK_OFF_AC].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_DISK_OFF_AC].szOption, CMDOPTION_DISK_OFF_AC ); lstrcpy( cmdOptions[CMDINDEX_DISK_OFF_AC].szValues, NULL_STRING ); // sub-option 'disk-timeout-dc'
cmdOptions[CMDINDEX_DISK_OFF_DC].dwFlags = CP_TYPE_UNUMERIC | CP_VALUE_MANDATORY; cmdOptions[CMDINDEX_DISK_OFF_DC].dwCount = 1; cmdOptions[CMDINDEX_DISK_OFF_DC].dwActuals = 0; cmdOptions[CMDINDEX_DISK_OFF_DC].pValue = &tChangeParam.ulSpindownTimeoutDc; cmdOptions[CMDINDEX_DISK_OFF_DC].pFunction = NULL; cmdOptions[CMDINDEX_DISK_OFF_DC].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_DISK_OFF_DC].szOption, CMDOPTION_DISK_OFF_DC ); lstrcpy( cmdOptions[CMDINDEX_DISK_OFF_DC].szValues, NULL_STRING ); // sub-option 'standby-timeout-ac'
cmdOptions[CMDINDEX_STANDBY_AC].dwFlags = CP_TYPE_UNUMERIC | CP_VALUE_MANDATORY; cmdOptions[CMDINDEX_STANDBY_AC].dwCount = 1; cmdOptions[CMDINDEX_STANDBY_AC].dwActuals = 0; cmdOptions[CMDINDEX_STANDBY_AC].pValue = &tChangeParam.ulIdleTimeoutAc; cmdOptions[CMDINDEX_STANDBY_AC].pFunction = NULL; cmdOptions[CMDINDEX_STANDBY_AC].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_STANDBY_AC].szOption, CMDOPTION_STANDBY_AC ); lstrcpy( cmdOptions[CMDINDEX_STANDBY_AC].szValues, NULL_STRING ); // sub-option 'standby-timeout-dc'
cmdOptions[CMDINDEX_STANDBY_DC].dwFlags = CP_TYPE_UNUMERIC | CP_VALUE_MANDATORY; cmdOptions[CMDINDEX_STANDBY_DC].dwCount = 1; cmdOptions[CMDINDEX_STANDBY_DC].dwActuals = 0; cmdOptions[CMDINDEX_STANDBY_DC].pValue = &tChangeParam.ulIdleTimeoutDc; cmdOptions[CMDINDEX_STANDBY_DC].pFunction = NULL; cmdOptions[CMDINDEX_STANDBY_DC].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_STANDBY_DC].szOption, CMDOPTION_STANDBY_DC ); lstrcpy( cmdOptions[CMDINDEX_STANDBY_DC].szValues, NULL_STRING ); // sub-option 'hibernate-timeout-ac'
cmdOptions[CMDINDEX_HIBER_AC].dwFlags = CP_TYPE_UNUMERIC | CP_VALUE_MANDATORY; cmdOptions[CMDINDEX_HIBER_AC].dwCount = 1; cmdOptions[CMDINDEX_HIBER_AC].dwActuals = 0; cmdOptions[CMDINDEX_HIBER_AC].pValue = &tChangeParam.ulDozeS4TimeoutAc; cmdOptions[CMDINDEX_HIBER_AC].pFunction = NULL; cmdOptions[CMDINDEX_HIBER_AC].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_HIBER_AC].szOption, CMDOPTION_HIBER_AC ); lstrcpy( cmdOptions[CMDINDEX_HIBER_AC].szValues, NULL_STRING ); // sub-option 'hibernate-timeout-dc'
cmdOptions[CMDINDEX_HIBER_DC].dwFlags = CP_TYPE_UNUMERIC | CP_VALUE_MANDATORY; cmdOptions[CMDINDEX_HIBER_DC].dwCount = 1; cmdOptions[CMDINDEX_HIBER_DC].dwActuals = 0; cmdOptions[CMDINDEX_HIBER_DC].pValue = &tChangeParam.ulDozeS4TimeoutDc; cmdOptions[CMDINDEX_HIBER_DC].pFunction = NULL; cmdOptions[CMDINDEX_HIBER_DC].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_HIBER_DC].szOption, CMDOPTION_HIBER_DC ); lstrcpy( cmdOptions[CMDINDEX_HIBER_DC].szValues, NULL_STRING ); // sub-option 'processor-throttle-ac'
cmdOptions[CMDINDEX_THROTTLE_AC].dwFlags = CP_TYPE_TEXT | CP_VALUE_MANDATORY; cmdOptions[CMDINDEX_THROTTLE_AC].dwCount = 1; cmdOptions[CMDINDEX_THROTTLE_AC].dwActuals = 0; cmdOptions[CMDINDEX_THROTTLE_AC].pValue = lpszThrottleAcStr; cmdOptions[CMDINDEX_THROTTLE_AC].pFunction = NULL; cmdOptions[CMDINDEX_THROTTLE_AC].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_THROTTLE_AC].szOption, CMDOPTION_THROTTLE_AC ); lstrcpy( cmdOptions[CMDINDEX_THROTTLE_AC].szValues, NULL_STRING );
// sub-option 'processor-throttle-dc'
cmdOptions[CMDINDEX_THROTTLE_DC].dwFlags = CP_TYPE_TEXT | CP_VALUE_MANDATORY; cmdOptions[CMDINDEX_THROTTLE_DC].dwCount = 1; cmdOptions[CMDINDEX_THROTTLE_DC].dwActuals = 0; cmdOptions[CMDINDEX_THROTTLE_DC].pValue = lpszThrottleDcStr; cmdOptions[CMDINDEX_THROTTLE_DC].pFunction = NULL; cmdOptions[CMDINDEX_THROTTLE_DC].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_THROTTLE_DC].szOption, CMDOPTION_THROTTLE_DC ); lstrcpy( cmdOptions[CMDINDEX_THROTTLE_DC].szValues, NULL_STRING ); // sub-option 'file'
cmdOptions[CMDINDEX_FILE].dwFlags = CP_TYPE_TEXT | CP_VALUE_MANDATORY; cmdOptions[CMDINDEX_FILE].dwCount = 1; cmdOptions[CMDINDEX_FILE].dwActuals = 0; cmdOptions[CMDINDEX_FILE].pValue = lpszFile; cmdOptions[CMDINDEX_FILE].pFunction = NULL; cmdOptions[CMDINDEX_FILE].pFunctionData = NULL; lstrcpy( cmdOptions[CMDINDEX_FILE].szOption, CMDOPTION_FILE ); lstrcpy( cmdOptions[CMDINDEX_FILE].szValues, NULL_STRING );
// parse parameters, take appropriate action
if(DoParseParam(argc,argv,NUM_CMDS,cmdOptions)) { // make sure only one command issued
DWORD dwCmdCount = 0; DWORD dwParamCount = 0; for(dwIdx=0;dwIdx<NUM_CMDS;dwIdx++) { if (dwIdx < NUM_MAIN_CMDS) { dwCmdCount += cmdOptions[dwIdx].dwActuals; } else { dwParamCount += cmdOptions[dwIdx].dwActuals; } } // determine other flags
bQuery = (cmdOptions[CMDINDEX_QUERY].dwActuals != 0); bCreate = (cmdOptions[CMDINDEX_CREATE].dwActuals != 0); bDelete = (cmdOptions[CMDINDEX_DELETE].dwActuals != 0); bSetActive = (cmdOptions[CMDINDEX_SETACTIVE].dwActuals != 0); bChange = (cmdOptions[CMDINDEX_CHANGE].dwActuals != 0); bHibernate = (cmdOptions[CMDINDEX_HIBERNATE].dwActuals != 0); bExport = (cmdOptions[CMDINDEX_EXPORT].dwActuals != 0); bImport = (cmdOptions[CMDINDEX_IMPORT].dwActuals != 0); bFile = (cmdOptions[CMDINDEX_FILE].dwActuals != 0); tChangeParam.bVideoTimeoutAc = (cmdOptions[CMDINDEX_MONITOR_OFF_AC].dwActuals != 0); tChangeParam.bVideoTimeoutDc = (cmdOptions[CMDINDEX_MONITOR_OFF_DC].dwActuals != 0); tChangeParam.bSpindownTimeoutAc = (cmdOptions[CMDINDEX_DISK_OFF_AC].dwActuals != 0); tChangeParam.bSpindownTimeoutDc = (cmdOptions[CMDINDEX_DISK_OFF_DC].dwActuals != 0); tChangeParam.bIdleTimeoutAc = (cmdOptions[CMDINDEX_STANDBY_AC].dwActuals != 0); tChangeParam.bIdleTimeoutDc = (cmdOptions[CMDINDEX_STANDBY_DC].dwActuals != 0); tChangeParam.bDozeS4TimeoutAc = (cmdOptions[CMDINDEX_HIBER_AC].dwActuals != 0); tChangeParam.bDozeS4TimeoutDc = (cmdOptions[CMDINDEX_HIBER_DC].dwActuals != 0); tChangeParam.bDynamicThrottleAc = (cmdOptions[CMDINDEX_THROTTLE_AC].dwActuals != 0); tChangeParam.bDynamicThrottleDc = (cmdOptions[CMDINDEX_THROTTLE_DC].dwActuals != 0); tChangeParam.lpszDynamicThrottleAc = lpszThrottleAcStr; tChangeParam.lpszDynamicThrottleDc = lpszThrottleDcStr;
if ((dwCmdCount == 1) && ((dwParamCount == 0) || (bChange && (dwParamCount > 0) && (!bFile)) || ((bImport || bExport) && bFile && (dwParamCount == 1)))) { // check flags, take appropriate action
if(bList) { DoList(); } else if (bQuery) { bFail = !DoQuery(lpszName,(lstrlen(lpszName) != 0)); } else if (bCreate) { bFail = !DoCreate(lpszName); } else if (bDelete) { bFail = !DoDelete(lpszName); } else if (bSetActive) { bFail = !DoSetActive(lpszName); } else if (bChange) { bFail = !DoChange(lpszName,&tChangeParam); } else if (bHibernate) { bFail = !DoHibernate(lpszBoolStr); } else if (bExport) { bFail = !DoExport(lpszName,lpszFile); } else if (bImport) { bFail = !DoImport(lpszName,lpszFile); } else if (bUsage) { DoUsage(); } else { if(lstrlen(g_lpszErr) == 0) g_lpszErr = GetResString(IDS_INVALID_CMDLINE_PARAM); bFail = TRUE; } } else { // handle error conditions
if(lstrlen(g_lpszErr) == 0) { g_lpszErr = GetResString(IDS_INVALID_CMDLINE_PARAM); } bFail = TRUE; } } else { g_lpszErr = GetResString(IDS_INVALID_CMDLINE_PARAM); bFail = TRUE; } // check error status, display msg if needed
if(bFail) { if(g_lpszErr2) { DISPLAY_MESSAGE(stderr,g_lpszErr2); } else { DISPLAY_MESSAGE(stderr,g_lpszErr); } }
// clean up allocs
LocalFree(lpszBoolStr); LocalFree(lpszName); LocalFree(lpszFile); LocalFree(lpszThrottleAcStr); LocalFree(lpszThrottleDcStr); if (g_lpszErr2) { LocalFree(g_lpszErr2); } // return appropriate result code
if(bFail) { return EXIT_FAILURE; } else { return EXIT_SUCCESS; } }
BOOL FreeScheme( PSCHEME_LIST psl ) /*++
Routine Description: Frees the memory associated with a scheme list entry. Arguments: psl - the PSCHEME_LIST to be freed Return Value:
Always returns TRUE, indicating success. --*/ { LocalFree(psl->lpszName); LocalFree(psl->lpszDesc); LocalFree(psl->ppp); LocalFree(psl->pmppp); LocalFree(psl); return TRUE; }
BOOL FreeSchemeList( PSCHEME_LIST psl, PSCHEME_LIST pslExcept ) /*++
Routine Description: Deallocates all power schemes in a linked-list of power schemes, except for the one pointed to by pslExcept Arguments: psl - the power scheme list to deallocate pslExcept - a scheme not to deallocate (null to deallocate all) Return Value: Always returns TRUE, indicating success. --*/ { PSCHEME_LIST cur = psl; PSCHEME_LIST next; while (cur != NULL) { next = CONTAINING_RECORD( cur->le.Flink, SCHEME_LIST, le ); if (cur != pslExcept) { FreeScheme(cur); } else { cur->le.Flink = NULL; cur->le.Blink = NULL; } cur = next; } return TRUE; }
PSCHEME_LIST CreateScheme( UINT uiID, DWORD dwNameSize, LPCTSTR lpszName, DWORD dwDescSize, LPCTSTR lpszDesc, PPOWER_POLICY ppp ) /*++
Routine Description: Builds a policy list entry. Note that the scheme is allocated and must be freed when done. Arguments: uiID - the numerical ID of the scheme dwNameSize - the number of bytes needed to store lpszName lpszName - the name of the scheme dwDescSize - the number of bytes needed to store lpszDesc lpszDesc - the description of the scheme ppp - the power policy for this scheme, may be NULL Return Value: A PSCHEME_LIST entry containing the specified values, with the next entry field set to NULL --*/ { PSCHEME_LIST psl = (PSCHEME_LIST)LocalAlloc(LPTR,sizeof(SCHEME_LIST)); if (psl) { // deal with potentially null input strings
if(lpszName == NULL) { lpszName = NULL_STRING; } if(lpszDesc == NULL) { lpszDesc = NULL_STRING; }
// allocate fields
psl->ppp = (PPOWER_POLICY)LocalAlloc(LPTR,sizeof(POWER_POLICY)); if (!psl->ppp) { g_lpszErr = GetResString(IDS_OUT_OF_MEMORY); return NULL; } psl->pmppp = (PMACHINE_PROCESSOR_POWER_POLICY)LocalAlloc( LPTR, sizeof(MACHINE_PROCESSOR_POWER_POLICY) ); if (!psl->pmppp) { LocalFree(psl->ppp); g_lpszErr = GetResString(IDS_OUT_OF_MEMORY); return NULL; } psl->lpszName = (LPTSTR)LocalAlloc(LPTR,dwNameSize); if (!psl->lpszName) { LocalFree(psl->ppp); LocalFree(psl->pmppp); g_lpszErr = GetResString(IDS_OUT_OF_MEMORY); return NULL; } psl->lpszDesc = (LPTSTR)LocalAlloc(LPTR,dwDescSize); if (!psl->lpszDesc) { LocalFree(psl->ppp); LocalFree(psl->pmppp); LocalFree(psl->lpszName); g_lpszErr = GetResString(IDS_OUT_OF_MEMORY); return NULL; } // initialize structure
psl->uiID = uiID; memcpy(psl->lpszName,lpszName,dwNameSize); memcpy(psl->lpszDesc,lpszDesc,dwDescSize); if (ppp) { memcpy(psl->ppp,ppp,sizeof(POWER_POLICY)); } psl->le.Flink = NULL; psl->le.Blink = NULL;
} else { g_lpszErr = GetResString(IDS_OUT_OF_MEMORY); } return psl; }
BOOLEAN CALLBACK PowerSchemeEnumProc( UINT uiID, DWORD dwNameSize, LPTSTR lpszName, DWORD dwDescSize, LPTSTR lpszDesc, PPOWER_POLICY ppp, LPARAM lParam ) /*++
Routine Description: This is a callback used in retrieving the policy list. Arguments: uiID - the numerical ID of the scheme dwNameSize - the number of bytes needed to store lpszName lpszName - the name of the scheme dwDescSize - the number of bytes needed to store lpszDesc lpszDesc - the description of the scheme ppp - the power policy for this scheme lParam - used to hold a pointer to the head-of-list pointer, allowing for insertions at the head of the list Return Value: TRUE to continue enumeration FALSE to abort enumeration --*/ { PSCHEME_LIST psl; // Allocate and initalize a policies element.
if ((psl = CreateScheme( uiID, dwNameSize, lpszName, dwDescSize, lpszDesc, ppp )) != NULL) { // add the element to the head of the linked list
psl->le.Flink = *((PLIST_ENTRY *)lParam); if(*((PLIST_ENTRY *)lParam)) { (*((PLIST_ENTRY *)lParam))->Blink = &(psl->le); } (*(PLIST_ENTRY *)lParam) = &(psl->le); return TRUE; } return FALSE; }
PSCHEME_LIST CreateSchemeList() /*++
Routine Description: Creates a linked list of existing power schemes. Arguments: None Return Value: A pointer to the head of the list. NULL would correspond to an empty list. --*/ { PLIST_ENTRY ple = NULL; PSCHEME_LIST psl; EnumPwrSchemes(PowerSchemeEnumProc, (LPARAM)(&ple)); if(ple) { PSCHEME_LIST res = CONTAINING_RECORD( ple, SCHEME_LIST, le ); psl = res; while(psl != NULL) { if(!ReadProcessorPwrScheme(psl->uiID,psl->pmppp)) { FreeSchemeList(res,NULL); g_lpszErr = GetResString(IDS_UNEXPECTED_ERROR); return NULL; } psl = CONTAINING_RECORD( psl->le.Flink, SCHEME_LIST, le); } return res; } else { return NULL; } }
PSCHEME_LIST FindScheme( LPCTSTR lpszName, UINT uiID ) /*++
Routine Description: Finds the policy with the matching name Arguments: lpszName - the name of the scheme to find Return Value: the matching scheme list entry, null if none --*/ { PSCHEME_LIST psl = CreateSchemeList(); PSCHEME_LIST pslRes = NULL; // find scheme entry
while(psl != NULL) { // check for match
if (((lpszName != NULL) && (!lstrcmpi(lpszName, psl->lpszName))) || ((lpszName == NULL) && (uiID == psl->uiID))) { pslRes = psl; break; } // traverse list
psl = CONTAINING_RECORD( psl->le.Flink, SCHEME_LIST, le ); } FreeSchemeList(psl,pslRes); // all except for pslRes
if (pslRes == NULL) g_lpszErr = GetResString(IDS_SCHEME_NOT_FOUND); return pslRes; }
BOOL MyWriteScheme( PSCHEME_LIST psl ) /*++
Routine Description: Writes a power scheme -- both user/machine power policies and processor power policy. The underlying powrprof.dll does not treat the processor power policy as part of the power policy because the processor power policies were added at a later date and backwards compatibility must be maintained. Arguments: psl - The scheme list entry to write Return Value: TRUE if successful, otherwise FALSE --*/ { g_lpszErr = GetResString(IDS_UNEXPECTED_ERROR); if(WritePwrScheme( &psl->uiID, psl->lpszName, psl->lpszDesc, psl->ppp)) { return WriteProcessorPwrScheme( psl->uiID, psl->pmppp ); } else { return FALSE; } }
BOOL MapIdleValue( ULONG ulVal, PULONG pulIdle, PULONG pulHiber, PPOWER_ACTION ppapIdle ) /*++
Routine Description: Modifies Idle and Hibernation settings to reflect the desired idle timeout. See GUI tool's PWRSCHEM.C MapHiberTimer for logic. Arguments: ulVal - the new idle timeout pulIdle - the idle timeout variable to be updated pulHiber - the hiber timeout variable to be updated Return Value: TRUE if successful FALSE if failed --*/ { // if previously, hiber was enabled and standby wasn't, standby timer
// takes over the hibernation timer's role
if (*ppapIdle == PowerActionHibernate) { if (ulVal > 0) { // enable standby
*pulHiber = *pulIdle + ulVal; *pulIdle = ulVal; *ppapIdle = PowerActionSleep; } else { // standby already disabled, no change
} } else // standby timer actually being used for standby (not hiber)
{ if (ulVal > 0) { // enable standby
if ((*pulHiber) != 0) { *pulHiber = *pulHiber + ulVal - *pulIdle; } *pulIdle = ulVal; if (ulVal > 0) { *ppapIdle = PowerActionSleep; } else { *ppapIdle = PowerActionNone; } } else { // disable standby
if ((*pulHiber) != 0) { *pulIdle = *pulHiber; *pulHiber = 0; *ppapIdle = PowerActionHibernate; } else { *pulIdle = 0; *ppapIdle = PowerActionNone; } } } return TRUE; }
BOOL MapHiberValue( ULONG ulVal, PULONG pulIdle, PULONG pulHiber, PPOWER_ACTION ppapIdle ) /*++
Routine Description: Modifies Idle and Hibernation settings to reflect the desired hibernation timeout. See GUI tool's PWRSCHEM.C MapHiberTimer for logic. Arguments: ulVal - the new hibernation timeout pulIdle - the idle timeout variable to be updated pulHiber - the hiber timeout variable to be updated Return Value: TRUE if successful FALSE if failed --*/
{ // check valid input
if (ulVal < (*pulIdle)) { g_lpszErr = GetResString(IDS_HIBER_OUT_OF_RANGE); return FALSE; }
// check for disable-hibernation
if (ulVal == 0) { if (((*ppapIdle) == PowerActionHibernate) || (!g_bStandbySupported)) { *pulIdle = 0; *pulHiber = 0; *ppapIdle = PowerActionNone; } else { *pulHiber = 0; if ((*pulIdle) == 0) { *ppapIdle = PowerActionNone; } else { *ppapIdle = PowerActionSleep; } } } else // enabled hibernation
{ if (((*ppapIdle) == PowerActionHibernate) || (!g_bStandbySupported)) { *pulHiber = 0; *pulIdle = ulVal; *ppapIdle = PowerActionHibernate; } else { *pulHiber = *pulHiber + ulVal - *pulIdle; *ppapIdle = PowerActionSleep; } } return TRUE; }
BOOL DoList() /*++
Routine Description: Lists the existing power schemes on stdout Arguments: none Return Value: TRUE if successful FALSE if failed --*/ { PSCHEME_LIST psl = CreateSchemeList(); if (psl != NULL) { DISPLAY_MESSAGE(stdout,GetResString(IDS_LIST_HEADER1)); DISPLAY_MESSAGE(stdout,GetResString(IDS_LIST_HEADER2)); } else { return FALSE; } while(psl != NULL) { DISPLAY_MESSAGE(stdout, psl->lpszName); DISPLAY_MESSAGE(stdout, L"\n"); psl = CONTAINING_RECORD( psl->le.Flink, SCHEME_LIST, le ); } FreeSchemeList(psl,NULL); // free all entries
return TRUE; }
BOOL DoQuery( LPCTSTR lpszName, BOOL bNameSpecified ) /*++
Routine Description: Show details of an existing scheme Arguments: lpszName - the name of the scheme Return Value: TRUE if successful FALSE if failed --*/ { PSCHEME_LIST psl;
// check if querying specific scheme or active scheme and deal w/it
if (bNameSpecified) { psl = FindScheme(lpszName,0); } else // fetch the active scheme
{ POWER_POLICY pp; UINT uiID; if (GetActivePwrScheme(&uiID)) { psl = FindScheme(NULL,uiID); } else { g_lpszErr = GetResString(IDS_ACTIVE_SCHEME_INVALID); return FALSE; } } // display info
if (psl) { // header
DISPLAY_MESSAGE(stdout, GetResString(IDS_QUERY_HEADER1)); DISPLAY_MESSAGE(stdout, GetResString(IDS_QUERY_HEADER2)); // name
DISPLAY_MESSAGE1( stdout, g_lpszBuf, GetResString(IDS_SCHEME_NAME), psl->lpszName ); // monitor timeout AC
DISPLAY_MESSAGE(stdout, GetResString(IDS_MONITOR_TIMEOUT_AC)); if (!g_bMonitorPowerSupported) { DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED)); } else if (psl->ppp->user.VideoTimeoutAc == 0) { DISPLAY_MESSAGE(stdout, GetResString(IDS_DISABLED)); } else { DISPLAY_MESSAGE1( stdout, g_lpszBuf, GetResString(IDS_MINUTES), psl->ppp->user.VideoTimeoutAc/60 ); }
// monitor timeout DC
DISPLAY_MESSAGE(stdout, GetResString(IDS_MONITOR_TIMEOUT_DC)); if (!g_bMonitorPowerSupported) { DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED)); } else if (psl->ppp->user.VideoTimeoutDc == 0) { DISPLAY_MESSAGE(stdout, GetResString(IDS_DISABLED)); } else { DISPLAY_MESSAGE1( stdout, g_lpszBuf, GetResString(IDS_MINUTES), psl->ppp->user.VideoTimeoutDc/60 ); }
// disk timeout AC
DISPLAY_MESSAGE(stdout, GetResString(IDS_DISK_TIMEOUT_AC)); if (!g_bDiskPowerSupported) { DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED)); } else if (psl->ppp->user.SpindownTimeoutAc == 0) { DISPLAY_MESSAGE(stdout, GetResString(IDS_DISABLED)); } else { DISPLAY_MESSAGE1( stdout, g_lpszBuf, GetResString(IDS_MINUTES), psl->ppp->user.SpindownTimeoutAc/60 ); } // disk timeout DC
DISPLAY_MESSAGE(stdout, GetResString(IDS_DISK_TIMEOUT_DC)); if (!g_bDiskPowerSupported) { DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED)); } else if (psl->ppp->user.SpindownTimeoutDc == 0) { DISPLAY_MESSAGE(stdout, GetResString(IDS_DISABLED)); } else { DISPLAY_MESSAGE1( stdout, g_lpszBuf, GetResString(IDS_MINUTES), psl->ppp->user.SpindownTimeoutDc/60 ); }
// standby timeout AC
DISPLAY_MESSAGE(stdout, GetResString(IDS_STANDBY_TIMEOUT_AC)); if (!g_bStandbySupported) { DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED)); } else if (psl->ppp->user.IdleAc.Action != PowerActionSleep) { DISPLAY_MESSAGE(stdout, GetResString(IDS_DISABLED)); } else { DISPLAY_MESSAGE1( stdout, g_lpszBuf, GetResString(IDS_MINUTES), psl->ppp->user.IdleTimeoutAc/60 ); }
// standby timeout DC
DISPLAY_MESSAGE(stdout, GetResString(IDS_STANDBY_TIMEOUT_DC)); if (!g_bStandbySupported) { DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED)); } else if (psl->ppp->user.IdleDc.Action != PowerActionSleep) { DISPLAY_MESSAGE(stdout, GetResString(IDS_DISABLED)); } else { DISPLAY_MESSAGE1( stdout, g_lpszBuf, GetResString(IDS_MINUTES), psl->ppp->user.IdleTimeoutDc/60 ); }
// hibernate timeout AC
DISPLAY_MESSAGE(stdout, GetResString(IDS_HIBER_TIMEOUT_AC)); if (!g_bHiberTimerSupported) { DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED)); } else if ((psl->ppp->mach.DozeS4TimeoutAc == 0) && ((psl->ppp->user.IdleAc.Action != PowerActionHibernate) || (psl->ppp->user.IdleTimeoutAc == 0))) { DISPLAY_MESSAGE(stdout, GetResString(IDS_DISABLED)); } else { DISPLAY_MESSAGE1( stdout, g_lpszBuf, GetResString(IDS_MINUTES), (psl->ppp->mach.DozeS4TimeoutAc + psl->ppp->user.IdleTimeoutAc)/60 ); }
// hibernate timeout DC
DISPLAY_MESSAGE(stdout, GetResString(IDS_HIBER_TIMEOUT_DC)); if (!g_bHiberTimerSupported) { DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED)); } else if ((psl->ppp->mach.DozeS4TimeoutDc == 0) && ((psl->ppp->user.IdleDc.Action != PowerActionHibernate) || (psl->ppp->user.IdleTimeoutDc == 0))) { DISPLAY_MESSAGE(stdout, GetResString(IDS_DISABLED)); } else { DISPLAY_MESSAGE1( stdout, g_lpszBuf, GetResString(IDS_MINUTES), (psl->ppp->mach.DozeS4TimeoutDc + psl->ppp->user.IdleTimeoutDc)/60 ); }
// throttle policy AC
DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_AC)); if (!g_bThrottleSupported) { DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED)); } else { switch(psl->pmppp->ProcessorPolicyAc.DynamicThrottle) { case PO_THROTTLE_NONE: DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_NONE)); break; case PO_THROTTLE_CONSTANT: DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_CONSTANT)); break; case PO_THROTTLE_DEGRADE: DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_DEGRADE)); break; case PO_THROTTLE_ADAPTIVE: DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_ADAPTIVE)); break; default: DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_UNKNOWN)); break; } }
// throttle policy DC
DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_DC)); if (!g_bThrottleSupported) { DISPLAY_MESSAGE(stdout, GetResString(IDS_UNSUPPORTED)); } else { switch(psl->pmppp->ProcessorPolicyDc.DynamicThrottle) { case PO_THROTTLE_NONE: DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_NONE)); break; case PO_THROTTLE_CONSTANT: DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_CONSTANT)); break; case PO_THROTTLE_DEGRADE: DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_DEGRADE)); break; case PO_THROTTLE_ADAPTIVE: DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_ADAPTIVE)); break; default: DISPLAY_MESSAGE(stdout, GetResString(IDS_THROTTLE_UNKNOWN)); break; } }
FreeScheme(psl); return TRUE; } else { return FALSE; } }
BOOL DoCreate( LPTSTR lpszName ) /*++
Routine Description: Adds a new power scheme The description will match the name All other details are copied from the active power scheme Fails if scheme already exists Arguments: lpszName - the name of the scheme Return Value: TRUE if successful FALSE if failed --*/ { PSCHEME_LIST psl = FindScheme(lpszName,0); UINT uiID; POWER_POLICY pp; BOOL bRes; LPTSTR lpszNewName; LPTSTR lpszNewDesc; if(psl) // already existed -> fail
{ FreeScheme(psl); g_lpszErr = GetResString(IDS_SCHEME_ALREADY_EXISTS); return FALSE; } // create a new scheme
if(GetActivePwrScheme(&uiID)) { psl = FindScheme(NULL,uiID); if(!psl) { g_lpszErr = GetResString(IDS_SCHEME_CREATE_FAIL); return FALSE; } lpszNewName = LocalAlloc(LPTR,(lstrlen(lpszName)+1)*sizeof(TCHAR)); if(!lpszNewName) { FreeScheme(psl); g_lpszErr = GetResString(IDS_OUT_OF_MEMORY); return FALSE; } lpszNewDesc = LocalAlloc(LPTR,(lstrlen(lpszName)+1)*sizeof(TCHAR)); if(!lpszNewDesc) { LocalFree(lpszNewName); FreeScheme(psl); g_lpszErr = GetResString(IDS_OUT_OF_MEMORY); return FALSE; } lstrcpy(lpszNewName,lpszName); lstrcpy(lpszNewDesc,lpszName); LocalFree(psl->lpszName); LocalFree(psl->lpszDesc); psl->lpszName = lpszNewName; psl->lpszDesc = lpszNewDesc; psl->uiID = NEWSCHEME; g_lpszErr = GetResString(IDS_UNEXPECTED_ERROR); bRes = MyWriteScheme(psl); FreeScheme(psl); return bRes; } g_lpszErr = GetResString(IDS_SCHEME_CREATE_FAIL); return FALSE; }
BOOL DoDelete( LPCTSTR lpszName ) /*++
Routine Description: Deletes an existing scheme Arguments: lpszName - the name of the scheme Return Value: TRUE if successful FALSE if failed --*/ { PSCHEME_LIST psl = FindScheme(lpszName,0); if (psl) { BOOL bRes = DeletePwrScheme(psl->uiID); FreeScheme(psl); g_lpszErr = GetResString(IDS_UNEXPECTED_ERROR); return bRes; } else { return FALSE; } }
BOOL DoSetActive( LPCTSTR lpszName ) /*++
Routine Description: Sets the active scheme Arguments: lpszName - the name of the scheme Return Value: TRUE if successful FALSE if failed --*/ { PSCHEME_LIST psl = FindScheme(lpszName,0); if (psl) { BOOL bRes = SetActivePwrScheme( psl->uiID, NULL, NULL ); FreeScheme(psl); g_lpszErr = GetResString(IDS_UNEXPECTED_ERROR); return bRes; } else { return FALSE; } }
BOOL DoChange( LPCTSTR lpszName, PCHANGE_PARAM pcp ) /*++
Routine Description: Modifies an existing scheme Arguments: lpszName - the name of the scheme pcp - PCHANGE_PARAM pointing to the parameter structure, indicates which variable(s) to change Return Value: TRUE if successful FALSE if failed --*/ { BOOL bRes = TRUE; PSCHEME_LIST psl = FindScheme(lpszName,0); if (psl) { // check for feature support
if ((pcp->bIdleTimeoutAc || pcp->bIdleTimeoutDc) && !g_bStandbySupported) { DISPLAY_MESSAGE(stderr, GetResString(IDS_STANDBY_WARNING)); } if ((pcp->bDozeS4TimeoutAc || pcp->bDozeS4TimeoutDc) && !g_bHiberTimerSupported) { DISPLAY_MESSAGE(stderr, GetResString(IDS_HIBER_WARNING)); } if ((pcp->bVideoTimeoutAc || pcp->bVideoTimeoutDc) && !g_bMonitorPowerSupported) { DISPLAY_MESSAGE(stderr, GetResString(IDS_MONITOR_WARNING)); } if ((pcp->bSpindownTimeoutAc || pcp->bSpindownTimeoutDc) && !g_bDiskPowerSupported) { DISPLAY_MESSAGE(stderr, GetResString(IDS_DISK_WARNING)); }
// change params
if (pcp->bVideoTimeoutAc) { psl->ppp->user.VideoTimeoutAc = pcp->ulVideoTimeoutAc*60; } if (pcp->bVideoTimeoutDc) { psl->ppp->user.VideoTimeoutDc = pcp->ulVideoTimeoutDc*60; } if (pcp->bSpindownTimeoutAc) { psl->ppp->user.SpindownTimeoutAc = pcp->ulSpindownTimeoutAc*60; } if (pcp->bSpindownTimeoutDc) { psl->ppp->user.SpindownTimeoutDc = pcp->ulSpindownTimeoutDc*60; } if (pcp->bIdleTimeoutAc) { bRes = bRes & MapIdleValue( pcp->ulIdleTimeoutAc*60, &psl->ppp->user.IdleTimeoutAc, &psl->ppp->mach.DozeS4TimeoutAc, &psl->ppp->user.IdleAc.Action ); } if (pcp->bIdleTimeoutDc) { bRes = bRes & MapIdleValue( pcp->ulIdleTimeoutDc*60, &psl->ppp->user.IdleTimeoutDc, &psl->ppp->mach.DozeS4TimeoutDc, &psl->ppp->user.IdleDc.Action ); } if (pcp->bDozeS4TimeoutAc) { bRes = bRes & MapHiberValue( pcp->ulDozeS4TimeoutAc*60, &psl->ppp->user.IdleTimeoutAc, &psl->ppp->mach.DozeS4TimeoutAc, &psl->ppp->user.IdleAc.Action ); } if (pcp->bDozeS4TimeoutDc) { bRes = bRes & MapHiberValue( pcp->ulDozeS4TimeoutDc*60, &psl->ppp->user.IdleTimeoutDc, &psl->ppp->mach.DozeS4TimeoutDc, &psl->ppp->user.IdleDc.Action ); } if (pcp->bDynamicThrottleAc) { if(lstrcmpi( pcp->lpszDynamicThrottleAc, _T("NONE") ) == 0) { psl->pmppp->ProcessorPolicyAc.DynamicThrottle = PO_THROTTLE_NONE; } else if(lstrcmpi( pcp->lpszDynamicThrottleAc, _T("CONSTANT") ) == 0) { psl->pmppp->ProcessorPolicyAc.DynamicThrottle = PO_THROTTLE_CONSTANT; } else if(lstrcmpi( pcp->lpszDynamicThrottleAc, _T("DEGRADE") ) == 0) { psl->pmppp->ProcessorPolicyAc.DynamicThrottle = PO_THROTTLE_DEGRADE; } else if(lstrcmpi( pcp->lpszDynamicThrottleAc, _T("ADAPTIVE") ) == 0) { psl->pmppp->ProcessorPolicyAc.DynamicThrottle = PO_THROTTLE_ADAPTIVE; } else { g_lpszErr = GetResString(IDS_INVALID_CMDLINE_PARAM); bRes = FALSE; } } if (pcp->bDynamicThrottleDc) {
if(lstrcmpi( pcp->lpszDynamicThrottleDc, _T("NONE") ) == 0) { psl->pmppp->ProcessorPolicyDc.DynamicThrottle = PO_THROTTLE_NONE; } else if(lstrcmpi( pcp->lpszDynamicThrottleDc, _T("CONSTANT") ) == 0) { psl->pmppp->ProcessorPolicyDc.DynamicThrottle = PO_THROTTLE_CONSTANT; } else if(lstrcmpi( pcp->lpszDynamicThrottleDc, _T("DEGRADE") ) == 0) { psl->pmppp->ProcessorPolicyDc.DynamicThrottle = PO_THROTTLE_DEGRADE; } else if(lstrcmpi( pcp->lpszDynamicThrottleDc, _T("ADAPTIVE") ) == 0) { psl->pmppp->ProcessorPolicyDc.DynamicThrottle = PO_THROTTLE_ADAPTIVE; } else { g_lpszErr = GetResString(IDS_INVALID_CMDLINE_PARAM); bRes = FALSE; } }
if (bRes) { // attempt to update power scheme
g_lpszErr = GetResString(IDS_UNEXPECTED_ERROR); bRes = MyWriteScheme(psl); // keep active power scheme consistent
if (bRes) { UINT uiIDactive;
if (GetActivePwrScheme(&uiIDactive) && (psl->uiID == uiIDactive)) { bRes = SetActivePwrScheme(psl->uiID,NULL,NULL); } }
FreeScheme(psl); return bRes; } else { return FALSE; } } else { return FALSE; } }
BOOL DoExport( LPCTSTR lpszName, LPCTSTR lpszFile ) /*++
Routine Description: Exports a power scheme Arguments: lpszName - the name of the scheme lpszFile - the file to hold the scheme Return Value: TRUE if successful FALSE if failed --*/ { DWORD res; // write result value
HANDLE f; // file handle
// find scheme
PSCHEME_LIST psl = FindScheme(lpszName,0); if(!psl) { return FALSE; }
// write to file
f = CreateFile( lpszFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if (f == INVALID_HANDLE_VALUE) { FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&g_lpszErr2, 0, NULL ); FreeScheme(psl); return FALSE; } if (!WriteFile( f, psl->ppp, sizeof(POWER_POLICY), &res, NULL )) { FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&g_lpszErr2, 0, NULL ); CloseHandle(f); FreeScheme(psl); return FALSE; } if (!WriteFile( f, psl->pmppp, sizeof(MACHINE_PROCESSOR_POWER_POLICY), &res, NULL )) { FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&g_lpszErr2, 0, NULL ); CloseHandle(f); FreeScheme(psl); return FALSE; } CloseHandle(f); FreeScheme(psl); return TRUE; }
BOOL DoImport( LPCTSTR lpszName, LPCTSTR lpszFile ) /*++
Routine Description: Imports a power scheme If the scheme already exists, overwrites it Arguments: lpszName - the name of the scheme lpszFile - the file that holds the scheme Return Value: TRUE if successful FALSE if failed --*/ { DWORD res; // write result value
HANDLE f; // file handle
UINT uiIDactive; // active ID
PSCHEME_LIST psl; // check for pre-existing scheme
psl = FindScheme(lpszName,0);
// if didn't exist, create it
if (!psl) { psl = CreateScheme( NEWSCHEME, (lstrlen(lpszName)+1)*sizeof(TCHAR), lpszName, (lstrlen(lpszName)+1)*sizeof(TCHAR), lpszName, NULL // psl->ppp will be allocated but uninitialized
); // check for successful alloc
if(!psl) { return FALSE; } }
// open file
f = CreateFile( lpszFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (f == INVALID_HANDLE_VALUE) { FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&g_lpszErr2, 0, NULL ); FreeScheme(psl); return FALSE; }
// read scheme
if (!ReadFile( f, psl->ppp, sizeof(POWER_POLICY), &res, NULL )) { FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&g_lpszErr2, 0, NULL ); CloseHandle(f); FreeScheme(psl); return FALSE; } if (!ReadFile( f, psl->pmppp, sizeof(MACHINE_PROCESSOR_POWER_POLICY), &res, NULL )) { FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&g_lpszErr2, 0, NULL ); CloseHandle(f); FreeScheme(psl); return FALSE; }
CloseHandle(f); g_lpszErr = GetResString(IDS_UNEXPECTED_ERROR);
// save scheme
if (!MyWriteScheme(psl)) { FreeScheme(psl); return FALSE; }
// check against active scheme
if (!GetActivePwrScheme(&uiIDactive)) { return FALSE; } if (uiIDactive == psl->uiID) { if (!SetActivePwrScheme(psl->uiID,NULL,NULL)) { return FALSE; } } FreeScheme(psl); return TRUE; }
BOOL DoHibernate( LPCTSTR lpszBoolStr ) /*++
Routine Description: Enables/Disables hibernation
NOTE: this functionality pretty much taken verbatim from the test program "base\ntos\po\tests\ehib\ehib.c" Arguments: lpszBoolStr - "on" or "off" Return Value: TRUE if successful FALSE if failed --*/ { BOOLEAN bEnable; // doesn't work with a BOOL, apparently
NTSTATUS Status; HANDLE hToken; TOKEN_PRIVILEGES tkp; // adjust privilege to allow hiber enable/disable
if( NT_SUCCESS( OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ))) { if( NT_SUCCESS( LookupPrivilegeValue( NULL, SE_CREATE_PAGEFILE_NAME, &tkp.Privileges[0].Luid ))) { tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if ( !NT_SUCCESS( AdjustTokenPrivileges( hToken, FALSE, &tkp, 0, NULL, 0 ))) { g_lpszErr = GetResString(IDS_HIBER_PRIVILEGE); return FALSE; }
} else { g_lpszErr = GetResString(IDS_HIBER_PRIVILEGE); return FALSE; } } else { g_lpszErr = GetResString(IDS_HIBER_PRIVILEGE); return FALSE; } // parse enable/disable state
if (!lstrcmpi(lpszBoolStr,GetResString(IDS_ON))) { bEnable = TRUE; } else if (!lstrcmpi(lpszBoolStr,GetResString(IDS_OFF))) { bEnable = FALSE; } else { g_lpszErr = GetResString(IDS_HIBER_INVALID_STATE); return FALSE; } // enable/disable hibernation
if (!g_bHiberFileSupported) { g_lpszErr = GetResString(IDS_HIBER_UNSUPPORTED); return FALSE; } else { Status = NtPowerInformation( SystemReserveHiberFile, &bEnable, sizeof(bEnable), NULL, 0 ); if (!NT_SUCCESS(Status)) { FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, RtlNtStatusToDosError(Status), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&g_lpszErr2, 0, NULL ); return FALSE; } } return TRUE; }
BOOL DoUsage() /*++
Routine Description: Displays usage information Arguments:
none Return Value: TRUE if successful FALSE if failed --*/ { ULONG ulIdx; for(ulIdx=IDS_USAGE_START;ulIdx<=IDS_USAGE_END;ulIdx++) DISPLAY_MESSAGE(stdout, GetResString(ulIdx)); return TRUE; }
|