reactos/rosapps/sysutils/utils/pice/module/parse.c

4103 lines
110 KiB
C

/*++
Copyright (c) 1998-2001 Klaus P. Gerlicher
Module Name:
parse.c
Abstract:
execution of debugger commands
Environment:
Kernel mode only
Author:
Klaus P. Gerlicher
Revision History:
19-Aug-1998: created
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"
#include "pci_ids.h"
///////////////////////////////////////////////////
// GLOBALS
ULONG ValueTrue=1,ValueFalse=0;
ULONG ulLastDisassStartAddress=0,ulLastDisassEndAddress=0,ulLastInvertedAddress=0;
USHORT gCurrentSelector=0;
ULONG gCurrentOffset=0;
LONG ulCurrentlyDisplayedLineNumber=0;
USHORT usOldDisasmSegment = 0;
ULONG ulOldDisasmOffset = 0;
static ULONG ulCountForWaitKey = 0;
extern PDEBUG_MODULE pdebug_module_head;
extern PDEBUG_MODULE pdebug_module_tail;
//extern unsigned long sys_call_table[];
BOOLEAN (*DisplayMemory)(PARGS) = DisplayMemoryDword;
char szCurrentFile[256]="";
PDEBUG_MODULE pCurrentMod=NULL;
PICE_SYMBOLFILE_HEADER* pCurrentSymbols=NULL;
// suppresses passing on of function keys while stepping code
BOOLEAN bStepping = FALSE;
BOOLEAN bInt3Here = TRUE;
BOOLEAN bInt1Here = TRUE;
KEYWORDS RegKeyWords[]={
{"eax",&CurrentEAX,sizeof(ULONG)},
{"ebx",&CurrentEBX,sizeof(ULONG)},
{"ecx",&CurrentECX,sizeof(ULONG)},
{"edx",&CurrentEDX,sizeof(ULONG)},
{"edi",&CurrentEDI,sizeof(ULONG)},
{"esi",&CurrentESI,sizeof(ULONG)},
{"ebp",&CurrentEBP,sizeof(ULONG)},
{"esp",&CurrentESP,sizeof(ULONG)},
{"eip",&CurrentEIP,sizeof(ULONG)},
{NULL,0,0}
};
KEYWORDS SelectorRegKeyWords[]={
{"cs",&CurrentCS,sizeof(USHORT)},
{"ds",&CurrentDS,sizeof(USHORT)},
{"es",&CurrentES,sizeof(USHORT)},
{"fs",&CurrentFS,sizeof(USHORT)},
{"gs",&CurrentGS,sizeof(USHORT)},
{"ss",&CurrentSS,sizeof(USHORT)},
{NULL,0,0}
};
KEYWORDS OnOffKeyWords[]={
{"on",&ValueTrue,sizeof(ULONG)},
{"off",&ValueFalse,sizeof(ULONG)},
{NULL,0,0}
};
KEYWORDS SpecialKeyWords[]={
{"process",&CurrentProcess,sizeof(ULONG)},
{NULL,0,0}
};
LPSTR LocalVarRegs[]=
{
"EAX",
"ECX",
"EDX",
"EBX",
"ESP",
"EBP",
"ESI",
"EDI",
"EIP",
"EFL",
"CS",
"SS",
"DS",
"ES",
"FS",
"GS"
};
#define COMMAND_HAS_NO_PARAMS (0)
#define COMMAND_HAS_PARAMS (1<<0)
#define COMMAND_HAS_SWITCHES (1<<1)
//
#define PARAM_CAN_BE_SYMBOLIC (1<<0)
#define PARAM_CAN_BE_SEG_OFFSET (1<<1)
#define PARAM_CAN_BE_MODULE (1<<2)
#define PARAM_CAN_BE_PRNAME (1<<3)
#define PARAM_CAN_BE_PID (1<<4)
#define PARAM_CAN_BE_SRC_FILE (1<<5)
#define PARAM_CAN_BE_NUMERIC (1<<6)
#define PARAM_CAN_BE_REG_KEYWORD (1<<7)
#define PARAM_CAN_BE_ONOFF_KEYWORD (1<<8)
#define PARAM_CAN_BE_SPECIAL_KEYWORD (1<<9)
#define PARAM_CAN_BE_ASTERISK (1<<10)
#define PARAM_CAN_BE_ONOFF (1<<11)
#define PARAM_CAN_BE_VIRTUAL_SYMBOLIC (1<<12)
#define PARAM_CAN_BE_SRCLINE (1<<13)
#define PARAM_CAN_BE_PARTIAL_SYM_NAME (1<<14)
#define PARAM_CAN_BE_ANY_STRING (1<<15)
#define PARAM_CAN_BE_DECIMAL (1<<16)
#define PARAM_CAN_BE_SIZE_DESC (1<<17)
#define PARAM_CAN_BE_LETTER (1<<18)
//
#define COMMAND_GROUP_HELP (0)
#define COMMAND_GROUP_FLOW (1)
#define COMMAND_GROUP_STRUCT (2)
#define COMMAND_GROUP_OS (3)
#define COMMAND_GROUP_MEM (4)
#define COMMAND_GROUP_BREAKPOINT (5)
#define COMMAND_GROUP_WINDOW (6)
#define COMMAND_GROUP_DEBUG (7)
#define COMMAND_GROUP_INFO (8)
#define COMMAND_GROUP_STATE (9)
#define COMMAND_GROUP_HELP_ONLY (10)
#define COMMAND_GROUP_LAST (11)
LPSTR CommandGroups[]=
{
"HELP",
"FLOW CONTROL",
"STRUCTURES",
"OS SPECIFIC",
"MEMORY",
"BREAKPOINTS",
"WINDOW",
"DEBUGGING",
"INFORMATION",
"STATE",
"EDITOR",
NULL
};
// table of command handlers
CMDTABLE CmdTable[]={
{"gdt",ShowGdt,"display current global descriptor table" ,0,{0,0,0,0,0},"",COMMAND_GROUP_STRUCT},
{"idt",ShowIdt,"display current interrupt descriptor table" ,0,{0,0,0,0,0},"",COMMAND_GROUP_STRUCT},
{"x",LeaveIce,"return to Reactos" ,0,{0,0,0,0,0},"",COMMAND_GROUP_FLOW},
{"t",SingleStep,"single step one instruction" ,0,{0,0,0,0,0},"",COMMAND_GROUP_FLOW},
{"vma",ShowVirtualMemory,"displays VMAs" ,0,{0,0,0,0,0},"",COMMAND_GROUP_OS},
{"h",ShowHelp,"list help on commands" ,0,{0,0,0,0,0},"",COMMAND_GROUP_HELP},
{"page",ShowPageDirs,"dump page directories" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_NUMERIC|PARAM_CAN_BE_REG_KEYWORD,0,0,0,0},"",COMMAND_GROUP_STRUCT},
{"proc",ShowProcesses,"list all processes" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_PRNAME|PARAM_CAN_BE_PID,0,0,0,0},"",COMMAND_GROUP_OS},
{"dd",DisplayMemoryDword,"display dword memory" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_NUMERIC|PARAM_CAN_BE_SYMBOLIC|PARAM_CAN_BE_REG_KEYWORD,0,0,0,0},"",COMMAND_GROUP_MEM},
{"db",DisplayMemoryByte,"display byte memory " ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_NUMERIC|PARAM_CAN_BE_SYMBOLIC|PARAM_CAN_BE_REG_KEYWORD,0,0,0,0},"",COMMAND_GROUP_MEM},
{"dpd",DisplayPhysMemDword,"display dword physical memory" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_NUMERIC,0,0,0,0},"",COMMAND_GROUP_MEM},
{"u",Unassemble,"disassemble at address" ,COMMAND_HAS_PARAMS|COMMAND_HAS_SWITCHES,{PARAM_CAN_BE_NUMERIC|PARAM_CAN_BE_SYMBOLIC|PARAM_CAN_BE_REG_KEYWORD|PARAM_CAN_BE_SRCLINE,0,0,0,0},"f",COMMAND_GROUP_MEM},
{"mod",ShowModules,"displays all modules" ,0,{0,0,0,0,0},"",COMMAND_GROUP_OS},
{"bpx",SetBreakpoint,"set code breakpoint" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_NUMERIC|PARAM_CAN_BE_VIRTUAL_SYMBOLIC|PARAM_CAN_BE_SYMBOLIC|PARAM_CAN_BE_SRCLINE|PARAM_CAN_BE_REG_KEYWORD,0,0,0,0},"",COMMAND_GROUP_BREAKPOINT},
{"bl",ListBreakpoints,"list breakpoints" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_NUMERIC,0,0,0,0},"",COMMAND_GROUP_BREAKPOINT},
{"bc",ClearBreakpoints,"clear breakpoints" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_NUMERIC|PARAM_CAN_BE_ASTERISK,0,0,0,0},"",COMMAND_GROUP_BREAKPOINT},
{"ver",Ver,"display pICE version and state information" ,0,{0,0,0,0,0},"",COMMAND_GROUP_INFO},
{"hboot",Hboot,"hard boot the system" ,0,{0,0,0,0,0},"",COMMAND_GROUP_FLOW},
{"code",SetCodeDisplay,"toggle code display" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_ONOFF,0,0,0,0},"",COMMAND_GROUP_STATE},
{"cpu",ShowCPU,"display CPU special registers" ,0,{0,0,0,0,0},"",COMMAND_GROUP_STRUCT},
{"stack",WalkStack,"display call stack" ,0,{0,0,0,0,0},"",COMMAND_GROUP_STRUCT},
{"peek",PeekMemory,"peek at physical memory" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_SIZE_DESC,PARAM_CAN_BE_NUMERIC,0,0,0},"",COMMAND_GROUP_MEM},
{"poke",PokeMemory,"poke to physical memory" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_SIZE_DESC,PARAM_CAN_BE_NUMERIC,PARAM_CAN_BE_NUMERIC,0,0},"",COMMAND_GROUP_MEM},
{".",UnassembleAtCurrentEip,"unassemble at current instruction" ,0,{0,0,0,0,0},"",COMMAND_GROUP_MEM},
{"p",StepOver,"single step over call" ,0,{0,0,0,0,0},"",COMMAND_GROUP_FLOW},
{"i",StepInto,"single step into call" ,0,{0,0,0,0,0},"",COMMAND_GROUP_FLOW},
{"locals",ShowLocals,"display local symbols" ,0,{0,0,0,0,0},"",COMMAND_GROUP_MEM},
{"table",SwitchTables,"display loaded symbol tables" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_MODULE,0,0,0,0},"",COMMAND_GROUP_DEBUG},
{"file",SwitchFiles,"display source files in symbol table" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_SRC_FILE,0,0,0,0},"",COMMAND_GROUP_DEBUG},
{"sym",ShowSymbols,"list known symbol information" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_PARTIAL_SYM_NAME,0,0,0,0},"",COMMAND_GROUP_DEBUG},
{"?",EvaluateExpression,"evaluate an expression" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_ANY_STRING,0,0,0,0},"",COMMAND_GROUP_DEBUG},
{"src",SetSrcDisplay,"sets disassembly mode" ,0,{0,0,0,0,0},"",COMMAND_GROUP_DEBUG},
{"wc",SizeCodeWindow,"change size of code window" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_DECIMAL,0,0,0,0},"",COMMAND_GROUP_WINDOW},
{"wd",SizeDataWindow,"change size of data window" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_DECIMAL,0,0,0,0},"",COMMAND_GROUP_WINDOW},
{"r",SetGetRegisters,"sets or displays registers" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_REG_KEYWORD,PARAM_CAN_BE_NUMERIC,0,0,0},"",COMMAND_GROUP_STRUCT},
{"cls",ClearScreen,"clear output window" ,0,{0,0,0,0,0},"",COMMAND_GROUP_WINDOW},
{"phys",ShowMappings,"show all mappings for linear address" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_NUMERIC,0,0,0,0},"",COMMAND_GROUP_MEM},
{"timers",ShowTimers,"show all active timers" ,0,{0,0,0,0,0},"",COMMAND_GROUP_OS},
{"pci",ShowPCI,"show PCI devices" ,COMMAND_HAS_PARAMS|COMMAND_HAS_SWITCHES,{PARAM_CAN_BE_DECIMAL,PARAM_CAN_BE_DECIMAL,0,0,0},"a",COMMAND_GROUP_INFO},
{"next",NextInstr,"advance EIP to next instruction" ,0,{0,0,0,0,0},""},
{"i3here",I3here,"catch INT 3s" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_ONOFF,0,0,0,0},"",COMMAND_GROUP_FLOW},
{"layout",SetKeyboardLayout,"sets keyboard layout" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_ANY_STRING,0,0,0,0},"",COMMAND_GROUP_FLOW},
{"syscall",ShowSysCallTable,"displays syscall (table)" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_DECIMAL,0,0,0,0},"",COMMAND_GROUP_FLOW},
{"altkey",SetAltKey,"set alternate break key" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_LETTER,0,0,0,0},"",COMMAND_GROUP_FLOW},
{"addr",ShowContext,"show/set address contexts" ,COMMAND_HAS_PARAMS,{PARAM_CAN_BE_PRNAME,0,0,0,0},"",COMMAND_GROUP_FLOW},
{"arrow up",NULL,"" ,0,{0,0,0,0,0},"",COMMAND_GROUP_HELP_ONLY},
{NULL,0,NULL}
};
char tempCmd[1024];
char HexDigit[] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
CPUINFO CPUInfo[]={
{"DR0",&CurrentDR0},
{"DR1",&CurrentDR1},
{"DR2",&CurrentDR2},
{"DR3",&CurrentDR3},
{"DR6",&CurrentDR6},
{"DR7",&CurrentDR7},
{"EFLAGS",&CurrentEFL},
{"CR0",&CurrentCR0},
{"CR2",&CurrentCR2},
{"CR3",&CurrentCR3},
{"",NULL},
};
BP Bp[4]={
{0,0,0,FALSE,FALSE,FALSE,"",""},
{0,0,0,FALSE,FALSE,FALSE,"",""},
{0,0,0,FALSE,FALSE,FALSE,"",""},
{0,0,0,FALSE,FALSE,FALSE,"",""}
};
BOOLEAN bShowSrc = TRUE;
BOOLEAN bCodeOn = FALSE;
BOOLEAN bNeedToFillBuffer = TRUE;
char *NonSystemSegmentTypes[]=
{
"Data RO",
"Data RO accessed",
"Data RW",
"Data RW accessed",
"Data RO expand-dwon",
"Data RO expand-down, accessed",
"Data RW expand-dwon",
"Data RW expand-down, accessed",
"Code EO",
"Code EO accessed",
"Code ER",
"Code ER accessed",
"Code EO conforming",
"Code EO conforming, accessed",
"Code ER conforming",
"Code ER conforming, accessed"
};
char *SystemSegmentTypes[]=
{
"reserved0",
"16-bit TSS (available)",
"LDT",
"16-bit TSS (busy)",
"16-bit call gate",
"task gate",
"16-bit interrupt gate",
"16-bit trap gate",
"reserved1",
"32-bit TSS (available)",
"reserved2",
"32-bit TSS (busy)",
"32-bit call gate",
"reserved3",
"32-bit interrupt gate",
"32-bit trap gate"
};
////////////////////////////////////////////////////
// FUNCTIONS
////
//*************************************************************************
// RepaintSource()
//
//*************************************************************************
void RepaintSource(void)
{
ARGS Args;
ENTER_FUNC();
// disassembly from current address
PICE_memset(&Args,0,sizeof(ARGS));
// make unassembler refresh all again
ulLastDisassStartAddress=ulLastDisassEndAddress=0;
Args.Count=0;
Unassemble(&Args);
LEAVE_FUNC();
}
//*************************************************************************
// RepaintDesktop()
//
//*************************************************************************
void RepaintDesktop(void)
{
ARGS Args;
ENTER_FUNC();
PrintTemplate();
DisplayRegs();
// display data window
Args.Value[0]=OldSelector;
Args.Value[1]=OldOffset;
Args.Count=2;
DisplayMemory(&Args);
// disassembly from current address
PICE_memset(&Args,0,sizeof(ARGS));
// make unassembler refresh all again
ulLastDisassStartAddress=ulLastDisassEndAddress=0;
Args.Count=0;
Unassemble(&Args);
PrintRingBuffer(wWindow[OUTPUT_WINDOW].cy-1);
Print(OUTPUT_WINDOW,"");
ShowStoppedMsg();
ShowStatusLine();
LEAVE_FUNC();
}
//*************************************************************************
// PutStatusText()
//
//*************************************************************************
void PutStatusText(LPSTR p)
{
ENTER_FUNC();
ClrLine(wWindow[OUTPUT_WINDOW].y-1);
PutChar(p,1,wWindow[OUTPUT_WINDOW].y-1);
LEAVE_FUNC();
}
//*************************************************************************
// WaitForKey()
//
//*************************************************************************
BOOLEAN WaitForKey(void)
{
BOOLEAN result=TRUE;
if(ulCountForWaitKey == 0)
SuspendPrintRingBuffer(TRUE);
ulCountForWaitKey++;
if(ulCountForWaitKey == (wWindow[OUTPUT_WINDOW].cy-1))
{
SuspendPrintRingBuffer(FALSE);
PrintRingBuffer(wWindow[OUTPUT_WINDOW].cy-1);
ulCountForWaitKey = 0;
SetBackgroundColor(WHITE);
ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
PutChar(" Press any key to continue listing or press ESC to stop... ",1,wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
ucKeyPressedWhileIdle=0;
while(!(ucKeyPressedWhileIdle=GetKeyPolled()))
{
PrintCursor(FALSE);
}
SetBackgroundColor(BLACK);
// if ESCAPE then indicate retreat
if(ucKeyPressedWhileIdle==SCANCODE_ESC)
{
result=FALSE;
}
ucKeyPressedWhileIdle=0;
}
return result;
}
/////////////////////////////////////////////////////////////
// command handlers
/////////////////////////////////////////////////////////////
//*************************************************************************
// SingleStep()
//
//*************************************************************************
COMMAND_PROTOTYPE(SingleStep)
{
ULONG ulLineNumber;
LPSTR pSrcStart,pSrcEnd,pFilename;
ENTER_FUNC();
if(FindSourceLineForAddress(GetLinearAddress(CurrentCS,CurrentEIP),&ulLineNumber,&pSrcStart,&pSrcEnd,&pFilename))
{
DPRINT((0,"SingleStep(): stepping into source\n"));
StepInto(NULL);
}
else
{
// modify trace flag
CurrentEFL|=0x100; // set trace flag (TF)
bSingleStep=TRUE;
bNotifyToExit=TRUE;
}
bStepping = TRUE;
LEAVE_FUNC();
return TRUE;
}
//*************************************************************************
// StepOver()
//
// step over calls
//*************************************************************************
COMMAND_PROTOTYPE(StepOver)
{
char tempDisasm[256];
ULONG dwBreakAddress;
ULONG ulLineNumber;
LPSTR pSrcStart,pSrcEnd,pFilename;
ENTER_FUNC();
DPRINT((0,"StepOver():\n"));
// only no arguments supplied
// when we have source and current disassembly mod is SOURCE
// we have to analyse the code block for the source line
if(FindSourceLineForAddress(GetLinearAddress(CurrentCS,CurrentEIP),&ulLineNumber,&pSrcStart,&pSrcEnd,&pFilename))
{
DPRINT((0,"StepOver(): we have source here!\n"));
DPRINT((0,"StepOver(): line #%u in file = %s!\n",ulLineNumber,pFilename));
g_ulLineNumberStart = ulLineNumber;
bStepThroughSource = TRUE;
// deinstall the INT3 in kernel's printk()
DeInstallPrintkHook();
goto proceed_as_normal;
}
else
{
DPRINT((0,"StepOver(): no source here!\n"));
proceed_as_normal:
// if there is some form of call instruction at EIP we need to find
// the return address
if(IsCallInstrAtEIP())
{
// get address of next instruction
dwBreakAddress=GetLinearAddress(CurrentCS,CurrentEIP);
Disasm(&dwBreakAddress,tempDisasm);
DPRINT((0,"address of break = %.4X:%.8X\n",CurrentCS,dwBreakAddress));
dwBreakAddress=GetLinearAddress(CurrentCS,dwBreakAddress);
DPRINT((0,"linear address of break = %.8X\n",dwBreakAddress));
DPRINT((0,"setting DR0=%.8X\n",dwBreakAddress));
SetHardwareBreakPoint(dwBreakAddress,0);
bSingleStep = FALSE;
bNotifyToExit = TRUE;
}
else
{
DPRINT((0,"no call at breakpoint\n"));
// modify trace flag
CurrentEFL|=0x100; // set trace flag (TF)
bSingleStep=TRUE;
bNotifyToExit=TRUE;
}
}
bStepInto = FALSE;
bStepping = TRUE;
LEAVE_FUNC();
return TRUE;
}
//*************************************************************************
// StepInto()
//
// step into calls
//*************************************************************************
COMMAND_PROTOTYPE(StepInto)
{
ULONG ulLineNumber;
LPSTR pSrcStart,pSrcEnd,pFilename;
ENTER_FUNC();
// only no arguments supplied
// when we have source and current disassembly mod is SOURCE
// we have to analyse the code block for the source line
if(FindSourceLineForAddress(GetLinearAddress(CurrentCS,CurrentEIP),&ulLineNumber,&pSrcStart,&pSrcEnd,&pFilename))
{
DPRINT((0,"StepOver(): we have source here!\n"));
DPRINT((0,"StepOver(): line #%u in file = %s!\n",ulLineNumber,pFilename));
g_ulLineNumberStart = ulLineNumber;
bStepThroughSource = TRUE;
// deinstall the INT3 in kernel's printk()
DeInstallPrintkHook();
goto proceed_as_normal_into;
}
else
{
DPRINT((0,"StepInto(): no source here!\n"));
proceed_as_normal_into:
// modify trace flag
CurrentEFL|=0x100; // set trace flag (TF)
bSingleStep=TRUE;
bNotifyToExit=TRUE;
}
bStepInto = TRUE;
bStepping = TRUE;
LEAVE_FUNC();
return TRUE;
}
//*************************************************************************
// SetBreakpoint()
//
//*************************************************************************
COMMAND_PROTOTYPE(SetBreakpoint)
{
ULONG addr,addrorg;
USHORT segment;
if(pArgs->Count<=2)
{
if(pArgs->bNotTranslated[0]==FALSE)
{
if(gCurrentSelector)
{
addr=pArgs->Value[0];
addrorg=gCurrentOffset;
segment=gCurrentSelector;
}
else
{
addrorg=addr=pArgs->Value[0];
segment=CurrentCS;
}
if(InstallSWBreakpoint(GetLinearAddress(segment,addr),FALSE,NULL) )
{
PICE_sprintf(tempCmd,"BP #%u set to %.4X:%.8X\n",0,segment,addr);
}
else
{
PICE_sprintf(tempCmd,"BP #%u NOT set (either page not valid OR already used)\n",0);
}
Print(OUTPUT_WINDOW,tempCmd);
}
else
{
if(InstallVirtualSWBreakpoint((LPSTR)pArgs->Value[0],(LPSTR)pArgs->Value[1]) )
{
PICE_sprintf(tempCmd,"BP #%u virtually set to %s!%s\n",0,(LPSTR)pArgs->Value[0],(LPSTR)pArgs->Value[1]);
}
else
{
PICE_sprintf(tempCmd,"BP #%u NOT set (maybe no symbols loaded)\n",0);
}
Print(OUTPUT_WINDOW,tempCmd);
}
RepaintSource();
}
return TRUE;
}
//*************************************************************************
// ListBreakpoints()
//
//*************************************************************************
COMMAND_PROTOTYPE(ListBreakpoints)
{
ULONG i;
ListSWBreakpoints();
for(i=0;i<4;i++)
{
if(Bp[i].Used)
{
PICE_sprintf(tempCmd,"(%u) %s %.4X:%.8X(linear %.8X)\n",i,Bp[i].Active?"*":" ",Bp[i].Segment,Bp[i].Offset,Bp[i].LinearAddress);
Print(OUTPUT_WINDOW,tempCmd);
}
}
return TRUE;
}
//*************************************************************************
// ClearBreakpoints()
//
//*************************************************************************
COMMAND_PROTOTYPE(ClearBreakpoints)
{
if(pArgs->Count)
{
if(pArgs->Value[0]<4)
{
Bp[pArgs->Value[0]].Used=Bp[pArgs->Value[0]].Active=FALSE;
}
RepaintSource();
}
else
{
ULONG i;
RemoveAllSWBreakpoints(FALSE);
for(i=0;i<4;i++)Bp[i].Used=Bp[i].Active=FALSE;
RepaintSource();
}
return TRUE;
}
//*************************************************************************
// LeaveIce()
//
//*************************************************************************
COMMAND_PROTOTYPE(LeaveIce)
{
// SetHardwareBreakPoints();
bSingleStep=FALSE;
bNotifyToExit=TRUE;
return TRUE;
}
//*************************************************************************
// ShowGdt()
//
//*************************************************************************
COMMAND_PROTOTYPE(ShowGdt)
{
ULONG gdtr[2];
USHORT i;
PGDT pGdt;
static ULONG addr=0;
LPSTR pVerbose;
// get GDT register
__asm__ ("sgdt %0\n"
:"=m" (gdtr));
// info out
PICE_sprintf(tempCmd,"Address=%.8X Limit=%.4X\n",(gdtr[1]<<16)|(gdtr[0]>>16),gdtr[0]&0xFFFF);
Print(OUTPUT_WINDOW,tempCmd);
WaitForKey();
// make pointer to GDT
pGdt=(PGDT)(((ULONG)(gdtr[1]<<16))|((ULONG)(gdtr[0]>>16)));
if(pArgs->Count==1)
{
ULONG limit=((pGdt[addr].Limit_19_16<<16)|pGdt[addr].Limit_15_0);
addr=pArgs->Value[0];
addr&=(~0x7);
if(pGdt[addr>>3].Gran)limit=(limit*4096)|0xfff;
if(!pGdt[addr>>3].DescType)
pVerbose = SystemSegmentTypes[pGdt[addr>>3].SegType];
else
pVerbose = NonSystemSegmentTypes[pGdt[addr>>3].SegType];
PICE_sprintf(tempCmd,"%.4X %.8X %.8X %s %u %s\n",
addr,
(pGdt[addr>>3].Base_31_24<<24)|(pGdt[addr>>3].Base_23_16<<16)|(pGdt[addr>>3].Base_15_0),
limit,
pGdt[addr>>3].Present?" P":"NP",
pGdt[addr>>3].Dpl,
pVerbose);
Print(OUTPUT_WINDOW,tempCmd);
}
else if(pArgs->Count==0)
{
for(i=0;i<((gdtr[0]&0xFFFF)>>3);i++)
{
ULONG limit=((pGdt[i].Limit_19_16<<16)|pGdt[i].Limit_15_0);
if(!pGdt[i].DescType)
pVerbose = SystemSegmentTypes[pGdt[i].SegType];
else
pVerbose = NonSystemSegmentTypes[pGdt[i].SegType];
if(pGdt[i].Gran)limit=(limit*4096)|0xfff;
PICE_sprintf(tempCmd,"%.4X %.8X %.8X %s %u %s\n",
i<<3,
(pGdt[i].Base_31_24<<24)|(pGdt[i].Base_23_16<<16)|(pGdt[i].Base_15_0),
limit,
pGdt[i].Present?" P":"NP",
pGdt[i].Dpl,
pVerbose);
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)break;
}
}
return TRUE;
}
//*************************************************************************
// OutputIdtEntry()
//
//*************************************************************************
void OutputIdtEntry(PIDT pIdt,ULONG i)
{
USHORT seg;
ULONG offset;
LPSTR pSym;
seg = (USHORT)pIdt[i].Selector;
offset = (pIdt[i].Offset_31_16<<16)|(pIdt[i].Offset_15_0);
switch(pIdt[i].DescType)
{
// task gate
case 0x5:
PICE_sprintf(tempCmd,"(%0.4X) %0.4X:%0.8X %u [task]\n",i,
seg,
GetLinearAddress((USHORT)seg,0),
pIdt[i].Dpl);
break;
// interrupt gate
case 0x6:
case 0xE:
if(ScanExportsByAddress(&pSym,GetLinearAddress((USHORT)seg,offset)))
{
PICE_sprintf(tempCmd,"(%0.4X) %0.4X:%0.8X %u [int] (%s)\n",i,
seg,
offset,
pIdt[i].Dpl,
pSym);
}
else
{
PICE_sprintf(tempCmd,"(%0.4X) %0.4X:%0.8X %u [int]\n",i,
seg,
offset,
pIdt[i].Dpl);
}
break;
// trap gate
case 0x7:
case 0xF:
if(ScanExportsByAddress(&pSym,GetLinearAddress((USHORT)seg,offset)))
{
PICE_sprintf(tempCmd,"(%0.4X) %0.4X:%0.8X %u [trap] (%s)\n",i,
seg,
offset,
pIdt[i].Dpl,
pSym);
}
else
{
PICE_sprintf(tempCmd,"(%0.4X) %0.4X:%0.8X %u [trap]\n",i,
seg,
offset,
pIdt[i].Dpl);
}
break;
default:
PICE_sprintf(tempCmd,"(%0.4X) INVALID\n",i);
break;
}
Print(OUTPUT_WINDOW,tempCmd);
}
//*************************************************************************
// ShowIdt()
//
//*************************************************************************
COMMAND_PROTOTYPE(ShowIdt)
{
ULONG idtr[2];
USHORT i;
PIDT pIdt;
ULONG addr=0;
ENTER_FUNC();
// get GDT register
__asm__ ("sidt %0\n"
:"=m" (idtr));
// info out
PICE_sprintf(tempCmd,"Address=%.8X Limit=%.4X\n",(idtr[1]<<16)|(idtr[0]>>16),idtr[0]&0xFFFF);
Print(OUTPUT_WINDOW,tempCmd);
WaitForKey();
// make pointer to GDT
pIdt=(PIDT)(((ULONG)(idtr[1]<<16))|((ULONG)(idtr[0]>>16)));
if(pArgs->Count==1)
{
addr=pArgs->Value[0];
addr&=(~0x7);
}
else if(pArgs->Count==0)
{
for(i=0;i<((idtr[0]&0xFFFF)>>3);i++)
{
OutputIdtEntry(pIdt,i);
if(WaitForKey()==FALSE)break;
}
}
LEAVE_FUNC();
return TRUE;
}
//*************************************************************************
// ShowHelp()
//
//*************************************************************************
COMMAND_PROTOTYPE(ShowHelp)
{
ULONG i,j;
PutStatusText("COMMAND KEYWORD DESCRIPTION");
for(j=0;j<COMMAND_GROUP_LAST;j++)
{
PICE_sprintf(tempCmd,"= %-20s =====================================\n",CommandGroups[j]);
Print(OUTPUT_WINDOW,tempCmd);
WaitForKey();
for(i=0;CmdTable[i].Cmd!=NULL;i++)
{
if(CmdTable[i].CommandGroup == j)
{
PICE_sprintf(tempCmd,"%-20s %s\n",CmdTable[i].Cmd,CmdTable[i].Help);
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)return TRUE;
}
}
}
return TRUE;
}
//*************************************************************************
// ShowPageDirs()
//
//*************************************************************************
COMMAND_PROTOTYPE(ShowPageDirs)
{
ULONG i;
PPAGEDIR pPageDir;
PULONG pPGD;
PULONG pPTE;
PEPROCESS my_current = IoGetCurrentProcess();
ENTER_FUNC();
DPRINT((0,"ShowPageDirs(): my_current = %.8X\n",(ULONG)my_current));
// don't touch if not valid process
if(my_current)
{
// no arguments supplied -> show all page directories
if(!pArgs->Count)
{
PutStatusText("Linear Physical Attributes");
// there are 1024 page directories each mapping 1024*4k of address space
for(i=0;i<1024;i++)
{
ULONG ulAddress = i<<22;
// from the mm_struct get pointer to page directory for this address
pPGD = ADDR_TO_PDE(ulAddress);
// create a structurized pointer from PGD
pPageDir = (PPAGEDIR)pPGD;
if(pPageDir->PTBase)
{
PICE_sprintf(tempCmd,"%.8X-%.8X %.8X %s %s %s\n",
ulAddress, ulAddress + 0x400000,
(pPageDir->PTBase<<12),
pPageDir->P?"P ":"NP",
pPageDir->RW?"RW":"R ",
pPageDir->US?"U":"S");
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)break;
}
}
}
// one arg supplied -> show individual page
else if(pArgs->Count == 1)
{
pPGD = ADDR_TO_PDE((ULONG)pArgs->Value[0]);
DPRINT((0,"ShowPageDirs(): VA = %.8X\n",pArgs->Value[0]));
DPRINT((0,"ShowPageDirs(): pPGD = %.8X\n",(ULONG)pPGD));
if(pPGD && ((*pPGD)&_PAGE_PRESENT))
{
// 4M page
if((*pPGD)&_PAGE_4M)
{
PPAGEDIR pPage = (PPAGEDIR)pPGD;
PutStatusText("Linear Physical Attributes");
PICE_sprintf(tempCmd,"%.8X %.8X %s %s %s (LARGE PAGE PTE @ %.8X)\n",
pArgs->Value[0],
(pPage->PTBase<<12)|(pArgs->Value[0]&0x7FFFFF),
pPage->P?"P ":"NP",
pPage->RW?"RW":"R ",
pPage->US?"U":"S",
(ULONG)pPGD);
}
else
{
pPTE = ADDR_TO_PTE(pArgs->Value[0]);
DPRINT((0,"ShowPageDirs(): pPTE = %.8X\n",(ULONG)pPTE));
if(pPTE)
{
PPAGEDIR pPage = (PPAGEDIR)pPTE;
DPRINT((0,"ShowPageDirs(): pPage->PTBase = %.8X\n",(ULONG)pPage->PTBase));
PutStatusText("Linear Physical Attributes");
PICE_sprintf(tempCmd,"%.8X %.8X %s %s %s (PTE @ %.8X)\n",
pArgs->Value[0],
(pPage->PTBase<<12)|(pArgs->Value[0]&(_PAGE_SIZE-1)),
(pPage->P==1)?"P ":"NP",
pPage->RW?"RW":"R ",
pPage->US?"U":"S",
(ULONG)pPTE);
}
}
Print(OUTPUT_WINDOW,tempCmd);
}
else
{
PICE_sprintf(tempCmd,"page at %.8X not present.\n",pArgs->Value[0]);
Print(OUTPUT_WINDOW,tempCmd);
}
}
}
return TRUE;
}
//*************************************************************************
// ShowProcesses()
//
//*************************************************************************
COMMAND_PROTOTYPE(ShowProcesses)
{
PEPROCESS my_current = IoGetCurrentProcess();
PLIST_ENTRY current_entry;
PEPROCESS currentps;
ENTER_FUNC();
current_entry = pPsProcessListHead->Flink;
if( current_entry ){
PutStatusText("NAME TASK PID");
while( current_entry != pPsProcessListHead ){
currentps = CONTAINING_RECORD(current_entry,
EPROCESS,
ProcessListEntry);
DPRINT((0,"currentps = %x\n",currentps));
//ei would be nice to mark current process!
PICE_sprintf(tempCmd,"%-16.16s %-12x %x\n",currentps->ImageFileName,
(ULONG)currentps,currentps->UniqueProcessId);
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)
break;
current_entry = current_entry->Flink;
}
}
LEAVE_FUNC();
return TRUE;
}
//*************************************************************************
// DisplayMemoryDword()
//
//*************************************************************************
COMMAND_PROTOTYPE(DisplayMemoryDword)
{
ULONG i,j,k;
static ULONG addr=0,addrorg;
static USHORT segment;
char temp[8];
LPSTR pSymbolName;
ENTER_FUNC();
DPRINT((0,"DisplayMemoryDword()\n"));
if(pArgs->Count==2)
{
segment=(USHORT)pArgs->Value[0];
if(!segment)segment=GLOBAL_DATA_SEGMENT;
addr=pArgs->Value[1];
OldSelector = segment;
OldOffset = addr;
addrorg=addr;
addr=GetLinearAddress(segment,addr);
}
else if(pArgs->Count==1)
{
segment=CurrentDS;
addr=pArgs->Value[0];
OldOffset = addr;
addrorg=addr;
addr=GetLinearAddress(segment,addr);
}
else if(pArgs->Count==0)
{
addr += sizeof(ULONG)*4*4;
OldOffset = addr;
}
if(ScanExportsByAddress(&pSymbolName,addr))
{
PICE_sprintf(tempCmd," %s ",pSymbolName);
SetForegroundColor(COLOR_TEXT);
SetBackgroundColor(COLOR_CAPTION);
PutChar(tempCmd,GLOBAL_SCREEN_WIDTH-1-PICE_strlen(tempCmd),wWindow[DATA_WINDOW].y-1);
ResetColor();
}
DisableScroll(DATA_WINDOW);
if(DisplayMemory != DisplayMemoryDword)
{
Clear(DATA_WINDOW);
DisplayMemory = DisplayMemoryDword;
}
else
Home(DATA_WINDOW);
for(k=0;k<wWindow[DATA_WINDOW].cy;k++) // 4 lines
{
PICE_sprintf(tempCmd,"%.4X:%.8X: ",segment,addrorg+k*16);
Print(1,tempCmd);
for(i=0;i<4;i++) // 4 dwords
{
tempCmd[0]=0;
Print(1," ");
for(j=0;j<4;j++) // 1 dword = 4 bytes
{
if(IsAddressValid(addr+i*4+j+k*16))
{
PICE_sprintf(temp,"%.2x",*(PUCHAR)(addr+i*4+j+k*16));
PICE_strrev(temp);
PICE_strcat(tempCmd,temp);
}
else
{
PICE_strcat(tempCmd,"??");
}
}
PICE_strrev(tempCmd);
Print(1,tempCmd);
}
Print(1," ");
tempCmd[0]=0;
for(j=0;j<16;j++) // 1 dword = 4 bytes
{
wWindow[DATA_WINDOW].usCurX = GLOBAL_SCREEN_WIDTH-17;
if(IsAddressValid(addr+j+k*16))
{
PICE_sprintf(temp,"%c",PICE_isprint(*(PUCHAR)(addr+j+k*16))?(*(PUCHAR)(addr+j+k*16)):'.');
PICE_strcat(tempCmd,temp);
}
else
{
PICE_strcat(tempCmd,"?");
}
}
Print(1,tempCmd);
Print(1,"\n");
}
EnableScroll(DATA_WINDOW);
addr+=16*4;
return TRUE;
}
//*************************************************************************
// DisplayMemoryByte()
//
//*************************************************************************
COMMAND_PROTOTYPE(DisplayMemoryByte)
{
ULONG j,k;
static ULONG addr=0,addrorg;
static USHORT segment;
char temp[8];
LPSTR pSymbolName;
if(pArgs->Count==2)
{
segment=(USHORT)pArgs->Value[0];
if(!segment)segment=GLOBAL_DATA_SEGMENT;
addr=pArgs->Value[1];
OldSelector = segment;
OldOffset = addr;
addrorg=addr;
addr=GetLinearAddress(segment,addr);
}
else if(pArgs->Count==1)
{
segment=CurrentDS;
addr=pArgs->Value[0];
OldOffset = addr;
addrorg=addr;
addr=GetLinearAddress(segment,addr);
}
else if(pArgs->Count==0)
{
addr += sizeof(ULONG)*4*4;
OldOffset = addr;
}
if(DisplayMemory != DisplayMemoryByte)
{
Clear(DATA_WINDOW);
DisplayMemory = DisplayMemoryByte;
}
else
Home(DATA_WINDOW);
if(ScanExportsByAddress(&pSymbolName,addr))
{
PICE_sprintf(tempCmd," %s ",pSymbolName);
SetForegroundColor(COLOR_TEXT);
SetBackgroundColor(COLOR_CAPTION);
PutChar(tempCmd,GLOBAL_SCREEN_WIDTH-1-PICE_strlen(tempCmd),wWindow[DATA_WINDOW].y-1);
ResetColor();
}
DisableScroll(DATA_WINDOW);
for(k=0;k<wWindow[DATA_WINDOW].cy;k++) // 4 lines
{
PICE_sprintf(tempCmd,"%.4X:%.8X: ",segment,addrorg+k*16);
Print(1,tempCmd);
tempCmd[0]=0;
Print(1," ");
for(j=0;j<16;j++) // 1 dword = 4 bytes
{
if(IsAddressValid(addr+j+k*16))
{
PICE_sprintf(temp,"%.2x ",*(PUCHAR)(addr+j+k*16));
PICE_strcat(tempCmd,temp);
}
else
{
PICE_strcat(tempCmd,"?? ");
}
}
Print(1,tempCmd);
Print(1," ");
tempCmd[0]=0;
for(j=0;j<16;j++) // 1 dword = 4 bytes
{
wWindow[DATA_WINDOW].usCurX = GLOBAL_SCREEN_WIDTH-17;
if(IsAddressValid(addr+j+k*16))
{
PICE_sprintf(temp,"%c",PICE_isprint(*(PUCHAR)(addr+j+k*16))?(*(PUCHAR)(addr+j+k*16)):'.');
PICE_strcat(tempCmd,temp);
}
else
{
PICE_strcat(tempCmd,"?");
}
}
Print(1,tempCmd);
Print(1,"\n");
}
EnableScroll(DATA_WINDOW);
addr+=16*4;
return TRUE;
}
//*************************************************************************
// DisplayPhysMemDword()
//
//*************************************************************************
COMMAND_PROTOTYPE(DisplayPhysMemDword)
{
ULONG i,j,k;
static ULONG addr=0,addrorg;
static USHORT segment;
char temp[8];
ENTER_FUNC();
DPRINT((0,"DisplayPhysMemDword()\n"));
if(pArgs->Count==1)
{
segment=CurrentDS;
addr=pArgs->Value[0];
OldOffset = addr;
addrorg=addr;
addr=GetLinearAddress(segment,addr);
}
else if(pArgs->Count==0)
{
addr += sizeof(ULONG)*4*4;
OldOffset = addr;
}
DisableScroll(DATA_WINDOW);
if(DisplayMemory != DisplayPhysMemDword)
{
Clear(DATA_WINDOW);
DisplayMemory = DisplayPhysMemDword;
}
else
Home(DATA_WINDOW);
for(k=0;k<wWindow[DATA_WINDOW].cy;k++) // 4 lines
{
PICE_sprintf(tempCmd,"PHYS:%.8X: ",addrorg+k*16);
Print(1,tempCmd);
for(i=0;i<4;i++) // 4 dwords
{
tempCmd[0]=0;
PICE_sprintf(tempCmd," %.8X",ReadPhysMem(addr+i*4+k*16,sizeof(ULONG)));
Print(1,tempCmd);
}
Print(1," ");
tempCmd[0]=0;
for(j=0;j<16;j++) // 1 dword = 4 bytes
{
UCHAR ucData;
wWindow[DATA_WINDOW].usCurX = GLOBAL_SCREEN_WIDTH-17;
ucData = ReadPhysMem(addr+j+k*16,sizeof(UCHAR));
PICE_sprintf(temp,"%c",PICE_isprint(ucData)?ucData:'.');
PICE_strcat(tempCmd,temp);
}
Print(1,tempCmd);
Print(1,"\n");
}
EnableScroll(DATA_WINDOW);
addr+=16*4;
return TRUE;
}
//*************************************************************************
// DisplaySourceFile()
//
//*************************************************************************
void DisplaySourceFile(LPSTR pSrcLine,LPSTR pSrcEnd,ULONG ulLineNumber,ULONG ulLineNumberToInvert)
{
ULONG i;
LPSTR pTemp;
ULONG j = ulLineNumber-1;
DPRINT((0,"DisplaySourceFile(%.8X,%u,%u)\n",pSrcLine,ulLineNumber,ulLineNumberToInvert));
// go to line
while(j--)
{
// goto end of current line
while(*pSrcLine!=0x0a && *pSrcLine!=0x0d)
pSrcLine++;
// skip over the line end
if(*pSrcLine == 0x0d)
pSrcLine++;
if(*pSrcLine == 0x0a)
pSrcLine++;
}
Clear(SOURCE_WINDOW);
DisableScroll(SOURCE_WINDOW);
for(i=0;i<wWindow[SOURCE_WINDOW].cy;i++)
{
pTemp = tempCmd;
if(pSrcLine<pSrcEnd)
{
PICE_sprintf(tempCmd,".%.5u ",ulLineNumber+i);
pTemp = tempCmd + PICE_strlen(tempCmd);
while(pSrcLine<pSrcEnd && *pSrcLine!=0x0a && *pSrcLine!=0x0d)
{
if(*pSrcLine==0x9) // TAB
{
*pTemp++ = 0x20;
*pTemp++ = 0x20;
*pTemp++ = 0x20;
*pTemp++ = 0x20;
pSrcLine++;
}
else
{
*pTemp++ = *pSrcLine++;
}
}
if(pSrcLine<pSrcEnd)
{
// skip over the line end
if(*pSrcLine == 0x0d)
pSrcLine++;
if(*pSrcLine == 0x0a)
pSrcLine++;
}
*pTemp++ = '\n';
*pTemp = 0;
if(PICE_strlen(tempCmd)>GLOBAL_SCREEN_WIDTH-1)
{
tempCmd[GLOBAL_SCREEN_WIDTH-2]='\n';
tempCmd[GLOBAL_SCREEN_WIDTH-1]=0;
}
if( (ulLineNumberToInvert!=-1) &&
((int)(ulLineNumberToInvert-ulLineNumber)>=0) &&
((ulLineNumberToInvert-ulLineNumber)<wWindow[SOURCE_WINDOW].cy) &&
(i==(ulLineNumberToInvert-ulLineNumber)) )
{
SetForegroundColor(COLOR_BACKGROUND);
SetBackgroundColor(COLOR_FOREGROUND);
}
Print(SOURCE_WINDOW,tempCmd);
if( (ulLineNumberToInvert!=-1) &&
((int)(ulLineNumberToInvert-ulLineNumber)>=0) &&
((ulLineNumberToInvert-ulLineNumber)<wWindow[SOURCE_WINDOW].cy) &&
(i==(ulLineNumberToInvert-ulLineNumber)) )
{
ResetColor();
}
}
else
{
Print(SOURCE_WINDOW,"---- End of source file --------------\n");
break;
}
}
EnableScroll(SOURCE_WINDOW);
}
//*************************************************************************
// UnassembleOneLineDown()
//
//*************************************************************************
void UnassembleOneLineDown(void)
{
ULONG addr,addrorg;
DPRINT((0,"UnassembleOneLineDown()\n"));
addrorg = addr = GetLinearAddress(usOldDisasmSegment,ulOldDisasmOffset);
DPRINT((0,"UnassembleOneLineDown(): addr = %.8X\n",addr));
tempCmd[0]=0;
Disasm(&addr,tempCmd);
DPRINT((0,"UnassembleOneLineDown(): addr after = %.8X\n",addr));
ulOldDisasmOffset += (addr - addrorg);
RepaintSource();
}
//*************************************************************************
// UnassembleOnePageDown()
//
//*************************************************************************
void UnassembleOnePageDown(ULONG page)
{
ULONG addr,addrorg,i;
DPRINT((0,"UnassembleOnePageDown()\n"));
addrorg = addr = GetLinearAddress(usOldDisasmSegment,ulOldDisasmOffset);
DPRINT((0,"UnassembleOnePageDown(): addr = %.8X\n",addr));
tempCmd[0]=0;
for(i=0;i<page;i++)
Disasm(&addr,tempCmd);
DPRINT((0,"UnassembleOnePageDown(): addr after = %.8X\n",addr));
ulOldDisasmOffset += (addr - addrorg);
RepaintSource();
}
//*************************************************************************
// UnassembleOneLineUp()
//
//*************************************************************************
void UnassembleOneLineUp(void)
{
ULONG addr,addrorg,addrbefore,start,end,addrstart;
LONG offset;
LPSTR pSymbol;
DPRINT((0,"UnassembleOneLineUp()\n"));
addrorg = addr = GetLinearAddress(usOldDisasmSegment,ulOldDisasmOffset);
DPRINT((0,"UnassembleOneLineUp(): addrorg = %.8X\n",addr));
offset = 1;
if((pSymbol = FindFunctionByAddress(addrorg-offset,&start,&end)) )
{
offset = addrorg - start;
DPRINT((0,"UnassembleOneLineUp(): %s @ offset = %u\n",pSymbol,offset));
}
else
{
// max instruction length is 15 bytes
offset = 15;
}
addrstart = addrorg;
// start at current address less offset
addr = addrorg - offset;
do
{
DPRINT((0,"UnassembleOneLineUp(): offset = %u addrorg %x addr %x\n",offset,addrorg,addr));
// disassemble while not reaching current instruction
addrbefore = addr;
tempCmd[0]=0;
Disasm(&addr,tempCmd);
DPRINT((0,"%.8X: %s\n",addrbefore,tempCmd));
}while((addr != addrorg) && (addrbefore < addrorg));
if((addrorg - addrstart)<=0)
ulOldDisasmOffset--;
else
ulOldDisasmOffset -= (addrorg - addrbefore);
DPRINT((0,"UnassembleOneLineUp(): new addr = %.4X:%.8X\n",usOldDisasmSegment,ulOldDisasmOffset));
RepaintSource();
}
//*************************************************************************
// UnassembleOneLineUp()
//
//*************************************************************************
void UnassembleOnePageUp(ULONG page)
{
ULONG addr,addrorg,addrbefore,start,end,i,addrstart;
LONG offset;
LPSTR pSymbol;
DPRINT((0,"UnassembleOnePageUp()\n"));
for(i=0;i<page;i++)
{
addrorg = addr = GetLinearAddress(usOldDisasmSegment,ulOldDisasmOffset);
DPRINT((0,"UnassembleOnePageUp(): addrorg = %.8X\n",addr));
offset = 1;
if((pSymbol = FindFunctionByAddress(addrorg-offset,&start,&end)) )
{
offset = addrorg - start;
DPRINT((0,"UnassembleOnePageUp(): %s @ offset = %u\n",pSymbol,offset));
}
else
{
// max instruction length is 15 bytes
offset = 15;
}
// start at current address less offset
addr = addrorg - offset;
addrstart = addrorg;
do
{
DPRINT((0,"UnassembleOnePageUp(): offset = %u addrorg %x addr %x\n",offset,addrorg,addr));
addrbefore = addr;
// disassemble while not reaching current instruction
tempCmd[0]=0;
Disasm(&addr,tempCmd);
DPRINT((0,"%.8X: %s\n",addrbefore,tempCmd));
}while((addr != addrorg) && (addrbefore < addrorg));
if((addrorg - addrstart)<=0)
ulOldDisasmOffset--;
else
ulOldDisasmOffset -= (addrorg - addrbefore);
}
DPRINT((0,"UnassembleOnePageUp(): new addr = %.4X:%.8X\n",usOldDisasmSegment,ulOldDisasmOffset));
RepaintSource();
}
//*************************************************************************
// Unassemble()
//
//*************************************************************************
COMMAND_PROTOTYPE(Unassemble)
{
ULONG i;
ULONG addr=0,addrorg,addrstart,ulLineNumber;
USHORT segment=0;
ULONG addrbefore;
LPSTR pSymbolName;
BOOLEAN bSWBpAtAddr;
LPSTR pSrc,pFilename,pSrcStart,pSrcEnd;
BOOLEAN bForceDisassembly = FALSE;
DPRINT((0,"Unassemble: CountSwitches: %u, count: %u\n", pArgs->CountSwitches, pArgs->Count));
if(pArgs->CountSwitches>1)
return TRUE;
if(pArgs->CountSwitches==1)
{
if(pArgs->Switch[0] == 'f')
bForceDisassembly = TRUE;
}
// we have args
if(pArgs->Count==2)
{
addr=pArgs->Value[1];
segment=(USHORT)pArgs->Value[0];
addrorg=addrstart=addr;
addr=GetLinearAddress(segment,addr);
usOldDisasmSegment = segment;
ulOldDisasmOffset = addr;
}
else if(pArgs->Count==1)
{
addr=pArgs->Value[0];
segment=CurrentCS;
addrorg=addrstart=addr;
addr=GetLinearAddress(segment,addr);
usOldDisasmSegment = segment;
ulOldDisasmOffset = addr;
}
else if(pArgs->Count==0)
{
segment = usOldDisasmSegment;
addrorg=addrstart=addr;
addr = GetLinearAddress(usOldDisasmSegment,ulOldDisasmOffset);
}
else
return TRUE;
DPRINT((0,"Unassemble(%0.4X:%0.8X), lastst: %x, lastend:%x\n",segment,addr,ulLastDisassStartAddress,ulLastDisassEndAddress));
//
// unassemble
//
DisableScroll(SOURCE_WINDOW);
// if we're inside last disassembly range we only need to move to highlight
if(ulLastDisassStartAddress && ulLastDisassEndAddress && addr>=ulLastDisassStartAddress &&
addr<ulLastDisassEndAddress )
{
addr=ulLastDisassStartAddress;
}
else
{
ulLastDisassStartAddress=ulLastDisassEndAddress=0;
}
SetForegroundColor(COLOR_TEXT);
SetBackgroundColor(COLOR_CAPTION);
ClrLine(wWindow[SOURCE_WINDOW].y-1);
ResetColor();
if(ScanExportsByAddress(&pSymbolName,addr))
{
SetForegroundColor(COLOR_TEXT);
SetBackgroundColor(COLOR_CAPTION);
PICE_sprintf(tempCmd," %s ",pSymbolName);
PutChar(tempCmd,GLOBAL_SCREEN_WIDTH-1-PICE_strlen(tempCmd),wWindow[SOURCE_WINDOW].y-1);
ResetColor();
}
pCurrentMod = FindModuleFromAddress(addr);
if(pCurrentMod)
{
ULONG mod_addr;
DPRINT((0,"Unassemble(): pCurrentMod->name = %S\n",pCurrentMod->name));
mod_addr = (ULONG)pCurrentMod->BaseAddress;
pCurrentSymbols = FindModuleSymbols(mod_addr);
DPRINT((0,"Unassemble(): pCurrentSymbols = %x\n",(ULONG)pCurrentSymbols));
}
DPRINT((0,"Unassemble(): pCurrentMod = %x, showsrc: %d\n",pCurrentMod, bShowSrc));
ulCurrentlyDisplayedLineNumber = 0;
if(bShowSrc && bForceDisassembly == FALSE && (pSrc = FindSourceLineForAddress(addr,&ulLineNumber,&pSrcStart,&pSrcEnd,&pFilename)) )
{
DPRINT((0,"FoundSourceLineForAddress: file: %s line: %d\n", pFilename, ulLineNumber));
PICE_strcpy(szCurrentFile,pFilename);
ulCurrentlyDisplayedLineNumber = ulLineNumber;
Clear(SOURCE_WINDOW);
// display file name
SetForegroundColor(COLOR_TEXT);
SetBackgroundColor(COLOR_CAPTION);
if(PICE_strlen(pFilename)<GLOBAL_SCREEN_WIDTH/2)
{
PutChar(pFilename,1,wWindow[SOURCE_WINDOW].y-1);
}
else
{
LPSTR p;
p = strrchr(pFilename,'/');
if(!p)
{
p = pFilename;
}
else
{
p++;
}
PutChar(p,1,wWindow[SOURCE_WINDOW].y-1);
}
ResetColor();
// display the source
if(ulLineNumber>(wWindow[SOURCE_WINDOW].cy/2) )
{
DisplaySourceFile(pSrcStart,pSrcEnd,ulLineNumber-(wWindow[SOURCE_WINDOW].cy/2),ulLineNumber);
}
else
{
DisplaySourceFile(pSrcStart,pSrcEnd,ulLineNumber,ulLineNumber);
}
}
else
{
*szCurrentFile = 0;
DPRINT((0,"Couldn't find source for file\n"));
Home(SOURCE_WINDOW);
// for each line in the disassembly window
for(i=0;i<wWindow[SOURCE_WINDOW].cy;i++)
{
extern ULONG ulWindowOffset;
bSWBpAtAddr = FALSE;
// if there is a potential SW breakpoint at address
// we might have to put back the original opcode
// in order to disassemble correctly.
if(IsSwBpAtAddress(addr))
{
// if INT3 is there, remove it while disassembling
if((bSWBpAtAddr = IsSwBpAtAddressInstalled(addr)))
{
DeInstallSWBreakpoint(addr);
}
}
ClrLine(wWindow[SOURCE_WINDOW].y+i);
// invert the line that we're about to execute
if(addr==CurrentEIP)
{
SetForegroundColor(COLOR_BACKGROUND);
SetBackgroundColor(COLOR_FOREGROUND);
ulLastInvertedAddress = CurrentEIP;
}
// output segment:offset address
PICE_sprintf(tempCmd,"%0.4X:%0.8X ",segment,addr);
Print(SOURCE_WINDOW,tempCmd);
// disassemble a line
addrbefore=addr;
if(bCodeOn)
{
tempCmd[30]=0;
Disasm(&addr,&tempCmd[30]);
}
else
{
tempCmd[0]=0;
Disasm(&addr,tempCmd);
}
addrorg+=(addr-addrbefore);
// want to display opcode bytes
if(bCodeOn)
{
ULONG j;
for(j=0;j<15;j++)
{
if(j<addr-addrbefore)
{
if(IsAddressValid(addrbefore+j))
{
tempCmd[j*2]=HexDigit[((*(PUCHAR)(addrbefore+j)&0xF0)>>4)];
tempCmd[j*2+1]=HexDigit[((*(PUCHAR)(addrbefore+j)&0xF))];
}
else
{
tempCmd[j*2]='?';
tempCmd[j*2+1]='?';
}
}
else
{
tempCmd[j*2]=' ';
tempCmd[j*2+1]=' ';
}
}
}
PICE_strcat(tempCmd,"\n");
if(ulWindowOffset)
{
LONG len = PICE_strlen(tempCmd);
if(ulWindowOffset < len)
PICE_memcpy(tempCmd,&tempCmd[ulWindowOffset],len-ulWindowOffset);
else
tempCmd[0]='\n';
}
Print(SOURCE_WINDOW,tempCmd);
if(addrbefore==CurrentEIP)
{
ResetColor();
}
// if potential SW breakpoint, undo marked text
if(IsSwBpAtAddress(addrbefore))
{
HatchLine(wWindow[SOURCE_WINDOW].y+i);
}
// if breakpoint was installed before disassembly, put it back
if(bSWBpAtAddr)
{
ReInstallSWBreakpoint(addrbefore);
}
}
if(ulLastDisassStartAddress==0 && ulLastDisassEndAddress==0)
{
ulLastDisassStartAddress=addrstart;
ulLastDisassEndAddress=addr;
}
if(!IsAddressValid(addrstart))
{
ulLastDisassStartAddress=0;
ulLastDisassEndAddress=0;
}
}
EnableScroll(SOURCE_WINDOW);
return TRUE;
}
//*************************************************************************
// ShowModules()
//
//*************************************************************************
COMMAND_PROTOTYPE(ShowModules)
{
PDEBUG_MODULE pMod;
DPRINT((0,"ShowModules()\n"));
if(BuildModuleList())
{
pMod = pdebug_module_head;
do
{
if(pMod->size)
{
if(pMod == pCurrentMod)
{
PICE_sprintf(tempCmd,"%.8X - %.8X *%-32S\n",
(unsigned int)pMod->BaseAddress,
(unsigned int) ((unsigned int)pMod->BaseAddress+pMod->size),pMod->name);
}
else
{
PICE_sprintf(tempCmd,"%.8X - %.8X %-32S\n",
(unsigned int)pMod->BaseAddress,
(unsigned int) ((unsigned int)pMod->BaseAddress+pMod->size),
pMod->name);
}
}
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)
break;
}while((pMod = pMod->next)!=pdebug_module_tail);
}
return TRUE;
}
//*************************************************************************
// DecodeVmFlags()
//
//*************************************************************************
//ei FIX THIS!!!!!!!!!!!!!!!!!!
LPSTR DecodeVmFlags(ULONG flags)
{
ULONG i;
/*
#define VM_READ 0x0001
#define VM_WRITE 0x0002
#define VM_EXEC 0x0004
#define VM_SHARED 0x0008
#define VM_MAYREAD 0x0010
#define VM_MAYWRITE 0x0020
#define VM_MAYEXEC 0x0040
#define VM_MAYSHARE 0x0080
#define VM_GROWSDOWN 0x0100
#define VM_GROWSUP 0x0200
#define VM_SHM 0x0400
#define VM_DENYWRITE 0x0800
#define VM_EXECUTABLE 0x1000
#define VM_LOCKED 0x2000
#define VM_IO 0x4000
#define VM_STACK_FLAGS 0x0177
*/
static LPSTR flags_syms_on[]={"R","W","X","S","MR","MW","MX","MS","GD","GU","SHM","exe","LOCK","IO",""};
static char temp[256];
// terminate string
*temp = 0;
//ei fix fix fix
#if 0
if(flags == VM_STACK_FLAGS)
{
PICE_strcpy(temp," (STACK)");
}
else
{
for(i=0;i<15;i++)
{
if(flags&0x1)
{
PICE_strcat(temp," ");
PICE_strcat(temp,flags_syms_on[i]);
}
flags >>= 1;
}
}
#endif
return temp;
}
//*************************************************************************
// ShowVirtualMemory()
//
//*************************************************************************
COMMAND_PROTOTYPE(ShowVirtualMemory)
{
PEPROCESS my_current = IoGetCurrentProcess();
PLIST_ENTRY current_entry;
PMADDRESS_SPACE vma = NULL;
MEMORY_AREA* current;
char filename[64];
DPRINT((0,"ShowVirtualMemory()\n"));
if( my_current )
vma = &(my_current->AddressSpace);
if( !vma )
vma = my_init_mm;
while( vma )
{
if(pArgs->Count == 0)
{
PutStatusText("START END LENGTH VMA TYPE ATTR");
current_entry = vma->MAreaListHead.Flink;
while (current_entry != &vma->MAreaListHead)
{
*filename = 0;
current = CONTAINING_RECORD(current_entry,
MEMORY_AREA,
Entry);
// find the filename
if(((current->Type == MEMORY_AREA_SECTION_VIEW) ) &&
current->Data.SectionData.Section->FileObject)
{
if(IsAddressValid((ULONG)current->Data.SectionData.Section->FileObject->FileName.Buffer) )
PICE_sprintf(filename,"%.64S",current->Data.SectionData.Section->FileObject->FileName.Buffer);
}
PICE_sprintf(tempCmd,"%.8X %.8X %.8X %.8X %x %x %s\n",
(ULONG)current->BaseAddress,
(ULONG)current->BaseAddress+current->Length,
current->Length,
(ULONG)current,
current->Type, current->Attributes,//DecodeVmFlags(current->Type, current->Attributes),
filename);
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)
break;
current_entry = current_entry->Flink;
}
}
if( vma == &(my_current->AddressSpace) )
vma = my_init_mm; // switch to kernel memory area
else vma = 0; // if we already did kernel, end loop
}
return TRUE;
}
//*************************************************************************
// Ver()
//
//*************************************************************************
COMMAND_PROTOTYPE(Ver)
{
//ei add kernel version info??!!
PICE_sprintf(tempCmd,"pICE: version %u.%u (build %u) for Reactos\n",
PICE_MAJOR_VERSION,
PICE_MINOR_VERSION,
PICE_BUILD);
Print(OUTPUT_WINDOW,tempCmd);
/* PICE_sprintf(tempCmd,"pICE: loaded on %s kernel release %s\n",
system_utsname.sysname,
system_utsname.release);
*/
Print(OUTPUT_WINDOW,tempCmd);
Print(OUTPUT_WINDOW,"pICE: written by Klaus P. Gerlicher and Goran Devic.\n");
Print(OUTPUT_WINDOW,"pICE: ported to Reactos by Eugene Ingerman.\n");
return TRUE;
}
//*************************************************************************
// Hboot()
//
//*************************************************************************
COMMAND_PROTOTYPE(Hboot)
{
// nudge the reset line through keyboard controller
__asm__("\n\t \
movb $0xFE,%al\n\t \
outb %al,$0x64");
// never gets here
return TRUE;
}
//*************************************************************************
// SetSrcDisplay()
//
//*************************************************************************
COMMAND_PROTOTYPE(SetSrcDisplay)
{
ARGS Args;
if(pArgs->Count==0)
{
bShowSrc=bShowSrc?FALSE:TRUE;
PICE_memset(&Args,0,sizeof(ARGS));
// make unassembler refresh all again
ulLastDisassStartAddress=ulLastDisassEndAddress=0;
Args.Count=0;
Unassemble(&Args);
}
return TRUE;
}
//*************************************************************************
// I3here()
//
//*************************************************************************
COMMAND_PROTOTYPE(I3here)
{
if(pArgs->Count==1)
{
if(pArgs->Value[0]==1)
{
if(!bInt3Here)
{
bInt3Here=TRUE;
Print(OUTPUT_WINDOW,"I3HERE is now ON\n");
}
else
Print(OUTPUT_WINDOW,"I3HERE is already ON\n");
}
else if(pArgs->Value[0]==0)
{
if(bInt3Here)
{
bInt3Here=FALSE;
Print(OUTPUT_WINDOW,"I3HERE is now OFF\n");
}
else
Print(OUTPUT_WINDOW,"I3HERE is already OFF\n");
}
}
else if(pArgs->Count==0)
{
if(bInt3Here)
{
Print(OUTPUT_WINDOW,"I3HERE is ON\n");
}
else
{
Print(OUTPUT_WINDOW,"I3HERE is OFF\n");
}
}
// never gets here
return TRUE;
}
COMMAND_PROTOTYPE(I1here)
{
if(pArgs->Count==1)
{
if(pArgs->Value[0]==1)
{
if(!bInt1Here)
{
bInt1Here=TRUE;
Print(OUTPUT_WINDOW,"I1HERE is now ON\n");
}
else
Print(OUTPUT_WINDOW,"I1HERE is already ON\n");
}
else if(pArgs->Value[0]==0)
{
if(bInt1Here)
{
bInt1Here=FALSE;
Print(OUTPUT_WINDOW,"I1HERE is now OFF\n");
}
else
Print(OUTPUT_WINDOW,"I1HERE is already OFF\n");
}
}
else if(pArgs->Count==0)
{
if(bInt1Here)
{
Print(OUTPUT_WINDOW,"I1HERE is ON\n");
}
else
{
Print(OUTPUT_WINDOW,"I1HERE is OFF\n");
}
}
// never gets here
return TRUE;
}
COMMAND_PROTOTYPE(NextInstr)
{
static char tempDisasm[256];
ULONG addr,addrbefore;
bNeedToFillBuffer=FALSE;
if(!pArgs->Count)
{
addr=addrbefore=GetLinearAddress(CurrentCS,CurrentEIP);
DPRINT((0,"addr before %.8X\n",addrbefore));
Disasm(&addr,tempDisasm);
DPRINT((0,"addr after %.8X\n",addr));
CurrentEIP=CurrentEIP+(addr-addrbefore);
// display register contents
DisplayRegs();
// unassemble
DPRINT((0,"new CS:EIP %04.x:%.8X\n",CurrentCS,CurrentEIP));
PICE_memset(pArgs,0,sizeof(ARGS));
// make unassembler refresh all again
ulLastDisassStartAddress=ulLastDisassEndAddress=0;
pArgs->Count=2;
pArgs->Value[0]=(ULONG)CurrentCS;
pArgs->Value[1]=CurrentEIP;
Unassemble(pArgs);
}
bNeedToFillBuffer=TRUE;
return TRUE;
}
COMMAND_PROTOTYPE(SetGetRegisters)
{
ULONG i;
if(pArgs->Count==0)
{
// display whole set
for(i=0;RegKeyWords[i].pValue!=0;i++)
{
switch(RegKeyWords[i].ulSize)
{
case 1:
PICE_sprintf(tempCmd,"%s = %.8X\n",RegKeyWords[i].KeyWord,*(PUCHAR)(RegKeyWords[i].pValue));
break;
case 2:
PICE_sprintf(tempCmd,"%s = %.8X\n",RegKeyWords[i].KeyWord,*(PUSHORT)(RegKeyWords[i].pValue));
break;
case 4:
PICE_sprintf(tempCmd,"%s = %.8X\n",RegKeyWords[i].KeyWord,*(PULONG)(RegKeyWords[i].pValue));
break;
}
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)break;
}
}
else if(pArgs->Count==1)
{
// display selected register
for(i=0;RegKeyWords[i].pValue!=0;i++)
{
if(PICE_strcmpi(pArgs->pToken[0],RegKeyWords[i].KeyWord)==0)
{
switch(RegKeyWords[i].ulSize)
{
case 1:
PICE_sprintf(tempCmd,"%s = %.2X\n",RegKeyWords[i].KeyWord,*(PUCHAR)(RegKeyWords[i].pValue));
break;
case 2:
PICE_sprintf(tempCmd,"%s = %.4X\n",RegKeyWords[i].KeyWord,*(PUSHORT)(RegKeyWords[i].pValue));
break;
case 4:
PICE_sprintf(tempCmd,"%s = %.8X\n",RegKeyWords[i].KeyWord,*(PULONG)(RegKeyWords[i].pValue));
break;
}
Print(OUTPUT_WINDOW,tempCmd);
break;
}
}
}
else if(pArgs->Count==2)
{
// set selected register to value
for(i=0;RegKeyWords[i].pValue!=0;i++)
{
if(PICE_strcmpi(pArgs->pToken[0],RegKeyWords[i].KeyWord)==0)
{
switch(RegKeyWords[i].ulSize)
{
case 1:
*(PUCHAR)(RegKeyWords[i].pValue)=(UCHAR)pArgs->Value[1];
break;
case 2:
*(PUSHORT)(RegKeyWords[i].pValue)=(USHORT)pArgs->Value[1];
break;
case 4:
*(PULONG)(RegKeyWords[i].pValue)=(ULONG)pArgs->Value[1];
break;
}
DisplayRegs();
RepaintSource();
break;
}
}
}
return TRUE;
}
//*************************************************************************
// SetCodeDisplay()
//
//*************************************************************************
COMMAND_PROTOTYPE(SetCodeDisplay)
{
ARGS Args;
if(pArgs->Count==0)
{
bCodeOn=bCodeOn?FALSE:TRUE;
PICE_memset(&Args,0,sizeof(ARGS));
Args.Count=0;
// make unassembler refresh all again
ulLastDisassStartAddress=ulLastDisassEndAddress=0;
Unassemble(&Args);
}
else if(pArgs->Count==1)
{
bCodeOn=(pArgs->Value[0]==0)?FALSE:TRUE;
PICE_memset(&Args,0,sizeof(ARGS));
Args.Count=0;
// make unassembler refresh all again
ulLastDisassStartAddress=ulLastDisassEndAddress=0;
Unassemble(&Args);
}
return TRUE;
}
//*************************************************************************
// ShowCPU()
//
//*************************************************************************
COMMAND_PROTOTYPE(ShowCPU)
{
ULONG i;
for(i=0;CPUInfo[i].pValue!=NULL;i++)
{
PICE_sprintf(tempCmd,"%s = %.8X\n",CPUInfo[i].Name,*(CPUInfo[i].pValue));
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)break;
}
return TRUE;
}
//*************************************************************************
// WalkStack()
//
//*************************************************************************
COMMAND_PROTOTYPE(WalkStack)
{
if(!pArgs->Count)
{
IntelStackWalk(CurrentEIP,CurrentEBP,CurrentESP);
}
return TRUE;
}
//*************************************************************************
// PokeDword()
//
//*************************************************************************
COMMAND_PROTOTYPE(PokeDword)
{
ULONG ulData;
// read old data
ulData = ReadPhysMem(pArgs->Value[1],sizeof(ULONG));
PICE_sprintf(tempCmd,"value @ %.8X was %.8X\n",pArgs->Value[1],ulData);
Print(OUTPUT_WINDOW,tempCmd);
// write new data
WritePhysMem(pArgs->Value[1],pArgs->Value[2],sizeof(ULONG));
// read check
ulData = ReadPhysMem(pArgs->Value[1],sizeof(ULONG));
PICE_sprintf(tempCmd,"value @ %.8X = %.8X\n",pArgs->Value[1],ulData);
Print(OUTPUT_WINDOW,tempCmd);
return TRUE;
}
//*************************************************************************
// PokeMemory()
//
//*************************************************************************
COMMAND_PROTOTYPE(PokeMemory)
{
DPRINT((0,"PokeMemory()\n"));
DPRINT((0,"PokeMemory(): value[0] = %.8X value[1] = %.8X value[3] = %.8X count = %.8X\n",pArgs->Value[0],pArgs->Value[1],pArgs->Value[2],pArgs->Count));
// must be three parameters
if(pArgs->Count == 3)
{
switch(pArgs->Value[0])
{
case 4:
return PokeDword(pArgs);
default:
case 1:
case 2:
break;
}
}
else
{
Print(OUTPUT_WINDOW,"you need to supply a physical address and datum to write!\n");
}
return TRUE;
}
//*************************************************************************
// PeekDword()
//
//*************************************************************************
COMMAND_PROTOTYPE(PeekDword)
{
ULONG ulData;
ulData = ReadPhysMem(pArgs->Value[1],sizeof(ULONG));
PICE_sprintf(tempCmd,"%.8X\n",ulData);
Print(OUTPUT_WINDOW,tempCmd);
return TRUE;
}
//*************************************************************************
// PeekWord()
//
//*************************************************************************
COMMAND_PROTOTYPE(PeekWord)
{
USHORT usData;
usData = (USHORT)ReadPhysMem(pArgs->Value[1],sizeof(USHORT));
PICE_sprintf(tempCmd,"%.4X\n",usData);
Print(OUTPUT_WINDOW,tempCmd);
return TRUE;
}
//*************************************************************************
// PeekByte()
//
//*************************************************************************
COMMAND_PROTOTYPE(PeekByte)
{
UCHAR ucData;
ucData = (UCHAR)ReadPhysMem(pArgs->Value[1],sizeof(UCHAR));
PICE_sprintf(tempCmd,"%.2X\n",ucData);
Print(OUTPUT_WINDOW,tempCmd);
return TRUE;
}
//*************************************************************************
// PeekMemory()
//
//*************************************************************************
COMMAND_PROTOTYPE(PeekMemory)
{
DPRINT((0,"PeekMemory()\n"));
DPRINT((0,"PeekMemory(): value[0] = %.8X value[1] = %.8X count = %.8X\n",pArgs->Value[0],pArgs->Value[1],pArgs->Count));
if(pArgs->Count == 2)
{
switch(pArgs->Value[0])
{
case 1:
return PeekByte(pArgs);
case 2:
return PeekWord(pArgs);
case 4:
return PeekDword(pArgs);
default:
break;
}
}
return TRUE;
}
//*************************************************************************
// UnassembleAtCurrentEip()
//
//*************************************************************************
COMMAND_PROTOTYPE(UnassembleAtCurrentEip)
{
PICE_memset(pArgs,0,sizeof(ARGS));
pArgs->Count = 2;
pArgs->Value[0] = CurrentCS;
pArgs->Value[1] = CurrentEIP;
Unassemble(pArgs);
return TRUE;
}
//*************************************************************************
// SwitchTables()
//
//*************************************************************************
COMMAND_PROTOTYPE(SwitchTables)
{
ULONG i;
DPRINT((0,"SwitchTables()\n"));
// no arguments -> display load symbol tables
if(!pArgs->Count)
{
for(i=0;i<DIM(apSymbols);i++)
{
if(apSymbols[i])
{
if(apSymbols[i] == pCurrentSymbols)
PICE_sprintf(tempCmd,"*%-32S @ %.8X (%5u source files)\n",apSymbols[i]->name,(ULONG)apSymbols[i],apSymbols[i]->ulNumberOfSrcFiles);
else
PICE_sprintf(tempCmd," %-32S @ %.8X (%5u source files)\n",apSymbols[i]->name,(ULONG)apSymbols[i],apSymbols[i]->ulNumberOfSrcFiles);
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)break;
}
}
}
// 1 argument -> set new current symbols
else if(pArgs->Count == 1)
{
PDEBUG_MODULE pTempMod;
char temp[DEBUG_MODULE_NAME_LEN];
pCurrentSymbols = (PICE_SYMBOLFILE_HEADER*)pArgs->Value[0];
CopyWideToAnsi( temp, pCurrentSymbols->name );
DPRINT((0,"TableSwitchSym: pCurrentSymbols: %x, Name: %s\n", pCurrentSymbols, temp));
pTempMod = IsModuleLoaded(temp);
if( pTempMod )
pCurrentMod = pTempMod;
}
return TRUE;
}
//*************************************************************************
// SwitchFiles()
//
//*************************************************************************
COMMAND_PROTOTYPE(SwitchFiles)
{
PICE_SYMBOLFILE_SOURCE* pSrc;
ULONG i;
LPSTR p;
DPRINT((0,"SwitchFiles()\n"));
// no arguments -> show files for current symbols
if(!pArgs->Count)
{
if(pCurrentSymbols && pCurrentSymbols->ulNumberOfSrcFiles)
{
LPSTR pCurrentFile=NULL;
// find out the current file name
if(*szCurrentFile!=0)
{
if((pCurrentFile = strrchr(szCurrentFile,'/')) )
{
pCurrentFile++;
}
else
{
pCurrentFile = szCurrentFile;
}
}
pSrc = (PICE_SYMBOLFILE_SOURCE*)((ULONG)pCurrentSymbols + pCurrentSymbols->ulOffsetToSrcFiles);
for(i=0;i<pCurrentSymbols->ulNumberOfSrcFiles;i++)
{
if(pCurrentFile)
{
if((p = strrchr(pSrc->filename,'/')) )
{
if(PICE_strcmpi(p+1,pCurrentFile)==0)
PICE_sprintf(tempCmd,"*%-32s @ %.8X\n",p+1,(ULONG)pSrc);
else
PICE_sprintf(tempCmd," %-32s @ %.8X\n",p+1,(ULONG)pSrc);
}
else
{
if(PICE_strcmpi(pSrc->filename,pCurrentFile)==0)
PICE_sprintf(tempCmd,"*%-32s @ %.8X\n",pSrc->filename,(ULONG)pSrc);
else
PICE_sprintf(tempCmd," %-32s @ %.8X\n",pSrc->filename,(ULONG)pSrc);
}
}
else
{
if((p = strrchr(pSrc->filename,'/')) )
{
PICE_sprintf(tempCmd,"%-32s @ %.8X\n",p+1,(ULONG)pSrc);
}
else
{
PICE_sprintf(tempCmd,"%-32s @ %.8X\n",pSrc->filename,(ULONG)pSrc);
}
}
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)break;
(LPSTR)pSrc += pSrc->ulOffsetToNext;
}
}
else
Print(OUTPUT_WINDOW,"No source files available!\n");
}
// 1 argument -> argument is pointer PICE_SYMBOLFILE_SOURCE struct ->
// set current file and show it
else if(pArgs->Count == 1)
{
PICE_SYMBOLFILE_SOURCE* pSrc = (PICE_SYMBOLFILE_SOURCE*)pArgs->Value[0];
LPSTR pFilename = pSrc->filename;
ClrLine(wWindow[SOURCE_WINDOW].y-1);
if(PICE_strlen(pFilename)<GLOBAL_SCREEN_WIDTH/2)
{
PutChar(pFilename,1,wWindow[SOURCE_WINDOW].y-1);
}
else
{
LPSTR p;
p = strrchr(pFilename,'/');
if(!p)
{
p = pFilename;
}
else
{
p++;
}
PutChar(p,1,wWindow[SOURCE_WINDOW].y-1);
}
// set new current file
PICE_strcpy(szCurrentFile,pFilename);
ulCurrentlyDisplayedLineNumber = 1;
DisplaySourceFile((LPSTR)pSrc+sizeof(PICE_SYMBOLFILE_SOURCE),
(LPSTR)pSrc+pSrc->ulOffsetToNext,
1,
-1);
}
return TRUE;
}
//*************************************************************************
// ShowLocals()
//
//*************************************************************************
COMMAND_PROTOTYPE(ShowLocals)
{
PLOCAL_VARIABLE p;
if(pArgs->Count==0)
{
p = FindLocalsByAddress(GetLinearAddress(CurrentCS,CurrentEIP));
DPRINT((0,"ShowLocals: %x\n", p));
if(p)
{
DPRINT((0,"ShowLocals: name %s, type_name %s\n", p->name, p->type_name));
while(PICE_strlen(p->name))
{
if(!p->bRegister)
{
PICE_sprintf(tempCmd,"[EBP%.4d / #%u] %x %s %s \n",p->offset,p->line,p->value,p->type_name,p->name);
}
else
{
PICE_sprintf(tempCmd,"[%-8s / #%u] %x %s %s #%u\n",LocalVarRegs[p->offset],p->line,p->value,p->type_name,p->name);
}
Print(OUTPUT_WINDOW,tempCmd);
p++;
}
}
}
return TRUE;
}
//*************************************************************************
// ShowSymbols()
//
//*************************************************************************
COMMAND_PROTOTYPE(ShowSymbols)
{
PICE_SYMBOLFILE_HEADER* pSymbols;
ULONG index,addr;
LPSTR pSearchString,pName,pFind;
// no args -> list full symbols for current module
if(!pArgs->Count)
{
// have current module ?
if(pCurrentMod)
{
DPRINT((0,"ShowSymbols(): full listing of symbols for %S\n",pCurrentMod->name));
addr = (ULONG)pCurrentMod->BaseAddress;
if((pSymbols = FindModuleSymbols(addr)) )
{
PICE_sprintf(tempCmd,"symbols for module \"%S\"\n",pCurrentMod->name);
Print(OUTPUT_WINDOW,tempCmd);
index = 0;
while((index = ListSymbolStartingAt(pCurrentMod,pSymbols,index,tempCmd)))
{
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)break;
}
}
}
}
// partial name
else if(pArgs->Count == 1)
{
if(pCurrentMod)
{
addr = (ULONG)pCurrentMod->BaseAddress;
if((pSymbols = FindModuleSymbols(addr)))
{
pSearchString = (LPSTR)pArgs->Value[0];
PICE_sprintf(tempCmd,"symbols for module \"%S\" (searching for \"%s\")\n",pCurrentMod->name,pSearchString);
Print(OUTPUT_WINDOW,tempCmd);
if(pSearchString)
{
if(*pSearchString=='*' && pSearchString[PICE_strlen(pSearchString)-1]=='*')
{
pSearchString[PICE_strlen(pSearchString)-1] = 0;
pSearchString++;
index = 0;
while((index = ListSymbolStartingAt(pCurrentMod,pSymbols,index,tempCmd)))
{
pName = strrchr(tempCmd,' ');
pName++;
pFind = strstr(pName,pSearchString);
if(pFind)
{
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)break;
}
}
// TODO
}
else if(pSearchString[PICE_strlen(pSearchString)-1]=='*')
{
pSearchString[PICE_strlen(pSearchString)-1] = 0;
index = 0;
index = ListSymbolStartingAt(pCurrentMod,pSymbols,index,tempCmd);
if(index)
{
do
{
pName = strrchr(tempCmd,' ');
pName++;
pFind = strstr(pName,pSearchString);
if(pFind && (((ULONG)pName-(ULONG)pFind)==0) )
{
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)break;
}
}while((index = ListSymbolStartingAt(pCurrentMod,pSymbols,index,tempCmd)));
}
}
}
}
}
}
return TRUE;
}
//*************************************************************************
// EvaluateExpression()
//
//*************************************************************************
COMMAND_PROTOTYPE(EvaluateExpression)
{
PICE_SYMBOLFILE_HEADER* pSymbols;
ULONG addr;
if(pArgs->Count == 1)
{
if(pCurrentMod)
{
addr = (ULONG)pCurrentMod->BaseAddress;
if( (pSymbols = FindModuleSymbols(addr) ) )
{
DPRINT((0,"EvaluateExpression: %s\n", (LPSTR)pArgs->Value[0]));
Evaluate(pSymbols,(LPSTR)pArgs->Value[0]);
}
}
}
return TRUE;
}
//*************************************************************************
// SizeCodeWindow()
//
//*************************************************************************
COMMAND_PROTOTYPE(SizeCodeWindow)
{
ULONG NewHeight,TotalHeight;
if(pArgs->Count == 1)
{
NewHeight = pArgs->Value[0];
TotalHeight = wWindow[SOURCE_WINDOW].cy +
wWindow[OUTPUT_WINDOW].cy;
if(NewHeight < TotalHeight)
{
if(wWindow[SOURCE_WINDOW].cy != NewHeight)
{
wWindow[SOURCE_WINDOW].cy = NewHeight;
wWindow[OUTPUT_WINDOW].y = wWindow[SOURCE_WINDOW].y + wWindow[SOURCE_WINDOW].cy + 1;
wWindow[OUTPUT_WINDOW].cy = TotalHeight - NewHeight;
RepaintDesktop();
}
}
}
else
{
PICE_sprintf(tempCmd,"code window at position %u has %u lines \n",wWindow[SOURCE_WINDOW].y,wWindow[SOURCE_WINDOW].cy);
Print(OUTPUT_WINDOW,tempCmd);
}
return TRUE;
}
//*************************************************************************
// SizeDataWindow()
//
//*************************************************************************
COMMAND_PROTOTYPE(SizeDataWindow)
{
ULONG NewHeight,TotalHeight;
if(pArgs->Count)
{
NewHeight = pArgs->Value[0];
TotalHeight = wWindow[DATA_WINDOW].cy +
wWindow[SOURCE_WINDOW].cy;
if(NewHeight < TotalHeight)
{
if(wWindow[DATA_WINDOW].cy != NewHeight)
{
wWindow[DATA_WINDOW].cy = NewHeight;
wWindow[SOURCE_WINDOW].y = wWindow[DATA_WINDOW].y + wWindow[DATA_WINDOW].cy + 1;
wWindow[SOURCE_WINDOW].cy = TotalHeight - NewHeight;
RepaintDesktop();
}
}
}
else
{
PICE_sprintf(tempCmd,"data window has %u lines \n",wWindow[DATA_WINDOW].cy);
Print(OUTPUT_WINDOW,tempCmd);
}
return TRUE;
}
//*************************************************************************
// ClearScreen()
//
//*************************************************************************
COMMAND_PROTOTYPE(ClearScreen)
{
EmptyRingBuffer();
Clear(OUTPUT_WINDOW);
CheckRingBuffer();
return TRUE;
}
//*************************************************************************
// ShowMappings()
//
//*************************************************************************
COMMAND_PROTOTYPE(ShowMappings)
{
#if 0
ULONG ulPageDir;
ULONG ulPageTable;
ULONG address;
ULONG phys_addr;
pgd_t * pPGD;
pmd_t * pPMD;
pte_t * pPTE;
struct mm_struct* p = NULL;
struct task_struct* my_current = (struct task_struct*)0xFFFFE000;
DPRINT((0,"ShowMappings()\n"));
if(pArgs->Count == 1)
{
// We're in DebuggerShell(), so we live on a different stack
(ULONG)my_current &= ulRealStackPtr;
// in case we have a user context we use it's mm_struct
if(my_current->mm)
{
p = my_current->mm;
}
// no user context -> use kernel's context
else
{
p = my_init_mm;
}
// get the requested address from arguments
phys_addr = pArgs->Value[0];
DPRINT((0,"ShowMappings(): p = %X phys_addr = %X\n",(ULONG)p,phys_addr));
// for every page directory
for(ulPageDir=0;ulPageDir<1024;ulPageDir++)
{
address = (ulPageDir<<22);
// get the page directory for the address
pPGD = pgd_offset(p,address);
// if page dir present
if(pPGD && pgd_val(*pPGD)&_PAGE_PRESENT)
{
DPRINT((0,"ShowMappings(): page directory present for %x\n",address));
// not large page
if(!(pgd_val(*pPGD)&_PAGE_4M))
{
DPRINT((0,"ShowMappings(): page directory for 4k pages\n"));
for(ulPageTable=0;ulPageTable<1024;ulPageTable++)
{
address = (ulPageDir<<22)|(ulPageTable<<12);
pPMD = pmd_offset(pPGD,address);
if(pPMD)
{
pPTE = pte_offset(pPMD,address);
if(pPTE)
{
if(*(PULONG)pPTE & _PAGE_PRESENT)
{
ULONG ulPte = *(PULONG)pPTE & 0xFFFFF000;
if(ulPte == (phys_addr & 0xFFFFF000))
{
PICE_sprintf(tempCmd,"%.8X\n",address+(phys_addr&0xFFF));
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)return TRUE;
}
}
}
}
}
}
// large page
else
{
address = (ulPageDir<<22);
if((pgd_val(*pPGD)&0xFFC00000) == (phys_addr & 0xFFC00000) )
{
if( ((address|(phys_addr&0x7FFFFF))&~TASK_SIZE) == phys_addr)
PICE_sprintf(tempCmd,"%.8X (identity map %.8X+%.8X)\n",address|(phys_addr&0x7FFFFF),TASK_SIZE,phys_addr);
else
PICE_sprintf(tempCmd,"%.8X\n",address|(phys_addr&0x7FFFFF));
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)return TRUE;
}
}
}
}
}
#endif
PICE_sprintf(tempCmd,"Not implemented yet!\n");
Print(OUTPUT_WINDOW,tempCmd);
return TRUE;
}
//*************************************************************************
// ShowTimers()
//
//*************************************************************************
COMMAND_PROTOTYPE(ShowTimers)
{
return TRUE;
}
//*************************************************************************
// FindPCIVendorName()
//
//*************************************************************************
LPSTR FindPCIVendorName(USHORT vendorid)
{
ULONG i;
for(i=0;i<DIM(PCIVendorIDs);i++)
{
if(vendorid == PCIVendorIDs[i].vendorid)
return PCIVendorIDs[i].vendor_name;
}
return NULL;
}
//*************************************************************************
// ShowPCI()
//
//*************************************************************************
COMMAND_PROTOTYPE(ShowPCI)
{
ULONG oldCF8,data,bus,dev,reg,i,ulNumBaseAddresses,bus_req=0,dev_req=0;
PCI_NUMBER pciNumber;
PCI_COMMON_CONFIG pciConfig,*ppciConfig;
PULONG p;
LPSTR pVendorName;
char temp[32];
BOOLEAN bShowAll = FALSE,bUseDev=TRUE,bUseBus=TRUE;
DPRINT((0,"ShowPCI()\n"));
if(pArgs->CountSwitches>1)
return TRUE;
if(pArgs->CountSwitches==1)
{
if(pArgs->Switch[0] == 'a')
bShowAll = TRUE;
}
if(pArgs->Count < 3)
{
if(pArgs->Count > 0)
{
bUseBus = FALSE;
bus_req = pArgs->Value[0];
}
if(pArgs->Count > 1)
{
bUseDev = FALSE;
dev_req = pArgs->Value[1];
}
// save old config space selector
oldCF8 = inl((PULONG)0xcf8);
for(bus=0;bus<256;bus++)
{
for(dev=0;dev<32;dev++)
{
if(!((bUseDev || dev == dev_req) &&
(bUseBus || bus == bus_req) ))
continue;
pciNumber.u.AsUlong = 0;
pciNumber.u.bits.dev = dev;
pciNumber.u.bits.bus = bus;
pciNumber.u.bits.func = 0;
pciNumber.u.bits.ce = 1;
outl(pciNumber.u.AsUlong,(PULONG)0xcf8);
data = inl((PULONG)0xcfc);
if(data != 0xFFFFFFFF) // valid device
{
if((pVendorName = FindPCIVendorName((USHORT)data)) )
{
PICE_sprintf(tempCmd,"Bus%-8uDev%-8u === %.4X %.4X %s ====\n",bus,dev,(USHORT)data,(USHORT)(data>>16),pVendorName);
}
else
{
PICE_sprintf(tempCmd,"Bus%-8uDev%-8u === %.4X %.4X N/A ====\n",bus,dev,(USHORT)data,(USHORT)(data>>16));
}
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)goto CommonShowPCIExit;
p = (PULONG)&pciConfig;
for(reg=0;reg<sizeof(PCI_COMMON_CONFIG)/sizeof(ULONG);reg++)
{
pciNumber.u.AsUlong = 0;
pciNumber.u.bits.dev = dev;
pciNumber.u.bits.bus = bus;
pciNumber.u.bits.func = 0;
pciNumber.u.bits.reg = reg;
pciNumber.u.bits.ce = 1;
outl(pciNumber.u.AsUlong,(PULONG)0xcf8);
*p++ = inl((PULONG)0xcfc);
}
PICE_sprintf(tempCmd,"SubVendorId %.4X SubSystemId %.4X\n",pciConfig.u.type0.SubVendorID,pciConfig.u.type0.SubSystemID);
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)goto CommonShowPCIExit;
if(bShowAll)
{
for(ulNumBaseAddresses=0,i=0;i<6;i++)
{
if(pciConfig.u.type0.BaseAddresses[i] != 0)
ulNumBaseAddresses++;
}
if(ulNumBaseAddresses)
{
Print(OUTPUT_WINDOW,"BaseAddresses:");
tempCmd[0] = 0;
for(i=0;i<6;i++)
{
if(pciConfig.u.type0.BaseAddresses[i] != 0)
{
PICE_sprintf(temp," %u:%.8X",i,pciConfig.u.type0.BaseAddresses[i]);
PICE_strcat(tempCmd,temp);
}
}
Print(OUTPUT_WINDOW,tempCmd);
Print(OUTPUT_WINDOW,"\n");
if(WaitForKey()==FALSE)goto CommonShowPCIExit;
}
ppciConfig = &pciConfig;
#if 0
// sedwards
SHOW_FIELD_WORD(ppciConfig,Status,TRUE);
SHOW_FIELD_WORD(ppciConfig,Command,TRUE);
SHOW_FIELD_BYTE(ppciConfig,RevisionID,TRUE);
SHOW_FIELD_BYTE(ppciConfig,ProgIf,TRUE);
SHOW_FIELD_BYTE(ppciConfig,BaseClass,TRUE);
SHOW_FIELD_BYTE(ppciConfig,SubClass,TRUE);
SHOW_FIELD_BYTE(ppciConfig,CacheLineSize,TRUE);
SHOW_FIELD_BYTE(ppciConfig,LatencyTimer,TRUE);
#endif
}
}
}
}
CommonShowPCIExit:
// restore old config space selector
outl(oldCF8,(PULONG)0xcf8);
}
else if(pArgs->Count == 1)
{
}
return TRUE;
}
//*************************************************************************
// SetKeyboardLayout()
//
//*************************************************************************
COMMAND_PROTOTYPE(SetKeyboardLayout)
{
PKEYBOARD_LAYOUT layout;
ENTER_FUNC();
layout = GetKeyboardLayout();
switch(pArgs->Count)
{
case 0:
PICE_sprintf(tempCmd,"current layout = %s\n", layout->name);
Print(OUTPUT_WINDOW,tempCmd);
break;
case 1:
layout = SetKeyboardLayoutByName((LPSTR)pArgs->Value[0]);
PICE_sprintf(tempCmd,"current layout = %s\n", layout->name);
Print(OUTPUT_WINDOW,tempCmd);
break;
}
LEAVE_FUNC();
return TRUE;
}
//*************************************************************************
// ShowSysCallTable()
//
//*************************************************************************
COMMAND_PROTOTYPE(ShowSysCallTable)
{
#if 0
LPSTR pName;
ULONG i;
ENTER_FUNC();
if(pArgs->Count == 0)
{
PICE_sprintf(tempCmd,"%u system calls\n",190);
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()!=FALSE)
for(i=0;i<190;i++)
{
if((pName = FindFunctionByAddress(sys_call_table[i],NULL,NULL)) )
{
PICE_sprintf(tempCmd,"%-.3u: %.8X (%s)\n",i,sys_call_table[i],pName);
}
else
{
PICE_sprintf(tempCmd,"%-.3u: %.8X (%s)\n",i,sys_call_table[i],pName);
}
Print(OUTPUT_WINDOW,tempCmd);
if(WaitForKey()==FALSE)
break;
}
}
else if(pArgs->Count == 1)
{
i = pArgs->Value[0];
if(i<190)
{
if((pName = FindFunctionByAddress(sys_call_table[i],NULL,NULL)) )
{
PICE_sprintf(tempCmd,"%-.3u: %.8X (%s)\n",i,sys_call_table[i],pName);
}
else
{
PICE_sprintf(tempCmd,"%-.3u: %.8X (%s)\n",i,sys_call_table[i],pName);
}
Print(OUTPUT_WINDOW,tempCmd);
}
}
LEAVE_FUNC();
#endif
PICE_sprintf(tempCmd,"Not implemented yet!\n");
Print(OUTPUT_WINDOW,tempCmd);
return TRUE;
}
//*************************************************************************
// SetAltKey()
//
//*************************************************************************
COMMAND_PROTOTYPE(SetAltKey)
{
if(pArgs->Count == 1)
{
ucBreakKey = (UCHAR)pArgs->Value[0];
PICE_sprintf(tempCmd,"new break key is CTRL-%c\n",ucBreakKey);
Print(OUTPUT_WINDOW,tempCmd);
}
else if(pArgs->Count == 0)
{
PICE_sprintf(tempCmd,"current break key is CTRL-%c\n",ucBreakKey);
Print(OUTPUT_WINDOW,tempCmd);
}
COMMAND_RET;
}
//*************************************************************************
// ShowContext()
//
//*************************************************************************
COMMAND_PROTOTYPE(ShowContext)
{
COMMAND_RET;
}
//*************************************************************************
//
// utility functions for parsing
//
//*************************************************************************
//*************************************************************************
// FindCommand()
//
//*************************************************************************
LPSTR FindCommand(LPSTR p)
{
ULONG i,j,k=0;
LPSTR result=NULL;
tempCmd[0]=0;
for(j=0,i=0;CmdTable[i].Cmd!=NULL;i++)
{
if(PICE_strncmpi(CmdTable[i].Cmd,p,PICE_strlen(p)) == 0 &&
CmdTable[i].CommandGroup != COMMAND_GROUP_HELP_ONLY)
{
if(PICE_strlen(tempCmd))
PICE_strcat(tempCmd,", ");
PICE_strcat(tempCmd,CmdTable[i].Cmd);
j++;
k=i;
}
}
if(PICE_strlen(tempCmd))
{
SetBackgroundColor(COLOR_CAPTION);
SetForegroundColor(COLOR_TEXT);
ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
PutChar(tempCmd,1,wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
if(j==1)
{
PICE_sprintf(tempCmd,"%s",CmdTable[k].Help);
PutChar(tempCmd,40,wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
result=CmdTable[k].Cmd;
}
ResetColor();
}
return result;
}
//*************************************************************************
// CompactString()
//
//*************************************************************************
void CompactString(LPSTR p)
{
ULONG i;
for(i=1;i<PICE_strlen(p);i++)
{
if(p[i]==' ' && p[i-1]==' ')
{
PICE_strcpy(&p[i-1],&p[i]);
i=1;
}
}
}
//*************************************************************************
// PICE_strtok()
//
//*************************************************************************
char* PICE_strtok(char *szInputString)
{
static char* szCurrString;
char *szTempString;
ULONG currlength;
ULONG i;
if(szInputString)
{
szCurrString=szInputString;
CompactString(szCurrString);
}
currlength=PICE_strlen(szCurrString);
if(!currlength)
{
szCurrString=0;
return NULL;
}
for(i=0;i<currlength;i++)
{
if(szCurrString[i]==' ')
{
szCurrString[i]=0;
break;
}
}
szTempString=szCurrString;
szCurrString=szCurrString+i+1;
return szTempString;
}
//*************************************************************************
// ConvertTokenToHex()
//
//*************************************************************************
BOOLEAN ConvertTokenToHex(LPSTR p,PULONG pValue)
{
ULONG result=0,i;
gCurrentSelector=0;
gCurrentOffset=0;
for(i=0;i<8 && p[i]!=0 && p[i]!=' ' && p[i]!=':';i++)
{
if(p[i]>='0' && p[i]<='9')
{
result<<=4;
result|=(ULONG)(UCHAR)(p[i]-'0');
}
else if(p[i]>='A' && p[i]<='F')
{
result<<=4;
result|=(ULONG)(UCHAR)(p[i]-'A'+10);
}
else if(p[i]>='a' && p[i]<='f')
{
result<<=4;
result|=(ULONG)(UCHAR)(p[i]-'a'+10);
}
else
return FALSE;
}
p+=(i+1);
if(p[i]==':')
{
ULONG ulSelector=result;
if(ulSelector>0xFFFF)
return FALSE;
for(i=0;i<8 && p[i]!=0 && p[i]!=' ' && p[i]!=':';i++)
{
if(p[i]>='0' && p[i]<='9')
{
result<<=4;
result|=(ULONG)(UCHAR)(p[i]-'0');
}
else if(p[i]>='A' && p[i]<='F')
{
result<<=4;
result|=(ULONG)(UCHAR)(p[i]-'A'+10);
}
else if(p[i]>='a' && p[i]<='f')
{
result<<=4;
result|=(ULONG)(UCHAR)(p[i]-'a'+10);
}
else
return FALSE;
}
gCurrentSelector=(USHORT)ulSelector;
gCurrentOffset=result;
result = GetLinearAddress((USHORT)ulSelector,result);
}
*pValue=result;
return TRUE;
}
//*************************************************************************
// ConvertTokenToDec()
//
//*************************************************************************
BOOLEAN ConvertTokenToDec(LPSTR p,PULONG pValue)
{
ULONG result=0;
char c;
while((c = *p))
{
if(c >= '0' && c <= '9')
{
result *= 10;
result += (ULONG)(c - '0');
}
else
return FALSE;
p++;
}
*pValue = result;
return TRUE;
}
//*************************************************************************
// ConvertTokenToSymbol()
//
//*************************************************************************
BOOLEAN ConvertTokenToSymbol(LPSTR pToken,PULONG pValue)
{
LPSTR pEx;
char temp[64];
LPSTR p;
PDEBUG_MODULE pModFound;
DPRINT((0,"ConvertTokenToSymbol()\n"));
PICE_strcpy(temp,pToken);
p = temp;
// test for module!symbol string
pEx = PICE_strchr(p,'!');
if(pEx)
{
DPRINT((0,"ConvertTokenToSymbol(): module!symbol syntax detected\n"));
// terminate module name
*pEx = 0;
// now we have two pointers
pEx++;
DPRINT((0,"ConvertTokenToSymbol(): module = %s symbol = %s\n",p,pEx));
if( pModFound=IsModuleLoaded(p) )
{
if((*pValue = FindFunctionInModuleByName(pEx,pModFound)))
return TRUE;
}
}
else
{
if(pCurrentMod)
{
if((*pValue = FindFunctionInModuleByName(p,pCurrentMod)))
return TRUE;
}
return ScanExports(p,pValue);
}
return FALSE;
}
//*************************************************************************
// ConvertTokenToModuleAndName()
//
//*************************************************************************
BOOLEAN ConvertTokenToModuleAndName(LPSTR pToken,PULONG pulModuleName,PULONG pulFunctionName)
{
LPSTR pEx;
char temp[64];
LPSTR p;
static char module_name[128];
static char function_name[128];
// test for module!symbol string
PICE_strcpy(temp,pToken);
p = temp;
DPRINT((0,"ConvertTokenToModuleAndName(%s)\n",p));
pEx = PICE_strchr(p,'!');
if(pEx)
{
DPRINT((0,"ConvertTokenToModuleAndName(): module!symbol syntax detected\n"));
// terminate module name
*pEx = 0;
// now we have two pointers
pEx++;
DPRINT((0,"ConvertTokenToModuleAndName(): module = %s symbol = %s\n",p,pEx));
PICE_strcpy(module_name,p);
PICE_strcpy(function_name,pEx);
*pulModuleName = (ULONG)module_name;
*pulFunctionName = (ULONG)function_name;
return TRUE;
}
return FALSE;
}
//*************************************************************************
// ConvertTokenToModule()
//
// convert an argument module name to a pointer to the module's symbols
//*************************************************************************
BOOLEAN ConvertTokenToModule(LPSTR p,PULONG pValue)
{
ULONG i;
char temp[DEBUG_MODULE_NAME_LEN];
for(i=0;i<DIM(apSymbols);i++)
{
if(apSymbols[i])
{
CopyWideToAnsi(temp,apSymbols[i]->name);
if(PICE_strcmpi(p,temp)==0)
{
*pValue = (ULONG)apSymbols[i];
return TRUE;
}
}
}
for(i=0;i<DIM(apSymbols);i++)
{
if(apSymbols[i])
{
CopyWideToAnsi(temp,apSymbols[i]->name);
if(PICE_strncmpi(temp,p,PICE_strlen(p))==0)
{
*pValue = (ULONG)apSymbols[i];
return TRUE;
}
}
}
return FALSE;
}
//*************************************************************************
// ConvertTokenToProcess()
//
//*************************************************************************
BOOLEAN ConvertTokenToProcess(LPSTR p,PULONG pValue)
{
return FALSE;
}
//*************************************************************************
// ReplaceKeywordWithValue()
//
//*************************************************************************
BOOLEAN ReplaceKeywordWithValue(LPSTR p,PULONG pValue,KEYWORDS* pKeyWords)
{
ULONG i;
for(i=0;pKeyWords[i].KeyWord!=NULL;i++)
{
if(PICE_strcmpi(p,pKeyWords[i].KeyWord)==0)
{
switch(pKeyWords[i].ulSize)
{
case sizeof(USHORT):
*pValue=(ULONG)*(PUSHORT)(pKeyWords[i].pValue);
break;
case sizeof(ULONG):
*pValue=*(PULONG)(pKeyWords[i].pValue);
break;
}
return TRUE;
}
}
return FALSE;
}
//*************************************************************************
// ConvertTokenToKeyword()
//
//*************************************************************************
BOOLEAN ConvertTokenToKeyword(LPSTR p,PULONG pValue)
{
char Name[256];
ULONG count;
DPRINT((0,"ConvertTokenToKeyword()\n"));
count=StrLenUpToWhiteChar(p," ");
PICE_strncpy(Name,p,count);
Name[count]=0;
if(ReplaceKeywordWithValue(Name,pValue,RegKeyWords))
{
DPRINT((0,"ConvertTokenToKeyword(): success\n"));
return TRUE;
}
return FALSE;
}
//*************************************************************************
// ConvertTokenToSpecialKeyword()
//
//*************************************************************************
BOOLEAN ConvertTokenToSpecialKeyword(LPSTR p,PULONG pValue)
{
char Name[256];
ULONG count;
count=StrLenUpToWhiteChar(p," ");
PICE_strncpy(Name,p,count);
Name[count]=0;
if(ReplaceKeywordWithValue(Name,pValue,SpecialKeyWords))
{
return TRUE;
}
return FALSE;
}
//*************************************************************************
// ConvertTokenToOnOff()
//
//*************************************************************************
BOOLEAN ConvertTokenToOnOff(LPSTR p,PULONG pValue)
{
char Name[256];
ULONG count;
count=StrLenUpToWhiteChar(p," ");
PICE_strncpy(Name,p,count);
Name[count]=0;
if(ReplaceKeywordWithValue(Name,pValue,OnOffKeyWords))
{
return TRUE;
}
return FALSE;
}
//*************************************************************************
// ConvertSizeToKeyword()
//
//*************************************************************************
BOOLEAN ConvertSizeToKeyword(LPSTR p,PULONG pValue)
{
ULONG count;
count=StrLenUpToWhiteChar(p," ");
if(count > 1)
return FALSE;
switch(*p)
{
// BYTE
case 'b':
case 'B':
*pValue = 1;
break;
// WORD
case 'w':
case 'W':
*pValue = 2;
break;
// DWORD
case 'd':
case 'D':
*pValue = 4;
break;
// QWORD
case 'q':
case 'Q':
*pValue = 4;
break;
default:
return FALSE;
}
return TRUE;
}
//*************************************************************************
// ConvertTokenToSrcFile()
//
//*************************************************************************
BOOLEAN ConvertTokenToSrcFile(LPSTR p,PULONG pValue)
{
PICE_SYMBOLFILE_SOURCE* pSrc;
LPSTR pFilename,pFilenameSrc;
ULONG i;
DPRINT((0,"ConvertTokenToSrcFile(%s)\n",p));
if(pCurrentSymbols && pCurrentSymbols->ulNumberOfSrcFiles)
{
DPRINT((0,"ConvertTokenToSrcFile(): current symbols for %S\n",pCurrentSymbols->name));
pSrc = (PICE_SYMBOLFILE_SOURCE*)((ULONG)pCurrentSymbols + pCurrentSymbols->ulOffsetToSrcFiles);
for(i=0;i<pCurrentSymbols->ulNumberOfSrcFiles;i++)
{
pFilename = strrchr(pSrc->filename,'/');
if(!pFilename)
pFilename = pSrc->filename;
else
pFilename++;
pFilenameSrc = strrchr(p,'/');
if(!pFilenameSrc )
pFilenameSrc = p;
else
pFilenameSrc++;
DPRINT((0,"ConvertTokenToSrcFile(): %s\n",pFilename));
if(PICE_strcmpi(pFilename,pFilenameSrc) == 0)
{
DPRINT((0,"ConvertTokenToSrcFile(): found %s\n",pFilename));
*pValue = (ULONG)pSrc;
return TRUE;
}
// go to next file
(LPSTR)pSrc += pSrc->ulOffsetToNext;
}
pSrc = (PICE_SYMBOLFILE_SOURCE*)((ULONG)pCurrentSymbols + pCurrentSymbols->ulOffsetToSrcFiles);
// if not found now do a lookup for partials
for(i=0;i<pCurrentSymbols->ulNumberOfSrcFiles;i++)
{
pFilename = strrchr(pSrc->filename,'/');
if(!pFilename)
pFilename = pSrc->filename;
else
pFilename++;
DPRINT((0,"ConvertTokenToSrcFile(): %s\n",pFilename));
if(PICE_strncmpi(pFilename,p,PICE_strlen(p)) == 0)
{
DPRINT((0,"ConvertTokenToSrcFile(): found %s\n",pFilename));
*pValue = (ULONG)pSrc;
return TRUE;
}
// go to next file
(LPSTR)pSrc += pSrc->ulOffsetToNext;
}
}
return FALSE;
}
//*************************************************************************
// ConvertTokenToLineNumber()
//
//*************************************************************************
BOOLEAN ConvertTokenToLineNumber(LPSTR p,PULONG pValue)
{
ULONG ulDecimal;
DPRINT((0,"ConvertTokenToLineNumber()\n"));
if(*p++ == '.')
{
ulDecimal = ExtractNumber(p);
DPRINT((0,"ConvertTokenToLineNumber(): ulDecimal = %u\n",ulDecimal));
if(ulDecimal)
{
DPRINT((0,"ConvertTokenToLineNumber(): current file = %s\n",szCurrentFile));
if(pCurrentMod && PICE_strlen(szCurrentFile))
{
DPRINT((0,"ConvertTokenToLineNumber(): current file %S\n",pCurrentMod->name));
if(FindAddressForSourceLine(ulDecimal,szCurrentFile,pCurrentMod,pValue))
{
DPRINT((0,"ConvertTokenToLineNumber(): value = %x\n",*pValue));
return TRUE;
}
}
}
}
return FALSE;
}
//*************************************************************************
// IsWhiteChar()
//
//*************************************************************************
BOOLEAN IsWhiteChar(char c,LPSTR WhiteChars)
{
USHORT lenWhiteChar = PICE_strlen(WhiteChars);
USHORT i;
for(i=0;i<lenWhiteChar;i++)
{
if(c == WhiteChars[i])
return TRUE;
}
return FALSE;
}
//*************************************************************************
// StrLenUpToWhiteChar()
//
//*************************************************************************
ULONG StrLenUpToWhiteChar(LPSTR p,LPSTR WhiteChars)
{
ULONG i;
for(i=0;p[i]!=0 && !IsWhiteChar(p[i],WhiteChars);i++);
return i;
}
//
// command line parser
//
void Parse(LPSTR pCmdLine,BOOLEAN bInvokedByFkey)
{
ULONG i,j;
BOOLEAN result=FALSE;
char *pToken;
ARGS Arguments;
CMDTABLE *pCurrentCommand=NULL;
ulCountForWaitKey = 0;
if(!bInvokedByFkey)
{
ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].usCurY);
}
PICE_memset(&Arguments,0,sizeof(ARGS));
for(j=0,i=0;CmdTable[i].Cmd!=NULL;i++)
{
if(PICE_strncmpi(CmdTable[i].Cmd,pCmdLine,PICE_strlen(CmdTable[i].Cmd))==0 &&
PICE_strlen(CmdTable[i].Cmd)==StrLenUpToWhiteChar(pCmdLine," ") &&
CmdTable[i].CommandGroup != COMMAND_GROUP_HELP_ONLY)
{
pCurrentCommand=&CmdTable[i];
break;
}
}
if(pCurrentCommand==NULL)
{
Print(OUTPUT_WINDOW," <-- command not found\n");
Print(OUTPUT_WINDOW,":");
goto CommonParseReturnPoint;
}
pToken = PICE_strtok( pCmdLine);
// get the args and convert them into numbers
i=0;
j=0;
do
{
pToken=PICE_strtok( NULL);
DPRINT((0,"pToken = %s\n",pToken));
if(pToken)
{
if(*pToken == '-' && PICE_strlen(pToken)==2)
{
DPRINT((0,"might be a switch\n"));
if(pCurrentCommand->Flags & COMMAND_HAS_SWITCHES)
{
// token starts with '-' and is 2 chars long
// must be a switch
if(PICE_strchr(pCurrentCommand->pszRecognizedSwitches,*(pToken+1)) )
{
DPRINT((0,"is a switch!\n"));
Arguments.Switch[j++]=*(pToken+1);
continue;
}
// not a valid switch
else
{
PICE_sprintf(tempCmd," <-- %s is not a valid switch\n",pToken);
Print(OUTPUT_WINDOW,tempCmd);
Print(OUTPUT_WINDOW,":");
goto CommonParseReturnPoint;
}
}
else
{
PICE_sprintf(tempCmd," <-- %s can't have any switches\n",pCurrentCommand->Cmd);
Print(OUTPUT_WINDOW,tempCmd);
Print(OUTPUT_WINDOW,":");
goto CommonParseReturnPoint;
}
}
if(pCurrentCommand->Flags & COMMAND_HAS_PARAMS)
{
if(!pCurrentCommand->ParamFlags[i])
{
PICE_sprintf(tempCmd," <-- %s can't have more than %u parameters\n",pCurrentCommand->Cmd,i);
Print(OUTPUT_WINDOW,tempCmd);
Print(OUTPUT_WINDOW,":");
goto CommonParseReturnPoint;
}
DPRINT((0,"Parse(): PARAM_CAN_BE_SRCLINE\n"));
if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_SRCLINE)
{
if(ConvertTokenToLineNumber(pToken,&Arguments.Value[i]))
{
i++;
continue;
}
if(*pToken == '.')
{
PICE_sprintf(tempCmd," <-- no line number %s found\n",pToken);
Print(OUTPUT_WINDOW,tempCmd);
Print(OUTPUT_WINDOW,":");
goto CommonParseReturnPoint;
}
}
DPRINT((0,"Parse(): PARAM_CAN_BE_NUMERIC\n"));
if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_NUMERIC)
{
if(ConvertTokenToHex(pToken,&Arguments.Value[i]))
{
i++;
continue;
}
}
DPRINT((0,"Parse(): PARAM_CAN_BE_DECIMAL\n"));
if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_DECIMAL)
{
if(ConvertTokenToDec(pToken,&Arguments.Value[i]))
{
i++;
continue;
}
}
DPRINT((0,"Parse(): PARAM_CAN_BE_REG_KEYWORD\n"));
if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_REG_KEYWORD)
{
if(ConvertTokenToKeyword(pToken,&Arguments.Value[i]))
{
Arguments.pToken[i] = pToken;
i++;
continue;
}
}
DPRINT((0,"Parse(): PARAM_CAN_BE_SYMBOLIC\n"));
if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_SYMBOLIC)
{
if(ConvertTokenToSymbol(pToken,&Arguments.Value[i]))
{
i++;
continue;
}
}
DPRINT((0,"Parse(): PARAM_CAN_BE_VIRTUAL_SYMBOLIC\n"));
if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_VIRTUAL_SYMBOLIC)
{
DPRINT((0,"might be a virtual modname!symbol syntax!\n"));
if(ConvertTokenToModuleAndName(pToken,&Arguments.Value[i],&Arguments.Value[i+1]))
{
Arguments.bNotTranslated[i]=TRUE;
Arguments.bNotTranslated[i+1]=TRUE;
i+=2;
continue;
}
}
DPRINT((0,"Parse(): PARAM_CAN_BE_MODULE\n"));
if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_MODULE)
{
if(ConvertTokenToModule(pToken,&Arguments.Value[i]))
{
i++;
continue;
}
}
DPRINT((0,"Parse(): PARAM_CAN_BE_PRNAME\n"));
if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_PRNAME)
{
if(ConvertTokenToProcess(pToken,&Arguments.Value[i]))
{
i++;
continue;
}
}
DPRINT((0,"Parse(): PARAM_CAN_BE_SRC_FILE\n"));
if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_SRC_FILE)
{
if(ConvertTokenToSrcFile(pToken,&Arguments.Value[i]))
{
i++;
continue;
}
}
DPRINT((0,"Parse(): PARAM_CAN_BE_ASTERISK\n"));
if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_ASTERISK)
{
if(PICE_strlen(pToken)==1 && pToken[0]=='*')
{
Arguments.Value[i]=-1;
i++;
continue;
}
}
DPRINT((0,"Parse(): PARAM_CAN_BE_LETTER\n"));
if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_LETTER)
{
if(PICE_strlen(pToken)==1 && PICE_isprint(pToken[0]))
{
Arguments.Value[i]=(ULONG)pToken[0];
i++;
continue;
}
}
DPRINT((0,"Parse(): PARAM_CAN_BE_ONOFF\n"));
if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_ONOFF)
{
if(ConvertTokenToOnOff(pToken,&Arguments.Value[i]))
{
i++;
continue;
}
}
DPRINT((0,"Parse(): PARAM_CAN_BE_PARTIAL_SYM_NAME\n"));
if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_PARTIAL_SYM_NAME)
{
Arguments.Value[i] = (ULONG)pToken;
i++;
continue;
}
DPRINT((0,"Parse(): PARAM_CAN_BE_ANY_STRING\n"));
if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_ANY_STRING)
{
Arguments.Value[i] = (ULONG)pToken;
i++;
continue;
}
DPRINT((0,"Parse(): PARAM_CAN_BE_SIZE_DESC\n"));
if(pCurrentCommand->ParamFlags[i] & PARAM_CAN_BE_SIZE_DESC)
{
if(ConvertSizeToKeyword(pToken,&Arguments.Value[i]))
{
Arguments.pToken[i] = pToken;
i++;
continue;
}
}
PICE_sprintf(tempCmd," <-- syntax error in parameter %u!\n",i);
Print(OUTPUT_WINDOW,tempCmd);
Print(OUTPUT_WINDOW,":");
goto CommonParseReturnPoint;
}
else
{
PICE_sprintf(tempCmd," <-- %s has no parameters\n",pCurrentCommand->Cmd);
Print(OUTPUT_WINDOW,tempCmd);
Print(OUTPUT_WINDOW,":");
goto CommonParseReturnPoint;
}
// next token
i++;
}
}while(pToken && i<MAX_ARGS);
Arguments.Count=i;
Arguments.CountSwitches=j;
if(pCurrentCommand)
{
DPRINT((0,"Parse(): command %s switches %u\n",pCurrentCommand->Cmd,Arguments.CountSwitches));
if(!bInvokedByFkey)
{
DPRINT((0,"Parse(): adding new line\n"));
Print(OUTPUT_WINDOW,"\n");
}
// call the command handler
result=pCurrentCommand->Handler(&Arguments);
if(result && !bInvokedByFkey && pCurrentCommand->Handler!=LeaveIce && pCurrentCommand->Handler!=SingleStep )
{
DPRINT((0,"Parse(): adding colon\n"));
Print(OUTPUT_WINDOW,":");
}
}
CommonParseReturnPoint:
SuspendPrintRingBuffer(FALSE);
PrintRingBuffer(wWindow[OUTPUT_WINDOW].cy-1);
ShowStatusLine();
}