GetVolumeInformation擷取磁碟資訊與DeviceIoControl擷取硬碟資訊

來源:互聯網
上載者:User

       硬碟序號: 英文名 Hard Disk Serial Number, 該號是出廠時生產廠家為區別產品而設定的, 是唯一的, 是唯讀, 利用硬碟序號的加密往往是利用其唯一和唯讀特性, 大多是針對有序號的 IDE HDD而言, 對於沒有序號或SCSI HDD硬碟則無能為力, 這也是利用它進行加密的局限性.

       卷的序號: 英文名 Volume Serial Number, 該號既可指軟磁碟要得, 如: A:盤和B:盤的, 又可以指硬碟的邏輯盤, 如: C:, D:...的, 是進階格式化時隨機產生的, 是可以修改的, 所以利用其進行 加密, 其唯一性還可, 而其可修改性對於安全而言就大打折扣了. 

        如何得到磁碟序號和卷標及其它資訊主要就是要調用GetVolumeInformation這個API函數,函式宣告如下
BOOL GetVolumeInformation(
  LPCTSTR lpRootPathName,        // address of root directory of the 
                                 // file system
  LPTSTR lpVolumeNameBuffer,     // address of name of the volume
  DWORD nVolumeNameSize,         // length of lpVolumeNameBuffer
  LPDWORD lpVolumeSerialNumber,  // address of volume serial number
  LPDWORD lpMaximumComponentLength,
                                 // address of system's maximum 
                                 // filename length
  LPDWORD lpFileSystemFlags,     // address of file system flags
  LPTSTR lpFileSystemNameBuffer, // address of name of file system
  DWORD nFileSystemNameSize      // length of lpFileSystemNameBuffer
);

[VB]
Public Declare Function GetVolumeInformation& Lib "kernel32" Alias "Ge
tVolumeInformationA" (ByVal lpRootPathName As String, ByVal pVolumeNam
eBuffer As String, ByVal nVolumeNameSize As Long, lpVolumeSerialNumber
As Long, lpMaximumComponentLength As Long, lpFileSystemFlags As Long,
ByVal lpFileSystemNameBuffer As String, ByVal nFileSystemNameSize As
Long)

用API 函數GetVolumeInformation得到的不是硬碟的序號!!! 看看英文啊:VolumeSerialNumber!得到的只是卷區序號!

硬碟的序號應該是
Drive Model Number________________: WDC WD400EB-00CPF0
Drive Serial Number_______________: WD-WCAATF083586
Drive Controller Revision Number__: 06.04G06
Controller Buffer Size on Drive___: 2097152 bytes
Drive Type________________________: Fixed
Drive Size________________________: 40020664320 bytes
中:

Drive Serial Number_______________: WD-WCAATF083586 這才是硬碟Serial Number!!!!

這個號是不會因為你格式化硬碟而改動,也不是網上流傳的修改工具能改的,(其實網上流傳的修改工具的也不過是卷區號而已,真是哭笑不得!)

硬碟序號與磁碟序號不同,磁碟序號是硬碟分區中某個卷(volumn)也就是我們說的磁碟的序號。而硬碟序號是整塊硬碟的序號,不能被修改。

 

 

 

-----------------------

DeviceIoControl可以擷取硬碟序號。其實現在CSDN上有下。摘錄部分

  BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
   BOOL bFlag = FALSE;
   int  drive = 0;
   char driveName [256];
   HANDLE hPhysicalDriveIOCTL = 0;   
     
   sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive);
   //  Windows NT/2000/XP下建立檔案需要管理員權限
   hPhysicalDriveIOCTL = CreateFile (driveName,
                            GENERIC_READ | GENERIC_WRITE,
                            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                            OPEN_EXISTING, 0, NULL);

   if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
   {
       GETVERSIONOUTPARAMS VersionParams;
       DWORD               cbBytesReturned = 0;

       // 得到磁碟機的IO控制器版本
       memset ((void*) &VersionParams, 0, sizeof(VersionParams));
       if(DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_VERSION,
                               NULL, 0, &VersionParams,
                               sizeof(VersionParams),
                               &cbBytesReturned, NULL) )
    {       
          if (VersionParams.bIDEDeviceMap > 0)
    {
              BYTE             bIDCmd = 0;   // IDE或者ATAPI識別命令
              SENDCMDINPARAMS  scip;
 
              // 如果磁碟機是光碟機,採用命令IDE_ATAPI_IDENTIFY, command,
              // 否則採用命令IDE_ATA_IDENTIFY讀取磁碟機資訊
              bIDCmd = (VersionParams.bIDEDeviceMap >> drive & 0x10)?
                      IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;

              memset (&scip, 0, sizeof(scip));
              memset (IdOutCmd, 0, sizeof(IdOutCmd));
              // 擷取磁碟機資訊
              if (WinNTGetIDEHDInfo (hPhysicalDriveIOCTL,
                                      &scip,
                                      (PSENDCMDOUTPARAMS)&IdOutCmd,
                                      (BYTE) bIDCmd,
                                      (BYTE) drive,
                                      &cbBytesReturned))
     {
                  int m = 0;
                  USHORT *pIdSector = (USHORT *)
                             ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;

                  for (m = 0; m < 256; m++)
                       buffer[m] = pIdSector [m];
                  bFlag = TRUE;  // 讀取硬碟資訊成功
     }
    }
    }
       CloseHandle (hPhysicalDriveIOCTL);  // 關閉控制代碼
   }
   return bFlag;

 

 

 

 

BOOL CGetHDSerial::WinNTGetIDEHDInfo (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
                 PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,
                 PDWORD lpcbBytesReturned)
{
   // 為讀取裝置資訊準備參數
   pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;
   pSCIP -> irDriveRegs.bFeaturesReg = 0;
   pSCIP -> irDriveRegs.bSectorCountReg = 1;
   pSCIP -> irDriveRegs.bSectorNumberReg = 1;
   pSCIP -> irDriveRegs.bCylLowReg = 0;
   pSCIP -> irDriveRegs.bCylHighReg = 0;

   // 計算磁碟機位置
   pSCIP -> irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) << 4);

   // 設定讀取命令
   pSCIP -> irDriveRegs.bCommandReg = bIDCmd;
   pSCIP -> bDriveNumber = bDriveNum;
   pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;
  
   // 讀取磁碟機資訊
   return ( DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_DRIVE_INFO,
               (LPVOID) pSCIP,
               sizeof(SENDCMDINPARAMS) - 1,
               (LPVOID) pSCOP,
               sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
               lpcbBytesReturned, NULL) );
}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.