[轉]Windows關機過程分析與快速關機


  Windows開機和關機慢,很多時候慢得令人抓狂。特別是做嵌入式開發時(如XPE和WinCE),任誰都無法忍受開發出來的設備開關機的蝸牛速度。所以我們得為她加速。采用HORM是不錯的方案,因為是直接從休眠文件中恢復系統現場,開機速度快了不少。采用HORM方案后,Windows默認的關機過程中,很多步驟對我們的設備來說,是完全不需要的,我們需要直接斷電關機。本文將分析Windows的關機過程,然后介紹如何使用Windows未公開的API實現直接斷電關機。

   一、Windows關機過程

   簡單地說,在Windows關機時,系統做了以下工作: 

   1. 軟保護  首先先結束登錄用戶打開的所有程序,保存用戶的設置和系統設置,然后停止系統服務和操作系統大部分進程。

  2. 硬保護 復位硬件,如復位磁盤的磁頭、停止硬件驅動程序等。

  3. 斷電 斷開主板給各硬件設備的電源。當然這步需要主板的電源管理模塊支持,一般來說,ATX電源和主板都支持軟斷電。

  在整個關機過程中,軟保護是最耗時的,少則五六秒,多則上分鍾。剛安裝的操作系統,因為未安裝驅動和開啟額外的系統服務,關機非常快。開啟服務一多,關機就慢下來了,特別是安裝了有Bug的驅動,問題可能更糟。

   二、軟保護

  為了保證數據的完整性,軟保護是必須的,不管是操作系統本身還是第三方的應用程序。

  軟保護的步驟有:

  1. 用戶發起關機指令以后,發起關機指令的程序會通知Windows子系統CSRSS.EXE,CSRSS.EXE收到通知以后會和Winlogon.EXE做一個數據交換,接着由Winlogon.EXE通知CSRSS.EXE開始關閉系統的流程 。

  2. CSRSS.EXE收到Winlogon.EXE的通知以后,會依次查詢擁有頂層窗口的用戶進程,讓這些用戶進程退出。如果某一個用戶進程在一個默認的超時時間5000毫秒(可以通過修改注冊表鍵值HKEY_CURRENT_USER/Cont rol Panel/Desktop/ HungAppTimeout設定超時時間)內沒有退出的話,Windows會顯示一個結束任務對話框用於詢問用戶是否結束這個任務。默認情況下將顯示這個對話框並一直保持而不會自動關閉。對於控制台程序來說,基本情況類似,只不過Windows使用HK EY_CURRENT_USER/Control Panel/Desktop/ WaitToKillAppTimeout值來設置超時時間。

  3. 接着是輪到終止系統進程了。系統進程包括SMSS.EXE、Winlogon.EXE、Lsass.EXE等。Windows在終止系統進程的時候並不像終止用戶進程那樣如果無法在規定時間內終止則提示用戶,而是跳過這個進程,去執行下一個系統 進程的終止操作。使用的超時時間和第2步使用的時間相同。

  三、硬保護和斷電

  在完成軟保護過程后,Winlogon.EXE調用一個原生API函數ZwShutdownSystem()或NtShutdownSystem()來命令系統執行后面的掃尾工作,包括上面提到的硬保護和ATX斷電。

  在ZwShutdownSystem函數調用過程中,Windows執行子系統會完成最后的關機操作,例如:設備驅動在這個階段里面完成一些驅動設定的特殊操作;也是在這個階段,配置管理系統將被修改過的注冊表數據會寫道磁盤里面。等除了電源管理以后的全部子系統完成退出以后,電源管理完成最后的操作,如重啟、關機等。

  四、響應關機事件

  不管是直接按機箱上的Power按鈕,還是點擊開始菜單->關閉計算機(注銷、關機、重啟),我們的應用程序都可以響應這類事件,那就是窗口消息WM_QUERYENDSESSION和WM_ENDSESSION。

  系統提供了一個常用的API實現系統的注銷、關機和重啟,它的聲明為:
  BOOL ExitWindowsEx(  UINT uFlags,  DWORD dwReason);

  參數uFlags可分為兩類,之間可以用“|”合並:

  1. 關閉動作,有以下標志:EWX_LOGOFF(注銷)、EWX_SHUTDOWN(關閉系統后不切斷電源,即使主板支持ATX電源管理)、EWX_POWEROFF(關機,關閉系統后切斷電源,需主板支持)、EWX_REBOOT(重啟)。

  2. 關閉強度,有以下標志:數值0(安全關閉,不使用該類標志時默認為該項)、EWX_FORCEIFHUNG(應用程序掛起一段時間后強行關閉)、EWX_FORCE(強行關閉,不管應用程序有沒有掛起)。

  如果不使用關閉強度標志(EWX_FORCE或EWX_FORCEIFHUNG),關機是安全的,也就是說,在關機的軟保護時,系統將給每個以桌面為頂級的窗口進程發送WM_QUERYENDSESSION消息。如果超過5000毫秒(可以通過修改注冊表鍵值HKEY_CURRENT_USER/Cont rol Panel/Desktop/ HungAppTimeout設定超時時間)仍未有WM_QUERYENDSESSION消息的返回,則彈出結束任務對話框用於詢問用戶是否結束這個任務。默認情況下將顯示這個對話框並一直保持而不會自動關閉;如果設置了自動結束任務(HKEY_CURRENT_USER/Cont rol Panel/Desktop/AutoEndTasks鍵值改為1),那么超時(HungAppTimeout)后仍未有WM_QUERYENDSESSION消息的返回值時,不再顯示結束任務對話框而直接結束這個掛起的任務。如果多個進程響應了WM_QUERYENDSESSION並掛起(如記事本彈出詢問是否保存的消息框),那么系統對於每個進程是串行處理的,即等待第一個掛起的進程響應WM_QUERYENDSESSION並返回后(立即發送WM_ENDSESSION通知同一窗口用戶的選擇<是否確認關閉>),再給下一個進程發送WM_QUERYENDSESSION並等待掛起超時。

  需要注意的是,不管是點擊系統彈出的結束任務對話框上的確定按鈕,還是系統超時自動結束所有任務(已設置AutoEndTasks),那么掛起后的WM_QUERYENDSESSION和WM_ENDSESSION響應代碼不會被執行。

  五、直接斷電關機

  如上分析,如果您不在乎應用程序的數據丟失和操作系統的系統文件破壞(可能進不了系統),您完全可以把關機的軟保護過程省略,來加快關機的速度。網上已經有許多快速關機軟件,就是直接調用ntdll.dll中的ZwShutdownSystem()實現的。當然Windows系統本身也提供了這樣的功能讓您有選擇地快速關機:打開任務管理器,按住鍵盤的Ctrl鍵,同時點擊菜單“關機”-“關閉(或重啟)”,即可在一兩秒內立即斷電關機。
  程序實現斷電關機的代碼如下:

const int SE_SHUTDOWN_PRIVILEGE = 0x13;
typedef int (__stdcall *PFN_RtlAdjustPrivilege)( INT, BOOL, BOOL, INT*);
typedef int (__stdcall *PFN_ZwShutdownSystem)(INT);
HMODULE hModule = ::LoadLibrary(_T("ntdll.dll"));
// 因為這里涉及到的函數都是微軟未公開的,所以只能動態調用
if( hModule != NULL)
{
PFN_RtlAdjustPrivilege pfnRtl = (PFN_RtlAdjustPrivilege)GetProcAddress( hModule, "RtlAdjustPrivilege");
PFN_ZwShutdownSystem pfnShutdown = (PFN_ZwShutdownSystem)GetProcAddress( hModule,"ZwShutdownSystem");
if( (pfnRtl != NULL) && (pfnShutdown != NULL ))
{
int en = 0;
int nRet= pfnRtl( SE_SHUTDOWN_PRIVILEGE, TRUE, TRUE, &en);
if( nRet == 0x0C000007C )
nRet = pfnRtl(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &en);
//SH_SHUTDOWN = 0;
//SH_RESTART = 1;
//SH_POWEROFF = 2;
const int SH_POWEROFF = 2;
nRet = pfnShutdown(SH_POWEROFF);
}
}

  

  補充,請注意文中提到的兩個消息:WM_QUERYENDSESSION 和 WM_ENDSESSION
  今天在測試程序的時候,因為主程序里有一個while(1)循環,最后在關閉電腦的時候就會出現上面提到的情形,出現一個對話框,后來查閱資料發現沒有處理到WM_DESTROY消息,后來又發現用自定義消息替換了系統消息之后還是不行,因為我的窗口過程是動態創建的,當沒有窗口過程時系統關機還是會彈出一個對話框。最后想到一個辦法,創建兩個窗口過程,可是在另外一個窗口中捕獲不到WM_DESTROY消息,最后分析Windows系統關機過程找到了WM_QUERYENDSESSION消息,於是在非動態創建的窗口過程中添加這個消息的處理就搞定了,系統退出時不會彈出提示框。
  知識就是在發現問題,查閱資料,解決問題,做好記錄的情形下學得的。

【參考資料 感謝作者】
1、 Windows關機過程分析與快速關機 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM