GetVolumeInformation獲取磁盤信息與DeviceIoControl獲取硬盤信息

       硬盤序列號: 英文名 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) );
}


 

發佈了0 篇原創文章 · 獲贊 10 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章