home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / mwait / src / mwait.c next >
C/C++ Source or Header  |  1998-08-19  |  138KB  |  4,271 lines

  1. #pragma module MWAIT "X-2"
  2.  
  3. /*
  4.  *
  5.  * Copyright ⌐ 1997,1998 by Kari Salminen. This code may be freely distributed
  6.  * and modified for non-commercial purposes as long as this copyright notice is
  7.  * retained.
  8.  *
  9.  * This software is provided "AS IS". The author makes no representations or
  10.  * warranties with respect to the software and specifically disclaim any implied
  11.  * warranties of merchantability or fitness for any particular purpose.
  12.  *
  13.  * COMPONENT:    mwait.c
  14.  *
  15.  * FACILITY:    ANALYZE A PROCESS HANG
  16.  *
  17.  * ABSTRACT:
  18.  *
  19.  *    This image analyzes the reason for a process hang and displays
  20.  *    approriate information of the target process.
  21.  *
  22.  * ENVIRONMENT:
  23.  *
  24.  *    Runs in User and Kernel mode. Raises IPL to SCHED.
  25.  *
  26.  *
  27.  * VERSION:    01.00
  28.  *
  29.  * AUTHOR:    Kari Salminen 
  30.  *
  31.  * DATE:    24-APR-1997
  32.  *
  33.  *
  34.  * MODIFIED BY:
  35.  *
  36.  *    V2.0    13-MAY-1997    Kari Salminen
  37.  *                Port to VMS V7.x
  38.  *                
  39.  *    V2.1    14-JUL-1997    Kari Salminen
  40.  *                Add EFN$C_ENF, thread upcall support.
  41.  *
  42.  *    V2.2    17-JUL-1997    Kari Salminen
  43.  *                Add thread stuff
  44.  *                Port the MACRO-32 subroutines into C.
  45.  *
  46.  *    V2.3    31-JUL-1997    Kari Salminen
  47.  *                Fix AST pending.
  48.  *                Add IRP's.
  49.  *
  50.  *    V2.4    18-SEP-1997    Kari Salminen
  51.  *                Add Network IRP's and PORT's
  52.  *
  53.  *    V2.5     4-DEC-1997    Kari Salminen
  54.  *                Add Master, Owner and Sub-processes
  55.  *
  56.  *    V2.6    21-APR-1998    Kari Salminen
  57.  *                Add OSI and TCP/IP version display
  58.  *
  59.  *    V2.7    10-JUN-1998    Kari Salminen
  60.  *                Get xxx_ATB symbol values at runtime from
  61.  *                NET$TRANSPORT_xxx.STB and LDR$GQ_IMAGE_LIST
  62.  *
  63.  *    V2.8    18-AUG-1998    Kari Salminen
  64.  *                Add INET device, the CXB's are on BGn:'s
  65.  *                Write output into a file
  66.  *
  67.  *
  68.  *
  69.  *
  70.  *
  71. */
  72.  
  73. #pragma code_psect    "NONPAGED_CODE"
  74. #pragma linkage_psect "NONPAGED_LINKAGE"
  75.  
  76.  
  77. #include <acbdef.h>        /* AST control block definitions     */
  78. #include <bufiodef.h>        /* Buffered I/O Packet headers         */
  79. #include <ccbdef.h>        /* Channel control block definitions     */
  80. #include <cebdef.h>        /* Common event flag wait definitions    */
  81. #include <cxbdef.h>        /* Complex chained buffer Definitions    */
  82. #include <dcdef.h>        /* Device adapter, class, and type defs  */
  83. #include <ddbdef.h>        /* Device data block definitions     */
  84. #include <descrip.h>        /* VMS Argument Descriptor Formats      */
  85. #include <devdef.h>        /* Device characteristics definitions     */
  86. #include <dispdef.h>        /* Change mode dispatcher offsets     */
  87. #include <dscdef.h>        /* VMS descriptors              */
  88. #include <dyndef.h>        /* Data structure type definitions     */
  89. #include <eobjrecdef.h>        /* Object record definitions          */
  90. #include <egsdef.h>        /* Global symbol definitions          */
  91. #include <egstdef.h>        /* Universal Symbol Definitions         */
  92. #include <fcbdef.h>        /* File control block definitions     */
  93. #include <imcbdef.h>        /* Image control block definitions     */
  94. #include <iodef.h>        /* I/O function codes              */
  95. #include <irpdef.h>        /* I/O request packet definitions     */
  96. #include <jibdef.h>        /* Job Information Block          */
  97. #include <jpidef.h>        /* Job Process Information definitions     */
  98. #include <kferesdef.h>        /* File entry defs for resident sections */
  99. #include <ldrimgdef.h>        /* System code loader definitions     */
  100. #include <lib$routines.h>    /* Library routines             */
  101. #include <pcbdef.h>        /* Process Control Block Definitions      */
  102. #include <pdscdef.h>        /* Procedure descriptor offset defs      */
  103. #include <phddef.h>        /* Process header definitions          */
  104. #include <pscandef.h>        /* Process scan definitions         */
  105. #include <prdef.h>        /* Processor register definitions     */
  106. #include <pridef.h>        /* Priority increment class definitions     */
  107. #include <psldef.h>        /* Processor status longword definitions */
  108. #include <rms.h>        /* RMS data structure definitions     */
  109. #include <rsndef.h>        /* Resource name definitions         */
  110. #include <sbdef.h>        /* System block definitions         */
  111. #include <secdef.h>             /* Process or global section definitions */
  112. #include <splcoddef.h>        /* Bits for SMP$GL_FLAGS and spinlock codes */
  113. #include <ssdef.h>        /* Define system status codes          */
  114. #include <statedef.h>        /* Define SCH$C_xxxx              */
  115. #include <stdio.h>        /* ANSI C Standard Input/Output         */
  116. #include <stdlib.h>             /* General Utilities                     */
  117. #include <string.h>        /* String Handling             */
  118. #include <ucbdef.h>        /* UCB definitions             */
  119. #include <vcrpdef.h>        /* VAX Communication Request Packet defs */
  120. #include <vms_macros.h>        /* VMS Exec/System macros         */
  121. #include <wcbdef.h>        /* Window control block definitions     */
  122.  
  123.  
  124.  
  125.         /* These .H files are not in C .TLB's     */
  126.  
  127. /* #include "ucbnidef.h"        */
  128.     /* LAN definitions that follow the standard UCB fields    */
  129.  
  130. typedef struct _ucbni {
  131. /* Overlay the UCB structure at UCB$Q_NI_RCVMSG        */
  132.     char ucbni$$ni_ucbfill_1 [744];
  133.     unsigned int ucb$q_ni_rcvreq;      /* S-Receive IRP waiting for messages */
  134.     } UCBNI;
  135.  
  136.  
  137. /* #include "proc_read_writedef.h"    */
  138.     /* Definitions for reading memory/regs      */
  139.  
  140. #define EACB$K_MEMORY 1                 /* virtual memory               */
  141. #define EACB$K_GENERAL_REGISTER 2       /* R0-R29,PC,PS                 */
  142. #define EACB$K_GEN_REGS_LENGTH 32    /* Register length        */
  143. #define EACB$K_R0 0            /* Register R0            */
  144. #define BUFFER_LENGTH 1024        /* .STB file read buffer size    */
  145. #define GSD_SIZ 8            /* GSD header size        */    
  146.  
  147. #define MAX_THREADS 16        /* Maximum # of threads             */
  148. #define MAX_IRP 300        /* Maximum # of IRP's for a unit         */
  149.  
  150. #define PHASEV 0x10000    /* DECnet Phase V = 50000 (101), IV = 40000 (100) */
  151.  
  152. #define PID_SIZE 8        /* PID length                */
  153. #define ESCAPE 27           /* Code for ASCII escape character */
  154.  
  155.  
  156. /* Note: the following structure information was found out with SDA,    */
  157. /*       without the source listings !, maybe not correct.        */
  158.  
  159. typedef struct _ucbbg {
  160.     char ucbbg$$bg_ucbfill_1 [336];
  161.     unsigned int ucb$l_bg_irp;        /* BG device IRP */
  162.     char ucbbg$$bg_ucbfill_2 [828];
  163.     unsigned int ucb$l_bg_irp2;        /* BG device IRP */
  164.     } UCBBG;
  165.  
  166.  
  167. typedef struct _atb {
  168.     unsigned int atb$l_atb;        /* ATB address        */
  169. /* Overlay the ATB$W_CTI_CUR_SLOTS structure */
  170.     char atb$$_fill_1 [12];
  171.     short int atb$w_cti_tot_slots;    /* PORT total slots  16    */
  172.     short int atb$w_cti_cur_slots;    /* PORT used slots   18    */
  173.     char atb$$_fill_2 [8];
  174.     unsigned int atb$a_cti_next_table;    /* Next ATB table    28 */
  175.     unsigned int atb$a_cti_slots;    /* PORT slot address 32 */
  176.     } ATB;
  177.  
  178.  
  179. typedef struct _port_slot {
  180.     unsigned int port_slot$l_port;    /* Port Address in ATB  0 */
  181.     } PORT_SLOT;
  182.  
  183. typedef struct _port {
  184.     unsigned int port$l_flink;        /* Port Flink        0    */
  185.     unsigned int port$l_blink;        /* Port Flink        4    */
  186.     short int port$w_size;        /* Size            8    */
  187.     char port$b_type;            /* Type           10    */
  188.     char port$b_subtype;        /* Subtype       12    */
  189.     char port$$_fill_0 [80];
  190.     unsigned int port$l_tpu_connection_id;  /* SCL port ID 92   */
  191.     char port$$_fill_1 [76];
  192.     unsigned int port$a_id_list;    /* Port Id list   172    */
  193.     unsigned int port$a_eib_emaa;    /* Port EIB addr  174   */
  194.     char port$$_fill_2 [8];
  195.     unsigned int port$l_nsp_fl;        /* NSP PORT Flink 188    */
  196.     unsigned int port$l_nsp_bl;        /* NSP PORT Blink 192    */
  197.     char port$$_fill_3 [20];
  198.     unsigned int port$l_osi_fl;        /* OSI PORT Flink 216    */
  199.     unsigned int port$l_osi_bl;        /* OSI PORT Blink 220    */
  200.     char port$$_fill_4 [32];
  201.     unsigned int port$a_constemplatenamelist;
  202.                     /* NSP Port #    256    */
  203.     char port$$_fill_5 [84];
  204.     unsigned int port$l_nsp_vcrp_fl;    /* NSP VCRP address 344    */
  205.     unsigned int port$l_nsp_vcrp_bl;    /* NSP VCRP address 348    */
  206.  
  207. /* Overlay the OSI PORT structure at PORT$T_LI + 8        */
  208.     char port$$_fill_6 [88];
  209.     unsigned int port$l_vcrp_fl;    /* OSI VCRP address 440    */
  210.     unsigned int port$l_vcrp_bl;    /* OSI VCRP address 444    */
  211.     } PORT;
  212.  
  213.  
  214. typedef struct _eib {
  215.     char eib$$_fill_1 [176];
  216.     unsigned int eib$l_link_ringlatency;    /* Remote/local reference */
  217.     } EIB;
  218.  
  219.  
  220. typedef struct _idlist {
  221. /* Overlay the ATB$W_CTI_CUR_SLOTS structure */
  222.     char idlist$$_fill_1 [45];
  223.     unsigned char idlist$b_port_name_len;    /* PORT name length  45    */
  224.     char idlist$t_port_name[20];        /* PORT name          46    */
  225.     } IDLIST;
  226.  
  227.  
  228. typedef struct _itmlist {
  229.         short  nambuflen;
  230.         short  jpicode;
  231.         void  *nambuf;
  232.         int   *retbuflen;
  233. } itmlist_t;
  234.  
  235.  
  236. struct {
  237.         short  buflen;
  238.         short  jpicode;
  239.         int    scanbuf;
  240.         int    flags;
  241.         int    terminator;
  242. } itmlst_pscan;
  243.  
  244.  
  245.     struct eobjrecdef *eobjrec;    /* Object record    */
  246.     struct egsdef     *egs;        /* Global symbols    */
  247.     struct egstdef    *egst;    /* Universal symbols    */
  248.  
  249.     struct FAB fab;
  250.     struct RAB rab;
  251.  
  252.     extern int EXE_STD$CVT_EPID_TO_PCB();
  253.     extern int EXE_STD$CVT_EPID_TO_IPID();
  254.  
  255.     extern int SYS$ASSIGN();
  256.     extern int SYS$CMKRNL();
  257.     extern int SYS$CLOSE();
  258.     extern int SYS$CONNECT();
  259.     extern int SYS$DASSGN();
  260.     extern int SYS$FAO();
  261.     extern int SYS$GET();
  262.     extern int SYS$GETJPIW();
  263.     extern int SYS$LKWSET();
  264.     extern int SYS$OPEN();
  265.     extern int SYS$PROCESS_SCAN();
  266.     extern int SYS$QIOW();
  267.  
  268.     extern int EXE$READ_PROCESS();        /* Read other process data  */
  269.  
  270.     extern int CTL$AG_CLIMAGE;        /* Address of CLI image        */
  271.     extern int CTL$GT_CLINAME;        /* CLI image name        */
  272.     extern int CTL$GL_CHINDX;        /* Max assigned chnl number */
  273.     extern int CTL$GA_CCB_TABLE;        /* CCB address            */
  274.  
  275.     extern int EXE$GL_DECNET_VERSION;    /* DECnet version        */
  276.  
  277.     extern int IAC$GL_IMAGE_LIST;        /* Address of list head        */
  278.     extern int IOC$GL_DEVLIST;        /* DDB list head        */
  279.     extern int LDR$GQ_IMAGE_LIST;        /* Address of image list    */
  280.  
  281.     extern int SCH$GL_MAXPIX;        /* Max process index        */
  282.     extern int SCH$GL_SWPPID;        /* Swapper PID            */
  283.  
  284.     extern int SCS$AR_LOCALSB;        /* Local system block         */
  285.  
  286.     extern int MMG$GQ_NEXT_FREE_S0S1_VA;    /* Highest system VA        */
  287.  
  288.     extern unsigned long exe$gl_abstim_tics;
  289.     extern SMP smp$gl_flags; /* System-wide multiprocessing control flags */
  290.  
  291.  
  292.  
  293. /* *** Lock down the fields accessed from kernel mode and all code *** */
  294.  
  295.    void last_address ();
  296.  
  297.    unsigned int lock_code_addr[2];
  298.    unsigned int lock_data_addr[2];
  299.  
  300.    int LOCK_D_START;        /* Dummy for data lock start */
  301.  
  302.    char cmdline[10];        /* Input line for PID     */
  303.    char    ceb_name2[17];        /* EFN cluster 2 name    */
  304.    char    ceb_name3[17];        /* EFN cluster 3 name    */
  305.    char file_name[100];        /* File name        */
  306.    char    pcb_lname[17];        /* Process name        */
  307.    char    pcb_terminal[9];    /* Terminal name    */
  308.    char image_name[40];        /* Image name        */
  309.    char jib_username[13];    /* User name        */
  310.    char port_name[20];        /* OSI/NSP Port name    */
  311.    char    unit_string[5];        /* Unit # string     */
  312.    char    tmp_string[20];        /* Temporary string     */
  313.    char disk[100];        /* Disk name        */
  314.    char inbuf[BUFFER_LENGTH];    /* .STB file read buffer */
  315.    char ddb_name[100];        /* Device name        */
  316.    char ddb_bg0[10];        /* BG Device name       */
  317.  
  318.    char    pcb_ast_k,pcb_aste_k,pcb_asta_k;
  319.    char    pcb_ast_e,pcb_aste_e,pcb_asta_e;
  320.    char    pcb_ast_s,pcb_aste_s,pcb_asta_s;
  321.    char    pcb_ast_u,pcb_aste_u,pcb_asta_u;
  322.  
  323.    char busy[]  = {"    "};
  324.    char busy0[] = {"    "};
  325.    char busy1[] = {"Busy"};
  326.  
  327.    char fao_str[] = {"!UL"};
  328.  
  329.    char *filename[] = {
  330.     "SYS$COMMON:[SYS$LDR]NET$TRANSPORT_OSI.STB",
  331.     "SYS$COMMON:[SYS$LDR]NET$TRANSPORT_NSP.STB"};
  332.  
  333.    char *net_image_name[] = {
  334.                 "NET$TRANSPORT_OSI",
  335.                 "NET$TRANSPORT_NSP"};
  336.  
  337.    char *atb_name[] = {
  338.     "OSITP$GA_ATB",
  339.     "TP_NSP$GA_NSP_ATB"};
  340.  
  341.    char *modes[] = {
  342.     "Kernel    ",
  343.     "Executive ",
  344.     "Supervisor",
  345.     "User      "};
  346.  
  347.    char *pd_kind[] = {
  348.     "Bound Procedure Descriptor",
  349.     "Unknown Procedure Descriptor",
  350.     "Unknown Procedure Descriptor",
  351.     "Unknown Procedure Descriptor",
  352.     "Unknown Procedure Descriptor",
  353.     "Unknown Procedure Descriptor",
  354.     "Unknown Procedure Descriptor",
  355.     "Unknown Procedure Descriptor",
  356.     "Null Frame Procedure Descriptor",
  357.     "Stack Frame Procedure Descriptor",
  358.     "Register Frame Procedure Descriptor"};
  359.  
  360.  
  361.    char *psects[] = {
  362.     "Address is not within a system or user image",
  363.     "MAIN",
  364.     "Merged",
  365.     "GLOBAL",
  366.     "Number 4",
  367.     "Nonpaged read only",
  368.     "Nonpaged read/write",
  369.     "Paged read only",
  370.     "Paged read/write",
  371.     "Activated Image",
  372.     "System Resident Code",
  373.     "Shareable Address Data",
  374.     "Shareable Read-Only Data",
  375.     "Read-Write Data",
  376.     "Demand Zero Data"};
  377.  
  378.    char *states[] = {
  379.     "COLPG               Collided page wait",
  380.     "MUTEX               Mutex/resource wait",
  381.     "CEF                 Common event flag wait",
  382.     "PFW                 Page fault wait",
  383.     "LEF                 Local event flag wait",
  384.     "LEFO                Local event flag wait, Outswapped",
  385.     "HIB                 Hibernate wait",
  386.     "HIBO                Hibernate wait, Outswapped",
  387.     "SUSP                Suspended",
  388.     "SUSPO               Suspended, Outswapped",
  389.     "FPG                 Freepage wait",
  390.     "COM                 Compute",
  391.     "COMO                Compute, Outswapped",
  392.     "CUR                 Current process"};
  393.  
  394.    char *process_status[] = {
  395.     "RES       Resident, in balance set",
  396.     "DELPEN    Delete pending",
  397.     "FORCPEN   Force exit pending",
  398.     "INQUAN    Initial quantum in progress",
  399.     "PSWAPM    Process cannot be swapped",
  400.     "RESPEN    Resume pending, skip suspend",
  401.     "SSFEXC    System service exception enable (K)",
  402.     "SSFEXCE   System service exception enable (E)",
  403.     "SSFEXCS   System service exception enable (S)",
  404.     "SSFEXCU   System service exception enable (U)",
  405.     "SSRWAIT   System service resource wait disable",
  406.     "SUSPEN    Suspend pending",
  407.     "WAKEPEN   Wake pending, skip hibernate",
  408.     "WALL      Wait for all events in mask",
  409.     "BATCH     Process is a batch job",
  410.     "NOACNT    No accounting for process",
  411.     "NOSUSPEND Process cannot be suspended",
  412.     "ASTPEN    AST pending",
  413.     "PHDRES    Process header resident",
  414.     "HIBER     Hibernate after initial image activate",
  415.     "LOGIN     Login without reading UAF",
  416.     "NETWRK    Network connect job",
  417.     "PWRAST    Power fail AST",
  418.     "NODELET   No delete",
  419.     "DISAWS    Disable automatic WS adjustment",
  420.     "INTER     Process is an interactive job",
  421.     "RECOVER   Process can recover locks",
  422.     "SECAUDIT  Mandatory security auditing enabled",
  423.     "HARDAFF   Process is bound to particular CPU",
  424.     "ERDACT    Exec mode rundown active",
  425.     "SOFTSUSP  Process is in soft suspend",
  426.     "PREEMPTED Hard suspend has preempted soft",
  427.     };
  428.  
  429.    char *resource_wait[] = {
  430.     "AST event/channel interlock",
  431.     "Mailbox space",
  432.     "Non-paged dynmic memory",
  433.     "Paging file space",
  434.     "Paged dynamic memory",
  435.     "Terminal broadcast",
  436.     "Image activation interlock",
  437.     "Job pooled quota",
  438.     "Lock ID's",
  439.     "Swapping file space",
  440.     "Modified page list empty",
  441.     "Modified page writer busy",
  442.     "System communication",
  443.     "Cluster state transition",
  444.     "CPU capability",
  445.     "Cluster server",
  446.     "Snapshot",
  447.     "POSIX fork",
  448.     "Inner mode access for Kthreads",
  449.     "Exit handler for Kthread"};
  450.  
  451.    char *m_wait[] = {
  452.     "RWAST               Wait for AST completion",
  453.     "RWMBX               Mailbox full",
  454.     "RWNPG               Wait for nonpaged dynamic memory",
  455.     "RWPFF               Paging file is full",
  456.     "RWPAG               Wait for paged dynamic memory",
  457.     "RWBRK               Wait for breakthrough",
  458.     "RWIMG               Wait for image activation lock",
  459.     "RWQUO               Wait for job pooled quota",
  460.     "RWLCK               Wait for lock identification database",
  461.     "RWSWP               Wait for swap file space",
  462.     "RWMPE               Modified page list empty",
  463.     "RWMPB               Modified page list busy",
  464.     "RWSCS               Wait for system communications",
  465.     "RWCLU               Wait for cluster state transition",
  466.     "RWCAP               Wait for CPU capability",
  467.     "RWCSV               Wait for cluster server",
  468.     "RWSNP               Wait for a system snapshot",
  469.     "PSXFR               Posix fork wait",
  470.     "INNER_MODE          Thread in an inner mode wait",
  471.     "EXH                 Thread in exit handling wait"};
  472.  
  473.  
  474.    char *iofun[] = {
  475.     "IO$_NOP",
  476.     "IO$_UNLOAD, IO$_LOADMCODE, IO$_START_BUS",
  477.     "IO$_SEEK, IO$_SPACEFILE, IO$_STARTMPROC, IO$_STOP_BUS",
  478.     "IO$_RECAL, IO$_DUPLEX, IO$_STOP, IO$_DEF_COMP",
  479.     "IO$_DRVCLR, IO$_INITIALIZE, IO$_MIMIC, IO$_DEF_COMP_LIST",
  480.     "IO$_RELEASE, IO$_SETCLOCKP, IO$_START_ANALYSIS",
  481.     "IO$_OFFSET, IO$_ERASETAPE, IO$_STARTDATAP, IO$_STOP_ANALYSIS",
  482.     "IO$_RETCENTER, IO$_QSTOP, IO$_START_MONITOR",
  483.     "IO$_PACKACK, IO$_STOP_MONITOR",
  484.     "IO$_SEARCH, IO$_SPACERECORD, IO$_READRCT",
  485.     "IO$_WRITECHECK",
  486.     "IO$_WRITEPBLK",
  487.     "IO$_READPBLK",
  488.     "IO$_WRITEHEAD, IO$_RDSTATS, IO$_CRESHAD",
  489.     "IO$_READHEAD, IO$_ADDSHAD",
  490.     "IO$_WRITETRACKD, IO$_COPYSHAD",
  491.     "IO$_READTRACKD, IO$_REMSHAD",
  492.     "IO$_AVAILABLE",
  493.     "IO$_SETPRFPATH",
  494.     "IO$_DISPLAY",
  495.     "IO$_REMSHADMBR",
  496.     "IO$_DSE",
  497.     "IO$_REREADN, IO$_DISK_COPY_DATA",
  498.     "IO$_MOUNTSHAD, IO$_REREADP, IO$_WHM, IO$_AS_SETCHAR",
  499.     "IO$_WRITERET, IO$_WRITECHECKH, IO$_AS_SENSECHAR",
  500.     "IO$_ADDSHADMBR, IO$_READPRESET, IO$_STARTSPNDL",
  501.     "IO$_SETCHAR",
  502.     "IO$_SENSECHAR",
  503.     "IO$_WRITEMARK, IO$_COPYMEM, IO$_PSXSETCHAR",
  504.     "IO$_WRTTMKR, IO$_DIAGNOSE, IO$_SHADMV, IO$_PSXSENSECHAR",
  505.     "IO$_FORMAT, IO$_CLEAN, IO$_UPSHAD",
  506.     "IO$_PHYSICAL",
  507.     "IO$_WRITELBLK (or IO$_WRITEVBLK)",
  508.     "IO$_READLBLK (or IO$_READVBLK)",
  509.     "IO$_REWINDOFF, IO$_READRCTL",
  510.     "IO$_SETMODE",
  511.     "IO$_REWIND",
  512.     "IO$_SKIPFILE, IO$_PSXSETMODE",
  513.     "IO$_SKIPRECORD, IO$_PSXSENSEMODE",
  514.     "IO$_SENSEMODE",
  515.     "IO$_WRITEOF, IO$_TTY_PORT_BUFIO",
  516.     "IO$_TTY_PORT, IO$_FREECAP",
  517.     "IO$_FLUSH, IO$_AS_SETMODE",
  518.     "IO$_READLCHUNK, IO$_AS_SENSEMODE",
  519.     "IO$_WRITELCHUNK",
  520.     "45 Not used",
  521.     "46 Not used",
  522.     "IO$_LOGICAL",
  523.     "IO$_WRITEVBLK",
  524.     "IO$_READVBLK",
  525.     "IO$_ACCESS, IO$_PSXWRITEVBLK",
  526.     "IO$_CREATE",
  527.     "IO$_DEACCESS, IO$_PSXREADVBLK",
  528.     "IO$_DELETE",
  529.     "IO$_MODIFY, IO$_NETCONTROL",
  530.     "IO$_READPROMPT, IO$_SETCLOCK, IO$_AUDIO",
  531.     "IO$_ACPCONTROL, IO$_STARTDATA, IO$_IOCTLV",
  532.     "IO$_MOUNT",
  533.     "IO$_TTYREADALL, IO$_DISMOUNT",
  534.     "IO$_TTYREADPALL",
  535.     "IO$_CONINTREAD",
  536.     "IO$_CONINTWRITE",
  537.     "IO$_READDIR"};
  538.  
  539.  
  540.   char  *str_ptr;
  541.   char  *str_ptr2;
  542.  
  543.   char  outname[] = "12345678.OUT";    /* Pid is 8 chars    */
  544.   FILE *outfile;
  545.  
  546.   char  prcname[16];
  547.   int   prclen;
  548.   unsigned int tmp_pid[1];
  549.  
  550.  
  551. const long int bit_mask[33] = {                /* Bits set */
  552.     0X0,0X1,    0X2,            0X4,
  553.     0X8, 0X10,   0X20,           0X40,
  554.     0X80, 0X100,   0X200,         0X400,
  555.     0X800, 0X1000,   0X2000,       0X4000,
  556.     0X8000, 0X10000,  0X20000,      0X40000,
  557.     0X80000, 0X100000,  0X200000,    0X400000,
  558.     0X800000, 0X1000000,  0X2000000,  0X4000000,
  559.     0X8000000, 0X10000000, 0X20000000, 0X40000000,
  560.     0X80000000
  561.     };
  562.  
  563.    itmlist_t itmlst[2]={
  564.         sizeof(prcname)-1, JPI$_PRCNAM, prcname, &prclen,
  565.         0, 0, 0, 0};
  566.  
  567.    itmlist_t itmlst_2[3]={
  568.         sizeof(prcname)-1, JPI$_PRCNAM, prcname, &prclen,
  569.         4, JPI$_PID, tmp_pid, 0,
  570.         0, 0, 0, 0};
  571.  
  572.  
  573.    int  cli_length  = 8;
  574.    int  link_length = 4;
  575.    int    arglist [3];
  576.    int  cmp_len[2];
  577.    int    cmdlen;
  578.    int     orig_ipl;
  579.    int    return_status;
  580.    int    size;
  581.    int    sym_val;
  582.    int  str_length;
  583.    int  ucb_address;
  584.    int  ucb_devchar;
  585.    int  iocou;
  586.    short int ucb_devtype;
  587.    int  ucb_sts;
  588.    int  unit;
  589.    int  bufquo;
  590.  
  591.    int t_delta;
  592.    int t_days;
  593.    int t_hours;
  594.    int t_minutes;
  595.    int t_seconds;
  596.  
  597.    int read_process_ast_count;
  598.    short int prc_index;
  599.    int ctl_chindx;
  600.    int ctl_chindx_length;
  601.    int ccb_length;
  602.    int ccb_table_address;
  603.    int ccb_table[6400];        /* CCB table 200 entries    */
  604.    int ddb_name_length;        /* Device name length        */
  605.    int window;
  606.  
  607.    int PSTbase;
  608.    int section;
  609.  
  610.    int kferes_link;
  611.    int kferes_offset;
  612.    int kferes_count;
  613.    int kferes_block[KFERES$K_SECTION_LENGTH];
  614.  
  615.    int prc_registers[64];        /* Process registers        */
  616.  
  617.    int found;
  618.    int offset;
  619.    int psect;
  620.    int start;
  621.    int end;
  622.  
  623.    int prvmod;
  624.    int curmod;
  625.    int ipl;
  626.    int frame[32800];            /* Max RSA_OFFSET + PDSC size    */
  627.    int frame_count;
  628.    int save_fp;
  629.    int save_ra;
  630.    int fp;
  631.    int next_fp;
  632.    int r26;
  633.    int pd;
  634.    int pdsc_b[8];            /* Procedure Descriptor (PDSC)    */
  635.    int pdsc_flags;
  636.    int pdsc_kind;
  637.    int pdsc_entry;
  638.    short int pdsc_rsa_offset;
  639.    unsigned int ireg_mask;
  640.  
  641.    int cli[2];
  642.    int imcb_link;
  643.    int imcb_block[IMCB$K_LENGTH+1];
  644.    int wcb_block[WCB$K_LENGTH+1];
  645.    int fcb_block[FCB$K_LENGTH+1];
  646.  
  647.    IRP *ucb_ioqfl_a;
  648.    IRP *ucb_ioqfl;
  649.  
  650.    IRP *pcb_irpfl_a;
  651.    IRP *pcb_irpfl;
  652.  
  653.    VCRP *vcrp_qfl_a;
  654.    VCRP *vcrp_qfl;
  655.  
  656.    BUFIO *ucb_bufiofl_a;
  657.    BUFIO *ucb_bufiofl;
  658.  
  659.    int irp_count;
  660.    int irp_addr[MAX_IRP];
  661.    int irp_efn[MAX_IRP];
  662.    int irp_func[MAX_IRP];
  663.    int irp_iost1[MAX_IRP];
  664.    uint64 irp_iosb_a[MAX_IRP];
  665.    uint64 irp_iosb[MAX_IRP];
  666.    int irp_bcnt[MAX_IRP];
  667.    uint64 irp_ast[MAX_IRP];
  668.    uint64 irp_astprm[MAX_IRP];
  669.    int irp_p1[MAX_IRP];
  670.    int irp_p2[MAX_IRP];
  671.    int irp_p3[MAX_IRP];
  672.    int irp_p4[MAX_IRP];
  673.    int irp_p5[MAX_IRP];
  674.    int irp_p6[MAX_IRP];
  675.    int irp_pid[MAX_IRP];
  676.    int irp_epid[MAX_IRP];
  677.    int irp_unit[MAX_IRP];
  678.  
  679.    unsigned int i_efwm;
  680.    unsigned int i_wefc;
  681.    unsigned int    target_pcb;    /* Process PCB */
  682.    unsigned int    pid;        /* Process PID */
  683.  
  684. /*    Thread fields    */
  685.  
  686.    unsigned int    pcb_state[MAX_THREADS];
  687.    unsigned int    pcb_sts[MAX_THREADS];
  688.             int    pcb_efwm[MAX_THREADS];    /* Signed int ! */
  689.    unsigned int    pcb_wefc[MAX_THREADS];
  690.    unsigned int    pcb_cpu_id[MAX_THREADS];
  691.    unsigned int    pcb_efcs[MAX_THREADS];
  692.    unsigned int    pcb_efcu[MAX_THREADS];
  693.    unsigned int    pcb_efc2p[MAX_THREADS];
  694.    unsigned int    pcb_efc3p[MAX_THREADS];
  695.  
  696.  
  697.  
  698. /*    PCB    */
  699.  
  700.    unsigned int    pcb_epid;
  701.    unsigned int    epid;
  702.    unsigned int    pcb_pid;
  703.    unsigned int    pcb_pri;
  704.    unsigned int    pcb_prib;
  705.    unsigned int    pcb_owner;
  706.    unsigned int owner_epid;
  707.    unsigned int    pcb_waitime;
  708.    unsigned int    pcb_diocnt;
  709.    unsigned int    pcb_diolm;
  710.    unsigned int    pcb_biocnt;
  711.    unsigned int    pcb_biolm;
  712.    unsigned int    pcb_prccnt;
  713.    unsigned int    pcb_dpc;
  714.    unsigned int    pcb_astcnt;
  715.    unsigned int    pcb_astact;
  716.    unsigned int    pcb_phd;
  717.    unsigned int pcb_wsquota;
  718.    unsigned int    pcb_ktbvec_a[MAX_THREADS];
  719.    unsigned int    pcb_kt_count;
  720.    int    *pcb_ktbvec;
  721.  
  722.    unsigned int wsextent;
  723.  
  724.    int phd_pstbasoff;     
  725.    unsigned int    phd_astlm;
  726.    uint64 phd_astsr_asten;
  727.  
  728.    unsigned int jib_flags;
  729.    unsigned int jib_bytcnt;
  730.    unsigned int jib_bytlm;
  731.    unsigned int jib_org_bytlm;
  732.    unsigned int jib_filcnt;
  733.    unsigned int jib_fillm;
  734.    unsigned int jib_mpid;
  735.    unsigned int master_epid;
  736.    unsigned int jib_tqcnt;
  737.    unsigned int jib_tqlm;
  738.    unsigned int jib_pgflcnt;
  739.    unsigned int jib_pgflquota;
  740.    unsigned int jib_prclim;
  741.    unsigned int    jib_prccnt;
  742.  
  743.    unsigned int abstim_tics;
  744.    unsigned int mmg_fresva;    /* First free system VA    */
  745.  
  746.    $DESCRIPTOR (cmdline_d, cmdline);
  747.    $DESCRIPTOR (disk_d, disk);
  748.    $DESCRIPTOR (fao_d, fao_str);
  749.    $DESCRIPTOR (file_d, file_name);
  750.    $DESCRIPTOR (str_d, unit_string);
  751.  
  752.  
  753.    static $DESCRIPTOR (prompt_pid, "Please give target process PID : ");
  754.  
  755.    int get_fp_and_pdsc();
  756.    int get_process_info();
  757.    int get_process_channels();
  758.    int get_device_name();
  759.    int get_process_registers();
  760.    int map_address();
  761.    int read_stb_file();
  762.    int get_symbol_offset();
  763.  
  764.    int  OSITP$GA_ATB;
  765.    int  TP_NSP$GA_NSP_ATB;
  766.  
  767.    int  i;
  768.    int  j;
  769.    int  k;
  770.    int  l;
  771.    int  m;
  772.    int  i_bit;
  773.    int  threads;
  774.    int  threads_ind;
  775.  
  776.    int  nsp_port;
  777.    int  atb_end;
  778.    int  atb_slots;
  779.    int  port_count;
  780.    int  net_port;
  781.    int  scl;
  782.  
  783.    PORT *port_fl_a;
  784.    PORT *port_fl;
  785.    int  next_port;
  786.  
  787.    int  tmp;
  788.    int  *tmp_ptr;
  789.  
  790.  
  791.    ATB    *atb;
  792.    BUFIO  *bufio;
  793.    CCB       *ccb;
  794.    CEB       *ceb;
  795.    CXB    *cxb;
  796.    DDB       *ddb;
  797.    EIB       *eib;
  798.    FCB       *fcb;
  799.    IDLIST *idlist;
  800.    IMCB   *imcb;
  801.    IRP       *irp;
  802.    JIB       *jib;
  803.    KFERES_SECTION *kferes_section;
  804.    KFERES *kferes;
  805.    LDRIMG *ldrimg;
  806.    PCB       *pcb;
  807.    PHD       *phd;
  808.    PORT   *port;
  809.    PORT_SLOT *port_slot;
  810.    SB        *sb;
  811.    UCB       *ucb;
  812.    UCB    *ucb_bg0;               /* BG0: UCB address     */
  813.    UCB    *ucb_2;
  814.    UCBBG  *ucbbg;
  815.    UCBNI  *ucbni;
  816.    VCRP      *vcrp;
  817.    MB_UCB *mb_ucb;
  818.    WCB       *wcb;
  819.  
  820.    struct pdscdef *pdsc;
  821.  
  822. /*VMS70   SECDEF *sec;    */
  823.  
  824.  
  825. /* ******** Temp stuff ************* */
  826.  
  827.    unsigned int    pcb_tmp;
  828.    unsigned int    ceb_tmp;
  829.    unsigned int    ceb1_tmp;
  830.  
  831.    int  tmp2;
  832.    int  tmp3;
  833.    int  tmp4;
  834.    int  tmp5;
  835.    int  tmp6;
  836.    int  tmp7;
  837.    int  tmp8;
  838.    int  tmp9;
  839.    int  tmp10;
  840.    int  tmp11;
  841.    int  tmp12;
  842.    int  tmp13;
  843.    int  tmp14;
  844.    int  tmp15;
  845.    int  tmp16;
  846.    int  tmp17;
  847.    int  tmp20;
  848.    int  tmp21;
  849.    int  tmp22;
  850.    int  tmp23;
  851.    int  tmp24;
  852.    int  tmp25;
  853.    int  tmp26;
  854.    int  tmp27;
  855.    int  tmp28;
  856.    int  tmp29;
  857.  
  858.    int  tempa[500];
  859.    int  tempb[500];
  860.    int  tempc[500];
  861.  
  862.    char tempstr[100];
  863.  
  864. /* ******** Temp stuff ************* */
  865.  
  866.  
  867.    int LOCK_D_END;        /* End of data to lock */
  868.  
  869. /* ******************************************************************* */
  870.  
  871. main()
  872. {
  873.    ucb_bg0 = 0;            /* No BG0: UCB address yet    */
  874.  
  875.    printf ("\n\n          *** MWAIT /Alpha V2.8 - Process Hang Analyzer ***\n\n");
  876.  
  877. /*    cmdline_d.dsc$w_length  = 9;            */
  878. /*    cmdline_d.dsc$b_dtype   = DSC$K_DTYPE_T;    */
  879. /*    cmdline_d.dsc$b_class   = DSC$K_CLASS_D;    */
  880. /*    cmdline_d.dsc$a_pointer = cmdline;        */
  881.    
  882.    return_status = LIB$GET_FOREIGN (&cmdline_d,0,&cmdlen,0);
  883.    
  884. /*    printf ("Foreign Command : %s\n",cmdline_d.dsc$a_pointer);    */
  885.  
  886.    
  887.    
  888.      if (cmdlen == 0) {
  889.      cmdline_d.dsc$w_length  = PID_SIZE;
  890.      return_status = LIB$GET_INPUT ( &cmdline_d,
  891.                      &prompt_pid, &cmdlen );
  892.      } 
  893.    
  894. /*    printf ("Command line    : %s\n",cmdline);        */
  895.  
  896.    
  897. /*    Lock data    */
  898.    
  899.    lock_data_addr[0] = (int) &LOCK_D_START;    /* Start of data to lock */
  900.    lock_data_addr[1] = (int) &LOCK_D_END;    /* End of data to lock   */
  901.    
  902.    return_status = SYS$LKWSET (&lock_data_addr,0,0);
  903.                         /* Lock code and data */
  904.    if (return_status != SS$_NORMAL) return (return_status);
  905.       
  906.    
  907. /*    Lock code    */
  908.    
  909.    pdsc = (struct pdscdef *) &main;         /* Main PDSC          */
  910.    lock_code_addr[0] = pdsc->pdsc$l_entry;    /* Start of code to lock */
  911.    
  912.    pdsc = (struct pdscdef *) &last_address;     /* last_address PDSC      */
  913.    lock_code_addr[1] = pdsc->pdsc$l_entry;    /* End of code to lock   */
  914.    
  915.    return_status = SYS$LKWSET (&lock_code_addr,0,0);
  916.                         /* Lock code and data */
  917.    if (return_status != SS$_NORMAL) return (return_status);
  918.       
  919. /* \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ */
  920.  
  921. /*    There is (?) no global pointer to OSITP$GA_ATB and     */
  922. /*     TP_NSP$GA_NSP_ATB.                     */
  923. /*    Read these values from .STB files and get the image     */
  924. /*    offsets from the loaded image list.            */
  925.  
  926.    return_status = read_stb_file ( filename[0], atb_name[0] );
  927.                         /* Get symbol value */
  928.    arglist [0] = 1;
  929.    arglist [1] = (int) net_image_name[0];
  930.  
  931.    return_status = SYS$CMKRNL(&get_symbol_offset, arglist);
  932.                         /* Get symbol offset */
  933.  
  934.    OSITP$GA_ATB = sym_val + offset;         /* Symbol value        */
  935.  
  936.  
  937.    return_status = read_stb_file ( filename[1], atb_name[1] );
  938.                         /* Get symbol value */
  939.    arglist [0] = 1;
  940.    arglist [1] = (int) net_image_name[1];
  941.  
  942.    return_status = SYS$CMKRNL(&get_symbol_offset, arglist);
  943.                         /* Get symbol offset */
  944.  
  945.    TP_NSP$GA_NSP_ATB = sym_val + offset;    /* Symbol value        */
  946.  
  947.  
  948. /* \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ */
  949.    
  950.    return_status = LIB$CVT_HTB ( cmdlen, cmdline_d.dsc$a_pointer, &pid);
  951.  
  952.    
  953. /*     Open output file    */
  954.  
  955.    for (i = 0; i < 8; i++)
  956.     outname[i] = cmdline[i];    /* Use PID as file name */
  957.  
  958.    printf ("\n *** The output will be written into file %s *** \n", (char *) outname);
  959.  
  960.    outfile = fopen (outname, "w");
  961.    if (outfile == 0) 
  962.     {
  963.     printf ("\n Can't open output file %s \n",outname);
  964.     return (SS$_NORMAL);
  965.     }
  966.  
  967.    fprintf (outfile, "\n\n          *** MWAIT /Alpha V2.8 - Process Hang Analyzer ***\n\n");
  968.  
  969.    
  970.    arglist [0] = 1;
  971.    arglist [1] = (int) pid;
  972.    
  973.    return_status =    SYS$CMKRNL(&get_process_info, arglist);
  974.    if (return_status != SS$_NORMAL) return (return_status);
  975.       
  976.    
  977.    
  978. /* ********************************************************************
  979.  *
  980.  *    Analyze process data and output the results.
  981.  *
  982.  ********************************************************************** */
  983.    
  984.    printf ("\nProcess name     : %-15s", pcb_lname); 
  985.    fprintf (outfile, "\nProcess name     : %-15s", pcb_lname); 
  986.  
  987.    printf ("     User name      : %s\n", jib_username); 
  988.    fprintf (outfile, "     User name      : %s\n", jib_username); 
  989.  
  990.    
  991.    if ( pcb_terminal[0] == 0 )
  992.      {
  993.      if ( pcb_owner == 0)             strncpy(pcb_terminal,"-Detached-", 16);
  994.      else                  strncpy(pcb_terminal,"-Subprocess-", 16);
  995.      if ( pcb_sts[0] & PCB$M_BATCH )  strncpy(pcb_terminal,"-Batch-", 16);
  996.      if ( pcb_sts[0] & PCB$M_NETWRK ) strncpy(pcb_terminal,"-Network-", 16);
  997.      }
  998.       
  999.    printf ("Extended PID     : %08X            Internal PID   : %08X\n", 
  1000.                                   pcb_epid,pcb_pid);
  1001.    fprintf (outfile, "Extended PID     : %08X            Internal PID   : %08X\n", 
  1002.                                   pcb_epid,pcb_pid);
  1003.    
  1004.    printf ("PCB address      : %8X",pcb_ktbvec_a[0]);
  1005.    fprintf (outfile, "PCB address      : %8X",pcb_ktbvec_a[0]);
  1006.  
  1007.    printf ("            Terminal name  : %-15s\n", pcb_terminal);
  1008.    fprintf (outfile, "            Terminal name  : %-15s\n", pcb_terminal);
  1009.  
  1010.    
  1011.    if (pcb_owner != 0) 
  1012.      {
  1013.      return_status = SYS$GETJPIW (0, &master_epid, 0, &itmlst, 0, 0, 0);
  1014.      printf ("Master PID       : %08X            Master Process : %s\n",master_epid,prcname);
  1015.      fprintf (outfile, "Master PID       : %08X            Master Process : %s\n",master_epid,prcname);
  1016.  
  1017.  
  1018.      return_status = SYS$GETJPIW (0, &owner_epid, 0, &itmlst, 0, 0, 0);
  1019.      printf ("Owner PID        : %08X            Owner Process  : %s\n",owner_epid,prcname);
  1020.      fprintf (outfile, "Owner PID        : %08X            Owner Process  : %s\n",owner_epid,prcname);
  1021.  
  1022.      }
  1023.  
  1024. /*
  1025.  * All (Sub)processes have the same Subprocess count JIB$L_PRCCNT
  1026.  *
  1027.  * Master PID is the same all (Sub)processes JIB$L_MPID
  1028.  *
  1029.  * Master Creator PID = 0 JIB$L_MPID
  1030.  *
  1031.  * Other Creator PID's = PID of the Creator (Sub)process PCB$L_OWNER
  1032.  *
  1033.  */
  1034.  
  1035. /*    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\    */
  1036.  
  1037.     if ( jib_prccnt != 0)
  1038.      {
  1039.  
  1040.      epid = 0;                /* Initial value    */
  1041.  
  1042. /*     PSCAN$_OWNER        scan sub-processes of process    */
  1043. /*     PSCAN$_MASTER_PID    scan sub-processes of master    */
  1044.  
  1045.     itmlst_pscan.buflen     = 0;        /* Buffer length        */
  1046.     itmlst_pscan.jpicode    = PSCAN$_MASTER_PID; /* Item code        */
  1047.     itmlst_pscan.scanbuf    = master_epid;    /* Master PID        */
  1048.     itmlst_pscan.flags      = 0;        /* Item specific flags  */
  1049.     itmlst_pscan.terminator = 0;        /* Terminator*/
  1050.  
  1051.  
  1052.      return_status = SYS$PROCESS_SCAN (&epid, &itmlst_pscan);
  1053.  
  1054.      printf ("\nProcesses in this job: \n");
  1055.      fprintf (outfile, "\nProcesses in this job: \n");
  1056.  
  1057.  
  1058.      tmp = 1;
  1059.  
  1060.      while (return_status != SS$_NOMOREPROC)
  1061.       {
  1062.        return_status = SYS$GETJPIW (0, &epid, 0, &itmlst_2, 0, 0, 0);
  1063.        if (return_status == SS$_NORMAL) 
  1064.          {
  1065.       if ( pcb_epid != tmp_pid[0] )
  1066.         {
  1067.             printf ("Process %2d  PID  : %08X            Process name   : %s\n",tmp, tmp_pid[0], prcname);
  1068.             fprintf (outfile, "Process %2d  PID  : %08X            Process name   : %s\n",tmp, tmp_pid[0], prcname);
  1069.         }
  1070.  
  1071.       else
  1072.         {
  1073.             printf ("Process %2d  PID  : %08X    (*)     Process name   : %s\n",tmp, tmp_pid[0], prcname);
  1074.             fprintf (outfile, "Process %2d  PID  : %08X    (*)     Process name   : %s\n",tmp, tmp_pid[0], prcname);
  1075.         }
  1076.          }
  1077.  
  1078.        tmp = tmp + 1;
  1079.       }
  1080.      printf ("\n");
  1081.      fprintf (outfile, "\n");
  1082.  
  1083.  
  1084.      } /* End if jib_prccnt */
  1085.  
  1086.  
  1087.  
  1088.       
  1089.    printf ("JIB address      : %8X",jib);
  1090.    fprintf (outfile, "JIB address      : %8X",jib);
  1091.  
  1092.    printf ("            Cur/Base prior : %d/%d\n",pcb_pri,pcb_prib);
  1093.    fprintf (outfile, "            Cur/Base prior : %d/%d\n",pcb_pri,pcb_prib);
  1094.  
  1095.    
  1096.    if (phd !=0 ) 
  1097.       {
  1098.       printf ("PHD address      : %X\n",phd);
  1099.       fprintf (outfile, "PHD address      : %X\n",phd);
  1100.       }
  1101.    else
  1102.       {
  1103.       printf ("PHD address      : Process is outswapped, PHD not resident\n");
  1104.       fprintf (outfile, "PHD address      : Process is outswapped, PHD not resident\n");
  1105.       }
  1106.  
  1107.       
  1108.    printf ("KTB vector       : %8X",pcb_ktbvec);
  1109.    fprintf (outfile, "KTB vector       : %8X",pcb_ktbvec);
  1110.  
  1111.    printf ("            Threads        : %d\n",pcb_kt_count);
  1112.    fprintf (outfile, "            Threads        : %d\n",pcb_kt_count);
  1113.  
  1114.    
  1115.    
  1116.    
  1117. /********************** Thread loop ***********************************/
  1118.    
  1119.    threads = pcb_kt_count;
  1120.    
  1121.    while (threads != 0)
  1122.      {
  1123.      
  1124.      threads_ind = pcb_kt_count - threads;
  1125.      
  1126.      printf ("Thread %02d\n",threads_ind);
  1127.      fprintf (outfile, "Thread %02d\n",threads_ind);
  1128.  
  1129.      printf ("--------- \n");
  1130.      fprintf (outfile, "--------- \n");
  1131.  
  1132.      
  1133.      printf ("KTB address      : %8X",pcb_ktbvec_a[threads_ind]);
  1134.      fprintf (outfile, "KTB address      : %8X",pcb_ktbvec_a[threads_ind]);
  1135.  
  1136.      printf ("            Running on CPU : %d\n",pcb_cpu_id[threads_ind]);
  1137.      fprintf (outfile, "            Running on CPU : %d\n",pcb_cpu_id[threads_ind]);
  1138.  
  1139.      
  1140.      
  1141.      if ( pcb_state[threads_ind] != SCH$C_MWAIT )
  1142.     {
  1143.         printf ("Thread state     : %s\n", states[pcb_state[threads_ind]-1]);
  1144.         fprintf (outfile, "Thread state     : %s\n", states[pcb_state[threads_ind]-1]);
  1145.     }
  1146.  
  1147.      else
  1148.        {
  1149.        if ( pcb_efwm[threads_ind] < RSN$_MAX && pcb_efwm[threads_ind] > 0)
  1150.      {
  1151.           printf ("Thread state     : %s\n", m_wait[pcb_efwm[threads_ind]-1]);
  1152.           fprintf (outfile, "Thread state     : %s\n", m_wait[pcb_efwm[threads_ind]-1]);
  1153.      }
  1154.  
  1155.        else
  1156.       {
  1157.           printf ("Thread state     : %s\n", states[pcb_state[threads_ind]-1]);
  1158.           fprintf (outfile, "Thread state     : %s\n", states[pcb_state[threads_ind]-1]);
  1159.       }
  1160.  
  1161.        }
  1162.      
  1163.      printf ("Thread status    : %08X  ",pcb_sts[threads_ind]);
  1164.      fprintf (outfile, "Thread status    : %08X  ",pcb_sts[threads_ind]);
  1165.  
  1166.      
  1167.      if ( !(pcb_sts[threads_ind] & PCB$M_SSRWAIT) ) 
  1168.     {
  1169.         printf ("ssrwait   System service resource wait enabled\n                             ");
  1170.         fprintf (outfile, "ssrwait   System service resource wait enabled\n                             ");
  1171.     }
  1172.  
  1173.      
  1174. /*    Print Process status bit names        */
  1175.      
  1176.      tmp = 0;
  1177.      
  1178.      for (i_bit = 0; i_bit < 33; i_bit++)  
  1179.        {
  1180.        if (( pcb_sts[threads_ind] & bit_mask[i_bit+1] ) >> i_bit) 
  1181.          {
  1182.          tmp = tmp + 1;
  1183.          if ( tmp == 1 )
  1184.         {
  1185.             printf ("%s ", process_status[i_bit]);
  1186.             fprintf (outfile, "%s ", process_status[i_bit]);
  1187.         }
  1188.  
  1189.          else
  1190.         {
  1191.             printf ("\n                             %s ", process_status[i_bit]);
  1192.             fprintf (outfile, "\n                             %s ", process_status[i_bit]);
  1193.         }
  1194.  
  1195.          }
  1196.        }
  1197.      
  1198.      
  1199.      printf ("\nEFN wait cluster : %X\n",pcb_wefc[threads_ind]);
  1200.      fprintf (outfile, "\nEFN wait cluster : %X\n",pcb_wefc[threads_ind]);
  1201.  
  1202.      printf ("EFN wait mask    : %08X",pcb_efwm[threads_ind]);
  1203.      fprintf (outfile, "EFN wait mask    : %08X",pcb_efwm[threads_ind]);
  1204.  
  1205.      
  1206.      if ( pcb_state[threads_ind] != SCH$C_MWAIT )     /* If not MWAIT */
  1207.        {
  1208.        
  1209.        
  1210. /*    MMG$GL_FRESVA    first free system VA    */
  1211.        
  1212. /*    if (pcb_efwm[threads_ind] < mmg_fresva && pcb_efwm[threads_ind] > 0X80000000 )
  1213.  
  1214.  
  1215. /*    EFN wait state    */
  1216.        
  1217.        if ( pcb_state[threads_ind] == SCH$C_CEF || pcb_state[threads_ind] == SCH$C_LEF ||
  1218.           pcb_state[threads_ind] == SCH$C_LEFO)     /* EFN wait      */
  1219.          {
  1220.          
  1221.          i_efwm = pcb_efwm[threads_ind] ^ 0XFFFFFFFF;    /* XOR ==> bit set for EFN's     */
  1222.          i_wefc = 32 * pcb_wefc[threads_ind];        /* Base EFN for this EFN cluster */
  1223.          
  1224. /*    Print EFN wait mask bits as EFN numbers     */
  1225.          
  1226.          
  1227. /*    Special case for EFN$C_ENF, thread upcall support EFN     */
  1228.          
  1229.          if (pcb_wefc[threads_ind] < 4 )
  1230.            {
  1231.            printf ("  EFN's = ");
  1232.            fprintf (outfile, "  EFN's = ");
  1233.  
  1234.            
  1235.            for (i_bit = 0; i_bit < 33; i_bit++)  
  1236.              {
  1237.              if (( i_efwm & bit_mask[i_bit+1] ) >> i_bit) 
  1238.         {
  1239.                 printf ("%d ", i_bit + i_wefc);
  1240.                 fprintf (outfile, "%d ", i_bit + i_wefc);
  1241.         }
  1242.              }
  1243.            }
  1244.          else
  1245.         {
  1246.             printf ("  EFN = 128, EFN$C_ENF for thread upcall support");
  1247.             fprintf (outfile, "  EFN = 128, EFN$C_ENF for thread upcall support");
  1248.         }
  1249.  
  1250.          
  1251.          } /* End if ( pcb_state[threads_ind] == SCH$C_CEF || pcb_state[threads_ind] == SCH$C_LEF ||  */
  1252.        
  1253.        
  1254.        }
  1255.      else    /*    Resource wait state    */
  1256.        {
  1257.        
  1258. /*    RSN wait state    */
  1259.        
  1260.        if ( pcb_efwm[threads_ind] < RSN$_MAX && pcb_efwm[threads_ind] > 0)
  1261.       {
  1262.           printf ("\033[31m  Process is waiting for %s \033[39m \n",resource_wait[pcb_efwm[threads_ind] - 1]);
  1263.           fprintf (outfile, "\033[31m  Process is waiting for %s \033[39m \n",resource_wait[pcb_efwm[threads_ind] - 1]);
  1264.       }
  1265.  
  1266.        else
  1267.          {
  1268.          if ( pcb_efwm[threads_ind] == (int) jib )
  1269.            {
  1270.            if (jib_flags & JIB$M_BYTCNT_WAITERS) 
  1271.           {
  1272.               printf ("  JIB address,\033[31m waiting on BYTCNT \033[39m");
  1273.               fprintf (outfile, "  JIB address,\033[31m waiting on BYTCNT \033[39m");
  1274.           }
  1275.  
  1276.            if (jib_flags & JIB$M_TQCNT_WAITERS)
  1277.           {
  1278.               printf ("  JIB address,\033[31m waiting on TQCNT \033[39m");
  1279.               fprintf (outfile, "  JIB address,\033[31m waiting on TQCNT \033[39m");
  1280.           }
  1281.  
  1282.            }
  1283.          else
  1284.         {
  1285.             printf ("  is the waiting address");
  1286.             fprintf (outfile, "  is the waiting address");
  1287.         }
  1288.  
  1289.          }
  1290.        
  1291.        } /* End if ( pcb_state[threads_ind] != SCH$C_MWAIT )     */
  1292.      
  1293.      
  1294.      
  1295.      
  1296.      printf ("\n");
  1297.      fprintf (outfile, "\n");
  1298.  
  1299.      
  1300.      if (pcb_efcs[threads_ind] != 0)  printf (" efcs        %X\n",pcb_efcs[threads_ind]);
  1301.      if (pcb_efcs[threads_ind] != 0)  fprintf (outfile, " efcs        %X\n",pcb_efcs[threads_ind]);
  1302.  
  1303.      if (pcb_efcu[threads_ind] != 0)  printf (" efcu        %X\n",pcb_efcu[threads_ind]);
  1304.      if (pcb_efcu[threads_ind] != 0)  fprintf (outfile, " efcu        %X\n",pcb_efcu[threads_ind]);
  1305.  
  1306.      
  1307.      if (pcb_efc2p[threads_ind] != 0)
  1308.        {
  1309.        printf ("EFC2P address    : %X\n",pcb_efc2p[threads_ind]);
  1310.        fprintf (outfile, "EFC2P address    : %X\n",pcb_efc2p[threads_ind]);
  1311.  
  1312.        printf ("EFN2 Clustername : %s\n", ceb_name2);
  1313.        fprintf (outfile, "EFN2 Clustername : %s\n", ceb_name2);
  1314.  
  1315.        }
  1316.      
  1317.      if (pcb_efc3p[threads_ind] != 0)
  1318.        {
  1319.        printf ("EFC3P address    : %X\n",pcb_efc3p[threads_ind]);
  1320.        fprintf (outfile, "EFC3P address    : %X\n",pcb_efc3p[threads_ind]);
  1321.  
  1322.        printf ("EFN3 Clustername : %s\n", ceb_name3);
  1323.        fprintf (outfile, "EFN3 Clustername : %s\n", ceb_name3);
  1324.  
  1325.        }
  1326.      
  1327.      threads = threads - 1;
  1328.      
  1329.      } /************ End of thread loop ***********/
  1330.    
  1331. /* ******************************************************************* */
  1332.    
  1333.    
  1334.    printf ("\nDirect   I/O count/limit    [IO's] : %8d /%8d",pcb_diocnt,pcb_diolm);
  1335.    fprintf (outfile, "\nDirect   I/O count/limit    [IO's] : %8d /%8d",pcb_diocnt,pcb_diolm);
  1336.  
  1337.    printf ("  In use : %d\n", pcb_diolm - pcb_diocnt);
  1338.    fprintf (outfile, "  In use : %d\n", pcb_diolm - pcb_diocnt);
  1339.  
  1340.    if ( pcb_diocnt == 0 )
  1341.       {
  1342.       printf("\033[31m   *** Process has run out of Direct I/O quota ***\033[39m \n");
  1343.       fprintf(outfile, "\033[31m   *** Process has run out of Direct I/O quota ***\033[39m \n");
  1344.       }
  1345.  
  1346.    
  1347. /* 
  1348.  * Print the previous in RED color (= ESC[31m" ), change then back to BLACK
  1349.  * 
  1350.  * Escape Sequences for Colors:
  1351.  * 
  1352.  *     BLACK   = "ESC[30m"
  1353.  *     RED     = "ESC[31m"
  1354.  *     GREEN   = "ESC[32m"
  1355.  *     YELLOW  = "ESC[33m"
  1356.  *     BLUE    = "ESC[34m"
  1357.  *     CYAN    = "ESC[35m"
  1358.  *     LBLUE   = "ESC[36m"
  1359.  *     WHITE   = "ESC[37m"
  1360.  * 
  1361.  *      RESET_FG = "ESC[39m"    Reset foreground color
  1362.  * 
  1363.  * 
  1364.  */
  1365.    
  1366.    
  1367.    
  1368.    printf ("Buffered I/O count/limit    [IO's] : %8d /%8d",pcb_biocnt,pcb_biolm);
  1369.    fprintf (outfile, "Buffered I/O count/limit    [IO's] : %8d /%8d",pcb_biocnt,pcb_biolm);
  1370.  
  1371.    printf ("  In use : %d\n", pcb_biolm - pcb_biocnt);
  1372.    fprintf (outfile, "  In use : %d\n", pcb_biolm - pcb_biocnt);
  1373.  
  1374.    
  1375.    
  1376.    if ( pcb_biocnt == 0 )
  1377.       {
  1378.       printf("\033[31m   *** Process has run out of Buffered I/O quota ***\033[39m \n");
  1379.       fprintf(outfile, "\033[31m   *** Process has run out of Buffered I/O quota ***\033[39m \n");
  1380.       }
  1381.  
  1382.    
  1383.    
  1384.    
  1385.    printf ("Sub-process count/limit    [Procs] : %8d /%8d",pcb_prccnt,jib_prclim);
  1386.    fprintf (outfile, "Sub-process count/limit    [Procs] : %8d /%8d",pcb_prccnt,jib_prclim);
  1387.  
  1388.    printf ("  In use : %d\n", pcb_prccnt);
  1389.    fprintf (outfile, "  In use : %d\n", pcb_prccnt);
  1390.  
  1391.    if ( pcb_prccnt == jib_prclim )
  1392.       {
  1393.       printf("\033[31m   *** Process has run out of Sub-process quota ***\033[39m \n");
  1394.       fprintf(outfile, "\033[31m   *** Process has run out of Sub-process quota ***\033[39m \n");
  1395.       }
  1396.  
  1397.  
  1398.    
  1399.    printf ("Byte count/limit           [Bytes] : %8d /%8d",jib_bytcnt,jib_bytlm);
  1400.    fprintf (outfile, "Byte count/limit           [Bytes] : %8d /%8d",jib_bytcnt,jib_bytlm);
  1401.  
  1402.    printf ("  In use : %d\n", jib_bytlm - jib_bytcnt);
  1403.    fprintf (outfile, "  In use : %d\n", jib_bytlm - jib_bytcnt);
  1404.  
  1405.    if ( jib_bytcnt == 0 )
  1406.       {
  1407.       printf("\033[31m   *** Process has run out of Byte count quota ***\033[39m \n");
  1408.       fprintf(outfile, "\033[31m   *** Process has run out of Byte count quota ***\033[39m \n");
  1409.       }
  1410.  
  1411.    
  1412.    printf ("Byte count/orig. limit     [Bytes] : %8d /%8d",jib_bytcnt,jib_org_bytlm);
  1413.    fprintf (outfile, "Byte count/orig. limit     [Bytes] : %8d /%8d",jib_bytcnt,jib_org_bytlm);
  1414.  
  1415.    printf ("  In use : %d\n", jib_org_bytlm - jib_bytcnt);
  1416.    fprintf (outfile, "  In use : %d\n", jib_org_bytlm - jib_bytcnt);
  1417.  
  1418.    
  1419.    printf ("File count/limit           [Files] : %8d /%8d",jib_filcnt,jib_fillm);
  1420.    fprintf (outfile, "File count/limit           [Files] : %8d /%8d",jib_filcnt,jib_fillm);
  1421.  
  1422.    printf ("  In use : %d\n", jib_fillm - jib_filcnt);
  1423.    fprintf (outfile, "  In use : %d\n", jib_fillm - jib_filcnt);
  1424.  
  1425.    if ( jib_filcnt == 0 )
  1426.       {
  1427.       printf("\033[31m   *** Process has run out of File limit quota ***\033[39m \n");
  1428.       fprintf(outfile, "\033[31m   *** Process has run out of File limit quota ***\033[39m \n");
  1429.       }
  1430.  
  1431.    
  1432.    printf ("Timer queue count/limit   [Timers] : %8d /%8d",jib_tqcnt,jib_tqlm);
  1433.    fprintf (outfile, "Timer queue count/limit   [Timers] : %8d /%8d",jib_tqcnt,jib_tqlm);
  1434.  
  1435.    printf ("  In use : %d\n", jib_tqlm - jib_tqcnt);
  1436.    fprintf (outfile, "  In use : %d\n", jib_tqlm - jib_tqcnt);
  1437.  
  1438.    if ( jib_tqcnt == 0 )
  1439.       {
  1440.       printf("\033[31m   *** Process has run out of Timer count quota ***\033[39m \n");
  1441.       fprintf(outfile, "\033[31m   *** Process has run out of Timer count quota ***\033[39m \n");
  1442.       }
  1443.  
  1444.    
  1445.    
  1446.    printf ("Working set quota/limit [Pagelets] : %8d /%8d",
  1447.                    wsextent - pcb_wsquota,wsextent);
  1448.    fprintf (outfile, "Working set quota/limit [Pagelets] : %8d /%8d",
  1449.                    wsextent - pcb_wsquota,wsextent);
  1450.  
  1451.    printf ("  In use : %d\n", pcb_wsquota);
  1452.    fprintf (outfile, "  In use : %d\n", pcb_wsquota);
  1453.  
  1454.    if ( wsextent - pcb_wsquota == 0 )
  1455.       {
  1456.       printf("\033[31m   *** Process has used all of Working set quota ***\033[39m \n");
  1457.       fprintf(outfile, "\033[31m   *** Process has used all of Working set quota ***\033[39m \n");
  1458.       }
  1459.  
  1460.    
  1461.    printf ("Page file quota/limit      [Pages] : %8d /%8d",jib_pgflcnt,jib_pgflquota);
  1462.    fprintf (outfile, "Page file quota/limit      [Pages] : %8d /%8d",jib_pgflcnt,jib_pgflquota);
  1463.  
  1464.    printf ("  In use : %d\n", jib_pgflquota - jib_pgflcnt);
  1465.    fprintf (outfile, "  In use : %d\n", jib_pgflquota - jib_pgflcnt);
  1466.  
  1467.    if ( jib_pgflcnt == 0 )
  1468.       {
  1469.       printf("\033[31m   *** Process has run out of Page file quota ***\033[39m \n");
  1470.       fprintf(outfile, "\033[31m   *** Process has run out of Page file quota ***\033[39m \n");
  1471.       }
  1472.  
  1473.    
  1474.    if ( phd_astlm != -1 )
  1475.      {
  1476.      printf ("AST count/limit            [AST's] : %8d /%8d",pcb_astcnt,phd_astlm);
  1477.      fprintf (outfile, "AST count/limit            [AST's] : %8d /%8d",pcb_astcnt,phd_astlm);
  1478.  
  1479.      printf ("  In use : %d\n", phd_astlm - pcb_astcnt);
  1480.      fprintf (outfile, "  In use : %d\n", phd_astlm - pcb_astcnt);
  1481.  
  1482.      }
  1483.    else
  1484.      {
  1485.      printf ("AST count/limit            [AST's] : %8d/     n.a. \n",pcb_astcnt);
  1486.      fprintf (outfile, "AST count/limit            [AST's] : %8d/     n.a. \n",pcb_astcnt);
  1487.      }
  1488.    if ( pcb_astcnt == 0 )
  1489.       {
  1490.       printf("\033[31m   *** Process has run out of AST quota ***\033[39m \n");
  1491.       fprintf(outfile, "\033[31m   *** Process has run out of AST quota ***\033[39m \n");
  1492.       }
  1493.  
  1494.    
  1495.    pcb_aste_k = '-';
  1496.    pcb_aste_e = '-';
  1497.    pcb_aste_s = '-';
  1498.    pcb_aste_u = '-';
  1499.    
  1500.    pcb_asta_k = '-';
  1501.    pcb_asta_e = '-';
  1502.    pcb_asta_s = '-';
  1503.    pcb_asta_u = '-';
  1504.    
  1505.    if (phd_astsr_asten != -1)
  1506.      {
  1507.      if ( phd_astsr_asten & PR$M_ASTEN_KEN ) pcb_aste_k  = 'K';
  1508.      if ( phd_astsr_asten & PR$M_ASTEN_EEN ) pcb_aste_e  = 'E';
  1509.      if ( phd_astsr_asten & PR$M_ASTEN_SEN ) pcb_aste_s  = 'S';
  1510.      if ( phd_astsr_asten & PR$M_ASTEN_UEN ) pcb_aste_u  = 'U';
  1511.      
  1512.      if (pcb_aste_k != 'K' || pcb_aste_e != 'E' || pcb_aste_s != 'S' || pcb_aste_u != 'U')
  1513.     {
  1514.         printf("\033[31m");            /* RED    */
  1515.         fprintf(outfile, "\033[31m");            /* RED    */
  1516.     }
  1517.  
  1518.         
  1519.      printf ("AST's enabled               [KESU] :     %1c%1c%1c%1c \033[39m \n",
  1520.                 pcb_aste_k,pcb_aste_e,pcb_aste_s,pcb_aste_u);
  1521.      fprintf (outfile, "AST's enabled               [KESU] :     %1c%1c%1c%1c \033[39m \n",
  1522.                 pcb_aste_k,pcb_aste_e,pcb_aste_s,pcb_aste_u);
  1523.  
  1524.      }
  1525.    else
  1526.      {
  1527.      printf ("AST's enabled               [KESU] : Process is outswapped \n");
  1528.      fprintf (outfile, "AST's enabled               [KESU] : Process is outswapped \n");
  1529.      }
  1530.    
  1531.    if ( pcb_astact & PR$M_ASTEN_KEN ) pcb_asta_k  = 'K';
  1532.    if ( pcb_astact & PR$M_ASTEN_EEN ) pcb_asta_e  = 'E';
  1533.    if ( pcb_astact & PR$M_ASTEN_SEN ) pcb_asta_s  = 'S';
  1534.    if ( pcb_astact & PR$M_ASTEN_UEN ) pcb_asta_u  = 'U';
  1535.    
  1536.    if (pcb_asta_k != '-' || pcb_asta_e != '-' || pcb_asta_s != '-' || pcb_asta_u != '-')
  1537.       {
  1538.       printf("\033[31m");            /* RED    */
  1539.       fprintf(outfile, "\033[31m");            /* RED    */
  1540.       }
  1541.  
  1542.       
  1543.    printf ("AST's active                [KESU] :     %1c%1c%1c%1c \033[39m \n",
  1544.               pcb_asta_k,pcb_asta_e,pcb_asta_s,pcb_asta_u);
  1545.    fprintf (outfile, "AST's active                [KESU] :     %1c%1c%1c%1c \033[39m \n",
  1546.               pcb_asta_k,pcb_asta_e,pcb_asta_s,pcb_asta_u);
  1547.  
  1548.    
  1549.    
  1550.    if (pcb_ast_k != '-' || pcb_ast_e != '-' || pcb_ast_s != '-' || pcb_ast_u != '-')
  1551.       {
  1552.       printf("\033[31m");            /* RED    */
  1553.       fprintf(outfile, "\033[31m");            /* RED    */
  1554.       }
  1555.  
  1556.    
  1557.    printf ("AST's queued                [KESU] :     %1c%1c%1c%1c \033[39m \n",
  1558.         pcb_ast_k,pcb_ast_e,pcb_ast_s,pcb_ast_u);
  1559.    fprintf (outfile, "AST's queued                [KESU] :     %1c%1c%1c%1c \033[39m \n",
  1560.         pcb_ast_k,pcb_ast_e,pcb_ast_s,pcb_ast_u);
  1561.  
  1562.    
  1563.    printf ("Delete pending count (XQP event)   : %8d\n",pcb_dpc);
  1564.    fprintf (outfile, "Delete pending count (XQP event)   : %8d\n",pcb_dpc);
  1565.  
  1566.    
  1567.    
  1568.    printf ("\nAbsolute/Last event/Delta time     : %08X / %08X / %08X [hex] ticks\n",
  1569.         abstim_tics, pcb_waitime, abstim_tics - pcb_waitime);
  1570.    fprintf (outfile, "\nAbsolute/Last event/Delta time     : %08X / %08X / %08X [hex] ticks\n",
  1571.         abstim_tics, pcb_waitime, abstim_tics - pcb_waitime);
  1572.  
  1573.    
  1574. /*    1 tick = 10 milliseconds,  100 ticks = 1 second        */
  1575.    
  1576.    t_delta   = abstim_tics - pcb_waitime;
  1577.    
  1578.    t_days    = t_delta/100/60/60/24;        /* Days        */
  1579.    t_delta   = t_delta - t_days * 100 * 60 * 60 * 24;
  1580.    
  1581.    t_hours   = t_delta/100/60/60;        /* Hours    */
  1582.    t_delta   = t_delta - t_hours * 100 * 60 * 60; 
  1583.    
  1584.    t_minutes = t_delta/100/60;            /* Minutes    */
  1585.    t_delta   = t_delta - t_minutes * 100 * 60;
  1586.    
  1587.    t_seconds = t_delta/100;            /* Seconds    */
  1588.    t_delta   = t_delta - t_seconds * 100;    /* 10 Milliseconds    */
  1589.    
  1590.    printf ("Time since last event :");
  1591.    fprintf (outfile, "Time since last event :");
  1592.  
  1593.    
  1594.    if (t_days    != 0 ) printf (" %d days", t_days);
  1595.    if (t_days    != 0 ) fprintf (outfile, " %d days", t_days);
  1596.  
  1597.    if (t_hours   != 0 ) printf (" %d hours",t_hours);
  1598.    if (t_hours   != 0 ) fprintf (outfile, " %d hours",t_hours);
  1599.  
  1600.    if (t_minutes != 0 ) printf (" %d minutes",t_minutes);
  1601.    if (t_minutes != 0 ) fprintf (outfile, " %d minutes",t_minutes);
  1602.  
  1603.    if (t_seconds != 0 ) printf (" %d seconds",t_seconds);
  1604.    if (t_seconds != 0 ) fprintf (outfile, " %d seconds",t_seconds);
  1605.  
  1606.  
  1607.    printf (" %d milliseconds\n",t_delta * 10);
  1608.    fprintf (outfile, " %d milliseconds\n",t_delta * 10);
  1609.  
  1610.       
  1611.    
  1612. /*    Get process channels    */
  1613.       
  1614.    prc_index = (short int) pcb_pid;
  1615.    
  1616.    arglist [0] = 2;
  1617.    arglist [1] = (int) prc_index;    /*    Index    */
  1618.    arglist [2] = (int) pcb_pid;        /*    IPID    */
  1619.    
  1620.    return_status =    SYS$CMKRNL(&get_process_channels, arglist);
  1621.    if (return_status == SS$_TIMEOUT)
  1622.       {
  1623.       printf ("%%MWAIT-F-NORESPONSE, can not read target process channels\n");
  1624.       fprintf (outfile, "%%MWAIT-F-NORESPONSE, can not read target process channels\n");
  1625.       }
  1626.  
  1627.    if (return_status != SS$_NORMAL) return (return_status);
  1628.       
  1629. /*                V6     V7
  1630.  *               ----    ----
  1631.  *    ccb_table[0] = UCB    UCB
  1632.  *    ccb_table[1] = WIND    STS
  1633.  *    ccb_table[2] = STS    IOC
  1634.  *    ccb_table[3] = IOC    DIRP
  1635.  *    ccb_table[4] = AMOD    AMOD
  1636.  *    ccb_table[5] = DIRP    WIND
  1637.  *    ccb_table[6] = CHAN    CHAN
  1638.  *
  1639. */
  1640.    printf ("\nProcess active channels: \n");
  1641.    fprintf (outfile, "\nProcess active channels: \n");
  1642.  
  1643.    
  1644.    printf ("\nChnl  Window  IOC Sts  Device/file accessed\n");
  1645.    fprintf (outfile, "\nChnl  Window  IOC Sts  Device/file accessed\n");
  1646.  
  1647.    printf ("----  ------  --- ---  --------------------\n");
  1648.    fprintf (outfile, "----  ------  --- ---  --------------------\n");
  1649.  
  1650.    
  1651.    for ( i = 0; i < ctl_chindx; i++)
  1652.      {
  1653.      
  1654.      j=8*i;                    /* CCB index        */
  1655.      ccb = (CCB *) &ccb_table[j];        /* CCB entry address    */
  1656.      
  1657.      if ( (ccb->ccb$b_amod != 0) && ( ccb->ccb$l_ucb != 0) )
  1658.        {
  1659.        if (ccb->ccb$l_ioc != 0)
  1660.           strncpy(busy,busy1,4);
  1661.        else
  1662.           strncpy(busy,busy0,4);
  1663.        
  1664.        
  1665.        for (k=0; k<100; k++)
  1666.          {
  1667.          ddb_name[k]  = 0;
  1668.          tempstr[k]   = 0;
  1669.          file_name[k] = 0;
  1670.          }
  1671.        
  1672.        arglist [0] = 2;
  1673.        arglist [1] = (int) ccb->ccb$l_ucb;      /* UCB        */
  1674.        arglist [2] = (int) ccb->ccb$l_ioc;    /* IO count    */
  1675.        
  1676.        window = (int) ccb->ccb$l_wind;        /* Window    */
  1677.  
  1678.        irp_count = 0;                /* Clear IRP #    */
  1679.        
  1680.        return_status =    SYS$CMKRNL(&get_device_name, arglist);
  1681.        if (return_status != SS$_NORMAL) return (return_status);
  1682.           
  1683.        
  1684.        for (k=0; k < 5; k++)
  1685.          {
  1686.          unit_string[k] = 0;
  1687.          }
  1688.        
  1689.        return_status = SYS$FAO (&fao_d, &size, &str_d, unit);
  1690.        if (return_status != SS$_NORMAL) return (return_status);
  1691.           
  1692. /*    printf ("Unit = %d %s size %d\n", unit, unit_string, size);    */
  1693. /*    fprintf (outfile, "Unit = %d %s size %d\n", unit, unit_string, size);    */
  1694.  
  1695.        
  1696.        strcat (ddb_name,unit_string);        /* Insert unit #    */
  1697.        strcat (ddb_name,":");            /* Insert :        */
  1698.        
  1699. /*    Filenames only for directory structured devices    */
  1700.        
  1701.        if ( (ucb_devchar & DEV$M_DIR) && !( (ucb_sts & UCB$M_MNTVERIP) || (ucb_sts & UCB$M_MSCP_MNTVERIP) ))
  1702.             /* Directory structured and no mount verify */
  1703.          {
  1704.          
  1705. /*    Get file name    */
  1706.          
  1707.          if ( (int)ccb->ccb$l_wind > 0 )
  1708.             ccb->ccb$l_wind = (WCB *) window;     /* PST index ==> window */
  1709.          
  1710.          if (ccb->ccb$l_wind != 0 )
  1711.            {
  1712.            fcb = (FCB *) fcb_block;        /* FCB local address    */
  1713.            if ( fcb->fcb$b_type != DYN$C_FCB ) break;    /* Not a FCB    */
  1714.               
  1715. /*    Set up disk name descriptor    */
  1716.            
  1717.            disk_d.dsc$b_class   = DSC$K_CLASS_S;
  1718.            disk_d.dsc$b_dtype   = DSC$K_DTYPE_T;
  1719.            disk_d.dsc$w_length  = strlen (ddb_name);
  1720.            disk_d.dsc$a_pointer = (char *) ddb_name;
  1721.            
  1722.            return_status = lib$fid_to_name (&disk_d, fcb->fcb$w_fid,
  1723.                            &file_d, &size, 0, &tmp);
  1724.            if (return_status != SS$_NORMAL) return (return_status);
  1725.               
  1726.            
  1727.            for (k=0; k<100; k++)
  1728.              {
  1729.              tempstr[k]   = 0;
  1730.              }
  1731.            
  1732. /*    printf(" filename : %s  size = %d status = %d ACPstatus = %d \n",
  1733.         file_name,size,return_status,tmp);            */
  1734.            
  1735.            str_ptr = (char *) file_name;
  1736.            str_ptr2 = strstr (file_name, "[");
  1737.            tmp = str_ptr2 - str_ptr;
  1738.            
  1739. /*    printf(" string = %08X  position = %08X diff = %d\n",
  1740.         str_ptr, str_ptr2, tmp);                */
  1741.            
  1742.            strncpy (tempstr, file_name + tmp, size - tmp);
  1743.            
  1744. /*    printf(" filex = %s\n", tempstr);                */
  1745.            
  1746.            strcat (ddb_name,tempstr);        /* Insert file name    */
  1747.            }
  1748.          } /* End if UCB = DEV$M_DIR    */
  1749.        
  1750.        
  1751.        if (ccb->ccb$l_ioc != 0) printf("\033[31m");    /* RED    */
  1752.        if (ccb->ccb$l_ioc != 0) fprintf(outfile, "\033[31m");    /* RED    */
  1753.  
  1754.           
  1755.        if (ddb_name[0] == 0x4d && ddb_name[1] == 0x42 )
  1756.       {
  1757.           printf ("%04X %08X %3d %4s %s (Buffered I/O Quota available: %d bytes)\n",
  1758.             ccb->ccb$l_chan, ccb->ccb$l_wind, ccb->ccb$l_ioc, busy,ddb_name,bufquo);
  1759.           fprintf (outfile, "%04X %08X %3d %4s %s (Buffered I/O Quota available: %d bytes)\n",
  1760.             ccb->ccb$l_chan, ccb->ccb$l_wind, ccb->ccb$l_ioc, busy,ddb_name,bufquo);
  1761.       }
  1762.  
  1763.        else
  1764.       {
  1765.           printf ("%04X %08X %3d %4s %s\n",
  1766.                  ccb->ccb$l_chan, ccb->ccb$l_wind, ccb->ccb$l_ioc, busy,ddb_name);
  1767.           fprintf (outfile, "%04X %08X %3d %4s %s\n",
  1768.                  ccb->ccb$l_chan, ccb->ccb$l_wind, ccb->ccb$l_ioc, busy,ddb_name);
  1769.       }
  1770.  
  1771.        
  1772.        if (ccb->ccb$l_ioc != 0) printf("\033[39m");    /* BLACK */
  1773.        if (ccb->ccb$l_ioc != 0) fprintf(outfile, "\033[39m");    /* BLACK */
  1774.  
  1775.           
  1776.  
  1777.     if ( net_port != 0)
  1778.       {
  1779.       printf ("Session Control Port : SCL$PORT$%08X \n",scl);
  1780.       fprintf (outfile, "Session Control Port : SCL$PORT$%08X \n",scl);
  1781.       }
  1782.  
  1783.     if ( net_port == 1)
  1784.       {
  1785.       printf ("OSI Transport Port   : %s\n\n",port_name);
  1786.       fprintf (outfile, "OSI Transport Port   : %s\n\n",port_name);
  1787.       }
  1788.  
  1789.     if ( net_port == 2)
  1790.       {
  1791.       printf ("NSP Transport Port   : %s\n\n",port_name);
  1792.       fprintf (outfile, "NSP Transport Port   : %s\n\n",port_name);
  1793.       }
  1794.  
  1795.  
  1796.     /*    IRP            */
  1797.        
  1798. /*    printf ("IRP_COUNT = %d\n",irp_count);        */
  1799. /*    fprintf (outfile, "IRP_COUNT = %d\n",irp_count);        */
  1800.  
  1801.        
  1802.        if ( irp_count != 0 )
  1803.          {
  1804.          for (k=0; k<irp_count; k++)
  1805.            {
  1806.  
  1807. /* INET device I/O packets are on CXB's at BG devices    */
  1808.  
  1809.    if ( (ddb_name[0] == 'I') && (ddb_name[1] == 'N') &&
  1810.         (ddb_name[2] == 'E') && (ddb_name[3] == 'T') )
  1811.       {
  1812.            printf ("       The CXB is on   BG%d:  \n",irp_unit[k]);
  1813.            fprintf (outfile, "       The CXB is on   BG%d:  \n",irp_unit[k]);
  1814.                             /* BG unit number */
  1815.       }
  1816.  
  1817.            
  1818.            printf ("       I/O-Packet %3d       Hex / Decimal\n",k+1);
  1819.            fprintf (outfile, "       I/O-Packet %3d       Hex / Decimal\n",k+1);
  1820.  
  1821.            printf ("       --------------  ------------------\n");
  1822.            fprintf (outfile, "       --------------  ------------------\n");
  1823.  
  1824.            
  1825.  
  1826. /*    Mailbox read/write from an other process    */
  1827.            
  1828.            if (irp_pid[k] != pcb_pid)
  1829.              {
  1830.              return_status = SYS$GETJPIW (0, &irp_epid[k], 0, &itmlst, 0, 0, 0);
  1831.              
  1832.              printf ("       Internal PID  : %08X    \033[31m       Process name: \033[39m \n",irp_pid[k]);
  1833.              fprintf (outfile, "       Internal PID  : %08X    \033[31m       Process name: \033[39m \n",irp_pid[k]);
  1834.  
  1835.              printf ("       PID           : %08X    \033[31m       %s \033[39m \n",irp_epid[k],prcname);
  1836.              fprintf (outfile, "       PID           : %08X    \033[31m       %s \033[39m \n",irp_epid[k],prcname);
  1837.  
  1838.              }
  1839.            
  1840.            printf ("       IRP address   : %08X\n",irp_addr[k]);
  1841.            fprintf (outfile, "       IRP address   : %08X\n",irp_addr[k]);
  1842.  
  1843.            printf ("       EFN           : %08X  %08d\n",irp_efn[k],irp_efn[k]);
  1844.            fprintf (outfile, "       EFN           : %08X  %08d\n",irp_efn[k],irp_efn[k]);
  1845.  
  1846.            printf ("       FUNC          : %08X  %08d %s\n",irp_func[k],irp_func[k],iofun[(irp_func[k] & IO$_VIRTUAL)]);
  1847.            fprintf (outfile, "       FUNC          : %08X  %08d %s\n",irp_func[k],irp_func[k],iofun[(irp_func[k] & IO$_VIRTUAL)]);
  1848.  
  1849.            printf ("       IOST1         : %08X\n",irp_iost1[k]);
  1850.            fprintf (outfile, "       IOST1         : %08X\n",irp_iost1[k]);
  1851.  
  1852.            printf ("       IOSB address  : %08X\n",irp_iosb_a[k]);
  1853.            fprintf (outfile, "       IOSB address  : %08X\n",irp_iosb_a[k]);
  1854.  
  1855.            printf ("       IOSB = [hex]  : %08X.%08X\n",irp_iosb[k]);
  1856.            fprintf (outfile, "       IOSB = [hex]  : %08X.%08X\n",irp_iosb[k]);
  1857.  
  1858.            printf ("       BCNT          : %08X  %08d Bytes\n",irp_bcnt[k],irp_bcnt[k]);
  1859.            fprintf (outfile, "       BCNT          : %08X  %08d Bytes\n",irp_bcnt[k],irp_bcnt[k]);
  1860.  
  1861.            printf ("       AST address   : %08X ",irp_ast[k]);
  1862.            fprintf (outfile, "       AST address   : %08X ",irp_ast[k]);
  1863.  
  1864.            
  1865.            if (irp_ast[k] != 0)
  1866.              {
  1867.  
  1868.          for (l=0; l < 40; l++)    image_name[l] = '\0';
  1869.  
  1870.              arglist [0] = 2;
  1871.              arglist [1] = irp_ast[k];        /* PC    */
  1872.              arglist [2] = irp_pid[k];        /* IPID    */
  1873.              
  1874.              return_status =    SYS$CMKRNL(&map_address, arglist);
  1875.              if (return_status == SS$_TIMEOUT)
  1876.         {
  1877.                 printf ("%%MWAIT-F-NORESPONSE, can not read target process image list\n");
  1878.                 fprintf (outfile, "%%MWAIT-F-NORESPONSE, can not read target process image list\n");
  1879.         }
  1880.  
  1881.              if (return_status != SS$_NORMAL) return (return_status);
  1882.                 
  1883.              if (found == 1)
  1884.                {
  1885.                printf ("          is in the image: \n\n%s\n", image_name);
  1886.                fprintf (outfile, "          is in the image: \n\n%s\n", image_name);
  1887.  
  1888.                
  1889.                printf ("Base      End       Image Offset  Psect type\n%08X  %08X  %08X      %s\n\n",
  1890.                            start,end,offset,psects[psect]);
  1891.                fprintf (outfile, "Base      End       Image Offset  Psect type\n%08X  %08X  %08X      %s\n\n",
  1892.                            start,end,offset,psects[psect]);
  1893.  
  1894.                }
  1895.              else
  1896.         {
  1897.                 printf ("          is not within a system or user image\n");
  1898.                 fprintf (outfile, "          is not within a system or user image\n");
  1899.         }
  1900.  
  1901.              
  1902.              } /* End irp_ast[k] != 0 */
  1903.            else
  1904.           {
  1905.               printf ("\n");            /* <CR>    */
  1906.               fprintf (outfile, "\n");            /* <CR>    */
  1907.           }
  1908.  
  1909.            
  1910.            
  1911.            printf ("       AST parameter : %08X  %08d\n",irp_astprm[k],irp_astprm[k]);
  1912.            fprintf (outfile, "       AST parameter : %08X  %08d\n",irp_astprm[k],irp_astprm[k]);
  1913.  
  1914.            printf ("       P1            : %08X  %08d\n",irp_p1[k],irp_p1[k]);
  1915.            fprintf (outfile, "       P1            : %08X  %08d\n",irp_p1[k],irp_p1[k]);
  1916.  
  1917.            printf ("       P2            : %08X  %08d\n",irp_p2[k],irp_p2[k]);
  1918.            fprintf (outfile, "       P2            : %08X  %08d\n",irp_p2[k],irp_p2[k]);
  1919.  
  1920.            printf ("       P3            : %08X  %08d\n",irp_p3[k],irp_p3[k]);
  1921.            fprintf (outfile, "       P3            : %08X  %08d\n",irp_p3[k],irp_p3[k]);
  1922.  
  1923.            printf ("       P4            : %08X  %08d\n",irp_p4[k],irp_p4[k]);
  1924.            fprintf (outfile, "       P4            : %08X  %08d\n",irp_p4[k],irp_p4[k]);
  1925.  
  1926.            printf ("       P5            : %08X  %08d\n",irp_p5[k],irp_p5[k]);
  1927.            fprintf (outfile, "       P5            : %08X  %08d\n",irp_p5[k],irp_p5[k]);
  1928.  
  1929.            printf ("       P6            : %08X  %08d\n\n",irp_p6[k],irp_p6[k]);
  1930.            fprintf (outfile, "       P6            : %08X  %08d\n\n",irp_p6[k],irp_p6[k]);
  1931.  
  1932.            
  1933.            
  1934.            } /*      */
  1935.          } /*      */
  1936.        } /*      */
  1937.      } /*      */
  1938.    
  1939. /* ************************************************************************ */
  1940.    
  1941.    arglist [0] = 1;
  1942.    arglist [1] = (int) pcb_pid;            /* IPID    */
  1943.    
  1944.    return_status =    SYS$CMKRNL(&get_process_registers, arglist);
  1945.    if (return_status == SS$_TIMEOUT)
  1946.       {
  1947.       printf ("%%MWAIT-F-NORESPONSE, can not read target process registers\n");
  1948.       fprintf (outfile, "%%MWAIT-F-NORESPONSE, can not read target process registers\n");
  1949.       }    
  1950.  
  1951.    if (return_status != SS$_NORMAL) return (return_status);
  1952.       
  1953.    printf ("\nCurrent process registers: \n\n");
  1954.    fprintf (outfile, "\nCurrent process registers: \n\n");
  1955.  
  1956.    
  1957.    
  1958. /*    Print registers, NOTE:  we must swap the high and low order longword */
  1959.    
  1960.    printf ("R0   = %08X %08X  R1   = %08X %08X  R2   = %08X %08X\n",
  1961.     prc_registers[1],prc_registers[0],prc_registers[3],prc_registers[2],
  1962.     prc_registers[5],prc_registers[4]);
  1963.    fprintf (outfile, "R0   = %08X %08X  R1   = %08X %08X  R2   = %08X %08X\n",
  1964.     prc_registers[1],prc_registers[0],prc_registers[3],prc_registers[2],
  1965.     prc_registers[5],prc_registers[4]);
  1966.  
  1967.    
  1968.    printf ("R3   = %08X %08X  R4   = %08X %08X  R5   = %08X %08X\n",
  1969.        prc_registers[7],prc_registers[6],prc_registers[9],prc_registers[8],
  1970.        prc_registers[11],prc_registers[10]);
  1971.    fprintf (outfile, "R3   = %08X %08X  R4   = %08X %08X  R5   = %08X %08X\n",
  1972.        prc_registers[7],prc_registers[6],prc_registers[9],prc_registers[8],
  1973.        prc_registers[11],prc_registers[10]);
  1974.  
  1975.    
  1976.    printf ("R6   = %08X %08X  R7   = %08X %08X  R8   = %08X %08X\n",
  1977.        prc_registers[13],prc_registers[12],prc_registers[15],prc_registers[14],
  1978.        prc_registers[17],prc_registers[16]);
  1979.    fprintf (outfile, "R6   = %08X %08X  R7   = %08X %08X  R8   = %08X %08X\n",
  1980.        prc_registers[13],prc_registers[12],prc_registers[15],prc_registers[14],
  1981.        prc_registers[17],prc_registers[16]);
  1982.  
  1983.    
  1984.    printf ("R9   = %08X %08X  R10  = %08X %08X  R11  = %08X %08X\n",
  1985.        prc_registers[19],prc_registers[18],prc_registers[21],prc_registers[20],
  1986.        prc_registers[23],prc_registers[22]);
  1987.    fprintf (outfile, "R9   = %08X %08X  R10  = %08X %08X  R11  = %08X %08X\n",
  1988.        prc_registers[19],prc_registers[18],prc_registers[21],prc_registers[20],
  1989.        prc_registers[23],prc_registers[22]);
  1990.  
  1991.    
  1992.    printf ("R12  = %08X %08X  R13  = %08X %08X  R14  = %08X %08X\n",
  1993.        prc_registers[25],prc_registers[24],prc_registers[27],prc_registers[26],
  1994.        prc_registers[29],prc_registers[28]);
  1995.    fprintf (outfile, "R12  = %08X %08X  R13  = %08X %08X  R14  = %08X %08X\n",
  1996.        prc_registers[25],prc_registers[24],prc_registers[27],prc_registers[26],
  1997.        prc_registers[29],prc_registers[28]);
  1998.  
  1999.    
  2000.    printf ("R15  = %08X %08X  R16  = %08X %08X  R17  = %08X %08X\n",
  2001.        prc_registers[31],prc_registers[30],prc_registers[33],prc_registers[32],
  2002.        prc_registers[35],prc_registers[34]);
  2003.    fprintf (outfile, "R15  = %08X %08X  R16  = %08X %08X  R17  = %08X %08X\n",
  2004.        prc_registers[31],prc_registers[30],prc_registers[33],prc_registers[32],
  2005.        prc_registers[35],prc_registers[34]);
  2006.  
  2007.    
  2008.    printf ("R18  = %08X %08X  R19  = %08X %08X  R20  = %08X %08X\n",
  2009.        prc_registers[37],prc_registers[36],prc_registers[39],prc_registers[38],
  2010.        prc_registers[41],prc_registers[40]);
  2011.    fprintf (outfile, "R18  = %08X %08X  R19  = %08X %08X  R20  = %08X %08X\n",
  2012.        prc_registers[37],prc_registers[36],prc_registers[39],prc_registers[38],
  2013.        prc_registers[41],prc_registers[40]);
  2014.  
  2015.    
  2016.    printf ("R21  = %08X %08X  R22  = %08X %08X  R23  = %08X %08X\n",
  2017.        prc_registers[43],prc_registers[42],prc_registers[45],prc_registers[44],
  2018.        prc_registers[47],prc_registers[46]);
  2019.    fprintf (outfile, "R21  = %08X %08X  R22  = %08X %08X  R23  = %08X %08X\n",
  2020.        prc_registers[43],prc_registers[42],prc_registers[45],prc_registers[44],
  2021.        prc_registers[47],prc_registers[46]);
  2022.  
  2023.    
  2024.    printf ("R24  = %08X %08X  R25  = %08X %08X  R26  = %08X %08X\n",
  2025.        prc_registers[49],prc_registers[48],prc_registers[51],prc_registers[50],
  2026.        prc_registers[53],prc_registers[52]);
  2027.    fprintf (outfile, "R24  = %08X %08X  R25  = %08X %08X  R26  = %08X %08X\n",
  2028.        prc_registers[49],prc_registers[48],prc_registers[51],prc_registers[50],
  2029.        prc_registers[53],prc_registers[52]);
  2030.  
  2031.    
  2032.    printf ("R27  = %08X %08X  R28  = %08X %08X  FP   = %08X %08X\n",
  2033.        prc_registers[55],prc_registers[54],prc_registers[57],prc_registers[56],
  2034.        prc_registers[59],prc_registers[58]);
  2035.    fprintf (outfile, "R27  = %08X %08X  R28  = %08X %08X  FP   = %08X %08X\n",
  2036.        prc_registers[55],prc_registers[54],prc_registers[57],prc_registers[56],
  2037.        prc_registers[59],prc_registers[58]);
  2038.  
  2039.    
  2040.    printf ("PC   = %08X %08X  PS   = %08X %08X\n",
  2041.    prc_registers[61],prc_registers[60],prc_registers[63],prc_registers[62]);
  2042.    fprintf (outfile, "PC   = %08X %08X  PS   = %08X %08X\n",
  2043.    prc_registers[61],prc_registers[60],prc_registers[63],prc_registers[62]);
  2044.  
  2045.    
  2046.    prvmod = prc_registers[62] & 0x3;          /* Extract previous mode */
  2047.    curmod = (prc_registers[62] & 0x18) >> 3;    /* Extract current mode  */
  2048.    ipl    = prc_registers[62] & 0x1F00;          /* Extract IPL       */
  2049.    
  2050.    printf ("\nCurrent mode     : %10s\nPrevious mode    : %10s\n",
  2051.                        modes[curmod],modes[prvmod]);
  2052.    fprintf (outfile, "\nCurrent mode     : %10s\nPrevious mode    : %10s\n",
  2053.                        modes[curmod],modes[prvmod]);
  2054.  
  2055.    printf ("Current IPL      : %d \n",ipl);
  2056.    fprintf (outfile, "Current IPL      : %d \n",ipl);
  2057.  
  2058.    
  2059. /*    Map Current PC    */
  2060.    
  2061.    for (k=0; k<40; k++)
  2062.      {
  2063.      image_name[k] = 0;
  2064.      }
  2065.    
  2066.    arglist [0] = 2;
  2067.    arglist [1] = prc_registers[60];        /* PC    */
  2068.    arglist [2] = (int) pcb_pid;            /* IPID    */
  2069.    
  2070.    return_status =    SYS$CMKRNL(&map_address, arglist);
  2071.    if (return_status == SS$_TIMEOUT)
  2072.       {
  2073.       printf ("%%MWAIT-F-NORESPONSE, can not read target process image list\n");
  2074.       fprintf (outfile, "%%MWAIT-F-NORESPONSE, can not read target process image list\n");
  2075.       }
  2076.  
  2077.    if (return_status != SS$_NORMAL) return (return_status);
  2078.       
  2079. /*   printf (" tmp = %08X  ldrimg = %08X  imcb = %08X start = %08X  end = %08X found = %d\n",
  2080. /*   fprintf (outfile, " tmp = %08X  ldrimg = %08X  imcb = %08X start = %08X  end = %08X found = %d\n",
  2081.  
  2082.                     tmp,ldrimg,imcb,start,end,found);  */
  2083.    
  2084. /*  printf (" start = %08X  end = %08X found = %d kfe_sect = %08X kfe_offs = %08X\n",
  2085. /*  fprintf (outfile, " start = %08X  end = %08X found = %d kfe_sect = %08X kfe_offs = %08X\n",
  2086.  
  2087.             start,end,found,kferes_section,kferes_offset);    */
  2088.    
  2089.    if (found == 1)
  2090.      {
  2091.      printf ("\nThe current PC:        %08X is in the image: \n%s\n",
  2092.             prc_registers[60],image_name);
  2093.      fprintf (outfile, "\nThe current PC:        %08X is in the image: \n%s\n",
  2094.             prc_registers[60],image_name);
  2095.  
  2096.      
  2097.      printf ("Base      End       Image Offset  Psect type\n%08X  %08X  %08X      %s\n",
  2098.             start,end,offset,psects[psect]);
  2099.      fprintf (outfile, "Base      End       Image Offset  Psect type\n%08X  %08X  %08X      %s\n",
  2100.             start,end,offset,psects[psect]);
  2101.  
  2102.      
  2103.      }
  2104.    else
  2105.       {
  2106.       printf ("\nThe current PC:  %08X is not within a system or user image\n",
  2107.             prc_registers[60]);
  2108.       fprintf (outfile, "\nThe current PC:  %08X is not within a system or user image\n",
  2109.             prc_registers[60]);
  2110.       }
  2111.  
  2112.    
  2113.    
  2114.    
  2115.    
  2116. /*    Map R26 (Return address)    */
  2117.    
  2118.    for (k=0; k<40; k++)    image_name[k] = 0;
  2119.       
  2120.    arglist [0] = 2;
  2121.    arglist [1] = prc_registers[52];        /* R26    */
  2122.    arglist [2] = (int) pcb_pid;            /* IPID    */
  2123.    
  2124.    return_status =    SYS$CMKRNL(&map_address, arglist);
  2125.    if (return_status == SS$_TIMEOUT)
  2126.       {
  2127.       printf ("%%MWAIT-F-NORESPONSE, can not read target process image list\n");
  2128.       fprintf (outfile, "%%MWAIT-F-NORESPONSE, can not read target process image list\n");
  2129.       }
  2130.  
  2131.    if (return_status != SS$_NORMAL) return (return_status);
  2132.       
  2133. /*  printf (" tmp = %08X  ldrimg = %08X  imcb = %08X start = %08X  end = %08X found = %d\n",
  2134.                     tmp,ldrimg,imcb,start,end,found);    */
  2135. /*  fprintf (outfile, " tmp = %08X  ldrimg = %08X  imcb = %08X start = %08X  end = %08X found = %d\n",
  2136.                     tmp,ldrimg,imcb,start,end,found);    */
  2137.  
  2138.    
  2139. /*  printf (" start = %08X  end = %08X found = %d kfe_sect = %08X kfe_offs = %08X\n",
  2140.             start,end,found,kferes_section,kferes_offset);    */
  2141. /*  fprintf (outfile, " start = %08X  end = %08X found = %d kfe_sect = %08X kfe_offs = %08X\n",
  2142.             start,end,found,kferes_section,kferes_offset);    */
  2143.  
  2144.    
  2145.    if (found == 1)
  2146.      {
  2147.      printf ("\nR26 (Return address):  %08X is in the image: \n%s\n",
  2148.              prc_registers[52],image_name);
  2149.      fprintf (outfile, "\nR26 (Return address):  %08X is in the image: \n%s\n",
  2150.              prc_registers[52],image_name);
  2151.  
  2152.      
  2153.      printf ("Base      End       Image Offset  Psect type\n%08X  %08X  %08X      %s\n",
  2154.              start,end,offset,psects[psect]);
  2155.      fprintf (outfile, "Base      End       Image Offset  Psect type\n%08X  %08X  %08X      %s\n",
  2156.              start,end,offset,psects[psect]);
  2157.  
  2158.      }
  2159.    else
  2160.       {
  2161.       printf ("\nR26 (Return address):  %08X is not within a system or user image \nand is not a return address\n",
  2162.            prc_registers[52]);
  2163.       fprintf (outfile, "\nR26 (Return address):  %08X is not within a system or user image \nand is not a return address\n",
  2164.            prc_registers[52]);
  2165.       }
  2166.  
  2167.    
  2168.    
  2169. /* *********** Get call frames ********************************** */
  2170.    
  2171.    fp      = prc_registers[58];
  2172.    next_fp = fp;
  2173.    
  2174.    
  2175.    frame_count = 0;
  2176.    
  2177.    while ( next_fp != 0 )
  2178.      {
  2179.      
  2180.      frame_count = frame_count + 1;
  2181.      
  2182.      printf ("\n******************* Call Frame %d ***************************************\n",
  2183.              frame_count);
  2184.      fprintf (outfile, "\n******************* Call Frame %d ***************************************\n",
  2185.              frame_count);
  2186.  
  2187.      
  2188.      arglist [0] = 1;
  2189.      arglist [1] = prc_registers[58];        /* FP    */
  2190.      
  2191.      return_status =    SYS$CMKRNL(&get_fp_and_pdsc, arglist);
  2192.      
  2193.      if (return_status == SS$_NODATA)
  2194.        {
  2195.        printf ("\n%%MWAIT-F-NOTINPHYS, Virtual data not in physical memory: \n");
  2196.        fprintf (outfile, "\n%%MWAIT-F-NOTINPHYS, Virtual data not in physical memory: \n");
  2197.  
  2198.        printf ("FP = %08X ==> PDSC = %08X\n", fp,pd);
  2199.        fprintf (outfile, "FP = %08X ==> PDSC = %08X\n", fp,pd);
  2200.  
  2201.        return (SS$_NORMAL);
  2202.        }
  2203.      
  2204.      if (return_status == SS$_INSFRAME)
  2205.        {
  2206.        printf ("\n%%MWAIT-F-INVFRAME, Invalid Call Frame: \n");
  2207.        fprintf (outfile, "\n%%MWAIT-F-INVFRAME, Invalid Call Frame: \n");
  2208.  
  2209.        printf ("Unknown procedure descriptor kind, FP = %08X, Kind = %02X\n",
  2210.                    fp,pdsc_kind);
  2211.        fprintf (outfile, "Unknown procedure descriptor kind, FP = %08X, Kind = %02X\n",
  2212.                    fp,pdsc_kind);
  2213.  
  2214.        return (SS$_NORMAL);
  2215.        }
  2216.      
  2217.      if (return_status == SS$_ITEMNOTFOUND)
  2218.        {
  2219.        printf ("\n%%MWAIT-F-INVFRAME, Invalid Call Frame: \n");
  2220.        fprintf (outfile, "\n%%MWAIT-F-INVFRAME, Invalid Call Frame: \n");
  2221.  
  2222.        printf ("Procedure descriptor not found at FP = %08X ==> %08X\n", fp,pd);
  2223.        fprintf (outfile, "Procedure descriptor not found at FP = %08X ==> %08X\n", fp,pd);
  2224.  
  2225.        return (SS$_NORMAL);
  2226.        }
  2227.      
  2228.      if (return_status != SS$_NORMAL) return (return_status);
  2229.         
  2230.      printf ("\nFP      = %08X \nPDSC    = %08X  %s\nNext FP = %08X\n",
  2231.              fp, pd, pd_kind[pdsc_kind], next_fp);
  2232.      fprintf (outfile, "\nFP      = %08X \nPDSC    = %08X  %s\nNext FP = %08X\n",
  2233.              fp, pd, pd_kind[pdsc_kind], next_fp);
  2234.  
  2235.      
  2236.      
  2237. /*
  2238.     printf ("flags = %08X    kind = %08X \n", pdsc_flags,pdsc_kind);
  2239.     fprintf (outfile, "flags = %08X    kind = %08X \n", pdsc_flags,pdsc_kind);
  2240.  
  2241.     printf ("entry = %08X    offset = %08X \n", pdsc_entry,pdsc_rsa_offset);
  2242.     fprintf (outfile, "entry = %08X    offset = %08X \n", pdsc_entry,pdsc_rsa_offset);
  2243.  
  2244.     printf ("mask = %08X tmp = %d tmp2 = %d  \n", ireg_mask,tmp,tmp2);
  2245.     fprintf (outfile, "mask = %08X tmp = %d tmp2 = %d  \n", ireg_mask,tmp,tmp2);
  2246.  
  2247.     printf ("save_fp = %08X save_ra = %08X\n", save_fp,save_ra);
  2248.     fprintf (outfile, "save_fp = %08X save_ra = %08X\n", save_fp,save_ra);
  2249.  
  2250.  
  2251.     printf ("frame[1] frame[0] = %08X %08X \n", frame[1],frame[0]);
  2252.     fprintf (outfile, "frame[1] frame[0] = %08X %08X \n", frame[1],frame[0]);
  2253.  
  2254.     printf ("frame[3] frame[2] = %08X %08X \n", frame[3],frame[2]);
  2255.     fprintf (outfile, "frame[3] frame[2] = %08X %08X \n", frame[3],frame[2]);
  2256.  
  2257.     printf ("frame[5] frame[4] = %08X %08X \n", frame[5],frame[4]);
  2258.     fprintf (outfile, "frame[5] frame[4] = %08X %08X \n", frame[5],frame[4]);
  2259.  
  2260.     printf ("frame[7] frame[6] = %08X %08X \n", frame[7],frame[6]);
  2261.     fprintf (outfile, "frame[7] frame[6] = %08X %08X \n", frame[7],frame[6]);
  2262.  
  2263.     printf ("frame[9] frame[8] = %08X %08X \n", frame[9],frame[8]);
  2264.     fprintf (outfile, "frame[9] frame[8] = %08X %08X \n", frame[9],frame[8]);
  2265.  
  2266.     printf ("frame[11] frame[10] = %08X %08X \n", frame[11],frame[10]);
  2267.     fprintf (outfile, "frame[11] frame[10] = %08X %08X \n", frame[11],frame[10]);
  2268.  
  2269. */
  2270.      
  2271.      fp = next_fp;
  2272.      
  2273. /*    Map Procedure entry    */
  2274.      
  2275.      for (k=0; k<40; k++)    image_name[k] = 0;
  2276.         
  2277.      arglist [0] = 2;
  2278.      arglist [1] = pdsc_b[2];            /* Procedure entry    */
  2279.      arglist [2] = (int) pcb_pid;        /* IPID    */
  2280.      
  2281.      return_status =    SYS$CMKRNL(&map_address, arglist);
  2282.      if (return_status == SS$_TIMEOUT)
  2283.     {
  2284.         printf ("%%MWAIT-F-NORESPONSE, can not read target process image list\n");
  2285.         fprintf (outfile, "%%MWAIT-F-NORESPONSE, can not read target process image list\n");
  2286.     }
  2287.  
  2288.      if (return_status != SS$_NORMAL) return (return_status);
  2289.         
  2290. /*  printf (" start = %08X  end = %08X found = %d kfe_sect = %08X kfe_offs = %08X\n",
  2291. /*  fprintf (outfile, " start = %08X  end = %08X found = %d kfe_sect = %08X kfe_offs = %08X\n",
  2292.  
  2293.             start,end,found,kferes_section,kferes_offset);    */
  2294.      
  2295.      if (found == 1)
  2296.        {
  2297.        printf ("\nProcedure Entry: %08X is in the image: \n%s\n",
  2298.                pdsc_b[2],image_name);
  2299.        fprintf (outfile, "\nProcedure Entry: %08X is in the image: \n%s\n",
  2300.                pdsc_b[2],image_name);
  2301.  
  2302.        
  2303.        printf ("Base      End       Image Offset  Psect type\n%08X  %08X  %08X      %s\n",
  2304.                start,end,offset,psects[psect]);
  2305.        fprintf (outfile, "Base      End       Image Offset  Psect type\n%08X  %08X  %08X      %s\n",
  2306.                start,end,offset,psects[psect]);
  2307.  
  2308.        
  2309.        }
  2310.      else
  2311.     {
  2312.         printf ("\nProcedure Entry: %08X is not within a system or user image\n",
  2313.                pdsc_b[2]);
  2314.         fprintf (outfile, "\nProcedure Entry: %08X is not within a system or user image\n",
  2315.                pdsc_b[2]);
  2316.     }
  2317.      
  2318.      
  2319. /*    Map R26 (Return address)    */
  2320.      
  2321.      for (k=0; k<40; k++)    image_name[k] = 0;
  2322.         
  2323.      arglist [0] = 2;
  2324.      arglist [1] = r26;                /* R26    */
  2325.      arglist [2] = (int) pcb_pid;        /* IPID    */
  2326.      
  2327.      return_status =    SYS$CMKRNL(&map_address, arglist);
  2328.      if (return_status == SS$_TIMEOUT)
  2329.     {
  2330.         printf ("%%MWAIT-F-NORESPONSE, can not read target process image list\n");
  2331.         fprintf (outfile, "%%MWAIT-F-NORESPONSE, can not read target process image list\n");
  2332.     }
  2333.  
  2334.      if (return_status != SS$_NORMAL) return (return_status);
  2335.         
  2336. /*  printf (" tmp = %08X  ldrimg = %08X  imcb = %08X start = %08X  end = %08X found = %d\n",
  2337. /*  fprintf (outfile, " tmp = %08X  ldrimg = %08X  imcb = %08X start = %08X  end = %08X found = %d\n",
  2338.  
  2339.                     tmp,ldrimg,imcb,start,end,found);    */
  2340.      
  2341. /*  printf (" start = %08X  end = %08X found = %d kfe_sect = %08X kfe_offs = %08X\n",
  2342. /*  fprintf (outfile, " start = %08X  end = %08X found = %d kfe_sect = %08X kfe_offs = %08X\n",
  2343.  
  2344.             start,end,found,kferes_section,kferes_offset);    */
  2345.      
  2346.      if (found == 1)
  2347.        {
  2348.        printf ("\nReturn address:  %08X is in the image: \n%s\n",
  2349.             r26,image_name);
  2350.        fprintf (outfile, "\nReturn address:  %08X is in the image: \n%s\n",
  2351.             r26,image_name);
  2352.  
  2353.        
  2354.        printf ("Base      End       Image Offset  Psect type\n%08X  %08X  %08X      %s\n",
  2355.             start,end,offset,psects[psect]);
  2356.        fprintf (outfile, "Base      End       Image Offset  Psect type\n%08X  %08X  %08X      %s\n",
  2357.             start,end,offset,psects[psect]);
  2358.  
  2359.        
  2360.        }
  2361.      else
  2362.     {
  2363.         printf ("\nReturn address:  %08X is not within a system or user image\n",
  2364.             r26);
  2365.         fprintf (outfile, "\nReturn address:  %08X is not within a system or user image\n",
  2366.             r26);
  2367.     }
  2368.  
  2369.      
  2370.      } /* end while */
  2371.    
  2372.    fclose (outfile);        /* Close output file    */
  2373.  
  2374.    printf ("\n *** The output was written into file %s *** \n", (char *) outname);
  2375.    
  2376.    return (SS$_NORMAL);
  2377.    
  2378.    }
  2379.  
  2380. /* ******************************************************************* */
  2381. /* ******************************************************************* */
  2382. /* ******************************************************************* */
  2383.  
  2384.  
  2385. /* Routine get_fp_and_pdsc (int frame_pointer)
  2386.  *
  2387.  *
  2388.  * FUNCTION
  2389.  *
  2390.  *     This routine gets the PDSC and next FP in Kernel mode
  2391.  *
  2392.  * INPUT
  2393.  *
  2394.  *    FP Frame pointer for the call frame
  2395.  *
  2396.  * IMPLICIT INPUT
  2397.  *
  2398.  *      PID process ID
  2399.  *
  2400.  * EXPLICIT OUTPUT
  2401.  *
  2402.  *      ss$_normal      Success.  
  2403.  *    ss$_nonexpr    Nonexistent process
  2404.  *
  2405.  */
  2406.  
  2407. int get_fp_and_pdsc (int frame_pointer)
  2408.    {
  2409.    
  2410. /*    Get Procedure Descriptor pointer (R27) */
  2411.    
  2412.    return_status = EXE$READ_PROCESS(pcb_pid,link_length,fp,
  2413.            &pd,EACB$K_MEMORY,&read_process_ast_count);
  2414.    if (return_status != SS$_NORMAL) return (return_status);
  2415.       
  2416.    if ( pd == 0 ) pd = fp;        /* Bound procedure descriptor */
  2417.       
  2418.    
  2419. /*    IF (FP)<2:0> is 0, then FP points to a quadword that contains
  2420.     a pointer to the procedure descriptor for the current procedure.
  2421.  
  2422.     IF (FP)<2:0> is not 0, then FP points to the procedure descriptor
  2423.     for the current procedure.
  2424.  */
  2425.    if ( pd & 7 )
  2426.       pd = fp;
  2427.    
  2428. /*    if ( pd & 7 ) return (SS$_ITEMNOTFOUND);    */
  2429.       
  2430.    
  2431. /*    Get Procedure Descriptor */
  2432.    
  2433.    return_status = EXE$READ_PROCESS(pcb_pid,PDSC$K_MIN_LENGTH_SF,pd,
  2434.        &pdsc_b,EACB$K_MEMORY,&read_process_ast_count);
  2435.    if (return_status != SS$_NORMAL) return (return_status);
  2436.       
  2437.    pdsc = (struct pdscdef *) pdsc_b;        /* PDSC     */
  2438.    
  2439.    
  2440.    pdsc_flags = pdsc->pdsc$w_flags;        /* PDSC flags     */
  2441.    
  2442.    pdsc_kind  = (pdsc_flags & 0Xf );        /* PDSC$V_KIND  */
  2443.    
  2444.    if (!(pdsc_kind == PDSC$K_KIND_BOUND    ||
  2445.      pdsc_kind == PDSC$K_KIND_NULL     ||
  2446.      pdsc_kind == PDSC$K_KIND_FP_STACK ||
  2447.      pdsc_kind == PDSC$K_KIND_FP_REGISTER) )    return (SS$_INSFRAME);
  2448.    
  2449. /* ******** Stack Frame Procedure *********** */
  2450.    
  2451.    if ( pdsc_flags & PDSC$M_BASE_REG_IS_FP)
  2452.      {
  2453.      
  2454.      pdsc_entry = pdsc->pdsc$l_entry;        /* Code entry    */
  2455.      
  2456.      pdsc_rsa_offset = pdsc->pdsc$w_rsa_offset; /* Register save offset */
  2457.      
  2458.      ireg_mask = pdsc->pdsc$l_ireg_mask;    /* IREG mask    */
  2459.      
  2460.      tmp = 0;
  2461.      for (i_bit = 0; i_bit < 33; i_bit++)
  2462.        {
  2463.        if (( ireg_mask & bit_mask[i_bit+1] ) >> i_bit)
  2464.           tmp = tmp + 1;            /* Count saved registers */
  2465.        }
  2466.      
  2467.      tmp2 = 8 * tmp + pdsc_rsa_offset;        /* Call frame size to be read */
  2468.                         /* from stack (before FMASK) */    
  2469.      
  2470. /*    Get IREG's from the call frame on stack     */
  2471.      
  2472.      return_status = EXE$READ_PROCESS(pcb_pid,tmp2,fp+pdsc_rsa_offset,
  2473.          &frame,EACB$K_MEMORY,&read_process_ast_count);
  2474.      if (return_status != SS$_NORMAL) return (return_status);
  2475.         
  2476.      
  2477.      r26     = frame[0];            /* Return Address    */
  2478.      next_fp = frame[2*tmp];            /* Next FP        */
  2479.      
  2480.      }
  2481.    
  2482. /* ******** Register Frame Procedure *********** */
  2483.    
  2484.    if ( pdsc_kind == PDSC$K_KIND_FP_REGISTER )
  2485.      {
  2486.      
  2487.      save_fp = pdsc->pdsc$b_save_fp;        /* Saved FP reg    */
  2488.      save_ra = pdsc->pdsc$b_save_ra;        /* Saved RA reg    */
  2489.      
  2490.      next_fp = prc_registers[2*save_fp];    /* Get FP    */
  2491.      r26     = prc_registers[2*save_ra];    /* Get RA    */
  2492.      
  2493.      pdsc_entry = pdsc->pdsc$l_entry;        /* Code entry    */
  2494.      
  2495.      }
  2496.    
  2497.    
  2498.    if ( pdsc_kind == PDSC$K_KIND_BOUND )
  2499.      {
  2500.      
  2501.      next_fp = pdsc->pdsc$l_proc_value;        /* Get FP    */
  2502.      
  2503.      }
  2504.    
  2505.    
  2506.    return (return_status);
  2507.    
  2508.    }
  2509.  
  2510.  
  2511.  
  2512. /* ******************************************************************* */
  2513.  
  2514.  
  2515.  
  2516. /* Routine get_process_info(int pid)
  2517.  *
  2518.  *
  2519.  * FUNCTION
  2520.  *
  2521.  *     This routine gets the process information in Kernel mode
  2522.  *
  2523.  * INPUT
  2524.  *
  2525.  *      PID process ID
  2526.  *
  2527.  * IMPLICIT INPUT
  2528.  *
  2529.  * EXPLICIT OUTPUT
  2530.  *
  2531.  *      ss$_normal      Success.  
  2532.  *    ss$_nonexpr    Nonexistent process
  2533.  *
  2534.  */
  2535.  
  2536. int get_process_info (int pid)
  2537.    {
  2538.    sys_lock (SCHED, 1, &orig_ipl);        /* Get SCHED lock    */
  2539.    
  2540.    
  2541.    pcb = (PCB *) EXE_STD$CVT_EPID_TO_PCB(pid);    /* Convert PID to PCB   */
  2542.    tmp = EXE_STD$CVT_EPID_TO_IPID(pid);        /* Convert PID to IPID  */
  2543.    
  2544. /*    SWAPPER is illegal, it has no JIB or normal process quotas    */
  2545.    
  2546.    if (pcb == 0 || tmp <= SCH$GL_SWPPID ) 
  2547.      {    
  2548.      sys_unlock (SCHED, orig_ipl, 0);        /* Release SCHED lock    */
  2549.      return (SS$_NONEXPR);            /* Nonexistent process    */
  2550.      }
  2551.    
  2552. /************** PCB *************************************************/
  2553.    
  2554.    
  2555. /*     __PAL_PROBER( address, length, mode )                 */
  2556.    
  2557.    if (! ( __PAL_PROBER (pcb->pcb$l_sqfl, 4, PR$C_PS_KERNEL) ) )
  2558.       return (SS$_ACCVIO);        /* Can PCB be read in Kernel mode ? */
  2559.    
  2560.    pcb_ktbvec   = pcb->pcb$l_ktbvec;        /* KTB vector adddress  */
  2561.    pcb_kt_count = pcb->pcb$l_kt_count;        /* Kthread count    */
  2562.    
  2563. /*    First get the length of the process name, the pcb$t_lname field
  2564.  *    can have 'leftovers'.
  2565.  */
  2566.    strncpy (tmp_string,pcb->pcb$t_lname, 2);     /* Process name    */
  2567.    str_length = (int) tmp_string[0];        /* Process name length  */
  2568.    strncpy (pcb_lname, pcb->pcb$t_lname+1, str_length); 
  2569.    
  2570.    strncpy (tmp_string,pcb->pcb$t_terminal, 2); /* Terminal name     */
  2571.    str_length = (int) tmp_string[0];        /* Terminal name length  */
  2572.    strncpy (pcb_terminal, pcb->pcb$t_terminal+1, str_length);
  2573.    
  2574.    pcb_epid   = pcb->pcb$l_epid;        /* EPID            */
  2575.    pcb_pid    = pcb->pcb$l_pid;        /* IPID            */
  2576.    pcb_pri    = PRI$C_NUM_PRI - 1 - pcb->pcb$l_pri;
  2577.                         /* Current priority    */
  2578.    pcb_prib   = PRI$C_NUM_PRI - 1 - pcb->pcb$l_prib;
  2579.                         /* Base priority    */
  2580.    pcb_owner  = pcb->pcb$l_owner;        /* Owner        */
  2581.    owner_epid = EXE_STD$CVT_IPID_TO_EPID(pcb->pcb$l_owner); /* Owner EPID */
  2582.    
  2583.    pcb_waitime  = pcb->pcb$l_waitime;        /* Waitime in 10ms ticks */
  2584.    pcb_diocnt   = pcb->pcb$l_diocnt;        /* DIO count        */
  2585.    pcb_diolm    = pcb->pcb$l_diolm;        /* DIO limit        */
  2586.    pcb_biocnt   = pcb->pcb$l_biocnt;        /* BIO count        */
  2587.    pcb_biolm    = pcb->pcb$l_biolm;        /* BIO limit        */
  2588.    pcb_prccnt   = pcb->pcb$l_prccnt;        /* Sub-process count    */
  2589.    pcb_dpc      = pcb->pcb$l_dpc;        /* Delete pending count    */
  2590.    pcb_astcnt   = pcb->pcb$l_astcnt;        /* AST count        */
  2591.    pcb_astact   = pcb->pcb$l_astact;        /* AST's active        */
  2592.    
  2593.    
  2594. /*     Get WSQUOTA = Process page count + Global page countin in WS    */
  2595. /*    pagelets = 16 * pages                        */
  2596.    
  2597.    pcb_wsquota= 16 * ( pcb->pcb$l_ppgcnt + pcb->pcb$l_gpgcnt );
  2598.    
  2599.    
  2600.    pcb_ast_k = '-';
  2601.    pcb_ast_e = '-';
  2602.    pcb_ast_s = '-';
  2603.    pcb_ast_u = '-';
  2604.    
  2605. /*    An AST is pending if AST queue forward link != forward link address */
  2606.    
  2607.    if ((ACB *) pcb->pcb$l_astqfl_k != (ACB *) &pcb->pcb$l_astqfl_k) pcb_ast_k = 'K';
  2608.    if ((ACB *) pcb->pcb$l_astqfl_e != (ACB *) &pcb->pcb$l_astqfl_e) pcb_ast_e = 'E';
  2609.    if ((ACB *) pcb->pcb$l_astqfl_s != (ACB *) &pcb->pcb$l_astqfl_s) pcb_ast_s = 'S';
  2610.    if ((ACB *) pcb->pcb$l_astqfl_u != (ACB *) &pcb->pcb$l_astqfl_u) pcb_ast_u = 'U';
  2611.    
  2612.       
  2613. /************** PCB/KTB thread ********************************************/
  2614.    
  2615. /*    Get KTBVEC contents    */
  2616.       
  2617.    
  2618.    if (! ( __PAL_PROBER ( pcb_ktbvec, 4*MAX_THREADS, PR$C_PS_KERNEL) ) )
  2619.       return (SS$_ACCVIO);        /* Can KTB be read in Kernel mode ? */
  2620.    
  2621.    memcpy (&pcb_ktbvec_a, pcb_ktbvec, 4*MAX_THREADS);
  2622.    
  2623.    
  2624.    for (threads_ind = 0; threads_ind < pcb_kt_count; threads_ind++)
  2625.      {
  2626.      
  2627.      if ( pcb_ktbvec_a[threads_ind] != 0 )
  2628.        {
  2629.        
  2630.        pcb = (PCB *) pcb_ktbvec_a[threads_ind];
  2631.        
  2632.        }
  2633.      
  2634.      
  2635.      pcb_state[threads_ind]  = pcb->pcb$l_state;  /* Process state    */
  2636.      pcb_sts[threads_ind]    = pcb->pcb$l_sts;      /* Process status    */
  2637.      pcb_efwm[threads_ind]   = pcb->pcb$l_efwm;      /* Event flag wait mask */
  2638.      pcb_wefc[threads_ind]   = pcb->pcb$l_wefc;      /* EFN cluster number    */
  2639.      pcb_cpu_id[threads_ind] = pcb->pcb$l_cpu_id; /* CPU id        */
  2640.      pcb_efcs[threads_ind]   = pcb->pcb$l_efcs;      /* System EFN mask    */
  2641.      pcb_efcu[threads_ind]   = pcb->pcb$l_efcu;      /* User EFN mask    */
  2642.      pcb_efc2p[threads_ind]  = pcb->pcb$l_efc2p;  /* EFC 2        */
  2643.      
  2644.      if (pcb_efc2p[threads_ind] != 0 )
  2645.        {
  2646.        ceb  = ( CEB *) pcb->pcb$l_efc2p;      /* EFC 2        */
  2647.        ceb_tmp = (unsigned int) ceb->ceb$t_efcnam;
  2648.        
  2649.        strncpy (tmp_string,ceb->ceb$t_efcnam, 2); /* EFN cluster name */
  2650.        str_length = (int) tmp_string[0];      /* EFN cluster name length */
  2651.        strncpy (ceb_name2, ceb->ceb$t_efcnam+1, str_length); 
  2652.        }
  2653.      
  2654.      pcb_efc3p[threads_ind]  = pcb->pcb$l_efc3p;  /* EFC 3        */
  2655.      
  2656.      if (pcb_efc3p[threads_ind] != 0 )
  2657.        {
  2658.        ceb  = ( CEB *) pcb->pcb$l_efc3p;      /* EFC 3        */
  2659.        ceb1_tmp = (unsigned int) ceb->ceb$t_efcnam;
  2660.        
  2661.        strncpy (tmp_string,ceb->ceb$t_efcnam, 2); /* EFN cluster name */
  2662.        str_length = (int) tmp_string[0];      /* EFN cluster name length  */
  2663.        strncpy (ceb_name3, ceb->ceb$t_efcnam+1, str_length);
  2664.        }
  2665.      
  2666.      } /* end if PCB/KTB thread */
  2667.    
  2668.    
  2669. /************** PHD *************************************************/
  2670.    
  2671.    phd_astlm  = -1;
  2672.    pcb_phd    = -1;
  2673.    phd_astsr_asten = -1;
  2674.    phd_pstbasoff = -1;
  2675.    
  2676.    if ( pcb->pcb$l_sts & PCB$M_PHDRES)        /* If PHD resident     */
  2677.      {
  2678. /*        if (! ( __PAL_PROBER ( (void *) phd , 4, PR$C_PS_KERNEL) ) )    */
  2679. /*        return (SS$_ACCVIO);                    */
  2680.                     /* Can PHD be read in Kernel mode ? */
  2681.      
  2682.      pcb_phd   = (int) pcb->pcb$l_phd;        /* PHD            */
  2683.      phd       = pcb->pcb$l_phd;        /* PHD            */
  2684.      phd_astlm = phd->phd$l_astlm;        /* AST limit        */
  2685.      phd_astsr_asten = phd->phd$q_astsr_asten;
  2686.                          /* AST's served/enabled */
  2687.      phd_pstbasoff = phd->phd$l_pst_base_offset; /* PST base offset */
  2688.      
  2689. /*    Maximum working set is PHD$L_WSAUTHEXT - PHD$L_WSLIST + 1 pages    */
  2690.      
  2691.      wsextent  = 16 * (phd->phd$l_wsauthext - phd->phd$l_wslist + 1);
  2692.      
  2693.      }
  2694.    
  2695. /************** JIB *************************************************/
  2696.    
  2697.    jib = pcb->pcb$l_jib;            /* JIB            */
  2698.    
  2699. /* if (!(__PAL_PROBER (jib->jib$l_mtlfl,4,PR$C_PS_KERNEL))) return (SS$_ACCVIO); */
  2700.                 /* Can JIB be read in Kernel mode ? */
  2701.    
  2702.    strncpy (jib_username, jib->jib$t_username, 12); /* User name    */
  2703.    
  2704.    jib_flags   = jib->jib$l_flags;        /* JIB wait flags    */
  2705.    jib_bytcnt  = jib->jib$l_bytcnt;        /* Byte count        */
  2706.    jib_bytlm   = jib->jib$l_bytlm;        /* Byte limit        */
  2707.    jib_org_bytlm = jib->jib$l_org_bytlm;    /* Original Byte limit    */
  2708.    jib_filcnt  = jib->jib$l_filcnt;        /* File count        */
  2709.    jib_fillm   = jib->jib$l_fillm;        /* File limit        */
  2710.    jib_prclim  = jib->jib$l_prclim;        /* Sub-process limit    */
  2711.    jib_prccnt  = jib->jib$l_prccnt;        /* Sub-process #     */
  2712.    jib_mpid    = jib->jib$l_mpid;        /* PID of master process */
  2713.    master_epid = EXE_STD$CVT_IPID_TO_EPID(jib->jib$l_mpid); /* Master EPID */
  2714.  
  2715.    jib_tqcnt   = jib->jib$l_tqcnt;        /* Timer count        */
  2716.    jib_tqlm    = jib->jib$l_tqlm;        /* Timer limit        */
  2717.    jib_pgflcnt = jib->jib$l_pgflcnt;        /* Page file count    */
  2718.    jib_pgflquota = jib->jib$l_pgflquota;    /* Page file quota    */
  2719.    
  2720.    
  2721.    abstim_tics = exe$gl_abstim_tics;         /* Absolute time    */
  2722.    
  2723.    mmg_fresva  = MMG$GQ_NEXT_FREE_S0S1_VA;    /* First free system VA */
  2724.    
  2725.    
  2726.    sys_unlock (SCHED, orig_ipl, 0);        /* Release SCHED lock    */
  2727.    
  2728.    return (SS$_NORMAL);                /* Success        */
  2729.    }
  2730.  
  2731.  
  2732. /* ******************************************************************* */
  2733.  
  2734. /*
  2735.  *    if( smp$gl_flags.smp$v_enabled )
  2736.  *        
  2737.  *
  2738.  *
  2739. */
  2740.  
  2741.  
  2742. /* ******************************************************************* */
  2743.  
  2744. /* Routine get_process_channels(int index, int pid)
  2745.  *
  2746.  *
  2747.  * FUNCTION
  2748.  *
  2749.  *     This routine gets the process channel information in Kernel mode
  2750.  *
  2751.  * INPUT
  2752.  *
  2753.  *      PID process ID
  2754.  *
  2755.  * IMPLICIT INPUT
  2756.  *
  2757.  * EXPLICIT OUTPUT
  2758.  *
  2759.  *      ss$_normal      Success.  
  2760.  *    ss$_nonexpr    Nonexistent process
  2761.  *
  2762.  */
  2763.  
  2764. int get_process_channels (int index, int pid)
  2765.    {
  2766.    ctl_chindx_length = 4;            /* Channel index length    */
  2767.    
  2768. /*    Check if valid PID    */
  2769.    
  2770.    if (SCH$GL_MAXPIX > index)
  2771.      {
  2772.      
  2773. /* Get number of channels            */
  2774.      
  2775.      return_status =    EXE$READ_PROCESS(pid,ctl_chindx_length,&CTL$GL_CHINDX,
  2776.          &ctl_chindx,EACB$K_MEMORY,&read_process_ast_count);
  2777.      if (return_status != SS$_NORMAL) return (return_status);
  2778.         
  2779.      ccb_length = ctl_chindx * CCB$K_LENGTH;    /* Table size */
  2780.      
  2781. /* Get address of CCB table            */
  2782.      
  2783.      return_status = EXE$READ_PROCESS(pid,ctl_chindx_length,&CTL$GA_CCB_TABLE,
  2784.          &ccb_table_address,EACB$K_MEMORY,&read_process_ast_count);
  2785.      
  2786.      if (return_status != SS$_NORMAL) return (return_status);
  2787.         
  2788.      
  2789. /* ?? CLEAR TABLE ?? */
  2790.      
  2791.      
  2792. /* Get CCB table    */
  2793.      
  2794.      return_status = EXE$READ_PROCESS(pid,ccb_length,ccb_table_address,
  2795.          &ccb_table,EACB$K_MEMORY,&read_process_ast_count);
  2796.      if (return_status != SS$_NORMAL) return (return_status);
  2797.         }
  2798.    
  2799.    else
  2800.      {
  2801.      return (SS$_NONEXPR);
  2802.      }
  2803.    
  2804.    return (SS$_NORMAL);
  2805.    
  2806.    }
  2807.  
  2808. /* *********************************************************************** */
  2809.  
  2810. /* Routine get_device_name(int ucb_address, int iocou)
  2811.  *
  2812.  *
  2813.  * FUNCTION
  2814.  *
  2815.  *     This routine gets the process channel information in Kernel mode
  2816.  * INPUT
  2817.  *
  2818.  *      UCB     Unit control block address
  2819.  *
  2820.  *
  2821.  * IMPLICIT INPUT
  2822.  *
  2823.  *    Window    CCB Window
  2824.  *
  2825.  * EXPLICIT OUTPUT
  2826.  *
  2827.  *      ss$_normal     Success
  2828.  *      ss$_accvio     Access violation
  2829.  *
  2830.  */
  2831.  
  2832. int get_device_name(int ucb_address, int iocou)
  2833.  
  2834.    {
  2835.     net_port = 0;            /* Clear Port name flag */
  2836.  
  2837.    ucb    = (UCB *) (ucb_address);        /* UCB address        */
  2838.    mb_ucb = (MB_UCB *) (ucb_address);        /* MB_UCB address    */
  2839.    
  2840.    if (! ( __PAL_PROBER (ucb->ucb$l_ddb, 4, PR$C_PS_KERNEL) ) )
  2841.       return (SS$_ACCVIO);            /* Can UCB be read in Kernel mode ? */
  2842.    
  2843.    unit   = ucb->ucb$w_unit;        /* Unit number              */
  2844.    bufquo = ucb->ucb$w_bufquo;        /* Buffered quota left    */
  2845.    ucb_devchar = ucb->ucb$l_devchar;    /* Device characteristic  */
  2846.    ucb_sts     = ucb->ucb$l_sts;    /* Device unit status      */
  2847.    ucb_devtype = ucb->ucb$b_devtype;    /* Device type          */
  2848.  
  2849.    irp_count = 0;            /* Clear IRP #    */
  2850.  
  2851. /* *********************************************************************** */
  2852.    
  2853.    ddb = ucb->ucb$l_ddb;            /* DDB address    */
  2854.    
  2855.    if (! ( __PAL_PROBER (ddb->ddb$t_name, 4, PR$C_PS_KERNEL) ) )
  2856.           return (SS$_ACCVIO);    /* Can DDB be read in Kernel mode ? */
  2857.    
  2858.    ddb_name_length = 0;                /* Clear name length    */
  2859.    
  2860.    sb = (SB *) ddb->ddb$l_sb;            /* System control block    */
  2861.    
  2862. /*     If remote device ==> Insert node name in device name    */
  2863.    
  2864.    if ( SCS$AR_LOCALSB != ddb->ddb$l_sb )
  2865.      {
  2866.      strncpy (tmp_string,sb->sb$t_nodename,2);     /* Node name */
  2867.      ddb_name_length = (int) tmp_string[0];    /* Node name length */
  2868.      strncpy (ddb_name, sb->sb$t_nodename+1, ddb_name_length);
  2869.      
  2870.      strcat (ddb_name,"$");            /* Insert $    */
  2871.      }
  2872.  
  2873.    strncpy (tmp_string,ddb->ddb$t_name,2);     /* Device name    */
  2874.    str_length = (int) tmp_string[0];           /* Device name length  */
  2875.    strncpy (tempstr, ddb->ddb$t_name+1, str_length);
  2876.    
  2877.    strcat (ddb_name,tempstr);            /* Insert device name    */
  2878.    
  2879.    
  2880. /*    We have PST index, get the window     */
  2881.    
  2882.    if ( (window > 0) && (phd_pstbasoff != -1) )    /* Global section index */
  2883.      {
  2884.      PSTbase  = (int) phd + phd_pstbasoff;    /* PST address */
  2885.      
  2886.      section = PSTbase - window;        /* PST entry address      */
  2887.                         /* window = Section Index */
  2888.      
  2889.      section = section + 16;       /* Address of window = sec->sec$l_window */
  2890.      
  2891. /*    Get the window    */
  2892.      
  2893.      return_status = EXE$READ_PROCESS(pcb_pid,link_length,section,
  2894.          &window,EACB$K_MEMORY,&read_process_ast_count);
  2895.          if (return_status != SS$_NORMAL) return (return_status);
  2896.  
  2897.      }
  2898.    
  2899. /*    Get file name, if a window and low bit is clear (= interlocked)    */
  2900. /*    And not a NET device                        */
  2901.  
  2902.    if ( (window != 0) && ((window & bit_mask[0]) == 0) && 
  2903.                     !(ucb_devchar & DEV$M_NET) )
  2904.      {
  2905.      
  2906.      if ( window > 0X80000000 )
  2907.        {
  2908.        
  2909. /*    Real window     */
  2910.  
  2911.        return_status = EXE$READ_PROCESS(pcb_pid,WCB$K_LENGTH,window,
  2912.            &wcb_block,EACB$K_MEMORY,&read_process_ast_count);
  2913.            if (return_status != SS$_NORMAL) return (return_status);
  2914.           
  2915.        wcb = (WCB *) wcb_block;            /* WCB local address    */
  2916.        
  2917.        if ( wcb->wcb$b_type != DYN$C_WCB ) return (SS$_NORMAL);
  2918.           
  2919.        fcb = wcb->wcb$l_fcb;                /* FCB address    */
  2920.        
  2921.        if ( (int) fcb == 0 ) return (SS$_NORMAL);    /* No FCB    */
  2922.           
  2923.        return_status = EXE$READ_PROCESS(pcb_pid,FCB$K_LENGTH,(int) fcb,
  2924.            &fcb_block,EACB$K_MEMORY,&read_process_ast_count);
  2925.            if (return_status != SS$_NORMAL) return (return_status);
  2926.        }
  2927.      
  2928.      }
  2929.    
  2930. /* *************** Look for IRP's ************************************** */
  2931.    
  2932. /*    Is there an IRP on UCB ?    */
  2933.  
  2934. /* ???    if ( (ucb_sts & UCB$M_BSY) && (iocou != 0) )    Unit busy and IOC > 0 */
  2935.  
  2936.    
  2937.    if ( (ucb->ucb$l_irp != 0) && (iocou != 0) && 
  2938.      (!( (ucb_devchar & DEV$M_NET) && (ucb_devchar & DEV$M_MBX) ) ) )
  2939.                 /* IRP and IOC > 0 and not NET only device */
  2940.      {
  2941.      
  2942.      irp       = ucb->ucb$l_irp;        /* IRP            */
  2943.      
  2944. /*    Loop through IRP's    */
  2945.  
  2946.     /* Can IRP be read in Kernel mode and a PID ? */
  2947.      
  2948.      if ( ( __PAL_PROBER (irp->irp$l_ioqfl, 4, PR$C_PS_KERNEL) &&
  2949.               irp->irp$l_pid != 0 ) )
  2950.        {
  2951.        while ( (iocou > 0) && (ucb == irp->irp$l_ucb) )
  2952.                     /* I/O count > 0 and this UCB */
  2953.          {
  2954.          
  2955.          if ( irp->irp$b_type == DYN$C_IRP )        /* IRP ?     */
  2956.            {
  2957.            irp_addr[irp_count]   = (int) irp;        /* IRP address   */
  2958.            irp_efn[irp_count]    = irp->irp$b_efn;
  2959.            irp_func[irp_count]   = irp->irp$l_func;
  2960.            irp_iost1[irp_count]  = irp->irp$l_iost1;
  2961.            irp_iosb_a[irp_count] = (uint64) irp->irp$pq_iosb;
  2962.            irp_bcnt[irp_count]   = irp->irp$l_bcnt;
  2963.            irp_ast[irp_count]    = (uint64) irp->irp$pq_acb64_ast;
  2964.            irp_astprm[irp_count] = irp->irp$q_acb64_astprm;
  2965.            irp_p1[irp_count]     = irp->irp$q_qio_p1;
  2966.            irp_p2[irp_count]     = irp->irp$q_qio_p2;
  2967.            irp_p3[irp_count]     = irp->irp$q_qio_p3;
  2968.            irp_p4[irp_count]     = irp->irp$q_qio_p4;
  2969.            irp_p5[irp_count]     = irp->irp$q_qio_p5;
  2970.            irp_p6[irp_count]     = irp->irp$q_qio_p6;
  2971.            
  2972.            irp_pid[irp_count]    = irp->irp$l_pid;
  2973.            irp_epid[irp_count]   = EXE_STD$CVT_IPID_TO_EPID(irp->irp$l_pid);
  2974.                         /* Convert IPID to EPID  */
  2975.            
  2976. /*    Read IOSB, use PID from IRP, it might be from a different process */
  2977.            
  2978.            return_status = EXE$READ_PROCESS(irp_pid[irp_count],cli_length,
  2979.                irp_iosb_a[irp_count],&irp_iosb[irp_count],EACB$K_MEMORY,
  2980.                &read_process_ast_count);
  2981.            }
  2982.  
  2983.          iocou     = iocou - 1;            /* Next I/O        */
  2984.          irp_count = irp_count + 1;        /* IRP count        */
  2985.          irp       = irp->irp$l_ioqfl;        /* Next IRP         */
  2986.          
  2987.          if (! ( __PAL_PROBER (irp->irp$l_ioqfl, 4, PR$C_PS_KERNEL) ) )
  2988.             break;            /* Can IRP be read in Kernel mode ? */
  2989.          
  2990.          
  2991.          } /* End while iocou */
  2992.        }
  2993.      
  2994.      } /* End if IRP and IOC > 0 and not NET device */
  2995.    
  2996.    ucb_ioqfl_a = (IRP *) &ucb->ucb$l_ioqfl; /* IO queue forward link address */
  2997.    ucb_ioqfl   = ucb->ucb$l_ioqfl;         /* IO queue forward link */
  2998.    
  2999.    irp       = ucb_ioqfl;            /* IRP        */
  3000.  
  3001.    
  3002. /*    Scan the IO queue     */
  3003.    
  3004.    while ( (ucb_ioqfl_a != ucb_ioqfl) && (irp_count < MAX_IRP) )
  3005.      {
  3006.      if (! ( __PAL_PROBER (irp->irp$l_ioqfl, 4, PR$C_PS_KERNEL) ) )
  3007.         return (SS$_ACCVIO);    /* Can IRP be read in Kernel mode ? */
  3008.      
  3009.      if ( irp->irp$b_type == DYN$C_IRP )        /* IRP ?    */
  3010.        {
  3011.        irp_addr[irp_count]   = (int) irp;        /* IRP address */
  3012.        irp_efn[irp_count]    = irp->irp$b_efn;
  3013.        irp_func[irp_count]   = irp->irp$l_func;
  3014.        irp_iost1[irp_count]  = irp->irp$l_iost1;
  3015.        irp_iosb_a[irp_count] = (uint64) irp->irp$pq_iosb;
  3016.        irp_bcnt[irp_count]   = irp->irp$l_bcnt;
  3017.        irp_ast[irp_count]    = (uint64) irp->irp$pq_acb64_ast;
  3018.        irp_astprm[irp_count] = irp->irp$q_acb64_astprm;
  3019.        irp_p1[irp_count]     = irp->irp$q_qio_p1;
  3020.        irp_p2[irp_count]     = irp->irp$q_qio_p2;
  3021.        irp_p3[irp_count]     = irp->irp$q_qio_p3;
  3022.        irp_p4[irp_count]     = irp->irp$q_qio_p4;
  3023.        irp_p5[irp_count]     = irp->irp$q_qio_p5;
  3024.        irp_p6[irp_count]     = irp->irp$q_qio_p6;
  3025.        
  3026.        irp_pid[irp_count]    = irp->irp$l_pid;
  3027.        irp_epid[irp_count]   = EXE_STD$CVT_IPID_TO_EPID(irp->irp$l_pid);
  3028.                     /* Convert IPID to EPID  */
  3029.        
  3030. /*    Use PID from IRP, might be from a different process    */
  3031.        
  3032.        return_status = EXE$READ_PROCESS(irp_pid[irp_count],cli_length,
  3033.            irp_iosb_a[irp_count],&irp_iosb[irp_count],EACB$K_MEMORY,
  3034.            &read_process_ast_count);
  3035.        }
  3036.      else
  3037.         break;                /* No, should not happen */
  3038.      
  3039.      irp_count = irp_count + 1;        /* Next IRP        */
  3040.      irp       = irp->irp$l_ioqfl;    /* Next IRP        */
  3041.      ucb_ioqfl = irp;            /* Update queue pointer    */
  3042.      
  3043.      } /* End while */
  3044.  
  3045. /* *********** LAN devices have an own IRP waiting queue ****************** */
  3046.  
  3047.  
  3048.    if ( (ucb_devchar & DEV$M_NET) && !(ucb_devchar & DEV$M_MBX) ) 
  3049.                     /* LAN device ? , not a NET device */
  3050.      {
  3051.      ucbni       = (UCBNI *) ucb;            /* UCB address    */
  3052.      ucb_ioqfl_a = (IRP *) &ucbni->ucb$q_ni_rcvreq;    /* NET dev queue addr */
  3053.      ucb_ioqfl   = (IRP *)  ucbni->ucb$q_ni_rcvreq;    /* NET device queue   */
  3054.      
  3055.      irp         = ucb_ioqfl;            /* IRP        */
  3056.  
  3057. /*    Scan the LAN device UCB$Q_NI_RCVREQ queue    */
  3058.      
  3059.      while ( (ucb_ioqfl_a != ucb_ioqfl) && (irp_count < MAX_IRP) &&
  3060.          (ucb_ioqfl != 0) && (__PAL_PROBER (irp, 4, PR$C_PS_KERNEL)) )
  3061.        {
  3062.        if (! ( __PAL_PROBER (irp->irp$l_ioqfl, 4, PR$C_PS_KERNEL) ) )
  3063.           return (SS$_ACCVIO);    /* Can IRP be read in Kernel mode ? */
  3064.        
  3065.        if ( irp->irp$b_type == DYN$C_IRP )        /* IRP ?    */
  3066.          {
  3067.          irp_addr[irp_count]   = (int) irp;        /* IRP address */
  3068.          irp_efn[irp_count]    = irp->irp$b_efn;
  3069.          irp_func[irp_count]   = irp->irp$l_func;
  3070.          irp_iost1[irp_count]  = irp->irp$l_iost1;
  3071.          irp_iosb_a[irp_count] = (uint64) irp->irp$pq_iosb;
  3072.          irp_bcnt[irp_count]   = irp->irp$l_bcnt;
  3073.          irp_ast[irp_count]    = (uint64) irp->irp$pq_acb64_ast;
  3074.          irp_astprm[irp_count] = irp->irp$q_acb64_astprm;
  3075.          irp_p1[irp_count]     = irp->irp$q_qio_p1;
  3076.          irp_p2[irp_count]     = irp->irp$q_qio_p2;
  3077.          irp_p3[irp_count]     = irp->irp$q_qio_p3;
  3078.          irp_p4[irp_count]     = irp->irp$q_qio_p4;
  3079.          irp_p5[irp_count]     = irp->irp$q_qio_p5;
  3080.          irp_p6[irp_count]     = irp->irp$q_qio_p6;
  3081.          
  3082.          irp_pid[irp_count]    = irp->irp$l_pid;
  3083.          irp_epid[irp_count]   = EXE_STD$CVT_IPID_TO_EPID(irp->irp$l_pid);
  3084.                     /* Convert IPID to EPID  */
  3085.          
  3086. /*    Use PID from IRP, might be from a different process    */
  3087.          
  3088.          return_status = EXE$READ_PROCESS(irp_pid[irp_count],cli_length,
  3089.              irp_iosb_a[irp_count],&irp_iosb[irp_count],EACB$K_MEMORY,
  3090.              &read_process_ast_count);
  3091.          }
  3092.        else
  3093.           break;                /* No, should not happen */
  3094.        
  3095.        irp_count = irp_count + 1;        /* Next IRP        */
  3096.        irp       = irp->irp$l_ioqfl;        /* Next IRP        */
  3097.        ucb_ioqfl = irp;                /* Update queue pointer    */
  3098.        
  3099.        } /* End while 'UCB$Q_NI_RCVREQ' */
  3100.  
  3101.  
  3102.      } /* End DEV$M_NET */
  3103.  
  3104.  
  3105. /* *********** UCX BG devices have an own IRP field ****************** */
  3106.  
  3107.  
  3108.    if ( (iocou != 0) && (ddb_name[0] == 0x42) && (ddb_name[1] == 0x47) )
  3109.                     /* BG device ? and IOC > 0 */
  3110.      {
  3111.      ucbbg       = (UCBBG *) ucb;        /* UCB address    */
  3112.  
  3113.      irp = (IRP *) ucbbg->ucb$l_bg_irp;        /* IRP        */
  3114.  
  3115.      if ( irp == 0 )
  3116.        irp = (IRP *) ucbbg->ucb$l_bg_irp2;    /* IRP         */
  3117.  
  3118. /* \\\\\ !!!! There is ucb$l_bg_irp3 too !!!!! \\\\\\\\\\\\\\\\\ */
  3119.  
  3120.      if (irp != 0)
  3121.        {
  3122.        if (! ( __PAL_PROBER (irp->irp$l_ioqfl, 4, PR$C_PS_KERNEL) ) )
  3123.           return (SS$_ACCVIO);    /* Can IRP be read in Kernel mode ? */
  3124.        
  3125.        if ( irp->irp$b_type == DYN$C_IRP )        /* IRP ?    */
  3126.          {
  3127.          irp_addr[irp_count]   = (int) irp;        /* IRP address */
  3128.          irp_efn[irp_count]    = irp->irp$b_efn;
  3129.          irp_func[irp_count]   = irp->irp$l_func;
  3130.          irp_iost1[irp_count]  = irp->irp$l_iost1;
  3131.          irp_iosb_a[irp_count] = (uint64) irp->irp$pq_iosb;
  3132.          irp_bcnt[irp_count]   = irp->irp$l_bcnt;
  3133.          irp_ast[irp_count]    = (uint64) irp->irp$pq_acb64_ast;
  3134.          irp_astprm[irp_count] = irp->irp$q_acb64_astprm;
  3135.          irp_p1[irp_count]     = irp->irp$q_qio_p1;
  3136.          irp_p2[irp_count]     = irp->irp$q_qio_p2;
  3137.          irp_p3[irp_count]     = irp->irp$q_qio_p3;
  3138.          irp_p4[irp_count]     = irp->irp$q_qio_p4;
  3139.          irp_p5[irp_count]     = irp->irp$q_qio_p5;
  3140.          irp_p6[irp_count]     = irp->irp$q_qio_p6;
  3141.          
  3142.          irp_pid[irp_count]    = irp->irp$l_pid;
  3143.          irp_epid[irp_count]   = EXE_STD$CVT_IPID_TO_EPID(irp->irp$l_pid);
  3144.                     /* Convert IPID to EPID  */
  3145.          
  3146. /*    Use PID from IRP, might be from a different process    */
  3147.          
  3148.          return_status = EXE$READ_PROCESS(irp_pid[irp_count],cli_length,
  3149.              irp_iosb_a[irp_count],&irp_iosb[irp_count],EACB$K_MEMORY,
  3150.              &read_process_ast_count);
  3151.        
  3152.          irp_count = irp_count + 1;        /* Next IRP        */
  3153.          }
  3154.  
  3155.        } /* if IRP != 0 */
  3156.        
  3157.      } /* End BG device */
  3158.  
  3159.  
  3160. /* *********** UCX INET devices use CXB's ****************************    */
  3161. /*
  3162.  *     The pointer to an INET IRP is in the BGn: IRP field
  3163.  *    IRP$Q_ACB64_ASTPRM = CXB, where the CXB$L_IRP field
  3164.  *     contains the address of the IRP.
  3165.  *
  3166. */
  3167.  
  3168.    if ( (iocou != 0) && (ddb_name[0] == 'I') && (ddb_name[1] == 'N') &&
  3169.     (ddb_name[2] == 'E') && (ddb_name[3] == 'T') )
  3170.                     /* INET device ? and IOC > 0 */
  3171.      {
  3172.  
  3173. /* *** Get BG0: UCB *** */
  3174.  
  3175.    if (ucb_bg0 == 0)        /* BG0: not yet defined    */
  3176.     {
  3177.     ddb_bg0[0] = 'B';
  3178.     ddb_bg0[1] = 'G';
  3179.     ddb_bg0[2] = '\0';            /* Terminator    */
  3180.  
  3181.     sys_lock (SCHED, 1, &orig_ipl);        /* Get SCHED lock       */
  3182.  
  3183.     for (ddb = (DDB *) IOC$GL_DEVLIST; ddb != NULL; ddb = (DDB *) ddb->ddb$l_link )
  3184.       {
  3185.       if (!strcmp(ddb_bg0, ddb->ddb$t_name_str)) break;    /* Found DDB */
  3186.       }
  3187.  
  3188.     if (ddb != NULL) ucb_bg0 = (UCB *) ddb->ddb$l_ucb;     /* BG0: UCB address */
  3189.  
  3190.     sys_unlock (SCHED, orig_ipl, 0);        /* Release SCHED lock   */
  3191.  
  3192.     } /* End if ucb_bg0 == 0 */
  3193.  
  3194. /* ************ Scan trough all BGn: devices for INET IRP's *********** */
  3195. /*
  3196.  *    This is necessary because we don't now which BG's are
  3197.  *    using this INET device
  3198.  */
  3199.  
  3200.     if (ucb_bg0 != 0)                /* If BG devices    */
  3201.     {
  3202.  
  3203.     sys_lock (SCHED, 1, &orig_ipl);              /* Get SCHED lock       */
  3204.  
  3205.     for (ucb_2 = ucb_bg0->ucb$l_link; ucb_2 != NULL; ucb_2 = ucb_2->ucb$l_link)
  3206.       {
  3207.  
  3208.       ucbbg = (UCBBG *) ucb_2;            /* BG0: UCB address     */
  3209.  
  3210.       irp = (IRP *) ucbbg->ucb$l_bg_irp;        /* IRP        */
  3211.  
  3212.       if ( irp == 0 )
  3213.         irp = (IRP *) ucbbg->ucb$l_bg_irp2;    /* IRP         */
  3214.  
  3215. /* \\\\\ !!!! There is ucb$l_bg_irp3 too !!!!! \\\\\\\\\\\\\\\\\ */
  3216.  
  3217.  
  3218.       if ( (irp != 0) && ( __PAL_PROBER (irp->irp$l_ioqfl, 4, PR$C_PS_KERNEL)) )
  3219.        {
  3220.        
  3221.        if ( irp->irp$b_type == DYN$C_IRP )        /* IRP ?    */
  3222.     {
  3223.  
  3224. /*** Scan CXB's  ****/
  3225.  
  3226.     for ( cxb = (CXB *) irp->irp$q_acb64_astprm; cxb != NULL; cxb = cxb->cxb$l_link )
  3227.     {
  3228.  
  3229.         if ( __PAL_PROBER (cxb->cxb$l_irp, 4, PR$C_PS_KERNEL) ) 
  3230.                         /* Can CXB be read in Kernel mode ? */
  3231.      {
  3232.  
  3233.          if ( cxb->cxb$b_type == DYN$C_CXB )        /* CXB ?    */
  3234.       {
  3235.  
  3236.           irp = cxb->cxb$l_irp;        /* INET IRP on this BGn:    */
  3237.  
  3238.           if ( __PAL_PROBER (irp->irp$l_ioqfl, 4, PR$C_PS_KERNEL) ) 
  3239.                           /* Can IRP be read in Kernel mode ? */
  3240.        {
  3241.  
  3242.            if ( (irp->irp$b_type == DYN$C_IRP) && (irp->irp$l_ucb == ucb) )
  3243.                     /* IRP and this INET UCB ?    */
  3244.             {
  3245.             irp_addr[irp_count]   = (int) irp;        /* IRP address */
  3246.             irp_efn[irp_count]    = irp->irp$b_efn;
  3247.             irp_func[irp_count]   = irp->irp$l_func;
  3248.             irp_iost1[irp_count]  = irp->irp$l_iost1;
  3249.             irp_iosb_a[irp_count] = (uint64) irp->irp$pq_iosb;
  3250.             irp_bcnt[irp_count]   = irp->irp$l_bcnt;
  3251.             irp_ast[irp_count]    = (uint64) irp->irp$pq_acb64_ast;
  3252.             irp_astprm[irp_count] = irp->irp$q_acb64_astprm;
  3253.             irp_p1[irp_count]     = irp->irp$q_qio_p1;
  3254.             irp_p2[irp_count]     = irp->irp$q_qio_p2;
  3255.             irp_p3[irp_count]     = irp->irp$q_qio_p3;
  3256.             irp_p4[irp_count]     = irp->irp$q_qio_p4;
  3257.             irp_p5[irp_count]     = irp->irp$q_qio_p5;
  3258.             irp_p6[irp_count]     = irp->irp$q_qio_p6;
  3259.          
  3260.             irp_pid[irp_count]    = irp->irp$l_pid;
  3261.             irp_epid[irp_count]   = EXE_STD$CVT_IPID_TO_EPID(irp->irp$l_pid);
  3262.                     /* Convert IPID to EPID  */
  3263.          
  3264. /*    Use PID from IRP, might be from a different process    */
  3265.          
  3266.             return_status = EXE$READ_PROCESS(irp_pid[irp_count],cli_length,
  3267.              irp_iosb_a[irp_count],&irp_iosb[irp_count],EACB$K_MEMORY,
  3268.              &read_process_ast_count);
  3269.  
  3270.            irp_unit[irp_count]   = ucb_2->ucb$w_unit;    /* BG unit number */
  3271.        
  3272.             irp_count = irp_count + 1;        /* Next IRP        */
  3273.  
  3274.             } /* End of irp = irp$b_type and INET ucb */
  3275.            } /* End of PROBER irp */
  3276.           } /* End of cxb = cxb$b_type */
  3277.          } /* End of PROBER cxb */
  3278.     } /* End for cxb */
  3279.     } /* End of irp = irp$b_type */
  3280.        } /* if IRP != 0 */
  3281.       } /* End for ucb_2 */
  3282.  
  3283.       sys_unlock (SCHED, orig_ipl, 0);        /* Release SCHED lock   */
  3284.  
  3285.       } /* End if ucb_bg0 != 0 */
  3286.      } /* End INET device */
  3287.  
  3288.    
  3289. /* ********* Mailbox has an own read IO queue ****************************** */
  3290.  
  3291.  
  3292.    if ( (ucb_devchar & DEV$M_MBX) && (ucb_devtype == DT$_MBX) ) /* Mailbox ? */
  3293.      {
  3294.      ucb_ioqfl_a = (IRP *) &mb_ucb->ucb$l_mb_readqfl; /* Mailbox read queue addr */
  3295.      ucb_ioqfl   = mb_ucb->ucb$l_mb_readqfl;    /* Mailbox read queue     */
  3296.      
  3297.      irp         = ucb_ioqfl;            /* IRP        */
  3298.  
  3299. /*    Scan the Mailbox UCB$L_MB_READQFL queue    */
  3300.      
  3301.      while ( (ucb_ioqfl_a != ucb_ioqfl) && (irp_count < MAX_IRP) )
  3302.        {
  3303.        if (! ( __PAL_PROBER (irp->irp$l_ioqfl, 4, PR$C_PS_KERNEL) ) )
  3304.           return (SS$_ACCVIO);    /* Can IRP be read in Kernel mode ? */
  3305.        
  3306.        if ( irp->irp$b_type == DYN$C_IRP )        /* IRP ?    */
  3307.          {
  3308.          irp_addr[irp_count]   = (int) irp;        /* IRP address */
  3309.          irp_efn[irp_count]    = irp->irp$b_efn;
  3310.          irp_func[irp_count]   = irp->irp$l_func;
  3311.          irp_iost1[irp_count]  = irp->irp$l_iost1;
  3312.          irp_iosb_a[irp_count] = (uint64) irp->irp$pq_iosb;
  3313.          irp_bcnt[irp_count]   = irp->irp$l_bcnt;
  3314.          irp_ast[irp_count]    = (uint64) irp->irp$pq_acb64_ast;
  3315.          irp_astprm[irp_count] = irp->irp$q_acb64_astprm;
  3316.          irp_p1[irp_count]     = irp->irp$q_qio_p1;
  3317.          irp_p2[irp_count]     = irp->irp$q_qio_p2;
  3318.          irp_p3[irp_count]     = irp->irp$q_qio_p3;
  3319.          irp_p4[irp_count]     = irp->irp$q_qio_p4;
  3320.          irp_p5[irp_count]     = irp->irp$q_qio_p5;
  3321.          irp_p6[irp_count]     = irp->irp$q_qio_p6;
  3322.          
  3323.          irp_pid[irp_count]    = irp->irp$l_pid;
  3324.          irp_epid[irp_count]   = EXE_STD$CVT_IPID_TO_EPID(irp->irp$l_pid);
  3325.                     /* Convert IPID to EPID  */
  3326.          
  3327. /*    Use PID from IRP, might be from a different process    */
  3328.          
  3329.          return_status = EXE$READ_PROCESS(irp_pid[irp_count],cli_length,
  3330.              irp_iosb_a[irp_count],&irp_iosb[irp_count],EACB$K_MEMORY,
  3331.              &read_process_ast_count);
  3332.          }
  3333.        else
  3334.           break;                /* No, should not happen */
  3335.        
  3336.        irp_count = irp_count + 1;        /* Next IRP        */
  3337.        irp       = irp->irp$l_ioqfl;        /* Next IRP        */
  3338.        ucb_ioqfl = irp;                /* Update queue pointer    */
  3339.        
  3340.        } /* End while 'UCB$L_MB_READQFL' */
  3341.      
  3342.      
  3343. /* **** Mailbox has own BUFIO queue at UCB$L_MB_MSGQFL / UCB$L_MB_MSGQBL *** */
  3344.      
  3345. /*    Scan the Mailbox UCB$L_MB_MSGQFL queue    */
  3346.  
  3347.      
  3348.      ucb_bufiofl_a = (BUFIO *) &ucb->ucb$l_mb_msgqfl; /* MBX BUFIO que adr */
  3349.      ucb_bufiofl   = ucb->ucb$l_mb_msgqfl;    /* MBX BUFIO queue */
  3350.      
  3351.      bufio         = ucb_bufiofl;        /* BUFIO    */
  3352.  
  3353.      while ( (ucb_bufiofl_a != ucb_bufiofl) && (irp_count < MAX_IRP) )
  3354.        {
  3355.        if (bufio->bufio$b_type == DYN$C_BUFIO)
  3356.          {
  3357.          
  3358. /*
  3359.  *    $BUFIODEF
  3360.  *
  3361.  * typedef struct _bufio {
  3362.  *    void *bufio$ps_pktdata;          = Ptr to the buffered data within packet
  3363.  *    void *bufio$ps_uva32;            = 32-bit ptr to user's buffer, or BUFIO$K_64 (-1)
  3364.  *    unsigned short int bufio$w_size; = Total packet size
  3365.  *    unsigned char bufio$b_type;      = Structure type, DYN$C_BUFIO
  3366.  *    char bufio$b_fill_1;           = Function code
  3367.  *    int bufio$l_fill_2;              = IRP
  3368.  *    unsigned __int64 bufio$pq_uva64; = 64-bit Address of User Buffer
  3369.  *
  3370.  *
  3371.  *    The IRP address is in the BUFIO field BUFIO$L_FILL_2
  3372.  *
  3373.  */         
  3374.  
  3375.      irp = (IRP *) bufio->bufio$l_fill_2;        /* IRP address */
  3376.  
  3377.      if ( (irp != 0) && 
  3378.           (__PAL_PROBER (irp->irp$l_ioqfl, 4, PR$C_PS_KERNEL)) )
  3379.                     /* Can IRP be read in Kernel mode ? */
  3380.      {         
  3381.          if ( irp->irp$b_type == DYN$C_IRP )        /* IRP ?    */
  3382.            {
  3383.            irp_addr[irp_count]   = (int) irp;        /* IRP address */
  3384.            irp_efn[irp_count]    = irp->irp$b_efn;
  3385.            irp_func[irp_count]   = irp->irp$l_func;
  3386.            irp_iost1[irp_count]  = irp->irp$l_iost1;
  3387.            irp_iosb_a[irp_count] = (uint64) irp->irp$pq_iosb;
  3388.            irp_bcnt[irp_count]   = irp->irp$l_bcnt;
  3389.            irp_ast[irp_count]    = (uint64) irp->irp$pq_acb64_ast;
  3390.            irp_astprm[irp_count] = irp->irp$q_acb64_astprm;
  3391.            irp_p1[irp_count]     = irp->irp$q_qio_p1;
  3392.            irp_p2[irp_count]     = irp->irp$q_qio_p2;
  3393.            irp_p3[irp_count]     = irp->irp$q_qio_p3;
  3394.            irp_p4[irp_count]     = irp->irp$q_qio_p4;
  3395.            irp_p5[irp_count]     = irp->irp$q_qio_p5;
  3396.            irp_p6[irp_count]     = irp->irp$q_qio_p6;
  3397.            
  3398.            irp_pid[irp_count]    = irp->irp$l_pid;
  3399.            irp_epid[irp_count]   = EXE_STD$CVT_IPID_TO_EPID(irp->irp$l_pid);
  3400.                     /* Convert IPID to EPID  */
  3401.            
  3402. /*    Use PID from IRP, might be from a different process    */
  3403.            
  3404.            return_status = EXE$READ_PROCESS(irp_pid[irp_count],cli_length,
  3405.                irp_iosb_a[irp_count],&irp_iosb[irp_count],EACB$K_MEMORY,
  3406.                &read_process_ast_count);
  3407.            } /* End if IRP */
  3408.          else
  3409.             break;                /* No, should not happen */
  3410.          
  3411.        irp_count   = irp_count + 1;        /* Next IRP        */
  3412.  
  3413.      } /* End if irp != 0 */
  3414.  
  3415.         } /* End if DYN$C_BUFIO*/
  3416.  
  3417.        bufio       = bufio->bufio$ps_pktdata;    /* Next BUFIO        */
  3418.        ucb_bufiofl = bufio;               /* Update queue pointer    */
  3419.        
  3420.        } /* End while */
  3421.      
  3422.  
  3423.  
  3424. /* **** If the process is in RWMBX state, the Mailbox can have     */
  3425. /* **** IRP's queued at PCB$L_ASTQFL_U.                */
  3426.  
  3427.  
  3428.      if ( pcb_efwm[0] == 2 )        /* If RWMBX     */
  3429.      {     
  3430.  
  3431. /*    Scan the PCB ASTQFL_U queue    */
  3432.  
  3433.      pcb_irpfl_a = (IRP *) &pcb->pcb$l_astqfl_u;  /* PCB astqfl_u adr */
  3434.      pcb_irpfl   = (IRP *) pcb->pcb$l_astqfl_u;      /* PCB astqfl_u     */
  3435.      
  3436.      irp = pcb_irpfl;                  /* IRP address */
  3437.  
  3438.      while ( (pcb_irpfl_a != pcb_irpfl) && (irp_count < MAX_IRP) )
  3439.        {
  3440.  
  3441.        if (! ( __PAL_PROBER (irp->irp$l_ioqfl, 4, PR$C_PS_KERNEL) ) )
  3442.                     /* Can IRP be read in Kernel mode ? */
  3443.          break;                /* Cancel    */
  3444.  
  3445.          if ( irp->irp$b_type == DYN$C_IRP )        /* IRP ?    */
  3446.            {
  3447.            irp_addr[irp_count]   = (int) irp;        /* IRP address */
  3448.            irp_efn[irp_count]    = irp->irp$b_efn;
  3449.            irp_func[irp_count]   = irp->irp$l_func;
  3450.            irp_iost1[irp_count]  = irp->irp$l_iost1;
  3451.            irp_iosb_a[irp_count] = (uint64) irp->irp$pq_iosb;
  3452.            irp_bcnt[irp_count]   = irp->irp$l_bcnt;
  3453.            irp_ast[irp_count]    = (uint64) irp->irp$pq_acb64_ast;
  3454.            irp_astprm[irp_count] = irp->irp$q_acb64_astprm;
  3455.            irp_p1[irp_count]     = irp->irp$q_qio_p1;
  3456.            irp_p2[irp_count]     = irp->irp$q_qio_p2;
  3457.            irp_p3[irp_count]     = irp->irp$q_qio_p3;
  3458.            irp_p4[irp_count]     = irp->irp$q_qio_p4;
  3459.            irp_p5[irp_count]     = irp->irp$q_qio_p5;
  3460.            irp_p6[irp_count]     = irp->irp$q_qio_p6;
  3461.            
  3462.            irp_pid[irp_count]    = irp->irp$l_pid;
  3463.            irp_epid[irp_count]   = EXE_STD$CVT_IPID_TO_EPID(irp->irp$l_pid);
  3464.                     /* Convert IPID to EPID  */
  3465.            
  3466. /*    Use PID from IRP, might be from a different process    */
  3467.            
  3468.            return_status = EXE$READ_PROCESS(irp_pid[irp_count],cli_length,
  3469.                irp_iosb_a[irp_count],&irp_iosb[irp_count],EACB$K_MEMORY,
  3470.                &read_process_ast_count);
  3471.  
  3472.            irp_count   = irp_count + 1;        /* Next IRP        */
  3473.  
  3474.            } /* End if IRP */
  3475.  
  3476.          else
  3477.             break;                /* Not an IRP         */
  3478.  
  3479.         irp       = irp->irp$l_ioqfl;        /* Next IRP             */
  3480.         pcb_irpfl = irp;               /* Update queue pointer    */
  3481.  
  3482.        } /* End while */
  3483.  
  3484.      }     
  3485.  
  3486.      } /* End Mailbox */
  3487.  
  3488.    
  3489. /*  ******** NET Devices ************************************************* */
  3490.  
  3491. /*    IRP's for DECnet Phase V (DECnet-Plus)    */
  3492.  
  3493.    if ( (EXE$GL_DECNET_VERSION & PHASEV))     /* Phase V ? */
  3494.      {
  3495.      
  3496.     /* IRP and IOC > 0 and NET device */
  3497.      
  3498.      if ( (ucb_devchar & DEV$M_NET) && (ucb_devchar & DEV$M_MBX) &&
  3499.         (iocou != 0) && (ddb_name[0] == 0x4E) )
  3500.        {
  3501.        
  3502.        for (m=0; m < 2; m++)
  3503.          {
  3504.          
  3505.          if (m == 0) 
  3506.             tmp = OSITP$GA_ATB;    /* DECNET OSI ATB list head    */
  3507.          
  3508.          if (m == 1) 
  3509.             tmp = TP_NSP$GA_NSP_ATB; /* DECNET NSP ATB list head    */
  3510.          
  3511.          atb = (ATB *) tmp;        /* DECNET ATB list head    */
  3512.          
  3513.          if (! ( __PAL_PROBER (atb, 4, PR$C_PS_KERNEL) ) )
  3514.             return (SS$_ACCVIO);    /* Can ATB be read in Kernel mode ? */
  3515.          
  3516.          atb = (ATB *) atb->atb$l_atb;    /* First ATB address        */
  3517.          
  3518. /* \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ */
  3519.          
  3520.          atb_end = 0;            /* Clear last ATB flag    */
  3521.          
  3522. /*    Check if we have only one ATB    */
  3523.          
  3524.          if (atb->atb$a_cti_next_table == 0)
  3525.             atb_end = 1;                /* Flag last ATB   */
  3526.                         /* 0 = Not last       */
  3527.                         /* 1 = Last, do it */
  3528.                         /* 2 = Last done   */
  3529.          
  3530.          while (    atb_end != 2 )             /* Last ATB */
  3531.            {
  3532.            if (! ( __PAL_PROBER (atb, 4, PR$C_PS_KERNEL) ) )
  3533.               return (SS$_ACCVIO);    /* Can ATB be read in Kernel mode ? */
  3534.            
  3535.            tmp = atb->atb$w_cti_cur_slots;    /* # of current slots    */
  3536.            atb_slots = atb->atb$w_cti_tot_slots;     /* # of total slots     */
  3537.            
  3538. /* ****    Find first OSI/NSP port from Association Block Table    */
  3539.            
  3540.            if ( tmp > 0 )                /* Slot # > 0    */
  3541.              {
  3542.              port_slot = (PORT_SLOT *) atb->atb$a_cti_slots;
  3543.                         /* Port slot 0 address    */
  3544.              for (k=0; k < atb_slots; k++)
  3545.                {
  3546.                port_slot = (PORT_SLOT *) ( (int) port_slot + 4);
  3547.                         /* Next slot address    */
  3548. /* Note: port_slot = port_slot + 4; Generates PORT_SLOT + 144 ??    */
  3549.                
  3550.                if (port_slot != 0) 
  3551.                  {
  3552.                  
  3553.                  if (! ( __PAL_PROBER (port_slot, 4, PR$C_PS_KERNEL) ) )
  3554.                     return (SS$_ACCVIO);   /* Can PORT_SLOT be read in Kernel mode ? */
  3555.                  
  3556.                  if ( !(port_slot->port_slot$l_port & 1) )    /* Low bit clear */
  3557.                    {
  3558.                    port = (PORT *) port_slot->port_slot$l_port; /* OSI PORT address */
  3559.                    break;
  3560.                    }
  3561.                  }
  3562.                } /* End for k */
  3563.              
  3564.              if (! ( __PAL_PROBER (port, 4, PR$C_PS_KERNEL) ) )
  3565.                 return (SS$_ACCVIO);   /* Can PORT be read in Kernel mode ? */
  3566.              
  3567. /* ***** OSI or NSP Port        */
  3568.              
  3569.              if (m == 0)             /* OSI    */
  3570.                {
  3571.                port_fl_a = (PORT *) &port->port$l_osi_fl; /* OSI port Flink address */
  3572.                port_fl   = (PORT *)  port->port$l_osi_fl; /* OSI port Flink          */
  3573.                }
  3574.              
  3575.              if (m == 1)             /* NSP  */
  3576.                {
  3577.                port_fl_a = (PORT *) &port->port$l_nsp_fl; /* NSP port Flink address */
  3578.                port_fl   = (PORT *)  port->port$l_nsp_fl; /* NSP port Flink         */
  3579.                }
  3580.              
  3581. /* ***** Find VCRP        */
  3582.              
  3583.              port_count = 0;                /* Clear port counter    */
  3584.              
  3585.              while ( (port_fl_a != port_fl) && (irp_count < MAX_IRP) )
  3586.                {
  3587.                
  3588.                port_count = port_count + 1;        /* Inc port counter    */
  3589.                
  3590.                if (m == 0)                     /* OSI */
  3591.                  {
  3592.                  vcrp_qfl_a = (VCRP *) &port->port$l_vcrp_fl;    /* Flink address */
  3593.                  vcrp_qfl   = (VCRP *)  port->port$l_vcrp_fl;    /* VCRP address  */
  3594.                  }
  3595.                
  3596.                if (m == 1)                     /* NSP  */
  3597.                  {
  3598.                  vcrp_qfl_a = (VCRP *) &port->port$l_nsp_vcrp_fl;  /* Flink address */
  3599.                  vcrp_qfl   = (VCRP *)  port->port$l_nsp_vcrp_fl;  /* VCRP address  */
  3600.                  }
  3601.                
  3602.                vcrp       = vcrp_qfl;            /* VCRP address  */
  3603.                
  3604. /*  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\    */
  3605. /*                    */
  3606. /* ADD: if vcrp_qfl_a != vcrp_qfl    */
  3607. /*                    */
  3608. /*  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\    */
  3609.                
  3610.                if ( vcrp != 0)
  3611.                  {
  3612.                  
  3613.                  if (! ( __PAL_PROBER (vcrp, 4, PR$C_PS_KERNEL) ) )
  3614.                     return (SS$_ACCVIO);   /* Can VCRP be read in Kernel mode ? */
  3615.                  
  3616.                  irp = (IRP *) vcrp->vcrp$l_creator_data1;    /* IRP address    */
  3617.                  
  3618.                  if (! ( __PAL_PROBER (irp, 4, PR$C_PS_KERNEL) ) )
  3619.                     return (SS$_ACCVIO);   /* Can IRP be read in Kernel mode ? */
  3620.                  
  3621.                  if ( (pcb_pid == vcrp->vcrp$l_pid) && (irp->irp$b_type == DYN$C_IRP) && (ucb == irp->irp$l_ucb) )
  3622.                 /* Our VCRP and IRP and this UCB    */
  3623.                    {
  3624.                    
  3625. /*     nsp_port = port->port$a_constemplatenamelist;    */
  3626.                         /* NSP Port #    */
  3627.                    
  3628.                    idlist = (IDLIST *) port->port$a_id_list;    /* Port Id list */
  3629.                    
  3630.                    str_length = idlist->idlist$b_port_name_len;    /* PORT name length  */
  3631.                    
  3632.                    strncpy (port_name, idlist->idlist$t_port_name, str_length);
  3633.                         /* Copy OSI/NSP Port name */
  3634.                    
  3635.                    eib = (EIB*) port->port$a_eib_emaa;    /* EIB address        */
  3636.                    scl = port->port$l_tpu_connection_id;    /* SCL port ID        */
  3637.                    
  3638.                    if (m == 0)                 /* OSI */
  3639.                       net_port = 1;                /* Flag OSI Port name there */
  3640.                    else                    /* NSP */
  3641.                       net_port = 2;                /* Flag NSP Port name there */
  3642.                    
  3643.                    irp_addr[irp_count]   = (int) irp;        /* IRP address */
  3644.                    irp_efn[irp_count]    = irp->irp$b_efn;
  3645.                    irp_func[irp_count]   = irp->irp$l_func;
  3646.                    irp_iost1[irp_count]  = irp->irp$l_iost1;
  3647.                    irp_iosb_a[irp_count] = (uint64) irp->irp$pq_iosb;
  3648.                    irp_bcnt[irp_count]   = irp->irp$l_bcnt;
  3649.                    irp_ast[irp_count]    = (uint64) irp->irp$pq_acb64_ast;
  3650.                    irp_astprm[irp_count] = irp->irp$q_acb64_astprm;
  3651.                    irp_p1[irp_count]     = irp->irp$q_qio_p1;
  3652.                    irp_p2[irp_count]     = irp->irp$q_qio_p2;
  3653.                    irp_p3[irp_count]     = irp->irp$q_qio_p3;
  3654.                    irp_p4[irp_count]     = irp->irp$q_qio_p4;
  3655.                    irp_p5[irp_count]     = irp->irp$q_qio_p5;
  3656.                    irp_p6[irp_count]     = irp->irp$q_qio_p6;
  3657.                    
  3658.                    irp_pid[irp_count]    = irp->irp$l_pid;
  3659.                    irp_epid[irp_count]   = EXE_STD$CVT_IPID_TO_EPID(irp->irp$l_pid);
  3660.                     /* Convert IPID to EPID  */
  3661.                    
  3662. /*    Use PID from IRP, might be from a different process    */
  3663.                    
  3664.                    return_status = EXE$READ_PROCESS(irp_pid[irp_count],cli_length,
  3665.                    irp_iosb_a[irp_count],&irp_iosb[irp_count],EACB$K_MEMORY,
  3666.                    &read_process_ast_count);
  3667.                    
  3668.                    irp_count = irp_count + 1;    /* Next IRP        */
  3669.                    
  3670.                    } /* End pid and IRP */
  3671.                  } /* End VRCP != 0    */
  3672.                
  3673.                
  3674.                if (m == 0) 
  3675.                   next_port = port->port$l_osi_fl;   /* Next OSI PORT Flink address */
  3676.                          /* Note: not PORT address !    */
  3677.                if (m == 1) 
  3678.                   next_port = port->port$l_nsp_fl;   /* Next NSP PORT Flink address */
  3679.                
  3680. /* Bump the port FL pointer once ==> the last port in the queue is done too */
  3681.                
  3682.                if (port_count == 1)
  3683.                   port_fl_a = port_fl;            /* Update PORT fl address   */
  3684.                
  3685.                
  3686. /* **** Note: Last FL points to a location, not to a PORT    */
  3687. /*    This location points to the first PORT Flink        */
  3688.                
  3689.                if (m == 0) 
  3690.                   port = (PORT *) (next_port - 0xD8);    /* Next OSI PORT address */
  3691.                if (m == 1) 
  3692.                   port = (PORT *) (next_port - 0xBC);    /* Next NSP PORT address */
  3693.                
  3694. /*    Check if an OSI Port or the above pointer    */
  3695.                
  3696.                if ( (port->port$b_type != DYN$C_DECNET) &&
  3697.                   ( (port->port$b_subtype != DYN$C_NET_OSITP_PORT) ||
  3698.                (port->port$b_subtype != DYN$C_NET_NSP_PORT)) )
  3699.                
  3700.                  {
  3701.                  port      = (PORT *) next_port;       /* PORT pointer address          */
  3702.                  next_port = port->port$l_flink;       /* Next (first) PORT Flink address */
  3703.                  if (m == 0) 
  3704.                     port = (PORT *) (next_port - 0xD8);    /* Next OSI PORT address */
  3705.                  if (m == 1) 
  3706.                     port = (PORT *) (next_port - 0xBC);    /* Next NSP PORT address */
  3707.                  }
  3708.                
  3709.                
  3710.                if (! ( __PAL_PROBER (port, 4, PR$C_PS_KERNEL) ) )
  3711.                   return (SS$_ACCVIO);   /* Can PORT be read in Kernel mode ? */
  3712.                
  3713.                
  3714.                if (m == 0) 
  3715.                   port_fl = (PORT *) port->port$l_osi_fl;    /* OSI Port flink */
  3716.                if (m == 1) 
  3717.                   port_fl = (PORT *) port->port$l_nsp_fl;       /* NSP PORT Flink */
  3718.                
  3719.                } /* End while fl_a != a */
  3720.              } /* End slot # > 0 */
  3721.            
  3722.            
  3723.            if (atb->atb$a_cti_next_table == 0)
  3724.               atb_end = atb_end + 1;            /* Flag last ATB   */
  3725.                             /* 0 = Not last       */
  3726.                             /* 1 = Last, do it */
  3727.                             /* 2 = Last done   */
  3728.            
  3729.            if (atb_end == 0)                /* Not last ATB    */
  3730.               atb = (ATB *) atb->atb$a_cti_next_table;    /* Next ATB */
  3731.            
  3732.            
  3733.            } /* End while atb_end != 2 */
  3734.          } /* End for m         */
  3735.        } /* End NET Device */
  3736.      
  3737.      } /* End PHASE V */
  3738.    
  3739.    
  3740.    return (SS$_NORMAL);
  3741.    } 
  3742.  
  3743. /* ************************************************************************* */
  3744.  
  3745. /* Routine get_process_registers(int index, int pid)
  3746.  *
  3747.  *
  3748.  * FUNCTION
  3749.  *
  3750.  *     This routine gets the process registers in Kernel mode
  3751.  *
  3752.  * INPUT
  3753.  *
  3754.  *      PID process ID
  3755.  *
  3756.  * IMPLICIT INPUT
  3757.  *
  3758.  * EXPLICIT OUTPUT
  3759.  *
  3760.  *      ss$_normal      Success.  
  3761.  *    ss$_nonexpr    Nonexistent process
  3762.  *
  3763.  */
  3764.  
  3765. int get_process_registers (int pid)
  3766.    {
  3767.    
  3768. /* Get registers            */
  3769.    
  3770.    return_status =    EXE$READ_PROCESS(pid,8*EACB$K_GEN_REGS_LENGTH,EACB$K_R0,
  3771.        &prc_registers,EACB$K_GENERAL_REGISTER,&read_process_ast_count);
  3772.    
  3773.    return (return_status);
  3774.    
  3775.    }
  3776.  
  3777. /* ************************************************************************* */
  3778.  
  3779. /* Routine map_address(int addr, int pid)
  3780.  *
  3781.  *
  3782.  * FUNCTION
  3783.  *
  3784.  *     This routine maps a given address
  3785.  *
  3786.  * INPUT
  3787.  *
  3788.  *      addr address to map
  3789.  *
  3790.  * IMPLICIT INPUT
  3791.  *
  3792.  *    LDR$GQ_IMAGE_LIST - Header of image list
  3793.  *
  3794.  * EXPLICIT OUTPUT
  3795.  *
  3796.  *      ss$_normal      Success
  3797.  *    ss$_nonexpr    Nonexistent process
  3798.  *
  3799.  */
  3800. int map_address (int addr, int pid)
  3801.    {
  3802. /*    Map the address            */
  3803.    
  3804.    found = -1;
  3805.    psect = 0;
  3806.    kferes_offset = 0;
  3807.    
  3808.    if ( addr == 0 ) return (SS$_NORMAL);
  3809.       
  3810. /*    Address is in system space    */
  3811.    
  3812.    if ( addr >= 0X80000000 )
  3813.      {
  3814.      tmp = (int) &LDR$GQ_IMAGE_LIST;           /* Address of Image Header list */
  3815.      ldrimg = (LDRIMG *) LDR$GQ_IMAGE_LIST;  /* First entry    */
  3816.      
  3817.      found = 0;
  3818.      
  3819. /*    Scan the image list    */
  3820.      
  3821.      while ( found == 0 )
  3822.        {
  3823.        
  3824.        if ( (int) ldrimg == tmp )
  3825.           found = -1;                /* Flag not found */
  3826.        else
  3827.          {
  3828.          
  3829. /*    Nonpaged read only    */
  3830.          
  3831.          start = (int) ldrimg->ldrimg$l_nonpag_r_base;
  3832.          end   = start + (int) ldrimg->ldrimg$l_nonpag_r_len;
  3833.          
  3834. /* ??? \\\ if ( ( start <= addr ) && ( end >= addr ) && end != 0 )
  3835. /*                         end == 0 image is not loaded */
  3836.          
  3837.          if ( ( start <= addr ) && ( end >= addr ) )
  3838.            {
  3839.            found = 1;                /* Flag  found    */
  3840.            offset = addr - start + ldrimg->ldrimg$l_nonpag_r_offset;
  3841.                         /* Image offset    */
  3842.            psect = 5;                /* Psect type    */
  3843.            break;
  3844.            }
  3845.          
  3846. /*    Nonpaged read/write    */
  3847.          
  3848.          start = (int) ldrimg->ldrimg$l_nonpag_w_base;
  3849.          end   = start + (int) ldrimg->ldrimg$l_nonpag_w_len;
  3850.          
  3851.          if ( ( start <= addr ) && ( end >= addr ) )
  3852.            {
  3853.            found = 1;                /* Flag  found    */
  3854.            offset = addr - start + ldrimg->ldrimg$l_nonpag_w_offset;
  3855.                         /* Image offset    */
  3856.            psect = 6;                /* Psect type    */
  3857.            break;
  3858.            }
  3859.          
  3860.          
  3861.          
  3862. /*    Paged read only    */
  3863.          
  3864.          start = (int) ldrimg->ldrimg$l_pag_r_base;
  3865.          end   = start + (int) ldrimg->ldrimg$l_pag_r_len;
  3866.          
  3867.          if ( ( start <= addr ) && ( end >= addr ) )
  3868.            {
  3869.            found = 1;                /* Flag  found    */
  3870.            offset = addr - start + ldrimg->ldrimg$l_pag_r_offset;
  3871.                         /* Image offset    */
  3872.            psect = 7;                /* Psect type    */
  3873.            break;
  3874.            }
  3875.          
  3876.          
  3877. /*    Paged read/write     */
  3878.          
  3879.          start = (int) ldrimg->ldrimg$l_pag_w_base;
  3880.          end   = start + (int) ldrimg->ldrimg$l_pag_w_len;
  3881.          
  3882.          if ( ( start <= addr ) && ( end >= addr ) )
  3883.            {
  3884.            found = 1;                /* Flag  found    */
  3885.            offset = addr - start + ldrimg->ldrimg$l_pag_w_offset;
  3886.                         /* Image offset    */
  3887.            psect = 8;                /* Psect type    */
  3888.            break;
  3889.            }
  3890.          
  3891.          
  3892.          
  3893.          ldrimg = ldrimg->ldrimg$l_flink;    /* Next entry   */
  3894.          }
  3895.        
  3896.        } /* end while */
  3897.      
  3898. /*???    look at the drivers    */
  3899.      
  3900. /*    IOC$GL_DPTLIST        list of drivers    */    
  3901. /*    DPT$W_SIZE(R6)        size of driver    */
  3902.      
  3903. /*???    look extra images (MSCP, TMSCP, VAXEMUL, FPEMUL)    */
  3904.      
  3905. /*      SCS$GL_MSCP        MSCP */
  3906. /*    SLV$L_CODESIZE        size of MSCP    */
  3907.      
  3908. /*    SCS$GL_TMSCP            */
  3909. /*    SLV$L_CODESIZE        size of     */
  3910.      
  3911.      
  3912.      
  3913.      if (found == 1)
  3914.        {
  3915.        str_length = ldrimg->ldrimg$b_imgnamlen;   /* Image name length  */
  3916.        strncpy (image_name, ldrimg->ldrimg$t_imgnam, str_length);
  3917.        return (SS$_NORMAL);
  3918.        }    
  3919.      } /* end if addr >= 0X80000000    */
  3920.    
  3921.    
  3922. /************ Address is in P0/P1 space ***********************************/
  3923.    
  3924. /*    Address was not in system address space, look for image space*/
  3925.    
  3926.    if (found == -1)
  3927.      {
  3928.      tmp  = (int) &IAC$GL_IMAGE_LIST;        /* Address of list head */
  3929.      
  3930.      
  3931. /*    Get first list head element */
  3932.      
  3933.      return_status = EXE$READ_PROCESS(pid,link_length,&IAC$GL_IMAGE_LIST,
  3934.          &imcb_link,EACB$K_MEMORY,&read_process_ast_count);
  3935.          if (return_status != SS$_NORMAL) return (return_status);
  3936.         
  3937.      imcb = (IMCB *) imcb_block;        /* Local IMCB array    */
  3938.      found = 0;
  3939.      
  3940. /*    Scan the user image    */
  3941.      
  3942.      while ( found == 0 )
  3943.        {
  3944.        if ( imcb_link == tmp )
  3945.           found = -1;                /* Flag not found */
  3946.        else
  3947.          {
  3948.          
  3949.          return_status = EXE$READ_PROCESS(pid,IMCB$K_LENGTH,imcb_link,
  3950.              &imcb_block,EACB$K_MEMORY,&read_process_ast_count);
  3951.              if (return_status != SS$_NORMAL) return (return_status);
  3952.             
  3953.          start = (int) imcb->imcb$l_starting_address;    /* Start address */
  3954.          end   = (int) imcb->imcb$l_end_address;    /* End address   */
  3955.          
  3956.          if ( ( start <= addr ) && ( end >= addr ) )
  3957.            {
  3958.            found = 1;                           /* Flag  found  */
  3959.            psect = (int) imcb->imcb$b_act_code;        /* Psect type   */
  3960.            break;
  3961.            }
  3962.          
  3963. /*    Check if a sliced image */
  3964.          
  3965.          if (found != 1) 
  3966.            {
  3967.            
  3968.            if ( imcb->imcb$l_flags & IMCB$M_DISCONTIGUOUS )
  3969.              {
  3970.              kferes = (KFERES *) imcb->imcb$l_kferes_ptr;
  3971.              
  3972. /*     Get # of resident sections */
  3973.              
  3974.              kferes_link = (int) kferes;
  3975.              
  3976.              return_status = EXE$READ_PROCESS(pid,KFERES$K_FIXED_LENGTH,kferes_link,
  3977.              &kferes_block,EACB$K_MEMORY,&read_process_ast_count);
  3978.              if (return_status != SS$_NORMAL) return (return_status);
  3979.                 
  3980.              kferes = (KFERES *) kferes_block;
  3981.              
  3982.              kferes_count = kferes->kferes$l_count;
  3983.              
  3984.              kferes_link = kferes_link + KFERES$K_FIXED_LENGTH;
  3985.                         /* Address of first section */
  3986.              
  3987. /*    Read KFERES section's    */
  3988.              
  3989.              while ( kferes_count > 0 )
  3990.                {
  3991.                return_status = EXE$READ_PROCESS(pid,KFERES$K_SECTION_LENGTH,kferes_link,
  3992.                &kferes_block,EACB$K_MEMORY,&read_process_ast_count);
  3993.                if (return_status != SS$_NORMAL) return (return_status);
  3994.                   
  3995.                kferes_section = (KFERES_SECTION *) kferes_block;
  3996.                
  3997.                if ( kferes_section->kferes$l_section_type == KFERES$K_CODE )
  3998.                  {
  3999.                  start = (int) kferes_section->kferes$l_va;  /* Start address */
  4000.                  end   = start + kferes_section->kferes$l_length;  /* End address   */
  4001.                  
  4002.                  if ( ( start <= addr ) && ( end >= addr ) )
  4003.                    {
  4004.                    found = 1;             /* Flag  found  */
  4005.                    kferes_offset = (int) kferes_section->kferes$l_image_offset;
  4006.                         /* Image offset    */
  4007.                    psect = 10;            /* Psect type System Resident Code  */
  4008.                    break;
  4009.                    }
  4010.                  
  4011.                  
  4012.                  } /* End if KFERES$K_CODE */
  4013.                
  4014.                kferes_link = kferes_link + KFERES$K_SECTION_LENGTH;
  4015.                             /* Next section*/
  4016.                kferes_count = kferes_count - 1;
  4017.                
  4018.                }  /* End while kferes_count */
  4019.              
  4020.              } /* End if IMCB$M_DISCONTIGUOUS */
  4021.            
  4022.            } /* End if found != 1    */
  4023.          
  4024. /* ********************************** */
  4025.          
  4026. /*     Get address of next element */
  4027.          
  4028.          return_status = EXE$READ_PROCESS(pid,link_length,imcb_link,
  4029.              &imcb_link,EACB$K_MEMORY,&read_process_ast_count);
  4030.              if (return_status != SS$_NORMAL) return (return_status);
  4031.             
  4032.          
  4033.          } /* end else */
  4034.        
  4035.        } /* end while found */
  4036.      
  4037.      if (found == 1)
  4038.        {
  4039.        offset = addr + kferes_offset;        /* Image offset    */
  4040.        
  4041.        if ( (int) imcb->imcb$b_act_code != IMCB$K_MAIN_PROGRAM )
  4042.           offset = offset - start;  /* Substract base if not main image */
  4043.        
  4044.        strncpy (tmp_string,imcb->imcb$t_image_name,2); /* Image name    */
  4045.        str_length = (int) tmp_string[0];               /* Image name length  */
  4046.        strncpy (image_name, imcb->imcb$t_image_name+1, str_length);
  4047.        
  4048.        return (SS$_NORMAL);
  4049.        }    
  4050.      
  4051. /*    Address is not within a system or user image    */
  4052.      
  4053.      if ( found <= 0 )
  4054.        {
  4055.        return_status = EXE$READ_PROCESS(pid,cli_length,&CTL$AG_CLIMAGE,
  4056.            &cli,EACB$K_MEMORY,&read_process_ast_count);
  4057.            if (return_status != SS$_NORMAL) return (return_status);
  4058.           
  4059.        start = cli[0];                /* Start address */
  4060.        end   = cli[1];                /* End address   */
  4061.        
  4062.        if ( ( start <= addr ) && ( end >= addr ) )
  4063.          {
  4064.          found  = 1;                              /* Flag  found  */
  4065.          offset = addr - start;         /* Image offset */
  4066.          
  4067.          strncpy (tmp_string, (char *) &CTL$GT_CLINAME,2); /* CLI name */
  4068.          str_length = (int) tmp_string[0];           /* CLI name length */
  4069.          strncpy (image_name, (char *) &CTL$GT_CLINAME+1, str_length);
  4070.          
  4071.          strcat (image_name,".EXE (CLI Image, in P1 Space)");
  4072.          
  4073.          
  4074.          psect  = 2;                /* Psect type   */
  4075.          return (SS$_NORMAL);
  4076.          }
  4077.        
  4078.        }
  4079.      
  4080.      }
  4081.    
  4082.    return (return_status);
  4083. }
  4084.  
  4085. /* ************************************************************************* */
  4086.  
  4087. /* Routine get_symbol_offset ( char img_nam[] )
  4088.  *
  4089.  *
  4090.  * FUNCTION
  4091.  *
  4092.  *     This routine gets the OSI symbol table offset
  4093.  *
  4094.  * INPUT
  4095.  *
  4096.  *      img_nam        Image name
  4097.  *
  4098.  * IMPLICIT INPUT
  4099.  *
  4100.  *    LDR$GQ_IMAGE_LIST - Header of image list
  4101.  *
  4102.  * OUTPUT
  4103.  *
  4104.  *      offset        NET$TRANSPORT_xxx.EXE symbol offset
  4105.  *
  4106.  * EXPLICIT OUTPUT
  4107.  *
  4108.  *      ss$_normal      Success
  4109.  *
  4110.  */
  4111. int get_symbol_offset ( char img_nam[] )
  4112.    {
  4113.  
  4114.    if (! ( __PAL_PROBER (img_nam, 4, PR$C_PS_KERNEL) ) )
  4115.       return (SS$_ACCVIO);        /* Can Image name be read in Kernel mode ? */
  4116.  
  4117.    tmp = (int) &LDR$GQ_IMAGE_LIST;           /* Address of Image Header list */
  4118.    ldrimg = (LDRIMG *) LDR$GQ_IMAGE_LIST;  /* First entry    */
  4119.      
  4120.    found = 0;
  4121.      
  4122. /*    Scan the image list    */
  4123.      
  4124.    while ( found == 0 )
  4125.     {
  4126.        
  4127.      if ( (int) ldrimg == tmp )
  4128.        found = -1;                /* Flag not found */
  4129.      else
  4130.        {
  4131.          
  4132. /*    Nonpaged read/write    */
  4133.          
  4134.         if ( !(strncmp(ldrimg->ldrimg$t_imgnam, img_nam, strlen(img_nam) )) )
  4135.       {
  4136.           found  = 1;                /* Flag  found    */
  4137.  
  4138.           start  = (int) ldrimg->ldrimg$l_nonpag_w_base;
  4139.           end    = (int) ldrimg->ldrimg$l_nonpag_w_offset;
  4140.           offset = start - end;        /* STB offset    */
  4141.  
  4142.           break;
  4143.           }
  4144.          
  4145.         ldrimg = ldrimg->ldrimg$l_flink;    /* Next entry   */
  4146.  
  4147.        } /* end else */
  4148.     } /* end while */
  4149.  
  4150.    return_status = found;
  4151.      
  4152.    return (return_status);
  4153.    }
  4154.  
  4155.  
  4156.  
  4157.  
  4158. /*    Dummy routine for end of code to lock    */
  4159.  
  4160. void last_address ()
  4161.    {
  4162.    }
  4163.  
  4164. /* ******************************************************************** */
  4165.  
  4166.  
  4167. /* Routine read_stb_file ( char filnam[], char atbnam[] )
  4168.  *
  4169.  *
  4170.  * FUNCTION
  4171.  *
  4172.  *      This routine reads the xxx_ATB symbol values from the
  4173.  *    NET$TRANSPORT_xxx.STB files
  4174.  *
  4175.  * INPUT
  4176.  *
  4177.  *    filnam        File name
  4178.  *    atbnam        Symbol name
  4179.  *
  4180.  * IMPLICIT INPUT
  4181.  *
  4182.  *      None
  4183.  *
  4184.  * OUTPUT
  4185.  *
  4186.  *      sym_val        NET$TRANSPORT_xxx.EXE symbol offset
  4187.  *
  4188.  * EXPLICIT OUTPUT
  4189.  *
  4190.  *      ss$_normal      Success
  4191.  *
  4192.  */
  4193.  
  4194. int read_stb_file ( char filnam[], char atbnam[]  )
  4195.    {
  4196.  
  4197.    fab              = cc$rms_fab;            /* Build the FAB     */
  4198.    fab.fab$l_fna = filnam;            /* File name        */
  4199.    fab.fab$b_fns = strlen(fab.fab$l_fna);    /* File name length      */
  4200.    fab.fab$l_dna = filnam;            /* File name            */
  4201.    fab.fab$b_dns = strlen(fab.fab$l_dna);    /* File name length     */
  4202.    fab.fab$b_fac = FAB$M_GET;        
  4203.    fab.fab$b_shr = FAB$M_SHRGET;        /* Allow shared read     */
  4204.  
  4205.  
  4206.    rab              = cc$rms_rab;            /* Build the RAB */
  4207.    rab.rab$l_fab = &fab;
  4208.    rab.rab$l_ubf = inbuf;
  4209.    rab.rab$w_usz = BUFFER_LENGTH - 1;
  4210.    rab.rab$l_rbf = inbuf;
  4211.  
  4212.    return_status = SYS$OPEN(&fab);        /* Open input file */
  4213.      if (!(return_status&1)) return (return_status);
  4214.  
  4215.    return_status = SYS$CONNECT(&rab);        /* Connect input RAB to FAB */
  4216.      if (!(return_status&1)) return (return_status);
  4217.  
  4218. /* ******************************************************************* */
  4219.  
  4220.    eobjrec = (struct eobjrecdef *) &inbuf[0];
  4221.    egs     = (struct egsdef *) &inbuf[0];
  4222.  
  4223.    eobjrec->eobj$w_rectyp = EOBJ$C_EMH;    /* Clear EEOM    */
  4224.  
  4225.    while ( eobjrec->eobj$w_rectyp != EOBJ$C_EEOM )
  4226.      {
  4227.  
  4228.       return_status = SYS$GET(&rab);        /* Get first record from input file */
  4229.       if (!(return_status&1)) return (return_status);
  4230.  
  4231. /* ********  */
  4232.  
  4233.       egst = (struct egstdef *) (&inbuf[0] + GSD_SIZ); /* Point to first subrecord */
  4234.  
  4235.  
  4236.       if ( eobjrec->eobj$w_rectyp == EOBJ$C_EGSD )
  4237.        {
  4238.        if ( egs->egsd$w_gsdtyp == EGSD$C_SYMG )
  4239.         {
  4240.         size = eobjrec->eobj$w_size;        /* GSD Record size    */
  4241.         size = size - GSD_SIZ;            /* less header record    */
  4242.  
  4243.         while (size > 0 )
  4244.           {
  4245.           if ( !(strncmp(egst->egst$t_name, atbnam, strlen(atbnam) )) )
  4246.            {
  4247. /*    printf("Symbol name : %s \n",  egst->egst$t_name);    */
  4248. /*    fprintf(outfile, "Symbol name : %s \n",  egst->egst$t_name);    */
  4249.  
  4250. /*    printf(" Value      : %X \n",  egst->egst$l_value);    */
  4251. /*    fprintf(outfile, " Value      : %X \n",  egst->egst$l_value);    */
  4252.  
  4253.  
  4254.            sym_val = egst->egst$l_value;     /* Symbol value    */
  4255.            eobjrec->eobj$w_rectyp = EOBJ$C_EEOM; /* Flag "end of file"    */
  4256.            }
  4257.         size = size - egst->egst$w_size;    /* GSD Subrecord size    */
  4258.         egst = (struct egstdef  *) ((int)egst + egst->egst$w_size);
  4259.                         /* Point to next subrecord */
  4260.         } /* End while size     */
  4261.        } /* End if EGSD$C_SYMG  */
  4262.      } /* End if EOBJ$C_EGSD    */
  4263.    } /* End while EOBJ$C_EEOM   */
  4264.                                     
  4265.    return_status = SYS$CLOSE(&fab);    /* Close input file */
  4266.  
  4267.    return_status = SS$_NORMAL;        /* Success */
  4268.    return (return_status);
  4269. }
  4270.  
  4271.