Incorporate rosapps. 0.3.15 was branched somewhat incorrectly so rosapps is not synce...
[reactos.git] / modules / rosapps / applications / sysutils / utils / pice / module / output.c
1 /*++
2
3 Copyright (c) 1998-2001 Klaus P. Gerlicher
4
5 Module Name:
6
7 output.c
8
9 Abstract:
10
11 catch debugging outputs
12
13 Environment:
14
15 Kernel mode only
16
17 Author:
18
19 Klaus P. Gerlicher
20
21 Revision History:
22
23 14-Nov-1999: created
24 15-Nov-2000: general cleanup of source files
25
26 Copyright notice:
27
28 This file may be distributed under the terms of the GNU Public License.
29
30 --*/
31
32 ////////////////////////////////////////////////////
33 // INCLUDES
34 ////
35 #include "remods.h"
36 #include "precomp.h"
37 /*
38 #include <linux/sched.h>
39 #include <asm/io.h>
40 #include <asm/page.h>
41 #include <asm/pgtable.h>
42 #include <linux/utsname.h>
43 #include <linux/sched.h>
44 #include <linux/console.h>
45 #include <asm/delay.h>
46 */
47
48 char tempOutput[1024],tempOutput2[1024];
49
50 //ULONG ulPrintk=0;
51
52 ULONG (*ulPrintk) (PANSI_STRING String);
53
54 BOOLEAN bInPrintk = FALSE;
55 BOOLEAN bIsDebugPrint = FALSE;
56 BOOLEAN bIsPrintkPatched = FALSE;
57
58 ULONG ulCountTimerEvents = 0;
59
60 #ifdef __cplusplus
61 #define CPP_ASMLINKAGE extern "C"
62 #else
63 #define CPP_ASMLINKAGE
64 #endif
65 #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
66
67 asmlinkage int printk(const char *fmt, ...);
68
69 //EXPORT_SYMBOL(printk);
70
71 //*************************************************************************
72 // printk()
73 //
74 // this function overrides printk() in the kernel
75 //*************************************************************************
76 asmlinkage int printk(const char *fmt, ...)
77 {
78 ULONG len,ulRingBufferLock;
79 static LONGLONG ulOldJiffies = 0;
80 LARGE_INTEGER jiffies;
81
82 va_list args;
83 va_start(args, fmt);
84
85 if((len = PICE_strlen((LPSTR)fmt)) )
86 {
87 save_flags(ulRingBufferLock);
88 cli();
89
90 PICE_vsprintf(tempOutput, fmt, args);
91 bIsDebugPrint = TRUE;
92 // if the last debug print was longer than 50 ms ago
93 // directly print it, else just add it to the ring buffer
94 // and let the timer process it.
95 KeQuerySystemTime(&jiffies);
96 if( (jiffies.QuadPart-ulOldJiffies) > 10000*(1*wWindow[OUTPUT_WINDOW].cy)/2)
97 {
98 ulOldJiffies = jiffies.QuadPart;
99 Print(OUTPUT_WINDOW,tempOutput);
100 }
101 else
102 {
103 AddToRingBuffer(tempOutput);
104 }
105
106 bIsDebugPrint = FALSE;
107 restore_flags(ulRingBufferLock);
108 }
109 va_end(args);
110
111 return 0;
112 }
113
114 //*************************************************************************
115 // CountArgs()
116 //
117 // count occurrence of '%' in format string (except %%)
118 // validity of whole format string must have been enforced
119 //*************************************************************************
120 ULONG CountArgs(LPSTR fmt)
121 {
122 ULONG count=0;
123
124 while(*fmt)
125 {
126 if(*fmt=='%' && *(fmt+1)!='%')
127 count++;
128 fmt++;
129 }
130 return count;
131 }
132
133 //***********************************************************************************
134 // Our replacement of kernel function.
135 // Must not make any calls to KdpPrintString (e.g. by calling DbgPrint).
136 //***********************************************************************************
137 ULONG PICE_KdpPrintString(PANSI_STRING String)
138 {
139 ULONG ulRingBufferLock;
140
141 save_flags(ulRingBufferLock);
142 cli();
143
144 /* CH: What is bIsDebugPrint used for? */
145 bIsDebugPrint = FALSE;
146
147 DPRINT((0,"PICE_KdpPrintString\n\n\n"));
148 AddToRingBuffer(String->Buffer);
149 restore_flags(ulRingBufferLock);
150 }
151 //*************************************************************************
152 // PrintkCallback()
153 //
154 // called from RealIsr() when processing INT3 placed
155 // Must not make any calls to KdpPrintString (e.g. by calling DbgPrint).
156 //*************************************************************************
157 void PrintkCallback(void)
158 {
159 LPSTR fmt,args;
160 ULONG ulAddress;
161 ULONG countArgs,i,len;
162 PANSI_STRING temp;
163 CHAR buf[128];
164
165 DPRINT((0,"In PrintkCallback\n"));
166
167 bInPrintk = TRUE;
168
169 // get the linear address of stack where string resides
170 ulAddress = GetLinearAddress(CurrentSS,CurrentESP);
171 if(ulAddress)
172 {
173 DPRINT((0,"In PrintkCallback: ulAddress: %x\n", ulAddress));
174 if(IsAddressValid(ulAddress+sizeof(char *)) )
175 {
176 //KdpPrintString has PANSI_STRING as a parameter
177 temp = (PANSI_STRING)*(PULONG)(ulAddress+sizeof(char *));
178 DPRINT((0,"PrintkCallback: %s\n", temp->Buffer));
179 /* Call our version of KdpPrintString() */
180 CurrentEIP = (ULONG_PTR)PICE_KdpPrintString;
181 }
182 }
183 bInPrintk = FALSE;
184 }
185
186 //*************************************************************************
187 // PiceRunningTimer()
188 //
189 //*************************************************************************
190
191 KTIMER PiceTimer;
192 KDPC PiceTimerDPC;
193
194 // do I need it here? Have to keep DPC memory resident #pragma code_seg()
195 VOID PiceRunningTimer(IN PKDPC Dpc,
196 IN PVOID DeferredContext,
197 IN PVOID SystemArgument1,
198 IN PVOID SystemArgument2)
199 {
200 CheckRingBuffer();
201
202 if(ulCountTimerEvents++ > 10)
203 {
204 LARGE_INTEGER jiffies;
205
206 ulCountTimerEvents = 0;
207
208 KeQuerySystemTime(&jiffies);
209 SetForegroundColor(COLOR_TEXT);
210 SetBackgroundColor(COLOR_CAPTION);
211 PICE_sprintf(tempOutput,"jiffies = %.8X\n",jiffies.u.LowPart);
212 PutChar(tempOutput,GLOBAL_SCREEN_WIDTH-strlen(tempOutput),GLOBAL_SCREEN_HEIGHT-1);
213 ResetColor();
214 }
215 }
216
217 //*************************************************************************
218 // InitPiceRunningTimer()
219 //
220 //*************************************************************************
221 void InitPiceRunningTimer(void)
222 {
223 LARGE_INTEGER Interval;
224
225 ENTER_FUNC();
226 #if 0 //won't work. we have to intercept timer interrupt so dpc will never fire while we are in pice
227 KeInitializeTimer( &PiceTimer );
228 KeInitializeDpc( &PiceTimerDPC, PiceRunningTimer, NULL );
229
230 Interval.QuadPart=-1000000L; // 100 millisec. (unit is 100 nanosec.)
231
232 KeSetTimerEx(&PiceTimer,
233 Interval, 1000000L,
234 &PiceTimerDpc);
235 #endif
236 LEAVE_FUNC();
237 }
238
239 //*************************************************************************
240 // RemovePiceRunningTimer()
241 //
242 //*************************************************************************
243 void RemovePiceRunningTimer(void)
244 {
245 KeCancelTimer( &PiceTimer );
246 }
247
248 //*************************************************************************
249 // InstallPrintkHook()
250 //
251 //*************************************************************************
252 void InstallPrintkHook(void)
253 {
254
255 ENTER_FUNC();
256
257 if( bIsPrintkPatched )
258 return;
259
260 DPRINT((0,"installing PrintString hook\n"));
261 ScanExports("_KdpPrintString",(PULONG)&ulPrintk);
262
263 DPRINT((0,"_KdpPrintString @ %x\n", ulPrintk));
264 ASSERT( ulPrintk ); // temporary
265 if(ulPrintk)
266 {
267 bIsPrintkPatched = InstallSWBreakpoint(ulPrintk,TRUE,PrintkCallback);
268 DPRINT((0,"KdpPrintStringTest breakpoint installed? %d\n", bIsPrintkPatched));
269 }
270
271 LEAVE_FUNC();
272 }
273
274 //*************************************************************************
275 // DeInstallPrintkHook()
276 //
277 //*************************************************************************
278 void DeInstallPrintkHook(void)
279 {
280 ENTER_FUNC();
281
282 DPRINT((0,"enter DeInstallPrintkHook()\n"));
283 if(bIsPrintkPatched && ulPrintk)
284 {
285 // will be done on exit debugger
286 if (DeInstallSWBreakpoint(ulPrintk))
287 bIsPrintkPatched = FALSE;
288 }
289 LEAVE_FUNC();
290 }