'SIB.BAS
'This is the BASIC SIB code for EVERLOCK
'Last Updated 28/May/96 SSS

'This program uses INT 21, FUNCTION 51h to place the SEGMENT of
'the PSP in the BX Register then using that segment with the offset of
'00FC finds the far pointer of the Secure Information Block.
'This is in flipped offset:segment format.
'This uses QuickBASIC 4.5 compiled with the /O option for a
'stand alone program.  Linked with QB.LIB and BCOM45.LIB for
'the CALL INTERRUPTX.
'
'BC SIB.BAS /o;
'
'LINK SIB.OBJ,,,qb + bcom45 /e;
'
'The register values before and after the interrupt are passed in
'variables declared as type RegTypeX. The following statement defines
'the RegTypeX user-defined type.  Each element of the type corresponds
'to a CPU register.
'
  TYPE RegTypeX
     ax         AS INTEGER
     bx         AS INTEGER
     cx         AS INTEGER
     dx         AS INTEGER
     bp         AS INTEGER
     si         AS INTEGER
     di         AS INTEGER
     flags      AS INTEGER
     ds         AS INTEGER
     es         AS INTEGER
  END TYPE
'
'Generate the software interrupt, loading all registers.
'
  DECLARE SUB INTERRUPTX (intnum AS INTEGER, inreg AS RegTypeX, outreg AS RegTypeX)
'
  DEFINT A-Z
'
  DIM inreg AS RegTypeX, outreg AS RegTypeX
'
'
'
'Set ax register for function 51H to place the  PSP segment address in the
'bx register.  DOS 2.0 and later. Function 62H can be used in DOS 3
'and above.
'
'
  inreg.ax = &H5100
'
'
'Call Int. 21 to get the PSP segment address.
'
'
  CALL INTERRUPTX(&H21, inreg, outreg)
'
'
'Display the bx register.
'
'
   PRINT "               PROGRAM TO FIND AND PRINT THE CONTENTS OF THE SIB"
   PRINT
   PRINT
   PRINT "Segment Address of the PSP is located in the BX Register"
   PRINT
   PRINT "BX REGISTER ="; HEX$(outreg.bx)
   PRINT
   PRINT
'
'
'Define the Segment to look in for the PSP.
'
'
  DEF SEG = outreg.bx
'
'
'Look in the offset positions 00FC - 00FF for the far pointer.
'
'
  ptr1 = PEEK(&HFC)
  ptr2 = PEEK(&HFD)
  ptr3 = PEEK(&HFE)
  ptr4 = PEEK(&HFF)

'***NOTE***
'If all you need from the SIB is the value for the NUC Handle you can
'  get that directly without looking through memory.  It is in the PSP
'  at offset &HFA.  The following code can be use to get the value.
'
' ptr1 = PEEK(&HFA)
' ptr2 = PEEK(&HFB)
' hnuc = INT(ptr2 * 256) + ptr1
'
'
'Print the Hex values in the far pointer position.
'
'
   PRINT "Segment:Offset of SIB = "; HEX$(ptr4); HEX$(ptr3); ":"; HEX$(ptr2); HEX$(ptr1)
   PRINT
'
'
'Define the segment to look in for the SIB.
'
'
  DEF SEG = (ptr4 * 256) + ptr3
'
'
'Define the offset to start looking for SIB.
'
'
  offset = (ptr2 * 256) + ptr1
  os = offset
'
'
'Look in the offset for the SIB.
'
'
 DIM sib(1 TO 512)
 FOR x = 1 TO 512
 sib(x) = PEEK(os + (x) - 1)
 NEXT 
'
'
' Now define the fields of the SIB. 
'
'
IF CHR$(sib(1)) = "A" AND CHR$(sib(2)) = "Z" THEN
   FOR i = 1 TO 4
      id$ = id$ + CHR$(sib(i))
   NEXT 
   drv$ = CHR$(sib(5))
   auth$ = CHR$(sib(6))
   ptype$ = CHR$(sib(7))
   FOR i = 8 TO 16
      prd$ = prd$ + CHR$(sib(i))
   NEXT 
   prdser# = (sib(20) * 16777216#) + (sib(19) * 65536#) + (sib(18) * 256#) + sib(17)
   hnuc = INT(sib(22) * 256) + sib(21)
   avers = INT(sib(24) * 256) + sib(23)
   ecl = INT(sib(26) * 256) + sib(25)
   edl = INT(sib(30) * 256) + sib(29)
   FOR i = 33 TO 41
      ed$ = ed$ + CHR$(sib(i))
   NEXT 
   nuc = INT(sib(44) * 256) + sib(43)
   nul = INT(sib(46) * 256) + sib(45)
   icr = INT(sib(48) * 256) + sib(47)
   FOR i = 49 TO 56
      accflg$ = accflg$ + CHR$(sib(i)) 
   NEXT
   FOR i = 57 TO 64
      usrdat$ = usrdat$ + CHR$(sib(i)) 
   NEXT
   rtype$ = CHR$(sib(65))
   FOR i = 66 TO 116
      rname$ = rname$ + CHR$(sib(i))
   NEXT
   FOR i = 117 TO 167
      rcomp$ = rcomp$ + CHR$(sib(i))
   NEXT
   FOR i = 168 TO 218
      rloc$ = rloc$ + CHR$(sib(i))
   NEXT
   FOR i = 219 TO 227
      rdate$ = rdate$ + CHR$(sib(i))
   NEXT
   FOR i = 228 TO 236
      cdate$ = cdate$ + CHR$(sib(i))
   NEXT
   secstr$ = ""
   FOR i = 257 TO 512
      IF ASC(CHR$(sib(i))) = 0 THEN
         EXIT FOR
      ELSE
         secstr$ = secstr$ + CHR$(sib(i))     'Secure String can be 256 bytes
      END IF
   NEXT 
'
'
'
' Now print out the SIB information. 
'
'
   PRINT "    Signature Literal:  "; id$
   PRINT "             Drive ID:  "; drv$
   PRINT "     Drive Authorized:  "; auth$
   PRINT "      Protection Type:  "; ptype$
   PRINT "              Product:  "; prd$
   PRINT "      Product Serial#:  "; prdser#
   PRINT "     Net-Users Handle:  "; hnuc
   PRINT "Authorization Version:  "; avers
   PRINT "     Exec-Count Limit:  "; ecl
   PRINT "    Expire-Days Limit:  "; edl
   PRINT "          Expire Date:  "; ed$
   PRINT " Concurrent-Use-Count:  "; nuc
   PRINT " Concurrent-Use-Limit:  "; nul
   IF ptype$ = "P" THEN
      PRINT "Current Install-Count:  "; icr
   END IF

'  Print User-Data
   PRINT "            User-Data: ";
   FOR i = 1 TO 8
      PRINT HEX$(ASC(MID$(usrdat$, i, 1)));
   NEXT i
   PRINT

'  Print list of Access Flags
   FLG$ = ""
   k = 0
   PRINT "     Access Flags Set: ";
   FOR i = 0 TO 7
      FLG$ = MID$(accflg$, i + 1, 1)
      FOR j = 1 TO 8
         IF j = 1 THEN
            IF ASC(FLG$) AND 1 THEN
               PRINT ((i * 8) + j); " ";
               k = k + 1
            END IF
         END IF
         IF j = 2 THEN
            IF ASC(FLG$) AND 2 THEN
               PRINT ((i * 8) + j); " ";
               k = k + 1
            END IF
         END IF
         IF j = 3 THEN
            IF ASC(FLG$) AND 4 THEN
               PRINT ((i * 8) + j); " ";
               k = k + 1
            END IF
         END IF
         IF j = 4 THEN
            IF ASC(FLG$) AND 8 THEN
               PRINT ((i * 8) + j); " ";
               k = k + 1
            END IF
         END IF
         IF j = 5 THEN
            IF ASC(FLG$) AND 16 THEN
               PRINT ((i * 8) + j); " ";
               k = k + 1
            END IF
         END IF
         IF j = 6 THEN
            IF ASC(FLG$) AND 32 THEN
               PRINT ((i * 8) + j); " ";
               k = k + 1
            END IF
         END IF
         IF j = 7 THEN
            IF ASC(FLG$) AND 64 THEN
               PRINT ((i * 8) + j); " ";
               k = k + 1
            END IF
         END IF
         IF j = 8 THEN
            IF ASC(FLG$) AND 128 THEN
               PRINT ((i * 8) + j); " ";
               k = k + 1
            END IF
         END IF
      NEXT j
   NEXT i
   IF k = 0 THEN
      PRINT "NONE"
   END IF

'  Print Registration Info
   IF rtype$ = "N" THEN
      PRINT "   Registered to Name: "; rname$
      PRINT "Registered to Company: "; rcomp$
      PRINT "  Registered Location: "; rloc$
      PRINT "      Registered Date: "; rdate$
   END IF

'  Print Current Date
   PRINT "         Current Date: "; cdate$

'  Print the Secure String
   PRINT
   PRINT "        Secure String: "
   PRINT secstr$
ELSE
   PRINT "          Invalid SIB"
END IF
END
