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

📄 vcom_device.c

📁 一个虚拟串口的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			}

			KeAcquireSpinLock(&pDeviceExtension->controlSpinLock, &oldIrql);

			RtlMoveMemory(&pDeviceExtension->serBaudRate, pNewBaudRate, sizeof(SERIAL_BAUD_RATE));

			KeReleaseSpinLock(&pDeviceExtension->controlSpinLock, oldIrql);

			break;
		}
		    
		case IOCTL_SERIAL_GET_LINE_CONTROL:
		
			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_GET_LINE_CONTROL\n"));

			if (pIrpStackLocation->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_LINE_CONTROL))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

			pIrp->IoStatus.Information = sizeof(SERIAL_LINE_CONTROL);

			KeAcquireSpinLock(&pDeviceExtension->controlSpinLock, &oldIrql);

			RtlMoveMemory(pIrp->AssociatedIrp.SystemBuffer, &pDeviceExtension->serLineControl, sizeof(SERIAL_LINE_CONTROL));

			KeReleaseSpinLock(&pDeviceExtension->controlSpinLock, oldIrql);

			break;		
		      
		case IOCTL_SERIAL_SET_LINE_CONTROL:
		{
			PSERIAL_LINE_CONTROL pNewLineControl = (PSERIAL_LINE_CONTROL)pIrp->AssociatedIrp.SystemBuffer;

			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_SET_LINE_CONTROL\n"));

			if (pIrpStackLocation->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_LINE_CONTROL))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

			KeAcquireSpinLock(&pDeviceExtension->controlSpinLock, &oldIrql);

			RtlMoveMemory(&pDeviceExtension->serLineControl, pNewLineControl, sizeof(SERIAL_LINE_CONTROL));

			KeReleaseSpinLock(&pDeviceExtension->controlSpinLock, oldIrql);

			break;
		}
		    		
		case IOCTL_SERIAL_GET_CHARS:
			
			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_GET_CHARS\n"));

			if (pIrpStackLocation->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_CHARS))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

			pIrp->IoStatus.Information = sizeof(SERIAL_CHARS);

			KeAcquireSpinLock(&pDeviceExtension->controlSpinLock, &oldIrql);

			RtlMoveMemory(pIrp->AssociatedIrp.SystemBuffer, &pDeviceExtension->serChars, sizeof(SERIAL_CHARS));

			KeReleaseSpinLock(&pDeviceExtension->controlSpinLock, oldIrql);

			break;
	      
		case IOCTL_SERIAL_SET_CHARS:
		{
			PSERIAL_CHARS pNewChars = (PSERIAL_CHARS)pIrp->AssociatedIrp.SystemBuffer;

			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_SET_CHARS\n"));

			if (pIrpStackLocation->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_CHARS))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

			KeAcquireSpinLock(&pDeviceExtension->controlSpinLock, &oldIrql);

			RtlMoveMemory(&pDeviceExtension->serChars, pNewChars, sizeof(SERIAL_CHARS));

			pDeviceExtension->serEventCharacter = pDeviceExtension->serChars.EventChar;
			
			KeReleaseSpinLock(&pDeviceExtension->controlSpinLock, oldIrql);

			break;
		}
			
		case IOCTL_SERIAL_GET_HANDFLOW:
			
			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_GET_HANDFLOW\n"));

			if (pIrpStackLocation->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_HANDFLOW))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

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

			KeAcquireSpinLock(&pDeviceExtension->controlSpinLock, &oldIrql);

			RtlMoveMemory(pIrp->AssociatedIrp.SystemBuffer, &pDeviceExtension->serHandFlow, sizeof(SERIAL_HANDFLOW));

			KeReleaseSpinLock(&pDeviceExtension->controlSpinLock, oldIrql);	        	     

			break;
			
		case IOCTL_SERIAL_SET_HANDFLOW:
		{
			PSERIAL_HANDFLOW pNewHandFlow = (PSERIAL_HANDFLOW)pIrp->AssociatedIrp.SystemBuffer;

			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_SET_HANDFLOW\n"));

			if (pIrpStackLocation->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_HANDFLOW))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

			KeAcquireSpinLock(&pDeviceExtension->controlSpinLock, &oldIrql);

			RtlMoveMemory(&pDeviceExtension->serHandFlow, pNewHandFlow, sizeof(SERIAL_HANDFLOW));

			KeReleaseSpinLock(&pDeviceExtension->controlSpinLock, oldIrql);

			break;
		}
		    	  
		case IOCTL_SERIAL_GET_MODEMSTATUS:
			
			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_GET_MODEMSTATUS\n"));

			if (pIrpStackLocation->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

			KeAcquireSpinLock(&pDeviceExtension->controlSpinLock, &oldIrql);
			
			pDeviceExtension->serModemStatusRegister = 0;
			
			if (pDeviceExtension->serCTS)
				pDeviceExtension->serModemStatusRegister |= SERIAL_MSR_CTS;
			
			if (pDeviceExtension->serDSR)
				pDeviceExtension->serModemStatusRegister |= SERIAL_MSR_DSR;
						
			pIrp->IoStatus.Information = sizeof(ULONG);

			*(PULONG)pIrp->AssociatedIrp.SystemBuffer = (ULONG) pDeviceExtension->serModemStatusRegister;

			KeReleaseSpinLock(&pDeviceExtension->controlSpinLock, oldIrql);
			
			break;
	      
		case IOCTL_SERIAL_GET_COMMSTATUS:
		{
			PSERIAL_STATUS pStatus = (PSERIAL_STATUS)pIrp->AssociatedIrp.SystemBuffer;

			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_GET_COMMSTATUS\n"));

			if (pIrpStackLocation->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_STATUS))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

			KeAcquireSpinLock(&pDeviceExtension->readSpinLock, &read_oldIrql);
			
			pDeviceExtension->serStatus.Errors = 0;
			pDeviceExtension->serStatus.HoldReasons = 0;
			pDeviceExtension->serStatus.AmountInInQueue = pDeviceExtension->outBufferCount;
			pDeviceExtension->serStatus.AmountInOutQueue = pDeviceExtension->inBufferCount;
			pDeviceExtension->serStatus.EofReceived = 0;
			pDeviceExtension->serStatus.WaitForImmediate = 0;		
									
			RtlMoveMemory(pStatus, &pDeviceExtension->serStatus, sizeof(SERIAL_STATUS));

			KeReleaseSpinLock(&pDeviceExtension->readSpinLock, read_oldIrql);	        	  

			pIrp->IoStatus.Information = sizeof(SERIAL_STATUS);

			KdPrint(("IOCTL_SERIAL_GET_COMMSTATUS: InQue=%d\n", pDeviceExtension->outBufferCount));
			KdPrint(("IOCTL_SERIAL_GET_COMMSTATUS: OutQue=%d\n", pDeviceExtension->inBufferCount));
			
			break;
		}
	    
		case IOCTL_SERIAL_GET_PROPERTIES:
			
			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_GET_PROPERTIES\n"));

			if (pIrpStackLocation->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_COMMPROP))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

			pIrp->IoStatus.Information = sizeof(SERIAL_COMMPROP);

			RtlMoveMemory(pIrp->AssociatedIrp.SystemBuffer, &vCOMProperties, sizeof(SERIAL_COMMPROP));

			break;
	      
		case IOCTL_SERIAL_CONFIG_SIZE:
			
			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_CONFIG_SIZE\n"));

			if (pIrpStackLocation->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

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

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

			break;
	           	        
		case IOCTL_SERIAL_LSRMST_INSERT:
				
			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_LSRMST_INSERT\n"));

			if (pIrpStackLocation->Parameters.DeviceIoControl.InputBufferLength < sizeof(UCHAR))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

			break;			
	        
		case IOCTL_SERIAL_SET_DTR:
			
			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_SET_DTR\n"));
			pDeviceExtension->serDTR = TRUE;			
			if (!pTwinDeviceExtension->serDSR)
			{
				pTwinDeviceExtension->serDSR = TRUE;
				vCOMCheckComEvents(pTwinDeviceExtension, SERIAL_EV_DSR);
			}
			pIrp->IoStatus.Information = 0;
			break;

		case IOCTL_SERIAL_CLR_DTR:
			
			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_CLR_DTR\n"));
			pDeviceExtension->serDTR = FALSE;
			if (pTwinDeviceExtension->serDSR)
			{
				pTwinDeviceExtension->serDSR = FALSE;
				vCOMCheckComEvents(pTwinDeviceExtension, SERIAL_EV_DSR);
			}			
			pIrp->IoStatus.Information = 0;			
			break;
			
		case IOCTL_SERIAL_SET_RTS:
			
			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_SET_RTS\n"));
			pDeviceExtension->serRTS = TRUE;
			if (!pTwinDeviceExtension->serCTS)
			{
				pTwinDeviceExtension->serCTS = TRUE;			
				vCOMCheckComEvents(pTwinDeviceExtension, SERIAL_EV_CTS);
			}
			pIrp->IoStatus.Information = 0;
			break;
			
		case IOCTL_SERIAL_CLR_RTS:
			
			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_CLR_RTS\n"));
			pDeviceExtension->serRTS = FALSE;
			if (pTwinDeviceExtension->serCTS)
			{
				pTwinDeviceExtension->serCTS = FALSE;			
				vCOMCheckComEvents(pTwinDeviceExtension, SERIAL_EV_CTS);
			}
			pIrp->IoStatus.Information = 0;
			break;
	      
		case IOCTL_SERIAL_GET_STATS:
			
			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_GET_STATS\n"));

			if (pIrpStackLocation->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIALPERF_STATS ))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

			pIrp->IoStatus.Information = sizeof(SERIALPERF_STATS );

			KeAcquireSpinLock(&pDeviceExtension->controlSpinLock, &oldIrql);

			RtlMoveMemory(pIrp->AssociatedIrp.SystemBuffer, &pDeviceExtension->serPerformanceStats, sizeof(SERIALPERF_STATS ));

			KeReleaseSpinLock(&pDeviceExtension->controlSpinLock, oldIrql);	        	     

			break;

		case IOCTL_SERIAL_CLEAR_STATS:
			
			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_CLEAR_STATS\n"));

			KeAcquireSpinLock(&pDeviceExtension->controlSpinLock, &oldIrql);

			RtlZeroMemory(&pDeviceExtension->serPerformanceStats, sizeof(SERIALPERF_STATS));

			KeReleaseSpinLock(&pDeviceExtension->controlSpinLock, oldIrql);	

			break;
	    
		case IOCTL_SERIAL_SET_QUEUE_SIZE:        
		{
			PSERIAL_QUEUE_SIZE pNewQueueSize = (PSERIAL_QUEUE_SIZE)pIrp->AssociatedIrp.SystemBuffer;

			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_SET_QUEUE_SIZE\n"));

			if (pIrpStackLocation->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_QUEUE_SIZE))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

			KeAcquireSpinLock(&pDeviceExtension->controlSpinLock, &oldIrql);

			RtlMoveMemory(&pDeviceExtension->serQueueSize, pNewQueueSize, sizeof(SERIAL_QUEUE_SIZE));

			KeReleaseSpinLock(&pDeviceExtension->controlSpinLock, oldIrql);

			KeAcquireSpinLock(&pDeviceExtension->readSpinLock, &oldIrql);

			if (pDeviceExtension->serQueueSize.InSize <= BUFFERLENGTH)
			{			
				pDeviceExtension->outBufferReadPosition = 0;
				pDeviceExtension->outBufferWritePosition = 0;
				pDeviceExtension->outBufferCount = 0;
				RtlZeroMemory(pDeviceExtension->outBuffer, BUFFERLENGTH);
				pDeviceExtension->outBufferSize = pDeviceExtension->serQueueSize.InSize;
			}

			KeReleaseSpinLock(&pDeviceExtension->readSpinLock, oldIrql);

			KeAcquireSpinLock(&pDeviceExtension->writeSpinLock, &oldIrql);

			if (pDeviceExtension->serQueueSize.OutSize <= BUFFERLENGTH)
			{				
				pDeviceExtension->inBufferReadPosition = 0;
				pDeviceExtension->inBufferWritePosition = 0;
				pDeviceExtension->inBufferCount = 0;
				RtlZeroMemory(pDeviceExtension->inBuffer, BUFFERLENGTH);
				pDeviceExtension->inBufferSize = pDeviceExtension->serQueueSize.OutSize;
			}

			KeReleaseSpinLock(&pDeviceExtension->writeSpinLock, oldIrql);

			break;
		}

		case IOCTL_SERIAL_GET_DTRRTS:
		{
			ULONG		serState = 0;
			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_GET_DTRRTS\n"));

			if (pIrpStackLocation->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

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

			KeAcquireSpinLock(&pDeviceExtension->controlSpinLock, &oldIrql);
						
			if (pDeviceExtension->serRTS)
				serState |= SERIAL_RTS_STATE;
			if (pDeviceExtension->serDTR)
				serState |= SERIAL_DTR_STATE;
			
			*(PULONG)pIrp->AssociatedIrp.SystemBuffer = serState;
			
			KeReleaseSpinLock(&pDeviceExtension->controlSpinLock, oldIrql);	        	     

			break;
		}

	   	case IOCTL_SERIAL_GET_MODEM_CONTROL:
		{
			KdPrint(("vCOMDeviceControl: IOCTL_SERIAL_GET_MODEM_CONTROL\n"));

			if (pIrpStackLocation->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
			{
				status = STATUS_BUFFER_TOO_SMALL;
				break;
			}

⌨️ 快捷键说明

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