📄 serialdevice.h
字号:
#ifndef __SERIAL_DEVICE__
#define __SERIAL_DEVICE__
#include "precomp.h"
typedef KdTimer * PKdTimer;
typedef KdIrp * PKdIrp;
class KdSerialDevice;
typedef VOID (KdSerialDevice::*P_GET_NEXT_ROUTINE) (PKdIrp CurrentOpIrp,
PLIST_ENTRY QueueToProcess,
PKdIrp NewIrp,
BOOLEAN CompleteCurrent);
typedef struct _SERIAL_UPDATE_CHAR {
ULONG CharsCopied;
BOOLEAN Completed;
} SERIAL_UPDATE_CHAR,*PSERIAL_UPDATE_CHAR;
// The following three macros are used to initialize, set
// and clear references in IRPs that are used by
// this driver. The reference is stored in the fourth
// argument of the irp, which is never used by any operation
// accepted by this driver.
#define SERIAL_REF_ISR (0x00000001)
#define SERIAL_REF_CANCEL (0x00000002)
#define SERIAL_REF_TOTAL_TIMER (0x00000004)
#define SERIAL_REF_INT_TIMER (0x00000008)
#define SERIAL_REF_XOFF_REF (0x00000010)
#define SERIAL_INIT_REFERENCE(Irp) { \
ASSERT(sizeof(LONG) <= sizeof(PVOID)); \
(Irp).GetStackLocation()->Parameters.Others.Argument4 = NULL; }
#define SERIAL_SET_REFERENCE(Irp,RefType) \
do { \
LONG _refType = (RefType); \
PLONG _arg4 = (PLONG)((PVOID)&(Irp).GetStackLocation()->Parameters.Others.Argument4); \
ASSERT(!(*_arg4 & _refType)); \
*_arg4 |= _refType; \
} while (0)
#define SERIAL_CLEAR_REFERENCE(Irp,RefType) \
do { \
LONG _refType = (RefType); \
PLONG _arg4 = (PLONG)((PVOID)&(Irp).GetStackLocation()->Parameters.Others.Argument4); \
ASSERT(*_arg4 & _refType); \
*_arg4 &= ~_refType; \
} while (0)
#define SERIAL_REFERENCE_COUNT(Irp) \
((LONG)(((Irp).GetStackLocation()->Parameters.Others.Argument4)))
class KdSerialDevice : public KdDevice
{
public:
KdSerialDevice();
virtual ~KdSerialDevice();
virtual NTSTATUS DispatchCreate ( IN KdIrp &Irp );
virtual NTSTATUS DispatchClose ( IN KdIrp &Irp );
virtual NTSTATUS DispatchDeviceControl ( IN KdIrp &Irp );
virtual NTSTATUS DispatchRead ( IN KdIrp &Irp );
virtual NTSTATUS DispatchWrite ( IN KdIrp &Irp );
virtual NTSTATUS DispatchFlushBuffers ( IN KdIrp &Irp );
virtual NTSTATUS DispatchSetInformation ( IN KdIrp &Irp );
virtual NTSTATUS DispatchQueryInformation ( IN KdIrp &Irp );
virtual NTSTATUS DispatchCleanup ( IN KdIrp &Irp );
typedef NTSTATUS (KdSerialDevice::*PSERIAL_START_ROUTINE) ();
DEFINE_IRP_CANCEL_ROUTINE(KdSerialDevice, CancelCurrentRead);
DEFINE_IRP_CANCEL_ROUTINE(KdSerialDevice, CancelImmediate);
DEFINE_IRP_CANCEL_ROUTINE(KdSerialDevice, CancelQueued);
DEFINE_IRP_CANCEL_ROUTINE(KdSerialDevice, CancelWait);
DEFINE_IRP_CANCEL_ROUTINE(KdSerialDevice, CancelCurrentWrite);
DEFINE_IRP_CANCEL_ROUTINE(KdSerialDevice, CancelCurrentXoff);
NTSTATUS CompleteIfError(KdIrp Irp);
BOOLEAN DoesPortExist(KdString InsertString, ULONG ForceFifo, ULONG LogFifo);
NTSTATUS InitializeOneController(PCONFIG_DATA ConfigData, BOOLEAN MapInterruptStatus);
NTSTATUS InitializeController(PCONFIG_DATA ConfigData, BOOLEAN MapInterruptStatus);
VOID PropagateDeleteSharers(PULONG CountSoFar = NULL, PKINTERRUPT Interrupt = NULL);
VOID TryToCompleteCurrent(KDIRQ_SYNC_CALLBACK SynchRoutine,
KIRQL IrqlForRelease,
NTSTATUS StatusToUse,
PKdIrp CurrentOpIrp,
PLIST_ENTRY QueueToProcess,
PKdTimer IntervalTimer,
PKdTimer TotalTimer,
PSERIAL_START_ROUTINE Starter,
P_GET_NEXT_ROUTINE GetNextIrpRoutine,
LONG RefType);
VOID CompleteWrite (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
VOID CompleteRead (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
VOID ReadTimeout (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
VOID IntervalReadTimeout(PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
VOID WriteTimeout (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
VOID CommError (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
VOID CompleteImmediate (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
VOID TimeoutImmediate (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
VOID CompleteWait (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
VOID TimeoutXoff (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
VOID CompleteXoff (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
VOID StartTimerLowerRTS (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
VOID InvokePerhapsLowerRTS(PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
NTSTATUS StartWrite();
NTSTATUS StartRead();
NTSTATUS StartFlush();
NTSTATUS StartMask();
NTSTATUS StartPurge();
VOID StartImmediate();
VOID KillAllReadsOrWrites(PLIST_ENTRY QueueToClean, PKdIrp CurrentOpIrp);
VOID HandleReducedIntBuffer();
VOID ProdXonXoff( IN BOOLEAN SendXon );
VOID PutChar(IN UCHAR CharToPut);
UCHAR ProcessLSR();
ULONG HandleModemUpdate(IN BOOLEAN DoingTX);
BOOLEAN SetupNewHandFlow(IN PSERIAL_HANDFLOW NewHandFlow);
LARGE_INTEGER GetCharTime();
VOID GetProperties(IN PSERIAL_COMMPROP Properties);
NTSTATUS StartOrQueue(KdIrp Irp,
PLIST_ENTRY QueueToExamine,
PKdIrp CurrentOpIrp,
PSERIAL_START_ROUTINE Starter);
NTSTATUS GetDivisorFromBaud(LONG DesiredBaud, PSHORT pAppropriateDivisor = NULL);
ULONG GetCharsFromIntBuffer();
NTSTATUS ResizeBuffer();
ULONG MoveToNewIntBuffer(PUCHAR NewBuffer);
BOOLEAN IsrCallBack(KdIrq *Irq, PVOID Context);
BOOLEAN ISR(PVOID Context);
BOOLEAN SharerIsr(PVOID Context);
BOOLEAN IndexedMultiportIsr(PVOID Context);
BOOLEAN BitMappedMultiportIsr(PVOID Context);
BOOLEAN GiveWriteToIsr();
BOOLEAN GiveImmediateToIsr();
BOOLEAN GrabImmediateFromIsr();
BOOLEAN SetBaud(IN PVOID Context);
BOOLEAN Reset();
BOOLEAN SetLineControl();
BOOLEAN ProcessEmptyTransmit();
BOOLEAN GrabReadFromIsr();
BOOLEAN UpdateReadByIsr();
BOOLEAN UpdateInterruptBuffer(IN PVOID Context);
BOOLEAN UpdateAndSwitchToUser(IN PVOID Context);
BOOLEAN UpdateAndSwitchToNew(IN PVOID Context);
BOOLEAN SetDTR();
BOOLEAN ClrDTR();
BOOLEAN SetRTS();
BOOLEAN ClrRTS();
BOOLEAN SetChars(IN PVOID Context);
BOOLEAN SetHandFlow(IN PVOID Context);
BOOLEAN TurnOnBreak();
BOOLEAN TurnOffBreak();
BOOLEAN PretendXoff();
BOOLEAN PretendXon();
BOOLEAN GetModemUpdate(IN PVOID Context);
BOOLEAN GetCommStatus(IN PVOID Context);
BOOLEAN SetEscapeChar(IN PVOID Context);
BOOLEAN GetStats(IN PVOID Context);
BOOLEAN DecrementRTSCounter();
BOOLEAN MarkOpen();
BOOLEAN CheckOpen(IN PVOID Context);
BOOLEAN NullSynch();
BOOLEAN MarkClose();
BOOLEAN PurgeInterruptBuff();
BOOLEAN PerhapsLowerRTS();
BOOLEAN ClearStats();
BOOLEAN GrabWaitFromIsr();
BOOLEAN GiveWaitToIsr();
BOOLEAN FinishOldWait();
BOOLEAN GrabWriteFromIsr();
BOOLEAN GrabXoffFromIsr();
BOOLEAN GiveXoffToIsr();
VOID GetNextWrite(PKdIrp CurrentOpIrp,
PLIST_ENTRY QueueToProcess,
PKdIrp NewIrp,
BOOLEAN CompleteCurrent);
VOID GetNextIrp(PKdIrp CurrentOpIrp,
PLIST_ENTRY QueueToProcess,
PKdIrp NextIrp,
BOOLEAN CompleteCurrent);
VOID GetNextImmediate(KdIrp *CurrentOpIrp,
PLIST_ENTRY QueueToProcess,
KdIrp *NewIrp,
BOOLEAN CompleteCurrent);
typedef BOOLEAN (KdSerialDevice::*ISR_FUNCTION)(PVOID Context);
typedef struct _SERIAL_ISR_CONTEXT
{
ISR_FUNCTION pFunction;
PVOID Context;
} SERIAL_ISR_CONTEXT, *PSERIAL_ISR_CONTEXT;
/*********************************************************************************************
*********************************************************************************************/
// Holds & Reports the resources that the device needs
KdResources m_Resources;
// Mark this as registered device;
BOOLEAN m_fRegisteredDeviceMap;
// This holds the isr that should be called from our own
// dispatching isr for "cards" that are trying to share the
// same interrupt.
// This holds the context that should be used when we
// call the above service routine.
SERIAL_ISR_CONTEXT m_TopLevelIsr;
// This links together all of the different "cards" that are
// trying to share the same interrupt of a non-mca machine.
LIST_ENTRY m_TopLevelSharers;
// This circular doubly linked list links together all
// devices that are using the same interrupt object.
// NOTE: This does not mean that they are using the
// same interrupt "dispatching" routine.
LIST_ENTRY m_CommonInterruptObject;
// For reporting resource usage, we keep around the physical
// address we got from the registry.
PHYSICAL_ADDRESS m_OriginalController;
// For reporting resource usage, we keep around the physical
// address we got from the registry.
PHYSICAL_ADDRESS m_OriginalInterruptStatus;
// This value is set by the read code to hold the time value
// used for read interval timing. We keep it in the device
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -