;*************************************************************************** ; SCAN_LNDB.MAR ; David Schwab ; DEMAX Software, San Mateo, CA ; Demonstration Program for DECUS session on Logical Name Internals. ; Spring 1991 DECUS Symposium. ; This program will print the information contained in each Logical ; Name Block in the user's process private tables and in all shareable ; tables. ; ; Copyright 1991, DEMAX Software, San Mateo, CA. ; ; David Schwab and DEMAX software make no warranty on this software. ; You are free to use it for any purpose except to include it in software ; for resale. Feel free to re-distribute this code, provided this ; informational header is left intact. ; THIS CODE RUNS IN KERNEL MODE. USE AT YOUR OWN RISK!! ; ; To link: LINK READ_LNDB,SCAN_LNDB,SYS$SYSTEM:SYS.STB/SEL,SYS$INPUT/OPT ; SYS$SHARE:VAXCRTL.EXE/SHARE ;*************************************************************************** ;**************************************************************************** ; The kernel mode routine SCAN_LNDB in this module uses context variables ; defined in READ_LNDB.C to keep track of where it is in the logical name ; database. Each time it is called, it moves to the next logical name block ; in the database, first going through the process private hash table and ; then through the system shareable hash table. The context variables should ; all be zero the first time this routine is called. ; ; APOLOGIES: This was a quick and dirty implementation for DECUS. This is ; last minute work and I have not had the time to write this kernel ; mode code as it should be written (for example, exception handlers ; so it won't crash your machine and probe statements to make sure that ; it can access the data pointed to by the context variables. This ; routine does work, but it should be run on a quiescent machine. It ; is possible that modifications to the logical name database between ; calls to this routine might invalidate pointers, causing an access ; violation and the crash of your system. I would not recommend running ; this code, which is for demonstration purposes only to show the ; structure of the logical name data base, on anything but a workstation. ;**************************************************************************** .LIBRARY /SYS$LIBRARY:LIB.MLB/ $IPLDEF $LNMSTRDEF .PSECT DSS$CODE,PIC,USR,CON,REL,LCL,SHR,EXE,NOWRT,RD .ENTRY SCAN_LNDB,^M ; Raise IPL and lock the logical name database for reading. LNM$LOCKR is ; part of the VMS executive, in module LNMSUBS SETIPL #IPL$_ASTDEL JSB G^LNM$LOCKR PUSHL R4 ; Save PCB address ; If LNMHSH is nonzero, then this is not the first call. We simply move the ; context variables into registers. TSTL LNMHSH ; Initialized? BEQL 5$ MOVL LNMHSH,R9 MOVL REMAINING,R10 MOVL BUCKET,R11 MOVL LNMB,R8 ; Next, we move to the next LNMB in the hash bucket, if there is one. If there ; is, we branch to the point where we copy data and return. If there is not ; we branch to the point where we move to the next hash bucket. MOVL LNMB$L_FLINK(R8),R8 BEQL 30$ BRB 60$ ; If we are here, this is the first call to SCAN_LNDB. Initialize to pointe ; to the process hash table. 5$: MOVAL G^LNM$AL_HASHTBL,R0 MOVL @4(R0),R9 ; R9 has address of process hash table ; Calculate the number of buckets in the hash table and point to the first ; bucket. 10$: MOVZWL LNMHSH$W_SIZE(R9),R10 SUBL2 #12,R10 DIVL2 #4,R10 ; R10 has hash buckets remaining MOVAL LNMHSH$C_BUCKET(R9),R11 ; R11 points to hash bucket ; Make sure that the bucket has a non-zero entry. If it does, branch. 20$: TSTL (R11) BNEQ 50$ ; We need to move to the next hash bucket. Increment R11 and decrement the ; count of buckets remaining in R10. If there are buckets remaining, branch ; back above to test the contents. If not, and if the hash table address in ; R9 has the high bit set (so that it is the system table), then we have ; looked at everything, so return. 30$: ADDL2 #4,R11 DECL R10 BNEQ 20$ BBC #31,R9,40$ POPL R4 ; Restore PCB address JSB LNM$UNLOCK ; Unlock the logical name database CLRL R0 ; Clear R0 because we're done RET ; We have branched to this point because we are done with the process hash ; table. Make R9 point to the system hash table and then branch back above ; to get the other initializations right. 40$: MOVAL G^LNM$AL_HASHTBL,R0 MOVL @(R0),R9 BRB 10$ ; We have branched here if the hash bucket contains a non-zero pointer. Move ; that pointer, a LNMB address, to R8 50$: MOVL (R11),R8 ; R8 holds LNMB ; At this point, we have all the pointers correct. Update the context variables ; and copy the LNMB and the LNMB of the table into the buffers. 60$: MOVL LNMB$L_TABLE(R8),R7 MOVL LNMTH$L_NAME(R7),R7 MOVL R9,LNMHSH MOVL R10,REMAINING MOVL R11,BUCKET MOVL R8,LNMB MOVC3 LNMB$W_SIZE(R8),(R8),CUR_LNMB MOVC3 LNMB$W_SIZE(R7),(R7),TAB_LNMB ; Restore the PCB address and unlock the logical name database. POPL R4 JSB G^LNM$UNLOCK MOVL #1,R0 RET .END