您的位置:首页 > 移动开发 > Objective-C

WINDOWS内核对象

2007-02-11 23:11 274 查看
  首先说一下什么是内核对象,之所以叫内核对象就是这个对象是由内核创建,由内核维护,不属于某一个进程,而是属于整个系统的。比如互斥对象,文件印象对象等等。。内核对象有两个比较重要的特性:

每个内核对象都不属于某个进程,而属于整个系统,几乎每个内核对象都有一个计数器,计数正在使用这个对象的进程数

每个内核对象都会有一个安全描述符,描述了谁创建了这个对象,谁能访问它,谁不能访问它。

既然内核对象由系统维护,那么某个进程是怎么维护它已经创建的内核对象呢?是通过一个进程内核对象句柄表,这个表是进程被初始化时,系统分配给他的。(这个表只记载着内核对象的使用情况,而不记载用户对象和GDI对象)。先给出一个内核对象表的模型

IndexPointer to Kernel Object Memory BlockAccess Mask (DWORD of Flag Bits)Flags (DWORD of Flag Bits)
10x????????0x????????0x????????
20x????????0x????????0x????????
下面通过进程创建一个内核对象和销毁一个内核对象来说明进程是怎么维护这个表的。。。。

创建内核对象:

进程调用Create*()创建了某个内核对象kObject,调用了Create*()后,内核就为kObject分配一个内存块,这时,内核对进程的句柄表进行扫描,找出一个空项,然后进行初始化。这个函数返回一个HANDLE(注意这个HANDLE是于进程相关的,其他进程调用这个HANDLE很可能出错!)其实这个HANDLE就是进程内核对象表中kObject所在的项目索引。

当操作系统给kObject进行初始化的时候,将kObject的计数器加1,如果计数器等于1就创建一个新的kObject,如果大于1则不会创建一个新的,而是用一个已经有的。

销毁内核对象:

 只需要调用CloseHandle(HANDLE hObj)就可以了。进程会找到对应的索引,然后删除这一项。

通过句柄表的项目找到内核的实际内存地址,然后将它的计数器减1,如果等于0,就释放这个内核对象所占用的空间

说到这里,我们发现内核对象虽然是属于系统的,但是,进程之间却还是不能共享某个内核对象。因为每个进程所拥有的仅仅是一个HANDLE,而这个HANDLE却是于进程相关的。其实要想进程间共享内核对象也是有办法的,下面就来介绍3种:

1.对象句柄的继承:

           首先说一下,这种方法只能用于父子进程之间。上面的句柄表中有一个项目Flags ,这个项目的值就表示这个内核对象是否可以被子进程所继承(1表示可以继承)。然后父进程在调用CreateProcess()的时候,只要将一个参数设置为可继承句柄表,那么父进程中的所有可继承句柄都将复制到子进程的句柄表中。注意,是复制,所以可继承的内核对象的条目在两个进程的句柄表中将是一模一样的,HANDLE也是一样,所以,子进程才可以使用这个HANDLE。但是注意,子进程在创建之后,它自己并不知道已经拥有了这个内核对象的句柄,所以,一般通过命令行将句柄传递给子进程,这是最常用的方法。当然还有其他的方法,但是我还没学到。。lol

           在对对象进行继承的时候,可能会遇到这种情况,你想把句柄表中的某一个项目继承给子进程A,但是却不希望将它传递给B。这个时候就可以调用SetHandleInformation(HANDLE hObj,DWORD dwMask,DWORD dwFlag)改变继承的属性。

2.命名对象:

           在调用Create*()创建内核对象时,可以将这个内核对象命名。下面来看下创建互斥对象的函数原形CreateMutex(PSECURITY_ATTRIBUTE psa,BOOL bInitialOwner,PCTSTR pszname);最后一个参数就是给这个互斥对象进行命名所用到的字符串指针(这个字符串一定要是以0结尾的)。当一个进程通过这个函数创建对象的时候,就会去查找名字空间,看是否已经有一个相同名字的内核对象,如果有,先检查是否是相同的对象,如果不是就调用失败,如果是,再检查安全性,看是否有响应的访问权,有就将这个内核对象的计数加1,并在进程的内核对象表中添加项目。有一点需要说明下,就是所有的内核对象都在一个名字空间里面。所以在命名的时候最好使用GUID。

3.复制对象句柄:

将一个进程的句柄表中的项目复制给另外一个。方法就是调用DuplicateHandle()。具体怎么调用查看MSDN。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  windows access object