##module SHOWIMAGVERS "SRH X1.0-000"#pragma builtins/*** COPYRIGHT (c) 1992 BY9** DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS.** ALL RIGHTS RESERVED.**H** THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIEDH** ONLY IN ACCORDANCE OF THE TERMS OF SUCH LICENSE AND WITH THEH** INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHERH** COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANYH** OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY** TRANSFERRED.**H** THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICEH** AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT** CORPORATION.**H** 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"6#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 56xxx$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(A fab.fab$l_stv, blk0, ihd, &vbn, &offset, &hdrvers, &last_word ); retstat = SYS$CLOSE( &fab );9 if ( last_word != (unsigned short int) IHD$C_NATIVE )3 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 );9 ihi = ihd + *(short *)((char *)ihd + IHD$W_IMGIDOFF); printf( " ident: %*s\n",4 (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 ); }P================================================================================ .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'0 .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 bugcheck6 .external BUG$_NOTSYSVA ; Invalid address bugcheck8 .external BUG$_UNXSIGNAL ; Unexpected ACP Signal B/C& .external COM$POST ; Post the IRP6 .external CTL$AL_STACK ; Address of stack pointers7 .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 ALTSTART9 .external EXE$DEANONPAGED ; Deallocates nonpaged pool# .external EXE$DEBIT_BYTCNT_NW ;9 .external EXE$GL_LOCKRTRY ; Number of times to QRETRY .external EXE$GL_SITESPEC ;2 .external INI$BRK ; XDELTA breakpoint request5 .external IOC$GL_AQBLIST ; System AQB list header5 .external IOC$GL_DPTLIST ; System DPT list header7 .external IOC$SCAN_IODB ; Traverse the I/O database8 .external LIB$GET_VM ; Allocates per-process memory< .external LIB$GET_VM_PAGE ; Allocates per-process memory7 .external SCH$IOLOCKR ; Lock I/O database for read8 .external SCH$IOLOCKW ; Lock I/O database for write4 .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 mode7 .external SYS$LKWSET ; lock pages into working-set0 .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  .Endm6 ;INI$BRK PHASE= ; example of above macro ARGCNT = 0P1 = 4P2 = 8P3 = 12P4 = 16 .sbttl XXX$CP_SHOWVER_K,;++; CALLS/CALLG Interface.;; Environment:A; kernel mode at IPL$_ASTDEL or below. Probably called<; via a call to the SYS$CMKRNL() system service...; ; Input; 0(AP) argument count (3)0; 4(AP) address of descriptor of driver name;; 8(AP) address of quadword output buffer for link dateA; 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 ;2 MOVZWL #SS$_BADPARAM,R0 ; pessimistic status code8 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 ;7 ; 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 failure2 MOVL P2(AP),R1 ; ident buffer descriptor address JSB G^EXE$PROBEW_DSC ;7 ; 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 error1 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 database7 MOVL G^IOC$GL_DPTLIST,R6 ; go looking for matching DPT4100$: 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 entry2 CMPL G^IOC$GL_DPTLIST,R6 ; back where we started?! BNEQ 100$ ; branch if not done+ MOVZWL #SS$_NOSUCHDEV,R10 ; assume failure BRB 700$ ; punt400$: 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) ;0 BNEQ 500$ ; if no match, branch and try again9 MOVL DDB$L_UCB(R6),R6 ; get UCB address from matched DDB2 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 ;3700$: JSB G^IOC$IOUNLOCK ; unlock the I/O database; UNLOCK_SYSTEM_PAGES ;+800$: MOVL R10,R0 ; (re)load final status RET ;900$:9 ; We're in kernel and we found a problem. Throw a snit. BUG_CHECK - ; INCONSTATE,FATAL ; HALT ; .End ÿÿ