Файл Problemsfil.Doc
140h |
32 |
50 52 4F 42 4C 45 7E 31 44 4F 43 20 00 54=84
97 53=10010 111010 10011 40 85=0100000 0100 00101 40 85=0100000 0100 00101 00 00 06 51=00000 110010 10001 40 6C 00 12 00 00 64 00 |
Имя: PROBLE~1.DOC Атрибуты файла(архивный) Поле для Windows NT Поле, уточняющее время создания(в десятках миллисекунд)=84 Время создания= 18:58:38 Дата создания: 05.04.2012 Время последнего доступа: 05.04.2012 Зарезервировано Время последней модификации:00:50:34 Дата последней модификации: 05.04.2012 Первый кластер: 18 Размер: 25600 байт |
120 |
32 |
01 50 00 72 00 6F 00 62 00 6C 00 0F 00 E5 65 00 6D 00 73 00 66 00 69 00 6C 00 00 00 2E 00 64 00
|
Номер фрагмента Символы 1-5 имени файла в Unicode Probl Атрибуты файла Байт флагов Контрольная сумма короткого имени Символы 6-11 имени файла в Unicode=emsfil Номер первого кластера Символы 12-13 имени файла в Unicode=.d |
100 |
32 |
42 6F 00 63 00 00 00 FF FF FF FF 0F 00 E5 FF FF FF FF FF FF FF FF FF FF FF FF 00 00 FF FF FF FF
|
Номер фрагмента Символы 1-5 имени файла в Unicode oc Атрибуты файла Байт флагов Контрольная сумма короткого имени Символы 6-11 имени файла в Unicode= Номер первого кластера Символы 12-13 имени файла в Unicode=il |
Задание 2.7
Используя приложение, разработанное в п. 2.3, найти в FAT и прочитать цепочки кластеров для двух-трех файлов:
-
корневого каталога;
-
двух-трех подкаталогов.
Представить результаты в отчете в виде последовательностей соответствующих кластерам файла элементов FAT.
Выведем содержимое FAT
Последовательность для файла Filosofiafile.doc корневого каталога(первый элемент FAT - 5)
Последовательность кластеров |
Последовательность элементов FAT |
6(00000006) 7(00000007) 8(00000008) 9(00000009) 10(0000000A) 11-EOF(Сигнатура FFFFFFFF) |
5 6 7 8 9 10 |
Последовательность для файла Problemsfil.doc из S1(первый элемент FAT 41)
Последовательность кластеров |
Последовательность элементов FAT |
42(0000002A) 43(0000002B) 44(0000002C) 45(0000002D) 46(0000002E) 47-EOF(Сигнатура FFFFFFFF) |
41 42 43 44 45 46 |
Последовательность для файла Filosofiafile.doc из S1(первый элемент FAT 48)
Последовательность кластеров |
Последовательность элементов FAT |
49(00000031) 50(00000032) 51(00000033) 52(00000034) 53(00000035) 54-EOF(Сигнатура FFFFFFFF) |
48 49 50 51 52 53 |
Приложения
Текст программы
Unit 1
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls, FileCtrl, ValEdit,unit2;
type
TForm1 = class(TForm)
Button1: TButton;
DriveComboBox1: TDriveComboBox;
StringGrid1: TStringGrid;
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
Button2: TButton;
Label3: TLabel;
ValueListEditor1: TValueListEditor;
Button3: TButton;
Button4: TButton;
Button5: TButton;
StringGrid2: TStringGrid;
DirectoryListBox1: TDirectoryListBox;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
procedure Edit2KeyPress(Sender: TObject; var Key: Char);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TInfFat = packed record
count:byte; // число таблиц
OneFat:DWORD; // количество секторов, занимаемый одной FAT
NumRoot:DWORD; // номер кластера для первого кластера корневого каталога
ReservSec:word; // число резервных секторов в резервной области раздела
end;
function __Mul(a,b: DWORD; var HiDWORD: DWORD): DWORD;
function ReadSecto(drive:char;StartingSector, SectorCount: DWORD;
Buffer: Pointer; BytesPerSector: DWORD = 512): DWORD;
var
s:integer;
Form1: TForm1;
bufFAT: array of dword;
Fat:tinffat;
implementation
{$R *.dfm}
function __Mul(a,b: DWORD; var HiDWORD: DWORD): DWORD; // Result = LoDWORD
asm
mul edx
mov [ecx],edx
end;
function ReadSecto(drive:char;StartingSector, SectorCount: DWORD;
Buffer: Pointer; BytesPerSector: DWORD = 512): DWORD;
var
hFile: THandle;
br,TmpLo,TmpHi: DWORD;
begin
Result := 0;
hFile := CreateFile(PChar('\\.\'+Drive+':'),
GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if hFile = INVALID_HANDLE_VALUE then Exit;
TmpLo := __Mul(StartingSector,BytesPerSector,TmpHi);
if SetFilePointer(hFile,TmpLo,@TmpHi,FILE_BEGIN) = TmpLo then
begin
SectorCount := SectorCount*BytesPerSector;
if ReadFile(hFile,Buffer^,SectorCount,br,nil) then Result := br;
end;
CloseHandle(hFile);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i:integer;
begin
s:=0;
for i:=1 to 10 do
begin
stringgrid1.Cells[i,0]:=inttostr(i-1);
stringgrid2.Cells[i,0]:=inttostr(i-1);
end;
stringgrid1.Cells[11,0]:='A';
stringgrid1.Cells[12,0]:='B';
stringgrid1.Cells[13,0]:='C';
stringgrid1.Cells[14,0]:='D';
stringgrid1.Cells[15,0]:='E';
stringgrid1.Cells[16,0]:='F';
stringgrid2.Cells[11,0]:='A';
stringgrid2.Cells[12,0]:='B';
stringgrid2.Cells[13,0]:='C';
stringgrid2.Cells[14,0]:='D';
stringgrid2.Cells[15,0]:='E';
stringgrid2.Cells[16,0]:='F';
end;
procedure TForm1.Button1Click(Sender: TObject);
var
buf:array of byte;
i,j:integer;
drive:char;
begin
drive:=Drivecombobox1.drive;
setlength(buf,512*strtoint(edit2.text));
if readsecto(drive,strtoint(edit1.text),strtoint(edit2.text),pointer(buf))=0 then showmessage('Нет доступа');
StringGrid1.RowCount:=round(length(buf)/15);
StringGrid2.RowCount:=round(length(buf)/15);
for i:=0 to round(length(buf)/16) do
begin
stringgrid1.Cells[0,i+1]:=inttohex(i*16,3);
stringgrid2.Cells[0,i+1]:=inttohex(i*16,3);
end;
for i:=1 to round(length(buf)/16) do
for j:=1 to 16 do
begin
stringgrid1.Cells[j,i]:=inttohex(buf[16*(i-1)+j-1],2);
stringgrid2.Cells[j,i]:=chr(buf[16*(i-1)+j-1]);
end;
Finalize(buf);
end;
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if not (key in ['0'..'9',#8]) then key := #0;
end;
procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char);
begin
if not (key in ['0'..'9',#8]) then key := #0;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
buf:array of byte;
i,j:integer;
drive:char;
begin
drive:=Drivecombobox1.drive;
setlength(buf,512);
if Readsecto(drive,0,1,buf)=0 then begin Showmessage('Ошибка доступа к диску! Выберите другой диск.'); Finalize(buf); end;
Move(buf[$10],FAT.count,1);
ValueListEditor1.InsertRow('Число таблиц(копий) FAT(10h)',inttostr(FAT.count),true);
Move(buf[$24],FAT.OneFat,4);
ValueListEditor1.InsertRow('Число секторов, занимаемых одной копией FAT (24h)',inttostr(FAT.OneFat),true);
Move(buf[$2c],FAT.NumRoot,4);
ValueListEditor1.InsertRow('Номер кластера для первого кластера корневого каталога(2Сh)',inttostr(FAT.NumRoot),true);
Move(buf[$0E],FAT.ReservSec,2);
ValueListEditor1.InsertRow('Число резервных секторов в резервной области раздела(ОЕh)',inttostr(FAT.ReservSec),true);
ValueListEditor1.InsertRow('Тип FAT','FAT32',true);
ValueListEditor1.InsertRow('Начальный сектор FAT(1 копия)',inttostr(FAT.ReservSec),true);
ValueListEditor1.InsertRow('Начальный сектор FAT(2 копия)',inttostr(FAT.ReservSec+FAT.OneFat),true);
ValueListEditor1.InsertRow('Первый сектор области данных',inttostr(FAT.ReservSec+2*FAT.OneFat),true);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
form2.showmodal;
end;
procedure TForm1.Button4Click(Sender: TObject);
var
buf:array of byte;
i,j:integer;
drive:char;
begin
drive:=Drivecombobox1.drive;
setlength(buf,512);
for i:=1 to round((length(buf)/16))+1 do
for j:=1 to 16 do
stringgrid1.Cells[j,i]:='';
if Readsecto(drive,0,1,buf)=0 then begin Showmessage('Ошибка доступа к диску! Выберите другой диск.'); Finalize(buf); end;
StringGrid1.RowCount:=round(length(buf)/15);
for i:=0 to round(length(buf)/16) do
stringgrid1.Cells[0,i+1]:=inttohex(i*16,3);
for i:=1 to round((length(buf)/16)-4) do
for j:=1 to 16 do
stringgrid1.Cells[j,i]:=inttohex(buf[16*4+16*(i-1)+j-1],2);
Finalize(buf);
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
if s=0 then
begin
stringgrid2.Visible:=true;
s:=1;
end
else
begin
stringgrid2.Visible:=false;
s:=0;
end;
end;
end.
Unit 2
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids;
type
TForm2 = class(TForm)
StringGrid1: TStringGrid;
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
Edit3: TEdit;
Button2: TButton;
Label3: TLabel;
StringGrid2: TStringGrid;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
procedure Edit3KeyPress(Sender: TObject; var Key: Char);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TStringl = string[8];
function ReverseValue(val:TStringl):TStringl;
var
Form2: TForm2;
implementation
uses Unit1;
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
close;
end;
procedure TForm2.Button2Click(Sender: TObject);
var
buf:array of byte;
buffat:array of dword;
i,j:integer;
drive:char;
lx,ly:integer;
begin
drive:=form1.Drivecombobox1.drive;
setlength(buf,512);
if readsecto(drive,0,1,pointer(buf))=0 then showmessage('Нет доступа');
Move(buf[$10],FAT.count,1); //число FAt
Move(buf[$24],FAT.OneFat,4); // количество секторов, занимаемый одной FAT
Move(buf[$2c],FAT.NumRoot,4); // номер кластера для первого кластера корневого каталога
Move(buf[$0E],FAT.ReservSec,2); // число резервных секторов в резервной области раздела,Начальный сектор FAT(1 копия)
Finalize(buf);
setlength(buffat,512*strtoint(edit3.text));
if readsecto(drive,FAT.ReservSec,strtoint(edit3.text),pointer(buffat))=0 then begin showmessage('Нет доступа'); Finalize(buf);end
else
begin
stringgrid1.RowCount:=round(512*strtoint(edit3.text)/64);
lx:=8;
ly:=16;
// выводим их
for i:= 0 to 7 do
for j:=0 to round(512*strtoint(edit3.text)/64) do
StringGrid1.Cells[i,j]:=reverseValue(inttohex(buffat[(j)*8+i],0));
edit1.Visible:=true;
edit2.Visible:=true;
end;
end;
function ReverseValue(val:TStringl):TStringl;//прибавление нулей
var
buf1:string[2];
begin
result:='';
while length(val)<>8 do
val:='0'+val;
result:=val;
end;
procedure TForm2.StringGrid1SelectCell(Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean);
begin
Edit1.Text:=inttostr(8*Arow+acol);
Edit2.Text:=inttostr(strtoint('$'+StringGrid1.Cells[ACOL,AROW]));
end;
procedure TForm2.Edit3KeyPress(Sender: TObject; var Key: Char);
begin
if not (key in ['0'..'9',#8]) then key := #0;
end;
procedure TForm2.Button3Click(Sender: TObject);
var
i,j:integer;
buf:array of byte;
drive:char;
begin
for i:=1 to 10 do
stringgrid2.Cells[i,0]:=inttostr(i-1);
stringgrid2.Cells[11,0]:='A';
stringgrid2.Cells[12,0]:='B';
stringgrid2.Cells[13,0]:='C';
stringgrid2.Cells[14,0]:='D';
stringgrid2.Cells[15,0]:='E';
stringgrid2.Cells[16,0]:='F';
if edit2.text='' then showmessage('Выберите кластер из таблицы слева')
else
begin
drive:=form1.Drivecombobox1.drive;
setlength(buf,512*8);//выделяем память под буфер в 8 секторов
if readsecto(drive,FAT.ReservSec+2*FAT.OneFat+8*strtoint(edit2.text),8,pointer(buf))=0 then
begin
showmessage('Нет доступа');
finalize(buf);
end
else
begin
stringgrid2.rowcount:=32*8+1;
for i:=0 to round(length(buf)/16) do
stringgrid2.Cells[0,i+1]:=inttohex(i*16,3);
for i:=1 to round(length(buf)/16) do
for j:=1 to 16 do
stringgrid2.Cells[j,i]:=inttohex(buf[16*(i-1)+j-1],2);
Finalize(buf);
end;
end;
end;
end.
1 Рекомендуется использовать flash-диск, отформатированный для FAT32