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)]);
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);
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
;