📄 comemuldrv.c
字号:
break;
}
case IOCTL_SERIAL_GET_DTRRTS:
{
ULONG ModemControl;
ModemControl = pExtension->DTRstate + (pExtension->RTSstate<<1);
*(PULONG)pIrp->AssociatedIrp.SystemBuffer = ModemControl;
pIrp->IoStatus.Information = sizeof(ULONG);
break;
}
case IOCTL_SERIAL_GET_MODEMSTATUS:
{
ULONG Cts, Dsr, Dcd;
Cts = pExtension->pOther->RTSstate;
Dsr = pExtension->pOther->DTRstate;
//Dcd = OpenCnt==2;
Dcd = pExtension->pOther->IsOpen;
*(PULONG)pIrp->AssociatedIrp.SystemBuffer =
(Cts ? SERIAL_CTS_STATE : 0) | (Dsr ? SERIAL_DSR_STATE : 0) /*|
(Dcd ? SERIAL_DCD_STATE : 0)*/;
pIrp->IoStatus.Information = sizeof(ULONG);
break;
}
case IOCTL_SERIAL_SET_TIMEOUTS:
{
//DbgPrint("SetTimeouts\n");
pExtension->Timeouts = *((PSERIAL_TIMEOUTS)(pIrp->AssociatedIrp.SystemBuffer));
break;
}
case IOCTL_SERIAL_GET_TIMEOUTS:
{
*((PSERIAL_TIMEOUTS)pIrp->AssociatedIrp.SystemBuffer) = pExtension->Timeouts;
pIrp->IoStatus.Information = sizeof(SERIAL_TIMEOUTS);
break;
}
case IOCTL_SERIAL_RESET_DEVICE:
{
//DbgPrint("ResetDevice\n");
break;
}
case IOCTL_SERIAL_PURGE:
{
// ???
break;
}
case IOCTL_SERIAL_SET_LINE_CONTROL:
{
pExtension->Lc = *((PSERIAL_LINE_CONTROL)(pIrp->AssociatedIrp.SystemBuffer));
break;
}
case IOCTL_SERIAL_GET_LINE_CONTROL:
{
*((PSERIAL_LINE_CONTROL)(pIrp->AssociatedIrp.SystemBuffer)) = pExtension->Lc;
pIrp->IoStatus.Information = sizeof(SERIAL_LINE_CONTROL);
break;
}
case IOCTL_SERIAL_SET_WAIT_MASK:
{
PIRP pOldWaitIrp;
PDRIVER_CANCEL pOldCancelRoutine;
pExtension->EventMask = *(PULONG)pIrp->AssociatedIrp.SystemBuffer;
//LogMessage(DeviceObject,0xD1,0,0,0,0,0);
KeAcquireSpinLock(&pExtension->IoctlSpinLock, &OldIrql);
// ggf. anh鬾gigen Wait-Request beenden
pOldWaitIrp = pExtension->pWaitIrp;
if (pOldWaitIrp != NULL)
{
pOldCancelRoutine = IoSetCancelRoutine(pOldWaitIrp, NULL);
// wurde Cancel-Routine schon aufgerufen?
if (pOldCancelRoutine != NULL)
{
// Nein, also Request beenden
pOldWaitIrp->IoStatus.Information = sizeof(ULONG);
*(PULONG)pOldWaitIrp->AssociatedIrp.SystemBuffer = 0;
pOldWaitIrp->IoStatus.Status = STATUS_SUCCESS;
pExtension->pWaitIrp = NULL;
}
else
{
// Ja, Cancel-Routine wird Request beenden
pOldWaitIrp = NULL;
}
}
KeReleaseSpinLock(&pExtension->IoctlSpinLock, OldIrql);
if (pOldWaitIrp != NULL)
IoCompleteRequest(pOldWaitIrp, IO_NO_INCREMENT);
break;
}
case IOCTL_SERIAL_GET_WAIT_MASK:
{
*(PULONG)pIrp->AssociatedIrp.SystemBuffer = pExtension->EventMask;
pIrp->IoStatus.Information = sizeof(ULONG);
break;
}
case IOCTL_SERIAL_WAIT_ON_MASK:
{
PDRIVER_CANCEL pOldCancelRoutine;
//LogMessage(DeviceObject,0xD2,0,0,0,0,0);
KeAcquireSpinLock(&pExtension->IoctlSpinLock, &OldIrql);
if ((pExtension->pWaitIrp != NULL) || (pExtension->EventMask == 0))
ntStatus = STATUS_INVALID_PARAMETER;
else
if ((pExtension->EventMask & pExtension->HistoryEvents) != 0)
{
// Some events happened
pIrp->IoStatus.Information = sizeof(ULONG);
*(PULONG)pIrp->AssociatedIrp.SystemBuffer = pExtension->EventMask & pExtension->HistoryEvents;
pExtension->HistoryEvents = 0;
ntStatus = STATUS_SUCCESS;
}
else
{
//LogMessage(DeviceObject,0x55,0,0,0,0,0);
pExtension->pWaitIrp = pIrp;
ntStatus = STATUS_PENDING;
IoSetCancelRoutine(pIrp, DriverCancelWaitIrp);
// soll IRP abgebrochen werden?
if (pIrp->Cancel)
{
pOldCancelRoutine = IoSetCancelRoutine(pIrp, NULL);
// wurde Cancel-Routine schon aufgerufen?
if (pOldCancelRoutine != NULL)
{
// Nein, also IRP hier abbrechen
ntStatus = STATUS_CANCELLED;
pExtension->pWaitIrp = NULL;
}
else
{
// Ja, Cancel-Routine wird Request beenden
IoMarkIrpPending(pIrp);
}
}
else
IoMarkIrpPending(pIrp);
}
KeReleaseSpinLock(&pExtension->IoctlSpinLock, OldIrql);
break;
}
case IOCTL_SERIAL_GET_COMMSTATUS:
{
PSERIAL_STATUS pStatus = (PSERIAL_STATUS)pIrp->AssociatedIrp.SystemBuffer;
ULONG InputLen;
//LogMessage(DeviceObject,0xD3,0,0,0,0,0);
KeAcquireSpinLock(&pExtension->pOther->WriteSpinLock, &OldIrql);
InputLen = pExtension->pOther->BufHead - pExtension->pOther->BufTail;
if (pExtension->pOther->BufHead < pExtension->pOther->BufTail)
InputLen += COMBUFLEN;
KeReleaseSpinLock(&pExtension->pOther->WriteSpinLock, OldIrql);
RtlZeroMemory(pIrp->AssociatedIrp.SystemBuffer, sizeof(SERIAL_STATUS));
pStatus->AmountInInQueue = InputLen;
pStatus->AmountInOutQueue = 0;
pIrp->IoStatus.Information = sizeof(SERIAL_STATUS);
break;
}
case IOCTL_SERIAL_GET_CHARS:
{
RtlZeroMemory(pIrp->AssociatedIrp.SystemBuffer, sizeof(SERIAL_CHARS));
pIrp->IoStatus.Information = sizeof(SERIAL_CHARS);
break;
}
case IOCTL_SERIAL_GET_HANDFLOW:
{
// ?
break;
}
default:
{
// LogMessage(DeviceObject,0xE1,irpSp->Parameters.DeviceIoControl.IoControlCode,0,0,0,0);
break;
}
/*
case IOCTL_SERIAL_GETDATA:
{
ULONG BufLen = *((ULONG*)pIrp->AssociatedIrp.SystemBuffer);
ULONG i = 0;
//LogMessage(DeviceObject,0x44,BufLen,0,0,0,0);
while (i<BufLen && pExtension->BufHead!=pExtension->BufTail)
{
((CHAR*)pIrp->AssociatedIrp.SystemBuffer)[i] =
pExtension->Buffer[pExtension->BufTail];
i++;
pExtension->BufTail++;
pExtension->BufTail %= COMBUFLEN;
}
pIrp->IoStatus.Information = i;
}
*/
}
pIrp->IoStatus.Status = ntStatus;
if (ntStatus!=STATUS_PENDING)
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return ntStatus;
}
NTSTATUS
MixPortDriverWriteDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP pIrp
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;// Assume success
PSERIAL_DEVICE_EXTENSION pExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( pIrp );
ULONG DataLen = irpSp->Parameters.Write.Length;
PCHAR pData = pIrp->AssociatedIrp.SystemBuffer;
ULONG i;
KIRQL OldIrql;
PIRP pOldReadIrp = NULL;
PDRIVER_CANCEL pOldCancelRoutine;
pIrp->IoStatus.Information = 0;
ntStatus = STATUS_SUCCESS;
//LogMessage(DeviceObject,0xC2,0,0,0,0,0);
if (DataLen == 0)
{
ntStatus = STATUS_SUCCESS;
}
else
{
//DbgPrint("Write\n");
KeAcquireSpinLock(&pExtension->WriteSpinLock, &OldIrql);
//LogMessage(DeviceObject,0x33,DataLen,0,0,pData,DataLen);
for (i=0; i<DataLen; i++)
{
pExtension->Buffer[pExtension->BufHead] = pData[i];
pExtension->BufHead++;
pExtension->BufHead %= COMBUFLEN;
}
if (pExtension->pOther->pReadIrp != NULL) // drop it out
{
pOldReadIrp = pExtension->pOther->pReadIrp;
pOldCancelRoutine = IoSetCancelRoutine(pOldReadIrp, NULL);
// wurde Cancel-Routine schon aufgerufen?
if (pOldCancelRoutine != NULL)
{
// Nein, also Request beenden
pOldReadIrp->IoStatus.Information = 0;
pOldReadIrp->IoStatus.Status = STATUS_SUCCESS;
pExtension->pOther->pReadIrp = NULL;
}
else
{
// Ja, Cancel-Routine wird Request beenden
pOldReadIrp = NULL;
}
}
DriverCheckEvent(pExtension->pOther, SERIAL_EV_RXCHAR | SERIAL_EV_RX80FULL);
DriverCheckEvent(pExtension, SERIAL_EV_TXEMPTY);
KeReleaseSpinLock(&pExtension->WriteSpinLock, OldIrql);
if (pOldReadIrp != NULL)
IoCompleteRequest(pOldReadIrp, IO_NO_INCREMENT);
}
pIrp->IoStatus.Status = ntStatus;
pIrp->IoStatus.Information = DataLen;
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return ntStatus;
}
VOID DriverCancelCurrentReadIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp)
{
PSERIAL_DEVICE_EXTENSION pExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
KIRQL OldIrql;
IoReleaseCancelSpinLock(pIrp->CancelIrql);
KeAcquireSpinLock(&pExtension->pOther->WriteSpinLock, &OldIrql);
pExtension->pReadIrp = NULL;
KeReleaseSpinLock(&pExtension->pOther->WriteSpinLock, OldIrql);
pIrp->IoStatus.Status = STATUS_CANCELLED;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
}
NTSTATUS
MixPortDriverReadDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP pIrp
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;// Assume success
PSERIAL_DEVICE_EXTENSION pExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( pIrp );
ULONG BufLen = irpSp->Parameters.Read.Length;
PCHAR pBuf = pIrp->AssociatedIrp.SystemBuffer;
ULONG i = 0;
KIRQL OldIrql;
PDRIVER_CANCEL pOldCancelRoutine;
pIrp->IoStatus.Information = 0;
//LogMessage(DeviceObject,0xC0,0,0,0,0,0);
if (BufLen == 0)
{
ntStatus = STATUS_SUCCESS;
}
else
{
//DbgPrint("Read\n");
KeAcquireSpinLock(&pExtension->pOther->WriteSpinLock, &OldIrql);
//LogMessage(DeviceObject,0x33,DataLen,0,0,pData,DataLen);
while ( i<BufLen &&
(pExtension->pOther->BufHead != pExtension->pOther->BufTail) )
{
pBuf[i] = pExtension->pOther->Buffer[pExtension->pOther->BufTail];
i++;
pExtension->pOther->BufTail++;
pExtension->pOther->BufTail %= COMBUFLEN;
}
pIrp->IoStatus.Information = i;
if (i==0 && pExtension->pReadIrp==NULL) // nothing, store
{
//LogMessage(DeviceObject,0xC1,0,0,0,0,0);
pExtension->pReadIrp = pIrp;
pIrp->IoStatus.Status = ntStatus = STATUS_PENDING;
IoSetCancelRoutine(pIrp, DriverCancelCurrentReadIrp);
if (pIrp->Cancel)
{
pOldCancelRoutine = IoSetCancelRoutine(pIrp, NULL);
if (pOldCancelRoutine != NULL)
{
// Nein, also IRP hier abbrechen
pIrp->IoStatus.Status = ntStatus = STATUS_CANCELLED;
pExtension->pReadIrp = NULL;
}
else
{
// Ja, Cancel-Routine wird Request beenden
IoMarkIrpPending(pIrp);
}
}
else
{
IoMarkIrpPending(pIrp);
}
}
KeReleaseSpinLock(&pExtension->pOther->WriteSpinLock, OldIrql);
//if (i)
//LogMessage(DeviceObject,0x77,i,0,0,0,0);
}
pIrp->IoStatus.Status = ntStatus;
if (ntStatus != STATUS_PENDING)
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
//LogMessage(DeviceObject,0xBB,0,0,0,0,0);
return ntStatus;
}
VOID DriverCancelWaitIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp)
{
PSERIAL_DEVICE_EXTENSION pExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
KIRQL OldIrql;
//LogMessage(DeviceObject,0x66,0,0,0,0,0);
IoReleaseCancelSpinLock(pIrp->CancelIrql);
KeAcquireSpinLock(&pExtension->IoctlSpinLock, &OldIrql);
pExtension->pWaitIrp = NULL;
KeReleaseSpinLock(&pExtension->IoctlSpinLock, OldIrql);
pIrp->IoStatus.Status = STATUS_CANCELLED;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
}
VOID DriverCheckEvent(IN PSERIAL_DEVICE_EXTENSION pExtension, IN ULONG events)
{
PIRP pOldWaitIrp = NULL;
PDRIVER_CANCEL pOldCancelRoutine;
KIRQL OldIrql;
// LOCKED_PAGED_CODE();
KeAcquireSpinLock(&pExtension->IoctlSpinLock, &OldIrql);
pExtension->HistoryEvents |= events;
events &= pExtension->EventMask;
if ((pExtension->pWaitIrp != NULL) && (events != 0))
{
pOldWaitIrp = pExtension->pWaitIrp;
pOldCancelRoutine = IoSetCancelRoutine(pOldWaitIrp, NULL);
// wurde Cancel-Routine schon aufgerufen?
if (pOldCancelRoutine != NULL)
{
// Nein, also Request beenden
pOldWaitIrp->IoStatus.Information = sizeof(ULONG);
*(PULONG)pOldWaitIrp->AssociatedIrp.SystemBuffer = events;
pOldWaitIrp->IoStatus.Status = STATUS_SUCCESS;
pExtension->pWaitIrp = NULL;
pExtension->HistoryEvents = 0;
}
else
{
// Ja, Cancel-Routine wird Request beenden
pOldWaitIrp = NULL;
}
}
KeReleaseSpinLock(&pExtension->IoctlSpinLock, OldIrql);
if (pOldWaitIrp != NULL)
IoCompleteRequest(pOldWaitIrp, IO_NO_INCREMENT);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -