如何获取物理驱动器的卷 ID?
Posted
技术标签:
【中文标题】如何获取物理驱动器的卷 ID?【英文标题】:How to get the physical drive's volume id? 【发布时间】:2016-10-02 23:31:36 【问题描述】:问题
我正在尝试从物理驱动器获取卷 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;
问题
没有运算符“>>”匹配这些操作数
问题
-
如何从
wchar_t DriveInfo
中提取卷ID?
除了GetVirtualDiskPhysicalPath
,还有什么方法可以获取volume id吗?
【问题讨论】:
通常,物理驱动器对象没有卷 ID - 只有该驱动器上的各个分区有。我认为安装的.vhd 通常也是如此。 (但我不确定您安装 ISO 的情况。) 【参考方案1】:我从某个我不记得的地方抄录了这段代码,但它似乎适用于从第一个有效驱动器获取序列号。抱歉,如果它不能编译,我不得不用通用的字符串类替换我们自己的字符串类。你可能想要的就是调用 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;
【讨论】:
我认为这只适用于有问题的卷分配了驱动器号的特殊情况。 这也无法确定 哪个 驱动器号(如果有)属于该驱动器。它只会选择 C: 99% 的时间。此外,A: 和 B: 是合法的硬盘驱动器号。它们不是为任何事情保留的。 @AndrewMedico:嗯,我想技术上是正确的,但我真的不建议使用它们。我不想想到有多少生产代码有类似的硬编码假设。以上是关于如何获取物理驱动器的卷 ID?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 mongoDb java 异步驱动程序插入 mongoDb 集合后获取 _id