📄 readwrit.c
字号:
// place <cr><lf>OK<cr><lf> in the buffer
PutCharInReadBuffer(DeviceExtension,'\r');
PutCharInReadBuffer(DeviceExtension,'\n');
PutCharInReadBuffer(DeviceExtension,'O');
PutCharInReadBuffer(DeviceExtension,'K');
PutCharInReadBuffer(DeviceExtension,'\r');
PutCharInReadBuffer(DeviceExtension,'\n');
}
}
break;
default:
break;
}
}
return;
}
VOID
PutCharInReadBuffer(
PDEVICE_EXTENSION DeviceExtension,
UCHAR Character
)
{
if (DeviceExtension->BytesInReadBuffer < READ_BUFFER_SIZE) {
// room in buffer
DeviceExtension->ReadBuffer[DeviceExtension->ReadBufferEnd]=Character;
DeviceExtension->ReadBufferEnd++;
DeviceExtension->ReadBufferEnd %= READ_BUFFER_SIZE;
DeviceExtension->BytesInReadBuffer++;
}
return;
}
VOID
ReadIrpWorker(
PDEVICE_OBJECT DeviceObject
)
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
NTSTATUS status=STATUS_UNSUCCESSFUL;
KIRQL OldIrql;
KeAcquireSpinLock( &deviceExtension->SpinLock, &OldIrql);
while ((deviceExtension->CurrentReadIrp == NULL)
&& !IsListEmpty(&deviceExtension->ReadQueue)) {
PLIST_ENTRY ListElement;
PIRP Irp;
PIO_STACK_LOCATION IrpSp;
KIRQL CancelIrql;
ListElement=RemoveHeadList( &deviceExtension->ReadQueue);
Irp=CONTAINING_RECORD(ListElement,IRP,Tail.Overlay.ListEntry);
IoAcquireCancelSpinLock(&CancelIrql);
if (Irp->Cancel) {
// this one has been canceled
Irp->IoStatus.Information=STATUS_CANCELLED;
IoReleaseCancelSpinLock(CancelIrql);
continue;
}
IoSetCancelRoutine(Irp, NULL);
IoReleaseCancelSpinLock(CancelIrql);
deviceExtension->CurrentReadIrp=Irp;
KeReleaseSpinLock(&deviceExtension->SpinLock, OldIrql);
TryToSatisfyRead( deviceExtension);
KeAcquireSpinLock(&deviceExtension->SpinLock, &OldIrql);
}
KeReleaseSpinLock( &deviceExtension->SpinLock, OldIrql);
return;
}
VOID
TryToSatisfyRead(
PDEVICE_EXTENSION DeviceExtension
)
{
NTSTATUS status=STATUS_UNSUCCESSFUL;
KIRQL OldIrql;
PIRP Irp=NULL;
PIO_STACK_LOCATION IrpSp;
ULONG BytesToMove;
ULONG FirstHalf;
ULONG SecondHalf;
KeAcquireSpinLock(
&DeviceExtension->SpinLock,
&OldIrql
);
if ((DeviceExtension->CurrentReadIrp != NULL) && (DeviceExtension->BytesInReadBuffer > 0)) {
//
// there is an IRP and there are characters waiting
//
Irp=DeviceExtension->CurrentReadIrp;
IrpSp=IoGetCurrentIrpStackLocation(Irp);
BytesToMove=IrpSp->Parameters.Read.Length < DeviceExtension->BytesInReadBuffer ?
IrpSp->Parameters.Read.Length : DeviceExtension->BytesInReadBuffer;
if (DeviceExtension->ReadBufferBegin+BytesToMove > READ_BUFFER_SIZE) {
//
// the buffer is wrapped around, have move in two pieces
//
FirstHalf=READ_BUFFER_SIZE-DeviceExtension->ReadBufferBegin;
SecondHalf=BytesToMove-FirstHalf;
RtlCopyMemory(
Irp->AssociatedIrp.SystemBuffer,
&DeviceExtension->ReadBuffer[DeviceExtension->ReadBufferBegin],
FirstHalf);
RtlCopyMemory(
(PUCHAR)Irp->AssociatedIrp.SystemBuffer+FirstHalf,
&DeviceExtension->ReadBuffer[0], SecondHalf);
} else {
//
// can do it all at once
//
RtlCopyMemory(
Irp->AssociatedIrp.SystemBuffer,
&DeviceExtension->ReadBuffer[DeviceExtension->ReadBufferBegin],
BytesToMove);
}
//
// fix up queue pointers
//
DeviceExtension->BytesInReadBuffer-=BytesToMove;
DeviceExtension->ReadBufferBegin+= BytesToMove;
DeviceExtension->ReadBufferBegin %= READ_BUFFER_SIZE;
Irp->IoStatus.Information=BytesToMove;
}
KeReleaseSpinLock( &DeviceExtension->SpinLock, OldIrql);
if (Irp != NULL) {
//
// if irp isn't null, then we handled one
//
RemoveReferenceAndCompleteRequest(
DeviceExtension->DeviceObject, Irp, STATUS_SUCCESS);
DeviceExtension->CurrentReadIrp=NULL;
}
return;
}
VOID
WriteCancelRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
NTSTATUS status=STATUS_UNSUCCESSFUL;
KIRQL OldIrql;
//
// release the cancel spinlock to avaoid deadlocks with deviceextension spinlock
//
IoReleaseCancelSpinLock(Irp->CancelIrql);
KeAcquireSpinLock( &deviceExtension->SpinLock, &OldIrql);
if (Irp->IoStatus.Information != STATUS_CANCELLED) {
//
// the irp is still in the queue, remove it
//
RemoveEntryList( &Irp->Tail.Overlay.ListEntry);
}
KeReleaseSpinLock( &deviceExtension->SpinLock, OldIrql);
Irp->IoStatus.Information = 0;
RemoveReferenceAndCompleteRequest( DeviceObject, Irp, STATUS_CANCELLED);
return;
}
VOID
ReadCancelRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
NTSTATUS status=STATUS_UNSUCCESSFUL;
KIRQL OldIrql;
// release the cancel spinlock to avoid deadlocks with deviceextension spinlock
IoReleaseCancelSpinLock(Irp->CancelIrql);
KeAcquireSpinLock( &deviceExtension->SpinLock, &OldIrql);
if (Irp->IoStatus.Information != STATUS_CANCELLED) {
// the irp is still in the queue, remove it
RemoveEntryList( &Irp->Tail.Overlay.ListEntry);
}
KeReleaseSpinLock( &deviceExtension->SpinLock, OldIrql);
Irp->IoStatus.Information = 0;
RemoveReferenceAndCompleteRequest( DeviceObject, Irp, STATUS_CANCELLED);
return;
}
VOID
ProcessConnectionStateChange(
IN PDEVICE_OBJECT DeviceObject
)
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
KIRQL OldIrql;
PIRP CurrentWaitIrp=NULL;
KeAcquireSpinLock( &deviceExtension->SpinLock, &OldIrql);
if (deviceExtension->ConnectionStateChanged) {
//
// state changed
//
deviceExtension->ConnectionStateChanged=FALSE;
if (deviceExtension->CurrentlyConnected) {
//
// now it is connected, raise CD
//
deviceExtension->ModemStatus |= SERIAL_DCD_STATE;
} else {
//
// not connected any more, clear CD
//
deviceExtension->ModemStatus &= ~(SERIAL_DCD_STATE);
}
if (deviceExtension->CurrentMask & SERIAL_EV_RLSD) {
//
// app want's to know about these changes, tell it
//
CurrentWaitIrp=deviceExtension->CurrentMaskIrp;
deviceExtension->CurrentMaskIrp=NULL;
}
}
KeReleaseSpinLock( &deviceExtension->SpinLock, OldIrql);
if (CurrentWaitIrp != NULL) {
D_TRACE(DbgPrint("FAKEMODEM: ProcessConectionState\n");)
*((PULONG)CurrentWaitIrp->AssociatedIrp.SystemBuffer)=SERIAL_EV_RLSD;
CurrentWaitIrp->IoStatus.Information=sizeof(ULONG);
RemoveReferenceAndCompleteRequest(
deviceExtension->DeviceObject, CurrentWaitIrp, STATUS_SUCCESS);
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -