#module SHOWIMAGVERS "SRH X1.0-000" #pragma builtins /* ** COPYRIGHT (c) 1992 BY ** DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS. ** ALL RIGHTS RESERVED. ** ** THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ** ONLY IN ACCORDANCE OF THE TERMS OF SUCH LICENSE AND WITH THE ** INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER ** COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY ** OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY ** TRANSFERRED. ** ** THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE ** AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT ** CORPORATION. ** ** DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ** SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. */ /* **++ ** Facility: ** ** Examples ** ** Version: V1.0 ** ** Abstract: ** ** Example of working with the undocumented image header ** via an undocumented library call or two... ** ** Author: ** Steve Hoffman, Digital, XDELTA::HOFFMAN ** ** Creation Date: 1-Jan-1992 ** ** Modification History: **-- */ #include #include #include #include #define XXX$$K_FN_XXX$RTL "IMAGENAME" #define XXX$$K_DN_XXX$RTL "SYS$SHARE:.EXE" #define XXX$$K_FN_XXDRIVER "DRIVERNAME" #define XXX$$K_DN_XXDRIVER "SYS$LOADABLE_IMAGES:.EXE" #define IHD$C_NATIVE -1 #define IHD$W_IMGIDOFF 6 #define IHI$T_IMGID 40 #define IHI$Q_LINKTIME 56 #define IHI$S_LINKTIME 56 xxx$show_version() { /* ** Example main program... */ xxx$$decode_ihd( XXX$$K_FN_XXX$RTL, XXX$$K_DN_XXX$RTL ); xxx$$decode_ihd( XXX$$K_FN_XXDRIVER, XXX$$K_DN_XXDRIVER ); return( SS$_NORMAL ); } /* ** The business end of the program -- looks around in the ** image header... */ xxx$$decode_ihd( img_fn, img_dn ) char *img_fn, *img_dn; { unsigned long int retstat; unsigned long int offset = 12; unsigned long int vbn = 1; struct FAB fab = cc$rms_fab; struct NAM nam = cc$rms_nam; char blk0[ 512 ]; char ihd[ 1024 ]; char *ihi; unsigned long int hdrvers = 2; unsigned long int last_word = 3; struct dsc$descriptor_s asctimbuf; asctimbuf.dsc$w_length = 23; asctimbuf.dsc$b_dtype = DSC$K_DTYPE_T; asctimbuf.dsc$b_class = DSC$K_CLASS_S; asctimbuf.dsc$a_pointer = calloc( 24, 1 ); fab.fab$l_nam = &nam; nam.nam$l_rsa = calloc( nam.nam$b_rss = NAM$C_MAXRSS, 1 ); fab.fab$b_fac = FAB$M_GET; fab.fab$l_fop = FAB$M_UFO | FAB$M_NAM; fab.fab$b_fns = strlen( img_fn ); fab.fab$l_fna = img_fn; fab.fab$b_dns = strlen( img_dn ); fab.fab$l_dna = img_dn; retstat = SYS$OPEN( &fab ); retstat = IMG$DECODE_IHD( fab.fab$l_stv, blk0, ihd, &vbn, &offset, &hdrvers, &last_word ); retstat = SYS$CLOSE( &fab ); if ( last_word != (unsigned short int) IHD$C_NATIVE ) printf( "File: %*s is not a native-mode image.\n", nam.nam$b_rsl, nam.nam$l_rsa ); printf( "File: %*s ", nam.nam$b_rsl, nam.nam$l_rsa ); ihi = ihd + *(short *)((char *)ihd + IHD$W_IMGIDOFF); printf( " ident: %*s\n", (char) ihi[IHI$T_IMGID], &ihi[IHI$T_IMGID+1] ); retstat = SYS$ASCTIM( 0, &asctimbuf, &ihi[IHI$Q_LINKTIME], 0 ); asctimbuf.dsc$a_pointer[23] = 0; printf( " linktime: %23s\n", asctimbuf.dsc$a_pointer ); cfree( asctimbuf.dsc$a_pointer ); cfree( nam.nam$l_rsa ); return( SS$_NORMAL ); } ================================================================================ .Title XXX$CP_SHOWVER_K .Ident /X1.1-000/ ; ; Launched in kernel mode (via a $CMKRNL) to look at device ; driver-specific version information -- used to see *which* ; version of a device driver is actually loaded on a system. ; .Library 'Sys$Library:Lib.Mlb' .Library 'Sys$Library:Starlet.Mlb' .Library 'Sys$Disk:[]XXX$ACP.Mlb' .Link 'Sys$System:Sys.Stb'/Selective_Search .enable debug .disable global $ACBDEF ; AST Control bl*ck $AQBDEF ; ACP Queue bl*ck $DDBDEF ; Device Data bl*ck $DEVDEF ; Device Definitions $DPTDEF ; Driver prologue table $DYNDEF ; Data Structure Definitions $IPLDEF ; Interrupt Priority Level $IRPDEF ; I/O Packet $IRPEDEF ; I/O Packet Extentions $PCBDEF ; Process Control bl*ck $PRDEF ; Processor Registers $PRTDEF ; Protection $PSLDEF ; Processor Status Longword $SSDEF ; System DisServices $STSDEF ; Status Field Definitions $UCBDEF ; Unit Control bl*ck $VCBDEF ; Volume Control bl*ck $XXXACPDEF $XX$DEF ; XXdriver data structures .external BUG$_INCONSTATE ; I/O database error bugcheck .external BUG$_NOTSYSVA ; Invalid address bugcheck .external BUG$_UNXSIGNAL ; Unexpected ACP Signal B/C .external COM$POST ; Post the IRP .external CTL$AL_STACK ; Address of stack pointers .external CTL$AL_STACKLIM ; Address of stack limits .external CTL$GL_PCB ; Address of PCB ;; .external EXE$ALLOCIRP ; get an IRP .external EXE$ALONONPAGED ; get some pool .external EXE$ALTQUEPKT ; queue IRP to driver ALTSTART .external EXE$DEANONPAGED ; Deallocates nonpaged pool .external EXE$DEBIT_BYTCNT_NW ; .external EXE$GL_LOCKRTRY ; Number of times to QRETRY .external EXE$GL_SITESPEC ; .external INI$BRK ; XDELTA breakpoint request .external IOC$GL_AQBLIST ; System AQB list header .external IOC$GL_DPTLIST ; System DPT list header .external IOC$SCAN_IODB ; Traverse the I/O database .external LIB$GET_VM ; Allocates per-process memory .external LIB$GET_VM_PAGE ; Allocates per-process memory .external SCH$IOLOCKR ; Lock I/O database for read .external SCH$IOLOCKW ; Lock I/O database for write .external SCH$IOUNLOCK ; Unlock the I/O database .external SGN$GL_USER3 ; .external SGN$GL_USER4 ; .external SGN$GW_MAXPRCCT ; maximum number of processes .External SMP$ACQUIRE ; .External SMP$RELEASE ; .External SMP$RESTORE ; .external SYS$CMKRNL ; off to kernel mode .external SYS$LKWSET ; lock pages into working-set .external SYS$SETPRT ; set page protections .macro INI$BRK,PHASE= INI_BASE = . .if IDN PHASE, .ift ;JSB g^INI$BRK .endc INI_TOP = . .If EQ .Repeat 6 NOP .EndR .EndC .Endm ;INI$BRK PHASE= ; example of above macro ARGCNT = 0 P1 = 4 P2 = 8 P3 = 12 P4 = 16 .sbttl XXX$CP_SHOWVER_K, ;++ ; CALLS/CALLG Interface. ; ; Environment: ; kernel mode at IPL$_ASTDEL or below. Probably called ; via a call to the SYS$CMKRNL() system service... ; ; Input ; 0(AP) argument count (3) ; 4(AP) address of descriptor of driver name ; 8(AP) address of quadword output buffer for link date ; 12(AP) address of descriptor of output buffer for ident info ; (currently must be exactly eight characters in length) ; ; Output ; R0 SS$_ACCVIO, SS$_NOSUCHDEV, SS$_BADPARAM, SS$_NORMAL ; R1 trashed per the calling standard ; ;-- .Psect ATKcode,pic,usr,con,rel,lcl,shr,exe,rd,nowrt,novec,long .align LONG .Entry XXX$CP_SHOWVER_K,^M JSB G^INI$BRK ; MOVZWL #SS$_BADPARAM,R0 ; pessimistic status code CMPB #3,ARGCNT(AP) ; get the argument count right, plz BNEQ 50$ ; oh, well. MOVL P1(AP),R1 ; driver name descriptor JSB G^EXE$PROBER_DSC ; ; output: R0 LBS ok, LBC punt; R1/R2 probed descriptor BLBC R0,50$ ; MOVQ R1,R7 ; MOVL P2(AP),R0 ; linktime buffer address MOVZBL #8,R1 ; linktime buf is a quadword MOVZBL #PSL$C_USER,R3 ; the mode to probe JSB G^EXE$PROBEW ; BLBC R0,50$ ; branch on failure MOVL P2(AP),R1 ; ident buffer descriptor address JSB G^EXE$PROBEW_DSC ; ; output: R0 LBS ok, LBC punt; R1/R2 probed descriptor BLBC R0,50$ ; branch on error CMPW #8,R1 ; force the size BNEQ 50$ ; branch on error MOVL R2,R9 ; store the ident descriptor buffer BRB 90$ ; ...and continue 50$: RET ; 90$: ; Let's go look for a DPT entry with a matching driver name ; LOCK_SYSTEM_PAGES, ENDVA=800$ MOVL G^CTL$GL_PCB,R4 ; JSB G^IOC$IOLOCKR ; lock the I/O database MOVL G^IOC$GL_DPTLIST,R6 ; go looking for matching DPT 100$: CMPC5 DSC$W_LENGTH(R7),- ; driver names match? DSC$A_POINTER(R7),- ; #0,- ; DPT$T_NAME(R6),- ; DPT$T_NAME+1(R6) ; BEQL 400$ ; yep, branch on match MOVL DPT$L_FLINK(R6),R6 ; nope, get next entry CMPL G^IOC$GL_DPTLIST,R6 ; back where we started? BNEQ 100$ ; branch if not done MOVZWL #SS$_NOSUCHDEV,R10 ; assume failure BRB 700$ ; punt 400$: MOVL P2(AP),R7 ; MOVQ DPT$Q_LINKTIME(R6),(R7) ; ; now go looking for a DDB/UCB with a matching driver name MOVL G^IOC$GL_DEVLIST,R6 ; now go looking for matching DDB ASSUME DDB$L_LINK, EQ, 0 ; so the next line doesn't break... 500$: MOVL DDB$L_LINK(R6),R6 ; get the next DDB BEQL 700$ ; branch if done BGTR 900$ ; branch if address hosed CMPC5 DSC$W_LENGTH(R7),- ; driver names match? DSC$A_POINTER(R7),- ; #0,- ; DDB$T_DRVNAME(R6),- ; DDB$T_DRVNAME+1(R6) ; BNEQ 500$ ; if no match, branch and try again MOVL DDB$L_UCB(R6),R6 ; get UCB address from matched DDB BEQL 500$ ; whoops, no UCB here. Try next DDB. BGTR 900$ ; branch if next-UCB address hosed MOVQ UCB$Q_XX_XXIDENT(R6),- ; store the image ident field (R9) ; MOVZBL #SS$_NORMAL,R10 ; 700$: JSB G^IOC$IOUNLOCK ; unlock the I/O database ; UNLOCK_SYSTEM_PAGES ; 800$: MOVL R10,R0 ; (re)load final status RET ; 900$: ; We're in kernel and we found a problem. Throw a snit. BUG_CHECK - ; INCONSTATE,FATAL ; HALT ; .End