2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/rtl/dbgprint.c
5 * PURPOSE: Debug output
7 * PROGRAMMERS: Eric Kohl (ekohl@abo.rhein-zeitung.de)
10 /* INCLUDES *****************************************************************/
13 #include <internal/debug.h>
15 /* DATA *********************************************************************/
22 #define MAX_KD_COMPONENT_TABLE_ENTRIES 128
23 KD_COMPONENT_DATA KdComponentTable
[MAX_KD_COMPONENT_TABLE_ENTRIES
];
24 ULONG KdComponentTableEntries
= 0;
26 /* FUNCTIONS ****************************************************************/
29 * Note: DON'T CHANGE THIS FUNCTION!!!
30 * DON'T CALL HalDisplayString OR SOMETING ELSE!!!
31 * You'll only break the serial/bochs debugging feature!!!
38 vDbgPrintExWithPrefix(IN LPCSTR Prefix
,
44 ANSI_STRING DebugString
;
48 #ifdef SERIALIZE_DBGPRINT
49 # define MESSAGETABLE_SIZE 16
52 static LONG TableWriteIndex
= 0, TableReadIndex
= 0;
53 static CHAR MessageTable
[MESSAGETABLE_SIZE
][sizeof(Buffer
)] = { { '\0' } };
54 #endif /* SERIALIZE_DBGPRINT */
56 /* TODO FIXME - call NtQueryDebugFilterState() instead per Alex */
57 if ( !DbgQueryDebugFilterState ( ComponentId
, Level
) )
60 /* init ansi string */
61 DebugString
.Buffer
= Buffer
;
62 DebugString
.MaximumLength
= sizeof(Buffer
);
65 pBufferSize
= sizeof(Buffer
);
66 DebugString
.Length
= 0;
67 if ( Prefix
&& *Prefix
)
69 DebugString
.Length
= strlen(Prefix
);
70 if ( DebugString
.Length
>= sizeof(Buffer
) )
71 DebugString
.Length
= sizeof(Buffer
) - 1;
72 memmove ( Buffer
, Prefix
, DebugString
.Length
);
73 Buffer
[DebugString
.Length
] = '\0';
74 pBuffer
= &Buffer
[DebugString
.Length
];
75 pBufferSize
-= DebugString
.Length
;
78 DebugString
.Length
+= _vsnprintf ( pBuffer
, pBufferSize
, Format
, ap
);
79 Buffer
[sizeof(Buffer
)-1] = '\0';
81 #ifdef SERIALIZE_DBGPRINT
82 /* check if we are already running */
83 if (InterlockedCompareExchange(&Lock
, 1, 0) == 1)
85 MyTableIndex
= InterlockedIncrement(&TableWriteIndex
) - 1;
86 InterlockedCompareExchange(&TableWriteIndex
, 0, MESSAGETABLE_SIZE
);
87 MyTableIndex
%= MESSAGETABLE_SIZE
;
89 if (MessageTable
[MyTableIndex
][0] != '\0') /* table is full */
91 DebugString
.Buffer
= "CRITICAL ERROR: DbgPrint Table is FULL!";
92 DebugString
.Length
= 39;
93 KdpPrintString(&DebugString
);
98 memcpy(MessageTable
[MyTableIndex
], DebugString
.Buffer
, DebugString
.Length
);
99 MessageTable
[MyTableIndex
][DebugString
.Length
] = '\0';
104 #endif /* SERIALIZE_DBGPRINT */
105 KdpPrintString (&DebugString
);
106 #ifdef SERIALIZE_DBGPRINT
107 MyTableIndex
= TableReadIndex
;
108 while (MessageTable
[MyTableIndex
][0] != '\0')
110 /*DebugString.Buffer = "$$$";
111 DebugString.Length = 3;
112 KdpPrintString(&DebugString);*/
114 DebugString
.Buffer
= MessageTable
[MyTableIndex
];
115 DebugString
.Length
= strlen(DebugString
.Buffer
);
116 DebugString
.MaximumLength
= DebugString
.Length
+ 1;
118 KdpPrintString(&DebugString
);
119 MessageTable
[MyTableIndex
][0] = '\0';
121 MyTableIndex
= InterlockedIncrement(&TableReadIndex
);
122 InterlockedCompareExchange(&TableReadIndex
, 0, MESSAGETABLE_SIZE
);
123 MyTableIndex
%= MESSAGETABLE_SIZE
;
125 InterlockedDecrement(&Lock
);
127 # undef MESSAGETABLE_SIZE
128 #endif /* SERIALIZE_DBGPRINT */
130 return (ULONG
)DebugString
.Length
;
137 vDbgPrintEx(IN ULONG ComponentId
,
142 return vDbgPrintExWithPrefix ( NULL
, ComponentId
, Level
, Format
, ap
);
149 DbgPrint(PCH Format
, ...)
154 va_start (ap
, Format
);
155 /* TODO FIXME - use DPFLTR_DEFAULT_ID and DPFLTR_INFO_LEVEL
157 * https://www.osronline.com/article.cfm?article=295
159 * ( first need to add those items to default registry and write the code
160 * to load those settings so we don't anger ros-devs when DbgPrint() suddenly
163 * ( also when you do this, remove -1 hack from DbgQueryDebugFilterState() )
165 rc
= vDbgPrintExWithPrefix ( NULL
, (ULONG
)-1, (ULONG
)-1, Format
, ap
);
176 DbgPrintEx(IN ULONG ComponentId
,
184 va_start (ap
, Format
);
185 rc
= vDbgPrintExWithPrefix ( NULL
, ComponentId
, Level
, Format
, ap
);
196 DbgPrintReturnControlC(PCH Format
,
208 DbgPrompt(PCH OutputString
,
216 Input
.MaximumLength
= InputSize
;
217 Input
.Buffer
= InputString
;
219 Output
.Length
= strlen (OutputString
);
220 Output
.MaximumLength
= Output
.Length
+ 1;
221 Output
.Buffer
= OutputString
;
223 /* FIXME: Not implemented yet!
224 KdpPromptString (&Output, &Input); */
232 DbgQueryDebugFilterState(IN ULONG ComponentId
,
237 /* HACK HACK HACK - see comments in DbgPrint() */
238 if ( ComponentId
== -1 )
241 /* convert Level to mask if it isn't already one */
245 for ( i
= 0; i
< KdComponentTableEntries
; i
++ )
247 if ( ComponentId
== KdComponentTable
[i
].ComponentId
)
249 if ( Level
& KdComponentTable
[i
].Level
)
262 DbgSetDebugFilterState(IN ULONG ComponentId
,
267 for ( i
= 0; i
< KdComponentTableEntries
; i
++ )
269 if ( ComponentId
== KdComponentTable
[i
].ComponentId
)
272 if ( i
== KdComponentTableEntries
)
274 if ( i
== MAX_KD_COMPONENT_TABLE_ENTRIES
)
275 return STATUS_INVALID_PARAMETER_1
;
276 ++KdComponentTableEntries
;
277 KdComponentTable
[i
].ComponentId
= ComponentId
;
278 KdComponentTable
[i
].Level
= 0;
281 KdComponentTable
[i
].Level
|= Level
;
283 KdComponentTable
[i
].Level
&= ~Level
;
284 return STATUS_SUCCESS
;
292 DbgLoadImageSymbols(IN PUNICODE_STRING Name
,
297 return STATUS_NOT_IMPLEMENTED
;