⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ioctl.c

📁 如题:POLAR LPC23XX-EK_DEMO software_Keil
💻 C
📖 第 1 页 / 共 5 页
字号:
                ("SERIAL: In Ioctl processing for wait mask\n")
                );
            if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(ULONG)) {

                SerialDump(
                    SERDIAG3,
                    ("SERIAL: Invalid size for the buffer %d\n",
                     irpStack->Parameters.DeviceIoControl.OutputBufferLength)
                    );
                ntStatus = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            //
            // Either start this irp or put it on the
            // queue.
            //

            SerialDump(
                SERDIAG3 | SERIRPPATH,
                ("SERIAL: Starting or queuing wait mask irp %x\n",Irp)
                );
            return SerialStartOrQueue(
                       deviceExtension,
                       Irp,
                       &deviceExtension->MaskQueue,
                       &deviceExtension->CurrentMaskIrp,
                       SerialStartMask
                       );
			
		}
        case IOCTL_SERIAL_IMMEDIATE_CHAR: {

            KIRQL OldIrql;

            if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(UCHAR)) {

                ntStatus = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            IoAcquireCancelSpinLock(&OldIrql);
            if (deviceExtension->CurrentImmediateIrp) {

                ntStatus = STATUS_INVALID_PARAMETER;
                IoReleaseCancelSpinLock(OldIrql);

            } else {

                //
                // We can queue the char.  We need to set
                // a cancel routine because flow control could
                // keep the char from transmitting.  Make sure
                // that the irp hasn't already been canceled.
                //

                if (Irp->Cancel) {

                    IoReleaseCancelSpinLock(OldIrql);
                    ntStatus = STATUS_CANCELLED;

                } else {

                    deviceExtension->CurrentImmediateIrp = Irp;
                    deviceExtension->TotalCharsQueued++;
                    IoReleaseCancelSpinLock(OldIrql);
 //                   SerialStartImmediate(deviceExtension);

                    return STATUS_PENDING;

                }

            }

            break;

        }
        case IOCTL_SERIAL_PURGE: {

            ULONG Mask;

            if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(ULONG)) {

                ntStatus = STATUS_BUFFER_TOO_SMALL;
                break;

            }
            //
            // Check to make sure that the mask only has
            // 0 or the other appropriate values.
            //

            Mask = *((ULONG *)(Irp->AssociatedIrp.SystemBuffer));

            if ((!Mask) || (Mask & (~(SERIAL_PURGE_TXABORT |
                                      SERIAL_PURGE_RXABORT |
                                      SERIAL_PURGE_TXCLEAR |
                                      SERIAL_PURGE_RXCLEAR
                                     )
                                   )
                           )) {

                ntStatus = STATUS_INVALID_PARAMETER;
                break;

            }

            //
            // Either start this irp or put it on the
            // queue.
            //

            return SerialStartOrQueue(
                       deviceExtension,
                       Irp,
                       &deviceExtension->PurgeQueue,
                       &deviceExtension->CurrentPurgeIrp,
                       SerialStartPurge
                       );

		}
        case IOCTL_SERIAL_GET_HANDFLOW: {

            if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(SERIAL_HANDFLOW)) {

                ntStatus = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            Irp->IoStatus.Information = sizeof(SERIAL_HANDFLOW);

            KeAcquireSpinLock(
                &deviceExtension->ControlLock,
                &OldIrql
                );

            *((PSERIAL_HANDFLOW)Irp->AssociatedIrp.SystemBuffer) =
                deviceExtension->HandFlow;

            KeReleaseSpinLock(
                &deviceExtension->ControlLock,
                OldIrql
                );

            break;

        }
        case IOCTL_SERIAL_SET_HANDFLOW: {

            SERIAL_IOCTL_SYNC S;
            PSERIAL_HANDFLOW HandFlow = Irp->AssociatedIrp.SystemBuffer;
			USHORT Value = 0;

            //
            // Make sure that the hand shake and control is the
            // right size.
            //

            if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(SERIAL_HANDFLOW)) {

                ntStatus = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            //
            // Make sure that there are no invalid bits set in
            // the control and handshake.
            //

            if (HandFlow->ControlHandShake & SERIAL_CONTROL_INVALID) {

                ntStatus = STATUS_INVALID_PARAMETER;
                break;

            }

            if (HandFlow->FlowReplace & SERIAL_FLOW_INVALID) {

                ntStatus = STATUS_INVALID_PARAMETER;
                break;

            }

            //
            // Make sure that the app hasn't set an invlid DTR mode.
            //

            if ((HandFlow->ControlHandShake & SERIAL_DTR_MASK) ==
                SERIAL_DTR_MASK) {

                ntStatus = STATUS_INVALID_PARAMETER;
                break;

            }

            //
            // Make sure that haven't set totally invalid xon/xoff
            // limits.
            //

            if ((HandFlow->XonLimit < 0) ||
                ((ULONG)HandFlow->XonLimit > deviceExtension->BufferSize)) {

                ntStatus = STATUS_INVALID_PARAMETER;
                break;

            }

            if ((HandFlow->XoffLimit < 0) ||
                ((ULONG)HandFlow->XoffLimit > deviceExtension->BufferSize)) {

                ntStatus = STATUS_INVALID_PARAMETER;
                break;

            }

            S.Extension = deviceExtension;
            S.Data = HandFlow;

			DbgPrint("ControlHandShake = 0x%x\n", HandFlow->ControlHandShake);
			DbgPrint("FlowReplace = 0x%x\n", HandFlow->FlowReplace);
			DbgPrint("XonLimit = %ld\n", HandFlow->XonLimit);
			DbgPrint("XoffLimit = %ld\n", HandFlow->XoffLimit);

			if (HandFlow->ControlHandShake & SERIAL_DTR_HANDSHAKE)
				Value = 0x0A;

			if (HandFlow->FlowReplace & SERIAL_RTS_HANDSHAKE)
				Value |= 0x11;

			if (HandFlow->FlowReplace & (SERIAL_AUTO_TRANSMIT | SERIAL_AUTO_RECEIVE))
				Value |= 0x180;

			UsbCom_SendVendor(DeviceObject, VendorFlowCtrl, Value);
/*
            KeAcquireSpinLock(
                &deviceExtension->ControlLock,
                &OldIrql
                );

            //
            // Under the protection of the lock, make sure that
            // we aren't turning on error replacement when we
            // are doing line status/modem status insertion.
            //

            if (deviceExtension->EscapeChar) {

                if (HandFlow->FlowReplace & SERIAL_ERROR_CHAR) {

                    ntStatus = STATUS_INVALID_PARAMETER;
                    KeReleaseSpinLock(
                        &deviceExtension->ControlLock,
                        OldIrql
                        );
                    break;

                }

            }

            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialSetHandFlow,
                &S
                );


//			SerialSetHandFlow(&S);



            KeReleaseSpinLock(
                &deviceExtension->ControlLock,
                OldIrql
                );
*/
            break;

        }
        case IOCTL_SERIAL_GET_MODEMSTATUS: {

            SERIAL_IOCTL_SYNC S;

            if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(ULONG)) {

                ntStatus = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            Irp->IoStatus.Information = sizeof(ULONG);

            S.Extension = deviceExtension;
            S.Data = Irp->AssociatedIrp.SystemBuffer;
/*
            KeAcquireSpinLock(
                &Extension->ControlLock,
                &OldIrql
                );

            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialGetModemUpdate,
                &S
                );

            KeReleaseSpinLock(
                &Extension->ControlLock,
                OldIrql
                );
*/
			SerialGetModemUpdate(&S);

            break;

        }
		case IOCTL_SERIAL_GET_PROPERTIES: {

			if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
				sizeof(SERIAL_COMMPROP)) {

				ntStatus = STATUS_BUFFER_TOO_SMALL;
				break;

			}

			//
			// No synchronization is required since this information
			// is "static".
			//

			SerialGetProperties(
				deviceExtension,
				Irp->AssociatedIrp.SystemBuffer
				);

			Irp->IoStatus.Information = sizeof(SERIAL_COMMPROP);
			Irp->IoStatus.Status = STATUS_SUCCESS;

			break;
										  
		}
        case IOCTL_SERIAL_XOFF_COUNTER: {

            PSERIAL_XOFF_COUNTER Xc = Irp->AssociatedIrp.SystemBuffer;

            if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(SERIAL_XOFF_COUNTER)) {

                ntStatus = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            if (Xc->Counter <= 0) {

                ntStatus = STATUS_INVALID_PARAMETER;
                break;

            }

            //
            // There is no output, so make that clear now
            //

            Irp->IoStatus.Information = 0;

            //
            // So far so good.  Put the irp onto the write queue.
            //

            return SerialStartOrQueue(
                       deviceExtension,
                       Irp,
                       &deviceExtension->WriteQueue,
                       &deviceExtension->CurrentWriteIrp,
                       SerialStartWrite
                       );

		}
        case IOCTL_SERIAL_LSRMST_INSERT: {

            PUCHAR escapeChar = Irp->AssociatedIrp.SystemBuffer;
            SERIAL_IOCTL_SYNC S;

            //
            // Make sure we get a byte.
            //

            if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(UCHAR)) {

                ntStatus = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            KeAcquireSpinLock(
                &deviceExtension->ControlLock,
                &OldIrql
                );

            if (*escapeChar) {

                //
                // We've got some escape work to do.  We will make sure that
                // the character is not the same as the Xon or Xoff character,
                // or that we are already doing error replacement.
                //

                if ((*escapeChar == deviceExtension->SpecialChars.XoffChar) ||
                    (*escapeChar == deviceExtension->SpecialChars.XonChar) ||
                    (deviceExtension->HandFlow.FlowReplace & SERIAL_ERROR_CHAR)) {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    KeReleaseSpinLock(
                        &deviceExtension->ControlLock,
                        OldIrql
                        );
                    break;

                }

            }

            S.Extension = deviceExtension;
            S.Data = Irp->AssociatedIrp.SystemBuffer;
/*
            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialSetEscapeChar,
                Irp
                );
*/
			SerialSetEscapeChar(Irp);

            KeReleaseSpinLock(
                &deviceExtension->ControlLock,
                OldIrql
                );

            break;

		}
        case IOCTL_SERIAL_CONFIG_SIZE: {

            if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(ULONG)) {

                ntStatus = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            Irp->IoStatus.Information = sizeof(ULONG);
            Irp->IoStatus.Status = STATUS_SUCCESS;

            *(PULONG)Irp->AssociatedIrp.SystemBuffer = 0;

            break;
		}
        case IOCTL_SERIAL_GET_STATS: {

            if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(SERIALPERF_STATS)) {

                ntStatus = STATUS_BUFFER_TOO_SMALL;
                break;

            }
            Irp->IoStatus.Information = sizeof(SERIALPERF_STATS);
            Irp->IoStatus.Status = STATUS_SUCCESS;
/*
            KeSynchronizeExecution(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -