erwvegm@cs.vu.nl (Erwin van Egmond) (04/22/91)
Hi, I'm using TP5.5 and I want to know if and how I can find out on wich sector/cluster a file is placed. I must probably readout my FAT, but how do I do that? Is there someone out there who can help me? Please? Thankx in advance Erwin van Egmond <erwvegm@cs.vu.nl> P.S A while ago I asked something about GIF-pictures in een .EXE file. Someone asked me to pass along any info. Unfortunately I lost has email adress, so could that someone please send me his email adress again? -- ++ Erwin van Egmond UUCP: ...!mcsun!cs.vu.nl!erwvegm ++ ++ ++ ++ With a rubber duck, one's never alone ++ ++ -- "The Hitchhiker's Guide to the Galaxy" ++
focke@gmdzi.gmd.de (Stefan Focke) (04/22/91)
erwvegm@cs.vu.nl (Erwin van Egmond) writes: >Hi, > I'm using TP5.5 and I want to know if and how I can find out > on wich sector/cluster a file is placed. > I must probably readout my FAT, but how do I do that? > Is there someone out there who can help me? Please? Hello, it is not too hard to do that: - Read the boot-sektor to find out where your directory and FAT is - From the directory you get the first cluster of your file - Than you have to follow the FAT to find all clusters of your file - You have to find out if you have a 12-bit or a 16-Bit FAT (DOS 4.x) I do not know where you can find this information. Who can help? mfg Stefan ------------------------------------------------------------------- Stefan Focke Tel. 02241-14-2265 GMD-Z2.W e-mail: focke@gmdzi.uucp Postfach 1240 focke@gmdzi.gmd.de 5205 St. Augustin 1 ...!{uunet!mcvax!}unido!gmdzi!focke
campbell@cutmcvax.cs.curtin.edu.au (Trevor George Campbell CC361) (04/24/91)
focke@gmdzi.gmd.de (Stefan Focke) writes: >erwvegm@cs.vu.nl (Erwin van Egmond) writes: >> I must probably readout my FAT, but how do I do that? >- You have to find out if you have a 12-bit or a 16-Bit FAT (DOS 4.x) > I do not know where you can find this information. Who can help? you can tell if it is a 12 bit FAT by the fact that with a you can only access at most 4087 clusters (?? sectors) using a 12 bits.. (ie: 4096 - the flags that indicate end of file... = 4087). If on the other hand the disk has more than 4087 (strictly greater) then it must be a 16 bit FAT .... you can find out how many allocation units the disk has by checking the DPB (Drive Parameter Block) part of the boot block.... I don't have more info on me at this stage... but if you want I may be able to e-mail (or post if enough interest) the source for such a program (limited capabilities) in TURBO ASSEMBLER (with a bit more time I could probably do a quick program in TURBO PASCAL).... Trevor alias <**<TOMCAT>**>
Kai_Henningsen@ms.maus.de (Kai Henningsen) (04/27/91)
Stefan Focke focke @ gmdzi.gmd.de schrieb am 22.04.1991, 08:33 SF>Hello, SF> SF>it is not too hard to do that: SF> SF>- Read the boot-sektor to find out where your directory and FAT is SF>- From the directory you get the first cluster of your file SF>- Than you have to follow the FAT to find all clusters of your file SF>- You have to find out if you have a 12-bit or a 16-Bit FAT (DOS 4.x) SF> I do not know where you can find this information. Who can help? Well, looks like it's time to post a program I wrote. The purpose is to set the date of every directory on a disk to that of the youngest file within. Be warned that, while the program runs without a problem on *my* harddisk (DOS 4), I do not make any claims that the same will be true elsewhere - the risk is yours, completely; I wrote this only for myself. You better make a backup first!! Also, the code is for TP 6.0, I use the inline assembler. As for comments, well ... Pascal is supposed to be selfdocumenting, no? But ask me if you don't understand something ... So, first a support unit ... unit DosAbsUt; interface uses Dos; type BootRec = record jmp: array[1..3] of byte; OEM: array[1..8] of char; bps: word; spc: byte; res: word; nFAT: byte; RootSz: word; Size: word; Media: byte; spFAT: word; spt: word; nHeads: word; res40: longint; Size40: longint; Phys: byte; nix: byte; Sig: byte; { $29 } ID: longint; Volume: array [1..11] of char; nix2: array[1..8] of char; end; function AbsRead(Drive: byte; nSecs: word; Start: longint; var Buffer): word; function AbsWrite(Drive: byte; nSecs: word; Start: longint; var Buffer): word; function SecSize(Drive: byte): word; procedure ResetDisk; implementation var r: registers; Dos4Abs : record First: longint; Count: word; Buf: pointer; end; function AbsRead(Drive: byte; nSecs: word; Start: longint; var Buffer): word; begin if lo(dosversion)<4 then begin asm {[f-]} mov al, [Drive]; mov cx, [nSecs]; mov dx, word ptr [Start]; push ds; lds bx, [Buffer]; int $25; jc @Err; xor ax, ax; @Err: popf; pop ds; mov [@Result], ax end {[f+]}; end else begin with Dos4Abs do begin First:=Start; Count:=nSecs; Buf:=@Buffer; end; asm {[f-]} mov al, [Drive]; mov cx, -1; push ds; mov bx, seg Dos4Abs; mov ds, bx; mov bx, offset Dos4Abs; int $25; jc @Err; xor ax, ax; @Err: popf; pop ds; mov [@Result], ax end {[f+]}; end; end; function AbsWrite(Drive: byte; nSecs: word; Start: longint; var Buffer): word; begin if lo(dosversion)<4 then begin asm {[f-]} mov al, [Drive]; mov cx, [nSecs]; mov dx, word ptr [Start]; push ds; lds bx, [Buffer]; int $26; jc @Err; xor ax, ax; @Err: popf; pop ds; mov [@Result], ax end {[f+]}; end else begin with Dos4Abs do begin First:=Start; Count:=nSecs; Buf:=@Buffer; end; asm {[f-]} mov al, [Drive]; mov cx, -1; push ds; mov bx, seg Dos4Abs; mov ds, bx; mov bx, offset Dos4Abs; int $26; jc @Err; xor ax, ax; @Err: popf; pop ds; mov [@Result], ax end {[f+]}; end; end; function SecSize(Drive: byte): word; begin with r do begin ah:=$1c; dl:=drive+1; msdos(r); secsize:=cx; end; end; procedure ResetDisk; begin r.ah:=$0d; msdos(r); end; end. MfG Kai
Kai_Henningsen@ms.maus.de (Kai Henningsen) (04/27/91)
... and now for the program proper ... program DirDate; uses Dos, DosAbsUt, m7utillo; type FATbuf= array[0..65520] of byte; FATarray= array[0..16380] of ^FATbuf; DIRent = record Fn: array[1..8] of char; Fe: array[1..3] of char; Attr: byte; Res: array[$0c..$15] of byte; Timestamp: longint; Start: word; Size: longint; end; Direct= array[0..2046] of DIRent; var BootSec: ^BootRec; p: string; dr: byte; err: word; ss: word; Clust: word; DskSz: longint; FAT0, ROOT0, DATA0: longint; FATbytes: longint; FATsecs: longint; shortFAT: boolean; FAT: ^FATarray; i: longint; dps, dpc: word; Indent: word; function FATentry(n: word): word; type wp = ^word; var b, bm, bd: longint; w: word; begin if shortFAT then b:=n*longint(3) div 2 else b:=n*longint(2); bm:=b mod ss; bd:=b div ss; if bm+1<ss then w:=wp(@FAT^[bd]^[bm])^ else w:=FAT^[bd]^[bm] or swap(FAT^[bd+1]^[0]); if shortFAT then begin if odd(n) then w:=w shr 4 else w:=w and $FFF; if w>=$ff8 then w:=w or $f000; end; FATentry:=w; end; procedure WriteName(n,e: string); begin trim(n); trim(e); if e='' then write(n,'':12-length(n)) else write(n,'.',e,'':11-length(n)-length(e)); end; procedure WriteDate(ts: longint); var dt : DateTime; { For Pack/UnpackTime} function LeadingZero(w : Word) : String; var s : String; begin Str(w:0,s); if Length(s) = 1 then s := '0' + s; LeadingZero := s; end; begin UnpackTime(ts,dt); with dt do begin Write(day:2,'.',month:2,'.',year,' ', LeadingZero(hour),':',LeadingZero(min),':',LeadingZero(sec)); end; end; function TraverseSubdir(Start: word): longint; forward; function Process(var D: DIRent; var dt0: longint): boolean; var dt: longint; begin Process:=false; with D do begin case Fn[1] of #0: Process:=true; #$E5: ; else begin write('':indent*2); writename(Fn,Fe); write(' '); writedate(Timestamp); writeln; if Fn[1]<>'.' then begin if (attr and directory)=directory then begin dt:=TraverseSubdir(Start); { if Timestamp<dt then} Timestamp:=dt; write('':indent*2); writename(Fn,Fe); write(' '); writedate(Timestamp); writeln; end; if Timestamp>dt0 then dt0:=Timestamp; end else Timestamp:=0; end; end; end; end; procedure TraverseRoot; var CurDir: ^Direct; i: word; cur: word; var dt: longint; begin dt:=0; Indent:=0; getmem(CurDir, ss); i:=0; cur:=$ffff; while (i<BootSec^.RootSz) do begin if (i div dps)<>cur then begin if cur<>$ffff then begin err:=AbsWrite(dr, 1, ROOT0+cur, CurDir^); if err<>0 then runerror(err); end; cur:=i div dps; err:=AbsRead(dr, 1, ROOT0+cur, CurDir^); if err<>0 then runerror(err); end; if Process(CurDir^[i mod dps], dt) then i:=$ffff else inc(i); end; err:=AbsWrite(dr, 1, ROOT0+cur, CurDir^); if err<>0 then runerror(err); freemem(CurDir, ss); end; function TraverseSubdir(Start: word): longint; var CurDir: ^Direct; i: word; cur: word; dt: longint; Last: word; begin dt:=0; inc(Indent); getmem(CurDir, Clust*ss); i:=0; cur:=$ffff; Last:=0; while (i<$FFFF) do begin if (i div dpc)<>cur then begin if cur<>$ffff then begin err:=AbsWrite(dr, Clust, DATA0+longint(Last)*Clust, CurDir^); if err<>0 then runerror(err); end; cur:=i div dpc; if (Start>=$FFF8) or (Start<2) then begin fillchar(CurDir^, Clust*ss, 0); Last:=0; end else begin err:=AbsRead(dr, Clust, DATA0+longint(Start)*Clust, CurDir^); if err<>0 then runerror(err); Last:=Start; Start:=FATentry(Start); end; end; if Process(CurDir^[i mod dpc], dt) then i:=$ffff else inc(i); end; if Last<>0 then begin err:=AbsWrite(dr, Clust, DATA0+longint(Last)*Clust, CurDir^); if err<>0 then runerror(err); end; freemem(CurDir, Clust*ss); dec(Indent); TraverseSubdir:=dt; end; ... rest follows ... MfG Kai
Kai_Henningsen@ms.maus.de (Kai Henningsen) (04/27/91)
... last part ... begin writeln; writeln; ResetDisk; p:=paramstr(1); if (paramcount<>1) or (length(p)<>1) then runerror; dr:=ord(upcase(p[1]))-ord('A'); ss:=SecSize(dr); getmem(bootsec, ss); err:=absread(dr, 1, 0, bootsec^); if err<>0 then runerror(err); with bootsec^do begin writeln(OEM); FAT0:=res; ROOT0:=FAT0+(longint(nFAT)*spFAT); DATA0:=ROOT0+(RootSz*longint(sizeof(DIRent))+ss-1) div ss - 2*spc; dps:=ss div sizeof(DIRent); dpc:=ss*spc div sizeof(DIRent); Clust:=spc; DskSz:=size; if size=0 then begin dsksz:=size40; if sig=$29 then begin writeln(volume,' ',nix2); end; end; FATbytes:=((DskSz-DATA0) div spc)*2; if fatbytes<8000 then shortFAT:=true else begin FATsecs:=(FATbytes+(ss-1)) div ss; shortFAT:=FATsecs<>spFAT; end; if shortFAT then begin FATbytes:=(((DskSz-DATA0) div spc)*3+1) div 2; FATsecs:=(FATbytes+(ss-1)) div ss; end; writeln(shortFAT,' ',FATsecs,' ',spFAT); if FATsecs<>spFAT then runerror; FATsecs:=spFAT; FATbytes:=FATsecs*ss; end; writeln(FAT0,' ',ROOT0,' ',DATA0); getmem(FAT, sizeof(pointer)*FATsecs); for i:=0 to FATsecs-1 do begin getmem(FAT^[i], ss); err:=AbsRead(dr, 1, i+FAT0, FAT^[i]^); if err<>0 then runerror(err); end; if FATentry(0)<>($ff00 or BootSec^.Media) then runerror; if FATentry(1)<>$ffff then runerror; TraverseRoot; ResetDisk; end. MfG Kai