1.什麼是內核對象:
首先是一個對象,比如時間對象,文件對象,作業對象,信箱對象,互斥對象,管道對象,進程對象等等都是一個內核對象,用於地層處理邏輯的對象,而內核對象只能被內核訪問,應用程序不能直接改變他們的內容,但是windows給我們提供了一組函數,以便我們使用方法進行操作:一般都是先調用CreateXXX函數,返回句柄,句柄是一個不透明值,並非是創建的內核對象的指針,實際是進程句柄表的表示,後面提到了過程。
2.內核對象的引用計數:
有點類似智能指針shareptr,內核對象是內核所擁有,不是由進程擁有,進程創建內核對象,那麼內核對象的計數加1,如果終止進程,內核獨享引用計數減1,只有所有進程都不適用該內核對象,內核對象的引用爲0,被銷燬。
3.創建內核對象:
當創建內核對象時,需要調用一些函數:
HANDEL CreateThread(
PSECURITY_ATTRIBUTES psa, // 安全權限,使用該內核對象時,權限不足不能使用
DWORD dwStackSize,
LPTHREAD_START_ROUTINE pfnStartAddr,
PVOID pvParam,
DWORD dwCreationFlags,
PDWORD pdwThreadId);
每個進程都有一個句柄表,當進程未初始化時,句柄表是空的,調用某個創建內核對象後,把創建的內核對象的指針放到句柄表裏,然後返回給應用程序句柄表中的索引,這樣應用程序通過句柄表的索引,找到指針,在通過指針真正調用內核對象。
4.關閉內核對象:
創建和關閉是一對的,在使用完畢內核對象之後,要記得關閉內核對象:
BOOL CloseHandle(HANDLE hobj);
調用之後,內核對象的的引用計數減1,如果引用計數爲0了,就回收該內核對象。
如果漏掉調用,那麼在進程關閉的時候,也會回收所有未釋放的資源,也會嘗試回收改內核對象。
5 跨越進程邊界共享內核對象:
有時候,希望兩個進程共享同一個對象,比如文件映射對象可以在同一個機器上運行兩個進程之間的共享數據塊等,那麼是如何達到共享內存對象的效果。
a.根據內核對象的繼承性:當進程具有父子關係,即父進程在調用CreateProcess,創建子進程時,子進程在創建過程中,會先遍歷父進程的句柄表,根據句柄表中是否可以繼承標誌,來決定是否複製到自己的進程的句柄表中,如果繼承,則把指針等數據複製到自己句柄表,這樣兩個進程句柄就是相同的。
b.命名空間:在創建內核對象時,有寫函數可以傳遞字符串,實際是給該內核對象命名,命名空間具有唯一性。如果系統內有相同名字的內核對象,但是訪問權限或者對象類型不同,那麼第二個創建同名字的內核對象將會返回失敗。否則,並非創建一個內核對象,而是把內核對象的指針等信息複製到自己的句柄表,此時兩個句柄表的內核對象句柄可能不同。這與上面繼承是有區別的。
c.複製對象句柄:調用函數DuplicateHandle函數,
BOOL DuplicateHandle(
HANDLE hSourceProcessHandle, // 自身進程句柄
HANDLE hScoureHandle, // 要拷貝的內核對象的句柄
HANDLE hTargetProcessHandle, // 目標進程的句柄
PHANDLE phTargetHandle, // 返回拷貝的內核對象在目標進程的句柄
DWORD dwDesiredAccess, // 表示屏蔽值和繼承性標誌
BOOL bInheritHandle,
DWORD dwOptions);
學習書籍:windows核心編程