(BOOL)NtUserCallHwndParam(hWnd, dwContextHelpId, HWNDPARAM_ROUTINE_SETWNDCONTEXTHLPID)
#define NtUserSetCaretPos(X, Y) \
- (BOOL)NtUserCallTwoParam((DWORD)X, (DWORD)Y, TWOPARAM_ROUTINE_SETCARETPOS)
+ (BOOL)NtUserCallTwoParam((DWORD_PTR)X, (DWORD_PTR)Y, TWOPARAM_ROUTINE_SETCARETPOS)
#define NtUserSetGUIThreadHandle(field, hwnd) \
- (BOOL)NtUserCallTwoParam((DWORD)field, (DWORD)hwnd, TWOPARAM_ROUTINE_SETGUITHRDHANDLE)
+ (BOOL)NtUserCallTwoParam((DWORD_PTR)field, (DWORD_PTR)hwnd, TWOPARAM_ROUTINE_SETGUITHRDHANDLE)
- #define NtUserSetMenuItemRect(menu, mir) \
- (BOOL)NtUserCallTwoParam((DWORD_PTR)menu, (DWORD_PTR)mir, TWOPARAM_ROUTINE_SETMENUITEMRECT)
-
#define NtUserSetMenuBarHeight(menu, height) \
- (BOOL)NtUserCallTwoParam((DWORD)menu, (DWORD)height, TWOPARAM_ROUTINE_SETMENUBARHEIGHT)
+ (BOOL)NtUserCallTwoParam((DWORD_PTR)menu, (DWORD_PTR)height, TWOPARAM_ROUTINE_SETMENUBARHEIGHT)
#define NtUserRegisterLogonProcess(hproc, x) \
- (BOOL)NtUserCallTwoParam((DWORD)hproc, (DWORD)x, TWOPARAM_ROUTINE_REGISTERLOGONPROC)
+ (BOOL)NtUserCallTwoParam((DWORD_PTR)hproc, (DWORD_PTR)x, TWOPARAM_ROUTINE_REGISTERLOGONPROC)
#define NtUserGetSysColorBrushes(HBrushes, count) \
- (BOOL)NtUserCallTwoParam((DWORD)(HBrushes), (DWORD)(count), TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES)
+ (BOOL)NtUserCallTwoParam((DWORD_PTR)(HBrushes), (DWORD_PTR)(count), TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES)
#define NtUserGetSysColors(ColorRefs, count) \
- (BOOL)NtUserCallTwoParam((DWORD)(ColorRefs), (DWORD)(count), TWOPARAM_ROUTINE_GETSYSCOLORS)
+ (BOOL)NtUserCallTwoParam((DWORD_PTR)(ColorRefs), (DWORD_PTR)(count), TWOPARAM_ROUTINE_GETSYSCOLORS)
#define NtUserSetCaretBlinkTime(uMSeconds) \
- (BOOL)NtUserCallOneParam((DWORD)uMSeconds, ONEPARAM_ROUTINE_SETCARETBLINKTIME)
+ (BOOL)NtUserCallOneParam((DWORD_PTR)uMSeconds, ONEPARAM_ROUTINE_SETCARETBLINKTIME)
/*
#define NtUserEnumClipboardFormats(format) \
*/
#define NtUserWindowFromDC(hDC) \
- (HWND)NtUserCallOneParam((DWORD)hDC, ONEPARAM_ROUTINE_WINDOWFROMDC)
+ (HWND)NtUserCallOneParam((DWORD_PTR)hDC, ONEPARAM_ROUTINE_WINDOWFROMDC)
#define NtUserSwitchCaretShowing(CaretInfo) \
- (BOOL)NtUserCallOneParam((DWORD)CaretInfo, ONEPARAM_ROUTINE_SWITCHCARETSHOWING)
+ (BOOL)NtUserCallOneParam((DWORD_PTR)CaretInfo, ONEPARAM_ROUTINE_SWITCHCARETSHOWING)
#define NtUserSwapMouseButton(fSwap) \
- (BOOL)NtUserCallOneParam((DWORD)fSwap, ONEPARAM_ROUTINE_SWAPMOUSEBUTTON)
+ (BOOL)NtUserCallOneParam((DWORD_PTR)fSwap, ONEPARAM_ROUTINE_SWAPMOUSEBUTTON)
- #define NtUserGetMenu(hWnd) \
- (HMENU)NtUserCallOneParam((DWORD_PTR)hWnd, ONEPARAM_ROUTINE_GETMENU)
-
#define NtUserSetMessageExtraInfo(lParam) \
- (LPARAM)NtUserCallOneParam((DWORD)lParam, ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO)
+ (LPARAM)NtUserCallOneParam((DWORD_PTR)lParam, ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO)
- #define NtUserIsWindowUnicode(hWnd) \
- (BOOL)NtUserCallOneParam((DWORD_PTR)hWnd, ONEPARAM_ROUTINE_ISWINDOWUNICODE)
-
#define NtUserGetWindowContextHelpId(hwnd) \
- NtUserCallOneParam((DWORD)hwnd, ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID)
+ NtUserCallOneParam((DWORD_PTR)hwnd, ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID)
- #define NtUserGetWindowInstance(hwnd) \
- (HINSTANCE)NtUserCallOneParam((DWORD_PTR)hwnd, ONEPARAM_ROUTINE_GETWINDOWINSTANCE)
-
#define NtUserGetCursorPos(lpPoint) \
- (BOOL)NtUserCallOneParam((DWORD)lpPoint, ONEPARAM_ROUTINE_GETCURSORPOSITION)
+ (BOOL)NtUserCallOneParam((DWORD_PTR)lpPoint, ONEPARAM_ROUTINE_GETCURSORPOSITION)
#define NtUserIsWindowInDestroy(hWnd) \
- (BOOL)NtUserCallOneParam((DWORD)hWnd, ONEPARAM_ROUTINE_ISWINDOWINDESTROY)
+ (BOOL)NtUserCallOneParam((DWORD_PTR)hWnd, ONEPARAM_ROUTINE_ISWINDOWINDESTROY)
#define NtUserEnableProcessWindowGhosting(bEnable) \
- NtUserCallOneParam((DWORD)bEnable, ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING)
+ NtUserCallOneParam((DWORD_PTR)bEnable, ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING)
#define NtUserShowCursor(bShow) \
- NtUserCallOneParam((DWORD)bShow, ONEPARAM_ROUTINE_SHOWCURSOR)
+ NtUserCallOneParam((DWORD_PTR)bShow, ONEPARAM_ROUTINE_SHOWCURSOR)
#define NtUserGetDesktopMapping(Ptr) \
- (PVOID)NtUserCallOneParam((DWORD)Ptr, ONEPARAM_ROUTINE_GETDESKTOPMAPPING)
+ (PVOID)NtUserCallOneParam((DWORD_PTR)Ptr, ONEPARAM_ROUTINE_GETDESKTOPMAPPING)
#define ShowCaret(hwnd) \
NtUserShowCaret(hwnd)
}
static VOID
- KdbpKdbTrapFrameFromKernelStack(PVOID KernelStack,
- PKDB_KTRAP_FRAME KdbTrapFrame)
+ KdbpKdbTrapFrameFromKernelStack(
+ PVOID KernelStack,
+ PKDB_KTRAP_FRAME KdbTrapFrame)
{
- ULONG_PTR *StackPtr;
+ ULONG_PTR *StackPtr;
- RtlZeroMemory(KdbTrapFrame, sizeof(KDB_KTRAP_FRAME));
- StackPtr = (ULONG_PTR *) KernelStack;
+ RtlZeroMemory(KdbTrapFrame, sizeof(KDB_KTRAP_FRAME));
+ StackPtr = (ULONG_PTR *) KernelStack;
+#if _M_X86_
- KdbTrapFrame->Tf.Ebp = StackPtr[3];
- KdbTrapFrame->Tf.Edi = StackPtr[4];
- KdbTrapFrame->Tf.Esi = StackPtr[5];
- KdbTrapFrame->Tf.Ebx = StackPtr[6];
- KdbTrapFrame->Tf.Eip = StackPtr[7];
- KdbTrapFrame->Tf.HardwareEsp = (ULONG) (StackPtr + 8);
- KdbTrapFrame->Tf.HardwareSegSs = KGDT_R0_DATA;
- KdbTrapFrame->Tf.SegCs = KGDT_R0_CODE;
- KdbTrapFrame->Tf.SegDs = KGDT_R0_DATA;
- KdbTrapFrame->Tf.SegEs = KGDT_R0_DATA;
- KdbTrapFrame->Tf.SegGs = KGDT_R0_DATA;
+ KdbTrapFrame->Tf.Ebp = StackPtr[3];
+ KdbTrapFrame->Tf.Edi = StackPtr[4];
+ KdbTrapFrame->Tf.Esi = StackPtr[5];
+ KdbTrapFrame->Tf.Ebx = StackPtr[6];
+ KdbTrapFrame->Tf.Eip = StackPtr[7];
+ KdbTrapFrame->Tf.HardwareEsp = (ULONG) (StackPtr + 8);
+ KdbTrapFrame->Tf.HardwareSegSs = KGDT_R0_DATA;
+ KdbTrapFrame->Tf.SegCs = KGDT_R0_CODE;
+ KdbTrapFrame->Tf.SegDs = KGDT_R0_DATA;
+ KdbTrapFrame->Tf.SegEs = KGDT_R0_DATA;
+ KdbTrapFrame->Tf.SegGs = KGDT_R0_DATA;
+#endif
- /* FIXME: what about the other registers??? */
+ /* FIXME: what about the other registers??? */
}
/*!\brief Overwrites the instruction at \a Address with \a NewInst and stores
* \retval FALSE No breakpoint was set.
*/
BOOLEAN
- KdbpStepIntoInstruction(ULONG_PTR Eip)
+ KdbpStepIntoInstruction(
+ ULONG_PTR Eip)
{
KDESCRIPTOR Idtr = {0};
- UCHAR Mem[2];
- INT IntVect;
- ULONG IntDesc[2];
- ULONG_PTR TargetEip;
+ UCHAR Mem[2];
+ INT IntVect;
+ ULONG IntDesc[2];
+ ULONG_PTR TargetEip;
- /* Read memory */
- if (!NT_SUCCESS(KdbpSafeReadMemory(Mem, (PVOID)Eip, sizeof (Mem))))
- {
- /*KdbpPrint("Couldn't access memory at 0x%p\n", Eip);*/
- return FALSE;
- }
+ /* Read memory */
+ if (!NT_SUCCESS(KdbpSafeReadMemory(Mem, (PVOID)Eip, sizeof (Mem))))
+ {
+ /*KdbpPrint("Couldn't access memory at 0x%p\n", Eip);*/
+ return FALSE;
+ }
- /* Check for INT instruction */
- /* FIXME: Check for iret */
- if (Mem[0] == 0xcc)
- IntVect = 3;
- else if (Mem[0] == 0xcd)
- IntVect = Mem[1];
- else if (Mem[0] == 0xce && KdbCurrentTrapFrame->Tf.EFlags & (1<<11)) /* 1 << 11 is the overflow flag */
- IntVect = 4;
- else
- return FALSE;
-
- if (IntVect < 32) /* We should be informed about interrupts < 32 by the kernel, no need to breakpoint them */
- {
- return FALSE;
- }
+ /* Check for INT instruction */
+ /* FIXME: Check for iret */
+ if (Mem[0] == 0xcc)
+ IntVect = 3;
+ else if (Mem[0] == 0xcd)
+ IntVect = Mem[1];
+ else if (Mem[0] == 0xce && KdbCurrentTrapFrame->Tf.EFlags & (1<<11)) /* 1 << 11 is the overflow flag */
+ IntVect = 4;
+ else
+ return FALSE;
+
+ if (IntVect < 32) /* We should be informed about interrupts < 32 by the kernel, no need to breakpoint them */
+ {
+ return FALSE;
+ }
- /* Read the interrupt descriptor table register */
- Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&Idtr.Limit);
- if (IntVect >= (Idtr.Limit + 1) / 8)
- {
- /*KdbpPrint("IDT does not contain interrupt vector %d\n.", IntVect);*/
- return TRUE;
- }
+ /* Read the interrupt descriptor table register */
+ __sidt(&Idtr.Limit);
+ if (IntVect >= (Idtr.Limit + 1) / 8)
+ {
+ /*KdbpPrint("IDT does not contain interrupt vector %d\n.", IntVect);*/
+ return TRUE;
+ }
- /* Get the interrupt descriptor */
- if (!NT_SUCCESS(KdbpSafeReadMemory(IntDesc, (PVOID)(ULONG_PTR)(Idtr.Base + (IntVect * 8)), sizeof (IntDesc))))
- {
- /*KdbpPrint("Couldn't access memory at 0x%p\n", (ULONG_PTR)Idtr.Base + (IntVect * 8));*/
- return FALSE;
- }
+ /* Get the interrupt descriptor */
- if (!NT_SUCCESS(KdbpSafeReadMemory(IntDesc, (PVOID)(Idtr.Base + (IntVect * 8)), sizeof (IntDesc))))
++ if (!NT_SUCCESS(KdbpSafeReadMemory(IntDesc, (PVOID)(ULONG_PTR)(Idtr.Base + (IntVect * 8)), sizeof (IntDesc))))
+ {
+ /*KdbpPrint("Couldn't access memory at 0x%p\n", (ULONG_PTR)Idtr.Base + (IntVect * 8));*/
+ return FALSE;
+ }
- /* Check descriptor and get target eip (16 bit interrupt/trap gates not supported) */
- if ((IntDesc[1] & (1 << 15)) == 0) /* not present */
- {
- return FALSE;
- }
- if ((IntDesc[1] & 0x1f00) == 0x0500) /* Task gate */
- {
- /* FIXME: Task gates not supported */
- return FALSE;
- }
- else if (((IntDesc[1] & 0x1fe0) == 0x0e00) || /* 32 bit Interrupt gate */
- ((IntDesc[1] & 0x1fe0) == 0x0f00)) /* 32 bit Trap gate */
- {
- /* FIXME: Should the segment selector of the interrupt gate be checked? */
- TargetEip = (IntDesc[1] & 0xffff0000) | (IntDesc[0] & 0x0000ffff);
- }
- else
- {
- return FALSE;
- }
+ /* Check descriptor and get target eip (16 bit interrupt/trap gates not supported) */
+ if ((IntDesc[1] & (1 << 15)) == 0) /* not present */
+ {
+ return FALSE;
+ }
+ if ((IntDesc[1] & 0x1f00) == 0x0500) /* Task gate */
+ {
+ /* FIXME: Task gates not supported */
+ return FALSE;
+ }
+ else if (((IntDesc[1] & 0x1fe0) == 0x0e00) || /* 32 bit Interrupt gate */
+ ((IntDesc[1] & 0x1fe0) == 0x0f00)) /* 32 bit Trap gate */
+ {
+ /* FIXME: Should the segment selector of the interrupt gate be checked? */
+ TargetEip = (IntDesc[1] & 0xffff0000) | (IntDesc[0] & 0x0000ffff);
+ }
+ else
+ {
+ return FALSE;
+ }
- /* Insert breakpoint */
- if (!NT_SUCCESS(KdbpInsertBreakPoint(TargetEip, KdbBreakPointTemporary, 0, 0, NULL, FALSE, NULL)))
- return FALSE;
+ /* Insert breakpoint */
+ if (!NT_SUCCESS(KdbpInsertBreakPoint(TargetEip, KdbBreakPointTemporary, 0, 0, NULL, FALSE, NULL)))
+ return FALSE;
- return TRUE;
+ return TRUE;
}
/*!\brief Gets the number of the next breakpoint >= Start.
*/
BOOLEAN
KdbpAttachToThread(
- PVOID ThreadId)
+ PVOID ThreadId)
{
- PETHREAD Thread = NULL;
- PEPROCESS Process;
+ PETHREAD Thread = NULL;
+ PEPROCESS Process;
- /* Get a pointer to the thread */
- if (!NT_SUCCESS(PsLookupThreadByThreadId(ThreadId, &Thread)))
- {
- KdbpPrint("Invalid thread id: 0x%08x\n", (ULONG_PTR)ThreadId);
- return FALSE;
- }
- Process = Thread->ThreadsProcess;
+ /* Get a pointer to the thread */
+ if (!NT_SUCCESS(PsLookupThreadByThreadId(ThreadId, &Thread)))
+ {
- KdbpPrint("Invalid thread id: 0x%08x\n", (ULONG)ThreadId);
++ KdbpPrint("Invalid thread id: 0x%08x\n", (ULONG_PTR)ThreadId);
+ return FALSE;
+ }
+ Process = Thread->ThreadsProcess;
- if (KeIsExecutingDpc() && Process != KdbCurrentProcess)
- {
- KdbpPrint("Cannot attach to thread within another process while executing a DPC.\n");
- ObDereferenceObject(Thread);
- return FALSE;
- }
+ if (KeIsExecutingDpc() && Process != KdbCurrentProcess)
+ {
+ KdbpPrint("Cannot attach to thread within another process while executing a DPC.\n");
+ ObDereferenceObject(Thread);
+ return FALSE;
+ }
- /* Save the current thread's context (if we previously attached to a thread) */
- if (KdbCurrentThread != KdbOriginalThread)
- {
- ASSERT(KdbCurrentTrapFrame == &KdbThreadTrapFrame);
- /* Actually, we can't save the context, there's no guarantee that there
- * was a trap frame */
- }
- else
- {
- ASSERT(KdbCurrentTrapFrame == &KdbTrapFrame);
- }
+ /* Save the current thread's context (if we previously attached to a thread) */
+ if (KdbCurrentThread != KdbOriginalThread)
+ {
+ ASSERT(KdbCurrentTrapFrame == &KdbThreadTrapFrame);
+ /* Actually, we can't save the context, there's no guarantee that there was a trap frame */
+ }
+ else
+ {
+ ASSERT(KdbCurrentTrapFrame == &KdbTrapFrame);
+ }
- /* Switch to the thread's context */
- if (Thread != KdbOriginalThread)
- {
- /* The thread we're attaching to isn't the thread on which we entered
- * kdb and so the thread we're attaching to is not running. There
- * is no guarantee that it actually has a trap frame. So we have to
- * peek directly at the registers which were saved on the stack when the
- * thread was preempted in the scheduler */
- KdbpKdbTrapFrameFromKernelStack(Thread->Tcb.KernelStack,
- &KdbThreadTrapFrame);
- KdbCurrentTrapFrame = &KdbThreadTrapFrame;
- }
- else /* Switching back to original thread */
- {
- KdbCurrentTrapFrame = &KdbTrapFrame;
- }
- KdbCurrentThread = Thread;
+ /* Switch to the thread's context */
+ if (Thread != KdbOriginalThread)
+ {
+ /* The thread we're attaching to isn't the thread on which we entered
+ * kdb and so the thread we're attaching to is not running. There
+ * is no guarantee that it actually has a trap frame. So we have to
+ * peek directly at the registers which were saved on the stack when the
+ * thread was preempted in the scheduler */
+ KdbpKdbTrapFrameFromKernelStack(Thread->Tcb.KernelStack,
+ &KdbThreadTrapFrame);
+ KdbCurrentTrapFrame = &KdbThreadTrapFrame;
+ }
+ else /* Switching back to original thread */
+ {
+ KdbCurrentTrapFrame = &KdbTrapFrame;
+ }
+ KdbCurrentThread = Thread;
- /* Attach to the thread's process */
- ASSERT(KdbCurrentProcess == PsGetCurrentProcess());
- if (KdbCurrentProcess != Process)
- {
- if (KdbCurrentProcess != KdbOriginalProcess) /* detach from previously attached process */
- {
- KeUnstackDetachProcess(&KdbApcState);
- }
- if (KdbOriginalProcess != Process)
- {
- KeStackAttachProcess(&Process->Pcb, &KdbApcState);
- }
- KdbCurrentProcess = Process;
- }
+ /* Attach to the thread's process */
+ ASSERT(KdbCurrentProcess == PsGetCurrentProcess());
+ if (KdbCurrentProcess != Process)
+ {
+ if (KdbCurrentProcess != KdbOriginalProcess) /* detach from previously attached process */
+ {
+ KeUnstackDetachProcess(&KdbApcState);
+ }
+
+ if (KdbOriginalProcess != Process)
+ {
+ KeStackAttachProcess(&Process->Pcb, &KdbApcState);
+ }
- ObDereferenceObject(Thread);
- return TRUE;
+ KdbCurrentProcess = Process;
+ }
+
+ ObDereferenceObject(Thread);
+ return TRUE;
}
/*!\brief Switches to another process/thread context
*/
BOOLEAN
KdbpAttachToProcess(
- PVOID ProcessId)
+ PVOID ProcessId)
{
- PEPROCESS Process = NULL;
- PETHREAD Thread;
- PLIST_ENTRY Entry;
+ PEPROCESS Process = NULL;
+ PETHREAD Thread;
+ PLIST_ENTRY Entry;
- /* Get a pointer to the process */
- if (!NT_SUCCESS(PsLookupProcessByProcessId(ProcessId, &Process)))
- {
- KdbpPrint("Invalid process id: 0x%08x\n", (ULONG_PTR)ProcessId);
- return FALSE;
- }
+ /* Get a pointer to the process */
+ if (!NT_SUCCESS(PsLookupProcessByProcessId(ProcessId, &Process)))
+ {
- KdbpPrint("Invalid process id: 0x%08x\n", (ULONG)ProcessId);
++ KdbpPrint("Invalid process id: 0x%08x\n", (ULONG_PTR)ProcessId);
+ return FALSE;
+ }
- Entry = Process->ThreadListHead.Flink;
- ObDereferenceObject(Process);
- if (Entry == &KdbCurrentProcess->ThreadListHead)
- {
- KdbpPrint("No threads in process 0x%p, cannot attach to process!\n", ProcessId);
- return FALSE;
- }
+ Entry = Process->ThreadListHead.Flink;
+ ObDereferenceObject(Process);
+ if (Entry == &KdbCurrentProcess->ThreadListHead)
+ {
- KdbpPrint("No threads in process 0x%08x, cannot attach to process!\n", (ULONG)ProcessId);
++ KdbpPrint("No threads in process 0x%p, cannot attach to process!\n", ProcessId);
+ return FALSE;
+ }
- Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
+ Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
- return KdbpAttachToThread(Thread->Cid.UniqueThread);
+ return KdbpAttachToThread(Thread->Cid.UniqueThread);
}
/*!\brief Calls the main loop ...
static VOID
KdbpInternalEnter()
{
- PETHREAD Thread;
- PVOID SavedInitialStack, SavedStackBase, SavedKernelStack;
- ULONG SavedStackLimit;
+ PETHREAD Thread;
+ PVOID SavedInitialStack, SavedStackBase, SavedKernelStack;
+ ULONG SavedStackLimit;
- KbdDisableMouse();
- if (KdpDebugMode.Screen)
- {
- InbvAcquireDisplayOwnership();
- }
+ KbdDisableMouse();
+ if (KdpDebugMode.Screen)
+ {
+ InbvAcquireDisplayOwnership();
+ }
- /* Call the interface's main loop on a different stack */
- Thread = PsGetCurrentThread();
- SavedInitialStack = Thread->Tcb.InitialStack;
- SavedStackBase = Thread->Tcb.StackBase;
- SavedStackLimit = Thread->Tcb.StackLimit;
- SavedKernelStack = Thread->Tcb.KernelStack;
- Thread->Tcb.InitialStack = Thread->Tcb.StackBase = (char*)KdbStack + KDB_STACK_SIZE;
- Thread->Tcb.StackLimit = (ULONG_PTR)KdbStack;
- Thread->Tcb.KernelStack = (char*)KdbStack + KDB_STACK_SIZE;
-
- /*KdbpPrint("Switching to KDB stack 0x%08x-0x%08x (Current Stack is 0x%08x)\n", Thread->Tcb.StackLimit, Thread->Tcb.StackBase, Esp);*/
-
- KdbpStackSwitchAndCall(KdbStack + KDB_STACK_SIZE - sizeof(ULONG), KdbpCallMainLoop);
-
- Thread->Tcb.InitialStack = SavedInitialStack;
- Thread->Tcb.StackBase = SavedStackBase;
- Thread->Tcb.StackLimit = SavedStackLimit;
- Thread->Tcb.KernelStack = SavedKernelStack;
- KbdEnableMouse();
+ /* Call the interface's main loop on a different stack */
+ Thread = PsGetCurrentThread();
+ SavedInitialStack = Thread->Tcb.InitialStack;
+ SavedStackBase = Thread->Tcb.StackBase;
+ SavedStackLimit = Thread->Tcb.StackLimit;
+ SavedKernelStack = Thread->Tcb.KernelStack;
+ Thread->Tcb.InitialStack = Thread->Tcb.StackBase = (char*)KdbStack + KDB_STACK_SIZE;
- Thread->Tcb.StackLimit = (ULONG)KdbStack;
++ Thread->Tcb.StackLimit = (ULONG_PTR)KdbStack;
+ Thread->Tcb.KernelStack = (char*)KdbStack + KDB_STACK_SIZE;
+
+ /*KdbpPrint("Switching to KDB stack 0x%08x-0x%08x (Current Stack is 0x%08x)\n", Thread->Tcb.StackLimit, Thread->Tcb.StackBase, Esp);*/
+
+ KdbpStackSwitchAndCall(KdbStack + KDB_STACK_SIZE - sizeof(ULONG), KdbpCallMainLoop);
+
+ Thread->Tcb.InitialStack = SavedInitialStack;
+ Thread->Tcb.StackBase = SavedStackBase;
+ Thread->Tcb.StackLimit = SavedStackLimit;
+ Thread->Tcb.KernelStack = SavedKernelStack;
+ KbdEnableMouse();
}
static ULONG