Windows内核对象
2009-08-11 10:48
267 查看
内核对象主要要用来供系统和应用程序管理系统资源,像进程、线程、文件等。存取符号对象、事件对象、文件对象、作业对象、互斥对象、管道对象、等待计时器对象等都是内核对象。我们在编程时经常要创建、打开和操作它们。内核对象通过调用函数来创建,如要创建文件映射对象,就调用CreateFileMapping函数。每个内核对象都会分配一个内存块,只能由其内核访问。该内存块是一种数据结构,用于管理对象的各种信息。
我们的应用程序不能直接访问内核对象的数据结构。需要通过Windows提供的函数来访问。
内核对象由内核拥有,并不是进程所拥有。每个内核对象都有一个计数器来存储有多少个进程在使用它的信息。
内核对象有安全描述符的保护,安全描述符描述了谁创建了该对象以及谁能够使用该对象。用于创建内核对象的函数几乎都有一个指向SEC URITY_ATTRIBUTES 结构的指针作为其参数。CreateFileMapping函数的指针的代码如下所示:
1
HANDLE CreateFileMapping(
2
HANDLE hFile.
3
PSECURITY_ATTRIBUTES psa,
4
DWORD flProtect,
5
DWORD dwMaximumSizeHigh,
6
DWORD dwMaximuniSizeLow,
7
PCTSTR pszNarne);
大多数应用程序通过传NULL值创建具有默认安全性的对象(对象管理小组的任何成员及创建者拥有全部访问权,而其他任何人均无权访问)
。如果你想限制别人对对象的访问,你就需要单独创建一个SECURITY_ATTRIBUTES对象并对其初始化。代码如下:
1
SECURITY_ATTRIBUTES sa;
2
sa.nLength = sizeof(sa); //Used for versioning
3
sa.lpSecuntyDescriptor = pSD, //Address of an initialized SD
4
sa.bInheritHandle = FALSE; //Discussed later
5
HANDLE hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE,
6
&sa, PAGE_REAOWRITE, 0, 1024, "MyFileMapping");
当一个进程被初始化时,系统会为其分配一个句柄表。句柄表用于内核对象,而不用于用户对象和GDI对象。
表3-1 进程的句柄结构
创建内核对象
进程初次初始化时,句柄表是空的。进程中的线程调用创建内核对象的函数时,内核就为相应的内核对象分配一个内存块,并初始化。内核对进程的句柄表进行扫描,找到一个空项,用对象的数据结构的内存地址进行初始化。下面是一些创建内核对象的函数:
1
HANDLE CreateThread(
2
PSECURITY_ATTRIBUTES psa,
3
DWORD dwStackSize,
4
PTHREAD_START_ROUTINE pfnStartAddr,
5
PVOID pvParam,
6
DWORD dwCreationFlags,
7
PDWORD pdwfhreadId);
8
9
HANDEE CreateFile(
10
PCTSTR pszFileName,
11
DWORD dwDesiredAccebS,
12
DWORD dwShareMode,
13
PSECURITY_ATTRIBUTES psa,
14
DWORD dwCreationDistribution,
15
DWORD dwFlagsAndAttnbutes,
16
HANDEE hTemplateFile);
关闭内核对象
不论通过何种方式创建内核对象,都通过调用CloseHandle方法来结束对内核对象的操作。
BOOL CloseHandle(HANDLE hobj);
为什么结束进程能释放所有占用的资源?进程在运行时有可能出现内存泄漏。在进程终止运行时,系统会自动扫描进程的句柄表。若表中拥有任何无效项目(进程终止前没关闭的对象),系统将关闭这些对象的句柄。对象的计数器被置0,内核便会撤销这些对象。
跨进程边界共享内核对象
很多时候,不同进程的线程需要共享内核对象。如邮箱和指定的管道使应用程序能在联网的计算机上不同的进程之间发送数据块。
对象句柄的兼容性:只有当进程之间是父子关系时,才能使用对象句柄的继承性。在这种情况下,父进程可以使用一个或多个内核对象句柄,并且该父进程可以决定生成一个子进程,为子进程赋予对父进程的内核对象的访问权。
实现过程:1.父进程创建内核对象,并指明对象的句柄是可继承的句柄,注意内核对象本身不具备继承性。
2.使用对象句柄继承性时要执行的下一个步骤是让父进程生成子进程。这要使用CreateProcess函数来完成:
我们的应用程序不能直接访问内核对象的数据结构。需要通过Windows提供的函数来访问。
内核对象由内核拥有,并不是进程所拥有。每个内核对象都有一个计数器来存储有多少个进程在使用它的信息。
内核对象有安全描述符的保护,安全描述符描述了谁创建了该对象以及谁能够使用该对象。用于创建内核对象的函数几乎都有一个指向SEC URITY_ATTRIBUTES 结构的指针作为其参数。CreateFileMapping函数的指针的代码如下所示:
1
HANDLE CreateFileMapping(
2
HANDLE hFile.
3
PSECURITY_ATTRIBUTES psa,
4
DWORD flProtect,
5
DWORD dwMaximumSizeHigh,
6
DWORD dwMaximuniSizeLow,
7
PCTSTR pszNarne);
大多数应用程序通过传NULL值创建具有默认安全性的对象(对象管理小组的任何成员及创建者拥有全部访问权,而其他任何人均无权访问)
。如果你想限制别人对对象的访问,你就需要单独创建一个SECURITY_ATTRIBUTES对象并对其初始化。代码如下:
1
SECURITY_ATTRIBUTES sa;
2
sa.nLength = sizeof(sa); //Used for versioning
3
sa.lpSecuntyDescriptor = pSD, //Address of an initialized SD
4
sa.bInheritHandle = FALSE; //Discussed later
5
HANDLE hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE,
6
&sa, PAGE_REAOWRITE, 0, 1024, "MyFileMapping");
当一个进程被初始化时,系统会为其分配一个句柄表。句柄表用于内核对象,而不用于用户对象和GDI对象。
表3-1 进程的句柄结构
索引 | 内核对象内存块的指针 | 访问屏蔽(标志位的D W O R D ) | 标志(标志位的D W O R D ) |
1 | 0 x ? ? ? ? ? ? ? ? | 0 x ? ? ? ? ? ? ? ? | 0 x ? ? ? ? ? ? ? ? |
2 | 0 x ? ? ? ? ? ? ? ? | 0 x ? ? ? ? ? ? ? ? | 0 x ? ? ? ? ? ? ? ? |
... | ... | ... | ... |
进程初次初始化时,句柄表是空的。进程中的线程调用创建内核对象的函数时,内核就为相应的内核对象分配一个内存块,并初始化。内核对进程的句柄表进行扫描,找到一个空项,用对象的数据结构的内存地址进行初始化。下面是一些创建内核对象的函数:
1
HANDLE CreateThread(
2
PSECURITY_ATTRIBUTES psa,
3
DWORD dwStackSize,
4
PTHREAD_START_ROUTINE pfnStartAddr,
5
PVOID pvParam,
6
DWORD dwCreationFlags,
7
PDWORD pdwfhreadId);
8
9
HANDEE CreateFile(
10
PCTSTR pszFileName,
11
DWORD dwDesiredAccebS,
12
DWORD dwShareMode,
13
PSECURITY_ATTRIBUTES psa,
14
DWORD dwCreationDistribution,
15
DWORD dwFlagsAndAttnbutes,
16
HANDEE hTemplateFile);
关闭内核对象
不论通过何种方式创建内核对象,都通过调用CloseHandle方法来结束对内核对象的操作。
BOOL CloseHandle(HANDLE hobj);
为什么结束进程能释放所有占用的资源?进程在运行时有可能出现内存泄漏。在进程终止运行时,系统会自动扫描进程的句柄表。若表中拥有任何无效项目(进程终止前没关闭的对象),系统将关闭这些对象的句柄。对象的计数器被置0,内核便会撤销这些对象。
跨进程边界共享内核对象
很多时候,不同进程的线程需要共享内核对象。如邮箱和指定的管道使应用程序能在联网的计算机上不同的进程之间发送数据块。
对象句柄的兼容性:只有当进程之间是父子关系时,才能使用对象句柄的继承性。在这种情况下,父进程可以使用一个或多个内核对象句柄,并且该父进程可以决定生成一个子进程,为子进程赋予对父进程的内核对象的访问权。
实现过程:1.父进程创建内核对象,并指明对象的句柄是可继承的句柄,注意内核对象本身不具备继承性。
2.使用对象句柄继承性时要执行的下一个步骤是让父进程生成子进程。这要使用CreateProcess函数来完成:
相关文章推荐
- windows笔记-【内核对象线程同步】事件内核对象
- windows笔记-【内核对象线程同步】信标内核对象
- windows笔记-【内核对象线程同步】互斥对象内核对象
- Windows 内核对象
- windows笔记-跨越进程边界共享内核对象【命名对象】
- Windows Internals 笔记——内核对象
- windows核心编程心解--内核对象
- "windows线程池" 之 内核对象触发调用回调函数
- 用命名内核对象防止windows同时运行两个程序
- Windows内核对象
- WINDOWS内核对象
- windows资源管理(内核对象/GDI对象/user对象)
- Windows内核对象句柄的继承小总结
- windows via c/c++ 三. 内核对象
- Windows内核对象头部结构
- Windows内核对象简介
- 《Windows via C/C++》学习笔记 —— 内核对象的“线程同步”之“等待函数”
- 《Windows via C/C++》学习笔记 —— 内核对象的“线程同步”之“互斥内核对象”
- windows程序设计 and windows核心编程(内核对象理论)
- Windows内核对象的理解