阅读:1392回复:1
为什么IoCopyCurrentIrpStackLocationToNext(Irp)与完成例程IoSetCompletionRoutine不能一起工作? 详见(键盘过滤)...我为《驱动程序模型设计》中第九章-过滤器驱动程序 添加一个“IRP_MJ_READ的完成例程” 目录 .\Chap9\FILTER //========================= NTSTATUS ReadComplete( IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN PDEVICE_EXTENSION pdx) { DebugPrintMsg("ReadComplete"); IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return Irp->IoStatus.Status; } //////////// NTSTATUS DispatchRead(IN PDEVICE_OBJECT fido, IN PIRP Irp) { // DispatchRead PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension; NTSTATUS status; status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if (!NT_SUCCESS(status)) { return CompleteRequest(Irp, status, 0); } DebugPrintMsg("DispatchRead"); IoSkipCurrentIrpStackLocation(Irp); //正常工作 // IoCopyCurrentIrpStackLocationToNext(Irp); // 不正常工作 IoSetCompletionRoutine( Irp, (PIO_COMPLETION_ROUTINE)ReadComplete, (PVOID)pdx, TRUE, TRUE, TRUE); status = IoCallDriver(pdx->LowerDeviceObject, Irp); // 不需要--在ReadComplete释放 // IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return status; } //===================== 可使用 IoCopyCurrentIrpStackLocationToNext(Irp); // 不正常工作 完成例程调用一次后,键盘驱动就好像死了,不管怎么按键都没反映 而 IoSkipCurrentIrpStackLocation(Irp); //可以正常工作--为什么 (可不能在完成例程中读数据) 以下全部DriverEntry.cpp的代码 --我使用了《WDM设备驱动程序开发指南》中的调试工具“DebugPrint” #pragma INITCODE extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { #if DBG DebugPrintInit("KbdFiter"); #else DebugPrintInit("KbdFiter"); #endif // Initialize function pointers DriverObject->DriverUnload = DriverUnload; DriverObject->DriverExtension->AddDevice = AddDevice; for (int i = 0; i < arraysize(DriverObject->MajorFunction); ++i) DriverObject->MajorFunction = DispatchAny; DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower; DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp; DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead; return STATUS_SUCCESS; } //////////////////// #pragma PAGEDCODE VOID DriverUnload(IN PDRIVER_OBJECT DriverObject) { PAGED_CODE(); DebugPrintClose(); } //////////////////// NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo) { // AddDevice PAGED_CODE(); NTSTATUS status; // Create a functional device object to represent the hardware we're managing. PDEVICE_OBJECT fdo; #define xsize sizeof(DEVICE_EXTENSION) status = IoCreateDevice(DriverObject, xsize, NULL, FILE_DEVICE_KEYBOARD, 0, FALSE, &fdo); if (!NT_SUCCESS(status)) { // can't create device object return status; } // can't create device object PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; //// IoInitializeRemoveLock(&pdx->RemoveLock, 0, 0, 0); PDEVICE_OBJECT ldo = IoAttachDeviceToDeviceStack(fdo, pdo); if (ldo==NULL) { status = STATUS_DEVICE_REMOVED; } pdx->LowerDeviceObject = ldo; fdo->Flags |= ldo->Flags & (DO_DIRECT_IO | DO_BUFFERED_IO | DO_POWER_PAGABLE | DO_POWER_INRUSH); fdo->Characteristics = ldo->Characteristics; fdo->Flags &= ~DO_DEVICE_INITIALIZING; return status; } //////////////////// #pragma LOCKEDCODE NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR info) { // CompleteRequest Irp->IoStatus.Status = status; Irp->IoStatus.Information = info; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } // CompleteRequest NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status) { // CompleteRequest Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } // CompleteRequest //////////////////// #pragma LOCKEDCODE // make no assumptions about pageability of dispatch fcns // NTSTATUS DispatchAny(IN PDEVICE_OBJECT fido, IN PIRP Irp) { // DispatchAny PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension; // Pass request down without additional processing KIRQL irql; NTSTATUS status; status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if (!NT_SUCCESS(status)) { return CompleteRequest(Irp, status, 0); } IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(pdx->LowerDeviceObject, Irp); IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return status; } // DispatchAny //////////// NTSTATUS ReadComplete( IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN PDEVICE_EXTENSION pdx) { DebugPrintMsg("ReadComplete"); IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return Irp->IoStatus.Status; } //////////// NTSTATUS DispatchRead(IN PDEVICE_OBJECT fido, IN PIRP Irp) { // DispatchRead PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension; NTSTATUS status; status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if (!NT_SUCCESS(status)) { return CompleteRequest(Irp, status, 0); } DebugPrintMsg("DispatchRead"); IoSkipCurrentIrpStackLocation(Irp); //正常工作 // IoCopyCurrentIrpStackLocationToNext(Irp); // 不正常工作 IoSetCompletionRoutine( Irp, (PIO_COMPLETION_ROUTINE)ReadComplete, (PVOID)pdx, TRUE, TRUE, TRUE); status = IoCallDriver(pdx->LowerDeviceObject, Irp); // 不需要--在ReadComplete释放 // IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return status; } // DispatchRead //////////////////// NTSTATUS DispatchPower(IN PDEVICE_OBJECT fido, IN PIRP Irp) { // DispatchPower PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension; PoStartNextPowerIrp(Irp); // must be done while we own the IRP NTSTATUS status; KIRQL irql; status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if (!NT_SUCCESS(status)) { return CompleteRequest(Irp, status, 0); } IoSkipCurrentIrpStackLocation(Irp); status = PoCallDriver(pdx->LowerDeviceObject, Irp); IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return status; } // DispatchPower //////////////////// NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fido, IN PIRP Irp) { // DispatchPnp PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); ULONG fcn = stack->MinorFunction; KIRQL irql; NTSTATUS status; PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension; status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if (!NT_SUCCESS(status)) { return CompleteRequest(Irp, status, 0); } IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(pdx->LowerDeviceObject, Irp); if (fcn == IRP_MN_REMOVE_DEVICE) { IoReleaseRemoveLockAndWait(&pdx->RemoveLock, Irp); RemoveDevice(fido); } else { IoReleaseRemoveLock(&pdx->RemoveLock, Irp); } return status; } // DispatchPnp //////////////////// #pragma PAGEDCODE VOID RemoveDevice(IN PDEVICE_OBJECT fdo) { // RemoveDevice PAGED_CODE(); PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; NTSTATUS status; if (pdx->LowerDeviceObject!=NULL) IoDetachDevice(pdx->LowerDeviceObject); IoDeleteDevice(fdo); } // RemoveDevice |
|
沙发#
发布于:2004-10-11 11:35
你先试试取消
IoAcquireRemoveLock IoReleaseRemoveLock 这两个函数的调用,会不会出现上述的现象。 |
|