您的位置:首页 > 编程语言

Windows核心编程笔记---内核对象

2012-12-31 14:16 239 查看
1、内核对象

1)内核对象的拥有者是操作系统内核,内核对象包括事件对象、文件对象、文件映射对象及作业对象等等。

2)每个内核对象都只是一个内存块,由操作系统内核分配,并只能由操作系统内核访问,这个内存块是一个数据结构,维护着与内核对象有关的信息。少数成员(安全描述符和使用级数等)是所有对象共有的,

3)内核对象的访问可以利用Windows提供的一组函数,当创建一个内核对象之后会返回一个句柄,标志着创建的对象,这个句柄是与进程有关的。

2、内核对象是由进程创建的,但是一个内核对象可以由多个进程共同使用。这就是共享机制,他们使用的方式是引用内核为对象分配的一个内存块。如何引用同意内存块,源于在进程内部有一个进程的句柄表的结构。在句柄表中的项目分别有索引、指向内核对象内存块的指针、访问掩码、标志。

1)用于创建内核对象的任何函数都会返回一个与进程相关的句柄。系统使用索引来表示在内核对象的信息保存在进程句柄表中的具体位置。

2)访问掩码指的是访问权限等

3)这里的标志有两中取值,一种是

HANDLE_FLAG_INHERIT ox00000001,以及HANDLE_FLAG_PROTECT_FROM_CLOSE ox00000002.分别表示的是,继承代表的是对象的句柄继承。以及关闭句柄的操作。在跨进程边界共享内核对象中我们将详细的阐述

3、那么如何控制这种共享呢,主要是利用计数。当创建一个内核时候,内核计数增加,进程终止时,计数会减1,但是不一定会销毁,会一直等到计数值为0。在利用继承句柄实现共享时,计数值会增加1。

4、内核对象的安全性,用一个安全描述符来描述谁是内核对象的拥有者,哪些组和用户被允许访问或者使用此对象。如如果被允许访问现有的文件映射内核对象,OpenFileMapping会返回一个有效的句柄值,但是访问被拒绝,会返回NULL,在GetLastError中返回5.判断一个对象是不是内核对象,最简单的方式是查看创建这个对象的函数,基本上创建内核对象的函数都有一个允许我们指定安全属性信息的参数,

备注:内存映射文件:是由一个文件到一块内存的映射。这个文件来自于某个磁盘上的内容,这样多个进程就可以使用内存映射文件来共享数据。

5、进程内核对象句柄表

1)一个进程在初始化时,系统会为它分配一个句柄表,在进程首次初始化的时候,句柄表为空,当进程内的一个线程调用一个会创建内核的函数时,内核将为这个对象分配并初始化一个内存块。这里面的句柄值只是与当前的进程有关,无法供其它的进程使用。因为句柄值实际是作为进程句柄表的索引来使用的,那么如果在其他的进程中使用它,实际引用的只是进程的句柄表中位于同意索引的内核对象,索引值相同而已,所以如果我们要使用同一个内核对象可以使用命名,但是在操作系统中没有机制来保证当前不存在同名的对象。这就是要在创建的时候进行相关的判断。

2)关闭内核对象。当进程终止运行时,操作系统会确保此进程所使用的所有资源都被释放。在创建一个内核对象时,我们通常会将返回的句柄保存在一个对象中,将此变量作为参数调用CloseHandle函数后,同时应该将这个变量设置为NULL。如果利用这个变量来调用一个win32的函数,那么可能的情况是,创建一个新的内核对象填补进程句柄表中的一项,如果新的对象的类型相同的话,那么就会错误,可能应用程序的状态都将损坏。如果不相同的话那么只是错误。这种情况如同窗口类与窗口对象中一样。

class CWnd
{
public:
BOOL CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, LPVOID lpParam /* = NULL */);
BOOL ShowWindow(int nCmdShow);
BOOL UpdateWindow();
public:
HWND m_hWnd;
};
BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, LPVOID lpParam )
{
m_hWnd=::CreateWindowEx(...);
if (m_hWnd==NULL)
{
return TRUE;
}
else
return FALSE;
}

在这里m_hWnd只是窗口类的一个变量而已,如果关闭了窗口,销毁之后,m_hWnd势必成为了野指针。那么在DestroyWindow函数中,该函数销毁窗口后,会将Cwnd成员变量:m_hWnd变量设为NULL。所以这个变量只是作为窗口类与窗口对象之间的纽带,在C++窗口类对象销毁后,与之相关的窗口也将销毁,但是反过来则不然。只是利用了一个变量来保存句柄,销毁了对象,但是这个变量还是存在的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: