📄 platform.cpp
字号:
(_T("%s: error %d while creating or writing values in '%s\\%s'\r\n"), pszFname, dwStatus,
PWRMGR_REG_KEY, pszSubKey));
}
// release resources
if(hkPM != NULL) RegCloseKey(hkPM);
PMLOGMSG(ZONE_INIT, (_T("-%s: returning %d\r\n"), pszFname, dwStatus));
return dwStatus;
}
// This routine performs platform-specific initialization on a device list.
// Primarily this involves determining what routines should be used to communicate
// with the class.
EXTERN_C BOOL WINAPI
PlatformDeviceListInit(PDEVICE_LIST pdl)
{
BOOL fOk = FALSE;
PDEVICE_INTERFACE pInterface;
SETFNAME(_T("PlatformDeviceListInit"));
PREFAST_DEBUGCHK(pdl != NULL);
DEBUGCHK(pdl->pGuid != NULL);
if(*pdl->pGuid == idPMDisplayDeviceClass) {
PMLOGMSG(ZONE_INIT || ZONE_PLATFORM,
(_T("%s: using display interface to access class %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x\r\n"),
pszFname, pdl->pGuid->Data1, pdl->pGuid->Data2, pdl->pGuid->Data3,
(pdl->pGuid->Data4[0] << 8) + pdl->pGuid->Data4[1], pdl->pGuid->Data4[2], pdl->pGuid->Data4[3],
pdl->pGuid->Data4[4], pdl->pGuid->Data4[5], pdl->pGuid->Data4[6], pdl->pGuid->Data4[7]));
#ifndef NODISPLAYINTERFACE
// Use the display driver interface to get to the device. To remove
// display code from the link, edit or conditionally compile this code out
// of the PM.
extern DEVICE_INTERFACE gDisplayInterface; // defined in the MDD
pInterface = &gDisplayInterface;
#else // NODISPLAYINTERFACE
PMLOGMSG(ZONE_INIT || ZONE_WARN, (_T("%s: warning: display interface not supported\r\n"), pszFname));
#endif // NODISPLAYINTERFACE
} else {
// use the standard stream interface to get to the device
PMLOGMSG(ZONE_INIT || ZONE_PLATFORM,
(_T("%s: using stream interface to access class %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x\r\n"),
pszFname, pdl->pGuid->Data1, pdl->pGuid->Data2, pdl->pGuid->Data3,
(pdl->pGuid->Data4[0] << 8) + pdl->pGuid->Data4[1], pdl->pGuid->Data4[2], pdl->pGuid->Data4[3],
pdl->pGuid->Data4[4], pdl->pGuid->Data4[5], pdl->pGuid->Data4[6], pdl->pGuid->Data4[7]));
extern DEVICE_INTERFACE gStreamInterface; // defined in the MDD
pInterface = &gStreamInterface;
}
// try to initialize the interface
if(pInterface != NULL) {
if(pInterface->pfnInitInterface() == FALSE) {
PMLOGMSG(ZONE_WARN, (_T("%s: warning: pfnInitInterface() failed for interface\r\n"), pszFname));
} else {
// pass back the pointer
pdl->pInterface = pInterface;
fOk = TRUE;
}
}
return fOk;
}
// This routine is responsible for mapping system power state hint
// values to known system power states that we maintain in the registry.
EXTERN_C DWORD WINAPI
PlatformMapPowerStateHint(DWORD dwHint, LPTSTR pszBuf, DWORD dwBufChars)
{
DWORD dwStatus = ERROR_SUCCESS;
LPTSTR pszMappedStateName = NULL;
SETFNAME(_T("PlatformMapPowerStateHint"));
// mask off unused bits
dwHint &= (POWER_STATE_ON | POWER_STATE_IDLE | POWER_STATE_SUSPEND | POWER_STATE_OFF | POWER_STATE_RESET | POWER_STATE_CRITICAL);
// Try to map the hint value. Note that only one bit at a time should be set.
switch(dwHint) {
case POWER_STATE_ON:
case POWER_STATE_IDLE:
pszMappedStateName = _T("on");
break;
case POWER_STATE_SUSPEND: // suspend the system normally
case POWER_STATE_OFF: // power off, cold boot on resume
case POWER_STATE_CRITICAL: // catastrophic power loss, shut down immediately
pszMappedStateName = _T("suspend");
break;
case POWER_STATE_RESET: // flush files and reboot
pszMappedStateName = _T("reboot");
break;
default:
PMLOGMSG(ZONE_PLATFORM | ZONE_WARN,
(_T("%s: bad hint value 0x%x\r\n"), pszFname, dwHint));
dwStatus = ERROR_FILE_NOT_FOUND;
break;
}
DEBUGCHK(dwStatus == ERROR_SUCCESS);
// if we have one, copy the name back to the caller
if(pszMappedStateName != NULL) {
if(dwBufChars < (_tcslen(pszMappedStateName) + 1)) {
dwStatus = ERROR_INSUFFICIENT_BUFFER;
} else {
_tcscpy(pszBuf, pszMappedStateName);
}
}
PMLOGMSG(dwStatus != ERROR_SUCCESS && ZONE_WARN,
(_T("%s: returning %d\r\n"), pszFname, dwStatus));
return dwStatus;
}
// This routine figures out what the next power state for the platform should be
// based on activity, battery state, elapsed time, and so forth. If necessary
// it will update the system power state. The eActivityEvent parameter indicates what
// has changed that may affect the system power state. The dwElapsedTime
// value indicates how many ticks have occurred since the last update. A value of
// INFINITE indicates that the system state should be forced and the timers updated.
DWORD
PlatformUpdateSystemPowerState(PLATFORM_ACTIVITY_EVENT eActivityEvent, DWORD dwElapsedTime)
{
PLATFORM_ACTIVITY_STATE asNew;
BOOL fChangingActivityStates = FALSE;
LPTSTR pszNewState;
BOOL fOnACPower;
SETFNAME(_T("PlatformUpdateSystemPowerState"));
PMLOGMSG(ZONE_PLATFORM, (_T("%s: activity '%s' in state '%s', elapsed time %d\r\n"), pszFname,
eActivityEvent == NoActivity ? _T("NoActivity") :
eActivityEvent == UserActivity ? _T("UserActivity") :
eActivityEvent == UserInactivity ? _T("UserInactivity") :
eActivityEvent == SystemActivity ? _T("SystemActivity") :
eActivityEvent == SystemInactivity ? _T("SystemInactivity") :
eActivityEvent == Timeout ? _T("Timeout") :
eActivityEvent == RestartTimeouts ? _T("RestartTimeouts") :
eActivityEvent == PowerSourceChange ? _T("PowerSourceChange") :
eActivityEvent == Resume ? _T("Resume") : _T("<UNKNOWN>"),
gActivityState == UserActive ? _T("UserActive") :
gActivityState == UserInactive ? _T("UserInactive") :
gActivityState == UserIdle ? _T("UserIdle") :
gActivityState == SystemActive ? _T("SystemActive") :
gActivityState == SystemInactive ? _T("SystemInactive") :
gActivityState == Suspend ? _T("Suspend") : _T("<UNKNOWN>"),
dwElapsedTime));
PMLOCK();
// assume no state change
asNew = gActivityState;
// are we on battery?
if(gSystemPowerStatus.bACLineStatus == AC_LINE_OFFLINE) {
// we're on battery power
fOnACPower = FALSE;
} else {
// no, assume AC power
fOnACPower = TRUE;
}
// are we forcing an update?
if(eActivityEvent == PowerSourceChange
|| eActivityEvent == Resume
|| eActivityEvent == RestartTimeouts
|| dwElapsedTime == INFINITE) {
// we are being told to force an update and to reset our
// timeout values. Note that if we're in UserInactive or
// UserIdle and the user is not currently active we should
// just restart the timeout for the current state.
fChangingActivityStates = TRUE;
if(WaitForSingleObject(ghevUserActive, 0) == WAIT_OBJECT_0) {
// user is active, don't transition unless they are inactive
asNew = UserActive;
} else if(asNew != UserInactive && asNew != UserIdle) {
if(WaitForSingleObject(ghevSystemActive, 0) == WAIT_OBJECT_0) {
// user idle but system active. Don't transition unless the
// system is inactive or the user becomes active.
asNew = SystemActive;
} else {
// Neither the user nor the system are doing anything. Suspend
// after the configured timeout.
asNew = SystemInactive;
}
}
} else {
// some change in activity levels has occurred, or there's been
// a timeout
switch(gActivityState) {
case UserActive: // should be in an "on" system power state
switch(eActivityEvent) {
case UserInactivity: // user transition to inactive signaled
asNew = UserInactive;
break;
}
break;
case UserInactive: // should be in an "on" system power state
switch(eActivityEvent) {
case UserActivity: // user activity signaled
asNew = UserActive;
break;
case Timeout:
DEBUGCHK(gdwStateTimeLeft != INFINITE);
if(dwElapsedTime >= gdwStateTimeLeft) {
asNew = UserIdle;
}
break;
}
break;
case UserIdle: // should be in a "useridle" system power state
switch(eActivityEvent) {
case UserActivity: // user activity signaled
asNew = UserActive;
break;
case Timeout:
if(dwElapsedTime >= gdwStateTimeLeft) {
if(WaitForSingleObject(ghevSystemActive, 0) == WAIT_OBJECT_0) {
asNew = SystemActive;
} else {
asNew = SystemInactive;
}
}
}
break;
case SystemActive: // should be in a "systemidle" system power state
switch(eActivityEvent) {
case UserActivity: // user activity signaled
asNew = UserActive;
break;
case SystemInactivity: // system transition to inactive signaled
asNew = SystemInactive;
break;
}
break;
case SystemInactive: // should be in a "systemidle" system power state
switch(eActivityEvent) {
case UserActivity: // user activity signaled
asNew = UserActive;
break;
case SystemActivity: // system activity signaled
asNew = SystemActive;
break;
case Timeout:
DEBUGCHK(gdwStateTimeLeft != INFINITE);
if(dwElapsedTime >= gdwStateTimeLeft) {
asNew = Suspend;
}
break;
}
break;
case Suspend: // should be in a "suspend" system power state
switch(eActivityEvent) {
case UserActivity: // user activity signaled
asNew = UserActive;
break;
case SystemActivity: // system activity signaled
asNew = SystemActive;
break;
}
break;
default:
PMLOGMSG(ZONE_WARN, (_T("%s: unknown platform state %d\r\n"), pszFname, gActivityState));
break;
}
}
// are we changing activity states?
if(asNew != gActivityState) {
fChangingActivityStates = TRUE;
gActivityState = asNew;
}
// calculate new timeouts and system power state names
switch(gActivityState) {
case UserActive:
pszNewState = _T("on");
gdwStateTimeLeft = INFINITE;
break;
case UserInactive:
pszNewState = _T("on");
if(fChangingActivityStates) {
if(fOnACPower) {
gdwStateTimeLeft = gdwACTimeoutToUserIdle;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -