Читаем Partition Table
Описываем необходимые типы
Код Delphi:
type Tmbr = packed record bootstrap_code: packed array [0..439] of byte; serial_num: packed array [0..3] of byte; reserved: packed array [0..1] of byte; end; type TPartitionTableEntry = packed record BootIndicator: Byte; // $80, если активный (загрузочный) раздел StartingHead: Byte; StartingCylAndSect: Word; SystemIndicator: Byte; EndingHead: Byte; EndingCylAndSect: Word; StartingSector: DWORD; // начальный сектор NumberOfSects: DWORD; // количество секторов end; type TPartitionTable = packed array [0..3] of TPartitionTableEntry; type PDriveInfo = ^TDriveInfo; TDriveInfo = record MBR: Tmbr; PartitionTable: TPartitionTable; LogicalDrives: array [0..3] of PDriveInfo; Signature: array[0..1] of byte; end;
... константы
Код Delphi:
const PartitionTableOffset = $1be; ExtendedPartitions = [5,$f];
... и функции
Код Delphi:
function TForm1.DecodeSystemIndicator(si: byte):string; var s: string; begin case si of $01: s:='DOS 12-bit FAT'; $02: s:='XENIX root'; $03: s:='XENIX /usr'; $04: s:='DOS 3.0+ 16-bit FAT (up to 32M)'; $05: s:='DOS Extended partition (DOS 3.3+)'; $06: s:='DOS 3.31+ 16-bit FAT (over 32M)'; $07: s:='NTFS или OS/2 IFS или exFAT'; $08: s:='OS/2 (v1.0-1.3 only) или AIX boot partition или SplitDrive или Commodore DOS'; $09: s:='AIX data partition или Coherent filesystem или QNX 1.x and 2.x ("qnz")'; $0A: s:='OS/2 Boot Manager или Coherent swap partition или OPUS'; $0B: s:='FAT32'; $0C: s:='FAT32, LBA-mapped'; $0D: s:='SILICON SAFE'; $0E: s:='FAT16, LBA-mapped'; $0F: s:='Extended, LBA-mapped'; $11: s:='Hidden FAT12'; $12: s:='Configuration/diagnostics partition'; $14: s:='Hidden DOS 16-bit FAT <32M'; $16: s:='Hidden DOS 16-bit FAT >=32M'; $17: s:='Hidden IFS (e.g., HPFS)'; $18: s:='AST SmartSleep Partition'; $1B: s:='Hidden WIN95 OSR2 FAT32'; $1C: s:='Hidden WIN95 OSR2 FAT32, LBA-mapped'; $1E: s:='Hidden WIN95 16-bit FAT, LBA-mapped'; $24: s:='NEC DOS 3.x'; $27: s:='PQservice или Windows RE hidden partition или MirOS partition или RouterBOOT kernel partition'; $2A: s:='AtheOS File System (AFS)'; $2B: s:='SyllableSecure (SylStor)'; $32: s:='NOS'; $35: s:='JFS on OS/2 or eCS'; $38: s:='THEOS ver 3.2 2gb partition'; $39: s:='Plan 9 partition или THEOS ver 4 spanned partition'; $3A: s:='THEOS ver 4 4gb partition'; $3B: s:='THEOS ver 4 extended partition'; $3C: s:='PartitionMagic recovery partition'; $3D: s:='Hidden NetWare'; $40: s:='Venix 80286 или PICK'; $41: s:='Linux/MINIX (sharing disk with DRDOS) или Personal RISC Boot или PPC PReP (Power PC Reference Platform) Boot'; $42: s:='Linux swap (sharing disk with DRDOS) или SFS (Secure Filesystem) или Windows 2000 dynamic extended partition marker'; $43: s:='Linux native (sharing disk with DRDOS)'; $44: s:='GoBack partition'; $45: s:='Boot-US boot manager или Priam или EUMEL/Elan'; $46: s:='EUMEL/Elan'; $47: s:='EUMEL/Elan'; $48: s:='EUMEL/Elan'; $4A: s:='Mark Aitchison''s ALFS/THIN lightweight filesystem for DOS или AdaOS Aquila (Withdrawn)'; $4C: s:='Oberon partition'; $4D: s:='QNX4.x'; $4E: s:='QNX4.x 2nd part'; $4F: s:='QNX4.x 3rd part или Oberon partition'; $50: s:='OnTrack Disk Manager (older versions) RO или Lynx RTOS или Native Oberon (alt)'; $51: s:='Ontrack extended partition или Novell'; $52: s:='CP/M или Microport SysV/AT'; $53: s:='Disk Manager 6.0 Aux3'; $54: s:='Disk Manager 6.0 Dynamic Drive Overlay (DDO)'; $55: s:='EZ-Drive'; $56: s:='Golden Bow VFeature Partitioned Volume или DM converted to EZ-BIOS или AT&T MS-DOS 3.x logically sectored FAT.'; $57: s:='DrivePro или VNDI Partition'; $5C: s:='Priam EDisk'; $61: s:='SpeedStor'; $63: s:='Unix System V (SCO, ISC Unix, UnixWare, ...), Mach, GNU Hurd'; $64: s:='Novell Netware 286, 2.xx'; $65: s:='Novell Netware 386, 3.xx or 4.xx'; $66: s:='Novell Netware SMS Partition'; $67: s:='Novell'; $69: s:='Novell Netware 5+, Novell Netware NSS Partition'; $70: s:='DiskSecure Multi-Boot'; $72: s:='V7/x86'; $74: s:='Scramdisk partition'; $75: s:='IBM PC/IX'; $77: s:='M2FS/M2CS partition или VNDI Partition'; $78: s:='XOSL FS'; $80: s:='MINIX until 1.4a'; $81: s:='MINIX since 1.4b, early Linux или Mitac disk manager'; $82: s:='Prime или Solaris x86 или Linux swap'; $83: s:='Linux native partition'; $84: s:='OS/2 hidden C: drive или Hibernation partition'; $85: s:='Linux extended partition'; $86: s:='Old Linux RAID partition superblock или FAT16 volume set'; $87: s:='NTFS volume set'; $88: s:='Linux plaintext partition table'; $8A: s:='Linux Kernel Partition (used by AiR-BOOT)'; $8B: s:='Legacy Fault Tolerant FAT32 volume'; $8C: s:='Legacy Fault Tolerant FAT32 volume using BIOS extd INT 13h'; $8D: s:='Free FDISK 0.96+ hidden Primary DOS FAT12 partitition'; $8E: s:='Linux Logical Volume Manager partition'; $90: s:='Free FDISK 0.96+ hidden Primary DOS FAT16 partitition'; $91: s:='Free FDISK 0.96+ hidden DOS extended partitition'; $92: s:='Free FDISK 0.96+ hidden Primary DOS large FAT16 partitition'; $93: s:='Hidden Linux native partition или Amoeba'; $94: s:='Amoeba bad block table'; $95: s:='MIT EXOPC native partitions'; $96: s:='CHRP ISO-9660 filesystem'; $97: s:='Free FDISK 0.96+ hidden Primary DOS FAT32 partitition'; $98: s:='Free FDISK 0.96+ hidden Primary DOS FAT32 partitition (LBA) или Datalight ROM-DOS Super-Boot Partition'; $99: s:='DCE376 logical drive'; $9A: s:='Free FDISK 0.96+ hidden Primary DOS FAT16 partitition (LBA)'; $9B: s:='Free FDISK 0.96+ hidden DOS extended partitition (LBA)'; $9E: s:='ForthOS partition'; $9F: s:='BSD/OS'; $A0: s:='Laptop hibernation partition'; $A1: s:='Laptop hibernation partition или HP Volume Expansion (SpeedStor variant)'; $A3: s:='HP Volume Expansion (SpeedStor variant)'; $A4: s:='HP Volume Expansion (SpeedStor variant)'; $A5: s:='BSD/386, 386BSD, NetBSD, FreeBSD'; $A6: s:='OpenBSD или HP Volume Expansion (SpeedStor variant)'; $A7: s:='NeXTStep'; $A8: s:='Mac OS-X'; $A9: s:='NetBSD'; $AA: s:='Olivetti Fat 12 1.44MB Service Partition'; $AB: s:='Mac OS-X Boot partition или GO! partition'; $AD: s:='RISC OS ADFS'; $AE: s:='ShagOS filesystem'; $AF: s:='ShagOS swap partition или MacOS X HFS'; $B0: s:='BootStar Dummy'; $B1: s:='HP Volume Expansion (SpeedStor variant) или QNX Neutrino Power-Safe filesystem'; $B2: s:='QNX Neutrino Power-Safe filesystem'; $B3: s:='HP Volume Expansion (SpeedStor variant) или QNX Neutrino Power-Safe filesystem'; $B4: s:='HP Volume Expansion (SpeedStor variant)'; $B6: s:='HP Volume Expansion (SpeedStor variant) или Corrupted Windows NT mirror set (master), FAT16 file system'; $B7: s:='Corrupted Windows NT mirror set (master), NTFS file system или BSDI BSD/386 filesystem'; $B8: s:='BSDI BSD/386 swap partition'; $BB: s:='Boot Wizard hidden'; $BC: s:='Acronis backup partition'; $BD: s:='BonnyDOS/286'; $BE: s:='Solaris 8 boot partition'; $BF: s:='New Solaris x86 partition'; $C0: s:='CTOS или REAL/32 secure small partition или NTFT Partition или DR-DOS/Novell DOS secured partition'; $C1: s:='DRDOS/secured (FAT-12)'; $C2: s:='Hidden Linux'; $C3: s:='Hidden Linux swap'; $C4: s:='DRDOS/secured (FAT-16, < 32M)'; $C5: s:='DRDOS/secured (extended)'; $C6: s:='DRDOS/secured (FAT-16, >= 32M) или Windows NT corrupted FAT16 volume/stripe set'; $C7: s:='Windows NT corrupted NTFS volume/stripe set или Syrinx boot'; $C8: s:='Reserved for DR-DOS 8.0+'; $C9: s:='Reserved for DR-DOS 8.0+'; $CA: s:='Reserved for DR-DOS 8.0+'; $CB: s:='DR-DOS 7.04+ secured FAT32 (CHS)/'; $CC: s:='DR-DOS 7.04+ secured FAT32 (LBA)/'; $CD: s:='CTOS Memdump?'; $CE: s:='DR-DOS 7.04+ FAT16X (LBA)/'; $CF: s:='DR-DOS 7.04+ secured EXT DOS (LBA)/'; $D0: s:='REAL/32 secure big partition или Multiuser DOS secured partition'; $D1: s:='Old Multiuser DOS secured FAT12'; $D4: s:='Old Multiuser DOS secured FAT16 <32M'; $D5: s:='Old Multiuser DOS secured extended partition'; $D6: s:='Old Multiuser DOS secured FAT16 >=32M'; $D8: s:='CP/M-86'; $DA: s:='Non-FS Data или Powercopy Backup'; $DB: s:='Digital Research CP/M, Concurrent CP/M, Concurrent DOS или CTOS (Convergent Technologies OS -Unisys) или KDG Telemetry SCPU boot'; $DD: s:='Hidden CTOS Memdump?'; $DE: s:='Dell PowerEdge Server utilities (FAT fs)'; $DF: s:='DG/UX virtual disk manager partition или BootIt EMBRM'; $E0: s:='Reserved by STMicroelectronics for a filesystem called ST AVFS.'; $E1: s:='DOS access or SpeedStor 12-bit FAT extended partition'; $E3: s:='DOS R/O or SpeedStor'; $E4: s:='SpeedStor 16-bit FAT extended partition < 1024 cyl.'; $E5: s:='Tandy MSDOS with logically sectored FAT'; $E6: s:='Storage Dimensions SpeedStor'; $E8: s:='LUKS'; $EA: s:='Rufus extra partition или Freedesktop boot'; $EB: s:='BeOS BFS'; $EC: s:='SkyOS SkyFS'; $EE: s:='Indication that this legacy MBR is followed by an EFI header'; $EF: s:='Partition that contains an EFI file system'; $F0: s:='Linux/PA-RISC boot loader'; $F1: s:='Storage Dimensions SpeedStor'; $F2: s:='DOS 3.3+ secondary partition'; $F4: s:='SpeedStor large partition или Prologue single-volume partition'; $F5: s:='Prologue multi-volume partition'; $F6: s:='Storage Dimensions SpeedStor'; $F7: s:='DDRdrive Solid State File System'; $F9: s:='pCache'; $FA: s:='Bochs'; $FB: s:='VMware File System partition'; $FC: s:='VMware Swap partition'; $FD: s:='Linux raid partition with autodetect using persistent superblock'; $FE: s:='SpeedStor > 1024 cyl или LANstep или IBM PS/2 IML (Initial Microcode Load) partition, located at the end of the disk или Windows NT Disk Administrator hidden partition или Linux Logical Volume Manager partition (old)'; $FF: s:='Xenix Bad Block Table'; end; DecodeSystemIndicator:=s; end; function TForm1.GetDriveInfo(DriveNumber: Byte; var DriveInfo: TDriveInfo; StartingSector: DWORD; BytesPerSector: DWORD = 512): Boolean; var buf: array of byte; CurExPartOffset: DWORD; i: byte; begin SetLength(buf,BytesPerSector); // читаем сектор в буфер if ReadSectors(DriveNumber,MainExPartOffset+StartingSector,1,@buf[0]) = 0 then begin Result := False; Exit; end; // заполняем MBR move(buf[0],DriveInfo.MBR,sizeof(Tmbr)); // заполняем структуру DriveInfo.PartitionTable move(buf[PartitionTableOffset],DriveInfo.PartitionTable,SizeOf(TPartitionTable)); // заполняем сигнатуру move(buf[$1FE],DriveInfo.Signature,SizeOf(DriveInfo.Signature)); 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,BytesPerSector); end else DriveInfo.LogicalDrives[i] := nil; end;
Функцию ReadSectors Вы найдете тут.
Ну и понеслось
Код Delphi:
GetDriveInfo(Drive,DriveInfo,0,DiskGeometry.BytesPerSector); ToLog('==Partition table=='); for i:=0 to length(DriveInfo.PartitionTable)-1 do begin if (DriveInfo.PartitionTable[i].SystemIndicator>0) then begin ToLog('>>PT'+IntToStr(i)); if (DriveInfo.PartitionTable[i].BootIndicator=$80) then ToLog('>>>Загрузочный раздел ('+IntToStr(DriveInfo.PartitionTable[i].BootIndicator)+')') else ToLog('>>>Незагрузочный раздел ('+IntToStr(DriveInfo.PartitionTable[i].BootIndicator)+')'); ToLog('>>>Начальная поверхность: '+IntToStr(DriveInfo.PartitionTable[i].StartingHead)); ToLog('>>>Начальные цилиндр и сектор: '+IntToStr(DriveInfo.PartitionTable[i].StartingCylAndSect)); ToLog('>>>Системный индикатор: '+IntToStr(DriveInfo.PartitionTable[i].SystemIndicator)+' ('+DecodeSystemIndicator(DriveInfo.PartitionTable[i].SystemIndicator)+')'); ToLog('>>>Конечная поверхность: '+IntToStr(DriveInfo.PartitionTable[i].EndingHead)); ToLog('>>>Конечные цилиндр и сектор: '+IntToStr(DriveInfo.PartitionTable[i].EndingCylAndSect)); ToLog('>>>Начальный сектор: '+IntToStr(DriveInfo.PartitionTable[i].StartingSector)); ToLog('>>>Число секторов: '+IntToStr(DriveInfo.PartitionTable[i].NumberOfSects)); // Развернуть логические диски if (DriveInfo.LogicalDrives[i]<>nil) then begin ToLog('===Логический диск '+IntToStr(I)+'==='); for i1:= 0 to length(DriveInfo.LogicalDrives[i].PartitionTable)-1 do begin if (DriveInfo.LogicalDrives[i].PartitionTable[i1].SystemIndicator>0) then begin ToLog('>>>>PT'+IntToStr(i1)); if (DriveInfo.LogicalDrives[i].PartitionTable[i1].BootIndicator=$80) then ToLog('>>>>>Загрузочный раздел ('+IntToStr(DriveInfo.LogicalDrives[i].PartitionTable[i1].BootIndicator)+')') else ToLog('>>>>>Незагрузочный раздел ('+IntToStr(DriveInfo.LogicalDrives[i].PartitionTable[i1].BootIndicator)+')'); ToLog('>>>>>Начальная поверхность: '+IntToStr(DriveInfo.LogicalDrives[i].PartitionTable[i1].StartingHead)); ToLog('>>>>>Начальные цилиндр и сектор: '+IntToStr(DriveInfo.LogicalDrives[i].PartitionTable[i1].StartingCylAndSect)); ToLog('>>>>>Системный индикатор: '+IntToStr(DriveInfo.LogicalDrives[i].PartitionTable[i1].SystemIndicator)+' ('+DecodeSystemIndicator(DriveInfo.LogicalDrives[i].PartitionTable[i1].SystemIndicator)+')'); ToLog('>>>>>Конечная поверхность: '+IntToStr(DriveInfo.LogicalDrives[i].PartitionTable[i1].EndingHead)); ToLog('>>>>>Конечные цилиндр и сектор: '+IntToStr(DriveInfo.LogicalDrives[i].PartitionTable[i1].EndingCylAndSect)); ToLog('>>>>>Начальный сектор: '+IntToStr(DriveInfo.LogicalDrives[i].PartitionTable[i1].StartingSector)); ToLog('>>>>>Число секторов: '+IntToStr(DriveInfo.LogicalDrives[i].PartitionTable[i1].NumberOfSects)); end; end; end; end; end;
Как вычислить DiskGeometry.BytesPerSector смотрите тут.
Оставьте свой комментарий
Войдите, чтобы оставлять комментарии
Оставить комментарий как гость