当前位置: 首页 > news >正文

第3章 Windows运行机理-3.1 内核分析(6)

3.1.3 VxD的设计实现

VxD的设计并不是通常我们所讲的调用API的Windows程序,而是通过对DDK的调用来工作。DDK可以从微软的网站上下载。在DDK中有很多VxD的例子,我们在设计时可以作为参照样板。VxD的设计一般要直接用汇编编程,并且要直接地操作硬件,所以设计比较困难。不过,用汇编写VxD的框架结构、用C来完成具体的工作实现就会大大地提高开发的效率,后面的例子中就是使用了这种方法。

1. 静态VxD

在下列情况下,VMM加载一个静态VxD:

(1)此VxD在注册表中的如下位置有定义:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\key\StaticVxD=VxD带路径文件名

(2)此VxD在system.ini中的[386enh]行下有定义:

[386enh] section:

device=VxD带路径文件名

在开发的时候,建议从system.ini载入VxD程序,因为这样如果VxD程序有错而将导致Windows不能启动,可以在DOS下修改system.ini,而如果使用注册表载入的办法,就无法修改了。

当VMM加载静态VxD程序时,VxD程序会按以下顺序接收到3个系统控制消息。

(1)Sys_Critical_Init:VMM在转入到保护模式后,开放中断前发出这个控制消息。大多数VxD程序不要用这个消息,除非VxD程序要接管一些其他VxD程序或者保护模式程序要用到的中断。既然处理这个消息的时候,这个中断还没有打开,就可以确定在你接管这个中断的时候,此中断不会被调用。VxD程序为其他的VxD程序提供了一些VxD服务。

(2)Device_Init:控制消息时需要调用一些VxD服务,既然Sys_Critical_Init 控制消息在Device_Init消息之前被发送,所以你应该在Sys_Critical_Init 消息发送时初始化你的程序。

如果要对这消息进行处理,则应该尽可能快地做完初始化工作,以免太长的执行时间导致硬中断丢失(记住,中断还没打开)。Device_Init VMM在开放中断后发送此信息。大多数VxD程序都在得到这个消息时初始化。因为中断都开放了,所以耗时的操作也可以在这里执行,而不怕会导致硬中断的丢失。你可以在这时进行初始化(如果你需要的话)。

(3)Init_Complete:在所有的VxD程序处理完Device_Init 消息之后,VMM释放初始化段(ICODE和RCODE段类)之前,VMM发出这个控制消息。只有少数几个VxD要处理这个消息。

VxD程序在成功地初始化后,必须将返回标志清零,反之,必须在返回之前把返回标志设为出错信息。如果VxD不需要初始化,就不必对这些消息进行处理。

当要结束静态VxD的时候,VMM发送如下的控制消息。

(1)System_Exit2:当VxD程序收到这个消息,Windows 9x正在关闭系统,除了系统虚拟机外,所有其他虚拟机都已经退出了。尽管如此,CPU仍然处于保护模式下,在系统虚拟机上执行实模式编码也是安全的。这时,Kernel32.dll也已经被卸载了。

(2)Sys_Critical_Exit2 :当所有的VxD完成对System_Exit2的响应处理并且中断都被关闭后,VxD收到这个消息。

许多VxD程序并不要响应这两个消息,除非你要为系统做转换到实模式的准备。要知道,当Windows 95关闭时,它进入到实模式。所以,如果VxD程序对实模式影像做了一些会导致它不稳定的操作,它就需要在这时进行恢复。

你也许会感到奇怪:为什么这两个消息后面都跟着个“2”?这是因为在VMM加载VxD程序的时候,它是按照初始化顺序值小的VxD先加载的顺序加载的,这样,VxD程序就可以使用那些在它们之前加载的VxD程序提供的服务。例如,VxD2要用到VxD1中的服务,它就必须把它的初始化顺序值定义得比VxD1小。加载的顺序是:

..... VxD1 => VxD2 => VxD3 .....

那么卸载的时候,理所当然地是初始化顺序值大的VxD程序先被卸载,这样它们仍然可以使用比它们后加载的那些VxD程序提供的服务。如上面的例子,次序是:

.... VxD3 => VxD2 => VxD1.....

在上边的例子中,如果VxD2在初始化时调用了VxD1中的某些服务,那么卸载时它可能也要再次用到一些VxD1中的服务。System_Exit2和Sys_Critical_Exit2是按反初始化顺序发送的。这表示,当VxD2接受到这些消息时,VxD1还没有被卸载,它仍可以调用VxD1的服务,而System_Exit和Sys_Critical_Exit消息不是按照反初始化顺序发送的。这意味着,你不能肯定你是否仍能调用在你之前加载的VxD提供的VxD服务。

现在的VxD程序不应该使用这些消息,而应该使用以下两种退出消息。

(1)Device_Reboot_Notify2 告诉VxD程序VMM正在准备重新启动系统。这时候,不管是中断还是开放的Crit_Reboot_Notify2,都会告诉VxD程序VMM正在准备重新启动系统,并把中断关闭。

(2)Device_Reboot_Notify和Crit_Reboot_Notify 消息一样,但它们并不是像“2”版本的消息那样,按反初始化顺序发送。其他就和Device_Reboot_Notify2一样了。

2. 动态VxD

动态VxD在Windows 9x里可以动态地被加载和卸载。这个特点在Windows 3.x下是没有的。动态VxD程序的主要作用是用来支持某些动态的硬件设备的重装,比如即插即用设备。尽管如此,可以从Win32程序中加载/卸载它,也可以把它看做是程序的一个到ring0的扩展。

上一节我们提到的例子是一个静态的VxD,你可以把它转换成一个动态的VxD,只要在.def文件中VxD标记的后面加上关键字DYNAMIC:

VxD STHVxD DYNAMIC

这就是把一个静态VxD转换成一个动态的VxD所要做的一切。

一个动态的VxD可以按以下的方法被加载。

(1)把它放到Windows目录下的\SYSTEM\IOSUBSYS目录中。在这个目录里的VxD会被输入输出监视器(IOS)加载。这些VxD必须支持层设备驱动。所以用这种方法加载动态VxD并不是一个好办法。

用VxD加载服务。VxDLDR是一个可以加载动态VxD的静态VxD。你可以在其他VxD里面或者在16位代码里面调用它的服务。

http://www.jsqmd.com/news/399196/

相关文章:

  • [Kaleidscope of Physics] 有心力和有心运动
  • 第3章 Windows运行机理-3.1 内核分析(7)
  • 2026年永真片市场概览:哪些品牌口碑与销量俱佳?永真片/生脉饮/养胃颗粒/抗衰老片/人参方,永真片品牌推荐排行榜单 - 品牌推荐师
  • 深入浅出Java线程池(二)
  • 本科生收藏!千笔,备受推崇的AI论文平台
  • vue+springboot校园学生健康监测数据管理系统的设计与实现
  • vue+springboot校园活动报名系统 场地预约系统
  • vue+springboot微信小程序 网上订餐配送系统
  • vue+springboot新农村信息平台建设——土地资源管理子系统
  • 浮点数在内存中的存储结构
  • [杂] 稍后再看
  • Kafka生态深化——Schema与Connect、CDC入湖的链路与一致性挑战
  • [杂] 网易云评论区评论烟之暗面
  • 研究生必看!圈粉无数的降AIGC软件 —— 千笔·降AIGC助手
  • 真空管市场2026新观察:这些厂商为何备受瞩目?液氩/真空管/液氧/制氮机/液氮/二氧化碳,真空管直销厂家找哪家 - 品牌推荐师
  • 京东e卡回收新思路,让闲置卡券“活”成现金流 - 京顺回收
  • 2026中低压管件生产新趋势,高压管件实力厂商盘点,管件/保温管道/工厂预制化管道/三通管件,高压管件供应商排行 - 品牌推荐师
  • 交稿前一晚!本科生必备的降AI率网站 —— 千笔·降AI率助手
  • 直接上结论:更贴合本科生的AI论文网站,千笔AI VS Checkjie!
  • 大模型推理引擎vLLM(9): vLLM 基本代码结构
  • 大模型推理引擎vLLM(10): vLLM 分布式推理源码结构解析
  • 大专数据可视化技术专业学习数据分析的价值
  • 高职统计与会计核算专业学数据分析的价值分析
  • Manim CE v0.20.0 发布:动画构建更丝滑,随机性终于“可控”了!
  • 2026年苏州可靠的家教机构怎么收费,家教/全托补习班/一对一家教试听课/上门家教/师范家教/全托冲刺,家教机构有哪些 - 品牌推荐师
  • k8s服务发现
  • Verify-in-the-Graph 利用交互式图表示增强实体消歧的复杂声明验证方法
  • nsq阅读(2)——diskqueue
  • golang sync包源码阅读