如何获取物理驱动器的卷ID?

时间:2016-06-03 02:55:58

标签: c++ winapi visual-c++ disk

问题

我正在尝试从物理驱动器获取卷ID。

我的代码

// define disk handle
HANDLE VDHANDLE;

// set "open disk" parameters
OPEN_VIRTUAL_DISK_PARAMETERS VHD_OPEN_PARAM;
VHD_OPEN_PARAM.Version = OPEN_VIRTUAL_DISK_VERSION_1;
VHD_OPEN_PARAM.Version1.RWDepth = OPEN_VIRTUAL_DISK_RW_DEPTH_DEFAULT;

// set storage type
VIRTUAL_STORAGE_TYPE VHD_STORAGE;
VHD_STORAGE.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_VHD;
VHD_STORAGE.VendorId = VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT;

// set "attach disk" parameters
ATTACH_VIRTUAL_DISK_PARAMETERS VHD_ATTACH_PARAM;
VHD_ATTACH_PARAM.Version = ATTACH_VIRTUAL_DISK_VERSION_1;

// open disk
if ( OpenVirtualDisk( &VHD_STORAGE, L"F:\\MyStorageBunker.vhd",
                      VIRTUAL_DISK_ACCESS_ALL, OPEN_VIRTUAL_DISK_FLAG_NONE,
                      &VHD_OPEN_PARAM, &VDHANDLE ) != ERROR_SUCCESS )
{
    return ERR_MOUNT_SCRIPTCREATE;
}

// attach drive
if ( AttachVirtualDisk( VDHANDLE, 0, ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME,
                        0, &VHD_ATTACH_PARAM, 0 ) != ERROR_SUCCESS )
{
    return ERR_MOUNT_SCRIPTEXECUTE;
}

// Get attached drive & info
wchar_t DriveInfo[ MAX_PATH ];
ULONG bufferSize = sizeof( DriveInfo );
GetVirtualDiskPhysicalPath( VDHANDLE, &bufferSize, DriveInfo );
// DriveInfo raw output = \PHYSICALDISKX
// X = volume id

我尝试了什么

std::wstringstream tmp;
int value;
char c;
std::wstringstream  ss( DriveInfo );
ss >> tmp >> c >> value;

问题

没有运营商“>>”匹配这些操作数

问题

  1. 如何从wchar_t DriveInfo
  2. 中提取卷ID
  3. 有没有办法获得除GetVirtualDiskPhysicalPath以外的卷ID?

1 个答案:

答案 0 :(得分:-2)

我从这个我无法回想起的地方抄袭了这个代码,但它似乎适用于从第一个有效驱动器获取序列号。对不起,如果它没有编译,我不得不用普通的字符串替换我们自己的字符串类。您可能想要的是调用GetVolumeInformation()

template <class ELT> static const ELT* NextToken(const ELT* ptr) {
    // Skip this null-terminated string
    while (*ptr != 0) {
        ptr++;
    }
    ptr++;
    return ptr;
}
int getDiskId() {
    int bufSize = GetLogicalDriveStrings(0, 0);
    WCHAR* buffer = new WCHAR[bufSize];
    GetLogicalDriveStrings(bufSize, buffer);
    std::vector<std::string> driveStrings;
    for (const WCHAR *ptr = buffer; *ptr != 0; ptr = NextToken(ptr)) {
        if (toupper(*ptr) == 'A' || toupper(*ptr) == 'B') {
            continue;
        }
        std::string tmp;
        tmp += toupper(*ptr);
        driveStrings.push_back(tmp);
    }
    // want lowest letter first
    std::sort(driveStrings.begin(), driveStrings.end());
    for (int i = 0; i < driveStrings.size(); i++) {
        DWORD dummy(0);
        DWORD serialNumber(0);
        if (
            GetVolumeInformation(
                driveStrings[i].c_str(),        // lpRootPathName
                0,          // lpVolumeNameBuffer
                0,          // nVolumeNameSize
                &serialNumber,
                &dummy,     // lpMaximumComponentLength
                &dummy,     // lpFileSystemFlags
                0,          // lpFileSystemNameBuffer
                0           // nFileSystemNameSize
            )
        ) {
            break;
        }
    }
    delete [] buffer;
    return serialNumber;
}