日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

内核对象——Windows核心编程学习手札系列之三

發布時間:2025/4/16 windows 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 内核对象——Windows核心编程学习手札系列之三 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

內核對象

——Windows核心編程學習手札系列之三

內核對象可供系統和應用程序使用來管理各種各樣的資源,如進程、線程、文件等,是內核分配的一個內存塊,只能又內核訪問,該內存塊是一種數據結構,它的成員負責維護該對象的各種信息。內核對象的數據結構,也就是內存塊是不允許應用程序直接修改其內容,而由Windows提供一組函數進行訪問,創建內核對象的函數會返回對象的句柄,該句柄對于進程中的任何線程都可見,這個句柄傳遞給Windows各個函數,操作系統就知道要操作的內核對象。內核句柄與進程相關,如果跨越進程調用句柄可能會失敗,如何實現多進程共享單個內核對象需要一定機制,后文將提到。

內核對象為內核所擁有,而非進程。如果一個進程創建了內核對象,在進程終止運行后內信對象不一定被撤消。內核通過內核對象類型中的常用數據成員使用計數知道有多少個進程正在使用該內核對象。當進程終止時,內核會對使用計數進行減一操作,如果到零則撤消該對象,確保在沒有任何進程引用該對象情況下系統中不保留該內核對象。

創建內核對象的函數都有一個SECURITY_ATTRIBUTES結構的指針作為參數,其結構成員lpSecurityDescriptor與內核對象安全性有關。安全描述符描述了誰創建了內核對象,誰可以訪問或使用該對象。這里可以通過設置SECURITY_ATTRIBUTES結構內lpSecurityDescriptor成值來滿足。對于用戶對象或圖形設備接口(菜單、窗口、光標、字體等)的創建函數是不需要設定安全屬性的信息,而內核對象則需要。

進程初始化時,操作系統會為其分配一個句柄表,該表用于設置內核對象數據結構的內存地址、訪問權限以及繼承等標志位。進程的線程在創建內核對象時,內核為其分配內存塊并初始化并到進程的句柄表中掃描空項并設置相關信息。當進程調用BOOL CloseHandle(HANDLE hobj)函數結束內核對象時,函數也會先檢查進程句柄表,以標識進程無權訪問該對象,同時獲得內核對象數據結構地址中使用計數的數據成員,如為零則從內存中撤消該內核對象。當然,如果忘記調用CloseHandle函數將導致內存泄露的可能,不過僅存在進程運行時才會發生。因為一旦進程終止運行,操作系統將對進程內的任何資源進行釋放,體現在內核對象的釋放上就是通過訪問進程句柄表;當進程終止運行,系統會掃描進程句柄表,如果該表仍有無效項目(終止進程前沒有關閉的對象),系統將自動關閉這些對象,如果這些對象的使用計數為零則由內核撤消該對象。

不同進程中運行的線程在如下情況中需要共享內核對象:文件映射對象使你能夠在同一臺機器上運行的兩個進程之間共享數據塊;郵箱或指定的管道使得應用程序能夠在聯網的不同機器上運行的進程之間發送數據塊;互斥對象、信標和事件使得不同進程中線程能夠同步它們的連續運行,這與一個應用程序在完成某項任務時需要通知另一個應用程序的情況相同。總的來說是數據共享、數據發送、同步控制三方面的需要。

內核對象句柄的繼承性,內核對象句柄是和進程相關的。當父進程創建內核對象句柄時,向操作系統指明對象句柄是個可繼承的句柄,通過對SECURITY_ATTRIBUTES結構中bInheritHandle設置來實現,這將對進程句柄表中繼承標志位設為1。內核對象本身不具備繼承性,但內核對象句柄具有繼承性。父進程中設置了該對象句柄可繼承,那么在創建子進程的函數CreateProcessbInheritHandle參數也需要設為TRUE,這時操作系統同樣為子進程分配新的和空的句柄表之外還會遍歷父進程句柄表,拷貝父進程有效的可繼承的句柄項目到子進程句柄表中,同時遞增內核對象的使用計數。對于已經運行的子進程,父進程正創建的帶有可繼承句柄的新內核對象是無法繼承的,也就是說對象句柄的繼承性只有在生成子進程時候才能使用。若要改變句柄標志,可通過SetHandleInformation函數:

BOOL SetHandleInformation( HANDLE hObject,DWORD dwMask,DWORD dwFlags);

第一個參數hObject是一個有效句柄;第二個參數dwMask告訴函數想要改變哪個標志,目前有兩個標志與每個句柄關聯,#define HANDLE_FLAG_INHERIT 0x00000001/#define HANDLE_FLAG_PROTECT_FROM_CLOSE 0x00000002,同時改變這兩個標志可用OR連接起來;第三個參數是dwFlags指明想將標志設置成什么值,如要打開一個內核對象句柄的繼承標志,可用下面代碼:

SetHandleInformation(hObj,HANDLE_FLAG_INHERIT,HANDLE_FLAG_INHERIT);

若要關閉標志,則:

SetHandleInformation(hObj,HANDLE_FLAG_INHERIT,0);

HANDLE_FLAG_PROTECT_FROM_CLOSE標志用于告訴系統,該句柄不應被關閉:

SetHandleInfomation(hObj,HANDLE_FLAG_PROTECT_FROM_CLOSE,HANDLE_FLAG_PROTECT_FROM_CLOSE);

CloseHandle(hObj);

如果一個線程試圖關閉一個受保護的句柄,CloseHandle會產生一個異常條件。當然可以通過GetHandleInformation來獲取句柄的標志是否滿足可繼承性,如下面:

DWORD dwFlags;

GetHandleInformation(hObj,&dwFlags);

BOOL fHandleIsInheritable=(0!=(dwFlags & HANDLE_FLAG_INHERIT));

if(fHandleIsInheritable) //可繼承

else //不可繼承

給對象命名是實現共享跨越進程邊界內核對象的第二種方法。對對象命名,而后要共享者打開該名字,即可共享該對象。服務器的名字命名空間對象是放在全局名字空間中,按照默認設置,在終端服務器中,應用程序的命名內核對象將放入會話的名字空間中。將命名對象置于全局名字空間的代碼:

HANDLE h=CreateEvent(NULL,FALSE,FALSE,”Global//myname”);

將內核對象放入會話的名字空間代碼:

HANDLE h=CreateEvent(NULL,FALSE,FALSE,”Local//myname”);

終端服務器擁有內核對象的多個名字空間,全局名字空間和會話名字空間。全局名字空間意味著所有客戶程序都可以訪問,該名字空間主要供服務程序使用;而會話名字空間則屬于每個客戶程序自己的名字空間,可防止運行相同應用程序的兩個或多個會話之間出現互相干擾情況,一個會話無法訪問另一個會話的對象,盡管對象之間可能擁有相同名字。MicrosoftGolbalLocal作為保留關鍵字。

復制對象句柄是共享跨越進程邊界內核對象最后方法:

BOOL DuplicateHandle(

??????????? HANDLE hSourceProcessHandle,

??????????? HANDLE hSoruceHandle,

??????????? HANDLE hTargetProcessHandle,

?????? ?????PHANDLE phTargetHandle,

??????????? DWORD dwDesiredAccess,

??????????? BOOL? bInheritHandle,

??????????? DWORD dwOptions);

這個函數將一個進程句柄表中的項目取出,拷貝到另一個進程的句柄表中。例子:Process S擁有對一個內核對象的訪問權,想讓Process T能夠訪問該對象:

//All of the following code is executed by Process S

//Create a mutex object accessible by Process S

HANDLE hObjProcessS=CreateMutex(NULL,FALSE,NULL);

//Open a handle to Process T’s kernel object.

HANDLE hProcessT=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessIDT);

HANDLE hObjProcessT;//An uninitialized handle relative to Process T

//Give Process T access to our mutex object.

DuplicateHandle(GetCurrentProcess(),hObjProcessS,hProcessT,&hObjProcessT,0,FALSE,

????????????? DUPLICATE_SAME_ACCESS);

//Use some IPC mechanism to get the handle

//value in hObjProcessS into Process T

……

//We no longer need to communicate with ProcessT.

CloseHandle(hProcessT);

……

//When Process S no longer needs to use the mutex,ti should close it

CloseHandle(hObjProcessS);

IPC(Internet Process Connection)是共享"命名管道"的資源,它是為了讓進程間通信而開放的命名管道,通過提供可信任的用戶名和口令,連接雙方可以建立安全的通道并以此通道進行加密數據的交換,從而實現對遠程計算機的訪問。

??????????????? 如非 2008-11-25

總結

以上是生活随笔為你收集整理的内核对象——Windows核心编程学习手札系列之三的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。