Procedure ReadMBR(x: Integer; //номер устройства
OutName: String; //файл, куда записываем прочитанное
SecCount: Integer // кол-во секторов
);
const
FILE_DEVICE_DISK = 7;
METHOD_BUFFERED = 0;
FILE_ANY_ACCESS = 0;
type
_MEDIA_TYPE = DWORD;
_DISKG_GEOMETRY = packed record
Cylinders: LARGE_INTEGER;
MediaType: _MEDIA_TYPE;
TracksPerCylinder: DWORD;
SectorsPerTrack: DWORD;
BytesPerSector: DWORD;
end;
var
DiskString: String;
H,HOut: THandle;
IOCTL_DISK_GET_DRIVE_GEOMETRY: Cardinal;
DiskGeometry: _DISKG_GEOMETRY;
BytesReturned: Cardinal;
Res: BOOL;
Posit: Int64;
Buff: PChar;
BuffSize, BytesRead, BytesWritten: Cardinal;
function GetCtlCode (_DeviceType, _Function, _Method, _Access: WORD): Cardinal;
begin
Result := (_DeviceType shl 16) or (_Access shl 14)
or (_Function shl 2) or _Method;
end;
begin
DiskString := Format ('\\.\PHYSICALDRIVE%s',[IntToStr(x)]); // x -- номер привода
// DiskString := Format ('\\.\%s',[DrCh+':']);// DrCh -- Буква логического диска... если нужно читать по файловой системе
// создаем "файл" - раздел
H := CreateFile(
PChar(DiskString),
GENERIC_READ,
FILE_SHARE_WRITE,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
if H <> 0 then
begin
// определяем геометрию диска
IOCTL_DISK_GET_DRIVE_GEOMETRY :=
GetCtlCode(FILE_DEVICE_DISK,0,METHOD_BUFFERED,FILE_ANY_ACCESS);
Res := DeviceIoControl(
H,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
nil,
0,
@DiskGeometry,
SizeOf(DiskGeometry),
BytesReturned,
nil
);
// если определили...
if Res then
begin
// выделяем буфер под чтение одного сектора
BuffSize := SecCount * DiskGeometry.BytesPerSector;
Buff := AllocMem(BuffSize);
//Перемещаемся в конец раздела//!!!!!!!!!!!!!!Уже не помню для чего!!!!!!!!!!!
//posit:=GetTotalDiskSpace('C:\');
// FileSeek(H,Posit-200,0);
// читаем нулевой сектор
ReadFile (H, Buff^, BuffSize, BytesRead, nil);
// создаем файл для записи
HOut := CreateFile(
PChar(OutName),
GENERIC_WRITE,
FILE_SHARE_READ,
nil,
CREATE_ALWAYS,
FILE_ATTRIBUTE_ARCHIVE,
0
);
// если файл создался
if HOut <> 0 then
begin
// записываем в него наш буфер
WriteFile (HOut, Buff^, SecCount * DiskGeometry.BytesPerSector, BytesWritten, nil);
//закрываем файл для записи
CloseHandle (HOut);
end;
end;
// особобождаем буфер
FreeMem(Buff);
// закрываем файл, открытый для чтения ("раздел")
CloseHandle(H);
end;
end;