如何在 C/C 中获取磁盘驱动器序列号

新手上路,请多包涵

这已经得到 回答,但它是一个 C# 解决方案。如何在 C 或 C++ 中执行此操作?

原文由 The Mask 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.6k
2 个回答

有几种方法可以做到这一点。您可以使用系统拨打电话以获取信息。

对于 Linux:

 system("hdparm -i /dev/hda | grep -i serial");

不使用系统:

 static struct hd_driveid hd;
int fd;

if ((fd = open("/dev/hda", O_RDONLY | O_NONBLOCK)) < 0) {
    printf("ERROR opening /dev/hda\n");
    exit(1);
}

if (!ioctl(fd, HDIO_GET_IDENTITY, &hd)) {
    printf("%.20s\n", hd.serial_no);
} else if (errno == -ENOMSG) {
    printf("No serial number available\n");
} else {
    perror("ERROR: HDIO_GET_IDENTITY");
    exit(1);
}

对于 Windows:

 system("wmic path win32_physicalmedia get SerialNumber");

不使用系统(基于 获取 WMI 数据):

 hres = pSvc->ExecQuery(
    bstr_t("WQL"),
    bstr_t("SELECT SerialNumber FROM Win32_PhysicalMedia"),
    WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
    NULL,
    &pEnumerator);
hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);

原文由 G– 发布,翻译遵循 CC BY-SA 3.0 许可协议

对于 Windows,如果您不需要 WMI,请使用 DeviceIOControl()。这是我多年来使用的一个工作实现。

 GetDiskSerialNumber("c:");

执行:

 std::string GetDiskSerialNumber(const std::string& pDevicePath)
{
    // open the device
    HANDLE hDevice = ::CreateFileA(devicePath.c_str(), 0, 0, NULL, OPEN_EXISTING, NULL, NULL);
    if (hDevice == INVALID_HANDLE_VALUE)
    {
        // unable to open disk
        M_LogT("GDSN - CF - FAILED - " << devicePath);
        return "";
    }

    // set the input data structure
    ::STORAGE_PROPERTY_QUERY storagePropertyQuery;
    ::ZeroMemory(&storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY));
    storagePropertyQuery.PropertyId = StorageDeviceProperty;
    storagePropertyQuery.QueryType  = PropertyStandardQuery;

    // get the necessary output buffer size
    STORAGE_DESCRIPTOR_HEADER storageDescriptorHeader = {0};
    DWORD dwBytesReturned = 0;
    if (!::DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &storagePropertyQuery,
            sizeof(STORAGE_PROPERTY_QUERY), &storageDescriptorHeader, sizeof(STORAGE_DESCRIPTOR_HEADER),
            &dwBytesReturned, NULL))
    {
        DWORD error = ::GetLastError();

        ::CloseHandle(hDevice);

        M_LogWarnT("MGDSNV - FAILED - " << M_WinError(error));

        return "";
    }

    // has serial number?
    if (!storageDescriptorHeader.Size)
        return "";

    // alloc the output buffer
    const DWORD dwOutBufferSize = storageDescriptorHeader.Size;
    std::unique_ptr<BYTE[]> pOutBuffer(new BYTE[dwOutBufferSize]);

    ::ZeroMemory(pOutBuffer.get(), dwOutBufferSize);

    // het the storage device descriptor
    if (!::DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &storagePropertyQuery,
            sizeof(STORAGE_PROPERTY_QUERY), pOutBuffer.get(), dwOutBufferSize, &dwBytesReturned, NULL))
    {
        DWORD error = ::GetLastError();
        ::CloseHandle(hDevice);

        LogWarnT("MGDSNV - FAILED - " << M_WinError(error));
        return "";
    }

    // cleanup
    ::CloseHandle(hDevice);

    std::string serial;

    // output buffer points to a STORAGE_DEVICE_DESCRIPTOR structure followed by additional
    // info like vendor ID, product ID, serial number, and so on.
    const STORAGE_DEVICE_DESCRIPTOR* pDeviceDescriptor = (STORAGE_DEVICE_DESCRIPTOR*)pOutBuffer.get();
    if (pDeviceDescriptor->SerialNumberOffset && *(pOutBuffer.get() + pDeviceDescriptor->SerialNumberOffset))
        // get the serial number
        serial = std::string(reinterpret_cast<char*>(pOutBuffer.get() + pDeviceDescriptor->SerialNumberOffset));

    return serial;
}

原文由 Niki 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题