|
|
#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
|