#if DBG #include #include #include #include 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