内核对象

来源:互联网 发布:js判断对象的长度 编辑:程序博客网 时间:2024/04/30 02:40

作为一个Wi n d o w s软件开发人员,你经常需要创建、打开和操作各种内核对象。系统要创建和操作若干类型的内核对象,比如存取符号对象、事件对象、文件对象、文件映射对象,I / O完成端口对象、作业对象、信箱对象、互斥对象、管道对象、进程对象、信标对象、线程对象和等待计时器对象等。这些对象都是通过调用函数来创建的。(多是create*()函数)

每个内核对象只是内核分配的一个内存快,并且只能由内核访问。应用程序无法在内存中直接找到这些数据结构,并直接改变他们的内容。windows提供了一组函数,作为应用程序访问这些内核对象的接口。当调用create函数创建内核对象时,会返回一个句柄。你的进程中的任何线程都可以使用这个值,把它传递给windows的函数,以确定所要操作的内核对象。

!注意句柄值是与创建他的进程密切相关的,因此,当你以某种进程间通信的方式传递给另外的进程,那么在这另一进程中对该句柄的任何调用将会失败。当然跨越进程边界共享内核对象是有方发的,下面会有介绍。

内核对象的撤销机制:注意内核对象由内核所有,而不是进程,他的撤销机制是使用计数。(和被共享使用的dll 的卸载一样的道理)。对内核对象的创建或者访问会使它的计数加1,当进程被中止时,内核自动去确定它所打开的所有内核对象的使用计数。如果计数降为0,那么内核对象就被撤销。

安全性:几乎所有创建内核对象的函数都有一个指向SECURITY_ATTRIBUTE结构的指针,他是一个安全描述符,用于描述谁创建了这个对象,谁对他有什么样的访问权。安全描述符通常在服务器程序中应用,大多数应用程序传递NULL参数,使用默认安全特性。即管理小组成员和创建者拥有全部访问去权,其他人无权访问。(可以由create函数是否包含这个参数来决定它是一个内核对象还是用户对象)

当你要获得一个内核对象的访问权时,必须制定要对该对象执行什么样的操作,如Handle hFileMapping = OpenFileMapping(FILE_MAP_READ,false, "MyFileMapping"),函数会在返回之前执行一次安全检查,以确定登陆用户是否有该权限。如果访问被拒绝,函数将返回NULL。如调用RegOpenKeyEx()函数,传入KEY_ALLACCESS时,由于注册表的子关键字可以被用户读取,但是不能写入,因此应用程序在win2k上运行时就会产生不可预计的后果。(应此设置正确的安全访问标志是很有必要的,他能防止你的应用程序在新系统中避免新的安全限制问题,比如从win98倒2k,尤其是再到vista都有很大的改变)。

进程再初始化的时候,系统会为它创建一个内核对象句柄表(句柄表不用于用户对象或GDI对象)。它是个数据结构的数组。每个结构都包含一个指向内核对象的指针、一个访问屏蔽和一些标志。无论怎样创建内核对象,都要向系统指明将通过调用C l o s e H a n d l e来结束对该对象的操作,在C l o s e H a n d l e返回之前,它会清除进程的句柄表中的项目,该句柄现在对你的进程已经无效,不应该试图使用它。无论内核对象是否已经撤消,都会发生清除操作。当调用C l o s e H a n d l e函数之后,将不再拥有对内核对象的访问权,不过,如果该对象的使用计数没有递减为0,那么该对象尚未被撤消。