⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pwsdef.cpp

📁 LX 800 WindowsCE 6.0 BSP
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// 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 + -