一、
Win32 SDK 开发主要是用户模式下的程序设计,但在开发过程中,经常要和内核对象打交道。
内核对象是系统分配的一块内存,是一种数据结构,是程序和系统内核交互的重要方式。
二、
常见的内核对象:时间对象、信标对象、文件映射对象、管道对象、互斥对象等等。
当进程和线程创建时,系统会为其建立进程内核对象和线程内核对象。
1、内核对象的重要数据成员之一是使用计数,即标识了当前该对象正在被访问的累加数,当使用计数为0时,系统撤消该对象,释放该对象占用的所有资源。
2、内核对象的一个重要属性是安全属性。在创建内核对象的函数所有函数里,几乎都有一个参数,用于指定将要创建的内核对象的安全属性,即SECURITY_ATTRIBUTES结构。其定义:
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength;
LPVOID lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES,
*PSECURITY_ATTRIBUTES;
第二成员使用于指定安全性,第三个成员指定对象句柄的继承性。
三、
进程在被初始化时,系统为其分配一个句柄表,此句柄表只用于内核对象。
句柄表的每一项记录了每个内核对象的信息,所谓信息主要包括:(句柄在句柄表表中的)索引、指向内核对象内存的地址、访问屏蔽标志、内核对象句柄继承标志。
进程在初始化时句柄表是空的,每当进程创建一个内核对象时,系统就在该进程的句柄表中找出一个空项,设置新创建的内核对象的信息。
内核对象的创建函数几乎都是形如Cerate*的形式,这些函数返回新创建的内核对象的句柄。这里返回的所谓句柄,其值实际上是该内核对象在进程句柄表中的索引,用于标识该对象在进程句柄表中的位置。
Cerate*函数返回失败的话,返回值通常为NULL(0),但也有一些是INVALID_HANDLE_VALUE(-1)。
关闭内核对象通过调用CloseHandle完成,每调用一次,内核对象使用计数递减1。
四、内核对象句柄的继承性
只用当进程具有父子关系时,才能使用内核对象的句柄的继承性。在父进程创建内核对象,并对SECURITY_ATTRIBUTES的数据成员BOOL bInheritHandle设为FALSE时,则子进程不能继承父进程的内核对象的句柄。
但 若设置了TRUE,则子进程可以继承父进程的内核对象的句柄值。当子进程创建初始化时,系统也会为其分配句柄表,然后系统扫描父进程句柄表,对于继承标志 位为TRUE的内核对象,系统把该项目拷贝到子进程的句柄表,并且拷贝到子进程句柄表中的位置和父进程句柄表中的位置是一样的。这就意味在父子进程中,此 内核对象的句柄值是一样的,所以能够保证父子进程都能使用该内核对象。
五、跨进程共享内核对象
一是使用命名内核对象,即在创建内核对象时给其命名,然后其它进程就可以打开使用此命名的内核对象。这种方法也可用于限制应用程序只启动一个实例。
二是复制内核对象句柄。使用函数
BOOL DuplicateHandle(
HANDLE hSourceProcessHandle,
HANDLE hSourceHandle,
HANDLE hTargetProcessHandle,
LPHANDLE lpTargetHandle,
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwOptions
);
Win32 SDK 开发主要是用户模式下的程序设计,但在开发过程中,经常要和内核对象打交道。
内核对象是系统分配的一块内存,是一种数据结构,是程序和系统内核交互的重要方式。
二、
常见的内核对象:时间对象、信标对象、文件映射对象、管道对象、互斥对象等等。
当进程和线程创建时,系统会为其建立进程内核对象和线程内核对象。
1、内核对象的重要数据成员之一是使用计数,即标识了当前该对象正在被访问的累加数,当使用计数为0时,系统撤消该对象,释放该对象占用的所有资源。
2、内核对象的一个重要属性是安全属性。在创建内核对象的函数所有函数里,几乎都有一个参数,用于指定将要创建的内核对象的安全属性,即SECURITY_ATTRIBUTES结构。其定义:
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength;
LPVOID lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES,
*PSECURITY_ATTRIBUTES;
第二成员使用于指定安全性,第三个成员指定对象句柄的继承性。
三、
进程在被初始化时,系统为其分配一个句柄表,此句柄表只用于内核对象。
句柄表的每一项记录了每个内核对象的信息,所谓信息主要包括:(句柄在句柄表表中的)索引、指向内核对象内存的地址、访问屏蔽标志、内核对象句柄继承标志。
进程在初始化时句柄表是空的,每当进程创建一个内核对象时,系统就在该进程的句柄表中找出一个空项,设置新创建的内核对象的信息。
内核对象的创建函数几乎都是形如Cerate*的形式,这些函数返回新创建的内核对象的句柄。这里返回的所谓句柄,其值实际上是该内核对象在进程句柄表中的索引,用于标识该对象在进程句柄表中的位置。
Cerate*函数返回失败的话,返回值通常为NULL(0),但也有一些是INVALID_HANDLE_VALUE(-1)。
关闭内核对象通过调用CloseHandle完成,每调用一次,内核对象使用计数递减1。
四、内核对象句柄的继承性
只用当进程具有父子关系时,才能使用内核对象的句柄的继承性。在父进程创建内核对象,并对SECURITY_ATTRIBUTES的数据成员BOOL bInheritHandle设为FALSE时,则子进程不能继承父进程的内核对象的句柄。
但 若设置了TRUE,则子进程可以继承父进程的内核对象的句柄值。当子进程创建初始化时,系统也会为其分配句柄表,然后系统扫描父进程句柄表,对于继承标志 位为TRUE的内核对象,系统把该项目拷贝到子进程的句柄表,并且拷贝到子进程句柄表中的位置和父进程句柄表中的位置是一样的。这就意味在父子进程中,此 内核对象的句柄值是一样的,所以能够保证父子进程都能使用该内核对象。
五、跨进程共享内核对象
一是使用命名内核对象,即在创建内核对象时给其命名,然后其它进程就可以打开使用此命名的内核对象。这种方法也可用于限制应用程序只启动一个实例。
二是复制内核对象句柄。使用函数
BOOL DuplicateHandle(
HANDLE hSourceProcessHandle,
HANDLE hSourceHandle,
HANDLE hTargetProcessHandle,
LPHANDLE lpTargetHandle,
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwOptions
);
转载于:https://blog.51cto.com/dking94/110922
本文详细介绍了Win32 SDK开发中的内核对象概念及其重要性,包括内核对象的基本属性、句柄表机制、句柄继承性和跨进程共享方法等内容。

760

被折叠的 条评论
为什么被折叠?



