当前位置:文档之家› 学习笔记windows驱动开发技术详解

学习笔记windows驱动开发技术详解

学习笔记windows驱动开发技术详解
学习笔记windows驱动开发技术详解

<学习笔记>Windows驱动开发技术详解

派遣函数是Windows驱动程序中的重要概念。驱动程序的主要功能是负责处理I/O请求,其中大部分I/O请求是在派遣函数中处理的。

用户模式下所有对驱动程序的I/O请求,全部由操作系统转换为一个叫做IRP数据结构,不同的IRP会被“派遣”到不同的派遣函数中。IRP与派遣函数

IRP的处理机制类似于Windows应用程序中的“消息处理”,驱动程序接收到不同的IRP后,会进入不同的派遣函数,在派遣函数中IRP得到处理。1.IRP

在Windows内核中,有一种数据结构叫做IRP(I/O Request Package),即输入输出请求包。上层应用程序与底层驱动程序通信时,应用程序会发出I/O请求。操作系统将I/O请求转化为相应的IRP数据,不同类型的IRP会被传递到不同的派遣函数中。

IRP有两个基本的重要属性,一个是MajorFunction,另一个MinorFunction,分别记录IRP的主类型和子类型,操作系统根据MajorFunction将IRP“派遣”到不同的派遣函数中,在派遣函数中还可以继续判断这个IRP属于哪种MinorFunction。

下面是HelloDDK的DriverEntry中关于派遣函数的注册:

view plaincopy to clipboardprint?

#pragma INITCODE

extern "C" NTSTATUS DriverEntry(

IN PDRIVER_OBJECT pDriverObject,

IN PUNICODE_STRING pRegisterPath

)

{

NTSTATUS status;

KdPrint(("Enter DriverEntry\n"));

//设置卸载函数

pDriverObject->DriverUnload = HelloDDKUnload;

//设置派遣函数

pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;

pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;

pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;

pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;

pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = HelloDDKDispatchRoutine;

pDriverObject->MajorFunction[IRP_MJ_SET_INFORMATI ON] = HelloDDKDispatchRoutine;

pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTR OL] = HelloDDKDispatchRoutine;

pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = HelloDDKDispatchRoutine;

pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTR OL] = HelloDDKDispatchRoutine;

//创建驱动设备对象

status = CreateDevice(pDriverObject);

KdPrint(("Leave DriverEntry\n"));

return status;

} 2.IRP的类型

文件I/O的相关函数,如CreateFile,ReadFile,WriteFile,CloseHandle等函数会使操作系统产生出IRP_MJ_CREATE,IRP_MJ_READ,IRP_MJ_WRITE,IRP_MJ_CLOSE等不同的IRP。另外,内核中的文件I/O处理函数,如ZwCreateFile,ZwReadFile,ZwWriteFile,ZwClose,他们同样会产以上IRP。一下列出了IRP的类型,并对其产生的来源做了说明IRP类型

来源

-----------------------------------------------------------------------------------------------------------------------------------------------

IRP_MJ_CREATE

创建设备,CreateFile会产生此IRP

-----------------------------------------------------------------------------------------------------------------------------------------------

IRP_MJ_CLOSE

关闭设备,CloseHandle会产生此IRP

-----------------------------------------------------------------------------------------------------------------------------------------------

IRP_MJ_CLEANUP

清除工作,CloseHandle会产生此IRP

-----------------------------------------------------------------------------------------------------------------------------------------------

IRP_MJ_DEVICE_CONTROL

DeviceControl函数会产生此IRP

-----------------------------------------------------------------------------------------------------------------------------------------------

IRP_MJ_PNP

即插即用消息,NT驱动不支持次IRP,WDM驱动才支持次IRP

-----------------------------------------------------------------------------------------------------------------------------------------------

IRP_MJ_POWER

在操作系统处理电源消息时,产生次IRP

-----------------------------------------------------------------------------------------------------------------------------------------------

IRP_MJ_QUERY_INFORMATION 获取

文件长度,GetFileSize会产生IRP

-----------------------------------------------------------------------------------------------------------------------------------------------

IRP_MJ_READ

读取设备内容,ReadFile会产生此IRP

-----------------------------------------------------------------------------------------------------------------------------------------------

IRP_MJ_SET_INFORMATION

设置文件长度,GetFileSize会产生IRP

-----------------------------------------------------------------------------------------------------------------------------------------------

IRP_MJ_SHUTDOWN

关闭系统前会产生此IRP

-----------------------------------------------------------------------------------------------------------------------------------------------

IRP_MJ_SYSTEM_CONTROL

系统内部产生的控制信息,类似于内核调用DeviceControl 函数

-----------------------------------------------------------------------------------------------------------------------------------------------

IRP_MJ_WRITE

对设备进行WriteFile时会产生此IRP

-----------------------------------------------------------------------------------------------------------------------------------------------3.对派遣函数的简单处理

大部分的IRP都源于文件I/O处理Win32API,处理这些IRP 最简单的方法就是在相应的派遣函数中,将IRP状态设置为成功,然后结束IRP的请求,并让派遣函数成功返回。结束IRP的请求使用函数IoCompleteRequest.。下面代码演示了一种最简单的处理IRP请求的派遣函数。view plaincopy to clipboardprint?

NTSTATUS HelloDDKDispatchRoutine(IN

PDEVICE_OBJECT pDevObj, IN PIRP pIrp)

{

KdPrint(("Enter HelloDDKDispatchRoutine\n"));

//对一般IRP的简单操作

NTSTATUS status = STATUS_SUCCESS;

//设置IRP完成状态

pIrp->IoStatus = status;

//设置IRP操作了多少字节

pIrp->https://www.doczj.com/doc/8416700797.html,rmation = 0;

//处理IRP

IoCompleteRequest(pIrp,IO_NO_INCREMENT);

KdPrint(("Leave HelloDDKDispatchRputine"));

return status;

}

本例中,派遣函数设置了IRP的完成状态为

STATUS_SUCCESS。这样,发起I/O操作请求的Win32API 将会返回TRUE。相反则会返回FALSE。这种情况时,可以使用GetLastError Win32API得到错误代码,所得的错误代码会和IRP设置的状态一致。

除了设置IRP的完成状态,派遣函数还要设置这个IRP操作了多少字节。

派遣函数将IRP请求结束,这是通过IoCompleteRequest函数完成的。4.通过设备链接打开设备

要打开设备,必须通过设备名字才能得到该设备的句柄。前面介绍过,每个设备都有设备名称,如HelloDDK驱动程序的设备名称为“\\Device\\MyDDKDevice”,但是设备名称无法被用户模式下的应用程序查询到,设备名只能被内核模式

下的程序查询到。在应用程序中需要通过符号链接进行访问。

下面程序演示在用户模式下打开驱动设备:view plaincopy to clipboardprint?

#include <windows.h>

#include <stdio.h>

int main()

{

HANDLE hDevice =

CreateFile("\\\\.\\HelloDDK",

GENERIC_READ |

GENERIC_WRITE,

0, // share mode none

NULL, // no security

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL,

NULL ); // no template

if (hDevice == INV ALID_HANDLE_V ALUE)

{

printf("Failed to obtain file handle to device: "

"%s with Win32 error code: %d\n",

"MyWDMDevice", GetLastError() );

return 1;

}

CloseHandle(hDevice);

return 0;

} 5.编写一个更通用的派遣函数

在Windows驱动开发中,有一个重要的内核数据结构,

IO_STACK_LOCATION,即I/O堆栈,这个数据结构和IRP 紧密相连。

驱动对象会创建一个个设备对象,并将这些设备对象“叠”成一个垂直结构,被称为“设备栈”。IRP会被操作系统发送到设备栈顶层,如果顶层设备结束了本次IRP的请求,则I/O 请求结束,如果不让I/O请求结束,可以将IRP继续转发到下一层设备。因此,一个IRP可能会被转发多次。为了记录IRP在每层设备中的操作,IRP会有一个

IO_STACK_LOCATION数组,每个IO_STACK_LOCATION 元素记录着对应设备中做的操作。对于本层的

IO_STACK_LOCATION,可以通过IoGetCurrentIrpStackLocation函数得到。

IO_STACK_LOCATION结构中会记录IRP的类型,即IO_STACK_LOCATION中的MajorFuncation子域。下面代码增加了派遣函数的难度:view plaincopy to clipboardprint?

#pragma PAGEDCODE

NTSTATUS HelloDDKDispatchRoutine(IN

PDEVICE_OBJECT pDevObj, IN PIRP pIrp)

{

KdPrint(("Enter HelloDDKDispatchRoutine\n"));

PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);

//建立一个字符串数组与IRP类型对应起来

static char * irpname[] =

{

"IRP_MJ_CREATE",

"IRP_MJ_CREATE_NAMED_PIPE",

"IRP_MJ_CLOSE",

"IRP_MJ_READ",

"IRP_MJ_WRITE",

"IRP_MJ_QUERY_INFORMATION",

"IRP_MJ_SET_INFORMATION",

"IRP_MJ_QUERY_EA",

"IRP_MJ_SET_EA",

"IRP_MJ_FLUSH_BUFFERS",

"IRP_MJ_QUERY_VOLUME_INFORMATION",

"IRP_MJ_SET_VOLUME_INFORMATION",

"IRP_MJ_DIRECTORY_CONTROL",

"IRP_MJ_FILE_SYSTEM_CONTROL",

"IRP_MJ_DEVICE_CONTROL",

"IRP_MJ_INTERNAL_DEVICE_CONTROL",

"IRP_MJ_SHUTDOWN",

"IRP_MJ_LOCK_CONTROL",

"IRP_MJ_CLEANUP",

"IRP_MJ_CREATE_MAILSLOT",

"IRP_MJ_QUERY_SECURITY",

"IRP_MJ_SET_SECURITY",

"IRP_MJ_POWER",

"IRP_MJ_SYSTEM_CONTROL",

"IRP_MJ_DEVICE_CHANGE",

"IRP_MJ_QUERY_QUOTA",

"IRP_MJ_SET_QUOTA",

"IRP_MJ_PNP",

};

UCHAR type = stack->MajorFunction;

if (type >= arraysize(irpname))

{

KdPrint(("-Unknow IRP ,major type %X\n",type));

}

else

{

KdPrint(("\t%s\n",irpname[type]));

}

//对一般IRP的简单操作,后面会介绍对IRP更复杂的操作

NTSTATUS status = STATUS_SUCCESS;

//完成IRP

pIrp->IoStatus.Status = status;

pIrp->https://www.doczj.com/doc/8416700797.html,rmation = 0;

IoCompleteRequest(pIrp,IO_NO_INCREMENT);

KdPrint(("Leave HelloDDKDispatchRoutine\n"));

return status;

} 缓冲区方式读写操作

驱动程序所创建的设备一般会有三种读写方式,一种是缓冲区方式,一种是直接方式,一种是其他方式。1.缓冲区方式IOCreateDevice创建完设备后,需要对设备对象的Flags子域进行设置,设置不同的Flags会导致以不同的方式操作设备。设备对象一共可以有三种读写方式,这三种方式的Flags分别对应为DO_BUFFERED_ID,DO_DIRECT_IO和0,缓冲区方式读写相对简单。

读写操作一般是由ReadFile或者WriteFile函数引起的,这里以WriteFile函数为例进行介绍。WriteFile要求用户提供一段缓冲区,并且说明缓冲区的大小,然后WriteFile将这段内存的数据传入到驱动程序中。

这段缓冲区内存是用户模式的内存地址,驱动程序如果直接引用这段内存是十分危险的。如果以缓冲区方式读写,操作系统会将应该用程序提供缓冲区的数据复制到内核模

式下的地址中,这样无论操作系统如何切换进程,内核模式的地址都不回改变。IRP派遣函数真正操作的是内核模式下的缓冲区地址,而不是用户模式下的缓冲区地址。但是这样做会有一定的效率影响。2.缓冲区设备读写

以缓冲区方式写设备时,操作系统将WriteFile提供的用户模式的缓冲区复制到内核模式地址下,这个地址由WriteFile创建的IRP的AssociateIrp.SystemBuffer子域记录。

另外,在派遣函数中也可以通过IO_STACK_LOCATION中的Parameters.Read.Length子域知道ReadFile请求多少字节。通过IO_STACK_LOCATION中的Parameters.Write.Length子域知道WriteFile请求多少字节。

然后,WriteFile和ReadFile指定对设备操作多少字节,并不真正意味着操作了这么多字节。在派遣函数中,应该设置IRP 的子域https://www.doczj.com/doc/8416700797.html,rmation.这个子域记录设备实际操作了多少字节。

下面代码演示了如何利用“缓冲区”方式读设备:view plaincopy to clipboardprint?

NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)

{

KdPrint(("Enter HelloDDKRead\n"));

//对一般IRP进行处理,后面会介绍对IRP更复杂的处理

NTSTATUS status = STATUS_SUCCESS;

PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);

//获得需要读设备的字节数

ULONG ulReadLength =

stack->Parameters.Read.Length;

//完成IRP

//设置IRP完成状态

pIrp->IoStatus.Status = status;

//设置IRP操作了多少字节

pIrp->https://www.doczj.com/doc/8416700797.html,rmation = ulReadLength;

memset(pIrp->AssociatedIrp.SystemBuffer,0XAA,ulReadLe ngth);

//处理IRP

IoCompleteRequest(pIrp,IO_NO_INCREMENT);

KdPrint(("Leave HelloDDKRead\n"));

return status;

}

ring3下的程序来读取数据:view plaincopy to clipboardprint?

#include <windows.h>

#include <stdio.h>

int main()

{

HANDLE hDevice =

CreateFile("\\\\.\\HelloDDK",

GENERIC_READ |

GENERIC_WRITE,

0, // share mode none

NULL, // no security

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL,

NULL ); // no template

if (hDevice == INV ALID_HANDLE_V ALUE)

{

printf("Failed to obtain file handle to device: "

"%s with Win32 error code: %d\n",

"MyWDMDevice", GetLastError() );

return 1;

}

UCHAR buffer[10];

ULONG ulRead;

BOOL bRet =

ReadFile(hDevice,buffer,10,&ulRead,NULL);

if (bRet)

{

printf("Read %d bytes:",ulRead);

for (int i=0;i<(int)ulRead;i++)

{

printf("%02X ",buffer[i]);

}

printf("\n");

}

CloseHandle(hDevice);

return 0;

}

直接读写方式:

1.直接读取设备:

除了“缓冲区”方式读写设备外,另一种方式是直接方式读写设备。这种方式需要在创建完设备对象后,在设置设备属性的时候,设置为DO_DIRECT_IO。

和缓冲区读写方式不同,直接读写设备,操作系统会将用户模式下的缓冲区锁住。然后操作系统将这段缓冲区在内核模式地址再次映射一遍。这样,用户模式的缓冲区和内核模式的缓冲区指向的是同一区域的物理内存。无论操作系统如何切换进程,内核模式地址都保持不变。

操作系统先将用户模式的地址锁住后,操作系统用内存描述符(MDL数据结构)记录这段内存。

MDL记录这段虚拟内存,这段虚拟内存的大小存储在

mdl->ByteCount里,这段虚拟内存的第一个页地址是mdl->StartVa,这段虚拟内存的首地址对于第一个页地址的偏移量是mdl->ByteOffset,。因此,这段虚拟内存的首地址应该是mdl->StartVa + mdl->ByteOffset。

DDK提供里几个宏方便程序员得到这几个数值:view plaincopy to clipboardprint?

#define MmGetMdlByteCount(mdl) ((Mdl)->ByteCount)

#define MmGetMdlByteOffset(mdl) ((Mdl)->ByteOffset)

#define MmGetMdlVirtualAddress(mdl)

((PVOID)((PCHAR)((Mdl->StartVa) +

(Mdl)->ByteOffset))

2.直接读取设备的读写

下面结合代码演示如何编写直接方式设备的派遣函数view plaincopy to clipboardprint?

NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,

IN PIRP pIrp)

{

KdPrint(("Enter HelloDDKRead\n"));

PDEVICE_EXTENSION pDevExt =

(PDEVICE_EXTENSION)pDevObj->DeviceExtension;

NTSTATUS status = STATUS_SUCCESS;

PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);

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驱动开发和调试环境搭建

Windows驱动开发和环境搭建 【文章标题】: Windows驱动开发和调试的环境设置 【文章作者】: haikerenwu 【使用工具】: VC6.0,VMware6.0.3,Windbg 【电脑配置】: 惠普笔记本xp sp3 (一)VMWare安装篇 VMWare的安装一路Next即可,关于其序列号,百度一下就能找到,虚拟机安装完成之后,需要安装操作系统,我在虚拟机中安装的是windows xp sp2系统。 点击“文件”----“新建”----“虚拟机” 进入新建虚拟机的向导,配置虚拟系统参数

选择虚拟系统文件的兼容格式(新手推荐选择默认选项) 按照默认设置继续点击下一步,选择好您需要的操作系统,此处我选择的是Windows XP Prefessional。 设置虚拟机名称和虚拟操作系统安装路径,我单独空出来一个F 盘,将虚拟机和虚拟操作系统全部装在该盘。

配置网络模式(推荐选择NA T,一般主机不用做任何的设置虚拟机就可以利用主机上网)。 配置虚拟磁盘的容量。在这里可以直接单击完成,来完成基本操作设置,磁盘默认空间是8GB,用户可以根据自己的实际使用情况来调整大小,也可以自定义分区。

操作完成之后,在“VM”菜单下有个“setting。。。”菜单,点击此菜单,在CD-ROM中选择合适的选项,我使用的是Use ISO image 选项,将我的xp sp2操作系统的ISO映像路径设置好,安装操作系统。点击ok之后,启动虚拟机,即开始安装操作系统,安装过程跟普通装机过程相同。安装完成之后,启动操作系统,然后在VM菜单下点击“Install VMWare Tools”,把虚拟操作系统的驱动装好。 (二)VMWare设置篇

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等外设都需要安装与设备型号相符的驱动程序,否则无法发挥其部分或全部功能。驱动程序一般可通过三种途径得到,一是购买的硬件附

wdm驱动开发之路

WDM驱动开发之路 写在前面:在专栏的前几期中,我们一起初步学习了vxd的开发技术。Vxd技术是很深奥的,不是一篇两篇文章能讲清楚,但你已经入了门,剩下的就要看你的修行了。多看书,多泡论坛(当然是上咱们的驱动开发网论坛了:->),多写程序…我的手不够用了。功到自然成嘛。不过话又说回来,vxd只是权宜之计,WDM才符合当今的潮流(程序员都是时髦人士,君不见先是VB、VC然后是asp、JSP、PHP,数也数不过来呀),Win9x寿终正寝时也就是vxd的末日,你不想随它而去吧(开个玩笑),那就随我来。 按笔者的想法,这篇文章写成连载形式,一次讲一个主题,并且必要时带着例子,让大伙step by step地把WDM驱动弄个透底,不想让大家觉得稀里糊涂,也不想让大家觉得白买杂志了。 今天我们一起讨论第一部分,了解篇。 (一)了解篇 WDM模型(Windows Driver Model)是微软公司为当前主流操作系统Windows98和Windows 2000的驱动程序设计的一种构架。它和传统的win3.x和win95使用的vxd的驱动是完全不同的体系结构。不过对于最终用户来说,WDM驱动程序在Windows98和Windows2000下的表现很相似。作为驱动开发人员来说,它在两者中有很多的不同。并且Windows98中的WDM只能算是Windowss2000中的WDM的一个了集。在Windows98中有一些驱动程序只能使用VXD来实现,如串行通讯驱动等。 要写驱动程序,首先要了解操作系统的结构。在WDM体系中,windows2000操作系统中是最标准的实现方式,Windows98则是部分兼容WDM结构。照微软的说法,Windows98和Windows2000 X86(Intel 架构)版本实现二进制码兼容(参见98DDK),Windows2000 x86版本与其它CPU平台版本实现源码级兼容(因为Windows 2000是基本NT相似的结构,最底层是硬件抽象层HAL,所有我们相信它们之间能源码级兼容)。但实际上,Windows2000的WDM实现中有很多例程在Windows98中没有实现,一旦试图加载这样的WDM驱动程序到Windows98中,则不能正常加载,当然我们也有办法实现它,那就是利用“桩”技术。具体可参见Walter Oney写的《Programming the Microsoft Windows Driver Model》一书。我们首先来看看Windows 2000的系统结构,然后再来看看Windows 98的。 图一是Windows 2000的系统结构图。从图中我们可以看出:整个系统被分为两个态,用户态和核心态。 从图中可以明显看出I/O操作最后是怎样作用到硬件上的。用户态应用程序对Windows 子系统进行win32 API调用,这个调用由系统服务接口作用到I/O管理器(严格地说,在Windows 系统中不存在I/O管理器这样的独立模块,这个只是为了方便叙述而将各种核心功能调用的集合称作I/O管理器,业界人士都这样称呼这个部分),I/O管理器进行必要的参数匹配和操作安全性检查,然后由这个请求构造出合适的IRP(IO Request Package,I/O请求包),并把此IRP传给驱动程序。简单情况下,驱动程序直接执行这个请求包,并与硬件打交道,从而完成I/O请求工作,最后由I/O管理器将执行结果返回给用户态程序。但在WDM体系结构中,大部分实行分层处理。即在图中“设备驱动“这部分,分成了若干层,典型地分成高层驱动程序、中间层驱动程序、底层驱动程序。每层驱动再把I/O请求划分成更简单的请求,以传给更下层的驱动执行。以文件系统驱动为例,最高层驱动只知道文件如何在磁盘上表示,但不知到怎样得到数据。最低层驱动程序只知道怎样从磁盘取出512B为单的数据块,但不知道文件怎样表示。举个更具体的生活例子。主人(最高层驱动)知道(并且需要)笔计本电脑,但不知道具体放在什么位置;而仆人(最底层驱动)却知道它放在具体什么地方,但

如何在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驱动开发培训 培训流程: 一、基础知识 在开始驱动开发之前,您应该知道操作系统原理以及驱动程序是如何在操作系统中进行工作的,了解这些基本原理将有助于您做出正确的设计决策并简化您的开发过程。 1、了解Windows操作系统构造\\ 可以链接进去 2、安装WDK,参考相关文档,熟悉WDK的内容\\ 可以链接进去 二、Windows驱动开发\\ 可以链接进去 一、基础知识 在开始驱动开发之前,您应该知道操作系统原理以及驱动程序是如何在操作系统中进行工作的,了解这些基本原理将有助于您做出正确的设计决策并简化您的开发过程。 1、了解Windows操作系统构造 (1)培训目标 深入了解Windows操作系统的系统结构以及工作原理 (2)培训内容 阅读书籍《深入解析Windows操作系统》的第3、4、6、7、9章,重点关注第九章“I/O系统” (3)培训任务 ①掌握Windows操作系统的系统结构 ②理解ISR、IRP、IRQL、DCP等概念的含义 ③了解注册表的用法,掌握注册表数据的查看和修改方法 ④了解进程和线程的内部机理以及线程的调度策略 ⑤了解I/O系统的内容,理解I/O请求以及I/O处理过程 注:以上相关内容,请在一周内完成。

2、安装WDK,参考相关文档,熟悉WDK的内容 (1)培训目标 了解WDK的安装过程,熟悉WDK的编译环境,掌握如何使用WDK的相关帮助文档;了解WDM驱动程序的基本结构 (2)培训内容 ①.阅读文档\\10.151.131.12\book\windows\MSWDM.chm,掌握WDM驱动程序的基本结构以及基本的编程技术。 ②.参考WDK的帮助文档:WDK documentation ,了解WDK的基本内容 (3)培训任务 ①理解分层驱动结构的含义,掌握设备和驱动程序的层次结构 ②理解“驱动对象”和“设备对象”的概念 ③理解2个基本例程:DriverEntry 和addDevice ④了解IRP的结构以及IRP处理的流程 ⑤初步了解I/O的控制操作 注:以上相关内容,请在一周内完成。 二、Windows驱动开发 学习如何基于WDK进行驱动程序的开发 1、培训目标 (1)学会根据WDK开发一个基本的Windows驱动程序和测试程序 (2)学会利用不同的IOCTL方式在内核模式和用户模式之间进行通讯 (3)学会如何在内核模式下和用户模式下访问注册表 (4)利用WinDbg跟踪程序,学会使用WinDbg进行调试 2、培训内容 (1)阅读\src\general\ioctl中的示例代码 (2)build并运行应用程序和驱动程序

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

利用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盘上进行文件的读取。

Windows 内核技术与驱动开发笔记(完整版)

Windows 内核技术与驱动开发笔记 1.简述Driver Entry例程 动程序的某些全局初始化操作只能在第一次被装入时执行一次,而Driver Entry例程就是这个目的。 * Driver Entry是内核模式驱动程序主入口点常用的名字。 * Driver Entry的第一个参数是一个指针,指向一个刚被初始化的驱动程序对象,该对象就代表你的驱动程序。WDM驱动程序的Driver Entry例程应完成对这个对象的初始化并返回。非WDM驱动程序需要做大量额外的工作,它们必须探测自己的硬件,为硬件创建设备对象(用于代表硬件),配置并初始化硬件使其正常工作。 * Driver Entry的第二个参数是设备服务键的键名。这个串不是长期存在的(函数返回后可能消失)。如果以后想使用该串就必须先把它复制到安全的地方。 * 对于WDM驱动程序的Driver Entry例程,其主要工作是把各种函数指针填入驱动程序对象,这些指针为操作系统指明了驱动程序容器中各种例程的位置。 2.简述使用VC进行内核程序编译的步骤 编译方式是使用VC++进行编译 1.用VC新建工程。 2.将两个源文件Driver.h和Driver.cpp拷贝到工程目录中,并添加到工程中。 3.增加新的编译版本。 4.修改工程属性,选择“project | setting”将IterMediate file和Output file 都改为MyDriver_Check。 5.选择C/C++选项卡,将原有的Project Options内容全部删除替换成相关参数。 6.选择Link选项卡,将原有的Project Options内容删除替换成相关Link。 7.修改VC的lib目录和include的目录。 8.在VC中选择tools | options,在弹出的对话框中选择“Directories”选项卡,在“Show directories for”下拉菜单中选择“Include file”菜单。添加DDK的相关路径。 3.简述单机内核调试技术 答:1.下载和安装WinDbg能够调试windows内核模块的调试工具不多,其中一个选择是微软提供的WinDbg 下载WinDbg后直接双击安装包执行安装。 2.安装好虚拟机以后必须把这个虚拟机上的windows设置为调试执行。在被调试系统2000、2003或是xp的情况下打开虚拟机中的windows系统盘。 3.将boot.ini文件最后一行复制一下,并加上新的参数使之以调试的方法启动。重启系统,在启动时就可以看到菜单,可以进入正常windows xp,也可以进入Debug模式的windows xp。 4.设置VMware管道虚拟串口。调试机与被调试机用串口相连,但是有被调试机是虚拟机的情况下,就不可能用真正的串口连接了,但是可以在虚拟机上生成一个用管道虚拟机的串口,从而可以继续内核调试。 4.请画出Windows架构简图

从零开始搭建Linux驱动开发环境

参考: 韦东山视频第10课第一节内核启动流程分析之编译体验 第11课第三节构建根文件系统之busybox 第11课第四节构建根文件系统之构建根文件系统韦东山书籍《嵌入式linux应用开发完全手册》 其他《linux设备驱动程序》第三版 平台: JZ2440、mini2440或TQ2440 交叉网线和miniUSB PC机(windows系统和Vmware下的ubuntu12.04) 一、交叉编译环境的选型 具体的安装交叉编译工具,网上很多资料都有,我的那篇《arm-linux- gcc交叉环境相关知识》也有介绍,这里我只是想提示大家:构建跟文件系统中所用到的lib库一定要是本系统Ubuntu中的交叉编译环境arm-linux- gcc中的。即如果电脑ubuntu中的交叉编译环境为arm-linux-

二、主机、开发板和虚拟机要三者互通 w IP v2.0》一文中有详细的操作步骤,不再赘述。 linux 2.6.22.6_jz2440.patch组合而来,具体操作: 1. 解压缩内核和其补丁包 tar xjvf linux-2.6.22.6.tar.bz2 # 解压内核 tar xjvf linux-2.6.22.6_jz2440.tar.bz2 # 解压补丁

cd linux_2.6.22.6 patch –p1 < ../linux-2.6.22.6_jz2440.patch 3. 配置 在内核目录下执行make 2410_defconfig生成配置菜单,至于怎么配置,《嵌入式linux应用开发完全手册》有详细介绍。 4. 生成uImage make uImage 四、移植busybox 在我们的根文件系统中的/bin和/sbin目录下有各种命令的应用程序,而这些程序在嵌入式系统中都是通过busybox来构建的,每一个命令实际上都是一个指向bu sybox的链接,busybox通过传入的参数来决定进行何种命令操作。 1)配置busybox 解压busybox-1.7.0,然后进入该目录,使用make menuconfig进行配置。这里我们这配置两项 一是在编译选项选择动态库编译,当然你也可以选择静态,不过那样构建的根文件系统会比动态编译的的大。 ->Busybox Settings ->Build Options

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的源码:

驱动程序开发技术-过滤键盘驱动

《驱动程序开发技术》大作业 ——过滤键盘驱动 姓名:梁海杰 学号:2009441624 班级:计科普0902

摘要 Kbdclass.sys是键盘的类驱动,无论是USB键盘,还是PS/2键盘都要经过它的处理;在键盘类驱动之下,和实际硬件打交道的驱动叫做“端口驱动”,比如:i8042prt.sys是ps/2键盘的端口驱动,Kbdhid.sys是USB键盘的端口驱动。键盘中断导致键盘中断服务例程被执行,导致最终i8042prt的I8042KeyboardInterruptService被执行。在I8042KeyboardInterruptService中,从端口读取扫描码,放到一个KEYBOARD_INPUT_DATA 结构中。并把这个结构放到i8042prt的输入队列中。最后会调用内核api函数KeInsertQueueDpc。在这个调用中会调用上层KbdClass.sys中处理输入的回调函数KeyboardClassServiceCallback,取走i8042prt的输入数据队列里的数据。利用驱动分层机制,使用过滤驱动捕获键盘的扫描码并保存下来;应用程序定时访问驱动程序取回扫描码,转换成相应的按键名称并显示;通过应用程序设定按键映射,应用程序将指令传送给驱动程序,以实现将指定的按键消息转换成其他按键。 关键词:过滤键盘;驱动分层;映射;扫描码

过滤键盘驱动 一、主要设计思路 利用驱动分层机制,使用过滤驱动捕获键盘的扫描码并保存下来;应用程序定时访问驱动程序取回扫描码,转换成相应的按键名称并显示;通过应用程序设定按键映射,应用程序将指令传送给驱动程序,以实现将指定的按键消息转换成其他按键。 键盘过滤驱动是工作在异步模式下的。系统为了得到一个按键操作,首先要发送一个IRP_MJ_READ消息到驱动的设备栈,驱动收到这个IRP后,会一直保持这个IRP为未确定(pending)态,因为当时并没有按键操作。直到一个键被真正的按下,驱动此时就会立刻完成这个IRP,并将刚按下的键的相关数据做为该IRP的返回值。在该IRP带着对应的数据返回后,操作系统将这些值传递给对应的事件系统来处理,然后系统紧接着又会立刻发送一个IRP_MJ_READ请求,等待下次的按键操作,重复以上的步骤。 为了实现截获键盘消息,需要在过滤驱动程序中创建一个挂接到物理键盘设备上层的过滤驱动设备。系统发送的IRP_MJ_READ消息会首先到达过滤驱动设备,这样就可以有机会给IRP_MJ_READ设置指定的完成例程,然后将消息下传给物理键盘设备。当有按键动作发生时,IRP_MJ_READ消息在完成后就会调用指定的完成例程,这时就可以在完成例程中读出键盘动作的内容,或者修改这些信息,以实现按键的映射。

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来

行为驱动开发

行为驱动开发 行为驱动开发(简称BDD)是测试驱动开发的升级版。它是一套软件工程实践方法,能帮助研发团队更快地构建和交付更有价值和更高质量的软件产品。采用BDD思想编写的测试读起来更像规格说明书而不是单元测试,所以它是使用测试作为表达和验证行为的一种手段。基于这个特性,BDD也非常适合应用在需求分析中。 一、行为驱动开发的原则 1.聚焦交付业务价值。使用验收标准作为目标,帮助业务实现更实际的可交付的功能。 2.团队共同确定交付标准。业务分析人员,开发人员,测试人员与最终用户一起定义和指定功能。 3.拥抱变化。项目开始时不锁定需求,而是假设需求,从用户那里得到早期的反馈,对需求的理解将在项目的整个生命周期中演进和变更。 4.不仅仅编写自动化测试,而是编写可执行规范和底层规范。团队将验收标准转换为自动化的验收测试,更准确地说是转换为可执行规范。在编写任何代码之前,开发人员将考虑代码实际上应该做什么,并将其表示为底层的可执行规范。可执行规范是一种自动化测试,它演示和验证应用程序如何交付特定的业务需求。自动化测试作为构建过程的一部分运行,并在对应用程序进行更改时运行,进行验收测试和回归测试。 5.交付活文档,并使用活文档来支持后续维护工作。在项目结束后持续维护项目可执行规范。 二、行为驱动开发的优势 1.专注业务目标,避免工程师把工作量浪费在不提供业务价值的功能上,能够降低成本,减少浪费。

2.完整的可执行规范,可充当开发人员的辅助技术文档,更容易理解现有的代码库并进行更改。 3.全面的自动化验收测试和回归测试,不仅可以提升执行效率,也能降低手工测试的出错率,使得迭代速度更快更可靠。 三、行为驱动开发的缺陷 1. 需要多个角色高度参与和协作,涉众如果不愿意或不能参与对话和协作,或者等到项目结束后才给出反馈,就很难充分利用BDD的优点。 2.比较适用于敏捷开发,但不太适用于瀑布式开发。 3.对参与角色能力要求很高,尤其是测试团队,不仅需要精通业务,对业务目标清晰,而且对测试技术能力要求更高,如果编写的自动化测试很烂,会导致更高的测试维护成本。

Windows驱动程序开发环境配置

Windows驱动程序开发笔记 一、WDK与DDK环境 最新版的WDK 微软已经不提供下载了这里:https://https://www.doczj.com/doc/8416700797.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大小。

相关主题
文本预览
相关文档 最新文档