(内核对象)

转载:http://blog.csdn.net/ljianhui/article/details/8171266
一、 什么是内核对象
每个内核对象只是内核分配的一个内存块,并且只能由该内核访问。该内存块是一种数据结构,它的成员负责维护该对象的各种信息。有些数据成员(如安全性描述符、使用计数等)在所有对象类型中是相同的,但大多数数据成员属于特定的对象类型。例如,进程对象有一个进程I D、一个基本优先级和一个退出代码,而文件对象则拥有一个字节位移、一个共享模式和一个打开模式。
内核对象的数据结构只能被内核访问,因此应用程序无法在内存中找到这些数据结构并直接改变它们的内容。
Wi n d o w s提供了一组函数,以便用定义得很好的方法来对这些结构进行操作。这些内核对象始终都可以通过这些函数进行访问。当调用一个用于创建内核对象的函数时,该函数就返回一个用于标识该对象的句柄。该句柄可以被视为一个不透明值,你的进程中的任何线程都可以使用这个值。将这个句柄传递给Wi n d o w s的各个函数,这样,系统就能知道你想操作哪个内核对象。
 
二、 内核对象的使用计数
内核对象由内核所拥有,而不是由进程所拥有。如果你的进程调用了一个创建内核对象的函数,然后你的进程终止运行,那么内核对象不一定被撤消。内核对象的存在时间可以比创建该对象的进程长。
内核通过内核对象的使用计数知道有多少进程正在使用某个内核对象。当一个对象刚刚创建时,它的使用计数被置为1。然后,当另一个进程访问一个现有的内核对象时,使用计数就递增1。当进程终止运行时,内核就自动确定该进程仍然打开的所有内核对象的使用计数。如果内核对象的使用计数降为0,内核就撤消该对象。
 
三、 安全性
内核对象能够得到安全描述符的保护。安全描述符用于描述谁创建了该对象,谁能够访问或使用该对象,谁无权访问该对象。安全描述符通常在编写服务器应用程序时使用,如果你编写客户机端的应用程序,那么可以忽略内核对象的这个特性。
 
当你想要获得对相应的一个内核对象的访问权(而不是创建一个新对象)时,必须设定要对该对象执行什么操作。例如,如果想要访问一个现有的文件映射内核对象,以便读取它的数据,那么应该调用下面这个O p e n f i l e M a p p i n g函数:
HANDLE hFileMapping = OpenFileMapping(FILE_MAP_READ,FALSE,”MyFileMapping”);
 
若要确定一个对象是否属于内核对象,最容易的方法是观察创建该对象所用的函数。创建内核对象的所有函数几乎都有一个参数,你可以用来设定安全属性的信息。
 
四、 进程的内核对象句柄表
当一个进程被初始化时,系统要为它分配一个句柄表。该句柄表只用于内核对象,不用于用户对象或G D I对象。它只是个数据结构的数组。每个结构都包含一个指向内核对象的指针、一个访问屏蔽和一些标志。
 
五、 创建内核对象
当进程初次被初始化时,它的句柄表是空的。然后,当进程中的线程调用创建内核对象的函数时,比如C r e a t e F i l e M a p p i n g,内核就为该对象分配一个内存块,并对它初始化。
用于创建内核对象的所有函数均返回与进程相关的句柄,这些句柄可以被在相同进程中运行的任何或所有线程成功地加以使用。该句柄值实际上是放入进程的句柄表中的索引,它用于标识内核对象的信息存放的位置。
 
如果调用一个函数以便创建内核对象,但是调用失败了,那么返回的句柄值通常是 0(N U L L)。注:C r e a t e F i l e未能打开指定的文件,那么它将返回I N VA L I D _ H A N D L E _ VA L U E,而不是返回N U L L。
 
六、 关闭内核对象
通过调用C l o s e H a n d l e来结束对该对象的操作:                       
BOOL CloseHandle (HANDLE hobj);
 
如果该索引是有效的,那么系统就可以获得内核对象的数据结构的地址,并可确定该结构中的使用计数的数据成员。如果使用计数是0,该内核便从内存中撤消该内核对象。无论内核对象是否已经撤消,都会发生清除操作。当调用C l o s e H a n d l e函数之后,将不再拥有对内核对象的访问权。
 
当进程终止运行时,系统会自动扫描进程的句柄表。如果该表拥有任何无效项目(即在终止进程运行前没有关闭的对象),系统将关闭这些对象句柄。如果这些对象中的任何对象的使用计数降为0,那么内核便撤消该对象。
 
七、 跨越进程边界共享内核对象的方法
1、 对象句柄的继承性
只有当进程具有父子关系时,才能使用对象句柄的继承性。在这种情况下,父进程可以使用一个或多个内核对象句柄,并且该父进程可以决定生成一个子进程,为子进程赋予对父进程的内核对象的访问权。创建子进程时系统要进行另一项操作,即它要遍历父进程的句柄表,对于它找到的包含有效的可继承句柄的每个项目,系统会将该项目准确地拷贝到子进程的句柄表中。该项目拷贝到子进程的句柄表中的位置将与父进程的句柄表中的位置完全相同。父进程可以立即关闭对象的句柄,而不影响子进程对该对象进行操作的能力。
 
2、为对象命名
注:Windows没有提供任何专门的机制来保证为内核对象指定的名称是唯一的。
 
3、复制句柄对象
posted @ 2015-09-04 15:54  vpoet  阅读(229)  评论(0编辑  收藏  举报