程式
//自訂型態 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 硬碟的實體序號
張貼留言