- Remove KD APIs from stub HAL, they've been in kdcom for a while (merge from kd...
authorAlex Ionescu <aionescu@gmail.com>
Sat, 3 Mar 2007 04:39:25 +0000 (04:39 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Sat, 3 Mar 2007 04:39:25 +0000 (04:39 +0000)
- DebugPrint/DebugPrompt should have an int3 after the int2d, and the int2d handler should ++ the trap frame's EIP to compensate (merge from kd-branch).
- Remove KDB symbol hooks (merge from kd-branch).
- Make PSEH compialble in MSVC again after Greatlord's break.
- Fix KiSaveProcessorControlState/KiRestoreProcessorControlState (merge from kd-branch).
- Disable GDB hook/hacks (merge from kd-branch).
- Add KD64 directory from kd-branch with SharedUserData access enabled (no other code changed). It's not currently compiled though, just putting it here.

svn path=/trunk/; revision=25965

20 files changed:
reactos/hal/hal/hal.c
reactos/hal/halx86/generic/misc.c
reactos/include/reactos/libs/pseh/framebased.h
reactos/lib/rtl/debug.c
reactos/lib/rtl/i386/debug_asm.S
reactos/ntoskrnl/include/internal/ke.h
reactos/ntoskrnl/io/iomgr/driver.c
reactos/ntoskrnl/kd64/kdapi.c [new file with mode: 0644]
reactos/ntoskrnl/kd64/kdbreak.c [new file with mode: 0644]
reactos/ntoskrnl/kd64/kddata.c [new file with mode: 0644]
reactos/ntoskrnl/kd64/kdinit.c [new file with mode: 0644]
reactos/ntoskrnl/kd64/kdlock.c [new file with mode: 0644]
reactos/ntoskrnl/kd64/kdprint.c [new file with mode: 0644]
reactos/ntoskrnl/kd64/kdtrap.c [new file with mode: 0644]
reactos/ntoskrnl/ke/i386/cpu.c
reactos/ntoskrnl/ke/i386/exp.c
reactos/ntoskrnl/ke/i386/trap.s
reactos/ntoskrnl/mm/rmap.c
reactos/ntoskrnl/mm/sysldr.c
reactos/ntoskrnl/ps/kill.c

index c3a9661..fbcb930 100644 (file)
@@ -17,7 +17,6 @@
 #include <ndk/halfuncs.h>
 #include <ndk/iofuncs.h>
 #include <ndk/kdfuncs.h>
-#include <internal/kd.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -727,132 +726,6 @@ IoMapTransfer(
 }
 
 
-BOOLEAN
-NTAPI
-KdPortGetByte(
-  PUCHAR  ByteRecieved)
-{
-  UNIMPLEMENTED;
-
-  return TRUE;
-}
-
-
-BOOLEAN
-NTAPI
-KdPortGetByteEx(
-  PKD_PORT_INFORMATION PortInformation,
-  PUCHAR  ByteRecieved)
-{
-  UNIMPLEMENTED;
-
-  return TRUE;
-}
-
-
-BOOLEAN
-NTAPI
-KdPortInitialize(
-  PKD_PORT_INFORMATION PortInformation,
-  ULONG Unknown1,
-  ULONG Unknown2)
-{
-  UNIMPLEMENTED;
-
-  return TRUE;
-}
-
-
-BOOLEAN
-NTAPI
-KdPortInitializeEx(
-  PKD_PORT_INFORMATION PortInformation,
-  ULONG Unknown1,
-  ULONG Unknown2)
-{
-  UNIMPLEMENTED;
-  
-  return TRUE;
-}
-
-
-BOOLEAN
-NTAPI
-KdPortPollByte(
-  PUCHAR  ByteRecieved)
-{
-  UNIMPLEMENTED;
-
-  return TRUE;
-}
-
-
-BOOLEAN
-NTAPI
-KdPortPollByteEx(
-  PKD_PORT_INFORMATION PortInformation,
-  PUCHAR  ByteRecieved)
-{
-  UNIMPLEMENTED;
-
-  return TRUE;
-}
-
-
-VOID
-NTAPI
-KdPortPutByte(
-  UCHAR ByteToSend)
-{
-  UNIMPLEMENTED;
-}
-
-
-VOID
-NTAPI
-KdPortPutByteEx(
-  PKD_PORT_INFORMATION PortInformation,
-  UCHAR ByteToSend)
-{
-  UNIMPLEMENTED;
-}
-
-
-VOID
-NTAPI
-KdPortRestore(VOID)
-{
-  UNIMPLEMENTED;
-}
-
-
-VOID
-NTAPI
-KdPortSave(VOID)
-{
-  UNIMPLEMENTED;
-}
-
-
-BOOLEAN
-NTAPI
-KdPortDisableInterrupts()
-{
-  UNIMPLEMENTED;
-
-  return FALSE;
-}
-
-
-BOOLEAN
-NTAPI
-KdPortEnableInterrupts()
-{
-  UNIMPLEMENTED;
-
-  return FALSE;
-}
-
 #undef KeAcquireSpinLock
 VOID
 NTAPI
index 3322643..7eb1d91 100644 (file)
@@ -77,7 +77,7 @@ HalHandleNMI(IN PVOID NmiInfo)
 
     /* Halt the system */
     HalDisplayString("\n*** The system has halted ***\n");
-    KeEnterKernelDebugger();
+    //KeEnterKernelDebugger();
 }
 
 /*
index bc2b3c3..4fbb174 100644 (file)
@@ -73,14 +73,8 @@ static __declspec(noreturn) __inline void __stdcall _SEHCompilerSpecificHandler
        _SEHPortableTryLevel_t * trylevel
 )
 {
-       /*
-       * help detetct if pseh going into endless loop
-       * if we see this debug msg repet never break
-       * we known something cause pseh going into 
-       *  endless loop, but it should never happen
-       */
-       DbgPrint("_SEHCompilerSpecificHandler(%p)\n", trylevel);
        _SEHTryLevel_t * mytrylevel;
+       DbgPrint("_SEHCompilerSpecificHandler(%p)\n", trylevel);
        mytrylevel = _SEH_CONTAINING_RECORD(trylevel, _SEHTryLevel_t, ST_Header);
        _SEHLongJmp(mytrylevel->ST_JmpBuf, 1);
 }
index defd7fe..c0f0173 100644 (file)
@@ -23,6 +23,7 @@ DebugPrint(IN PANSI_STRING DebugString,
            IN ULONG Level)
 {
     /* Call the INT2D Service */
+    //return STATUS_SUCCESS;
     return DebugService(BREAKPOINT_PRINT,
                         DebugString->Buffer,
                         DebugString->Length,
index 79b7bad..8ec4d86 100644 (file)
@@ -54,7 +54,7 @@ _DebugService2@12:
     mov ecx, [ebp+8]
     mov edx, [ebp+12]
     int 0x2D
-    //int 3
+    int 3
 
     /* Restore stack */
     pop ebp
@@ -82,7 +82,7 @@ _DebugService@20:
     mov ebx, [ebp+20]
     mov edi, [ebp+24]
     int 0x2D
-    //int 3
+    int 3
 
     /* Restore registers */
     pop ebx
index 3623139..6c9b8ff 100644 (file)
@@ -151,6 +151,7 @@ extern UCHAR KiDebugRegisterTrapOffsets[9];
 extern UCHAR KiDebugRegisterContextOffsets[9];
 extern ULONG KeTimeIncrement;
 extern ULONG_PTR KiBugCheckData[5];
+extern ULONG KiFreezeFlag;
 
 /* MACROS *************************************************************************/
 
index 838e292..b17134a 100644 (file)
@@ -874,9 +874,6 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
    }
 #endif
 
-   /* Load symbols */
-   KDB_SYMBOLFILE_HOOK(ModuleName);
-
    /*
     * Strip the file extension from ServiceName
     */
@@ -926,9 +923,6 @@ IopInitializeBootDrivers(VOID)
 {
     PLIST_ENTRY ListHead, NextEntry;
     PLDR_DATA_TABLE_ENTRY LdrEntry;
-#ifdef DBG
-    UNICODE_STRING NtosSymName = RTL_CONSTANT_STRING(L"ntoskrnl.sym");
-#endif
     PDEVICE_NODE DeviceNode;
     PDRIVER_OBJECT DriverObject;
     LDR_DATA_TABLE_ENTRY ModuleObject;
@@ -974,9 +968,6 @@ IopInitializeBootDrivers(VOID)
         return;
     }
 
-    /* Hack for NTOSKRNL.SYM */
-    KDB_SYMBOLFILE_HOOK(&NtosSymName);
-
     /* Loop the boot modules */
     ListHead = &KeLoaderBlock->LoadOrderListHead;
     NextEntry = ListHead->Flink;
diff --git a/reactos/ntoskrnl/kd64/kdapi.c b/reactos/ntoskrnl/kd64/kdapi.c
new file mode 100644 (file)
index 0000000..0bbce23
--- /dev/null
@@ -0,0 +1,1158 @@
+/*\r
+ * PROJECT:         ReactOS Kernel\r
+ * LICENSE:         GPL - See COPYING in the top level directory\r
+ * FILE:            ntoskrnl/kd64/kdapi.c\r
+ * PURPOSE:         KD64 Public Routines and Internal Support\r
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)\r
+ */\r
+\r
+/* INCLUDES ******************************************************************/\r
+\r
+#include <ntoskrnl.h>\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+/* PRIVATE FUNCTIONS *********************************************************/\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
+                  IN PCONTEXT Context,\r
+                  IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange)\r
+{\r
+    USHORT InstructionCount;\r
+    BOOLEAN HadBreakpoints;\r
+\r
+    /* Setup common stuff available for all CPU architectures */\r
+    WaitStateChange->NewState = NewState;\r
+    WaitStateChange->ProcessorLevel = KeProcessorLevel;\r
+    WaitStateChange->Processor = (USHORT)KeGetCurrentPrcb()->Number;\r
+    WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors;\r
+    WaitStateChange->Thread = (ULONG)(LONG_PTR)KeGetCurrentThread();\r
+    WaitStateChange->ProgramCounter = (ULONG)(LONG_PTR)Context->Eip;\r
+\r
+    /* Zero out the Control Report */\r
+    RtlZeroMemory(&WaitStateChange->ControlReport,\r
+                  sizeof(DBGKD_CONTROL_REPORT));\r
+\r
+    /* Now copy the instruction stream and set the count */\r
+    RtlCopyMemory(&WaitStateChange->ControlReport.InstructionStream[0],\r
+                  (PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter,\r
+                  DBGKD_MAXSTREAM);\r
+    InstructionCount = DBGKD_MAXSTREAM;\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
+    if (HadBreakpoints)\r
+    {\r
+        /* Copy the instruction stream again, this time without breakpoints */\r
+        RtlCopyMemory(&WaitStateChange->ControlReport.InstructionStream[0],\r
+                      (PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter,\r
+                      WaitStateChange->ControlReport.InstructionCount);\r
+    }\r
+}\r
+\r
+VOID\r
+NTAPI\r
+KdpSetContextState(IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange,\r
+                   IN PCONTEXT Context)\r
+{\r
+    PKPRCB Prcb = KeGetCurrentPrcb();\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
+\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
+\r
+    /* Copy EFlags */\r
+    WaitStateChange->ControlReport.EFlags = Context->EFlags;\r
+\r
+    /* Set Report Flags */\r
+    WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_SEGS;\r
+    if (WaitStateChange->ControlReport.SegCs == KGDT_R0_CODE)\r
+    {\r
+        WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_CS;\r
+    }\r
+}\r
+\r
+VOID\r
+NTAPI\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
+    STRING Header;\r
+\r
+    /* Fill out the header */\r
+    Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);\r
+    Header.Buffer = (PCHAR)State;\r
+\r
+    /* Get the version block */\r
+    KdpSysGetVersion(&State->u.GetVersion64);\r
+\r
+    /* Fill out the state */\r
+    State->ApiNumber = DbgKdGetVersionApi;\r
+    State->ReturnStatus = STATUS_SUCCESS;\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
+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 ((ULONG_PTR)State->u.ReadMemory.TargetBaseAddress < KSEG0_BASE)\r
+    {\r
+        Length = 0;\r
+        Status = STATUS_UNSUCCESSFUL;\r
+    }\r
+    else if ((ULONG_PTR)State->u.ReadMemory.TargetBaseAddress >= (ULONG_PTR)SharedUserData)\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
+        /* 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
+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 Context)\r
+{\r
+    STRING Data, Header;\r
+    DBGKD_MANIPULATE_STATE64 ManipulateState;\r
+    ULONG Length;\r
+    KDSTATUS RecvCode;\r
+\r
+    /* Setup the Manipulate State structure */\r
+    Header.MaximumLength = sizeof(DBGKD_MANIPULATE_STATE64);\r
+    Header.Buffer = (PCHAR)&ManipulateState;\r
+    Data.MaximumLength = sizeof(KdpMessageBuffer);\r
+    Data.Buffer = KdpMessageBuffer;\r
+    //KdpContextSent = FALSE;\r
+\r
+SendPacket:\r
+    /* Send the Packet */\r
+    KdSendPacket(PacketType, SendHeader, SendData, &KdpContext);\r
+\r
+    /* If the debugger isn't present anymore, just return success */\r
+    if (KdDebuggerNotPresent) return ContinueSuccess;\r
+\r
+    /* Main processing Loop */\r
+    for (;;)\r
+    {\r
+        /* Receive Loop */\r
+        do\r
+        {\r
+            /* Wait to get a reply to our packet */\r
+            RecvCode = KdReceivePacket(PACKET_TYPE_KD_STATE_MANIPULATE,\r
+                                       &Header,\r
+                                       &Data,\r
+                                       &Length,\r
+                                       &KdpContext);\r
+\r
+            /* If we got a resend request, do it */\r
+            if (RecvCode == KdPacketNeedsResend) goto SendPacket;\r
+        } while (RecvCode == KdPacketTimedOut);\r
+\r
+        /* Now check what API we got */\r
+        switch (ManipulateState.ApiNumber)\r
+        {\r
+            case DbgKdReadVirtualMemoryApi:\r
+\r
+                /* Read virtual memory */\r
+                KdpReadVirtualMemory(&ManipulateState, &Data, Context);\r
+                break;\r
+\r
+            case DbgKdWriteVirtualMemoryApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdWriteVirtualMemoryApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdGetContextApi:\r
+\r
+                /* Get the current context */\r
+                KdpGetContext(&ManipulateState, &Data, Context);\r
+                break;\r
+\r
+            case DbgKdSetContextApi:\r
+\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
+                break;\r
+\r
+            case DbgKdRestoreBreakPointApi:\r
+\r
+                /* FIXME: TODO */\r
+                KdpRestoreBreakpoint(&ManipulateState, &Data, Context);\r
+                break;\r
+\r
+            case DbgKdContinueApi:\r
+\r
+                /* Simply continue */\r
+                return NT_SUCCESS(ManipulateState.u.Continue.ContinueStatus);\r
+\r
+            case DbgKdReadControlSpaceApi:\r
+\r
+                /* Read control space */\r
+                KdpReadControlSpace(&ManipulateState, &Data, Context);\r
+                break;\r
+\r
+            case DbgKdWriteControlSpaceApi:\r
+\r
+                /* FIXME: TODO */\r
+                KdpWriteControlSpace(&ManipulateState, &Data, Context);\r
+                break;\r
+\r
+            case DbgKdReadIoSpaceApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdReadIoSpaceApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdWriteIoSpaceApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdWriteIoSpaceApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdRebootApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdRebootApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdContinueApi2:\r
+\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 DbgKdWritePhysicalMemoryApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdWritePhysicalMemoryApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdQuerySpecialCallsApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdQuerySpecialCallsApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdSetSpecialCallApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdSetSpecialCallApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdClearSpecialCallsApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdClearSpecialCallsApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdSetInternalBreakPointApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdSetInternalBreakPointApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdGetInternalBreakPointApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdGetInternalBreakPointApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdReadIoSpaceExtendedApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdReadIoSpaceExtendedApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdWriteIoSpaceExtendedApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdWriteIoSpaceExtendedApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdGetVersionApi:\r
+\r
+                /* Get version data */\r
+                KdpGetVersion(&ManipulateState);\r
+                break;\r
+\r
+            case DbgKdWriteBreakPointExApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdWriteBreakPointExApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdRestoreBreakPointExApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdRestoreBreakPointExApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdCauseBugCheckApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdCauseBugCheckApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdSwitchProcessor:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdSwitchProcessor);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdPageInApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdPageInApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdReadMachineSpecificRegister:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdReadMachineSpecificRegister);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdWriteMachineSpecificRegister:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdWriteMachineSpecificRegister);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case OldVlm1:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(OldVlm1);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case OldVlm2:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(OldVlm2);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdSearchMemoryApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdSearchMemoryApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdGetBusDataApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdGetBusDataApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdSetBusDataApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdSetBusDataApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdCheckLowMemoryApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdCheckLowMemoryApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdClearAllInternalBreakpointsApi:\r
+\r
+                /* Just clear the counter */\r
+                KdpNumInternalBreakpoints = 0;\r
+                break;\r
+\r
+            case DbgKdFillMemoryApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdFillMemoryApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdQueryMemoryApi:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdQueryMemoryApi);\r
+                while (TRUE);\r
+                break;\r
+\r
+            case DbgKdSwitchPartition:\r
+\r
+                /* FIXME: TODO */\r
+                Ke386SetCr2(DbgKdSwitchPartition);\r
+                while (TRUE);\r
+                break;\r
+\r
+            /* Unsupported Message */\r
+            default:\r
+\r
+                /* Setup an empty message, with failure */\r
+                while (TRUE);\r
+fail:\r
+                Data.Length = 0;\r
+                ManipulateState.ReturnStatus = STATUS_UNSUCCESSFUL;\r
+\r
+                /* Send it */\r
+                KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,\r
+                             &Header,\r
+                             &Data,\r
+                             &KdpContext);\r
+                break;\r
+        }\r
+    }\r
+}\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpReportLoadSymbolsStateChange(IN PSTRING PathName,\r
+                                IN PKD_SYMBOLS_INFO SymbolInfo,\r
+                                IN BOOLEAN Unload,\r
+                                IN OUT PCONTEXT Context)\r
+{\r
+    PSTRING ExtraData;\r
+    STRING Data, Header;\r
+    DBGKD_WAIT_STATE_CHANGE64 WaitStateChange;\r
+    KCONTINUE_STATUS Status;\r
+\r
+    /* Start wait loop */\r
+    do\r
+    {\r
+        /* Build the architecture common parts of the message */\r
+        KdpSetCommonState(DbgKdLoadSymbolsStateChange,\r
+                          Context,\r
+                          &WaitStateChange);\r
+\r
+        /* Now finish creating the structure */\r
+        KdpSetContextState(&WaitStateChange, Context);\r
+\r
+        /* Fill out load data */\r
+        WaitStateChange.u.LoadSymbols.UnloadSymbols = Unload;\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
+        /* Check if we have a symbol name */\r
+        if (PathName)\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
+        }\r
+        else\r
+        {\r
+            /* No name */\r
+            WaitStateChange.u.LoadSymbols.PathNameLength = 0;\r
+            ExtraData = NULL;\r
+        }\r
+\r
+        /* Setup the header */\r
+        Header.Length = sizeof(DBGKD_WAIT_STATE_CHANGE64);\r
+        Header.Buffer = (PCHAR)&WaitStateChange;\r
+\r
+        /* Send the packet */\r
+        Status = KdpSendWaitContinue(PACKET_TYPE_KD_STATE_CHANGE64,\r
+                                     &Header,\r
+                                     ExtraData,\r
+                                     Context);\r
+    } while(Status == ContinueProcessorReselected);\r
+\r
+    /* Return status */\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
+        /* 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
+VOID\r
+NTAPI\r
+KdpTimeSlipDpcRoutine(IN PKDPC Dpc,\r
+                      IN PVOID DeferredContext,\r
+                      IN PVOID SystemArgument1,\r
+                      IN PVOID SystemArgument2)\r
+{\r
+    LONG OldSlip, NewSlip, PendingSlip;\r
+\r
+    /* Get the current pending slip */\r
+    PendingSlip = KdpTimeSlipPending;\r
+    do\r
+    {\r
+        /* Save the old value and either disable or enable it now. */\r
+        OldSlip = PendingSlip;\r
+        NewSlip = OldSlip > 1 ? 1 : 0;\r
+\r
+        /* Try to change the value */\r
+    } while (InterlockedCompareExchange(&KdpTimeSlipPending,\r
+                                        NewSlip,\r
+                                        OldSlip) != OldSlip);\r
+\r
+    /* If the New Slip value is 1, then do the Time Slipping */\r
+    if (NewSlip) ExQueueWorkItem(&KdpTimeSlipWorkItem, DelayedWorkQueue);\r
+}\r
+\r
+VOID\r
+NTAPI\r
+KdpTimeSlipWork(IN PVOID Context)\r
+{\r
+    KIRQL OldIrql;\r
+    LARGE_INTEGER DueTime;\r
+\r
+    /* Update the System time from the CMOS */\r
+    ExAcquireTimeRefreshLock(FALSE);\r
+    ExUpdateSystemTimeFromCmos(FALSE, 0);\r
+    ExReleaseTimeRefreshLock();\r
+\r
+    /* Check if we have a registered Time Slip Event and signal it */\r
+    KeAcquireSpinLock(&KdpTimeSlipEventLock, &OldIrql);\r
+    if (KdpTimeSlipEvent) KeSetEvent(KdpTimeSlipEvent, 0, FALSE);\r
+    KeReleaseSpinLock(&KdpTimeSlipEventLock, OldIrql);\r
+\r
+    /* Delay the DPC until it runs next time */\r
+    DueTime.QuadPart = -1800000000;\r
+    KeSetTimer(&KdpTimeSlipTimer, DueTime, &KdpTimeSlipDpc);\r
+}\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpSwitchProcessor(IN PEXCEPTION_RECORD ExceptionRecord,\r
+                   IN OUT PCONTEXT ContextRecord,\r
+                   IN BOOLEAN SecondChanceException)\r
+{\r
+    BOOLEAN Status;\r
+\r
+    /* Save the port data */\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
+    return Status;\r
+}\r
+\r
+LARGE_INTEGER\r
+NTAPI\r
+KdpQueryPerformanceCounter(IN PKTRAP_FRAME TrapFrame)\r
+{\r
+    LARGE_INTEGER Null = {{0}};\r
+\r
+    /* Check if interrupts were disabled */\r
+    if (!(TrapFrame->EFlags & EFLAGS_INTERRUPT_MASK))\r
+    {\r
+        /* Nothing to return */\r
+        return Null;\r
+    }\r
+\r
+    /* Otherwise, do the call */\r
+    return KeQueryPerformanceCounter(NULL);\r
+}\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdEnterDebugger(IN PKTRAP_FRAME TrapFrame,\r
+                IN PKEXCEPTION_FRAME ExceptionFrame)\r
+{\r
+    BOOLEAN Entered;\r
+\r
+    /* Check if we have a trap frame */\r
+    if (TrapFrame)\r
+    {\r
+        /* Calculate the time difference for the enter */\r
+        KdTimerStop = KdpQueryPerformanceCounter(TrapFrame);\r
+        KdTimerDifference.QuadPart = KdTimerStop.QuadPart -\r
+                                     KdTimerStart.QuadPart;\r
+    }\r
+    else\r
+    {\r
+        /* No trap frame, so can't calculate */\r
+        KdTimerStop.QuadPart = 0;\r
+    }\r
+\r
+    /* Save the current IRQL */\r
+    KeGetCurrentPrcb()->DebuggerSavedIRQL = KeGetCurrentIrql();\r
+\r
+    /* Freeze all CPUs */\r
+    Entered = KeFreezeExecution(TrapFrame, ExceptionFrame);\r
+\r
+    /* Lock the port, save the state and set debugger entered */\r
+    KdpPortLocked = KeTryToAcquireSpinLockAtDpcLevel(&KdpDebuggerLock);\r
+    KdSave(FALSE);\r
+    KdEnteredDebugger = TRUE;\r
+\r
+    /* Check freeze flag */\r
+    if (KiFreezeFlag & 1)\r
+    {\r
+        /* Print out errror */\r
+        DbgPrint("FreezeLock was jammed!  Backup SpinLock was used!\n");\r
+    }\r
+\r
+    /* Check processor state */\r
+    if (KiFreezeFlag & 2)\r
+    {\r
+        /* Print out errror */\r
+        DbgPrint("Some processors not frozen in debugger!\n");\r
+    }\r
+\r
+    /* Make sure we acquired the port */\r
+    if (!KdpPortLocked) DbgPrint("Port lock was not acquired!\n");\r
+\r
+    /* Return enter state */\r
+    return Entered;\r
+}\r
+\r
+VOID\r
+NTAPI\r
+KdExitDebugger(IN BOOLEAN Entered)\r
+{\r
+    ULONG TimeSlip;\r
+\r
+    /* Restore the state and unlock the port */\r
+    KdRestore(FALSE);\r
+    if (KdpPortLocked) KdpPortUnlock();\r
+\r
+    /* Unfreeze the CPUs */\r
+    KeThawExecution(Entered);\r
+\r
+    /* Compare time with the one from KdEnterDebugger */\r
+    if (!KdTimerStop.QuadPart)\r
+    {\r
+        /* We didn't get a trap frame earlier in so never got the time */\r
+        KdTimerStart = KdTimerStop;\r
+    }\r
+    else\r
+    {\r
+        /* Query the timer */\r
+        KdTimerStart = KeQueryPerformanceCounter(NULL);\r
+    }\r
+\r
+    /* Check if a Time Slip was on queue */\r
+    TimeSlip = InterlockedIncrement(&KdpTimeSlipPending);\r
+    if (TimeSlip == 1)\r
+    {\r
+        /* Queue a DPC for the time slip */\r
+        InterlockedIncrement(&KdpTimeSlipPending);\r
+        KeInsertQueueDpc(&KdpTimeSlipDpc, NULL, NULL);\r
+    }\r
+}\r
+\r
+NTSTATUS\r
+NTAPI\r
+KdEnableDebuggerWithLock(BOOLEAN NeedLock)\r
+{\r
+    KIRQL OldIrql = PASSIVE_LEVEL;\r
+\r
+    /* Check if we need to acquire the lock */\r
+    if (NeedLock)\r
+    {\r
+        /* Lock the port */\r
+        KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);\r
+        KdpPortLock();\r
+    }\r
+\r
+    /* Check if we're not disabled */\r
+    if (!KdDisableCount)\r
+    {\r
+        /* Check if we had locked the port before */\r
+        if (NeedLock)\r
+        {\r
+            /* Do the unlock */\r
+            KeLowerIrql(OldIrql);\r
+            KdpPortUnlock();\r
+        }\r
+\r
+        /* Fail: We're already enabled */\r
+        return STATUS_INVALID_PARAMETER;\r
+    }\r
+\r
+    /* Decrease the disable count */\r
+    if (!(--KdDisableCount))\r
+    {\r
+        /* We're now enabled again! Were we enabled before, too? */\r
+        if (KdPreviouslyEnabled)\r
+        {\r
+            /* Reinitialize the Debugger */\r
+            KdInitSystem(0, NULL) ;\r
+            KdpRestoreAllBreakpoints();\r
+        }\r
+    }\r
+\r
+    /* Check if we had locked the port before */\r
+    if (NeedLock)\r
+    {\r
+        /* Yes, now unlock it */\r
+        KeLowerIrql(OldIrql);\r
+        KdpPortUnlock();\r
+    }\r
+\r
+    /* We're done */\r
+    return STATUS_SUCCESS;\r
+}\r
+\r
+/* PUBLIC FUNCTIONS **********************************************************/\r
+\r
+/*\r
+ * @implemented\r
+ */\r
+NTSTATUS\r
+NTAPI\r
+KdEnableDebugger(VOID)\r
+{\r
+    /* Use the internal routine */\r
+    while (TRUE);\r
+    return KdEnableDebuggerWithLock(TRUE);\r
+}\r
+\r
diff --git a/reactos/ntoskrnl/kd64/kdbreak.c b/reactos/ntoskrnl/kd64/kdbreak.c
new file mode 100644 (file)
index 0000000..4b9b9af
--- /dev/null
@@ -0,0 +1,149 @@
+/*\r
+ * PROJECT:         ReactOS Kernel\r
+ * LICENSE:         GPL - See COPYING in the top level directory\r
+ * FILE:            ntoskrnl/kd64/kdbreak.c\r
+ * PURPOSE:         KD64 Breakpoint Support\r
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)\r
+ */\r
+\r
+/* INCLUDES ******************************************************************/\r
+\r
+#include <ntoskrnl.h>\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+/* FUNCTIONS *****************************************************************/\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpLowWriteContent(IN ULONG BpIndex)\r
+{\r
+    /* Make sure that the breakpoint is actually active */\r
+    if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointPending)\r
+    {\r
+        /* So we have a valid breakpoint, but it hasn't been used yet... */\r
+        KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointPending;\r
+        return TRUE;\r
+    }\r
+\r
+    /* Is the original instruction an INT3 anyway? */\r
+    if (KdpBreakpointTable[BpIndex].Content == KdpBreakpointInstruction)\r
+    {\r
+        /* Then leave it that way... */\r
+        return TRUE;\r
+    }\r
+\r
+    /* We have an active breakpoint with an instruction to bring back. Do it. */\r
+    RtlCopyMemory(KdpBreakpointTable[BpIndex].Address,\r
+                  &KdpBreakpointTable[BpIndex].Content,\r
+                  sizeof(UCHAR));\r
+\r
+    /* Everything went fine, return */\r
+    return TRUE;\r
+}\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpLowRestoreBreakpoint(IN ULONG BpIndex)\r
+{\r
+    /* Were we not able to remove it earlier? */\r
+    if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointExpired)\r
+    {\r
+        /* Well then, we'll just re-use it and return success! */\r
+        KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointExpired;\r
+        return TRUE;\r
+    }\r
+\r
+    /* Are we merely writing an INT3 on top of another INT3? */\r
+    if (KdpBreakpointTable[BpIndex].Content == KdpBreakpointInstruction)\r
+    {\r
+        /* Nothing to do then... */\r
+        return TRUE;\r
+    }\r
+\r
+    /* Ok, we actually have to overwrite the instruction now */\r
+    RtlCopyMemory(KdpBreakpointTable[BpIndex].Address,\r
+                  &KdpBreakpointInstruction,\r
+                  sizeof(UCHAR));\r
+\r
+    /* Clear any possible previous pending flag and return success */\r
+    KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointPending;\r
+    return TRUE;\r
+}\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpDeleteBreakpoint(IN ULONG BpEntry)\r
+{\r
+    ULONG BpIndex = BpEntry - 1;\r
+\r
+    /* Check for invalid breakpoint entry */\r
+    if (!(BpEntry) || (BpEntry > 20)) return FALSE;\r
+\r
+    /* If the specified breakpoint table entry is not valid, then return FALSE. */\r
+    if (!KdpBreakpointTable[BpIndex].Flags) return FALSE;\r
+\r
+    /* Check if the breakpoint is suspended */\r
+    if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointSuspended)\r
+    {\r
+        /* Check if breakpoint is not ...? */\r
+        if (!(KdpBreakpointTable[BpIndex].Flags & KdpBreakpointExpired))\r
+        {\r
+            /* Invalidate it and return success */\r
+            KdpBreakpointTable[BpIndex].Flags = 0;\r
+            return TRUE;\r
+        }\r
+    }\r
+\r
+    /* Restore original data, then invalidate it and return success */\r
+    if (KdpLowWriteContent(BpIndex)) KdpBreakpointTable[BpIndex].Flags = 0;\r
+    return TRUE;\r
+}\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpDeleteBreakpointRange(IN PVOID Base,\r
+                         IN PVOID Limit)\r
+{\r
+    ULONG BpIndex;\r
+    BOOLEAN Return = FALSE;\r
+\r
+    /* Loop the breakpoint table */\r
+    for (BpIndex = 0; BpIndex < 20; BpIndex++)\r
+    {\r
+        /* Make sure that the breakpoint is active and matches the range. */\r
+        if ((KdpBreakpointTable[BpIndex].Flags & KdpBreakpointActive) &&\r
+            ((KdpBreakpointTable[BpIndex].Address >= Base) &&\r
+             (KdpBreakpointTable[BpIndex].Address <= Limit)))\r
+        {\r
+            /* Delete it */\r
+            Return = Return || KdpDeleteBreakpoint(BpIndex + 1);\r
+        }\r
+    }\r
+\r
+    /* Return to caller */\r
+    return Return;\r
+}\r
+\r
+VOID\r
+NTAPI\r
+KdpRestoreAllBreakpoints(VOID)\r
+{\r
+    ULONG BpIndex;\r
+\r
+    /* No more suspended Breakpoints */\r
+    BreakpointsSuspended = FALSE;\r
+\r
+    /* Loop the breakpoints */\r
+    for (BpIndex = 0; BpIndex < 20; BpIndex++ )\r
+    {\r
+        /* Check if they are valid, suspended breakpoints */\r
+        if ((KdpBreakpointTable[BpIndex].Flags & KdpBreakpointActive) &&\r
+            (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointSuspended))\r
+        {\r
+            /* Unsuspend them */\r
+            KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointSuspended;\r
+            KdpLowRestoreBreakpoint(BpIndex);\r
+        }\r
+    }\r
+}\r
diff --git a/reactos/ntoskrnl/kd64/kddata.c b/reactos/ntoskrnl/kd64/kddata.c
new file mode 100644 (file)
index 0000000..d1389f4
--- /dev/null
@@ -0,0 +1,467 @@
+/*\r
+ * PROJECT:         ReactOS Kernel\r
+ * LICENSE:         GPL - See COPYING in the top level directory\r
+ * FILE:            ntoskrnl/kd64/kddata.c\r
+ * PURPOSE:         Contains all global variables and settings for KD64\r
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)\r
+ */\r
+\r
+/* INCLUDES ******************************************************************/\r
+\r
+#include <ntoskrnl.h>\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+VOID NTAPI RtlpBreakWithStatusInstruction(VOID);\r
+\r
+/* GLOBALS *******************************************************************/\r
+\r
+//\r
+// Debugger State\r
+//\r
+KD_CONTEXT KdpContext;\r
+BOOLEAN KdpControlCPressed;\r
+BOOLEAN KdpControlCWaiting;\r
+BOOLEAN KdpPortLocked;\r
+KSPIN_LOCK KdpDebuggerLock;\r
+\r
+//\r
+// Debug Trap Handlers\r
+//\r
+PKDEBUG_ROUTINE KiDebugRoutine = KdpStub;\r
+PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine;\r
+\r
+//\r
+// Debugger Configuration Settings\r
+//\r
+BOOLEAN KdBreakAfterSymbolLoad;\r
+BOOLEAN KdPitchDebugger;\r
+BOOLEAN _KdDebuggerNotPresent;\r
+BOOLEAN _KdDebuggerEnabled;\r
+BOOLEAN KdAutoEnableOnEvent;\r
+BOOLEAN KdPreviouslyEnabled;\r
+BOOLEAN KdpDebuggerStructuresInitialized;\r
+BOOLEAN KdEnteredDebugger;\r
+ULONG KdDisableCount;\r
+LARGE_INTEGER KdPerformanceCounterRate;\r
+\r
+//\r
+// Breakpoint Data\r
+//\r
+BREAKPOINT_ENTRY KdpBreakpointTable[20];\r
+ULONG KdpBreakpointInstruction = 0xCC;\r
+BOOLEAN KdpOweBreakpoint;\r
+BOOLEAN BreakpointsSuspended;\r
+ULONG KdpNumInternalBreakpoints;\r
+\r
+ULONG KdpCurrentSymbolStart, KdpCurrentSymbolEnd;\r
+\r
+//\r
+// Time Slip Support\r
+//\r
+KDPC KdpTimeSlipDpc;\r
+KTIMER KdpTimeSlipTimer;\r
+WORK_QUEUE_ITEM KdpTimeSlipWorkItem;\r
+LONG KdpTimeSlipPending = 1;\r
+PKEVENT KdpTimeSlipEvent;\r
+KSPIN_LOCK KdpTimeSlipEventLock;\r
+LARGE_INTEGER KdTimerStop, KdTimerStart, KdTimerDifference;\r
+\r
+//\r
+// Buffers\r
+//\r
+CHAR KdpMessageBuffer[4096];\r
+CHAR KdpPathBuffer[4096];\r
+\r
+//\r
+// KdPrint Buffers\r
+//\r
+CHAR KdPrintDefaultCircularBuffer[0x8000];\r
+PCHAR KdPrintWritePointer = KdPrintDefaultCircularBuffer;\r
+ULONG KdPrintRolloverCount;\r
+PCHAR KdPrintCircularBuffer = KdPrintDefaultCircularBuffer;\r
+ULONG KdPrintBufferSize = sizeof(KdPrintDefaultCircularBuffer);\r
+ULONG KdPrintBufferChanges = 0;\r
+\r
+//\r
+// Debug Filter Masks\r
+//\r
+ULONG Kd_WIN2000_Mask = 1;\r
+ULONG Kd_SYSTEM_Mask;\r
+ULONG Kd_SMSS_Mask;\r
+ULONG Kd_SETUP_Mask;\r
+ULONG Kd_NTFS_Mask;\r
+ULONG Kd_FSTUB_Mask;\r
+ULONG Kd_CRASHDUMP_Mask;\r
+ULONG Kd_CDAUDIO_Mask;\r
+ULONG Kd_CDROM_Mask;\r
+ULONG Kd_CLASSPNP_Mask;\r
+ULONG Kd_DISK_Mask;\r
+ULONG Kd_REDBOOK_Mask;\r
+ULONG Kd_STORPROP_Mask;\r
+ULONG Kd_SCSIPORT_Mask;\r
+ULONG Kd_SCSIMINIPORT_Mask;\r
+ULONG Kd_CONFIG_Mask;\r
+ULONG Kd_I8042PRT_Mask;\r
+ULONG Kd_SERMOUSE_Mask;\r
+ULONG Kd_LSERMOUS_Mask;\r
+ULONG Kd_KBDHID_Mask;\r
+ULONG Kd_MOUHID_Mask;\r
+ULONG Kd_KBDCLASS_Mask;\r
+ULONG Kd_MOUCLASS_Mask;\r
+ULONG Kd_TWOTRACK_Mask;\r
+ULONG Kd_WMILIB_Mask;\r
+ULONG Kd_ACPI_Mask;\r
+ULONG Kd_AMLI_Mask;\r
+ULONG Kd_HALIA64_Mask;\r
+ULONG Kd_VIDEO_Mask;\r
+ULONG Kd_SVCHOST_Mask;\r
+ULONG Kd_VIDEOPRT_Mask;\r
+ULONG Kd_TCPIP_Mask;\r
+ULONG Kd_DMSYNTH_Mask;\r
+ULONG Kd_NTOSPNP_Mask;\r
+ULONG Kd_FASTFAT_Mask;\r
+ULONG Kd_SAMSS_Mask;\r
+ULONG Kd_PNPMGR_Mask;\r
+ULONG Kd_NETAPI_Mask;\r
+ULONG Kd_SCSERVER_Mask;\r
+ULONG Kd_SCCLIENT_Mask;\r
+ULONG Kd_SERIAL_Mask;\r
+ULONG Kd_SERENUM_Mask;\r
+ULONG Kd_UHCD_Mask;\r
+ULONG Kd_RPCPROXY_Mask;\r
+ULONG Kd_AUTOCHK_Mask;\r
+ULONG Kd_DCOMSS_Mask;\r
+ULONG Kd_UNIMODEM_Mask;\r
+ULONG Kd_SIS_Mask;\r
+ULONG Kd_FLTMGR_Mask;\r
+ULONG Kd_WMICORE_Mask;\r
+ULONG Kd_BURNENG_Mask;\r
+ULONG Kd_IMAPI_Mask;\r
+ULONG Kd_SXS_Mask;\r
+ULONG Kd_FUSION_Mask;\r
+ULONG Kd_IDLETASK_Mask;\r
+ULONG Kd_SOFTPCI_Mask;\r
+ULONG Kd_TAPE_Mask;\r
+ULONG Kd_MCHGR_Mask;\r
+ULONG Kd_IDEP_Mask;\r
+ULONG Kd_PCIIDE_Mask;\r
+ULONG Kd_FLOPPY_Mask;\r
+ULONG Kd_FDC_Mask;\r
+ULONG Kd_TERMSRV_Mask;\r
+ULONG Kd_W32TIME_Mask;\r
+ULONG Kd_PREFETCHER_Mask;\r
+ULONG Kd_RSFILTER_Mask;\r
+ULONG Kd_FCPORT_Mask;\r
+ULONG Kd_PCI_Mask;\r
+ULONG Kd_DMIO_Mask;\r
+ULONG Kd_DMCONFIG_Mask;\r
+ULONG Kd_DMADMIN_Mask;\r
+ULONG Kd_WSOCKTRANSPORT_Mask;\r
+ULONG Kd_VSS_Mask;\r
+ULONG Kd_PNPMEM_Mask;\r
+ULONG Kd_PROCESSOR_Mask;\r
+ULONG Kd_DMSERVER_Mask;\r
+ULONG Kd_SR_Mask;\r
+ULONG Kd_INFINIBAND_Mask;\r
+ULONG Kd_IHVDRIVER_Mask;\r
+ULONG Kd_IHVVIDEO_Mask;\r
+ULONG Kd_IHVAUDIO_Mask;\r
+ULONG Kd_IHVNETWORK_Mask;\r
+ULONG Kd_IHVSTREAMING_Mask;\r
+ULONG Kd_IHVBUS_Mask;\r
+ULONG Kd_HPS_Mask;\r
+ULONG Kd_RTLTHREADPOOL_Mask;\r
+ULONG Kd_LDR_Mask;\r
+ULONG Kd_TCPIP6_Mask;\r
+ULONG Kd_ISAPNP_Mask;\r
+ULONG Kd_SHPC_Mask;\r
+ULONG Kd_STORPORT_Mask;\r
+ULONG Kd_STORMINIPORT_Mask;\r
+ULONG Kd_PRINTSPOOLER_Mask;\r
+ULONG Kd_VSSDYNDISK_Mask;\r
+ULONG Kd_VERIFIER_Mask;\r
+ULONG Kd_VDS_Mask;\r
+ULONG Kd_VDSBAS_Mask;\r
+ULONG Kd_VDSDYNDR_Mask;\r
+ULONG Kd_VDSUTIL_Mask;\r
+ULONG Kd_DFRGIFC_Mask;\r
+ULONG Kd_DEFAULT_Mask;\r
+ULONG Kd_MM_Mask;\r
+ULONG Kd_DFSC_Mask;\r
+ULONG Kd_WOW64_Mask;\r
+ULONG Kd_ENDOFTABLE_Mask;\r
+\r
+//\r
+// Debug Filter Component Table\r
+//\r
+PULONG KdComponentTable[104] =\r
+{\r
+    &Kd_SYSTEM_Mask,\r
+    &Kd_SMSS_Mask,\r
+    &Kd_SETUP_Mask,\r
+    &Kd_NTFS_Mask,\r
+    &Kd_FSTUB_Mask,\r
+    &Kd_CRASHDUMP_Mask,\r
+    &Kd_CDAUDIO_Mask,\r
+    &Kd_CDROM_Mask,\r
+    &Kd_CLASSPNP_Mask,\r
+    &Kd_DISK_Mask,\r
+    &Kd_REDBOOK_Mask,\r
+    &Kd_STORPROP_Mask,\r
+    &Kd_SCSIPORT_Mask,\r
+    &Kd_SCSIMINIPORT_Mask,\r
+    &Kd_CONFIG_Mask,\r
+    &Kd_I8042PRT_Mask,\r
+    &Kd_SERMOUSE_Mask,\r
+    &Kd_LSERMOUS_Mask,\r
+    &Kd_KBDHID_Mask,\r
+    &Kd_MOUHID_Mask,\r
+    &Kd_KBDCLASS_Mask,\r
+    &Kd_MOUCLASS_Mask,\r
+    &Kd_TWOTRACK_Mask,\r
+    &Kd_WMILIB_Mask,\r
+    &Kd_ACPI_Mask,\r
+    &Kd_AMLI_Mask,\r
+    &Kd_HALIA64_Mask,\r
+    &Kd_VIDEO_Mask,\r
+    &Kd_SVCHOST_Mask,\r
+    &Kd_VIDEOPRT_Mask,\r
+    &Kd_TCPIP_Mask,\r
+    &Kd_DMSYNTH_Mask,\r
+    &Kd_NTOSPNP_Mask,\r
+    &Kd_FASTFAT_Mask,\r
+    &Kd_SAMSS_Mask,\r
+    &Kd_PNPMGR_Mask,\r
+    &Kd_NETAPI_Mask,\r
+    &Kd_SCSERVER_Mask,\r
+    &Kd_SCCLIENT_Mask,\r
+    &Kd_SERIAL_Mask,\r
+    &Kd_SERENUM_Mask,\r
+    &Kd_UHCD_Mask,\r
+    &Kd_RPCPROXY_Mask,\r
+    &Kd_AUTOCHK_Mask,\r
+    &Kd_DCOMSS_Mask,\r
+    &Kd_UNIMODEM_Mask,\r
+    &Kd_SIS_Mask,\r
+    &Kd_FLTMGR_Mask,\r
+    &Kd_WMICORE_Mask,\r
+    &Kd_BURNENG_Mask,\r
+    &Kd_IMAPI_Mask,\r
+    &Kd_SXS_Mask,\r
+    &Kd_FUSION_Mask,\r
+    &Kd_IDLETASK_Mask,\r
+    &Kd_SOFTPCI_Mask,\r
+    &Kd_TAPE_Mask,\r
+    &Kd_MCHGR_Mask,\r
+    &Kd_IDEP_Mask,\r
+    &Kd_PCIIDE_Mask,\r
+    &Kd_FLOPPY_Mask,\r
+    &Kd_FDC_Mask,\r
+    &Kd_TERMSRV_Mask,\r
+    &Kd_W32TIME_Mask,\r
+    &Kd_PREFETCHER_Mask,\r
+    &Kd_RSFILTER_Mask,\r
+    &Kd_FCPORT_Mask,\r
+    &Kd_PCI_Mask,\r
+    &Kd_DMIO_Mask,\r
+    &Kd_DMCONFIG_Mask,\r
+    &Kd_DMADMIN_Mask,\r
+    &Kd_WSOCKTRANSPORT_Mask,\r
+    &Kd_VSS_Mask,\r
+    &Kd_PNPMEM_Mask,\r
+    &Kd_PROCESSOR_Mask,\r
+    &Kd_DMSERVER_Mask,\r
+    &Kd_SR_Mask,\r
+    &Kd_INFINIBAND_Mask,\r
+    &Kd_IHVDRIVER_Mask,\r
+    &Kd_IHVVIDEO_Mask,\r
+    &Kd_IHVAUDIO_Mask,\r
+    &Kd_IHVNETWORK_Mask,\r
+    &Kd_IHVSTREAMING_Mask,\r
+    &Kd_IHVBUS_Mask,\r
+    &Kd_HPS_Mask,\r
+    &Kd_RTLTHREADPOOL_Mask,\r
+    &Kd_LDR_Mask,\r
+    &Kd_TCPIP6_Mask,\r
+    &Kd_ISAPNP_Mask,\r
+    &Kd_SHPC_Mask,\r
+    &Kd_STORPORT_Mask,\r
+    &Kd_STORMINIPORT_Mask,\r
+    &Kd_PRINTSPOOLER_Mask,\r
+    &Kd_VSSDYNDISK_Mask,\r
+    &Kd_VERIFIER_Mask,\r
+    &Kd_VDS_Mask,\r
+    &Kd_VDSBAS_Mask,\r
+    &Kd_VDSDYNDR_Mask,\r
+    &Kd_VDSUTIL_Mask,\r
+    &Kd_DFRGIFC_Mask,\r
+    &Kd_DEFAULT_Mask,\r
+    &Kd_MM_Mask,\r
+    &Kd_DFSC_Mask,\r
+    &Kd_WOW64_Mask,\r
+    &Kd_ENDOFTABLE_Mask,\r
+};\r
+\r
+ULONG KdComponentTableSize = sizeof(KdComponentTable);\r
+\r
+//\r
+// Debugger Data\r
+//\r
+LIST_ENTRY KdpDebuggerDataListHead;\r
+KSPIN_LOCK KdpDataSpinLock;\r
+\r
+//\r
+// Debugger Version and Data Block\r
+//\r
+DBGKD_GET_VERSION64 KdVersionBlock =\r
+{\r
+    0,\r
+    0,\r
+    DBGKD_64BIT_PROTOCOL_VERSION2,\r
+    KD_SECONDARY_VERSION_DEFAULT,\r
+    DBGKD_VERS_FLAG_DATA,\r
+    IMAGE_FILE_MACHINE_I386,\r
+    PACKET_TYPE_MAX,\r
+    0,\r
+    0,\r
+    DBGKD_SIMULATION_NONE,\r
+    {0},\r
+    0,\r
+    0,\r
+    0\r
+};\r
+KDDEBUGGER_DATA64 KdDebuggerDataBlock =\r
+{\r
+    {{0}},\r
+    0,\r
+    {PtrToUlong(RtlpBreakWithStatusInstruction)},\r
+    0,\r
+    FIELD_OFFSET(KTHREAD, CallbackStack),\r
+    CBSTACK_CALLBACK_STACK,\r
+    CBSTACK_EBP,\r
+    0,\r
+    {PtrToUlong(KiCallUserMode)},\r
+    {0},\r
+    {PtrToUlong(&PsLoadedModuleList)},\r
+    {PtrToUlong(&PsActiveProcessHead)},\r
+    {PtrToUlong(&PspCidTable)},\r
+    {PtrToUlong(&ExpSystemResourcesList)},\r
+    {0},                                                        // ExpPagedPoolDescriptor\r
+    {0},                                                        // ExpNumberOfPagedPools\r
+    {PtrToUlong(&KeTimeIncrement)},\r
+    {PtrToUlong(&KeBugcheckCallbackListHead)},\r
+    {PtrToUlong(KiBugCheckData)},\r
+    {PtrToUlong(&IopErrorLogListHead)},\r
+    {PtrToUlong(&ObpRootDirectoryObject)},\r
+    {PtrToUlong(&ObpTypeObjectType)},\r
+    {0},                                                        // MmSystemCacheStart\r
+    {0},                                                        // MmSystemCacheEnd\r
+    {0},                                                        // MmSystemCacheWs\r
+    {0},                                                        // MmPfnDatabase\r
+    {0},                                                        // MmSystemPtesStart\r
+    {0},                                                        // MmSystemPtesEnd\r
+    {0},                                                        // MmSubsectionBase\r
+    {0},                                                        // MmNumberOfPagingFiles\r
+    {0},                                                        // MmLowestPhysicalPage\r
+    {0},                                                        // MmHighestPhysicalPage\r
+    {0},                                                        // MmNumberOfPhysicalPages\r
+    {0},                                                        // MmMaximumNonPagedPoolInBytes\r
+    {0},                                                        // MmNonPagedSystemStart\r
+    {0},                                                        // MmNonPagedPoolStart\r
+    {0},                                                        // MmNonPagedPoolEnd\r
+    {0},                                                        // MmPagedPoolStart\r
+    {0},                                                        // MmPagedPoolEnd\r
+    {0},                                                        // MmPagedPoolInfo\r
+    PAGE_SIZE,\r
+    {0},                                                        // MmSizeOfPagedPoolInBytes\r
+    {0},                                                        // MmTotalCommitLimit\r
+    {0},                                                        // MmTotalCommittedPages\r
+    {0},                                                        // MmSharedCommit\r
+    {0},                                                        // MmDriverCommit\r
+    {0},                                                        // MmProcessCommit\r
+    {0},                                                        // MmPagedPoolCommit\r
+    {0},\r
+    {0},                                                        // MmZeroedPageListHead\r
+    {0},                                                        // MmFreePageListHead\r
+    {0},                                                        // MmStandbyPageListHead\r
+    {0},                                                        // MmModifiedPageListHead\r
+    {0},                                                        // MmModifiedNoWritePageListHead\r
+    {0},                                                        // MmAvailablePages\r
+    {0},                                                        // MmResidentAvailablePages\r
+    {0},                                                        // PoolTrackTable\r
+    {0},                                                        // NonPagedPoolDescriptor\r
+    {PtrToUlong(&MmHighestUserAddress)},\r
+    {PtrToUlong(&MmSystemRangeStart)},\r
+    {PtrToUlong(&MmUserProbeAddress)},\r
+    {PtrToUlong(KdPrintDefaultCircularBuffer)},\r
+    {PtrToUlong(KdPrintDefaultCircularBuffer + 1)},\r
+    {PtrToUlong(&KdPrintWritePointer)},\r
+    {PtrToUlong(&KdPrintRolloverCount)},\r
+    {0},                                                        // MmLoadedUserImageList\r
+    {PtrToUlong(&NtBuildLab)},\r
+    {0},\r
+    {PtrToUlong(KiProcessorBlock)},\r
+    {0},                                                        // MmUnloadedDrivers\r
+    {0},                                                        // MmLastUnloadedDrivers\r
+    {0},                                                        // MmTriageActionTaken\r
+    {0},                                                        // MmSpecialPoolTag\r
+    {0},                                                        // KernelVerifier\r
+    {0},                                                        // MmVerifierData\r
+    {0},                                                        // MmAllocatedNonPagedPool\r
+    {0},                                                        // MmPeakCommitment\r
+    {0},                                                        // MmtotalCommitLimitMaximum\r
+    {PtrToUlong(&CmNtCSDVersion)},\r
+    {0},                                                        // MmPhysicalMemoryBlock\r
+    {0},                                                        // MmSessionBase\r
+    {0},                                                        // MmSessionSize\r
+    {0},\r
+    {0},\r
+    FIELD_OFFSET(KTHREAD, NextProcessor),\r
+    FIELD_OFFSET(KTHREAD, Teb),\r
+    FIELD_OFFSET(KTHREAD, KernelStack),\r
+    FIELD_OFFSET(KTHREAD, InitialStack),\r
+    FIELD_OFFSET(KTHREAD, ApcState.Process),\r
+    FIELD_OFFSET(KTHREAD, State),\r
+    0,\r
+    0,\r
+    sizeof(EPROCESS),\r
+    FIELD_OFFSET(EPROCESS, Peb),\r
+    FIELD_OFFSET(EPROCESS, InheritedFromUniqueProcessId),\r
+    FIELD_OFFSET(EPROCESS, Pcb.DirectoryTableBase),\r
+    sizeof(KPRCB),\r
+    FIELD_OFFSET(KPRCB, DpcRoutineActive),\r
+    FIELD_OFFSET(KPRCB, CurrentThread),\r
+    FIELD_OFFSET(KPRCB, MHz),\r
+    FIELD_OFFSET(KPRCB, CpuType),\r
+    FIELD_OFFSET(KPRCB, VendorString),\r
+    FIELD_OFFSET(KPRCB, ProcessorState.ContextFrame),\r
+    FIELD_OFFSET(KPRCB, Number),\r
+    sizeof(ETHREAD),\r
+    {PtrToUlong(KdPrintDefaultCircularBuffer)},\r
+    {PtrToUlong(&KdPrintBufferSize)},\r
+    {PtrToUlong(&KeLoaderBlock)},\r
+    sizeof(KIPCR) + sizeof(KPRCB),\r
+    FIELD_OFFSET(KIPCR, Self),\r
+    FIELD_OFFSET(KPCR, Prcb),\r
+    FIELD_OFFSET(KIPCR, PrcbData),\r
+    0,\r
+    0,\r
+    0,\r
+    0,\r
+    0,\r
+    FIELD_OFFSET(KIPCR, PrcbData) +\r
+    FIELD_OFFSET(KPRCB, ProcessorState.SpecialRegisters),\r
+    KGDT_R0_CODE,\r
+    KGDT_R0_DATA,\r
+    KGDT_R0_PCR,\r
+    KGDT_R3_CODE,\r
+    KGDT_R3_DATA,\r
+    KGDT_R3_TEB,\r
+    KGDT_LDT,\r
+    KGDT_TSS,\r
+    0,\r
+    0,\r
+    {0},                                                        // IopNumTriagDumpDataBlocks\r
+    {0},                                                        // IopTriageDumpDataBlocks\r
+};\r
diff --git a/reactos/ntoskrnl/kd64/kdinit.c b/reactos/ntoskrnl/kd64/kdinit.c
new file mode 100644 (file)
index 0000000..8a88e3a
--- /dev/null
@@ -0,0 +1,267 @@
+/*\r
+ * PROJECT:         ReactOS Kernel\r
+ * LICENSE:         GPL - See COPYING in the top level directory\r
+ * FILE:            ntoskrnl/kd64/kdinit.c\r
+ * PURPOSE:         KD64 Initialization Code\r
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)\r
+ */\r
+\r
+/* INCLUDES ******************************************************************/\r
+\r
+#include <ntoskrnl.h>\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+/* FUNCTIONS *****************************************************************/\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdRegisterDebuggerDataBlock(IN ULONG Tag,\r
+                            IN PDBGKD_DEBUG_DATA_HEADER64 DataHeader,\r
+                            IN ULONG Size)\r
+{\r
+    KIRQL OldIrql;\r
+    PLIST_ENTRY NextEntry;\r
+    PDBGKD_DEBUG_DATA_HEADER64 CurrentHeader;\r
+\r
+    /* Acquire the Data Lock */\r
+    KeAcquireSpinLock(&KdpDataSpinLock, &OldIrql);\r
+\r
+    /* Loop the debugger data list */\r
+    NextEntry = KdpDebuggerDataListHead.Flink;\r
+    while (NextEntry != &KdpDebuggerDataListHead)\r
+    {\r
+        /* Get the header for this entry */\r
+        CurrentHeader = CONTAINING_RECORD(NextEntry,\r
+                                          DBGKD_DEBUG_DATA_HEADER64,\r
+                                          List);\r
+\r
+        /*  Move to the next one */\r
+        NextEntry = NextEntry->Flink;\r
+\r
+        /* Check if we already have this data block */\r
+        if ((CurrentHeader == DataHeader) || (CurrentHeader->OwnerTag == Tag))\r
+        {\r
+            /* Release the lock and fail */\r
+            KeReleaseSpinLock(&KdpDataSpinLock, OldIrql);\r
+            return FALSE;\r
+        }\r
+    }\r
+\r
+    /* Setup the header */\r
+    DataHeader->OwnerTag = Tag;\r
+    DataHeader->Size = Size;\r
+\r
+    /* Insert it into the list and release the lock */\r
+    InsertTailList(&KdpDebuggerDataListHead, (PLIST_ENTRY)&DataHeader->List);\r
+    KeReleaseSpinLock(&KdpDataSpinLock, OldIrql);\r
+    return TRUE;\r
+}\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdInitSystem(IN ULONG BootPhase,\r
+             IN PLOADER_PARAMETER_BLOCK LoaderBlock)\r
+{\r
+    BOOLEAN EnableKd;\r
+    LPSTR CommandLine, DebugLine;\r
+    ANSI_STRING ImageName;\r
+    PLDR_DATA_TABLE_ENTRY LdrEntry;\r
+    PLIST_ENTRY NextEntry;\r
+    ULONG i, j, Length;\r
+    CHAR NameBuffer[256];\r
+    PWCHAR Name;\r
+\r
+    /* Check if this is Phase 1 */\r
+    if (BootPhase)\r
+    {\r
+        /* Just query the performance counter */\r
+        KeQueryPerformanceCounter(&KdPerformanceCounterRate);\r
+        return TRUE;\r
+    }\r
+\r
+    /* Check if we already initialized once */\r
+    if (KdDebuggerEnabled) return TRUE;\r
+\r
+    /* Set the Debug Routine as the Stub for now */\r
+    KiDebugRoutine = KdpStub;\r
+\r
+    /* Disable break after symbol load for now */\r
+    KdBreakAfterSymbolLoad = FALSE;\r
+\r
+    /* Check if the Debugger Data Block was already initialized */\r
+    if (!KdpDebuggerDataListHead.Flink)\r
+    {\r
+        /* It wasn't...Initialize the KD Data Listhead */\r
+        InitializeListHead(&KdpDebuggerDataListHead);\r
+\r
+        /* Register the Debugger Data Block */\r
+        KdRegisterDebuggerDataBlock(KDBG_TAG,\r
+                                    &KdDebuggerDataBlock.Header,\r
+                                    sizeof(KdDebuggerDataBlock));\r
+\r
+        /* Fill out the KD Version Block */\r
+        KdVersionBlock.MajorVersion = (USHORT)(NtBuildNumber >> 28);\r
+        KdVersionBlock.MinorVersion = (USHORT)(NtBuildNumber & 0xFFFF);\r
+\r
+#ifdef CONFIG_SMP\r
+        /* This is an MP Build */\r
+        KdVersionBlock.Flags |= DBGKD_VERS_FLAG_MP;\r
+#endif\r
+\r
+        /* Save Pointers to Loaded Module List and Debugger Data */\r
+        KdVersionBlock.PsLoadedModuleList = (ULONGLONG)(LONG_PTR)&PsLoadedModuleList;\r
+        KdVersionBlock.DebuggerDataList = (ULONGLONG)(LONG_PTR)&KdpDebuggerDataListHead;\r
+\r
+        /* Set protocol limits */\r
+        KdVersionBlock.MaxStateChange = DbgKdMaximumStateChange -\r
+                                        DbgKdMinimumStateChange;\r
+        KdVersionBlock.MaxManipulate = DbgKdMaximumManipulate -\r
+                                       DbgKdMinimumManipulate;\r
+        KdVersionBlock.Unused[0] = 0;\r
+\r
+        /* Link us in the KPCR */\r
+        KeGetPcr()->KdVersionBlock =  &KdVersionBlock;\r
+    }\r
+\r
+    /* Check if we have a loader block */\r
+    if (LoaderBlock)\r
+    {\r
+        /* Get the image entry */\r
+        LdrEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink,\r
+                                     LDR_DATA_TABLE_ENTRY,\r
+                                     InLoadOrderLinks);\r
+\r
+        /* Save the Kernel Base */\r
+        PsNtosImageBase = (ULONG)LdrEntry->DllBase;\r
+        KdVersionBlock.KernBase = (ULONGLONG)(LONG_PTR)LdrEntry->DllBase;\r
+\r
+        /* Check if we have a command line */\r
+        CommandLine = LoaderBlock->LoadOptions;\r
+        if (CommandLine)\r
+        {\r
+            /* Upcase it */\r
+            _strupr(CommandLine);\r
+\r
+            /* Assume we'll disable KD */\r
+            EnableKd = FALSE;\r
+\r
+            /* Check for CRASHDEBUG and NODEBUG */\r
+            if (strstr(CommandLine, "CRASHDEBUG")) KdPitchDebugger = FALSE;\r
+            if (strstr(CommandLine, "NODEBUG")) KdPitchDebugger = TRUE;\r
+\r
+            /* Check if DEBUG was on */\r
+            DebugLine = strstr(CommandLine, "DEBUG");\r
+            if (DebugLine)\r
+            {\r
+                /* Enable KD */\r
+                EnableKd = TRUE;\r
+\r
+                /* Check if there was additional data */\r
+                if (DebugLine[5] == '=')\r
+                {\r
+                    /* FIXME: Check for NOUMEX, DISABLE, AUTOENABLE */\r
+                }\r
+            }\r
+        }\r
+        else\r
+        {\r
+            /* No command line options? Disable debugger by default */\r
+            KdPitchDebugger = TRUE;\r
+            EnableKd = FALSE;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        /* Called from a bugcheck...Save the Kernel Base */\r
+        KdVersionBlock.KernBase = (ULONGLONG)(LONG_PTR)PsNtosImageBase;\r
+\r
+        /* Unconditionally enable KD */\r
+        EnableKd = TRUE;\r
+    }\r
+\r
+    /* Set the Kernel Base in the Data Block */\r
+    KdDebuggerDataBlock.KernBase = (ULONGLONG)(LONG_PTR)KdVersionBlock.KernBase;\r
+\r
+    /* Initialize the debugger if requested */\r
+    if ((EnableKd) && (NT_SUCCESS(KdDebuggerInitialize0(LoaderBlock))))\r
+    {\r
+        /* Now set our real KD routine */\r
+        KiDebugRoutine = KdpTrap;\r
+\r
+        /* Check if we've already initialized our structures */\r
+        if (!KdpDebuggerStructuresInitialized)\r
+        {\r
+            /* Set the Debug Switch Routine and Retries*/\r
+            KdpContext.KdpDefaultRetries = 20;\r
+            KiDebugSwitchRoutine = KdpSwitchProcessor;\r
+\r
+            /* Initialize the Time Slip DPC */\r
+            KeInitializeDpc(&KdpTimeSlipDpc, KdpTimeSlipDpcRoutine, NULL);\r
+            KeInitializeTimer(&KdpTimeSlipTimer);\r
+            ExInitializeWorkItem(&KdpTimeSlipWorkItem, KdpTimeSlipWork, NULL);\r
+\r
+            /* First-time initialization done! */\r
+            KdpDebuggerStructuresInitialized = TRUE;\r
+        }\r
+\r
+        /* Initialize the timer */\r
+        KdTimerStart.QuadPart = 0;\r
+\r
+        /* Officially enable KD */\r
+        KdPitchDebugger = FALSE;\r
+        KdDebuggerEnabled = TRUE;\r
+\r
+        /* Let user-mode know that it's enabled as well */\r
+#undef KdDebuggerEnabled\r
+        SharedUserData->KdDebuggerEnabled = TRUE;\r
+#define KdDebuggerEnabled _KdDebuggerEnabled\r
+\r
+        /* Check if we have a loader block */\r
+        if (LoaderBlock)\r
+        {\r
+            /* Loop boot images */\r
+            NextEntry = LoaderBlock->LoadOrderListHead.Flink;\r
+            i = 0;\r
+            while ((NextEntry != &LoaderBlock->LoadOrderListHead) && (i < 2))\r
+            {\r
+                /* Get the image entry */\r
+                LdrEntry = CONTAINING_RECORD(NextEntry,\r
+                                             LDR_DATA_TABLE_ENTRY,\r
+                                             InLoadOrderLinks);\r
+\r
+                /* Generate the image name */\r
+                Name = LdrEntry->FullDllName.Buffer;\r
+                Length = LdrEntry->FullDllName.Length / sizeof(WCHAR);\r
+                j = 0;\r
+                do\r
+                {\r
+                    /* Do cheap Unicode to ANSI conversion */\r
+                    NameBuffer[j++] = (CHAR)*Name++;\r
+                } while (j < Length);\r
+\r
+                /* Null-terminate */\r
+                NameBuffer[j] = ANSI_NULL;\r
+\r
+                /* Load symbols for image */\r
+                RtlInitAnsiString(&ImageName, NameBuffer);\r
+                DbgLoadImageSymbols(&ImageName, LdrEntry->DllBase, -1);\r
+\r
+                /* Go to the next entry */\r
+                NextEntry = NextEntry->Flink;\r
+                i++;\r
+            }\r
+        }\r
+\r
+        /* Check for incoming breakin and break on symbol load if we have it*/\r
+        KdBreakAfterSymbolLoad = KdPollBreakIn();\r
+    }\r
+    else\r
+    {\r
+        /* Disable debugger */\r
+        KdDebuggerNotPresent = TRUE;\r
+    }\r
+\r
+    /* Return initialized */\r
+    return TRUE;\r
+}\r
diff --git a/reactos/ntoskrnl/kd64/kdlock.c b/reactos/ntoskrnl/kd64/kdlock.c
new file mode 100644 (file)
index 0000000..141df03
--- /dev/null
@@ -0,0 +1,125 @@
+/*\r
+ * PROJECT:         ReactOS Kernel\r
+ * LICENSE:         GPL - See COPYING in the top level directory\r
+ * FILE:            ntoskrnl/kd64/kdlock.c\r
+ * PURPOSE:         KD64 Port Lock and Breakin Support\r
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)\r
+ */\r
+\r
+/* INCLUDES ******************************************************************/\r
+\r
+#include <ntoskrnl.h>\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+/* PRIVATE FUNCTIONS *********************************************************/\r
+\r
+VOID\r
+NTAPI\r
+KdpPortLock(VOID)\r
+{\r
+    /* Acquire the lock */\r
+    KiAcquireSpinLock(&KdpDebuggerLock);\r
+}\r
+\r
+VOID\r
+NTAPI\r
+KdpPortUnlock(VOID)\r
+{\r
+    /* Release the lock */\r
+    KiReleaseSpinLock(&KdpDebuggerLock);\r
+}\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpPollBreakInWithPortLock(VOID)\r
+{\r
+    BOOLEAN DoBreak = FALSE;\r
+\r
+    /* First make sure that KD is enabled */\r
+    if (KdDebuggerEnabled)\r
+    {\r
+        /* Check if a CTRL-C is in the queue */\r
+        if (KdpContext.KdpControlCPending)\r
+        {\r
+            /* Set it and prepare for break */\r
+            DoBreak = TRUE;\r
+            KdpContext.KdpControlCPending = FALSE;\r
+        }\r
+        else\r
+        {\r
+            /* Now get a packet */\r
+            if (!KdReceivePacket(PACKET_TYPE_KD_POLL_BREAKIN,\r
+                                 NULL,\r
+                                 NULL,\r
+                                 NULL,\r
+                                 NULL))\r
+            {\r
+                /* Successful breakin */\r
+                DoBreak = TRUE;\r
+            }\r
+        }\r
+    }\r
+\r
+    /* Tell the caller to do a break */\r
+    return DoBreak;\r
+}\r
+\r
+/* PUBLIC FUNCTIONS **********************************************************/\r
+\r
+/*\r
+ * @implemented\r
+ */\r
+BOOLEAN\r
+NTAPI\r
+KdPollBreakIn(VOID)\r
+{\r
+    BOOLEAN DoBreak = FALSE;\r
+    ULONG Flags = 0;\r
+\r
+    /* First make sure that KD is enabled */\r
+    if (KdDebuggerEnabled)\r
+    {\r
+        /* Disable interrupts */\r
+        Ke386SaveFlags(Flags);\r
+        //Flags = __getcallerseflags();\r
+        _disable();\r
+\r
+        /* Check if a CTRL-C is in the queue */\r
+        if (KdpControlCWaiting)\r
+        {\r
+            /* Set it and prepare for break */\r
+            KdpControlCPressed = TRUE;\r
+            DoBreak = TRUE;\r
+            KdpControlCWaiting = FALSE;\r
+        }\r
+        else\r
+        {\r
+            /* Try to acquire the lock */\r
+            if (KeTryToAcquireSpinLockAtDpcLevel(&KdpDebuggerLock))\r
+            {\r
+                /* Now get a packet */\r
+                if (!KdReceivePacket(PACKET_TYPE_KD_POLL_BREAKIN,\r
+                                     NULL,\r
+                                     NULL,\r
+                                     NULL,\r
+                                     NULL))\r
+                {\r
+                    /* Successful breakin */\r
+                    DoBreak = TRUE;\r
+                    KdpControlCPressed = TRUE;\r
+                }\r
+\r
+                /* Let go of the port */\r
+                KdpPortUnlock();\r
+            }\r
+        }\r
+\r
+        /* Re-enable interrupts if they were disabled */\r
+        if (Flags & EFLAGS_INTERRUPT_MASK) _enable();\r
+    }\r
+\r
+    /* Tell the caller to do a break */\r
+    return DoBreak;\r
+}\r
+\r
diff --git a/reactos/ntoskrnl/kd64/kdprint.c b/reactos/ntoskrnl/kd64/kdprint.c
new file mode 100644 (file)
index 0000000..2f35592
--- /dev/null
@@ -0,0 +1,198 @@
+/*\r
+ * PROJECT:         ReactOS Kernel\r
+ * LICENSE:         GPL - See COPYING in the top level directory\r
+ * FILE:            ntoskrnl/kd64/kdprint.c\r
+ * PURPOSE:         KD64 Trap Handler Routines\r
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)\r
+ */\r
+\r
+/* INCLUDES ******************************************************************/\r
+\r
+#include <ntoskrnl.h>\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+/* FUNCTIONS *****************************************************************/\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpPrintString(IN PSTRING Output)\r
+{\r
+    STRING Data, Header;\r
+    DBGKD_DEBUG_IO DebugIo;\r
+    ULONG Length = Output->Length;\r
+\r
+    /* Copy the string */\r
+    RtlMoveMemory(KdpMessageBuffer, Output->Buffer, Length);\r
+\r
+    /* Make sure we don't exceed the KD Packet size */\r
+    if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE)\r
+    {\r
+        /* Normalize length */\r
+        Length = PACKET_MAX_SIZE - sizeof(DBGKD_DEBUG_IO);\r
+    }\r
+\r
+    /* Build the packet header */\r
+    DebugIo.ApiNumber = DbgKdPrintStringApi;\r
+    DebugIo.ProcessorLevel = KeProcessorLevel;\r
+    DebugIo.Processor = KeGetCurrentPrcb()->Number;\r
+    DebugIo.u.PrintString.LengthOfString = Length;\r
+    Header.Length = sizeof(DBGKD_DEBUG_IO);\r
+    Header.Buffer = (PCHAR)&DebugIo;\r
+\r
+    /* Build the data */\r
+    Data.Length = Length;\r
+    Data.Buffer = KdpMessageBuffer;\r
+\r
+    /* Send the packet */\r
+    KdSendPacket(PACKET_TYPE_KD_DEBUG_IO, &Header, &Data, &KdpContext);\r
+\r
+    /* Check if the user pressed CTRL+C */\r
+    return KdpPollBreakInWithPortLock();\r
+}\r
+\r
+ULONG\r
+NTAPI\r
+KdpCommandString(IN ULONG Length,\r
+                 IN LPSTR String,\r
+                 IN KPROCESSOR_MODE PreviousMode,\r
+                 IN PCONTEXT ContextRecord,\r
+                 IN PKTRAP_FRAME TrapFrame,\r
+                 IN PKEXCEPTION_FRAME ExceptionFrame)\r
+{\r
+    /* FIXME */\r
+    return FALSE;\r
+}\r
+\r
+ULONG\r
+NTAPI\r
+KdpSymbol(IN PSTRING DllPath,\r
+          IN PKD_SYMBOLS_INFO DllBase,\r
+          IN BOOLEAN Unload,\r
+          IN KPROCESSOR_MODE PreviousMode,\r
+          IN PCONTEXT ContextRecord,\r
+          IN PKTRAP_FRAME TrapFrame,\r
+          IN PKEXCEPTION_FRAME ExceptionFrame)\r
+{\r
+    BOOLEAN Entered;\r
+    PKPRCB Prcb = KeGetCurrentPrcb();\r
+    ULONG Status;\r
+\r
+    /* Check if we need to do anything */\r
+    if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return 0;\r
+\r
+    /* Enter the debugger */\r
+    Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);\r
+\r
+    /* Save the CPU Control State and save the context */\r
+    KiSaveProcessorControlState(&Prcb->ProcessorState);\r
+    RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,\r
+                  ContextRecord,\r
+                  sizeof(CONTEXT));\r
+\r
+    /* Report the new state */\r
+    Status = KdpReportLoadSymbolsStateChange(DllPath,\r
+                                             DllBase,\r
+                                             Unload,\r
+                                             &Prcb->ProcessorState.\r
+                                             ContextFrame);\r
+\r
+    /* Now restore the processor state, manually again. */\r
+    RtlCopyMemory(ContextRecord,\r
+                  &Prcb->ProcessorState.ContextFrame,\r
+                  sizeof(CONTEXT));\r
+    //KiRestoreProcessorControlState(&Prcb->ProcessorState);\r
+\r
+    /* Exit the debugger and clear the CTRL-C state */\r
+    KdExitDebugger(Entered);\r
+    return 0;\r
+}\r
+\r
+ULONG\r
+NTAPI\r
+KdpPrompt(IN LPSTR InString,\r
+          IN ULONG InStringLength,\r
+          OUT LPSTR OutString,\r
+          IN ULONG OutStringLength,\r
+          IN KPROCESSOR_MODE PreviousMode,\r
+          IN PKTRAP_FRAME TrapFrame,\r
+          IN PKEXCEPTION_FRAME ExceptionFrame)\r
+{\r
+    /* FIXME */\r
+    return FALSE;\r
+}\r
+\r
+ULONG\r
+NTAPI\r
+KdpPrint(IN ULONG ComponentId,\r
+         IN ULONG ComponentMask,\r
+         IN LPSTR String,\r
+         IN ULONG Length,\r
+         IN KPROCESSOR_MODE PreviousMode,\r
+         IN PKTRAP_FRAME TrapFrame,\r
+         IN PKEXCEPTION_FRAME ExceptionFrame,\r
+         OUT PBOOLEAN Status)\r
+{\r
+    NTSTATUS ReturnValue;\r
+    BOOLEAN Entered;\r
+    ANSI_STRING AnsiString;\r
+\r
+    /* Assume failure */\r
+    *Status = FALSE;\r
+\r
+    /* Validate the mask */\r
+    if (ComponentMask <= 0x1F) ComponentMask = 1 << ComponentMask;\r
+    if (!(Kd_WIN2000_Mask & ComponentMask) ||\r
+        ((ComponentId < KdComponentTableSize) &&\r
+        !(*KdComponentTable[ComponentId] & ComponentMask)))\r
+    {\r
+        /* Mask validation failed */\r
+        *Status = TRUE;\r
+        return FALSE;\r
+    }\r
+\r
+    /* Normalize the length */\r
+    Length = min(Length, 512);\r
+\r
+    /* Check if we need to verify the buffer */\r
+    if (PreviousMode != KernelMode)\r
+    {\r
+        /* FIXME: Support user-mode */\r
+    }\r
+\r
+    /* Setup the ANSI string */\r
+    AnsiString.Buffer = String;\r
+    AnsiString.Length = (USHORT)Length;\r
+\r
+    /* Log the print */\r
+    //KdLogDbgPrint(&AnsiString);\r
+\r
+    /* Check for a debugger */\r
+    if (KdDebuggerNotPresent)\r
+    {\r
+        /* Fail */\r
+        *Status = TRUE;\r
+        return (ULONG)STATUS_DEVICE_NOT_CONNECTED;\r
+    }\r
+\r
+    /* Enter the debugger */\r
+    Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);\r
+\r
+    /* Print the string */\r
+    if (KdpPrintString(&AnsiString))\r
+    {\r
+        /* User pressed CTRL-C, breakpoint on return */\r
+        ReturnValue = STATUS_BREAKPOINT;\r
+    }\r
+    else\r
+    {\r
+        /* String was printed */\r
+        ReturnValue = STATUS_SUCCESS;\r
+    }\r
+\r
+    /* Exit the debugger and return */\r
+    KdExitDebugger(Entered);\r
+    *Status = TRUE;\r
+    return ReturnValue;\r
+}\r
+\r
diff --git a/reactos/ntoskrnl/kd64/kdtrap.c b/reactos/ntoskrnl/kd64/kdtrap.c
new file mode 100644 (file)
index 0000000..264b283
--- /dev/null
@@ -0,0 +1,239 @@
+/*\r
+ * PROJECT:         ReactOS Kernel\r
+ * LICENSE:         GPL - See COPYING in the top level directory\r
+ * FILE:            ntoskrnl/kd64/kdtrap.c\r
+ * PURPOSE:         KD64 Trap Handlers\r
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)\r
+ */\r
+\r
+/* INCLUDES ******************************************************************/\r
+\r
+#include <ntoskrnl.h>\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+/* FUNCTIONS *****************************************************************/\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpReport(IN PKTRAP_FRAME TrapFrame,\r
+          IN PKEXCEPTION_FRAME ExceptionFrame,\r
+          IN PEXCEPTION_RECORD ExceptionRecord,\r
+          IN PCONTEXT ContextRecord,\r
+          IN KPROCESSOR_MODE PreviousMode,\r
+          IN BOOLEAN SecondChanceException)\r
+{\r
+    BOOLEAN Entered, Status;\r
+    PKPRCB Prcb;\r
+    NTSTATUS ExceptionCode = ExceptionRecord->ExceptionCode;\r
+\r
+    /* Check if this is INT1 or 3, or if we're forced to handle it */\r
+    if ((ExceptionCode == STATUS_BREAKPOINT) ||\r
+        (ExceptionCode == STATUS_SINGLE_STEP) ||\r
+        //(ExceptionCode == STATUS_ASSERTION_FAILURE) ||\r
+        (NtGlobalFlag & FLG_STOP_ON_EXCEPTION))\r
+    {\r
+        /* Check if we can't really handle this */\r
+        if ((SecondChanceException) ||\r
+            (ExceptionCode == STATUS_PORT_DISCONNECTED) ||\r
+            (NT_SUCCESS(ExceptionCode)))\r
+        {\r
+            /* Return false to have someone else take care of the exception */\r
+            return FALSE;\r
+        }\r
+    }\r
+    else if (SecondChanceException)\r
+    {\r
+        /* We won't bother unless this is second chance */\r
+        return FALSE;\r
+    }\r
+\r
+    /* Enter the debugger */\r
+    Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);\r
+\r
+    /*\r
+     * Get the KPRCB and save the CPU Control State manually instead of\r
+     * using KiSaveProcessorState, since we already have a valid CONTEXT.\r
+     */\r
+    Prcb = KeGetCurrentPrcb();\r
+    KiSaveProcessorControlState(&Prcb->ProcessorState);\r
+    RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,\r
+                  ContextRecord,\r
+                  sizeof(CONTEXT));\r
+\r
+    /* Report the new state */\r
+    Status = KdpReportExceptionStateChange(ExceptionRecord,\r
+                                           &Prcb->ProcessorState.\r
+                                           ContextFrame,\r
+                                           SecondChanceException);\r
+\r
+    /* Now restore the processor state, manually again. */\r
+    RtlCopyMemory(ContextRecord,\r
+                  &Prcb->ProcessorState.ContextFrame,\r
+                  sizeof(CONTEXT));\r
+    //KiRestoreProcessorControlState(&Prcb->ProcessorState);\r
+\r
+    /* Exit the debugger and clear the CTRL-C state */\r
+    KdExitDebugger(Entered);\r
+    KdpControlCPressed = FALSE;\r
+    return Status;\r
+}\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpTrap(IN PKTRAP_FRAME TrapFrame,\r
+        IN PKEXCEPTION_FRAME ExceptionFrame,\r
+        IN PEXCEPTION_RECORD ExceptionRecord,\r
+        IN PCONTEXT ContextRecord,\r
+        IN KPROCESSOR_MODE PreviousMode,\r
+        IN BOOLEAN SecondChanceException)\r
+{\r
+    BOOLEAN Unload = FALSE;\r
+    ULONG Eip, Eax;\r
+    BOOLEAN Status = FALSE;\r
+\r
+    /*\r
+     * Check if we got a STATUS_BREAKPOINT with a SubID for Print, Prompt or\r
+     * Load/Unload symbols.\r
+     */\r
+    if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&\r
+        (ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK))\r
+    {\r
+        /* Save EIP */\r
+        Eip = ContextRecord->Eip;\r
+\r
+        /* Check what kind of operation was requested from us */\r
+        switch (ExceptionRecord->ExceptionInformation[0])\r
+        {\r
+            /* DbgPrint */\r
+            case BREAKPOINT_PRINT:\r
+\r
+                /* Call the worker routine */\r
+                Eax = KdpPrint(ContextRecord->Ebx,\r
+                               ContextRecord->Edi,\r
+                               (LPSTR)ExceptionRecord->ExceptionInformation[1],\r
+                               (ULONG)ExceptionRecord->ExceptionInformation[2],\r
+                               PreviousMode,\r
+                               TrapFrame,\r
+                               ExceptionFrame,\r
+                               &Status);\r
+\r
+                /* Update the return value for the caller */\r
+                ContextRecord->Eax = Eax;\r
+                break;\r
+\r
+            /* DbgPrompt */\r
+            case BREAKPOINT_PROMPT:\r
+\r
+                /* Call the worker routine */\r
+                while (TRUE);\r
+                Eax = 0;\r
+                Status = TRUE;\r
+\r
+                /* Update the return value for the caller */\r
+                ContextRecord->Eax = Eax;\r
+                break;\r
+\r
+            /* DbgUnloadSymbols */\r
+            case BREAKPOINT_UNLOAD_SYMBOLS:\r
+\r
+                /* Drop into the load case below, with the unload parameter */\r
+                Unload = TRUE;\r
+\r
+            /* DbgLoadSymbols */\r
+            case BREAKPOINT_LOAD_SYMBOLS:\r
+\r
+                /* Call the worker routine */\r
+                KdpSymbol((PVOID)ExceptionRecord->ExceptionInformation[1],\r
+                          (PVOID)ExceptionRecord->ExceptionInformation[2],\r
+                          Unload,\r
+                          PreviousMode,\r
+                          ContextRecord,\r
+                          TrapFrame,\r
+                          ExceptionFrame);\r
+                Status = TRUE;\r
+                break;\r
+\r
+            /* DbgCommandString*/\r
+            case BREAKPOINT_COMMAND_STRING:\r
+\r
+                /* Call the worker routine */\r
+                while (TRUE);\r
+                Status = TRUE;\r
+\r
+            /* Anything else, do nothing */\r
+            default:\r
+\r
+                /* Get out */\r
+                break;\r
+        }\r
+\r
+        /*\r
+         * If EIP was not updated, we'll increment it ourselves so execution\r
+         * continues past the breakpoint.\r
+         */\r
+        if (ContextRecord->Eip == Eip) ContextRecord->Eip++;\r
+    }\r
+    else\r
+    {\r
+        /* Call the worker routine */\r
+        Status = KdpReport(TrapFrame,\r
+                           ExceptionFrame,\r
+                           ExceptionRecord,\r
+                           ContextRecord,\r
+                           PreviousMode,\r
+                           SecondChanceException);\r
+    }\r
+\r
+    /* Return TRUE or FALSE to caller */\r
+    return Status;\r
+}\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpStub(IN PKTRAP_FRAME TrapFrame,\r
+        IN PKEXCEPTION_FRAME ExceptionFrame,\r
+        IN PEXCEPTION_RECORD ExceptionRecord,\r
+        IN PCONTEXT ContextRecord,\r
+        IN KPROCESSOR_MODE PreviousMode,\r
+        IN BOOLEAN SecondChanceException)\r
+{\r
+    ULONG ExceptionCommand = ExceptionRecord->ExceptionInformation[0];\r
+\r
+    /* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */\r
+    if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&\r
+        (ExceptionRecord->NumberParameters > 0) &&\r
+        ((ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) ||\r
+         (ExceptionCommand == BREAKPOINT_UNLOAD_SYMBOLS) ||\r
+         (ExceptionCommand == BREAKPOINT_COMMAND_STRING) ||\r
+         (ExceptionCommand == BREAKPOINT_PRINT)))\r
+    {\r
+        /* This we can handle: simply bump EIP */\r
+        ContextRecord->Eip++;\r
+        return TRUE;\r
+    }\r
+    else if (KdPitchDebugger)\r
+    {\r
+        /* There's no debugger, fail. */\r
+        return FALSE;\r
+    }\r
+    else if ((KdAutoEnableOnEvent) &&\r
+             (KdPreviouslyEnabled) &&\r
+             !(KdDebuggerEnabled) &&\r
+             (KdEnableDebugger()) &&\r
+             (KdDebuggerEnabled))\r
+    {\r
+        /* Debugging was Auto-Enabled. We can now send this to KD. */\r
+        return KdpTrap(TrapFrame,\r
+                       ExceptionFrame,\r
+                       ExceptionRecord,\r
+                       ContextRecord,\r
+                       PreviousMode,\r
+                       SecondChanceException);\r
+    }\r
+    else\r
+    {\r
+        /* FIXME: All we can do in this case is trace this exception */\r
+        return FALSE;\r
+    }\r
+}\r
index 332560e..979b02b 100644 (file)
@@ -697,8 +697,8 @@ KiRestoreProcessorControlState(PKPROCESSOR_STATE ProcessorState)
     //
     // Restore GDT, IDT, LDT and TSS
     //
-    Ke386SetGlobalDescriptorTable(ProcessorState->SpecialRegisters.Gdtr);
-    Ke386SetInterruptDescriptorTable(ProcessorState->SpecialRegisters.Idtr);
+    Ke386SetGlobalDescriptorTable(ProcessorState->SpecialRegisters.Gdtr.Base);
+    Ke386SetInterruptDescriptorTable(ProcessorState->SpecialRegisters.Idtr.Base);
     Ke386SetTr(ProcessorState->SpecialRegisters.Tr);
     Ke386SetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr);
 }
@@ -724,8 +724,8 @@ KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
     Ke386SetDr7(0);
 
     /* Save GDT, IDT, LDT and TSS */
-    Ke386GetGlobalDescriptorTable(ProcessorState->SpecialRegisters.Gdtr);
-    Ke386GetInterruptDescriptorTable(ProcessorState->SpecialRegisters.Idtr);
+    Ke386GetGlobalDescriptorTable(ProcessorState->SpecialRegisters.Gdtr.Base);
+    Ke386GetInterruptDescriptorTable(ProcessorState->SpecialRegisters.Idtr.Base);
     Ke386GetTr(ProcessorState->SpecialRegisters.Tr);
     Ke386GetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr);
 }
index 500a1db..90a365f 100644 (file)
@@ -800,7 +800,7 @@ KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
     /* Set the context flags */
     Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
 
-    /* Check if User Mode or if the debugger isenabled */
+    /* Check if User Mode or if the debugger is enabled */
     if ((PreviousMode == UserMode) || (KdDebuggerEnabled))
     {
         /* Add the FPU Flag */
@@ -846,9 +846,6 @@ KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
                 goto Handled;
             }
 
-            /* HACK: GDB Entry */
-            if (KdpCallGdb(TrapFrame, ExceptionRecord, &Context)) goto Handled;
-
             /* If the Debugger couldn't handle it, dispatch the exception */
             if (RtlDispatchException(ExceptionRecord, &Context)) goto Handled;
         }
@@ -894,9 +891,6 @@ KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
                 goto Handled;
             }
 
-            /* HACK: GDB Entry */
-            if (KdpCallGdb(TrapFrame, ExceptionRecord, &Context)) goto Handled;
-
             /* Forward exception to user mode debugger */
             if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) goto Exit;
 
@@ -1045,4 +1039,3 @@ KeRaiseUserException(IN NTSTATUS ExceptionCode)
     /* Return the old EIP */
     return (NTSTATUS)OldEip;
 }
-
index abb36b7..7392de6 100644 (file)
@@ -228,22 +228,6 @@ CopyParams:
     /* Copy the parameters */
     rep movsd
 
-#ifdef DBG
-    /*
-     * The following lines are for the benefit of GDB. It will see the return
-     * address of the "call ebx" below, find the last label before it and
-     * thinks that that's the start of the function. It will then check to see
-     * if it starts with a standard function prolog (push ebp, mov ebp,esp1).
-     * When that standard function prolog is not found, it will stop the
-     * stack backtrace. Since we do want to backtrace into usermode, let's
-     * make GDB happy and create a standard prolog.
-     */
-KiSystemService:
-    push ebp
-    mov ebp,esp
-    pop ebp
-#endif
-
     /* Do the System Call */
     call ebx
 
@@ -482,7 +466,7 @@ _KiDebugService:
     TRAP_PROLOG kids
 
     /* Increase EIP so we skip the INT3 */
-    //inc dword ptr [ebp+KTRAP_FRAME_EIP]
+    inc dword ptr [ebp+KTRAP_FRAME_EIP]
 
     /* Call debug service dispatcher */
     mov eax, [ebp+KTRAP_FRAME_EAX]
@@ -821,7 +805,11 @@ _KiTrap3:
     /* Enter trap */
     TRAP_PROLOG kit3
 
+    /* Set status code */
+    mov eax, 0 //STATUS_SUCCESS
+
     /* Check for V86 */
+PrepareInt3:
     test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
     jnz V86Int3
 
index 1228a02..7b1d51b 100644 (file)
@@ -432,9 +432,9 @@ MmInsertRmap(PFN_TYPE Page, PEPROCESS Process,
       {
           DbgPrint("MmInsertRmap tries to add a second rmap entry for address %p\n    current caller ", 
                    current_entry->Address);
-          KeRosPrintAddress(new_entry->Caller);
+          DbgPrint("%p", new_entry->Caller);
           DbgPrint("\n    previous caller ");
-          KeRosPrintAddress(current_entry->Caller);
+          DbgPrint("%p", current_entry->Caller);
           DbgPrint("\n");
           KeBugCheck(0);
       }
index d67d4a4..d8d599b 100644 (file)
@@ -1752,9 +1752,6 @@ LoaderScan:
     if (ModuleObject) *ModuleObject = LdrEntry;\r
     if (ImageBaseAddress) *ImageBaseAddress = LdrEntry->DllBase;\r
 \r
-    /* Hook for KDB on loading a driver. */\r
-    KDB_LOADDRIVER_HOOK(FileName, LdrEntry);\r
-\r
 Quickie:\r
     /* If we have a file handle, close it */\r
     if (FileHandle) ZwClose(FileHandle);\r
index d5e05d0..c8e9957 100644 (file)
@@ -287,9 +287,6 @@ PspDeleteProcess(IN PVOID ObjectBody)
         KeUnstackDetachProcess(&ApcState);
     }
 
-    /* KDB hook */
-    KDB_DELETEPROCESS_HOOK(Process);
-
     /* Check if we have an address space, and clean it */
     if (Process->HasAddressSpace)
     {