1.什么是内核对象:
首先是一个对象,比如时间对象,文件对象,作业对象,信箱对象,互斥对象,管道对象,进程对象等等都是一个内核对象,用于地层处理逻辑的对象,而内核对象只能被内核访问,应用程序不能直接改变他们的内容,但是windows给我们提供了一组函数,以便我们使用方法进行操作:一般都是先调用CreateXXX函数,返回句柄,句柄是一个不透明值,并非是创建的内核对象的指针,实际是进程句柄表的表示,后面提到了过程。
2.内核对象的引用计数:
有点类似智能指针shareptr,内核对象是内核所拥有,不是由进程拥有,进程创建内核对象,那么内核对象的计数加1,如果终止进程,内核独享引用计数减1,只有所有进程都不适用该内核对象,内核对象的引用为0,被销毁。
3.创建内核对象:
当创建内核对象时,需要调用一些函数:
HANDEL CreateThread(
PSECURITY_ATTRIBUTES psa, // 安全权限,使用该内核对象时,权限不足不能使用
DWORD dwStackSize,
LPTHREAD_START_ROUTINE pfnStartAddr,
PVOID pvParam,
DWORD dwCreationFlags,
PDWORD pdwThreadId);
每个进程都有一个句柄表,当进程未初始化时,句柄表是空的,调用某个创建内核对象后,把创建的内核对象的指针放到句柄表里,然后返回给应用程序句柄表中的索引,这样应用程序通过句柄表的索引,找到指针,在通过指针真正调用内核对象。
4.关闭内核对象:
创建和关闭是一对的,在使用完毕内核对象之后,要记得关闭内核对象:
BOOL CloseHandle(HANDLE hobj);
调用之后,内核对象的的引用计数减1,如果引用计数为0了,就回收该内核对象。
如果漏掉调用,那么在进程关闭的时候,也会回收所有未释放的资源,也会尝试回收改内核对象。
5 跨越进程边界共享内核对象:
有时候,希望两个进程共享同一个对象,比如文件映射对象可以在同一个机器上运行两个进程之间的共享数据块等,那么是如何达到共享内存对象的效果。
a.根据内核对象的继承性:当进程具有父子关系,即父进程在调用CreateProcess,创建子进程时,子进程在创建过程中,会先遍历父进程的句柄表,根据句柄表中是否可以继承标志,来决定是否复制到自己的进程的句柄表中,如果继承,则把指针等数据复制到自己句柄表,这样两个进程句柄就是相同的。
b.命名空间:在创建内核对象时,有写函数可以传递字符串,实际是给该内核对象命名,命名空间具有唯一性。如果系统内有相同名字的内核对象,但是访问权限或者对象类型不同,那么第二个创建同名字的内核对象将会返回失败。否则,并非创建一个内核对象,而是把内核对象的指针等信息复制到自己的句柄表,此时两个句柄表的内核对象句柄可能不同。这与上面继承是有区别的。
c.复制对象句柄:调用函数DuplicateHandle函数,
BOOL DuplicateHandle(
HANDLE hSourceProcessHandle, // 自身进程句柄
HANDLE hScoureHandle, // 要拷贝的内核对象的句柄
HANDLE hTargetProcessHandle, // 目标进程的句柄
PHANDLE phTargetHandle, // 返回拷贝的内核对象在目标进程的句柄
DWORD dwDesiredAccess, // 表示屏蔽值和继承性标志
BOOL bInheritHandle,
DWORD dwOptions);
学习书籍:windows核心编程