您的位置:首页 > 编程语言

WM/WINCE代码研读系列之Power Management(5)

2009-11-21 11:02 411 查看
下面是pNewPowerState->EnterState的具体内容
pNewPowerState->EnterState

{
PmSetSystemPowerState_I(GetStateString(),0 ,0, TRUE);
{
if (((!_tcsicmp(szStateName,_T("suspend"))) || (dwStateHint==POWER_STATE_OFF)) &&(fInternal==TRUE))
{
//将用户关闭系统的消息写入周日志里面
PMSQM_Set(PMSQM_DATAID_POWER_USER_SHUTDOWNS,1);
}

PlatformSetSystemPowerState
{
/*将TEXT("HKEY_LOCAL_MACHINE//SYSTEM//CurrentControlSet//Control//Power//State//$(SystemPowerState的Name)")下的_T("Default")值赋值给psps->defaultCeilingDx(在当前系统电源状态下的所有设备的默认的最大电源级别);_T("Flags")值赋值给psps->dwFlags;
TEXT("HKEY_LOCAL_MACHINE//SYSTEM//CurrentControlSet//Control//Power//State//$(SystemPowerState的Name)//$(Device的Name)")下的子键的名字和由它转化成的GUID赋值给pdpr->pDeviceId,子键的值赋值给pdpr->devDx
将{A32942B7-920C-486b-B0E6-92A702A99B35} (这个GUID表征generic power-managed devices)这个GUID赋值给pdpr->pDeviceId子键下的值赋值给pdpr->devDx(这是当前系统电源状态下的某一个或某一类设备的特定的最大电源级别)
*/
PmUpdateSystemPowerStatesIfChanged
RegReadSystemPowerState

//将PBT_TRANSITION消息发送给所有注册了相应电源管理通知事件的驱动
pbb.Message = PBT_TRANSITION;
pbb.Flags = pNewSystemPowerState->dwFlags;
pbb.Length = _tcslen(pNewSystemPowerState->pszName) + 1;
_tcsncpy(pbb.SystemPowerState,pNewSystemPowerState->pszName, pbb.Length);
pbb.Length *= sizeof(pbb.SystemPowerState[0]);
GenerateNotifications((PPOWER_BROADCAST) &pbb);

//更新所有Classes的设备的电源状态
UpdateAllDeviceStates();
{
//从gpDeviceLists中遍历各个Device interface classes
for(pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext)
{
UpdateClassDeviceStates(pdl);
{
pds = pdl->pList; //pdl中再遍历各个Device
while(!fDeviceRemoved && pds != NULL)
{
UpdateDeviceState(pds)
pdsNext = pds->pNext;
}
}
}
}

//下面就SUSPEND和Resuming这两种特殊情况分别讨论

//1.Suspended
if((dwNewStateFlags &(POWER_STATE_SUSPEND|POWER_STATE_OFF|
POWER_STATE_CRITICAL|POWER_STATE_RESET)) != 0)
fSuspendSystem = TRUE;
GwesPowerDown() //关掉GWES

//关闭除了idBlockDevices Class的设备以外的所有设备电源状态。因为这个时候还要访问注册表,写文件。所以与此相关的idBlockDevices 的电源状态还应暂时不变.
for(pdl = gpDeviceLists;pdl != NULL;pdl = pdl->pNext)
{
if(*pdl->pGuid != idBlockDevices)
UpdateClassDeviceStates(pdl);
}

//这里会调用IOCTL_HAL_PRESUSPEND,在进入Suspended之前给OEM一个机会去设置一些东西。微软建议OEM实现IOCTL_HAL_PRESUSPEND时清掉唤醒标示。并且强制来一次线程调度
KernelIoControl(IOCTL_HAL_PRESUSPEND,NULL,0,NULL,0, NULL);
iCurrentPriority = CeGetThreadPriority(GetCurrentThread());
CeSetThreadPriority(GetCurrentThread(),giPreSuspendPriority);
Sleep(0);
CeSetThreadPriority(GetCurrentThread(),iCurrentPriority);

//如果[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power]下有L"PageOutAllModules"则
if(gfPageOutAllModules)
PageOutModule(GetCurrentProcess(),PAGE_OUT_ALL_DEPENDENT_DLL);
//这个用来找出哪个驱动错误的使用了pageable机制

FileSystemPowerFunction(FSNOTIFY_POWER_OFF); //关闭文件系统

//关闭block device的电源
pdl = GetDeviceListFromClass(&idBlockDevices);
UpdateClassDeviceStates(pdl);

//下面是重启的情况
if((dwNewStateFlags & POWER_STATE_RESET) != 0)
{
//如果是冷启动则CleanReBoot
if(_tcscmp(pszName, _T("coldreboot")) == 0)
SetCleanRebootFlag();

//调用OEM去实现的IOCTL_HAL_REBOOT,这个函数不应该返回。
KernelLibIoControl((HANDLE)KMOD_OAL,IOCTL_HAL_REBOOT,NULL,0,NULL,0,NULL);
}

//设置标志位并调PowerOffSystem,这个函数最终会调到OEMPowerOff()
gfSystemSuspended = TRUE;
PowerOffSystem();

Sleep(0); //CPU唤醒后强制来此系统调度
gfSystemSuspended = FALSE; // clear the suspend flag
gfPasswordOn = 0;

//2. Resuming
//打开block device的电源
pdl = GetDeviceListFromClass(&idBlockDevices);
UpdateClassDeviceStates(pdl);

//打开文件系统
FileSystemPowerFunction(FSNOTIFY_POWER_ON);
//打开除了idBlockDevices Class的设备以外的所有设备电源状态
for(pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext)
{
if(*pdl->pGuid != idBlockDevices)
UpdateClassDeviceStates(pdl);
}

gpfnGwesPowerUp(fWantStartupScreen); //唤醒GWES

//将PBT_RESUME消息发送给所有注册了相应电源管理通知事件的驱动
pbb.Message = PBT_RESUME;
pbb.Flags = 0;
pbb.Length = 0;
pbb.SystemPowerState[0] = 0;
GenerateNotifications((PPOWER_BROADCAST) &pbb);

}
}

m_LastNewState = GetState();//更新电源状态标志
//激活UserActivity事件
m_dwEventArray[PM_USER_ACTIVITY_EVENT] = m_pPwrStateMgr->GetUserActivityTimer()->hevActive;
//重新校正BacklightTimeout,SuspendTimeout,UserIdleTimeout这三个超时器
m_pPwrStateMgr->ReAdjustTimeOuts();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: