From: Vyacheslav F. <vf...@us...> - 2005-05-13 16:58:13
|
Update of /cvsroot/com0com/com0com In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21179 Modified Files: trace.c openclos.c ioctl.c io.c com0com.h Log Message: Implemented IOCTL_SERIAL_LSRMST_INSERT Index: io.c =================================================================== RCS file: /cvsroot/com0com/com0com/io.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** io.c 13 May 2005 06:32:16 -0000 1.3 --- io.c 13 May 2005 16:58:03 -0000 1.4 *************** *** 20,23 **** --- 20,26 ---- * * $Log$ + * Revision 1.4 2005/05/13 16:58:03 vfrolov + * Implemented IOCTL_SERIAL_LSRMST_INSERT + * * Revision 1.3 2005/05/13 06:32:16 vfrolov * Implemented SERIAL_EV_RXCHAR *************** *** 43,49 **** PIO_STACK_LOCATION pIrpStack; - if (!pBuf->pBase) - return STATUS_PENDING; - status = STATUS_PENDING; pIrpStack = IoGetCurrentIrpStackLocation(pIrp); --- 46,49 ---- *************** *** 51,55 **** for (;;) { ULONG length, writeLength, readLength; ! PVOID pWriteBuf, pReadBuf; readLength = pIrpStack->Parameters.Read.Length - pIrp->IoStatus.Information; --- 51,55 ---- for (;;) { ULONG length, writeLength, readLength; ! PUCHAR pWriteBuf, pReadBuf; readLength = pIrpStack->Parameters.Read.Length - pIrp->IoStatus.Information; *************** *** 60,70 **** } ! if (!pBuf->busy) break; writeLength = pBuf->pFree <= pBuf->pBusy ? pBuf->pEnd - pBuf->pBusy : pBuf->busy; - pReadBuf = GET_REST_BUFFER(pIrp); pWriteBuf = pBuf->pBusy; --- 60,82 ---- } ! pReadBuf = GET_REST_BUFFER(pIrp); ! ! if (!pBuf->busy) { ! if (pBuf->escape) { ! pBuf->escape = FALSE; ! *pReadBuf++ = SERIAL_LSRMST_ESCAPE; ! pIrp->IoStatus.Information++; ! readLength--; ! if (!readLength) ! status = STATUS_SUCCESS; ! } break; + } + + ASSERT(pBuf->pBase); writeLength = pBuf->pFree <= pBuf->pBusy ? pBuf->pEnd - pBuf->pBusy : pBuf->busy; pWriteBuf = pBuf->pBusy; *************** *** 92,95 **** --- 104,165 ---- } + VOID CopyCharsWithEscape( + PC0C_IO_PORT pReadIoPort, + PUCHAR pReadBuf, ULONG readLength, + PUCHAR pWriteBuf, ULONG writeLength, + PULONG pReadDone, + PULONG pWriteDone) + { + ULONG readDone; + ULONG writeDone; + UCHAR escapeChar; + + readDone = 0; + + if (pReadIoPort->readBuf.escape && readLength) { + pReadIoPort->readBuf.escape = FALSE; + *pReadBuf++ = SERIAL_LSRMST_ESCAPE; + readDone++; + readLength--; + } + + escapeChar = pReadIoPort->escapeChar; + + if (!escapeChar) { + writeDone = writeLength < readLength ? writeLength : readLength; + + if (writeDone) + RtlCopyMemory(pReadBuf, pWriteBuf, writeDone); + + readDone += writeDone; + } else { + writeDone = 0; + + while (writeLength--) { + UCHAR curChar; + + if (!readLength--) + break; + + curChar = *pWriteBuf++; + writeDone++; + *pReadBuf++ = curChar; + readDone++; + + if (curChar == escapeChar) { + if (!readLength--) { + pReadIoPort->readBuf.escape = TRUE; + break; + } + *pReadBuf++ = SERIAL_LSRMST_ESCAPE; + readDone++; + } + } + } + + *pReadDone = readDone; + *pWriteDone = writeDone; + } + NTSTATUS WriteBuffer(PIRP pIrp, PC0C_IO_PORT pReadIoPort, PLIST_ENTRY pQueueToComplete) { *************** *** 105,110 **** for (;;) { ! ULONG length, writeLength, readLength; PVOID pWriteBuf, pReadBuf; writeLength = pIrpStack->Parameters.Write.Length - pIrp->IoStatus.Information; --- 175,181 ---- for (;;) { ! ULONG writeLength, readLength; PVOID pWriteBuf, pReadBuf; + ULONG readDone, writeDone; writeLength = pIrpStack->Parameters.Write.Length - pIrp->IoStatus.Information; *************** *** 124,139 **** pReadBuf = pBuf->pFree; ! length = writeLength < readLength ? writeLength : readLength; ! ! RtlCopyMemory(pReadBuf, pWriteBuf, length); ! pBuf->busy += length; ! pBuf->pFree += length; if (pBuf->pFree == pBuf->pEnd) pBuf->pFree = pBuf->pBase; ! pIrp->IoStatus.Information += length; ! WaitCompleteRxChar(pReadIoPort, pQueueToComplete); } --- 195,213 ---- pReadBuf = pBuf->pFree; ! CopyCharsWithEscape( ! pReadIoPort, ! pReadBuf, readLength, ! pWriteBuf, writeLength, ! &readDone, &writeDone); ! pBuf->busy += readDone; ! pBuf->pFree += readDone; if (pBuf->pFree == pBuf->pEnd) pBuf->pFree = pBuf->pBase; ! pIrp->IoStatus.Information += writeDone; ! if (writeDone) ! WaitCompleteRxChar(pReadIoPort, pQueueToComplete); } *************** *** 146,193 **** PNTSTATUS pStatusLocal, PNTSTATUS pStatusRemote, ! PC0C_IO_PORT pIoPortLocal, PLIST_ENTRY pQueueToComplete) { - PIO_STACK_LOCATION pIrpStackLocal; - PIO_STACK_LOCATION pIrpStackRemote; - ULONG length, writeLength, readLength; - PVOID pWriteBuf, pReadBuf; PC0C_IO_PORT pReadIoPort; ! pIrpStackLocal = IoGetCurrentIrpStackLocation(pIrpLocal); ! pIrpStackRemote = IoGetCurrentIrpStackLocation(pIrpRemote); ! if (pIrpStackLocal->MajorFunction == IRP_MJ_WRITE) { ! pWriteBuf = GET_REST_BUFFER(pIrpLocal); ! writeLength = pIrpStackLocal->Parameters.Write.Length - pIrpLocal->IoStatus.Information; ! pReadBuf = GET_REST_BUFFER(pIrpRemote); ! readLength = pIrpStackRemote->Parameters.Read.Length - pIrpRemote->IoStatus.Information; ! pReadIoPort = pIoPortLocal->pDevExt->pIoPortRemote; ! if (writeLength <= readLength) ! *pStatusLocal = STATUS_SUCCESS; ! if (writeLength >= readLength) ! *pStatusRemote = STATUS_SUCCESS; ! } else { ! pReadBuf = GET_REST_BUFFER(pIrpLocal); ! readLength = pIrpStackLocal->Parameters.Read.Length - pIrpLocal->IoStatus.Information; ! pWriteBuf = GET_REST_BUFFER(pIrpRemote); ! writeLength = pIrpStackRemote->Parameters.Write.Length - pIrpRemote->IoStatus.Information; ! pReadIoPort = pIoPortLocal; ! if (readLength <= writeLength) ! *pStatusLocal = STATUS_SUCCESS; ! if (readLength >= writeLength) ! *pStatusRemote = STATUS_SUCCESS; ! } ! length = writeLength < readLength ? writeLength : readLength; ! if (length) { ! RtlCopyMemory(pReadBuf, pWriteBuf, length); ! pIrpRemote->IoStatus.Information += length; ! pIrpLocal->IoStatus.Information += length; WaitCompleteRxChar(pReadIoPort, pQueueToComplete); - } } --- 220,270 ---- PNTSTATUS pStatusLocal, PNTSTATUS pStatusRemote, ! PC0C_IO_PORT pIoPortRemote, PLIST_ENTRY pQueueToComplete) { PC0C_IO_PORT pReadIoPort; + ULONG readDone, writeDone; + PIRP pIrpRead, pIrpWrite; + PNTSTATUS pStatusRead, pStatusWrite; + ULONG writeLength, readLength; + PVOID pWriteBuf, pReadBuf; ! if (IoGetCurrentIrpStackLocation(pIrpLocal)->MajorFunction == IRP_MJ_WRITE) { ! pIrpRead = pIrpRemote; ! pIrpWrite = pIrpLocal; ! pStatusRead = pStatusRemote; ! pStatusWrite = pStatusLocal; ! pReadIoPort = pIoPortRemote; ! } else { ! pIrpRead = pIrpLocal; ! pIrpWrite = pIrpRemote; ! pStatusRead = pStatusLocal; ! pStatusWrite = pStatusRemote; ! pReadIoPort = pIoPortRemote->pDevExt->pIoPortRemote; ! } ! pReadBuf = GET_REST_BUFFER(pIrpRead); ! readLength = IoGetCurrentIrpStackLocation(pIrpRead)->Parameters.Read.Length ! - pIrpRemote->IoStatus.Information; ! pWriteBuf = GET_REST_BUFFER(pIrpWrite); ! writeLength = IoGetCurrentIrpStackLocation(pIrpWrite)->Parameters.Write.Length ! - pIrpWrite->IoStatus.Information; ! CopyCharsWithEscape( ! pReadIoPort, ! pReadBuf, readLength, ! pWriteBuf, writeLength, ! &readDone, &writeDone); ! pIrpRead->IoStatus.Information += readDone; ! pIrpWrite->IoStatus.Information += writeDone; ! if (readDone == readLength) ! *pStatusRead = STATUS_SUCCESS; ! if (writeDone == writeLength) ! *pStatusWrite = STATUS_SUCCESS; ! if (writeDone) WaitCompleteRxChar(pReadIoPort, pQueueToComplete); } Index: openclos.c =================================================================== RCS file: /cvsroot/com0com/com0com/openclos.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** openclos.c 1 Feb 2005 16:51:51 -0000 1.3 --- openclos.c 13 May 2005 16:58:03 -0000 1.4 *************** *** 20,23 **** --- 20,26 ---- * * $Log$ + * Revision 1.4 2005/05/13 16:58:03 vfrolov + * Implemented IOCTL_SERIAL_LSRMST_INSERT + * * Revision 1.3 2005/02/01 16:51:51 vfrolov * Used C0C_BUFFER_PURGE() *************** *** 79,82 **** --- 82,86 ---- pDevExt->pIoPortLocal->waitMask = 0; pDevExt->pIoPortLocal->eventMask = 0; + pDevExt->pIoPortLocal->escapeChar = 0; UpdateHandFlow(pDevExt, &queueToComplete); Index: ioctl.c =================================================================== RCS file: /cvsroot/com0com/com0com/ioctl.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ioctl.c 1 Feb 2005 16:47:57 -0000 1.2 --- ioctl.c 13 May 2005 16:58:03 -0000 1.3 *************** *** 20,23 **** --- 20,26 ---- * * $Log$ + * Revision 1.3 2005/05/13 16:58:03 vfrolov + * Implemented IOCTL_SERIAL_LSRMST_INSERT + * * Revision 1.2 2005/02/01 16:47:57 vfrolov * Implemented SERIAL_PURGE_RXCLEAR and IOCTL_SERIAL_GET_COMMSTATUS *************** *** 196,201 **** KeAcquireSpinLock(pDevExt->pIoLock, &oldIrql); ! pDevExt->handFlow = *pSysBuf; ! UpdateHandFlow(pDevExt, &queueToComplete); KeReleaseSpinLock(pDevExt->pIoLock, oldIrql); --- 199,211 ---- KeAcquireSpinLock(pDevExt->pIoLock, &oldIrql); ! if (pDevExt->pIoPortLocal->escapeChar && ! (pSysBuf->FlowReplace & SERIAL_ERROR_CHAR)) { ! status = STATUS_INVALID_PARAMETER; ! } ! ! if (status == STATUS_SUCCESS) { ! pDevExt->handFlow = *pSysBuf; ! UpdateHandFlow(pDevExt, &queueToComplete); ! } KeReleaseSpinLock(pDevExt->pIoLock, oldIrql); *************** *** 223,227 **** TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS); break; ! case IOCTL_SERIAL_SET_CHARS: if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_CHARS)) { status = STATUS_BUFFER_TOO_SMALL; --- 233,239 ---- TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS); break; ! case IOCTL_SERIAL_SET_CHARS: { ! PSERIAL_CHARS pSysBuf; ! if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_CHARS)) { status = STATUS_BUFFER_TOO_SMALL; *************** *** 229,236 **** } ! KeAcquireSpinLock(&pDevExt->controlLock, &oldIrql); ! pDevExt->specialChars = *(PSERIAL_CHARS)pIrp->AssociatedIrp.SystemBuffer; ! KeReleaseSpinLock(&pDevExt->controlLock, oldIrql); break; case IOCTL_SERIAL_GET_CHARS: if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_CHARS)) { --- 241,261 ---- } ! pSysBuf = (PSERIAL_CHARS)pIrp->AssociatedIrp.SystemBuffer; ! ! KeAcquireSpinLock(pDevExt->pIoLock, &oldIrql); ! ! if (pDevExt->pIoPortLocal->escapeChar && ! ((pDevExt->pIoPortLocal->escapeChar == pSysBuf->XoffChar) || ! (pDevExt->pIoPortLocal->escapeChar == pSysBuf->XonChar))) ! { ! status = STATUS_INVALID_PARAMETER; ! } ! ! if (status == STATUS_SUCCESS) ! pDevExt->specialChars = *pSysBuf; ! ! KeReleaseSpinLock(pDevExt->pIoLock, oldIrql); break; + } case IOCTL_SERIAL_GET_CHARS: if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_CHARS)) { *************** *** 239,245 **** } ! KeAcquireSpinLock(&pDevExt->controlLock, &oldIrql); *(PSERIAL_CHARS)pIrp->AssociatedIrp.SystemBuffer = pDevExt->specialChars; ! KeReleaseSpinLock(&pDevExt->controlLock, oldIrql); pIrp->IoStatus.Information = sizeof(SERIAL_CHARS); --- 264,270 ---- } ! KeAcquireSpinLock(pDevExt->pIoLock, &oldIrql); *(PSERIAL_CHARS)pIrp->AssociatedIrp.SystemBuffer = pDevExt->specialChars; ! KeReleaseSpinLock(pDevExt->pIoLock, oldIrql); pIrp->IoStatus.Information = sizeof(SERIAL_CHARS); *************** *** 247,250 **** --- 272,302 ---- TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS); break; + case IOCTL_SERIAL_LSRMST_INSERT: { + UCHAR escapeChar; + + if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(UCHAR)) { + status = STATUS_BUFFER_TOO_SMALL; + break; + } + + escapeChar = *(PUCHAR)pIrp->AssociatedIrp.SystemBuffer; + + KeAcquireSpinLock(pDevExt->pIoLock, &oldIrql); + + if (escapeChar && ((escapeChar == pDevExt->specialChars.XoffChar) || + (escapeChar == pDevExt->specialChars.XonChar) || + (pDevExt->handFlow.FlowReplace & SERIAL_ERROR_CHAR))) + { + status = STATUS_INVALID_PARAMETER; + } + + if (status == STATUS_SUCCESS) { + pDevExt->pIoPortLocal->escapeChar = escapeChar; + pIrp->IoStatus.Information = sizeof(UCHAR); + } + + KeReleaseSpinLock(pDevExt->pIoLock, oldIrql); + break; + } case IOCTL_SERIAL_SET_LINE_CONTROL: if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_LINE_CONTROL)) { Index: trace.c =================================================================== RCS file: /cvsroot/com0com/com0com/trace.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** trace.c 28 Feb 2005 12:10:08 -0000 1.3 --- trace.c 13 May 2005 16:58:03 -0000 1.4 *************** *** 20,23 **** --- 20,26 ---- * * $Log$ + * Revision 1.4 2005/05/13 16:58:03 vfrolov + * Implemented IOCTL_SERIAL_LSRMST_INSERT + * * Revision 1.3 2005/02/28 12:10:08 vfrolov * Log skipped lines to trace file (was to syslog) *************** *** 1173,1176 **** --- 1176,1183 ---- pDestStr = AnsiStrCopyCommStatus(pDestStr, &size, (PSERIAL_STATUS)pSysBuf); break; + case IOCTL_SERIAL_LSRMST_INSERT: + if ((flags & TRACE_FLAG_PARAMS) && inLength >= sizeof(UCHAR)) + pDestStr = AnsiStrFormat(pDestStr, &size, " escapeChar=0x%02X", (int)(*(PUCHAR)pSysBuf & 0xFF)); + break; } break; Index: com0com.h =================================================================== RCS file: /cvsroot/com0com/com0com/com0com.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** com0com.h 12 May 2005 07:41:27 -0000 1.4 --- com0com.h 13 May 2005 16:58:03 -0000 1.5 *************** *** 20,23 **** --- 20,26 ---- * * $Log$ + * Revision 1.5 2005/05/13 16:58:03 vfrolov + * Implemented IOCTL_SERIAL_LSRMST_INSERT + * * Revision 1.4 2005/05/12 07:41:27 vfrolov * Added ability to change the port names *************** *** 85,93 **** PUCHAR pEnd; ULONG busy; } C0C_BUFFER, *PC0C_BUFFER; #define C0C_BUFFER_PURGE(buf) \ (buf).pFree = (buf).pBusy = (buf).pBase; \ ! (buf).busy = 0 struct _C0C_FDOPORT_EXTENSION; --- 88,98 ---- PUCHAR pEnd; ULONG busy; + BOOLEAN escape; } C0C_BUFFER, *PC0C_BUFFER; #define C0C_BUFFER_PURGE(buf) \ (buf).pFree = (buf).pBusy = (buf).pBase; \ ! (buf).busy = 0; \ ! (buf).escape = FALSE struct _C0C_FDOPORT_EXTENSION; *************** *** 117,120 **** --- 122,126 ---- ULONG waitMask; ULONG eventMask; + UCHAR escapeChar; #define C0C_MSB_CTS 0x10 |