📄 shell.c
字号:
/*++
Copyright (c) 1998-2001 Klaus P. Gerlicher
Module Name:
shell.c
Abstract:
user interface for debugger
Environment:
Kernel mode only
Author:
Klaus P. Gerlicher
Revision History:
16-Jul-1998: created
22-Sep-1998: rewrite of keyboard hooking through patching the original keyboard driver
29-Sep-1998: started documentation on project
15-Nov-2000: general cleanup of source files
Copyright notice:
This file may be distributed under the terms of the GNU Public License.
--*/
////////////////////////////////////////////////////
// INCLUDES
////
#include "remods.h"
#include "precomp.h"
////////////////////////////////////////////////////
// DEFINES
////
#define LINES_IN_COMMAND_BUFFER (64)
////////////////////////////////////////////////////
// PROTOTYPES
////
////////////////////////////////////////////////////
// GLOBALS
////
ULONG bPreviousCommandWasGo = FALSE;
// flags to set when we need to pass things to the old INT handlers
ULONG dwCallOldInt1Handler = 0;
ULONG dwCallOldInt3Handler = 0;
ULONG dwCallOldIntEHandler = 0;
ULONG dwCallOldGPFaultHandler = 0;
ULONG g_ulLineNumberStart=0;
ULONG ulWindowOffset = 0;
BOOLEAN bStepThroughSource=FALSE;
BOOLEAN bStepInto = FALSE;
// key handling
UCHAR ucConverted; // key converted from scancode to ANSI
volatile BOOLEAN bControl=FALSE; // TRUE when CTRL key was pressed
volatile BOOLEAN bShift=FALSE; // TRUE when SHIFT key was pressed
volatile BOOLEAN bAlt=FALSE; // TRUE when ALT key was pressed
volatile ULONG OldInt31Handler; // address of old keyboard ISR
volatile ULONG OldGlobalInt31Handler; // address of old global keyboard ISR
volatile BOOLEAN bEnterNow=FALSE; // TRUE if already stopped
volatile BOOLEAN bNotifyToExit=FALSE; // TRUE when debugger should leave
volatile BOOLEAN bSkipMainLoop=FALSE; // TRUE when debugger should skip main loop
volatile UCHAR ucKeyPressedWhileIdle=0; // key pressed when system was stopped
volatile BOOLEAN bInDebuggerShell=FALSE; // TRUE while in DebuggerShell()
BOOLEAN bIrqStateAtBreak;
ULONG ulRealStackPtr;
static ULONG PCR_SEL = PCR_SELECTOR;
static ULONG OLD_PCR;
char tempShell[256]; // temporary string container
// old address of display memory
USHORT OldSelector=0;
ULONG OldOffset=0;
ULONG ulLastLineDisplayedOffset = 0;
// functions of function keys
char *szFunctionKeys[10]={
"mod", // F1
"proc", // F2
"src", // F3
"code", // F4
"x", // F5
"vma", // F6
"", // F7
"t", // F8
"", // F9
"p" // F10
};
// new stack for "deep parsing"
ULONG aulNewStack[0x20000];
ULONG ulOldStack;
// registers save area (context)
ULONG CurrentEIP,CurrentEFL;
ULONG CurrentEAX,CurrentEBX,CurrentECX,CurrentEDX;
ULONG CurrentESP,CurrentEBP,CurrentESI,CurrentEDI;
USHORT CurrentCS,CurrentDS=0,CurrentES,CurrentFS,CurrentGS,CurrentSS;
ULONG CurrentDR0,CurrentDR1,CurrentDR2,CurrentDR3,CurrentDR6,CurrentDR7;
ULONG CurrentCR0,CurrentCR2,CurrentCR3;
// previous context
ULONG OldEIP=0,OldEFL;
ULONG OldEAX,OldEBX,OldECX,OldEDX;
ULONG OldESP,OldEBP,OldESI,OldEDI;
USHORT OldCS=0,OldDS,OldES,OldFS,OldGS,OldSS;
ULONG CurrentProcess;
UCHAR ucCommandBuffer[256];
USHORT usCurrentPosInInputBuffer=0;
volatile BOOLEAN bSingleStep=FALSE;
// the last command lines
char aszCommandLines[LINES_IN_COMMAND_BUFFER][sizeof(ucCommandBuffer)+2];
ULONG ulCommandInPos=0,ulCommandLastPos=0;
ULONG ulCommandCurrentPos=0;
extern ULONG KeyboardIRQL;
//*************************************************************************
// GetLinesInCommandHistory()
//
//*************************************************************************
ULONG GetLinesInCommandHistory(void)
{
ULONG ulResult = (ulCommandInPos-ulCommandLastPos)%LINES_IN_COMMAND_BUFFER;
ENTER_FUNC();
DPRINT((0,"GetLinesInCommandHistory() returns %u (ulIn %u ulLast %u)\n",ulResult,ulCommandInPos,ulCommandLastPos));
LEAVE_FUNC();
return ulResult;
}
//*************************************************************************
// AddToCommandLineHistory()
//
//*************************************************************************
void AddToCommandLineHistory(LPSTR s)
{
ULONG i;
ENTER_FUNC();
DPRINT((0,"AddToCommandLineHistory(%s)\n",s));
if(PICE_strlen(s))
{
for(i=0;i<LINES_IN_COMMAND_BUFFER;i++)
{
if(PICE_strcmpi(&aszCommandLines[i][1],s) == 0)
{
DPRINT((0,"AddToCommandLineHistory(): command line already exists\n"));
LEAVE_FUNC();
return;
}
}
aszCommandLines[ulCommandInPos][0]=':';
PICE_strcpy(&aszCommandLines[ulCommandInPos][1],s);
ulCommandCurrentPos = ulCommandInPos = (ulCommandInPos +1)%LINES_IN_COMMAND_BUFFER;
if(ulCommandInPos == ulCommandLastPos)
{
ulCommandLastPos = (ulCommandLastPos+1)%LINES_IN_COMMAND_BUFFER;
}
}
LEAVE_FUNC();
}
//*************************************************************************
// GetFromCommandLineHistory()
//
//*************************************************************************
LPSTR GetFromCommandLineHistory(ULONG ulCurrentCommandPos)
{
LPSTR pRet;
ENTER_FUNC();
DPRINT((0,"GetFromCommandLineHistory(): current = %u\n",ulCurrentCommandPos));
// skip leading ':'
pRet = aszCommandLines[ulCurrentCommandPos] + 1;
DPRINT((0,"GetFromCommandLineHistory(%s)\n",pRet));
LEAVE_FUNC();
return pRet;
}
//*************************************************************************
// ShowStatusLine()
//
//*************************************************************************
void ShowStatusLine(void)
{
PEPROCESS pCurrentProcess = IoGetCurrentProcess();
LPSTR pProcessName;
ENTER_FUNC();
if(IsAddressValid((ULONG)pCurrentProcess))
{
SetForegroundColor(COLOR_TEXT);
SetBackgroundColor(COLOR_CAPTION);
ClrLine(wWindow[OUTPUT_WINDOW].y-1);
pProcessName = pCurrentProcess->ImageFileName;
if(IsAddressValid((ULONG)pProcessName) )
{
PICE_sprintf(tempShell,
" PROCESS(%.8X \"%s\") ",
(ULONG)pCurrentProcess,pProcessName);
}
else
{
PICE_sprintf(tempShell,
" PROCESS(%.8X) ",
(ULONG)pCurrentProcess);
}
PutChar(tempShell,1,wWindow[OUTPUT_WINDOW].y-1);
ResetColor();
}
LEAVE_FUNC();
}
//*************************************************************************
// ProcessBootParams()
//
//*************************************************************************
void ProcessBootParams(void)
{
LPSTR p1,p2;
ENTER_FUNC();
if(*szBootParams)
{
DPRINT((0,"ProcessBootParams()\n"));
p1 = szBootParams;
while(*p1)
{
p2 = ucCommandBuffer;
DPRINT((0,"ProcessBootParams(): boot params = %s\n",p1));
while(*p1 && *p1!=';')
{
*p2++ = *p1++;
}
*p2=0;
DPRINT((0,"ProcessBootParams(): cmd buf = %s\n",ucCommandBuffer));
if(*p1 != ';')
{
DPRINT((0,"ProcessBootParams(): error in cmd buf\n"));
break;
}
p1++;
DPRINT((0,"ProcessBootParams(): next cmd buf = %s\n",p1));
Parse(ucCommandBuffer,TRUE);
}
PICE_memset(ucCommandBuffer,0,sizeof(ucCommandBuffer));
*szBootParams = 0;
}
LEAVE_FUNC();
}
//*************************************************************************
// bNoCtrlKeys()
//
//*************************************************************************
BOOLEAN __inline bNoCtrlKeys(void)
{
return (!bControl && !bAlt && !bShift);
}
//*************************************************************************
// DebuggerShell()
//
// handle user interface when stopped system
//*************************************************************************
void DebuggerShell(void)
{
ARGS Args;
UCHAR speaker;
PEPROCESS pCurrentProcess;
ENTER_FUNC();
// save the graphics state
SaveGraphicsState();
// tell USER we are stopped
ShowStoppedMsg();
FlushKeyboardQueue();
CheckRingBuffer();
// kill the speakers annoying beep
speaker = inb_p((PCHAR)0x61);
speaker &= 0xFC;
outb_p(speaker,(PCHAR)0x61);
ProcessBootParams();
DPRINT((0,"DebuggerShell(): DisplayRegs()\n"));
// display register contents
DisplayRegs();
DPRINT((0,"DebuggerShell(): DisplayMemory()\n"));
// display data window
Args.Value[0]=OldSelector;
Args.Value[1]=OldOffset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -