ReactOS 0.4.16-dev-820-g96aa1ee
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
65{
66 static BOOLEAN Initialized = FALSE;
67 PSTR CommandLine, PortString, BaudString, IrqString;
69 CHAR DbgStringBuffer[256];
70
71 /* Always reset the debugging channels */
72
73#if defined (DEBUG_ALL)
74 memset(DbgChannels, MAX_LEVEL, DBG_CHANNELS_COUNT);
75#elif defined (DEBUG_WARN)
76 memset(DbgChannels, WARN_LEVEL|FIXME_LEVEL|ERR_LEVEL, DBG_CHANNELS_COUNT);
77#elif defined (DEBUG_ERR)
78 memset(DbgChannels, ERR_LEVEL, DBG_CHANNELS_COUNT);
79#else
80 memset(DbgChannels, 0, DBG_CHANNELS_COUNT);
81#endif
82
83#if defined (DEBUG_INIFILE)
84 DbgChannels[DPRINT_INIFILE] = MAX_LEVEL;
85#elif defined (DEBUG_REACTOS)
86 DbgChannels[DPRINT_REACTOS] = MAX_LEVEL;
87 DbgChannels[DPRINT_REGISTRY] = MAX_LEVEL;
88#elif defined (DEBUG_CUSTOM)
89 DbgChannels[DPRINT_WARNING] = MAX_LEVEL;
90 DbgChannels[DPRINT_WINDOWS] = MAX_LEVEL;
91#endif
92
93 CommandLine = NULL;
94 if (!DebugString || !*DebugString)
95 {
96 /* No command-line is provided: during pre-initialization,
97 * initialize the debug port with default settings;
98 * otherwise just return during main initialization */
99 if (!Initialized)
100 goto Done;
101 return;
102 }
103
104 /* Get a copy of the command-line */
105 strcpy(DbgStringBuffer, DebugString);
106 CommandLine = DbgStringBuffer;
107
108 /* Upcase it */
109 _strupr(CommandLine);
110
111 /* Get the port and baud rate */
112 PortString = strstr(CommandLine, "DEBUGPORT");
113 BaudString = strstr(CommandLine, "BAUDRATE");
114 IrqString = strstr(CommandLine, "IRQ");
115
116 /*
117 * Check if we got /DEBUGPORT parameters.
118 * NOTE: Inspired by reactos/ntoskrnl/kd/kdinit.c, KdInitSystem(...)
119 */
120 while (PortString)
121 {
122 /* Move past the actual string, to reach the port*/
123 PortString += strlen("DEBUGPORT");
124
125 /* Now get past any spaces and skip the equal sign */
126 while (*PortString == ' ') PortString++;
127 PortString++;
128
129 /* Check for possible ports and set the port to use */
130 if (strncmp(PortString, "SCREEN", 6) == 0)
131 {
132 PortString += 6;
133 DebugPort |= SCREEN;
134 }
135 else if (strncmp(PortString, "BOCHS", 5) == 0)
136 {
137 PortString += 5;
138 DebugPort |= BOCHS;
139 }
140 else if (strncmp(PortString, "COM", 3) == 0)
141 {
142 PortString += 3;
143 DebugPort |= RS232;
144
145 /* Set the port to use */
146 Value = atol(PortString);
147 if (Value) ComPort = Value;
148 }
149
150 PortString = strstr(PortString, "DEBUGPORT");
151 }
152
153 /* Check if we got a baud rate */
154 if (BaudString)
155 {
156 /* Move past the actual string, to reach the rate */
157 BaudString += strlen("BAUDRATE");
158
159 /* Now get past any spaces */
160 while (*BaudString == ' ') BaudString++;
161
162 /* And make sure we have a rate */
163 if (*BaudString)
164 {
165 /* Read and set it */
166 Value = atol(BaudString + 1);
167 if (Value) BaudRate = Value;
168 }
169 }
170
171 /* Check Serial Port Settings [IRQ] */
172 if (IrqString)
173 {
174 /* Move past the actual string, to reach the rate */
175 IrqString += strlen("IRQ");
176
177 /* Now get past any spaces */
178 while (*IrqString == ' ') IrqString++;
179
180 /* And make sure we have an IRQ */
181 if (*IrqString)
182 {
183 /* Read and set it */
184 Value = atol(IrqString + 1);
185 if (Value) PortIrq = Value;
186 }
187 }
188
189Done:
191
192 /* Try to initialize the port; if it fails, remove the corresponding flag */
193 if (DebugPort & RS232)
194 {
195 if (!Rs232PortInitialize(ComPort, BaudRate))
196 DebugPort &= ~RS232;
197 }
198}
199
200VOID DebugPrintChar(UCHAR Character)
201{
202 if (Character == '\n')
203 DebugStartOfLine = TRUE;
204
205 if (DebugPort & RS232)
206 {
207 if (Character == '\n')
208 Rs232PortPutByte('\r');
209
210 Rs232PortPutByte(Character);
211 }
212 if (DebugPort & BOCHS)
213 {
214 WRITE_PORT_UCHAR((PUCHAR)BOCHS_OUTPUT_PORT, Character);
215 }
216 if (DebugPort & SCREEN)
217 {
218 MachConsPutChar(Character);
219 }
220}
221
222ULONG
223DbgPrint(const char *Format, ...)
224{
225 va_list ap;
226 int Length;
227 char* ptr;
228 CHAR Buffer[512];
229
231 Length = _vsnprintf(Buffer, sizeof(Buffer), Format, ap);
232 va_end(ap);
233
234 /* Check if we went past the buffer */
235 if (Length == -1)
236 {
237 /* Terminate it if we went over-board */
238 Buffer[sizeof(Buffer) - 1] = '\n';
239
240 /* Put maximum */
241 Length = sizeof(Buffer);
242 }
243
244 ptr = Buffer;
245 while (Length--)
246 DebugPrintChar(*ptr++);
247
248 return 0;
249}
250
251VOID
252DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format, ...)
253{
254 va_list ap;
255 char Buffer[2096];
256 char *ptr = Buffer;
257
258 /* Mask out unwanted debug messages */
259 if (!(DbgChannels[Mask] & Level) && !(Level & DBG_DEFAULT_LEVELS))
260 {
261 return;
262 }
263
264 /* Print the header if we have started a new line */
265 if (DebugStartOfLine)
266 {
267 DbgPrint("(%s:%lu) ", File, Line);
268
269 switch (Level)
270 {
271 case ERR_LEVEL:
272 DbgPrint("err: ");
273 break;
274 case FIXME_LEVEL:
275 DbgPrint("fixme: ");
276 break;
277 case WARN_LEVEL:
278 DbgPrint("warn: ");
279 break;
280 case TRACE_LEVEL:
281 DbgPrint("trace: ");
282 break;
283 }
284
285 DebugStartOfLine = FALSE;
286 }
287
290 va_end(ap);
291
292 while (*ptr)
293 {
294 DebugPrintChar(*ptr++);
295 }
296}
297
298VOID
300{
301 PUCHAR BufPtr = (PUCHAR)Buffer;
303
304 /* Mask out unwanted debug messages */
305 if (!(DbgChannels[Mask] & TRACE_LEVEL))
306 return;
307
308 DebugStartOfLine = FALSE; // We don't want line headers
309 DbgPrint("Dumping buffer at %p with length of %lu bytes:\n", Buffer, Length);
310
311 Offset = 0;
312 while (Offset < Length)
313 {
314 /* We don't want line headers */
315 DebugStartOfLine = FALSE;
316
317 /* Print the offset */
318 DbgPrint("%04x:\t", Offset);
319
320 /* Print either 16 or the remaining number of bytes */
321 Count = min(Length - Offset, 16);
322 for (i = 0; i < Count; i++, Offset++)
323 {
324 DbgPrint("%02x%c", BufPtr[Offset], (i == 7) ? '-' : ' ');
325 }
326
327 DbgPrint("\n");
328 }
329}
330
331VOID
333{
334 DebugPort &= ~SCREEN;
335}
336
337static BOOLEAN
338DbgAddDebugChannel(CHAR* channel, CHAR* level, CHAR op)
339{
340 int iLevel, iChannel;
341
342 if (channel == NULL || *channel == '\0' || strlen(channel) == 0)
343 return FALSE;
344
345 if (level == NULL || *level == '\0' || strlen(level) == 0)
346 iLevel = MAX_LEVEL;
347 else if (strcmp(level, "err") == 0)
348 iLevel = ERR_LEVEL;
349 else if (strcmp(level, "fixme") == 0)
350 iLevel = FIXME_LEVEL;
351 else if (strcmp(level, "warn") == 0)
352 iLevel = WARN_LEVEL;
353 else if (strcmp(level, "trace") == 0)
354 iLevel = TRACE_LEVEL;
355 else
356 return FALSE;
357
358 if (strcmp(channel, "memory" ) == 0) iChannel = DPRINT_MEMORY;
359 else if (strcmp(channel, "filesystem") == 0) iChannel = DPRINT_FILESYSTEM;
360 else if (strcmp(channel, "inifile" ) == 0) iChannel = DPRINT_INIFILE;
361 else if (strcmp(channel, "ui" ) == 0) iChannel = DPRINT_UI;
362 else if (strcmp(channel, "disk" ) == 0) iChannel = DPRINT_DISK;
363 else if (strcmp(channel, "cache" ) == 0) iChannel = DPRINT_CACHE;
364 else if (strcmp(channel, "registry" ) == 0) iChannel = DPRINT_REGISTRY;
365 else if (strcmp(channel, "linux" ) == 0) iChannel = DPRINT_LINUX;
366 else if (strcmp(channel, "hwdetect" ) == 0) iChannel = DPRINT_HWDETECT;
367 else if (strcmp(channel, "windows" ) == 0) iChannel = DPRINT_WINDOWS;
368 else if (strcmp(channel, "peloader" ) == 0) iChannel = DPRINT_PELOADER;
369 else if (strcmp(channel, "scsiport" ) == 0) iChannel = DPRINT_SCSIPORT;
370 else if (strcmp(channel, "heap" ) == 0) iChannel = DPRINT_HEAP;
371 else if (strcmp(channel, "all" ) == 0)
372 {
373 int i;
374
375 for (i = 0; i < DBG_CHANNELS_COUNT; i++)
376 {
377 if (op == '+')
378 DbgChannels[i] |= iLevel;
379 else
380 DbgChannels[i] &= ~iLevel;
381 }
382
383 return TRUE;
384 }
385 else return FALSE;
386
387 if (op == '+')
388 DbgChannels[iChannel] |= iLevel;
389 else
390 DbgChannels[iChannel] &= ~iLevel;
391
392 return TRUE;
393}
394
395VOID
397{
398 CHAR *str, *separator, *c, op;
399
400 str = Value;
401
402 do
403 {
404 separator = strchr(str, ',');
405 if (separator != NULL)
406 *separator = '\0';
407
408 c = strchr(str, '+');
409 if (c == NULL)
410 c = strchr(str, '-');
411
412 if (c != NULL)
413 {
414 op = *c;
415 *c = '\0';
416 c++;
417
418 DbgAddDebugChannel(c, str, op);
419 }
420
421 str = separator + 1;
422 } while (separator != NULL);
423}
424
425#else
426
427#undef DebugInit
428VOID
431{
433}
434
435ULONG
437{
439 return 0;
440}
441
442VOID
443DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format, ...)
444{
450}
451
452VOID
454{
458}
459
460#undef DbgParseDebugChannels
461VOID
463{
465}
466
467#endif // DBG
468
469ULONG
470MsgBoxPrint(const char *Format, ...)
471{
472 va_list ap;
473 CHAR Buffer[512];
475
477
478 /* Construct a string */
479 Length = _vsnprintf(Buffer, 512, Format, ap);
480
481 /* Check if we went past the buffer */
482 if (Length == MAXULONG)
483 {
484 /* Terminate it if we went over-board */
485 Buffer[sizeof(Buffer) - 1] = '\n';
486
487 /* Put maximum */
488 Length = sizeof(Buffer);
489 }
490
491 /* Show it as a message box */
493
494 /* Cleanup and exit */
495 va_end(ap);
496 return 0;
497}
498
500VOID
501NTAPI
503 IN ULONG BugCheckCode,
504 IN ULONG_PTR BugCheckParameter1,
505 IN ULONG_PTR BugCheckParameter2,
506 IN ULONG_PTR BugCheckParameter3,
507 IN ULONG_PTR BugCheckParameter4)
508{
509 char Buffer[70];
510
512 "*** STOP: 0x%08lX (0x%p,0x%p,0x%p,0x%p)",
513 BugCheckCode,
514 (PVOID)BugCheckParameter1,
515 (PVOID)BugCheckParameter2,
516 (PVOID)BugCheckParameter3,
517 (PVOID)BugCheckParameter4);
518
520 ASSERT(FALSE);
521 for (;;);
522}
523
524VOID
525NTAPI
526RtlAssert(IN PVOID FailedAssertion,
530{
531 if (Message)
532 {
533 DbgPrint("Assertion \'%s\' failed at %s line %lu: %s\n",
534 (PCHAR)FailedAssertion,
537 Message);
538 }
539 else
540 {
541 DbgPrint("Assertion \'%s\' failed at %s line %lu\n",
542 (PCHAR)FailedAssertion,
544 LineNumber);
545 }
546
548}
549
551{
552 "TEST_BUGCHECK",
553 "MISSING_HARDWARE_REQUIREMENTS",
554 "FREELDR_IMAGE_CORRUPTION",
555 "MEMORY_INIT_FAILURE",
556#ifdef UEFIBOOT
557 "EXIT_BOOTSERVICES_FAILURE",
558#endif
559};
560
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 * 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 DbgParseDebugChannels(val)
Definition: debug.h:124
#define DPRINT_FILESYSTEM
Definition: debug.h:26
#define DebugInit(DebugString)
Definition: debug.h:120
#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:123
#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:561
char * BugCodeStrings[]
Definition: debug.c:550
VOID DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format,...)
Definition: debug.c:443
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:502
ULONG MsgBoxPrint(const char *Format,...)
Definition: debug.c:470
VOID DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length)
Definition: debug.c:453
VOID NTAPI RtlAssert(IN PVOID FailedAssertion, IN PVOID FileName, IN ULONG LineNumber, IN PCHAR Message OPTIONAL)
Definition: debug.c:526
static CCHAR DebugString[256]
Definition: settings.c:16
Definition: bufpool.h:45
Definition: File.h:16
#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)
#define c
Definition: ke_i.h:80
#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
@ Initialized
Definition: ketypes.h:388
#define _In_
Definition: no_sal2.h:158
int Count
Definition: noreturn.cpp:7
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:176
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
CONST CHAR * PCCH
Definition: ntbasedef.h:400
_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
_strupr
Definition: string.h:453
strcpy
Definition: string.h:131
#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
char * PSTR
Definition: typedefs.h:51
#define NTAPI
Definition: typedefs.h:36
const char * PCSTR
Definition: typedefs.h:52
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