mirror of
https://github.com/reactos/reactos.git
synced 2025-03-10 18:24:02 +00:00
291 lines
7.1 KiB
C
291 lines
7.1 KiB
C
![]() |
/*++
|
||
|
|
||
|
Copyright (c) 1998-2001 Klaus P. Gerlicher
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
output.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
catch debugging outputs
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
Kernel mode only
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Klaus P. Gerlicher
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
14-Nov-1999: created
|
||
|
15-Nov-2000: general cleanup of source files
|
||
|
|
||
|
Copyright notice:
|
||
|
|
||
|
This file may be distributed under the terms of the GNU Public License.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
////////////////////////////////////////////////////
|
||
|
// INCLUDES
|
||
|
////
|
||
|
#include "remods.h"
|
||
|
#include "precomp.h"
|
||
|
/*
|
||
|
#include <linux/sched.h>
|
||
|
#include <asm/io.h>
|
||
|
#include <asm/page.h>
|
||
|
#include <asm/pgtable.h>
|
||
|
#include <linux/utsname.h>
|
||
|
#include <linux/sched.h>
|
||
|
#include <linux/console.h>
|
||
|
#include <asm/delay.h>
|
||
|
*/
|
||
|
|
||
|
char tempOutput[1024],tempOutput2[1024];
|
||
|
|
||
|
//ULONG ulPrintk=0;
|
||
|
|
||
|
ULONG (*ulPrintk) (PANSI_STRING String);
|
||
|
|
||
|
BOOLEAN bInPrintk = FALSE;
|
||
|
BOOLEAN bIsDebugPrint = FALSE;
|
||
|
BOOLEAN bIsPrintkPatched = FALSE;
|
||
|
|
||
|
ULONG ulCountTimerEvents = 0;
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
#define CPP_ASMLINKAGE extern "C"
|
||
|
#else
|
||
|
#define CPP_ASMLINKAGE
|
||
|
#endif
|
||
|
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
|
||
|
|
||
|
asmlinkage int printk(const char *fmt, ...);
|
||
|
|
||
|
//EXPORT_SYMBOL(printk);
|
||
|
|
||
|
//*************************************************************************
|
||
|
// printk()
|
||
|
//
|
||
|
// this function overrides printk() in the kernel
|
||
|
//*************************************************************************
|
||
|
asmlinkage int printk(const char *fmt, ...)
|
||
|
{
|
||
|
ULONG len,ulRingBufferLock;
|
||
|
static LONGLONG ulOldJiffies = 0;
|
||
|
LARGE_INTEGER jiffies;
|
||
|
|
||
|
va_list args;
|
||
|
va_start(args, fmt);
|
||
|
|
||
|
if((len = PICE_strlen((LPSTR)fmt)) )
|
||
|
{
|
||
|
save_flags(ulRingBufferLock);
|
||
|
cli();
|
||
|
|
||
|
PICE_vsprintf(tempOutput, fmt, args);
|
||
|
bIsDebugPrint = TRUE;
|
||
|
// if the last debug print was longer than 50 ms ago
|
||
|
// directly print it, else just add it to the ring buffer
|
||
|
// and let the timer process it.
|
||
|
KeQuerySystemTime(&jiffies);
|
||
|
if( (jiffies.QuadPart-ulOldJiffies) > 10000*(1*wWindow[OUTPUT_WINDOW].cy)/2)
|
||
|
{
|
||
|
ulOldJiffies = jiffies.QuadPart;
|
||
|
Print(OUTPUT_WINDOW,tempOutput);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AddToRingBuffer(tempOutput);
|
||
|
}
|
||
|
|
||
|
bIsDebugPrint = FALSE;
|
||
|
restore_flags(ulRingBufferLock);
|
||
|
}
|
||
|
va_end(args);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//*************************************************************************
|
||
|
// CountArgs()
|
||
|
//
|
||
|
// count occurrence of '%' in format string (except %%)
|
||
|
// validity of whole format string must have been enforced
|
||
|
//*************************************************************************
|
||
|
ULONG CountArgs(LPSTR fmt)
|
||
|
{
|
||
|
ULONG count=0;
|
||
|
|
||
|
while(*fmt)
|
||
|
{
|
||
|
if(*fmt=='%' && *(fmt+1)!='%')
|
||
|
count++;
|
||
|
fmt++;
|
||
|
}
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
//***********************************************************************************
|
||
|
// Our replacement of kernel function.
|
||
|
// Must not make any calls to KdpPrintString (e.g. by calling DbgPrint).
|
||
|
//***********************************************************************************
|
||
|
ULONG PICE_KdpPrintString(PANSI_STRING String)
|
||
|
{
|
||
|
ULONG ulRingBufferLock;
|
||
|
|
||
|
save_flags(ulRingBufferLock);
|
||
|
cli();
|
||
|
|
||
|
/* CH: What is bIsDebugPrint used for? */
|
||
|
bIsDebugPrint = FALSE;
|
||
|
|
||
|
DPRINT((0,"PICE_KdpPrintString\n\n\n"));
|
||
|
AddToRingBuffer(String->Buffer);
|
||
|
restore_flags(ulRingBufferLock);
|
||
|
}
|
||
|
//*************************************************************************
|
||
|
// PrintkCallback()
|
||
|
//
|
||
|
// called from RealIsr() when processing INT3 placed
|
||
|
// Must not make any calls to KdpPrintString (e.g. by calling DbgPrint).
|
||
|
//*************************************************************************
|
||
|
void PrintkCallback(void)
|
||
|
{
|
||
|
LPSTR fmt,args;
|
||
|
ULONG ulAddress;
|
||
|
ULONG countArgs,i,len;
|
||
|
PANSI_STRING temp;
|
||
|
CHAR buf[128];
|
||
|
|
||
|
DPRINT((0,"In PrintkCallback\n"));
|
||
|
|
||
|
bInPrintk = TRUE;
|
||
|
|
||
|
// get the linear address of stack where string resides
|
||
|
ulAddress = GetLinearAddress(CurrentSS,CurrentESP);
|
||
|
if(ulAddress)
|
||
|
{
|
||
|
DPRINT((0,"In PrintkCallback: ulAddress: %x\n", ulAddress));
|
||
|
if(IsAddressValid(ulAddress+sizeof(char *)) )
|
||
|
{
|
||
|
//KdpPrintString has PANSI_STRING as a parameter
|
||
|
temp = (PANSI_STRING)*(PULONG)(ulAddress+sizeof(char *));
|
||
|
DPRINT((0,"PrintkCallback: %s\n", temp->Buffer));
|
||
|
/* Call our version of KdpPrintString() */
|
||
|
CurrentEIP = (ULONG_PTR)PICE_KdpPrintString;
|
||
|
}
|
||
|
}
|
||
|
bInPrintk = FALSE;
|
||
|
}
|
||
|
|
||
|
//*************************************************************************
|
||
|
// PiceRunningTimer()
|
||
|
//
|
||
|
//*************************************************************************
|
||
|
|
||
|
KTIMER PiceTimer;
|
||
|
KDPC PiceTimerDPC;
|
||
|
|
||
|
// do I need it here? Have to keep DPC memory resident #pragma code_seg()
|
||
|
VOID PiceRunningTimer(IN PKDPC Dpc,
|
||
|
IN PVOID DeferredContext,
|
||
|
IN PVOID SystemArgument1,
|
||
|
IN PVOID SystemArgument2)
|
||
|
{
|
||
|
CheckRingBuffer();
|
||
|
|
||
|
if(ulCountTimerEvents++ > 10)
|
||
|
{
|
||
|
LARGE_INTEGER jiffies;
|
||
|
|
||
|
ulCountTimerEvents = 0;
|
||
|
|
||
|
KeQuerySystemTime(&jiffies);
|
||
|
SetForegroundColor(COLOR_TEXT);
|
||
|
SetBackgroundColor(COLOR_CAPTION);
|
||
|
PICE_sprintf(tempOutput,"jiffies = %.8X\n",jiffies.u.LowPart);
|
||
|
PutChar(tempOutput,GLOBAL_SCREEN_WIDTH-strlen(tempOutput),GLOBAL_SCREEN_HEIGHT-1);
|
||
|
ResetColor();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//*************************************************************************
|
||
|
// InitPiceRunningTimer()
|
||
|
//
|
||
|
//*************************************************************************
|
||
|
void InitPiceRunningTimer(void)
|
||
|
{
|
||
|
LARGE_INTEGER Interval;
|
||
|
|
||
|
ENTER_FUNC();
|
||
|
#if 0 //won't work. we have to intercept timer interrupt so dpc will never fire while we are in pice
|
||
|
KeInitializeTimer( &PiceTimer );
|
||
|
KeInitializeDpc( &PiceTimerDPC, PiceRunningTimer, NULL );
|
||
|
|
||
|
Interval.QuadPart=-1000000L; // 100 millisec. (unit is 100 nanosec.)
|
||
|
|
||
|
KeSetTimerEx(&PiceTimer,
|
||
|
Interval, 1000000L,
|
||
|
&PiceTimerDpc);
|
||
|
#endif
|
||
|
LEAVE_FUNC();
|
||
|
}
|
||
|
|
||
|
//*************************************************************************
|
||
|
// RemovePiceRunningTimer()
|
||
|
//
|
||
|
//*************************************************************************
|
||
|
void RemovePiceRunningTimer(void)
|
||
|
{
|
||
|
KeCancelTimer( &PiceTimer );
|
||
|
}
|
||
|
|
||
|
//*************************************************************************
|
||
|
// InstallPrintkHook()
|
||
|
//
|
||
|
//*************************************************************************
|
||
|
void InstallPrintkHook(void)
|
||
|
{
|
||
|
|
||
|
ENTER_FUNC();
|
||
|
|
||
|
if( bIsPrintkPatched )
|
||
|
return;
|
||
|
|
||
|
DPRINT((0,"installing PrintString hook\n"));
|
||
|
ScanExports("_KdpPrintString",(PULONG)&ulPrintk);
|
||
|
|
||
|
DPRINT((0,"_KdpPrintString @ %x\n", ulPrintk));
|
||
|
ASSERT( ulPrintk ); // temporary
|
||
|
if(ulPrintk)
|
||
|
{
|
||
|
bIsPrintkPatched = InstallSWBreakpoint(ulPrintk,TRUE,PrintkCallback);
|
||
|
DPRINT((0,"KdpPrintStringTest breakpoint installed? %d\n", bIsPrintkPatched));
|
||
|
}
|
||
|
|
||
|
LEAVE_FUNC();
|
||
|
}
|
||
|
|
||
|
//*************************************************************************
|
||
|
// DeInstallPrintkHook()
|
||
|
//
|
||
|
//*************************************************************************
|
||
|
void DeInstallPrintkHook(void)
|
||
|
{
|
||
|
ENTER_FUNC();
|
||
|
|
||
|
DPRINT((0,"enter DeInstallPrintkHook()\n"));
|
||
|
if(bIsPrintkPatched && ulPrintk)
|
||
|
{
|
||
|
// will be done on exit debugger
|
||
|
if (DeInstallSWBreakpoint(ulPrintk))
|
||
|
bIsPrintkPatched = FALSE;
|
||
|
}
|
||
|
LEAVE_FUNC();
|
||
|
}
|