阅读:987回复:1
一个关于STATUS――PENDING的问题,请高手指点
请参考以下代码:
我的问题是: 1。请问当请求发送当低级驱动后的执行流程是什么?(请以例子进行说明) 2。当请求发送到低级驱动程序之后,当它返回STATUS_PENDING之后,完成例程要调用IoMarkIrpPending(Irp),后面的KeSetEvent会不会被调用。如果KeSetEvent被调用,那么将使事件变为信号态,则将会杰出GpdDispatchPnp中的KeWaitForSingleObject的等待,按理STATUS_PENDING中线程应该在这个事件上等待呀,这样解除了有什么用呢? NTSTATUS GpdCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) /*++ Routine Description: The completion routine for plug & play irps that needs to be processed first by the lower drivers. Arguments: DeviceObject - pointer to a device object. Irp - pointer to an I/O Request Packet. Context - pointer to an event object. Return Value: NT status code --*/ { PKEVENT event; event = (PKEVENT) Context; UNREFERENCED_PARAMETER(DeviceObject); if (Irp->PendingReturned) { IoMarkIrpPending(Irp); } // // We could switch on the major and minor functions of the IRP to perform // different functions, but we know that Context is an event that needs // to be set. // KeSetEvent(event, 0, FALSE); // // Allows the caller to reuse the IRP // return STATUS_MORE_PROCESSING_REQUIRED; } NTSTATUS GpdDispatchPnp ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: The plug and play dispatch routines. Most of these the driver will completely ignore. In all cases it must pass the IRP to the next lower driver. Arguments: DeviceObject - pointer to a device object. Irp - pointer to an I/O Request Packet. Return Value: NT status code --*/ { PIO_STACK_LOCATION irpStack; NTSTATUS status = STATUS_SUCCESS; KEVENT event; UNICODE_STRING win32DeviceName; PLOCAL_DEVICE_INFO deviceInfo; PAGED_CODE(); deviceInfo = (PLOCAL_DEVICE_INFO) DeviceObject->DeviceExtension; irpStack = IoGetCurrentIrpStackLocation(Irp); status = IoAcquireRemoveLock (&deviceInfo->RemoveLock, NULL); if (!NT_SUCCESS (status)) { Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; } DebugPrint(("%s\n",PnPMinorFunctionString(irpStack->MinorFunction))); switch (irpStack->MinorFunction) { case IRP_MN_START_DEVICE: // // The device is starting. // // We cannot touch the device (send it any non pnp irps) until a // start device has been passed down to the lower drivers. // IoCopyCurrentIrpStackLocationToNext(Irp); KeInitializeEvent(&event, NotificationEvent, FALSE ); IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) GpdCompletionRoutine, &event, TRUE, TRUE, TRUE); status = IoCallDriver(deviceInfo->NextLowerDriver, Irp); if (STATUS_PENDING == status) { KeWaitForSingleObject( &event, Executive, // Waiting for reason of a driver KernelMode, // Must be kernelmode if event memory is in stack FALSE, // No allert NULL); // No timeout } if (NT_SUCCESS(status) && NT_SUCCESS(Irp->IoStatus.Status)) { status = GpdStartDevice(DeviceObject, Irp); if(NT_SUCCESS(status)) { // // As we are successfully now back from our start device // we can do work. // deviceInfo->Started = TRUE; deviceInfo->Removed = FALSE; } } // // We must now complete the IRP, since we stopped it in the // completion routine with STATUS_MORE_PROCESSING_REQUIRED. // Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); break; |
|
沙发#
发布于:2004-10-18 14:46
顶一下
|
|