当前位置:文档之家› 驱动名词解释

驱动名词解释

驱动NTSTATUSNTSTATUS 是被定义为32位的无符号长整型。

在驱动程序开发中,人们习惯用NTSTATUS 返回状态。

其中0~0X7FFFFFFF,被认为是正确的状态,而0X80000000~0XFFFFFFFF被认为是错误的状态。

有一个非常有用的宏-----NT_SUCCESS,用来检测状态是否正确。

ININ,OUT,INOUT是一个空的宏,只是用来说明这个参数是用于输入参数,还是输出的参数。

DriverEntry操作系统在初始化驱动程序的时候会调用DriverEntry,通常会用这个函数来填充dispatch例程的指针,这就象注册回调函数一样。

有的设备要创建设备的对象,或者还要创建一个设备名字,以及其他的初始化操作。

它的原型:NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath){}IN,OUT,INOUT是一个空的宏,只是用来说明这个参数是用于输入参数,还是输出的参数。

NTSTATUS实际是个长整型可以在DDK头文件NTSTA TUS.H中找到NTSTATUS的代码列表。

函数的第一个参数DriverObject是刚被初始化的驱动对象,就是操作系统为这个驱动分配的空间的指针。

函数的第二个参数RegistryPath是驱动在注册表中的键值。

如果驱动程序需要访问设备的服务键需要保存这个键值以备后用。

UNICODE_STRINGUNICODE_STRING结构是通过使用各种本地安全认证(LSA)的功能来指定一个Unicode 字符串。

2结构体原型:typedef struct _LSA_UNICODE_STRING {USHORT Length;USHORT MaximumLength;PWSTR Buffer;} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;3结构成员:Length指定字符串的长度,以字节为单位指出的Buffer字符串的长度。

如果是以NULL字符结尾(即'\0'),则不包括NULL字符的长度。

MaximumLengthBuffer字符串的总长度。

MaximumLength和Length的关系可以参照:char c[10] = "123";sizeof(c);和strlen(c);得出的结果。

一个宽字符的字符串的指针。

注意,通过各种LSA函数返回的字符串可能不是以NULL结尾。

4使用范例:编辑UNICODE_STRING str = RTL_CONSTANT_STRING(L"Hello");KdPrint(("Buffer:%ws\nMaxinumLength:%d\nLength:%d", str.Buffer, str.MaximumLength, str.Length));AddDeviceAddDevice例程是WDM特有的,在DriverEntry中需要设置AddDevice例程的函数地址。

设置的方式是在驱动对象的DriverExtension子域的AddDevice子域保存AddDevice实际例程的函数地址。

AddDevice例程的名字可以随意命名。

******************************************************************************* **************NTSTAUS MyAddDevice(IN PDRIVER_OBJECT pDriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)// 设置AddDevice实际例程的地址pDriverObject->DriverExtension-> AddDevice = MyAddDevice;#pragma code_set("INIT")//将此函数放到INIT段中当驱动加载结束后,此函数就可以从内存中卸载掉#pragma code_seg("PAGE")//此例程分派在分页中保存IRP_MJ_PNP即插即用例程的一个基本操作,其完成操作系统即插即用管理器发出的即插即用信息,主要包括启动设备、停止设备、删除设备这三个功能,个别驱动还需要几个即插即用操作。

RtlInitUnicodeString初始化字串代码1:UNICODE_STRING US1;RtlInitUnicodeString(&US1,L"DDDD");会动态分配一块指向“DDDD”的内存指针,赋值给US1.Buffer;代码2:wchar_t tmpstr[260]={0};UNICODE_STRING US1;RtlInitUnicodeString(&US1,tmpstr);这时US1.Buffer直接指向tmpstr,如果修改了US1,也会同时修改tmpstr。

另外此时US1.MaximumLength=2;要重新设定MaximumLength=260*2,才能正常使用。

IoCreateDevice()IoCreateDevice函数用于创建常规的设备对象.NTSTATUS IoCreateDevice(IN PDRIVER_OBJECT DriverObject,IN ULONG DeviceExtensionSize,IN PUNICODE_STRING DeviceNameOPTIONAL,IN DEVICE_TYPE DeviceType,IN ULONG DeviceCharacteristics,IN BOOLEAN Exclusive,OUT PDEVICE_OBJECT *DeviceObject);DriverObject一个指向调用该函数的驱动程序对象.每一个驱动程序在它的DriverEntry过程里接收一个指向它的驱动程序对象.WDM功能和过滤驱动程序也在他们的AddDevice过程接受一个驱动程序对象的指针. DeviceExtensionSize指定驱动程序为设备扩展对象而定义的结构体的大小.DeviceName(可选的参数)指向一个以零结尾的包含Unicode字符串的缓冲区,那是这个设备的名称,该字符串必须是一个完整的设备路径名.WDM功能驱动程序和过滤驱动程序它们的设备对象没有名字.注意:如果设备名未提供(即这个参数是NULL),IoCreateDevice创建的设备对象将不会有一个DACL与之相关联.DeviceType指定一个由一个系统定义的FILE_DEVICE_XXX常量,表明了这个设备的类型(如FILE_DEVICE_DISK,FILE_DEVICE_KEYBOARD等),或供应商定义的一种新型设备的类型.DeviceCharacteristics指定一个或多个系统定义的常量,连接在一起,提供有关驱动程序的设备其他信息.对于可能的设备特征信息,见DEVICE_OBJECT结构体.Exclusive如果指定设备是独占的,大部分驱动程序设置这个值为FALSE,如果是独占的话设置为TRUE,非独占设置为FALSE.DeviceObject一个指向DEVICE_OBJECT结构体指针的指针,这是一个指针的指针,指向的指针用来接收DEVICE_OBJECT结构体的指针.IoCreateDevice函数成功时返回STA TUS_SUCCESS,失败时返回适当的NTSTATUS错误代码.这时这个函返回值STATUS_INSUFFICIENT_RESOURCESSTA TUS_OBJECT_NAME_EXISTSSTA TUS_OBJECT_NAME_COLLISIONDEVICE_EXTENSION设备扩展(DEVICE_EXTENSION)是与设备对象相关的另一种重要的数据结构。

可以用它来保存与特定设备关联的信息。

设备扩展其实只是一个未分页的池,由驱动开发者来定义它的大小和内容。

并由I/O管理器自动把它分配给设备对象,即设备对象的PVOID DeviceExtension字段。

由于此结构是驱动开发者自定义的,所以必须要让系统知道需要给此结构预留多少空间,因此要把设备扩展结构的大小作为参数传递给IoCreateDevice函数。

I/O管理器的IoCreateDevice函数将为设备对象和设备扩展对象在非分页内存池内申请内存。

设备扩展一般要包括设备对象的反向指针、设备状态或驱动程序环境信息等,它的布局类似于如下结构:typedef struct tagDEVICE_EXTENSION {PDEVICE_OBJECT DeviceObject; // device object this extension belongs to PDEVICE_OBJECT LowerDeviceObject; // next lower driver in same stackPDEVICE_OBJECT Pdo; // the PDOIO_REMOVE_LOCK RemoveLock; // removal control locking structureUNICODE_STRING devname;. . . . . .} DEVICE_EXTENSION, *PDEVICE_EXTENSION;设备扩展的内容依赖特定的驱动程序,应该根据驱动程序的需要来定义。

设备扩展主要用来维护设备状态信息、存储驱动程序使用的内核对象或系统资源(如自旋锁)、保存驱动程序需要的数据等。

由于大多数的总线驱动、功能驱动和过滤器驱动都要工作在任意线程上下文,即任意线程都可能成为当前线程,所以,设备扩展是保存设备状态信息和数据的主要空间。

每一个实现了ISR的驱动程序都要存储中断对象(一种内核对象)指针,大部分的驱动程序把它们存储在设备扩展里。

每一个标准的驱动程序函数在接收一个IRP时,同时接收到的还有一个指向申请该IO操作的设备对象的指针,此函数能够通过此指针访问到相应的设备扩展。

另外,上一层的设备扩展都保存一个指向下一层设备对象的指针(如上述结构中的PDEVICE_OBJECT LowerDeviceObject字段)作为调用IoCallDriver函数的参数。

FILE_DEVICE_UNKNOWN未知设备IoCreateSymbolicLink创建一个设备链接。

驱动程序虽然有了设备名称,但是这种设备名称只能在内核态可见,而对于应用程序是不可见的,因此,驱动需要要暴露一个符号链接,该链接指向真正的设备名称NTSTATUS IoCreateSymbolicLink(IN PUNICODE_STRING SymbolicLinkName,IN PUNICODE_STRING DeviceName );参数:SymbolicLinkNameUnicode字符串指针,是一个用户态可见的名称。

相关主题