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

📄 ioctl.c

📁 如题:POLAR LPC23XX-EK_DEMO software_Keil
💻 C
📖 第 1 页 / 共 5 页
字号:
                ntStatus = STATUS_BUFFER_TOO_SMALL;
                break;

            }

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

            *((PSERIAL_TIMEOUTS)Irp->AssociatedIrp.SystemBuffer) = deviceExtension->Timeouts;
            Irp->IoStatus.Information = sizeof(SERIAL_TIMEOUTS);

            KeReleaseSpinLock(
                &deviceExtension->ControlLock,
                OldIrql
                );

            break;
        }
        case IOCTL_SERIAL_SET_CHARS: {

            SERIAL_IOCTL_SYNC S;
            PSERIAL_CHARS NewChars =
                ((PSERIAL_CHARS)(Irp->AssociatedIrp.SystemBuffer));


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

                ntStatus = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            //
            // The only thing that can be wrong with the chars
            // is that the xon and xoff characters are the
            // same.
            //
#if 0
            if (NewChars->XonChar == NewChars->XoffChar) {

                ntStatus = STATUS_INVALID_PARAMETER;
                break;

            }
#endif

            //
            // We acquire the control lock so that only
            // one request can GET or SET the characters
            // at a time.  The sets could be synchronized
            // by the interrupt spinlock, but that wouldn't
            // prevent multiple gets at the same time.
            //

            S.Extension = deviceExtension;
            S.Data = NewChars;

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

            //
            // Under the protection of the lock, make sure that
            // the xon and xoff characters aren't the same as
            // the escape character.
            //

            if (deviceExtension->EscapeChar) {

                if ((deviceExtension->EscapeChar == NewChars->XonChar) ||
                    (deviceExtension->EscapeChar == NewChars->XoffChar)) {

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

                }

            }

            deviceExtension->WmiCommData.XonCharacter = NewChars->XonChar;
            deviceExtension->WmiCommData.XoffCharacter = NewChars->XoffChar;
/*
            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialSetChars,
                &S
                );
*/
			SerialSetChars(&S);

            KeReleaseSpinLock(
                &deviceExtension->ControlLock,
                OldIrql
                );

            break;

        }
        case IOCTL_SERIAL_GET_CHARS: {

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

                ntStatus = STATUS_BUFFER_TOO_SMALL;
                break;

            }

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

            *((PSERIAL_CHARS)Irp->AssociatedIrp.SystemBuffer) = deviceExtension->SpecialChars;
            Irp->IoStatus.Information = sizeof(SERIAL_CHARS);

            KeReleaseSpinLock(
                &deviceExtension->ControlLock,
                OldIrql
                );

            break;
        }
        case IOCTL_SERIAL_SET_DTR:
        case IOCTL_SERIAL_CLR_DTR: {
           //
           // Make sure we are at power D0
           //
/*
           if (Extension->PowerState != PowerDeviceD0) {
              ntStatus = SerialGotoPowerState(Extension->Pdo, Extension,
                                            PowerDeviceD0);
              if (!NT_SUCCESS(ntStatus)) {
                     break;
              }
           }
*/
            //
            // We acquire the lock so that we can check whether
            // automatic dtr flow control is enabled.  If it is
            // then we return an error since the app is not allowed
            // to touch this if it is automatic.
            //
/*
            KeAcquireSpinLock(
                &deviceExtension->ControlLock,
                &OldIrql
                );
*/
            if ((deviceExtension->HandFlow.ControlHandShake & SERIAL_DTR_MASK)
                == SERIAL_DTR_HANDSHAKE) {

                ntStatus = STATUS_INVALID_PARAMETER;

            } else {
/*
                KeSynchronizeExecution(
                    Extension->Interrupt,
                    ((IrpSp->Parameters.DeviceIoControl.IoControlCode ==
                     IOCTL_SERIAL_SET_DTR)?
                     (SerialSetDTR):(SerialClrDTR)),
                    Extension
                    );
*/
				if (irpStack->Parameters.DeviceIoControl.IoControlCode ==
                     IOCTL_SERIAL_SET_DTR)
					SerialSetDTR(deviceExtension);
				else
					SerialClrDTR(deviceExtension);
            }
/*
            KeReleaseSpinLock(
                &deviceExtension->ControlLock,
                OldIrql
                );
*/
            break;
        }
        case IOCTL_SERIAL_RESET_DEVICE: {

            break;
        }
        case IOCTL_SERIAL_SET_RTS:
        case IOCTL_SERIAL_CLR_RTS: {
           //
           // Make sure we are at power D0
           //
/*
           if (Extension->PowerState != PowerDeviceD0) {
              ntStatus = SerialGotoPowerState(Extension->Pdo, Extension,
                                            PowerDeviceD0);
              if (!NT_SUCCESS(ntStatus)) {
                 break;
              }
           }
*/
            //
            // We acquire the lock so that we can check whether
            // automatic rts flow control or transmit toggleing
            // is enabled.  If it is then we return an error since
            // the app is not allowed to touch this if it is automatic
            // or toggling.
            //
/* This is remarked away because later calling IoBuildDeviceIoControlRequest must be
called at passive level.
            KeAcquireSpinLock(
                &deviceExtension->ControlLock,
                &OldIrql
                );
*/
            if (((deviceExtension->HandFlow.FlowReplace & SERIAL_RTS_MASK)
                 == SERIAL_RTS_HANDSHAKE) ||
                ((deviceExtension->HandFlow.FlowReplace & SERIAL_RTS_MASK)
                 == SERIAL_TRANSMIT_TOGGLE)) {

                ntStatus = STATUS_INVALID_PARAMETER;

            } else {
/*
                KeSynchronizeExecution(
                    Extension->Interrupt,
                    ((IrpSp->Parameters.DeviceIoControl.IoControlCode ==
                     IOCTL_SERIAL_SET_RTS)?
                     (SerialSetRTS):(SerialClrRTS)),
                    Extension
                    );
*/
				if (irpStack->Parameters.DeviceIoControl.IoControlCode ==
					IOCTL_SERIAL_SET_RTS)
					SerialSetRTS(deviceExtension);
				else
					SerialClrRTS(deviceExtension);
            }
/*
            KeReleaseSpinLock(
                &deviceExtension->ControlLock,
                OldIrql
                );
*/
            break;

        }			
        case IOCTL_SERIAL_SET_XOFF: {
/*
            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialPretendXoff,
                Extension
                );
*/
            SerialPretendXoff(deviceExtension);

            break;

        }
        case IOCTL_SERIAL_SET_XON: {
/*
            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialPretendXon,
                Extension
                );
*/
			SerialPretendXon(deviceExtension);

            break;

        }
        case IOCTL_SERIAL_SET_BREAK_ON: {
           //
           // Make sure we are at power D0
           //
/*
           if (Extension->PowerState != PowerDeviceD0) {
              ntStatus = SerialGotoPowerState(Extension->Pdo, Extension,
                                            PowerDeviceD0);
              if (!NT_SUCCESS(ntStatus)) {
                 break;
              }
           }

            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialTurnOnBreak,
                Extension
                );
*/
			SerialTurnOnBreak(deviceExtension);

            break;
        }
        case IOCTL_SERIAL_SET_BREAK_OFF: {
           //
           // Make sure we are at power D0
           //
/*
           if (Extension->PowerState != PowerDeviceD0) {
              ntStatus = SerialGotoPowerState(Extension->Pdo, Extension,
                                            PowerDeviceD0);
              if (!NT_SUCCESS(ntStatus)) {
                 break;
              }
           }

            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialTurnOffBreak,
                Extension
                );
*/
			SerialTurnOffBreak(deviceExtension);

            break;
        }
        case IOCTL_SERIAL_SET_QUEUE_SIZE: {

            //
            // Type ahead buffer is fixed, so we just validate
            // the the users request is not bigger that our
            // own internal buffer size.
            //

            PSERIAL_QUEUE_SIZE Rs =
                ((PSERIAL_QUEUE_SIZE)(Irp->AssociatedIrp.SystemBuffer));

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

                ntStatus = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            //
            // We have to allocate the memory for the new
            // buffer while we're still in the context of the
            // caller.  We don't even try to protect this
            // with a lock because the value could be stale
            // as soon as we release the lock - The only time
            // we will know for sure is when we actually try
            // to do the resize.
            //

            if (Rs->InSize <= deviceExtension->BufferSize) {

                ntStatus = STATUS_SUCCESS;
                break;

            }

            try {

                irpStack->Parameters.DeviceIoControl.Type3InputBuffer =
                    ExAllocatePoolWithQuota(
                        NonPagedPool,
                        Rs->InSize
                        );

            } except (EXCEPTION_EXECUTE_HANDLER) {

                irpStack->Parameters.DeviceIoControl.Type3InputBuffer = NULL;
                ntStatus = GetExceptionCode();

            }

            if (!irpStack->Parameters.DeviceIoControl.Type3InputBuffer) {

                break;

            }

            //
            // Well the data passed was big enough.  Do the request.
            //
            // There are two reason we place it in the read queue:
            //
            // 1) We want to serialize these resize requests so that
            //    they don't contend with each other.
            //
            // 2) We want to serialize these requests with reads since
            //    we don't want reads and resizes contending over the
            //    read buffer.
            //

            return SerialStartOrQueue(
                       deviceExtension,
                       Irp,
                       &deviceExtension->ReadQueue,
                       &deviceExtension->CurrentReadIrp,
                       SerialStartRead
                       );

            break;
		}
		case IOCTL_SERIAL_GET_WAIT_MASK: {

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

                ntStatus = STATUS_BUFFER_TOO_SMALL;
                break;

            }

            //
            // Simple scalar read.  No reason to acquire a lock.
            //

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

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

            break;

        }
		case IOCTL_SERIAL_SET_WAIT_MASK: {

            ULONG NewMask;

            DbgPrint("SERIAL: In Ioctl processing for set mask\n");
            if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
                sizeof(ULONG)) {

	        DbgPrint("SERIAL: Invalid size fo the buffer %d\n",
				irpStack->Parameters.DeviceIoControl.InputBufferLength);
                ntStatus = STATUS_BUFFER_TOO_SMALL;
                break;

            } else {

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

            }

            //
            // Make sure that the mask only contains valid
            // waitable events.
            //

            if (NewMask & ~(SERIAL_EV_RXCHAR   |
                            SERIAL_EV_RXFLAG   |
                            SERIAL_EV_TXEMPTY  |
                            SERIAL_EV_CTS      |
                            SERIAL_EV_DSR      |
                            SERIAL_EV_RLSD     |
                            SERIAL_EV_BREAK    |
                            SERIAL_EV_ERR      |
                            SERIAL_EV_RING     |
                            SERIAL_EV_PERR     |
                            SERIAL_EV_RX80FULL |
                            SERIAL_EV_EVENT1   |
                            SERIAL_EV_EVENT2)) {

            DbgPrint("SERIAL: Unknown mask %x\n",NewMask);
                ntStatus = STATUS_INVALID_PARAMETER;
                break;

            }

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

            DbgPrint("SERIAL: Starting or queuing set mask irp %x\n",Irp);
            return SerialStartOrQueue(
                       deviceExtension,
                       Irp,
                       &deviceExtension->MaskQueue,
                       &deviceExtension->CurrentMaskIrp,
                       SerialStartMask
                       );

		}
        case IOCTL_SERIAL_WAIT_ON_MASK:	{

            SerialDump(
                SERDIAG3 | SERIRPPATH,

⌨️ 快捷键说明

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