Win32 读取硬盘信息实例

打开硬盘句柄

使用CreateFile方式打开硬盘。

QString filePath = QString("\\\\.\\PhysicalDrive%1").arg(index);
fileHandler = CreateFileA(filePath.toLocal8Bit().data(), 
                          GENERIC_READ | GENERIC_WRITE,
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
                          NULL,
                          OPEN_EXISTING,
                          0, 0 );

IDSECTOR方式读取

结构体声明。我没找到官方的定义。

#define  IDENTIFY_BUFFER_SIZE  512

#define  IDE_ATAPI_IDENTIFY  0xA0
#define  IDE_ATA_IDENTIFY    0xEC
#define  DFP_RECEIVE_DRIVE_DATA   0x0007c088

#pragma pack(1)
typedef struct _IDSECTOR
{
    USHORT  wGenConfig;
    USHORT  wNumCyls;
    USHORT  wReserved;
    USHORT  wNumHeads;
    USHORT  wBytesPerTrack;
    USHORT  wBytesPerSector;
    USHORT  wSectorsPerTrack;
    USHORT  wVendorUnique[3];
    CHAR    sSerialNumber[20];
    USHORT  wBufferType;
    USHORT  wBufferSize;
    USHORT  wECCSize;
    CHAR    sFirmwareRev[8];
    CHAR    sModelNumber[40];
    USHORT  wMoreVendorUnique;
    USHORT  wDoubleWordIO;
    USHORT  wCapabilities;
    USHORT  wReserved1;
    USHORT  wPIOTiming;
    USHORT  wDMATiming;
    USHORT  wBS;
    USHORT  wNumCurrentCyls;
    USHORT  wNumCurrentHeads;
    USHORT  wNumCurrentSectorsPerTrack;
    ULONG   ulCurrentSectorCapacity;
    USHORT  wMultSectorStuff;
    ULONG   ulTotalAddressableSectors;
    USHORT  wSingleWordDMA;
    USHORT  wMultiWordDMA;
    BYTE    bReserved[128];
}IDSECTOR, *PIDSECTOR;


#pragma pack()
BOOL bResult;
DWORD dwBytesRet;
//获取硬盘详细信息 序列号等情况
GETVERSIONINPARAMS gVersionParsams;

bResult = DeviceIoControl(fileHandler,
                         SMART_GET_VERSION,
                         NULL,
                         NULL,
                         &gVersionParsams,
                         sizeof(gVersionParsams),
                         &dwBytesRet,
                         NULL);
if(bResult && gVersionParsams.bIDEDeviceMap > 0){
   SENDCMDINPARAMS scip;
   ZeroMemory( &scip,sizeof(SENDCMDINPARAMS));

   scip.cBufferSize=IDENTIFY_BUFFER_SIZE;
   scip.irDriveRegs.bSectorCountReg=1;
   scip.irDriveRegs.bSectorNumberReg=1;
   scip.irDriveRegs.bDriveHeadReg= IDE_ATAPI_IDENTIFY;
   scip.irDriveRegs.bCommandReg= IDE_ATA_IDENTIFY;
   scip.bDriveNumber = index & 0xFF;

   BYTE btBuffer[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE]={ 0 };

   bResult = DeviceIoControl(fileHandler,
                             SMART_RCV_DRIVE_DATA,
                             &scip,
                             sizeof(scip) - 1,
                             btBuffer,
                             sizeof(btBuffer),
                             &dwBytesRet,NULL);
  if(bResult){
      PSENDCMDOUTPARAMS pOut = (PSENDCMDOUTPARAMS)btBuffer;
      PIDSECTOR pIdSec = (PIDSECTOR)(pOut->bBuffer);
      ChangeByteOrder(pIdSec->sSerialNumber, sizeof(pIdSec->sSerialNumber));
      ChangeByteOrder(pIdSec->sModelNumber, sizeof(pIdSec->sModelNumber));

      sn = QString::fromLocal8Bit(pIdSec->sSerialNumber,
                                  sizeof(pIdSec->sSerialNumber)).trimmed();
      model = QString::fromLocal8Bit(pIdSec->sModelNumber,
                                     sizeof(pIdSec->sModelNumber)).trimmed();
  }
}else{
   qDebug() << "错误码:" <<GetLastError();
}
void ChangeByteOrder(LPSTR lpString, int nLen)
{
    USHORT i;
    CHAR c;

    // 63 63 72 75 6E 2E 63 6F 6D
    for(int i = 0; i < nLen; i += 2)
    {
        c = lpString[i];
        lpString[i] = lpString[i+1];
        lpString[i+1] = c;
    }
}

这种方式读取,需要转换字节顺序。USB硬盘有点读不到。

STORAGE_PROPERTY_QUERY方式读取

STORAGE_PROPERTY_QUERY query;

query.PropertyId = StorageDeviceProperty;
query.QueryType = PropertyStandardQuery;

char buffer[sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1];
STORAGE_DEVICE_DESCRIPTOR *pDevDesc = (STORAGE_DEVICE_DESCRIPTOR *)buffer;
pDevDesc->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1;

bResult = DeviceIoControl(fileHandler, IOCTL_STORAGE_QUERY_PROPERTY,
                          &query,
                          sizeof(query),
                          pDevDesc,
                          pDevDesc->Size,
                          &dwBytesRet, NULL);
if (bResult){
    removableMedia = pDevDesc->RemovableMedia;
    bus = pDevDesc->BusType;
    char temp[512];
    strcpy(temp,&buffer[pDevDesc->ProductIdOffset]);//此即为producter
    qDebug() << QString::fromLocal8Bit(temp);
    strcpy(temp,&buffer[pDevDesc->ProductRevisionOffset]);//此即为version
    qDebug() << QString::fromLocal8Bit(temp);
    strcpy(temp ,&buffer[pDevDesc->VendorIdOffset]);//此即为vendor
    qDebug() << QString::fromLocal8Bit(temp);
    strcpy(temp,&buffer[pDevDesc->SerialNumberOffset]);
    qDebug() << QString::fromLocal8Bit(temp);
}

参考

https://blog.csdn.net/helptome/article/details/2047063
https://bbs.pediy.com/thread-221514.htm

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值