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 registry by default tho so we don't anger
160 * ros-devs when DbgPrint() suddenly stops working )
162 * ( also when you do this, remove -1 hack from DbgQueryDebugFilterState() )
164 rc
= vDbgPrintExWithPrefix ( NULL
, (ULONG
)-1, (ULONG
)-1, Format
, ap
);
175 DbgPrintEx(IN ULONG ComponentId
,
183 va_start (ap
, Format
);
184 rc
= vDbgPrintExWithPrefix ( NULL
, ComponentId
, Level
, Format
, ap
);
195 DbgPrintReturnControlC(PCH Format
,
207 DbgPrompt(PCH OutputString
,
215 Input
.MaximumLength
= InputSize
;
216 Input
.Buffer
= InputString
;
218 Output
.Length
= strlen (OutputString
);
219 Output
.MaximumLength
= Output
.Length
+ 1;
220 Output
.Buffer
= OutputString
;
222 /* FIXME: Not implemented yet!
223 KdpPromptString (&Output, &Input); */
231 DbgQueryDebugFilterState(IN ULONG ComponentId
,
236 if ( ComponentId
== -1 )
239 /* convert Level to mask if it isn't already one */
243 for ( i
= 0; i
< KdComponentTableEntries
; i
++ )
245 if ( ComponentId
== KdComponentTable
[i
].ComponentId
)
247 if ( Level
& KdComponentTable
[i
].Level
)
260 DbgSetDebugFilterState(IN ULONG ComponentId
,
265 for ( i
= 0; i
< KdComponentTableEntries
; i
++ )
267 if ( ComponentId
== KdComponentTable
[i
].ComponentId
)
270 if ( i
== KdComponentTableEntries
)
272 if ( i
== MAX_KD_COMPONENT_TABLE_ENTRIES
)
273 return STATUS_INVALID_PARAMETER_1
;
274 ++KdComponentTableEntries
;
275 KdComponentTable
[i
].ComponentId
= ComponentId
;
276 KdComponentTable
[i
].Level
= 0;
279 KdComponentTable
[i
].Level
|= Level
;
281 KdComponentTable
[i
].Level
&= ~Level
;
282 return STATUS_SUCCESS
;
290 DbgLoadImageSymbols(IN PUNICODE_STRING Name
,
295 return STATUS_NOT_IMPLEMENTED
;