'=========================================================================== ' Subject: DISPLAY CONTENTS OF HARDDISK Date: 12-19-96 (19:06) ' Author: Rick Elbers Code: QB, QBasic, PDS ' Origin: t030611@tip.nl Packet: DOS.ABC '=========================================================================== DECLARE SUB sectorread (datas%(), sector&) DECLARE SUB demo () DECLARE FUNCTION int2str$ (sword%) '--------------------------------------------------------------------------- 'XS2DISK: A program that displays the contents of your harddisk( all of it) 'Necessary requirement: DOS 4+( since there is made use of longsectors!) 'Rick Elbers december 1996 '--------------------------------------------------------------------------- CLS 'The program uses the dos 4+ format of function INT 25( read absolute disksectors) 'since i thought everybody does have a hard disk bigger then 32 MB by now..... 'There is some heavy math involved in the translation to unsigned integers and 'unsigned longs necessary for INT 25. Also there is some heavy cosmetica 'necessary to present the disksectors according to there meaning. Most of the 'math and cosmetics are however found in the demo part. 'But the most meaningful part of this contribution seems to me the function 'sectorread. The most important part of the sectorread function is the 'parameter block that is passed to the INT 25. Once you understand that you 'got it all...,well... almost... 'If you want to do something with the combination of FAT/DIRECTORY then you 'might want to add a very simple text file to your ROOTDIRECTORY. After that 'you can calculate the sector offset of the file and read him directly. That's 'quite a lot of fun, really... 'Good luck. '----------------------------------------------------------------------------- 'Rick demo SUB demo 'Define the databuffer in the demo 'because we want to pass the array '----------------------------------- DIM datas%(&H105) '---------------------------- 'go read the 0 (boot)sector '---------------------------- sector& = 0 'go read out the information '---------------------------- offset% = VARPTR(datas%(0)) + &HA '------------------------------------------------------------------------- 'The cosmetics sector: how to print things.." 'The first line will always contain: sectornr, area 'Updated will only be sectornr and sometimes the areaname ''1,15 >sectornr 1,38 > area indicator 'The second line will always contain the start line '------------------------------------------------------------------------- CLS LOCATE 1, 1: PRINT "READ SECTOR: "; LOCATE 1, 30: PRINT " AREA: "; LOCATE 2, 1: PRINT STRING$(80, "_") '------------------------------------------------------------------------- 'line 20 will contain the closing line which will be contant 'Line 24 will contain the prompt information which will be contant 'The lines 21,22,23 will contain additional information and 'will only sometimes be updated. LOCATE 19, 1: PRINT STRING$(80, "_") VIEW PRINT 24 TO 25: LOCATE 24, 1: COLOR 17, 0: PRINT "SECTOR,CLUSTER,END,<.>NEXT SECTOR"; : COLOR 7, 0: VIEW PRINT '------------------------------------------------------------------------ 'Let us run the program until escape '------------------------------------- DO i$ = "" 'no keypress yet '------------------------------------------------------------------------ 'AREA DEPENDENT COSMETICS: '-------------------------- IF (sector& AND &H7FFFFFFF) > total& OR sector& < 0 THEN sector& = 0 SELECT CASE sector& AND &H7FFFFFFF CASE 0 sectorread datas%(), sector& DEF SEG = VARSEG(datas%(0)) '------------- '0) BOOTSECTOR '-------------- 'First the header VIEW PRINT sec$ = HEX$(sector&): LOCATE 1, 15: COLOR O, 7: PRINT STRING$(8 - LEN(sec$), "0") + sec$: COLOR 7, 0: LOCATE 1, 38: COLOR 0, 7: PRINT "(MASTER)BOOTSECTOR OF C:\": COLOR 7, 0: VIEW PRINT 20 TO 23: CLS 2: VIEW PRINT 3 TO 18: CLS 2: LOCATE 3, 1: 'calculate relavant details of bootrecord. secpclus% = PEEK(&HD + &HA) nrfat% = PEEK(&H10 + &HA): direntrancenr% = PEEK(&H12 + &HA) * 256& OR PEEK(&H11 + &HA) bytepsec% = PEEK(&HC + &HA) * 256& OR PEEK(&HB + &HA) fatsec% = PEEK(&H16 + &HA) + PEEK(&H17 + &HA) * 256 ressec% = PEEK(&HF + &HA) * 256& + PEEK(&HE + &HA) help% = PEEK(&H13 + &HA) + PEEK(&H14 + &HA) * 256 IF help% = 0 THEN total& = 256& * PEEK(&H21 + &HA) + PEEK(&H20 + &HA) + 65535 * (PEEK(&H22 + &HA) + PEEK(&H23 + &HA) * 256) ELSE total& = help% END IF hiddensec% = PEEK(&H1C + &HA) + PEEK(&H1D + &HA) * 256 startdir% = nrfat% * fatsec% + ressec% 'we have to call this ones again startdata% = 1 + startdir% + (direntrancenr% * 32 / bytepsec%) 'Oke let us print the relevant details... COLOR 7, 0: PRINT "BYTES per sector :"; : COLOR 0, 13: PRINT bytepsec% COLOR 7, 0: PRINT "SECTORs per cluster :"; : COLOR 0, 2: PRINT secpclus% COLOR 7, 0: PRINT "NUMBER of FATs :"; : COLOR 0, 3: PRINT nrfat% COLOR 7, 0: PRINT "SECTORS per FAT :"; : COLOR 0, 4: PRINT fatsec% COLOR 7, 0: PRINT "Number of reserved sectors :"; : COLOR 0, 5: PRINT ressec% COLOR 7, 0: PRINT "Number of hidden sectors :"; : COLOR 0, 6: PRINT hiddensec% COLOR 7, 0: PRINT "TOTAL NUMBER OF SECTORS(dec) :"; : COLOR 0, 15: PRINT total& COLOR 7, 0: PRINT "START OF DOSDIRECTORY at sector :"; : COLOR 0, 11: PRINT startdir%; "("; HEX$(startdir%); ")" COLOR 7, 0: PRINT "START OF DATA(FILE/SUB directory) :"; : COLOR 0, 2: PRINT startdata% - 1; "("; HEX$(startdata% - 1); ")" COLOR 7, 0: PRINT "TOTAL SPACE( BYTES) ON DISK :"; : COLOR 0, 11: PRINT total& * bytepsec% COLOR 7, 0: PRINT "TOTAL CLUSTERS ON DISK(hex) :"; : COLOR 0, 10: PRINT " "; HEX$(total& \ secpclus%) COLOR 7, 0: PRINT "BYTES PER CLUSTER :"; : COLOR 0, 12: PRINT secpclus% * bytepsec% DO UNTIL i$ <> "": i$ = INKEY$: LOOP IF MID$(i$, 2, 1) = CHR$(&H40) THEN 'f6 pressed VIEW PRINT 24 TO 25: LOCATE 24, 50 COLOR 29, 0: INPUT "NEXT CLUSTER(hex) "; a$ COLOR 7, 0: LOCATE 24, 50: PRINT SPACE$(29); sector& = (VAL("&h" + a$) AND &HFFFF&) * secpclus% ELSEIF MID$(i$, 2, 1) = CHR$(&H3F) THEN 'f5 pressed VIEW PRINT 24 TO 25: LOCATE 24, 50 COLOR 29, 0: INPUT "NEXT SECTOR(dec) "; sector& COLOR 7, 0: LOCATE 24, 50: PRINT SPACE$(29); ELSEIF i$ = CHR$(27) THEN EXIT SUB ELSE sector& = 1 END IF CASE IS < startdir% '1)FAT AREA: '----------- 'first the header: VIEW PRINT LOCATE 1, 38: COLOR 0, 7: PRINT "FATAREA ": COLOR 7, 0: 'Second the footer VIEW PRINT 20 TO 23: CLS 2 LOCATE 20, 1: PRINT "FAT 1 until sector "; : COLOR 0, 7: PRINT fatsec%; COLOR 7, 0: PRINT " FAT 2 until sector "; : COLOR 0, 7: PRINT startdir% LOCATE 21, 1: PRINT "CODED LIKE:"; : COLOR 0, 7: PRINT "'0000'=FREE "; "'FFF8-FFFF'=END OF FAIL CHAIN "; "'FFF1--FFF7'=BAD SECTORS "; "OTHER=FILE CHAIN NEXT ENTRY "; COLOR 7, 0: 'Third lets roll the program '---------------------------- DO VIEW PRINT sec$ = HEX$(sector&): LOCATE 1, 15: COLOR O, 7: PRINT STRING$(8 - LEN(sec$), "0") + sec$: COLOR 7, 0: i$ = "" sectorread datas%(), sector& DEF SEG = VARSEG(datas%(0)) '------------------------- 'Let us display the data: '------------------------- VIEW PRINT 3 TO 18: CLS 2: LOCATE 3, 1: FOR i% = offset% TO offset% + &H200 - 1 a$ = HEX$(PEEK(i%)) PRINT a$ + STRING$(2 - LEN(a$), "0"); IF i% MOD 2 = 1 THEN PRINT " "; IF i% - offset% MOD 32 = 31 THEN PRINT NEXT 'user input a key or or esc ? '--------------------------------- DO UNTIL i$ <> "": i$ = INKEY$: LOOP IF LEN(i$) = 2 THEN i$ = MID$(i$, 2, 1) sector& = sector& + 1 LOOP WHILE (sector& AND &HFFFF) < startdir% AND i$ <> CHR$(&H3F) AND i$ <> CHR$(&H40) AND i$ <> CHR$(27)'non- function key pressed SELECT CASE i$ CASE CHR$(&H40) 'f6 pressed VIEW PRINT 24 TO 25: LOCATE 24, 50 COLOR 29, 0: INPUT "NEXT CLUSTER(hex) "; a$ COLOR 7, 0: LOCATE 24, 50: PRINT SPACE$(29); sector& = (VAL("&h" + a$) AND &HFFFF&) * secpclus% CASE CHR$(&H3F) 'f5 pressed VIEW PRINT 24 TO 25: LOCATE 24, 50 COLOR 29, 0: INPUT "NEXT SECTOR(dec) "; sector& COLOR 7, 0: LOCATE 24, 50: PRINT SPACE$(29); CASE CHR$(27) 'esc pressed EXIT SUB END SELECT CASE startdir% TO startdata% - 2 '2)DIRECTORY '----------- 'First the header: '------------------- VIEW PRINT sec$ = HEX$(sector&): LOCATE 1, 15: COLOR O, 7: PRINT STRING$(8 - LEN(sec$), "0") + sec$: COLOR 7, 0: LOCATE 1, 38: COLOR 0, 7: PRINT "DOS DIRECTORY AREA ": COLOR 7, 0: 'Second print footer '------------------ VIEW PRINT 20 TO 23: CLS 2: LOCATE 20, 1: PRINT " ^ ^ ^ ^ T^^^D^^^S^^^FS^^^^^^" PRINT "filenam.ext;atr; timedatestartfilesize"; PRINT "legenda: T=filetime(W),D=filedate(W),S = startsector(W),FS = filesize(DW) "; COLOR 0, 14: PRINT "STARTSECTOR FILE:= (STARTCLUSTER-2)*"; secpclus%; " + "; HEX$(startdata% - 1); : COLOR 7, 0: 'Third lets roll the program '---------------------------- DO VIEW PRINT sec$ = HEX$(sector&): LOCATE 1, 15: COLOR O, 7: PRINT STRING$(8 - LEN(sec$), "0") + sec$: COLOR 7, 0: i$ = "" sectorread datas%(), sector& DEF SEG = VARSEG(datas%(0)) '------------------------- 'Let us display the data: '------------------------- VIEW PRINT 3 TO 18: CLS 2: LOCATE 3, 1: FOR i% = offset% TO offset% + &H200 - 1 a% = PEEK(i%): p% = (i% - offset%) MOD 32 IF p% < 11 THEN PRINT CHR$(a%); ELSE a$ = HEX$(a%): PRINT STRING$(2 - LEN(a$), "0") + a$; IF p% = 31 AND i% <> offset% + &H200 - 1 THEN PRINT NEXT 'user input a key or or esc ? '--------------------------------- DO UNTIL i$ <> "": i$ = INKEY$: LOOP IF LEN(i$) = 2 THEN i$ = MID$(i$, 2, 1) sector& = sector& + 1 LOOP WHILE (sector& AND &HFFFF) < startdata% - 1 AND i$ <> CHR$(&H3F) AND i$ <> CHR$(&H40) AND i$ <> CHR$(17)'key pressed IF i$ = CHR$(&H40) THEN 'f6 pressed VIEW PRINT 24 TO 25: LOCATE 24, 50 COLOR 29, 0: INPUT "NEXT CLUSTER(hex) "; a$ COLOR 7, 0: LOCATE 24, 50: PRINT SPACE$(29); sector& = (VAL("&h" + a$) AND &HFFFF&) * secpclus% ELSEIF i$ = CHR$(&H3F) THEN 'f5 pressed VIEW PRINT 24 TO 25: LOCATE 24, 50 COLOR 29, 0: INPUT "NEXT SECTOR(dec) "; sector& COLOR 7, 0: LOCATE 24, 50: PRINT SPACE$(29); ELSEIF i$ = CHR$(27) THEN EXIT SUB END IF CASE ELSE 'data '3)DATA AREA: '----------- 'First the header '----------------- VIEW PRINT LOCATE 1, 38: COLOR 0, 7: PRINT "DATAAREA ": COLOR 7, 0: 'Second the footer '------------------ VIEW PRINT 20 TO 23: CLS 2 'Third lets roll the program '---------------------------- DO i$ = "" VIEW PRINT clushelp& = (sector& \ secpclus%): clushelp& = clushelp& AND &HFFFF& clus% = clushelp& AND &H7FFF: clus% = clus% OR -(clushelp& AND &H8000) clus$ = HEX$(clus%) LOCATE 20, 1: PRINT "CLUSTER NUMBER DISPLAYED: "; : COLOR 0, 7: PRINT STRING$(4 - LEN(clus$), "0") + clus$: COLOR 7, 0 LOCATE 21, 1: PRINT " 33 < ASCII < 126 DISPLAYED IN:"; : COLOR 0, 7: PRINT " CHARACTERS+SPACE"; : COLOR 7, 0: LOCATE 22, 1: PRINT "ASCII < 33 OR ASCII > 126 DISPLAYED AS:"; : COLOR 0, 7: PRINT " HEXADECIMAL BYTE": COLOR 7, 0: sec$ = HEX$(sector&): LOCATE 1, 15: COLOR O, 7: PRINT STRING$(8 - LEN(sec$), "0") + sec$: COLOR 7, 0: sectorread datas%(), sector& DEF SEG = VARSEG(datas%(0)) '------------------------- 'Let us display the data: '------------------------- VIEW PRINT 3 TO 18: CLS 2: LOCATE 3, 1: FOR i% = offset% TO offset% + &H200 - 1 a% = PEEK(i%) IF a% < 33 OR a% > 126 THEN PRINT STRING$(2 - LEN(HEX$(a%)), "0") + HEX$(a%); ELSE PRINT CHR$(a%) + " "; IF (i% - offset%) MOD 32 = 31 AND i% <> offset% + &H200 - 1 THEN PRINT NEXT 'user input a key or or esc ? '--------------------------------- DO UNTIL i$ <> "": i$ = INKEY$: LOOP IF LEN(i$) = 2 THEN i$ = MID$(i$, 2, 1) sector& = sector& + 1 LOOP WHILE i$ <> CHR$(&H3F) AND i$ <> CHR$(&H40) AND i$ <> CHR$(27)'non- function key pressed IF i$ = CHR$(&H40) THEN 'f6 pressed VIEW PRINT 24 TO 25: LOCATE 24, 50 COLOR 29, 0: INPUT "NEXT CLUSTER(hex) "; a$ COLOR 7, 0: LOCATE 24, 50: PRINT SPACE$(29); sector& = (VAL("&h" + a$) AND &HFFFF&) * secpclus% ELSEIF i$ = CHR$(&H3F) THEN 'f5 pressed VIEW PRINT 24 TO 25: LOCATE 24, 50 COLOR 29, 0: INPUT "NEXT SECTOR(dec) "; sector& COLOR 7, 0: LOCATE 24, 50: PRINT SPACE$(29); ELSEIF i$ = CHR$(27) THEN EXIT SUB END IF END SELECT LOOP WHILE i$ <> CHR$(27) END SUB FUNCTION int2str$ (sword%) 'This function is translating SWORD Integers into a string. Its only use 'is when you still use asm$ for assembler functions( like i do). In that 'case you can make your integer values usable .. 'THis function simply translates the hexa bytes 'into stringbytes as is. '---------------------------------------------------- DEF SEG = VARSEG(sword%) ptr% = VARPTR(sword%) int2str$ = CHR$(PEEK(ptr%)) + CHR$(PEEK(ptr% + 1)) DEF SEG END FUNCTION SUB sectorread (datas%(), sector&) '------------------------------------------------------------------------ 'datas%(&h105) '0:DW = sector2start '4:W = nrsector2read '6:DW = offset:segment van buffer '0A:100*W = sectorbuffer '------------------------------------------------------------------------ ds% = VARSEG(datas%(0)): bx% = VARPTR(datas%(0)) ds$ = int2str$(ds%): bx$ = int2str$(bx%) helplowbyte& = sector& AND &HFFFF& lowbyte% = helplowbyte& AND &H7FFF datas%(0) = lowbyte% OR -(helplowbyte& AND &H8000): helphighbyte& = ((sector& AND &HFFFF0000) \ 65535) AND &HFFFF& highbyte% = helphighbyte& AND &H7FFF datas%(1) = highbyte% OR -(helphighbyte& AND &H8000) datas%(2) = &H1: datas%(4) = ds%: datas%(3) = bx% + 10 '------------------------------------------------------------------------ asm$ = "" asm$ = asm$ + CHR$(&H50) 'PUSH AX asm$ = asm$ + CHR$(&H53) 'PUSH BX asm$ = asm$ + CHR$(&H51) 'PUSH CX asm$ = asm$ + CHR$(&H1E) 'PUSH DS asm$ = asm$ + CHR$(&HB8) + ds$ 'mov ax,ds$ asm$ = asm$ + CHR$(&H8E) + CHR$(&HD8) 'mov ds,ax asm$ = asm$ + CHR$(&HB8) + CHR$(&H2) + CHR$(&H0) 'MOV AX,2 asm$ = asm$ + CHR$(&HBB) + bx$ 'MOV BX,BX$ asm$ = asm$ + CHR$(&HB9) + CHR$(&HFF) + CHR$(&HFF)'MOV CX,-1 asm$ = asm$ + CHR$(&HCD) + CHR$(&H25) 'INT 25 asm$ = asm$ + CHR$(&H83) + CHR$(&HC4) + CHR$(&H2) 'ADD SP,2 asm$ = asm$ + CHR$(&H1F) 'POP DS asm$ = asm$ + CHR$(&H59) 'POP CX asm$ = asm$ + CHR$(&H5B) 'POP BX asm$ = asm$ + CHR$(&H58) 'POP AX 'say, we are done? asm$ = asm$ + CHR$(&HCB) 'RETF DEF SEG = VARSEG(asm$): offcode% = SADD(asm$) CALL absolute(offcode%) END SUB