ReactOS 0.4.15-dev-7907-g95bf896
debug.c
Go to the documentation of this file.
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#include <debug.h>
22
23#if DBG
24
25// #define DEBUG_ALL
26// #define DEBUG_WARN
27// #define DEBUG_ERR
28// #define DEBUG_INIFILE
29// #define DEBUG_REACTOS
30// #define DEBUG_CUSTOM
31#define DEBUG_NONE
32
33#define DBG_DEFAULT_LEVELS (ERR_LEVEL|FIXME_LEVEL)
34
35static UCHAR DbgChannels[DBG_CHANNELS_COUNT];
36
37#define SCREEN 1
38#define RS232 2
39#define BOCHS 4
40
41#define BOCHS_OUTPUT_PORT 0xE9
42
43ULONG DebugPort = RS232;
44
45/* Serial debug connection */
46#if defined(SARCH_PC98)
47ULONG BaudRate = 9600;
48#else
49ULONG BaudRate = 115200;
50#endif
51
52ULONG ComPort = 0; // The COM port initializer chooses the first available port starting from COM4 down to COM1.
53ULONG PortIrq = 0; // Not used at the moment.
54
55BOOLEAN DebugStartOfLine = TRUE;
56
57#ifdef UEFIBOOT
58VOID
59ARMWriteToUART(UCHAR Data);
60#endif
61
62VOID DebugInit(IN ULONG_PTR FrLdrSectionId)
63{
64 PCHAR CommandLine, PortString, BaudString, IrqString;
66 CHAR DebugString[256];
67
68 /* Always reset the debugging channels */
69
70#if defined (DEBUG_ALL)
71 memset(DbgChannels, MAX_LEVEL, DBG_CHANNELS_COUNT);
72#elif defined (DEBUG_WARN)
73 memset(DbgChannels, WARN_LEVEL|FIXME_LEVEL|ERR_LEVEL, DBG_CHANNELS_COUNT);
74#elif defined (DEBUG_ERR)
75 memset(DbgChannels, ERR_LEVEL, DBG_CHANNELS_COUNT);
76#else
77 memset(DbgChannels, 0, DBG_CHANNELS_COUNT);
78#endif
79
80#if defined (DEBUG_INIFILE)
81 DbgChannels[DPRINT_INIFILE] = MAX_LEVEL;
82#elif defined (DEBUG_REACTOS)
83 DbgChannels[DPRINT_REACTOS] = MAX_LEVEL;
84 DbgChannels[DPRINT_REGISTRY] = MAX_LEVEL;
85#elif defined (DEBUG_CUSTOM)
86 DbgChannels[DPRINT_WARNING] = MAX_LEVEL;
87 DbgChannels[DPRINT_WINDOWS] = MAX_LEVEL;
88#endif
89
90 /* Check for pre- or main initialization phase */
91 if (FrLdrSectionId == 0)
92 {
93 /* Pre-initialization phase: use the FreeLdr command-line debugging string */
94 CommandLine = (PCHAR)CmdLineGetDebugString();
95
96 /* If no command-line is provided, initialize the debug port with default settings */
97 if (CommandLine == NULL)
98 goto Done;
99
100 strcpy(DebugString, CommandLine);
101 }
102 else
103 {
104 /* Main initialization phase: use the FreeLdr INI debugging string */
105 if (!IniReadSettingByName(FrLdrSectionId, "Debug", DebugString, sizeof(DebugString)))
106 {
107 return;
108 }
109 }
110
111 /* Get the Command Line */
112 CommandLine = DebugString;
113
114 /* Upcase it */
115 _strupr(CommandLine);
116
117 /* Get the port and baud rate */
118 PortString = strstr(CommandLine, "DEBUGPORT");
119 BaudString = strstr(CommandLine, "BAUDRATE");
120 IrqString = strstr(CommandLine, "IRQ");
121
122 /*
123 * Check if we got /DEBUGPORT parameters.
124 * NOTE: Inspired by reactos/ntoskrnl/kd/kdinit.c, KdInitSystem(...)
125 */
126 while (PortString)
127 {
128 /* Move past the actual string, to reach the port*/
129 PortString += strlen("DEBUGPORT");
130
131 /* Now get past any spaces and skip the equal sign */
132 while (*PortString == ' ') PortString++;
133 PortString++;
134
135 /* Check for possible ports and set the port to use */
136 if (strncmp(PortString, "SCREEN", 6) == 0)
137 {
138 PortString += 6;
139 DebugPort |= SCREEN;
140 }
141 else if (strncmp(PortString, "BOCHS", 5) == 0)
142 {
143 PortString += 5;
144 DebugPort |= BOCHS;
145 }
146 else if (strncmp(PortString, "COM", 3) == 0)
147 {
148 PortString += 3;
149 DebugPort |= RS232;
150
151 /* Set the port to use */
152 Value = atol(PortString);
153 if (Value) ComPort = Value;
154 }
155
156 PortString = strstr(PortString, "DEBUGPORT");
157 }
158
159 /* Check if we got a baud rate */
160 if (BaudString)
161 {
162 /* Move past the actual string, to reach the rate */
163 BaudString += strlen("BAUDRATE");
164
165 /* Now get past any spaces */
166 while (*BaudString == ' ') BaudString++;
167
168 /* And make sure we have a rate */
169 if (*BaudString)
170 {
171 /* Read and set it */
172 Value = atol(BaudString + 1);
173 if (Value) BaudRate = Value;
174 }
175 }
176
177 /* Check Serial Port Settings [IRQ] */
178 if (IrqString)
179 {
180 /* Move past the actual string, to reach the rate */
181 IrqString += strlen("IRQ");
182
183 /* Now get past any spaces */
184 while (*IrqString == ' ') IrqString++;
185
186 /* And make sure we have an IRQ */
187 if (*IrqString)
188 {
189 /* Read and set it */
190 Value = atol(IrqString + 1);
191 if (Value) PortIrq = Value;
192 }
193 }
194
195Done:
196 /* Try to initialize the port; if it fails, remove the corresponding flag */
197 if (DebugPort & RS232)
198 {
199 if (!Rs232PortInitialize(ComPort, BaudRate))
200 DebugPort &= ~RS232;
201 }
202}
203
204VOID DebugPrintChar(UCHAR Character)
205{
206 if (Character == '\n')
207 DebugStartOfLine = TRUE;
208
209 if (DebugPort & RS232)
210 {
211 if (Character == '\n')
212 Rs232PortPutByte('\r');
213
214 Rs232PortPutByte(Character);
215 }
216 if (DebugPort & BOCHS)
217 {
218 WRITE_PORT_UCHAR((PUCHAR)BOCHS_OUTPUT_PORT, Character);
219 }
220 if (DebugPort & SCREEN)
221 {
222 MachConsPutChar(Character);
223 }
224}
225
226ULONG
227DbgPrint(const char *Format, ...)
228{
229 va_list ap;
230 int Length;
231 char* ptr;
232 CHAR Buffer[512];
233
235 Length = _vsnprintf(Buffer, sizeof(Buffer), Format, ap);
236 va_end(ap);
237
238 /* Check if we went past the buffer */
239 if (Length == -1)
240 {
241 /* Terminate it if we went over-board */
242 Buffer[sizeof(Buffer) - 1] = '\n';
243
244 /* Put maximum */
245 Length = sizeof(Buffer);
246 }
247
248 ptr = Buffer;
249 while (Length--)
250 DebugPrintChar(*ptr++);
251
252 return 0;
253}
254
255VOID
256DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format, ...)
257{
258 va_list ap;
259 char Buffer[2096];
260 char *ptr = Buffer;
261
262 /* Mask out unwanted debug messages */
263 if (!(DbgChannels[Mask] & Level) && !(Level & DBG_DEFAULT_LEVELS))
264 {
265 return;
266 }
267
268 /* Print the header if we have started a new line */
269 if (DebugStartOfLine)
270 {
271 DbgPrint("(%s:%lu) ", File, Line);
272
273 switch (Level)
274 {
275 case ERR_LEVEL:
276 DbgPrint("err: ");
277 break;
278 case FIXME_LEVEL:
279 DbgPrint("fixme: ");
280 break;
281 case WARN_LEVEL:
282 DbgPrint("warn: ");
283 break;
284 case TRACE_LEVEL:
285 DbgPrint("trace: ");
286 break;
287 }
288
289 DebugStartOfLine = FALSE;
290 }
291
294 va_end(ap);
295
296 while (*ptr)
297 {
298 DebugPrintChar(*ptr++);
299 }
300}
301
302VOID
303DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length)
304{
305 PUCHAR BufPtr = (PUCHAR)Buffer;
307
308 /* Mask out unwanted debug messages */
309 if (!(DbgChannels[Mask] & TRACE_LEVEL))
310 return;
311
312 DebugStartOfLine = FALSE; // We don't want line headers
313 DbgPrint("Dumping buffer at %p with length of %lu bytes:\n", Buffer, Length);
314
315 Offset = 0;
316 while (Offset < Length)
317 {
318 /* We don't want line headers */
319 DebugStartOfLine = FALSE;
320
321 /* Print the offset */
322 DbgPrint("%04x:\t", Offset);
323
324 /* Print either 16 or the remaining number of bytes */
325 Count = min(Length - Offset, 16);
326 for (i = 0; i < Count; i++, Offset++)
327 {
328 DbgPrint("%02x%c", BufPtr[Offset], (i == 7) ? '-' : ' ');
329 }
330
331 DbgPrint("\n");
332 }
333}
334
335VOID
337{
338 DebugPort &= ~SCREEN;
339}
340
341static BOOLEAN
342DbgAddDebugChannel(CHAR* channel, CHAR* level, CHAR op)
343{
344 int iLevel, iChannel;
345
346 if (channel == NULL || *channel == '\0' || strlen(channel) == 0)
347 return FALSE;
348
349 if (level == NULL || *level == '\0' || strlen(level) == 0)
350 iLevel = MAX_LEVEL;
351 else if (strcmp(level, "err") == 0)
352 iLevel = ERR_LEVEL;
353 else if (strcmp(level, "fixme") == 0)
354 iLevel = FIXME_LEVEL;
355 else if (strcmp(level, "warn") == 0)
356 iLevel = WARN_LEVEL;
357 else if (strcmp(level, "trace") == 0)
358 iLevel = TRACE_LEVEL;
359 else
360 return FALSE;
361
362 if (strcmp(channel, "memory" ) == 0) iChannel = DPRINT_MEMORY;
363 else if (strcmp(channel, "filesystem") == 0) iChannel = DPRINT_FILESYSTEM;
364 else if (strcmp(channel, "inifile" ) == 0) iChannel = DPRINT_INIFILE;
365 else if (strcmp(channel, "ui" ) == 0) iChannel = DPRINT_UI;
366 else if (strcmp(channel, "disk" ) == 0) iChannel = DPRINT_DISK;
367 else if (strcmp(channel, "cache" ) == 0) iChannel = DPRINT_CACHE;
368 else if (strcmp(channel, "registry" ) == 0) iChannel = DPRINT_REGISTRY;
369 else if (strcmp(channel, "linux" ) == 0) iChannel = DPRINT_LINUX;
370 else if (strcmp(channel, "hwdetect" ) == 0) iChannel = DPRINT_HWDETECT;
371 else if (strcmp(channel, "windows" ) == 0) iChannel = DPRINT_WINDOWS;
372 else if (strcmp(channel, "peloader" ) == 0) iChannel = DPRINT_PELOADER;
373 else if (strcmp(channel, "scsiport" ) == 0) iChannel = DPRINT_SCSIPORT;
374 else if (strcmp(channel, "heap" ) == 0) iChannel = DPRINT_HEAP;
375 else if (strcmp(channel, "all" ) == 0)
376 {
377 int i;
378
379 for (i = 0; i < DBG_CHANNELS_COUNT; i++)
380 {
381 if (op == '+')
382 DbgChannels[i] |= iLevel;
383 else
384 DbgChannels[i] &= ~iLevel;
385 }
386
387 return TRUE;
388 }
389 else return FALSE;
390
391 if (op == '+')
392 DbgChannels[iChannel] |= iLevel;
393 else
394 DbgChannels[iChannel] &= ~iLevel;
395
396 return TRUE;
397}
398
399VOID
401{
402 CHAR *str, *separator, *c, op;
403
404 str = Value;
405
406 do
407 {
408 separator = strchr(str, ',');
409 if (separator != NULL)
410 *separator = '\0';
411
412 c = strchr(str, '+');
413 if (c == NULL)
414 c = strchr(str, '-');
415
416 if (c != NULL)
417 {
418 op = *c;
419 *c = '\0';
420 c++;
421
422 DbgAddDebugChannel(c, str, op);
423 }
424
425 str = separator + 1;
426 } while (separator != NULL);
427}
428
429#else
430
431ULONG
433{
434 return 0;
435}
436
437#endif // DBG
438
439ULONG
440MsgBoxPrint(const char *Format, ...)
441{
442 va_list ap;
443 CHAR Buffer[512];
445
447
448 /* Construct a string */
449 Length = _vsnprintf(Buffer, 512, Format, ap);
450
451 /* Check if we went past the buffer */
452 if (Length == MAXULONG)
453 {
454 /* Terminate it if we went over-board */
455 Buffer[sizeof(Buffer) - 1] = '\n';
456
457 /* Put maximum */
458 Length = sizeof(Buffer);
459 }
460
461 /* Show it as a message box */
463
464 /* Cleanup and exit */
465 va_end(ap);
466 return 0;
467}
468
470VOID
471NTAPI
473 IN ULONG BugCheckCode,
474 IN ULONG_PTR BugCheckParameter1,
475 IN ULONG_PTR BugCheckParameter2,
476 IN ULONG_PTR BugCheckParameter3,
477 IN ULONG_PTR BugCheckParameter4)
478{
479 char Buffer[70];
480
482 "*** STOP: 0x%08lX (0x%p,0x%p,0x%p,0x%p)",
483 BugCheckCode,
484 (PVOID)BugCheckParameter1,
485 (PVOID)BugCheckParameter2,
486 (PVOID)BugCheckParameter3,
487 (PVOID)BugCheckParameter4);
488
490 ASSERT(FALSE);
491 for (;;);
492}
493
494VOID
495NTAPI
496RtlAssert(IN PVOID FailedAssertion,
500{
501 if (Message)
502 {
503 DbgPrint("Assertion \'%s\' failed at %s line %lu: %s\n",
504 (PCHAR)FailedAssertion,
507 Message);
508 }
509 else
510 {
511 DbgPrint("Assertion \'%s\' failed at %s line %lu\n",
512 (PCHAR)FailedAssertion,
514 LineNumber);
515 }
516
518}
519
521{
522 "TEST_BUGCHECK",
523 "MISSING_HARDWARE_REQUIREMENTS",
524 "FREELDR_IMAGE_CORRUPTION",
525 "MEMORY_INIT_FAILURE",
526#ifdef UEFIBOOT
527 "EXIT_BOOTSERVICES_FAILURE",
528#endif
529};
530
unsigned char BOOLEAN
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * strchr(const char *String, int ch)
Definition: utclib.c:501
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 LineNumber
Definition: acpixf.h:1220
BOOLEAN Rs232PortInitialize(IN ULONG ComPort, IN ULONG BaudRate)
Definition: debug.c:15
VOID Rs232PortPutByte(UCHAR ByteToSend)
Definition: debug.c:22
#define DPRINT_CACHE
Definition: debug.h:30
#define DPRINT_LINUX
Definition: debug.h:33
#define DPRINT_UI
Definition: debug.h:28
#define DebugInit(FrLdrSectionId)
Definition: debug.h:117
#define DbgParseDebugChannels(val)
Definition: debug.h:121
#define DPRINT_FILESYSTEM
Definition: debug.h:26
#define DPRINT_SCSIPORT
Definition: debug.h:37
#define DBG_CHANNELS_COUNT
Definition: debug.h:39
#define DPRINT_HEAP
Definition: debug.h:38
#define DPRINT_INIFILE
Definition: debug.h:27
#define DPRINT_REACTOS
Definition: debug.h:32
#define DPRINT_HWDETECT
Definition: debug.h:34
#define DPRINT_REGISTRY
Definition: debug.h:31
#define DPRINT_DISK
Definition: debug.h:29
#define DPRINT_WINDOWS
Definition: debug.h:35
#define DebugDisableScreenPort()
Definition: debug.h:120
#define DPRINT_MEMORY
Definition: debug.h:25
#define DPRINT_WARNING
Definition: debug.h:24
#define DPRINT_PELOADER
Definition: debug.h:36
#define MachConsPutChar(Ch)
Definition: machine.h:86
VOID UiMessageBoxCritical(_In_ PCSTR MessageText)
Definition: ui.c:372
VOID UiMessageBox(_In_ PCSTR Format,...)
Definition: ui.c:359
ULONG_PTR BugCheckInfo[5]
Definition: debug.c:531
char * BugCodeStrings[]
Definition: debug.c:520
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:472
ULONG MsgBoxPrint(const char *Format,...)
Definition: debug.c:440
VOID NTAPI RtlAssert(IN PVOID FailedAssertion, IN PVOID FileName, IN ULONG LineNumber, IN PCHAR Message OPTIONAL)
Definition: debug.c:496
Definition: bufpool.h:45
Definition: File.h:16
CCHAR DebugString[256]
Definition: cmdline.c:22
PCSTR CmdLineGetDebugString(VOID)
Definition: cmdline.c:123
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:236
static const WCHAR separator[]
Definition: asmname.c:65
static const WCHAR Message[]
Definition: register.c:74
unsigned int Mask
Definition: fpcontrol.c:82
GLint level
Definition: gl.h:1546
const GLubyte * c
Definition: glext.h:8905
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define DbgPrint
Definition: hal.h:12
int __cdecl vsprintf(char *_Dest, const char *_Format, va_list _Args)
Definition: sprintf.c:733
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
NTSYSAPI void WINAPI DbgBreakPoint(void)
BOOLEAN IniReadSettingByName(ULONG_PTR SectionId, PCSTR SettingName, PCHAR Buffer, ULONG BufferSize)
Definition: inifile.c:149
#define c
Definition: ke_i.h:80
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
static PVOID ptr
Definition: dispmode.c:27
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define min(a, b)
Definition: monoChain.cc:55
int Count
Definition: noreturn.cpp:7
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:176
CONST CHAR * PCCH
Definition: ntbasedef.h:392
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
const WCHAR * str
_CRTIMP char *__cdecl _strupr(_Inout_z_ char *_String)
#define memset(x, y, z)
Definition: compat.h:39
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
Definition: ncftp.h:79
#define MAXULONG
Definition: typedefs.h:251
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56
#define _vsnprintf
Definition: xmlstorage.h:202
unsigned char UCHAR
Definition: xmlstorage.h:181
char CHAR
Definition: xmlstorage.h:175