程式
//自訂型態
type
IDEREGS = record
bFeaturesReg: Byte;
bSectorCountReg: Byte;
bSectorNumberReg: Byte;
bCylLowReg: Byte;
bCylHighReg: Byte;
bDriveHeadReg: Byte;
bCommandReg: Byte;
bReserved: Byte;
end; DRIVERSTATUS = record
bDriveError: Byte;
bIDEStatus: Byte;
bReserved: array[1..2] of Byte;
dwReserved: array [1..2] of LongWord;
end;
SENDCMDOUTPARAMS = record
cBufferSize: LongWord;
DStatus: DRIVERSTATUS;
bBuffer: array[1..512] of Byte;
end;
SENDCMDINPARAMS = record
cBufferSize: LongWord;
irDriveRegs: IDEREGS;
bDriveNumber: Byte;
bReserved: array[1..3] of Byte;
dwReserved: array[1..4] of LongWord;
end;
THdInfoType = (HD_MODEL_NUMBER, HD_SERIAL_NUMBER, HD_FIRMWARE_REVISION);
// API宣告 function DeviceIoControl (hDevice: LongWord; dwIoControlCode: LongWord; lpInBuffer: Pointer; nInBufferSize: LongWord; lpOutBuffer: Pointer; nOutBufferSize: LongWord; var lpBytesReturned: LongWord; lpOverlapped: LongWord): LongWord; stdcall; external 'Kernel32';
// 取得硬碟序號
function Get_HD_Info(DrvIdx: byte; HdInfoType: THdInfoType): String;
var
ParaIn: SENDCMDINPARAMS;
ParaOut: SENDCMDOUTPARAMS;
Sno: String;
h, br: LongWord;
i, st, ed: Integer;
PlatForm: string;
procedure GetPlatForm;
var OS: OSVERSIONINFO;
begin
OS.dwOSVersionInfoSize := SizeOf(OS);
GetVersionEx(OS);
PlatForm := 'UNK';
case OS.dwPlatformId of
VER_PLATFORM_WIN32S:
PlatForm := '32S'; // Win32S
VER_PLATFORM_WIN32_WINDOWS:
begin
if OS.dwMinorVersion = 0 then
PlatForm := 'W95' // Win 95
else
PlatForm := 'W98' // Win 98
end;
VER_PLATFORM_WIN32_NT:
PlatForm := 'WNT'; // Win NT/2000
end;
end;
begin
GetPlatForm;
if Pos(PlatForm, 'WNT') > 0 then
h := CreateFile(PChar('\\.\PhysicalDrive' + IntToStr(DrvIdx)), GENERIC_READ + GENERIC_WRITE,
FILE_SHARE_READ + FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)
else if Pos(PlatForm, 'W95,W98') > 0 then
h := CreateFileA('\\.\Smartvsd', 0, 0, 0, CREATE_NEW, 0, 0)
else
Raise Exception.Create('Platform must be Win95, Win98, WinNT');
If h = 0 Then Exit;
ZeroMemory(@ParaIn, SizeOf(ParaIn));
ZeroMemory(@ParaOut, SizeOf(ParaOut));
with ParaIn do
begin
bDriveNumber := DrvIdx;
cBufferSize := 512;
With irDriveRegs do
begin
if (DrvIdx and 1) = 1 then
bDriveHeadReg := $B0
else
bDriveHeadReg := $A0;
bCommandReg := $EC;
bSectorCountReg := 1;
bSectorNumberReg := 1;
end;
end;
DeviceIoControl(h, $7C088, @ParaIn, SizeOf(ParaIn), @ParaOut, SizeOf(ParaOut), br, 0);
case HdInfoType of
HD_MODEL_NUMBER:
begin
st := 55;
ed := 94;
end;
HD_SERIAL_NUMBER:
begin
st := 21;
ed := 40;
end;
HD_FIRMWARE_REVISION:
begin
st := 47;
ed := 54;
end;
end;
i := st;
while i <= ed do
begin
if ParaOut.bBuffer[i + 1] = 0 then
break;
Sno := Sno + Chr(ParaOut.bBuffer[i + 1]);
if ParaOut.bBuffer[i] > 0 then
Sno := Sno + Chr(ParaOut.bBuffer[i]);
i := i + 2;
end;
CloseHandle(h);
Result := Trim(Sno);
end;
呼叫範例
Memo1.Lines.Add('型號:' + Get_HD_Info(0, HD_MODEL_NUMBER));
Memo1.Lines.Add('序號:' + Get_HD_Info(0, HD_SERIAL_NUMBER));
Memo1.Lines.Add('韌體版本:' + Get_HD_Info(0, HD_FIRMWARE_REVISION));
1 則留言:
殘念!
此方法只能取得 IDE 或是 SATA 硬碟的實體序號,無法取得 SCSI 硬碟的實體序號
張貼留言