Chinaunix首页 | 论坛 | 博客
  • 博客访问: 972490
  • 博文数量: 108
  • 博客积分: 3243
  • 博客等级: 中校
  • 技术积分: 964
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-15 22:09
文章分类

全部博文(108)

文章存档

2020年(2)

2019年(1)

2018年(2)

2017年(9)

2016年(20)

2015年(1)

2013年(1)

2012年(12)

2011年(28)

2010年(27)

2009年(4)

2008年(1)

分类:

2010-05-03 16:40:51

type

  TIDERegs = packed   record
    bFeaturesReg     : BYTE;
    bSectorCountReg  : BYTE;
    bSectorNumberReg : BYTE;
    bCylLowReg       : BYTE;
    bCylHighReg      : BYTE;
    bDriveHeadReg    : BYTE;
    bCommandReg      : BYTE;
    bReserved        : BYTE;
  end;
 
  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;
 
  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    : DWORD;
    wMultSectorStuff           : Word;
    ulTotalAddressableSectors  : DWORD;
    wSingleWordDMA             : Word;
    wMultiWordDMA              : Word;
    bReserved                  : array[0..127]   of   BYTE;
  end;
 
  PIdSector = ^TIdSector;
  TDriverStatus = packed record
    bDriverError : Byte;
    bIDEStatus   : Byte;
    bReserved    : array[0..1]   of   Byte;
    dwReserved   : array[0..1]   of   DWORD;
  end;
 
  TSendCmdOutParams = packed record
    cBufferSize  : DWORD;
    DriverStatus : TDriverStatus;
    bBuffer      : array[0..0]   of   BYTE;
  end;
 
// 获取硬盘的出厂系列号;
function GetDiskSerialNumber : Pchar;     
  const IDENTIFY_BUFFER_SIZE = 512;  
var
  hDevice : Thandle;
  cbBytesReturned : DWORD;
  SCIP      : TSendCmdInParams;
  aIdOutCmd : array[0..(SizeOf(TSendCmdOutParams) + IDENTIFY_BUFFER_SIZE - 1) - 1] of Byte;
  IdOutCmd  : TSendCmdOutParams absolute aIdOutCmd;
  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   :=   '';
  if SysUtils.Win32Platform = VER_PLATFORM_WIN32_NT then  // Windows NT, Windows 2000
  begin
    hDevice := CreateFile('\\.\PhysicalDrive0', GENERIC_READ or GENERIC_WRITE,
      FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
  end
  else   // Version Windows95 OSR2, Windows 98
    hDevice := CreateFile('\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0);
  if hDevice = INVALID_HANDLE_VALUE then
    Exit;
  try
    FillChar(SCIP,   SizeOf(TSendCmdInParams)   -   1,   #0);
    FillChar(aIdOutCmd,   SizeOf(aIdOutCmd),   #0);
    cbBytesReturned   :=   0;
    with SCIP do
    begin
      cBufferSize := IDENTIFY_BUFFER_SIZE;
      with irDriveRegs do
      begin
        bSectorCountReg   :=   1;
        bSectorNumberReg   :=   1;
        bDriveHeadReg   :=   $A0;
        bCommandReg   :=   $EC;
      end;
    end;  
    if not DeviceIoControl(hDevice, $0007C088, @SCIP, SizeOf(TSendCmdInParams) - 1,
      @aIdOutCmd, SizeOf(aIdOutCmd), cbBytesReturned, nil) then
      Exit;
  finally
    CloseHandle(hDevice);
  end;
  with PIdSector(@IdOutCmd.bBuffer)^ do
  begin
    ChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber));
    (Pchar(@sSerialNumber) + SizeOf(sSerialNumber))^ := #0;
    Result := Pchar(@sSerialNumber);
  end;
end;
 
调用方法:
ShowMessage(StrPas(GetDiskSerialNumber));
阅读(1283) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~