Windows驱动学习笔记

Windows驱动学习笔记
Windows驱动学习笔记

版权声明

本书是免费的电子书,作者保留一切编辑、修改和发布的权利,在保证本书原文内容完整性(包括版权声明、作者简介、前言、正文内容、尾记)的前提下,欢迎读者以任何形式转载、复制本书,但务必不得将其用于赢利目的,否则将视为侵权行为进行追究。

本书(包括更新、勘误、技术支持)将在邪恶八进制社区(E.S.T)、泡面代码社区(iCoodle)以及作者博客同时发布,您可以在这三个站点进行下载、求助、讨论等操作,但请不要违反各论坛的有关规定。

邪恶八进制社区和泡面代码社区同时享有本书的任何处理权利。

作者简介

灰狐,又名grayfox、nokyo等,马甲众多,自2005年至2009年就读于成都信息工程学院,喜编程、擅灌水,以结识志同道合者为好,常混迹于各大BBS,潜水居多。

MSN:peiyaoqiang@https://www.360docs.net/doc/f114160554.html,

Gtalk:peiyaoqiang@https://www.360docs.net/doc/f114160554.html,

Email:peiyaoqiang@https://www.360docs.net/doc/f114160554.html,

QQ群:醉爱编程[iCoodle](群号:78298479)

个人主页:https://www.360docs.net/doc/f114160554.html,

相关链接

灰狐's Blog:https://www.360docs.net/doc/f114160554.html,

Adly's Blog:https://www.360docs.net/doc/f114160554.html,

泡面代码社区:https://www.360docs.net/doc/f114160554.html,

邪恶八进制:https://www.360docs.net/doc/f114160554.html,

关于iCoodle的一点说明

在您访问iCoodle的时候,可能还没有正式开放,因为我们苦于没有空间支持,免费的空间又总有这样那样的缺陷,希望能有好心的读者给予赞助一点服务器空间,我们只需要放置一个主页,发表原创性质的文章,仅需要您有Access数据库和支持ASP。

同时希望各位有心一起进步的会员加入到iCoodle来,我们共创一个灿烂的明天。

一开始,我只是想把自己的学习笔记、心得发出来,承蒙风泽大哥的厚爱,建议我把这些内容进行整理,制作成电子书,以方便他人的阅读、学习。

本书所涉及到的内容,大多都已经网络上广为流传,我本人是通过《Windows驱动开发技术详解》和楚狂人的《Windows驱动编程基础教程》学习的,因此本书中的内容大多是来自这两本教程中的一些总结和概括,不敢擅称“原创”。

在学习Windows驱动开发的过程中,道路不可谓曲折,从一开始学习直到半年后还是不得其门而入,对驱动学习的畏惧感骤然上升。当然,这也与我在学习的过程中心境不够清醒有关,往往感到浮躁,越是想快速入门,越是倍受挫折。

《Windows驱动开发技术详解》,这本书的确不错,由浅入深,逐步推进地对驱动开发的相关概念都进行了详细的讲解,非常适合新手入门。

学习驱动,亲自动手编写程序是必须的,而且要大量地编写,只有在亲自把代码编写完毕、调试成功之后,我们才能真正理解理论上的概念。

在我学习的过程中,非常感谢adly的指导,每当我遇到了一些难题,总会在他那里得到一针见血的答案。在adly的指点下,我也算是简单地入门了,不过想到自己在学习过程中的艰辛,还是感觉有必要把自己的学习过程记录下来,给后来的新手们一个指导。

由于我自己对驱动还不是很熟悉,在本文中难免会出现一些错误的概念或结论,如果您看到了这些错误,衷心地恳请您给予指导。

需要说明的是,本书并不是一本详尽的入门书籍,它只是根据我本人的学习过程进行的经验总结,适合作为专门教程的辅助读物。

版权声明 (1)

作者简介 (1)

前言 (2)

目录 (3)

第一章驱动开发环境的搭建 (5)

1.1关于DDK (5)

1.2关于驱动程序的编译 (5)

1.3驱动程序的运行 (6)

第二章驱动程序的结构 (8)

2.1驱动程序的头文件 (8)

2.2驱动程序的入口点 (8)

2.3创建设备例程 (9)

2.4卸载驱动例程 (10)

2.5派遣例程 (10)

第三章编写第一个驱动程序 (11)

3.1内核模式下的字符串操作 (11)

3.2内核模式下各种开头函数的区别 (12)

3.3第一个示例程序 (13)

第四章在驱动中使用链表 (17)

4.1内存的分配与释放 (17)

4.2使用LIST_ENTRY (18)

4.3使用自旋锁 (18)

4.4演示程序 (18)

第五章在驱动中读写文件 (21)

5.1使用OBJECT_ATTRIBUTES (21)

5.2创建、打开文件 (21)

5.3读写文件操作 (22)

5.4文件相关的其他操作 (22)

5.5演示程序 (23)

第六章在驱动中操作注册表 (27)

6.1创建、打开注册表 (27)

6.2读写注册表 (28)

6.3枚举注册表 (28)

6.4演示程序 (28)

第七章在驱动中获取系统时间 (31)

7.1获取启动毫秒数 (31)

7.2获取系统时间 (31)

7.3演示程序 (31)

第八章在驱动中创建内核线程 (33)

8.1创建内核线程 (33)

8.2关于线程同步 (33)

8.3演示程序 (34)

第九章初探IRP (35)

9.1IRP的概念 (35)

9.2IRP的处理 (35)

9.3IRP派遣例程示例 (36)

第十章编程加载驱动 (38)

10.1有关NT式驱动的加载 (38)

10.2服务编程加载驱动 (38)

第十一章驱动程序与应用层的通信 (43)

11.1使用WriteFile通信 (43)

11.2使用DeviceIoControl通信 (45)

第十二章HOOK SSDT的实现 (46)

12.1什么是SSDT (46)

12.2实现HOOK SSDT (46)

注:本书所述内容均来自互联网,例如楚狂人的《Windo ws驱动编程基础教程》和张帆的《Windo ws驱动开发技术详解》以及其他一些参考资料。本书属于学习笔记系列文章汇总,并不敢称为原创,凡因此书引发的版权问题,作者本人不负任何责任。

本书所有代码均经过作者的初步测试,所有章节提及到的代码均在附书源码的对应“.\Src\第x章”目录中有完整源码工程。

如果您在本书中发现错误,请及时给作者(http://nokyo.blog https://www.360docs.net/doc/f114160554.html,)留言说明,我也很愿意与您一起讨论相关的问题。

第一章驱动开发环境的搭建

工欲善其事,必先利其器。同样地,我们要想顺利地在驱动开发的道路上启程,准备一款趁手的工具是必须的。

1.1关于DDK

开发驱动程序必备的一个东西就是DDK(Device Development Kit,设备驱动开发包),它跟我们在ring3常听到的SDK差不多,只不过它们分别支持开发不同的程序而已。DDK 和微软其他的产品一样,具有良好的向后兼容性,比如你用DDK2000开发的驱动在DDK XP 里面同样可以编译,但反之却不能保证。

DDK常见的版本有DDK2000、DDK XP等(别提Win98,那已经是古董了),不过现在微软推出的驱动开发包已经不叫DDK了,而是WDK(Windows Driver Kit,Windows驱动开发包)。同时您还可能听说过DriverStudio之类的驱动开发工具,其实那只是对DDK的简单封装,跟SDK与MFC的关系差不多,不过DriverStudio不仅仅是对DDK的封装,而是个完整的开发工具包,它提供了很多有用的工具用于驱动程序的开发和调试,不过这些工具我们可以单独提取出来使用。

DDK可以在微软的官方网站下载,当然也可以在Google搜索到很多链接,推荐您至少使用DDK XP或更高的版本,下载到本地后直接双击安装就可以了。

1.2关于驱动程序的编译

前面我们说了,DDK相当于在开发普通的ring3应用程序所使用的SDK,那么我们是否有与开发ring3应用程序对应的IDE呢,比如VC6.0、https://www.360docs.net/doc/f114160554.html,2003、Delphi等。

很遗憾,除了DriverStudio,关于驱动开发的IDE我知道的不多,多数情况下我们都是使用DDK提供的builder.exe在命令行下直接编译连接生成“.sys”文件,同时还需要自己编写makefile和sources文件。

对于使用VC开始学习编程的人们来说,makefile概念有点可能有点陌生,而且很多习惯了使用IDE的人们往往很讨厌麻烦的命令行编译。实际上我们要知道,VC本身只是个框架,“编译”这个工作还是由一个名为“cl.exe”的命令行工具执行的,VC不过是通过一个良好的界面帮我们完成了一些参数设置的工作。

知道了这一点,我们就应该明白,使用VC来编译驱动程序是可行的,实际上已经有很多文章详细介绍如何使用VC环境开发驱动程序,版本从经典的VC6.0到最新的VS2008都没有被遗漏。

这里我们介绍一个简单的方法,即使用EasySys这个小工具。这是一个很实用的小工具,它可以通过简单的设置生成一个完整的“.dsw”工程,我们使用VC6.0打开该工程文件就可以方便地编写代码了,然后直接按“F7”完成编译连接这个过程。

EasySys是开源的程序,所有人都可以通过修改代码来定制自己的EasySys,但在我们对驱动开发比较熟悉之前,不建议这样做,如果我们生成的代码不合理很容易造成蓝屏。网上有很多大牛发布有自己修改过的版本,我们直接下载使用就可以了。

它通过一个批处理文件来设置编译参数,但我们在开始学习时可以不理会它是如何工作的,只要能使用就是好东西。

我们先来简单看看EasySys的界面和使用方法,如图1-1所示:

图1-1EasySys运行界面

第一个编译框我们要填写的是需要建立的工程名,不用废话了;第二个编辑框是这个工程要存在的目录,也不废话了;第三个下拉列表框是选择我们已安装的DDK版本;最后一个是选择我们的驱动程序要运行的目标系统平台,因为驱动与系统相关性很强,我们在开发的时候需要注意这个问题。

点击【Create】按钮之后会在指定的目录下创建一个文件夹,名字就是工程名,进入该目录看看,会不会觉得很眼熟?如图1-2所示:

图1-2EasySys生成的目录

双击如图1-2所示的“Test.dsw”文件便可使用VC6.0打开这个工程,我们直接编辑“Test.c”和“Test.h”这两个文件,然后编译、连接就可以生成驱动目标文件。

1.3驱动程序的运行

通常我们生成的驱动程序格式都是“.sys”,虽然它也是PE格式,但不能直接运行,必须被加载到系统中。

因此我们在编写好一个驱动程序后,如果想运行查看结果,则必须使用一些工具来进行加载,当然也可以自己编写,我们将会在第十章介绍如何编程加载驱动。现在我们使用一个名为“KmdManager”的小工具来加载驱动。其运行界面如图1-3所示:

图1-3KmdManager运行界面

如图1-3,我们先浏览找到自己需要加载的驱动文件,然后依次点击【Register】和【Run】按钮即可运行驱动程序(其实是执行DriverEntry例程),在测试完毕后记得点击【Stop】和【Unregister】按钮将其卸载。

关于驱动程序开发环境的搭建就简单介绍到这里,如果你使用的是VC其他版本,请自行通过Google搜索相关设置指导。

【补充知识】

实际上,常见的Windows驱动程序是可以分成两类的:一类是不支持即插即用功能的NT式驱动程序,另一类是支持即插即用的WDM式驱动程序。

NT式驱动的安装是基于服务的,可以通过修改注册表进行,也可以直接通过服务函数如CreateService进行安装;但WDM式驱动不同,它安装的时候需要通过编写一个inf文件进行控制。

除此之外,它们所使用的头文件也不大相同,例如NT式驱动往往需要导入一个名为“ntddk.h”的头文件,而WDM式驱动需要的却是“wdm.h”头文件。我们在学习的过程中所编写的大多属于NT式驱动,除非我们需要自己的设备支持即插即用,才需要考虑编写WDM式驱动程序。

如果没有特别声明的话,该电子书中所涉及到的驱动程序均为NT式驱动。

第二章驱动程序的结构

驱动程序与其他的普通应用程序一样,都是有着一定的框架结构的,在《Windows驱动开发技术详解》的第一章提供了两个最简单的完整驱动程序。由于代码量还是有点多,就不在这里贴出来了(本书不是入门教程,而是入门教程的辅助读物)。

2.1驱动程序的头文件

在第一章我们曾经提到过,NT式驱动需要导入的头文件是“ntddk.h”,而WDM式驱动需要导入的是“wdm.h”,即:#include"ntddk.h";。

在驱动中用到的变量或函数都需要指定分配在分页或非分页内存中,分页内存在物理内存不够的情况下可能会被交换出去,对于一些需要高IRQL的例程绝对不能被交换出页面,因此它们必须被定义为非分页内存。

关于非页内存与非分页内存的详细介绍,我看到过一篇非常不错的文章,

“https://www.360docs.net/doc/f114160554.html,/u/25096/showart_463863.html”,这篇文章对于新手可能不太容易看懂,不过等学到一定程序再回来看就会很容易理解。

通常来说在驱动程序的自定义头文件中都是定义了一些宏或函数声明,没有什么特别需要注意的地方。

在配套工具目录的第二章里面有一个由EasySys生成的框架,有兴趣的可以看一下它的文件结构,暂时看不懂也可以先有个大概印象。

2.2驱动程序的入口点

犹如控制台程序需要main、Win32程序需要WinMain、DLL程序需要DllMain一样,驱动程序也有自己的入口点,即DriverEntry。

DriverEntry需要被加载到INIT内存区域中,这样当驱动被卸载后它可以退出内存。DriverEntry是由内核中的I/O管理器负责调用的,它有两个参数DriverObject和RegistryPath (当然形参的名字我们可以自己改变,这个是由EasySys生成的)。其中DriverObject是由I/O 管理器传递进来的驱动对象,RegistryPath则指向此驱动负责的注册表。

在配套工具目录的第二章里面,我们可以看到DriverEntry首先是定义了一些变量,然后调用IoCreateDevice创建设备对象,紧接着调用IoCreateSymbolicLink创建符号链接,为了条理清晰,我们在2.3中介绍这两段内容。

现在我们来看看紧接在IoCreateSymbolicLink之后的内容,如下所示:

DriverObject->MajorFunction[IRP_MJ_CREATE]=TestDispatchCreate;

DriverObject->MajorFunction[IRP_MJ_CLOSE]=TestDispatchClose;

DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=TestDispatchDeviceControl;

DriverObject->DriverUnload=TestUnload;

这是驱动程序在向Windows的I/O管理器注册一些回调函数。上面代码的含义是:当驱动程序将被卸载时自动调用TestUnload例程;当驱动程序接收到IRP_MJ_CREATE时自动调用TestDispatchCreate;剩下两个也是一样。

关于IRP的详细概念我们到后面再讲,现在我们就把它理解成ring3的“消息”一样的东西。当我们的驱动程序接收到不同的IRP就表明发生了不同的事件,然后我们及时给予处理。

在驱动对象DriverObject中,有个函数指针数组MajorFunction,它里面的每一个元素都记录着一个函数的地址对应着相应的IRP,我们可以通过简单地设置这个数组将IRP与相应的派遣函数关联起来。诸如IRP_MJ_CREATE其实是使用#define定义的一个宏,比如

IRP_MJ_CREATE实际上就是0x00,而IRP_MJ_CLOSE则是0x02等。

由于在进入DriverEntry之前,I/O管理器会将_IopInvalidDeviceRequest的地址填满整个MajorFunction数组,因此除了我们自行设置过的IRP之外,其他的IRP都与系统默认的

_IopInvalidDeviceRequest函数关联。

2.3创建设备例程

这里我们又遇到了一个新的概念“例程”,其实也不新,驱动中所说的例程实际上就是函数的另外一种说法,我们毋需过于关心这种细节(实际上例程与函数还是有所区别的,但我们不作关心)。

创建设备本来是在DriverEntry中完成的,不过这里为了讲解方便,我专门将其抽了出来,下面我们来看看相关代码:

//创建设备对象

RtlInitUnicodeString(&ntDeviceName,TEST_DEVICE_NAME_W);

Status=IoCreateDevice(

DriverObject,

sizeof(DEVICE_EXTENSION),//DeviceExtensionSize

&ntDeviceName,//DeviceName

FILE_DEVICE_TEST,//DeviceType

0,//DeviceCharacteristics

TRUE,//Exclusive

&deviceObject//[OUT]

);

if(!NT_SUCCESS(Status))

{

KdPrint(("[Test]IoCreateDevice Error Code=0x%X\n",Status));

return Status;

}

deviceE xtension=(PDEVICE_EXTENSION)deviceObject->DeviceExtension;

//创建符号链接

RtlInitUnicodeString(&dosDeviceName,TEST_DOS_DEVICE_NAME_W);

Status=IoCreateSymbolicLink(&dosDeviceName,&ntDeviceName);

if(!NT_SUCCESS(Status))

{

KdPrint(("[Test]IoCreateSymbolicLink Error Code=0x%X\n",Status));

IoDeleteDevice(deviceObject);

return Status;

}

在上述代码中,我们先来看创建设备对象的代码,首先我们使用RtlInitUnicodeString 函数来初始化UNICODE字符串,关于字符串的用法请参考其他书籍;然后我们调用函数IoCreateDevice来完成创建设备对象的功能,该函数返回一个NTSTATUS值,有一个宏

NT_SUCCESS可以很方便地判断这个NTSTATUS是否成功。

紧接着我们调用IoCreateSymbolicLink创建一个符号链接,符号链接有什么用?这么说吧,前面我们创建的设备对象虽然有个参数指定了设备名称,但是这个设备名称只能在内核态可见,也就说ring3的应用层程序是看不见它的,因此驱动程序需要向ring3公布一个符号链接,这个链接指向真正的设备名称,而ring3的应用程序可以通过该符号链接找到驱动程序进行通信。实际上我们经常所说的C盘、D盘就是一个符号链接,它们在内核中的真正设备对象是“\Device\HarddiskVolume1”和“\Device\HarddiskVolume2”。

在内核模式下,符号链接是以“\??\”(或“\DosDevices\”)开头的,如C盘就是“\??\C:”,而在用户模式下,则是以“\\.\”开头的,如C盘就是“\\.\C:”。

2.4卸载驱动例程

卸载驱动例程是我们在DriverEntry中自己定义的,当驱动被卸载时I/O管理器负责调用该例程,它主要做一些扫尾处理的工作。相关代码如下所示:

UNICODE_STRING dosDeviceName;

//释放其他资源

//删除符号链接

RtlInitUnicodeString(&dosDeviceName,TEST_DOS_DEVICE_NAME_W);

IoDeleteSymbolicLink(&dosDeviceName);

//删除设备对象

IoDeleteDevice(DriverObject->DeviceObject);

KdPrint(("[Test]Unloaded"));

上述代码没有难以理解的地方,我们就简单介绍一下代码最后一句的KdPrint吧。由于驱动程序工作于内核态,不像我们控制台的程序一样可以使用printf输出一些信息,也不像Win32程序可以通过MessageBox来弹出一个对话框,它要想输出一些信息,就需要调用DbgPrint函数,不过这个函数输出的信息我们无法直接看到,需要使用一些专门的工具,比如DbgView等。

有些内容我们只想在调试版输出,在发行版忽略,因此DDK中定义了一个宏KdPrint,它在发行版不被编译,只在调试版才会运行。KdPrint的用法很奇怪,由于它是这样定义的:#define KdPrint(_x_)DbgPrint_x_,这就导致了它的用法很奇怪,在使用时最外层要有两个连续的括号,真不知道DDK为啥这样定义,定义的时候就多加一个括号多方便啊。

2.5派遣例程

派遣例程是处理IRP的,为了快速入门,现在我们暂时不处理和IRP有关的地方,因此这里就使用EasySys生成的框架,不做修改,第九章我们会详细介绍IRP的内容。

第三章编写第一个驱动程序

其实第一个驱动程序挺难写的,因为整体的框架有EasySys帮我们生成好了,难道我们也像初学C语言时打印个“Hello,world!”?

这样也太低级了,就一句KdPrint(("He llo,world!"));谁不会啊?但要写的难一点吧,又怕看不懂,很发愁啊。也罢,我们就先介绍一下字符串吧。

3.1内核模式下的字符串操作

内核模式与用户模式一样都是有ANSI和UNICODE两种字符串,但可以这么说,Windows内核是使用Unicode编码的,ANSI只在很少的特殊场合才会使用,而这种场合往往是非常罕见的(摘自楚狂人的驱动教程),因此我们就不考虑ANSI字符串了,这里只介绍Unicode字符串的用法。

Unicode字符串有一个结构体定义如下:

typedef struct_UNICODE_STRING{

USHORT Length;//字符串的长度(字节数)

USHORT MaximumLength;//字符串缓冲区的长度(字节数)

PWSTR Buffer;//字符串缓冲区

}UNICODE_STRING,*PUNICODE_STRING;

需要注意的是,当我们定义了一个UNICODE_STRING变量之后,它的Buffer域还没有分配空间,因此我们不能直接赋值,好的做法是使用微软提供的Rtl系列函数。

UNICODE_STRING str;

RtlInitUnicodeString(&str,L"my first string!");

或者如下所示:

#include

UNICODE_STRING str=RTL_CONSTANT_STRING(L"my first string!");

看了上面的代码之后我们回顾一下第二章讲解创建设备对象和符号链接的代码,是不是就用RtlInitUnicode函数来初始化的。

还有一个需要注意的地方是,与ring3不同,我们的UNICODE字符串并不是以“\0”来表示字符串结束的,而是依靠UNICODE_STRING的Length域来确定。

字符串的很多操作都有相应的函数,例如字符串的复制可以使用RtlCopyUnicodeString 函数,字符串的比较可以使用RtlCompareUnicodeString函数,字符串转换成大写可以使用RtlUpcaseUnicodeString函数(没有转换成小写的),字符串与整数数字互相转换分别可以使用RtlUnicodeStringToInteger和RtlIntegerToUnicodeString函数。

下面我们来着重说明一下字符串的打印方法。

比如在输出日志记录的时候,我们往往同时涉及数字、字符等信息,在C语言中我们可以使用sprintf和swprintf函数来完成任务,这两个函数在驱动中仍然可以使用,但很不安全,因为有许多C语言的运行时函数都是基于Win32API的,在驱动中绝对不能使用,如果我们不清楚哪些可以使用哪些不能使用,就都不要使用,而使用微软推荐的Rtl系列函数。对应sprintf的功能函数是RtlStringCbPrintfW,它需要包含头文件“ntstrsafe.h”和静态连接库“ntsafestr.lib”。相关代码如下所示:

#include

//任何时候,假设文件路径的长度为有限的都是不对的。应该动态的分配内存。但动态分配内存的

//方法还没有讲述,所以这里再次把内存空间定义在局部变量中,也就是所谓的“在栈中”

WCHAR buf[512]={0};

UNICODE_STRING dst;

NTSTA TUS status;

……

//字符串初始化为空串。缓冲区长度为512*sizeof(WCHAR)

RtlInitEmptyString(dst,dst_buf,512*sizeof(WCHAR));

//调用RtlStringCbPrintfW来进行打印

status=RtlStringCbPrintfW(

dst->Buffer,L”file path=%wZ file size=%d\r\n”,

&file_path,file_size);

//这里调用wcslen没问题,这是因为RtlStringCbPrintfW打印的字符串是以空结束的。

dst->Length=wcslen(dst->Buffer)*sizeof(WCHAR);

RtlStringCbPrintfW在目标缓冲区内存不足的时候依然可以打印,但是多余的部分被截去了。返回的status值为STA TUS_BUFFER_OVERFLOW。调用这个函数之前很难知道究竟需要多长的缓冲区。一般都采取倍增尝试。每次都传入一个为前次尝试长度为2倍长度的新缓冲区,直到这个函数返回STA TUS_SUCCESS为止。

值得注意的是UNICODE_STRING类型的指针,通常用%wZ可以打印出字符串。在不能保证字符串为空结束的时候,必须避免使用%ws或者%s。其他的打印格式字符串与传统C语言中的printf函数完全相同。可以尽情使用。

3.2内核模式下各种开头函数的区别

在驱动开发的过程中,我们可能遇到很多不同开头的函数,如前面我们遇到过的Rtl和Io系列,此外还有比如Ex、Ps、Nt等等。

常见的函数开头及其含义如下表所示。

函数开头含义

Cc Cache manager

Cm Configuration manager

Ex Executive support routines

FsRtl File system driver run-time library

Hal Hardware abstraction layer

Io I/O manager

Ke Kernel

Lpc Local Procedure Call

Lsa Local security authentication

Mm Memory manager

Nt Windows2000system services(most of which are exported as

Win32functions),例如NtCreateFile往往导出为CreateFile Ob Object manager

Po Power manager

Pp PnP manager

Ps Process support

Rtl Run-time library

Se Security

Wmi Windows Management Instrumentation

Zw Mirror entry point for system services(beginning with Nt)that sets

previous access mode to kernel,which eliminates parameter

validation,since Nt system services validate parameters only if

previous access mode is user see Inside Microsoft Windows2000

上表中所提及到的并不完整,还有一些Dbg、Fs、Csr、Etw等开头的都没有提及到,这些可以等需要用到的时候再进行说明。

3.3第一个示例程序

现在我们把第二章生成的Test工程复制到第三章目录下并打开,然后在“Test.c”开头的函数声明处添加以下声明:

BOOL

CreateFileTest(IN PUNICODE_STRING FileName);

然后在“Test.c”的最后添加函数定义,如下所示:

BOOL

CreateFileTest(IN PUNICODE_STRING FileName)

{

BOOL bRet=FALSE;

HANDLE hFile=NULL;

NTSTA TUS status;

IO_STATUS_BLOCK Io_Status_Block;

//初始化文件路径

OBJECT_ATTRIBUTES obj_attrib;

InitializeObjectAttributes(&obj_attrib,

&FileName,

OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,

NULL,

NULL);

//创建文件

status=ZwCreateFile(hFile,

GENERIC_ALL,

NULL,

Io_Status_Block,

NULL,

FILE_ATTRIBUTE_NORMAL,

FILE_SHARE_READ,

FILE_CREATE,

FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT,

NULL,

0);

if(Io_Status_https://www.360docs.net/doc/f114160554.html,rmation!=FILE_CREATED)

{

bRet=FALSE;

}

else

{

bRet=TRUE;

}

if(hFile)

{

ZwClose(hFile);

}

return bRet;

}

上面的代码你看出问题了么,没有?好吧,我们先来编译一下:咦,出现了6个错误,真令人郁闷。

不要紧,我们慢慢来分析错误原因。

错误提示都指向了函数声明和定义的地方,提示“error C2061:syntax error:identifier

'CreateFileTest'”,啊,忘了说这时候我们不能直接使用BOOL类型的,因为我们DDK的头文件中没有定义,它是在“Windows.h”中定义的。

现在我们有两种方法解决,一是把BOOL改成BOOLEAN;二是在自己在文件开头添加一个定义“#define BOOL BOOLEAN”。我们就采用第一种办法吧,把函数声明和定义处的BOOL改成BOOLEAN。

现在我们再次编译:天哪,居然提示有46个错误和5个警告。

查看错误提示,第一个提示就是“error C2065:'BOOL':undeclared identifier”,哦,我们忘了修改函数中第一行的BOOL啦,将其改成BOOLEAN,再次编译:呵呵,变成了4个错误和2个警告。

下面这些错误比较隐蔽,而且有些错误编译器也未能发现,我就直接说出来吧。

1,我们的形参是PUNICODE_STRING类型,因此Initializ eOb jectAttributes函数的第二个参数应该是FileName而不是&FileName。

2,ZwCreateFile函数的第四个参数是PIO_STATUS_BLOCK类型,因此我们在调用的时候应该写成&Io_Status_Block。

3,ZwCreateFile函数与ring3的CreateFile函数不同,它不能直接获得需要创建或打开的文件路径信息,这个文件路径必须通过一个OBJECT_ATTRIBUTES变量传递,在前面我们定义了一个obj_attrib却在ZwCreateFile函数中忘了调用,因此我们需要把ZwCreateFile 函数的第三个参数由NULL修改成&obj_attrib。

4,我们认真查看DDK的帮助文档可以发现,ZwCreateFile的第一个参数类型应该是

PHANDLE类型,因此我们这里应该把hFile改成&hFile。由于在ring3我们很少能够遇到返回一个句柄指针的情况,所以新手往往很容易犯这个错误。

5,最后要指出的是,我们的驱动程序是使用C语言编写的,因此我们在使用一个变量前必须在函数开头进行定义,而不能像C++中那样可以“随用随定义”,否则编译器将会报错,这个务必要注意。但我们这个程序比较小,没有出现这个错误。

需要说明一点,C++同样是可以用来编写驱动程序的,不过需要稍微修改一下代码,也可以使用某些修改过的C++版EasySys。

根据上述说明,我们把函数定义分别修改如下所示(函数声明也要根据它修改):

NTSTA TUS

CreateFileTest(IN PUNICODE_STRING FileName)

{

HANDLE hFile=NULL;

NTSTA TUS status;

IO_STATUS_BLOCK Io_Status_Block;

//初始化文件路径

OBJECT_ATTRIBUTES obj_attrib;

InitializeObjectAttributes(&obj_attrib,

FileName,

OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,

NULL,

NULL);

//创建文件

status=ZwCreateFile(&hFile,

GENERIC_ALL,

&obj_attrib,

&Io_Status_Block,

NULL,

FILE_ATTRIBUTE_NORMAL,

FILE_SHARE_READ,

FILE_CREATE,

FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT,

NULL,

0);

if(NT_SUCCESS(status))

{

status=STA TUS_SUCCESS;

}

else

{

status=Io_Status_Block.Status;

}

KdPrint(("hFile=%08X",hFile));

//关闭句柄

if(hFile)

{

ZwClose(hFile);

}

return status;

}

这时候再进行编译,就没有一点错误和警告了。

【补充知识】

大部分的Win32API都是通过Native API实现的,Native API函数一般都是Win32API 函数前面加上Nt两个字符,例如CreateFile函数对应着NtCreateFile函数,这些Nt函数都是在“ntdll.dll”实现的,而多数Win32API都是在“kernel.dll”导出的,也有少部分GDI 或窗口相关的函数是在“gdi32.dll”和“user32.dll”导出的。

Native API从用户模式穿越进入到内核模式调用系统服务,这个穿越过程是通过软中断的方式进入的。这个软中断的实现方法在不同版本的Windows实现方式略有不同,在Win2K 下是通过“int2eh”实现的,在Win XP是通过“sysenter”指令完成的。

软中断会将Native API的参数和系统服务号的参数一起传进内核模式,不同的Native API会对应不同的系统服务号,这个过程是由SSDT辅助完成的。

系统服务函数一般和Native API具有相同的名字,例如都是NtCreateFile,但它们的实现不同,系统服务调用是在“ntoskrnl.exe”导出的。

第四章在驱动中使用链表

在驱动开发的过程中,我们经常遇到一些使用数组力不从心的情况,这时候就可以考虑使用链表来完成相关功能。

4.1内存的分配与释放

传统的C语言中,分配内存常常使用的函数是malloc,但在驱动开发过程中这个函数不再有效。驱动中分配内存,最常用的是调用ExAllocatePoolWithTag或ExAllocatePool。

//定义一个内存分配标记

#define MEM_TAG‘MyTt’

//目标字符串,接下来它需要分配空间。

UNICODE_STRING dst={0};

//分配空间给目标字符串。根据源字符串的长度。

dst.Buffer=(PWCHAR)ExAllocatePoolWithTag(NonpagedPool,src->Length,MEM_TAG);

if(dst.Buffer==NULL)

{

//错误处理

status=STA TUS_INSUFFICIENT_RESOUCRES;

……

}

dst.Length=dst.MaximumLength=src->Length;

ExAllocatePoolWithTag的第一个参数NonpagedPool表明分配的内存是非分页内存,这样它们可以永远存在于物理内存,而不会被分页交换到硬盘上去;第二个参数是长度;第三个参数是一个所谓的“内存分配标记”。

内存分配标记用于检测内存泄漏。想象一下,我们根据占用越来越多的内存的分配标记,就能大概知道泄漏的来源。一般每个驱动程序定义一个自己的内存标记。也可以在每个模块中定义单独的内存标记。内存标记是随意的32位数字。即使冲突也不会有什么问题。

此外也可以分配可分页内存,使用PagedPool标识第一个参数即可。

ExAllocatePoolWithTag分配的内存可以使用ExFreePool来释放,否则的话这块内存就会产生泄漏。虽然用户进程关闭后自动释放进程内分配的空间,但驱动不太一样,即使它已经被卸载,空间也不会自动释放,除非重启计算机。

ExFreePool只需要提供需要释放的指针即可。举例如下:

ExFreePool(dst.Buffer);

dst.Buffer=NULL;

dst.Length=dst.MaximumLength=0;

注意,ExFreePool不能用来释放一个栈空间的指针,否则系统立刻崩溃。诸如下面的代码将会招致立刻蓝屏的灾难:

UNICODE_STRING src=RTL_CONST_STRING(L”My source string!”);

ExFreePool(src.Buffer);

请务必保持ExAllocatePoolWithTag或ExAllocatePool和ExFreePool的成对关系。

4.2使用LIST_ENTRY

Windows内核提供了一个双向链表结构LIST_ENTRY,此外还有一些其他的结构,比如SINGLE_LIST_ENTRY(单向链表),我们这里不作介绍。

LIST_ENTRY是一个双向链表结构,但直接使用它将毫无任何意义,通常的做法是我们自定义一个结构体,将LIST_ENTRY作为该结构体的一个子域,这样给予了我们最大限度的灵活性,因为我们的数据需求千差万别,可能是整数、字符串等等,但只要要简单修改一下便可利用LIST_ENTRY轻松实现一个链表。如下所示:

typedef struct_MYDATASTRUCT{

ULONG number;

LIST_ENTRYListEntry;

}MYDATASTRUCT,*PMYDATASTRUCT;

实际上,如果将LIST_ENTRY作为结构体的第一个子域是最简单的做法,当然也可以把它放在后面,比如微软提供的很多结构就不是将其放在第一个子域。

这时候,如果我们想获取节点的地址,需要有一个计算偏移的过程,DDK里面提供了一个宏CONTAINING_RECORD可以在指定结构中找到节点地址的指针。

4.3使用自旋锁

链表之类的结构总是涉及到恼人的多线程同步问题,这时候就必须使用锁。本章只介绍最简单的自选锁。

有些读者可能疑惑锁存在的意义,其实这和多线程操作有关。在驱动开发的代码中,大多是存在于多线程执行环境的,就是说可能同时有多个线程操作一个变量,这时候就可能会引起不可预料的后果。

虽然,多线程并不是真正的并发,但操作链表的过程翻译成汇编指令后往往是由多条指令组成的,简单如int c=a+b;之类的代码也是由多条指令组成的,这就是说这些操作不具有原子性,通过反汇编查看一下就很容易明白。

如下的代码演示了如何使用自选锁:

KSPIN_LOCK my_spin_lock;

KIRQL irql;

//初始化

KeInitializeSpinLock(&my_spin_lock);

KeAcquireSpinLock(&my_spin_lock,&irql);

//do something…

KeReleaseSpinLock(&my_spin_lock,irql);

在使用的时候,我们把需要同步的代码加在KeAcquireSpinLock和KeReleaseSpinLock 这两个函数之间,这样在一个线程操作完成调用KeReleaseSpinLock之前,其他线程只能在KeAcquireSpinLock前面等候。KIRQL是一个中断级,KeAcquireSpinLock函数会提高当前的中断级,目前我们忽略这个问题。

4.4演示程序

在下面的程序中,我们演示了链表和自旋锁的操作方法。

VOID

LinkListTest()

{

LIST_ENTRYlinkListHead;//链表

PMYDATASTRUCT pData;//节点数据

ULONG i=0;//计数

KSPIN_LOCK spin_lock;//自旋锁

KIRQL irql;//中断级别

//初始化

InitializeListHead(&linkListHead);

KeInitializeSpinLock(&spin_lock);

//向链表中插入10个元素

KdPrint(("[Test]Begin insert to link list"));

//锁定,注意这里的irql是个指针

KeAcquireSpinLock(&spin_lock,&irql);

for(i=0;i<10;i++)

{

pData=(PMYDATASTRUCT)ExAllocatePool(PagedPool,sizeof(MYDATASTRUCT));

pData->number=i;

InsertHeadList(&linkListHead,&pData->ListEntry);

}

//解锁,注意这里的irql不是指针

KeReleaseSpinLock(&spin_lock,irql);

//从链表中取出所有数据并显示

KdPrint(("[Test]Begin remove from link list\n"));

//锁定

KeAcquireSpinLock(&spin_lock,&irql);

while(!IsListEmpty(&linkListHead))

{

PLIST_ENTRY pEntry=RemoveTailList(&linkListHead);

//获取节点地址

pData=CONTAINING_RECORD(pEntry,MYDATASTRUCT,ListEntry);

//读取节点数据

KdPrint(("[Test]%d\n",pData->number));

ExFreePool(pData);

}

//解锁

KeReleaseSpinLock(&spin_lock,irql);

}

现在我们在DriverEntry的IRP分发代码后面添加一句:LinkListTest();重新编译生成驱动(注意要Checked版本的),然后从“.\objchk\i386”目录中复制出生成的驱动文件。

现在我们需要查看程序的运行效果,首先打开DbgView,设置过滤条件为“*[Test]*”,然后使用第一章介绍过的KmdManager加载此驱动并运行(最好在虚拟机中测试),注意查看DbgView的输出,如图4-1所示:

图4-1程序演示结果

需要注意的是,像上述代码中在函数中定义一个锁的做法是没有实际意义的,因为它是一个局部变量,被定义在栈中,每当有线程调用该函数时,都会重新初始化一个锁,因此它就失去了本来的作用。

在实际的编程中,我们应该把锁定义为一个全局变量、静态(static)变量或者将其定义在堆中。不过在驱动中应该尽量避免使用全局变量,良好的做法是将需要全局访问的变量定义为设备扩展结构体DEVICE_EXTENSION的一个子域。

另外,我们还可以为每个链表都定义并初始化一个锁,在需要向该链表插入或移除节点时不使用前面介绍的普通函数,而是使用如下方法:

ExInterlockedInsertHeadList(&linkListHead,&pData->ListEntry,&spin_lock);

pData=(PMYDATASTRUCT)ExInterlockedRemoveHeadList(&linkListHead,&spin_lock);

此时在向链表中插入或移除节点时会自动调用关联的锁进行加锁操作,可以有效地保证多线程安全性,详细做法请参考楚狂人的驱动教程。

任务驱动教学法与项目教学法的比较

任务驱动教学法与项目教学法的比较 在新一轮的职业专业课程改革中,教学方法的改革显得尤为突出。行动导向教学法,被广泛运用于教学实践之中,其中倍受推崇的是任务驱动教学法和项目教学法。在实际的教学实践中有时很难将任务驱动教学法和项目教学法区分开,因为这两种教学法都是实践性教学方法,需要设置教学情境(任务、项目),由学生分组完成教学活动,学生在活动中具体很强的自主性和探究性,在教学方法上强调学生的自我管理,教学活动结束时,由学生、教师共同对活动成果进行评价。但两种教学法之间又有差异。本文对这两种教学方法进行比较分析,并对“项目引导、任务驱动”教学法进行初步探索。 一、任务驱动教学法 “任务驱动”教学法,就是教师或者学生根据教学要求提出有实际意义的、符合学生认知水平的“任务”,以完成一个个具体的“任务”为线索,把教学内容巧妙地隐含在每个“任务”之中,学生自己或者在教师的指导下提出解决问题的思路和方法,然后进行具体的操作,教师引导学生边学边做完成相应的“任务”。当学生完成这个任务后也就建构了本节课所学的新知识。任务驱动教学法具有以下特点:(1)任务驱动,以工作任务为中心引领知识、技能和态度,让学生在完成工作任务的过程中学习相关理论知识,发展学生的综合职业能力。(2)目标具体,内容实用。任务驱动教学法的教学目标清楚明确,能更好地指导教学过程,也可以更好地评价教学效果;教学内容的选择要紧紧围绕工作任务完成的需要,不求理论的系统性,只求内容的实用性。(3)做学

一体。任务驱动教学法打破长期以来的理论与实践二元分离的局面,以工作任务为中心,实现理论与实践的一体化教学。(4) 培养学生发现问题、解决问题和综合应用的能力。(5)提高学生学习的主动参与意识,激发学生的学习兴趣。 二、项目教学法 项目教学是将某门专业课程按类别分为若干技术或技能单元,每个技术或技能单元作为一个教学项目,实行理论、实践一体化的单元式教学,每个单元教学都以应用该项技术或技能完成一个作业来结束,并进行下一个项目的教学。简而言之,项目教学就是师生为完成某一具体的工作任务而展开的教学行动。项目教学是一种方法,更是一种方案。“项目教学法”的特点:(1)在教学内容上:不再用以前的以“知识点”为线索的方式,而是根据学生的接受能力及信息时代的需求,改用以“项目”为线索,以“子项目”为模块,精心组织教学内容,使其符合学生的认知特点,特别是强调所学知识要与时代同步。(2)在教学方法上:强调学生的自主学习和探索,强调培养学生的自学能力。在教学过程中不断地根据“项目”的需求来学习,变被动地接受知识为主动地寻求知识,改变学生传统的学习观,由“学会”到“会学”。(3)在能力培养上:着重培养学生的创新精神和合作意识,学生在完成“项目”的过程中,会积极地去思考、探索。每个人的思路、想法不尽相同,老师可引导他们进行讨论和交流,并适当地给予点评和鼓励,使他们相互取长补短,既调动和学生的积极性,又培养了他们的创新精神和合作意识。(4)在就业指向上,因采取的项目全都来自实际工作。

windows cmd 命令脚本大全

winver 检查Windows版本 wmimgmt.msc 打开Windows管理体系结构(wmi) wupdmgr Windows更新程序 wscript Windows脚本宿主设置 write 写字板 winmsd 系统信息 wiaacmgr 扫描仪和照相机向导 winchat xp自带局域网聊天 mem.exe 显示内存使用情况 msconfig.exe 系统配置实用程序 mplayer2 简易widnows media player mspaint 画图板 mstsc 远程桌面连接 mplayer2 媒体播放机 magnify 放大镜实用程序 mmc 打开控制台 mobsync 同步命令 dxdiag 检查directx信息 drwtsn32 系统医生 devmgmt.msc 设备管理器 dfrg.msc 磁盘碎片整理程序 diskmgmt.msc 磁盘管理实用程序 dcomcnfg 打开系统组件服务 ddeshare 打开dde共享设置 dvdplay dvd播放器 net stop messenger 停止信使服务 net start messenger 开始信使服务 notepad 打开记事本 nslookup 网络管理的工具向导 ntbackup 系统备份和还原 narrator 屏幕“讲述人” ntmsmgr.msc 移动存储管理器 ntmsoprq.msc 移动存储管理员操作请求

netstat -an (tc)命令检查接口 syncapp 创建一个公文包 sysedit 系统配置编辑器 sigverif 文件签名验证程序 sndrec32 录音机 shrpubw 创建共享文件夹 secpol.msc 本地安全策略 syskey 系统加密,一旦加密就不能解开,保护Windows xp系统的双重密码services.msc 本地服务设置 sndvol32 音量控制程序 sfc.exe 系统文件检查器 sfc /scannow windows文件保护tsshutdn 60秒倒计时关机命令 tourstart xp简介(安装完成后出现的漫游xp程序) taskmgr 任务管理器 eventvwr 事件查看器 eudcedit 造字程序 explorer 打开资源管理器 packager 对象包装程序 perfmon.msc 计算机性能监测程序 progman 程序管理器 regedit.exe 注册表 rsop.msc 组策略结果集 regedt32 注册表编辑器 rononce -p 15秒关机 regsvr32 /u *.dll 停止dll文件运行 regsvr32 /u zipfldr.dll 取消zip支持 cmd.exe cmd命令提示符 chkdsk.exe chkdsk磁盘检查 certmgr.msc 证书管理实用程序 calc 启动计算器

windows设备管理与驱动程序

计算机可以配置许多I/O设备,种类很多,而且随着技术的发展新设备也不断出现。I/O 设备既是人机交互的界面,也是计算机与计算机通信的枢纽,需要处理的信息其原始形态是光波、电波、声波、红外线等各种不同的物理信号,它们承载的信息可以是文本、图像、声音、视频等各种不同的载体。这方面导致了计算机应用的多样性和普遍性,另一方面也使得I/O设备的管理相当复杂。 此外,I/O设备的速度比CPU和内存的速度要慢得多,它们经常成为系统性能的瓶颈。多任务处理是提高系统性能的一个途径,但是在多任务处理中,怎么保证I/O设备安全可靠而且被多个任务共享使用,这也是操作系统需要解决的一项任务。 为此,操作系统中的设备管理程序负责对系统中的各种输入/输出设备进行统一的管理,处理用户或应用程序的输入输出请求,方便、有效、安全地完成输入输出操作。 ⑴方便性。用户(程序)总是希望方便地使用I/O设备,但I/O过程非常复杂,如果直接控制或使用I/O设备,必须了解许多与应用本身没有直接关系的具体细节,工作量大,效率低,设备型号和系统配置的变化将引起程序的修改,影响程序的独立性和适应性。而且让程序员直接操作物理设备,也不利于设备及其数据的保护。 解决这个问题的方法是采用设备驱动程序。设备驱动程序处于操作系统的底层,它将具体物体设备的性质和硬件操作的细节予以品屏蔽和抽象,只向操作系统的高层和应用程序提供统一的建斌啊医用的抽象设备和逻辑操作,操作系统高层和应用程序通过驱动程序访问外设,由驱动程序负责把抽象设备的操作转换成具体物理设备的操作。这样一来,不同规格和性能参数的外部设别(如各种不同的打印机)通过安装各自定制的设备驱动程序,就能使系统和应用程序不需要进行任何修改就了直接使用该设备。通常,外设的生产厂商在提供硬件设备的同时必须提供该设备的驱动程序。 ⑵有效性。为了确保I/O设备多个任务所共享,设备管理程序必须解决许多问题。例如:设备的命名、登记、分配、回收及调度等。对于可并发共享的设备(如磁盘、显示器等),为了使设备的利用率达到最优,设备管理程序将根据每个设备的特点来全局调度和安排设备的操作。例如,对硬盘的多个读写要求可以进行进行排序,使得每次读写操作的磁头移动距离都尽可能短。对于独占设备(如打印机、绘图仪等),可以采用假脱机技术,把每一个要打印或绘制的文档,按先来先服务的顺序将其存放在队列中,然后以后台方式依次进行打印或绘图,从而大大提高了慢速独占设备的利用率。 为了解决I/O设备速度过慢,效率不高的问题,设备管理中大多应用了缓冲技术,以减少I/O操作的等待时间。虽然有些I/O设备或控制器内部已有硬件缓冲(如打印机和磁盘控制器内部有缓存存储器),但操作系统仍然在内存中开设I/O缓冲区和文件系统缓冲区。 ⑶安全性。在多任务系统中,由于I/O设备的数量有限,并不是每个任务随时都可以使用这些设备的。为了使用某个设备,必须先向设备管理程序提出申请,然后由设备管理程序按一定算法进行分配。如果申请没有成功,它就必须排队等待,只有分配到该设备并完成I/O操作后相关的任务才能继续执行下去。Windows就采用了这种安全分配方式。 在windows操作系统中,设备管理程序还支持即插即用功能,并按ACPI标准进行电源管理(系统的能耗状态可设置为工作状态、等待状态或休眠状态等多种),它能检测设备的闲置时间,当发现超过预定值时,就把设备切换到低能耗状态。 Windows操作系统中有一个称为设备管理器的工具程序,它可以利用我的电脑快捷菜单中的属性命令或通过控制面板中的系统启动。启动后用户可以按类型或链接方式来寻找所关心的设备,查看该设备的信息和当前工作状态,也可以修改或重新配置设备的操作环境。

设备驱动程序

驱动程序 驱动程序一般指的是设备驱动程序(Device Driver),是一种可以使计算机和设备通信的特殊程序。相当于硬件的接口,操作系统只有通过这个接口,才能控制硬件设备的工作,假如某设备的驱动程序未能正确安装,便不能正常工作。 因此,驱动程序被比作“硬件的灵魂”、“硬件的主宰”、和“硬件和系统之间的桥梁”等。 中文名 驱动程序 外文名 Device Driver 全称 设备驱动程序 性质 可使计算机和设备通信的特殊程序 目录 1定义 2作用 3界定 ?正式版 ?认证版 ?第三方 ?修改版 ?测试版 4驱动程序的开发 ?微软平台 ?Unix平台 5安装顺序 6inf文件 1定义 驱动程序(Device Driver)全称为“设备驱动程序”,是一种可以使计算机和设备通信的特殊程序,可以说相当于硬件的接口,操作系统只能通过这个接口,才能控制硬件设备的工作,假如某设备的驱动程序未能正确安装,便不能正常工作。 惠普显卡驱动安装 正因为这个原因,驱动程序在系统中的所占的地位十分重要,一般当操作系统安装完毕后,首要的便是安装硬件设备的驱动程序。不过,大多数情况下,我们并不需要安装所有硬件设备的驱动程序,例如硬盘、显示器、光驱等就不需要安装驱动程序,而显卡、声卡、扫描仪、摄像头、Modem等就需要安装驱动程序。另外,不同版本的操作系统对硬件设

备的支持也是不同的,一般情况下版本越高所支持的硬件设备也越多,例如笔者使用了Windows XP,装好系统后一个驱动程序也不用安装。 设备驱动程序用来将硬件本身的功能告诉操作系统,完成硬件设备电子信号与操作系统及软件的高级编程语言之间的互相翻译。当操作系统需要使用某个硬件时,比如:让声卡播放音乐,它会先发送相应指令到声卡驱动程序,声卡驱动程序接收到后,马上将其翻译成声卡才能听懂的电子信号命令,从而让声卡播放音乐。 所以简单的说,驱动程序提供了硬件到操作系统的一个接口以及协调二者之间的关系,而因为驱动程序有如此重要的作用,所以人们都称“驱动程序是硬件的灵魂”、“硬件的主宰”,同时驱动程序也被形象的称为“硬件和系统之间的桥梁”。 戴尔电脑驱动盘 驱动程序即添加到操作系统中的一小块代码,其中包含有关硬件设备的信息。有了此信息,计算机就可以与设备进行通信。驱动程序是硬件厂商根据操作系统编写的配置文件,可以说没有驱动程序,计算机中的硬件就无法工作。操作系统不同,硬件的驱动程序也不同,各个硬件厂商为了保证硬件的兼容性及增强硬件的功能会不断地升级驱动程序。如:Nvidia显卡芯片公司平均每个月会升级显卡驱动程序2-3次。驱动程序是硬件的一部分,当你安装新硬件时,驱动程序是一项不可或缺的重要元件。凡是安装一个原本不属于你电脑中的硬件设备时,系统就会要求你安装驱动程序,将新的硬件与电脑系统连接起来。驱动程序扮演沟通的角色,把硬件的功能告诉电脑系统,并且也将系统的指令传达给硬件,让它开始工作。 当你在安装新硬件时总会被要求放入“这种硬件的驱动程序”,很多人这时就开始头痛。不是找不到驱动程序的盘片,就是找不到文件的位置,或是根本不知道什么是驱动程序。比如安装打印机这类的硬件外设,并不是把连接线接上就算完成,如果你这时候开始使用,系统会告诉你,找不到驱动程序。怎么办呢参照说明书也未必就能顺利安装。其实在安装方面还是有一定的惯例与通则可寻的,这些都可以帮你做到无障碍安装。 在Windows系统中,需要安装主板、光驱、显卡、声卡等一套完整的驱动程序。如果你需要外接别的硬件设备,则还要安装相应的驱动程序,如:外接游戏硬件要安装手柄、方向盘、摇杆、跳舞毯等的驱动程序,外接打印机要安装打印机驱动程序,上网或接入局域网要安装网卡、Modem甚至ISDN、ADSL的驱动程序。说了这么多的驱动程序,你是否有一点头痛了。下面就介绍Windows系统中各种的不同硬件设备的驱动程序,希望能让你拨云见日。 在Windows 9x下,驱动程序按照其提供的硬件支持可以分为:声卡驱动程序、显卡驱动程序、鼠标驱动程序、主板驱动程序、网络设备驱动程序、打印机驱动程序、扫描仪驱动程序等等。为什么没有CPU、内存驱动程序呢因为CPU和内存无需驱动程序便可使用,不仅如此,绝大多数键盘、鼠标、硬盘、软驱、显示器和主板上的标准设备都可以用Windows 自带的标准驱动程序来驱动,当然其它特定功能除外。如果你需要在Windows系统中的DOS 模式下使用光驱,那么还需要在DOS模式下安装光驱驱动程序。多数显卡、声卡、网卡等内置扩展卡和打印机、扫描仪、外置Modem等外设都需要安装与设备型号相符的驱动程序,否则无法发挥其部分或全部功能。驱动程序一般可通过三种途径得到,一是购买的硬件附

usb驱动程序教程

编写Windows https://www.360docs.net/doc/f114160554.html,的usb驱动程序教程 Windows https://www.360docs.net/doc/f114160554.html, 是微软推出的功能强大的嵌入式操作系统,国内采用此操作系统的厂商已经很多了,本文就以windows https://www.360docs.net/doc/f114160554.html,为例,简单介绍一下如何开发windows https://www.360docs.net/doc/f114160554.html, 下的USB驱动程序。 Windows https://www.360docs.net/doc/f114160554.html, 的USB系统软件分为两层: USB Client设备驱动程序和底层的Windows CE实现的函数层。USB设备驱动程序主要负责利用系统提供的底层接口配置设备,和设备进行通讯。底层的函数提本身又由两部分组成,通用串行总线驱动程序(USBD)模块和较低的主控制器驱动程序(HCD)模块。HCD负责最最底层的处理,USBD模块实现较高的USBD函数接口。USB设备驱动主要利用 USBD接口函数和他们的外围设备打交道。 USB设备驱动程序主要和USBD打交道,所以我们必须详细的了解USBD提供的函数。 主要的传输函数有: abourttransfer issuecontroltransfer closetransfer issuein te rruptransfer getisochresult issueisochtransfer gettransferstatus istransfercomplete issuebulktransfer issuevendortransfer 主要的用于打开和关闭usbd和usb设备之间的通信通道的函数有: abortpipetransfers closepipe isdefaultpipehalted ispipehalted openpipe resetdefaultpipe resetpipe 相应的打包函数接口有: getframelength getframenumber releaseframelengthcontrol setframelength takeframelengthcontrol 取得设置设备配置函数: clearfeature setdescriptor getdescriptor setfeature

如何在Windows下开发Python:在cmd下运行Python脚本

如何在Windows下开发Python:在cmd下运行Python脚本 此处提供两种方法:使用者自行选择 第一种方法: 1.找个文本编辑器,一般选择notepad++,新建个.py文件,写上Python代码, 代码可选择简单的print()函数。 源码:简单打印一些Python版本信息和系统信息 #!D:\Field\python –>可不修改#!/usr/bin/env python # -*- coding: utf-8 -*- """ Function: 【整理】如何在Windows下开发Python(如何运行Python脚本) Author: Field Yang Version: 2016-12-06 """ import platform; pythonVersion = platform.python_version();

uname = platform.uname(); print("Just for demo how to do python development under windows:") print("Current python version info is %s"%(pythonVersion)) print("uname=",uname) 2.首行解释执行器添加安装Python的路径,此处为D:\Field\python 3.打开cmd CMD>path="解释器位置" →enter→python运行脚本名.py 或python绝对路径/运行脚本名.py 此处为path=D:\Field\python →Enter →python demoRunPythonUnderWindows.py 或python d:\Field\ demoRunPythonUnderWindows.py 附:Windows命令行的切换路径 切换盘输入盘符:如D:或E: 切换文件夹cd 文件夹名如:cd Field 返回上级目录输入cd .. 第二种方法: 点击菜单→点击计算机→系统属性 →高级系统设置→环境变量→TEMP →编辑path→输入python安装路径(此处为D:\Field\python)

Windows驱动程序手册

Windows驱动程序手册ELP-108/168/188ES(Rev.1.4)

目录 1.手册信息 (1) 2.操作系统 (1) 3.程序准备 (1) 4.驱动的安装 (2) 5.驱动的设置 (4) 5.1打印首选项 (4) 5.2其他设置 (9) 6.规格 (10) 6.1分辨率 (10) 6.2纸张规格 (10)

1.手册信息 本手册提供了Windows驱动程序安装说明和主要功能方面的信息。 我们致力于提高和升级产品的功能和质量,规格书的内容可能会更改,恕不另行通知。 2.操作系统 本打印机的Windows驱动适用于以下操作系统: ●Microsoft Windows8(32bit/64bit) ●Microsoft Windows7SPI(32bit/64bit) ●Microsoft Windows7SPI(32bit/64bit) ●Microsoft Windows7SPI(32bit/64bit) ●Microsoft Windows Vista SP2(32bit/64bit) ●Microsoft Windows XP Professional SP3(32bit) ●Microsoft Windows Server2012(64bit) ●Microsoft Windows Server2008R2 ●Microsoft Windows Server2008SP2(32bit/64bit) ●Microsoft Windows Server2003R2SP2(32bit/64bit) 3.程序准备 驱动程序包含在随机所附CD。 驱动文件命名为:Tengen ELP Label Driver-v-X.X.X.X.exe 如:Tengen ELP Label Driver-v-1.2.0.0.exe

最新开发usb驱动程序的方法连载一

最新开发usb驱动程序的方法连载一 开发usb驱动程序的方法(连载二) NT还有更多其他的对象,例如中断对象、Controller对象、定时器对象等等,但在我们开发的驱动程序中并没有用到,因此在这里不做介绍。 I/O缓冲策略 很明显的,驱动程序和客户应用程序经常需要进行数据交换,但我们知道驱动程序和客户应用程序可能不在同一个地址空间,因此操作系统必须解决两者之间的数据交换。这就就设计到设备的I/O缓冲策略。 读写请求的I/O缓冲策略 前面说到通过设置Device对象的Flag可以选择控制处理读写请求的I/O缓冲策略。下面对这些缓冲策略分别做一介绍。 1、缓冲I/O(DO_BUFFERED_IO) 在读写请求的一开始,I/O管理器检查用户缓冲区的可访问性,然后分配与调用者的缓冲区一样大的非分页池,并把它的地址放在IRP的AssociatedIrp.SystemBuffer域中。驱动程序就利用这个域来进行实际数据的传输。 对于IRP_MJ_READ读请求,I/O管理器还把IRP的UserBuffer域设置成调用者缓冲区的用户空间地址。当请求完成时,I/O管理器利用这个地址将数据从驱动程序的系统空间拷贝回调用者的缓冲区。对于IRP_MJ_WRITE写请求,UserBuffer被设置为NULL,并把用户缓冲区的数据拷贝到系统缓冲区中。 2、直接I/O(DO_DIRECT_IO) I/O管理器首先检查用户缓冲区的可访问性,并在物理内存中锁定它。然后它为该缓冲区创建一个内存描述表(MDL),并把MDL的地址存放在IRP的MdlAddress域中。AssociatedIrp.SystemBuffer和 UserBuffer 都被设置为NULL。驱动程序可以调用函数 MmGetSystemAddressForMdl得到用户缓冲区的系统空间地址,从而进行数据操作。这个函数将调用者的缓冲区映射到非份页的地址空间。驱动程序完成I/O请求后,系统自动从系统空间解除缓冲区的映射。 3、这两种方法都不是 这种情况比较少用,因为这需要驱动程序自己来处理缓冲问题。 I/O管理器仅把调用者缓冲区的用户空间地址放到IRP的UserBuffer 域中。我们并不推荐这种方式。 IOCTL缓冲区的缓冲策略 IOCTL请求涉及来自调用者的输入缓冲区和返回到调用者的输出缓冲区。为了理解IOCTL请求,我们先来看看WIN32 API DeviceIoControl函数的原型。 BOOL DeviceIoControl ( HANDLE hDevice, // 设备句柄 DWORD dwIoControlCode, // IOCTL请求操作代码 LPVOID lpInBuffer, // 输入缓冲区地址 DWORD nInBufferSize, // 输入缓冲区大小 LPVOID lpOutBuffer, // 输出缓冲区地址 DWORD nOutBufferSize, // 输出缓冲区大小 LPDWORD lpBytesReturned, // 存放返回字节数的指针

利用wmic对Windows主机批量执行脚本

利用wmic对Windows主机批量执行脚本 2014年11月13日 AM 10:53 与类Unix操作系统相比较,Windows系统由于对字符界面的支持不完善,并没有与类Unix系统的shell可以相提并论的工具(cmd的命令行特性难用程度与 shell相比简直令人发指,虽然目前Windows推出所谓的PowerShell,但要跟上bash、korn shell等前辈还需要时间来沉淀)。一直以来,对于Windows进行批量管理大多依靠于图形界面,效率低下且可靠性不足。 其实Windows本身提供了WMI管理规范和接口,专用于支持命令行方式的系统管理,更推出wmic工具来给系统管理员使用,以下是百度百科对于wmic的介绍:WMIC扩展WMI(Windows Management Instrumentation,Windows管理规范),提供了从命令行接口和批命令脚本执行系统管理的支持。在WMIC出现之前,如果要管理WMI系统,必须使用一些专门的WMI应用,例如SMS,或者使用WMI的脚本编程API,或者使用象CIM Studio之类的工具。如果不熟悉C++之类的编程语言或VBScript之类的脚本语言,或者不掌握WMI名称空间的基本知识,要用WMI管理系统是很困难的。WMIC改变了这种情况,为WMI名称空间提供了一个强大的、友好的命令行接口。 概念的介绍总是容易让读者云里雾里,以下试验将演示如何使用wmic以及Windows共享功能来对批量服务器执行一个离线安全扫描脚本并取回结果。 试验背景: 现需要对批量Windows Server服务器进行离线安全扫描,即登录到每一台服务器执行一个vbs脚本,脚本会生成扫描结果文件,然后将结果文件下载到本地。倘若服务器数量不多,那么一台台登录执行也就罢了,但当目标服务器数量达到一定数量后,再手工进行此操作,就成为一件繁琐重复的工作。有人说,懒惰是推动人类文明不断进步的源动力。所以为了偷懒,不,为了人类文明的进步,这个工作必须使用批量和自动化的工具来完成。 实现思路: 将此工作分解为以下步骤,逐一实现: 1、登录Windows Server服务器; 2、上传扫描脚本到目标服务器; 3、执行扫描脚本; 4、下载结果文件; 5、对其他服务器重复前4个步骤。 第1步的登录服务器,传统来说,肯定是使用远程桌面了,但如前面所说,图形界面的东西,要进行批量操作是很麻烦的。那自然要使用字符界面来进行登录了,再自然地想到telnet方式是最简便通用的协议。但现今所有负责任的系统或安全管理人员都会告诉你,想用telnet来连接我的服务器?门都没有!幸好wmic就提供了远程主机的管理接口,使用"wmic /node:IP地址 /user:帐号 /password:密码"的形式可以登录到远程主机执行wmic命令。第3步的执行脚本,其实与登录是同时进行的,此处结合第1、第3步,命令就是: wmic /node:IP地址 /user:帐号 /password:密码 process call create "cmd /c cmd命令或脚本" 第2和第4步,上传与下载,其实是同样的需求,如果开通了ftp之类的文件传输服务,自然简单。但当前环境并未开通ftp,所以考虑使用Windows的文件夹共享与网络映射来实现。首先在远端服务器使用wmic创建一个路径为c:\tempshare的共享目录,然后将其映射到本地的Z盘,再直接在Z盘上进行文件的读取。

USB驱动程序的编写采用WDM驱动程序

U S B驱动程序的编写采用W D M驱动程序 Document serial number【UU89WT-UU98YT-UU8CB-UUUT-UUT108】

USB驱动程序的编写采用WDM 驱动程序。WDM 驱动程序是一些例程的集合,它们被动地存在,等待主机系 统软件(PnP 管理器、I/O 管理器、电源管理器等)来调用或激活它们。具体驱动程序不同,其所包含 的例程也不同。一个WDM 驱动程序的基本组成包括以下5个例程:(1)驱动程序入口例程:处理驱动程序的初始化。 (2)即插即用例程:处理PnP 设备的添加、删除和停止。 (3)分发例程:处理用户应用程序发出的各种 I/O 请求。 (4)电源管理例程:处理电源管理请求。 (5)卸载例程:处理驱动程序的卸载。 包含文件: , , , , , makefile,sources) 在文件中,包含了上述五个例程: 中定义了各种数据结构还有各种IOCTL控制码,用于不同数据的读写。

中实现了各种驱动例程。包含了上述五个所说例程外还包含了其他例程,课程从下面的驱动 程序入口例程得出一些信息。 驱动程序入口例程: NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS ntStatus = STATUS_SUCCESS; PDEVICE_OBJECT deviceObject = NULL; DriverObject->MajorFunction[IRP_MJ_CREATE] = Ezusb_Create; DriverObject->MajorFunction[IRP_MJ_CLOSE] = Ezusb_Close; ources. If you want to add a new source # file to this

[浅谈“任务驱动”教学法]任务驱动教学法

[浅谈“任务驱动”教学法]任务驱动教学法信息技术是一门新兴的学科,是一门实践性很强的技术学科。传统的教学方式不太适合信息技术教学,这就要求在教学观念和教学方法上都要创新。近几年对信息技术的教学方法出现了许多新的理论,其中“任务驱动法”最受大家的推崇,认为其比较适合信息技术学科特点。它不但改变了教师教的模式,也改变了学生学的模式。而且许多版本信息技术课本也逐渐改变了其书写方式,将过去的单纯的介绍操作方法改为了将知识蕴涵在任务之中。在我们的日常教学中,也一直在使用这种方法。经过将近一年的教学实践,自己对“任务驱动法”教学模式也有了一些认识,下面就谈谈我的看法: 所谓“任务驱动法”就是指将知识隐含在一个或者几个任务中,通过完成任务的过程,介绍和学习基本知识和技能,同时培养学生分析问题、解决问题和综合应用所学知识的技能。我认为“任务驱动法”既是一种教学方法,也是一种学习方法。对于教师来说可以通过完成任务的过程来完成教学内容;而对于学生来说可以明确学习内容,能够通过完成任务来学会操作的方法。 一、选择“任务驱动法”的原因

首先:中学信息技术是一门技术学科,它的知识不像其他学科具 有很强的理论性,课本知识多数为计算机操作,它没有理论性可言。不需要太多的理解、分析。比如说在word中设置段落格式,它没有其实现的理论,只有实现的方法。如果直接讲解设置段落格式从“格式菜单”选择“段落”进行设置,学生不易理解,如果我们把这些内容放在一个任务中,比如说为了美化一篇文章我们需要调整文章的对齐方式、行间距等。这样在完成任务的过程中很自然很形象的讲解了教学内容。 其次:“任务驱动法”能够实现新课标理念。在新课标中信息技术要求强调学生解决问题的能力和运用信息技术进行创新实践的能 力的培养。每一个任务就是一个问题,学生通过分析问题,利用各种方法解决问题的过程提高了解决问题的能力,培养了其创新和实践能力。 二、“任务驱动法”的具体实施过程 1、教师提出任务,讲解任务的具体实施过程。

Windows驱动开发入门

接触windows驱动开发有一个月了,感觉Windows驱动编程并不像传说中的那么神秘。为了更好地为以后的学习打下基础,记录下来这些学习心得,也为像跟我一样致力于驱动开发却苦于没有门路的菜鸟朋友们抛个砖,引个玉。 我的开发环境:Windows xp 主机+ VMW ARE虚拟机(windows 2003 server系统)。编译环境:WinDDK6001.18002。代码编辑工具:SourceInsight。IDE:VS2005/VC6.0。调试工具:WinDBG,DbgView.exe, SRVINSTW.EXE 上面所有工具均来自互联网。 对于初学者,DbgView.exe和SRVINSTW.EXE是非常简单有用的两个工具,一定要装上。前者用于查看日志信息,后者用于加载驱动。 下面从最简单的helloworld说起吧。Follow me。 驱动程序的入口函数叫做DriverEntry(PDRIVER_OBJECT pDriverObj,PUNICODE_STRING pRegisgryString)。两个参数,一个是驱动对象,代表该驱动程序;另一个跟注册表相关,是驱动程序在注册表中的服务名,暂时不用管它。DriverEntry 类似于C语言中的main函数。它跟main的差别就是,main完全按照顺序调用的方法执行,所有东西都按照程序员预先设定的顺序依次发生;而DriverEntry则有它自己的规则,程序员只需要填写各个子例程,至于何时调用,谁先调,由操作系统决定。我想这主要是因为驱动偏底层,而底层与硬件打交道,硬件很多都是通过中断来与操作系统通信,中断的话就比较随机了。但到了上层应用程序,我们是看不到中断的影子的。说到中断,驱动程序中可以人为添加软中断,__asm int 3或者Int_3();前者是32位操作系统用的,后者是64位用的。64位驱动不允许内嵌汇编。下面是我的一个helloworld的源码:

任务驱动教学法

任务驱动教学法 百科名片 任务驱动的教与学的方式,能为学生提供体验实践的情境和感悟问题的情境,围绕任务展开学习,以任务的完成结果检验和总结学习过程等,改变学生的学习状态,使学生主动建构探究、实践、思考、运用、解决、高智慧的学习体系。 简介 所谓“任务驱动”就是在学习信息技术的过程中,学生在教师的帮助下,紧紧围绕一个共同的任务活动中心,在强烈的问题动机的驱动下,通过对学习资源的积极主动应用,进行自主探索和互动协作的学习,并在完成既定任务的同时,引导学生产生一种学习实践活动。“任务驱动”是一种建立在建构主义教学理论基础上的教学法。它要求“任务”的目标性和教学情境的创建。使学生带着真实的任务在探索中学习。在这个过程中,学生还会不断地获得成就感,可以更大地激发他们的求知欲望,逐步形成一个感知心智活动的良性循环,从而培养出独立探索、勇于开拓进取的自学能力。 基本含义。"任务驱动教学法"是以解决问题、完成任务为主的多维互动式的教学理念;将再现式教学转变为探究式学习,使学生处于积极的学习状态,每一位学生都能根据自己对当前问题的理解,运用共有的知识和自己特有的经验提出方案、解决问题。 基本理论 建构主义学习理论强调:学生的学习活动必须与任务或问题相结合,以探索问题来引导和维持学习者的学习兴趣和动机,创建真实的教学环境,让学生带着真实的任务学习,以使学生拥有学习的主动权。学生的学习不单是知识由外到内的转移和传递,更应该是学生主动建构自己的知识经验的过程,通过新经验和原有知识经验的相互作用,充实和丰富自身的知识、能力。 基本环节 1、创设情境:使学生的学习能在与现实情况基本一致或相类似的情境中发生。 需要创设与当前学习主题相关的、尽可能真实的学习情境,引导学习者带着真实的"任务"进入学习情境,使学习直观性和形象化。

windows批处理命令详解及脚本实例

批处理文件是将一系列命令按一定的顺序集合为一个可执行的文本文件,其扩展名为BAT。第一部分:批处理内部命令 1、REM REM 是个注释命令一般是用来给程序加上注解的,该命令后的内容在程序执行的时候将不会被显示和执行。例: REM 你现在看到的就是注解,这一句将不会被执行。在以后的例子中解释的内容都REM 会放在REM后面。请大家注意。 2、ECHO ECHO 是一个回显命令主要参数有OFF和ON,一般用ECHO message来显示一个特定的消息。例: Echo off Rem 以上代表关闭回显即不显示所执行的命令 Echo 这个就是消息。 Rem 以上代表显示"这就是消息"这列字符 执行结果: C:\>ECHO.BAT 这个就是消息。 3、GOTO GOTO 即为跳转的意思。在批处理中允许以":XXX"来构建一个标号然后用GOTO :标号直接来执行标号后的命令。例 :LABEL REM 上面就是名为LABEL的标号。 DIR C:\ DIR D:\ GOTO LABEL REM 以上程序跳转标号LABEL处继续执行。 4、CALL CALL 命令可以在批处理执行过程中调用另一个批处理,当另一个批处理执行完后再继续

执行原来的批处理。例: 批处理2.BAT内容如下: ECHO 这就是2的内容 批处理1.BAT内容如下: ECHO 这是1的内容 CALL 2.BAT ECHO 1和2的内容全部显示完成 执行结果如下: C:\>1.BAT 这是1的内容 这就是2的内容 1和2的内容全部显示完成 5、PAUSE PAUSE 停止系统命令的执行并显示下面的内容。例: C:\> PAUSE 请按任意键继续. . . 6、IF IF 条件判断语句,语法格式如下: IF [NOT] ERRORLEVEL number command IF [NOT] string1==string2 command IF [NOT] EXIST filename command 说明: [NOT] 将返回的结果取反值即"如果没有"的意思。 ERRORLEVEL 是命令执行完成后返回的退出值 Number 退出值的数字取值范围0~255。判断时值的排列顺序应该又大到小。返回的值大于或等于指定的值时条件成立。 string1==string2 string1和string2都为字符的数据,英文字符的大小写将看做不同,这个条件中的等于号必须是2个(绝对相等),条件想等后即执行后面的command EXIST filename 为文件或目录存在的意思。 IF ERRORLEVEL这条语句必须放在某一个命令后面。执行命令后由IF ERRORLEVEL来

Windows驱动程序开发环境配置

Windows驱动程序开发笔记 一、WDK与DDK环境 最新版的WDK 微软已经不提供下载了这里:https://https://www.360docs.net/doc/f114160554.html,/ 可以下并且这里有好多好东东! 不要走进一个误区:下最新版的就好,虽然最新版是Windows Driver Kit (WDK) 7_0_0,支持windows7,vista 2003 xp等但是它的意思是指在windows7操作系统下安装能编写针对windows xp vista的驱动程序, 但是不能在xp 2003环境下安装Windows Driver Kit (WDK) 7_0_0这个高版本,否则你在build的时候会有好多好多的问题. 上文build指:首先安装好WDK/DDK,然后进入"开始"->"所有程序"->"Windows Driver Kits"->"WDK XXXX.XXXX.X" ->"Windows XP"->"x86 Checked Build Environment"在弹出来的命令行窗口中输入"Build",让它自动生成所需要的库 如果你是要给xp下的开发环境还是老老实实的找针对xp的老版DDK吧,并且xp无WDK 版只有DDK版build自己的demo 有个常见问题: 'jvc' 不是内部或外部命令,也不是可运行的程序。 解决办法:去掉build路径中的空格。 二、下载 WDK 开发包的步骤 1、访问Microsoft Connect Web site站点 2、使用微软 Passport 账户登录站点 3、登录进入之后,点击站点目录链接 4、在左侧的类别列表中选择开发人员工具,在右侧打开的类别:开发人员工具目录中找到Windows Driver Kit (WDK) and Windows Driver Framework (WDF)并添加到您的控制面板中 5、添加该项完毕后,选择您的控制面板,就可以看到新添加进来的项了。 6、点击Windows Driver Kit (WDK) and Windows Driver Framework (WDF),看到下面有下载链接,OK,下载开始。下载后的文件名为: 6.1.6001.18002.081017-1400_wdksp-WDK18002SP_EN_DVD.iso将近600M大小。

USB驱动开发

第17章USB设备驱动 USB设备驱动和PCI设备驱动是PC中最主要的两种设备驱动程序。与PCI协议相比,USB协议更复杂,涉及面较多。本章将介绍USB设备驱动开发。首先介绍USB协议,使读者对USB协议有个整体认识。然后介绍USB设备在WDM中的开发框架。由于操作系统的USB总线驱动程序提供了丰富的功能调用,因此开发USB驱动开发变得相对简单,只需要调用USB总线驱动接口。 17.1 USB总线协议 USB总线协议比PCI协议复杂的多,涉及USB物理层协议,又涉及USB传输层协议等。对于USB驱动程序开发者来说,不需要对USB协议的每个细节都很清楚。本节概要地介绍USB总线协议,并对驱动开发者需要了解的地方进行详细介绍。 17.1.1 USB设备简介 USB即通用串行总线(Universal Serial Bus),是一种支持即插即用的新型串行接口。也有人称之为“菊链(daisy-chaining)”,是因为在一条“线缆”上有链接127 个设备的能力。USB要比标准串行口快得多,其数据传输率可达每秒4Mb~12Mb(而老式的串行口最多是每秒115Kb)。除了具有较高的传输率外,它还能给外围设备提供支持。 需要注意的是,这不是一种新的总线标准,而是计算机系统连接外围设备(如键盘、鼠标、打印机等)的输入/输出接口标准。到现在为止,计算机系统连接外围设备的接口还没有统一的标准,例如,键盘的插口是圆的、连接打印机要用9针或25针的并行接口、鼠标则要用9针或25针的串行接口。USB能把这些不同的接口统一起来,仅用一个4针插头作为标准插头,如图17-1所示。通过这个标准插头,采用菊花链形式可以把所有的外设连接起来,并且不会损失带宽。USB正在取代当前PC上的串口和并口。

浅析基于工作过程导向的任务驱动教学方法

浅析基于工作过程导向的任务驱动教学方法 摘要:如何让学生在掌握理论知识的同时提升实践能力,是技工学校教育教学的一项重要内容。本文以机械基础课程教学中的减速器拆装为例,探讨基于工作过程导向的任务驱动教学法在机械基础课程教学中的应用。以工作过程为导向,设置“全真+仿真”的工作环境,优化教学方法,培养学生的探究意识、训练学生的机械思维和提高学生的动手能力。 关键词:任务驱动教学减速器拆装评价激励 经济的高速发展为机械专业学生提供了良好的就业机会,同时也提高了对学生专业技能的要求。新课改背景下的课堂教学与传统课堂教学有了较大区别,因此学校及教师要根据实际需要,不断更新教学内容,改进教学方法,培养学生的综合职业能力。笔者在多年的机械基础课程教学实践中发现,基于工作过程导向的任务驱动教学法对培养学生的探究意识、机械思维和动手能力有重要 意义。 一、基于工作过程导向的任务驱动教学法的概念界定 基于工作过程导向的任务驱动教学法是以工作任务为载体,将教学过程与工作过程有机融合,使学生在教学(模拟)情境中,通过完成任务获得知识与技能,从而提高职业能力的一种教学方法。工作任务,亦区别于常规的趣味性任务,是把教学目标进行有效组织,形成具有职业性的工作任务。因此,基于工作过程导向的任

务驱动教学法以工作任务为明线、培养学生的专业技能和职业能力为暗线。下面以装拆zdy型减速器为例,浅谈基于工作过程导向的任务驱动教学法在机械基础课程教学中的应用。 二、基于工作过程导向的任务驱动教学法课例剖析 1.项目名称 拆装zdy型减速器 2.项目背景分析 减速器拆装在传统教学中略有涉及,通常先由老师讲解拆装要点,接着示范操作,学生很难真正参与其中。根据笔者多年的教学经验,学习减速器拆装对机械基础的学习有很大助益。 减速器拆装是继学习轴及轴系零件、齿轮传动和蜗杆传动之后的综合应用。它既是前面所学内容的运用和实际演练,又为深入学习机械基础提供了理论基础。教师通过研究学习,不但要解决理论问题,还必须解决实际操作的问题,从而培养学生动手、分析和探究能力。 3.教学资源准备 教学设备:减速器拆装多媒体软件、任务书(实训报告)与引导文、机械设计手册每小组一本、单级直齿圆柱齿轮减速器每小组一台拆卸及测量工具:活动扳手,螺丝起、木锤、游标卡尺、钢尺、内外卡钳等工具。

相关文档
最新文档