Editați-vă discul

// Drive - numărul discului (numerotarea de la zero).

hFile: = CreateFile (PChar ( '\\ \ PhysicalDrive' + IntToStr (Drive)), GENERIC_READ, FILE_SHARE_READ + FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0,0);






dacă hFile = INVALID_HANDLE_VALUE apoi Exit;

Astfel, putem trata un disc fizic ca un fișier mare.
Al doilea lucru de făcut este să obțineți informații despre geometria discului.

const IOCTL_DISK_GET_DRIVE_GEOMETRY = 70000 $;

tip
TDiskGeometrie = înregistrare în ambalaj
Cilindri: Int64; // numărul
cilindri
MediaType: DWORD; // tip de mediu
TracksPerCylinder: DWORD; // piese pe cilindru
SectorsPerTrack: DWORD; // sectoarele de pe pistă
BytesPerSector: DWORD; // octeți în sector
se încheie;

Rezultat: = DeviceIoControl (hFile, IOCTL_DISK_GET_DRIVE_GEOMETRY, zero, 0,
@ DiskGeometry, SizeOf (TDiskGeometry), junk, zero) și (junk = SizeOf (TDiskGeometry));

Funcția returnează True dacă operația a avut succes și False altfel.
cazul.

Acum puteți începe să determinați locația unităților logice pe
hard disk. Trebuie să începeți acest lucru prin citirea sectorului zero al discului fizic.
Acesta conține MBR (Master Boot Record), precum și tabela de partiții. Apropo, cred,
Va fi interesant să salvați conținutul MBR într-un fișier și să vedeți programul de descărcare
un fel de dezastru. Dar în prezent suntem interesați doar de masa de partiționare.

Acest tabel este localizat în sector cu offsetul $ 1be și este alcătuit din patru
elemente identice, fiecare dintre acestea descriind o secțiune:

TPartitionTableEntry = înregistrare în ambalaj
BootIndicator: Byte; // $ 80, dacă partiția activă (boot)
StartHead: Byte;
StartingCylAndSect: Word;
SystemIndicator: Byte;
EndingHead: Byte;
EndingCylAndSect: Word;
StartSector: DWORD; // sectorul inițial
NumberOfSects: DWORD; // numărul de sectoare
se încheie;

În consecință, tabela de partiționare poate fi reprezentată ca o matrice:

TPartitionTable = matrice împachetată [0..3] din TPartitionTableEntry;

Exemple de valori ale câmpului SystemIndicator:
01 - FAT12
04 - FAT16
05 - EXTENDED
06 - FAT16
07 - NTFS
0B - FAT32
0F - EXTENDED

Acum puteți începe să analizați structura discurilor logice. imediat
(și în viitor) vom avea nevoie de funcția ReadSectors.

// deoarece discul pentru noi este un fișier mare, apoi să mergem pe el
// folosind SetFilePointer aveți nevoie de aritmetică de 64 biți

funcția __Mul (a, b: DWORD; var HiDWORD: DWORD): DWORD; // Result = LoDWORD
asm
mul edx
mov [ecx], edx
se încheie;

funcție ReadSectors (DriveNumber: Byte; StartingSector, SectorCount: DWORD;
Tampon: Pointer; BytesPerSector: DWORD = 512): DWORD;
var
hFile: Thandle;
br, TmpLo, TmpHi: DWORD;
începe
Rezultat: = 0;
hFile: = CreateFile (PChar ('\\. \ PhysicalDrive' + IntToStr (DriveNumber)),






GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
dacă hFile = INVALID_HANDLE_VALUE apoi Exit;
TmpLo: = __Mul (PornireSector, BytesPerSector, TmpHi);
dacă SetFilePointer (hFile, TmpLo, @ TmpHi, FILE_BEGIN) = TmpLo atunci
începe
SectorCount: = SectorCount * BytesPerSector;
dacă nu ReadFile (hFile, Buffer ^, SectorCount, br, nil) apoi Exit;
Rezultat: = br;
se încheie;
CloseHandle (hFile);
se încheie;

Și, în același timp, funcția de scriere:

funcția WriteSectors (DriveNumber: Byte; StartingSector, SectorCount: DWORD;
Tampon: Pointer; BytesPerSector: DWORD = 512): DWORD;
var
hFile: Thandle;
bw, TmpLo, TmpHi: DWORD;
începe
Rezultat: = 0;
hFile: = CreateFile (PChar ('\\. \ PhysicalDrive' + IntToStr (DriveNumber)),
GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
dacă hFile = INVALID_HANDLE_VALUE apoi Exit;
TmpLo: = __Mul (PornireSector, BytesPerSector, TmpHi);
dacă SetFilePointer (hFile, TmpLo, @ TmpHi, FILE_BEGIN) = TmpLo atunci
începe
SectorCount: = SectorCount * BytesPerSector;
dacă nu WriteFile (hFile, Buffer ^, SectorCount, bw, nil) apoi Exit;
Rezultat: = greutate corporală;
se încheie;
CloseHandle (hFile);
se încheie;

PDriveInfo = ^ TDriveInfo;
TDriveInfo = înregistrare
PartitionTable: TPartitionTable;
LogicalDrives: matrice [0..3] a PDriveInfo;
se încheie;

Ei bine, acum codul în sine:

const
PartitionTableOffset = $ 1be;
ExtendedPartitions = [5, $ f];

var
MainExPartOffset: DWORD = 0;

funcția GetDriveInfo (DriveNumber: Byte; DriveInfo: PDriveInfo;
StartSector: DWORD; BytesPerSector: DWORD = 512): Boolean;
var
buf: o mulțime de octeți;
CurExPartOffset: DWORD;
i: Integer;
începe
SetLength (buf, BytesPerSector);
// citiți sectorul în tampon
dacă ReadSectors (DriveNumber, MainExPartOffset + StartingSector, 1, @ buf [0]) = 0 atunci
începe
Rezultat: = False;
Finalize (buf);
Exit;
se încheie;
// completați structura DriveInfo.PartitionTable
Mutați (buf [PartitionTableOffset], DriveInfo.PartitionTable, SizeOf (TPartitionTable));
Finalize (buf); // tamponul nu mai este necesar

Rezultat: = Adevărat;
pentru i: = 0 la 3 nu // pentru fiecare intrare din tabela de partiții
dacă DriveInfo.PartitionTable [i] .SystemIndicator în ExtendedPartitions apoi
începe
Nou (DriveInfo.LogicalDrives [I]);
dacă MainExPartOffset = 0 atunci
începe
MainExPartOffset: = DriveInfo.PartitionTable [I] .StartingSector;
CurExPartOffset: = 0;
incheia altul CurExPartOffset: = DriveInfo.PartitionTable [I] .StartingSector;
Rezultat: = Rezultat și GetDriveInfo (DriveNumber, DriveInfo.LogicalDrives [I],
CurExPartOffset);
incheie altul DriveInfo.LogicalDrives [I]: = zero;
se încheie;

Funcția umple structura DriveInfo și se întoarce
Adevărat dacă operația a avut succes sau False altfel.
Acum avem informații utile despre secțiuni ca fiind inițiale
sector, numărul total de sectoare, precum și sistemul de fișiere.
În sectorul zero al fiecărei partiții principale se află parametrul BIOS
Bloc care conține informații, cum ar fi numele sistemului de fișiere, numărul de sectoare din
cluster, etc. Și, de asemenea, programul de încărcător (salvați sectorul în fișier și arătați
dezastrul dvs. favorit).

Din fericire, în Delphi, au deja (IntToHex și StrToInt) și rămâne doar
utilizat corect. StrToInt poate fi folosit pentru a converti un șir,
conținând un număr hexazecimal în Integer, dacă adăugați un $ în față.

Codul complet al programului care demonstrează ceea ce este descris în articol
este atașat. Programul poate afișa structura discurilor logice, poate afișa conținutul specificat
de asemenea, vă permite să salvați depozitul sectorului selectat într-un fișier. punerea în aplicare
Am lăsat posibilitatea de a edita un disc în program ca temă.

Pentru a accesa discul fizic, am deschis dispozitivul \\. \ PHYSICALDRIVE,
și-a dezasamblat structura. A fost posibil să se facă mai ușor. Deschide imediat logic
discuri (\\. \ C :, \\. \ D: etc), dar cu această opțiune am fi trecut cu vederea unele
zona discului. De exemplu, zonele MBR și zonele neimprimate ale discului. Și, în general, de la sarcină depinde,
cu ceea ce trebuie să lucrați.

Distribuiți acest articol cu ​​prietenii dvs.:







Trimiteți-le prietenilor: