//读硬盘序列号<br><br>function GetIdeSerialNumber: pchar;<br> const IDENTIFY_BUFFER_SIZE = 512;<br>type<br> TIDERegs = packed record<br> bFeaturesReg: BYTE; // Used for specifying SMART "commands".<br> bSectorCountReg: BYTE; // IDE sector count register<br> bSectorNumberReg: BYTE; // IDE sector number register<br> bCylLowReg: BYTE; // IDE low order cylinder value<br> bCylHighReg: BYTE; // IDE high order cylinder value<br> bDriveHeadReg: BYTE; // IDE drive/head register<br> bCommandReg: BYTE; // Actual IDE command.<br> bReserved: BYTE; // reserved for future use. Must be zero.<br> end;<br> TSendCmdInParams = packed record<br> // Buffer size in bytes<br> cBufferSize: DWORD;<br> // Structure with drive register values.<br> irDriveRegs: TIDERegs;<br> // Physical drive number to send command to (0,1,2,3).<br> bDriveNumber: BYTE;<br> bReserved: array[0..2] of Byte;<br> dwReserved: array[0..3] of DWORD;<br> bBuffer: array[0..0] of Byte; // Input buffer.<br> end;<br> TIdSector = packed record<br> wGenConfig: Word;<br> wNumCyls: Word;<br> wReserved: Word;<br> wNumHeads: Word;<br> wBytesPerTrack: Word;<br> wBytesPerSector: Word;<br> wSectorsPerTrack: Word;<br> wVendorUnique: array[0..2] of Word;<br> sSerialNumber: array[0..19] of CHAR;<br> wBufferType: Word;<br> wBufferSize: Word;<br> wECCSize: Word;<br> sFirmwareRev: array[0..7] of Char;<br> sModelNumber: array[0..39] of Char;<br> wMoreVendorUnique: Word;<br> wDoubleWordIO: Word;<br> wCapabilities: Word;<br> wReserved1: Word;<br> wPIOTiming: Word;<br> wDMATiming: Word;<br> wBS: Word;<br> wNumCurrentCyls: Word;<br> wNumCurrentHeads: Word;<br> wNumCurrentSectorsPerTrack: Word;<br> ulCurrentSectorCapacity: DWORD;<br> wMultSectorStuff: Word;<br> ulTotalAddressableSectors: DWORD;<br> wSingleWordDMA: Word;<br> wMultiWordDMA: Word;<br> bReserved: array[0..127] of BYTE;<br> end;<br> PIdSector = ^TIdSector;<br> TDriverStatus = packed record<br> // 驱动器返回的错误代码,无错则返回0<br> bDriverError: Byte;<br> // IDE出错寄存器的内容,只有当bDriverError 为 SMART_IDE_ERROR 时有效<br> bIDEStatus: Byte;<br> bReserved: array[0..1] of Byte;<br> dwReserved: array[0..1] of DWORD;<br> end;<br> TSendCmdOutParams = packed record<br> // bBuffer的大小<br> cBufferSize: DWORD;<br> // 驱动器状态<br> DriverStatus: TDriverStatus;<br> // 用于保存从驱动器读出的数据的缓冲区,实际长度由cBufferSize决定<br> bBuffer: array[0..0] of BYTE;<br> end;<br>var<br> hDevice: Thandle;<br> cbBytesReturned: DWORD;<br> SCIP: TSendCmdInParams;<br> aIdOutCmd: array[0..(SizeOf(TSendCmdOutParams) + IDENTIFY_BUFFER_SIZE-1)-1] of Byte;<br> IdOutCmd: TSendCmdOutParams absolute aIdOutCmd;<br>procedure ChangeByteOrder(var Data; Size: Integer);<br>var<br> ptr: Pchar;<br> i: Integer;<br> c: Char;<br>begin<br> ptr := @Data;<br> for I := 0 to (Size shr 1) - 1 do begin<br> c := ptr^;<br> ptr^ := (ptr + 1)^;<br> (ptr + 1)^ := c;<br> Inc(ptr, 2);<br> end;<br>end;<br>begin<br>Result := ''; // 如果出错则返回空串<br>if SysUtils.Win32Platform = VER_PLATFORM_WIN32_NT then begin // Windows NT, Windows 2000<br>// 提示! 改变名称可适用于其它驱动器,如第二个驱动器: '//./PhysicalDrive1/'<br>hDevice := CreateFile('//./PhysicalDrive0', GENERIC_READ or GENERIC_WRITE,<br>FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);<br>end else // Version Windows 95 OSR2, Windows 98<br>hDevice := CreateFile('//./SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0);<br>if hDevice = INVALID_HANDLE_VALUE then Exit;<br>try<br>FillChar(SCIP, SizeOf(TSendCmdInParams) - 1, #0);<br>FillChar(aIdOutCmd, SizeOf(aIdOutCmd), #0);<br>cbBytesReturned := 0;<br>// Set up data structures for IDENTIFY command.<br>with SCIP do begin<br>cBufferSize := IDENTIFY_BUFFER_SIZE;<br>// bDriveNumber := 0;<br>with irDriveRegs do begin<br>bSectorCountReg := 1;<br>bSectorNumberReg := 1;<br>// if Win32Platform=VER_PLATFORM_WIN32_NT then bDriveHeadReg := $A0<br>// else bDriveHeadReg := $A0 or ((bDriveNum and 1) shl 4);<br>bDriveHeadReg := $A0;<br>bCommandReg := $EC;<br>end;<br>end;<br>if not DeviceIoControl(hDevice, $0007C088, @SCIP, SizeOf(TSendCmdInParams) - 1,<br>@aIdOutCmd, SizeOf(aIdOutCmd), cbBytesReturned, nil) then Exit;<br>finally<br>CloseHandle(hDevice);<br>end;<br>with PIdSector(@IdOutCmd.bBuffer)^ do begin<br>ChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber));<br>(Pchar(@sSerialNumber) + SizeOf(sSerialNumber))^:= #0;<br>Result := Pchar(@sSerialNumber);<br>end;<br>end;<br>//网上找的,测试过可以用