'=========================================================================== ' Subject: MISC. DETECTION ROUTINES Date: 10-28-96 (12:49) ' Author: Ben Kaashoek Code: QB, PDS ' Origin: robertk@worldaccess.nl Packet: DOS.ABC '=========================================================================== DEFINT A-Z 'Use integers as default. REM $INCLUDE: 'qb.bi' 'INTERRUPT include file in QB45 'REM $INCLUDE: 'qbx.bi' 'INTERRUPT include file in QBX/PDS 'The story: ' This little piece of code started out as a simple NDOS detection routine. ' Suddenly it became a "Why-Don't-I-Put-All-My-Detection-Routines-In-Here?" ' sort of program. Anyway. Hope you can use some of it. ' I will keep adding new detection routines to this file when I find others. ' So keep your eyes PEEKing:) for new detection stuff. There are loads ' more out there (and somewhere around here too). ' I tried to comment as much as possible. (Is there something like TOO much ' when you're commenting code?) ' ' BEN 'Resources: ' - Ralph Brown's Interrupt List. I think V43 (Get your hands on it) ' A newer version will probably be released into the public domain. ' - Microsoft Windows V3.11 helpfile (Honest, it actually contained ' something usefull. ;-) ). ' - NDOS helpfile. DECLARE SUB NDOSVersion (majVer%, minVer%) 'Works OK. DECLARE SUB SMARTDRVInfo (Hits&, misses&, dirty&, majVer%, minVer%, HitRate%, oops%) DECLARE SUB SMARTDRVSize (full%, current%, BytesPerElement!, windows%) DECLARE FUNCTION DetectANSI% () DECLARE FUNCTION DetectDOSKEY% () DECLARE FUNCTION DetectKSTACK% () 'Untested. DECLARE FUNCTION DetectNDOS% () 'It detects my NDOS V7.0 DECLARE FUNCTION DetectNGUIDES% () 'Works OK. DECLARE FUNCTION DetectNovellIPX% () 'Untested. DECLARE FUNCTION DetectSMARTDRV% () 'Works OK. DECLARE FUNCTION DetectXMS% () 'Works OK. DECLARE FUNCTION PutKeysInKSTACK% (Keys$) 'Untested. DIM SHARED Inreg AS RegType, Outreg AS RegType DIM SHARED InRegX AS RegTypeX, OutRegX AS RegTypeX '-------------------------- Begin demonstration ---------------------------- CONST False = 0: True = NOT False 'Boolean constants. SCREEN 12: CLS : COLOR 7 'Test is independent of screenmode! IF DetectNGUIDES THEN PRINT "Norton Guide is resident in memory" ELSE PRINT "Norton Guide is not resident in memory" END IF IF DetectNDOS THEN NDOSVersion Maj%, Min% PRINT "NDOS V"; LTRIM$(STR$(Maj%)); "."; LTRIM$(STR$(Min%)); " detected" ELSE PRINT "NDOS not detected" END IF IF DetectNovellIPX THEN PRINT "Novell Netware IPX driver detected" ELSE PRINT "Novell Netware IPX driver not detected" END IF IF DetectDOSKEY THEN PRINT "DOSKEY detected" ELSE PRINT "DOSKEY not detected" END IF IF DetectXMS THEN PRINT "V2.0+ XMS driver detected" ELSE PRINT "V2.0+ XMS driver not detected" END IF IF DetectKSTACK THEN PRINT "KSTACK.COM detected" ELSE PRINT "KSTACK.COM not detected" END IF IF DetectANSI THEN PRINT "ANSI.SYS detected" ELSE PRINT "ANSI.SYS not detected" END IF IF DetectSMARTDRV THEN SMARTDRVInfo Hits&, misses&, dirty&, majVer%, minVer%, HitRate%, oops% PRINT "SMARTDRV V"; LTRIM$(STR$(majVer)); "."; LTRIM$(STR$(minVer)); " detected" PRINT USING " ÃÄ Cache hits : #####"; Hits& PRINT USING " ÃÄ Cache misses : #####"; misses& PRINT USING " ÃÄ Dirty caches : #####"; dirty& PRINT USING " ÃÄ Cache hitrate: ###%"; HitRate% 'Notice how the hitrate only changes after disk activity. 'Why?, that's because the drive has become a SMART drive :-). 'Theoretically it should not exceed 100% (if it does you have a 'really smart one). SMARTDRVSize full%, current%, BytesPerElement!, windows% DosSize& = current% * BytesPerElement! WinSize& = windows% * BytesPerElement! TotalSize& = full% * BytesPerElement! PRINT " ÀÄ Cache sizes (bytes)" PRINT USING " ÃÄ DOS = ########"; DosSize& PRINT USING " ÃÄ Windows = ########"; WinSize& PRINT " ³ ----------- +" PRINT USING " ÀÄ Total = ########"; TotalSize& ELSE PRINT "SMARTDRV not detected" END IF PRINT "" COLOR 15 PRINT "Hope you can use this. Happy keyboard crunching !" DO: LOOP UNTIL INKEY$ <> "" 'Wait until a key is pressed. COLOR 7 'Restore default MS-DOS colour. SCREEN 0 'Restore screen (else Win95 crashes HARD) END 'Terminate program. '---------------------------- End demonstration ---------------------------- FUNCTION DetectANSI Inreg.AX = &H1A00 'Function 1Ah, Subfunction 0h CALL INTERRUPT(&H2F, Inreg, Outreg) 'Call DOS (Int 2Fh) DetectANSI = 0 'Assume it's not there IF Outreg.AX \ 256 = &HFF THEN DetectANSI = -1 END FUNCTION FUNCTION DetectDOSKEY% Inreg.AX = &H4800 'Function 48h, Subfunction 0h CALL INTERRUPT(&H2F, Inreg, Outreg) 'Call DOS (Int 2Fh) DetectDOSKEY% = 0 'Assume it's not there IF Outreg.AX MOD 256 <> 0 THEN DetectDOSKEY% = -1 END FUNCTION FUNCTION DetectKSTACK Inreg.AX = &HE44F 'Function E4h, Subfunction 4Fh Inreg.BX = 0 CALL INTERRUPT(&H2F, Inreg, Outreg) 'Call DOS (Int 2Fh) DetectKSTACK = 0 'Assume it's not there. IF Outreg.AX = &H44EE THEN DetectKSTACK = -1 END FUNCTION FUNCTION DetectNDOS% Inreg.AX = &HE44D 'Function E4h, Subfunction 4Dh CALL INTERRUPT(&H2F, Inreg, Outreg) 'Call DOS (Int 2Fh) DetectNDOS = 0 'Assume it's not there. IF Outreg.AX = &H44EE THEN DetectNDOS = -1 END FUNCTION FUNCTION DetectNGUIDES% Inreg.AX = &HF398 'Function F3h, Subfunction 98h CALL INTERRUPT(&H16, Inreg, Outreg) 'Call DOS (Int 16h) DetectNGUIDES% = 0 'Assume it's not there. IF Outreg.AX = &H6A73 THEN DetectNGUIDES% = -1 END FUNCTION FUNCTION DetectNovellIPX% 'I haven't tested this routine because I don't have a network. Maybe in a few 'year's I can continue programming even when nature calls :-) Inreg.AX = &H7A00 'Function 7Ah, Subfunction 0h CALL INTERRUPT(&H2F, Inreg, Outreg) 'Call DOS (Int 2Fh) IF Outreg.AX MOD 256 = 0 THEN DetectNovellIPX% = 0 IF Outreg.AX MOD 256 = &HFF THEN DetectNovellIPX% = -1 END FUNCTION FUNCTION DetectSMARTDRV% Inreg.AX = &H4A10 'function 4Ah, Subfunction 10h Inreg.BX = 0 'Sorry, lost the info on this ! Inreg.CX = &HEBAB 'Sorry, lost the info on this ! CALL INTERRUPT(&H2F, Inreg, Outreg) 'Call DOS (Int 2fh) DetectSMARTDRV = 0 'Assume it's not there. IF Outreg.AX = &HBABE THEN DetectSMARTDRV = -1 END FUNCTION FUNCTION DetectXMS% Inreg.AX = &H4300 'Function 43h, Subfunction 0h CALL INTERRUPT(&H2F, Inreg, Outreg) 'Call DOS (int 2Fh) DetectXMS% = 0 'Assume it's not there. IF Outreg.AX MOD 256 = &H80 THEN DetectXMS% = -1 END FUNCTION SUB NDOSVersion (majVer%, minVer%) Inreg.AX = &HE44D 'Function E4h, Subfunction 4Dh CALL INTERRUPT(&H2F, Inreg, Outreg) 'Call DOS (Int 2Fh) majVer% = minVer% = 0 'Return zeroes if NDOS not loaded. IF Outreg.AX = &H44EE THEN 'Modify version if it's there. majVer% = Outreg.BX MOD 256 'Major version in register BL minVer% = Outreg.BX \ 256 'Minor version in register BH END IF END SUB FUNCTION PutKeysInKSTACK% (Keys$) 'If it doesn't work you may have to uncomment the line marked with "<---" 'and change the parameter of the VARSEG/SADD instruction. 'Many DOS functions require a Zero terminated string (ASCIIZ for short). 'KeysZ$ = Keys$ + CHR$(0) '<--- Uncomment this one InRegX.AX = &HE44F 'Function E4h, Sub-function 4Fh InRegX.BX = 1 InRegX.CX = LEN(Keys$) 'Number of keystrokes being passed. InRegX.DS = VARSEG(Keys$) 'Segment of the keystroke string. InRegX.DX = SADD(Keys$) 'Address of the keystroke string. CALL INTERRUPTX(&H2F, InRegX, OutRegX) '| Int 2Fh END FUNCTION SUB SMARTDRVInfo (Hits&, misses&, dirty&, majVer%, minVer%, HitRate%, oops%) STATIC PrevHits&, PrevTotal& 'Keep data of previous call. Inreg.AX = &H4A10 'function 4Ah, subfunction 10h Inreg.BX = 0 Inreg.CX = &HEBAB CALL INTERRUPT(&H2F, Inreg, Outreg) 'Call DOS (int 2fh) IF Outreg.AX = &HBABE THEN Hits& = Outreg.DX * &H100 + Outreg.BX misses& = Outreg.DI * &H100 + Outreg.SI dirty& = CLNG(Outreg.CX) majVer% = VAL(HEX$(Outreg.BP)) \ 100 minVer% = VAL(HEX$(Outreg.BP)) - majVer * 100 oops% = 0 ELSE oops% = -1 EXIT SUB END IF 'Calculate the hitrate with the formula as found in Microsoft Windows help. 'Hit_rate = 100 * (CurrentHits - PreviousHits) / (CurrentTotal - PreviousTotal) CurrTotal& = Hits& + misses& + dirty& HitRate% = 100 * (Hits& - PrevHits&) / (CurrTotal& - PrevTotal&) END SUB SUB SMARTDRVSize (full%, current%, BytesPerElement!, windows%) Inreg.AX = &H4A10 'function 4Ah, subfunction 10h Inreg.BX = &H4 CALL INTERRUPT(&H2F, Inreg, Outreg) 'Call DOS (Int 2Fh) full% = Outreg.AX 'Size in elements of full sized cache current% = Outreg.BX 'Current size in elements BytesPerElement! = Outreg.CX 'Size of one element in bytes windows% = Outreg.DX 'Number of elements under windows END SUB