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

📄 platform.cpp

📁 此代码为WCE5.0下电源管理的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        if(dwElapsedTime >= gdwStateTimeLeft) {
            // suspend timeout has expired
            asNew = Suspend;
        }
        break;
    case RestartTimeouts:
    case PowerSourceChange:
        // reset suspend timers to the value appropriate to the new power source
        if(gActivityState == Resuming) {
            gdwStateTimeLeft = dwResumingSuspendTimeout;
        } else if(gActivityState == Suspend) {
            gdwStateTimeLeft = INFINITE;
        } else {
            gdwStateTimeLeft = dwSuspendTimeout;
        }
        dwElapsedTime = 0;
        break;
    case UserActivity:
        // if we're in normal operation, reset the suspend timeout
        fUserActive = TRUE;
        break;
    case UserInactivity:
        fUserActive = FALSE;
        if(gActivityState == On) {
            gdwStateTimeLeft = dwSuspendTimeout;
            dwElapsedTime = 0;
        }
        break;
    case SystemIdleTimerWasReset:
        // reset the suspend timeout as long as we're not resuming
        if(gActivityState != Resuming) {
            gdwStateTimeLeft = dwSuspendTimeout;
            dwElapsedTime = 0;
        }
        break;
    case EnterUnattendedModeRequest:
        // Update the number of unattended mode requests.  These can be
        // made while we're in any system power state unless
        // gfSuspendToUnattendedMode is false, in which case we must be
        // in Resuming or Unattended.
        if(gfSuspendToUnattendedMode
        || gActivityState == Resuming 
        || gActivityState == Unattended) {
            gdwUnattendedModeRequests++;
        }

        // actually transition into unattended mode if we're currently 
        // resuming
        if(gActivityState == Resuming) {
            asNew = Unattended;
        }
        break;
    case LeaveUnattendedModeRequest:
        // Reduce the number of unattended mode requests.  These can be 
        // made while we're in any system power state unless
        // gfSuspendToUnattendedMode is FALSE, in which case we must
        // be in Unattended mode.
        if(gfSuspendToUnattendedMode || gActivityState == Unattended) {
            PMLOGMSG(ZONE_WARN && (gdwUnattendedModeRequests == 0),
                (_T("%s: LeaveUnattendedModeRequest received with request count %d\r\n"),
                pszFname, gdwUnattendedModeRequests));
            if(gdwUnattendedModeRequests > 0) {
                gdwUnattendedModeRequests--;
            }
            if(gdwUnattendedModeRequests == 0 && gActivityState == Unattended) {
                // suspend if we're currently in unattended mode
                asNew = Suspend;
            }
        }
        break;
    case NoActivity:
        // ignore inactivity
        break;
    case SystemPowerStateChange:
        // someone is changing the system power state -- see if we need to update
        // our state machine.
        DEBUGCHK(gpSystemPowerState != NULL);
        {
            PLATFORM_ACTIVITY_STATE eActivityState;
            BOOL fOk = SystemStateToActivityState(gpSystemPowerState, &eActivityState);
            if(fOk) {
                // is this a state change initiated by someone outside the PM?
                if(eActivityState != asNew) {
                    // yes, we need to sync up with the transition
                    PMLOGMSG(ZONE_PLATFORM, (_T("%s: forcing state machine update to state %d\r\n"),
                        pszFname, eActivityState));
                    asNew = eActivityState;
                }
            }
            dwElapsedTime = 0;
        }
        break;
    default:
        PMLOGMSG(ZONE_WARN, (_T("%s: unknown activity event state %d\r\n"), pszFname, eActivityEvent));
        break;
    }

    // are we changing activity states?
    if(asNew != gActivityState) {
        fChangingActivityStates = TRUE;
        gActivityState = asNew;

        // reload the suspend timeout
        switch(gActivityState) {
        case Resuming:
            gdwStateTimeLeft = dwResumingSuspendTimeout;
            break;
        case Suspend:
            gdwStateTimeLeft = INFINITE;
            break;
        default:
            gdwStateTimeLeft = dwSuspendTimeout;
            break;
        }
    }

    // don't suspend timeout while we're "on" and the user is actively using the system
    if(gActivityState == On && fUserActive) {
        gdwStateTimeLeft = INFINITE;
    }

    // calculate new timeouts and system power state names
    pszNewState = ActivityStateToSystemState(gActivityState);
    PREFAST_DEBUGCHK(pszNewState != NULL);

    // update elapsed time
    if(!fChangingActivityStates && gdwStateTimeLeft != INFINITE) {
        if(gdwStateTimeLeft > dwElapsedTime) {
            gdwStateTimeLeft -= dwElapsedTime;
        } else {
            gdwStateTimeLeft = 0;
        }
    }

    // are we changing states or forcing an update?
    PMLOGMSG(ZONE_PLATFORM,
        (_T("%s: %s activity state '%s', state time left %d\r\n"), pszFname,
        fChangingActivityStates ? _T("changing to") : _T("staying in"),
        gActivityState == On ? _T("on") :
        gActivityState == ScreenOff ? _T("ScreenOff") :
        gActivityState == Unattended ? _T("Unattended") :
        gActivityState == Resuming ? _T("Resuming") :
        gActivityState == Suspend ? _T("Suspend") : _T("<UNKNOWN>"), gdwStateTimeLeft));
    if(dwElapsedTime == INFINITE 
    || gpSystemPowerState == NULL
    || _tcscmp(pszNewState, gpSystemPowerState->pszName) != 0) {
        PMLOGMSG(ZONE_PLATFORM, (_T("%s: update from activity state %d to activity state %d\r\n"),
            pszFname, gActivityState, asNew));
    } else {
        // no update necessary
        pszNewState = NULL;
    }

    PMUNLOCK();

    // SystemPowerStateChange notifications are informational only, so suppress
    // the call to PmSetSystemPowerState().
    if(eActivityEvent == SystemPowerStateChange) {
        pszNewState = NULL;
    }
    
    // update the system power state if necessary
    if(pszNewState != NULL) {
        PmSetSystemPowerState_I(pszNewState, 0, 0, TRUE);
    }

    return gdwStateTimeLeft;
}

// This routine reads and verifies system power state information from
// the registry, then updates all devices appropriately.  The caller of this
// routine should hold the system power state critical section.  The fInternal
// flag indicates whether the call originated within the PM or outside it.
EXTERN_C DWORD WINAPI
PlatformSetSystemPowerState(LPCTSTR pszName, BOOL fForce, BOOL fInternal)
{
    DWORD dwStatus = ERROR_SUCCESS;
    PSYSTEM_POWER_STATE pNewSystemPowerState = NULL;
    PDEVICE_POWER_RESTRICTION pNewCeilingDx = NULL;
    BOOL fDoTransition = FALSE;
    INT iPreSuspendPriority = 0;
    static BOOL fFirstCall = TRUE;
    SETFNAME(_T("PlatformSetSystemPowerState"));
    
    // read system power state variables and construct new lists
    if (gfFileSystemsAvailable)
        PmUpdateSystemPowerStatesIfChanged();
    dwStatus = RegReadSystemPowerState(pszName, &pNewSystemPowerState, &pNewCeilingDx);
        
    // did we get registry information about the new power state?			
    if(dwStatus == ERROR_SUCCESS) {
        BOOL fSuspendSystem = FALSE;
        BOOL fWantStartupScreen = FALSE;
        DWORD dwNewStateFlags = pNewSystemPowerState->dwFlags;
        BOOL  fPasswordOn = ((dwNewStateFlags & POWER_STATE_PASSWORD)!=0) ;
        
        // assume we will update the system power state
        fDoTransition = TRUE;
        
        // Are we going to suspend the system as a whole?
        if((dwNewStateFlags & (POWER_STATE_SUSPEND | POWER_STATE_OFF | POWER_STATE_CRITICAL | POWER_STATE_RESET)) != 0) {
            fSuspendSystem = TRUE;
        }
        
        // A "critical" suspend might mean we have totally lost battery power and need
        // to suspend really quickly.  Depending on the platform, OEMs may be able
        // to bypass driver notification entirely and rely on xxx_PowerDown() notifications
        // to suspend gracefully.  Or they may be able to implement a critical suspend
        // kernel ioctl.  This sample implementation is very generic and simply sets the 
        // POWER_FORCE flag, which is not used.
        if(dwNewStateFlags & (POWER_STATE_CRITICAL | POWER_STATE_OFF | POWER_STATE_RESET)) {
            fForce = TRUE;
        }
        
        // Determine whether to allow the system power state transition to take place.  
        // We will allow applications to initiate transitions to the "on" state, the 
        // "screenoff" state, or the "suspend" state. Since we may be translating an
        // external request to enter POWER_STATE_SUSPEND into entering unattended mode, 
        // we'll allow external entities to go into unattended mode.
        if(!fInternal) {
            // allow aliases for these state names by using the flags field
            BOOL fAllow = FALSE;
            if(dwNewStateFlags & (POWER_STATE_SUSPEND | POWER_STATE_CRITICAL)) fAllow = TRUE;   // suspend state
            if(dwNewStateFlags & POWER_STATE_RESET) fAllow = TRUE;                              // reboot
            if(dwNewStateFlags & POWER_STATE_OFF) fAllow = TRUE;                                // cold suspend
            if(dwNewStateFlags & (POWER_STATE_IDLE | POWER_STATE_ON)) fAllow = TRUE;            // normal operation
            if(gfSuspendToUnattendedMode && _tcscmp(pszName, _T("unattended")) == 0) {
                fAllow = TRUE;                 // unattended mode
            }
            if(!fAllow) {
                PMLOCK();
                // we should also permit changes to the current system state to succeed
                if(gpSystemPowerState != NULL
                    && _tcscmp(gpSystemPowerState->pszName, pNewSystemPowerState->pszName) != 0) {
                    fDoTransition = FALSE;
                    dwStatus = ERROR_ACCESS_DENIED;
                }
                PMUNLOCK();
            }
        }
        
        // if everything seems ok, do the set operation
        if(fDoTransition) {
            POWER_BROADCAST_BUFFER pbb;
            PDEVICE_LIST pdl;
            BOOL fResumeSystem = FALSE;
            
            // send out system power state change notifications
            pbb.Message = PBT_TRANSITION;
            pbb.Flags = pNewSystemPowerState->dwFlags;
            pbb.Length = _tcslen(pNewSystemPowerState->pszName) + 1; // char count not byte count for now
            if(pbb.Length > MAX_PATH) {
                // truncate the system power state name -- note, we actually have MAX_PATH + 1
                // characters available.
                pbb.Length = MAX_PATH;
            }
            _tcsncpy(pbb.SystemPowerState, pNewSystemPowerState->pszName, pbb.Length);
            pbb.Length *= sizeof(pbb.SystemPowerState[0]);      // convert to byte count
            GenerateNotifications((PPOWER_BROADCAST) &pbb);
            
            // are we suspending?
            if(fSuspendSystem && gpfnGwesPowerDown != NULL) {
                // is GWES ready?
                if(!gfGwesReady) {
                    DEBUGCHK(ghevGwesReady != NULL);
                    if(WaitForSingleObject(ghevGwesReady, 0) == WAIT_OBJECT_0) {
                        gfGwesReady = TRUE;
                        CloseHandle(ghevGwesReady);
                        ghevGwesReady = NULL;
                    }
                }
                
                // Start the process of suspending GWES
                if(gfGwesReady) {
                    fWantStartupScreen = gpfnGwesPowerDown();
                }
            }
            
            // update global system state variables
            PMLOCK();
            PSYSTEM_POWER_STATE pOldSystemPowerState = gpSystemPowerState;
            PDEVICE_POWER_RESTRICTION pOldCeilingDx = gpCeilingDx;
            if(gpSystemPowerState != NULL
                && (gpSystemPowerState->dwFlags & (POWER_STATE_SUSPEND | POWER_STATE_OFF | POWER_STATE_CRITICAL)) != 0) {
                // we are exiting a suspended state
                fResumeSystem = TRUE;
            }
            gpSystemPowerState = pNewSystemPowerState;
            gpCeilingDx = pNewCeilingDx;
            PMUNLOCK();
            
            // are we suspending, resuming, or neither?
            if(fSuspendSystem) {
                INT iCurrentPriority;

⌨️ 快捷键说明

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