驱动开发学习笔记(4-1)–INF文件-1

INF是Device INFormation File的英文缩写,是Microsoft公司为硬件设备制造商发布其驱动程序推出的一种文件格式,INF文件中包含硬件设备的信息或脚本以控制硬件操作。在INF文件中指明了硬件驱动该如何安装到系统中,源文件在哪里、安装到哪一个文件夹中、怎样在注册表中加入自身相关信息等等。 安装监视器、调制解调器和打印机等设备所需的驱动程序,都是通过INF文件,正是INF的功劳才使得Windows可以找到这些硬件设备的驱动并正确安装。当我们通过“开始→控制面板→添加删除程序→Windows安装程序”来添加系统组件的时候,INF文件将会自动调用。而在其他场合下,则需要在INF文件上点击鼠标右键,然后选择“安装”,你才能顺利安装应用程序。

在C:/Windows/INF文件夹中存放有大量的INF文件。该文件夹一般处在隐含状态,如果你想查看该文件夹,可选择“查看→文件夹选项→查看”,然后在“文件和文件夹”选项下选择“显示所有文件”。

解剖INF文件的结构

INF文件其实是一种纯文本文件,可以用任意一款文本编辑软件来打开进行编辑,如:记事本、写字板等。INF文件有一整套的编写规则,每一个INF文件都是严格按照这些规则来编写的。

*规则一:INF文件是分节的,每一个INF文件有许多的节组成,节名用方括号括起来。这些节名有些是系统定义好的,有一些是用户自定义的。每一个节名最长为255个字符(Windows 2000/XP/2003操作系统中)或28个字符(Windows 98操作系统中)。节与节之间没有先后顺序的区别,另外,同一个INF文件中如果出现两个同样的节名,则系统会自动将这两个节名下面的条目合并到一起。

*规则二:在节与节之间的内容叫条目,每一个节又是由许多的条目组成的,每一个条目都是由形如“signature=”$CHICAGO$””的形式组成的。如果每一个条目的等号后有多个值,则每一个值之间用“,”号分隔开。

*规则三:INF文件对大小写不敏感。

*规则四:“;”号后面的内容为注释。

*规则五:如果一个条目的内容过多,在一行无法书写完全,则用“\”将一行内容书写为多行。

Continue Reading

驱动开发学习笔记(3-8)–Four-F的驱动开发教程-后备列表

在这里下载本文的源代码

7. 后备列表

本篇翻译:songsong <http://www.songsong.org>
源代位置:KmdKit\examples\basic\MemoryWorks\LookasideList

我回来了,对门的那个白人MM听说我是黑客(其实长得黑而已)对我特崇拜,差点要以身相许,幸亏咱意志坚定……
好了,我们开始最后一节了,你能读完并理解,你就是高手了……

Continue Reading

驱动开发学习笔记(3-7)–Four-F的驱动开发教程-系统内存堆

在这里下载本文的源代码

6. 系统内存堆

本篇翻译:songsong <http://www.songsong.org>
源码位置:KmdKit\examples\basic\MemoryWorks\SystemModules

首先是罗云彬的废话:感谢刘松一起参与这个翻译项目,这样本教程的中文翻译才能这么快和大家见面,刘松是温哥华的帅哥作家,著有《GRE Yellow Bible》(《GRE词汇黄宝书》),文风幽默,看他的翻译,使大家看枯燥的驱动教程如同看泡妞教程,于轻松间掌握繁琐的东西。原本这也是本人梦想中的写作风格,可惜本人多年努力,除了外貌长得还是一如既往的幽默外,文字中还是幽默不起来,没办法哟~~~,好了,废话少说,下面请刘松出场。
(稀稀落落的掌声)……
……
我是温哥华的松松,被罗大哥抓来翻译文章,几个MM还等着我去酒吧,只好不去了……
如果各位帅哥美女已经看完了前面的基础知识,那就跟小弟来看看”一些”必要的底层技术。
为什么”一些”要加引号(一女同学提问)?那是因为驱动程序可以做许许多多的事情啊!
如果你不懂MM,你就别混了!(一男同学问:驱动程序和泡妞还有关系?)哦,我这里的MM不是指”美眉”,是指”内存管理(Memory Management)”。
好的,我们现在就开始学习MM……
内存管理器给用户进程提供了大量的用于MM的API。这些API可以分为三类:虚拟内存函数、内存映射文件函数和堆函数。内核的成员(包括驱动程序)有很多高级的工具。例如:驱动程序能够在物理地址空间里分配一个连续的内存。这类函数呢,前缀是”Mm”。另外呢,还有一种以”Ex”为前缀的函数,用于从系统内存池里(分页和不分页的)分配和释放内存,还可以操作后备列表(lookaside lists)。
后备列表是啥东东?我们下一节会讲,它可以提供更快的内存分配,却要使用预定义的固定的块大小。

Continue Reading

驱动开发学习笔记(3-5)–Four-F的驱动开发教程-I/O子系统

在这里下载本文的源代码

4. I/O子系统

※ 和本节内容相关的源代码见KmdKit\examples\simple\VirtToPhys

4.1 I/O管理器

在用户模式下,我们可以通过访问某个地址来直接调用dll中的函数,与此不同的是,从系统的稳定性考虑,在内核模式下这样做的话是很危险的。所以,系统提供了和内核模式通讯的媒介–I/O管理器,它是I/O子系统的部件之一。I/O管理器将应用程序、系统部件和设备连接起来,并定义了一个架构来支持设备驱动程序。
图4.1是I/O管理器如何在用户模式程序和驱动程序之间进行沟通的简单图解。

图4.1 I/O子系统的简单架构

从上图可以看到,所有用户模式程序到设备(包括设备驱动程序)的调用都必须通过I/O管理器来完成。
一般来说,用户模式的操作都被转换成了对具体硬件设备的I/O操作,仅对于某些设备,设备由驱动程序来创建和控制,这些设备就是虚拟设备。当然,创建这些设备并不意味着你创造了什么硬件(不然我每天创建n个显卡再卖掉,然后换BMW,呵呵~~~~),而仅仅是在内存中创建了一个新的对象而已。每个对象和一个物理设备或者逻辑设备对应,用于描述它们的特征。
创建设备后,驱动程序告诉I/O管理器:”这里有个我控制的设备,如果你收到了操作这个设备的I/O请求的话,直接发给我好了,剩下的由我来搞定!”。驱动程序知道如何对自己管理的设备进行I/O操作,I/O管理器唯一的职责在于创建I/O请求并把它发送给适当的设备驱动程序。用户模式的代码不知道(也不必知道)其中的细节,也不用知道究竟是哪个驱动程序在管理哪个设备。

Continue Reading

驱动开发学习笔记(3-4)–Four-F的驱动开发教程-最简单的设备驱动程序

在这里下载本文的源代码

3. 最简单的设备驱动程序

※ 和本章内容相关的源代码见:
KmdKit\examples\simple\Beeper
KmdKit\examples\simple\DateTime

3.1 如何编译和链接内核模式驱动程序

我总是把驱动程序的汇编源代码放到批处理文件中,这样的文件从内容上看是.asm和.bat文件的混合体,但是扩展名是.bat(注:读者在实际使用的时候是不是这样做完全可以根据个人喜好而定)

;@echo off
;goto make

.386                      ; driver's code start
  ;::::::::::::::::::::::::::::::::
  ; the rest of the driver's code ;
  ;::::::::::::::::::::::::::::::::
end DriverEntry            ; driver's code end

:make
set drv=drvname
\masm32\bin\ml /nologo /c /coff %drv%.bat
\masm32\bin\link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native %drv%.obj
del %drv%.obj
echo.
pause

如果你运行这个”自编译”的批处理文件的话,系统会做以下的事情:
对于汇编编译器来说,前面两行的命令是被注释掉的,所以会被忽略;但是对于命令解释器来说,这两行会被执行,因为命令解释器会忽略前面的分号。这样一来,执行会跳到最后面的:make标号处,接下来下面的编译和链接命令就会被执行,跳转语句和:make标号中间的汇编源代码会被忽略。另外,对于汇编编译器来说,所有end标号后面的内容都会被忽略,所以后面的:make及其后的内容会被编译器忽略。
这种方式用起来很方便,因为源代码和如何编译、链接程序的信息都被放在一起了,如果需要的话,读者也可以自己另外加些命令上去,在我编写的所有的驱动代码中,我都使用了这种方法。
下面我来解释一下:make后面的一些命令的含义。

Continue Reading

驱动开发学习笔记(3-3)–Four-F的驱动开发教程-服务

在这里下载本文的源代码

2. 服务

※ 和本节对应的例子代码见KmdKit\examples\simple\Beeper

读者也许有点疑惑:用户模式的服务关内核模式的驱动程序什么事呀?事实上,两者的确风马牛不相及,但是如果我们要和设备驱动程序通讯的话,我们必须首先安装它,启动它,而和设备驱动程序通讯的界面刚好和服务通讯的界面是类似的。

2.1 Windows服务

Windows NT使用某种机制来启动进程,并让它们不和某个具体的交互式的用户界面相关联,这些进程就被称为服务(service),服务的一个很好的例子就是Web服务器,这些Web服务都没有用户界面,服务是唯一以这种方式运行的应用程序(注:指没有用户界面,当然,严格地说病毒、木马以及所有不想见光的程序也是这样的~~),服务可以在系统启动的时候自动启动,也可以被手工启动,从这一点来看,设备驱动程序和服务是类似的。
Windows NT还支持驱动程序服务,只要使用的时候遵循设备驱动程序协议就可以了,这和用户模式的服务类似,所以,”服务”一词既可以指用户模式的服务进程或者内核模式的设备驱动程序,微软不知何故没有明确地区分两者的概念,所以下面的叙述可能看起来有点让人疑惑。可能有的地方我会说到”driver”一词,但在其他的文章中可能说到”service”一词,但既然这篇教程讲的是如何编写内核设备驱动程序,那么我们就约定无论说到”service”还是”driver”,我们的意思都是指”驱动程序”,当的确需要提及”服务”的时候,我会明确地指出来的。
另外,请读者时刻记得,文档中关于服务管理的函数其实是叙述得相当含糊的,因为这些函数既能用于驱动程序也能用于服务,在下面的文章中,我们只强调它们在驱动方面的用途和忽略服务方面的用途。
Windows NT中有三个组件和服务管理相关:
◎ 服务控制管理器(Service Control Manager/SCM)–用于启动服务以及和它通讯
◎ 服务控制程序(Service Control Program/SCP)–用于和SCM进行通讯,告诉它何时启动或者停止服务

Continue Reading

驱动开发学习笔记(3-2)–Four-F的驱动开发教程-内核模式驱动程序基础

1.Kernel Mode驱动程序基础

本教程讲述了如何在Windows NT为基础的操作系统上用Win32汇编开发KMD,包括NT4.0、2000、XP和2003等操作系统。开发Windows 95/98/ME使用的VxD驱动程序方面的知识并不在本教程讲述的范围内,另外,毫无疑问本教程并不那么完美,可能还包含了诸多未发现的错误,如果您发现了问题,请告知作者,毕竟作者的母语并不是英语,把它翻译成英文已经够难为我了(注:原作者是俄国人也),也感谢masquer和Volodya的校对工作。

1.1 KMD结构概述

1.1.1 主要组成部分

根据地址空间、代码权限和职责的不同,Windows NT内部划分为两个截然不同的部分。
地址空间的享用方式也非常容易理解,整个32位系统的4GB内容被划分为两个相等的部分,用户模式(user-mode)的进程使用的地址空间被映射到低位的2GB上(地址范围00000000 – 7FFFFFFFh),而高位的2GB(地址范围80000000h – 0FFFFFFFFh)则供操作系统的组成部分来使用,如设备驱动程序、系统内存池、系统使用的数据结构等,在这部分中,内存共享的权限和职责等方面就要复杂一点了。

下面就是用户模式进程的一些简单分类:
◎ 系统支持进程–如Logon进程(位于\%SystemRoot%\System32\Winlogon.exe)
◎ 服务进程–如Spooler进程(位于\%SystemRoot%\System32\spoolsv.exe)
◎ 用户应用程序–任何Win32、Windows 3.1、DOS、POSIX或者OS/2程序
◎ 子系统–Windows内置3个子系统:Win32(位于\%SystemRoot%\System32\Csrss.exe)、POSIX子系统(位于\%SystemRoot%\System32\Psxss.exe)和OS/2子系统(位于\%SystemRoot%\System32\Os2ss.exe),在Windows XP以及后续的操作系统中,POSIX和OS/2子系统已经被去掉了。

Continue Reading