#include "precomp.h" // Precompiled header /************************************************************************/ /* */ /* Title : Dispatch Entry for INTERNAL IOCTLs */ /* */ /* Author : N.P.Vassallo */ /* */ /* Creation : 14th October 1998 */ /* */ /* Version : 1.0.0 */ /* */ /* Description : Internal IOCTLs support the SERENUM */ /* attached serial device enumerator: */ /* IOCTL_SERIAL_INTERNAL_BASIC_SETTINGS */ /* IOCTL_SERIAL_INTERNAL_RESTORE_SETTINGS */ /* */ /************************************************************************/ /* History... 1.0.0 14/20/98 NPV Creation. */ #define FILE_ID SPX_IIOC_C // File ID for Event Logging see SPX_DEFS.H for values. /***************************************************************************** ********************** *********************** ********************** Spx_SerialInternalIoControl *********************** ********************** *********************** ****************************************************************************** prototype: NTSTATUS Spx_SerialInternalIoControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) description: Internal IOCTL dipatch routine. These IOCTLs are only issued from know trusted system components such as the SERENUM.SYS attached serial device enumerator and the mouse driver: parameters: pDevObj points to the device object structure pIrp points to the IOCTL Irp packet returns: STATUS_SUCCESS */ NTSTATUS Spx_SerialInternalIoControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { NTSTATUS status; PIO_STACK_LOCATION pIrpStack; PPORT_DEVICE_EXTENSION pPort = pDevObj->DeviceExtension; KIRQL OldIrql; SpxDbgMsg(SPX_TRACE_IRP_PATH,("%s[card=%d,port=%d]: Internal IOCTL Dispatch Entry\n", PRODUCT_NAME, pPort->pParentCardExt->CardNumber, pPort->PortNumber)); if(SerialCompleteIfError(pDevObj, pIrp) != STATUS_SUCCESS) return(STATUS_CANCELLED); pIrpStack = IoGetCurrentIrpStackLocation(pIrp); pIrp->IoStatus.Information = 0L; status = STATUS_SUCCESS; switch(pIrpStack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_SERIAL_INTERNAL_BASIC_SETTINGS: case IOCTL_SERIAL_INTERNAL_RESTORE_SETTINGS: { SERIAL_BASIC_SETTINGS Basic; PSERIAL_BASIC_SETTINGS pBasic; SERIAL_IOCTL_SYNC S; if (pIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SERIAL_INTERNAL_BASIC_SETTINGS) { /* Check the buffer size... */ if(pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_BASIC_SETTINGS)) { status = STATUS_BUFFER_TOO_SMALL; break; } /* Everything is 0 -- timeouts and flow control. */ /* If we add additional features, this zero memory method may not work. */ RtlZeroMemory(&Basic,sizeof(SERIAL_BASIC_SETTINGS)); pIrp->IoStatus.Information = sizeof(SERIAL_BASIC_SETTINGS); pBasic = (PSERIAL_BASIC_SETTINGS)pIrp->AssociatedIrp.SystemBuffer; /* Save off the old settings... */ RtlCopyMemory(&pBasic->Timeouts, &pPort->Timeouts, sizeof(SERIAL_TIMEOUTS)); RtlCopyMemory(&pBasic->HandFlow, &pPort->HandFlow, sizeof(SERIAL_HANDFLOW)); /* Point to our new settings... */ pBasic = &Basic; } else { if(pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_BASIC_SETTINGS)) { status = STATUS_BUFFER_TOO_SMALL; break; } pBasic = (PSERIAL_BASIC_SETTINGS)pIrp->AssociatedIrp.SystemBuffer; } KeAcquireSpinLock(&pPort->ControlLock,&OldIrql); /* Set the timeouts... */ RtlCopyMemory(&pPort->Timeouts, &pBasic->Timeouts, sizeof(SERIAL_TIMEOUTS)); /* Set flowcontrol... */ S.pPort = pPort; S.Data = &pBasic->HandFlow; XXX_SetHandFlow(pPort, &S); /* Set the handflow for specific hardware */ KeReleaseSpinLock(&pPort->ControlLock, OldIrql); break; } default: status = STATUS_INVALID_PARAMETER; break; } pIrp->IoStatus.Status = status; SpxDbgMsg(SPX_TRACE_IRP_PATH,("%s[card=%d,port=%d]: Internal IOCTL Dispatch Complete\n", PRODUCT_NAME, pPort->pParentCardExt->CardNumber, pPort->PortNumber)); IoCompleteRequest(pIrp,0); return(status); } /* Spx_SerialInternalIoControl */ /* End of SPX_IIOC.C */