battapi.c
字号:
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* Use of this source code is subject to the terms of the Microsoft end-user
* license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
* If you did not accept the terms of the EULA, you are not authorized to use
* this source code. For a copy of the EULA, please see the LICENSE.RTF on your
* install media.
* *//**
* @file battapi.c
* @brief Battery MDD.
*
* This module contains an MDD for the battery API. It relies on the OEM
* to provide PDD routines customized for the platform's battery hardware
* interface.
*
* @version $Id$
*
******************************************************************************/
/*
* Include files
*/
#include <battimpl.h>
/*
* Global Definitions
*/
/** The last time the batteries were changed, in real time. */
FILETIME v_ftLastChange;
/** The last time the cpu turned on. */
DWORD v_imsStart;
/** How long the current batteries have been used, not counting the
* current power cycle. */
DWORD v_cmsUsed;
/** How long the previous batteries lasted. */
DWORD v_cmsPreviousCpuUsage;
/** Are we currently on external power? */
BOOL v_fOnExternalPower;
/** Is the stopwatch running? */
BOOL v_fStopwatchRunning;
/******************************************************************************
* Function: BatteryAPIStopwatch *//**
*
* @brief This function keeps track of how long the batteries have been in
* use while the cpu is awake. This function gets called just before
* power goes off and just after it comes back on. See GwesPowerOff.
*
* @param fStart Start / stop
*
* @param fReset Rememeber how long the stopwatch has been on, then reset.
*
*****************************************************************************/
void BatteryAPIStopwatch ( BOOL fStart, BOOL fReset )
{
DWORD cmsT;
if ( fReset ) {
cmsT = v_cmsPreviousCpuUsage;
v_cmsPreviousCpuUsage = v_cmsUsed;
if ( v_fStopwatchRunning ) {
v_cmsPreviousCpuUsage += GetTickCount() - v_imsStart;
}
if ( 0 == v_cmsPreviousCpuUsage ) {
/** If user ran just on AC, don't destroy his previous battery
time. */
v_cmsPreviousCpuUsage = cmsT;
}
v_cmsUsed = 0;
}
if ( fStart && (!v_fStopwatchRunning || fReset) ) {
v_imsStart = GetTickCount();
v_fStopwatchRunning = TRUE;
} else if ( !fStart && v_fStopwatchRunning ) {
v_cmsUsed += GetTickCount() - v_imsStart;
v_fStopwatchRunning = FALSE;
}
}
/******************************************************************************
* Function: BatteryAPIGetSystemPowerStatusEx2
* *//**
* @brief Retrieves the power status of the system.
*
* @param pstatus Buffer to be filled in.
*
* @param wLen Length of pstatus buffer.
*
* @param fUpdate Get the latest information from the device driver,
* as opposed to cached information that may be out-of-date by
* several seconds.
*
*****************************************************************************/
DWORD WINAPI BatteryAPIGetSystemPowerStatusEx2(
PSYSTEM_POWER_STATUS_EX2 pstatus, DWORD dwLen, BOOL fUpdate )
{
static SYSTEM_POWER_STATUS_EX2 status;
BOOL fBatteriesChangedSinceLastCall;
FILETIME ftNow;
SYSTEMTIME st;
if ( ! pstatus )
return( 0 );
try {
if ( fUpdate ) {
/** get latest information. */
BatteryPDDGetStatus (&status, &fBatteriesChangedSinceLastCall);
if ( status.ACLineStatus != AC_LINE_OFFLINE ) {
if ( !v_fOnExternalPower ) {
v_fOnExternalPower = TRUE;
BatteryAPIStopwatch (FALSE, FALSE); // stop
}
} else {
if ( v_fOnExternalPower ) {
v_fOnExternalPower = FALSE;
BatteryAPIStopwatch (TRUE, FALSE); // start
}
}
/** if BATTERY_STATUS.fBatteriesChangedSinceLastCall or if we just
booted and have no last change time. */
if ( fBatteriesChangedSinceLastCall ||
(0 == v_ftLastChange.dwHighDateTime &&
0 == v_ftLastChange.dwLowDateTime) ) {
GetLocalTime (&st);
SystemTimeToFileTime (&st, &ftNow);
v_ftLastChange = ftNow;
BatteryAPIStopwatch (!v_fOnExternalPower, /*fReset*/TRUE);
}
DEBUGMSG( 0, (TEXT("fBatteriesChangedSinceLastCall %X\r\n"),
(WORD)fBatteriesChangedSinceLastCall));
}
/** Copy data to users buffer. */
if ( dwLen > sizeof(status) )
dwLen = sizeof(status);
memcpy( pstatus, &status, dwLen );
DEBUGMSG( 0, (TEXT("ACLineStatus %X\r\n"),
status.ACLineStatus));
DEBUGMSG( 0, (TEXT("BatteryFlag %X\r\n"), status.BatteryFlag));
DEBUGMSG( 0, (TEXT("BatteryLifePercent %X\r\n"),
status.BatteryLifePercent));
DEBUGMSG( 0, (TEXT("BatteryLifeTime %X\r\n"), status.BatteryLifeTime));
DEBUGMSG( 0, (TEXT("BatteryFullLifeTime %X\r\n"),
status.BatteryFullLifeTime));
DEBUGMSG( 0, (TEXT("BackupBatteryFlag %X\r\n"),
status.BackupBatteryFlag));
DEBUGMSG( 0, (TEXT("BackupBatteryLifePercent %X\r\n"),
status.BackupBatteryLifePercent));
DEBUGMSG( 0, (TEXT("BackupBatteryLifeTime %X\r\n"),
status.BackupBatteryLifeTime));
DEBUGMSG( 0, (TEXT("BackupBatteryFullLifeTime %X\r\n"),
status.BackupBatteryFullLifeTime));
DEBUGMSG( 0, (TEXT("BatteryVoltage %X\r\n"), status.BatteryVoltage));
DEBUGMSG( 0, (TEXT("BatteryCurrent %X\r\n"), status.BatteryCurrent));
DEBUGMSG( 0, (TEXT("BatteryAverageCurrent %X\r\n"),
status.BatteryAverageCurrent));
DEBUGMSG( 0, (TEXT("BatteryAverageInterval %X\r\n"),
status.BatteryAverageInterval));
DEBUGMSG( 0, (TEXT("BatterymAHourConsumed %X\r\n"),
status.BatterymAHourConsumed));
DEBUGMSG( 0, (TEXT("BatteryTemperature %X\r\n"),
status.BatteryTemperature));
DEBUGMSG( 0, (TEXT("BackupBatteryVoltage %X\r\n"),
status.BackupBatteryVoltage));
DEBUGMSG( 0, (TEXT("BatteryChemistry %X\r\n"),
status.BatteryChemistry));
}except(EXCEPTION_EXECUTE_HANDLER) {
dwLen = 0;
SetLastError(ERROR_GEN_FAILURE);
}
return (dwLen);
}
/******************************************************************************
* Function: BatteryAPIGetSystemPowerStatusEx
* *//**
* @brief Retrieves the power status of the system.
*
* @param pstatus Buffer to be filled in.
*
* @param fUpdate Get the latest information from the device driver,
* as opposed to cached information that may be out-of-date by
* several seconds.
*
*****************************************************************************/
BOOL WINAPI BatteryAPIGetSystemPowerStatusEx(
PSYSTEM_POWER_STATUS_EX pstatus, BOOL fUpdate )
{
DWORD dwRetLen;
if ( ! pstatus )
return( FALSE );
/** Just call the new Ex2 version and tell it we have a smaller
structure. */
dwRetLen = BatteryAPIGetSystemPowerStatusEx2(
(PSYSTEM_POWER_STATUS_EX2)pstatus,
sizeof(SYSTEM_POWER_STATUS_EX), fUpdate );
DEBUGMSG( 0, (TEXT("GetSystemPowerStatusEx Len %d\r\n"), dwRetLen));
DEBUGMSG( 0, (TEXT("ACLineStatus %X\r\n"), pstatus->ACLineStatus));
DEBUGMSG( 0, (TEXT("BatteryFlag %X\r\n"), pstatus->BatteryFlag));
DEBUGMSG( 0, (TEXT("BatteryLifePercent %X\r\n"),
pstatus->BatteryLifePercent));
DEBUGMSG( 0, (TEXT("BatteryLifeTime %X\r\n"), pstatus->BatteryLifeTime));
DEBUGMSG( 0, (TEXT("BatteryFullLifeTime %X\r\n"),
pstatus->BatteryFullLifeTime));
DEBUGMSG( 0, (TEXT("BackupBatteryFlag %X\r\n"),
pstatus->BackupBatteryFlag));
DEBUGMSG( 0, (TEXT("BackupBatteryLifePercent %X\r\n"),
pstatus->BackupBatteryLifePercent));
DEBUGMSG( 0, (TEXT("BackupBatteryLifeTime %X\r\n"),
pstatus->BackupBatteryLifeTime));
DEBUGMSG( 0, (TEXT("BackupBatteryFullLifeTime %X\r\n"),
pstatus->BackupBatteryFullLifeTime));
if ( dwRetLen == sizeof(SYSTEM_POWER_STATUS_EX) )
return( TRUE );
else
return( FALSE );
}
/******************************************************************************
* Function: BatteryAPIGetLifeTimeInfo
* *//**
* @brief Retrieves information on how long the batteries have lasted.
*
* @param pstLastChange Buffer to be filled in.
*
* @param pcmsCpuUsage The amount of time the current batteries
* have been in active use.
*
* @param pcmsPreviousCpuUsage The amount of time the previous
* batteries were in active use before
* being replaced, or zero if unknown.
*
*****************************************************************************/
void WINAPI BatteryAPIGetLifeTimeInfo ( LPSYSTEMTIME pstLastChange,
DWORD * pcmsCpuUsage, DWORD * pcmsPreviousCpuUsage )
{
try {
if ( pstLastChange )
FileTimeToSystemTime (&v_ftLastChange, pstLastChange);
if ( pcmsCpuUsage ) {
*pcmsCpuUsage = v_cmsUsed;
if ( v_fStopwatchRunning ) {
*pcmsCpuUsage += GetTickCount() - v_imsStart;
}
}
if ( pcmsPreviousCpuUsage )
*pcmsPreviousCpuUsage = v_cmsPreviousCpuUsage;
}except(EXCEPTION_EXECUTE_HANDLER) {
SetLastError(ERROR_INVALID_PARAMETER);
}
}
void add64_64_64(const FILETIME *lpnum1, LPFILETIME lpnum2, LPFILETIME lpres) {
__int64 num1, num2;
num1 = (((__int64)lpnum1->dwHighDateTime)<<32)+
(__int64)lpnum1->dwLowDateTime;
num2 = (((__int64)lpnum2->dwHighDateTime)<<32)+
(__int64)lpnum2->dwLowDateTime;
num1 += num2;
lpres->dwHighDateTime = (DWORD)(num1>>32);
lpres->dwLowDateTime = (DWORD)(num1&0xffffffff);
}
void sub64_64_64(const FILETIME *lpnum1, LPFILETIME lpnum2, LPFILETIME lpres) {
__int64 num1, num2;
num1 = (((__int64)lpnum1->dwHighDateTime)<<32)+
(__int64)lpnum1->dwLowDateTime;
num2 = (((__int64)lpnum2->dwHighDateTime)<<32)+
(__int64)lpnum2->dwLowDateTime;
num1 -= num2;
lpres->dwHighDateTime = (DWORD)(num1>>32);
lpres->dwLowDateTime = (DWORD)(num1&0xffffffff);
}
/******************************************************************************
* Function: BatteryAPINotifyOfTimeChange
* *//**
* @brief Adjust times to account for the user changing the real (clock) time.
*
* @param fForward Time has jumped forward
*
* @param pftDelta The amount the time has changed
*
*****************************************************************************/
void WINAPI BatteryAPINotifyOfTimeChange ( BOOL fForward, FILETIME * pftDelta )
{
try {
if ( pftDelta ) {
if ( fForward ) {
add64_64_64 (&v_ftLastChange, pftDelta, &v_ftLastChange);
} else {
sub64_64_64 (&v_ftLastChange, pftDelta, &v_ftLastChange);
}
}
}except(EXCEPTION_EXECUTE_HANDLER) {
SetLastError(ERROR_INVALID_PARAMETER);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -