Эта таблица располагается в секторе по смещению $1be и состоит из четырех одинаковых элементов, каждый из которых описывает один раздел:
Code: |
TPartitionTableEntry = packed record BootIndicator: Byte; // $80, если активный (загрузочный) раздел StartingHead: Byte; StartingCylAndSect: Word; SystemIndicator: Byte; EndingHead: Byte; EndingCylAndSect: Word; StartingSector: DWORD; // начальный сектор NumberOfSects: DWORD; // количество секторов end; |
Соответственно, саму Partition Table можно представить как массив:
TPartitionTable = packed array [0..3] of TPartitionTableEntry;
Подробнее остановлюсь на этой структуре. Как видно из описания структур, Partition Table может содержать только четыре раздела. А так как, возможно, пользователю необходимо большее количество, было введено понятие "Extended Partition" (таким образом, разделы бывают Primary и Extended). Extended Partition - это раздел, который имеет свою собственную Partition Table (и, соответственно может содержать в себе еще четыре раздела). Extended Partition содержит логические диски. Тип раздела определяется полем SystemIndicator. Оно содержит информацию о файловой системе логического диска, либо 5 (или $f), если это Extended Partition.
Примеры значений поля SystemIndicator:
01 - FAT12
04 - FAT16
05 - EXTENDED
06 - FAT16
07 - NTFS
0B - FAT32
0F - EXTENDED
Теперь можно приступить к разбору структуры логических дисков. Сейчас уже нам пригодится функция ReadSectors.
Code: |
// так как диск для нас - это единый файл, то для перемещения по нему // с помощью 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; |
Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.
ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!