?? io.c
字號:
if (pIoPortWrite->sendBreak) {
/* get BREAK char */
dataChar.data.chr.type = RW_DATA_TYPE_CHR_BREAK;
dataChar.data.chr.chr = 0;
dataChar.data.chr.isChr = TRUE;
} else {
/* get XON or XOFF char */
switch (pIoPortWrite->sendXonXoff) {
case C0C_XCHAR_ON:
dataChar.data.chr.type = RW_DATA_TYPE_CHR_XCHR;
dataChar.data.chr.chr = pIoPortWrite->specialChars.XonChar;
dataChar.data.chr.isChr = TRUE;
break;
case C0C_XCHAR_OFF:
dataChar.data.chr.type = RW_DATA_TYPE_CHR_XCHR;
dataChar.data.chr.chr = pIoPortWrite->specialChars.XoffChar;
dataChar.data.chr.isChr = TRUE;
break;
default:
dataChar.data.chr.type = RW_DATA_TYPE_CHR_NONE;
dataChar.data.chr.isChr = FALSE;
}
}
/* get first pIrpWrite */
wasWrite = FALSE;
doneWrite = 0;
firstWrite = TRUE;
if(startWrite) {
dataIrpWrite.data.irp.pIrp = pQueueWrite->pCurrent;
pCancelRoutineWrite = NULL;
} else {
dataIrpWrite.data.irp.pIrp =
StartCurrentIrp(pQueueWrite, &pCancelRoutineWrite, &firstWrite);
}
/* read/write direct */
while (dataIrpRead.data.irp.pIrp) {
if (dataChar.data.chr.isChr) {
if (!pWriteLimit || *pWriteLimit) {
if (CAN_WRITE_RW_DATA_CHR(pIoPortWrite, dataChar)) {
if (dataIrpRead.data.irp.status == STATUS_PENDING) {
SIZE_T done = 0;
ReadWriteDirect(dataIrpRead.data.irp.pIrp,
&dataChar,
&dataIrpRead.data.irp.status,
pIoPortRead,
pQueueToComplete,
pWriteLimit,
&doneRead, &done);
if (done) {
if (pWriteDelay)
pWriteDelay->sentFrames += done;
}
}
}
else
if (pWriteDelay) {
pWriteDelay->sentFrames += *pWriteLimit;
*pWriteLimit = 0;
}
}
}
while (dataIrpWrite.data.irp.pIrp) {
if (IoGetCurrentIrpStackLocation(dataIrpWrite.data.irp.pIrp)->MajorFunction ==
IRP_MJ_FLUSH_BUFFERS)
{
dataIrpWrite.data.irp.status = STATUS_SUCCESS;
} else {
dataIrpWrite.data.irp.status = STATUS_PENDING;
if (!pWriteLimit || *pWriteLimit) {
if (!pIoPortWrite->writeHolding) {
if (dataIrpRead.data.irp.status == STATUS_PENDING) {
SIZE_T done = 0;
ReadWriteDirect(dataIrpRead.data.irp.pIrp,
&dataIrpWrite,
&dataIrpRead.data.irp.status,
pIoPortRead,
pQueueToComplete,
pWriteLimit,
&doneRead, &done);
if (done) {
doneWrite += done;
wasWrite = TRUE;
if (pWriteDelay)
pWriteDelay->sentFrames += done;
}
}
}
else
if (pWriteDelay) {
pWriteDelay->sentFrames += *pWriteLimit;
*pWriteLimit = 0;
}
}
}
if (dataIrpWrite.data.irp.status == STATUS_PENDING)
break;
if(startWrite && firstWrite) {
status = dataIrpWrite.data.irp.status;
ShiftQueue(pQueueWrite);
} else {
StopCurrentIrp(dataIrpWrite.data.irp.status, pCancelRoutineWrite, firstWrite,
doneWrite, pIoPortWrite, pQueueWrite, pQueueToComplete);
}
/* get next pIrpWrite */
doneWrite = 0;
firstWrite = FALSE;
dataIrpWrite.data.irp.pIrp =
StartCurrentIrp(pQueueWrite, &pCancelRoutineWrite, &firstWrite);
}
if (startRead && firstRead) {
if (dataIrpRead.data.irp.status == STATUS_PENDING)
dataIrpRead.data.irp.status =
SetIrpTimeout(pIoPortRead, dataIrpRead.data.irp.pIrp);
status = dataIrpRead.data.irp.status;
if (dataIrpRead.data.irp.status != STATUS_PENDING)
ShiftQueue(pQueueRead);
} else {
dataIrpRead.data.irp.status = StopCurrentIrp(
dataIrpRead.data.irp.status, pCancelRoutineRead, firstRead,
doneRead, pIoPortRead, pQueueRead, pQueueToComplete);
}
/* get next pIrpRead */
if (dataIrpRead.data.irp.status != STATUS_PENDING) {
dataIrpRead.data.irp.status = STATUS_PENDING;
doneRead = 0;
firstRead = FALSE;
dataIrpRead.data.irp.pIrp =
StartCurrentIrp(pQueueRead, &pCancelRoutineRead, &firstRead);
} else {
dataIrpRead.data.irp.pIrp = NULL;
}
}
/* write to buffer */
if (dataChar.data.chr.isChr) {
if (!pWriteLimit || *pWriteLimit) {
if (CAN_WRITE_RW_DATA_CHR(pIoPortWrite, dataChar)) {
SIZE_T done = 0;
WriteBuffer(&dataChar, pIoPortRead,
pQueueToComplete, pWriteLimit, &done);
readBufBusyEnd = C0C_BUFFER_BUSY(&pIoPortRead->readBuf);
if (readBufBusyBeg < readBufBusyEnd) {
if ((pIoPortRead->waitMask & SERIAL_EV_RX80FULL) &&
readBufBusyEnd > pIoPortRead->readBuf.size80 &&
readBufBusyBeg <= pIoPortRead->readBuf.size80)
{
pIoPortRead->eventMask |= SERIAL_EV_RX80FULL;
WaitComplete(pIoPortRead, pQueueToComplete);
}
UpdateHandFlow(pIoPortRead, FALSE, pQueueToComplete);
readBufBusyBeg = readBufBusyEnd;
}
if (pIoPortRead->emuOverrun &&
dataChar.data.chr.isChr &&
CAN_WRITE_RW_DATA_CHR(pIoPortWrite, dataChar) &&
C0C_BUFFER_BUSY(&pIoPortRead->readBuf) >= C0C_BUFFER_SIZE(&pIoPortRead->readBuf))
{
WriteOverrun(&dataChar, pIoPortRead,
pQueueToComplete, pWriteLimit, &done);
}
if (done) {
if (pWriteDelay)
pWriteDelay->sentFrames += done;
}
}
else
if (pWriteDelay) {
pWriteDelay->sentFrames += *pWriteLimit;
*pWriteLimit = 0;
}
}
}
if (!dataChar.data.chr.isChr) {
switch (dataChar.data.chr.type) {
case RW_DATA_TYPE_CHR_XCHR:
pIoPortWrite->sendXonXoff = 0;
break;
case RW_DATA_TYPE_CHR_BREAK:
if (pIoPortWrite->sendBreak) {
pIoPortWrite->sendBreak = FALSE;
if (pIoPortRead->escapeChar) {
UCHAR lsr = 0x10; /* break interrupt indicator */
if (!pIoPortRead->amountInWriteQueue || pIoPortRead->writeHolding)
lsr |= 0x60; /* transmit holding register empty and transmitter empty indicators */
InsertLsrMst(pIoPortRead, FALSE, lsr, pQueueToComplete);
}
if (pIoPortRead->handFlow.FlowReplace & SERIAL_BREAK_CHAR)
InsertChar(pIoPortRead, pIoPortRead->specialChars.BreakChar, pQueueToComplete);
}
break;
}
}
while (dataIrpWrite.data.irp.pIrp) {
if (IoGetCurrentIrpStackLocation(dataIrpWrite.data.irp.pIrp)->MajorFunction ==
IRP_MJ_FLUSH_BUFFERS)
{
dataIrpWrite.data.irp.status = STATUS_SUCCESS;
} else {
dataIrpWrite.data.irp.status = STATUS_PENDING;
if (!pWriteLimit || *pWriteLimit) {
if (!pIoPortWrite->writeHolding) {
SIZE_T done = 0;
WriteBuffer(&dataIrpWrite, pIoPortRead,
pQueueToComplete, pWriteLimit, &done);
readBufBusyEnd = C0C_BUFFER_BUSY(&pIoPortRead->readBuf);
if (readBufBusyBeg < readBufBusyEnd) {
if ((pIoPortRead->waitMask & SERIAL_EV_RX80FULL) &&
readBufBusyEnd > pIoPortRead->readBuf.size80 &&
readBufBusyBeg <= pIoPortRead->readBuf.size80)
{
pIoPortRead->eventMask |= SERIAL_EV_RX80FULL;
WaitComplete(pIoPortRead, pQueueToComplete);
}
UpdateHandFlow(pIoPortRead, FALSE, pQueueToComplete);
readBufBusyBeg = readBufBusyEnd;
}
if (pIoPortRead->emuOverrun &&
dataIrpWrite.data.irp.status == STATUS_PENDING &&
!pIoPortWrite->writeHolding &&
C0C_BUFFER_BUSY(&pIoPortRead->readBuf) >= C0C_BUFFER_SIZE(&pIoPortRead->readBuf))
{
WriteOverrun(&dataIrpWrite, pIoPortRead,
pQueueToComplete, pWriteLimit, &done);
}
if (done) {
doneWrite += done;
wasWrite = TRUE;
if (pWriteDelay)
pWriteDelay->sentFrames += done;
}
}
else
if (pWriteDelay) {
pWriteDelay->sentFrames += *pWriteLimit;
*pWriteLimit = 0;
}
}
}
if(startWrite && firstWrite) {
if (dataIrpWrite.data.irp.status == STATUS_PENDING)
dataIrpWrite.data.irp.status =
SetIrpTimeout(pIoPortWrite, dataIrpWrite.data.irp.pIrp);
status = dataIrpWrite.data.irp.status;
if (dataIrpWrite.data.irp.status != STATUS_PENDING)
ShiftQueue(pQueueWrite);
} else {
dataIrpWrite.data.irp.status =
StopCurrentIrp(dataIrpWrite.data.irp.status, pCancelRoutineWrite, firstWrite,
doneWrite, pIoPortWrite, pQueueWrite, pQueueToComplete);
}
/* get next pIrpWrite */
if (dataIrpWrite.data.irp.status != STATUS_PENDING) {
doneWrite = 0;
firstWrite = FALSE;
dataIrpWrite.data.irp.pIrp = StartCurrentIrp(pQueueWrite, &pCancelRoutineWrite, &firstWrite);
} else {
dataIrpWrite.data.irp.pIrp = NULL;
}
}
if (wasWrite && !pQueueWrite->pCurrent &&
pIoPortWrite->waitMask & SERIAL_EV_TXEMPTY)
{
pIoPortWrite->eventMask |= SERIAL_EV_TXEMPTY;
WaitComplete(pIoPortWrite, pQueueToComplete);
}
UpdateTransmitToggle(pIoPortWrite, pQueueToComplete);
return status;
}
NTSTATUS ReadWrite(
PC0C_IO_PORT pIoPortRead,
BOOLEAN startRead,
PC0C_IO_PORT pIoPortWrite,
BOOLEAN startWrite,
PLIST_ENTRY pQueueToComplete)
{
NTSTATUS status;
status = TryReadWrite(
pIoPortRead, startRead,
pIoPortWrite, startWrite,
pQueueToComplete);
pIoPortWrite->tryWrite = FALSE;
while (pIoPortRead->tryWrite) {
PC0C_IO_PORT pIoPortTmp;
pIoPortTmp = pIoPortRead;
pIoPortRead = pIoPortWrite;
pIoPortWrite = pIoPortTmp;
TryReadWrite(
pIoPortRead, FALSE,
pIoPortWrite, FALSE,
pQueueToComplete);
pIoPortWrite->tryWrite = FALSE;
if (status == STATUS_PENDING && (startRead || startWrite))
break;
}
return status;
}
VOID SetModemStatus(
IN PC0C_IO_PORT pIoPort,
IN ULONG bits,
IN ULONG mask,
PLIST_ENTRY pQueueToComplete)
{
ULONG modemStatusOld;
ULONG modemStatusChanged;
modemStatusOld = pIoPort->modemStatus;
pIoPort->modemStatus |= bits & mask;
pIoPort->modemStatus &= ~(~bits & mask);
/* DCD = DSR */
if (pIoPort->modemStatus & C0C_MSB_DSR)
pIoPort->modemStatus |= C0C_MSB_RLSD;
else
pIoPort->modemStatus &= ~C0C_MSB_RLSD;
modemStatusChanged = modemStatusOld ^ pIoPort->modemStatus;
if (modemStatusChanged) {
TraceModemStatus(pIoPort);
SetModemStatusHolding(pIoPort);
if (pIoPort->escapeChar)
InsertLsrMst(pIoPort, TRUE,
(UCHAR)(pIoPort->modemStatus | (modemStatusChanged >> 4)), pQueueToComplete);
if (modemStatusChanged & C0C_MSB_CTS)
pIoPort->eventMask |= pIoPort->waitMask & SERIAL_EV_CTS;
if (modemStatusChanged & C0C_MSB_DSR)
pIoPort->eventMask |= pIoPort->waitMask & SERIAL_EV_DSR;
if (modemStatusChanged & C0C_MSB_RING)
pIoPort->eventMask |= pIoPort->waitMask & SERIAL_EV_RING;
if (modemStatusChanged & C0C_MSB_RLSD)
pIoPort->eventMask |= pIoPort->waitMask & SERIAL_EV_RLSD;
WaitComplete(pIoPort, pQueueToComplete);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -