📄 hellowdm.cpp
字号:
PIRP Irp)
{
PAGED_CODE();
NTSTATUS ntStatus = STATUS_SUCCESS;// Assume success
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
KIRQL OldIrql;
Irp->IoStatus.Information = 0;
ntStatus = STATUS_SUCCESS;
PrintIoControlCode(irpSp->Parameters.DeviceIoControl.IoControlCode);
switch ( irpSp->Parameters.DeviceIoControl.IoControlCode )
{
case IOCTL_SERIAL_SET_BAUD_RATE:
{
pdx->BaudRate = ((PSERIAL_BAUD_RATE)(Irp->AssociatedIrp.SystemBuffer))->BaudRate;
Irp->IoStatus.Information = 0;
break;
}
case IOCTL_SERIAL_GET_BAUD_RATE:
{
PSERIAL_BAUD_RATE Br = (PSERIAL_BAUD_RATE)Irp->AssociatedIrp.SystemBuffer;
Br->BaudRate = pdx->BaudRate;
Irp->IoStatus.Information = sizeof(SERIAL_BAUD_RATE);
break;
}
case IOCTL_SERIAL_SET_RTS:
{
pdx->RTSstate = 1;
break;
}
case IOCTL_SERIAL_CLR_RTS:
{
pdx->RTSstate = 0;
break;
}
case IOCTL_SERIAL_SET_DTR:
{
pdx->DTRstate = 1;
break;
}
case IOCTL_SERIAL_CLR_DTR:
{
pdx->DTRstate = 0;
break;
}
case IOCTL_SERIAL_GET_DTRRTS:
{
ULONG ModemControl;
ModemControl = pdx->DTRstate + (pdx->RTSstate<<1);
*(PULONG)Irp->AssociatedIrp.SystemBuffer = ModemControl;
Irp->IoStatus.Information = sizeof(ULONG);
break;
}
case IOCTL_SERIAL_GET_MODEMSTATUS:
{
ULONG Cts, Dsr, Dcd;
Cts = 1; //对方传送请求 //pdx->pOther->RTSstate;
Dsr = 1; //对方数据终端是否准备好 //pdx->pOther->DTRstate;
Dcd = 1; //对方设备是否打开 //pdx->pOther->IsOpen;
*(PULONG)Irp->AssociatedIrp.SystemBuffer =
(Cts ? SERIAL_CTS_STATE : 0) | (Dsr ? SERIAL_DSR_STATE : 0) |
(Dcd ? SERIAL_DCD_STATE : 0);
Irp->IoStatus.Information = sizeof(ULONG);
break;
}
case IOCTL_SERIAL_SET_TIMEOUTS:
{
pdx->Timeouts = *((PSERIAL_TIMEOUTS)(Irp->AssociatedIrp.SystemBuffer));
break;
}
case IOCTL_SERIAL_GET_TIMEOUTS:
{
*((PSERIAL_TIMEOUTS)Irp->AssociatedIrp.SystemBuffer) = pdx->Timeouts;
Irp->IoStatus.Information = sizeof(SERIAL_TIMEOUTS);
break;
}
case IOCTL_SERIAL_RESET_DEVICE:
{
break;
}
case IOCTL_SERIAL_PURGE:
{
break;
}
case IOCTL_SERIAL_SET_LINE_CONTROL:
{
pdx->Lc = *((PSERIAL_LINE_CONTROL)(Irp->AssociatedIrp.SystemBuffer));
break;
}
case IOCTL_SERIAL_GET_LINE_CONTROL:
{
*((PSERIAL_LINE_CONTROL)(Irp->AssociatedIrp.SystemBuffer)) = pdx->Lc;
Irp->IoStatus.Information = sizeof(SERIAL_LINE_CONTROL);
break;
}
case IOCTL_SERIAL_SET_WAIT_MASK:
{
PIRP pOldWaitIrp;
PDRIVER_CANCEL pOldCancelRoutine;
pdx->EventMask = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
KeAcquireSpinLock(&pdx->IoctlSpinLock, &OldIrql);
pOldWaitIrp = pdx->pWaitIrp;
if (pOldWaitIrp != NULL)
{
pOldCancelRoutine = IoSetCancelRoutine(pOldWaitIrp, NULL);
//对以前没有进行完成例程的等待irp,进行完成
if (pOldCancelRoutine != NULL)
{
pOldWaitIrp->IoStatus.Information = sizeof(ULONG);
*(PULONG)pOldWaitIrp->AssociatedIrp.SystemBuffer = 0;
pOldWaitIrp->IoStatus.Status = STATUS_SUCCESS;
pdx->pWaitIrp = NULL;
}
else
{
pOldWaitIrp = NULL;
}
}
KeReleaseSpinLock(&pdx->IoctlSpinLock, OldIrql);
if (pOldWaitIrp != NULL)
{
IoCompleteRequest(pOldWaitIrp, IO_NO_INCREMENT);
}
break;
}
case IOCTL_SERIAL_GET_WAIT_MASK:
{
*(PULONG)Irp->AssociatedIrp.SystemBuffer = pdx->EventMask;
Irp->IoStatus.Information = sizeof(ULONG);
break;
}
case IOCTL_SERIAL_WAIT_ON_MASK:
{
PDRIVER_CANCEL pOldCancelRoutine;
KeAcquireSpinLock(&pdx->IoctlSpinLock, &OldIrql);
//等待irp一定被清除,且eventMask一定不为0
if ((pdx->pWaitIrp != NULL) || (pdx->EventMask == 0))
ntStatus = STATUS_INVALID_PARAMETER;
else if ((pdx->EventMask & pdx->HistoryEvents) != 0)
{
// Some events happened
Irp->IoStatus.Information = sizeof(ULONG);
*(PULONG)Irp->AssociatedIrp.SystemBuffer = pdx->EventMask & pdx->HistoryEvents;
pdx->HistoryEvents = 0;
ntStatus = STATUS_SUCCESS;
}else
{
pdx->pWaitIrp = Irp;
ntStatus = STATUS_PENDING;
IoSetCancelRoutine(Irp, DriverCancelWaitIrp);
if (Irp->Cancel)
{
pOldCancelRoutine = IoSetCancelRoutine(Irp, NULL);
if (pOldCancelRoutine != NULL)
{
ntStatus = STATUS_CANCELLED;
pdx->pWaitIrp = NULL;
}
else
{
IoMarkIrpPending(Irp);
}
}
else
{
IoMarkIrpPending(Irp);
}
}
KeReleaseSpinLock(&pdx->IoctlSpinLock, OldIrql);
break;
}
case IOCTL_SERIAL_GET_COMMSTATUS:
{
PSERIAL_STATUS pStatus = (PSERIAL_STATUS)Irp->AssociatedIrp.SystemBuffer;
ULONG InputLen;
KeAcquireSpinLock(&pdx->WriteSpinLock, &OldIrql);
InputLen = pdx->uReadWrite;
KeReleaseSpinLock(&pdx->WriteSpinLock, OldIrql);
RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer, sizeof(SERIAL_STATUS));
pStatus->AmountInInQueue = InputLen;
pStatus->AmountInOutQueue = 0;
Irp->IoStatus.Information = sizeof(SERIAL_STATUS);
break;
}
case IOCTL_SERIAL_GET_CHARS:
{
RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer, sizeof(SERIAL_CHARS));
Irp->IoStatus.Information = sizeof(SERIAL_CHARS);
break;
}
case IOCTL_SERIAL_GET_HANDFLOW:
{
break;
}
default:
{
break;
}
}
Irp->IoStatus.Status = ntStatus;
if (ntStatus!=STATUS_PENDING)
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return ntStatus;
}
#pragma PAGEDCODE
NTSTATUS HelloWDMClose(IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
PAGED_CODE();
KdPrint(("HelloWDMClose()\n"));
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pdx->pWaitIrp = NULL;
pdx->pReadIrp = NULL;
pdx->IsOpen = FALSE;
pdx->uReadWrite = 0;
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
VOID DriverCancelCurrentReadIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp)
{
PDEVICE_EXTENSION pExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
KIRQL OldIrql;
IoReleaseCancelSpinLock(pIrp->CancelIrql);
KeAcquireSpinLock(&pExtension->WriteSpinLock, &OldIrql);
pExtension->pReadIrp = NULL;
KeReleaseSpinLock(&pExtension->WriteSpinLock, OldIrql);
pIrp->IoStatus.Status = STATUS_CANCELLED;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
}
NTSTATUS HelloWDMRead(IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
KdPrint(("HelloWDMRead\n"));
NTSTATUS ntStatus = STATUS_SUCCESS;// Assume success
PDEVICE_EXTENSION pExtension = (PDEVICE_EXTENSION)fdo->DeviceExtension;
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
ULONG BufLen = irpSp->Parameters.Read.Length;
PCHAR pBuf = (PCHAR)Irp->AssociatedIrp.SystemBuffer;
KIRQL OldIrql;
PDRIVER_CANCEL pOldCancelRoutine;
Irp->IoStatus.Information = 0;
DbgPrint("DeviceObject:%08X Read\n",fdo);
if (BufLen == 0)
{
ntStatus = STATUS_SUCCESS;
}
else
{
KeAcquireSpinLock(&pExtension->WriteSpinLock, &OldIrql);
RtlCopyMemory(pBuf,pExtension->Buffer,BufLen);
Irp->IoStatus.Information = BufLen;
if (BufLen==0 && pExtension->pReadIrp==NULL) // nothing, store
{
pExtension->pReadIrp = Irp;
Irp->IoStatus.Status = ntStatus = STATUS_PENDING;
IoSetCancelRoutine(Irp, DriverCancelCurrentReadIrp);
if (Irp->Cancel)
{
pOldCancelRoutine = IoSetCancelRoutine(Irp, NULL);
if (pOldCancelRoutine != NULL)
{
// Nein, also IRP hier abbrechen
Irp->IoStatus.Status = ntStatus = STATUS_CANCELLED;
pExtension->pReadIrp = NULL;
}
else
{
// Ja, Cancel-Routine wird Request beenden
IoMarkIrpPending(Irp);
}
}
else
{
IoMarkIrpPending(Irp);
}
}
KeReleaseSpinLock(&pExtension->WriteSpinLock, OldIrql);
}
Irp->IoStatus.Status = ntStatus;
if (ntStatus != STATUS_PENDING)
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return ntStatus;
}
NTSTATUS HelloWDMWrite(IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
KdPrint(("HelloWDMWrite\n"));
NTSTATUS ntStatus = STATUS_SUCCESS;// Assume success
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
ULONG DataLen = irpSp->Parameters.Write.Length;
PUCHAR pData = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
KIRQL OldIrql;
PIRP pOldReadIrp = NULL;
PDRIVER_CANCEL pOldCancelRoutine;
Irp->IoStatus.Information = 0;
ntStatus = STATUS_SUCCESS;
if (DataLen == 0)
{
ntStatus = STATUS_SUCCESS;
}else if (DataLen>COMBUFLEN)
{
ntStatus = STATUS_INVALID_PARAMETER;
}
else
{
KdPrint(("Write\n"));
KeAcquireSpinLock(&pdx->WriteSpinLock, &OldIrql);
RtlCopyMemory(pdx->Buffer,pData,DataLen);
pdx->uReadWrite = DataLen;
if (pdx->pReadIrp != NULL) // drop it out
{
pOldReadIrp = pdx->pReadIrp;
pOldCancelRoutine = IoSetCancelRoutine(pOldReadIrp, NULL);
if (pOldCancelRoutine != NULL)
{
pOldReadIrp->IoStatus.Information = 0;
pOldReadIrp->IoStatus.Status = STATUS_SUCCESS;
pdx->pReadIrp = NULL;
}
else
{
pOldReadIrp = NULL;
}
}
DriverCheckEvent(pdx, SERIAL_EV_RXCHAR | SERIAL_EV_RX80FULL);
// DriverCheckEvent(pdx, SERIAL_EV_TXEMPTY);
KeReleaseSpinLock(&pdx->WriteSpinLock, OldIrql);
if (pOldReadIrp != NULL)
IoCompleteRequest(pOldReadIrp, IO_NO_INCREMENT);
}
Irp->IoStatus.Status = ntStatus;
Irp->IoStatus.Information = DataLen;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return ntStatus;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -