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,

                                                                              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)对象。

                                                                          

                                                

 

时间: 2024-10-21 03:42:26

windows编程基础之内核对象的相关文章

Windows编程基础

1. 控件() 使用Windows窗体时, 就是在使用System.Windows.Forms名称空间 大多数控件 都派生于System.Windows.Forms.Control类 1.1 控件属性 Anchor 控件的容器大小发生改变时, 该如何响应 Enable 是否可接收用户输入 1.2 控件的定位.停靠和对齐 1.3 事件 3种处理事件的基本方式 <1>双击控件 <2>Properties窗口中Events列表, 单击闪电图标, 就会显示Events列表      在Ev

Java多线程编程基础之线程对象

在进入java平台的线程对象之前,基于基础篇(一)的一些问题,我先插入两个基本概念. [线程的并发与并行] 在单CPU系统中,系统调度在某一时刻只能让一个线程运行,虽然这种调试机制有多种形式(大多数是时间片轮巡为主),但无论如何,要通过不断切换需要运行的线程让其运行的方式就叫并发(concurrent).而在多CPU系统中,可以让两个以上的线程同时运行,这种可以同时让两个以上线程同时运行的方式叫做并行(parallel). 在上面包括以后的所有论述中,请各位朋友谅解,我无法用最准确的词语来定义储

Windows编程基础之Rect

[Windows编程基础之Rect] 作者:Tocy????时间:2014-09-20 整理本文的最初目的是理清IsRectEmpty和IsRectNull函数的区别,但是在浏览msdn时发现有很多关于Rect函数都没有用过,因此整理下,以作记录并加深记忆. Rect,矩形区域,通常我们会使用四个坐标表示,一种表示法是矩形区域某个顶点坐标+区域宽高,一种表示法是使用矩形区域中相对的两个顶点.Windows下采用第二种表示,定义如下: typedef struct tagRECT { LONG l

MFC入门教程01 Windows编程基础

Windows内核对象

1. 内核对象 Windows中每个内核对象都只是一个内存块,它由操作系统内核分配,并只能由操作系统内核进行访问,应用程序不能在内存中定位这些数据结构并直接更改其内容.这个内存块是一个数据结构,其成员维护着与对象相关的信息.少数成员(安全描述符和使用计数)是所有内核对象都有的,但大多数成员都是不同类型对象特有的. 2. 内核对象的使用计数与生命期 内核对象的所有者是操作系统内核,而非进程.换言之也就是说当进程退出,内核对象不一定会销毁.操作系统内核通过内核对象的使用计数,知道当前有多少个进程正在

Windows 程序基础

在Windows中,程序的基本单位不是过程和函数,而是窗口.一个窗口是一组数据以及处理这些数据的窗口函数的集合.如果从面向对象的角度考虑,窗口本身就是一个对象.Windows程序的执行过程本身就是窗口等对象的创建.处理和消亡的过程.Windows中消息的发送可以理解为一个窗口对象向其他窗口对象请求服务的过程.因此.面向对象的编程思想是进行windows程序设计的首选. 一.句柄 微软将这种描述了事物的数据结构实例都叫做对象.微软公司虽然在Windows系统中定义了这些数据结构,但并未向用户公开,

走进windows编程的世界-----入门篇

1   Windows编程基础 1.1Win32应用程序基本类型 1)  控制台程序 不须要完好的windows窗体,能够使用DOS窗体方式显示 2)  Win32窗体程序 包括窗体的程序,能够通过窗体与程序进行交互 3)  Win32库程序 提供已有的代码,供其它程序使用 动态库(DLL):是在运行的时候能够载入的. 静态库(LIB):是在编译链接是使用的程序.成为当前程序的一部分. 1.2头文件和库 1.2.1头文件 主要的头文件windows.h包括了windows经常使用的定义等,其它,

【Windows编程】系列第六篇:创建Toolbar与Statusbar

上一篇我们学习了解了如何使用Windows GDI画图,该应用程序都是光光的静态窗口,我们使用Windows应用程序,但凡稍微复杂一点的程序都会有工具栏和状态栏,工具栏主要用于一些快捷功能按钮.比如典型的windows应用程序的上面是菜单栏,从菜单栏我们可以选择应用程序提供的各种功能,但是有的功能比较常用,且不能放在第一级菜单,需要进入二级.三级甚至更多的菜单才能选择.显然这样使用起来比较麻烦,于是这时候工具栏的作用就体现出来了,一般工具栏位于菜单栏的下面,但是位于客户窗口的上面.下面就是win

读书笔记----《windows核心编程》第三章 内核对象1(句柄与安全性)

最近一直没有更新博客,因为一直在想一个问题,内核对象这一章内容很多很重要,自己没有掌握好也没有把握写好这一章,最后还是决定能写多少写多少,一面写一面学,后续学到新的再更新吧; <windows核心编程>提了几种内核对象: 访问令牌对象:与windows的安全性有关,目前不是很懂,了解后再写; 事件对象: Event对象,可跨进程同步; 由CreateEvent创建; 文件对象: File对象,比较常见; 由CreateFile创建; 文件映射对象: 通过文件映射可以方便的操作文件(如同文件数据