#ifdef public_domain_notice Copyright (c) 1996 David P. Murphy for Datametrics Systems Corporation --- please send all comments and bug reports to murphy@connor.datametrics.com Permission is granted to any individual or institution to use, copy, or redistribute this software so long as all of the original files are included, that it is not sold for profit, and that this copyright notice is retained. Use at your own risk. Neither Murphy nor Datametrics assumes responsibility. Do not taunt Happy Fun Ball. #endif #ifndef MYCROFT_DEFINED #define MYCROFT_DEFINED 1 /* channels */ /* all of the data in this structure is simply copied straight from P1 space * so it's extremely cheap to obtain, considering we've already gone to the * trouble of calling an exec-mode user-written system service. each member * has its source structure named in the comment to assist your understanding. * many of these fields are bitmasks --- you'll have to derive their meanings * from the $GETDVI() manuals or (preferably) SYS$LIBRARY:LIB.REQ, since i am * _not_ going to copy all of the bit definitions here! * * note that * CTL$GA_CCB_TABLE->CCB (well, kind of) * and * CCB->UCB->VCB * and * CCB->UCB->DDB->SB * and also that * CCB->WIND->FCB * and finally * IAC$GL_IMAGE_LIST->ICB->KFE * * finally, please remember that you _cannot_ safely dereference these addresses * from user- or even supervisor-mode . . . they are passed back to you to save * you the trouble of recalculating the one or two in which you might actually * be interested, and because it doesn't cost anything to do so. */ typedef union MYCROFT_KFE_BITMASK { unsigned short themask; struct { unsigned protect : 1; /* KFE : known file was installed protected (for images only) */ unsigned lim : 1; /* KFE : linkable image (for images only) */ unsigned procpriv : 1; /* KFE : use process privilege mask (for images only) */ unsigned open : 1; /* KFE : image installed /OPEN (for images only) */ unsigned hdrres : 1; /* KFE : image header block is resident (for images only) */ unsigned shared : 1; /* KFE : image is shared (for images only) */ unsigned shmident : 1; /* KFE : shared memory ident already set (for images only) */ unsigned compatmod : 1; /* KFE : image is compatability mode (for images only) */ unsigned nopurge : 1; /* KFE : image entry may not be purged (for images only) */ unsigned account : 1; /* KFE : image level accounting (for images only) */ unsigned writeable : 1; /* KFE : global sections are writeable (for images only) */ unsigned exeonly : 1; /* KFE : image has only execute access allowed (for images only) */ unsigned disctg : 1; /* KFE : image has resident sections (for images only) */ unsigned : 3; } thebits; } MHInstalledMask; typedef union MYCROFT_MISC_BITMASK { unsigned short themask; struct { unsigned sectfile : 1; /* the file is a "section" file */ unsigned readacc : 1; /* the device was assigned with read access */ unsigned writeacc : 1; /* the device was assigned with write access */ unsigned : 5; } thebits; } MHMiscMask; typedef struct MYCROFT_CHEAP_CHANNEL_INFO { void *ccb; /* ctl$ : address of Channel Control Block */ void *icb; /* iac$ : address of Image Control Block */ void *ucb; /* CCB : address of Unit Control Block */ void *wind; /* CCB : address of Window Block */ void *crb; /* UCB : address of Channel Request Block */ void *ddb; /* UCB : address of Device Data Block */ void *orb; /* UCB : address of Object's Rights Block */ void *vcb; /* UCB : address of Volume Control Block */ void *ddt; /* DDB : address of the Driver Dispatch Table */ void *sb; /* DDB : address of System Block which owns the device */ void *localsb; /* scs$ : address of current node's System Block */ void *fcb; /* WCB : address of File Control Block */ void *kfe; /* ICB : address of Known File Entry (for images only) */ void *vastart; /* ICB : beginning virtual address (for images only) */ void *vaend; /* ICB : ending virtual address (for images only) */ unsigned long chan; /* CCB : associated channel number */ unsigned long ioc; /* CCB : number of outstanding i/o requests on channel */ unsigned long opcnt; /* UCB : count of operations completed */ unsigned long errcnt; /* UCB : device error count */ unsigned long refcnt; /* UCB : reference count of processes */ unsigned long allocls; /* DDB : device allocation class */ unsigned long csts; /* CCB : channel status */ unsigned long usts; /* UCB : device unit status */ unsigned long devsts; /* UCB : device dependent status */ unsigned long devchar; /* UCB : original device characteristic bits */ unsigned long devchar2; /* UCB : extended device characteristic bits */ unsigned long devdepend; /* UCB : first device dependent longword */ unsigned long devdepnd2; /* UCB : second device dependent longword */ unsigned long devdepnd3; /* UCB : 3rd device dependent longword */ unsigned long devdepnd4; /* UCB : 4th device dependent longword */ unsigned long hdlbn; /* FCB : lbn of file header */ unsigned long filesize; /* FCB : file size in blocks */ unsigned long imageflags; /* ICB : attribute bitmask (for images only) */ unsigned long matchcontrol; /* ICB : GSMATCH=XXX value (for images only) */ unsigned long majorid; /* ICB : (for images only) */ unsigned long minorid; /* ICB : (for images only) */ unsigned long privs[2]; /* KFE : process privilege mask (for MAIN EXECUTABLE images only) */ unsigned long lspare[20]; unsigned short fid[3]; /* FCB : file identification */ unsigned short revision; /* FCB : file revision */ unsigned short status; /* FCB : file status */ unsigned short acnt; /* FCB : file access count */ unsigned short unit; /* UCB : physical device unit number */ unsigned short devbufsiz; /* UCB : buffer size, in bytes */ unsigned short msgmax; /* UCB : maximum messages allowed (only if devclass == DC$_MAILBOX) */ unsigned short msgcnt; /* UCB : current number of messages (only if devclass == DC$_MAILBOX) */ unsigned short kfemask; /* KFE : bitmask which reflects how the file is INSTALLed */ unsigned short wspare[9]; unsigned char amod; /* CCB : allocation access mode */ unsigned char devclass; /* UCB : a DC$_XXXXX value from */ unsigned char devtype; /* UCB : a DT$_XXXXX value from */ unsigned char access; /* WCB : access control byte */ unsigned char actcode; /* ICB : activation code (for images only) */ unsigned char miscmask; /* this is really a MHMiscMask structure */ unsigned char bspare[39]; char name[15 + 1]; /* DDB : generic path name of device (asciz) */ char node[15 + 1]; /* SB : SCS nodename which "owns" the device (asciz) */ char fulldevname[63 + 1]; /* full device name (asciz) */ char label[12 + 1]; /* VCB : volume label (asciz) */ char imgname[39 + 1]; /* ICB : image name string (asciz) (for images only) */ char tspare[46]; } MHCheapChanInfo; /* even though the file is already open, i cannot find a way to reconstruct * the filespec :-( therefore, i assign a channel and open the file _again_ * with at least one ATR$ request code --- so don't use this structure unless * you _really_ want the filespec. * * the ATTRIBUTE LIST DESCRIPTION module is included solely for the size of the * buffer needed to read the header and the maximum size of the resultant * filespec (we're not dealing with RMS here, so we don't use NAM$C_MAXRSS). * note that the "header" member of this structure is the FILE header, * not the IMAGE header. */ #include typedef struct MYCROFT_EXPENSIVE_CHANNEL_INFO { unsigned long credate[2]; /* creation date */ unsigned long revdate[2]; /* revision date */ unsigned long expdate[2]; /* expiration date */ unsigned long bakdate[2]; /* backup date */ unsigned long uic; /* owner uic */ unsigned long lspare[6]; unsigned short fpro; /* file protection */ unsigned short wspare[6]; unsigned char bspare[22]; char resfs[ATR$S_FILE_SPEC + 1]; /* resultant filespec (asciz) */ char fileheader[ATR$S_HEADER]; /* pure data, NOT asciz! */ char tspare[31]; } MHExpensiveChanInfo; /* the Image Header is read directly into the caller's buffer. this way, * if there's any field in the header which is not nicely formatted for you, * you can do it yourself. note that the "header" member of this structure * is the IMAGE header, not the FILE header. * * i consider this collection of data a "tip" because it does cost resources to * obtain (an extra $qiow to read the block), but that cost pales considering * the effort that just went into assigning a channel, opening the file, and * building the filespec. */ #ifndef IHD$S_IHDDEF #define IHD$S_IHDDEF 512 #endif typedef struct MYCROFT_TIP_CHANNEL_INFO { void *tfradr1; /* first transfer address */ void *tfradr2; /* second transfer address */ void *tfradr3; /* third transfer address */ void *inishr; /* shared image initialization */ unsigned long linktime[2]; /* date and time this image was linked */ unsigned long lspare[6]; unsigned short wspare[6]; unsigned shareable : 1; /* this is a "shareable image", not a "main executable" */ unsigned lnktrace : 1; /* the image was linked /TRACE */ unsigned lnkdebug : 1; /* the image was linked /DEBUG */ unsigned : 5; unsigned char bspare[5]; char imageheader[IHD$S_IHDDEF]; /* pure data, NOT asciz! */ char imgid[15 + 1]; /* image ident name string (asciz) */ char linkid[15 + 1]; /* linker ident name string (asciz) */ char patches[404 + 1]; /* applied ECO numbers in the format 1,2,3,... (asciz) * (9*2 + 90*3 + 29*4 == 404) */ char tspare[9]; } MHTipChanInfo; /* if and are both clear, the entry is just a normal timer. * if is clear, the entry is referred to as a "single shot" request. */ typedef union MYCROFT_TIMER_FLAGS { unsigned char themask; struct { unsigned sssngl : 1; /* system subroutine request */ unsigned wksngl : 1; /* wake entry request */ unsigned repeat : 1; /* repeat request */ unsigned absolute : 1; /* absolute expiration time specified? */ unsigned chk_cputim : 1; /* process CPU time constrained request */ unsigned : 3; /* reserved for future use */ } thebits; } MHTimerFlags; typedef struct MYCROFT_TIMER_INFO { struct MYCROFT_TIMER_INFO *tqfl; /* time queue forward link */ struct MYCROFT_TIMER_INFO *tqbl; /* time queue backward link */ unsigned short size; /* size of tqe in bytes */ unsigned char type; /* structure type for tqe */ unsigned char rqtype; /* time queue entry type (really a MHTimerFlags structure) */ union { unsigned long pid; /* timer or wake request process id */ void *fpc; /* timer subroutine address */ } huh1; union { struct { void *ast; /* address of ast routine */ unsigned long astprm; /* ast parameter */ } zz; #ifdef __ALPHA unsigned long fr3[2]; /* timer subroutine saved r3 */ #else struct { unsigned long fr3; /* timer subroutine saved r3 */ unsigned long fr4; /* timer subroutine saved r4 */ } savedr; #endif } huh2; #ifdef __ALPHA unsigned long fr4[2]; /* timer subroutine saved r4 */ #endif unsigned long time[2]; /* absolute expiration time */ unsigned long delta[2]; /* delta repeat time */ #ifdef __ALPHA unsigned long rmod; /* access mode of request */ unsigned long efn; /* event flag number and event group */ #else unsigned char rmod; /* access mode of request */ unsigned char efn; /* event flag number and event group */ unsigned char spare[2]; #endif unsigned long rqpid; /* requester process id */ unsigned long cputim; /* process CPU time at which entry becomes due */ } MHTimerInfo; /* MYCROFT function prototypes */ extern unsigned long MH_GetChannelInfo( /* w : a VMS condition value, usually SS$_NORMAL */ unsigned long *context, /* m : contents must be zero upon entering loop */ unsigned long pid, /* r : process to be examined (ignored at this time) */ MHCheapChanInfo *cheapptr, /* w : required */ MHExpensiveChanInfo *expenptr, /* w : optional */ MHTipChanInfo *tipptr, /* w : optional */ void *unused /* z : reserved for future use, must be NULL */ ); extern unsigned long MH_GetLockInfo( /* w : condition value */ long efn, /* r : event flag to be used in SYS$GETLKIW() calls */ void *lockid1, /* r : lock to be examined in first SYS$GETLKIW() call */ void *itemlist1, /* r : itemlist to be used in first SYS$GETLKIW() call */ void *lockid2, /* r : lock to be examined in second SYS$GETLKIW() call */ void *itemlist2 /* r : itemlist to be used in second SYS$GETLKIW() call */ ); extern unsigned long MH_GetTimerInfo( /* w : the number of timers found (or copied) */ unsigned long pid, /* r : process to be examined */ int count, /* r : number of array elements available in */ MHTimerInfo *arrayptr /* w : array into which data will be copied */ ); #endif