mirror of
https://github.com/reactos/reactos.git
synced 2025-06-13 08:48:29 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
422
sdk/lib/rtl/debug.c
Normal file
422
sdk/lib/rtl/debug.c
Normal file
|
@ -0,0 +1,422 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Run-Time Library
|
||||
* FILE: lib/rtl/debug.c
|
||||
* PURPOSE: Debug Print and Prompt routines
|
||||
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
||||
* Royce Mitchel III
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <rtl.h>
|
||||
|
||||
#include <ndk/kdfuncs.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* PRIVATE FUNCTIONS ********************************************************/
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
DebugPrint(IN PSTRING DebugString,
|
||||
IN ULONG ComponentId,
|
||||
IN ULONG Level)
|
||||
{
|
||||
/* Call the Debug Service */
|
||||
return DebugService(BREAKPOINT_PRINT,
|
||||
DebugString->Buffer,
|
||||
UlongToPtr(DebugString->Length),
|
||||
UlongToPtr(ComponentId),
|
||||
UlongToPtr(Level));
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
DebugPrompt(IN PSTRING Output,
|
||||
IN PSTRING Input)
|
||||
{
|
||||
/* Call the Debug Service */
|
||||
return DebugService(BREAKPOINT_PROMPT,
|
||||
Output->Buffer,
|
||||
UlongToPtr(Output->Length),
|
||||
Input->Buffer,
|
||||
UlongToPtr(Input->MaximumLength));
|
||||
}
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
vDbgPrintExWithPrefixInternal(IN PCCH Prefix,
|
||||
IN ULONG ComponentId,
|
||||
IN ULONG Level,
|
||||
IN PCCH Format,
|
||||
IN va_list ap,
|
||||
IN BOOLEAN HandleBreakpoint)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
STRING DebugString;
|
||||
CHAR Buffer[512];
|
||||
SIZE_T Length, PrefixLength;
|
||||
EXCEPTION_RECORD ExceptionRecord;
|
||||
|
||||
/* Check if we should print it or not */
|
||||
if ((ComponentId != MAXULONG) &&
|
||||
(NtQueryDebugFilterState(ComponentId, Level)) != (NTSTATUS)TRUE)
|
||||
{
|
||||
/* This message is masked */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* For user mode, don't recursively DbgPrint */
|
||||
if (RtlpSetInDbgPrint()) return STATUS_SUCCESS;
|
||||
|
||||
/* Guard against incorrect pointers */
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Get the length and normalize it */
|
||||
PrefixLength = strlen(Prefix);
|
||||
if (PrefixLength > sizeof(Buffer)) PrefixLength = sizeof(Buffer);
|
||||
|
||||
/* Copy it */
|
||||
strncpy(Buffer, Prefix, PrefixLength);
|
||||
|
||||
/* Do the printf */
|
||||
Length = _vsnprintf(Buffer + PrefixLength,
|
||||
sizeof(Buffer) - PrefixLength,
|
||||
Format,
|
||||
ap);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
/* Fail */
|
||||
_SEH2_YIELD(return _SEH2_GetExceptionCode());
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
/* Check if we went past the buffer */
|
||||
if (Length == MAXULONG)
|
||||
{
|
||||
/* Terminate it if we went over-board */
|
||||
Buffer[sizeof(Buffer) - 1] = '\n';
|
||||
|
||||
/* Put maximum */
|
||||
Length = sizeof(Buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Add the prefix */
|
||||
Length += PrefixLength;
|
||||
}
|
||||
|
||||
/* Build the string */
|
||||
DebugString.Length = (USHORT)Length;
|
||||
DebugString.Buffer = Buffer;
|
||||
|
||||
/* First, let the debugger know as well */
|
||||
if (RtlpCheckForActiveDebugger())
|
||||
{
|
||||
/* Fill out an exception record */
|
||||
ExceptionRecord.ExceptionCode = DBG_PRINTEXCEPTION_C;
|
||||
ExceptionRecord.ExceptionRecord = NULL;
|
||||
ExceptionRecord.NumberParameters = 2;
|
||||
ExceptionRecord.ExceptionFlags = 0;
|
||||
ExceptionRecord.ExceptionInformation[0] = DebugString.Length + 1;
|
||||
ExceptionRecord.ExceptionInformation[1] = (ULONG_PTR)DebugString.Buffer;
|
||||
|
||||
/* Raise the exception */
|
||||
RtlRaiseException(&ExceptionRecord);
|
||||
|
||||
/* This code only runs in user-mode, so setting the flag is safe */
|
||||
NtCurrentTeb()->InDbgPrint = FALSE;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Call the Debug Print routine */
|
||||
Status = DebugPrint(&DebugString, ComponentId, Level);
|
||||
|
||||
/* Check if this was with Control-C */
|
||||
if (HandleBreakpoint)
|
||||
{
|
||||
/* Check if we got a breakpoint */
|
||||
if (Status == STATUS_BREAKPOINT)
|
||||
{
|
||||
/* Breakpoint */
|
||||
DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* In user-mode, clear the InDbgPrint Flag */
|
||||
RtlpClearInDbgPrint();
|
||||
|
||||
/* Return */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
ULONG
|
||||
NTAPI
|
||||
vDbgPrintExWithPrefix(IN PCCH Prefix,
|
||||
IN ULONG ComponentId,
|
||||
IN ULONG Level,
|
||||
IN PCCH Format,
|
||||
IN va_list ap)
|
||||
{
|
||||
/* Call the internal routine that also handles ControlC */
|
||||
return vDbgPrintExWithPrefixInternal(Prefix,
|
||||
ComponentId,
|
||||
Level,
|
||||
Format,
|
||||
ap,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
ULONG
|
||||
NTAPI
|
||||
vDbgPrintEx(IN ULONG ComponentId,
|
||||
IN ULONG Level,
|
||||
IN PCCH Format,
|
||||
IN va_list ap)
|
||||
{
|
||||
/* Call the internal routine that also handles ControlC */
|
||||
return vDbgPrintExWithPrefixInternal("",
|
||||
ComponentId,
|
||||
Level,
|
||||
Format,
|
||||
ap,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
ULONG
|
||||
__cdecl
|
||||
DbgPrint(PCCH Format,
|
||||
...)
|
||||
{
|
||||
ULONG Status;
|
||||
va_list ap;
|
||||
|
||||
/* Call the internal routine that also handles ControlC */
|
||||
va_start(ap, Format);
|
||||
Status = vDbgPrintExWithPrefixInternal("",
|
||||
-1,
|
||||
DPFLTR_ERROR_LEVEL,
|
||||
Format,
|
||||
ap,
|
||||
TRUE);
|
||||
va_end(ap);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
ULONG
|
||||
__cdecl
|
||||
DbgPrintEx(IN ULONG ComponentId,
|
||||
IN ULONG Level,
|
||||
IN PCCH Format,
|
||||
...)
|
||||
{
|
||||
ULONG Status;
|
||||
va_list ap;
|
||||
|
||||
/* Call the internal routine that also handles ControlC */
|
||||
va_start(ap, Format);
|
||||
Status = vDbgPrintExWithPrefixInternal("",
|
||||
ComponentId,
|
||||
Level,
|
||||
Format,
|
||||
ap,
|
||||
TRUE);
|
||||
va_end(ap);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
ULONG
|
||||
__cdecl
|
||||
DbgPrintReturnControlC(PCCH Format,
|
||||
...)
|
||||
{
|
||||
ULONG Status;
|
||||
va_list ap;
|
||||
|
||||
/* Call the internal routine that also handles ControlC */
|
||||
va_start(ap, Format);
|
||||
Status = vDbgPrintExWithPrefixInternal("",
|
||||
-1,
|
||||
DPFLTR_ERROR_LEVEL,
|
||||
Format,
|
||||
ap,
|
||||
FALSE);
|
||||
va_end(ap);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
ULONG
|
||||
NTAPI
|
||||
DbgPrompt(IN PCCH Prompt,
|
||||
OUT PCH Response,
|
||||
IN ULONG MaximumResponseLength)
|
||||
{
|
||||
STRING Output;
|
||||
STRING Input;
|
||||
|
||||
/* Setup the input string */
|
||||
Input.MaximumLength = (USHORT)MaximumResponseLength;
|
||||
Input.Buffer = Response;
|
||||
|
||||
/* Setup the output string */
|
||||
Output.Length = (USHORT)strlen(Prompt);
|
||||
Output.Buffer = (PCHAR)Prompt;
|
||||
|
||||
/* Call the system service */
|
||||
return DebugPrompt(&Output, &Input);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DbgQueryDebugFilterState(IN ULONG ComponentId,
|
||||
IN ULONG Level)
|
||||
{
|
||||
/* Call the Nt routine */
|
||||
return NtQueryDebugFilterState(ComponentId, Level);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DbgSetDebugFilterState(IN ULONG ComponentId,
|
||||
IN ULONG Level,
|
||||
IN BOOLEAN State)
|
||||
{
|
||||
/* Call the Nt routine */
|
||||
return NtSetDebugFilterState(ComponentId, Level, State);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
DbgLoadImageSymbols(IN PSTRING Name,
|
||||
IN PVOID Base,
|
||||
IN ULONG_PTR ProcessId)
|
||||
{
|
||||
PIMAGE_NT_HEADERS NtHeader;
|
||||
KD_SYMBOLS_INFO SymbolInfo;
|
||||
|
||||
/* Setup the symbol data */
|
||||
SymbolInfo.BaseOfDll = Base;
|
||||
SymbolInfo.ProcessId = ProcessId;
|
||||
|
||||
/* Get NT Headers */
|
||||
NtHeader = RtlImageNtHeader(Base);
|
||||
if (NtHeader)
|
||||
{
|
||||
/* Get the rest of the data */
|
||||
SymbolInfo.CheckSum = NtHeader->OptionalHeader.CheckSum;
|
||||
SymbolInfo.SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No data available */
|
||||
SymbolInfo.CheckSum =
|
||||
SymbolInfo.SizeOfImage = 0;
|
||||
}
|
||||
|
||||
/* Load the symbols */
|
||||
DebugService2(Name, &SymbolInfo, BREAKPOINT_LOAD_SYMBOLS);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
DbgUnLoadImageSymbols(IN PSTRING Name,
|
||||
IN PVOID Base,
|
||||
IN ULONG_PTR ProcessId)
|
||||
{
|
||||
KD_SYMBOLS_INFO SymbolInfo;
|
||||
|
||||
/* Setup the symbol data */
|
||||
SymbolInfo.BaseOfDll = Base;
|
||||
SymbolInfo.ProcessId = ProcessId;
|
||||
SymbolInfo.CheckSum = SymbolInfo.SizeOfImage = 0;
|
||||
|
||||
/* Load the symbols */
|
||||
DebugService2(Name, &SymbolInfo, BREAKPOINT_UNLOAD_SYMBOLS);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
DbgCommandString(IN PCCH Name,
|
||||
IN PCCH Command)
|
||||
{
|
||||
STRING NameString, CommandString;
|
||||
|
||||
/* Setup the strings */
|
||||
NameString.Buffer = (PCHAR)Name;
|
||||
NameString.Length = (USHORT)strlen(Name);
|
||||
CommandString.Buffer = (PCHAR)Command;
|
||||
CommandString.Length = (USHORT)strlen(Command);
|
||||
|
||||
/* Send them to the debugger */
|
||||
DebugService2(&NameString, &CommandString, BREAKPOINT_COMMAND_STRING);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
RtlPopFrame(IN PTEB_ACTIVE_FRAME Frame)
|
||||
{
|
||||
/* Restore the previous frame as the active one */
|
||||
NtCurrentTeb()->ActiveFrame = Frame->Previous;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
RtlPushFrame(IN PTEB_ACTIVE_FRAME Frame)
|
||||
{
|
||||
/* Save the current frame and set the new one as active */
|
||||
Frame->Previous = NtCurrentTeb()->ActiveFrame;
|
||||
NtCurrentTeb()->ActiveFrame = Frame;
|
||||
}
|
||||
|
||||
PTEB_ACTIVE_FRAME
|
||||
NTAPI
|
||||
RtlGetFrame(VOID)
|
||||
{
|
||||
/* Return the frame that's currently active */
|
||||
return NtCurrentTeb()->ActiveFrame;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue