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; } } }