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

📄 platform.cpp

📁 此代码为WCE5.0下电源管理的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                pOldCeilingDx = pdpr;
            }
            
            PMLOCK();
            if ( fPasswordOn != gfPasswordOn ) {
                if (gfGwesReady && gpfnShowStartupWindow && fPasswordOn )
                    gpfnShowStartupWindow();
                gfPasswordOn = fPasswordOn;
            }
            PMUNLOCK();
            
            // are we suspending?
            if(fSuspendSystem) {
                // clear activity flags
                ResetEvent(ghevUserActive);
                ResetEvent(ghevSignalUserActivity);
                ResetEvent(ghevSystemActive);
                ResetEvent(ghevSignalSystemActivity);
                
                // set a flag to notify the resume thread that this was a controlled
                // suspend
                gfSystemSuspended = TRUE;
                
                PMLOGMSG(ZONE_PLATFORM || ZONE_RESUME, (_T("%s: calling PowerOffSystem()\r\n"), pszFname));
                PowerOffSystem();       // sets a flag in the kernel for the scheduler
                Sleep(0);               // so we force the scheduler to run
                PMLOGMSG(ZONE_PLATFORM || ZONE_RESUME, (_T("%s: back from PowerOffSystem()\r\n"), pszFname));
                
                // clear the suspend flag
                gfSystemSuspended = FALSE;
                
                // resume into an appropriate system power state
                if(gfActiveManagement) {
                    // figure out the right power state
                    PlatformUpdateSystemPowerState(Resume, INFINITE);
                    
                    // For now, synchronize with the system management thread by reloading timeouts.
                    // We can't just have the system thread enter the resume state because 
                    // FileSystemPowerFunction(FSNOTIFY_POWER_OFF) blocks all other threads from
                    // accessing the registry.
                    SetEvent(ghevReloadActivityTimeouts);
                } else {
                    // resume into a default system power state
                    LPTSTR pszResumeState = _T("on");
                    PMLOGMSG(ZONE_RESUME, (_T("%s: resuming into '%s' system power state\r\n"),
                        pszFname, pszResumeState));
                    dwStatus = PmSetSystemPowerState_I(pszResumeState, 0, POWER_FORCE, TRUE);
                    DEBUGCHK(dwStatus == ERROR_SUCCESS);
                }
                
                // tell gwes to wake up
                if(gpfnGwesPowerUp != NULL && gfGwesReady) {
                    gpfnGwesPowerUp(fWantStartupScreen);
                }
                
                // send out resume notification
                pbb.Message = PBT_RESUME;
                pbb.Flags = 0;
                pbb.Length = 0;
                pbb.SystemPowerState[0] = 0;
                GenerateNotifications((PPOWER_BROADCAST) &pbb);
            }
        } else {
            // release the unused new state information
            SystemPowerStateDestroy(pNewSystemPowerState);
            while(pNewCeilingDx != NULL) {
                PDEVICE_POWER_RESTRICTION pdpr = pNewCeilingDx->pNext;
                PowerRestrictionDestroy(pNewCeilingDx);
                pNewCeilingDx = pdpr;
            }
            
        }
    }
    
    // restore our priority if we updated it during a suspend transition
    if(giSuspendPriority != 0 && iPreSuspendPriority != 0) {
        PMLOGMSG(ZONE_PLATFORM, (_T("%s: restoring thread priority to %d\r\n"), 
            pszFname, iPreSuspendPriority));
        CeSetThreadPriority(GetCurrentThread(), iPreSuspendPriority);
    }
    
    // if we're initializing, tell the management thread we're done
    if(fFirstCall) {
        if(ghevReloadActivityTimeouts != NULL) SetEvent(ghevReloadActivityTimeouts);
        fFirstCall = FALSE;
    }
    
    return dwStatus;
}

// This routine reads a power state timeout value from the registry.  The
// timeout value should be expressed in seconds; this routine returns 
// the timeout value in milliseconds.
DWORD
RegReadStateTimeout(HKEY hk, LPCTSTR pszName, DWORD dwDefault)
{
    DWORD dwValue, dwSize, dwStatus;
    
    dwSize = sizeof(dwValue);
    dwStatus = RegQueryTypedValue(hk, pszName, &dwValue, &dwSize, REG_DWORD);
    if(dwStatus != ERROR_SUCCESS) {
        dwValue = dwDefault;
    } else {
        if(dwValue == 0) {
            dwValue = INFINITE;
        } else {
            if(dwValue > MAXACTIVITYTIMEOUT) {
                dwValue = MAXACTIVITYTIMEOUT;
            }
        }
    }

    // convert to milliseconds
    if(dwValue != INFINITE) {
        dwValue *= 1000;
    }

    return dwValue;
}

// This routine reads the system's timeout values from the registry.  It
// is called at boot time and whenever the reload event is signaled.
VOID
PlatformLoadTimeouts(VOID)
{
    DWORD dwStatus;
    TCHAR szPath[MAX_PATH];
    HKEY hk;
    SETFNAME(_T("PlatformLoadTimeouts"));

    // assume default values
    gdwACTimeoutToUserIdle = DEF_TIMEOUTTOUSERIDLE * 1000;
    gdwACTimeoutToSystemIdle = DEF_TIMEOUTTOSYSTEMIDLE * 1000;
    gdwACTimeoutToSuspend = DEF_TIMEOUTTOSUSPEND * 1000;
    gdwBattTimeoutToUserIdle = DEF_TIMEOUTTOUSERIDLE * 1000;
    gdwBattTimeoutToSystemIdle = DEF_TIMEOUTTOSYSTEMIDLE * 1000;
    gdwBattTimeoutToSuspend = DEF_TIMEOUTTOSUSPEND * 1000;

    // get timeout thresholds for transitions between states
    wsprintf(szPath, _T("%s\\%s"), PWRMGR_REG_KEY, _T("Timeouts"));
    dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szPath, 0, 0, &hk);
    if(dwStatus == ERROR_SUCCESS) {
        // read system power state timeouts
        gdwACTimeoutToUserIdle = RegReadStateTimeout(hk, _T("ACUserIdle"), DEF_TIMEOUTTOUSERIDLE);
        gdwACTimeoutToSystemIdle = RegReadStateTimeout(hk, _T("ACSystemIdle"), DEF_TIMEOUTTOSYSTEMIDLE);
        gdwACTimeoutToSuspend = RegReadStateTimeout(hk, _T("ACSuspend"), DEF_TIMEOUTTOSUSPEND);
        gdwBattTimeoutToUserIdle = RegReadStateTimeout(hk, _T("BattUserIdle"), DEF_TIMEOUTTOUSERIDLE);
        gdwBattTimeoutToSystemIdle = RegReadStateTimeout(hk, _T("BattSystemIdle"), DEF_TIMEOUTTOSYSTEMIDLE);
        gdwBattTimeoutToSuspend = RegReadStateTimeout(hk, _T("BattSuspend"), DEF_TIMEOUTTOSUSPEND);

        // release resources
        RegCloseKey(hk);
    }

    PMLOGMSG(ZONE_INIT || ZONE_PLATFORM, 
        (_T("%s: ACUserIdle %d, ACSystemIdle %d, ACSuspend %d, BattUserIdle %d, BattSystemIdle %d, BattSuspend %d\r\n"),
        pszFname, gdwACTimeoutToUserIdle, gdwACTimeoutToSystemIdle, gdwACTimeoutToSuspend, 
        gdwBattTimeoutToUserIdle, gdwBattTimeoutToSystemIdle, gdwBattTimeoutToSuspend));
}

// This routine determines if the PM is supposed to be actively managing power on the
// system or not.  If it isn't, then the code that updates our internal state machine
// based on system activity is extraneous and can be removed by the OEM.
BOOL
PlatformPMActivelyManagesPower(void)
{
    BOOL fActivelyManaging = FALSE;
    TCHAR szPath[MAX_PATH];
    HKEY hk;
    DWORD dwStatus;
    SETFNAME(_T("PlatformPMActivelyManagesPower"));

    // open the timeout registry key
    wsprintf(szPath, _T("%s\\%s"), PWRMGR_REG_KEY, _T("Timeouts"));
    dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szPath, 0, 0, &hk);
    if(dwStatus == ERROR_SUCCESS) {
        DWORD dwValue, dwType;
        DWORD dwSize = sizeof(dwValue);
        dwStatus = RegQueryValueEx(hk, _T("ACUserIdle"), NULL, &dwType, (LPBYTE) &dwValue, &dwSize);
        if(dwStatus == ERROR_SUCCESS && dwType == REG_DWORD) {
            fActivelyManaging = TRUE;
        }
        RegCloseKey(hk);
    }

    PMLOGMSG(ZONE_INIT || ZONE_PLATFORM, (_T("%s: returning %d\r\n"), pszFname, fActivelyManaging));
    return fActivelyManaging;

}

// This routine implements the main power manager event loop.  This loop implements
// the power manager's response to external events, such as being docked in a cradle,
// running low on battery power, going on or off AC power, etc.  This sample implementation
// simply monitors battery level changes and generates the appropriate notifications.
EXTERN_C VOID WINAPI 
PlatformManageSystemPower(HANDLE hevReady)
{
    BOOL fDone = FALSE;
    HANDLE hEvents[7], hqNotify = NULL;
    DWORD dwTimeout, dwStatus, dwNumEvents;
    HMODULE hmCoreDll = NULL;
    PACTIVITY_TIMER pat;
    SETFNAME(_T("PlatformManageSystemPower"));
    
    PMLOGMSG(ZONE_INIT || ZONE_PLATFORM, (_T("+%s\r\n"), pszFname));
    
    // init globals
    ghevReloadActivityTimeouts = NULL;
    ghevRestartTimers = NULL;
    
    // determine thread priority settings while we're suspending (in case
    // of priority inversion)
    if(!GetPMThreadPriority(_T("PreSuspendPriority256"), &giPreSuspendPriority)) {
        giPreSuspendPriority = DEF_PRESUSPEND_THREAD_PRIORITY;
    }
    if(!GetPMThreadPriority(_T("SuspendPriority256"), &giSuspendPriority)) {
        giSuspendPriority = DEF_SUSPEND_THREAD_PRIORITY;
    }
    
    // get events from activity timers
    PMLOCK();
    pat = ActivityTimerFindByName(_T("UserActivity"));
    if(pat != NULL) {
        ghevSignalUserActivity = pat->hevReset;
        ghevUserActive = pat->hevActive;
        ghevUserInactive = pat->hevInactive;
    } else {
        ghevSignalUserActivity = NULL;
        ghevUserActive = NULL;
        ghevUserInactive = NULL;
    }
    pat = ActivityTimerFindByName(_T("SystemActivity"));
    if(pat != NULL) {
        ghevSignalSystemActivity = pat->hevReset;
        ghevSystemActive = pat->hevActive;
        ghevSystemInactive = pat->hevInactive;
    } else {
        ghevSignalSystemActivity = NULL;
        ghevSystemActive = NULL;
        ghevSystemInactive = NULL;
    }
    PMUNLOCK();
    
    // determine if we're supposed to be actively managing power on this system
    gfActiveManagement = PlatformPMActivelyManagesPower();
    
    // Get pointers to GWES's suspend/routine APIs.  These require GWES, so the OEM may
    // not have them on this platform.  Also get battery level APIs, which require a 
    // battery driver and may not be present.
    hmCoreDll = (HMODULE) LoadLibrary(_T("coredll.dll"));
    gfGwesReady = FALSE;
    PmInitPowerStatus(hmCoreDll);
    if(hmCoreDll != NULL) {
        gpfnGwesPowerDown = (PFN_GwesPowerDown) GetProcAddress(hmCoreDll, _T("GwesPowerDown"));
        gpfnGwesPowerUp = (PFN_GwesPowerUp) GetProcAddress(hmCoreDll, _T("GwesPowerUp"));
        gpfnShowStartupWindow = (PFN_ShowStartupWindow) GetProcAddress(hmCoreDll, _T("ShowStartupWindow"));
        
        // do we have both gwes suspend/resume APIs?
        if(gpfnGwesPowerDown == NULL || gpfnGwesPowerUp == NULL) {
            // no, ignore GWES
            gpfnGwesPowerDown = NULL;
            gpfnGwesPowerUp = NULL;
        } else {
            // monitor GWES apis
            ghevGwesReady = OpenEvent(EVENT_ALL_ACCESS, FALSE, _T("SYSTEM/GweApiSetReady"));
            DEBUGCHK(ghevGwesReady != NULL);
        }
    }
    
    // are we using the PM in an active or passive role?  For now, key off of the presence
    // of the PM timeout value for AC power.
    if(!gfActiveManagement) {
        PMLOGMSG(ZONE_PLATFORM || ZONE_INIT, (_T("%s: PM role on platform is passive, exiting\r\n"),
            pszFname));
        // indicate we're ready, since there's no error involved in passive PM
        SetEvent(hevReady);
        Sleep(1000);            // don't want PM initialization to fail when we exit
        goto done;
    }
    
    // create events
    ghevReloadActivityTimeouts = CreateEvent(NULL, FALSE, FALSE, _T("PowerManager/ReloadActivityTimeouts"));
    ghevRestartTimers = CreateEvent(NULL, FALSE, FALSE, NULL);
    if(ghevReloadActivityTimeouts == NULL 
        || ghevRestartTimers == NULL) {
        PMLOGMSG(ZONE_WARN, (_T("%s: CreateEvent() failed for system event\r\n"), pszFname));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -