/* 1.基本的驱动数据结构 //驱动对象结构体 typedef struct _DRIVER_OBJECT { CSHORT Type; //结构类型 CSHORT Size; //结构大小 PDEVICE_OBJECT DeviceObject; //驱动设备对象 PDRIVER_EXTENSION DriverExtension; //驱动扩展指针 UNICODE_STRING DriverName; //驱动程序的名字 PDRIVER_UNLOAD DriverUnload; //驱动的卸载函数 PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; //普通的分发函数 ...... //其他的成员没有列出 } DRIVER_OBJECT; //定义驱动对象指针 typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT; //************************************************************************************************************ //设备对象结构体 typedef struct _DEVICE_OBJECT { CSHORT Type;//结构类型 USHORT Size;//结构大小 LONG ReferenceCount; //引用计数 struct _DRIVER_OBJECT *DriverObject; //这个设备所属对象 struct _DEVICE_OBJECT *NextDevice; //指向下一个设备。 //在一个驱动对象中有N个设备,这些设备通过这个指针链接起来作为一个单向链表 ULONG Flags; struct _DEVOBJ_EXTENSION *DeviceObjectExtension; //设备扩展结构 ...... //其他的成员没有列出 } DEVICE_OBJECT; //定义设备对象指针 typedef struct _DEVICE_OBJECT *P_DEVICE_OBJECT; //============================================================================================================ 2.驱动编程基本函数介绍: //Unicode字符串的初始化 VOID RtlInitUnicodeString( OUT PUNICODE_STRING DestinationString, IN PCWSTR SourceString) DestinationString 需要初始化的指针PUNICODE_STRING SourceString 指向一个以空结尾的Unicode字符串常量,用这个字符串来初始化DestinationString。 例子 PUNICODE_STRING s; RtlInitUnicodeString(s, L"宽字符"); //s=L"宽字符"; //************************************************************************************************************ //IoCreateDevice为驱动创建一个设备对象 NTSTATUS IoCreateDevice( IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName OPTIONAL, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject) //指针的指针 参数: DriverObject 为指向驱动对象的指针。 DeviceExtensionSize 给_DEVICE_OBJECT.DeviceExtension指定内存空间大小,具体看定义的设备扩展结构的大小 DeviceName 设备名字,如:\\Device\\GetGDT0 DeviceType 设备类型,这里我们用 FILE_DEVICE_UNKNOWN DeviceCharacteristics 设备特征信息 一般为0 Exclusive 是否指定设备为独占 是为TRUE,否为FALSE DeviceObject 指针变量接收一个指向新创建的DEVICE_OBJECT结构。用来回传数据 返回值解释: 调用成功会返回 STATUS_SUCCESS 如果出错会返回下列值 STATUS_INSUFFICIENT_RESOURCES //资源不足 STATUS_OBJECT_NAME_EXISTS //指定对象名存在 STATUS_OBJECT_NAME_COLLISION //对象名有冲突 //************************************************************************************************************ //IoCreateSymbolicLink创建一个设备链接符。 //驱动程序虽然有了设备名称,但是这种设备名称只能在内核态可见,而对于应用程序是不可见的, //因此,驱动程序需要暴露一个符号链接,该链接指向真正的设备名称(不是必须的) //只是让Ring3环应用程序连接驱动程序更容易 NTSTATUS IoCreateSymbolicLink( IN PUNICODE_STRING SymbolicLinkName, IN PUNICODE_STRING DeviceName); 参数: SymbolicLinkName Unicode字符串指针,是一个用户态可见的名称。如:\\DosDevices\\GetGDT0 或者 \\??\\GetGDT0 DeviceName Unicode字符串指针,是驱动程序创建的设备对象名称。如:\\Device\\GetGDT0 返回值解释: 如果符号链接创建成功 返回STATUS_SUCCESS //************************************************************************************************************ VOID IoDeleteDevice( IN PDEVICE_OBJECT DeviceObject) 参数 DeviceObject PDEVICE_OBJECT类型的设备对象指针,指向需要删除的设备对象 //============================================================================================================ 3.编写简单的驱动程序Demo 创建设备的步骤: 1用RtlInitUnicodeString初如化设备名称指针 2用IoCreateDevice创建设备,如果不成功则返回 3用IoCreateSymlicLink创建符号链接,创建成功返回 STATUS_SUCCESS;创建不成功则调用 IoDeleteDevice删除设备; 简单的代码示例: //代码片段--使用C语言 #define INITCODE code_seg("INIT") //初始化时载入内存,然后可以从内存中卸掉 #pragma INITCODE NTSTATUS CreateMyDevice (IN PDRIVER_OBJECT pDriverObject) { NTSTATUS status; //用来返回创建设备 PDEVICE_OBJECT pDevObj; //创建设备名称 UNICODE_STRING devName; UNICODE_STRING symLinkName; //对devName初始化字串为 "\\Device\\XX_Device" RtlInitUnicodeString(&devName,L"\\Device\\XX_Device"); //创建设备对象 status = IoCreateDevice(pDriverObject,\ 0,\ &devName,\ FILE_DEVICE_UNKNOWN,\ 0, TRUE,\ &pDevObj); if (!NT_SUCCESS(status)) return status; //设置缓冲区通信方式 pDevObj->Flags |= DO_BUFFERED_IO; //创建符号链接 RtlInitUnicodeString(&symLinkName,L"\\??\\XX_Device"); status = IoCreateSymbolicLink( &symLinkName,&devName ); if (!NT_SUCCESS(status)) { IoDeleteDevice( pDevObj ); return status; } return STATUS_SUCCESS; } //参考资料: //郁金香老师讲课资料整理 */