Windows系統剖析[2]-系統機制之物件模型

來源:互聯網
上載者:User
完成第一篇之後,我一直在考慮怎樣來開始後面的內容。怎樣寫好這個系列的難度超過了我所預想的:介紹
一個概括性的結構比較容易,介紹一個具體的系統功能也不難,可是Windows系統不是一個簡單的階層下多個
具體功能實現那麼簡單。如果說第一篇的介紹讓你感覺Windows系統象是在搭積木,那麼接下來幾篇Windows系統
機制方面的介紹,會讓你感覺Windows更象是一鍋粥——有點悲觀,不過,我們的目的,就是鋸開積木,探究其中的
紋理與脈絡。先記住一句話,不管積木是什麼形狀什麼顏色的,本質上它們都是一塊木頭。

     機制,Mechanism。
     金山詞霸云: (1)有機體的構造、功能及其相互關係,如分娩機制;
                       (2)機器的構造和工作原理。如:電腦的機制。
     請你把接下來的幾篇關於Windows機制的內容,當作Windows系統中普遍存在的原理來理解。
    
2、Windows系統機制之一——物件模型
     你一定用過Windows的資源管理員,即便是初學者也要經常點擊案頭上那個“我的電腦”表徵圖。資源管理員中,
電腦內所有的東西都一覽無餘,檔案的開啟、尋找、替換、刪除……還有控制台、網路位置……所有的檔案和控制
命令都是一個按鈕,差不多90%的日常操作都利用它來作為進入點。可是你只是Windows的一個使用者,即便你是
Administrator,你也不過是一個超級使用者,真正在控制電腦的還是Windows,它對你隱瞞了很多,當然,這也
是它的好處之一。我們用資源管理員來管理電腦,Windows則用對象管理器管理電腦的各種資源。先給你一個
利器,讓你看到Windows對你隱瞞的一切,不過,目前還是僅能看看而已。 
   
點擊此處下載:http://www.sysinternals.com/files/winobj.zip

    這個工具是對象查看器WinObj,它直觀的顯示了對象管理器資料庫,注意不要與對象管理器混淆,對象管理器
是Windows的一種機制,實施資源控制操作。請留意對象的組織方式,“\”是根節點,我們平時所見的C盤在對象管理
器中名為“\Device\Harddiskvolume1”,這個是全域命名,很像linux及Unix下以“/”節點為根的分類樹吧?再仔細
看,會發現你平時所見的Windows裝置在\??這個節點下都有對應的對象與之對應。你將硬碟看作分區C、D、E、F……,
Windows將硬碟看作對象\Device\Harddiskvolume1、\Device\Harddiskvolume2、\Device\Harddiskvolume3、
\Device\Harddiskvolume4……,你將串口1看作COM1,Windows將它看作對象\Device\serial0……。你所知道的所有
電腦中的實體,Windows都把它們實現為對象然後當作對象來處理,進程、線程、檔案、驅動、裝置、案頭、事件……
在Windows裡統統是對象,於是有了各種物件控點handle。控制代碼看起來是個32位整數(想起了研一時對控制代碼這個東東
的疑惑),本質上是為了安全的訪問對象而提供的對對象的間接引用。你可以把Windows對象跟普通C++程式的類關聯
起來理解:檔案的建立(CreateFile)會返回一個檔案控制代碼,建立檔案的過程可以理解為類的構造方法,寫檔案、讀檔案
這些操作,其實都是檔案對象的方法。

    好了,廢話說了不少,我們正式開始介紹Windows物件模型。

    Windows為了能夠一致而安全的訪問在執行程式中實現的各種內部服務而實現了物件模型。如前篇所述,執行程
序Executive是核心態的,也就是說在應用層級我們是看不到對象的,只能通過控制代碼handle來實現對對象的訪問。盡
管我們可以在程式中建立檔案,操作檔案,但是實際的操作都是在核心層級完成的,你執行的操作都是Windows給你
規定好的,除了調用它給你提供的函數,你沒有別的選擇,你所拿到的只有一個控制代碼和一組規定好的操作。另一方面,
有些執行程式層級的對象往往包含一些原語層級的對象,由更底層的核心來提供。如此對象就有兩類,執行程式對象
和核心對象。我們不探討核心對象和執行程式對象之間究竟什麼關係,沒有太多意義。我們僅通過討論執行程式對象
讓大家看到對象的一些屬性和操作,對對象有更深的理解,不至於只知道利用handle來執行操作,只知其然而不知其
所以然。 

     維護一份愛情或是友情,往往需要換位思考,我們也來個換位思考,站在Windows設計者的角度思考為什麼要
採用物件模型,物件模型應該具備什麼特性。這樣理解起來至少會少一些莫名其妙。先提需求:

     需求一:電腦擁有各種各樣的資源,不同的資源使用起來的方法是不一樣的,這件事情如果讓應用開發人員來做,
他一定會煩得要死,所以Windows必須提供統一的資源使用機制,這必須對各種資源的共性進行抽象,對象化的方法
無疑是不錯的選擇;

    需求二:Windows 2000的設計目標之一是要實現C2級的安全,簡單點說Windows要對資源採取一定的保護機制,
落實到實現上,必須提供對象的保護屬性和方法; 

    需求三:從磁碟到顯示器,電腦的東東可是太多了,必須採取一定的管理機制,比如對象的分類、統一命名等;

    需求四:每個對象如果僅供一個進程或是僅供核心使用,效率太低浪費嚴重,核心的資訊永遠也傳不到應用程式,
應用程式也訪問不到核心,使用物件模型的重要目標之一就是要通過受保護的對象來完成應用對核心提出請求以及核心
對應用進行服務。因此,一個對象可能同時供核心和多個應用進程使用,必須有一種計數機制來保證對象的生存期。

    對應每個需求,我們自己可以做一些分析和設計,你可能會有比Windows更好的設計方案,如果你真的能設計出可
實現的方案並有能力付諸施行,恭喜,我們國家自己的OS有一定希望了。不過,我們還是先來看看MS的設計吧,下面每
個設計對應上面的每個需求,這些正是Windows上正在運行著的機制。

     設計一:對象要有以下基本屬性:對象名(標識對象)、對象目錄(對象名儲存位置),這兩者類似於檔案管理工具
裡所見的檔案名稱和檔案目錄。所有對象具備的通用操作:關閉(最常用的closehandle函數)、複製、查詢(獲得對象
的屬性資訊)、等待單個對象(用一個對象同步一個線程)、等待多個對象(用多個對象同步一個線程)。出於效能上
的考慮,各類對象有單獨的建立、開啟等操作。
     需要說明一點,對象化的抽象是軟體設計中比較難的問題,而且也沒有統一的標準,不要因為看到只有這幾個有限
的操作就覺得簡單,MS的工程師在這個問題上一定費了不少心思。

     設計二:安全。最常見的安全機制就是多級安全,再具體一點可以明確每個層級能夠做什麼事。Windows對象也是
如此。在對象屬性中包含了一個安全性描述元屬性,通過它來決定誰能使用對象和對對象能執行什麼樣的操作。這個“誰”
可以是進程、線程或是其它的對象,也可以是一個使用者令牌。同時,要增加安全方面的操作,包括查詢安全(取得對象
的安全性描述元)和設定安全(通過修改安全性描述元改變對象的保護屬性)。關於安全方面的詳細內容後面將有專門的篇
章介紹。(這文章寫的比較早了,那時對存取控制的理論和技術理解甚淺,以後撰文另述吧。)

     設計三:對象管理。這就是你在工具WinObj中看到的內容。Windows執行程式共實現了27類物件類型,通過一種
特殊的對象——類型對象來描述這27類對象,在ObjectTypes對象目錄下可以看到。但是很多個物件只能供執行程式自己
使用,比如說驅動對象等。只有對象目錄\??和\BaseNamedObjects下的對象對使用者程式是可見的,不過基本上都是符
號串連,有點類似Linux上的檔案串連。現在對象屬性中又添加了一個物件類型屬性。
     類型對象中包含了某類對象的公有資訊,比如這類對象的訪問類型(唯讀還是可讀可寫)、該類對象可在的記憶體類
型(是頁式記憶體還是非頁式記憶體)、該類對象的方法(如前述所言,有些操作是按對象的不同類型分別實現的,這是一
些常式,定義了在執行比如對象的開啟、關閉等操作時應該做什麼)。

     設計四:對象計數。進程和核心都使用對象,進程使用對象是通過物件控點,核心使用對象則直接通過引用。在對
象屬性中添加三個屬性,開啟的控制代碼數,開啟的控制代碼數鏈表(裡面記錄是哪些進程開啟了該對象的控制代碼)和引用計數(記
錄了核心對該對象的引用次數)。每有一個進程開啟該對象,則開啟的控制代碼數加1,同時引用計數加1,而核心對對象的
引用次數增加僅僅增加引用計數。開啟的控制代碼數和引用計數都為0時才關閉該對象,釋放資源。

 

     經過如上的分析,Windows對象的基本結構出來了。如附圖示,一個對象由對象頭和對象體構成,上述內容主要在
對象頭內,是每個Windows對象的公用屬性。Windows對象管理器通過對象頭來管理對象而不考慮物件類型。對於相同
的物件類型而言,對象體的格式都是相同。
     如前所述,對象擁有對開啟它控制代碼的進程的記錄,而Windows進程中則擁有一個進程控制代碼表,記錄著該進程開啟的
所有的物件控點。進程控制代碼表採用3級方案實現,很類似x86記憶體管理器實現虛擬位址到物理地址記憶體的轉換。這一點在
後面討論進程結構時將再次提到。

     本篇主要討論了Windows物件模型,內容比較抽象,我絞盡腦汁以資源管理員做為一個對比,但是總覺有不當之處。
對象是位於檔案、裝置、進程等這些比較具體內容之後的、對使用者層級不可見的一種抽象化的機制。編程時直接面對的
還是這些具體內容,我想要陳述的是這些具體內容的規律,比如對檔案、進程等進行訪問時,都是首先獲得控制代碼,然後
要提供訪問方式,還要有存取權限位,訪問完畢要關閉控制代碼。一個新手面對浩瀚的MSDN和SDK文檔望洋興歎,老手程式
寫多了會說這些東西都差不多,深究起來也是茫然。本文旨在協助大家看到本質,不指導具體編程也不解決實際問題。
其實,如果對Windows的機制理解夠深,解決具體問題的方案會比較容易的出現在你腦子裡,剩下的就是寫程式了,注
意不要眼高手低即可。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.