VOID KdpSetStateChange ( IN PDBGKD_WAIT_STATE_CHANGE WaitStateChange, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN BOOLEAN SecondChance ) /*++ Routine Description: Fill in the Wait_State_Change message record. Arguments: WaitStateChange - Supplies pointer to record to fill in ExceptionRecord - Supplies a pointer to an exception record. ContextRecord - Supplies a pointer to a context record. SecondChance - Supplies a boolean value that determines whether this is the first or second chance for the exception. Return Value: None. --*/ { BOOLEAN status; // // Set up description of event, including exception record // WaitStateChange->NewState = DbgKdExceptionStateChange; WaitStateChange->ProcessorLevel = KeProcessorLevel; WaitStateChange->Processor = (USHORT)KeGetCurrentPrcb()->Number; WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors; WaitStateChange->Thread = (PVOID)KeGetCurrentThread(); WaitStateChange->ProgramCounter = (PVOID)CONTEXT_TO_PROGRAM_COUNTER(ContextRecord); KdpQuickMoveMemory( (PCHAR)&WaitStateChange->u.Exception.ExceptionRecord, (PCHAR)ExceptionRecord, sizeof(EXCEPTION_RECORD) ); WaitStateChange->u.Exception.FirstChance = !SecondChance; // // Copy instruction stream immediately following location of event // WaitStateChange->ControlReport.InstructionCount = KdpMoveMemory( &(WaitStateChange->ControlReport.InstructionStream[0]), WaitStateChange->ProgramCounter, DBGKD_MAXSTREAM ); // // Copy context record immediately following instruction stream // if (KdpSendContext) { KdpMoveMemory((PCHAR)&WaitStateChange->Context, (PCHAR)ContextRecord, sizeof(*ContextRecord)); } // // Clear breakpoints in copied area // status = KdpDeleteBreakpointRange( WaitStateChange->ProgramCounter, (PVOID)((PUCHAR)WaitStateChange->ProgramCounter + WaitStateChange->ControlReport.InstructionCount - 1) ); // // If there were any breakpoints cleared, recopy the area without them // if (status == TRUE) { KdpMoveMemory( &(WaitStateChange->ControlReport.InstructionStream[0]), WaitStateChange->ProgramCounter, WaitStateChange->ControlReport.InstructionCount ); } }
VOID KdpSetStateChange ( IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN BOOLEAN SecondChance ) /*++ Routine Description: Fill in the Wait_State_Change message record. Arguments: WaitStateChange - Supplies pointer to record to fill in ExceptionRecord - Supplies a pointer to an exception record. ContextRecord - Supplies a pointer to a context record. SecondChance - Supplies a boolean value that determines whether this is the first or second chance for the exception. Return Value: None. --*/ { ULONG Count; PVOID End; // // Set up description of event, including exception record // WaitStateChange->NewState = DbgKdExceptionStateChange; WaitStateChange->ProcessorLevel = KeProcessorLevel; WaitStateChange->Processor = (USHORT)KdpGetCurrentPrcb()->Number; WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors; WaitStateChange->Thread = (ULONG_PTR)KdpGetCurrentThread(); WaitStateChange->ProgramCounter = (ULONG_PTR)CONTEXT_TO_PROGRAM_COUNTER(ContextRecord); if (sizeof(EXCEPTION_RECORD) == sizeof(WaitStateChange->u.Exception.ExceptionRecord)) { KdpQuickMoveMemory((PCHAR)&WaitStateChange->u.Exception.ExceptionRecord, (PCHAR)ExceptionRecord, sizeof(EXCEPTION_RECORD)); } else { ExceptionRecord32To64((PEXCEPTION_RECORD32)ExceptionRecord, &WaitStateChange->u.Exception.ExceptionRecord ); } WaitStateChange->u.Exception.FirstChance = !SecondChance; // // Copy the immediate instruction stream into the control report structure. // Count = KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], (PVOID)WaitStateChange->ProgramCounter, DBGKD_MAXSTREAM); WaitStateChange->ControlReport.InstructionCount = (USHORT)Count; // // Clear breakpoints in the copied instruction stream. If any breakpoints // are clear, then recopy the instruction strasm. // End = (PVOID)((PUCHAR)(WaitStateChange->ProgramCounter) + Count - 1); if (KdpDeleteBreakpointRange((PVOID)WaitStateChange->ProgramCounter, End) != FALSE) { KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], (PVOID)WaitStateChange->ProgramCounter, Count); } // // Copy the context record into the wait state structure. // KdpMoveMemory((PCHAR)&WaitStateChange->Context, (PCHAR)ContextRecord, sizeof(*ContextRecord)); return; }