VC 之获取硬盘序列号

来源:互联网 发布:软件报告 编辑:程序博客网 时间:2024/06/05 00:37
硬盘物理序列号是硬盘的出厂序列号,它是全球都是唯一的,不会随着系统的安装、硬盘的格式化等操作而改变,跟mac地址一样都具有唯一性。

1,第一步:创建设备对象,得到设备句柄,设备为硬盘。
{
CString sFilePath;
sFilePath.Format("\\\\.\\PHYSICALDRIVE%d", driver);
HANDLE hFile
=::CreateFile(sFilePath,
                     GENERIC_READ | GENERIC_WRITE,
                     FILE_SHARE_READ | FILE_SHARE_WRITE,
                     NULL, OPEN_EXISTING,
                     0, NULL);
DWORD dwBytesReturned;
GETVERSIONINPARAMS gvopVersionParams;
DeviceIoControl(hFile,       //向设备对象发送
SMART_GET_VERSION设备请求,获取硬盘属性
                SMART_GET_VERSION,
                NULL,
                0,
                &gvopVersionParams,
                sizeof(gvopVersionParams),
                 &dwBytesReturned, NULL);
 if(gvopVersionParams.bIDEDeviceMap <= 0)    return -2; 
2。第二步,发送SMART_RCV_DRIVE_DATA设备请求,获取硬盘详细信息。
    // IDE or ATAPI IDENTIFY cmd
    int btIDCmd = 0;
    SENDCMDINPARAMS InParams;
    int nDrive =0;
    btIDCmd = (gvopVersionParams.bIDEDeviceMap >> nDrive & 0x10) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;


    // 输出参数
    BYTE btIDOutCmd[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];

    if(DoIdentify(hFile,
                    &InParams,
                    (PSENDCMDOUTPARAMS)btIDOutCmd,
                    (BYTE)btIDCmd,
                    (BYTE)nDrive, &dwBytesReturned) == FALSE)    return -3;
    ::CloseHandle(hFile);

    DWORD dwDiskData[256];
    USHORT *pIDSector; // 对应结构IDSECTOR,见头文件

    pIDSector = (USHORT*)((SENDCMDOUTPARAMS*)btIDOutCmd)->bBuffer;
    for(int i=0; i < 256; i++)    dwDiskData[i] = pIDSector[i];

    // 取系列号
    ZeroMemory(szSerialNumber, sizeof(szSerialNumber));
    strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19));

    // 取模型号
    ZeroMemory(szModelNumber, sizeof(szModelNumber));
    strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46));

    return 0;
}

BOOL __fastcall DoIdentify( HANDLE hPhysicalDriveIOCTL,
                            PSENDCMDINPARAMS pSCIP,
                            PSENDCMDOUTPARAMS pSCOP,
                            BYTE btIDCmd,
                            BYTE btDriveNum,
                            PDWORD pdwBytesReturned)
{
    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 = (btDriveNum & 1) ? 0xB0 : 0xA0;
    pSCIP->irDriveRegs.bCommandReg = btIDCmd;
    pSCIP->bDriveNumber = btDriveNum;
    pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;

    return DeviceIoControl(    hPhysicalDriveIOCTL,
                            SMART_RCV_DRIVE_DATA,
                            (LPVOID)pSCIP,
                            sizeof(SENDCMDINPARAMS) - 1,
                            (LPVOID)pSCOP,
                            sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
                            pdwBytesReturned, NULL);
}

char *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex)
{
    static char szResBuf[1024];
    char ss[256];
    int nIndex = 0;
    int nPosition = 0;

    for(nIndex = nFirstIndex; nIndex <= nLastIndex; nIndex++)
    {
        ss[nPosition] = (char)(dwDiskData[nIndex] / 256);
        nPosition++;

        // Get low BYTE for 2nd character
        ss[nPosition] = (char)(dwDiskData[nIndex] % 256);
        nPosition++;
    }

    // End the string
    ss[nPosition] = '\0';

    int i, index=0;
    for(i=0; i<nPosition; i++)
    {
        if(ss[i]==0 || ss[i]==32)    continue;
        szResBuf[index]=ss[i];
        index++;
    }
    szResBuf[index]=0;

    return szResBuf;
}

详细信息请搜索msdn。

上述代码在WinXP sp2平台测试通过。

原创粉丝点击