294 lines
5.9 KiB
C
294 lines
5.9 KiB
C
|
#if DBG
|
||
|
#include <irda.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdarg.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
CHAR DbgMsgs[DBG_MSG_CNT][MAX_MSG_LEN];
|
||
|
UINT First, Last;
|
||
|
CTETimer DbgTimer;
|
||
|
BOOLEAN TimerRunning;
|
||
|
CTELock DbgLock;
|
||
|
PIRP pDbgIrp;
|
||
|
UCHAR *IrpBuf;
|
||
|
ULONG IrpBufLen;
|
||
|
ULONG IrpBufWritten;
|
||
|
|
||
|
VOID DbgTimerExp(CTEEvent *Event, void *Arg);
|
||
|
|
||
|
VOID
|
||
|
DbgMsgInit()
|
||
|
{
|
||
|
|
||
|
pDbgIrp = NULL;
|
||
|
First = 0;
|
||
|
Last = 0;
|
||
|
TimerRunning = FALSE;
|
||
|
|
||
|
CTEInitLock(&DbgLock);
|
||
|
|
||
|
CTEInitTimer(&DbgTimer);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
DbgMsgUninit()
|
||
|
{
|
||
|
CTELockHandle LockHandle;
|
||
|
KIRQL Irql;
|
||
|
|
||
|
CTEGetLock(&DbgLock, &LockHandle);
|
||
|
|
||
|
if (pDbgIrp)
|
||
|
{
|
||
|
IoAcquireCancelSpinLock(&Irql);
|
||
|
|
||
|
IoSetCancelRoutine(pDbgIrp, NULL);
|
||
|
|
||
|
IoReleaseCancelSpinLock(Irql);
|
||
|
|
||
|
pDbgIrp->IoStatus.Information = 0;
|
||
|
pDbgIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||
|
|
||
|
DbgPrint("Complete irp!\n");
|
||
|
IoCompleteRequest(pDbgIrp, IO_NO_INCREMENT);
|
||
|
|
||
|
pDbgIrp = NULL;
|
||
|
}
|
||
|
|
||
|
CTEFreeLock(&DbgLock, LockHandle);
|
||
|
}
|
||
|
VOID
|
||
|
DbgMsg(CHAR *Format, ...)
|
||
|
{
|
||
|
va_list Args;
|
||
|
CTELockHandle LockHandle;
|
||
|
CHAR Temp[MAX_MSG_LEN];
|
||
|
LARGE_INTEGER Time;
|
||
|
ULONG UlongTime;
|
||
|
|
||
|
KeQueryTickCount(&Time);
|
||
|
|
||
|
//
|
||
|
// change it milliseconds and stuff it in a dword
|
||
|
//
|
||
|
UlongTime=(ULONG)((Time.QuadPart * KeQueryTimeIncrement()) / 10000);
|
||
|
|
||
|
sprintf(Temp,"%6d.%03d - ",UlongTime/1000, UlongTime%1000);
|
||
|
|
||
|
va_start(Args, Format);
|
||
|
|
||
|
vsprintf(&Temp[strlen(Temp)], Format, Args);
|
||
|
|
||
|
if (DbgOutput & DBG_OUTPUT_DEBUGGER)
|
||
|
{
|
||
|
DbgPrint(Temp);
|
||
|
}
|
||
|
|
||
|
if (DbgOutput & DBG_OUTPUT_BUFFER)
|
||
|
{
|
||
|
CTEGetLock(&DbgLock, &LockHandle);
|
||
|
|
||
|
strcpy(DbgMsgs[Last], Temp);
|
||
|
|
||
|
Last++;
|
||
|
|
||
|
if (Last == DBG_MSG_CNT)
|
||
|
Last = 0;
|
||
|
|
||
|
if (First == Last)
|
||
|
{
|
||
|
First++;
|
||
|
if (First == DBG_MSG_CNT)
|
||
|
First = 0;
|
||
|
}
|
||
|
|
||
|
if (pDbgIrp && !TimerRunning)
|
||
|
{
|
||
|
CTEStartTimer(&DbgTimer, DBG_TIMER_INTERVAL,
|
||
|
DbgTimerExp, NULL);
|
||
|
TimerRunning = TRUE;
|
||
|
}
|
||
|
|
||
|
CTEFreeLock(&DbgLock, LockHandle);
|
||
|
}
|
||
|
|
||
|
va_end(Args);
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
FillDbgIrp(UCHAR Msg[])
|
||
|
{
|
||
|
NTSTATUS Status = STATUS_PENDING;
|
||
|
UINT i;
|
||
|
|
||
|
if ((IrpBufLen - IrpBufWritten) < MAX_MSG_LEN)
|
||
|
{
|
||
|
Status = STATUS_SUCCESS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Msg[MAX_MSG_LEN - 1] = 0; // just to be sure
|
||
|
|
||
|
i = 0;
|
||
|
|
||
|
while (1)
|
||
|
{
|
||
|
IrpBuf[IrpBufWritten++] = Msg[i];
|
||
|
|
||
|
if (Msg[i] == 0)
|
||
|
break;
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
VOID CancelDbgIrp(
|
||
|
PDEVICE_OBJECT DeviceObject,
|
||
|
PIRP pIrp)
|
||
|
{
|
||
|
// DbgPrint("CancelDbgIrp %x\n", pIrp);
|
||
|
|
||
|
pDbgIrp = NULL;
|
||
|
|
||
|
IoReleaseCancelSpinLock(pIrp->CancelIrql);
|
||
|
|
||
|
pIrp->IoStatus.Status = STATUS_CANCELLED;
|
||
|
pIrp->IoStatus.Information = 0;
|
||
|
|
||
|
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
DbgMsgIrp(
|
||
|
PIRP pIrp,
|
||
|
PIO_STACK_LOCATION pIrpSp)
|
||
|
{
|
||
|
CTELockHandle LockHandle;
|
||
|
NTSTATUS Status = STATUS_PENDING;
|
||
|
|
||
|
if (pDbgIrp != NULL)
|
||
|
return STATUS_DEVICE_BUSY;
|
||
|
|
||
|
CTEGetLock(&DbgLock, &LockHandle);
|
||
|
|
||
|
IrpBufLen = pIrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||
|
IrpBufWritten = 0;
|
||
|
|
||
|
if (IrpBufLen < MAX_MSG_LEN)
|
||
|
{
|
||
|
CTEFreeLock(&DbgLock, LockHandle);
|
||
|
return STATUS_BUFFER_OVERFLOW;
|
||
|
}
|
||
|
|
||
|
IrpBuf = pIrp->AssociatedIrp.SystemBuffer;
|
||
|
|
||
|
while (First != Last)
|
||
|
{
|
||
|
Status = FillDbgIrp(DbgMsgs[First]);
|
||
|
|
||
|
if (Status == STATUS_SUCCESS)
|
||
|
break;
|
||
|
|
||
|
First++;
|
||
|
if (First == DBG_MSG_CNT)
|
||
|
First = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
if (Status == STATUS_SUCCESS)
|
||
|
{
|
||
|
pIrp->IoStatus.Information = IrpBufWritten;
|
||
|
}
|
||
|
else if (Status == STATUS_PENDING)
|
||
|
{
|
||
|
KIRQL Irql;
|
||
|
PDRIVER_CANCEL PrevCancel;
|
||
|
|
||
|
pDbgIrp = pIrp;
|
||
|
|
||
|
IoMarkIrpPending(pIrp);
|
||
|
|
||
|
IoAcquireCancelSpinLock(&Irql);
|
||
|
|
||
|
PrevCancel = IoSetCancelRoutine(pIrp, CancelDbgIrp);
|
||
|
|
||
|
CTEAssert(PrevCancel == NULL);
|
||
|
|
||
|
IoReleaseCancelSpinLock(Irql);
|
||
|
|
||
|
if (IrpBufWritten != 0)
|
||
|
{
|
||
|
CTEStartTimer(&DbgTimer, DBG_TIMER_INTERVAL,
|
||
|
DbgTimerExp, NULL);
|
||
|
|
||
|
TimerRunning = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CTEFreeLock(&DbgLock, LockHandle);
|
||
|
|
||
|
//DbgPrint("DbgIrp status %x, bw %d, irp %x\n", Status, IrpBufWritten, pIrp);
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
DbgTimerExp(CTEEvent *Event, void *Arg)
|
||
|
{
|
||
|
CTELockHandle LockHandle;
|
||
|
PIRP pIrp;
|
||
|
KIRQL Irql;
|
||
|
|
||
|
//DbgPrint("Texp\n");
|
||
|
|
||
|
if (pDbgIrp == NULL)
|
||
|
{
|
||
|
DbgPrint("DbgIrp is null\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
IoAcquireCancelSpinLock(&Irql);
|
||
|
|
||
|
IoSetCancelRoutine(pDbgIrp, NULL);
|
||
|
|
||
|
IoReleaseCancelSpinLock(Irql);
|
||
|
|
||
|
if (pDbgIrp->Cancel)
|
||
|
{
|
||
|
DbgPrint("DbgIrp is being canceled\n");
|
||
|
pDbgIrp = NULL;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
CTEGetLock(&DbgLock, &LockHandle);
|
||
|
|
||
|
TimerRunning = FALSE;
|
||
|
|
||
|
while (First != Last)
|
||
|
{
|
||
|
if (FillDbgIrp(DbgMsgs[First]) == STATUS_SUCCESS)
|
||
|
break;
|
||
|
|
||
|
First++;
|
||
|
if (First == DBG_MSG_CNT)
|
||
|
First = 0;
|
||
|
}
|
||
|
|
||
|
pIrp = pDbgIrp;
|
||
|
|
||
|
pDbgIrp = NULL;
|
||
|
|
||
|
CTEFreeLock(&DbgLock, LockHandle);
|
||
|
|
||
|
pIrp->IoStatus.Information = IrpBufWritten;
|
||
|
pIrp->IoStatus.Status = STATUS_SUCCESS;
|
||
|
|
||
|
// DbgPrint("Comp bw %d, irp %x\n", IrpBufWritten, pIrp);
|
||
|
|
||
|
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
|
||
|
}
|
||
|
|
||
|
#endif
|