windows编程以内核对象

      学好windows编程,理解内核对象仍是相当重要的(●'◡'●)。闲话很少说,下面先来了解一下关于内核对象的知识:编程

      内核对象(kernel object):内核对象是用于管理进程、线程和文件等诸多种类的大量资源。windows

      内核对象的分类:进程对象,线程对象,互斥量(mutex)对象,信号量(semaphore)对象,事件对象,做业对象,文件对象,文件映射对象,管道(pipe)对象,邮件槽(mailslot)对象,I/O完成端口对象,线程池工厂(thread pool  worker  factory)对象,令牌(access token)对象、可等待的计时器(waitable timer)对象等。安全

      内核对象的特性:数据结构

      每一个内核对象都只是一个内存块,它由操做系统分配,并只能由操做系统内核访问,这个内存块是一个数据结构,其成员维护着与对象相关的信息。少数成员(安全描述符和使用计数等)是全部对象都有的,但其余大多数成员都是不一样类型的对象特有的。例如,进程对象有一个ID,一个基本的优先级和一个退出代码;而文件对象有一个字节偏移量(byte offset)、一个共享模式和一个打开模式。app

      因为内核对象的数据结构只能被操做系统访问,故应用程序不能在内存中定位这些数据结构并更改其内容;函数

     当调用一个能够建立内核对象的函数后,该函数会返回一个用于标识该对象的句柄。若是将该句柄值传递给另外一个进程中的一个线程,那么这另外一个进程使用你的进程的句柄值所做的调用就会失败。若是想在多个进程中共享内核对象,要经过必定的机制(如对象句柄的继承性,命名对象,复制对象句柄)。学习

   

      下图所示是一个能够查看一个包含全部内核对象类型的列表的软件(WinObj)界面。有兴趣的能够下载学习一下,加深一下对内核对象的认识。字体

      image

内核对象的安全性:内核对象能够用一个安全描述符(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);

相关文章
相关标签/搜索