进程内核对象句柄表

一个进程在初始化时,系统将为它分配一个句柄表(handle table)。这个句柄表仅供内核对象使用,不适用于用户对象或GDI对象。

 

调用函数来创建一个内核对象时,如果调用失败,那么返回的句柄值通常为0(NULL),这就是为什么第一个有效的句柄值为4的原因。之所以失败,可能是由于系统内存不足,或者遇到一个安全问题。遗憾的是,有几个函数在调用失败时会返回句柄值-1(也就是在WinBase.h中定义的INVALID_HANDLE_VALUE)。例如,如果CreateFile无法打开指定文件,它会返回INVALID_HANDLE_VALUE,而不是NULL。凡是用于创建内核对象的函数,在检查它们的返回值时,务必相当仔细。

 

就在CloseHandle函数返回之前,它会清除进程句柄表中对应的记录性--这个句柄现在对我们的进程来说是无效的,不要再试图使用它。无论内核对象是否销毁,这个清除过程都会发生!一旦调用了CloseHandle,我们的进程就不会访问那个内核对象;但是,如果内核对像的使用计数还没有递减至0,它就不会被销毁。这是完全正确的;它表明另外还有一个或多个进程在使用该对象。当其他进程(通过调用CloseHandle)全部停止使用这个对象后,对象就会被销毁。

 

通常,在创建一个内核对象时,我们会将相应的句柄保存到一个变量中。将此变亮作为参数调用CloseHandle函数后,还应同时将这个变量设为NULL。如果不小心用这个变量来调用了一个Win32函数,可能会发生两种意外情况。第一种可能的情况是,由于此变量所引用的句柄表记录项已被清除,所以Windows会接收到一个无效的参数并报告错误。另外,还能发生另一种更难调试的情况。创建一个新的内核对象时,Windows会在句柄表中查找空白记录项。所以,如果应用程序已经创建好一些新的内核对象,那么该变量所引用的句柄表肯定包含某个新建的内核对象。因此,要函数调用时,一旦错误滴用这个尚未设为NULL的变量,就可能会定位到一个错误类型的内核对象(这种情况会报错)。更糟糕的是,可能会定位到一个类型(和已经关闭的内核对象)相同的内核对象(这种情况不会报错)。在第二种情况下,应用程序的状态将损坏,没有任何办法可以恢复。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值