Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenkdprint.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/kd64/kdprint.c 00005 * PURPOSE: KD64 Trap Handler Routines 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 * Stefan Ginsberg (stefan.ginsberg@reactos.org) 00008 */ 00009 00010 /* INCLUDES ******************************************************************/ 00011 00012 #include <ntoskrnl.h> 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 /* FUNCTIONS *****************************************************************/ 00017 00018 BOOLEAN 00019 NTAPI 00020 KdpPrintString(IN PSTRING Output) 00021 { 00022 STRING Data, Header; 00023 DBGKD_DEBUG_IO DebugIo; 00024 USHORT Length = Output->Length; 00025 00026 /* Copy the string */ 00027 RtlMoveMemory(KdpMessageBuffer, Output->Buffer, Length); 00028 00029 /* Make sure we don't exceed the KD Packet size */ 00030 if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE) 00031 { 00032 /* Normalize length */ 00033 Length = PACKET_MAX_SIZE - sizeof(DBGKD_DEBUG_IO); 00034 } 00035 00036 /* Build the packet header */ 00037 DebugIo.ApiNumber = DbgKdPrintStringApi; 00038 DebugIo.ProcessorLevel = (USHORT)KeProcessorLevel; 00039 DebugIo.Processor = KeGetCurrentPrcb()->Number; 00040 DebugIo.u.PrintString.LengthOfString = Length; 00041 Header.Length = sizeof(DBGKD_DEBUG_IO); 00042 Header.Buffer = (PCHAR)&DebugIo; 00043 00044 /* Build the data */ 00045 Data.Length = Length; 00046 Data.Buffer = KdpMessageBuffer; 00047 00048 /* Send the packet */ 00049 KdSendPacket(PACKET_TYPE_KD_DEBUG_IO, &Header, &Data, &KdpContext); 00050 00051 /* Check if the user pressed CTRL+C */ 00052 return KdpPollBreakInWithPortLock(); 00053 } 00054 00055 BOOLEAN 00056 NTAPI 00057 KdpPromptString(IN PSTRING PromptString, 00058 IN PSTRING ResponseString) 00059 { 00060 STRING Data, Header; 00061 DBGKD_DEBUG_IO DebugIo; 00062 ULONG Length = PromptString->Length; 00063 KDSTATUS Status; 00064 00065 /* Copy the string to the message buffer */ 00066 RtlCopyMemory(KdpMessageBuffer, 00067 PromptString->Buffer, 00068 PromptString->Length); 00069 00070 /* Make sure we don't exceed the KD Packet size */ 00071 if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE) 00072 { 00073 /* Normalize length */ 00074 Length = PACKET_MAX_SIZE - sizeof(DBGKD_DEBUG_IO); 00075 } 00076 00077 /* Build the packet header */ 00078 DebugIo.ApiNumber = DbgKdGetStringApi; 00079 DebugIo.ProcessorLevel = (USHORT)KeProcessorLevel; 00080 DebugIo.Processor = KeGetCurrentPrcb()->Number; 00081 DebugIo.u.GetString.LengthOfPromptString = Length; 00082 DebugIo.u.GetString.LengthOfStringRead = ResponseString->MaximumLength; 00083 Header.Length = sizeof(DBGKD_DEBUG_IO); 00084 Header.Buffer = (PCHAR)&DebugIo; 00085 00086 /* Build the data */ 00087 Data.Length = PromptString->Length; 00088 Data.Buffer = KdpMessageBuffer; 00089 00090 /* Send the packet */ 00091 KdSendPacket(PACKET_TYPE_KD_DEBUG_IO, &Header, &Data, &KdpContext); 00092 00093 /* Set the maximum lengths for the receive */ 00094 Header.MaximumLength = sizeof(DBGKD_DEBUG_IO); 00095 Data.MaximumLength = sizeof(KdpMessageBuffer); 00096 00097 /* Enter receive loop */ 00098 do 00099 { 00100 /* Get our reply */ 00101 Status = KdReceivePacket(PACKET_TYPE_KD_DEBUG_IO, 00102 &Header, 00103 &Data, 00104 &Length, 00105 &KdpContext); 00106 00107 /* Return TRUE if we need to resend */ 00108 if (Status == KdPacketNeedsResend) return TRUE; 00109 00110 /* Loop until we succeed */ 00111 } while (Status != KdPacketReceived); 00112 00113 /* Don't copy back a larger response than there is room for */ 00114 Length = min(Length, ResponseString->MaximumLength); 00115 00116 /* Copy back the string and return the length */ 00117 RtlCopyMemory(ResponseString->Buffer, KdpMessageBuffer, Length); 00118 ResponseString->Length = (USHORT)Length; 00119 00120 /* Success; we don't need to resend */ 00121 return FALSE; 00122 } 00123 00124 VOID 00125 NTAPI 00126 KdpCommandString(IN PSTRING NameString, 00127 IN PSTRING CommandString, 00128 IN KPROCESSOR_MODE PreviousMode, 00129 IN PCONTEXT ContextRecord, 00130 IN PKTRAP_FRAME TrapFrame, 00131 IN PKEXCEPTION_FRAME ExceptionFrame) 00132 { 00133 BOOLEAN Enable; 00134 PKPRCB Prcb = KeGetCurrentPrcb(); 00135 00136 /* Check if we need to do anything */ 00137 if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return; 00138 00139 /* Enter the debugger */ 00140 Enable = KdEnterDebugger(TrapFrame, ExceptionFrame); 00141 00142 /* Save the CPU Control State and save the context */ 00143 KiSaveProcessorControlState(&Prcb->ProcessorState); 00144 RtlCopyMemory(&Prcb->ProcessorState.ContextFrame, 00145 ContextRecord, 00146 sizeof(CONTEXT)); 00147 00148 /* Send the command string to the debugger */ 00149 KdpReportCommandStringStateChange(NameString, 00150 CommandString, 00151 &Prcb->ProcessorState.ContextFrame); 00152 00153 /* Restore the processor state */ 00154 RtlCopyMemory(ContextRecord, 00155 &Prcb->ProcessorState.ContextFrame, 00156 sizeof(CONTEXT)); 00157 KiRestoreProcessorControlState(&Prcb->ProcessorState); 00158 00159 /* Exit the debugger and return */ 00160 KdExitDebugger(Enable); 00161 } 00162 00163 VOID 00164 NTAPI 00165 KdpSymbol(IN PSTRING DllPath, 00166 IN PKD_SYMBOLS_INFO SymbolInfo, 00167 IN BOOLEAN Unload, 00168 IN KPROCESSOR_MODE PreviousMode, 00169 IN PCONTEXT ContextRecord, 00170 IN PKTRAP_FRAME TrapFrame, 00171 IN PKEXCEPTION_FRAME ExceptionFrame) 00172 { 00173 BOOLEAN Enable; 00174 PKPRCB Prcb = KeGetCurrentPrcb(); 00175 00176 /* Check if we need to do anything */ 00177 if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return; 00178 00179 /* Enter the debugger */ 00180 Enable = KdEnterDebugger(TrapFrame, ExceptionFrame); 00181 00182 /* Save the CPU Control State and save the context */ 00183 KiSaveProcessorControlState(&Prcb->ProcessorState); 00184 RtlCopyMemory(&Prcb->ProcessorState.ContextFrame, 00185 ContextRecord, 00186 sizeof(CONTEXT)); 00187 00188 /* Report the new state */ 00189 KdpReportLoadSymbolsStateChange(DllPath, 00190 SymbolInfo, 00191 Unload, 00192 &Prcb->ProcessorState.ContextFrame); 00193 00194 /* Restore the processor state */ 00195 RtlCopyMemory(ContextRecord, 00196 &Prcb->ProcessorState.ContextFrame, 00197 sizeof(CONTEXT)); 00198 KiRestoreProcessorControlState(&Prcb->ProcessorState); 00199 00200 /* Exit the debugger and return */ 00201 KdExitDebugger(Enable); 00202 } 00203 00204 USHORT 00205 NTAPI 00206 KdpPrompt(IN LPSTR PromptString, 00207 IN USHORT PromptLength, 00208 OUT LPSTR ResponseString, 00209 IN USHORT MaximumResponseLength, 00210 IN KPROCESSOR_MODE PreviousMode, 00211 IN PKTRAP_FRAME TrapFrame, 00212 IN PKEXCEPTION_FRAME ExceptionFrame) 00213 { 00214 STRING PromptBuffer, ResponseBuffer; 00215 BOOLEAN Enable, Resend; 00216 00217 /* Normalize the lengths */ 00218 PromptLength = min(PromptLength, 512); 00219 MaximumResponseLength = min(MaximumResponseLength, 512); 00220 00221 /* Check if we need to verify the string */ 00222 if (PreviousMode != KernelMode) 00223 { 00224 /* FIXME: Handle user-mode */ 00225 } 00226 00227 /* Setup the prompt and response buffers */ 00228 PromptBuffer.Buffer = PromptString; 00229 PromptBuffer.Length = PromptLength; 00230 ResponseBuffer.Buffer = ResponseString; 00231 ResponseBuffer.Length = 0; 00232 ResponseBuffer.MaximumLength = MaximumResponseLength; 00233 00234 /* Log the print */ 00235 //KdLogDbgPrint(&PromptBuffer); 00236 00237 /* Enter the debugger */ 00238 Enable = KdEnterDebugger(TrapFrame, ExceptionFrame); 00239 00240 /* Enter prompt loop */ 00241 do 00242 { 00243 /* Send the prompt and receive the response */ 00244 Resend = KdpPromptString(&PromptBuffer, &ResponseBuffer); 00245 00246 /* Loop while we need to resend */ 00247 } while (Resend); 00248 00249 /* Exit the debugger */ 00250 KdExitDebugger(Enable); 00251 00252 /* Return the number of characters received */ 00253 return ResponseBuffer.Length; 00254 } 00255 00256 NTSTATUS 00257 NTAPI 00258 KdpPrint(IN ULONG ComponentId, 00259 IN ULONG Level, 00260 IN LPSTR String, 00261 IN USHORT Length, 00262 IN KPROCESSOR_MODE PreviousMode, 00263 IN PKTRAP_FRAME TrapFrame, 00264 IN PKEXCEPTION_FRAME ExceptionFrame, 00265 OUT PBOOLEAN Handled) 00266 { 00267 NTSTATUS ReturnStatus; 00268 BOOLEAN Enable; 00269 STRING OutputString; 00270 00271 /* Assume failure */ 00272 *Handled = FALSE; 00273 00274 /* Validate the mask */ 00275 if (Level < 32) Level = 1 << Level; 00276 if (!(Kd_WIN2000_Mask & Level) || 00277 ((ComponentId < KdComponentTableSize) && 00278 !(*KdComponentTable[ComponentId] & Level))) 00279 { 00280 /* Mask validation failed */ 00281 *Handled = TRUE; 00282 return STATUS_SUCCESS; 00283 } 00284 00285 /* Normalize the length */ 00286 Length = min(Length, 512); 00287 00288 /* Check if we need to verify the buffer */ 00289 if (PreviousMode != KernelMode) 00290 { 00291 /* FIXME: Support user-mode */ 00292 } 00293 00294 /* Setup the output string */ 00295 OutputString.Buffer = String; 00296 OutputString.Length = Length; 00297 00298 /* Log the print */ 00299 //KdLogDbgPrint(&OutputString); 00300 00301 /* Check for a debugger */ 00302 if (KdDebuggerNotPresent) 00303 { 00304 /* Fail */ 00305 *Handled = TRUE; 00306 return STATUS_DEVICE_NOT_CONNECTED; 00307 } 00308 00309 /* Enter the debugger */ 00310 Enable = KdEnterDebugger(TrapFrame, ExceptionFrame); 00311 00312 /* Print the string */ 00313 if (KdpPrintString(&OutputString)) 00314 { 00315 /* User pressed CTRL-C, breakpoint on return */ 00316 ReturnStatus = STATUS_BREAKPOINT; 00317 } 00318 else 00319 { 00320 /* String was printed */ 00321 ReturnStatus = STATUS_SUCCESS; 00322 } 00323 00324 /* Exit the debugger and return */ 00325 KdExitDebugger(Enable); 00326 *Handled = TRUE; 00327 return ReturnStatus; 00328 } 00329 00330 VOID 00331 __cdecl 00332 KdpDprintf(IN PCHAR Format, 00333 ...) 00334 { 00335 STRING String; 00336 CHAR Buffer[100]; 00337 USHORT Length; 00338 va_list ap; 00339 00340 /* Format the string */ 00341 va_start(ap, Format); 00342 Length = (USHORT)_vsnprintf(Buffer, 00343 sizeof(Buffer), 00344 Format, 00345 ap); 00346 00347 /* Set it up */ 00348 String.Buffer = Buffer; 00349 String.Length = Length + 1; 00350 00351 /* Send it to the debugger directly */ 00352 KdpPrintString(&String); 00353 va_end(ap); 00354 } Generated on Mon May 28 2012 04:37:21 for ReactOS by
1.7.6.1
|