内核对象

什么是内核对象


内核对象其实就是由不同的函数创建的并由操作系统分配的一个内存块,这个内存块是一个数据结构。

如何访问内核对象


由于内核对象由操作系统内核分配,所以也只能由操作系统内核访问。既然不能直接更改这些结构,应用程序如何操纵这些内核对象呢?

答案是利用Windows提供的一组函数,这组函数可以最恰当的方式来操纵这些结构, 调用一个会创建内核对象的函数后,函数会返回一个句柄(handle),他标识了所创建的对象。它可由进程中的任何线程使用,为了让操作系统知道我们要对哪个内核对象进行操作,我们需要将这个句柄传给各种windows函数。为了增强可靠性,这些句柄值是与进程相关的,所以将句柄值传给另一个进程中的线程,那么另一个进程用我们的进程的句柄值来发出调用时,就可能失败。

使用计数

内核对象归操作系统所有,当进程结束时,内核对象不一定会销毁。操作系统内核知道当前有多少个进程正在使用一个特定的内核对象,因为每个对象都包含一个使用计数(usage count),初次创建一个对象的时候,使用计数为1,另一个进程获得对现有内核对象的访问后,使用计数就会递增,进程终止后,操作系统内核将自动递减此进程仍然打开的所有内核对象的使用计数,如果一旦对象的使用计数变成0,操作系统内核就会销毁该对象,这样一来,可以保证系统中不存在没被任何进程引用的内核对象。

跨进程边界共享内核对象

原因:
利用文件映射对象,可以在同一台机器上运行的两个不同的进程之间共享数据块。
借组邮件槽和命名管道,在网络中的不同计算上运行的进程可以相互发送数据块。
互斥量,信号量和事件允许不同进程中的线程同步执行。例如,一个应用程序可能需要在完成某个任务之后,向另一个应用程序发出通知。

但内核对象的句柄是与一个进程相关的(process-relative),所以执行这些任务并不轻松。

方法:
1.使用 对象句柄继承
2.为对象命名
3.复制对象句柄

使用对象句柄继承的步骤
1.父进程必须分配并初始化一个SECURITY_ATTRIBUTES结构,并将这个结构的地址传给具体的Create函数,例如:
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;        //使返回的句柄可继承

HANDLE hMutex = CreateMutex(&sa, FALSE, NULL);
2.由父进程生成子进程,这是通过CreateProcess函数完成的。
   由于我们传给CreateProcess函数的bInheritHandles参数的值是TRUE,所以系统还会多做一件事:它会遍历父进程的句柄表,对它的每一个记录项进行检查。凡是包含一个有效的“可继承的句柄”的项,都会被完整的复制到子进程的句柄表。在子进程的句柄表中,复制项的位置与它在父进程句柄表中的位置是完全一样的。这是非常重要的一个设计,因为它意味着:在父进程和子进程中,对一个内核对象进行标志的句柄值是完全一样的。

notice:
记住,对象句柄的继承只会在生成子进程的时候发生。例如父进程后来又创建了新的内核对象,并同样将他们的句柄设为可继承的句柄。那么正在运行的子进程是不会继承这些新句柄的。


为对象命名
如果要根据对象名称来共享一个对象,我们必须为此对象指定一个名称。
HANDLE  hMutexProcessA = CreateMutex(NULL, FALSE, TEXT("JeffMutex"));
这个函数调用创建一个新的互斥量内核对象,并将其命名为“JeffMutex”.注意,在进程A的句柄(表)中,hMutexProcessA并不是一个可继承的句柄----但是,通过为对象命名来实现共享时,是否可以继承并非一个必要条件。


相对于对象句柄继承的优点
利用对象名称来共享内核对象,最大的一个优势是“进程B不一定是进程A的子进程”。进程B开始执时,它执行以下代码:
HANDLE hMutexProcessB = CreateMutex(NULL, FALSE, TEXT("JeffMutex"));
notice:
两个进程中的句柄值极有可能是不同的值。这没有什么关系。进程A用它自己的句柄值来引用那个互斥量对象,进程B也用它自己的句柄值来引用同一个互斥量对象。


复制对象句柄
BOOL DuplicateHandle(
HANDLE  hSourceProcessHandle,
HANDLE  hSourceHandle,
HANDLE  hTargetProcessHandle,
PHANDLE phargetHandle,
DWORD   dwDesiredAccess,
BOOL       bInheritHandle,
DWORD  dwOptions);

.............
HANDLE hObjInProcessS = CreateMutex(NULL, FALSE, NULL);

HANDLE hProcessT = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessIdT);

HANDLE hObjInProcessT;

DuplicateHandle(GetCurrentProcess(), hObjInProcess, hProcessT, &hObjInProcessT, 0 , FALSE, DUPLICATE_SAME_ACCESS);

.......
.............





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值