请问高手:如何利用API函数获取硬盘的序列号???(100分)

  • 主题发起人 bluecoral
  • 开始时间
见&lt;a href="Dispuser.asp?UserName=chinahawk"&gt;chinahawk&lt;/a&gt;所提的问题<br>还有:LID=95684, LID=121695<br>一定要用API吗?<br>
 
可利用API函数GetVolumeInformation,来获取某硬盘序列号。该函数具体使用<br>你可查看帮助。
 
使用API 函数deviceoncontrol,<br>如果使用win9x,则要读硬盘序列号很困难,因为win9x操作系统不允许直接操作硬件,只有进入<br>ring0,获得系统特权,才能进行操作<br>网上有这方面的资料,不过没有源吗,如果你想要,与我联系,我有delphi写的去硬盘序列号<br>程序<br>
 
tangdongping: &nbsp;我想找源码!我该怎么联系你呢?<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
 
我做过,用GetVolumeInformation 就可以搞定.<br>
 
呵呵,这里有:<br>取得硬盘序列号:<br>Function GetHardDiskSerieNummer : string;<br>var<br>&nbsp; Teller &nbsp; &nbsp; &nbsp;: integer;<br>&nbsp; Lus &nbsp; &nbsp; &nbsp; &nbsp; : integer;<br>&nbsp; SerieNummer : array[0..24] of char;<br>begin<br>&nbsp; result := '';<br>&nbsp; Teller := 1;<br>&nbsp; for Lus := 1 to 8 do<br>&nbsp; begin<br>&nbsp; &nbsp;SerieNummer[Teller] := chr((HardDiskGegevens[10+Lus] div 256 ));<br>&nbsp; &nbsp;inc(Teller);<br>&nbsp; &nbsp;SerieNummer[Teller] := CHR((HardDiskGegevens[10+Lus] mod 256 ));<br>&nbsp; &nbsp;inc(Teller);<br>&nbsp; end;<br>&nbsp; result := SerieNummer;<br>&nbsp;end;<br>老弟,以后提问题前,先搜索一下吧,不信,你就“硬盘”两个字搜索一下,肯定能找到<br>你要的东西,这样可以节省你一点money~~:)<br><br>
 
这类问题要成灾了。
 
function tform1.getnumber(drive:string):string;<br>var volumer,temp:dword;<br>begin<br>getvolumerinformation(pchar(drive),nil,0,@volumer,temp,temp,nil,0);<br>getnumber:=copy(inttohex(volumer,0),1,8);<br>end;
 
看我的回答,应该是最全面的<br>http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?LID=508394<br><br>欢迎访问vcl控件讨论区: vcl.xilubbs.com<br>控件存放地(刚开业):vcl.4y4y.net
 
来自:fatman 时间:01-1-10 10:11:21 ID:436157 &nbsp;<br>下面是一位前辈写的代码<br>IDE.PAS (IDE硬盘参数检测)<br>&nbsp; ?Programmed by: 刘 杰 &nbsp; <br>&nbsp; ?nbsp;Designed &nbsp; &nbsp; : 04/11/92 <br>&nbsp; ?nbsp;Last modified: 01/26/95<br>&nbsp; ?请使用 Turbo Pascal 7.0 编译. <br><br>const <br>&nbsp; &nbsp;{ read/write --------------------------- } <br>&nbsp; &nbsp;HDC_DATA &nbsp; &nbsp;= $01F0; <br>&nbsp; &nbsp;HDC_ERROR &nbsp; = $01F1; <br>&nbsp; &nbsp;HDC_SECCOU &nbsp;= $01F2; <br>&nbsp; &nbsp;HDC_SECNUM &nbsp;= $01F3; <br>&nbsp; &nbsp;HDC_CYLLOW &nbsp;= $01F4; <br>&nbsp; &nbsp;HDC_CYLHIGH = $01F5; <br>&nbsp; &nbsp;HDC_SDH &nbsp; &nbsp; = $01F6; <br>&nbsp; &nbsp;{ read --------------------------------- } <br>&nbsp; &nbsp;HDC_STATUS &nbsp;: Word = $01F7; <br>&nbsp; &nbsp;HDC_ALTSTA &nbsp;= $03F6; <br>&nbsp; &nbsp;{ write -------------------------------- } <br>&nbsp; &nbsp;HDC_COMMAND = $01F7; <br>&nbsp; &nbsp;HDC_FIXED &nbsp; = $03F6; <br>&nbsp; &nbsp;{ commands ----------------------------- } <br>&nbsp; &nbsp;HDC_COMMAND_RESTORE = $10; <br>&nbsp; &nbsp;HDC_COMMAND_SEEK &nbsp; &nbsp;= $70; <br>&nbsp; &nbsp;HDC_COMMAND_READ &nbsp; &nbsp;= $20; <br>&nbsp; &nbsp;HDC_COMMAND_WRITE &nbsp; = $30; <br>&nbsp; &nbsp;HDC_COMMAND_FORMAT &nbsp;= $50; <br>&nbsp; &nbsp;HDC_COMMAND_READVER = $90; <br>&nbsp; &nbsp;HDC_COMMAND_DIAG &nbsp; &nbsp;= $90; <br>&nbsp; &nbsp;HDC_COMMAND_SETPAR &nbsp;= $91; <br>&nbsp; &nbsp;HDC_COMMAND_WRSTACK = $E8; <br>&nbsp; &nbsp;HDC_COMMAND_RDSTACK = $E4; <br>&nbsp; &nbsp;HDC_COMMAND_READPAR = $EC; <br>&nbsp; &nbsp;HDC_COMMAND_POWER &nbsp; = $E0; <br>&nbsp; &nbsp;HDC_FIXED_IRQ &nbsp; &nbsp; &nbsp; = $02; <br>&nbsp; &nbsp;HDC_FIXED_RESET &nbsp; &nbsp; = $04; <br>&nbsp; &nbsp;HDC_STATUS_ERROR &nbsp; &nbsp;= $01; <br>&nbsp; &nbsp;HDC_STATUS_INDEX &nbsp; &nbsp;= $02; <br>&nbsp; &nbsp;HDC_STATUS_ECC &nbsp; &nbsp; &nbsp;= $04; <br>&nbsp; &nbsp;HDC_STATUS_DRQ &nbsp; &nbsp; &nbsp;= $08; <br>&nbsp; &nbsp;HDC_STATUS_COMPLETE = $10; <br>&nbsp; &nbsp;HDC_STATUS_WRFAULT &nbsp;= $20; <br>&nbsp; &nbsp;HDC_STATUS_READY &nbsp; &nbsp;= $40; <br>&nbsp; &nbsp;HDC_STATUS_BUSY &nbsp; &nbsp; = $80; <br>type <br>&nbsp; &nbsp;TIdeTypes = record <br>&nbsp; &nbsp; &nbsp; Cylinders, <br>&nbsp; &nbsp; &nbsp; Heads, <br>&nbsp; &nbsp; &nbsp; Sectors: Word; <br>&nbsp; &nbsp; &nbsp; Name: String[38]; <br>&nbsp; &nbsp;end; <br>&nbsp; &nbsp;PIdeInfo = ^TIdeInfo; <br>&nbsp; &nbsp;TIdeInfo = record <br>&nbsp; &nbsp; &nbsp; genconf, <br>&nbsp; &nbsp; &nbsp; fixcyls, <br>&nbsp; &nbsp; &nbsp; remcyls, <br>&nbsp; &nbsp; &nbsp; heads, <br>&nbsp; &nbsp; &nbsp; bytetrack, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { bytes per track } <br>&nbsp; &nbsp; &nbsp; bytesector, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ bytes per sector } <br>&nbsp; &nbsp; &nbsp; sectors, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ sectors per track } <br>&nbsp; &nbsp; &nbsp; byteisg, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ bytes intesector gap } <br>&nbsp; &nbsp; &nbsp; byteplo, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ bytes in sync } <br>&nbsp; &nbsp; &nbsp; worduniq: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ words unique status } <br>&nbsp; &nbsp; &nbsp; serial: array[1..20] of Char; <br>&nbsp; &nbsp; &nbsp; contype, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { controller type } <br>&nbsp; &nbsp; &nbsp; bufsiz, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ buffer size in 512 byte blocks } <br>&nbsp; &nbsp; &nbsp; byteecc: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ ECC bytes trasferred in read/write long &nbsp;<br>} <br>&nbsp; &nbsp; &nbsp; firmware: array[1..8] of Char; { firmware revision } <br>&nbsp; &nbsp; &nbsp; model: array[1..40] of Char; &nbsp; { model ID } <br>&nbsp; &nbsp; &nbsp; secsint, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ number of sectors transferred per inte <br>rrupt } <br>&nbsp; &nbsp; &nbsp; dblword, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ double word transfer flag } <br>&nbsp; &nbsp; &nbsp; writepro: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ write protect } <br>&nbsp; &nbsp;end; <br>const <br>&nbsp; &nbsp;IdesInDataBase = 17; <br>&nbsp; &nbsp;IdeTypes: array[1..IdesInDataBase] of TIdeTypes = <br>&nbsp; &nbsp;((Cylinders:667; &nbsp;Heads:4; &nbsp;Sectors:33; Name:'Fujitsu M2611T (42.9 MB)'), <br>&nbsp;<br>&nbsp; &nbsp; (Cylinders:667; &nbsp;Heads:8; &nbsp;Sectors:33; Name:'Fujitsu M2612T (85.9 MB)'), <br>&nbsp;<br>&nbsp; &nbsp; (Cylinders:667; &nbsp;Heads:12; Sectors:33; Name:'Fujitsu M2613T (128.9 MB)') <br>, <br>&nbsp; &nbsp; (Cylinders:667; &nbsp;Heads:16; Sectors:33; Name:'Fujitsu M2614T (171.9 MB)') <br>, <br>&nbsp; &nbsp; (Cylinders:782; &nbsp;Heads:2; &nbsp;Sectors:27; Name:'Western Digital WD93024-A ( <br>20.6 MB)'), <br>&nbsp; &nbsp; (Cylinders:782; &nbsp;Heads:4; &nbsp;Sectors:27; Name:'Western Digital WD93044-A ( <br>41.2 MB)'), <br>&nbsp; &nbsp; (Cylinders:845; &nbsp;Heads:3; &nbsp;Sectors:35; Name:'Toshiba MK232FC (45.4 MB'), <br>&nbsp;<br>&nbsp; &nbsp; (Cylinders:845; &nbsp;Heads:7; &nbsp;Sectors:35; Name:'Toshiba MK234FC (106 MB'), <br>&nbsp; &nbsp; (Cylinders:965; &nbsp;Heads:5; &nbsp;Sectors:17; Name:'Quantum ProDrive 40AT (40 M <br>B)'), <br>&nbsp; &nbsp; (Cylinders:965; &nbsp;Heads:10; Sectors:17; Name:'Quantum ProDrive 80AT (80 M <br>B)'), <br>&nbsp; &nbsp; (Cylinders:1050; Heads:2; &nbsp;Sectors:40; Name:'Teac SD-340 (41 MB)'), <br>&nbsp; &nbsp; (Cylinders:776; &nbsp;Heads:8; &nbsp;Sectors:33; Name:'Conner CP-3104 (100 MB)'), <br>&nbsp; &nbsp; (Cylinders:745; &nbsp;Heads:4; &nbsp;Sectors:28; Name:'Priam 3804M (40.7 MB)'), <br>&nbsp; &nbsp; (Cylinders:980; &nbsp;Heads:10; Sectors:17; Name:'Western Digitial Caviar AC2 <br>80 (81 MB)'), <br>&nbsp; &nbsp; (Cylinders:560; &nbsp;Heads:6; &nbsp;Sectors:26; Name:'Seagate ST157A (42 MB)'), <br>&nbsp; &nbsp; (Cylinders:732; &nbsp;Heads:8; &nbsp;Sectors:35; Name:'ALPS ELECTRIC Co.,LTD. DR31 <br>1C (102 MB)'), <br>&nbsp; &nbsp; (Cylinders:0; &nbsp; &nbsp;Heads:0; &nbsp;Sectors:0; &nbsp;Name:'')); <br>type <br>&nbsp; &nbsp;parray = ^tarray; <br>&nbsp; &nbsp;tarray = array[1..256] of Word; <br>var <br>&nbsp; &nbsp;secbuf: parray; <br>&nbsp; &nbsp;drive: Byte; <br>&nbsp; &nbsp;drv: String[1]; <br>procedure printinfo; <br>var <br>&nbsp; &nbsp;id: TIdeInfo; <br>&nbsp; &nbsp;capacity: Word; <br>&nbsp; &nbsp;types: String; <br>&nbsp; &nbsp;i: Integer; <br>&nbsp; &nbsp;function zo(const value: Byte): String; <br>&nbsp; &nbsp;begin <br>&nbsp; &nbsp; &nbsp; if Boolean(value) then <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;zo := '' <br>&nbsp; &nbsp; &nbsp; else <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;zo := 'not'; <br>&nbsp; &nbsp;end; <br>&nbsp; &nbsp;function ToStr(value: LongInt): String; <br>&nbsp; &nbsp;var <br>&nbsp; &nbsp; &nbsp; S: String; <br>&nbsp; &nbsp;begin <br>&nbsp; &nbsp; &nbsp; Str(value, S); <br>&nbsp; &nbsp; &nbsp; ToStr := S; <br>&nbsp; &nbsp;end; <br>&nbsp; &nbsp;function ConvertHex(Value: Word): String; <br>&nbsp; &nbsp;const <br>&nbsp; &nbsp; &nbsp; hexTable: array[0..15] of Char = '0123456789ABCDEF'; <br>&nbsp; &nbsp;begin <br>&nbsp; &nbsp; &nbsp; ConvertHex := hexTable[Hi(Value) shr 4] + hexTable[Hi(Value) and $f] + <br>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hexTable[Lo(Value) shr 4] + hexTable[Lo(Value) and $f]; <br>&nbsp; &nbsp;end; <br>&nbsp; &nbsp;procedure SwapBytes(var Source, Dest; Len: Byte); assembler; <br>&nbsp; &nbsp;asm <br>&nbsp; &nbsp; &nbsp; &nbsp;push &nbsp;ds <br>&nbsp; &nbsp; &nbsp; &nbsp;lds &nbsp; si, Source <br>&nbsp; &nbsp; &nbsp; &nbsp;les &nbsp; di, Dest <br>&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; cl, len <br>&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; ch, ch <br>&nbsp; &nbsp;@1: mov &nbsp; ax, ds:[si] <br>&nbsp; &nbsp; &nbsp; &nbsp;xchg &nbsp;ah, al <br>&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; es:[di], ax <br>&nbsp; &nbsp; &nbsp; &nbsp;inc &nbsp; si <br>&nbsp; &nbsp; &nbsp; &nbsp;inc &nbsp; si <br>&nbsp; &nbsp; &nbsp; &nbsp;inc &nbsp; di <br>&nbsp; &nbsp; &nbsp; &nbsp;inc &nbsp; di <br>&nbsp; &nbsp; &nbsp; &nbsp;loop &nbsp;@1 <br>&nbsp; &nbsp; &nbsp; &nbsp;pop &nbsp; &nbsp;ds <br>&nbsp; &nbsp;end; <br>begin <br>&nbsp; &nbsp;id := PIdeInfo(secbuf)^; <br>&nbsp; &nbsp;{ get disk type by characteristics } <br>&nbsp; &nbsp;i := 1; <br>&nbsp; &nbsp;while IdeTypes.Cylinders &lt;&gt; 0 do <br>&nbsp; &nbsp; &nbsp; Begin <br>&nbsp; if (IdeTypes.cylinders = id.fixcyls) and <br>&nbsp; &nbsp; &nbsp;(IdeTypes.heads = id.heads) and <br>&nbsp; &nbsp; &nbsp;(IdeTypes.sectors = id.sectors) then <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;types := IdeTypes.name; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;inc(i); <br>&nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp;{ unknown disk } <br>&nbsp; &nbsp;if (IdeTypes.cylinders = 0) then <br>&nbsp; &nbsp; &nbsp; Begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;types := ' '; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ calculate capacity in MB } <br>&nbsp; capacity := (LongInt(id.fixcyls) * id.heads * id.sectors) div 2048; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;types := types + ToStr(capacity); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;types := types + ' Mbytes'; <br>&nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp;{ swap bytes in ASCII fields except for WD disks } <br>&nbsp; &nbsp;if (i &lt;&gt; 4) and (i &lt;&gt; 5) then <br>&nbsp; &nbsp; &nbsp; Begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SwapBytes(id.serial, id.serial, 10); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SwapBytes(id.firmware, id.firmware, 4); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SwapBytes(id.model, id.model, 20); <br>&nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp;WriteLn('Drive ', drive-2, ' &nbsp; &nbsp; :', types); <br>&nbsp; &nbsp;WriteLn('Drive ID &nbsp; &nbsp;: ', ConvertHex(id.genconf)); <br>&nbsp; &nbsp;WriteLn('Cylinders &nbsp; : ', id.fixcyls{, ' ' id.remcyls, ' removables'}); <br>&nbsp; &nbsp;WriteLn('Heads &nbsp; &nbsp; &nbsp; : ', id.heads); <br>&nbsp; &nbsp;Writeln('Sectors &nbsp; &nbsp; : ', id.sectors); <br>&nbsp; &nbsp;WriteLn('Serial No. &nbsp;: ', id.serial); <br>&nbsp; &nbsp;WriteLn('Firmware &nbsp; &nbsp;: ', id.firmware); <br>&nbsp; &nbsp;WriteLn('Model &nbsp; &nbsp; &nbsp; : ', id.model); <br>{ &nbsp; WriteLn('Bytes per track &nbsp; &nbsp; &nbsp; &nbsp; : ', id.bytetrack); <br>&nbsp; &nbsp;Writeln('Bytes per sector &nbsp; &nbsp; &nbsp; &nbsp;: ', id.bytesector); <br>&nbsp; &nbsp;WriteLn('Bytes of intersector gap: ', id.byteisg); <br>&nbsp; &nbsp;Writeln('Bytes of sync &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : ', id.byteplo); <br>&nbsp; &nbsp;WriteLn('Controller type &nbsp; &nbsp; &nbsp; &nbsp; : ', id.contype);} <br>&nbsp; &nbsp;Writeln('Buffer &nbsp; &nbsp; &nbsp;: ', id.bufsiz div 2, ' KBytes'); <br>&nbsp; &nbsp;WriteLn('Bytes of ECC: ', id.byteecc); <br>end; <br>procedure readsect; assembler; <br>asm <br>{ poll DRQ } <br>@1: mov &nbsp; dx, HDC_STATUS <br>&nbsp; &nbsp; in &nbsp; &nbsp;al, dx <br>&nbsp; &nbsp; and &nbsp; al, HDC_STATUS_BUSY <br>&nbsp; &nbsp; or &nbsp; &nbsp;al, al <br>&nbsp; &nbsp; jne &nbsp; @1 <br>{ read up sector } <br>&nbsp; &nbsp; mov &nbsp; cx, 256 <br>&nbsp; &nbsp; mov &nbsp; dx, HDC_DATA <br>&nbsp; &nbsp; les &nbsp; di, secbuf <br>@2: in &nbsp; &nbsp;ax, dx <br>&nbsp; &nbsp; mov &nbsp; es:[di], ax <br>&nbsp; &nbsp; inc &nbsp; di <br>&nbsp; &nbsp; inc &nbsp; di <br>&nbsp; &nbsp; loop &nbsp;@2 <br>end; <br>function DriveValid(Drive: Char; var Drv: Byte): Boolean; assembler; <br>asm <br>&nbsp; &nbsp; mov &nbsp; ah, 19h &nbsp; &nbsp; &nbsp;{ Save the current drive in BL } <br>&nbsp; &nbsp; int &nbsp; 21h <br>&nbsp; &nbsp; mov &nbsp; bl, al <br>&nbsp; &nbsp; mov &nbsp; dl, Drive &nbsp; &nbsp;{ Select the given drive } <br>&nbsp; &nbsp; sub &nbsp; dl, 'A' <br>&nbsp; &nbsp; les &nbsp; di, DRV <br>&nbsp; &nbsp; mov &nbsp; es:[di], dl <br>&nbsp; &nbsp; mov &nbsp; ah, 0Eh <br>&nbsp; &nbsp; int &nbsp; 21h <br>&nbsp; &nbsp; mov &nbsp; ah, 19h &nbsp; &nbsp; &nbsp;{ Retrieve what DOS thinks is current } <br>&nbsp; &nbsp; int &nbsp; 21h <br>&nbsp; &nbsp; mov &nbsp; cx, 0 &nbsp; &nbsp; &nbsp; &nbsp;{ Assume false } <br>&nbsp; &nbsp; cmp &nbsp; al, dl &nbsp; &nbsp; &nbsp; { Is the current drive the given drive? } <br>&nbsp; &nbsp; jne &nbsp; @1 <br>&nbsp; &nbsp; mov &nbsp; cx, 1 &nbsp; &nbsp; &nbsp; &nbsp;{ It is, so the drive is valid } <br>&nbsp; &nbsp; mov &nbsp; dl, bl &nbsp; &nbsp; &nbsp; { Restore the old drive } <br>&nbsp; &nbsp; mov &nbsp; ah, 0eh <br>&nbsp; &nbsp; int &nbsp; 21h <br>@1: xchg &nbsp;ax, cx &nbsp; &nbsp; &nbsp; { Put the return value into AX } <br>end; <br>function CurDisk: Byte; assembler; <br>{ Returns current drive } <br>asm <br>&nbsp; &nbsp; mov &nbsp; ah, 19h <br>&nbsp; &nbsp; int &nbsp; 21h <br>end; <br>begin <br>&nbsp; &nbsp;Writeln('IDE ver 1.2 &nbsp;(c) 1995 Keenvim software workgroup, Inc.'); <br>&nbsp; &nbsp;writeln('Programmed by &nbsp;Mr. LiuJie'#13#10); <br>&nbsp; &nbsp;if ParamCount &gt; 0 then <br>&nbsp; &nbsp; &nbsp; Begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;drv := ParamStr(1); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;drv[1] := UpCase(drv[1]); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if not DriveValid(drv[1], Drive) or not (drv[1] in ['C'..'Z']) then <br>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;WriteLn('There isn''t such drive or drive invalid!'); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Halt(1); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp; &nbsp; end <br>&nbsp; &nbsp;else <br>&nbsp; &nbsp; &nbsp; drive := CurDisk; <br>&nbsp; &nbsp;{ disable interrupt from drive } <br>&nbsp; &nbsp;Port[HDC_FIXED] := HDC_FIXED_IRQ; <br>&nbsp; &nbsp;{ set up task file parameter } <br>&nbsp; &nbsp;Port[HDC_SDH] := $A0 + (drive shl 4); <br>&nbsp; &nbsp;{ issue read parameters } <br>&nbsp; &nbsp;Port[HDC_COMMAND] := HDC_COMMAND_READPAR; <br>&nbsp; &nbsp;GetMem(secbuf, SizeOf(secbuf)); <br>&nbsp; &nbsp;{ read up sector } <br>&nbsp; &nbsp;readsect; <br>&nbsp; &nbsp;{ print out info } <br>&nbsp; &nbsp;printinfo; <br>&nbsp; &nbsp;FreeMem(secbuf, SizeOf(secbuf)); <br>end. <br><br>&nbsp;<br>&nbsp;<br>嘿嘿
 
什么乱七八糟的,没有一位老兄的代码行的通
 
用GetVolumeInformation省事了<br><br>BOOL GetVolumeInformation(<br><br>&nbsp; &nbsp; LPCTSTR lpRootPathName, // address of root directory of the file system <br>&nbsp; &nbsp; LPTSTR lpVolumeNameBuffer, // address of name of the volume <br>&nbsp; &nbsp; DWORD nVolumeNameSize, // length of lpVolumeNameBuffer <br>&nbsp; &nbsp; LPDWORD lpVolumeSerialNumber, // address of volume serial number <br>&nbsp; &nbsp; LPDWORD lpMaximumComponentLength, // address of system's maximum filename length<br>&nbsp; &nbsp; LPDWORD lpFileSystemFlags, // address of file system flags <br>&nbsp; &nbsp; LPTSTR lpFileSystemNameBuffer, // address of name of file system <br>&nbsp; &nbsp; DWORD nFileSystemNameSize // length of lpFileSystemNameBuffer <br>&nbsp; &nbsp;);
 
到故纸堆里去翻吧——分先分掉
 
一个console程序;<br>在Win9x下需要有 smartvsd.vxd,把他从/windows/system/拷贝到<br>/windows/system/iosubsys/重启 <br><br>program IdeSN; <br><br>{$APPTYPE CONSOLE} <br><br>uses <br>&nbsp; Windows, <br>&nbsp; SysUtils; // only for Win32Platform and SysErrorMessage <br><br>//------------------------------------------------------------- <br>function GetIdeDiskSerialNumber : String; <br>type <br>&nbsp; TSrbIoControl = packed record <br>&nbsp; &nbsp; HeaderLength : ULONG; <br>&nbsp; &nbsp; Signature &nbsp; &nbsp;: Array[0..7] of Char; <br>&nbsp; &nbsp; Timeout &nbsp; &nbsp; &nbsp;: ULONG; <br>&nbsp; &nbsp; ControlCode &nbsp;: ULONG; <br>&nbsp; &nbsp; ReturnCode &nbsp; : ULONG; <br>&nbsp; &nbsp; Length &nbsp; &nbsp; &nbsp; : ULONG; <br>&nbsp; end; <br>&nbsp; SRB_IO_CONTROL = TSrbIoControl; <br>&nbsp; PSrbIoControl = ^TSrbIoControl; <br><br>&nbsp; TIDERegs = packed record <br>&nbsp; &nbsp; bFeaturesReg &nbsp; &nbsp; : Byte; // Used for specifying SMART "commands". <br>&nbsp; &nbsp; bSectorCountReg &nbsp;: Byte; // IDE sector count register <br>&nbsp; &nbsp; bSectorNumberReg : Byte; // IDE sector number register <br>&nbsp; &nbsp; bCylLowReg &nbsp; &nbsp; &nbsp; : Byte; // IDE low order cylinder value <br>&nbsp; &nbsp; bCylHighReg &nbsp; &nbsp; &nbsp;: Byte; // IDE high order cylinder value <br>&nbsp; &nbsp; bDriveHeadReg &nbsp; &nbsp;: Byte; // IDE drive/head register <br>&nbsp; &nbsp; bCommandReg &nbsp; &nbsp; &nbsp;: Byte; // Actual IDE command. <br>&nbsp; &nbsp; bReserved &nbsp; &nbsp; &nbsp; &nbsp;: Byte; // reserved. &nbsp;Must be zero. <br>&nbsp; end; <br>&nbsp; IDEREGS &nbsp; = TIDERegs; <br>&nbsp; PIDERegs &nbsp;= ^TIDERegs; <br><br>&nbsp; TSendCmdInParams = packed record <br>&nbsp; &nbsp; cBufferSize &nbsp;: DWORD; <br>&nbsp; &nbsp; irDriveRegs &nbsp;: TIDERegs; <br>&nbsp; &nbsp; bDriveNumber : Byte; <br>&nbsp; &nbsp; bReserved &nbsp; &nbsp;: Array[0..2] of Byte; <br>&nbsp; &nbsp; dwReserved &nbsp; : Array[0..3] of DWORD; <br>&nbsp; &nbsp; bBuffer &nbsp; &nbsp; &nbsp;: Array[0..0] of Byte; <br>&nbsp; end; <br>&nbsp; SENDCMDINPARAMS &nbsp; = TSendCmdInParams; <br>&nbsp; PSendCmdInParams &nbsp;= ^TSendCmdInParams; <br><br>&nbsp; TIdSector = packed record <br>&nbsp; &nbsp; wGenConfig &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wNumCyls &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wReserved &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wNumHeads &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wBytesPerTrack &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wBytesPerSector &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wSectorsPerTrack &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wVendorUnique &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Array[0..2] of Word; <br>&nbsp; &nbsp; sSerialNumber &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Array[0..19] of Char; <br>&nbsp; &nbsp; wBufferType &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wBufferSize &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wECCSize &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; sFirmwareRev &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Array[0..7] of Char; <br>&nbsp; &nbsp; sModelNumber &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Array[0..39] of Char; <br>&nbsp; &nbsp; wMoreVendorUnique &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wDoubleWordIO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wCapabilities &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wReserved1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wPIOTiming &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wDMATiming &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wBS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wNumCurrentCyls &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wNumCurrentHeads &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wNumCurrentSectorsPerTrack : Word; <br>&nbsp; &nbsp; ulCurrentSectorCapacity &nbsp; &nbsp;: ULONG; <br>&nbsp; &nbsp; wMultSectorStuff &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; ulTotalAddressableSectors &nbsp;: ULONG; <br>&nbsp; &nbsp; wSingleWordDMA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wMultiWordDMA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; bReserved &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Array[0..127] of Byte; <br>&nbsp; end; <br>&nbsp; PIdSector = ^TIdSector; <br><br>const <br>&nbsp; IDE_ID_FUNCTION = $EC; <br>&nbsp; IDENTIFY_BUFFER_SIZE &nbsp; &nbsp; &nbsp; = 512; <br>&nbsp; DFP_RECEIVE_DRIVE_DATA &nbsp; &nbsp; &nbsp; &nbsp;= $0007c088; <br>&nbsp; IOCTL_SCSI_MINIPORT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = $0004d008; <br>&nbsp; IOCTL_SCSI_MINIPORT_IDENTIFY &nbsp;= $001b0501; <br>&nbsp; DataSize = sizeof(TSendCmdInParams)-1+IDENTIFY_BUFFER_SIZE; <br>&nbsp; BufferSize = SizeOf(SRB_IO_CONTROL)+DataSize; <br>&nbsp; W9xBufferSize = IDENTIFY_BUFFER_SIZE+16; <br>var <br>&nbsp; hDevice : THandle; <br>&nbsp; cbBytesReturned : DWORD; <br>&nbsp; pInData : PSendCmdInParams; <br>&nbsp; pOutData : Pointer; // PSendCmdOutParams <br>&nbsp; Buffer : Array[0..BufferSize-1] of Byte; <br>&nbsp; srbControl : TSrbIoControl absolute Buffer; <br><br>&nbsp; procedure ChangeByteOrder( var Data; Size : Integer ); <br>&nbsp; var ptr : PChar; <br>&nbsp; &nbsp; &nbsp; i : Integer; <br>&nbsp; &nbsp; &nbsp; c : Char; <br>&nbsp; begin <br>&nbsp; &nbsp; ptr := @Data; <br>&nbsp; &nbsp; for i := 0 to (Size shr 1)-1 do <br>&nbsp; &nbsp; begin <br>&nbsp; &nbsp; &nbsp; c := ptr^; <br>&nbsp; &nbsp; &nbsp; ptr^ := (ptr+1)^; <br>&nbsp; &nbsp; &nbsp; (ptr+1)^ := c; <br>&nbsp; &nbsp; &nbsp; Inc(ptr,2); <br>&nbsp; &nbsp; end; <br>&nbsp; end; <br><br>begin <br>&nbsp; Result := ''; <br>&nbsp; FillChar(Buffer,BufferSize,#0); <br>&nbsp; if Win32Platform=VER_PLATFORM_WIN32_NT then <br>&nbsp; &nbsp; begin // Windows NT, Windows 2000 <br>&nbsp; &nbsp; &nbsp; // Get SCSI port handle <br>&nbsp; &nbsp; &nbsp; hDevice := CreateFile( '//./Scsi0:', <br>&nbsp; &nbsp; &nbsp; &nbsp; GENERIC_READ or GENERIC_WRITE, <br>&nbsp; &nbsp; &nbsp; &nbsp; FILE_SHARE_READ or FILE_SHARE_WRITE, <br>&nbsp; &nbsp; &nbsp; &nbsp; nil, OPEN_EXISTING, 0, 0 ); <br>&nbsp; &nbsp; &nbsp; if hDevice=INVALID_HANDLE_VALUE then Exit; <br>&nbsp; &nbsp; &nbsp; try <br>&nbsp; &nbsp; &nbsp; &nbsp; srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL); <br>&nbsp; &nbsp; &nbsp; &nbsp; System.Move('SCSIDISK',srbControl.Signature,8); <br>&nbsp; &nbsp; &nbsp; &nbsp; srbControl.Timeout &nbsp; &nbsp; &nbsp;:= 2; <br>&nbsp; &nbsp; &nbsp; &nbsp; srbControl.Length &nbsp; &nbsp; &nbsp; := DataSize; <br>&nbsp; &nbsp; &nbsp; &nbsp; srbControl.ControlCode &nbsp;:= IOCTL_SCSI_MINIPORT_IDENTIFY; <br>&nbsp; &nbsp; &nbsp; &nbsp; pInData := PSendCmdInParams(PChar(@Buffer) <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+SizeOf(SRB_IO_CONTROL)); <br>&nbsp; &nbsp; &nbsp; &nbsp; pOutData := pInData; <br>&nbsp; &nbsp; &nbsp; &nbsp; with pInData^ do <br>&nbsp; &nbsp; &nbsp; &nbsp; begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cBufferSize &nbsp;:= IDENTIFY_BUFFER_SIZE; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bDriveNumber := 0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; with irDriveRegs do <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bFeaturesReg &nbsp; &nbsp; := 0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bSectorCountReg &nbsp;:= 1; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bSectorNumberReg := 1; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bCylLowReg &nbsp; &nbsp; &nbsp; := 0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bCylHighReg &nbsp; &nbsp; &nbsp;:= 0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bDriveHeadReg &nbsp; &nbsp;:= $A0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bCommandReg &nbsp; &nbsp; &nbsp;:= IDE_ID_FUNCTION; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp; &nbsp; &nbsp; if not DeviceIoControl( hDevice, IOCTL_SCSI_MINIPORT, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Buffer, BufferSize, @Buffer, BufferSize, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbBytesReturned, nil ) then Exit; <br>&nbsp; &nbsp; &nbsp; finally <br>&nbsp; &nbsp; &nbsp; &nbsp; CloseHandle(hDevice); <br>&nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp; end <br>&nbsp; else <br>&nbsp; &nbsp; begin // Windows 95 OSR2, Windows 98 <br>&nbsp; &nbsp; &nbsp; hDevice := CreateFile( '//./SMARTVSD', 0, 0, nil, <br>&nbsp; &nbsp; &nbsp; &nbsp; CREATE_NEW, 0, 0 ); <br>&nbsp; &nbsp; &nbsp; if hDevice=INVALID_HANDLE_VALUE then Exit; <br>&nbsp; &nbsp; &nbsp; try <br>&nbsp; &nbsp; &nbsp; &nbsp; pInData := PSendCmdInParams(@Buffer); <br>&nbsp; &nbsp; &nbsp; &nbsp; pOutData := @pInData^.bBuffer; <br>&nbsp; &nbsp; &nbsp; &nbsp; with pInData^ do <br>&nbsp; &nbsp; &nbsp; &nbsp; begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cBufferSize &nbsp;:= IDENTIFY_BUFFER_SIZE; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bDriveNumber := 0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; with irDriveRegs do <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bFeaturesReg &nbsp; &nbsp; := 0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bSectorCountReg &nbsp;:= 1; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bSectorNumberReg := 1; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bCylLowReg &nbsp; &nbsp; &nbsp; := 0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bCylHighReg &nbsp; &nbsp; &nbsp;:= 0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bDriveHeadReg &nbsp; &nbsp;:= $A0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bCommandReg &nbsp; &nbsp; &nbsp;:= IDE_ID_FUNCTION; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp; &nbsp; &nbsp; if not DeviceIoControl( hDevice, DFP_RECEIVE_DRIVE_DATA, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pInData, SizeOf(TSendCmdInParams)-1, pOutData, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; W9xBufferSize, cbBytesReturned, nil ) then Exit; <br>&nbsp; &nbsp; &nbsp; finally <br>&nbsp; &nbsp; &nbsp; &nbsp; CloseHandle(hDevice); <br>&nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp; end; <br>&nbsp; &nbsp; with PIdSector(PChar(pOutData)+16)^ do <br>&nbsp; &nbsp; begin <br>&nbsp; &nbsp; &nbsp; ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber)); <br>&nbsp; &nbsp; &nbsp; SetString(Result,sSerialNumber,SizeOf(sSerialNumber)); <br>&nbsp; &nbsp; end; <br>end; <br><br><br>//============================================================= <br>var s : String; <br>&nbsp; &nbsp; rc : DWORD; <br>begin <br>&nbsp; s := GetIdeDiskSerialNumber; <br>&nbsp; if s='' then <br>&nbsp; &nbsp; begin <br>&nbsp; &nbsp; &nbsp; rc := GetLastError; <br>&nbsp; &nbsp; &nbsp; if rc=0 then WriteLn('IDE drive is not support SMART feature') <br>&nbsp; &nbsp; &nbsp; else WriteLn(SysErrorMessage(rc)); <br>&nbsp; &nbsp; end <br>&nbsp; else WriteLn('Disk serial number: ''', s,''''); <br>end.
 
lu0.126.com<br>陆陵同志通过MS的S.M.A.R.T.接口,直接从RING3调用API DeviceIoControl()来获取硬盘<br>信息
 
顶部