国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

讀取硬盤的物理序列號

2019-11-18 18:35:03
字體:
來源:轉載
供稿:網友
 

讀取硬盤的物理序列號

//獲得硬盤序列號
function GetIdeSerialNumber() : PChar; stdcall;
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: DWord;
    // 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 DWORD;
    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: DWORD;
    wMultSectorStuff: Word;
    ulTotalAddressableSectors: DWORD;
    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 DWORD;
  end;

  TSendCmdOutParams = packed record
    // bBuffer的大小
    cBufferSize: DWORD;
    // 驅動器狀態
    DriverStatus: TDriverStatus;
    // 用于保存從驅動器讀出的數據的緩沖區,實際長度由cBufferSize決定
    bBuffer: array[0..0] of BYTE;
  end;
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
    // 提示! 改變名稱可適用于其它驅動器,如第二個驅動器: '//./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;


上一篇:Win32調試API學習心得(一)

下一篇:用兩種方法快速簡單的實現窗口淡入淡出

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

主站蜘蛛池模板: 洛隆县| 吉首市| 根河市| 永春县| 轮台县| 岐山县| 余姚市| 镇远县| 南开区| 罗源县| 杭锦旗| 景洪市| 广汉市| 桦南县| 西乡县| 南平市| 平顺县| 陇南市| 休宁县| 外汇| 菏泽市| 广河县| 井陉县| 响水县| 三都| 龙岩市| 静安区| 大名县| 玛沁县| 峨边| 儋州市| 日土县| 云南省| 长沙县| 高碑店市| 都安| 香港| 乌恰县| 宝山区| 扎囊县| 凭祥市|