www.pudn.com > vcom.zip > ComfilntDevice.cpp


// ComfilntDevice.cpp 
// Implementation of ComfilntDevice device class 
// 
// Generated by DriverWizard version DriverStudio 2.5.0 (Build 240) 
// Requires Compuware's DriverWorks classes 
// 
 
#include  
//#include "ntddser.h" 
#include  
#include "Comfilnt.h" 
#include "ComfilntDevice.h" 
 
#pragma warning(disable:4065) // Allow switch statement with no cases 
 
extern	KTrace	t;			// Global driver trace object	 
 
//////////////////////////////////////////////////////////////////////// 
// ComfilntDevice::~ComfilntDevice 
// 
//	Routine Description: 
//		This is the destructor for the ComfilntDevice 
// 
//	Parameters: 
//		None 
// 
//	Return Value: 
//		None 
// 
//	Comments: 
//		Disconnect and release resources here. 
// 
//		Although the use of SAFE_DESTRUCTORS in the class definition cures 
//		improper emission of the destructor into the INIT section most of the 
//		time, certain rare cases can still cause improper behavior.  To avoid 
//		these cases, the destructor	must preceed the INIT section, causing it 
//		to be referenced first by the default compiler section. 
// 
 
ComfilntDevice::~ComfilntDevice() 
{ 
	delete m_RegPath; 
} 
 
#pragma code_seg("INIT") 
 
//////////////////////////////////////////////////////////////////////////////// 
//  ComfilntDevice::ComfilntDevice 
// 
//	Routine Description: 
//		The device constructor is typically responsible for allocating 
//		any physical resources that are associated with the device. 
// 
//	Parameters: 
//		Unit - Unit number. This is a number to append to the device's 
//			base device name to distinguish multiple units of this 
//			device type. 
// 
//	Return Value: 
//		None 
// 
//	Comments: 
//		The device constructor often reads the registry to setup 
//		various configurable parameters. 
 
ComfilntDevice::ComfilntDevice(ULONG Unit,PRW pRW) : 
	KDevice() 
{ 
	t << "Enter ComfilntDevice: unit number= " << Unit << "; status= " << (ULONG) m_ConstructorStatus << EOL; 
	if ( ! NT_SUCCESS(m_ConstructorStatus) ) 
	{ 
		t << "Failed to create device ComfilntDevice unit number " << Unit << " status " << (ULONG) m_ConstructorStatus << EOL; 
		return; 
	} 
	m_Unit = Unit; 
	m_IsOpened=0; 
	m_pRW=pRW; 
//	t << (ULONG) pRW <PipeB.NumberOfItemsAvailableForRead(); 
		//if(Count>dwTotalSize) 
 
		ReadedBytes=0; 
		if(Count==0) 
			m_pRW->MaskB &=~SERIAL_EV_RXCHAR; 
 
			dwBytesRead=m_pRW->PipeB.Read(pBuffer,dwTotalSize); 
			ReadedBytes=dwBytesRead; 
		 
	}else{ 
		Count=m_pRW->PipeA.NumberOfItemsAvailableForRead(); 
		ReadedBytes=0; 
		if(Count==0) 
			m_pRW->MaskA &=~SERIAL_EV_RXCHAR; 
 
			dwBytesRead=m_pRW->PipeA.Read(pBuffer,dwTotalSize); 
			ReadedBytes=dwBytesRead; 
		 
	} 
//	t << "Read Buffer=" << (TCHAR*)pBuffer <MaskB &=~SERIAL_EV_RXCHAR; 
//		m_pRW->WriteCountB=(ULONG)0; 
	}else{ 
		m_pRW->MaskA &=~SERIAL_EV_RXCHAR; 
//		m_pRW->WriteCountA=(ULONG)0; 
	} 
	if(Count <= ReadedBytes) 
	m_WaitMask &= ~EV_RXFLAG; 
 
	I.Information() = ReadedBytes; 
	status = STATUS_SUCCESS; 
	CancelSpinLock::Release(); 
	return I.Complete(status); 
} 
 
 
//////////////////////////////////////////////////////////////////////// 
//  ComfilntDevice::Write 
// 
//	Routine Description: 
//		Handler for IRP_MJ_WRITE 
// 
//	Parameters: 
//		I - Current IRP 
// 
//	Return Value: 
//		NTSTATUS - Result code 
// 
//	Comments: 
//		This routine handles write requests. 
 
NTSTATUS ComfilntDevice::Write(KIrp I) 
{ 
	t << "--- Write " <0x100) 
		dwTotalSize=0x100; 
	 
	if((m_Unit&1)==0){ 
		if(m_pRW->PipeA.IsFull()==FALSE){ 
			dwBytesSent=m_pRW->PipeA.Write(pBuffer,dwTotalSize); 
			m_pRW->WriteCountA=dwBytesSent; 
//			t<<"Write PipeA,CountA="<<(ULONG)m_pRW->WriteCountA<MaskA=SERIAL_EV_RXCHAR; 
//			t <<"MaskA"<<(ULONG)m_pRW->MaskA<< EOL; 
		}else{ 
//			t <<"Pending(A),COM="<<(ULONG)m_Unit<< EOL; 
			dwBytesSent=0; 
			status	= STATUS_PENDING; 
		} 
	}else{ 
		if(m_pRW->PipeB.IsFull()==FALSE){ 
			dwBytesSent=m_pRW->PipeB.Write(pBuffer,dwTotalSize); 
			m_pRW->WriteCountB=dwBytesSent; 
			t<<"Write PipeB,CountB="<<(ULONG)m_pRW->PipeB.NumberOfItemsAvailableForRead()<MaskB<< EOL; 
			m_pRW->MaskB=SERIAL_EV_RXCHAR; 
		}else{ 
//			t <<"Pending (B),COM="<<(ULONG)m_Unit<< EOL; 
			dwBytesSent = 0; 
			status	= STATUS_PENDING; 
		} 
	} 
 
//	t << "****Write Buffer=" <<(char*)wkBuffer <MaskA<< EOL; 
//	}else{ 
//		t <<"MaskB"<<(ULONG)m_pRW->MaskB<< EOL; 
//		m_pRW->MaskB|=SERIAL_EV_RXCHAR; 
//	} 
	CancelSpinLock::Release(); 
	return I.Complete(status); 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  ComfilntDevice::DeviceControl 
// 
//	Routine Description: 
//		Handler for IRP_MJ_DEVICE_CONTROL 
// 
//	Parameters: 
//		I - Current IRP 
//  
//	Return Value: 
//		NTSTATUS - Result code 
// 
//	Comments: 
//		This routine is the first handler for Device Control requests. 
 
NTSTATUS ComfilntDevice::DeviceControl(KIrp I)  
{ 
	NTSTATUS status; 
	ULONG Mask; 
//	t << "<>" <BaudRate) );  
			 
		if (I.IoctlInputBufferSize() < sizeof(SERIAL_BAUD_RATE) ) 
			status = STATUS_BUFFER_TOO_SMALL; 
		else 
		{ 
			IoctlSetBaudRate( *pBR ); 
			I.Information() = 0; 
			status = STATUS_SUCCESS; 
		} 
		break; 
	} 
	/////////////////////////////////////////////////////////////////// 
	// Get Baud Rate 
	//(50h--20) 
	case IOCTL_SERIAL_GET_BAUD_RATE: 
 
//		GTRACE((TLEVEL,"--IOCTL_SERIAL_GET_BAUD_RATE\n"));  
 
		if (I.IoctlOutputBufferSize() < sizeof(SERIAL_BAUD_RATE) ) 
			status = STATUS_BUFFER_TOO_SMALL; 
		else 
		{ 
			IoctlGetBaudRate(*(SERIAL_BAUD_RATE*)I.IoctlBuffer()); 
			I.Information() = sizeof(SERIAL_BAUD_RATE); 
			status = STATUS_SUCCESS; 
		}			 
		break; 
 
	/////////////////////////////////////////////////////////////////// 
	// Set Line Control (parity, data bits, stop bits) 
	//(0ch--3) 
	case IOCTL_SERIAL_SET_LINE_CONTROL: 
		t <<"SetLineControl" << EOL; 
//		GTRACE((TLEVEL,"--IOCTL_SERIAL_SET_LINE_CONTROL: %x\n", *(UCHAR*)I.IoctlBuffer()));  
		if (I.IoctlInputBufferSize() < sizeof(SERIAL_LINE_CONTROL) ) 
			status = STATUS_BUFFER_TOO_SMALL; 
		else 
			status = IoctlSetLineControl(*(SERIAL_LINE_CONTROL*)I.IoctlBuffer()); 
			I.Information() = 0; 
			status = STATUS_SUCCESS; 
 
		break;		 
 
	/////////////////////////////////////////////////////////////////// 
	// Get Line Control (parity, data bits, stop bits) 
	//(54h--21) 
	case IOCTL_SERIAL_GET_LINE_CONTROL: 
		t <<"GetLineControl" << EOL; 
 
//		GTRACE((TLEVEL,"--IOCTL_SERIAL_GET_LINE_CONTROL\n"));  
 
		if (I.IoctlOutputBufferSize() < sizeof(SERIAL_LINE_CONTROL) ) 
			status = STATUS_INVALID_PARAMETER; 
		else 
		{ 
			IoctlGetLineControl(*(SERIAL_LINE_CONTROL*)I.IoctlBuffer()); 
			I.Information() = sizeof (SERIAL_LINE_CONTROL); 
			status = STATUS_SUCCESS; 
		} 
		break; 
 
	/////////////////////////////////////////////////////////////////// 
	// Reset device 
	//(2ch--11) 
	case IOCTL_SERIAL_RESET_DEVICE: 
		t <<"ReSetDevice" << EOL; 
//		IoctlReset(); 
		I.Information() = 0; 
		status = STATUS_SUCCESS; 
		break; 
 
	/////////////////////////////////////////////////////////////////// 
	// Set Handshake / Flow control 
	//(60h--24) 
	case IOCTL_SERIAL_GET_HANDFLOW: 
		t <<"GetHandFlow" << EOL; 
 
//		GTRACE((TLEVEL,"--IOCTL_SERIAL_GET_HANDFLOW\n")); 
 
		if (I.IoctlOutputBufferSize() < sizeof SERIAL_HANDFLOW) 
			status = STATUS_BUFFER_TOO_SMALL; 
		else 
		{			 
			IoctlGetHandFlow(*(SERIAL_HANDFLOW*)I.IoctlBuffer()); 
			I.Information() = sizeof(SERIAL_HANDFLOW); 
			status = STATUS_SUCCESS; 
		} 
		break; 
 
	/////////////////////////////////////////////////////////////////// 
	// Set Handshake / Flow control 
	//(64h--25) 
	case IOCTL_SERIAL_SET_HANDFLOW: 
	{ 
		t <<"SetHandflow" << EOL; 
 
 
		SERIAL_HANDFLOW& hf = *(SERIAL_HANDFLOW*)I.IoctlBuffer(); 
//		GTRACE((TLEVEL,"- Handshake=%x, FlowReplace=%x", hf.ControlHandShake, hf.FlowReplace)); 
 
	// Validate parameters 
		if (I.IoctlInputBufferSize() < sizeof(SERIAL_HANDFLOW) ) 
			status = STATUS_BUFFER_TOO_SMALL; 
 
		else if ( (hf.ControlHandShake & SERIAL_CONTROL_INVALID) || 
				  (hf.FlowReplace & SERIAL_FLOW_INVALID) || 
				  ((hf.ControlHandShake & SERIAL_DTR_MASK) == SERIAL_DTR_MASK) || 
				  (hf.XonLimit < 0) || 
				  (hf.XoffLimit < 0) 
				) 
			status = STATUS_INVALID_PARAMETER; 
 
		else 
			status = IoctlSetHandFlow(hf); 
 
		break; 
	} 
	/////////////////////////////////////////////////////////////////// 
	// Set DTR 
	//(24h--9) 
	case IOCTL_SERIAL_SET_DTR: 
		t <<"SetDTR" << EOL; 
 
 
//		IoctlSetDTR(TRUE); 
		I.Information() = 0; 
		status = STATUS_SUCCESS; 
		break; 
 
	/////////////////////////////////////////////////////////////////// 
	// Clear DTR 
	//(28h--10) 
	case IOCTL_SERIAL_CLR_DTR: 
		t <<"CLRDTR" << EOL; 
 
 
//		IoctlSetDTR(FALSE); 
		I.Information() = 0; 
		status = STATUS_SUCCESS; 
		break; 
 
	/////////////////////////////////////////////////////////////////// 
	// Set RTS 
	//(30h--12) 
	case IOCTL_SERIAL_SET_RTS: 
		t <<"SetRTS" << EOL; 
 
//		IoctlSetRTS(TRUE); 
		I.Information() = 0; 
		status = STATUS_SUCCESS; 
		break; 
 
	/////////////////////////////////////////////////////////////////// 
	// Clear RTS 
	//(34h--13) 
	case IOCTL_SERIAL_CLR_RTS: 
		t <<"CLRRTS" << EOL; 
 
//		IoctlSetRTS(FALSE); 
		I.Information() = 0; 
		status = STATUS_SUCCESS; 
		break; 
 
	/////////////////////////////////////////////////////////////////// 
	// Get Special Characters 
	//(58h--22) 
	case IOCTL_SERIAL_GET_CHARS: 
		t <<"GetCHARS" << EOL; 
 
		if (I.IoctlOutputBufferSize() < sizeof(SERIAL_CHARS) ) 
			status = STATUS_BUFFER_TOO_SMALL; 
 
		else  
		{ 
			IoctlGetSpecialCharacters( *(SERIAL_CHARS*)I.IoctlBuffer()); 
			I.Information() = sizeof(SERIAL_CHARS); 
			status = STATUS_SUCCESS; 
		} 
		break; 
 
	/////////////////////////////////////////////////////////////////// 
	// Set Special Characters 
	//(5ch--23) 
	case IOCTL_SERIAL_SET_CHARS: 
	{ 
		t <<"SetCHARS" << EOL; 
 
		SERIAL_CHARS* p = (SERIAL_CHARS*)I.IoctlBuffer(); 
 
		if (I.IoctlInputBufferSize() < sizeof(SERIAL_CHARS) ) 
			status = STATUS_BUFFER_TOO_SMALL; 
		else 
		{ 
			IoctlSetSpecialCharacters( *(SERIAL_CHARS*)I.IoctlBuffer()); 
			status = STATUS_SUCCESS; 
		} 
		break; 
	} 
	/////////////////////////////////////////////////////////////////// 
	// Set Timeouts 
	//(1ch--7) 
	case IOCTL_SERIAL_SET_TIMEOUTS: 
	{ 
		t <<"SetTIMEOUT" << EOL; 
		SERIAL_TIMEOUTS* p=(SERIAL_TIMEOUTS*)I.IoctlBuffer(); 
 
		if (I.IoctlInputBufferSize() < sizeof(SERIAL_TIMEOUTS) ) 
			return STATUS_BUFFER_TOO_SMALL; 
 
		else 
		{ 
			IoctlSetTimeOuts( *(SERIAL_TIMEOUTS*)I.IoctlBuffer()); 
			status = STATUS_SUCCESS; 
		} 
 
		break; 
	} 
	/////////////////////////////////////////////////////////////////// 
	// Get Timeouts 
	//(20h--8) 
	case IOCTL_SERIAL_GET_TIMEOUTS: 
	{ 
		t <<"GetTIMEOUT" << EOL; 
 
		if (I.IoctlOutputBufferSize() < sizeof(SERIAL_TIMEOUTS) ) 
			return STATUS_BUFFER_TOO_SMALL; 
 
		else 
		{ 
			IoctlGetTimeOuts( *(SERIAL_TIMEOUTS*)I.IoctlBuffer()); 
			I.Information() = sizeof(SERIAL_TIMEOUTS); 
			status = STATUS_SUCCESS; 
 
			SERIAL_TIMEOUTS* p=(SERIAL_TIMEOUTS*)I.IoctlBuffer(); 
		} 
		break; 
	} 
#if NTVERSION > 351 
	/////////////////////////////////////////////////////////////////// 
	// Get Statistics 
	// 
	case IOCTL_SERIAL_GET_STATS: 
		t <<"GetSTAT" << EOL; 
 
 
		if (I.IoctlOutputBufferSize() < sizeof (SERIALPERF_STATS) ) 
			status = STATUS_BUFFER_TOO_SMALL; 
		else 
		{ 
			IoctlGetStatistics(*(SERIALPERF_STATS*)I.IoctlBuffer()); 
			I.Information() = sizeof(SERIALPERF_STATS); 
			status = STATUS_SUCCESS; 
		} 
		break; 
#endif 
 
#if NTVERSION > 351 
	/////////////////////////////////////////////////////////////////// 
	// Clear Statistics 
	// 
	case IOCTL_SERIAL_CLEAR_STATS: 
		t <<"CLRSTATS" << EOL; 
 
 
		IoctlClearStatistics(); 
		status = STATUS_SUCCESS; 
 
		break; 
#endif 
 
	/////////////////////////////////////////////////////////////////// 
	// Get Wait Mask 
	//(40h--16) 
	case IOCTL_SERIAL_GET_WAIT_MASK: 
		t <<"GetWAITMASK" << EOL; 
 
 
		if (I.IoctlOutputBufferSize() < sizeof(ULONG) ) 
			status = STATUS_BUFFER_TOO_SMALL; 
		else 
		{ 
			*(ULONG*)I.IoctlBuffer() = IoctlGetWaitMask(); 
			I.Information() = sizeof(ULONG); 
			status = STATUS_SUCCESS; 
		} 
 
		break; 
 
	/////////////////////////////////////////////////////////////////// 
	// Set Wait Mask 
	//(44h--11) 
	case IOCTL_SERIAL_SET_WAIT_MASK: 
//		GTRACE((TLEVEL,"--IOCTL_SERIAL_SET_WAIT_MASK\n")); 
//	GTRACE((TLEVEL,"Set wait mask to %x\n", *(ULONG*)I.IoctlBuffer())); 
 
//		if (I.IoctlInputBufferSize() < sizeof(ULONG) ) 
//			status = STATUS_BUFFER_TOO_SMALL; 
//		else if ( ~m_SupportedEvents & *(ULONG*)I.IoctlBuffer() ) 
//			status = STATUS_INVALID_PARAMETER; 
//		else 
//			status = m_WaitIrpQueue.QueueIrp(I); 
//			status = STATUS_SUCCESS; 
			m_WaitMask = *(ULONG*)I.IoctlBuffer(); 
//		t << "Set Mask" << m_WaitMask<StartSetMask(Mask); 
//			I.Status() = STATUS_SUCCESS; 
			I.Information() = 0; 
			status = STATUS_SUCCESS; 
		break; 
 
	/////////////////////////////////////////////////////////////////// 
	// Wait on Mask 
	//(48h--18) 
	case IOCTL_SERIAL_WAIT_ON_MASK: 
//		GTRACE((TLEVEL,"--IOCTL_SERIAL_WAIT_ON_MASK\n")); 
 
//		if (I.IoctlOutputBufferSize() < sizeof(ULONG) ) 
//			status = STATUS_BUFFER_TOO_SMALL; 
//		else if (m_WaitMask == 0) 
//			status = STATUS_INVALID_PARAMETER; 
//		else 
//			status = m_WaitIrpQueue.QueueIrp(I); 
			if((m_Unit&1)==0){ 
				*(ULONG*)I.IoctlBuffer()=(ULONG)m_pRW->MaskB; 
			//	if((ULONG)m_pRW->MaskB==1) 
			//		t<<"Wait on MaskB:"<<(ULONG)m_pRW->MaskB<MaskA; 
			//	if((ULONG)m_pRW->MaskA==1) 
			//		t<<"Wait on MaskA:"<<(ULONG)m_pRW->MaskA< SMALL_INTERVAL_CUTOFF) 
//			m_IntervalTimerPeriod = LONG_INTERVAL; 
//		else 
//			m_IntervalTimerPeriod = SHORT_INTERVAL; 
//	} 
} 
 
///////////////////////////////////////////////////////////////// 
// IoctlGetSpecialCharacters 
// 
VOID ComfilntDevice::IoctlGetSpecialCharacters(SERIAL_CHARS& Chars) 
{ 
	Chars = m_Chars; 
 
} 
 
///////////////////////////////////////////////////////////////// 
// IoctlSetSpecialCharacters 
// 
VOID ComfilntDevice::IoctlSetSpecialCharacters(SERIAL_CHARS& Chars) 
{ 
	m_Chars = Chars; 
} 
 
#if NTVERSION > 351 
///////////////////////////////////////////////////////////////// 
// IoctlGetStatistics 
// 
VOID ComfilntDevice::IoctlGetStatistics(SERIALPERF_STATS& Stats) 
{ 
	Stats = m_Statistics; 
} 
///////////////////////////////////////////////////////////////// 
// IoctlClearStatistics 
// 
VOID ComfilntDevice::IoctlClearStatistics(void) 
{ 
	RtlZeroMemory(&m_Statistics, sizeof(SERIALPERF_STATS)); 
} 
#endif 
 
///////////////////////////////////////////////////////////////// 
// IoctlGetWaitMask 
// 
ULONG ComfilntDevice::IoctlGetWaitMask(void) 
{ 
	 
	return m_WaitMask; 
} 
 
///////////////////////////////////////////////////////////////// 
// IoctlSetWaitMask 
// 
NTSTATUS ComfilntDevice::IoctlSetWaitMask(ULONG mask) 
{ 
	m_WaitMask = mask; 
	return STATUS_SUCCESS; 
} 
 
///////////////////////////////////////////////////////////////// 
// IoctlGetProperties 
// 
VOID ComfilntDevice::IoctlGetProperties(SERIAL_COMMPROP& Properties) 
{ 
} 
 
///////////////////////////////////////////////////////////////// 
// IoctlGetModemStatus 
// 
ULONG ComfilntDevice::IoctlGetModemStatus(void) 
{ 
	return 0; 
} 
 
///////////////////////////////////////////////////////////////// 
// IoctlGetCommStatus 
// 
VOID ComfilntDevice::IoctlGetCommStatus(SERIAL_STATUS& CommStatus) 
{ 
	CommStatus.Errors = 0; 
	CommStatus.HoldReasons = 0; 
	if((m_Unit & 1 )== 0){ 
		CommStatus.AmountInInQueue = m_pRW->PipeB.NumberOfItemsAvailableForRead(); 
		CommStatus.AmountInOutQueue = m_pRW->WriteCountA; 
	}else{ 
		CommStatus.AmountInInQueue = m_pRW->PipeA.NumberOfItemsAvailableForRead(); 
		CommStatus.AmountInOutQueue = m_pRW->WriteCountB; 
	} 
//	t << "COM=" <WriteCountA ; 
//	t << "; " << (ULONG)m_pRW->WriteCountB <>>>>>>>>>>>>>>>> " << EOL; 
	t << "Irp=" << I ; 
	t << "COM=" <PipeA.Flush(); 
			m_pRW->MaskA &=~SERIAL_EV_RXCHAR; 
			m_pRW->WriteCountA=0; 
		}else{ 
			m_pRW->PipeB.Flush(); 
			m_pRW->MaskB &=~SERIAL_EV_RXCHAR; 
			m_pRW->WriteCountB=0; 
		} 
	} 
	if (PurgeMask & SERIAL_PURGE_RXABORT) 
	{ 
		if((m_Unit&1)==0){ 
			m_pRW->PipeB.Flush(); 
			m_pRW->MaskB &=~SERIAL_EV_RXCHAR; 
			m_pRW->WriteCountB=0; 
		}else{ 
			m_pRW->PipeA.Flush(); 
			m_pRW->MaskA &=~SERIAL_EV_RXCHAR; 
			m_pRW->WriteCountA=0; 
		} 
	} 
}