簡單地說:
核心對象是系統的一種資源。系統對象一旦產生,任何應用程式都可以開啟並且使用該對象。系統給核心對象一個計數值作為管理只用,核心對象包括:
event,mutex,semaphore,file,file-mapping,preocess,thread.
這些核心對象每次產生都會返回一個handle,作為標示,每使用一次,對應的計數值加1,調用CloseHandle可以結束核心對象的使用。
具體:
1. 核心對象:
1).符號對象
2).事件對象
3).檔案對象
4).檔案影象對象
5).I/O完成對象
6).工作物件
7).信箱對象
8).互斥對象
9).管道對象
10).進程對象
11).信標對象
12).線程對象
13).待計時器對象
等
2.核心對象只能由核心所擁有,而不是由進程擁有.(就是說進程沒有了,核心還可以被其他進程使用)
3.核心對象的資料結構有計數器,進程調用時,計數器增1,調用結束,計數器減1,核心對象計數器為零時,銷毀此核心對象.(系統來管理核心對象)
4.核心安全性,進程使用什麼許可權調用核心對象,由SECURITY_ATTRIBUTES結構的資料結構來指定.幾乎所有的調用核心對象的函數都含有SECURITY_ATTRIBUTES結構的指標參數.(可以由這個參數來判斷是不是核心對象哦)
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength; //結構體長度
LPVOID lpSecurityDescriptor; //安全性設定
BOOL bInheritHandle; //可繼承性
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES;
5.進程的核心對象的控制代碼表,進程調用核心對象時,就會建立核心對象的控制代碼表,就是核心對象在進程中的索引,索引值就是調用核心對象函數返回的控制代碼.關閉所有的核心對象,使用CloseHandle();
6.跨越進程邊界共用核心對象
MICROSOFT把控制代碼設計成進程控制代碼,不設計成系統控制代碼是為了實現控制代碼的健壯性和安全性。
1)核心物件控點的繼承性。(為了實現核心的多個進程的共用)
作用:為了子進程實現對父進程建立的核心對象的訪問。
步驟:首先,父進程建立核心對象時,初始化SECURITY_ATTRIBUTES結構的對象,讓SECURITY_ATTRIBUTES結構體的成員變數bInheritHandle設定為TRUE。
然後,子進程建立後,產生自己的控制代碼表,控制代碼表遍曆父進程的控制代碼表,找到有繼承性的控制代碼,並複製一份到子進程的控制代碼表中,子進程的核心對象和父進程的核心對象使用相同的記憶體塊指標,核心對象計數器在子進程中建立核心對象後增一,父進程調用CloseHandle()來關閉核心對象,確不影響子進程使用該核心對象。
2)改變控制代碼的標誌
BOOL SetHandleInformation(
HANDLE hObject, // handle to object
DWORD dwMask, // flags to change
DWORD dwFlags // new values for flags
);
開啟核心的可繼承性標誌
SetHandleInformation(hobj,HANDLE_FLAG_INHERIT,HANDLE_FLAG_INHERIT);
關閉核心的可繼承性標誌
SetHandleInformation(hobj,HANDLE_FLAG_INHERIT,0);
若想讓核心對象不被關閉,設定HANDLE_FLAG_PROTECT_FROM_CLOSE。
獲得控制代碼標誌的函數
BOOL GetHandleInformation(
HANDLE hObject, // handle to object
LPDWORD lpdwFlags // handle properties
);
3)命名物件
作用:讓進程中的核心對象可以共用,讓別的進程可以通過命名空間,跨進程來訪問這個進程的核心對象。
建立對象和訪問對象使用函數
建立對象Create*:如果命名的核心對象已經存在並具備安全存取權限,則參數被忽略,進程的控制代碼表複製一份核心對象的指標和標誌到進程的控制代碼表,如果不存在,則馬上建立核心對象。
例子:
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, // SD
BOOL bInitialOwner, // initial owner
LPCTSTR lpName // 對象名字
);
開啟對象Open*:如果命名的核心對象已經存在並具備安全存取權限,進程的控制代碼表複製一份核心對象的指標和標誌到進程的控制代碼表,如果不存在,則返回NULL,使用GetLassError(),得到傳回值2。
4)終端服務的名字空間
每個客戶程式會話都有自己的服務名字空間,一個會話無法訪問另一個會話的對象,儘管他們具備相同的對象名字。
服務程式的名字空間對象總放在全域名字空間中。
5)複製物件控點
DuplicateHandle函數來對另一個進程對象的控制代碼進行複製到調用此函數的進程控制代碼表中,實現進程間共用核心對象。
BOOL DuplicateHandle(
HANDLE hSourceProcessHandle, // handle to source process
HANDLE hSourceHandle, // handle to duplicate
HANDLE hTargetProcessHandle, // handle to target process
LPHANDLE lpTargetHandle, // duplicate handle
DWORD dwDesiredAccess, // requested access
BOOL bInheritHandle, // handle inheritance option
DWORD dwOptions // optional actions
);