function GetHarddiskID(HarddiskID: Byte=0):
String;
type
TIDERegs =
packed record
bFeaturesReg : BYTE;
// Used for specifying SMART "commands".
bSectorCountReg : BYTE;
// IDE sector count register
bSectorNumberReg : BYTE;
// IDE sector number register
bCylLowReg : BYTE;
// IDE low order cylinder value
bCylHighReg : BYTE;
// IDE high order cylinder value
bDriveHeadReg : BYTE;
// IDE drive/head register
bCommandReg : BYTE;
// Actual IDE command.
bReserved : BYTE;
// reserved for future use. Must be zero.
end;
TSendCmdInParams =
packed record
cBufferSize : DWORD;
// Buffer size in bytes
irDriveRegs : TIDERegs;
// Structure with drive register values.
bDriveNumber : BYTE;
// Physical drive number to send command to (0,1,2,3).
bReserved :
Array[0..2]
of Byte;
// Reserved for future expansion.
dwReserved :
Array[0..3]
of DWORD;
// For future use.
bBuffer :
Array[0..0]
of Byte;
// Input buffer.
end;
TDriverStatus =
packed record
bDriverError : Byte;
bIDEStatus : Byte;
bReserved :
Array[0..1]
of Byte;
dwReserved :
Array[0..1]
of DWORD;
end;
TSendCmdOutParams =
packed record
cBufferSize : DWORD;
DriverStatus : TDriverStatus;
bBuffer :
Array[0..0]
of BYTE;
end;
TIdSector =
packed record
all:
Array[0..254]
of Char;
end;
const
DFP_RECEIVE_DRIVE_DATA = $0007c088;
IDENTIFY_BUFFER_SIZE = 512;
BufferSize = SizeOf(TSendCmdOutParams)+IDENTIFY_BUFFER_SIZE-1;
IDE_ID_FUNCTION = $
EC;
CAP_IDE_ID_FUNCTION = 1;
var SCIP : TSendCmdInParams;
Buffer :
Array [0..BufferSize-1]
of Byte;
SCOP : TSendCmdOutParams
absolute Buffer;
dwBytesReturned : DWORD;
LBool: LongBool;
hdevice: THandle;
IdSectorSize: Integer;
idsector: TIdSector;
LGiveback:
String;
LCount: Integer;
LChar: Char;
begin
FillChar(idSector, sizeof(idsector), #0);
FillChar(SCIP,SizeOf(TSendCmdInParams)-1,#0);
FillChar(Buffer,BufferSize,#0);
dwBytesReturned := 0;
// Set up data structures for IDENTIFY command.
with SCIP
do
begin
cBufferSize := IDENTIFY_BUFFER_SIZE;
bDriveNumber := 0;
with irDriveRegs
do
begin
bFeaturesReg := 0;
bSectorCountReg := 1;
bSectorNumberReg := 1;
bCylLowReg := 0;
bCylHighReg := 0;
bDriveHeadReg := $A0
or ((0
and 1)
shl 4);
bCommandReg := IDE_ID_FUNCTION;
// The command can either be IDE identify or ATAPI identify.
end;
end;
hDevice := CreateFile( PChar('
\\.\PhysicalDrive' + IntToStr(HarddiskID)), GENERIC_READ
or GENERIC_WRITE, FILE_SHARE_READ
or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, 0, 0 );
LBool := DeviceIoControl(hDevice, DFP_RECEIVE_DRIVE_DATA, @SCIP, SizeOf(TSendCmdInParams)-1, @SCOP, BufferSize, dwBytesReturned,
nil );
if LBool
then
begin
IDSectorSize := sizeof(IDSector);
if IdSectorSize > 0
then
System.Move(SCOP.bBuffer,IdSector,IdSectorSize);
end;
CloseHandle(hDevice);
LGiveback := '
';
for LCount := 0
to 19
do
begin
//if idSector.all[20 + LCount] <> ' ' then
LGiveback := LGiveback + idSector.all[20 + LCount];
end;
for LCount := 20
downto 1
do
if LCount
mod 2 = 0
then
begin
LChar := LGiveback[LCount];
LGiveback[LCount] := LGiveback[LCount-1];
LGiveback[LCount-1] := LChar;
end;
result := Trim(LGiveback);
end;