Windows 是一个对象驱动的OS。通过研究RecctOS 研究下对象的结构,创建,管理,删除操作。

1.对象的结构

其实对象就是一块内存,对象的结构有对象头和对象体两部分组成。

1.1对象头的结构:

typedef struct _OBJECT_HEADER

/*

* PURPOSE: Header for every object managed by the object manager

*/

{

UNICODE_STRING Name;              // 名字

LIST_ENTRY Entry;                    // 对象链表

LONG RefCount;                       // 对象的引用计数

LONG HandleCount;                    //

BOOLEAN Permanent;                  // ??

struct _DIRECTORY_OBJECT* Parent;

POBJECT_TYPE ObjectType;            // 对象的类型

/*

* PURPOSE: Object type

* NOTE: This overlaps the first member of the object body

*/

CSHORT Type;

/*

* PURPOSE: Object size

* NOTE: This overlaps the second member of the object body

*/

CSHORT Size;                       对象的大小,包含了对象体

} OBJECT_HEADER, *POBJECT_HEADER;

对象头是通用的,也就是说,所有类型的对象的对象头结构是一致的。那么我们对对象的访问也就可以通用起来。

1.2 对象体的结构
不同的对象的对象体是不同的。

2. 对象的创建

在0.17代码中,是通过ObCreateObject 系统调用实现的。

PVOID STDCALL ObCreateObject(PHANDLE Handle,

ACCESS_MASK DesiredAccess,

POBJECT_ATTRIBUTES ObjectAttributes,

POBJECT_TYPE Type)

{

if (ObjectAttributes != NULL &&

ObjectAttributes->ObjectName != NULL)

{

ObFindObject(ObjectAttributes,

&Parent,

&RemainingPath,

NULL);

}

else

{

RtlInitUnicodeString (&RemainingPath, NULL);

}

RtlMapGenericMask(&DesiredAccess,

Type->Mapping);

/*分配对象的内存*/

Header = (POBJECT_HEADER)ExAllocatePool(NonPagedPool,

OBJECT_ALLOC_SIZE(Type));

/*初始化对象数据*/

ObInitializeObject(Header,

Handle,

DesiredAccess,

Type,

ObjectAttributes);

if (Header->ObjectType != NULL &&

Header->ObjectType->Create != NULL)

{

/*初始化该类型的对象体*/

Status = Header->ObjectType->Create(HEADER_TO_BODY(Header),

Parent,

RemainingPath.Buffer,

ObjectAttributes);

RtlFreeUnicodeString( &RemainingPath );

/*返回对象体*/

return(HEADER_TO_BODY(Header));

}

[ObCreateObjcet ----- > ObInitializeObject ]

VOID ObInitializeObject(POBJECT_HEADER ObjectHeader,

PHANDLE Handle,

ACCESS_MASK DesiredAccess,

POBJECT_TYPE Type,

POBJECT_ATTRIBUTES ObjectAttributes)

{

/*初始化对象的头*/

ObjectHeader->HandleCount = 0;

ObjectHeader->RefCount = 1;

ObjectHeader->ObjectType = Type;

if (ObjectAttributes != NULL &&

ObjectAttributes->Attributes & OBJ_PERMANENT)

{

ObjectHeader->Permanent = TRUE;

}

else

{

ObjectHeader->Permanent = FALSE;

}

RtlInitUnicodeString(&(ObjectHeader->Name),NULL);

/* 在当前进程中创建一个handle指向该对象*/

if (Handle != NULL)

{

ObCreateHandle(PsGetCurrentProcess(),

HEADER_TO_BODY(ObjectHeader),

DesiredAccess,

FALSE,

Handle);

}

}

//

3. 对象的使用

/*
  * PURPOSE: Returns the byte offset of a field within a structure
  */

#define FIELD_OFFSET            (long)( & ((type*)(0) -> field))

/*
 * PURPOSE: Returns the base address structure if the caller knows the
 * address of a field within the structure
 * ARGUMENTS:
 *          Address = address of the field
 *          Type = Type of the whole structure
 *          Field = Name of the field whose address is none
 */

#define  CONTAINING_RECORD(Address, type , field )   (type*)( (long)Address - FIELE_OFFSET(type, fileld) )

上面是两个非常精致的宏。。。从注释可知:

宏1 是返回一个字段相对于结构体的偏移。。

宏2 是已知一个字段的地址,根据该地址得到结构体的地址 。。

NTSTATUS ObCreateHandle(PEPROCESS Process,
   PVOID ObjectBody,
   ACCESS_MASK GrantedAccess,
   BOOLEAN Inherit,
   PHANDLE HandleReturn)
/*
 * FUNCTION: Add a handle referencing an object
 * ARGUMENTS:
 *         obj = Object body that the handle should refer to
 * RETURNS: The created handle
 * NOTE: THe handle is valid only in the context of the current process
 */
{
   LIST_ENTRY* current;
   unsigned int handle=1;
   unsigned int i;
   HANDLE_BLOCK* new_blk = NULL;
   PHANDLE_TABLE HandleTable;
   KIRQL oldlvl;
  
   DPRINT("ObCreateHandle(Process %x, obj %x)\n",Process,ObjectBody);
  
   if (ObjectBody != NULL)
     {
 BODY_TO_HEADER(ObjectBody)->HandleCount++;
     }
  
   HandleTable = &Process->HandleTable;    // 得到进程的句柄表(是一个双向链表 LIST_ENTRY)
   
   KeAcquireSpinLock(&HandleTable->ListLock, &oldlvl);
   current = HandleTable->ListHead.Flink;               // 
   
   /*
    * Scan through the currently allocated handle blocks looking for a free
    * slot
    */
   while (current != (&HandleTable->ListHead))
     {
 HANDLE_BLOCK* blk = CONTAINING_RECORD(current,HANDLE_BLOCK,entry);

DPRINT("Current %x\n",current);

for (i=0;i<HANDLE_BLOCK_ENTRIES;i++)
   {
      DPRINT("Considering slot %d containing %x\n",i,blk->handles[i]);
      if (blk->handles[i].ObjectBody==NULL)
        {
    blk->handles[i].ObjectBody = ObjectBody;
    blk->handles[i].GrantedAccess = GrantedAccess;
    blk->handles[i].Inherit = Inherit;
    KeReleaseSpinLock(&HandleTable->ListLock, oldlvl);
    *HandleReturn = (HANDLE)((handle + i) << 2);
    return(STATUS_SUCCESS);
        }
   }
 
 handle = handle + HANDLE_BLOCK_ENTRIES;
 current = current->Flink;
     }
  
   /*
    * Add a new handle block to the end of the list
    */
   new_blk = (HANDLE_BLOCK *)ExAllocatePool(NonPagedPool,sizeof(HANDLE_BLOCK));
   memset(new_blk,0,sizeof(HANDLE_BLOCK));
   InsertTailList(&(Process->HandleTable.ListHead),
    &new_blk->entry);
   KeReleaseSpinLock(&HandleTable->ListLock, oldlvl);
   new_blk->handles[0].ObjectBody = ObjectBody;
   new_blk->handles[0].GrantedAccess = GrantedAccess;
   new_blk->handles[0].Inherit = Inherit;
   *HandleReturn = (HANDLE)(handle << 2);
   return(STATUS_SUCCESS);
}

从上面的代码可以看出, 进程的句柄链表是 分块的, 也就是下面的结构

Block 1  --- > block 2 ---- > Block 3------> block4

|                   |                    |                     |

handle1           handle4           ....                  ......

handle2           handle5

handle3           handle6

并且一个block是一个page..

转载于:https://www.cnblogs.com/herso/archive/2009/07/13/1522881.html

ReactOS 对象的结构,创建,使用,删除相关推荐

  1. C# 阿里云对象存储OSS创建、删除、上传代码实现

    一.开始接入 1.Nuget安装Aliyun.OSS.SDK: 2.代码实现: /// <summary> /// 阿里云对象存储服务 /// </summary> publi ...

  2. NGUI创建Camera参数为Simple 2D的UI UI对象的结构UI Root(2D)

    NGUI创建Camera参数为Simple 2D的UI UI对象的结构UI Root(2D) 使用NGUI创建的Camera参数为Simple 2D的UI,会在游戏的场景中生成1个名为UI Root( ...

  3. unity双击打不开脚本_游戏对象和脚本 (创建一个时钟)

    该文章是一篇译文,附上原文链接 Game Objects and Scripts​catlikecoding.com 使用简单对象构建一个时钟 编写一个C#脚本 转动时钟的指针来显示时间 创建指针动画 ...

  4. Oracle数据库:创建和删除视图view,简单和复杂视图,内建视图,topN分析,oracle分页查询

    Oracle数据库:创建和删除视图view,简单和复杂视图,内建视图,topN分析,oracle分页查询 2022找工作是学历.能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开 ...

  5. oracle创建和删除表空间,oracle 表空间创建和删除

    oracle数据库:数据库对象以及表数据都存储在表空间中,创建用户时可以指定对应的表空间.这样用户可以在各自的表空间中操作数据,互不干扰. 1. 表空间创建 若不清楚表空间对应文件的路径,可以登录系统 ...

  6. #python元组(元组的创建和删除)

    元组的创建和删除 元组(tuple)是python中另一个重要的序列结构,与列表类似,也是有一系列按特定排列的元素组成.但是他是不可变序列,因此元组也可以称之为不可变的列表.在形式上元组的所有元素都放 ...

  7. JAVA基础初探(十二)Map接口及其常用实现类(HashMap)、File类详解(概述、创建、删除、重命名、文件属性读取/设置、遍历文件夹)

    该篇博客目录 1.Map接口及其常用实现类(HashMap.Hashtable) 2.File类(概述.创建.删除.重命名.文件属性读取/设置.遍历文件夹) 一.Map接口及其常用实现类(HashMa ...

  8. MySQL之数据表(数据库的创建与删除、数据表的创建与删除)

    MySQL之数据表 创建数据库 删除数据库 认识数据表 创建数据表 删除数据表 创建数据库   在创建表之前,一定要先创建用来存储表的数据库.数据库中包含数据表.视图.索引.查询.规则.默认值等数据库 ...

  9. 2019-7-26 [MySQL] 安装与介绍 语句分类/语法 数据类型 DDL数据定义:创建/查看/删除/使用 DML数据操作:增删改 主键约束 自动增长列 非空约束 默认值 Navicat

    文章目录 0.知识回顾 1.数据库介绍 1.1 数据库概述 1.1.1 什么是数据库 1.1.2 什么是数据库管理系统 1.1.3 数据库与数据库管理系统的关系 1.2 数据库表 1.3 表数据 1. ...

最新文章

  1. 求真不二,春风细雨:AI界追忆黄煦涛教授的为学、为师、为人
  2. 你的GitHub爆款项目,面试官可能问都不问
  3. sql server 数据库 ' ' 附近有语法错误
  4. SVN报Previous operation has not finished; run 'cleanup' if it was interrupted错误的解决方法
  5. 【深度学习】PyTorch 数据集随机值的完美实践
  6. 2.2 矩阵基本运算
  7. 【汇编语言】程序设计过程,如何避免数据类型匹配错误?
  8. C语言(CED)钢条最优切割收益
  9. 9块钱,构建个私有网盘,关键不限速
  10. 基于JAVA+SpringBoot+Mybatis+MYSQL的在线动漫信息平台
  11. SQL计算两个日期之间的工作天数
  12. Let’s Encrypt 推动了 HTTPS 的普及
  13. 利用git进行word文档的版本管理
  14. 3DMax2015的下载和安装
  15. android7.1.1彩蛋魅族,魅族PRO 6 Android 7.1.1尝鲜, 一功能很“原生”
  16. 创宇区块链|Inverse Finance 安全事件分析
  17. yum下载速度慢解决,提速飞起来
  18. 无线网络 笔记本连接正常上网,手机之类的就不能上网
  19. application-dev.yml、application-test.yml、application-prod.yml的区别
  20. 2023创业可以做什么项目,适合新手的六个创业项目推荐

热门文章

  1. Spring MVC应用@Autowired和@Service进行依赖注入
  2. Java 枚举(enum)
  3. ai面试的优缺点_面试也能开“外挂”?领英AI做了什么
  4. 零基础学python看什么书好?
  5. 『初识C语言』语法入门详解
  6. P - C语言实验——某年某月的天数
  7. 云服务器搭建虚拟主机教程,云服务器搭建虚拟主机教程
  8. 计算机基础知识判断题答案,计算机基础知识试题及答案判断题模板.docx
  9. linux 工业 网络协议,简单了解Linux TCP/IP协议栈
  10. 学好python需要哪些基础_学Python要避免哪些坑,如何巩固好基础