DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: pesamo
今日帖子: 10
在线用户: 7
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 babebear (BabeBear) ★☆☆☆☆ -
盒子活跃会员
2003/11/12 8:36:07
标题:
[求教]如何获取硬盘序列号? 浏览:2099
加入我的收藏
楼主: [求教]如何获取硬盘序列号?

我看到一段程序,是获取硬盘序列号的,但在我的机器上不能返回序列号值, getVolumnInformation 返回保龄球为 False. 这到底是怎么回呈?请大侠指教。
我的硬盘是是希捷40G的, Win98SE +  Delphi7. 盼复谢了。

procedure TForm1.Button1Click(Sender: TObject);   
var SerialNum : pdword; a, b : dword; Buffer : array [0..255] of char;   
begin   
  if GetVolumeInformation('c:\', Buffer, SizeOf(Buffer), SerialNum, a, b, nil, 0) then Label1.Caption := IntToStr(SerialNum^); ;

end;  

 

 
 


----------------------------------------------
熊囡囡
作者:
男 lantu (十步一杀) ★☆☆☆☆ -
盒子活跃会员
2003/11/12 11:42:14
1楼: 看看我的这段程序

unit Unit_Main;


interface


uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;


type
  TSrbIoControl = packed record
  HeaderLength: ULONG;
  Signature: array[0..7] of Char;
  Timeout: ULONG;
  ControlCode: ULONG;
  ReturnCode: ULONG;
  Length: ULONG;

end;

SRB_IO_CONTROL = TSrbIoControl;
PSrbIoControl = ^TSrbIoControl;

TIDERegs = packed record

    bFeaturesReg: Byte; // Used for specifying SMART "commands".

    bSectorCountReg: Byte; // IDE sector count register

    bSectorNumberReg: Byte; // IDE sector number register

    bCylLowReg: Byte; // IDE low order cylinder value

    bCylHighReg: Byte; // IDE high order cylinder value

    bDriveHeadReg: Byte; // IDE drive/head register

    bCommandReg: Byte; // Actual IDE command.

    bReserved: Byte; // reserved.  Must be zero.

  end;

  IDEREGS = TIDERegs;
  PIDERegs = ^TIDERegs;

  TSendCmdInParams = packed record
  cBufferSize: DWORD;
  irDriveRegs: TIDERegs;
  bDriveNumber: Byte;
  bReserved: array[0..2] of Byte;
  dwReserved: array[0..3] of DWORD;
  bBuffer: array[0..0] of Byte;

  end;

  SENDCMDINPARAMS = TSendCmdInParams;

  PSendCmdInParams = ^TSendCmdInParams;


  TIdSector = packed record

    wGenConfig: Word;

    wNumCyls: Word;

    wReserved: Word;

    wNumHeads: Word;

    wBytesPerTrack: Word;

    wBytesPerSector: Word;

    wSectorsPerTrack: Word;

    wVendorUnique: array[0..2] of Word;

    sSerialNumber: array[0..19] of Char;

    wBufferType: Word;

    wBufferSize: Word;

    wECCSize: Word;

    sFirmwareRev: array[0..7] of Char;

    sModelNumber: array[0..39] of Char;

    wMoreVendorUnique: Word;

    wDoubleWordIO: Word;

    wCapabilities: Word;

    wReserved1: Word;

    wPIOTiming: Word;

    wDMATiming: Word;

    wBS: Word;

    wNumCurrentCyls: Word;

    wNumCurrentHeads: Word;

    wNumCurrentSectorsPerTrack: Word;

    ulCurrentSectorCapacity: ULONG;

    wMultSectorStuff: Word;

    ulTotalAddressableSectors: ULONG;

    wSingleWordDMA: Word;

    wMultiWordDMA: Word;

    bReserved: array[0..127] of Byte;

  end;

  PIdSector = ^TIdSector;


const

  IDE_ID_FUNCTION = $EC;

  IDENTIFY_BUFFER_SIZE = 512;

  DFP_RECEIVE_DRIVE_DATA = $0007C088;

  IOCTL_SCSI_MINIPORT = $0004D008;

  IOCTL_SCSI_MINIPORT_IDENTIFY = $001B0501;

  DataSize = sizeof(TSendCmdInParams) - 1 + IDENTIFY_BUFFER_SIZE;

  BufferSize = SizeOf(SRB_IO_CONTROL) + DataSize;

  W9xBufferSize = IDENTIFY_BUFFER_SIZE + 16;


type

  TForm_Main = class(TForm)
    Label1: TLabel;

   Edit_HardDiskNumber: TEdit;
    Button_Get: TButton;






    procedure Button_GetClick(Sender: TObject);

  private

    { Private declarations }

  public

    { Public declarations }

  end;


var

  Form_Main: TForm_Main;


implementation


{$R *.dfm}


function GetIdeDiskSerialNumber: string;

type

  TSrbIoControl = packed record

    HeaderLength: ULONG;

    Signature: array[0..7] of Char;

    Timeout: ULONG;

    ControlCode: ULONG;

    ReturnCode: ULONG;

    Length: ULONG;

  end;

  SRB_IO_CONTROL = TSrbIoControl;

  PSrbIoControl = ^TSrbIoControl;


  TIDERegs = packed record

    bFeaturesReg: Byte; // Used for specifying SMART "commands".

    bSectorCountReg: Byte; // IDE sector count register

    bSectorNumberReg: Byte; // IDE sector number register

    bCylLowReg: Byte; // IDE low order cylinder value

    bCylHighReg: Byte; // IDE high order cylinder value

    bDriveHeadReg: Byte; // IDE drive/head register

    bCommandReg: Byte; // Actual IDE command.

    bReserved: Byte; // reserved for future use.  Must be zero.

  end;

  IDEREGS = TIDERegs;

  PIDERegs = ^TIDERegs;


  TSendCmdInParams = packed record

    cBufferSize: DWORD; // Buffer size in bytes

    irDriveRegs: TIDERegs; // Structure with drive register values.

    bDriveNumber: Byte; // Physical drive number to send command to (0,1,2,3).

    bReserved: array[0..2] of Byte; // Reserved for future expansion.

    dwReserved: array[0..3] of DWORD; // For future use.

    bBuffer: array[0..0] of Byte; // Input buffer.

  end;

  SENDCMDINPARAMS = TSendCmdInParams;

  PSendCmdInParams = ^TSendCmdInParams;


  TIdSector = packed record

    wGenConfig: Word;

    wNumCyls: Word;

    wReserved: Word;

    wNumHeads: Word;

    wBytesPerTrack: Word;

    wBytesPerSector: Word;

    wSectorsPerTrack: Word;

    wVendorUnique: array[0..2] of Word;

    sSerialNumber: array[0..19] of Char;

    wBufferType: Word;

    wBufferSize: Word;

    wECCSize: Word;

    sFirmwareRev: array[0..7] of Char;

    sModelNumber: array[0..39] of Char;

    wMoreVendorUnique: Word;

    wDoubleWordIO: Word;

    wCapabilities: Word;

    wReserved1: Word;

    wPIOTiming: Word;

    wDMATiming: Word;

    wBS: Word;

    wNumCurrentCyls: Word;

    wNumCurrentHeads: Word;

    wNumCurrentSectorsPerTrack: Word;

    ulCurrentSectorCapacity: ULONG;

    wMultSectorStuff: Word;

    ulTotalAddressableSectors: ULONG;

    wSingleWordDMA: Word;

    wMultiWordDMA: Word;

    bReserved: array[0..127] of Byte;

  end;

  PIdSector = ^TIdSector;


const

  IDE_ID_FUNCTION = $EC;

  IDENTIFY_BUFFER_SIZE = 512;

  DFP_RECEIVE_DRIVE_DATA = $0007C088;

  IOCTL_SCSI_MINIPORT = $0004D008;

  IOCTL_SCSI_MINIPORT_IDENTIFY = $001B0501;

  DataSize = sizeof(TSendCmdInParams) - 1 + IDENTIFY_BUFFER_SIZE;

  BufferSize = SizeOf(SRB_IO_CONTROL) + DataSize;

  W9xBufferSize = IDENTIFY_BUFFER_SIZE + 16;

var

  hDevice: THandle;

  cbBytesReturned: DWORD;

  pInData: PSendCmdInParams;

  pOutData: Pointer; // PSendCmdInParams;

  Buffer: array[0..BufferSize - 1] of Byte;

  srbControl: TSrbIoControl absolute Buffer;


  procedure ChangeByteOrder(var Data; Size: Integer);

  var ptr: PChar;

    i: Integer;

    c: Char;

  begin

    ptr := @Data;

    for i := 0 to (Size shr 1) - 1 do

    begin

      c := ptr^;

      ptr^ := (ptr + 1)^;

      (ptr + 1)^ := c;

      Inc(ptr, 2);

    end;

  end;

begin

  Result := ';

  FillChar(Buffer, BufferSize, #0);

  if Win32Platform = VER_PLATFORM_WIN32_NT then

  begin // Windows NT, Windows 2000

      // Get SCSI port handle

    hDevice := CreateFile('\\.\Scsi0:', GENERIC_READ or GENERIC_WRITE,

      FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);

    if hDevice = INVALID_HANDLE_VALUE then Exit;

    try

      srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL);

      System.Move('SCSIDISK', srbControl.Signature, 8);

      srbControl.Timeout := 2;

      srbControl.Length := DataSize;

      srbControl.ControlCode := IOCTL_SCSI_MINIPORT_IDENTIFY;

      pInData := PSendCmdInParams(PChar(@Buffer) + SizeOf(SRB_IO_CONTROL));

      pOutData := pInData;

      with pInData^ do

      begin

        cBufferSize := IDENTIFY_BUFFER_SIZE;

        bDriveNumber := 0;

        with irDriveRegs do

        begin

          bFeaturesReg := 0;

          bSectorCountReg := 1;

          bSectorNumberReg := 1;

          bCylLowReg := 0;

          bCylHighReg := 0;

          bDriveHeadReg := $A0;

          bCommandReg := IDE_ID_FUNCTION;

        end;

      end;

      if not DeviceIoControl(hDevice, IOCTL_SCSI_MINIPORT, @Buffer, BufferSize, @Buffer, BufferSize, cbBytesReturned, nil) then Exit;

    finally

      CloseHandle(hDevice);

    end;

  end

  else

  begin // Windows 95 OSR2, Windows 98

    hDevice := CreateFile('\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0);

    if hDevice = INVALID_HANDLE_VALUE then Exit;

    try

      pInData := PSendCmdInParams(@Buffer);

      pOutData := PChar(@pInData^.bBuffer);

      with pInData^ do

      begin

        cBufferSize := IDENTIFY_BUFFER_SIZE;

        bDriveNumber := 0;

        with irDriveRegs do

        begin

          bFeaturesReg := 0;

          bSectorCountReg := 1;

          bSectorNumberReg := 1;

          bCylLowReg := 0;

          bCylHighReg := 0;

          bDriveHeadReg := $A0;

          bCommandReg := IDE_ID_FUNCTION;

        end;

      end;

      if not DeviceIoControl(hDevice, DFP_RECEIVE_DRIVE_DATA, pInData, SizeOf(TSendCmdInParams) - 1, pOutData, W9xBufferSize, cbBytesReturned, nil) then Exit;

    finally

      CloseHandle(hDevice);

    end;

  end;

  with PIdSector(PChar(pOutData) + 16)^ do

  begin

    ChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber));

    SetString(Result, sSerialNumber, SizeOf(sSerialNumber));

  end;

end;


procedure TForm_Main.Button_GetClick(Sender: TObject);
begin
Edit_HardDiskNumber.Text := GetIdeDiskSerialNumber;
end;


end.

----------------------------------------------
-
作者:
男 babebear (BabeBear) ★☆☆☆☆ -
盒子活跃会员
2003/11/27 11:36:11
2楼: 高, 实在是高! 
用起来挺好用的, 但看不懂。

----------------------------------------------
熊囡囡
作者:
男 bios (阿贡) ★☆☆☆☆ -
盒子中级会员
2003/11/27 12:47:58
3楼: 复杂的原代码多的是啊
----------------------------------------------
按此在新窗口浏览图片
按此在新窗口浏览图片
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行277.3438毫秒 RSS