windows编程之内核对象
学好windows编程,理解内核对象还是至关重要的(●'◡'●)。闲话不多说,下面先来了解一下关于内核对象的知识:
内核对象(kernel object):内核对象是用于管理进程、线程和文件等诸多种类的大量资源。
内核对象的分类:进程对象,线程对象,互斥量(mutex)对象,信号量(semaphore)对象,事件对象,作业对象,文件对象,文件映射对象,管道(pipe)对象,邮件槽(mailslot)对象,I/O完成端口对象,线程池工厂(thread pool worker factory)对象,令牌(access token)对象、可等待的计时器(waitable timer)对象等。
内核对象的特性:
每个内核对象都只是一个内存块,它由操作系统分配,并只能由操作系统内核访问,这个内存块是一个数据结构,其成员维护着与对象相关的信息。少数成员(安全描述符和使用计数等)是所有对象都有的,但其他大多数成员都是不同类型的对象特有的。例如,进程对象有一个ID,一个基本的优先级和一个退出代码;而文件对象有一个字节偏移量(byte offset)、一个共享模式和一个打开模式。
由于内核对象的数据结构只能被操作系统访问,故应用程序不能在内存中定位这些数据结构并更改其内容;
当调用一个可以创建内核对象的函数后,该函数会返回一个用于标识该对象的句柄。如果将该句柄值传递给另一个进程中的一个线程,那么这另一个进程使用你的进程的句柄值所作的调用就会失败。如果想在多个进程中共享内核对象,要通过一定的机制(如对象句柄的继承性,命名对象,复制对象句柄)。
下图所示是一个可以查看一个包含所有内核对象类型的列表的软件(WinObj)界面。有兴趣的可以下载学习一下,加深一下对内核对象的认识。
内核对象的安全性:内核对象可以用一个安全描述符(security descriptor,SD)来保护。用于创建内核对象的所有函数几乎都指向一个SECURITY_ATTRIBUTES结构的指针作为参数:如下面的
CreateFileMapping(
HHANDLE hFile,
PSECURITY_ATTRIBUTES psa,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSiizelow,
PCTSTR pszName
);
大多数应用程序只是为这个参数传入NULL,这样创建的内核对象具有默认的安全性----具体包括哪些默认的安全性,要取决于当前进程的安全令牌(security token)。但是也可以分配一个SECURITY_ATTRIBUTES结构,并对它进行初始化,再将它的地址传给这个参数。SECURITY_ATTRIBUTES结构体如下所示:
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength;
LPVOID lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES;
虽然这个结构称为SECURITY_ATTRIBUTES,但它实际上只包含一个和安全性有关的成员,即lpSecurityDescriptor。如果相对创建的内核对象加以访问限制,就必须创建一个安全描述符,然后按下面所示初始化其结构:
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecrityDeccriptor = pSD;
sa.bInheritHandle = FALSE;
HANDLE hFileMApping = CreateFileMapping(INVALID_HANDLE_VALUE,
&sa,
P0AGE_READWRITE,
0,
1024,
TEXT(“MyFileMapping”));
若想访问一个现有的文件映射对象,以便从中读取数据,可以如下下述方式调用:
HANDLE hFileMapping = OpenFileMapping(
FILE_MAP_READ,FALSE,
FALSE,
TEXT(“MyFileMapping”));
若想判断一个对象是不是内核对象,最简单的方式是查看创建这个对象的函数。几乎所有创建内核对象的函数都有一个指定安全属性信息的参数,就像上述的CreateFileMapping函数一样。相反,用于创建用户对象或GDI对象的函数都没有PSECURITY_ATTRIBUTES参数。如下所示的CreateIcon函数
HICON CreateIcon(
HINSTANCE hinst,
int nWidth,
int nHight,
BYTE cPlanes,
BYTE cBitsPixel,
CONST BYTE *pbANDbits,
CONST BYTE *pbXORbits);
ps:像菜单、窗口、鼠标光标、画刷和字体这样的对象属于用户对象或GDI(Graphical Device Interface)对象。
部分创建内核对象的函数:
HANDLE CraeateThread (
PSECURITY_ATTRIBUTES psa,
size_t dwStackSize,
LPTHREAD_START_ROUTINE pfnstartAddress,
PVOID pvParam,
DWORD dwCreatinFlags,
PDWORD pdwThread );
HANDLE CraeateFile (
PCTSTR pszFileName
DWORD dwDesiredAccess,
DWORD dwShareMode,
PSECURITY_ATTRIBUTES psa,
DWORD daCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile );
HANDLE CreateSemaphore (
PSECURITY_ATTRIBUTES psa,
LONG lInitialCount,
LONG lMaxiumumCount,
PCTSTR pszName);
……
结束内核对象,需调用:BOOL CloseHandle(HANDLE hobject);
最新文章
- UI控件之ListView
- windows下做react native官方例子遇到的问题
- AndroidStudio开发工具快捷键
- 摄像头(4)用Camera和SurfaceView自定义拍照程序
- LINUX Shell 下求两个文件交集和差集的办法
- 只响应ccTouchBegan的问题
- poj2521---lose money
- .NET(C#):XML序列化时派生类的处理
- 可重入锁(good)
- eclipse 发布web工程,修改tomcat端口
- Gradle之恋-命令行详解
- ionic2 跳转子页面隐藏底部导航栏
- 【Ubuntu Desktop】VMware 中 Unknown Display
- [转]最常用的15大Eclipse开发快捷键技巧
- aes加解密 Illegal key size
- LeetCode算法题-Symmetric Tree(Java实现)
- vs下开发windows服务程序
- 解题:国家集训队 Crash 的文明世界
- 3503: [Cqoi2014]和谐矩阵
- (转)MPEG4码流简单分析
热门文章
- spring装载配置文件失败报错:org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException
- php分页类 可直接调用
- redis底层数据结构--简单动态字符串 链表 字典 跳跃表 整数集合 压缩列表
- 汇编_指令_CS与DS的区别
- solr 的使用及安装【转】
- Spring MVC中发布Restful Web服务
- 在单板上使用WIFI网卡的固件问题
- linux查看进程是否存在,不存在则重启
- 仅用CSS3创建h5预加载旋转圈
- Tkinter Listbox(列表框)