NTSTATUS FdoPortImmediateChar( IN PC0C_IO_PORT pIoPort, IN PIRP pIrp, IN PIO_STACK_LOCATION pIrpStack) { if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(UCHAR)) return STATUS_BUFFER_TOO_SMALL; return FdoPortStartIrp(pIoPort, pIrp, C0C_QUEUE_WRITE, StartIrpWrite); }
NTSTATUS FdoPortXoffCounter( IN PC0C_IO_PORT pIoPort, IN PIRP pIrp, IN PIO_STACK_LOCATION pIrpStack) { PSERIAL_XOFF_COUNTER pXoffCounter; if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_XOFF_COUNTER)) return STATUS_BUFFER_TOO_SMALL; pXoffCounter = (PSERIAL_XOFF_COUNTER)pIrp->AssociatedIrp.SystemBuffer; if (pXoffCounter->Counter <= 0) return STATUS_INVALID_PARAMETER; return FdoPortStartIrp(pIoPort, pIrp, C0C_QUEUE_WRITE, StartIrpWrite); }
NTSTATUS FdoPortClose(IN PC0C_FDOPORT_EXTENSION pDevExt, IN PIRP pIrp) { NTSTATUS status; LIST_ENTRY queueToComplete; KIRQL oldIrql; PC0C_IO_PORT pIoPort; pIoPort = pDevExt->pIoPortLocal; pIoPort->isOpen = FALSE; if (pIoPort->pIoPortRemote->plugInMode) IoInvalidateDeviceRelations(pIoPort->pIoPortRemote->pPhDevObj, BusRelations); InitializeListHead(&queueToComplete); KeAcquireSpinLock(pIoPort->pIoLock, &oldIrql); pIoPort->escapeChar = 0; pIoPort->writeHoldingRemote = 0; pIoPort->sendXonXoff = 0; SetModemControl(pIoPort, C0C_MCR_OUT2, C0C_MCR_MASK | C0C_MCR_OPEN, &queueToComplete); FreeBuffer(&pIoPort->readBuf); SetBreakHolding(pIoPort, FALSE, &queueToComplete); KeReleaseSpinLock(pIoPort->pIoLock, oldIrql); FdoPortCompleteQueue(&queueToComplete); status = FdoPortStartIrp(pIoPort, pIrp, C0C_QUEUE_CLOSE, StartIrpClose); if (status != STATUS_PENDING) { pIrp->IoStatus.Status = status; IoCompleteRequest(pIrp, IO_NO_INCREMENT); } return status; }
NTSTATUS FdoPortWrite(IN PC0C_IO_PORT pIoPort, IN PIRP pIrp) { NTSTATUS status; pIrp->IoStatus.Information = 0; if ((pIoPort->handFlow.ControlHandShake & SERIAL_ERROR_ABORT) && pIoPort->errors) { status = STATUS_CANCELLED; } else { if (IoGetCurrentIrpStackLocation(pIrp)->MajorFunction == IRP_MJ_FLUSH_BUFFERS || IoGetCurrentIrpStackLocation(pIrp)->Parameters.Write.Length) status = FdoPortStartIrp(pIoPort, pIrp, C0C_QUEUE_WRITE, StartIrpWrite); else status = STATUS_SUCCESS; } if (status != STATUS_PENDING) { TraceIrp("FdoPortWrite", pIrp, &status, TRACE_FLAG_RESULTS); pIrp->IoStatus.Status = status; IoCompleteRequest(pIrp, IO_NO_INCREMENT); } return status; }