如何用DELPHI读出硬盘的出厂物理序列号,和如何读出硬盘格式化的序列号(100分)

  • 主题发起人 主题发起人 人生55555
  • 开始时间 开始时间

人生55555

Unregistered / Unconfirmed
GUEST, unregistred user!
请教:用DELPHI编程时,用哪个函数可以直接读出如何用DELPHI读出硬盘的出厂物理序列号,和如何读出硬盘格式化的序列号?
 
//读硬盘序列号<br><br>function GetIdeSerialNumber: pchar;<br>&nbsp; const IDENTIFY_BUFFER_SIZE = 512;<br>type<br>&nbsp; &nbsp;TIDERegs = packed record<br>&nbsp; &nbsp; &nbsp;bFeaturesReg: BYTE; // Used for specifying SMART "commands".<br>&nbsp; &nbsp; &nbsp;bSectorCountReg: BYTE; // IDE sector count register<br>&nbsp; &nbsp; &nbsp;bSectorNumberReg: BYTE; // IDE sector number register<br>&nbsp; &nbsp; &nbsp;bCylLowReg: BYTE; // IDE low order cylinder value<br>&nbsp; &nbsp; &nbsp;bCylHighReg: BYTE; // IDE high order cylinder value<br>&nbsp; &nbsp; &nbsp;bDriveHeadReg: BYTE; // IDE drive/head register<br>&nbsp; &nbsp; &nbsp;bCommandReg: BYTE; // Actual IDE command.<br>&nbsp; &nbsp; &nbsp;bReserved: BYTE; // reserved for future use. Must be zero.<br>&nbsp; end;<br>&nbsp; TSendCmdInParams = packed record<br>&nbsp; &nbsp; // Buffer size in bytes<br>&nbsp; &nbsp; cBufferSize: DWORD;<br>&nbsp; &nbsp; // Structure with drive register values.<br>&nbsp; &nbsp; irDriveRegs: TIDERegs;<br>&nbsp; &nbsp; // Physical drive number to send command to (0,1,2,3).<br>&nbsp; &nbsp; bDriveNumber: BYTE;<br>&nbsp; &nbsp; bReserved: array[0..2] of Byte;<br>&nbsp; &nbsp; dwReserved: array[0..3] of DWORD;<br>&nbsp; &nbsp; bBuffer: array[0..0] of Byte; // Input buffer.<br>&nbsp; end;<br>&nbsp; TIdSector = packed record<br>&nbsp; &nbsp; wGenConfig: Word;<br>&nbsp; &nbsp; wNumCyls: Word;<br>&nbsp; &nbsp; wReserved: Word;<br>&nbsp; &nbsp; wNumHeads: Word;<br>&nbsp; &nbsp; wBytesPerTrack: Word;<br>&nbsp; &nbsp; wBytesPerSector: Word;<br>&nbsp; &nbsp; wSectorsPerTrack: Word;<br>&nbsp; &nbsp; wVendorUnique: array[0..2] of Word;<br>&nbsp; &nbsp; sSerialNumber: array[0..19] of CHAR;<br>&nbsp; &nbsp; wBufferType: Word;<br>&nbsp; &nbsp; wBufferSize: Word;<br>&nbsp; &nbsp; wECCSize: Word;<br>&nbsp; &nbsp; sFirmwareRev: array[0..7] of Char;<br>&nbsp; &nbsp; sModelNumber: array[0..39] of Char;<br>&nbsp; &nbsp; wMoreVendorUnique: Word;<br>&nbsp; &nbsp; wDoubleWordIO: Word;<br>&nbsp; &nbsp; wCapabilities: Word;<br>&nbsp; &nbsp; wReserved1: Word;<br>&nbsp; &nbsp; wPIOTiming: Word;<br>&nbsp; &nbsp; wDMATiming: Word;<br>&nbsp; &nbsp; wBS: Word;<br>&nbsp; &nbsp; wNumCurrentCyls: Word;<br>&nbsp; &nbsp; wNumCurrentHeads: Word;<br>&nbsp; &nbsp; wNumCurrentSectorsPerTrack: Word;<br>&nbsp; &nbsp; ulCurrentSectorCapacity: DWORD;<br>&nbsp; &nbsp; wMultSectorStuff: Word;<br>&nbsp; &nbsp; ulTotalAddressableSectors: DWORD;<br>&nbsp; &nbsp; wSingleWordDMA: Word;<br>&nbsp; &nbsp; wMultiWordDMA: Word;<br>&nbsp; &nbsp; bReserved: array[0..127] of BYTE;<br>&nbsp; end;<br>&nbsp; PIdSector = ^TIdSector;<br>&nbsp; TDriverStatus = packed record<br>&nbsp; &nbsp; // 驱动器返回的错误代码,无错则返回0<br>&nbsp; &nbsp; bDriverError: Byte;<br>&nbsp; &nbsp; // IDE出错寄存器的内容,只有当bDriverError 为 SMART_IDE_ERROR 时有效<br>&nbsp; &nbsp; bIDEStatus: Byte;<br>&nbsp; &nbsp; bReserved: array[0..1] of Byte;<br>&nbsp; &nbsp; dwReserved: array[0..1] of DWORD;<br>&nbsp; end;<br>&nbsp; TSendCmdOutParams = packed record<br>&nbsp; &nbsp; // bBuffer的大小<br>&nbsp; &nbsp; cBufferSize: DWORD;<br>&nbsp; &nbsp; // 驱动器状态<br>&nbsp; &nbsp; DriverStatus: TDriverStatus;<br>&nbsp; &nbsp; // 用于保存从驱动器读出的数据的缓冲区,实际长度由cBufferSize决定<br>&nbsp; &nbsp; bBuffer: array[0..0] of BYTE;<br>&nbsp; end;<br>var<br>&nbsp; hDevice: Thandle;<br>&nbsp; cbBytesReturned: DWORD;<br>&nbsp; SCIP: TSendCmdInParams;<br>&nbsp; aIdOutCmd: array[0..(SizeOf(TSendCmdOutParams) + IDENTIFY_BUFFER_SIZE-1)-1] of Byte;<br>&nbsp; IdOutCmd: TSendCmdOutParams absolute aIdOutCmd;<br>procedure ChangeByteOrder(var Data; Size: Integer);<br>var<br>&nbsp; ptr: Pchar;<br>&nbsp; i: Integer;<br>&nbsp; c: Char;<br>begin<br>&nbsp; ptr := @Data;<br>&nbsp; for I := 0 to (Size shr 1) - 1 do begin<br>&nbsp; &nbsp; c := ptr^;<br>&nbsp; &nbsp; ptr^ := (ptr + 1)^;<br>&nbsp; &nbsp; (ptr + 1)^ := c;<br>&nbsp; &nbsp; Inc(ptr, 2);<br>&nbsp; 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>//网上找的,测试过可以用
 
楼上的答案太正确了,我试过了,<br>我在网上一直都没有找到Delphi的代码,<br>只找到了C++的代码。<br>现在好了,谢谢。
 
读出硬盘格式化后的序列号<br>function GetDiskSerialNo(): string;<br>var<br>&nbsp; VolumeSerialNumber : DWORD;<br>&nbsp; MaximumComponentLength : DWORD;<br>&nbsp; FileSystemFlags : DWORD;<br>&nbsp; DriveID: char;<br>begin<br>&nbsp; &nbsp; result := '';<br>&nbsp; &nbsp; DriveID := 'C';<br>&nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; &nbsp; GetVolumeInformation(PChar(DriveID + ':/'),<br>&nbsp; &nbsp; &nbsp; &nbsp; nil, 0, @VolumeSerialNumber,<br>&nbsp; &nbsp; &nbsp; &nbsp; MaximumComponentLength,<br>&nbsp; &nbsp; &nbsp; &nbsp; FileSystemFlags, nil, 0);<br>&nbsp; &nbsp; &nbsp; &nbsp; result := IntToStr(VolumeSerialNumber);<br>&nbsp; &nbsp; except<br>&nbsp; &nbsp; end;<br>end;
 
读出来又有啥用
 
lxw5214的代码只能用在windows2003以下的系统中,win2003以上的系统不能用,我一直在用这段代码,不过在win2003以上的系统必须修改
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部