windows-nt/Source/XPSP1/NT/net/irda/irutil/dbgmsg.c
2020-09-26 16:20:57 +08:00

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