mirror of
https://github.com/reactos/reactos.git
synced 2025-03-10 18:24:02 +00:00
290 lines
7.1 KiB
C
290 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();
|
|
}
|