【问题标题】:Getting List of Volumes always Says C:\获取卷列表总是说 C:\
【发布时间】:2011-09-29 16:23:57
【问题描述】:

为什么下面的代码总是报告 C:\ 尽管它报告了不同的设备名称

  handle = FindFirstVolumeW(volName, sizeof(volName));
  do{
    wchar_t wVolName[MAX_PATH];
    QString::fromWCharArray(volName).toWCharArray(wVolName);//make a copy of volName on wVolName
    wVolName[wcslen(volName)-1] = L'\0';
    wchar_t wDeviceName[MAX_PATH];
    int charCount = 0;
    charCount = QueryDosDeviceW(&wVolName[4], wDeviceName, ARRAYSIZE(wDeviceName));

    qDebug() << QString::fromWCharArray(wVolName) << "Device: " << QString::fromWCharArray(wDeviceName);//print wVolName and wDeviceName

    wchar_t driveName[MAX_PATH];
    GetVolumePathName(wDeviceName, driveName, MAX_PATH);
    CloseHandle(handle);

    qDebug() << QString::fromWCharArray(driveName);

  }while(FindNextVolume(handle, volName, sizeof(volName)));
  FindVolumeClose(handle);

输出:

"\\?\Volume{5c77cc58-d5ab-11e0-a0ec-806d6172696f}" Device:  "\Device\HarddiskVolume2" 
"C:\" 
"\\?\Volume{5c77cc59-d5ab-11e0-a0ec-806d6172696f}" Device:  "\Device\HarddiskVolume3" 
"C:\" 
"\\?\Volume{5c77cc57-d5ab-11e0-a0ec-806d6172696f}" Device:  "\Device\CdRom0" 
"C:\" 
"\\?\Volume{5c77cc56-d5ab-11e0-a0ec-806d6172696f}" Device:  "\Device\Floppy0" 
"C:\" 
"\\?\Volume{8d974f2c-e9a1-11e0-b7da-0013d407432f}" Device:  "\Device\Harddisk1\DP(1)0-    0+8" 
"C:\" 

为什么不报告DE等..

编辑

以及如何获得分配给卷的驱动器号

【问题讨论】:

  • 你检查GetVolumePathName成功了吗?它是否返回错误或成功代码?
  • 因为\Device\HarddiskVolume2 可能会根据您当前的目录解析为C:\Device\HarddiskVolume2
  • 文档中其实是这样写的:必须指定一个有效的Win32命名空间路径。如果指定 NT 命名空间路径,例如“\DosDevices\H:”或“\Device\HardDiskVolume6”,则该函数返回当前卷的驱动器号,而不是该 NT 命名空间路径的驱动器号。
  • @Useless:是的,我检查过了。它返回 1。我只是省略了它以简要介绍代码。
  • @avakar: 那我需要做些什么来防止它以这种方式播放(前置`C:\`)?

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


【解决方案1】:

函数的文档说明了一切:

您必须指定有效的 Win32 命名空间路径。如果指定 NT 命名空间路径,例如“\DosDevices\H:”或“\Device\HardDiskVolume6”,则该函数返回当前卷的驱动器号,而不是该 NT 命名空间路径的驱动器号。

顺便说一句,一个卷可以挂载到多个驱动器号(像C: 这样的驱动器名称只不过是 NT 命名空间中的一个符号链接),因此以这种方式进行翻译没有任何意义。

【讨论】:

  • 那我需要做什么才能让它不总是返回当前的卷?
  • @NeelBasu,你可以遍历所有驱动器号,将它们解析为 NT 路径,然后进行比较。
  • 那将是一种蛮力。我想避免暴力破解
  • 不管怎样,你必须通过所有的符号链接。设备对象上没有反向引用列表。
【解决方案2】:

来自GetVolumePathName documentation

如果您指定一个相对目录或文件名而不带卷 限定符,GetVolumePathName 返回当前的驱动器号 音量。

【讨论】:

  • 那我需要做什么才能让它不总是返回当前的卷?
  • @NeelBasu,使用 GetVolumePathNamesForVolumeName 代替 wVolName 作为参数。
  • 是的,伙计!它的工作。但还有一个问题。它说 GetVolumePathNames 那么如果有多个地方它已经安装了它会如何表现?
  • 哦!我明白了“列表是一个以空字符结尾的字符串数组,由一个额外的空字符终止。”但我必须说这是一个非常糟糕的设计
【解决方案3】:

也许是因为你在循环中调用CloseHandle:不要那样做。

您的代码看起来像是在 http://msdn.microsoft.com/en-us/library/cc542456%28v=vs.85%29.aspx 之后建模的:您会注意到他们调用 CloseHandle 的唯一时间是在整个循环完成之后。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-20
  • 1970-01-01
  • 2015-02-20
  • 1970-01-01
  • 1970-01-01
  • 2015-10-21
相关资源
最近更新 更多