// CprDrvr.h // // // Requires DDK Only // File created on 2/2/2005 // #ifndef __CPR_H__ #define __CPR_H__ // Needs to be passed in via -D //#define USE_WSK #ifdef GENERIC #define CPR_DRVR_VERSION "4.301.2.500" // 4.3.1.2 #elif SCPR #define CPR_DRVR_VERSION "4.302.2.500" // 4.3.2.2 //#elif x64 //#define CPR_DRVR_VERSION "4.304.2.500" // 4.3.4.2 #else #define CPR_DRVR_VERSION "4.300.2.500" // 4.3.0.2 #endif #define CPR_ROLLOVER_PATH _T("\\REGISTRY\\MACHINE\\SOFTWARE\\Classes\\Iflr") void DriverEntry_Wsk(); void CprUnload_Wsk(); //#ifdef CPR_DEBUG #if 0 #define CprAcquireSerialSpinLock(de,irql) { \ DbgPrint("Acquiring SerialLock Norm: %s %d\n", \ __FUNCTION__, __LINE__); \ KeAcquireSpinLock(&de->SerialLock,irql); \ RtlStringCchPrintfA( \ de->SerialLock_Acq, 50, "AcqN: %s %d\n", \ __FUNCTION__, __LINE__); \ DbgPrint(de->SerialLock_Acq); \ } #define CprAcquireSerialSpinLockAtDpcLevel(de) { \ DbgPrint("Acquiring SerialLock DpcL: %s %d\n", \ __FUNCTION__, __LINE__); \ KeAcquireSpinLockAtDpcLevel(&de->SerialLock); \ RtlStringCchPrintfA( \ de->SerialLock_Acq, 50, "AcqD: %s %d\n", \ __FUNCTION__, __LINE__); \ DbgPrint(de->SerialLock_Acq); \ } #define CprReleaseSerialSpinLock(de,irql) { \ DbgPrint("Releasing SerialLock Norm: %s %d\n", \ __FUNCTION__, __LINE__); \ KeReleaseSpinLock(&de->SerialLock,irql); \ RtlStringCchPrintfA( \ de->SerialLock_Rel, 50, "RelN: %s %d\n", \ __FUNCTION__, __LINE__); \ DbgPrint(de->SerialLock_Rel); \ } #define CprReleaseSerialSpinLockFromDpcLevel(de) { \ DbgPrint("Releasing SerialLock DpcL: %s %d\n", \ __FUNCTION__, __LINE__); \ KeReleaseSpinLockFromDpcLevel(&de->SerialLock); \ RtlStringCchPrintfA( \ de->SerialLock_Rel, 50, "RelD: %s %d\n", \ __FUNCTION__, __LINE__); \ DbgPrint(de->SerialLock_Rel); \ } #else #define CprAcquireSerialSpinLock(de,irql) KeAcquireSpinLock(&de->SerialLock,irql) #define CprAcquireSerialSpinLockAtDpcLevel(de) KeAcquireSpinLockAtDpcLevel(&de->SerialLock) #define CprReleaseSerialSpinLock(de,irql) KeReleaseSpinLock(&de->SerialLock,irql) #define CprReleaseSerialSpinLockFromDpcLevel(de) KeReleaseSpinLockFromDpcLevel(&de->SerialLock) #endif #define IoClearIrpPending( Irp ) ( \ IoGetCurrentIrpStackLocation( (Irp) )->Control &= ~SL_PENDING_RETURNED ) // Number of driver managed queues used by this driver #define NUMBER_OF_QUEUES 4 // Memory allocation pool tag #define CPR_POOL_TAG 'aDrC' // CrDa #define CPR_POOL_TAG_MISC 'iMrC' // CrMi #define CPR_POOL_TAG_LOOKASIDE 'ALrC' // CrLA #define CPR_POOL_TAG_EVENT 'vErC' // CrEv #define CPR_POOL_TAG_BUFFER 'uBrC' // CrBu #define CPR_POOL_TAG_UART 'aUrC' // CrUa #define CPR_POOL_TAG_DUMP 'uDrC' // CrDu #define CPR_POOL_TAG_REMAIN_BUF 'BRrC' // CrRB #define CPR_POOL_TAG_SESSION 'eSrC' // CrSe #define CPR_POOL_TAG_RFC2217 '22rC' // Cr22 #define CPR_POOL_TAG_RFC2217_BUF 'B2rC' // Cr2B #define CPR_POOL_TAG_REMOVAL 'eRrC' // CrRe #define CPR_POOL_TAG_KEEPALIVE 'AKrC' // CrKA #define CPR_POOL_TAG_KEEPALIVE_CONTEXT 'xKrC' // CrKx #define CPR_POOL_TAG_REG_PATH 'PRrC' // CrRP #define CPR_POOL_TAG_DRIVER_NAME 'rDrC' // CrDr #define CPR_POOL_TAG_REG_QUERY 'QRrC' // CrRQ #define CPR_POOL_TAG_REG_KEY 'KRrC' // CrRK #define CPR_POOL_TAG_ENUM_KEYS 'KErC' // CrEK #define CPR_POOL_TAG_DISPLAY_NAME 'NDrC' // CrDN #define CPR_POOL_TAG_REG_BUF 'BGrC' // CrGB #define CPR_POOL_TAG_NAME_BUF 'BNrC' // CrNB #define CPR_POOL_TAG_REM_CONTEXT 'CRrC' // CrRC #define CPR_POOL_TAG_PURGE_CONTEXT 'CPrC' // CrPC #define CPR_POOL_TAG_CON_INFO 'ICrC' // CrCI #define CPR_POOL_TAG_CON_CONTEXT 'CCrC' // CrCC #define CPR_POOL_TAG_CON_SOCKET 'SCrC' // CrCS #define CPR_POOL_TAG_SOCKET 'oSrC' // CrSo #define CPR_POOL_TAG_EA 'AErC' // CrEA #define CPR_POOL_TAG_RECON_CONTEXT 'xRrC' // CrRx #define CPR_POOL_TAG_COM_STATUS_IRP 'SCrC' // CrCS #define CPR_POOL_TAG_SYMBOLIC_LINK 'LSrC' // CrSL #define CPR_POOL_TAG_WMI_BUFFER 'BWrC' // CrWB #define CPR_POOL_TAG_OVERFLOW_CONTEXT 'COrC' // CrOC // Make all pool allocations tagged #undef ExAllocatePool #define ExAllocatePool(type, size) \ ExAllocatePoolWithTag(type, size, CPR_POOL_TAG_MISC); // set of defines to track irp usage #define CPR_IRPREF_IO 0x00000001 #define CPR_IRPREF_CANCEL 0x00000002 #define CPR_IRPREF_TIMER 0x00000004 #define CPR_IRPREF_INTERVAL 0x00000008 #define CPR_DEVEXT_RECONNECT 0x00000010 // set of defines to track the TransmitEmpty DPC // when UseRFC2217 is enabled and // TransmitEmpty == TX_EMPTY_SERVER #define CPR_TXEMPTY_CLEAR 0x00000000 #define CPR_TXEMPTY_DPC 0x00000001 #define CPR_TXEMPTY_CANCEL 0x00000002 #define CPR_TXEMPTY_MAX_WAIT 40 // special set of defines to inform interval timer // if cancel/timer/completion was executed #define CPR_COMPLETE_READ_CANCEL ((LONG)-1) #define CPR_COMPLETE_READ_TOTAL ((LONG)-2) #define CPR_COMPLETE_READ_COMPLETE ((LONG)-3) // Default xon/xoff characters. #define CPR_SERIAL_DEF_XON 0x11 #define CPR_SERIAL_DEF_XOFF 0x13 // Reasons that recption may be held up. #define CPR_SERIAL_RX_DTR 0x01 #define CPR_SERIAL_RX_XOFF 0x02 #define CPR_SERIAL_RX_RTS 0x04 #define CPR_SERIAL_RX_DSR 0x08 // Reasons that transmission may be held up. #define CPR_SERIAL_TX_CTS 0x01 #define CPR_SERIAL_TX_DSR 0x02 #define CPR_SERIAL_TX_DCD 0x04 #define CPR_SERIAL_TX_XOFF 0x08 #define CPR_SERIAL_TX_BREAK 0x10 //#define CPR_MAX_SERVICES 10 /////////////////////////////////////////////////////////////////////////////////////////////////// // TDI /////////////////////////////////////////////////////////////////////////////////////////////////// #define TCP_DEVICE_NAME _T("\\Device\\Tcp") #define UDP_DEVICE_NAME _T("\\Device\\Udp") #define RAWIP_DEVICE_NAME _T("\\Device\\RawIp") // server/client socket typedef struct _CPR_TDI_SOCKET { KEVENT RemoveEvent; // RefCount == 0 event LONG RefCount; // socket reference count LIST_ENTRY ListEntry; // list entry used by parent ConnectSocketList UNICODE_STRING ProtocolName; LIST_ENTRY IrpList; // preallocated irp pool KSPIN_LOCK IrpLock; // irp pool lock struct _CPR_UART *Uart; // Uart that has control of this socket PFILE_OBJECT ControlFileObject; // control transport file object PFILE_OBJECT ConnectionFileObject; // connection file object HANDLE ConnectionHandle; // connection handle PFILE_OBJECT AddressFileObject; // address file object HANDLE AddressHandle; // address handle USHORT LocalPort; // Local TCP Port. PIRP WriteTdiIrp; // Write Irp used for TDI communication. PIRP ImmediateTdiIrp; // Write Irp used for TDI communication. PIRP DirectTdiIrp; // Write Irp used for TDI communication. // used for tdi requests KEVENT Event; KEVENT WaitWriteEvent; KEVENT LtxLockEvent; // CPR can be used on Lantronix Devices Only IO_STATUS_BLOCK IoStatus; // used in stream server connect sockets struct _CPR_TDI_SOCKET* ListenSocket; // used in stream server listen sockets LIST_ENTRY ConnectSocketList; KSPIN_LOCK ConnectSocketLock; } CPR_TDI_SOCKET, *PCPR_TDI_SOCKET; typedef PCPR_TDI_SOCKET SOCKET; typedef struct _CPR_PROCESS_OVERFLOW_CONTEXT { PCPR_TDI_SOCKET socket; PUCHAR remainBuf; PMDL mdl; } CPR_PROCESS_OVERFLOW_CONTEXT, *PCPR_PROCESS_OVERFLOW_CONTEXT; NTSTATUS CprTdiStartup( IN PUNICODE_STRING ClientName ); VOID CprTdiCleanup( ); NTSTATUS CprTdiPnPPowerChange( IN PUNICODE_STRING DeviceName, IN PNET_PNP_EVENT PowerEvent, IN PTDI_PNP_CONTEXT Context1, IN PTDI_PNP_CONTEXT Context2 ); VOID CprTdiPnPBindingChange( IN TDI_PNP_OPCODE PnPOpcode, IN PUNICODE_STRING DeviceName, IN PWSTR MultiSZBindList ); VOID CprTdiPnPAddNetAddress( IN PTA_ADDRESS Address, IN PUNICODE_STRING DeviceName, IN PTDI_PNP_CONTEXT Context ); VOID CprTdiPnPDelNetAddress( IN PTA_ADDRESS Address, IN PUNICODE_STRING DeviceName, IN PTDI_PNP_CONTEXT Context ); NTSTATUS CprTdiOpen( IN PUNICODE_STRING ProtocolName, IN ULONG EaLength, IN PFILE_FULL_EA_INFORMATION Ea, OUT PHANDLE Handle, OUT PFILE_OBJECT* FileObject ); NTSTATUS CprTdiOpenAddress( IN PCPR_TDI_SOCKET Socket, IN PTRANSPORT_ADDRESS TransportAddress ); NTSTATUS CprTdiOpenConnection( IN PCPR_TDI_SOCKET Socket ); NTSTATUS CprTdiAssociateAddress( IN PCPR_TDI_SOCKET Socket ); NTSTATUS CprTdiDisassociateAddress( IN PCPR_TDI_SOCKET Socket ); NTSTATUS CprTdiConnect( IN PCPR_TDI_SOCKET Socket, IN PTDI_CONNECTION_INFORMATION RequestAddr, OUT PTDI_CONNECTION_INFORMATION ReturnAddr ); NTSTATUS CprTdiDisconnect( IN PCPR_TDI_SOCKET Socket, IN BOOLEAN Abort, IN PTDI_CONNECTION_INFORMATION RequestConnectionInfo, OUT PTDI_CONNECTION_INFORMATION ReturnConnectionInfo ); NTSTATUS CprTdiSend( IN PCPR_TDI_SOCKET Socket, IN ULONG Flags, IN PMDL Mdl, IN ULONG Length ); NTSTATUS CprTdiSendImmediate( IN PCPR_TDI_SOCKET Socket, IN ULONG Flags, IN PMDL Mdl, IN ULONG Length ); NTSTATUS CprTdiSendDirect( IN PCPR_TDI_SOCKET Socket, IN ULONG Flags, IN PMDL Mdl, IN ULONG Length, BOOLEAN Wait ); VOID CprTdiCancelSend( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); //NTSTATUS CprTdiSendNoWait( // IN PCPR_TDI_SOCKET Socket, // IN ULONG Flags, // IN PMDL Mdl, // IN ULONG Length // ); NTSTATUS CprTdiReceive( IN PCPR_TDI_SOCKET Socket, IN ULONG Flags, IN PMDL Mdl, IN ULONG Length ); NTSTATUS CprTdiSendDatagram( IN PCPR_TDI_SOCKET Socket, IN PMDL Mdl, IN ULONG Length, IN PTDI_CONNECTION_INFORMATION SendDatagramInfo, IN PLARGE_INTEGER Timeout ); NTSTATUS CprTdiReceiveDatagram( IN PCPR_TDI_SOCKET Socket, IN PMDL Mdl, IN ULONG Length, IN PTDI_CONNECTION_INFORMATION ReceiveDatagramInfo, OUT PTDI_CONNECTION_INFORMATION ReturnInfo ); NTSTATUS CprTdiListen( IN PCPR_TDI_SOCKET Socket, IN PTDI_CONNECTION_INFORMATION RequestConnectionInfo, OUT PTDI_CONNECTION_INFORMATION ReturnConnectionInfo ); NTSTATUS CprTdiAccept( IN PCPR_TDI_SOCKET Socket, IN PTDI_CONNECTION_INFORMATION RequestConnectionInfo, OUT PTDI_CONNECTION_INFORMATION ReturnConnectionInfo ); NTSTATUS CprTdiSetEventHandler( IN PCPR_TDI_SOCKET Socket, IN LONG EventType, IN PVOID EventHandler, IN PVOID EventContext ); NTSTATUS CprTdiQueryInformation( IN PCPR_TDI_SOCKET Socket, IN ULONG QueryType, IN PMDL Mdl ); NTSTATUS CprTdiSetInformation( IN PCPR_TDI_SOCKET Socket, IN ULONG SetType, IN PMDL Mdl ); NTSTATUS CprTdiSetKeepAlive( IN PCPR_TDI_SOCKET Socket, BOOLEAN onOff ); NTSTATUS CprTdiAction( IN PCPR_TDI_SOCKET Socket, IN PMDL Mdl ); NTSTATUS CprTdiEventConnect( IN PVOID TdiEventContext, IN LONG RemoteAddressLength, IN PVOID RemoteAddress, IN LONG UserDataLength, IN PVOID UserData, IN LONG OptionsLength, IN PVOID Options, OUT CONNECTION_CONTEXT* ConnectionContext, OUT PIRP* AcceptIrp ); NTSTATUS CprTdiEventDisconnect( IN PVOID TdiEventContext, IN CONNECTION_CONTEXT ConnectionContext, IN LONG DisconnectDataLength, IN PVOID DisconnectData, IN LONG DisconnectInformationLength, IN PVOID DisconnectInformation, IN ULONG DisconnectFlags ); NTSTATUS CprTdiEventReceive( IN PVOID TdiEventContext, IN CONNECTION_CONTEXT ConnectionContext, IN ULONG ReceiveFlags, IN ULONG BytesIndicated, IN ULONG BytesAvailable, OUT PULONG BytesTaken, IN PVOID Tsdu, OUT PIRP* Irp ); NTSTATUS CprTdiEventChainedReceive( IN PVOID TdiEventContext, IN CONNECTION_CONTEXT ConnectionContext, IN ULONG ReceiveFlags, IN ULONG ReceiveLength, IN ULONG StartingOffset, IN PMDL Tsdu, IN PVOID TsduDescriptor ); NTSTATUS CprTdiEventReceiveExpedited( IN PVOID TdiEventContext, IN CONNECTION_CONTEXT ConnectionContext, IN ULONG ReceiveFlags, IN ULONG BytesIndicated, IN ULONG BytesAvailable, OUT PULONG BytesTaken, IN PVOID Tsdu, OUT PIRP* IoRequestPacket ); NTSTATUS CprTdiEventChainedReceiveExpedited( IN PVOID TdiEventContext, IN CONNECTION_CONTEXT ConnectionContext, IN ULONG ReceiveFlags, IN ULONG ReceiveLength, IN ULONG StartingOffset, IN PMDL Tsdu, IN PVOID TsduDescriptor ); NTSTATUS CprTdiEventReceiveDatagram( IN PVOID TdiEventContext, IN LONG SourceAddressLength, IN PVOID SourceAddress, IN LONG OptionsLength, IN PVOID Options, IN ULONG ReceiveDatagramFlags, IN ULONG BytesIndicated, IN ULONG BytesAvailable, OUT PULONG BytesTaken, IN PVOID Tsdu, OUT PIRP* IoRequestPacket ); NTSTATUS CprTdiEventReceiveConfigDatagram( IN PVOID TdiEventContext, IN LONG SourceAddressLength, IN PVOID SourceAddress, IN LONG OptionsLength, IN PVOID Options, IN ULONG ReceiveDatagramFlags, IN ULONG BytesIndicated, IN ULONG BytesAvailable, OUT PULONG BytesTaken, IN PVOID Tsdu, OUT PIRP* IoRequestPacket ); NTSTATUS CprTdiEventReceiveMacResolutionDatagram( IN PVOID TdiEventContext, IN LONG SourceAddressLength, IN PVOID SourceAddress, IN LONG OptionsLength, IN PVOID Options, IN ULONG ReceiveDatagramFlags, IN ULONG BytesIndicated, IN ULONG BytesAvailable, OUT PULONG BytesTaken, IN PVOID Tsdu, OUT PIRP* IoRequestPacket ); NTSTATUS CprTdiEventChainedReceiveDatagram( IN PVOID TdiEventContext, IN LONG SourceAddressLength, IN PVOID SourceAddress, IN LONG OptionsLength, IN PVOID Options, IN ULONG ReceiveDatagramFlags, IN ULONG ReceiveDatagramLength, IN ULONG StartingOffset, IN PMDL Tsdu, IN PVOID TsduDescriptor ); NTSTATUS CprTdiEventSendPossible( IN PVOID TdiEventContext, IN PVOID ConnectionContext, IN ULONG BytesAvailable ); NTSTATUS CprTdiEventError( IN PVOID TdiEventContext, IN NTSTATUS Status ); NTSTATUS CprTdiEventErrorEx( IN PVOID TdiEventContext, IN NTSTATUS Status, IN PVOID Buffer ); __inline ULONG ntohl(ULONG value) { return RtlUlongByteSwap(value); } __inline ULONG htonl(ULONG value) { return RtlUlongByteSwap(value); } __inline USHORT ntohs(USHORT value) { return RtlUshortByteSwap(value); } __inline USHORT htons(USHORT value) { return RtlUshortByteSwap(value); } ULONG inet_addr( IN PCCHAR p ) ; BOOLEAN inet_ntoa( IN ULONG Address, OUT PCHAR Buffer, IN ULONG BufferLength ); BOOLEAN inet_ntow( IN ULONG Address, OUT PWCHAR Buffer, IN ULONG BufferLength ); NTSTATUS CprTdiAllocateIrpPool( IN PCPR_TDI_SOCKET Socket, IN ULONG IrpCount ); VOID CprTdiFreeIrpPool( IN PCPR_TDI_SOCKET Socket ); PIRP CprTdiAllocIrp( IN PCPR_TDI_SOCKET Socket ); VOID CprTdiFreeIrp( IN PCPR_TDI_SOCKET Socket, IN PIRP Irp ); PCPR_TDI_SOCKET CprTdiCreateSocket( IN PWSTR ProtocolName ); VOID CprTdiCloseSocket( IN PCPR_TDI_SOCKET Socket ); VOID CprTdiDeleteSocket( IN PCPR_TDI_SOCKET Socket ); NTSTATUS CprTdiAllocateConnectSocketPool( IN PCPR_TDI_SOCKET Socket, IN ULONG SocketCount ); VOID CprTdiFreeConnectSocketPool( IN PCPR_TDI_SOCKET Socket ); PCPR_TDI_SOCKET CprTdiAllocConnectSocket( IN PCPR_TDI_SOCKET Socket ); VOID CprTdiFreeConnectSocket( IN PCPR_TDI_SOCKET ConnectSocket ); VOID CprTdiAddRef( IN PCPR_TDI_SOCKET Socket ); VOID CprTdiRelease( IN PCPR_TDI_SOCKET Socket ); VOID CprTdiReleaseAndWait( IN PCPR_TDI_SOCKET Socket ); /////////////////////////////////////////////////////////////////////////////////////////////////// // virtual UART register flags /////////////////////////////////////////////////////////////////////////////////////////////////// // interrupt enable register #define CPR_UART_IER_RDA 0x01 #define CPR_UART_IER_THR 0x02 #define CPR_UART_IER_RLS 0x04 #define CPR_UART_IER_MS 0x08 // interrupt identification register #define CPR_UART_IIR_RLS 0x06 #define CPR_UART_IIR_RDA 0x04 #define CPR_UART_IIR_CTI 0x0c #define CPR_UART_IIR_THR 0x02 #define CPR_UART_IIR_MS 0x00 #define CPR_UART_IIR_FIFOS_ENABLED 0xc0 #define CPR_UART_IIR_NO_INTERRUPT_PENDING 0x01 // modem control register #define CPR_UART_MCR_DTR 0x01 #define CPR_UART_MCR_RTS 0x02 #define CPR_UART_MCR_OUT1 0x04 #define CPR_UART_MCR_OUT2 0x08 #define CPR_UART_MCR_LOOP 0x10 // modem status register #define CPR_UART_MSR_DCTS 0x01 #define CPR_UART_MSR_DDSR 0x02 #define CPR_UART_MSR_TERI 0x04 #define CPR_UART_MSR_DDCD 0x08 #define CPR_UART_MSR_CTS 0x10 #define CPR_UART_MSR_DSR 0x20 #define CPR_UART_MSR_RI 0x40 #define CPR_UART_MSR_DCD 0x80 // line status register #define CPR_UART_LSR_DR 0x01 #define CPR_UART_LSR_OE 0x02 #define CPR_UART_LSR_PE 0x04 #define CPR_UART_LSR_FE 0x08 #define CPR_UART_LSR_BI 0x10 #define CPR_UART_LSR_THRE 0x20 #define CPR_UART_LSR_TEMT 0x40 #define CPR_UART_LSR_FIFOERR 0x80 // line control register #define CPR_UART_LCR_DLAB 0x80 #define CPR_UART_LCR_BREAK 0x40 #define CPR_UART_LCR_5_DATA 0x00 #define CPR_UART_LCR_6_DATA 0x01 #define CPR_UART_LCR_7_DATA 0x02 #define CPR_UART_LCR_8_DATA 0x03 #define CPR_UART_LCR_DATA_MASK 0x03 #define CPR_UART_LCR_1_STOP 0x00 #define CPR_UART_LCR_1_5_STOP 0x04 #define CPR_UART_LCR_2_STOP 0x04 #define CPR_UART_LCR_STOP_MASK 0x04 #define CPR_UART_LCR_NONE_PARITY 0x00 #define CPR_UART_LCR_ODD_PARITY 0x08 #define CPR_UART_LCR_EVEN_PARITY 0x18 #define CPR_UART_LCR_MARK_PARITY 0x28 #define CPR_UART_LCR_SPACE_PARITY 0x38 #define CPR_UART_LCR_PARITY_MASK 0x38 // Currently, only Write only uses these #define CURRENT_IRP_STATUS_IDLE 0 #define CURRENT_IRP_STATUS_QUEUED 1 #define CURRENT_IRP_STATUS_TRANSMITTING 2 #define CURRENT_IRP_STATUS_TRANSMITTED 3 #define CURRENT_IRP_STATUS_COMPLETE 4 #define CURRENT_IRP_STATUS_REMOVED 5 // // Receive Buffer Macros // #define RxCount(pu) ((ULONG)(((pu)->RxWritePtr >= (pu)->RxReadPtr) \ ? ((pu)->RxWritePtr - (pu)->RxReadPtr) \ : (((pu)->RxEndBuffer - (pu)->RxReadPtr) + ((pu)->RxWritePtr - (pu)->RxBuffer)))) #define RxAvailableCount(pu) (PAGE_SIZE - RxCount(pu) - 1) #define RxBufferEmpty(pu) ((pu)->RxReadPtr == (pu)->RxWritePtr) #define RxDataAvailable(pu) ((pu)->RxReadPtr != (pu)->RxWritePtr) // // Transmit Buffer Macros // #define TxCount(pu) ((ULONG)(((pu)->TxWritePtr >= (pu)->TxReadPtr) \ ? ((pu)->TxWritePtr - (pu)->TxReadPtr) \ : (((pu)->TxEndBuffer - (pu)->TxReadPtr) + ((pu)->TxWritePtr - (pu)->TxBuffer)))) #define TxAvailableCount(pu) (PAGE_SIZE - TxCount(pu)) #define TxBufferEmpty(pu) ((pu)->TxReadPtr == (pu)->TxWritePtr) #define TxDataAvailable(pu) ((pu)->TxReadPtr != (pu)->TxWritePtr) #define TxOkToSend(pu) (((pu)->TxReadPtr != (pu)->TxWritePtr) && \ ((pu)->TxSendBegPtr == (pu)->TxSendEndPtr)) #define TxAmountToWrite(pu) ((ULONG)(((pu)->TxWritePtr >= (pu)->TxReadPtr) \ ? ((pu)->TxWritePtr - (pu)->TxReadPtr) \ : ((pu)->TxEndBuffer == (pu)->TxReadPtr) \ ? ((pu)->TxWritePtr - (pu)->TxBuffer) \ : ((pu)->TxEndBuffer - (pu)->TxReadPtr))) #define TxAmountToSend(pu) ((pu)->TxSendEndPtr - (pu)->TxReadPtr) // virtual uart structure typedef struct _CPR_UART { struct _CPR_DEVICE_EXTENSION* DeviceExtension; // pointer to device extension PUCHAR RxBuffer; // pointer to Rx buffer DAG: a circular buffer now. PUCHAR RxEndBuffer; // pointer to the end of the Rx buffer PUCHAR RxReadPtr; // Read pointer into Rx buffer PUCHAR RxWritePtr; // Write pointer into Rx buffer PUCHAR TxBuffer; // pointer to Tx buffer DAG: a circular buffer now. PUCHAR TxEndBuffer; // pointer to the end of the Tx buffer PUCHAR TxReadPtr; // Read pointer into Tx buffer PUCHAR TxWritePtr; // Write pointer into Tx buffer PUCHAR TxSendBegPtr; // Beginning of buffer sent to TDI PUCHAR TxSendEndPtr; // End of buffer sent to TDI ULONG TxTdiWriteLength; // Amount of data sent for current // write to TDI (UartWrite to CprTdiWriteComplete ULONG TxSerialWriteLength; // Amount of data sent from // WriteQueueStartIo to CprSerialWriteComplete ULONG TxRFC2217Additional; ULONG OverflowSize; // CprTdiEventReceive had no room to write incoming data // When there is room, call TDI_RECEIVE for remaining // data and set OverflowSize to 0 KDPC EventDpc; // dpc used to signal events ULONG BaudRate; // current baud rate UCHAR Ier; // interrupt enable UCHAR Fcr; // Fifo control UCHAR Lcr; // line control UCHAR Mcr; // model control UCHAR Lsr; // line status UCHAR Msr; // modem status BOOLEAN TxEmptyEvent; // tx completed BOOLEAN RxDataEvent; // new rx data BOOLEAN LineStatusEvent; // line status changed BOOLEAN ModemStatusEvent; // modem status changed } CPR_UART, *PCPR_UART; #define IS_WIN7_OR_GREATER (((g_Data.OsMajorVersion == 6) && (g_Data.OsMinorVersion >= 1)) || \ (g_Data.OsMajorVersion > 6)) // Windows OS Major Minor Build // -------------- ----- ----- ----- // 2000 5 0 2195 // 2000 Server 5 0 2195 // XP 5 1 2600 // 2003 Server 5 2 3790 // Vista 6 0 6000 // Windows 7 6 1 7600 // global (per driver) data block typedef struct _CPR_DATA { UNICODE_STRING RegistryPath; // saved registry path ULONG OsMajorVersion; // Windows OS Major Version ULONG OsMinorVersion; // Windows OS Minor Version ULONG OsBuildNumber; // Windows OS Build Number //RTL_OSVERSIONINFOEXW osVersion; BOOLEAN updateDriver; ULONG InstanceCount; // FDO instance count USHORT WdmVersion; // os version HANDLE BindingHandle; // tdi pnp callback handle PDEVICE_OBJECT BackdoorDevice; // Backdoor Device BOOLEAN PerformLockToLtx; // Perform Locking to Lantronix Devices int NumLtxRequests; // Number of times to try UDP request to device. int LtxRequestWaitTime; // Wait time in milliseconds ULONG ComStatus[NUM_COM_ULONGS]; // Status of Com Ports (Including network side) BOOLEAN AESEnabled; // Not saved in regular registry settings // will use some licensing/encryption scheme // to set this variable int MaxAesSessions; int CurAesSessions; BOOLEAN NoServiceRollover; // Only allow one service. #ifdef USE_WSK // Windows 7 on up Only. // Host Name Resolution BOOLEAN wskRegistred; WSK_REGISTRATION wskRegistration; // A pointer to a memory location that identifies a // WSK application's registration instance. This memory // location will be initialized by the WskRegister call // and will be used by the other WSK registration functions. BOOLEAN wskProviderValid; WSK_PROVIDER_NPI wskProviderNpi; // A pointer to the NPI returned by the WSK provider. // This WSK_PROVIDER_NPI structure contains a pointer // to the WSK provider dispatch table of WSK functions // that the WSK application can call. #endif } CPR_DATA, *PCPR_DATA; extern CPR_DATA g_Data; // PnP states typedef enum _CPR_PNP_STATE { PnpStateNotStarted = 0, PnpStateStarted, PnpStateStopPending, PnpStateStopped, PnpStateRemovePending, PnpStateRemoved, PnpStateSurpriseRemoved } CPR_PNP_STATE; // queue start io callback typedef VOID (*PCPR_QUEUE_STARTIO)( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); typedef VOID (*PCPR_QUEUE_STATUS_CHANGE)( IN PDEVICE_OBJECT DeviceObject, ULONG CurrentIrpStatus ); // irp queue type definition typedef struct _CPR_QUEUE { PCPR_QUEUE_STARTIO StartIoRoutine; PCPR_QUEUE_STATUS_CHANGE StatusChangeRoutine; PDEVICE_OBJECT DeviceObject; LIST_ENTRY IrpQueue; KSPIN_LOCK QueueLock; PIRP CurrentIrp; KEVENT StopEvent; LONG StallCount; NTSTATUS ErrorStatus; KDPC CprStartIoDpc; BOOLEAN bUseCprStartIoDpc; } CPR_QUEUE, *PCPR_QUEUE; extern PCPR_EVENT_LOG_BUFFER pEventLogBuffer; #define EventLogDataAvailable(ph) ((ph)->readNdx != (ph)->writeNdx) #define EventLogEmpty(ph) ((ph)->readNdx == (ph)->writeNdx) #define EventLogFull(ph) (((ph)->writeNdx == ((ph)->readNdx-1)) || \ (((ph)->readNdx == (ph)->begNdx) && \ ((ph)->writeNdx == ((ph)->endNdx-1)))) #define CprGetNextEventLog(pe) (EventLogFull(&(pe)->header)) \ ? NULL : &(pe)->eventLogs[(pe)->header.writeNdx] #define IncWritePtr(ph) (ph)->writeNdx = ((ph)->writeNdx == ((ph)->endNdx-1)) \ ? (ph)->begNdx \ : (ph)->writeNdx+1 // event log queue start io callback typedef VOID (*PCPR_EVENT_LOG_QUEUE_STARTIO)( IN PDEVICE_OBJECT DeviceObject, IN PCPR_EVENT_LOG_KERNEL pEventLog ); // Event Log queue type definition typedef struct _CPR_EVENT_LOG_QUEUE { LIST_ENTRY EventLogHead; KSPIN_LOCK QueueLock; NTSTATUS ErrorStatus; } CPR_EVENT_LOG_QUEUE, *PCPR_EVENT_LOG_QUEUE; // Event Log queue type definition typedef struct _CPR_EVENT_READ_IRP_QUEUE { LIST_ENTRY EventReadIrpHead; KSPIN_LOCK QueueLock; NTSTATUS ErrorStatus; } CPR_EVENT_READ_IRP_QUEUE, *PCPR_EVENT_READ_IRP_QUEUE; // cancel-safe irp list type definition typedef struct _CPR_LIST { PDEVICE_OBJECT DeviceObject; LIST_ENTRY IrpList; KSPIN_LOCK ListLock; NTSTATUS ErrorStatus; } CPR_LIST, *PCPR_LIST; // stall IRP list to syncronize Pnp, Power with // the rest of IO typedef struct _CPR_IO_LOCK { PDEVICE_OBJECT DeviceObject; // our device object KEVENT StallCompleteEvent; // io stalled event LIST_ENTRY StallIrpList; // stalled irps KSPIN_LOCK IoLock; // spin lock to syncronize io with stall/unstall LONG StallCount; // number of times stall was requested LONG ActiveIrpCount; // number of oustanding, not-stalled IRPs NTSTATUS ErrorStatus; PIRP CurrentIrp; // used by unstall code } CPR_IO_LOCK, *PCPR_IO_LOCK; #define IrpSessionId(irp) ((ULONG)(((ULONGLONG)((irp)->Tail.Overlay.DriverContext[1]))) & 0xFFFFFFFF) // The device extension for the device object typedef struct _CPR_DEVICE_EXTENSION { PDEVICE_OBJECT BackdoorDevice; // Points back to the Backdoor device PDEVICE_OBJECT DeviceObject; // pointer to the DeviceObject PDEVICE_OBJECT PhysicalDeviceObject; // underlying PDO PDEVICE_OBJECT LowerDeviceObject; // top of the device stack ULONG sessionId; // Terminal Services Session ID int portNumber; // Com Port Number ULONG UseRFC2217; // Registry dword variable ULONG DtrConnection; // Registry dword variable #define DTR_TO_DCD_DSR_ACTIVE 0 #define DTR_TO_DCD_DSR_INACTIVE 1 #define DTR_TO_DSR_DCD_ACTIVE 2 #define DTR_TO_DSR_DCD_INACTIVE 3 #define DTR_TO_DSR_AND_DCD 4 #define DTR_TO_NONE 5 ULONG AES; // Registry dword variable unsigned char AESKey[MAX_AES_KEY_LEN]; // Registry string variable ULONG AESKeyLength; // Registry dword variable ULONG AutoReconErr; // Registry dword variable Reconnect on timeout ULONG AutoReconPeer; // Registry dword variable Reconnect on Device Server Close ULONG CnTmo; // Registry dword variable ULONG NoDiscon; // Registry dword variable (No Net Close) ULONG ReconLimit; // Registry dword variable ULONG WaitOnWrite; // Registry dword variable ULONG BufferWrites; // Registry dword variable ULONG TransmitEmpty; // Registry dword variable #define TX_EMPTY_CPR 0 // CPR to Server #define TX_EMPTY_SERVER 1 // Server to Device ULONG ListenMode; #define LISTEN_MODE_NONE 0 // Not in lisen mode #define LISTEN_MODE_ONCE 1 // Listen once, disconnect will close #define LISTEN_MODE_AUTO 2 // Continuous listen ULONG NumServices; // Registry dword variable ULONG CurService; CPR_SERVICE Services[MAX_SERVICES]; // Registry string variable BOOLEAN Validated[MAX_SERVICES]; // Validated as a Lantronix Device. USHORT ListenMode_sin_port; ULONG ListenMode_in_addr; // No Net Close (NoDiscon) USHORT ComStatus; USHORT NetworkStatus; LONG OpenHandleCount; BOOLEAN IsDeviceEnabled; BOOLEAN IsDeviceOpening; BOOLEAN IsDeviceNegotiating; ULONG Instance; /* Keep Alive */ ULONG KeepAliveOnOff; // Registry dword variable ULONG KeepAliveTime; // Registry dword variable ULONG KeepAliveInterval; // Registry dword variable BOOLEAN BaudSent; BOOLEAN StopSent; BOOLEAN ParitySent; BOOLEAN DataSizeSent; BOOLEAN FlowSent; // Transmit Empty DPC for RFC2217 enabled // and TransmitEmpty = TX_EMPTY_SERVER // BOOLEAN TxWriteInProgress; ULONG TxEmptyWaitCount; ULONG TxEmptyRef; // owner count to syncronize cancel, timeout, and io completion BOOLEAN TxEmptyVerifyPending; KTIMER TxEmptyTimer; LARGE_INTEGER TxEmptyInitTimeout; LARGE_INTEGER TxEmptyTimeout; LARGE_INTEGER TxEmptyCurrentTimeout; KDPC TxEmptyDpc; BOOLEAN TxEmptyRequested; #ifdef BUFFER_STATE BOOLEAN BufferStatePending; #endif ULONG WriteIrpStatus; UCHAR LtxLockCount; UCHAR LtxLockInterval; UCHAR LtxLockTestAgain; ULONG ResolvedIpAddress; UCHAR MacAddress[6]; UCHAR DeviceId[2]; UCHAR PurgeResponse; CPR_TELNET_STATE TelnetState[MAX_TELNET_COMMANDS]; // uses bits, CPR_TELNET_STATE is 1 byte BOOLEAN Rfc2217Enabled; BOOLEAN Rfc2217OwnSignature; // If a loop back plug is on the device server // we would get our own signature. unsigned char LastFromNet; /* Last received byte */ unsigned char LastToNet; /* Last sent byte */ CPR_BUFFER_TYPE ToNetBuf; /* Effective status for IAC escaping and interpretation */ IACState IACEscape; // = IACNormal; /* Same as above during signature reception */ IACState IACSigEscape; /* Current IAC command begin received */ unsigned char IACCommand[TmpStrLen]; /* Modem state mask set by the client */ unsigned char ModemStateMask; // = ((unsigned char) 0xFF); /* Line state mask set by the client */ unsigned char LineStateMask; // = ((unsigned char) 0); /* Position of insertion into IACCommand[] */ size_t IACPos; BOOLEAN BreakSignaled; // = False; BOOLEAN InputFlow; // = True; BOOLEAN RemoteFlowOff; // = False; NTSTATUS Rfc2217WaitStatus; KEVENT Rfc2217SendEvent; // event to use in sending data KEVENT Rfc2217Event; // event to sync RFC2217 commands KTIMER Rfc2217Timer; LARGE_INTEGER Rfc2217Timeout; KDPC Rfc2217TimeoutDpc; KTIMER FlushBuffersTimer; LARGE_INTEGER FlushBuffersTimeout; KDPC FlushBuffersTimeoutDpc; BOOLEAN Closing; HANDLE DpcThreadId; BOOLEAN Cancelled; SOCKET socket; // TDI socket (PCPR_TDI_SOCKET) SOCKET ListenSocket; // TDI socket (PCPR_TDI_SOCKET) LONG RemoveCount; // 1-based reference count KEVENT RemoveEvent; // event to sync device removal CPR_IO_LOCK IoLock; // misc io lock CPR_PNP_STATE PnpState; // PnP state variable CPR_PNP_STATE PreviousPnpState; // Previous PnP state variable SYSTEM_POWER_STATE SystemPowerState; // current system power state DEVICE_POWER_STATE DevicePowerState; // current device power state DEVICE_CAPABILITIES DeviceCaps; // device capabilities used to get S to D mappings PIRP SystemPowerIrp; // Storage for system IRP during power transitions PIRP DevicePowerIrp; // Storage for device IRP during power transitions PIO_WORKITEM PowerWorkItem; // Work item used for power transitions LONG bPowerStop; // Flag to signal that power code stopped io PCPR_QUEUE QueueArray[NUMBER_OF_QUEUES]; // Array of our IRP queues WMILIB_CONTEXT WmiLibContext; // Context for wmi processing UNICODE_STRING WmiIdentifier; SERIAL_WMI_COMM_DATA WmiCommData; SERIAL_WMI_HW_DATA WmiHwData; SERIAL_WMI_PERF_DATA WmiPerfData; #ifdef CPR_DEBUG char SerialLock_Acq[50]; char SerialLock_Rel[50]; #endif KSPIN_LOCK SerialLock; // lock to syncronize access to serial interface UNICODE_STRING InterfaceName; // name returned from IoRegisterDeviceInterface UNICODE_STRING DeviceName; // name used in IoCreateDevice ULONG BaudRate; // baud rate SERIAL_CHARS SerialChars; // chars used for handshare flow control SERIAL_HANDFLOW SerialHandFlow; // handshake flow control SERIAL_TIMEOUTS Timeouts; // read and write request timeouts UCHAR DataMask; // bit word mask UCHAR EscapeChar; // escape char to prefix line or modem status SERIALPERF_STATS SerialStats; // statistics // reconnect KTIMER ReconnectTimer; // timer for reconnect work item KDPC ReconnectTimeoutDpc; // dpc called on timeout of reconnecting ULONG ReconnectRef; // syncronize reconnect USHORT ReconnectPort; // Local TCP Port that needs reconnecting. ULONG ReconnectAttempts; // if ReconLimit == 0 then forever // write KTIMER WriteTimer; // timer for write request CPR_QUEUE WriteQueue; // driver managed IRP queue ULONG WriteIrpRef; // owner count to syncronize cancel, timeout, and io completion KDPC WriteCompleteDpc; // dpc called on completion of write io KDPC WriteTimeoutDpc; // dpc called on timeout of write io PUCHAR WriteBuffer; // buffer of characters to transmit ULONG WriteLength; // size of write buffer BOOLEAN SystemWriteInProgress; // size of write when taken from the IRP system buffer ULONG PendingWriteCount; // amount of outstanding write data // DAG-TX-EMPTY //ULONG PendingWriteCountTxEmpty; // amount of outstanding write data // in regards to Tx Empty //ULONG WriteCompleteCount; // Used by Tx Empty from Device Server BOOLEAN WriteReceived; // Used for Tx Empty checking // immediate char write PIRP ImmediateCharIrp; ULONG ImmediateCharIrpRef; KTIMER ImmediateCharTimer; KDPC ImmediateCharCompleteDpc; KDPC ImmediateCharTimeoutDpc; UCHAR ImmediateChar; // xon/off write BOOLEAN SendXonChar; BOOLEAN SendXoffChar; // Xoff counter PIRP XoffIrp; ULONG XoffIrpRef; KTIMER XoffTimer; KDPC XoffTimeoutDpc; KDPC XoffCompleteDpc; LONG XoffCount; // read CPR_QUEUE ReadQueue; // driver managed IRP queue ULONG ReadIrpRef; KTIMER ReadTimer; KTIMER ReadIntervalTimer; KDPC ReadCompleteDpc; KDPC ReadTimeoutDpc; KDPC ReadIntervalTimeoutDpc; LARGE_INTEGER LastReadTime; LARGE_INTEGER IntervalTime; LARGE_INTEGER CutOverAmount; PLARGE_INTEGER IntervalTimeToUse; LARGE_INTEGER LongIntervalAmount; LARGE_INTEGER ShortIntervalAmount; ULONG QueueSize; // size of read queue ULONG QueueSizePt8; // .8 size of read queue PUCHAR QueueBuffer; // read queue buffer PUCHAR ReadBuffer; // current read buffer (either queue or read irp) PUCHAR ReadBufferEnd; // the end of read buffer ULONG ReadCount; // number of chars in read buffer PUCHAR ReadCharFirst; // first unread char in read buffer PUCHAR ReadCharLast; // last written char in read buffer + 1 ULONG ReadLength; // size of read irp buffer ULONG ReturnReadPhase; LONG IntervalReadCount; ULONG LastReadCount; // error handling KDPC ErrorDpc; ULONG ErrorWord; // event mask CPR_QUEUE MaskQueue; // queue to serialize mask irps ULONG WaitEvents; // set of serial events ULONG WaitMask; // current event mask PIRP WaitIrp; // IOCTL_SERIAL_WAIT_ON_MASK Irp ULONG WaitIrpRef; // mask to keep track who has access to irp PULONG IrpWaitMask; // pointer to ULONG in IOCTL_SERIAL_WAIT_ON_MASK Irp KDPC WaitCompleteDpc; // dpc used to complete IOCTL_SERIAL_WAIT_ON_MASK Irp // handflow control ULONG TxStopReason; ULONG RxStopReason; ULONG RxOverrun; // uart CPR_UART Uart; BOOLEAN TxIdle; // state of transmit engine from CPR to Device Server BOOLEAN TxImmediate; // TRUE, if there is an immediate character transmit is pending UCHAR LineControl; // purge support CPR_QUEUE PurgeQueue; // Set this flag when we have a successful Open. It indicates for the next read // to send the rijndael init vector if rijndael has been enabled. BOOLEAN AESInitVectorFlag; int InitRcvLen; int KeyLength; UCHAR KeyBytes[32]; cr_keyStruct AES_Encryption_Key; cr_block EncryptVector; cr_block DecryptVector; int EncryptLeft; int DecryptLeft; int MaxAESSessions; int CurAESSEssions; UCHAR TempReadBuf[PAGE_SIZE]; } CPR_DEVICE_EXTENSION, *PCPR_DEVICE_EXTENSION; /////////////////////////////////////////////////////////////////////////////////////////////////// // Backdoor /////////////////////////////////////////////////////////////////////////////////////////////////// typedef struct _BACKDOOR_DEVICE_EXTENSION { PDEVICE_OBJECT serialDevice[MAX_PORTS+1]; // pointers to our serial devices, // ones based ULONG numPorts; ULONG opened; KSPIN_LOCK Lock; // lock to syncronize access } BACKDOOR_DEVICE_EXTENSION, *PBACKDOOR_DEVICE_EXTENSION; NTSTATUS CprInitBackdoorDevice( PDRIVER_OBJECT DriverObject ); NTSTATUS NameResolution( __in PCWSTR NodeName, __in_opt PCWSTR ServiceName, __in_opt PADDRINFOEXW Hints, __in PWSK_PROVIDER_NPI WskProviderNpi, __out char *addrStr ); NTSTATUS ResolveHostName( PCPR_DEVICE_EXTENSION pDevExt, char* hostName ); VOID CprDeleteBackdoorDevice(); NTSTATUS CprBackdoorIoctl ( PDEVICE_OBJECT DeviceObject, PIRP Irp ); VOID CprInitializeEventLog(); VOID CprCloseDownEventLog(); PCPR_EVENT_LOG_KERNEL CprGetNewEventLog(); VOID CprReleaseEventLog( PCPR_EVENT_LOG_KERNEL pEventLog ); PVOID _CprEventLogAllocate( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag ); VOID _CprEventLogFree( PVOID Buffer ); #define CPR_EVENT_LOG_MAX 2000 //extern volatile ULONG CprEventLogFilter; //extern volatile ULONG CprELIoctlFilter; //extern volatile ULONG CprTraceFlags; //extern volatile ULONG CprEventFlags; //typedef struct _CPR_FILTER_DATA //{ // ULONG CprEventLogFilter; // Event Log Filter for Session // ULONG CprELIoctlFilter; // Event Log Ioctl Filter for Session // ULONG CprTraceFlags; // Trace flags for Session // ULONG CprEventFlags; // Event flags for Session // ULONG CprComPorts[8]; // ((8*4)bytes)*(8 bits)=256 bits // // to hold 256 com ports //} CPR_FILTER, *PCPR_FILTER; //#define USE_COM_STATUS_LIST #ifdef USE_COM_STATUS_LIST typedef struct _CPR_SESSION { ULONG SessionId; // Terminal Services ID BOOLEAN EventLogActive; // Status of Event Logging LIST_ENTRY EventLogIrpList; // Pending Event Log Irp (One at a time) CPR_EVENT_LOG_QUEUE EventLogQueue; // QueueEvents if Irp is unavailable CPR_FILTER_DATA FilterData; // Current Filter for Session LIST_ENTRY ListEntry; // Doubly-linked Session queue LIST_ENTRY ComStatusIrpList; // Pending Com Status Irp (One at a time) } CPR_SESSION, *PCPR_SESSION; typedef struct _CPR_IRP_LIST { HANDLE ProcessId; // ProcessId for adding and removing identification PIRP ComStatusIrp; // Pending Com Satus Irp LIST_ENTRY ListEntry; // Doubly-linked Session queue } CPR_IRP_LIST, *PCPR_IRP_LIST; #else typedef struct _CPR_SESSION { ULONG SessionId; // Terminal Services ID BOOLEAN EventLogActive; // Status of Event Logging PIRP EventLogIrp; // Pending Event Log Irp (One at a time) CPR_EVENT_LOG_QUEUE EventLogQueue; // QueueEvents if Irp is unavailable CPR_FILTER_DATA FilterData; // Current Filter for Session LIST_ENTRY ListEntry; // Doubly-linked Session queue PIRP ComStatusIrp; // Pending Com Status Irp (One at a time) } CPR_SESSION, *PCPR_SESSION; #endif typedef struct _CPR_SESSION_QUEUE { LIST_ENTRY ListHead; // Double-linked Session queue KSPIN_LOCK QueueLock; // QueueLock } CPR_SESSION_QUEUE, *PCPR_SESSION_QUEUE; // // CprLogEvent is a macro so that if event logging is off // there is no function call // extern CPR_SESSION_QUEUE gSessionQueue; #define LoggingEvent (!IsListEmpty(&gSessionQueue.ListHead)) #define CprLogEvent(t,s,d,st,m) {if (LoggingEvent) {_CprLogEvent(t,s,d,st,m);}} // // DO NOT CALL _CprLogEvent DIRECTLY!!!!!, USE THE CprLogEvent MACRO INSTEAD. // NTSTATUS _CprLogEvent( ULONG type, ULONG subType, PCPR_DEVICE_EXTENSION devExt, NTSTATUS status, char *msg ); char *StatusString( NTSTATUS Status ); void BackdoorEventLogCancelRoutine ( PDEVICE_OBJECT DeviceObject, PIRP Irp ); NTSTATUS BackdoorEventLogRead ( PIRP Irp ); int BackdoorEventLogDataAvailable ( PBACKDOOR_DEVICE_EXTENSION bdExt ); NTSTATUS GiveEventLogDataToApp ( PCPR_SESSION pSession ); //NTSTATUS //ReleaseEventLogApp(); void BackdoorCleanup ( PDEVICE_OBJECT DeviceObject, PIRP Irp ); void BackdoorCancelIrp ( PDEVICE_OBJECT DeviceObject, PIRP *ppIrp ); #ifdef __cplusplus extern "C" { #endif NTSTATUS __stdcall DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ); NTSTATUS __stdcall CprAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject ); NTSTATUS CprSerialReadSymName( IN PCPR_DEVICE_EXTENSION DeviceExtension, IN HANDLE Handle, OUT PUNICODE_STRING SymbolicLinkName, OUT PWCHAR* RegName ); NTSTATUS CprReadRegistry( IN PCPR_DEVICE_EXTENSION deviceExtension ); VOID __stdcall CprUnload( IN PDRIVER_OBJECT DriverObject ); NTSTATUS __stdcall CprPnpDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS CprHandleRemovalRelations( PDEVICE_OBJECT DeviceObject, PIRP Irp, PCPR_DEVICE_EXTENSION deviceExtension ); NTSTATUS __stdcall CprPowerDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS __stdcall CprDeviceIoControlDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS __stdcall CprCreateDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS __stdcall CprCloseDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS CprOpenPort( PCPR_DEVICE_EXTENSION deviceExtension, PIRP Irp ); NTSTATUS CprClosePort( PCPR_DEVICE_EXTENSION deviceExtension ); NTSTATUS __stdcall CprReadDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS __stdcall CprWriteDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS __stdcall CprWriteData( IN PIRP Irp, IN PCPR_DEVICE_EXTENSION deviceExtension ); NTSTATUS __stdcall CprCleanupDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS CprCleanupPort( PCPR_DEVICE_EXTENSION deviceExtension, IN PFILE_OBJECT FileObject ); NTSTATUS __stdcall CprSystemControlDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS __stdcall CprFlushBuffersDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); #ifdef __cplusplus } #endif NTSTATUS CprStartSerialDevice( IN PCPR_DEVICE_EXTENSION DeviceExtension, IN PIRP Irp ); NTSTATUS CprFreeSerialResources( IN PCPR_DEVICE_EXTENSION DeviceExtension ); BOOLEAN CprIsStoppable( IN PCPR_DEVICE_EXTENSION DeviceExtension ); BOOLEAN CprIsRemovable( IN PCPR_DEVICE_EXTENSION DeviceExtension ); BOOLEAN CprAcquireRemoveLock( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprReleaseRemoveLock( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprWaitForSafeRemove( IN PCPR_DEVICE_EXTENSION DeviceExtension ); NTSTATUS CprSubmitIrpSync( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID CprStallQueues( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprRestartQueues( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprQueueCancelAll( IN PCPR_QUEUE Queue ); BOOLEAN CprCancelTdiIrps( IN PCPR_DEVICE_EXTENSION pDevExt ); VOID CprFlushQueues( IN PCPR_DEVICE_EXTENSION DeviceExtension, IN PFILE_OBJECT FileObject ); VOID CprInitializeEventLogQueue( IN PCPR_EVENT_LOG_QUEUE EventLogQueue ); NTSTATUS CprQueueEventLog( IN PCPR_SESSION pSession, IN PCPR_EVENT_LOG_KERNEL pEventLog ); PCPR_EVENT_LOG_KERNEL CprDeQueueEventLog( IN PCPR_EVENT_LOG_QUEUE EventLogQueue ); PCPR_EVENT_LOG_KERNEL CprFindAndRemoveEventLog( IN PCPR_EVENT_LOG_QUEUE EventLogQueue, ULONG sessionId ); VOID CprFlushEventLogQueue( IN PCPR_EVENT_LOG_QUEUE EventLogQueue ); VOID CprInvalidateEventLogQueue( IN PCPR_EVENT_LOG_QUEUE EventLogQueue ); NTSTATUS CprQueueEventReadIrp( IN PCPR_EVENT_READ_IRP_QUEUE EventReadIrpQueue, IN PIRP pIrp ); PIRP CprDeQueueEventReadIrp( IN PCPR_EVENT_READ_IRP_QUEUE EventReadIrpQueue ); PIRP CprFindAnRemoveEventReadIrp( IN PCPR_EVENT_READ_IRP_QUEUE EventReadIrpQueue, IN ULONG sessionId ); VOID CprFlushEventReadIrpQueue( IN PCPR_EVENT_READ_IRP_QUEUE EventReadIrpQueue ); VOID CprInvalidateEventReadIrpQueue( IN PCPR_EVENT_READ_IRP_QUEUE EventReadIrpQueue ); /////////////////////////////////////////////////////////////////////////////////////////////////// // Iorw /////////////////////////////////////////////////////////////////////////////////////////////////// VOID WriteQueueStartIo( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID WriteQueueStatusChange( IN PDEVICE_OBJECT DeviceObject, ULONG CurrentIrpStatus ); VOID MaskQueueStartIo( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID MaskQueueStatusChange( IN PDEVICE_OBJECT DeviceObject, ULONG CurrentIrpStatus ); VOID ReadQueueStartIo( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID ReadQueueStatusChange( IN PDEVICE_OBJECT DeviceObject, ULONG CurrentIrpStatus ); VOID PurgeQueueStartIo( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID PurgeQueueStatusChange( IN PDEVICE_OBJECT DeviceObject, ULONG CurrentIrpStatus ); /////////////////////////////////////////////////////////////////////////////////////////////////// // Power /////////////////////////////////////////////////////////////////////////////////////////////////// typedef struct _CPR_POWER_IRP_CONTEXT { PKEVENT Event; NTSTATUS Status; } CPR_POWER_IRP_CONTEXT, *PCPR_POWER_IRP_CONTEXT; #ifdef __cplusplus extern "C" { #endif // __cplusplus NTSTATUS CprSystemPowerDispatch( IN PCPR_DEVICE_EXTENSION DeviceExtension, IN PIRP Irp ); NTSTATUS CprSystemPowerCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); NTSTATUS CprDeviceQueryPowerCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); NTSTATUS CprDeviceSetPowerCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); VOID CprDevicePowerCompleteCallback( IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus ); #ifdef __cplusplus } #endif // __cplusplus NTSTATUS CprGetDevicePowerState( IN PCPR_DEVICE_EXTENSION DeviceExtension, IN SYSTEM_POWER_STATE SystemState, OUT PDEVICE_POWER_STATE DeviceState ); VOID CprPowerDownPreparation( IN PCPR_DEVICE_EXTENSION DeviceExtension, IN PIO_WORKITEM_ROUTINE Callback ); VOID CprPowerDownPrepCallback( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context ); VOID CprPowerD0PrepCallback( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context ); VOID CprPowerUpCallback( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context ); VOID CprRequestDevicePowerIrpCallback( IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus ); NTSTATUS CprRequestDevicePowerIrp( IN PCPR_DEVICE_EXTENSION DeviceExtension, IN DEVICE_POWER_STATE DeviceState ); /////////////////////////////////////////////////////////////////////////////////////////////////// // Pnp /////////////////////////////////////////////////////////////////////////////////////////////////// // define this PnP IRP. This IRP is only defined in ntddk.h normally #if !defined(IRP_MN_QUERY_LEGACY_BUS_INFORMATION) #define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18 #endif // IRP_MN_QUERY_LEGACY_BUS_INFORMATION NTSTATUS CprStartDevice( IN PCPR_DEVICE_EXTENSION DeviceExtension, IN PIRP Irp ); NTSTATUS CprFreeResources( IN PCPR_DEVICE_EXTENSION DeviceExtension ); NTSTATUS CprGetDeviceCapabilities( IN PCPR_DEVICE_EXTENSION DeviceExtension ); /////////////////////////////////////////////////////////////////////////////////////////////////// // Wmi /////////////////////////////////////////////////////////////////////////////////////////////////// NTSTATUS CprWmiRegister( IN PCPR_DEVICE_EXTENSION DeviceExtension ); NTSTATUS CprWmiDeRegister( IN PCPR_DEVICE_EXTENSION DeviceExtension ); NTSTATUS CprWmiQueryReginfo( IN PDEVICE_OBJECT DeviceObject, OUT PULONG RegFlags, OUT PUNICODE_STRING InstanceName, OUT PUNICODE_STRING* RegistryPath, OUT PUNICODE_STRING MofResourceName, OUT PDEVICE_OBJECT* Pdo ); NTSTATUS CprWmiQueryDataBlock( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG InstanceCount, IN OUT PULONG InstanceLengthArray, IN ULONG BufferAvail, OUT PUCHAR Buffer ); NTSTATUS CprWmiSetDataBlock( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG BufferSize, IN PUCHAR Buffer ); NTSTATUS CprWmiSetDataItem( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG DataItemId, IN ULONG BufferSize, IN PUCHAR Buffer ); NTSTATUS CprWmiExecuteMethod( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG MethodId, IN ULONG InBufferSize, IN ULONG OutBufferSize, IN OUT PUCHAR Buffer ); NTSTATUS CprWmiFunctionControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN WMIENABLEDISABLECONTROL Function, IN BOOLEAN Enable ); /////////////////////////////////////////////////////////////////////////////////////////////////// // Debug /////////////////////////////////////////////////////////////////////////////////////////////////// // definition of debug levels //#define DBG_NONE 0 //#define DBG_ERR 1 //#define DBG_WARN 2 //#define DBG_TRACE 3 //#define DBG_INFO 4 //#define DBG_VERB 5 #ifdef CPR_WMI_TRACE /* tracepdb -f objchk_wxp_x86\i386\Cpr.pdb -p C:\Cpr SET TRACE_FORMAT_SEARCH_PATH=C:\Cpr tracelog -start Cpr -guid Cpr.ctl -f Cpr.log -flags 0x7FFFFFFF -level 5 tracelog -stop Cpr tracefmt -o Cpr.txt -f Cpr.log */ #define WPP_AREA_LEVEL_LOGGER(Area,Lvl) WPP_LEVEL_LOGGER(Area) #define WPP_AREA_LEVEL_ENABLED(Area,Lvl) (WPP_LEVEL_ENABLED(Area) && WPP_CONTROL(WPP_BIT_##Area).Level >= Lvl) #define WPP_CONTROL_GUIDS \ WPP_DEFINE_CONTROL_GUID(Cpr,(CDA7449C,0042,4B92,A931,3BBD5BD29F18), \ WPP_DEFINE_BIT(DBG_GENERAL) /* bit 0 = 0x00000001 */ \ WPP_DEFINE_BIT(DBG_PNP) /* bit 1 = 0x00000002 */ \ WPP_DEFINE_BIT(DBG_POWER) /* bit 2 = 0x00000004 */ \ WPP_DEFINE_BIT(DBG_COUNT) /* bit 3 = 0x00000008 */ \ WPP_DEFINE_BIT(DBG_CREATECLOSE) /* bit 4 = 0x00000010 */ \ WPP_DEFINE_BIT(DBG_WMI) /* bit 5 = 0x00000020 */ \ WPP_DEFINE_BIT(DBG_UNLOAD) /* bit 6 = 0x00000040 */ \ WPP_DEFINE_BIT(DBG_IO) /* bit 7 = 0x00000080 */ \ WPP_DEFINE_BIT(DBG_INIT) /* bit 8 = 0x00000100 */ \ WPP_DEFINE_BIT(DBG_READ) /* bit 9 = 0x00000200 */ \ WPP_DEFINE_BIT(DBG_WRITE) /* bit 10 = 0x00000400 */ \ WPP_DEFINE_BIT(DBG_11) /* bit 11 = 0x00000800 */ \ WPP_DEFINE_BIT(DBG_12) /* bit 12 = 0x00001000 */ \ WPP_DEFINE_BIT(DBG_13) /* bit 13 = 0x00002000 */ \ WPP_DEFINE_BIT(DBG_14) /* bit 14 = 0x00004000 */ \ WPP_DEFINE_BIT(DBG_15) /* bit 15 = 0x00008000 */ \ WPP_DEFINE_BIT(DBG_16) /* bit 16 = 0x00010000 */ \ WPP_DEFINE_BIT(DBG_17) /* bit 17 = 0x00020000 */ \ WPP_DEFINE_BIT(DBG_18) /* bit 18 = 0x00040000 */ \ WPP_DEFINE_BIT(DBG_19) /* bit 19 = 0x00080000 */ \ WPP_DEFINE_BIT(DBG_20) /* bit 20 = 0x00100000 */ \ WPP_DEFINE_BIT(DBG_21) /* bit 21 = 0x00200000 */ \ WPP_DEFINE_BIT(DBG_22) /* bit 22 = 0x00400000 */ \ WPP_DEFINE_BIT(DBG_23) /* bit 23 = 0x00800000 */ \ WPP_DEFINE_BIT(DBG_24) /* bit 24 = 0x01000000 */ \ WPP_DEFINE_BIT(DBG_25) /* bit 25 = 0x02000000 */ \ WPP_DEFINE_BIT(DBG_26) /* bit 26 = 0x04000000 */ \ WPP_DEFINE_BIT(DBG_27) /* bit 27 = 0x08000000 */ \ WPP_DEFINE_BIT(DBG_28) /* bit 28 = 0x10000000 */ \ WPP_DEFINE_BIT(DBG_29) /* bit 29 = 0x20000000 */ \ WPP_DEFINE_BIT(DBG_30) /* bit 30 = 0x40000000 */ \ WPP_DEFINE_BIT(DBG_31) /* bit 31 = 0x80000000 */ \ ) __inline VOID CprDumpIrp( IN PIRP Irp, PCPR_DEVICE_EXTENSION deviceExtension ) { } __inline PCHAR SystemPowerStateString( IN SYSTEM_POWER_STATE SystemState ) { return ""; } __inline PCHAR DevicePowerStateString( IN DEVICE_POWER_STATE DeviceState ) { return ""; } __inline VOID CprTdiDumpAddress( IN PTA_ADDRESS Address ) { return; } #else // definition of debug areas extern ULONG g_DebugLevel; extern ULONG g_DebugArea; //#define DBG_GENERAL (1 << 0) //#define DBG_PNP (1 << 1) //#define DBG_POWER (1 << 2) //#define DBG_COUNT (1 << 3) //#define DBG_CREATECLOSE (1 << 4) //#define DBG_WMI (1 << 5) //#define DBG_UNLOAD (1 << 6) //#define DBG_IO (1 << 7) //#define DBG_INIT (1 << 8) //#define DBG_READ (1 << 9) //#define DBG_WRITE (1 << 10) //#define DBG_ALL 0xFFFFFFFF #define Do_Debug_Print #ifdef Do_Debug_Print VOID CprDebugPrint( IN PCPR_DEVICE_EXTENSION pDevExt, IN ULONG Area, IN ULONG Level, IN PCCHAR Format, IN ... ); #define CprDebugPrint1(d,a,l,f,a1) CprDebugPrint(d,a,l,f,a1) #define CprDebugPrint2(d,a,l,f,a1,a2) CprDebugPrint(d,a,l,f,a1,a2) #define CprDebugPrint3(d,a,l,f,a1,a2,a3) CprDebugPrint(d,a,l,f,a1,a2,a3) #define CprDebugPrint4(d,a,l,f,a1,a2,a3,a4) CprDebugPrint(d,a,l,f,a1,a2,a3,a4) #define CprDebugPrint5(d,a,l,f,a1,a2,a3,a4,a5) CprDebugPrint(d,a,l,f,a1,a2,a3,a4,a5) #define CprDebugPrint6(d,a,l,f,a1,a2,a3,a4,a5,a6) CprDebugPrint(d,a,l,f,a1,a2,a3,a4,a5,a6) #define CprDebugPrint7(d,a,l,f,a1,a2,a3,a4,a5,a6,a7) CprDebugPrint(d,a,l,f,a1,a2,a3,a4,a5,a6,a7) #define CprDebugPrint8(d,a,l,f,a1,a2,a3,a4,a5,a6,a7,a8) CprDebugPrint(d,a,l,f,a1,a2,a3,a4,a5,a6,a7,a8) VOID CprDumpIrp( IN PIRP Irp, PCPR_DEVICE_EXTENSION deviceExtension ); VOID CprTdiDumpAddress( IN PTA_ADDRESS Address ); VOID CprDumpBuffer( IN char *str, IN PUCHAR buf, ULONG bufSize ); #else #define CprDebugPrint(d,a,l,f) #define CprDebugPrint1(d,a,l,f,a1) #define CprDebugPrint2(d,a,l,f,a1,a2) #define CprDebugPrint3(d,a,l,f,a1,a2,a3) #define CprDebugPrint4(d,a,l,f,a1,a2,a3,a4) #define CprDebugPrint5(d,a,l,f,a1,a2,a3,a4,a5) #define CprDebugPrint6(d,a,l,f,a1,a2,a3,a4,a5,a6) #define CprDebugPrint7(d,a,l,f,a1,a2,a3,a4,a5,a6,a7) #define CprDumpIrp(i,d) #define CprTdiDumpAddress(a) #define CprDumpBuffer(s,b,bs) #endif #define TDI_IRP_REFERENCE(irp) ((irp)->Tail.Overlay.DriverContext[1]) PCHAR IrpMajorFunctionString( IN UCHAR MajorFunction ); PCHAR PnPMinorFunctionString( IN UCHAR MinorFunction ); PCHAR PowerMinorFunctionString( IN UCHAR MinorFunction ); PCHAR SystemPowerStateString( IN SYSTEM_POWER_STATE SystemState ); PCHAR DevicePowerStateString( IN DEVICE_POWER_STATE DeviceState ); PCHAR WMIMinorFunctionString ( IN UCHAR MinorFunction ); #endif /////////////////////////////////////////////////////////////////////////////////////////////////// // Queue Functions /////////////////////////////////////////////////////////////////////////////////////////////////// VOID CprInitializeQueue( IN PCPR_QUEUE Queue, IN PCPR_QUEUE_STARTIO StartIoRoutine, IN PCPR_QUEUE_STATUS_CHANGE StatusChangeRoutine, IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN bUseCprStartIoDpc ); NTSTATUS CprQueueIrp( IN PCPR_QUEUE QueueExtension, IN PIRP Irp, BOOLEAN markPending ); VOID CprStartNext( IN PCPR_QUEUE QueueExtension ); VOID CprFlushQueue( IN PCPR_QUEUE QueueExtension, IN PFILE_OBJECT FileObject ); VOID CprInvalidateQueue( IN PCPR_QUEUE Queue, IN NTSTATUS ErrorStatus ); VOID CprPauseQueue( IN PCPR_QUEUE QueueExtension ); VOID CprRestartQueue( IN PCPR_QUEUE QueueExtension ); VOID CprStartIoDpc( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); VOID CprQueueCancelRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); /////////////////////////////////////////////////////////////////////////////////////////////////// // List functions /////////////////////////////////////////////////////////////////////////////////////////////////// VOID CprInitializeList( IN PCPR_LIST List, IN PDEVICE_OBJECT DeviceObject ); NTSTATUS CprInsertHead( IN PCPR_LIST List, IN PIRP Irp ); NTSTATUS CprInsertTail( IN PCPR_LIST List, IN PIRP Irp ); PIRP CprRemoveHead( IN PCPR_LIST List ); PIRP CprRemoveTail( IN PCPR_LIST List ); VOID CprFlushList( IN PCPR_LIST List, IN PFILE_OBJECT FileObject ); VOID CprInvalidateList( IN PCPR_LIST List, IN NTSTATUS ErrorStatus ); VOID CprListCancelRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); /////////////////////////////////////////////////////////////////////////////////////////////////// // CPR_IO_LOCK /////////////////////////////////////////////////////////////////////////////////////////////////// VOID CprInitializeIoLock( IN PCPR_IO_LOCK IoLock, IN PDEVICE_OBJECT DeviceObject ); NTSTATUS CprCheckIoLock( IN PCPR_IO_LOCK IoLock, IN PIRP Irp ); VOID CprPendingIoCancelRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS CprIncrementIoCount( IN PCPR_IO_LOCK IoLock ); VOID CprDecrementIoCount( IN PCPR_IO_LOCK IoLock ); VOID CprLockIo( IN PCPR_IO_LOCK IoLock ); VOID CprWaitForStopIo( IN PCPR_IO_LOCK IoLock ); VOID CprUnlockIo( IN PCPR_IO_LOCK IoLock ); VOID CprFlushPendingIo( IN PCPR_IO_LOCK IoLock, IN PFILE_OBJECT FileObject ); VOID CprInvalidateIo( IN PCPR_IO_LOCK IoLock, IN NTSTATUS ErrorStatus ); /////////////////////////////////////////////////////////////////////////////////////////////////// // Registry /////////////////////////////////////////////////////////////////////////////////////////////////// //PVOID CprRegQueryValueKey( // IN HANDLE RegKeyHandle, // IN PWSTR SubKeyName, // IN PWSTR ValueName, // OUT PULONG Length // ); NTSTATUS CprRegQueryValueKey( IN HANDLE RegKeyHandle, IN PWSTR SubKeyName, IN PWSTR ValueName, IN OUT PVOID RegValuePtr ); VOID CprRegEnumerateKeys( IN HANDLE RegKeyHandle ); VOID CprRegEnumerateValueKeys( IN HANDLE RegKeyHandle ); /////////////////////////////////////////////////////////////////////////////////////////////////// // virtual uart /////////////////////////////////////////////////////////////////////////////////////////////////// VOID CprUartEventDpcCallback( IN PKDPC Dpc, IN PVOID Context, IN PVOID SysArg1, IN PVOID SysArg2 ); NTSTATUS CprUartInitialize( IN PCPR_UART Uart, IN PCPR_DEVICE_EXTENSION DeviceExtension ); NTSTATUS CprUartReinitialize( IN PCPR_UART Uart, IN PCPR_DEVICE_EXTENSION DeviceExtension ); void CprDumpBufPtrs( IN PCPR_DEVICE_EXTENSION DeviceExtension, char *msg ); VOID CprUartFree( IN PCPR_UART Uart ); BOOLEAN CprUartIsLantronixDevice( IN PCPR_UART Uart, ULONG in_addr, BOOLEAN testOnly ); NTSTATUS CprUartUdpConfigPorts( IN PCPR_UART Uart, ULONG in_addr ); NTSTATUS CprResolveMacAddress( PCPR_UART Uart, char *macStr // size is IP_MAC_HOST_LEN ); NTSTATUS CprUartUdpPurgeBuffers( PCPR_DEVICE_EXTENSION pDevExt, BOOLEAN purgeRx, BOOLEAN purgeTx ); VOID CprUartUdpPurgeBuffers_WorkerRoutine( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context ); NTSTATUS CprUartConnect( IN PCPR_UART Uart, IN USHORT localPort ); NTSTATUS CprUartClose( IN PCPR_UART Uart ); VOID CprUartCheckEvents( IN PCPR_UART Uart ); NTSTATUS CprUartWrite( IN PCPR_UART Uart, IN UCHAR *Data, IN int Length ); NTSTATUS CprUartWriteImmediate( IN PCPR_UART Uart, IN UCHAR *Buffer ); NTSTATUS CprUartWriteDirect( IN PCPR_UART Uart, IN UCHAR *Buffer, IN int Length, BOOLEAN Wait, BOOLEAN okToEncrypt ); //NTSTATUS CprUartWriteNoWait( // IN PCPR_UART Uart, // IN UCHAR *Buffer, // IN int Length // ); UCHAR CprUartRead( IN PCPR_UART Uart ); ULONG CprUartReadBlock( IN PCPR_UART Uart, OUT PUCHAR Buf, IN ULONG BufSize ); UCHAR CprUartReadIIR( IN PCPR_UART Uart ); UCHAR CprUartReadLSR( IN PCPR_UART Uart ); UCHAR CprUartReadMSR( IN PCPR_UART Uart ); UCHAR CprUartReadMCR( IN PCPR_UART Uart ); VOID CprUartWriteMCR( IN PCPR_UART Uart, IN UCHAR Mcr ); UCHAR CprUartReadLCR( IN PCPR_UART Uart ); VOID CprUartWriteLCR( IN PCPR_UART Uart, IN UCHAR Lcr ); VOID CprUartStartWrite( IN PCPR_UART Uart ); VOID CprUartWriteIER( IN PCPR_UART Uart, IN UCHAR Ier ); /////////////////////////////////////////////////////////////////////////////////////////////////// // serial /////////////////////////////////////////////////////////////////////////////////////////////////// VOID CprSerialWriteComplete( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); VOID CprSerialCancelCurrentWrite( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID CprSerialStopCurrentWrite( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprSerialWriteTimeout( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); VOID CprTdiReconnectTimeout( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); VOID CprRfc2217Timeout( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); VOID CprResolveTimeout( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); VOID CprFlushBuffersTimeout( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); //VOID CprKeepAliveTimeout( // IN PKDPC Dpc, // IN PVOID Context, // IN PVOID Unused1, // IN PVOID Unused2 // ); VOID CprSerialReadComplete( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); VOID CprSerialCancelCurrentRead( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID CprSerialReadTimeout( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); VOID CprSerialReadIntervalTimeout( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); VOID CprSerialImmediateCharComplete( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); VOID CprSerialImmediateCharTimeout( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); VOID CprSerialCancelImmediate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS CprSerialStartImmediate( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprSerialStopImmediateChar( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprSerialCancelCurrentXoff( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID CprSerialStopXoff( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprSerialXoffTimeout( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); VOID CprSerialXoffComplete( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); VOID CprCancelWaitMask( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID CprSerialWaitComplete( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); VOID CprCheckForEmptyTransmitEvent( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprTxEmptyCheck( IN PKDPC Dpc, IN PVOID Context, IN PVOID SystemContext1, IN PVOID SystemContext2 ); VOID CprSerialError( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); NTSTATUS CprCheckForError( IN PCPR_DEVICE_EXTENSION DeviceExtension, IN PIRP Irp ); VOID CprUartEventDpcCallback( IN PKDPC Dpc, IN PVOID Context, IN PVOID Unused1, IN PVOID Unused2 ); VOID CprSerialPutChar( IN PCPR_DEVICE_EXTENSION DeviceExtension, IN UCHAR Data ); UCHAR CprSerialProcessLSR( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprSerialProcessDataReady( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprSerialProcessTransmitDone( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprSerialSetupNewHandFlow( IN PCPR_DEVICE_EXTENSION DeviceExtension, IN PSERIAL_HANDFLOW NewHandFlow ); ULONG CprSerialHandleModemUpdate( IN PCPR_DEVICE_EXTENSION DeviceExtension, IN BOOLEAN DoingTX ); VOID CprSerialTurnOnBreak( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprSerialTurnOffBreak( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprSerialSetDTR( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprSerialClrDTR( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprSerialSetRTS( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprSerialClrRTS( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprCheckForReceiveBufferChangedEvent( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprSerialProdXonXoff( IN PCPR_DEVICE_EXTENSION DeviceExtension, IN BOOLEAN SendXon ); NTSTATUS CprSerialResizeBuffer( IN PCPR_DEVICE_EXTENSION DeviceExtension, IN PIRP Irp ); VOID CprSerialGetCharsFromIntBuffer( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprSerialPretendXoff( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprSerialPretendXon( IN PCPR_DEVICE_EXTENSION DeviceExtension ); VOID CprSerialSetHandFlow( IN PCPR_DEVICE_EXTENSION DeviceExtension, IN PSERIAL_HANDFLOW HandFlow ); NTSTATUS CprSerialIoControl( IN PCPR_DEVICE_EXTENSION DeviceExtension, IN PIRP Irp ); char *UnicodeToAscii(TCHAR *uni); ULONG UnicodeToULong(TCHAR *tc); NTSTATUS CprTdiReconnect( IN PCPR_DEVICE_EXTENSION DeviceExtension ); NTSTATUS CprTdiStartReconnect( IN PCPR_DEVICE_EXTENSION DeviceExtension ); void ProcessOverflow( IN PCPR_UART Uart ); ULONG GetSessionId(); NTSTATUS CprQueueSession( IN PCPR_SESSION_QUEUE SessionIrpQueue, IN PCPR_SESSION pSession, IN BOOLEAN lock ); PCPR_SESSION CprDeQueueSession( IN PCPR_SESSION_QUEUE SessionIrpQueue ); PCPR_SESSION CprFindSession( IN PCPR_SESSION_QUEUE SessionIrpQueue, IN ULONG sessionId, IN BOOLEAN remove, IN BOOLEAN lock ); void CprCleanUpSessions(); void CprCleanUpSession(PCPR_SESSION pSession); NTSTATUS CprRfc2217_Negotiate( PCPR_DEVICE_EXTENSION deviceExtension ); NTSTATUS CprRfc2217_SendPortSettings( PCPR_DEVICE_EXTENSION devExt ); void CprRfc2217_SendOurSignature( PCPR_DEVICE_EXTENSION devExt ); void CprRfc2217_RequestSignature( PCPR_DEVICE_EXTENSION devExt ); NTSTATUS CprRfc2217_GetBuffer( CPR_BUFFER_TYPE *ToNetBuf, unsigned char **ppBuf, int *pLength ); void CprRfc2217_FreeBuffer( PCPR_DEVICE_EXTENSION devExt, unsigned char *pBuf ); NTSTATUS CprRfc2217_SendToNet( PCPR_DEVICE_EXTENSION devExt, BOOLEAN Wait ); void CprRfc2217_EscRedirectChar( PCPR_DEVICE_EXTENSION devExt, unsigned char C ); void CprRfc2217_SendBaudRate( PCPR_DEVICE_EXTENSION devExt, unsigned long int BR ); void CprRfc2217_SendCPCByteCommand( PCPR_DEVICE_EXTENSION devExt, unsigned char Command, unsigned char Parm ); unsigned char CprRfc2217_GetPortDataSize( PCPR_DEVICE_EXTENSION devExt ); unsigned char CprRfc2217_GetPortParity( PCPR_DEVICE_EXTENSION devExt ); unsigned char CprRfc2217_GetPortStopSize( PCPR_DEVICE_EXTENSION devExt ); unsigned char CprRfc2217_GetPortFlowControl( PCPR_DEVICE_EXTENSION devExt, unsigned char Which ); unsigned char CprRfc2217_GetModemState( PCPR_DEVICE_EXTENSION devExt ); unsigned char CprRfc2217_GetLineState( PCPR_DEVICE_EXTENSION devExt ); unsigned long int CprRfc2217_GetPortSpeed( PCPR_DEVICE_EXTENSION devExt ); void FillCommStatus( PBACKDOOR_DEVICE_EXTENSION bdExt, ULONG *comArray ); void ULongToIpStringW( ULONG in_addr, WCHAR *IpString, int IpStringLen ); PCPR_SESSION CreateSession( BOOLEAN lock ); void CopyComStatus( ULONG *comArray ); void ComStatusClear( int portNumber ); void ComStatusChange( PCPR_DEVICE_EXTENSION pDevExt, USHORT comStatus ); BOOLEAN AreComStatusEqual( ULONG *statusArg ); void NetworkStatusChange( PCPR_DEVICE_EXTENSION pDevExt, USHORT netStatus ); BOOLEAN HasComStatusChanged(); BOOLEAN CheckLineState( PCPR_DEVICE_EXTENSION devExt, unsigned char LState ); void RequestLineState( PCPR_DEVICE_EXTENSION devExt ); #endif // __CPR_H__