文档库 最新最全的文档下载
当前位置:文档库 › windows内核编程

windows内核编程

笔者刚开始学习Windows 核心编程的时候,没有做好笔记,所以学得很模糊,现在利用在工作的机会,好好学习和进修Windows核心编程时,想边学边做一些学习的笔记,以为自己的学习提供帮助,和以后自己查看、温习和提高。

Windows核心编程的前两章,笔者觉得是没什么好多讲的,看看就可以了,理解起来并不困难,只要知道有这么个东西,以后编程时注意养成习惯就可以了,更何况,这些东西,我们平常也是在用的。

笔者就从第3章——内核对象开始做学习笔记吧:https://www.wendangku.net/doc/b612124296.html,

众所周知,Windows编程最基础的还是对资源的利用、控制操作,资源是一个比较具体的东西,比如CPU、内存等等。那么怎么来对资源进行操作呢,我们通常是通过对象与资源去打交道(这是本人现在的理解,可能有误)。而对象又可以分为用户对象、GDI对象和内核对象。显然被称作内核对象,他肯定是只能被内核访问的创建于内存中的数据结构。对于各种不同类型的内核对象,居然只能被内核访问,那我们又怎么来操作这些存在内存中的内核结构呢?

微软为我们提供了句柄,就可以使我们很方便的来通过句柄操作内核对象了。因此在每一个内核对象被创建的时候,我们都可以得到一个唯一标识该内核对象的句柄值。因为内核对象是在进程中创建的,所以在一个进程中都有一份与内核对象有关的进程句柄表,也正是由于这个原因,同一个进程中的所有线程都可以访问该进程中的所有内核对象句柄(当然被关闭了的句柄也就不被称为内核对象句柄了)。

讲了这么多,还没有提到内核对象到底是怎么样一个数据结构呢,微软并没有给出明确的数据结构,但是一个内核结构他肯定具有两个很重要的属性:一、内核对象使用计数器,每当一个内核对象被创建时,系统都会创建这个使用计数,并且初始为1,当这个使用计数减为0的时候,那么这个内核对象就被从内存中释放掉,也就不复存在了。二、内核对象安全性描述,关于这个描述,微软为我们提供了一个SECURITY_ATTRIBUTE结构,专门在创建内核对象时设置该内核对象的安全性描述。这里我们可以提供一条用来判断一个对象是否为内核对象的依据,即如果在创建对象句柄的函数参数中包含了SECURITY_ATTRIBUTE结构的参数,那么该对象肯定是内核对象。

以上我们提到了,内核对象句柄是进程的句柄,那么有很多情况下我们需要在不同进程运行的线程能够共享一些内核对象,就很难得到了实现了。微软也考虑了这种情况,为此为我们提供了三种方法可以实现跨进程边界的共享内核对象,也可以说是三种情况下可以进行

共享内核对象的可能操作吧。

第一种方法,就是当父进程在创建子进程前,将那些需要被子进程继承的内核对象句柄的标志位设置为1(通过创建内核对象时将SECURITY_ATTRIBUTE结构中的 bInheritHandle置为TRUE就可以了),然后在创建子进程的函数中把bInheritHandle同样设置为TRUE,就实现了需要继承的内核对象被子进程继承的功能(同时子进程得到一份继承句柄的拷贝项加入自己的内核对象句柄表,同时这些内核对象的使用计数都加1)。这样在子进程中就可以使用父进程中的内核对象句柄了。

注意:在这里我们只是说在创建内核句柄的时候设置内核对象句柄的标志位,其实我们也可以调用SetHandlInformation()函数来重新设置内核对象的句柄位。

第二种方法,通过给对象命名的方法来实现,即我们在创建内核对象时给它一个字符串作为唯一标识该内核对象,因为非终端服务器类型的系统,其名字空间只有一个,所以在一个进程中用以上方法创建了一个内核对象,如果在其它进程再创建同一个名字的内核对象(需要前一进程创建的内核对象还未被内存释放),则在前后两个进程中就可以实现对该内核对象的共享了。以上说的是Greate函数方法,其实我们也可以采用Open函数方法。实质跟fileOpen函数具有类似的功效,不过一个对于文件来说,而前者则是对于内核对象来说而已。

第三种方法,通过 DuplicateHandle()函数来实现,至于这个函数的参数较多,并且他的功能更为强大,所以书本上给我们罗列了三个例子,来详细说明了三种情况的应用。在这里笔者觉得看书上例子就可以了。

自然了,以上创建和共享了内核对象的句柄,本来就是用来使用这些句柄的,具体的使用和操作句柄,我想大家如果搞过点MFC的,就很清楚了。在这里不作展开了。在一个进程中用完之后,我们必须记得关闭该句柄,以使得内核对象的计数减1,从而实现该内核对象不再被访问时能够顺利的释放内存,而不必等到所有程序都关闭时才释放,这是对资源的一种浪费,同时还有可能造成资源的泄漏。

关于内核对象,就介绍到这里。


相关文档
相关文档 最新文档