📄 pwsdef.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//
// This module implements a set of states defined by the MS Mobile Devices
// Division as a baseline for Pocket PC devices. OEMs may choose to customize
// this file to support the hardware specific to their platform.
//
#include <pmimpl.h>
#include <nkintr.h>
#include <extfile.h>
#include <pmpolicy.h>
#include <pwsdef.h>
PowerState::PowerState(DefaultPowerStateManager *pPwrStateMgr, PowerState * pNextPowerState)
: m_pPwrStateMgr (pPwrStateMgr)
, m_pNextPowerState (pNextPowerState)
{
memset (m_dwEventArray,0,sizeof(m_dwEventArray)) ;
m_hUnsignaledHandle = CreateEvent(NULL, FALSE, FALSE,NULL);
PREFAST_ASSERT(pPwrStateMgr!=NULL);
m_dwEventArray [ PM_SHUTDOWN_EVENT ] = pPwrStateMgr->GetEventHandle(PM_SHUTDOWN_EVENT );
m_dwEventArray [ PM_RELOAD_ACTIVITY_TIMEOUTS_EVENT ] = pPwrStateMgr->GetEventHandle( PM_RELOAD_ACTIVITY_TIMEOUTS_EVENT);
m_dwEventArray [ PM_MSGQUEUE_EVENT ] = pPwrStateMgr->GetEventHandle( PM_MSGQUEUE_EVENT );
m_dwEventArray [ PM_RESTART_TIMER_EVENT ] = pPwrStateMgr->GetEventHandle( PM_RESTART_TIMER_EVENT );
m_dwEventArray [ PM_USER_ACTIVITY_EVENT ] = (pPwrStateMgr->GetUserActivityTimer()!=NULL? pPwrStateMgr->GetUserActivityTimer()->hevActive:NULL);
m_dwEventArray [ PM_SYSTEM_ACTIVITY_EVENT ] = (pPwrStateMgr->GetSystemActivityTimer()!=NULL? pPwrStateMgr->GetSystemActivityTimer()->hevActive:NULL);
m_dwEventArray [ PM_SYSTEM_API_EVENT] = pPwrStateMgr->GetEventHandle(PM_SYSTEM_API_EVENT);
m_dwEventArray [ PM_BOOTPHASE2_EVENT] = pPwrStateMgr->GetEventHandle(PM_BOOTPHASE2_EVENT);
m_dwNumOfEvent = PM_BASE_TOTAL_EVENT;
for (DWORD dwIndex=0 ; dwIndex < PM_BASE_TOTAL_EVENT; dwIndex ++ ) {
if (m_dwEventArray[dwIndex] == NULL) { // Use dummy one.
m_dwEventArray[dwIndex] = m_hUnsignaledHandle;
}
}
m_InitFlags = 0;
m_LastNewState = PM_UNKNOWN_POWER_STATE ;
}
PowerState::~PowerState()
{
if (m_hUnsignaledHandle!=NULL)
CloseHandle(m_hUnsignaledHandle);
}
BOOL PowerState::Init()
{
SETFNAME(_T("PowerState::Init"));
if (m_pPwrStateMgr && m_hUnsignaledHandle ) {
for (DWORD dwIndex=0; dwIndex < m_dwNumOfEvent; dwIndex++)
if ( m_dwEventArray[dwIndex] == NULL) {
ASSERT(FALSE);
return FALSE;
}
m_LastNewState = GetState(); // Point to itself
DWORD dwReturn = StateValidateRegistry();
if (dwReturn != ERROR_SUCCESS) {
PMLOGMSG(ZONE_PLATFORM, (_T("%s: StateValidateRegistry return (0x%08x) fails\r\n"), pszFname, dwReturn));
ASSERT(FALSE);
return FALSE;
}
return TRUE;
}
return FALSE;
}
PLATFORM_ACTIVITY_EVENT PowerState::MsgQueueEvent()
{
SETFNAME(_T("PowerState::MsgQueueEvent"));
PLATFORM_ACTIVITY_EVENT activeEvent = NoActivity ;
POWERPOLICYMESSAGE ppm;
DWORD dwStatus = PmPolicyReadNotificationQueue( m_dwEventArray [ PM_MSGQUEUE_EVENT ], &ppm, sizeof(ppm));
if(dwStatus == ERROR_SUCCESS) {
PMLOGMSG(ZONE_PLATFORM, (_T("%s: got request 0x%04x (data 0x%08x) from process 0x%08x\r\n"),
pszFname, ppm.dwMessage, ppm.dwData, ppm.hOwnerProcess));
switch(ppm.dwMessage) {
case PPN_POWERCHANGE:
if(PmUpdatePowerStatus()){
activeEvent = PowerSourceChange;
}
break;
case PPN_SUSPENDKEYPRESSED:
activeEvent = PowerButtonPressed;
break;
case PPN_APPBUTTONPRESSED:
activeEvent = AppButtonPressed;
break;
case PPN_UNATTENDEDMODE:
// somebody wants to enter or leave unattended mode
if(ppm.dwData != FALSE) {
activeEvent = EnterUnattendedModeRequest;
} else {
activeEvent = LeaveUnattendedModeRequest;
}
break;
default:
// unhandled notification type, ignore it
PMLOGMSG(ZONE_WARN, (_T("%s: unhandled policy notification 0x%04x (data 0x%08x)\r\n"),
pszFname, ppm.dwMessage, ppm.dwData));
break;
}
}
PMLOGMSG(ZONE_PLATFORM, (_T("%s: return ActiveEvent = 0x%08x\r\n"), pszFname, activeEvent));
return activeEvent;
}
void PowerState::EnterState()
{
PmSetSystemPowerState_I ( GetStateString(), 0 , 0, TRUE);
m_LastNewState = GetState(); // Point to itself
// Initial Timeout to Active First.
if (m_pPwrStateMgr->GetUserActivityTimer())
m_dwEventArray [ PM_USER_ACTIVITY_EVENT ] = m_pPwrStateMgr->GetUserActivityTimer()->hevActive;
if (m_pPwrStateMgr->GetSystemActivityTimer())
m_dwEventArray [ PM_SYSTEM_ACTIVITY_EVENT ] = m_pPwrStateMgr->GetSystemActivityTimer()->hevActive;
//TODO Do not forget to implement this in vender specific code. m_pPwrStateMgr->ReAdjustTimeOuts( );
}
PLATFORM_ACTIVITY_EVENT PowerState::WaitForEvent(DWORD dwTimeouts, DWORD dwNumOfExternEvent, HANDLE * pExternEventArray)
{
DWORD dwNumOfEvent = m_dwNumOfEvent ;
if (dwNumOfExternEvent!=0 && pExternEventArray!=NULL ) {
for ( ; dwNumOfExternEvent!=0 && dwNumOfEvent < MAX_EVENT_ARRAY ; dwNumOfEvent++ )
if (*pExternEventArray != NULL ) {
m_dwEventArray [ dwNumOfEvent ] = *pExternEventArray ;
pExternEventArray ++;
dwNumOfExternEvent --;
}
else {
ASSERT(FALSE);
return NoActivity;
}
}
DWORD dwTicksElapsed = GetTickCount();
DWORD dwReturn = WaitForMultipleObjects ( min(dwNumOfEvent,MAX_EVENT_ARRAY), m_dwEventArray, FALSE, dwTimeouts);
dwTicksElapsed = GetTickCount() - dwTicksElapsed;
m_pPwrStateMgr->SubtractTimeout(dwTicksElapsed);
if (dwReturn == WAIT_TIMEOUT)
return Timeout;
else if (dwReturn >= WAIT_OBJECT_0 + m_dwNumOfEvent) { // Extern Event
return (PLATFORM_ACTIVITY_EVENT)(ExternedEvent + dwReturn - (WAIT_OBJECT_0 + m_dwNumOfEvent));
}
else {
PLATFORM_ACTIVITY_EVENT platEvent = NoActivity;
switch(dwReturn - WAIT_OBJECT_0 ) {
case PM_SHUTDOWN_EVENT:
platEvent = PmShutDown;
break;
case PM_RELOAD_ACTIVITY_TIMEOUTS_EVENT:
platEvent = PmReloadActivityTimeouts;
break;
case PM_MSGQUEUE_EVENT:
platEvent = MsgQueueEvent();
break;
case PM_RESTART_TIMER_EVENT:
platEvent = RestartTimeouts;
break;
case PM_USER_ACTIVITY_EVENT:
if (m_pPwrStateMgr->GetUserActivityTimer()) {
if (m_dwEventArray [ PM_USER_ACTIVITY_EVENT ] == m_pPwrStateMgr->GetUserActivityTimer()->hevActive ) { // Active Signaled. Same State and Wait For Inactive
m_dwEventArray [ PM_USER_ACTIVITY_EVENT ] = m_pPwrStateMgr->GetUserActivityTimer()->hevInactive;
m_pPwrStateMgr->ResetUserIdleTimeout(FALSE);
m_pPwrStateMgr->ResetSystemIdleTimeTimeout(FALSE); // User Activity will tread as System Actiivty
platEvent = UserActivity ;
}
else { // Inactive Signaled . Start to wait on Active.
ASSERT(m_dwEventArray [ PM_USER_ACTIVITY_EVENT ] == m_pPwrStateMgr->GetUserActivityTimer()->hevInactive);
m_dwEventArray [ PM_USER_ACTIVITY_EVENT ] = m_pPwrStateMgr->GetUserActivityTimer()->hevActive ;
m_pPwrStateMgr->ResetUserIdleTimeout(TRUE);
m_pPwrStateMgr->ResetSystemIdleTimeTimeout(TRUE);
platEvent = UserInactivity ;
}
}
else
ASSERT(FALSE);
break;
case PM_SYSTEM_ACTIVITY_EVENT:
PMLOGMSG(ZONE_PLATFORM, (_T("%s: Jack PM_SYSTEM_ACTIVITY_EVENT\r\n")));
if (m_pPwrStateMgr->GetSystemActivityTimer()) {
if (m_dwEventArray [ PM_SYSTEM_ACTIVITY_EVENT ] == m_pPwrStateMgr->GetSystemActivityTimer()->hevActive ) { // Active Signaled. Same State and Wait For Inactive
PMLOGMSG(ZONE_PLATFORM, (_T("%s: Jack PM_SYSTEM_ACTIVITY_EVENT 1\r\n")));
m_dwEventArray [ PM_SYSTEM_ACTIVITY_EVENT ] = m_pPwrStateMgr->GetSystemActivityTimer()->hevInactive;
m_pPwrStateMgr->ResetSystemIdleTimeTimeout(FALSE); // User Activity will tread as System Actiivty
platEvent = SystemActivity ;
}
else { // Inactive Signaled . Start to wait on Active.
PMLOGMSG(ZONE_PLATFORM, (_T("%s: Jack PM_SYSTEM_ACTIVITY_EVENT 2\r\n")));
ASSERT(m_dwEventArray [ PM_SYSTEM_ACTIVITY_EVENT ] == m_pPwrStateMgr->GetSystemActivityTimer()->hevInactive);
m_dwEventArray [ PM_SYSTEM_ACTIVITY_EVENT ] = m_pPwrStateMgr->GetSystemActivityTimer()->hevActive ;
m_pPwrStateMgr->ResetSystemIdleTimeTimeout(TRUE);
platEvent = SystemInactivity ;
}
}
break;
case PM_SYSTEM_API_EVENT:
platEvent = SystemPowerStateAPI;
break;
case PM_BOOTPHASE2_EVENT: // This event only signal once.
platEvent = RestartTimeouts;
m_dwEventArray [ PM_BOOTPHASE2_EVENT ] = m_hUnsignaledHandle;
break;
default:
platEvent = UnwantedEventHandle( dwReturn);
break;
}
return platEvent;
}
}
/*TODO do not forget to implemet this in vender specific.
PLATFORM_ACTIVITY_STATE PowerState::DefaultEventHandle(PLATFORM_ACTIVITY_EVENT platActivityEvent )
{
switch (platActivityEvent) {
case AppButtonPressed:
m_LastNewState = On;
break;
default:
break;
}
return GetLastNewState();
}
*/
DWORD PowerState::StateValidateRegistry(DWORD dwDState , DWORD dwFlag )
{
HKEY hkPM = NULL, hkSubkey;
TCHAR pszSubKey[MAX_PATH];
DWORD dwDisposition;
SETFNAME(_T("PowerState::StateValidateRegistry"));
// open the PM registry key
DWORD dwStatus = RegCreateKeyEx(HKEY_LOCAL_MACHINE, PWRMGR_REG_KEY, 0, NULL, 0, 0, NULL, &hkPM, &dwDisposition);
if(dwStatus != ERROR_SUCCESS) {
PMLOGMSG(ZONE_ERROR, (_T("%s: can't open '%s', error is %d\r\n"), pszFname, PWRMGR_REG_KEY, dwStatus));
}
// verify the On system state
if(dwStatus == ERROR_SUCCESS) {
StringCchPrintf(pszSubKey,MAX_PATH,_T("State\\%s"), GetStateString());
dwStatus = RegCreateKeyEx(hkPM, pszSubKey, 0, NULL, 0, 0, NULL, &hkSubkey, &dwDisposition);
if(dwStatus == ERROR_SUCCESS) {
if(dwDisposition == REG_CREATED_NEW_KEY) {
// allow devices to go to any power level
DWORD dwValue = dwDState; // D State
dwStatus = RegSetValueEx(hkSubkey, NULL, 0, REG_DWORD, (LPBYTE) &dwValue, sizeof(dwValue));
// write the flags value
if(dwStatus == ERROR_SUCCESS) {
dwValue = dwFlag ;
m_InitFlags = dwFlag;
dwStatus = RegSetValueEx(hkSubkey, _T("Flags"), 0, REG_DWORD, (LPBYTE) &dwValue, sizeof(dwValue));
}
}
else {
DWORD dwValue = 0;
DWORD dwLen = sizeof(DWORD);
DWORD dwType = 0 ;
if (RegQueryValueEx( hkSubkey, _T("Flags"),NULL, &dwType, (PBYTE)&dwValue, &dwLen ) == ERROR_SUCCESS ) {
m_InitFlags = dwValue ;
}
}
RegCloseKey(hkSubkey);
}
PMLOGMSG(dwStatus != ERROR_SUCCESS && ZONE_ERROR,
(_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);
return dwStatus;
}
DefaultPowerStateManager::DefaultPowerStateManager(PVOID /*pParam*/)
{
// create events
m_hevReloadActivityTimeouts = CreateEvent(NULL, FALSE, FALSE, _T("PowerManager/ReloadActivityTimeouts"));
m_hevBootPhase2 = OpenEvent(EVENT_ALL_ACCESS, FALSE, _T("SYSTEM/BootPhase2"));
m_hevRestartTimers = CreateEvent(NULL, FALSE, FALSE, NULL);
m_hqNotify = PmPolicyCreateNotificationQueue();
// Using Global Event
m_hevPmShutdown = ghevPmShutdown;
m_pPowerStateList = NULL;
m_pCurPowerState = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -