微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > windowsNT4.0下设备驱动程序的开发与应用

windowsNT4.0下设备驱动程序的开发与应用

时间:09-12 来源:互联网 点击:

_WRITE]=

XxWriteDispatch

DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=XxSelfDispatch

DriverObject->DriverUnload=XxUnload

//生成Windows NT Executive知道的设备名

RtlInitUnicodeString(NtDeviceName, SelfDeviceName);

//生成自己的设备

Status=IoCreateDevice(

DriverObject, // Driver对象

sizeof(SELF_DEVICE_INFO), // Device对象

Extension结构大小

NtDeviceName,

DeviceType,

0,

FALSE, // 不执行

DeviceObject //Device对象指针

);

//生成Win32子系统下的用户程序可识别的设备名

RtlInitUnicodeString(Win32DeviceName, SelfWin32Name);

//联接内部设备名与Win32子系统下的设备名

Status = IoCreateSymbolicLink( Win32DeviceName, NtDeviceName);

//利用RtlQueryRegistryValues函数读出注册表中Parameters下的参数值,初始化自己的硬件

...

4 驱动程序服务例程

驱动程序初始化之后,始终等待发自用户的命令或由其它事件源引起的事件。一旦命令或事件发生,I/O管理器就调用相应的服务例程提供服务。而几乎所有的I/O都是通过I/O请求包IRP驱动的。所谓IRP驱动,就是I/O管理器负责在非分页的系统内存中分配一定空间,当接受用户发出的命令或由事件引发后,将工作指令按一定的数据结构置于其中,传递到驱动程序服务例程。换言之,IRP包含了驱动程序服务例程所需要的信息指令。表2、表3为IRP的一些数据结构。

同时,I/O管理器和驱动程序都需要在所有时候知道一个I/O设备所进行的情况。系统提供Device对象以满足此要求。该对象在DriverEntry例程中生成设备时由系统创建后,分配给驱动程序,并在整个驱动程序生存期内有效。当I/O管理器调用驱动程序服务例程时,传递该对象。表4为Device对象的外部可见域。

表2 IRP标头中外部可见的域

2.jpg

表3 IRP堆栈单元的一些内容

3.jpg

表4 Device 对象的外部可见域

4.jpg

其中,DeviceExtension域是一个重要的数据结构。它是由I/O管理器创建并自动挂接到Device对象的非分页池,是保存驱动程序任意全局变量的最好办法。因为DeviceExtension是驱动程序特定的,要自定义它的数据结构。

下面是一个驱动程序服务例程利用Device对象和IRP的片段:

NTSTATUS XxSelfDispatch(IN PDEVICE_OBJECT pDO IN PIRP pIrp);

{

PLOCAL_DEVICE_INFO pLDI;

PIO_STACK_LOCATION pIrpStack;

PULONG pIOBuffer;

//得到全局信息

pLDI = (PSELF_DEVICE_INFO)pDO->DeviceExtension;

pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

//得到由用户应用程序发来的用户数据,并在需要时,将结果通过此变量返回给用户

pIOBuffer=PULONGpIrp->AssociatedIrp.System

Buffer;

// 由IRP携带的信息决定驱动程序的执行

switch (pIrpStack->MajorFunction)

{

case IRP_MJ_CREATE:

case IRP_MJ_CLOSE:

Status = STATUS_SUCCESS;

break;

case IRP_MJ_DEVICE_CONTROL:

//由Parameters进一步解释控制代码含义

switch (pIrpStack->Parameters.DeviceIoControl.IoControlCode)

{

case IOCTL_Function1:

//执行功能代码

Field1 = pLDI->SelfField1;

...

break;

case IOCTL_Function2:

//执行功能代码

...

break;

break

// 返回I/O操作的状态

pIrp->IoStatus.Status = Status;

IoCompleteRequest(pIrp IO_NO_INCREMENT);

return Status;

5 驱动程序终止例程

Unload例程负责取消由DriverEntry例程所做的任何事情,包括解除属于该驱动程序的任何硬件资源的分配,以及删除属于驱动程序的任何内核对象。通常这仅在系统关闭时需要。

VOID XxUnload(PDRIVER_OBJECT DriverObject)

{

PLOCAL_DEVICE_INFO pLDI;

UNICODE_STRING Win32DeviceName;

// 得到全局数据,根据全局数据进行清理工作

pLDI=PLOCAL_DEVICE_INFODriverObject->Device

Object->DeviceExtension

if (pLDI->Field2 == TRUE)

{

...

// 删除分配的设备名及设备

RtlInitUnicodeString(Win32DeviceName, SelfWin32 Name);

IoDeleteSymbolicLink(Win32DeviceName);

IoDeleteDevice(pLDI->DeviceObject);

6 用户层应用程序与驱动程序间的接口

驱动程序完成后,将在系统重新引导时装入并初始化(由DriverEntry例程完成)。此时,驱动程序处于可用状态,等待用户层应用程序使用。用户层应用程序可以:

·打开该设备文件(由IRP_MJ_CREATE功能代码完成)

·读出数据(由IRP_MJ_READ功能代码完成)

·写入数据(由IRP_MJ_WRITE功能代码完成)

·执行用户自定义的功能代码(由IRP_MJ_DEVICE_CONTROL功能代码完成)

·关

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top