home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 230.lha / SPY / Sources / Snoop.Mod < prev    next >
Text File  |  1989-04-08  |  11KB  |  360 lines

  1. IMPLEMENTATION MODULE Snoop;
  2.  
  3.         (************************************************)
  4.         (*    Snoop : The core of the Spy program       *)
  5.         (*                                              *)
  6.         (*  Written by Steve Faiwiszewski,   June 1988  *)
  7.         (*                                              *)
  8.         (*   Not to be used for commercial purpose      *)
  9.         (************************************************)
  10.  
  11. FROM IntuiCommon IMPORT OpenSimpleWindow;
  12. FROM Conversions IMPORT ConvStringToNumber, ConvNumberToString;
  13. FROM TermInOut   IMPORT WriteLn, WriteString, WriteCard, Write;
  14. FROM Strings     IMPORT StringLength;
  15. FROM Tasks       IMPORT Task, TaskPtr, CurrentTask, TaskState,
  16.                         FindTask, SignalSet, Wait;
  17. FROM Interrupts  IMPORT Forbid, Permit;
  18. FROM Nodes       IMPORT Node, NodePtr, NTProcess;
  19. FROM Ports       IMPORT MsgPortPtr, GetMsg, ReplyMsg, WaitPort,
  20.                         MessagePtr;
  21. FROM Text        IMPORT Text, TextLength;
  22. FROM Drawing     IMPORT Move, Draw, SetAPen, SetBPen,
  23.                         WritePixel, RectFill;
  24. FROM Rasters     IMPORT RastPortPtr;
  25. FROM Intuition   IMPORT WindowFlags, WindowFlagsSet,
  26.                         IDCMPFlagsSet, IDCMPFlags,
  27.                         WindowPtr, CloseWindow,
  28.                         SetWindowTitles, IntuiMessagePtr;
  29. FROM AmigaDOSProcess
  30.                  IMPORT ProcessPtr, Delay;
  31. FROM AmigaDOSExt IMPORT CommandLineInterfacePtr;
  32. FROM SYSTEM      IMPORT ADDRESS, ADR, WORD, LONGWORD, BYTE,
  33.                         TSIZE;
  34.  
  35. CONST
  36.     MaxStringSize = 26;
  37.     LetterHeight = 9;
  38.     HorizOffs = 9;
  39.  
  40. TYPE
  41.     LongPtr = POINTER TO LONGCARD;
  42.     WordPtr = POINTER TO WORD;
  43.  
  44.     StringPointer = POINTER TO ARRAY[0..255] OF CHAR;
  45.     CoordRec = RECORD
  46.                 X,Y : CARDINAL;
  47.                END;
  48.     RegRec = RECORD
  49.                 Value : LONGWORD;
  50.                 Name  : ARRAY[0..2] OF CHAR;
  51.                 Loc   : CoordRec;
  52.              END;
  53. VAR
  54.     rPort : RastPortPtr;
  55.     CurLine : CARDINAL;
  56.     Regs : ARRAY[0..14] OF RegRec;
  57.     PcLoc,
  58.     SrLoc,
  59.     StateLoc,
  60.     ProcNameLoc,
  61.     TaskNameLoc : CoordRec;
  62.     WindowTitleString : ARRAY[0..26] OF CHAR;
  63.     TaskIsProcess : BOOLEAN;
  64.     CmdLineLenPtr : POINTER TO BYTE;
  65.     CmdLineStrPtr : StringPointer;
  66.  
  67.  
  68. (* +++++++++++++++++++++++++++++++++++++++++++++++++++++ *)
  69. PROCEDURE NewLine;
  70. BEGIN
  71.     INC(CurLine,LetterHeight);
  72.     Move(rPort^,HorizOffs,CurLine);
  73. END NewLine;
  74.  
  75.  
  76. (* +++++++++++++++++++++++++++++++++++++++++++++++++++++ *)
  77. PROCEDURE ClearLine(X,Y : CARDINAL);
  78. BEGIN
  79.     SetAPen(rPort^,0);
  80.     RectFill(rPort^,X,Y+2-LetterHeight,WIDTH-3,Y);
  81.     SetAPen(rPort^,1);
  82. END ClearLine;
  83.  
  84.  
  85. (* +++++++++++++++++++++++++++++++++++++++++++++++++++++ *)
  86. (*$D-*) (* all arguments are really passed by reference *)
  87.         (* for efficiency *)
  88. PROCEDURE SetupString(Str : ARRAY OF CHAR;
  89.                       VAR Coord : CoordRec; NL : BOOLEAN);
  90. VAR length : CARDINAL;
  91. BEGIN
  92.     length := StringLength(Str);
  93.     Text(rPort^,ADR(Str), length);
  94.     Coord.X := TextLength(rPort^,ADR(Str), length);
  95.     Coord.Y := CurLine;
  96.     IF NL THEN NewLine END;
  97. END SetupString;
  98. (*$D+*) (* go back to normal parameter passing *)
  99.  
  100.  
  101. (* +++++++++++++++++++++++++++++++++++++++++++++++++++++ *)
  102. PROCEDURE IsItAprocess(TargetTask : TaskPtr) : BOOLEAN;
  103. (* Check if the target task is also a process.  If that *)
  104. (* is so, then get the pointer to the process name.     *)
  105. VAR
  106.     pp : ProcessPtr;
  107.     CliPtr : CommandLineInterfacePtr;
  108. BEGIN
  109.     IF CHAR(TargetTask^.tcNode.lnType) = CHAR(NTProcess) THEN
  110.         pp := ProcessPtr(TargetTask);
  111.         IF pp^.prCLI <> NIL THEN
  112.             CliPtr := ADDRESS(LONGCARD(pp^.prCLI)*4D);
  113.             CmdLineLenPtr := 
  114.                 ADDRESS(LONGCARD(CliPtr^.cliCommandName) * 4D);
  115.             CmdLineStrPtr :=
  116.                 ADDRESS(LONGCARD(CmdLineLenPtr) + 1D);
  117.             RETURN TRUE
  118.         END;
  119.     END;
  120.     RETURN FALSE
  121. END IsItAprocess;
  122.  
  123.  
  124. (* +++++++++++++++++++++++++++++++++++++++++++++++++++++ *)
  125. PROCEDURE SetupWindow(TargetTask : TaskPtr);
  126. (* Create the text for all the fields that will be         *)
  127. (* displayed.  Keep track of their location in the window. *)
  128. CONST
  129.     TaskNameStr = 'Task Name:  ';
  130.     ProcNameStr = 'Proc Name:  ';
  131.     StateStr = 'State:  ';
  132.     PcStr = 'PC:  ';
  133.     SrStr = 'SR:  ';
  134.     SpaceStr = '          ';
  135.     ColonStr = ':  ';
  136. VAR
  137.     i,tmp,
  138.     length : CARDINAL;
  139.     DummyLoc : CoordRec;
  140.     HexStr : ARRAY[0..7] OF CHAR;
  141. BEGIN
  142.     WindowTitleString := 'Spying on Task 0x????????';
  143.     ConvNumberToString(HexStr,TargetTask,FALSE,16,8,'0');
  144.     FOR i := 0 TO 7 DO
  145.         WindowTitleString[i+17] := HexStr[i]
  146.     END;
  147.     SetWindowTitles(SpyWindow^,ADR(WindowTitleString),
  148.                 ADR('Spy, written by Steve Faiwiszewski'));
  149.     rPort := SpyWindow^.RPort;
  150.     CurLine := 17;
  151.     SetAPen(rPort^,0);
  152.     SetBPen(rPort^,0);
  153.     RectFill(rPort^,5,10,WIDTH-3,HEIGHT-2);
  154.     SetAPen(rPort^,1);
  155.     Move(rPort^,HorizOffs,CurLine);
  156.     SetupString(TaskNameStr,TaskNameLoc,TRUE);
  157.     TaskIsProcess := IsItAprocess(TargetTask);
  158.     IF TaskIsProcess THEN
  159.         SetupString(ProcNameStr,ProcNameLoc,TRUE);
  160.     END;
  161.     SetupString(StateStr,StateLoc,TRUE);
  162.     SetupString(PcStr,PcLoc,TRUE);
  163.     SetupString(SrStr,SrLoc,TRUE);
  164.     length := StringLength(SpaceStr);
  165.     tmp := TextLength(rPort^,ADR(SpaceStr), length);
  166.     FOR i := 0 TO 7 DO
  167.         WITH Regs[i] DO
  168.             SetupString(Name,Loc,FALSE);
  169.             SetupString(ColonStr,DummyLoc,FALSE);
  170.             INC(Loc.X,DummyLoc.X);
  171.         END;
  172.         IF i < 7 THEN
  173.             WITH Regs[i+8] DO
  174.                 Text(rPort^,ADR(SpaceStr), length);
  175.                 SetupString(Name,Loc,FALSE);
  176.                 SetupString(ColonStr,DummyLoc,TRUE);
  177.                 Loc.X :=
  178.                     Loc.X + tmp + Regs[i].Loc.X + DummyLoc.X;
  179.             END
  180.         END;
  181.     END;
  182. END SetupWindow;
  183.  
  184.  
  185. (* +++++++++++++++++++++++++++++++++++++++++++++++++++++ *)
  186. PROCEDURE ShowProcessName;
  187. VAR
  188.     length : CARDINAL;
  189.     CharPtr : StringPointer;
  190. BEGIN
  191.     IF CHAR(CmdLineLenPtr^) = 0C THEN
  192.         CharPtr := ADR('(No Command)');
  193.         length := 12;
  194.     ELSE
  195.         CharPtr := CmdLineStrPtr;
  196.         length := CARDINAL(CmdLineLenPtr^)
  197.     END;
  198.     IF length > MaxStringSize THEN
  199.         length := MaxStringSize
  200.     END;
  201.     WITH ProcNameLoc DO
  202.         ClearLine(X,Y);
  203.         Move(rPort^,X,Y);
  204.     END;
  205.     Text(rPort^,CharPtr, length);
  206. END ShowProcessName;
  207.  
  208.  
  209. (* +++++++++++++++++++++++++++++++++++++++++++++++++++++ *)
  210. PROCEDURE ShowTaskName(CharPtr : StringPointer);
  211. VAR
  212.     length : CARDINAL;
  213.  
  214. BEGIN
  215.     length := StringLength(CharPtr^);
  216.     IF length > MaxStringSize THEN
  217.         length := MaxStringSize
  218.     END;
  219.     WITH TaskNameLoc DO
  220.         ClearLine(X,Y);
  221.         Move(rPort^,X,Y);
  222.     END;
  223.     Text(rPort^,CharPtr, length);
  224. END ShowTaskName;
  225.  
  226.  
  227. (* +++++++++++++++++++++++++++++++++++++++++++++++++++++ *)
  228. PROCEDURE ShowTaskState(tstate : TaskState);
  229. BEGIN
  230.     WITH StateLoc DO
  231.         ClearLine(X,Y);
  232.         Move(rPort^,X,Y);
  233.     END;
  234.     CASE tstate OF
  235.         TSInvalid : Text(rPort^,ADR('Invalid '),8)      |
  236.         TSAdded   : Text(rPort^,ADR('Added '),6)        |
  237.         TSRun     : Text(rPort^,ADR('Run '),4)          |
  238.         TSReady   : Text(rPort^,ADR('Ready '),6)        |
  239.         TSWait    : Text(rPort^,ADR('Wait '),5)         |
  240.         TSExcept  : Text(rPort^,ADR('Except '),7)       |
  241.         TSRemoved : Text(rPort^,ADR('Removed '),8)
  242.     END;
  243. END ShowTaskState;
  244.  
  245.  
  246. (* +++++++++++++++++++++++++++++++++++++++++++++++++++++ *)
  247. PROCEDURE Spy(target : TaskPtr);
  248. (* This is the actual code that looks up all the info   *)
  249. (* on the given task, and then displays it.             *)
  250. VAR
  251.     Str   : ARRAY[0..8] OF CHAR;
  252.     mp    : IntuiMessagePtr;
  253.     tstate: TaskState;
  254.     Stack : LongPtr;
  255.     stack2: WordPtr;
  256.     i     : CARDINAL;
  257.     stop  : BOOLEAN;
  258.     pc,sr : LONGWORD;
  259.     CharPtr : StringPointer;
  260. BEGIN
  261.     REPEAT
  262.         stop := FALSE;
  263. (* Get all important info, but first make sure the rug  *)
  264. (* doesn't get pulled from under our feet.              *)
  265.         Forbid;
  266.         WITH target^ DO
  267.             CharPtr := tcNode.lnName;
  268.             tstate := TaskState(tcState);
  269.             Stack := tcSPReg;
  270.             pc := Stack^;
  271.             stack2 := WordPtr(LONGCARD(Stack) + 4D);
  272.             sr := LONGWORD(stack2^);
  273.             Stack := LongPtr(LONGCARD(Stack) + 6D);
  274.             FOR i := 0 TO 14 DO
  275.                 Regs[i].Value := Stack^;
  276.                 Stack := LongPtr(LONGCARD(Stack) + 4D);
  277.             END;
  278.         END; (* with *)
  279.         Permit; (* got everything we needed! *)
  280.         ShowTaskName(CharPtr);
  281.         IF TaskIsProcess THEN
  282.             ShowProcessName;
  283.         END;
  284.         ShowTaskState(tstate);
  285. (* Display the Program Counter  *)
  286.         Move(rPort^,PcLoc.X,PcLoc.Y);
  287.         ConvNumberToString(Str,pc,FALSE,16,8,'0');
  288.         Text(rPort^,ADR(Str),8);
  289. (* Display the Status Register *)
  290.         Move(rPort^,SrLoc.X,SrLoc.Y);
  291.         ConvNumberToString(Str,sr,FALSE,16,4,'0');
  292.         Text(rPort^,ADR(Str),4);
  293. (* Display all other registers *)
  294.         FOR i := 0 TO 14 DO
  295.             WITH Regs[i] DO
  296.                 Move(rPort^,Loc.X,Loc.Y);
  297.                 ConvNumberToString(Str,Value,FALSE,16,8,'0');
  298.                 Text(rPort^,ADR(Str),8);
  299.             END;
  300.         END;
  301.  
  302.         mp := GetMsg(SpyWindow^.UserPort^);
  303.         IF mp <> NIL THEN
  304.             stop := Closewindow IN mp^.Class;
  305.             ReplyMsg(mp);
  306.         END;
  307.         Delay(5)
  308.     UNTIL stop;
  309. END Spy;
  310.  
  311.  
  312. (* +++++++++++++++++++++++++++++++++++++++++++++++++++++ *)
  313. PROCEDURE Observe(TargetTask : TaskPtr);
  314. (* Display various things about the target task *)
  315. BEGIN
  316.     IF SpyWindow = NIL THEN
  317.         SpyWindow := OpenSimpleWindow(WIDTH,HEIGHT,WINDOWLEFT,
  318.                         WINDOWTOP,NIL,
  319.                         WindowFlagsSet{WindowDrag,WindowDepth,
  320.                         WindowClose, NoCareRefresh},
  321.                         IDCMPFlagsSet{Closewindow},NIL,NIL);
  322.     END;
  323.     IF SpyWindow = NIL THEN
  324.         WriteString('Could not open window!'); WriteLn
  325.     ELSE
  326.         SetupWindow(TargetTask);
  327.         Spy(TargetTask);
  328.         CloseWindow(SpyWindow^);
  329.         SpyWindow := NIL;
  330.     END;
  331. END Observe;
  332.  
  333.  
  334. (* +++++++++++++++++++++++++++++++++++++++++++++++++++++ *)
  335. PROCEDURE InitRegNames;
  336. BEGIN
  337.     Regs[0].Name := 'D0';
  338.     Regs[1].Name := 'D1';
  339.     Regs[2].Name := 'D2';
  340.     Regs[3].Name := 'D3';
  341.     Regs[4].Name := 'D4';
  342.     Regs[5].Name := 'D5';
  343.     Regs[6].Name := 'D6';
  344.     Regs[7].Name := 'D7';
  345.     Regs[8].Name := 'A0';
  346.     Regs[9].Name := 'A1';
  347.     Regs[10].Name := 'A2';
  348.     Regs[11].Name := 'A3';
  349.     Regs[12].Name := 'A4';
  350.     Regs[13].Name := 'A5';
  351.     Regs[14].Name := 'A6';
  352. END InitRegNames;
  353.  
  354. (* +++++++++++++++++++++++++++++++++++++++++++++++++++++ *)
  355.  
  356. BEGIN
  357.     InitRegNames;
  358.     SpyWindow := NIL;
  359. END Snoop.
  360.