Программная реализация чтения системных структур раздела диска с файловой системой FAT 32 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Программная реализация чтения системных структур раздела диска с файловой системой FAT 32



 

Обращение к разделу жесткого диска в операционных системах Windows 2000/XP может быть выполнено путем открытия диска как файла с помощью функции CreateFile и указания диска или его раздела по схеме Device Namespace (открывается физический диск - ' \\.\PHYSICALDRIVE<n> '). Полученный хэндл в дальнейшем используется для работы с диском с помощью функций ReadFile, WriteFile и DeviceIoControl.

Для выполнения этой операции можно использовать следующий программный код:[7]

// Drive - номер диска (нумерация с нуля).

 

hFile:= CreateFile (PChar('\\.\PhysicalDrive'+IntToStr(Drive)),

GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil,OPEN_EXISTING,0,0);

if hFile = INVALID_HANDLE_VALUE then Exit;

 

В результате появляется возможность воспринимать физический диск как единый файл.

Чтобы получить информацию о геометрии диска можно использовать еще один программный фрагмент:

Const

IOCTL_DISK_GET_DRIVE_GEOMETRY = $70000;

 

Type

TDiskGeometry = packed record

Cylinders: Int64; // количество цилиндров

 

MediaType: DWORD; // тип носителя

TracksPerCylinder: DWORD; // дорожек на цилиндре

SectorsPerTrack: DWORD; // секторов на дорожке

BytesPerSector: DWORD; // байт в секторе

end;

 

Result:= DeviceIoControl (hFile,IOCTL_DISK_GET_DRIVE_GEOMETRY, nil,0,

@DiskGeometry,SizeOf(TDiskGeometry),junk, nil) and (junk = SizeOf(TDiskGeometry));

 

Функция DeviceIoControl возвращает True, если операция прошла успешно, и False в противном случае.

Основной операцией при работе с системными структурами данных FAT32 является операция чтения содержимого сектора диска. Она может быть выполнена с помощью функции, одна из программных реализаций которых (функция ReadSectors) представлена ниже.

// так как диск - это единый файл, то для перемещения по нему

// с помощью функции SetFilePointer понадобится 64х-разрядная арифметика

 

function __Mul(a,b: DWORD; var HiDWORD: DWORD): DWORD; // Result = LoDWORD

Asm

mul edx

mov [ecx],edx

end;

 

function ReadSectors (DriveNumber: Byte; StartingSector, SectorCount: DWORD;

Buffer: Pointer; BytesPerSector: DWORD = 512): DWORD;

Var

hFile: THandle;

br,TmpLo,TmpHi: DWORD;

Begin

Result:= 0;

hFile:= CreateFile (PChar('\\.\PhysicalDrive'+IntToStr(DriveNumber)),

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;

 

 

Функция ReadSectors возвращает количество прочитанных байт.

Ниже в качестве примера приводится программный код для чтения сектора диска, содержащего структуры MBR и Partition Table.

 

TPartitionTableEntry = packed record

BootIndicator: Byte; // $80, если активный (загрузочный) раздел

StartingHead: Byte;

StartingCylAndSect: Word;

SystemIndicator: Byte;

EndingHead: Byte;

EndingCylAndSect: Word;

StartingSector: DWORD; // начальный сектор

 

NumberOfSects: DWORD; // количество секторов

end;

TPartitionTable = packed array [0..3] of TPartitionTableEntry;

 

PDriveInfo = ^TDriveInfo;

TDriveInfo = record

PartitionTable: TPartitionTable;

LogicalDrives: array [0..3] of PDriveInfo;

end;

Const

 

PartitionTableOffset = $1be;

ExtendedPartitions = [5,$f];

 

Var

MainExPartOffset: DWORD = 0;

 

function GetDriveInfo (DriveNumber: Byte; DriveInfo: PDriveInfo;

StartingSector: DWORD; BytesPerSector: DWORD = 512): Boolean;

Var

buf: array of Byte;

CurExPartOffset: DWORD;

i: Integer;

Begin

 

SetLength(buf,BytesPerSector);

// читаем сектор в буфер

if ReadSectors (DriveNumber,MainExPartOffset+StartingSector,1,@buf[0]) = 0 then

Begin

Result:= False;

Exit;

end;

// заполняем структуру DriveInfo.PartitionTable

 

Move(buf[PartitionTableOffset],DriveInfo.PartitionTable,SizeOf(TPartitionTable));

Finalize(buf); // буфер больше не нужен

 

Result:= True;

for i:= 0 to 3 do // для каждой записи в Partition Table

 

if DriveInfo.PartitionTable[i].SystemIndicator in ExtendedPartitions then

Begin

New(DriveInfo.LogicalDrives[I]);

if MainExPartOffset = 0 then

 

Begin

MainExPartOffset:= DriveInfo.PartitionTable[I].StartingSector;

CurExPartOffset:= 0;

end else CurExPartOffset:= DriveInfo.PartitionTable[I].StartingSector;

Result:= Result and GetDriveInfo (DriveNumber,DriveInfo.LogicalDrives[I],

CurExPartOffset);

end else DriveInfo.LogicalDrives[I]:= nil;

end;

 

Функция GetDriveInfo заполняет структуру DriveInfo и возвращает True, если операция прошла успешно, или False в противном случае.

 

Практическая часть

2.1.Используя данные п. 1.2 и 1.3, разработать приложение Windows для чтения произвольного сектора заданного логического диска.

Для выбора диска рекомендуется использовать компонент TDriveComboBox (рис. 2).

Рис. 2

Отображать содержимое выбранного сектора удобнее всего в компоненте TStringGrid (рис. 3).

Рис. 3

 

2.2. С помощью разработанного приложения прочитать системные структуры данных BR, резервную копию BR, BF_BPB, FSInfo для одного из логических дисков[8].

Зафиксировать полученные данные в отчете, расшифровать их и представить в виде соответствующих таблиц.

2.3. Модифицировать приложение для чтения информации о типе, расположении на диске и содержимом FAT, а также содержимом секторов задаваемого кластера диска.

Для отображения информации о FAT рекомендуется использовать компонент TValueListEditor (рис. 4), а для расшифровки FAT – компонент TStringGrid (рис. 5).

 

Рис. 4

Рис. 5

2.4. По данным, полученным в п.2.2, прочитать информацию о FAT и зафиксировать ее в отчете.

2.5. Создать на диске каталожную структуру (по варианту в лабораторной работе № 2).

2.6. Прочитать секторы диска, содержащие дескрипторы файлов и подкаталогов корневого каталога, двух-трех подкаталогов и двух-трех файлов с длинными именами в каждом подкаталоге. Прочитанную информацию зафиксировать в отчете, расшифровать ее и представить в виде таблиц, структура которых аналогична таблицам в лабораторной работе № 2.

2.7. Используя приложение, разработанное в п. 2.3, найти в FAT и прочитать цепочки кластеров для двух-трех файлов:

a) корневого каталога;

b) двух-трех подкаталогов.

Представить результаты в отчете в виде последовательностей соответствующих кластерам файла элементов FAT.

Содержание отчета

Требования к содержанию отчета соответствуют требованиям к отчету в лабораторной работе № 1.

Литература

1. Верма Р. Д. Справочник по функциям Win32 API. – М.: Горячая линия – Телеком, 2002. – 488с.:ил.

2. Румянцев П. В. Азбука программирования в Win32 API. М.: Горячая линия – Телеком, 2001.

3. Джонсон М. Xaрт. Системное программирование в Win32 API. М.: Вильямс, 2001.

4. Кузан Д. Я., Шапоров В. Н. Программирование Win32 API в Delphi.- Спб.: БХВ-Петербург, 2005. – 368 с.: ил.


1) Структура FAT, корневого каталога и области данных рассматриваются в лабораторной работе № 2.

[1] За исключением FAT 32, изучению которой посвящена лабораторная работа №4

[2] Командой < Shift – F4 > в текущем каталоге

[3] Структура и особенности FAT 32 рассматриваются в лабораторной работе № 4

[4] Этот формат имеет название «8.3»

[5] Рекомендуется использовать флеш-диск

[6] Здесь для сравнения приведена структура раздела диска для FAT12 и FAT16

[7] Все примеры программных фрагментов приводятся на языке Object Pascal системы программирования Delphi.

[8] Рекомендуется использовать flash-диск, отформатированный для FAT32



Поделиться:


Последнее изменение этой страницы: 2017-02-06; просмотров: 677; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.224.214.215 (0.014 с.)