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

📄 platform.cpp

📁 LX 800 WindowsCE 6.0 BSP
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                PMLOGMSG(ZONE_PLATFORM || ZONE_RESUME, 
                    (_T("%s: suspending - notifying non-block drivers\r\n"), pszFname));
                for(pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext) {
                    if(*pdl->pGuid != idBlockDevices) {
                        UpdateClassDeviceStates(pdl);
                    }
                }
                
                // Notify the kernel that we are about to suspend.  This gives the
                // kernel an opportunity to clear wake source flags before we initiate
                // the suspend process.  If we don't do this and a wake source interrupt
                // occurs between the time we call PowerOffSystem() and the time 
                // OEMPowerOff() is invoked it is hard for the kernel to know whether or
                // not to suspend.
                PMLOGMSG(ZONE_PLATFORM || ZONE_RESUME, 
                    (_T("%s: calling KernelIoControl(IOCTL_HAL_PRESUSPEND)\r\n"), pszFname));
                KernelIoControl(IOCTL_HAL_PRESUSPEND, NULL, 0, NULL, 0, NULL);
                iCurrentPriority = CeGetThreadPriority(GetCurrentThread());
                DEBUGCHK(iCurrentPriority != THREAD_PRIORITY_ERROR_RETURN);
                if(iCurrentPriority != THREAD_PRIORITY_ERROR_RETURN) {
                    CeSetThreadPriority(GetCurrentThread(), giPreSuspendPriority);
                    Sleep(0);
                    CeSetThreadPriority(GetCurrentThread(), iCurrentPriority);
                }

                // Notify file systems that their block drivers will soon go away.  After making
                // this call, this thread is the only one that can access the file system
                // (including registry and device drivers) without blocking.  Unfortunately,
                // this API takes and holds the file system critical section, so other threads
                // attempting to access the registry or files may cause priority inversions.
                // To avoid priority problem that may starve the PM, we may raise our own priority
                // to a high level.  Do this if giSuspendPriority is non-zero.
                if(giSuspendPriority != 0) {
                    iPreSuspendPriority = CeGetThreadPriority(GetCurrentThread());
                    DEBUGCHK(iPreSuspendPriority != THREAD_PRIORITY_ERROR_RETURN);
                    PMLOGMSG(ZONE_PLATFORM, 
                        (_T("%s: suspending: raising thread priority for 0x%08x from %d to %d\r\n"),
                        pszFname, GetCurrentThreadId(), iPreSuspendPriority, giSuspendPriority));
                    CeSetThreadPriority(GetCurrentThread(), giSuspendPriority);
                }
                FileSystemPowerFunction(FSNOTIFY_POWER_OFF);
                gfFileSystemsAvailable = FALSE;

                // update block device power states
                PMLOGMSG(ZONE_PLATFORM || ZONE_RESUME, 
                    (_T("%s: suspending - notifying block drivers\r\n"), pszFname));
                pdl = GetDeviceListFromClass(&idBlockDevices);
                if(pdl != NULL) {
                    UpdateClassDeviceStates(pdl);
                }
                
                // Handle resets and shutdowns here, after flushing files.  Since Windows CE does
                // not define a standard mechanism for handling shutdown (via POWER_STATE_OFF),
                // OEMs will need to fill in the appropriate code here.  Similarly, if an OEM does
                // not support IOCTL_HAL_REBOOT, they should not support POWER_STATE_RESET.
                if((dwNewStateFlags & POWER_STATE_RESET) != 0) {
                    // is this to be a cold boot?
                    if(_tcscmp(pszName, _T("coldreboot")) == 0) {
                        SetCleanRebootFlag();
                    }

                    // should not return from this call, but if we do just suspend the system
                    KernelLibIoControl((HANDLE)KMOD_OAL, IOCTL_HAL_REBOOT, NULL, 0, NULL, 0, NULL);
                    RETAILMSG(TRUE, (_T("PM: PlatformSetSystemPowerState: KernelIoControl(IOCTL_HAL_REBOOT) returned!\r\n")));
                    DEBUGCHK(FALSE);        // break into the debugger
                } 
            } else if(fResumeSystem) {
                // we're waking up from a resume -- update block device power states
                // so we can access the registry and/or files.
                PMLOGMSG(ZONE_PLATFORM || ZONE_RESUME, 
                    (_T("%s: resuming - notifying block drivers\r\n"), pszFname));
                pdl = GetDeviceListFromClass(&idBlockDevices);
                if(pdl != NULL) {
                    UpdateClassDeviceStates(pdl);
                }
                
                // Notify file systems that their block drivers are back.
                FileSystemPowerFunction(FSNOTIFY_POWER_ON);
                gfFileSystemsAvailable = TRUE;
                
                // update all devices other than block devices
                PMLOGMSG(ZONE_PLATFORM || ZONE_RESUME, 
                    (_T("%s: resuming - notifying block drivers\r\n"), pszFname));
                for(pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext) {
                    if(*pdl->pGuid != idBlockDevices) {
                        UpdateClassDeviceStates(pdl);
                    }
                }
                // tell gwes to wake up
                if(gpfnGwesPowerUp != NULL && gfGwesReady) {
                    gpfnGwesPowerUp(fWantStartupScreen);
                    fWantStartupScreen = FALSE;
                }
                // send out resume notification
                pbb.Message = PBT_RESUME;
                pbb.Flags = 0;
                pbb.Length = 0;
                pbb.SystemPowerState[0] = 0;
                GenerateNotifications((PPOWER_BROADCAST) &pbb);
            } else {
                // update all devices without any particular ordering
                UpdateAllDeviceStates();
            }
            
            // release the old state information
            SystemPowerStateDestroy(pOldSystemPowerState);
            while(pOldCeilingDx != NULL) {
                PDEVICE_POWER_RESTRICTION pdpr = pOldCeilingDx->pNext;
                PowerRestrictionDestroy(pOldCeilingDx);
                pOldCeilingDx = pdpr;
            }
            
            // are we suspending?
            if(fSuspendSystem) {
                // Once file systems are disabled, discard code pages from drivers.  This
                // is a diagnostic tool to forcibly expose paging-related bugs that could 
                // cause apparently random system crashes or hangs.  Optionally, OEMs can
                // disable this for production systems to speed up resume times.
                if(gfPageOutAllModules) {
                    BOOL fOk = PageOutModule(GetCurrentProcess(), PAGE_OUT_ALL_DEPENDENT_DLL);
                    DEBUGCHK(fOk);                    
                }

                // 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;
                gfPasswordOn = 0 ;
            }
            else {
                PMLOCK();
                if ( fPasswordOn != gfPasswordOn ) {
                    if (gfGwesReady && gpfnShowStartupWindow && fPasswordOn )
                        gpfnShowStartupWindow();
                    gfPasswordOn = fPasswordOn;
                }
                PMUNLOCK();
            }
        } 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);
    }
    
    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 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 hqNotify = NULL;
    HMODULE hmCoreDll = NULL;
    SETFNAME(_T("PlatformManageSystemPower"));
    
    PMLOGMSG(ZONE_INIT || ZONE_PLATFORM, (_T("+%s\r\n"), pszFname));
        
    // 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 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);
        }
    }
            
    if (!fDone) {
        DefaultPowerStateManager *pPowerStateManager = CreateDefaultPowerManager( NULL );
        if (pPowerStateManager && pPowerStateManager->Init()) {
            g_pPowerStateManager = pPowerStateManager ;
            // we're up and running
            SetEvent(hevReady);
            g_pPowerStateManager->ThreadRun() ;
        }
        else {
            ASSERT(FALSE);
            if (pPowerStateManager)
                delete pPowerStateManager;
            PMLOGMSG(ZONE_INIT || ZONE_ERROR, (_T("%s: PowerStateManager Intialization Failed!!!\r\n"), pszFname));
        }
        if (g_pPowerStateManager) {
            delete g_pPowerStateManager;
            g_pPowerStateManager = 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"));
    
    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 (g_pPowerStateManager) {
        g_pPowerStateManager->PlatformResumeSystem(gfSystemSuspended);
    }
    PMLOGMSG(ZONE_RESUME, (_T("-%s\r\n"), pszFname));
}

DWORD WINAPI PlatformSendSystemPowerState(LPCWSTR pwsState, DWORD dwStateHint, DWORD dwOptions)
{
    DWORD dwReturn = ERROR_GEN_FAILURE;
    if (g_pPowerStateManager) {
        dwReturn = g_pPowerStateManager->SendSystemPowerState(pwsState, dwStateHint, dwOptions );
    }
    return dwReturn;
}

⌨️ 快捷键说明

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