VC获取硬盘序列号



转载自: http://blog.163.com/jinfd@126/blog/static/6233227720133218314327/

博主写的很认真,建议大家看原博客

#include "stdafx.h"

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif

#include <windows.h>
#include <winioctl.h>

//
BOOL GetPhyDriveSerial(LPTSTR pModelNo, LPTSTR pSerialNo);
void ToLittleEndian(PUSHORT pWords, int nFirstIndex, int nLastIndex, LPTSTR pBuf);
void TrimStart(LPTSTR pBuf);

int _tmain(int argc, _TCHAR* argv[])
{
    TCHAR szModelNo[48], szSerialNo[24];
    if(GetPhyDriveSerial(szModelNo, szSerialNo))
    {
        _tprintf(_T(" : 0 1 2\n"));
        _tprintf(_T(" : 012345678901234567890123456789\n"));
        _tprintf(_T("Model No: %s\n"), szModelNo);
        _tprintf(_T("Serial No: %s\n"), szSerialNo);
        TrimStart(szSerialNo);
        _tprintf(_T("Serial No: %s\n"), szSerialNo);
    }
    else
    {
        _tprintf(_T("Failed.\n"));
    }
    getchar();
    return 0;
}

//
// Model Number: 40 ASCII Chars
// SerialNumber: 20 ASCII Chars
//
BOOL GetPhyDriveSerial(LPTSTR pModelNo, LPTSTR pSerialNo)
{
    //-1是因为 SENDCMDOUTPARAMS 的结尾是 BYTE bBuffer[1];
    BYTE IdentifyResult[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
    DWORD dwBytesReturned;
    GETVERSIONINPARAMS get_version;
    SENDCMDINPARAMS send_cmd = { 0 };

    HANDLE hFile = CreateFile(_T("\\\\.\\PHYSICALDRIVE0"), GENERIC_READ | GENERIC_WRITE,    
        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if(hFile == INVALID_HANDLE_VALUE)
        return FALSE;

    //get version
    DeviceIoControl(hFile, SMART_GET_VERSION, NULL, 0,
        &get_version, sizeof(get_version), &dwBytesReturned, NULL);

    //identify device
    send_cmd.irDriveRegs.bCommandReg = (get_version.bIDEDeviceMap & 0x10)? ATAPI_ID_CMD : ID_CMD;
    DeviceIoControl(hFile, SMART_RCV_DRIVE_DATA, &send_cmd, sizeof(SENDCMDINPARAMS) - 1,
        IdentifyResult, sizeof(IdentifyResult), &dwBytesReturned, NULL);
    CloseHandle(hFile);

    //adjust the byte order
    PUSHORT pWords = (USHORT*)(((SENDCMDOUTPARAMS*)IdentifyResult)->bBuffer);
    ToLittleEndian(pWords, 27, 46, pModelNo);
    ToLittleEndian(pWords, 10, 19, pSerialNo);
    return TRUE;
}

//把WORD数组调整字节序为little-endian,并滤除字符串结尾的空格。
void ToLittleEndian(PUSHORT pWords, int nFirstIndex, int nLastIndex, LPTSTR pBuf)
{
    int index;
    LPTSTR pDest = pBuf;
    for(index = nFirstIndex; index <= nLastIndex; ++index)
    {
        pDest[0] = pWords[index] >> 8;
        pDest[1] = pWords[index] & 0xFF;
        pDest += 2;
    }    
    *pDest = 0;
    
    //trim space at the endof string; 0x20: _T(' ')
    --pDest;
    while(*pDest == 0x20)
    {
        *pDest = 0;
        --pDest;
    }
}

//滤除字符串起始位置的空格
void TrimStart(LPTSTR pBuf)
{
    if(*pBuf != 0x20)
        return;

    LPTSTR pDest = pBuf;
    LPTSTR pSrc = pBuf + 1;
    while(*pSrc == 0x20)
        ++pSrc;

    while(*pSrc)
    {
        *pDest = *pSrc;
        ++pDest;
        ++pSrc;
    }
    *pDest = 0;
}

### 回答1: VC6.0是一个老旧的编程工具,但是它仍然可以读取硬盘序列号硬盘序列号硬盘唯一的标识符,可以帮助我们区分不同的硬盘。下面是读取硬盘序列号的步骤: 1. 在VC6.0中创建一个新的Win32控制台应用程序。 2. 在源文件中添加头文件#include <windows.h>,此头文件中定义了读取硬盘序列号的API函数。 3. 在主函数中,使用GetVolumeInformationA函数获取硬盘的信息,如下: char szVolumeSerialNumber[256]; DWORD dwSerialNumber; DWORD dwMaxComponentLength; DWORD dwFileSystemFlags; char szFileSystemName[256]; BOOL bSuccess = GetVolumeInformationA("C:\\", NULL, 0, &dwSerialNumber, &dwMaxComponentLength, &dwFileSystemFlags, szFileSystemName, 256); 4. 上述代码中,C:\\表示要获取硬盘的驱动器号,NULL表示不需要获取卷标,0表示卷标缓冲区的大小,而dwSerialNumber即为所获取硬盘序列号。 5. 将硬盘序列号转换成字符串格式: sprintf(szVolumeSerialNumber, "%08X", dwSerialNumber); 6. 最终,将读取到的硬盘序列号输出到控制台: printf("Hard Disk Serial Number: %s\n", szVolumeSerialNumber); 通过以上步骤,就可以利用VC6.0读取硬盘序列号了,这对于某些需要以硬盘序列号作为标识的程序很有用。 ### 回答2: VC6.0是微软早期的编程开发工具之一,使用它可以读取硬盘序列号硬盘序列号是指硬盘唯一的标识符,每个硬盘都具有独特的序列号读取硬盘序列号可以实现硬件设备的唯一标识和数据安全性的保证。 在VC6.0中,读取硬盘序列号需要用到Windows API函数GetVolumeInformation,这个函数的作用是获取指定磁盘卷的相关信息,包括卷标、文件系统和序列号等。 具体步骤如下: 1.调用GetVolumeInformation函数,指定需要获取信息的硬盘驱动器号(例如:C盘为0、D盘为1等)。 2.将函数返回的信息存储在变量中,其中包括硬盘序列号等。 3.将硬盘序列号转换成字符串型,以便于进行后续操作。 需要注意的是,这种方法只适用于单个硬盘的情况,若系统中存在多个硬盘,则需要通过遍历硬盘列表的方式获取每个硬盘序列号。 最后,VC6.0读取硬盘序列号还需要考虑兼容性问题。由于VC6.0是一个比较老的开发工具,可以使用的Windows API函数和数据类型可能不够丰富,因此需要在开发过程中进行充分测试和调试,确保程序在各个平台上都能正常运行。 ### 回答3: VC++6.0读取硬盘序列号可以使用Windows API函数来实现。具体步骤如下: 1. 打开硬盘设备文件 可以使用CreateFile函数打开硬盘设备文件,设备名称可以通过GetLogicalDriveStrings函数获取。 2. 发送IO控制命令 使用DeviceIoControl函数发送IO控制命令获取硬盘序列号。使用的命令为IOCTL_STORAGE_QUERY_PROPERTY,具体细节可以参考Microsoft官方文档。 3. 解析获取到的数据 硬盘序列号是以十六进制形式存储在结构体中的,需要将其转换为字符串形式。具体实现可以参考以下代码示例: ```c++ HANDLE hDevice; DWORD bytesReturned; STORAGE_PROPERTY_QUERY query; query.PropertyId = StorageDeviceProperty; query.QueryType = PropertyStandardQuery; STORAGE_DEVICE_DESCRIPTOR descriptor; if (GetLogicalDriveStrings(0, NULL) == 0) { cout << "无法获取磁盘设备名称!" << endl; return 0; } TCHAR driveStrings[MAX_PATH]; if (GetLogicalDriveStrings(MAX_PATH, driveStrings) == 0) { cout << "无法获取磁盘设备名称!" << endl; return 0; } TCHAR* drive = driveStrings; while (*drive != 0) { TCHAR drivePath[MAX_PATH] = { 0 }; _sntprintf(drivePath, MAX_PATH - 1, _T("\\\\.\\%c:"), *drive); hDevice = CreateFile(drivePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice != INVALID_HANDLE_VALUE) { if (DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), &descriptor, sizeof(descriptor), &bytesReturned, NULL)) { DWORD serialNumberOffset = descriptor.SerialNumberOffset; if (serialNumberOffset != 0) { char serialNumber[255]; ZeroMemory(serialNumber, sizeof(serialNumber)); memcpy(serialNumber, ((char*)&descriptor) + serialNumberOffset, (descriptor.SerialNumberLength - 1) * 2 + 1); cout << "磁盘" << *drive << "的序列号为:" << serialNumber << endl; } } CloseHandle(hDevice); } drive += _tcslen(drive) + 1; } ``` 以上代码可遍历系统中的所有磁盘,输出磁盘序列号
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值