VOID TimeoutRoutine( PC0C_IO_PORT pIoPort, IN PC0C_IRP_QUEUE pQueue) { LIST_ENTRY queueToComplete; KIRQL oldIrql; InitializeListHead(&queueToComplete); KeAcquireSpinLock(pIoPort->pIoLock, &oldIrql); if (pQueue->pCurrent) { PC0C_IRP_STATE pState; pState = GetIrpState(pQueue->pCurrent); HALT_UNLESS(pState); pState->flags |= C0C_IRP_FLAG_EXPIRED; switch (pState->iQueue) { case C0C_QUEUE_WRITE: ReadWrite(pIoPort->pIoPortRemote, FALSE, pIoPort, FALSE, &queueToComplete); break; case C0C_QUEUE_READ: ReadWrite(pIoPort, FALSE, pIoPort->pIoPortRemote, FALSE, &queueToComplete); break; case C0C_QUEUE_CLOSE: FdoPortIo(C0C_IO_TYPE_CLOSE_COMPLETE, NULL, pIoPort, &pIoPort->irpQueues[C0C_QUEUE_CLOSE], &queueToComplete); break; } } KeReleaseSpinLock(pIoPort->pIoLock, oldIrql); FdoPortCompleteQueue(&queueToComplete); }
NTSTATUS FdoPortPnp( IN PC0C_FDOPORT_EXTENSION pDevExt, IN PIRP pIrp) { NTSTATUS status; PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp); ULONG minorFunction = pIrpStack->MinorFunction; PDEVICE_OBJECT pLowDevObj = pDevExt->pLowDevObj; // IRP_MN_REMOVE_DEVICE deletes *pDevExt! status = STATUS_SUCCESS; switch (minorFunction) { case IRP_MN_QUERY_DEVICE_RELATIONS: { LIST_ENTRY queueToComplete; KIRQL oldIrql; PC0C_IO_PORT pIoPort = pDevExt->pIoPortLocal; if ((pIoPort->exclusiveMode && pIoPort->isOpen) || (pIoPort->plugInMode && !pIoPort->pIoPortRemote->isOpen)) { HidePort(pDevExt); } else { ShowPort(pDevExt); } /* complete pending CLOSE IRPs */ InitializeListHead(&queueToComplete); KeAcquireSpinLock(pIoPort->pIoLock, &oldIrql); FdoPortIo(C0C_IO_TYPE_CLOSE_COMPLETE, NULL, pIoPort, &pIoPort->irpQueues[C0C_QUEUE_CLOSE], &queueToComplete); KeReleaseSpinLock(pIoPort->pIoLock, oldIrql); FdoPortCompleteQueue(&queueToComplete); break; } case IRP_MN_QUERY_REMOVE_DEVICE: if (pDevExt->openCount) status = STATUS_DEVICE_BUSY; else pIrp->IoStatus.Status = STATUS_SUCCESS; break; case IRP_MN_REMOVE_DEVICE: RemoveFdoPort(pDevExt); pDevExt = NULL; pIrp->IoStatus.Status = STATUS_SUCCESS; break; case IRP_MN_START_DEVICE: case IRP_MN_STOP_DEVICE: case IRP_MN_QUERY_STOP_DEVICE: case IRP_MN_CANCEL_STOP_DEVICE: case IRP_MN_SURPRISE_REMOVAL: pIrp->IoStatus.Status = STATUS_SUCCESS; break; } if (status == STATUS_SUCCESS) { IoSkipCurrentIrpStackLocation(pIrp); status = IoCallDriver(pLowDevObj, pIrp); TraceCode((PC0C_COMMON_EXTENSION)pDevExt, "PNP ", codeNameTablePnp, minorFunction, &status); } else { TraceIrp("PNP", pIrp, &status, TRACE_FLAG_RESULTS); pIrp->IoStatus.Status = status; IoCompleteRequest(pIrp, IO_NO_INCREMENT); } return status; }