硬盘获取uuid的方法(FAT/FAT32/NTFS)

1 磁盘的一些信息

1.1 引导项简单描述

       MBR分区表的硬盘最多只能划分4个主分区磁盘,并且MBR最大仅支持2TB的硬盘,但拥有很好的兼容性,如果需要分区的硬盘容量超过2TB了,则需要使用GPT分区表类型,此分区表类型不受分区个数,硬盘大小的限制,最大支持18EB(1EB=1024PB=1,048,576TB),且是一种新的硬盘分区标准。

      GPT是一个正逐渐取代MBR的新标准,它由UEFI而形成的,有了UEFI用于取代老旧的BIOS,而GPT则取代老旧的MBR,磁盘驱动器容量可以大得多。Windows最大仅支持128个GPT分区,不过NTFS格式最大仅支持256TB,大到操作系统和文件系统都没法支持。

1.2 windows系统的磁盘格式说明

(1)FAT模式;

        FAT即FAT16,最大支持分区大小是4GB,一般用在MS-DOS,WIN95等系统。FAT32的最大分区是2TB,但是不支持小于512MB的分区。

(2)FAT32模式;

 

(3)NTFS模式;

 

        没有直接列出磁盘的uuid信息。

(4)工具里面显示的磁盘格式。

 

2 获取硬盘的uuid代码实现

        注意NTFS格式磁盘的uuid,通过CreateFile打开磁盘时,磁盘的路径是\\\\.\\c:的。\\\\.\\c:\\这样会提示打开失败。

QString formatFat32UUID(LARGE_INTEGER uuid)
{
    BYTE b[4];
    DWORD uuidHigh = uuid.HighPart;
    memcpy(b, &uuidHigh, 4);

    QString uuidstr = QString("%1%2-%3%4").
                      arg(int(b[3]), 2, 16, QLatin1Char('0')).
                      arg(int(b[2]), 2, 16, QLatin1Char('0')).
                      arg(int(b[1]), 2, 16, QLatin1Char('0')).
                      arg(int(b[0]), 2, 16, QLatin1Char('0'));
    return uuidstr.toUpper();
}

QString formatNTFSUUID(LARGE_INTEGER uuid)
{
    BYTE b[8];
    memcpy(b, &uuid, 8);

    QString uuidstr = QString("%1%2%3%4%5%6%7%8").
                      arg(int(b[7]), 2, 16, QLatin1Char('0')).
                      arg(int(b[6]), 2, 16, QLatin1Char('0')).
                      arg(int(b[5]), 2, 16, QLatin1Char('0')).
                      arg(int(b[4]), 2, 16, QLatin1Char('0')).
                      arg(int(b[3]), 2, 16, QLatin1Char('0')).
                      arg(int(b[2]), 2, 16, QLatin1Char('0')).
                      arg(int(b[1]), 2, 16, QLatin1Char('0')).
                      arg(int(b[0]), 2, 16, QLatin1Char('0'));
    return uuidstr.toUpper();
}

bool getNTFSUUID(const QString& strDrive, LARGE_INTEGER& uuid)
{
    HANDLE fileHandle = CreateFile(strDrive.toStdWString().c_str(), // \\\\.\\c: or use syntax "\\?\Volume{GUID}"
                                   GENERIC_READ,
                                   FILE_SHARE_READ | FILE_SHARE_WRITE,
                                   NULL,
                                   OPEN_EXISTING,
                                   0,
                                   NULL);

    if (INVALID_HANDLE_VALUE == fileHandle) {
        int nErrorCode = GetLastError();
        qDebug() << "getNTFSUUID fail;errorCode=" << nErrorCode;
        return false;
    }

    DWORD i;
    NTFS_VOLUME_DATA_BUFFER ntfsInfo;
    DeviceIoControl(fileHandle,
                    FSCTL_GET_NTFS_VOLUME_DATA,
                    NULL,
                    0,
                    &ntfsInfo,
                    sizeof(ntfsInfo),
                    &i,
                    NULL);

    CloseHandle(fileHandle);
    uuid = ntfsInfo.VolumeSerialNumber;
    return true;
}

void testGetDiskUUID(const QString& lpRootPathName)
{
    // QString lpRootPathName = "C:\\";
    LPTSTR lpVolumeNameBuffer = new TCHAR[12]; //磁盘卷标
    DWORD nVolumeNameSize = 12; // 卷标的字符串长度
    DWORD VolumeSerialNumber;//硬盘序列号  ==》
    DWORD MaximumComponentLength;// 最大的文件长度
    LPTSTR lpFileSystemNameBuffer = new TCHAR[10]; // 存储所在盘符的分区类型的长指针变量
    DWORD nFileSystemNameSize = 10; // 分区类型的长指针变量所指向的字符串长度
    DWORD FileSystemFlags;// 文件系统的一此标志

    GetVolumeInformation((LPTSTR)lpRootPathName.utf16(),
                         lpVolumeNameBuffer, nVolumeNameSize,
                         &VolumeSerialNumber, &MaximumComponentLength,
                         &FileSystemFlags,
                         lpFileSystemNameBuffer, nFileSystemNameSize);

    qDebug() << VolumeSerialNumber;

    QString strXuuid = "";
    QStorageInfo storage(lpRootPathName);

    QString fileType = storage.fileSystemType();

    LARGE_INTEGER uUUID;
    uUUID.HighPart = VolumeSerialNumber;

    if (fileType.compare("NTFS", Qt::CaseInsensitive) == 0) {
        // QString  strVol = "\\\\.\\i:";   // ok;  CreateFile打开磁盘驱动器,\\\\.\\c:;
        QString  strVol = "\\\\.\\" + lpRootPathName.left(2);  // \\\\.\\c:\\不支持这种情况;
        //    QString  strVol = "\\Device\\HarddiskVolume10\\";   // xx;
        // QString  strVol = "\\?\Volume{73534fd4-d231-11eb-9a29-0800272918b7}";  // xx;
        getNTFSUUID(strVol, uUUID);
        strXuuid = formatNTFSUUID(uUUID);   // getNTFSUUID失败,则只有后面一半的guid;
    } else if ((fileType.compare("FAT", Qt::CaseInsensitive) == 0)
               || (fileType.compare("FAT32", Qt::CaseInsensitive)) == 0) {
        strXuuid = formatFat32UUID(uUUID);  // ok;
    }

    qDebug() << "rootPath:" << lpRootPathName << "; fileType=" << fileType << "; uuid=" << strXuuid;
}

3 调用方式

//    testGetDiskUUID("G:\\");
//    testGetDiskUUID("h:\\");
    testGetDiskUUID("I:\\");
//    testGetDiskUUID("c:\\");

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值