内核对象&句柄

目录

  • 1 内核对象的概念
  • 2 内核对象的使用计数
  • 3 句柄
  • 4 句柄表

??项目工程代码中设计句柄的使用,一时不知句柄是何物,通过查阅自学之后,对句柄及其使用有一个初步的了解。分享出来,算是抛砖引玉吧。
??在阐述句柄之前,先说明一下内核对象。

1 内核对象的概念

??内核对象就是一个内存块,有内核分配,只能由内核访问。

??内存块是一种数据结构,其中的数据成员负责维护该对象的相应信息,这个数据结构以及其中的数据成员只能由内核访问,应用程序是无法访问到的,更别说修改其中的数据成员了。

??如何访问这些内核对象(内存块)呢?

??操作系统为使用者封装了一组API,使用者可以通过这些API访问内核对象(内存块)。比如,创建内核对象(内存块)时,使用者调用API中的创建内核对象函数,由内核创建一个内核对象(分配一块内存)。

??内核对象创建好之后,用一个句柄来标识该内核对象(内存块),这个句柄作为函数值返回。这个句柄就是个整数,32位机句柄就是32bit,64位机句柄就是64bit,同一进程中的任何线程都能使用这个句柄,当需要操作内核对象(内存块)时,通过API将这个句柄传给内核,内核就知道是对哪个内核对象(内存块)进行操作了。

创建内核对象,引出句柄。 

2 内核对象的使用计数

??在应用程序中,可能有多个进程,这些进程中的一个或多个可能会访问同一个内核对象。内核对象有使用就会有撤销,那么什么情况下内核会撤销某个内核对象呢。内核的使用计数就派上用场了。使用计数是内核对象这个数据结构的数据成员,通过使用计数就能知道该内核对象被多少个进程使用。开始创建内核对象时,使用计数置为1,之后每多一个不同的进程使用该内核对象,使用计数就自加1.

??无论什么方式创建内核对象,我们都需要调用 ClosseHandle 向系统表明我们已经结束使用对象.就在 CloseHandle 函数返回前,它会清除进程句柄表中对应的记录项 -- 这个句柄现在对我们的进程来说是无效的,不要在试图利用它.换句话说,一旦调用 CloseHandle, 我们的进程就不能访问那个内核对象.

??当进程关闭时,内核自动访问该进程仍然打开的内核对象的使用计数,该进程关联的每个内核对象的使用计数自减1,当使用计数减到0时,内核就会撤销该内核对象。

??内核对象的使用计数有些像智能指针。

3 句柄

??内核对象创建好之后,用一个句柄来标识该内核对象(内存块),这个句柄作为函数值返回。这个句柄就是个整数,32位机句柄就是32bit,64位机句柄就是64bit。

??在同一进程中,一个句柄对应一个内核对象,我们在访问内核对象(内存块)时,就是通过句柄告诉内核,我要访问哪个内核对象。

??通俗的说,句柄,就是个编号,操作系统对于我们来说就是个黑箱,我们通过句柄向操作系统要东西。

4 句柄表

??当一个进程被初始化时,系统要为它分配一个句柄表.该句柄表只用于内核对象,不用于用户对象或GDI对象.句柄表也是由内核操作。进程表包含的元素如下所示:

索引  内核对象  内存块的指针访问屏蔽(标志位的DWORD)  标志(标志位的DWORD)

??进程被初次初始化时,句柄表是空的。

??当进程中的线程创建内核对象时,内核给该对象分配一块内存,并对其初始化。内核遍历该进程的句柄表,找出一个空闲位置,设置内核对象,内存块指针,访问掩码,标识,并获取该位置的索引,作为函数值返回,这个索引就是我们所说的句柄。这个句柄只能有同一个进程的所有线程使用, 系统用索引来表示内核对象的信息保存在进程句柄表中的具体位置。其他进程不能使用该进程的索引,因为句柄表不同(每个进程有一个单独的句柄表)。

??所以,句柄实际上是句柄表的索引。可以这么理解,指针指向一块内存空间,那么句柄就是指向其对应的内核对象,通过操作系统提供的API吧句柄传给内核,内核就知道要操作那个内核对象。

原文地址:https://www.cnblogs.com/MisterXu/p/10846918.html

时间: 2024-08-04 23:22:06

内核对象&句柄的相关文章

内核对象&句柄&泄漏&检测

今天看到这个问题如何评价王垠的 <讨厌的 C# IDisposable 接口>? - 王垠(人物),答案被歪到windows 内核对象和句柄,答案中谈的太浅显而且有误.翻出陈年老文章(此文成于2012年,只在公司内部分享过),大部分内容来自Windows内核原理 1句柄和句柄泄露 在Windows编程过程中,很多时候我们都要和句柄打交道,比如窗体句柄,内核对象句柄,GDI句柄,Windows Multimedia库中的多种句柄等等,以及其他更多未曾使用过的句柄类型.句柄(Handle)是Win

白话windows内核对象共享之复制对象句柄

引子:话说老王的果园大丰收,老王心花怒放,带着全家去美国阿拉斯加度假.阿拉斯加有很多东西琳琅满目,都是中国没有的,老王及家人都过了一把购物瘾.但是有一次却遇到了比较尴尬的事.怎么回事呢?原来老王第一次出国,在买地摊上的东西时讨价还价100元,但是给人家的却是100元人民币,人家自然不干撒,你100元才多少美元呀,老王只好忍痛割爱给了600元人民币. 为什么会出现这样的尴尬呢?因为两个国家的货币换算不是一样的.中国的100元和美国的100元不是等价的,如何才能等价呢?必须根据当前汇率来换算.今天要

第3章 内核对象(2)

3.3 跨进程边界共享内核对象 3.3.1 使用对象句柄继承 (1)对象句柄继承,只发生在进程之间有父子关系的时候(即一个进程而另一个进程CreateProcess起来) (2)内核对象句柄继承的实现 ①父进程必须先指出哪些内核对象句柄是可继承(注意不是内核对象本身的继承,而是内核对象的句柄继承),父进程在创建内核对象时要将SECURITY_ATTRIBUTES的bInheritHandle字段设为TRUE,表示可继承.这时句柄表中相应的记录项的标志位被设为1,否则为0. ②父进程调用Creat

第3章 内核对象(1)

3.1 何为内核对象 3.1.1 Windows平台上的3大对象 (1)分类 对象 描述 备注 GUI对象 也叫用户对象,一般是单线程访问,属于线程级的对象,如 加速键表(HACCEL).插入记号(Caret).光标(HCURSOR).桌面(HDESK). 钩子(HHOOK).图标(HICON).菜单(HMENU).窗口(HWND).窗口栈(HWINSTA) 句柄值是系统唯一的,即一个进程可以通过该句柄值对另一个进程中的对象进行操作,如发送消息. GDI对象 如DC.Pen.Font等,一般是单

Windows内核之内核对象

1内核对象定义: 1.1:每个内 核对象只是内核分配的一个内存块,并且只能由该内核访问. 1.2:该内存块是一种数据结构,它的成员负责维护该对象的各种信息. 有些数据成员(如安全性描述符.使用计数等)在所有对象类型中是相同的,但大多数数据成员属于特定的对象类型.例如,进程对象有一个进程ID .一个基 本优先级和一个退出代码,而文件对象则拥有一个字节位移.一个共享模式和一个打开模式. 2内核对象种类: 比如存取符号对象. 事件对象.文件对象.文件映射对象.I / O 完成端口对象.作业对象.信箱对

WVC_01_内核对象

内核对象是由内核分配的一个内存块,该内存块是一种数据结构,只能由内核访问和修改.内核对象可以被系统或应用程序用来管理各种各样的资源. 应用程序中经常需要通过调用Win32 API函数来创建各种内核对象,如文件对象,文件映射对象,进程对象,线程对象等. 内核对象是由内核所有,而不是由进程所有. 除了内核对象,还有用户对象,如菜单,窗口,画刷,字体等. 当调用一个用于创建内核对象的函数时,该函数就返回一个用于标识该对象的句柄. 进程的内核对象句柄表 每个进程被初始化时,系统要为它分配一个句柄表.该句

内核对象

每个内核对象都只是一个内存块,它由操作系统内核分配,并只能由操作系统内核访问.这个内存块是一个数据结构,其成员维护着与对象相关的信息.少数成员(安全描述符和使用计数)是所有对象都有的,但其他大多数成员都是不同类型的对象特有的 由于内核对象的数据结构只能由操作系统内核访问,所以应用程序不能在内存中定位这些数据结构并直接更改其内容.正因为有这个限制,所以微软能自由地添加.删除或修改这些数据结构中的成员,同时不会干扰任何应用程序的正常运行 为了增强系统的可靠性,内核对象的句柄是与进程相关的.如果进程A

线程同步——内核对象实现线程同步——等待函数

1 对于内核对象实现线程同步,不得不提三点: 2 1)大多数内核对象既有触发也有未触发两个状态 3 比如:进程.线程.作业.文件流.事件.可等待的计时器.信号量.互斥量 4 2)等待函数:等待函数使线程自愿进入等待状态,直到指定的内核对象变为触发状态为止, 5 说道等待我们最喜欢不过了,因为这样不会浪费我们宝贵的CPU时间. 6 3)对于自动重置对象来说,当对象被触发时,函数会自动检测到(手动重置对象为触发是,函数也能检测到), 7 并开始执行,但是在函数会在返回之前使事件变为非触发状态. 8

Windows API学习---线程与内核对象的同步

前言 若干种内核对象,包括进程,线程和作业.可以将所有这些内核对象用于同步目的.对于线程同步来说,这些内核对象中的每种对象都可以说是处于已通知或未通知的状态之中.这种状态的切换是由Microsoft为每个对象建立的一套规则来决定的.例如,进程内核对象总是在未通知状态中创建的.当进程终止运行时,操作系统自动使该进程的内核对象处于已通知状态.一旦进程内核对象得到通知,它将永远保持这种状态,它的状态永远不会改为未通知状态. 当进程正在运行的时候,进程内核对象处于未通知状态,当进程终止运行的时候,它就变