delphi获取硬盘序列号的dll代码,支持win7

来源:互联网 发布:非冗余数据库 编辑:程序博客网 时间:2024/05/16 17:14
library GetDiskSN;{ Important note about DLL memory management: ShareMem must be the  first unit in your library's USES clause AND your project's (select  Project-View Source) USES clause if your DLL exports any procedures or  functions that pass strings as parameters or function results. This  applies to all strings passed to and from your DLL--even those that  are nested in records and classes. ShareMem is the interface unit to  the BORLNDMM.DLL shared memory manager, which must be deployed along  with your DLL. To avoid using BORLNDMM.DLL, pass string information  using PChar or ShortString parameters. }uses  SysUtils,  Classes,  Windows;{$R *.res}function GetIdeSerialNumber: PChar;const  IDENTIFY_BUFFER_SIZE = 512;type  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;  TSendCmdInParams = packed record    // Buffer size in bytes    cBufferSize: Longword;    // Structure with drive register values.    irDriveRegs: TIDERegs;    // Physical drive number to send command to (0,1,2,3).    bDriveNumber: Byte;    bReserved: array[0..2] of Byte;    dwReserved: array[0..3] of Longword;    bBuffer: array[0..0] of Byte; // Input buffer.  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: Longword;    wMultSectorStuff: Word;    ulTotalAddressableSectors: Longword;    wSingleWordDMA: Word;    wMultiWordDMA: Word;    bReserved: array[0..127] of Byte;  end;  PIdSector     = ^TIdSector;  TDriverStatus = packed record    // 驱动器返回的错误代码,无错则返回0    bDriverError: Byte;    // IDE出错寄存器的内容,只有当bDriverError 为 SMART_IDE_ERROR 时有效    bIDEStatus: Byte;    bReserved: array[0..1] of Byte;    dwReserved: array[0..1] of Longword;  end;  TSendCmdOutParams = packed record    // bBuffer的大小    cBufferSize: Longword;    // 驱动器状态    DriverStatus: TDriverStatus;    // 用于保存从驱动器读出的数据的缓冲区,实际长度由cBufferSize决定    bBuffer: array[0..0] of Byte;  end;var  hDevice: THandle;  cbBytesReturned: Longword;  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  begin // Windows NT, Windows 2000        // 提示! 改变名称可适用于其它驱动器,如第二个驱动器: '\\.\PhysicalDrive1\'    hDevice := CreateFile('\\.\PhysicalDrive0', GENERIC_READ or GENERIC_WRITE,      FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);  end  else // Version Windows 95 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;    // Set up data structures for IDENTIFY command.    with SCIP do    begin      cBufferSize := IDENTIFY_BUFFER_SIZE;      // bDriveNumber := 0;      with irDriveRegs do      begin        bSectorCountReg := 1;        bSectorNumberReg := 1;        // if Win32Platform=VER_PLATFORM_WIN32_NT then bDriveHeadReg := $A0        // else bDriveHeadReg := $A0 or ((bDriveNum and 1) shl 4);        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;exportsGetIdeSerialNumber index 1;beginend.


 
0 0
原创粉丝点击