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

📄 devctrl.cpp

📁 USBconvert232 USB转232驱动源程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "vcp4usb.h"
#include "ntddser.h"

VOID ReportEvent(IN PVCP4USB_DEVICE_EXTENSION dx, IN ULONG events)
{
    PIRP            pOldWaitIrp = NULL;
    PDRIVER_CANCEL  pOldCancelRoutine;
    
    //KIRQL oldIrql; // Don't use spinLock
    //KeAcquireSpinLock(&dx->spinLock, &oldIrql);
    
    DPrint(DBG_DRVCONTRAL, ("ReportEvent() @ %d\n", KeGetCurrentIrql()));
    
    dx->historyEvents |= events;
    events &= dx->eventMask;
    
    if ((dx->pWaitCtrlIrp != NULL) && (events != 0))
    {
        pOldWaitIrp = dx->pWaitCtrlIrp;
        IoAcquireCancelSpinLock(&pOldWaitIrp->CancelIrql);
        pOldCancelRoutine = IoSetCancelRoutine(pOldWaitIrp, NULL);
        IoReleaseCancelSpinLock(pOldWaitIrp->CancelIrql);
        if (pOldCancelRoutine != NULL)
        {
            pOldWaitIrp->IoStatus.Information = sizeof(ULONG);
            *(PULONG)pOldWaitIrp->AssociatedIrp.SystemBuffer = events;
            
            pOldWaitIrp->IoStatus.Status = STATUS_SUCCESS;
            DPrint(DBG_DRVCONTRAL, ("ReportEvent: complete dx->pWaitCtrlIrp\n"));
            dx->pWaitCtrlIrp = NULL;
            dx->historyEvents = 0;
        }
        else
        {
            pOldWaitIrp = NULL;
        }
    }
    
    if (pOldWaitIrp != NULL)
        IoCompleteRequest(pOldWaitIrp, IO_NO_INCREMENT);
    
    DPrint(DBG_DRVCONTRAL, ("ReportEvent() exit\n"));
    
    //KeReleaseSpinLock(&dx->spinLock, oldIrql);
}

VOID CancelWaitCtrlIrp(IN PDEVICE_OBJECT PDevObj, IN PIRP Irp)
{
    PVCP4USB_DEVICE_EXTENSION dx = (PVCP4USB_DEVICE_EXTENSION)PDevObj->DeviceExtension;
    PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
    
    DPrint(DBG_DRVCONTRAL, ("CancelWaitCtrlIrp() @ %d\n", KeGetCurrentIrql()));
    
    Irp->IoStatus.Status = STATUS_CANCELLED;
    Irp->IoStatus.Information = 0;
    IoSetCancelRoutine(Irp, NULL);
    IoReleaseCancelSpinLock(Irp->CancelIrql);
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    
    dx->pWaitCtrlIrp = NULL;
    
    DPrint(DBG_DRVCONTRAL, ("CancelWaitCtrlIrp() exit\n"));
}
NTSTATUS Vcp4usbDeviceControl(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
    PVCP4USB_DEVICE_EXTENSION dx=(PVCP4USB_DEVICE_EXTENSION)fdo->DeviceExtension;
    PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
    NTSTATUS status;
    
    // default value
    status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    
    switch (IrpStack->Parameters.DeviceIoControl.IoControlCode)
    {
    case IOCTL_SERIAL_SET_BAUD_RATE:
        {
            if (IrpStack->Parameters.DeviceIoControl.InputBufferLength
                < sizeof(SERIAL_BAUD_RATE))
            {
                status = STATUS_BUFFER_TOO_SMALL;
                DPrint(DBG_DRVCONTRAL, ("SET_BAUD_RATE: rtn TOO_SMALL.\n"));
                break;
            }
            RtlMoveMemory(&dx->curBaudRate, 
                Irp->AssociatedIrp.SystemBuffer, sizeof(SERIAL_BAUD_RATE));
            DPrint(DBG_DRVCONTRAL, ("SET_BAUD_RATE: 0x%x.\n", dx->curBaudRate.BaudRate));
            break;
        }
    case IOCTL_SERIAL_SET_QUEUE_SIZE:
        {
            PSERIAL_QUEUE_SIZE pNewQueueSize= (PSERIAL_QUEUE_SIZE)Irp->AssociatedIrp.SystemBuffer;
            if (IrpStack->Parameters.DeviceIoControl.InputBufferLength
                < sizeof(SERIAL_QUEUE_SIZE))
            {
                status = STATUS_BUFFER_TOO_SMALL;
                DPrint(DBG_DRVCONTRAL, ("SET_QUEUE_SIZE: rtn TOO_SMALL.\n"));
                break;
            }
            DPrint(DBG_DRVCONTRAL, ("SET_QUEUE_SIZE: not handle and InSize=%d, OutSize=%d.\n",
                pNewQueueSize->InSize, pNewQueueSize->OutSize));
            break;
        }
    case IOCTL_SERIAL_SET_LINE_CONTROL:
        {
            PSERIAL_LINE_CONTROL pNewLineControl = (PSERIAL_LINE_CONTROL)Irp->AssociatedIrp.SystemBuffer;
            if (IrpStack->Parameters.DeviceIoControl.InputBufferLength
                < sizeof(SERIAL_LINE_CONTROL))
            {
                status = STATUS_BUFFER_TOO_SMALL;
                DPrint(DBG_DRVCONTRAL, ("SET_LINE_CONTROL: rtn TOO_SMALL.\n"));
                break;
            }
            RtlMoveMemory(&dx->curLineControl, 
                pNewLineControl, sizeof(SERIAL_LINE_CONTROL));
            DPrint(DBG_DRVCONTRAL, ("SET_LINE_CONTROL: StopBits=%d, Parity=%d, WordLength=%d\n",
                pNewLineControl->StopBits, pNewLineControl->Parity, pNewLineControl->WordLength));
            break;
        }
    case IOCTL_SERIAL_SET_BREAK_ON:
        {
            DPrint(DBG_DRVCONTRAL, ("SET_BREAK_ON: do nothing and success.\n"));
            break;
        }
    case IOCTL_SERIAL_SET_BREAK_OFF:
        {
            DPrint(DBG_DRVCONTRAL, ("SET_BREAK_OFF: do nothing and success.\n"));
            break;
        }
    case IOCTL_SERIAL_IMMEDIATE_CHAR:
        {
            UCHAR ch = (UCHAR)Irp->AssociatedIrp.SystemBuffer;
            if (IrpStack->Parameters.DeviceIoControl.InputBufferLength
                < sizeof(UCHAR))
            {
                status = STATUS_BUFFER_TOO_SMALL;
                DPrint(DBG_DRVCONTRAL, ("IMMEDIATE_CHAR: rtn TOO_SMALL.\n"));
                break;
            }
            Irp->IoStatus.Information = sizeof(UCHAR);
            DPrint(DBG_DRVCONTRAL, ("IMMEDIATE_CHAR: not handle and UCHAR(0x%x).\n", ch));
            break;
        }
    case IOCTL_SERIAL_SET_TIMEOUTS:
        {
            PSERIAL_TIMEOUTS pNewTimeouts = (PSERIAL_TIMEOUTS)Irp->AssociatedIrp.SystemBuffer;
            if (IrpStack->Parameters.DeviceIoControl.InputBufferLength
                < sizeof(SERIAL_TIMEOUTS))
            {
                status = STATUS_BUFFER_TOO_SMALL;
                DPrint(DBG_DRVCONTRAL, ("SET_TIMEOUTS: rtn TOO_SMALL.\n"));
                break;
            }
            RtlMoveMemory(&dx->curTimeouts, pNewTimeouts, sizeof(SERIAL_TIMEOUTS));
            DPrint(DBG_DRVCONTRAL, ("SET_TIMEOUTS: RdIv=%d, RdTM=%d, RdTC=%d, WTTM=%d, WTTC=%d.\n",
                pNewTimeouts->ReadIntervalTimeout,
                pNewTimeouts->ReadTotalTimeoutMultiplier,
                pNewTimeouts->ReadTotalTimeoutConstant,
                pNewTimeouts->WriteTotalTimeoutMultiplier,
                pNewTimeouts->WriteTotalTimeoutConstant));
            break;
        }
    case IOCTL_SERIAL_GET_TIMEOUTS:
        {
            if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength
                < sizeof(SERIAL_TIMEOUTS))
            {
                status = STATUS_BUFFER_TOO_SMALL;
                DPrint(DBG_DRVCONTRAL, ("GET_TIMEOUTS: rtn TOO_SMALL.\n"));
                break;
            }
            Irp->IoStatus.Information = sizeof(SERIAL_TIMEOUTS);
            RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &dx->curTimeouts, sizeof(SERIAL_TIMEOUTS));
            DPrint(DBG_DRVCONTRAL, ("GET_TIMEOUTS: RdIv=%d, RdTM=%d, RdTC=%d, WTTM=%d, WTTC=%d.\n",
                dx->curTimeouts.ReadIntervalTimeout,
                dx->curTimeouts.ReadTotalTimeoutMultiplier,
                dx->curTimeouts.ReadTotalTimeoutConstant,
                dx->curTimeouts.WriteTotalTimeoutMultiplier,
                dx->curTimeouts.WriteTotalTimeoutConstant));
            break;
        }
    case IOCTL_SERIAL_SET_DTR:
        {
            DPrint(DBG_DRVCONTRAL, ("SET_DTR: do nothing and success.\n"));
            break;
        }
    case IOCTL_SERIAL_CLR_DTR:
        {
            DPrint(DBG_DRVCONTRAL, ("CLR_DTR: do nothing and success.\n"));
            break;
        }
    case IOCTL_SERIAL_RESET_DEVICE:
        {
            DPrint(DBG_DRVCONTRAL, ("RESET_DEVICE: do nothing and success.\n"));
            break;
        }
    case IOCTL_SERIAL_SET_RTS:
        {
            DPrint(DBG_DRVCONTRAL, ("SET_RTS: do nothing and success.\n"));
            break;
        }
    case IOCTL_SERIAL_CLR_RTS:
        {
            DPrint(DBG_DRVCONTRAL, ("CLR_RTS: do nothing and success.\n"));
            break;
        }
    case IOCTL_SERIAL_SET_XOFF:
        {
            DPrint(DBG_DRVCONTRAL, ("SET_XOFF: do nothing and success.\n"));
            break;
        }
    case IOCTL_SERIAL_SET_XON:
        {
            DPrint(DBG_DRVCONTRAL, ("SET_XON: do nothing and success.\n"));
            break;
        }
    case IOCTL_SERIAL_GET_WAIT_MASK:
        {
            if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength
                < sizeof(ULONG))
            {
                status = STATUS_BUFFER_TOO_SMALL;
                DPrint(DBG_DRVCONTRAL, ("GET_WAIT_MASK: rtn TOO_SMALL.\n"));
                break;
            }
            Irp->IoStatus.Information = sizeof(ULONG);
            *(PULONG)Irp->AssociatedIrp.SystemBuffer = dx->eventMask;
            DPrint(DBG_DRVCONTRAL, ("GET_WAIT_MASK: eventMask=0x%x\n", dx->eventMask));
            break;
        }
    case IOCTL_SERIAL_SET_WAIT_MASK:
        {
            ULONG newMask;
            if (IrpStack->Parameters.DeviceIoControl.InputBufferLength
                < sizeof(ULONG))
            {
                status = STATUS_BUFFER_TOO_SMALL;
                DPrint(DBG_DRVCONTRAL, ("SET_WAIT_MASK: rtn TOO_SMALL.\n"));
                break;
            }
            newMask = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
            dx->eventMask = newMask;
            DPrint(DBG_DRVCONTRAL, ("SET_WAIT_MASK: newMask=0x%x\n", newMask));
			if (dx->pWaitCtrlIrp != NULL)
			{
				PIRP pOldWaitIrp = dx->pWaitCtrlIrp;
				IoAcquireCancelSpinLock(&pOldWaitIrp->CancelIrql);
				IoSetCancelRoutine(pOldWaitIrp, NULL);
				IoReleaseCancelSpinLock(pOldWaitIrp->CancelIrql);
				pOldWaitIrp->IoStatus.Information = sizeof(ULONG);
				*(PULONG)pOldWaitIrp->AssociatedIrp.SystemBuffer = 0;
				pOldWaitIrp->IoStatus.Status = STATUS_SUCCESS;
				IoCompleteRequest(pOldWaitIrp, IO_NO_INCREMENT);

				DPrint(DBG_DRVCONTRAL, ("SET_WAIT_MASK: complete dx->pWaitCtrlIrp\n"));
				dx->pWaitCtrlIrp = NULL;
			}
            break;
        }
    case IOCTL_SERIAL_WAIT_ON_MASK: // 1.
        {
            PDRIVER_CANCEL  pOldCancelRoutine;
            
            if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength
                < sizeof(ULONG))
            {
                status = STATUS_BUFFER_TOO_SMALL;
                DPrint(DBG_DRVCONTRAL, ("WAIT_ON_MASK: rtn TOO_SMALL.\n"));
                break;
            }
            
            if ((dx->pWaitCtrlIrp != NULL) || (dx->eventMask == 0))
            {
                Irp->IoStatus.Information = 0;
                status = STATUS_INVALID_PARAMETER;
                DPrint(DBG_DRVCONTRAL, ("WAIT_ON_MASK: STATUS_INVALID_PARAMETER\n"));
                break;
            }
            if ((dx->eventMask & dx->historyEvents) != 0)
            {
                // report any saved events
                Irp->IoStatus.Information = sizeof(ULONG);
                *(PULONG)Irp->AssociatedIrp.SystemBuffer = dx->eventMask & dx->historyEvents;
                DPrint(DBG_DRVCONTRAL, ("WAIT_ON_MASK: STATUS_SUCCESS mask=0x%x\n",
                    dx->eventMask & dx->historyEvents));
                dx->historyEvents = 0;
                status = STATUS_SUCCESS;
                break;

⌨️ 快捷键说明

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