Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426/* * 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 ********************************************************/
ULONGNTAPIDebugPrint(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));}
ULONGNTAPIDebugPrompt(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 ****************************************************************/
ULONGNTAPIvDbgPrintExWithPrefixInternal(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) { /* In user-mode, clear the InDbgPrint Flag */ RtlpClearInDbgPrint(); /* 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) - 2] = '\n'; Buffer[sizeof(Buffer) - 1] = '\0';
/* Put maximum */ Length = sizeof(Buffer) - 1; } 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);
/* In user-mode, clear the InDbgPrint Flag */ RtlpClearInDbgPrint(); 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 */ULONGNTAPIvDbgPrintExWithPrefix(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 */ULONGNTAPIvDbgPrintEx(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__cdeclDbgPrint(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__cdeclDbgPrintEx(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__cdeclDbgPrintReturnControlC(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 */ULONGNTAPIDbgPrompt(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 */NTSTATUSNTAPIDbgQueryDebugFilterState(IN ULONG ComponentId, IN ULONG Level){ /* Call the Nt routine */ return NtQueryDebugFilterState(ComponentId, Level);}
/* * @implemented */NTSTATUSNTAPIDbgSetDebugFilterState(IN ULONG ComponentId, IN ULONG Level, IN BOOLEAN State){ /* Call the Nt routine */ return NtSetDebugFilterState(ComponentId, Level, State);}
/* * @implemented */VOIDNTAPIDbgLoadImageSymbols(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 */VOIDNTAPIDbgUnLoadImageSymbols(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 */VOIDNTAPIDbgCommandString(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*/VOIDNTAPIRtlPopFrame(IN PTEB_ACTIVE_FRAME Frame){ /* Restore the previous frame as the active one */ NtCurrentTeb()->ActiveFrame = Frame->Previous;}
/** @implemented*/VOIDNTAPIRtlPushFrame(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_FRAMENTAPIRtlGetFrame(VOID){ /* Return the frame that's currently active */ return NtCurrentTeb()->ActiveFrame;}