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

📄 platform.cpp

📁 此代码为WCE5.0下电源管理的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        goto done;
    }
    
    // check that all of our activity events exist
    if(ghevUserActive == NULL
        || ghevUserInactive == NULL
        || ghevSystemActive == NULL
        || ghevSystemInactive == NULL) {
        PMLOGMSG(ZONE_WARN, (_T("%s: activity timer events not found\r\n"), pszFname));
        goto done;
    }
    
    
    // create our notification queue
    hqNotify = PmPolicyCreateNotificationQueue();
    if(hqNotify == NULL) {
        PMLOGMSG(ZONE_WARN, (_T("%s: PmPolicyCreateNotificationQueue() failed\r\n"), pszFname));
        goto done;
    }
    
    // we're up and running
    SetEvent(hevReady);
    
    // we don't want to start updating system power states until the PM is completely
    // up and running.  We'll wait for the first call to SetSystemPowerState() coming from
    // device.exe's initialization code as our signal to continue.
    PMLOGMSG(ZONE_INIT, (_T("%s: waiting for initialization to complete\r\n"),
        pszFname));
    hEvents[0] = ghevPmShutdown;
    hEvents[1] = ghevReloadActivityTimeouts;
    dwStatus = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE);
    switch(dwStatus) {
    case (WAIT_OBJECT_0 + 0):
        PMLOGMSG(ZONE_INIT || ZONE_WARN, (_T("%s: shutdown event signaled, exiting\r\n"), 
            pszFname));
        fDone = TRUE;
        break;
    case (WAIT_OBJECT_0 + 1):
        PMLOGMSG(ZONE_INIT, (_T("%s: initialization complete\r\n"), pszFname));
        break;
    default:
        PMLOGMSG(ZONE_INIT || ZONE_WARN, 
            (_T("%s: WaitForMultipleObjects() returned %d, exiting\r\n"),
            pszFname, dwStatus));
        fDone = TRUE;
    }

    // get notifications in case of hive based registry
    ghevBootPhase2 = OpenEvent(EVENT_ALL_ACCESS, FALSE, _T("SYSTEM/BootPhase2"));
    
    // read the timeout values
    PlatformLoadTimeouts();
    
    // set up wait events -- assume user is active and system is active
    hEvents[0] = ghevPmShutdown;
    hEvents[1] = ghevReloadActivityTimeouts;
    hEvents[2] = hqNotify;
    hEvents[3] = ghevRestartTimers;
    hEvents[4] = ghevUserInactive;
    hEvents[5] = ghevSystemInactive;
    if(ghevBootPhase2 != NULL) {
        hEvents[6] = ghevBootPhase2;
        dwNumEvents = dim(hEvents);
    } else {
        dwNumEvents = dim(hEvents) - 1;
    }
    dwTimeout = INFINITE;
    
    PMLOGMSG(ZONE_PLATFORM, (_T("%s: waiting for events\r\n"), pszFname));
    while(!fDone) {
        PLATFORM_ACTIVITY_EVENT eCurrentActivity;
        DWORD dwStartTime, dwElapsedTime;
        
        // wait for an event; keep track of elapsed time
        dwStartTime = GetTickCount();
        dwStatus = WaitForMultipleObjects(dwNumEvents, hEvents, FALSE, dwTimeout);
        dwElapsedTime = GetTickCount() - dwStartTime;
        PMLOGMSG(ZONE_PLATFORM, 
            (_T("%s: wait returned %d, elapsed time %d, timeout was %d\r\n"), pszFname,
            dwStatus, dwElapsedTime, dwTimeout));
        
#ifdef NOT_USED
        // sanity check
        if(WaitForSingleObject(ghevUserActive, 0) == WAIT_OBJECT_0) PMLOGMSG(TRUE, (_T("%s: user active signaled\r\n"), pszFname));
        if(WaitForSingleObject(ghevUserInactive, 0) == WAIT_OBJECT_0) PMLOGMSG(TRUE, (_T("%s: user inactive signaled\r\n"), pszFname));
        if(WaitForSingleObject(ghevSystemActive, 0) == WAIT_OBJECT_0) PMLOGMSG(TRUE, (_T("%s: system active signaled\r\n"), pszFname));
        if(WaitForSingleObject(ghevSystemInactive, 0) == WAIT_OBJECT_0) PMLOGMSG(TRUE, (_T("%s: system inactive signaled\r\n"), pszFname));
#endif  // NOT_USED
        
        // figure out what happened
        eCurrentActivity = NoActivity;
        switch(dwStatus) {
        case (WAIT_OBJECT_0 + 0):   // shutdown event signaled
            fDone = TRUE;
            eCurrentActivity = NoActivity;
            break;
        case (WAIT_OBJECT_0 + 1):   // reset timeout variables and restart timers
            PlatformLoadTimeouts();
            eCurrentActivity = RestartTimeouts;
            break;
        case (WAIT_OBJECT_0 + 2):   // notification from outside the PM
            {
                POWERPOLICYMESSAGE ppm;
                dwStatus = PmPolicyReadNotificationQueue(hqNotify, &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()){
                            eCurrentActivity = PowerSourceChange;
                        }
                        break;
                    case PPN_SUSPENDKEYPRESSED:
                        SuspendButtonPressed(gfSupportPowerButtonRelease);
                        break;
                    case PPN_SUSPENDKEYRELEASED:
                        SuspendButtonReleased(gfSupportPowerButtonRelease);
                        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;
                    }
                }
            }
            break;
        case (WAIT_OBJECT_0 + 3):   // restart timers
            eCurrentActivity = RestartTimeouts;
            break;
        case (WAIT_OBJECT_0 + 4):   // user activity or inactivity signaled
            if(hEvents[4] == ghevUserInactive) {
                eCurrentActivity = UserInactivity;
            } else {
                eCurrentActivity = UserActivity;
            }
            break;
        case (WAIT_OBJECT_0 + 5):   // system activity or inactivity signaled
            if(hEvents[5] == ghevSystemInactive) {
                eCurrentActivity = SystemInactivity;
            } else {
                eCurrentActivity = SystemActivity;
            }
            break;
        case (WAIT_OBJECT_0 + 6):   // hive based registry load complete
            DEBUGCHK(ghevBootPhase2 != NULL);
            
            // update timeouts in case they've been changed
            PlatformLoadTimeouts();
            eCurrentActivity = RestartTimeouts;

            // don't need to wait on this handle again
            dwNumEvents--;
            CloseHandle(ghevBootPhase2);
            ghevBootPhase2 = NULL;
            break;
        case WAIT_TIMEOUT:
            eCurrentActivity = Timeout;
            break;
        default:
            eCurrentActivity = NoActivity;
            PMLOGMSG(ZONE_WARN, (_T("%s: WaitForMultipleObjects() returned %d\r\n"), pszFname,
                GetLastError()));
            break;
        }
        
        // update system power state based on activity information
        dwTimeout = PlatformUpdateSystemPowerState(eCurrentActivity, dwElapsedTime);
        
        // determine which activity handles we need to wait on
        if(WaitForSingleObject(ghevUserActive, 0) == WAIT_OBJECT_0) {
            hEvents[4] = ghevUserInactive;
        } else {
            hEvents[4] = ghevUserActive;
        }
        if(WaitForSingleObject(ghevSystemActive, 0) == WAIT_OBJECT_0) {
            hEvents[5] = ghevSystemInactive;
        } else {
            hEvents[5] = ghevSystemActive;
        }
    }
    
done:
    // clean up before exiting
    if(ghevReloadActivityTimeouts == NULL) { 
        CloseHandle(ghevReloadActivityTimeouts);
        ghevReloadActivityTimeouts = NULL;
    }
    if(ghevRestartTimers != NULL) {
        CloseHandle(ghevRestartTimers);
        ghevRestartTimers = NULL;
    }
    
    if(hqNotify != NULL) {
        PmPolicyCloseNotificationQueue(hqNotify);
        hqNotify = NULL;
    }
    
    if(hmCoreDll != NULL) FreeLibrary(hmCoreDll);
    
    PMLOGMSG(ZONE_PLATFORM, (_T("-%s: exiting\r\n"), pszFname));
}

// This routine is called when the system has resumed.  It is responsible for
// determining why the system woke up and initiating the appropriate system
// power state transition.  This routine is invoked in the context of the PM's
// resume thread.  
// Note:  this thread must be running at a higher priority than any thread
// that might suspend the system using SetSystemPowerState().  Otherwise it cannot
// tell whether it needs to update the system power state on its own.  In general,
// OEMs should not suspend the system without calling SetSystemPowerState() -- the
// code in this routine that handles unexpected suspends is present only as a fallback.
EXTERN_C VOID WINAPI
PlatformResumeSystem(void)
{
    SETFNAME(_T("PlatformResumeSystem"));
    TCHAR szResumeState[MAX_PATH];
    DWORD dwStatus;
    HANDLE hevActivityReset = NULL;
    
    PMLOGMSG(ZONE_RESUME, (_T("+%s: suspend flag is %d\r\n"), pszFname, gfSystemSuspended));
    
    // Was this an unexpected resume event?  If so, there may be a thread priority problem
    // or some piece of software suspended the system without calling SetSystemPowerState().
    DEBUGCHK(gfSystemSuspended);
    if(!gfSystemSuspended) {
        // Unexpected resume -- turn everything back on.  OEMs may choose to customize this
        // routine to dynamically determine which system power state is most appropriate rather
        // than using PlatformMapPowerStateHint().
        PMLOGMSG(ZONE_WARN || ZONE_RESUME, (_T("%s: WARNING: unexpected resume!\r\n"), pszFname));
        dwStatus = PlatformMapPowerStateHint(POWER_STATE_ON, szResumeState, dim(szResumeState));
        DEBUGCHK(dwStatus == ERROR_SUCCESS);
        
        // Go into the new state.  OEMs that choose to support unexpected resumes may want to
        // lock PM variables with PMLOCK(), then set the curDx and actualDx values for all
        // devices to PwrDeviceUnspecified before calling PmSetSystemPowerState_I().  This will
        // force an update IOCTL to all devices.
        dwStatus = PmSetSystemPowerState_I(szResumeState, 0, POWER_FORCE, TRUE);
        DEBUGCHK(dwStatus == ERROR_SUCCESS);
    } else if(gfActiveManagement) {
        DWORD dwWakeSource, dwBytesReturned;
        BOOL fOk;
        
        // get the system wake source to help determine which power state we resume into
        fOk = KernelIoControl(IOCTL_HAL_GET_WAKE_SOURCE, NULL, 0, &dwWakeSource, 
            sizeof(dwWakeSource), &dwBytesReturned);
        if(fOk) {
            // ioctl succeeded (not all platforms necessarily support it), but sanity check
            // the return value, just in case.
            if(dwBytesReturned != sizeof(dwWakeSource)) {
                PMLOGMSG(ZONE_WARN, (_T("%s: KernelIoControl() returned an invalid size %d\r\n"),
                    pszFname, dwBytesReturned));
            } else {
                // look for an activity timer corresponding to this wake source
                PACTIVITY_TIMER pat = ActivityTimerFindByWakeSource(dwWakeSource);
                if(pat != NULL) {
                    PMLOGMSG(ZONE_RESUME || ZONE_TIMERS, (_T("%s: signaling '%s' activity at resume\r\n"),
                        pszFname, pat->pszName));
                    hevActivityReset = pat->hevReset;
                }
            }
        }
        
        // did we find an activity timer?
        if(hevActivityReset == NULL) {
            PMLOGMSG(ZONE_RESUME, (_T("%s: assuming user activity\r\n"), pszFname));
            hevActivityReset = ghevSignalUserActivity;
        }
    }
    
    // is there an activity timer we need to reset?
    if(hevActivityReset != NULL) {
        // found a timer, elevate the timer management priority thread so that it 
        // executes before the suspending thread
        DWORD dwOldPriority = CeGetThreadPriority(ghtActivityTimers);
        DWORD dwNewPriority = (CeGetThreadPriority(GetCurrentThread()) - 1);
        DEBUGCHK(dwNewPriority >= 0);
        SetEvent(hevActivityReset);
        CeSetThreadPriority(ghtActivityTimers, dwNewPriority);
        CeSetThreadPriority(ghtActivityTimers, dwOldPriority);
    }
    
    PMLOGMSG(ZONE_RESUME, (_T("-%s\r\n"), pszFname));
}

⌨️ 快捷键说明

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