WDM驱动

来源:互联网 发布:600d套机拍摄淘宝图 编辑:程序博客网 时间:2024/04/29 23:31
/************************************************************************* 文件名称:HelloWDM.h                                                 * 作    者:张帆* 完成日期:2007-11-1*************************************************************************/#ifdef __cplusplusextern "C" //保证符号连接的正确性{#endif#include <wdm.h>#ifdef __cplusplus}#endif typedef struct _DEVICE_EXTENSION//本设备相关信息{    PDEVICE_OBJECT fdo;    PDEVICE_OBJECT NextStackDevice;UNICODE_STRING ustrDeviceName;// 设备名UNICODE_STRING ustrSymLinkName;// 符号链接名} DEVICE_EXTENSION, *PDEVICE_EXTENSION;#define PAGEDCODE code_seg("PAGE")//分页内存#define LOCKEDCODE code_seg()// 非分页内存#define INITCODE code_seg("INIT")#define PAGEDDATA data_seg("PAGE")#define LOCKEDDATA data_seg()#define INITDATA data_seg("INIT")#define arraysize(p) (sizeof(p)/sizeof((p)[0]))NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,                           IN PDEVICE_OBJECT PhysicalDeviceObject);NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,                        IN PIRP Irp);NTSTATUS HelloWDMDispatchRoutine(IN PDEVICE_OBJECT fdo, IN PIRP Irp);void HelloWDMUnload(IN PDRIVER_OBJECT DriverObject);extern "C"NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,                     IN PUNICODE_STRING RegistryPath);
/************************************************************************* 文件名称:HelloWDM.cpp                                                 * 作    者:张帆* 完成日期:2007-11-1*************************************************************************/#include "HelloWDM.h"/************************************************************************* 函数名称:DriverEntry* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象* 参数列表:      pDriverObject:从I/O管理器中传进来的驱动对象      pRegistryPath:驱动程序在注册表的中的路径* 返回 值:返回初始化驱动状态*************************************************************************/#pragma INITCODE extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath){KdPrint(("进入李赛赛 DriverEntry\n"));pDriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;//驱动扩展里 可用添加设备 wdm独有pDriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;//回调函数pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = pDriverObject->MajorFunction[IRP_MJ_CREATE] = pDriverObject->MajorFunction[IRP_MJ_READ] = pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloWDMDispatchRoutine;pDriverObject->DriverUnload = HelloWDMUnload;KdPrint(("进入李赛赛Leave DriverEntry\n"));return STATUS_SUCCESS;}/************************************************************************* 函数名称:HelloWDMAddDevice* 功能描述:添加新设备* 参数列表:      DriverObject:从I/O管理器中传进来的驱动对象      PhysicalDeviceObject:从I/O管理器中传进来的物理设备对象* 返回 值:返回添加新设备状态*************************************************************************/#pragma PAGEDCODENTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT PhysicalDeviceObject)//物理设备{ PAGED_CODE();//中断请求超过APC_LEVEL 会产生断言 断言会使程序终止执行并报告出错地址 check版本有效KdPrint(("进入李赛赛Enter HelloWDMAddDevice\n"));NTSTATUS status;PDEVICE_OBJECT fdo;UNICODE_STRING devName;RtlInitUnicodeString(&devName,L"\\Device\\MyWDMDevice");//设备名status = IoCreateDevice(DriverObject,sizeof(DEVICE_EXTENSION),&(UNICODE_STRING)devName,FILE_DEVICE_UNKNOWN,0,FALSE,&fdo);//得到设备对象 有设备扩展if( !NT_SUCCESS(status))return status;PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;//设备扩展 通过指针赋值pdx->fdo = fdo;//赋值本设备对象pdx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);//将fdo设备挂接到物理设备堆栈上 (下层堆栈的位置)(返回值)  下一个栈里的设备  返回真实设备UNICODE_STRING symLinkName;RtlInitUnicodeString(&symLinkName,L"\\DosDevices\\HelloWDM");//符号连接pdx->ustrDeviceName = devName;pdx->ustrSymLinkName = symLinkName;status = IoCreateSymbolicLink(&(UNICODE_STRING)symLinkName,&(UNICODE_STRING)devName);if( !NT_SUCCESS(status)){IoDeleteSymbolicLink(&pdx->ustrSymLinkName);status = IoCreateSymbolicLink(&symLinkName,&devName);if( !NT_SUCCESS(status)){return status; }}fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;fdo->Flags &= ~DO_DEVICE_INITIALIZING;KdPrint(("Leave HelloWDMAddDevice\n"));return STATUS_SUCCESS;}/************************************************************************* 函数名称:DefaultPnpHandler* 功能描述:对PNP IRP进行缺省处理* 参数列表:      pdx:设备对象的扩展      Irp:从IO请求包* 返回 值:返回状态*************************************************************************/ #pragma PAGEDCODENTSTATUS DefaultPnpHandler(PDEVICE_EXTENSION pdx, PIRP Irp)//其他的小功能请求处理本设备的设备扩展{PAGED_CODE();KdPrint(("Enter DefaultPnpHandler\n"));IoSkipCurrentIrpStackLocation(Irp);//略过当前堆栈  进入下一层堆栈 不停的传下去KdPrint(("Leave DefaultPnpHandler\n"));return IoCallDriver(pdx->NextStackDevice, Irp);//用下层堆栈的驱动设备对象 处理此irp       例程发送一个IRP给指定设备对象关联的驱动程序。 真实设备}/************************************************************************* 函数名称:HandleRemoveDevice* 功能描述:对IRP_MN_REMOVE_DEVICE IRP进行处理* 参数列表:      fdo:功能设备对象      Irp:从IO请求包* 返回 值:返回状态*************************************************************************/#pragma PAGEDCODENTSTATUS HandleRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp)//自己定义的函数名  小功能函数 卸载函数{PAGED_CODE();KdPrint(("Enter HandleRemoveDevice\n"));Irp->IoStatus.Status = STATUS_SUCCESS;//设置irp的状态顺利完成NTSTATUS status = DefaultPnpHandler(pdx, Irp);//调用默认的pnp irp处理函数IoDeleteSymbolicLink(&(UNICODE_STRING)pdx->ustrSymLinkName);//删除此设备的符号连接    if (pdx->NextStackDevice)//有真实设备IoDetachDevice(pdx->NextStackDevice);  //调用IoDetachDevice()把fdo从设备栈中脱开:    IoDeleteDevice(pdx->fdo);//删除fdoKdPrint(("Leave HandleRemoveDevice\n"));return status;}/************************************************************************* 函数名称:HelloWDMPnp* 功能描述:对即插即用IRP进行处理* 参数列表:      fdo:功能设备对象      Irp:从IO请求包* 返回 值:返回状态*************************************************************************/#pragma PAGEDCODENTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,IN PIRP Irp)//对即插即用IRP进行处理  28个历程里的{PAGED_CODE();KdPrint(("Enter HelloWDMPnp\n"));NTSTATUS status = STATUS_SUCCESS;PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;//本驱动的设备的设备扩展信息 PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);//得到 IRP栈static NTSTATUS (*fcntab[])(PDEVICE_EXTENSION pdx, PIRP Irp) =    //指针数组  一个个函数指针{DefaultPnpHandler,// IRP_MN_START_DEVICEDefaultPnpHandler,// IRP_MN_QUERY_REMOVE_DEVICEHandleRemoveDevice,// IRP_MN_REMOVE_DEVICE       //自己定义的函数名DefaultPnpHandler,// IRP_MN_CANCEL_REMOVE_DEVICEDefaultPnpHandler,// IRP_MN_STOP_DEVICEDefaultPnpHandler,// IRP_MN_QUERY_STOP_DEVICEDefaultPnpHandler,// IRP_MN_CANCEL_STOP_DEVICEDefaultPnpHandler,// IRP_MN_QUERY_DEVICE_RELATIONSDefaultPnpHandler,// IRP_MN_QUERY_INTERFACEDefaultPnpHandler,// IRP_MN_QUERY_CAPABILITIESDefaultPnpHandler,// IRP_MN_QUERY_RESOURCESDefaultPnpHandler,// IRP_MN_QUERY_RESOURCE_REQUIREMENTSDefaultPnpHandler,// IRP_MN_QUERY_DEVICE_TEXTDefaultPnpHandler,// IRP_MN_FILTER_RESOURCE_REQUIREMENTSDefaultPnpHandler,// DefaultPnpHandler,// IRP_MN_READ_CONFIGDefaultPnpHandler,// IRP_MN_WRITE_CONFIGDefaultPnpHandler,// IRP_MN_EJECTDefaultPnpHandler,// IRP_MN_SET_LOCKDefaultPnpHandler,// IRP_MN_QUERY_IDDefaultPnpHandler,// IRP_MN_QUERY_PNP_DEVICE_STATEDefaultPnpHandler,// IRP_MN_QUERY_BUS_INFORMATIONDefaultPnpHandler,// IRP_MN_DEVICE_USAGE_NOTIFICATIONDefaultPnpHandler,// IRP_MN_SURPRISE_REMOVAL};ULONG fcn = stack->MinorFunction;//通过irp栈得到应用程序发来的pnp小功能编号if (fcn >= arraysize(fcntab))//其他小功能编号 处理掉{status = DefaultPnpHandler(pdx, Irp);//其他的IRP进行处理  不履行即插即用处理者  自己定义的函数名return status;}#if DBGstatic char* fcnname[] = {"IRP_MN_START_DEVICE","IRP_MN_QUERY_REMOVE_DEVICE","IRP_MN_REMOVE_DEVICE","IRP_MN_CANCEL_REMOVE_DEVICE","IRP_MN_STOP_DEVICE","IRP_MN_QUERY_STOP_DEVICE","IRP_MN_CANCEL_STOP_DEVICE","IRP_MN_QUERY_DEVICE_RELATIONS","IRP_MN_QUERY_INTERFACE","IRP_MN_QUERY_CAPABILITIES","IRP_MN_QUERY_RESOURCES","IRP_MN_QUERY_RESOURCE_REQUIREMENTS","IRP_MN_QUERY_DEVICE_TEXT","IRP_MN_FILTER_RESOURCE_REQUIREMENTS","","IRP_MN_READ_CONFIG","IRP_MN_WRITE_CONFIG","IRP_MN_EJECT","IRP_MN_SET_LOCK","IRP_MN_QUERY_ID","IRP_MN_QUERY_PNP_DEVICE_STATE","IRP_MN_QUERY_BUS_INFORMATION","IRP_MN_DEVICE_USAGE_NOTIFICATION","IRP_MN_SURPRISE_REMOVAL",};KdPrint(("PNP Request (%s)\n", fcnname[fcn]));//打印进来的小功能号名字#endif // DBGstatus = (*fcntab[fcn])(pdx, Irp);//自己定义的几个功能号 下发下去KdPrint(("进入李赛赛Leave HelloWDMPnp\n"));return status;}/************************************************************************* 函数名称:HelloWDMDispatchRoutine* 功能描述:对缺省IRP进行处理* 参数列表:      fdo:功能设备对象      Irp:从IO请求包* 返回 值:返回状态*************************************************************************/#pragma PAGEDCODENTSTATUS HelloWDMDispatchRoutine(IN PDEVICE_OBJECT fdo,IN PIRP Irp){PAGED_CODE();KdPrint(("Enter HelloWDMDispatchRoutine\n"));Irp->IoStatus.Status = STATUS_SUCCESS;Irp->IoStatus.Information = 0;// no bytes xferedIoCompleteRequest( Irp, IO_NO_INCREMENT );//io完成请求 不再传递下去KdPrint(("进入李赛赛Leave HelloWDMDispatchRoutine\n"));return STATUS_SUCCESS;}/************************************************************************* 函数名称:HelloWDMUnload* 功能描述:负责驱动程序的卸载操作* 参数列表:      DriverObject:驱动对象* 返回 值:返回状态*************************************************************************/#pragma PAGEDCODEvoid HelloWDMUnload(IN PDRIVER_OBJECT DriverObject){PAGED_CODE();KdPrint(("进入李赛赛 HelloWDMUnload\n"));KdPrint(("进入李赛赛HelloWDMUnload\n"));}//devcon.exe install HelloWDM.inf "HelloWDM"devcon.exe devcon - m:\\test find pci\*
;; The Win2K DDK documentation contains an excellent INF reference.;--------- Version Section ---------------------------------------------------[Version]Signature="$CHICAGO$"Provider=Zhangfan_DeviceDriverVer=11/1/2007,3.0.0.3; If device fits one of the standard classes, use the name and GUID here,; otherwise create your own device class and GUID as this example shows.Class=ZhangfanDeviceClassGUID={EF2962F0-0D55-4bff-B8AA-2221EE8A79B0};--------- SourceDiskNames and SourceDiskFiles Section -----------------------; These sections identify source disks and files for installation. They are; shown here as an example, but commented out.[SourceDisksNames]1 = "HelloWDM",Disk1,,[SourceDisksFiles]HelloWDM.sys = 1,MyDriver_Check,;--------- ClassInstall/ClassInstall32 Section -------------------------------; Not necessary if using a standard class; 9X Style[ClassInstall]Addreg=Class_AddReg; NT Style[ClassInstall32]Addreg=Class_AddReg[Class_AddReg]HKR,,,,%DeviceClassName%HKR,,Icon,,"-5";--------- DestinationDirs Section -------------------------------------------[DestinationDirs]YouMark_Files_Driver = 10,System32\Drivers;--------- Manufacturer and Models Sections ----------------------------------[Manufacturer]%MfgName%=Mfg0[Mfg0]; PCI hardware Ids use the form; PCI\VEN_aaaa&DEV_bbbb&SUBSYS_cccccccc&REV_dd;改成你自己的ID%DeviceDesc%=YouMark_DDI, PCI\VEN_9999&DEV_9999;---------- DDInstall Sections -----------------------------------------------; --------- Windows 9X -----------------; Experimentation has shown that DDInstall root names greater than 19 characters; cause problems in Windows 98[YouMark_DDI]CopyFiles=YouMark_Files_DriverAddReg=YouMark_9X_AddReg[YouMark_9X_AddReg]HKR,,DevLoader,,*ntkernHKR,,NTMPDriver,,HelloWDM.sysHKR, "Parameters", "BreakOnEntry", 0x00010001, 0; --------- Windows NT -----------------[YouMark_DDI.NT]CopyFiles=YouMark_Files_DriverAddReg=YouMark_NT_AddReg[YouMark_DDI.NT.Services]Addservice = HelloWDM, 0x00000002, YouMark_AddService[YouMark_AddService]DisplayName = %SvcDesc%ServiceType = 1 ; SERVICE_KERNEL_DRIVERStartType = 3 ; SERVICE_DEMAND_STARTErrorControl = 1 ; SERVICE_ERROR_NORMALServiceBinary = %10%\System32\Drivers\HelloWDM.sys[YouMark_NT_AddReg]HKLM, "System\CurrentControlSet\Services\HelloWDM\Parameters",\"BreakOnEntry", 0x00010001, 0; --------- Files (common) -------------[YouMark_Files_Driver]HelloWDM.sys;--------- Strings Section ---------------------------------------------------[Strings]ProviderName="Zhangfan."MfgName="Zhangfan Soft"DeviceDesc="Hello World WDM!"DeviceClassName="Zhangfan_Device"SvcDesc="Zhangfan"


原创粉丝点击