ReactOS 对象的结构,创建,使用,删除
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 对象的结构,创建,使用,删除相关推荐
- C# 阿里云对象存储OSS创建、删除、上传代码实现
一.开始接入 1.Nuget安装Aliyun.OSS.SDK: 2.代码实现: /// <summary> /// 阿里云对象存储服务 /// </summary> publi ...
- 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( ...
- unity双击打不开脚本_游戏对象和脚本 (创建一个时钟)
该文章是一篇译文,附上原文链接 Game Objects and Scriptscatlikecoding.com 使用简单对象构建一个时钟 编写一个C#脚本 转动时钟的指针来显示时间 创建指针动画 ...
- Oracle数据库:创建和删除视图view,简单和复杂视图,内建视图,topN分析,oracle分页查询
Oracle数据库:创建和删除视图view,简单和复杂视图,内建视图,topN分析,oracle分页查询 2022找工作是学历.能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开 ...
- oracle创建和删除表空间,oracle 表空间创建和删除
oracle数据库:数据库对象以及表数据都存储在表空间中,创建用户时可以指定对应的表空间.这样用户可以在各自的表空间中操作数据,互不干扰. 1. 表空间创建 若不清楚表空间对应文件的路径,可以登录系统 ...
- #python元组(元组的创建和删除)
元组的创建和删除 元组(tuple)是python中另一个重要的序列结构,与列表类似,也是有一系列按特定排列的元素组成.但是他是不可变序列,因此元组也可以称之为不可变的列表.在形式上元组的所有元素都放 ...
- JAVA基础初探(十二)Map接口及其常用实现类(HashMap)、File类详解(概述、创建、删除、重命名、文件属性读取/设置、遍历文件夹)
该篇博客目录 1.Map接口及其常用实现类(HashMap.Hashtable) 2.File类(概述.创建.删除.重命名.文件属性读取/设置.遍历文件夹) 一.Map接口及其常用实现类(HashMa ...
- MySQL之数据表(数据库的创建与删除、数据表的创建与删除)
MySQL之数据表 创建数据库 删除数据库 认识数据表 创建数据表 删除数据表 创建数据库 在创建表之前,一定要先创建用来存储表的数据库.数据库中包含数据表.视图.索引.查询.规则.默认值等数据库 ...
- 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. ...
最新文章
- 求真不二,春风细雨:AI界追忆黄煦涛教授的为学、为师、为人
- 你的GitHub爆款项目,面试官可能问都不问
- sql server 数据库 ' ' 附近有语法错误
- SVN报Previous operation has not finished; run 'cleanup' if it was interrupted错误的解决方法
- 【深度学习】PyTorch 数据集随机值的完美实践
- 2.2 矩阵基本运算
- 【汇编语言】程序设计过程,如何避免数据类型匹配错误?
- C语言(CED)钢条最优切割收益
- 9块钱,构建个私有网盘,关键不限速
- 基于JAVA+SpringBoot+Mybatis+MYSQL的在线动漫信息平台
- SQL计算两个日期之间的工作天数
- Let’s Encrypt 推动了 HTTPS 的普及
- 利用git进行word文档的版本管理
- 3DMax2015的下载和安装
- android7.1.1彩蛋魅族,魅族PRO 6 Android 7.1.1尝鲜, 一功能很“原生”
- 创宇区块链|Inverse Finance 安全事件分析
- yum下载速度慢解决,提速飞起来
- 无线网络 笔记本连接正常上网,手机之类的就不能上网
- application-dev.yml、application-test.yml、application-prod.yml的区别
- 2023创业可以做什么项目,适合新手的六个创业项目推荐
热门文章
- Spring MVC应用@Autowired和@Service进行依赖注入
- Java 枚举(enum)
- ai面试的优缺点_面试也能开“外挂”?领英AI做了什么
- 零基础学python看什么书好?
- 『初识C语言』语法入门详解
- P - C语言实验——某年某月的天数
- 云服务器搭建虚拟主机教程,云服务器搭建虚拟主机教程
- 计算机基础知识判断题答案,计算机基础知识试题及答案判断题模板.docx
- linux 工业 网络协议,简单了解Linux TCP/IP协议栈
- 学好python需要哪些基础_学Python要避免哪些坑,如何巩固好基础