[CMAKE]
[reactos.git] / boot / freeldr / freeldr / debug.c
1 /*
2 * FreeLoader
3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <freeldr.h>
21
22 #include <debug.h>
23
24 #if DBG && !defined(_M_ARM)
25
26 //#define DEBUG_ALL
27 //#define DEBUG_INIFILE
28 //#define DEBUG_REACTOS
29 //#define DEBUG_CUSTOM
30 #define DEBUG_NONE
31
32 #if defined (DEBUG_ALL)
33 ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY | DPRINT_FILESYSTEM |
34 DPRINT_UI | DPRINT_DISK | DPRINT_CACHE | DPRINT_REACTOS |
35 DPRINT_LINUX | DPRINT_HWDETECT;
36 #elif defined (DEBUG_INIFILE)
37 ULONG DebugPrintMask = DPRINT_INIFILE;
38 #elif defined (DEBUG_REACTOS)
39 ULONG DebugPrintMask = DPRINT_REACTOS | DPRINT_REGISTRY;
40 #elif defined (DEBUG_CUSTOM)
41 ULONG DebugPrintMask = DPRINT_WARNING |
42 DPRINT_UI | DPRINT_CACHE | DPRINT_REACTOS |
43 DPRINT_LINUX;
44 #else //#elif defined (DEBUG_NONE)
45 ULONG DebugPrintMask = 0;
46 #endif
47
48 #define SCREEN 1
49 #define RS232 2
50 #define BOCHS 4
51
52 #define COM1 1
53 #define COM2 2
54 #define COM3 3
55 #define COM4 4
56
57 #define BOCHS_OUTPUT_PORT 0xe9
58
59 ULONG DebugPort = RS232;
60 //ULONG DebugPort = SCREEN;
61 //ULONG DebugPort = BOCHS;
62 //ULONG DebugPort = SCREEN|BOCHS;
63 ULONG ComPort = COM1;
64 //ULONG BaudRate = 19200;
65 ULONG BaudRate = 115200;
66
67 BOOLEAN DebugStartOfLine = TRUE;
68
69 // We need to emulate these, because the original ones don't work in freeldr
70 int __cdecl wctomb(char *mbchar, wchar_t wchar)
71 {
72 *mbchar = wchar;
73 return 1;
74 }
75
76 int __cdecl mbtowc (wchar_t *wchar, const char *mbchar, size_t count)
77 {
78 *wchar = *mbchar;
79 return 1;
80 }
81
82 VOID DebugInit(VOID)
83 {
84 if (DebugPort & RS232)
85 {
86 Rs232PortInitialize(ComPort, BaudRate);
87 }
88 }
89
90 VOID DebugPrintChar(UCHAR Character)
91 {
92 if (Character == '\n')
93 {
94 DebugStartOfLine = TRUE;
95 }
96
97 if (DebugPort & RS232)
98 {
99 if (Character == '\n')
100 {
101 Rs232PortPutByte('\r');
102 }
103 Rs232PortPutByte(Character);
104 }
105 if (DebugPort & BOCHS)
106 {
107 WRITE_PORT_UCHAR((PUCHAR)BOCHS_OUTPUT_PORT, Character);
108 }
109 if (DebugPort & SCREEN)
110 {
111 MachConsPutChar(Character);
112 }
113 }
114
115 ULONG
116 DbgPrint(const char *Format, ...)
117 {
118 int i;
119 int Length;
120 va_list ap;
121 CHAR Buffer[512];
122
123 va_start(ap, Format);
124 Length = _vsnprintf(Buffer, sizeof(Buffer), Format, ap);
125 va_end(ap);
126
127 /* Check if we went past the buffer */
128 if (Length == -1)
129 {
130 /* Terminate it if we went over-board */
131 Buffer[sizeof(Buffer) - 1] = '\n';
132
133 /* Put maximum */
134 Length = sizeof(Buffer);
135 }
136
137 for (i = 0; i < Length; i++)
138 {
139 DebugPrintChar(Buffer[i]);
140 }
141
142 return 0;
143 }
144
145 VOID DebugPrintHeader(ULONG Mask)
146 {
147 /* No header */
148 if (Mask == 0)
149 return;
150
151 switch (Mask)
152 {
153 case DPRINT_WARNING:
154 DbgPrint("WARNING: ");
155 break;
156 case DPRINT_MEMORY:
157 DbgPrint("MEMORY: ");
158 break;
159 case DPRINT_FILESYSTEM:
160 DbgPrint("FILESYS: ");
161 break;
162 case DPRINT_INIFILE:
163 DbgPrint("INIFILE: ");
164 break;
165 case DPRINT_UI:
166 DbgPrint("UI: ");
167 break;
168 case DPRINT_DISK:
169 DbgPrint("DISK: ");
170 break;
171 case DPRINT_CACHE:
172 DbgPrint("CACHE: ");
173 break;
174 case DPRINT_REGISTRY:
175 DbgPrint("REGISTRY: ");
176 break;
177 case DPRINT_REACTOS:
178 DbgPrint("REACTOS: ");
179 break;
180 case DPRINT_LINUX:
181 DbgPrint("LINUX: ");
182 break;
183 case DPRINT_WINDOWS:
184 DbgPrint("WINLDR: ");
185 break;
186 case DPRINT_HWDETECT:
187 DbgPrint("HWDETECT: ");
188 break;
189 case DPRINT_PELOADER:
190 DbgPrint("PELOADER: ");
191 break;
192 case DPRINT_SCSIPORT:
193 DbgPrint("SCSIPORT: ");
194 break;
195 default:
196 DbgPrint("UNKNOWN: ");
197 break;
198 }
199 }
200
201 char* g_file;
202 int g_line;
203
204 VOID DbgPrintMask(ULONG Mask, char *format, ...)
205 {
206 va_list ap;
207 char Buffer[2096];
208 char *ptr = Buffer;
209
210 // Mask out unwanted debug messages
211 if (!(Mask & DebugPrintMask))
212 {
213 return;
214 }
215
216 // Disable file/line for scsiport messages
217 if (Mask & DPRINT_SCSIPORT)
218 {
219 DebugStartOfLine = FALSE;
220 }
221
222 // Print the header if we have started a new line
223 if (DebugStartOfLine)
224 {
225 DbgPrint("(%s:%d) ", g_file, g_line);
226 DebugPrintHeader(Mask);
227 DebugStartOfLine = FALSE;
228 }
229
230 va_start(ap, format);
231 vsprintf(Buffer, format, ap);
232 va_end(ap);
233
234 while (*ptr)
235 {
236 DebugPrintChar(*ptr++);
237 }
238 }
239
240 VOID DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length)
241 {
242 PUCHAR BufPtr = (PUCHAR)Buffer;
243 ULONG Idx;
244 ULONG Idx2;
245
246 // Mask out unwanted debug messages
247 if (!(Mask & DebugPrintMask))
248 {
249 return;
250 }
251
252 DebugStartOfLine = FALSE; // We don't want line headers
253 DbgPrintMask(Mask, "Dumping buffer at 0x%x with length of %d bytes:\n", Buffer, Length);
254
255 for (Idx=0; Idx<Length; )
256 {
257 DebugStartOfLine = FALSE; // We don't want line headers
258
259 if (Idx < 0x0010)
260 {
261 DbgPrintMask(Mask, "000%x:\t", Idx);
262 }
263 else if (Idx < 0x0100)
264 {
265 DbgPrintMask(Mask, "00%x:\t", Idx);
266 }
267 else if (Idx < 0x1000)
268 {
269 DbgPrintMask(Mask, "0%x:\t", Idx);
270 }
271 else
272 {
273 DbgPrintMask(Mask, "%x:\t", Idx);
274 }
275
276 for (Idx2=0; Idx2<16; Idx2++,Idx++)
277 {
278 if (BufPtr[Idx] < 0x10)
279 {
280 DbgPrintMask(Mask, "0");
281 }
282 DbgPrintMask(Mask, "%x", BufPtr[Idx]);
283
284 if (Idx2 == 7)
285 {
286 DbgPrintMask(Mask, "-");
287 }
288 else
289 {
290 DbgPrintMask(Mask, " ");
291 }
292 }
293
294 Idx -= 16;
295 DbgPrintMask(Mask, " ");
296
297 for (Idx2=0; Idx2<16; Idx2++,Idx++)
298 {
299 if ((BufPtr[Idx] > 20) && (BufPtr[Idx] < 0x80))
300 {
301 DbgPrintMask(Mask, "%c", BufPtr[Idx]);
302 }
303 else
304 {
305 DbgPrintMask(Mask, ".");
306 }
307 }
308
309 DbgPrintMask(Mask, "\n");
310 }
311 }
312
313 #else
314
315 VOID DbgPrintMask(ULONG Mask, char *format, ...)
316 {
317 }
318
319 ULONG DbgPrint(PCCH Format, ...)
320 {
321 return 0;
322 }
323
324 #endif // DBG
325
326 ULONG
327 MsgBoxPrint(const char *Format, ...)
328 {
329 va_list ap;
330 CHAR Buffer[512];
331 ULONG Length;
332
333 va_start(ap, Format);
334
335 /* Construct a string */
336 Length = _vsnprintf(Buffer, 512, Format, ap);
337
338 /* Check if we went past the buffer */
339 if (Length == MAXULONG)
340 {
341 /* Terminate it if we went over-board */
342 Buffer[sizeof(Buffer) - 1] = '\n';
343
344 /* Put maximum */
345 Length = sizeof(Buffer);
346 }
347
348 /* Show it as a message box */
349 UiMessageBox(Buffer);
350
351 /* Cleanup and exit */
352 va_end(ap);
353 return 0;
354 }
355
356 NTKERNELAPI
357 VOID
358 NTAPI
359 KeBugCheckEx(
360 IN ULONG BugCheckCode,
361 IN ULONG_PTR BugCheckParameter1,
362 IN ULONG_PTR BugCheckParameter2,
363 IN ULONG_PTR BugCheckParameter3,
364 IN ULONG_PTR BugCheckParameter4)
365 {
366 char Buffer[70];
367 sprintf(Buffer, "*** STOP: 0x%08lX (0x%08lX, 0x%08lX, 0x%08lX, 0x%08lX)",
368 BugCheckCode, BugCheckParameter1, BugCheckParameter2,
369 BugCheckParameter3, BugCheckParameter4);
370 UiMessageBoxCritical(Buffer);
371 assert(FALSE);
372 for (;;);
373 }