为什么wdm驱动加载后自动卸载并继续加载
刚看书上wdm驱动的介绍,自己动手写了个wdm驱动,本以为编译成功便完事,没想到winxp上一加载,就自己卸载,并继续加载,并循环下去,看了半天,不得解,求帮助~~。下面是代码,主要是参考张帆的windows驱动详解:
#ifdef __cplusplus extern "C"{ #endif #include <wdm.h> #ifdef __cplusplus } #endif #define arraysize(p) (sizeof(p)/sizeof((p)[0])) typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT fdo; PDEVICE_OBJECT NextStackDevice; UNICODE_STRING ustrDeviceName;//设备名 UNICODE_STRING ustrSymLinkName;//符号链接名 }DEVICE_EXTENSION,*PDEVICE_EXTENSION; void HelloWDMUnload(PDRIVER_OBJECT DriverObject); NTSTATUS HelloWDMDispatchRoutine(PDEVICE_OBJECT fdo,PIRP Irp); NTSTATUS DefaultPnpHandler(PDEVICE_EXTENSION pdx, PIRP Irp); NTSTATUS HandleRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp); NTSTATUS HelloWDMPnp(PDEVICE_OBJECT fdo, PIRP Irp); NTSTATUS HelloWDMAddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT PhysicalDeviceObject); #pragma code_seg("INIT") extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pRegistryPath) { _asm int 3 NTSTATUS status; KdPrint(("Enter DriverEntry\n")); pDriverObject -> DriverExtension->AddDevice = HelloWDMAddDevice; pDriverObject ->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp; pDriverObject ->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HelloWDMDispatchRoutine; pDriverObject ->MajorFunction[IRP_MJ_CREATE] = HelloWDMDispatchRoutine; pDriverObject ->MajorFunction[IRP_MJ_READ] = HelloWDMDispatchRoutine; pDriverObject ->MajorFunction[IRP_MJ_WRITE] = HelloWDMDispatchRoutine; pDriverObject->DriverUnload = HelloWDMUnload; KdPrint(("DriverEntry end\n")); return status; } NTSTATUS HelloWDMDispatchRoutine(PDEVICE_OBJECT fdo,PIRP Irp) { PAGED_CODE(); KdPrint(("Enter HelloWDMDispatchRoutine\n")); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp,IO_NO_INCREMENT); KdPrint(("Leave HelloWDMDispatchRoutine\n")); return STATUS_SUCCESS; } #pragma code_seg("PAGE") NTSTATUS HelloWDMAddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT PhysicalDeviceObject) { 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);//挂接在设备堆栈上,返回下层堆栈位置 UNICODE_STRING symLinkName; RtlInitUnicodeString(&symLinkName,L"\\DosDevice\\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; } #pragma code_seg("PAGE") NTSTATUS HelloWDMPnp(PDEVICE_OBJECT fdo, PIRP Irp) { PAGED_CODE();//该宏保证该例程运行在低于APC_LEVEL的中断优先级的级别上 KdPrint(("Enter HelloWDMPnp\n")); NTSTATUS status = STATUS_SUCCESS; PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); static NTSTATUS (*fcntab[])(PDEVICE_EXTENSION pdx,PIRP Irp) = { DefaultPnpHandler, // IRP_MN_START_DEVICE DefaultPnpHandler, // IRP_MN_QUERY_REMOVE_DEVICE HandleRemoveDevice, // IRP_MN_REMOVE_DEVICE DefaultPnpHandler, // IRP_MN_CANCEL_REMOVE_DEVICE DefaultPnpHandler, // IRP_MN_STOP_DEVICE DefaultPnpHandler, // IRP_MN_QUERY_STOP_DEVICE DefaultPnpHandler, // IRP_MN_CANCEL_STOP_DEVICE DefaultPnpHandler, // IRP_MN_QUERY_DEVICE_RELATIONS DefaultPnpHandler, // IRP_MN_QUERY_INTERFACE DefaultPnpHandler, // IRP_MN_QUERY_CAPABILITIES DefaultPnpHandler, // IRP_MN_QUERY_RESOURCES DefaultPnpHandler, // IRP_MN_QUERY_RESOURCE_REQUIREMENTS DefaultPnpHandler, // IRP_MN_QUERY_DEVICE_TEXT DefaultPnpHandler, // IRP_MN_FILTER_RESOURCE_REQUIREMENTS DefaultPnpHandler, // DefaultPnpHandler, // IRP_MN_READ_CONFIG DefaultPnpHandler, // IRP_MN_WRITE_CONFIG DefaultPnpHandler, // IRP_MN_EJECT DefaultPnpHandler, // IRP_MN_SET_LOCK DefaultPnpHandler, // IRP_MN_QUERY_ID DefaultPnpHandler, // IRP_MN_QUERY_PNP_DEVICE_STATE DefaultPnpHandler, // IRP_MN_QUERY_BUS_INFORMATION DefaultPnpHandler, // IRP_MN_DEVICE_USAGE_NOTIFICATION DefaultPnpHandler, // IRP_MN_SURPRISE_REMOVAL }; ULONG fcn = stack->MinorFunction; if(fcn >= arraysize(fcntab)) { //未知的IRP类别 status = DefaultPnpHandler(pdx,Irp);//对于未知的IRP类别,我们让DefaultPnpHandler函数处理 return status; } status = (*fcntab[fcn])(pdx,Irp);//根据pnp功能号调用函数指针 KdPrint(("Leave HelloWDMPnp\n")); return status; } #pragma code_seg("PAGE") NTSTATUS DefaultPnpHandler(PDEVICE_EXTENSION pdx, PIRP Irp) { PAGED_CODE(); KdPrint(("Enter DefaultPnpHandler\n")); IoSkipCurrentIrpStackLocation(Irp);//忽略当前堆栈 KdPrint(("Leave DefaultPnpHandler\n")); return IoCallDriver(pdx->NextStackDevice,Irp);//用下层堆栈的驱动设备对象处理此IRP } #pragma code_seg("PAGE") NTSTATUS HandleRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp) { PAGED_CODE(); KdPrint(("Enter HandleRemoveDevice\n")); Irp->IoStatus.Status = STATUS_SUCCESS; NTSTATUS status = DefaultPnpHandler(pdx,Irp); IoDeleteSymbolicLink(&(UNICODE_STRING)pdx->ustrSymLinkName); //调用IoDetachDevice()把fdo从设备栈中脱开 if(pdx->NextStackDevice) IoDetachDevice(pdx->NextStackDevice); //删除fdo IoDeleteDevice(pdx->fdo); KdPrint(("Leave HandleRemoveDevice\n")); return status; } #pragma code_seg("PAGE") void HelloWDMUnload(PDRIVER_OBJECT DriverObject) { PAGED_CODE(); KdPrint(("Enter HelloWDMUnload\n")); KdPrint(("Leave HelloWDMUnload\n")); } inf文件: /************************************************************************ * 文件名称:wdm_aaaa,inf *************************************************************************/;; The Win2K DDK documentation contains an excellent INF reference. ;--------- Version Section --------------------------------------------------- [Version] Signature="$CHICAGO$"Provider=Guzy_Device DriverVer=11/10/2012,1.0.0.0 ; 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=GuzyDevice ClassGUID={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 = "wdm_aaaa",Disk1,, [SourceDisksFiles] wdm_aaaa.sys = 1,, ;--------- 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_Driver AddReg=YouMark_9X_AddReg [YouMark_9X_AddReg] HKR,,DevLoader,,*ntkern HKR,,NTMPDriver,,wdm_aaaa.sys HKR, "Parameters", "BreakOnEntry", 0x00010001, 0 ; --------- Windows NT ----------------- [YouMark_DDI.NT] CopyFiles=YouMark_Files_Driver AddReg=YouMark_NT_AddReg [YouMark_DDI.NT.Services] Addservice = wdm_aaaa, 0x00000002, YouMark_AddService [YouMark_AddService] DisplayName = %SvcDesc% ServiceType = 1 ; SERVICE_KERNEL_DRIVER StartType = 3 ; SERVICE_DEMAND_START ErrorControl = 1 ; SERVICE_ERROR_NORMAL ServiceBinary = %10%\System32\Drivers\wdm_aaaa.sys [YouMark_NT_AddReg] HKLM, "System\CurrentControlSet\Services\wdm_aaaa\Parameters",\ "BreakOnEntry", 0x00010001, 0 ; --------- Files (common) ------------- [YouMark_Files_Driver] wdm_aaaa.sys ;--------- Strings Section --------------------------------------------------- [Strings] ProviderName="Guzy."MfgName="Guzy Soft"DeviceDesc="Hello World WDM!"DeviceClassName="Guzy_Device"SvcDesc="Guzy"
设备是PCI设备PCI\VEN_9999&DEV_9999,属于真正的PNP设备。
系统在加载你驱动之后,会调用一系列的IRP_MJ_PNP IRP。
很可能是你的HelloWDMPnp处理例程写得太简单了。