[comp.os.vms] Found: Getting identification information from .EXE file

nagy%43198.hepnet%lbl.arpa@LBL.ARPA (04/27/87)

Thanks to everyone who responded to my query about reading the image
identication from the .EXE file.  My memory got prompted and I found
the code in the Languages&Tools section of the most recent DECUS SIG
Newsletter.

Accordingly, I have written a small procedure from the example code
in the article and include the source for that procedure here.  The
version I have written is adapted for use from VAX C at this time
(the strings are returned by reference and are terminated by NUL
characters).
-----------------------------cut here---------------------------------------
	.TITLE	ElibExeIdent  Read image identification and link time
	.IDENT	/V1.0/

; EXEIDENT.MAR
;
; *********************************************************************
; *********************************************************************
; ****								   **** 
; ****								   **** 
; ****	      	EPICURE Beamline Control System			   **** 
; ****		Copyright (c) Fermilab, 1987			   **** 
; ****								   **** 
; ****		Extended Run-Time Library Routine	           **** 
; ****								   **** 
; ****								   **** 
; *********************************************************************
; *********************************************************************
;
; Function Description:
;   This routine returns the image identification and link time from the
;   image header of the .EXE file.
;
; Environment:
;   Normal user-mode.  WARNING: depends on definition of CTL$GL_IMGHDRBF
;   global label which MAY change with a new major version of VMS.
;
; Published Information:
;   DECUS U.S. Chapter SIGs NewsLetters, Languages and Tools SIG
;   April 1987  Volume 2, Number 8
;   "Reading a Program Version Number from the Image Header"
;   John Miano, Berlex Laboratories, Inc.
;
;   See also:	VAX/VMS Linker Reference Manual
;		sec. 2.3 Link Options under IDENTIFICATION=id-name
;
; Change Requests:
;======================================================================
; Author: Frank J. Nagy		Fermilab Research Division EED/Controls
; Modification History:
;
; V1.0	27-Apr-87  FJN	Created from sample code in the L&T article
;

	.SUBTITLE	Declarations

;
; Include Files:
;
	.LIBRARY  "SYS$LIBRARY:LIB.MLB"
	.LINK	"SYS$SYSTEM:SYS.STB" /SELECTIVE_SEARCH
;
; Library Macros:
;
	.NOCROSS
	$DSCDEF				;Descriptor definitions
	$IHDDEF				;Image header definitions
	$IHIDEF				;Image identification defs.
	.CROSS
;
; Local Macros:
;
;	None
;
; Equated Symbols:
;
time_length = 23			;Length of complete date/time string

	.EXTERNAL  CTL$GL_IMGHDRBF
;
; Program section for code
;
	.PSECT	_ELIB_CODE,PIC,USR,CON,REL,LCL,SHR,EXE,NOWRT,RD
	.SHOW	BINARY


	.SUBTITLE  Module code

;+ elib_exe_ident
; \subnam
;  elib_exe_ident
; \subcal
;  elib_exe_ident( [idstr] [,timstr] [,namstr] )
; \subtxt
;  This routine extracts identification information from the image header
;  of the current image.  The image header is found in the buffer in P1 space
;  pointed to by the longword at CTL$GL_IMGHDRBF.  This symbol is defined
;  in the system symbol table (SYS$SYSTEM:SYS.STB) and the linker will
;  automatically be told to search this table.  Because of the dependence
;  on this symbol, this routine might cause programs to break with a new
;  major release of VMS.  However, all that should be required is to relink
;  the program under to new release of VMS.
; \arglist
;  \argn   idstr  pointer to char string to optionally return the image
;		identification text (can be set with the Linker's
;		IDENTIFICATION option).  For executable images, the
;		image id froms from the id of the object module that
;		contains the main entry point for the image.
;  \argn   timstr pointer to char string to optionally return, as ASCII text,
;		the date and time the image was linked.
;  \argn   namstr pointer to char string to optionally return the image name.
; \arglend
;-

	.ENTRY	Elib_Exe_Ident,^M<R2,R3,R4,R5,R6>
;
; Make sure we have at something to do...
;
	TSTL	(AP)
	BEQL	99$			;BR if no arguments...
;
; Get address of image header ID block...
;
	MOVL	G^CTL$GL_IMGHDRBF,R0	;Address of image buffer
	MOVL	(R0),R0			;Address of image header
	CVTWL	IHD$W_IMGIDOFF(R0),R6	;Offset to ID block
	MOVAB	(R0)[R6],R6		;Address of ID block
;
; Return the image identification, if desired.
;
	TSTL	1*4(AP)			;Check for argument #1
	BEQL	19$			;BR if image ident not wanted
	MOVAB	IHI$T_IMGID(R6),R0	;Get pointer to ID string (ASCIC)
	MOVZBL	(R0)+,R1		;Get string length and text pointer
	MOVC3	R1,(R0),@1*4(AP)	;Move ID text
	CLRB	(R3)			;Add NUL terminator after dest. text
19$:
;
; Return the image link time (converted to ASCII).
;
	CMPL	(AP),#2			;Check for 2nd (or 3rd) arguments
	BLSSU	99$			;Exit if none
	MOVL	2*4(AP),-(SP)		;Get string pointer, argument #2
	BEQL	29$			;BR if link time not wanted
	MOVB	#DSC$K_CLASS_S,-(SP)	;Set static descriptor class
	MOVB	#DSC$K_DTYPE_T,-(SP)	;Set text descriptor type
	MOVW	#time_length,-(SP)	;Set length for ASCII time string
	MOVL	SP,R5			;Save pointer to descriptor
	$ASCTIM_S  timbuf=(R5), timadr=IHI$Q_LINKTIME(R6), timlen=(R5)
	MOVZWL	(R5),R5			;Get length of destination string
	BLBS	R0,20$			;Check for success from $ASCTIM
	CLRL	R5			;If failure, write empty string
20$:	CLRB	@2*4(AP)[R5]		;Add NUL terminator to string
29$:
;
; Return the image identification, if desired.
;
	CMPL	(AP),#3			;Check for 3rd argument
	BLSSU	99$			;Exit if none
	TSTL	3*4(AP)			;Check for argument #3
	BEQL	39$			;BR if image name not wanted
	MOVAB	IHI$T_IMGNAM(R6),R0	;Get pointer to name string (ASCIC)
	MOVZBL	(R0)+,R1		;Get string length and text pointer
	MOVC3	R1,(R0),@3*4(AP)	;Move image name text
	CLRB	(R3)			;Add NUL terminator after dest. text
39$:
;
99$:	RET

	.END

tedcrane@batcomputer.UUCP (04/29/87)

In article <8704281243.AA18094@ucbvax.Berkeley.EDU> nagy%43198.hepnet%lbl.arpa@LBL.ARPA writes:
>	MOVAB	IHI$T_IMGID(R6),R0	;Get pointer to ID string (ASCIC)
>	MOVZBL	(R0)+,R1		;Get string length and text pointer
>	MOVC3	R1,(R0),@1*4(AP)	;Move ID text
>	CLRB	(R3)			;Add NUL terminator after dest. text

Please note that that string copy (and the others for the 2nd and 3rd args)
have the potential to overwrite data in the calling routine.  There is no
check to compare the length of the resultant string to the size of the
buffer which will receive it.

Since this is intended for use w/ C, might it be better to call the
C RTL routine "strcpy" to do the work?