學好windows編程,理解內核對象仍是相當重要的(●'◡'●)。閒話很少說,下面先來了解一下關於內核對象的知識:編程
內核對象(kernel object):內核對象是用於管理進程、線程和文件等諸多種類的大量資源。windows
內核對象的分類:進程對象,線程對象,互斥量(mutex)對象,信號量(semaphore)對象,事件對象,做業對象,文件對象,文件映射對象,管道(pipe)對象,郵件槽(mailslot)對象,I/O完成端口對象,線程池工廠(thread pool worker factory)對象,令牌(access token)對象、可等待的計時器(waitable timer)對象等。安全
內核對象的特性:數據結構
每一個內核對象都只是一個內存塊,它由操做系統分配,並只能由操做系統內核訪問,這個內存塊是一個數據結構,其成員維護着與對象相關的信息。少數成員(安全描述符和使用計數等)是全部對象都有的,但其餘大多數成員都是不一樣類型的對象特有的。例如,進程對象有一個ID,一個基本的優先級和一個退出代碼;而文件對象有一個字節偏移量(byte offset)、一個共享模式和一個打開模式。app
因爲內核對象的數據結構只能被操做系統訪問,故應用程序不能在內存中定位這些數據結構並更改其內容;函數
當調用一個能夠建立內核對象的函數後,該函數會返回一個用於標識該對象的句柄。若是將該句柄值傳遞給另外一個進程中的一個線程,那麼這另外一個進程使用你的進程的句柄值所做的調用就會失敗。若是想在多個進程中共享內核對象,要經過必定的機制(如對象句柄的繼承性,命名對象,複製對象句柄)。學習
下圖所示是一個能夠查看一個包含全部內核對象類型的列表的軟件(WinObj)界面。有興趣的能夠下載學習一下,加深一下對內核對象的認識。字體
內核對象的安全性:內核對象能夠用一個安全描述符(security descriptor,SD)來保護。用於建立內核對象的全部函數幾乎都指向一個SECURITY_ATTRIBUTES結構的指針做爲參數:以下面的操作系統
CreateFileMapping(線程
HHANDLE hFile,
PSECURITY_ATTRIBUTES psa,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSiizelow,
PCTSTR pszName
);
大多數應用程序只是爲這個參數傳入NULL,這樣建立的內核對象具備默認的安全性----具體包括哪些默認的安全性,要取決於當前進程的安全令牌(security token)。可是也能夠分配一個SECURITY_ATTRIBUTES結構,並對它進行初始化,再將它的地址傳給這個參數。SECURITY_ATTRIBUTES結構體以下所示:
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength;
LPVOID lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES;
雖然這個結構稱爲SECURITY_ATTRIBUTES,但它實際上只包含一個和安全性有關的成員,即lpSecurityDescriptor。若是相對建立的內核對象加以訪問限制,就必須建立一個安全描述符,而後按下面所示初始化其結構:
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecrityDeccriptor = pSD;
sa.bInheritHandle = FALSE;
HANDLE hFileMApping = CreateFileMapping(INVALID_HANDLE_VALUE,
&sa,
P0AGE_READWRITE,
0,
1024,
TEXT(「MyFileMapping」));
若想訪問一個現有的文件映射對象,以便從中讀取數據,能夠以下下述方式調用:
HANDLE hFileMapping = OpenFileMapping(
FILE_MAP_READ,FALSE,
FALSE,
TEXT(「MyFileMapping」));
若想判斷一個對象是否是內核對象,最簡單的方式是查看建立這個對象的函數。幾乎全部建立內核對象的函數都有一個指定安全屬性信息的參數,就像上述的CreateFileMapping函數同樣。相反,用於建立用戶對象或GDI對象的函數都沒有PSECURITY_ATTRIBUTES參數。以下所示的CreateIcon函數
HICON CreateIcon(
HINSTANCE hinst,
int nWidth,
int nHight,
BYTE cPlanes,
BYTE cBitsPixel,
CONST BYTE *pbANDbits,
CONST BYTE *pbXORbits);
ps:像菜單、窗口、鼠標光標、畫刷和字體這樣的對象屬於用戶對象或GDI(Graphical Device Interface)對象。
部分建立內核對象的函數:
HANDLE CraeateThread (
PSECURITY_ATTRIBUTES psa,
size_t dwStackSize,
LPTHREAD_START_ROUTINE pfnstartAddress,
PVOID pvParam,
DWORD dwCreatinFlags,
PDWORD pdwThread );
HANDLE CraeateFile (
PCTSTR pszFileName
DWORD dwDesiredAccess,
DWORD dwShareMode,
PSECURITY_ATTRIBUTES psa,
DWORD daCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile );
HANDLE CreateSemaphore (
PSECURITY_ATTRIBUTES psa,
LONG lInitialCount,
LONG lMaxiumumCount,
PCTSTR pszName);
……
結束內核對象,需調用:BOOL CloseHandle(HANDLE hobject);