X-NEWS: acfclu vmsnet.sources: 459 Xref: cmcl2 comp.os.vms:114570 vmsnet.sources:459 Path: cmcl2!hsdndev!wuarchive!gumby!peirce From: peirce@gumby.cc.wmich.edu (Leonard Peirce) Newsgroups: comp.os.vms,vmsnet.sources Subject: VALIDATE_TT_VEC -- see if WATCH is running on a system (part 1 of 1) Message-ID: <1991Mar8.234357.3777@gumby.cc.wmich.edu> Date: 8 Mar 91 23:43:57 GMT Organization: Western Michigan University Academic Computing Services Lines: 829 NOTE: I am posting this for a friend. I didn't write it and I haven't tested it yet (see warning in following paragraph) so USE IT AT YOUR OWN RISK. I've included a small BUILD.COM to help build it but you're on your own if you use it. BE AWARE THAT, AS IS, THIS PROGRAM CAN CRASH YOUR SYSTEM. Actually, it was originally designed that way (see note from author below). If you want to use it, you should modify the code that forces the bugcheck and change it to something less deadly. A message to the console might be a nice idea. Other ideas and subsequent coding are left as an exercise for the user. ;-} To build it, run the BUILD.COM to create VALIDATE_TT_VEC.EXE. Again, there is no documentation included other than the source. -- Leonard Peirce Internet: peirce@gumby.cc.wmich.edu Western Michigan University peirce@gw.wmich.edu Academic Computing Services UUCP: ...!uunet!sharkey!wmichgw!peirce Kalamazoo, MI 49008 Phone: (616) 387-5469 ================================================================================== The attached code was written to detect if a terminal had the port and class vectors replaced. It was originally written to detect if the WATCH program was being used on a workstation to break into a cluster. If it detects that the vectors have been replaced it crashes the system. Before running it on anything but a standalone system I would strongly suggest changing this to something less severe. It will allow the TFF code, and the TDSMP code to work and will allow you to add other similar device drivers to the list of approved mid drivers. Forrest $! ------------------ CUT HERE ----------------------- $ v='f$verify(f$trnlnm("SHARE_VERIFY"))' $! $! This archive created by VMS_SHARE Version 7.2-007 22-FEB-1990 $! On 8-MAR-1991 17:59:23.06 By user PEIRCE $! $! This VMS_SHARE Written by: $! Andy Harper, Kings College London UK $! $! Acknowledgements to: $! James Gray - Original VMS_SHARE $! Michael Bednarek - Original Concept and implementation $! $! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER $! AND EXECUTE AS A COMMAND PROCEDURE ( @name ) $! $! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING: $! 1. BUILD.COM;10 $! 2. VALIDATE_TT_VEC.C;2 $! 3. VALIDATE_VEC.MAR;2 $! $set="set" $set symbol/scope=(nolocal,noglobal) $f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID")) $e="write sys$error ""%UNPACK"", " $w="write sys$output ""%UNPACK"", " $ if f$trnlnm("SHARE_LOG") then $ w = "!" $ ve=f$getsyi("version") $ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START $ e "-E-OLDVER, Must run at least VMS 4.4" $ v=f$verify(v) $ exit 44 $UNPACK: SUBROUTINE ! P1=filename, P2=checksum $ if f$search(P1) .eqs. "" then $ goto file_absent $ e "-W-EXISTS, File ''P1' exists. Skipped." $ delete 'f'* $ exit $file_absent: $ if f$parse(P1) .nes. "" then $ goto dirok $ dn=f$parse(P1,,,"DIRECTORY") $ w "-I-CREDIR, Creating directory ''dn'." $ create/dir 'dn' $ if $status then $ goto dirok $ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped." $ delete 'f'* $ exit $dirok: $ w "-I-PROCESS, Processing file ''P1'." $ if .not. f$verify() then $ define/user sys$output nl: $ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1' PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET( SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:= CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b)); LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION( BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1); IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE; MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1; ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")= 1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF"; POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r); ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1; COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE, "output_file"));ENDPROCEDURE;Unpacker;QUIT; $ delete/nolog 'f'* $ CHECKSUM 'P1' $ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT $ e "-E-CHKSMFAIL, Checksum of ''P1' failed." $ ENDSUBROUTINE $START: $ create 'f' X$ CC VALIDATE_TT_VEC.C X$ MACRO VALIDATE_VEC.MAR X$ LINK VALIDATE_TT_VEC,VALIDATE_VEC,SYS$SYSTEM:SYS.STB/SELECT,SYS$INPUT:/OPT XSYS$SHARE:VAXCRTL/SHARE X$ exit $ CALL UNPACK BUILD.COM;10 1229983894 $ create 'f' X/* X ++ XFACILITY: X`20 X `09VALIDATE_TT_VEC X`20 XABSTRACT: X`20 X `09This program will build and load a piece of code into nonpaged pool that Xverifies that the terminal pointers in TT UCB's are still valid. The progra Vm`20 Xwill crash the system with a TTDRVR1 bugcheck if an invalid set of pointers V are Xfound. The program comes with a list of two acceptable terminal MID drivers V,`20 Xand allows the user to add more. The program requires that all MID drivers V be Xloaded before it is run. Failure to do so will result in an error and the u Vser Xwill be given to opportunity to exit the program. An additional capability V has Xbeen added that allows the verification to be disabled. The only valid reas Von to`20 Xdo this would be to add another MID driver to the list. To use this program V a`20 Xuser must have CMKRNL priviledge, and PSWAPM priv. X`20 XAUTHOR: X`20 X `09F. Kenney`09`0912-December-1988 X`20 XRevision history: X`20 X `09X-XX`09XXXnnn`09`09Xxxxxxx X. Xxxxxx`09DD-MMMMMMM-YYYY X `09`09Explain change X`20 X-- X*/ X`0C X/* Constant definitions */ X X#define`09`09DRIVER_TABLE_LEN`0912 X#define`09`09DRIVER_NAME_LEN `0912 X X X/* Included files */ X X#include`09ctype X#include`09ssdef X#include`09stdio X X X/* Global variables */ Xchar`09`09driver_names`5BDRIVER_TABLE_LEN`5D`5BDRIVER_NAME_LEN+1`5D; X X Xshort int`09driver_name_lens`5BDRIVER_TABLE_LEN`5D; X Xint`09`09driver_entries; X Xstruct X`7B Xint`09`09start; Xint`09`09end; X`7D`09driver_table`5BDRIVER_TABLE_LEN`5D; X X`0C X/* Main program */ Xvalidate_tt_vec() X`7B Xchar`09`09resp; Xchar`09`09trash; X Xint`09`09*disable_tt_watching(); Xint`09`09*enable_tt_watching(); Xint`09`09get_driver_names(); Xint`09`09lock_code();`20 Xint`09`09status; X Xstruct X`7B Xshort int`09num_args; Xshort int`09unused;`20 Xint`09`09num_entries; Xint`09`09*driver_table; X`7D`09arglist = `7B2, 0, 0, &driver_table`5B0`5D`7D; X X Xstatus = lock_code(); Xif ((status & SS$_NORMAL) != SS$_NORMAL) LIB$SIGNAL(status); X X X/* Fill in known driver names and figure out what to do */ Xdo X`7B X driver_name_lens`5B0`5D = (short int)sprintf(&driver_names`5B0`5D`5B0`5D, V"%s", "FBDRIVER"); X driver_name_lens`5B1`5D = (short int)sprintf(&driver_names`5B1`5D`5B0`5D, V"%s", "TDDRIVER"); X X driver_entries = 2; X printf("\n\n\nEnter E to enable, D to diable TT vector checking, or CTRL- VZ to exit: "); X status = scanf("%c", &resp); X X if (status != EOF) X `7B X do X `7B X`09 trash = (char)getchar(); X `7D while (trash != '\n'); X X resp = _toupper(resp); X if (resp == 'E') X `7B X`09 status = get_driver_names(); X if (status & 1)`20 X `7B X`09 arglist.num_entries = driver_entries; X`09 status = SYS$CMKRNL(&enable_tt_watching, &arglist); X`09 if (status == SS$_DEVACTIVE) X`09 `7B X`09 printf("\nYou must disable the current watching code before enablin Vg new watching code.\n"); X`09 `7D X else if ((status & SS$_NORMAL) != SS$_NORMAL) LIB$SIGNAL(status) V; X `7D X `7D X else if (resp == 'D')`20 X `7B X`09 status = SYS$CMKRNL(&disable_tt_watching, 0); X`09 if (status == SS$_NOTINSTALL) X`09 `7B X`09 printf("\nTT Watching code is not enabled...\n"); X`09 `7D X else if ((status & SS$_NORMAL) != SS$_NORMAL) LIB$SIGNAL(status); X `7D X else X `7B X`09 printf("\nIllegal command try again!\n"); X `7D `20 X `7D X`7D while (!feof(stdin)); X Xprintf("\nUser requested EXIT!."); Xreturn(1); X X`7D X`0C X/* Get an additional MID driver names and build fill in "driver_table" */ Xint get_driver_names() X`7B Xchar`09`09buffer`5BDRIVER_NAME_LEN`5D; Xchar`09`09resp; Xchar`09`09trash; X Xint`09`09actual_driver_entries = 0; Xint`09`09*get_driver_addresses(); Xint`09`09i; Xint`09`09status; X Xstruct X`7B Xshort int`09arg_count; Xshort int`09unused; Xint`09`09entries; Xint`09`09*names; Xint`09`09*lens; Xint`09`09*table; X`7D`09arglist = `7B4, 0, 0, &driver_names`5B0`5D`5B0`5D, &driver_name_lens`5 VB0`5D, &driver_table`5B0`5D`7D; X X X/* Print out provided MID driver names */ Xprintf("\n\nThe following MID drivers are provided:\n"); Xfor (i=0; i to end list): ") V; X for (i=0; i PCB X;-- X X`09.ENTRY`09GET_DRIVER_ADDRESSES, -`09; Save registers used by routine X`09`09`5EM`09`09; X`09PUSHL`09R4`09`09`09; Save PCB address X`09JSB`09G`5ESCH$IOLOCKW`09`09; Lock the I/O database for write access X`09MOVL`09P2(AP),R4`09`09; Get count of entries X`09MOVL`09P3(AP),R5`09`09; Get address of strings X`09MOVL`09P4(AP),R6`09`09; Get address of name string X`09MOVL`09P5(AP),R7`09`09; Get address of driver table X`09MOVAL`09G`5EIOC$GL_DPTLIST,R8`09; Get DPT list head address X10$: X`09MOVL`09(R8),R9`09`09`09; Get first element X20$: X`09CMPC3`09(R6),(R5),`09-`09; Compare names X`09`09DPT$T_NAME+1(R9)`09; X`09BEQL`0930$`09`09`09; EQL go compute addresses X`09MOVL`09(R9),R9`09`09`09; Find next entry X`09CMPL`09(R9),R8`09`09`09; See if list done X`09BNEQ`0920$`09`09`09; Try next entry X`09CLRW`09(R6)+`09`09`09; Signal no driver of this name X`09ADDL`09#DRIVER_NAME_LEN,R5`09; Point to next driver name X`09SOBGTR`09R4,10$`09`09`09; See if another driver to look for X`09BRB`0940$`09`09`09; Exit X30$: X`09MOVL`09R9,(R7)+`09`09; Store starting Address X`09CVTWL`09DPT$W_SIZE(R9),R2`09; Get driver length X`09ADDL3`09R2,R9,(R7)+`09`09; Compute ending address X`09ADDL`09#2,R6`09`09`09; Point to next string length X`09ADDL`09#DRIVER_NAME_LEN,R5`09; Point to next string X`09SOBGTR`09R4,10$`09`09`09; See if another driver to look for X40$: X`09POPL`09R4 X`09JSB`09G`5ESCH$IOUNLOCK`09`09; Unlock I/O database X`09MOVL`09#SS$_NORMAL,R0`09`09; Signal success X`09RET X`0C X`09.SBTTL`09LOCK_CODE - Lock HIGH IPL code into memory X;++ X; LOCK_CODE - Lock the code that needs to run at IPL 8 into memory X; X; FUNCTIONAL DESCRIPTION: X; X;`09This routine will lock the enable_tt_watching, diable_tt_watching, X; and validate_vec routines into memory. This is necessary to prevent a`20 X; pagefault at high IPL crash. X; X; INPUTS: X; X;`09None X; X; OUTPUTS: X; X;`09None X; X; IMPLICIT INPUTS: X; X;`09Starting address to be locked down X;`09Ending address to be locked down X; X;-- X`09.ENTRY`09LOCK_CODE,`5EM<> X`09PUSHAL`09LOCK_END`09`09; Ending address lock down X`09PUSHAL`09LOCK_BEGIN`09`09; Stating address to lock down X`09MOVL`09SP,R0`09`09`09; Save addresses used X`09CLRQ`09-(SP)`09`09`09; Clear off top of stack X`09PUSHL`09R0`09`09`09; Pointer to pages to lock down X`09CALLS`09#3,G`5ESYS$LCKPAG`09`09; Lock pages down X`09RET X`0C X`09.SBTTL`09ENABLE_TT_WATCHING - Put in place watching code X;++ X; ENABLE_TT_WATCHING - Place code in place to prevent terminal watching X; X;FUNCTIONAL DESCRIPTION: X; X;`09This routine will load a piece of code into pool that prevents X; MID drivers and MID driver like code from working. It works by replacing X; the STARTIO pointer in the DDT. This routine will first check that`20 X; a copy of itself is not already loaded. While having two copies in`20 X; place is not fatal it is dumb. `20 X; X; INPUTS: X; X;`09P1(AP)`09- Number arguments not used X;`09P2(AP)`09- Number of entries in MID driver table X;`09P3(AP) - Address of MID driver table X; X; OUTPUTS: X; X;`09R0`09- SS$_NORMAL all worked ok X;`09`09 SS$_DEVACTIVE watching already active X; X; NOTES: X;`09This code assumes that all users of TTDRIVER use IO_LOCK8 X;`09for forking. X; X;-- X`09.PSECT`09LOCK_CODE`09PAGE,RD,NOWRT,EXE,PIC XLOCK_BEGIN: X X X`09.ENTRY`09ENABLE_TT_WATCHING, -`09; Entry mask`20 X`09`09`5EM`09`09; X`09MOVL`09#TABLE_SIZE,R0`09`09; Store size of table of alternate drivers X`09MOVAL`09TABLE,R2`09`09; Get address of loaded MID driver tables X10$: X`09CLRQ`09(R2)+`09`09`09; Zero the entries X`09SOBGTR`09R0,10$`09`09`09; Loop until table is zeroed X`09MOVL`09P2(AP),R0`09`09; Get number of entries in user table X`09BEQL`0930$`09`09`09; EQL no table entries X`09MOVL`09P3(AP),R1`09`09; Get address of users MID driver table X`09BEQL`0930$`09`09`09; Programmers error no use table X`09MOVAL`09TABLE,R2`09`09; Get address of STATIC table X20$: X`09MOVQ`09(R1)+,(R2)+`09`09; Move user table to static table X`09SOBGTR`09R0,20$`09`09`09; Loop until done X30$: X`09MOVL`09G`5ETTY$GL_DPT,R1`09`09; Get TTDRIVER DPT address X`09CVTWL`09DPT$W_VECTOR(R1),R0`09; Get VECTOR offset X`09ADDL3`09R0,R1,R2`09`09; Compute TABLE offset X`09MOVL`09R2,CLASS_VEC`09`09; Fill in class vector offset X`09MOVL`09CLASS_GETNXT(R2),GETNXT`09; Fill in class GETNXT routine address X`09MOVL`09CLASS_PUTNXT(R2),PUTNXT`09; Fill in class PUTNXT routine address X`09MOVL`09CLASS_DDT(R2),R3`09; Get DDT address X;+ X; This code must be done whild holding the FORKLOCK to prevent any changes X; while we are fiddeling around. X;- X`09FORKLOCK LOCK=#SPL$C_IOLOCK8, -`09; Take I/O lock 8 X`09`09LOCKIPL=#IPL$_IOLOCK8,-`09;`20 X`09`09SAVIPL=-(SP),`09-`09; X`09`09PRESERVE=NO`09`09; X`09CMPL`09DDT$L_START(R3),R2`09; See if start address is after DDT X`09BLSSU`0940$`09`09`09; LSS error exit X`09CVTWL`09DPT$W_SIZE(R1),R0`09; Get Driver size X`09ADDL`09R0,R1`09`09`09; Compute end of driver address X`09CMPL`09DDT$L_START(R3),R1`09; Is start address before end of driver X`09BGTRU`0940$`09`09`09; GTR error exit X`09MOVL`09DDT$L_START(R3),STARTIO`09; Store TTDRIVER STARTIO address X`09MOVL`09#LOAD_LEN,R1`09`09; Size of loaded code X`09JSB`09G`5EEXE$ALONPAGVAR`09; Allocate block of memory to hold loaded code X`09BLBC`09R0,50$`09`09`09; LBC signal error X`09PUSHR`09#`5EM`09; Save registes we care about X`09MOVL`09R1,LOAD_SIZE`09`09; Save size of block allocated X`09MOVC3`09#LOAD_LEN,LOAD_START, -`09; Move code into block X`09`09(R2)`09`09`09; X`09POPR`09#`5EM`09; Restore registers X`09ADDL3`09#NEW_STARTIO_OFFSET, -`09; Store new STARTIO address in DDT X`09`09R2,DDT$L_START(R3)`09; X`09FORKUNLOCK `09`09-`09; Release I/O lock 8 X`09`09LOCK=#SPL$C_IOLOCK8, -`09; X`09`09NEWIPL=(SP)+,`09-`09; X`09`09CONDITION=RESTORE, -`09; X`09`09PRESERVE=NO`09`09;`20 X`09MOVZWL`09#SS$_NORMAL,R0`09`09; Signal success X`09RET X X40$: X`09MOVZWL`09#SS$_DEVACTIVE,R0`09; Signal that watching is already active X50$: X`09FORKUNLOCK `09`09-`09; Release I/O lock 8 X`09`09LOCK=#SPL$C_IOLOCK8, -`09; X`09`09NEWIPL=(SP)+,`09-`09; X`09`09CONDITION=RESTORE, -`09; X`09`09PRESERVE=YES`09`09;`20 X`09RET X`0C X`09.SBTTL`09DISABLE_TT_WATCHING - Remove watching code from STARTIO path X;++ X; DISABLE_TT_WATCHING - Remove watching code from STARTIO path X; X; FUNCTIONAL DESCRIPTION: X; X;`09This routine will examine the the STARTIO address to see if it points to X; the TTDRIVER. If the STARTIO address in the DDT is not inside the driver V then X; additional checks will be made. If it is detemined that the TT vector X; validation code is loaded it will be removed. X; X; INPUTS: X; X;`09None X; X; OUTPUTS: X; X;`09R0 - SS$_NORMAL removed watching code X;`09 - SS$_NOTINSTALL watching code not enables this could occur for X;`09 a number of reasons. X; X; IMPLICIT INPUTS: X; X;`09None X; X; NOTE: X;`09This code assumes that all users of the terminal driver use IO_LOCK8`20 X;`09for forking. `20 X; X;-- X`09.ENTRY`09DISABLE_TT_WATCHING, -`09; X`09`09`5EM`09`09; X`09MOVL`09G`5ETTY$GL_DPT,R1`09`09; Get DPT address X`09CVTWL`09DPT$W_VECTOR(R1),R2`09; Get the VECTOR size X`09ADDL`09R1,R2`09`09`09; Get vector address X`09MOVL`09CLASS_DDT(R2),R6`09; Get DDT address X`09CVTWL`09DPT$W_SIZE(R1),R2`09; Get driver size X`09ADDL`09R1,R2`09`09`09; Compute driver ending address X;+ X; We need to block out access to TTDRIVER DDT, use FORKLOCK to do this X;- X`09FORKLOCK LOCK=#SPL$C_IOLOCK8, -`09; Take I/O lock 8 X`09`09LOCKIPL=#IPL$_IOLOCK8,-`09;`20 X`09`09SAVIPL=-(SP),`09-`09; X`09`09PRESERVE=NO`09`09; X`09CMPL`09DDT$L_START(R6),R1`09; Is STARTIO inside TTDRIVER X`09BLSS`0920$`09`09`09; LSS no assume watching enabled X`09CMPL`09DDT$L_START(R6),R2`09;`20 X`09BGTR`0920$`09`09`09; GTR no assume watching enabled X10$: X`09FORKUNLOCK `09`09-`09; Release I/O lock 8 X`09`09LOCK=#SPL$C_IOLOCK8, -`09; X`09`09NEWIPL=(SP)+,`09-`09; X`09`09CONDITION=RESTORE, -`09; X`09`09PRESERVE=NO`09`09;`20 X`09MOVZWL`09#SS$_NOTINSTALL,R0`09; Signal not able to disable X`09RET X X;+ X; STARTIO points outside of TTDRIVER see if it points to our code. If not X; signal inability to disable. Otherwise remove it. X;- X20$: X`09MOVL`09DDT$L_START(R6),R5`09; Get STARTIO address X`09CMPC3`09#LOAD_CODE_LEN,`09-`09; Compare loaded code against expected X`09`09VALIDATE_VEC,(R5)`09; code X`09BNEQ`0910$`09`09`09; NEQ cannot match exit X`09SUBL3`09#SAVED_STARTIO_LOC, -`09; Find location of saved STARTIO routine X`09`09R5,R0`09`09`09;`20 X`09MOVL`09(R0),DDT$L_START(R6)`09; Restore STARTIO address X`09FORKUNLOCK `09`09-`09; Release I/O lock 8 X`09`09LOCK=#SPL$C_IOLOCK8, -`09; X`09`09NEWIPL=(SP)+,`09-`09; X`09`09CONDITION=RESTORE, -`09; X`09`09PRESERVE=NO`09`09; X`09SUBL3`09#NEW_STARTIO_OFFSET, -`09; Get starting address of loaded code X`09`09R5,R0`09`09`09; block X`09MOVL`09(R0),IRP$W_SIZE(R0)`09; Fill in size of block where deallocate cod Ve want it X`09JSB`09G`5EEXE$DEANONPAGED`09; Return block to pool X`09MOVZWL`09#SS$_NORMAL,R0`09`09; Signal success X`09RET`09`09`09`09; X`0C X`09.SBTTL`09VALIDATE_VEC - Validate UCB X;++ X; VALIDATE_VEC - Validate the pointers in the UCB`20 X; X; FUNCTIONAL DESCRIPTION: X; X;`09This routine will exampine the CLASS, GETNXT, and the PUTNXT pointers X; in the UCB. If the CLASS, PUTNXT, or the GETNXT pointers point to the cla Vss`20 X; driver. IF these tests fail it will then check against a list of trusted X; drivers. If it fails this test then it will BUGCHECK the system with the X; reason TTDRVR1 bugcheck. X; X;`09This code will be loaded into NONPAGED Pool and will be called in place` V20 X; of the normal TTDRIVER STARTIO routine. It will then validate the request V and X; jump to the real terminal driver STARTIO routine. This approach was choos Ven to X; minimize the impact on overall system performance. Ideally it should add V only`20 X; ten or eleven instructions to the normal STARTIO path. X; X; INPUTS: X; X;`09R3 = IRP X;`09R5 = LOGUCB X; X; OUTPUTS: X; X;`09None X; X; IMPLICIT IMPUTS: X; X;`09The fork lock must be held. X; X; NOTE: X;`09This code assumes that all users of the terminal driver use IO_LOCK8`20 X;`09for forking. `20 X; X;-- X`09.PSECT`09_LOAD$CODE PAGE,RD,WRT,EXE,PIC X XLOAD_START: X XLOAD_SIZE:`09`09`09`09; Size of block to be returned X`09.LONG`090`09`09`09; XSTARTIO:`09`09`09`09; TTDRIVER STARTIO address X`09.LONG`090`09`09`09; XCLASS_VEC:`09`09`09`09; Address of CLASS driver VECTOR X`09.LONG`090`09`09`09; table XGETNXT:`09`09`09`09`09; Address of CLASS driver GET NEXT X`09.LONG`090`09`09`09; routine XPUTNXT:`09`09`09`09`09; Address of CLASS driver PUT NEXT`20 X`09.LONG`090`09`09`09; routine XTABLE:`09`09`09`09`09; Table of alternate GET and PUT NEXT X`09.BLKL`09`09`09; routines X`09.LONG`090`09`09`09; End of table slot X XVALIDATE_VEC:: X`09PUSHL`09R5`09`09`09; Save LOGUCB address X`09MOVL`09UCB$L_TL_PHYUCB(R5),R5`09; Get PHYUCB address X`09CMPL`09CLASS_VEC,`09-`09; Compare CLASS vector table address X`09`09UCB$L_TT_CLASS(R5)`09; X`09BNEQ`0920$`09`09`09; NEQ next level test X`09CMPL`09GETNXT, `09-`09; Compare GETNXT address X`09`09UCB$L_TT_GETNXT(R5)`09; X`09BNEQ`0920$`09`09`09; NEQ next level test X`09CMPL`09PUTNXT, `09-`09; Compare PUTNXT address X`09`09UCB$L_TT_PUTNXT(R5)`09; X`09BNEQ`0920$`09`09`09; NEQ next level test X10$: X`09POPL`09R5`09`09`09; Restore LOGUCB address X`09JMP`09@STARTIO`09`09; Jump to real TTDRIVER startio X X20$: X`09MOVAL`09TABLE,R2`09`09; Get address of alternate drivers X30$: X`09MOVL`09(R2)+,R0`09`09; Get driver start address X`09BEQL`0940$`09`09`09; EQL enpty table X`09MOVL`09(R2)+,R1`09`09; Get driver ending address X`09BEQL`0940$`09`09`09; EQL enpty table X X`09CMPL`09UCB$L_TT_GETNXT(R5),R0`09; See if GETNXT is in driver X`09BLSS`0930$`09`09`09; LSS no try next driver X`09CMPL`09UCB$L_TT_GETNXT(R5),R1`09; See if GETNXT is in driver X`09BGTR`0930$`09`09`09; GTR no try next driver X`09CMPL`09UCB$L_TT_PUTNXT(R5),R0`09; See if PUTNXT is in driver X`09BLSS`0930$`09`09`09; LSS try next driver X`09CMPL`09UCB$L_TT_PUTNXT(R5),R1`09; See if PUTNXT is in driver X`09BGTR`0930$`09`09`09; GTR no try next entry X`09BRB`0910$`09`09`09; Match so use TTDRIVER STARTIO`20 X X40$: X`09POPL`09R5`09`09`09; Restore LOGUCB address X`09BUG_CHECK`09TTDRVR1,FATAL`09; Crash with TTDRVR fatal error X XLOAD_END: XLOCK_END: XLOAD_CODE_LEN = . - VALIDATE_VEC XLOAD_LEN = .- LOAD_START X XNEW_STARTIO_OFFSET = VALIDATE_VEC - LOAD_SIZE XSAVED_STARTIO_LOC = VALIDATE_VEC - STARTIO X X`09.END $ CALL UNPACK VALIDATE_VEC.MAR;2 439322046 $ v=f$verify(v) $ EXIT