\r
/* PRIVATE FUNCTIONS *********************************************************/\r
\r
+VOID\r
+NTAPI\r
+KdpQueryMemory(IN PDBGKD_MANIPULATE_STATE64 State,\r
+ IN PCONTEXT Context)\r
+{\r
+ PDBGKD_QUERY_MEMORY Memory = &State->u.QueryMemory;\r
+ STRING Header;\r
+ NTSTATUS Status = STATUS_SUCCESS;\r
+\r
+ /* Validate the address space */\r
+ if (Memory->AddressSpace == DBGKD_QUERY_MEMORY_VIRTUAL)\r
+ {\r
+ /* Check if this is process memory */\r
+ if ((PVOID)(LONG_PTR)Memory->Address < MmHighestUserAddress)\r
+ {\r
+ /* It is */\r
+ Memory->AddressSpace = DBGKD_QUERY_MEMORY_PROCESS;\r
+ }\r
+ else\r
+ {\r
+ /* FIXME: Check if it's session space */\r
+ Memory->AddressSpace = DBGKD_QUERY_MEMORY_KERNEL;\r
+ }\r
+\r
+ /* Set flags */\r
+ Memory->Flags = DBGKD_QUERY_MEMORY_READ |\r
+ DBGKD_QUERY_MEMORY_WRITE |\r
+ DBGKD_QUERY_MEMORY_EXECUTE;\r
+ }\r
+ else\r
+ {\r
+ /* Invalid */\r
+ Status = STATUS_INVALID_PARAMETER;\r
+ }\r
+\r
+ /* Return structure */\r
+ State->ReturnStatus = Status;\r
+ Memory->Reserved = 0;\r
+\r
+ /* Build header */\r
+ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);\r
+ Header.Buffer = (PCHAR)State;\r
+\r
+ /* Send the packet */\r
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,\r
+ &Header,\r
+ NULL,\r
+ &KdpContext);\r
+}\r
+\r
+VOID\r
+NTAPI\r
+KdpWriteBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State,\r
+ IN PSTRING Data,\r
+ IN PCONTEXT Context)\r
+{\r
+ PDBGKD_WRITE_BREAKPOINT64 Breakpoint = &State->u.WriteBreakPoint;\r
+ STRING Header;\r
+\r
+ /* Build header */\r
+ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);\r
+ Header.Buffer = (PCHAR)State;\r
+ ASSERT(Data->Length == 0);\r
+\r
+ /* Create the breakpoint */\r
+ Breakpoint->BreakPointHandle =\r
+ KdpAddBreakpoint((PVOID)(LONG_PTR)Breakpoint->BreakPointAddress);\r
+ if (!Breakpoint->BreakPointHandle)\r
+ {\r
+ /* We failed */\r
+ State->ReturnStatus = STATUS_UNSUCCESSFUL;\r
+ }\r
+ else\r
+ {\r
+ /* Success! */\r
+ State->ReturnStatus = STATUS_SUCCESS;\r
+ }\r
+\r
+ /* Send the packet */\r
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,\r
+ &Header,\r
+ NULL,\r
+ &KdpContext);\r
+}\r
+\r
+VOID\r
+NTAPI\r
+DumpTraceData(IN PSTRING TraceData)\r
+{\r
+ /* Update the buffer */\r
+ TraceDataBuffer[0] = TraceDataBufferPosition;\r
+\r
+ /* Setup the trace data */\r
+ TraceData->Length = TraceDataBufferPosition * sizeof(ULONG);\r
+ TraceData->Buffer = (PCHAR)TraceDataBuffer;\r
+\r
+ /* Reset the buffer location */\r
+ TraceDataBufferPosition = 1;\r
+}\r
+\r
+VOID\r
+NTAPI\r
+KdpGetStateChange(IN PDBGKD_MANIPULATE_STATE64 State,\r
+ IN PCONTEXT Context)\r
+{\r
+ PKPRCB Prcb;\r
+ ULONG i;\r
+\r
+ /* Check for success */\r
+ if (NT_SUCCESS(State->u.Continue2.ContinueStatus))\r
+ {\r
+ /* Check if we're tracing */\r
+ if (State->u.Continue2.ControlSet.TraceFlag)\r
+ {\r
+ /* Enable TF */\r
+ Context->EFlags |= EFLAGS_TF;\r
+ }\r
+ else\r
+ {\r
+ /* Remove it */\r
+ Context->EFlags &= ~EFLAGS_TF;\r
+ }\r
+\r
+ /* Loop all processors */\r
+ for (i = 0; i < KeNumberProcessors; i++)\r
+ {\r
+ /* Get the PRCB and update DR7 and DR6 */\r
+ Prcb = KiProcessorBlock[i];\r
+ Prcb->ProcessorState.SpecialRegisters.KernelDr7 =\r
+ State->u.Continue2.ControlSet.Dr7;\r
+ Prcb->ProcessorState.SpecialRegisters.KernelDr6 = 0;\r
+ }\r
+\r
+ /* Check if we have new symbol information */\r
+ if (State->u.Continue2.ControlSet.CurrentSymbolStart != 1)\r
+ {\r
+ /* Update it */\r
+ KdpCurrentSymbolStart =\r
+ State->u.Continue2.ControlSet.CurrentSymbolStart;\r
+ KdpCurrentSymbolEnd= State->u.Continue2.ControlSet.CurrentSymbolEnd;\r
+ }\r
+ }\r
+}\r
+\r
VOID\r
NTAPI\r
KdpSetCommonState(IN ULONG NewState,\r
WaitStateChange->ProcessorLevel = KeProcessorLevel;\r
WaitStateChange->Processor = (USHORT)KeGetCurrentPrcb()->Number;\r
WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors;\r
- WaitStateChange->Thread = (ULONG)KeGetCurrentThread();\r
- WaitStateChange->ProgramCounter = (ULONG64)Context->Eip;\r
+ WaitStateChange->Thread = (ULONG)(LONG_PTR)KeGetCurrentThread();\r
+#if defined(_M_X86_)\r
+ WaitStateChange->ProgramCounter = (ULONG)(LONG_PTR)Context->Eip;\r
+#elif defined(_AMD64)\r
+ WaitStateChange->ProgramCounter = (ULONG)(LONG_PTR)Context->Rip;\r
+#else\r
+#error Unknown platform\r
+#endif\r
\r
/* Zero out the Control Report */\r
RtlZeroMemory(&WaitStateChange->ControlReport,\r
WaitStateChange->ControlReport.InstructionCount = InstructionCount;\r
\r
/* Clear all the breakpoints in this region */\r
- HadBreakpoints = FALSE;\r
-#if 0\r
- KdpDeleteBreakpointRange((PVOID)WaitStateChange->ProgramCounter,\r
- (PVOID)(WaitStateChange->ProgramCounter +\r
- WaitStateChange->ControlReport.\r
- InstructionCount - 1));\r
-#endif\r
+ HadBreakpoints =\r
+ KdpDeleteBreakpointRange((PVOID)(LONG_PTR)WaitStateChange->ProgramCounter,\r
+ (PVOID)((ULONG_PTR)WaitStateChange->ProgramCounter +\r
+ WaitStateChange->ControlReport.InstructionCount - 1));\r
if (HadBreakpoints)\r
{\r
/* Copy the instruction stream again, this time without breakpoints */\r
\r
VOID\r
NTAPI\r
-KdpSetContextState(IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange,\r
- IN PCONTEXT Context)\r
+KdpSysGetVersion(IN PDBGKD_GET_VERSION64 Version)\r
+{\r
+ /* Copy the version block */\r
+ RtlCopyMemory(Version, &KdVersionBlock, sizeof(DBGKD_GET_VERSION64));\r
+}\r
+\r
+VOID\r
+NTAPI\r
+KdpGetVersion(IN PDBGKD_MANIPULATE_STATE64 State)\r
{\r
- PKPRCB Prcb = KeGetCurrentPrcb();\r
+ STRING Header;\r
\r
- /* Copy i386 specific debug registers */\r
- WaitStateChange->ControlReport.Dr6 = Prcb->ProcessorState.SpecialRegisters.\r
- KernelDr6;\r
- WaitStateChange->ControlReport.Dr7 = Prcb->ProcessorState.SpecialRegisters.\r
- KernelDr7;\r
+ /* Fill out the header */\r
+ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);\r
+ Header.Buffer = (PCHAR)State;\r
\r
- /* Copy i386 specific segments */\r
- WaitStateChange->ControlReport.SegCs = (USHORT)Context->SegCs;\r
- WaitStateChange->ControlReport.SegDs = (USHORT)Context->SegDs;\r
- WaitStateChange->ControlReport.SegEs = (USHORT)Context->SegEs;\r
- WaitStateChange->ControlReport.SegFs = (USHORT)Context->SegFs;\r
+ /* Get the version block */\r
+ KdpSysGetVersion(&State->u.GetVersion64);\r
\r
- /* Copy EFlags */\r
- WaitStateChange->ControlReport.EFlags = Context->EFlags;\r
+ /* Fill out the state */\r
+ State->ApiNumber = DbgKdGetVersionApi;\r
+ State->ReturnStatus = STATUS_SUCCESS;\r
\r
- /* Set Report Flags */\r
- WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_SEGS;\r
- if (WaitStateChange->ControlReport.SegCs == KGDT_R0_CODE)\r
+ /* Send the packet */\r
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,\r
+ &Header,\r
+ NULL,\r
+ &KdpContext);\r
+}\r
+\r
+VOID\r
+NTAPI\r
+KdpReadVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State,\r
+ IN PSTRING Data,\r
+ IN PCONTEXT Context)\r
+{\r
+ STRING Header;\r
+ ULONG Length = State->u.ReadMemory.TransferCount;\r
+ NTSTATUS Status = STATUS_SUCCESS;\r
+\r
+ /* Validate length */\r
+ if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64)))\r
+ {\r
+ /* Overflow, set it to maximum possible */\r
+ Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64);\r
+ }\r
+\r
+#if 0\r
+ if (!MmIsAddressValid((PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress))\r
+ {\r
+ Ke386SetCr2(State->u.ReadMemory.TargetBaseAddress);\r
+ while (TRUE);\r
+ }\r
+#endif\r
+\r
+ if (!State->u.ReadMemory.TargetBaseAddress)\r
+ {\r
+ Length = 0;\r
+ Status = STATUS_UNSUCCESSFUL;\r
+ }\r
+ else\r
+ {\r
+ RtlCopyMemory(Data->Buffer,\r
+ (PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress,\r
+ Length);\r
+ }\r
+\r
+ /* Fill out the header */\r
+ Data->Length = Length;\r
+ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);\r
+ Header.Buffer = (PCHAR)State;\r
+\r
+ /* Fill out the state */\r
+ State->ReturnStatus = Status;\r
+ State->u.ReadMemory.ActualBytesRead = Length;\r
+\r
+ /* Send the packet */\r
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,\r
+ &Header,\r
+ Data,\r
+ &KdpContext);\r
+}\r
+\r
+VOID\r
+NTAPI\r
+KdpReadControlSpace(IN PDBGKD_MANIPULATE_STATE64 State,\r
+ IN PSTRING Data,\r
+ IN PCONTEXT Context)\r
+{\r
+ PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory;\r
+ STRING Header;\r
+ ULONG Length, RealLength;\r
+ PVOID ControlStart;\r
+\r
+ /* Setup the header */\r
+ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);\r
+ Header.Buffer = (PCHAR)State;\r
+ ASSERT(Data->Length == 0);\r
+\r
+ /* Check the length requested */\r
+ Length = ReadMemory->TransferCount;\r
+ if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64)))\r
{\r
- WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_CS;\r
+ /* Use maximum allowed */\r
+ Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64);\r
}\r
+\r
+ /* Make sure that this is a valid request */\r
+ if (((ULONG)ReadMemory->TargetBaseAddress < sizeof(KPROCESSOR_STATE)) &&\r
+ (State->Processor < KeNumberProcessors))\r
+ {\r
+ /* Get the actual length */\r
+ RealLength = sizeof(KPROCESSOR_STATE) -\r
+ (ULONG_PTR)ReadMemory->TargetBaseAddress;\r
+ if (RealLength < Length) Length = RealLength;\r
+\r
+ /* Set the proper address */\r
+ ControlStart = (PVOID)((ULONG_PTR)ReadMemory->TargetBaseAddress +\r
+ (ULONG_PTR)&KiProcessorBlock[State->Processor]->\r
+ ProcessorState);\r
+\r
+ /* Copy the memory */\r
+ RtlCopyMemory(Data->Buffer, ControlStart, Length);\r
+ Data->Length = Length;\r
+\r
+ /* Finish up */\r
+ State->ReturnStatus = STATUS_SUCCESS;\r
+ ReadMemory->ActualBytesRead = Data->Length;\r
+ }\r
+ else\r
+ {\r
+ /* Invalid request */\r
+ Data->Length = 0;\r
+ State->ReturnStatus = STATUS_UNSUCCESSFUL;\r
+ ReadMemory->ActualBytesRead = 0;\r
+ }\r
+\r
+ /* Send the reply */\r
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,\r
+ &Header,\r
+ Data,\r
+ &KdpContext);\r
}\r
\r
-BOOLEAN\r
+VOID\r
+NTAPI\r
+KdpWriteControlSpace(IN PDBGKD_MANIPULATE_STATE64 State,\r
+ IN PSTRING Data,\r
+ IN PCONTEXT Context)\r
+{\r
+ PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory;\r
+ STRING Header;\r
+ ULONG Length;\r
+ PVOID ControlStart;\r
+\r
+ /* Setup the header */\r
+ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);\r
+ Header.Buffer = (PCHAR)State;\r
+\r
+ /* Make sure that this is a valid request */\r
+ Length = WriteMemory->TransferCount;\r
+ if ((((ULONG)WriteMemory->TargetBaseAddress + Length) <=\r
+ sizeof(KPROCESSOR_STATE)) &&\r
+ (State->Processor < KeNumberProcessors))\r
+ {\r
+ /* Set the proper address */\r
+ ControlStart = (PVOID)((ULONG_PTR)WriteMemory->TargetBaseAddress +\r
+ (ULONG_PTR)&KiProcessorBlock[State->Processor]->\r
+ ProcessorState);\r
+\r
+ /* Copy the memory */\r
+ RtlCopyMemory(ControlStart, Data->Buffer, Data->Length);\r
+ Length = Data->Length;\r
+\r
+ /* Finish up */\r
+ State->ReturnStatus = STATUS_SUCCESS;\r
+ WriteMemory->ActualBytesWritten = Length;\r
+ }\r
+ else\r
+ {\r
+ /* Invalid request */\r
+ Data->Length = 0;\r
+ State->ReturnStatus = STATUS_UNSUCCESSFUL;\r
+ WriteMemory->ActualBytesWritten = 0;\r
+ }\r
+\r
+ /* Send the reply */\r
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,\r
+ &Header,\r
+ Data,\r
+ &KdpContext);\r
+}\r
+\r
+VOID\r
+NTAPI\r
+KdpRestoreBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State,\r
+ IN PSTRING Data,\r
+ IN PCONTEXT Context)\r
+{\r
+ PDBGKD_RESTORE_BREAKPOINT RestoreBp = &State->u.RestoreBreakPoint;\r
+ STRING Header;\r
+\r
+ /* Fill out the header */\r
+ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);\r
+ Header.Buffer = (PCHAR)State;\r
+ ASSERT(Data->Length == 0);\r
+\r
+ /* Get the version block */\r
+ if (KdpDeleteBreakpoint(RestoreBp->BreakPointHandle))\r
+ {\r
+ /* We're all good */\r
+ State->ReturnStatus = STATUS_SUCCESS;\r
+ }\r
+ else\r
+ {\r
+ /* We failed */\r
+ State->ReturnStatus = STATUS_UNSUCCESSFUL;\r
+ }\r
+\r
+ /* Send the packet */\r
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,\r
+ &Header,\r
+ NULL,\r
+ &KdpContext);\r
+}\r
+\r
+VOID\r
+NTAPI\r
+KdpGetContext(IN PDBGKD_MANIPULATE_STATE64 State,\r
+ IN PSTRING Data,\r
+ IN PCONTEXT Context)\r
+{\r
+ STRING Header;\r
+ PVOID ControlStart;\r
+\r
+ /* Setup the header */\r
+ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);\r
+ Header.Buffer = (PCHAR)State;\r
+ ASSERT(Data->Length == 0);\r
+\r
+ /* Make sure that this is a valid request */\r
+ if (State->Processor < KeNumberProcessors)\r
+ {\r
+ /* Check if the request is for this CPU */\r
+ if (State->Processor == KeGetCurrentPrcb()->Number)\r
+ {\r
+ /* We're just copying our own context */\r
+ ControlStart = Context;\r
+ }\r
+ else\r
+ {\r
+ /* SMP not yet handled */\r
+ ControlStart = NULL;\r
+ while (TRUE);\r
+ }\r
+\r
+ /* Copy the memory */\r
+ RtlCopyMemory(Data->Buffer, ControlStart, sizeof(CONTEXT));\r
+ Data->Length = sizeof(CONTEXT);\r
+\r
+ /* Finish up */\r
+ State->ReturnStatus = STATUS_SUCCESS;\r
+ }\r
+ else\r
+ {\r
+ /* Invalid request */\r
+ State->ReturnStatus = STATUS_UNSUCCESSFUL;\r
+ }\r
+\r
+ /* Send the reply */\r
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,\r
+ &Header,\r
+ Data,\r
+ &KdpContext);\r
+}\r
+\r
+VOID\r
+NTAPI\r
+KdpSetContext(IN PDBGKD_MANIPULATE_STATE64 State,\r
+ IN PSTRING Data,\r
+ IN PCONTEXT Context)\r
+{\r
+ STRING Header;\r
+ PVOID ControlStart;\r
+\r
+ /* Setup the header */\r
+ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);\r
+ Header.Buffer = (PCHAR)State;\r
+ ASSERT(Data->Length == sizeof(CONTEXT));\r
+\r
+ /* Make sure that this is a valid request */\r
+ if (State->Processor < KeNumberProcessors)\r
+ {\r
+ /* Check if the request is for this CPU */\r
+ if (State->Processor == KeGetCurrentPrcb()->Number)\r
+ {\r
+ /* We're just copying our own context */\r
+ ControlStart = Context;\r
+ }\r
+ else\r
+ {\r
+ /* SMP not yet handled */\r
+ ControlStart = NULL;\r
+ while (TRUE);\r
+ }\r
+\r
+ /* Copy the memory */\r
+ RtlCopyMemory(ControlStart, Data->Buffer, sizeof(CONTEXT));\r
+\r
+ /* Finish up */\r
+ State->ReturnStatus = STATUS_SUCCESS;\r
+ }\r
+ else\r
+ {\r
+ /* Invalid request */\r
+ State->ReturnStatus = STATUS_UNSUCCESSFUL;\r
+ }\r
+\r
+ /* Send the reply */\r
+ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,\r
+ &Header,\r
+ Data,\r
+ &KdpContext);\r
+}\r
+\r
+KCONTINUE_STATUS\r
NTAPI\r
KdpSendWaitContinue(IN ULONG PacketType,\r
IN PSTRING SendHeader,\r
IN PSTRING SendData OPTIONAL,\r
- IN OUT PCONTEXT ContextRecord)\r
+ IN OUT PCONTEXT Context)\r
{\r
STRING Data, Header;\r
DBGKD_MANIPULATE_STATE64 ManipulateState;\r
KdSendPacket(PacketType, SendHeader, SendData, &KdpContext);\r
\r
/* If the debugger isn't present anymore, just return success */\r
- if (KdDebuggerNotPresent) return TRUE;\r
+ if (KdDebuggerNotPresent) return ContinueSuccess;\r
\r
/* Main processing Loop */\r
for (;;)\r
do\r
{\r
/* Wait to get a reply to our packet */\r
- ManipulateState.ApiNumber = 0xFFFFFFFF;\r
RecvCode = KdReceivePacket(PACKET_TYPE_KD_STATE_MANIPULATE,\r
&Header,\r
&Data,\r
{\r
case DbgKdReadVirtualMemoryApi:\r
\r
- /* FIXME: TODO */\r
- Ke386SetCr2(DbgKdReadVirtualMemoryApi);\r
- while (TRUE);\r
+ /* Read virtual memory */\r
+ KdpReadVirtualMemory(&ManipulateState, &Data, Context);\r
break;\r
\r
case DbgKdWriteVirtualMemoryApi:\r
\r
case DbgKdGetContextApi:\r
\r
- /* FIXME: TODO */\r
- Ke386SetCr2(DbgKdGetContextApi);\r
- while (TRUE);\r
+ /* Get the current context */\r
+ KdpGetContext(&ManipulateState, &Data, Context);\r
break;\r
\r
case DbgKdSetContextApi:\r
\r
- /* FIXME: TODO */\r
- Ke386SetCr2(DbgKdSetContextApi);\r
- while (TRUE);\r
+ /* Set a new context */\r
+ KdpSetContext(&ManipulateState, &Data, Context);\r
break;\r
\r
case DbgKdWriteBreakPointApi:\r
\r
- /* FIXME: TODO */\r
- Ke386SetCr2(DbgKdWriteBreakPointApi);\r
- while (TRUE);\r
+ /* Write the breakpoint */\r
+ KdpWriteBreakpoint(&ManipulateState, &Data, Context);\r
break;\r
\r
case DbgKdRestoreBreakPointApi:\r
\r
/* FIXME: TODO */\r
- Ke386SetCr2(DbgKdRestoreBreakPointApi);\r
- while (TRUE);\r
+ KdpRestoreBreakpoint(&ManipulateState, &Data, Context);\r
break;\r
\r
case DbgKdContinueApi:\r
\r
- /* FIXME: TODO */\r
- Ke386SetCr2(DbgKdContinueApi);\r
- while (TRUE);\r
- break;\r
+ /* Simply continue */\r
+ return NT_SUCCESS(ManipulateState.u.Continue.ContinueStatus);\r
\r
case DbgKdReadControlSpaceApi:\r
\r
- /* FIXME: TODO */\r
- Ke386SetCr2(DbgKdReadControlSpaceApi);\r
- while (TRUE);\r
+ /* Read control space */\r
+ KdpReadControlSpace(&ManipulateState, &Data, Context);\r
break;\r
\r
case DbgKdWriteControlSpaceApi:\r
\r
/* FIXME: TODO */\r
- Ke386SetCr2(DbgKdWriteControlSpaceApi);\r
- while (TRUE);\r
+ KdpWriteControlSpace(&ManipulateState, &Data, Context);\r
break;\r
\r
case DbgKdReadIoSpaceApi:\r
\r
case DbgKdContinueApi2:\r
\r
- /* FIXME: TODO */\r
- Ke386SetCr2(DbgKdContinueApi2);\r
- while (TRUE);\r
+ /* Check if caller reports success */\r
+ if (NT_SUCCESS(ManipulateState.u.Continue2.ContinueStatus))\r
+ {\r
+ /* Update the state */\r
+ KdpGetStateChange(&ManipulateState, Context);\r
+ return ContinueSuccess;\r
+ }\r
+ else\r
+ {\r
+ /* Return an error */\r
+ return ContinueError;\r
+ }\r
break;\r
\r
case DbgKdReadPhysicalMemoryApi:\r
\r
/* FIXME: TODO */\r
+ goto fail;\r
Ke386SetCr2(DbgKdReadPhysicalMemoryApi);\r
while (TRUE);\r
break;\r
\r
case DbgKdGetVersionApi:\r
\r
- /* FIXME: TODO */\r
- Ke386SetCr2(DbgKdGetVersionApi);\r
- while (TRUE);\r
+ /* Get version data */\r
+ KdpGetVersion(&ManipulateState);\r
break;\r
\r
case DbgKdWriteBreakPointExApi:\r
\r
case DbgKdClearAllInternalBreakpointsApi:\r
\r
- /* FIXME: TODO */\r
- Ke386SetCr2(DbgKdClearAllInternalBreakpointsApi);\r
- while (TRUE);\r
+ /* Just clear the counter */\r
+ KdpNumInternalBreakpoints = 0;\r
break;\r
\r
case DbgKdFillMemoryApi:\r
\r
case DbgKdQueryMemoryApi:\r
\r
- /* FIXME: TODO */\r
- Ke386SetCr2(DbgKdQueryMemoryApi);\r
- while (TRUE);\r
+ /* Query memory */\r
+ KdpQueryMemory(&ManipulateState, Context);\r
break;\r
\r
case DbgKdSwitchPartition:\r
\r
/* Setup an empty message, with failure */\r
while (TRUE);\r
+fail:\r
Data.Length = 0;\r
ManipulateState.ReturnStatus = STATUS_UNSUCCESSFUL;\r
\r
\r
/* Fill out load data */\r
WaitStateChange.u.LoadSymbols.UnloadSymbols = Unload;\r
- WaitStateChange.u.LoadSymbols.BaseOfDll = (ULONG)SymbolInfo->BaseOfDll;\r
+ WaitStateChange.u.LoadSymbols.BaseOfDll = (ULONGLONG)(LONG_PTR)SymbolInfo->BaseOfDll;\r
WaitStateChange.u.LoadSymbols.ProcessId = SymbolInfo->ProcessId;\r
WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum;\r
WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage;\r
{\r
/* Setup the information */\r
WaitStateChange.u.LoadSymbols.PathNameLength = PathName->Length;\r
+ RtlCopyMemory(KdpPathBuffer, PathName->Buffer, PathName->Length);\r
Data.Buffer = KdpPathBuffer;\r
Data.Length = WaitStateChange.u.LoadSymbols.PathNameLength;\r
ExtraData = &Data;\r
} while(Status == ContinueProcessorReselected);\r
\r
/* Return status */\r
- while (TRUE);\r
+ return Status;\r
+}\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpReportExceptionStateChange(IN PEXCEPTION_RECORD ExceptionRecord,\r
+ IN OUT PCONTEXT Context,\r
+ IN BOOLEAN SecondChanceException)\r
+{\r
+ STRING Header, Data;\r
+ DBGKD_WAIT_STATE_CHANGE64 WaitStateChange;\r
+ BOOLEAN Status;\r
+\r
+ /* Start report loop */\r
+ do\r
+ {\r
+ /* Build the architecture common parts of the message */\r
+ KdpSetCommonState(DbgKdExceptionStateChange, Context, &WaitStateChange);\r
+\r
+ /* Convert the exception record to 64-bits and set First Chance flag */\r
+ ExceptionRecord32To64((PEXCEPTION_RECORD32)ExceptionRecord,\r
+ &WaitStateChange.u.Exception.ExceptionRecord);\r
+ WaitStateChange.u.Exception.FirstChance = !SecondChanceException;\r
+\r
+ /* Now finish creating the structure */\r
+ KdpSetContextState(&WaitStateChange, Context);\r
+\r
+ /* Setup the actual header to send to KD */\r
+ Header.Length = sizeof(DBGKD_WAIT_STATE_CHANGE64);\r
+ Header.Buffer = (PCHAR)&WaitStateChange;\r
+\r
+ /* Setup the trace data */\r
+ DumpTraceData(&Data);\r
+\r
+ /* Send State Change packet and wait for a reply */\r
+ Status = KdpSendWaitContinue(PACKET_TYPE_KD_STATE_CHANGE64,\r
+ &Header,\r
+ &Data,\r
+ Context);\r
+ } while (Status == KdPacketNeedsResend);\r
+\r
+ /* Return */\r
return Status;\r
}\r
\r
KdSave(FALSE);\r
\r
/* Report a state change */\r
-#if 0\r
Status = KdpReportExceptionStateChange(ExceptionRecord,\r
ContextRecord,\r
SecondChanceException);\r
-#else\r
- Status = FALSE;\r
-#endif\r
\r
/* Restore the port data and return */\r
KdRestore(FALSE);\r
NTAPI\r
KdEnableDebuggerWithLock(BOOLEAN NeedLock)\r
{\r
- KIRQL OldIrql;\r
+ KIRQL OldIrql = PASSIVE_LEVEL;\r
\r
/* Check if we need to acquire the lock */\r
if (NeedLock)\r
{\r
/* Reinitialize the Debugger */\r
KdInitSystem(0, NULL) ;\r
- //KdpRestoreAllBreakpoints();\r
+ KdpRestoreAllBreakpoints();\r
}\r
}\r
\r
return KdEnableDebuggerWithLock(TRUE);\r
}\r
\r
+/*\r
+ * @unimplemented\r
+ */\r
+NTSTATUS\r
+NTAPI\r
+KdSystemDebugControl(IN SYSDBG_COMMAND Command,\r
+ IN PVOID InputBuffer,\r
+ IN ULONG InputBufferLength,\r
+ OUT PVOID OutputBuffer,\r
+ IN ULONG OutputBufferLength,\r
+ IN OUT PULONG ReturnLength,\r
+ IN KPROCESSOR_MODE PreviousMode)\r
+{\r
+ /* HACK */\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+/*\r
+ * @unimplemented\r
+ */\r
+NTSTATUS\r
+NTAPI\r
+KdChangeOption(IN KD_OPTION Option,\r
+ IN ULONG InBufferBytes OPTIONAL,\r
+ IN PVOID InBuffer,\r
+ IN ULONG OutBufferBytes OPTIONAL,\r
+ OUT PVOID OutBuffer,\r
+ OUT PULONG OutBufferNeeded OPTIONAL)\r
+{\r
+ /* HACK */\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+/*\r
+ * @unimplemented\r
+ */\r
+NTSTATUS\r
+NTAPI\r
+KdPowerTransition(IN DEVICE_POWER_STATE NewState)\r
+{\r
+ /* HACK */\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+/*\r
+ * @unimplemented\r
+ */\r
+NTSTATUS\r
+NTAPI\r
+KdDisableDebugger(VOID)\r
+{\r
+ /* HACK */\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+/*\r
+ * @unimplemented\r
+ */\r
+BOOLEAN\r
+NTAPI\r
+KdRefreshDebuggerNotPresent(VOID)\r
+{\r
+ /* HACK */\r
+ return KdDebuggerNotPresent;\r
+}\r
+\r
+NTSTATUS\r
+NTAPI\r
+NtQueryDebugFilterState(ULONG ComponentId,\r
+ ULONG Level)\r
+{\r
+ /* HACK */\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+NTSTATUS\r
+NTAPI\r
+NtSetDebugFilterState(ULONG ComponentId,\r
+ ULONG Level,\r
+ BOOLEAN State)\r
+{\r
+ /* HACK */\r
+ return STATUS_SUCCESS;\r
+}\r
+\r