参考:显示卷路径
代码整理:
void GetVolumePaths(__in PWCHAR VolumeName, std::vector<std::wstring>& paths)
{
paths.clear();
DWORD CharCount = MAX_PATH + 1;
PWCHAR Names = NULL;
for (;;)
{
// Allocate a buffer to hold the paths.
Names = (PWCHAR) new BYTE[CharCount * sizeof(WCHAR)];
if (!Names) return;
// Obtain all of the paths
// for this volume.
BOOL Success = GetVolumePathNamesForVolumeNameW(VolumeName, Names, CharCount, &CharCount);
if (Success)
{
for (PWCHAR NameIdx = Names; NameIdx[0] != L'\0'; NameIdx += wcslen(NameIdx) + 1)
{
XLOGI("GetVolumePaths VolumeName:%s NtName:%s", W2ACSTR(VolumeName), W2ACSTR(NameIdx));
//删除末尾的 '\'
std::wstring wtemp = NameIdx;
if (!wtemp.empty() && wtemp[wtemp.size() - 1] == '\\')
wtemp.erase(wtemp.size() - 1);
paths.push_back(wtemp);
}
break;
}
if (GetLastError() != ERROR_MORE_DATA)break;
// Try again with the
// new suggested size.
delete[] Names;
Names = NULL;
}
if (Names != NULL)
{
delete[] Names;
Names = NULL;
}
return;
}
DWORD EnumtVolumeW(std::map<std::wstring, std::wstring>& map_nt_to_dos_paths)
{
// Enumerate all volumes in the system.
DWORD dwRet = ERROR_SUCCESS;
WCHAR VolumeName[MAX_PATH] = L"";
HANDLE FindHandle = FindFirstVolumeW(VolumeName, ARRAYSIZE(VolumeName));
if (FindHandle == INVALID_HANDLE_VALUE) return GetLastError();
for (;;)
{
// Skip the \\?\ prefix and remove the trailing backslash.
size_t Index = wcslen(VolumeName) - 1;
if (VolumeName[0] != L'\\' ||
VolumeName[1] != L'\\' ||
VolumeName[2] != L'?' ||
VolumeName[3] != L'\\' ||
VolumeName[Index] != L'\\')
{
dwRet = ERROR_BAD_PATHNAME;
break;
}
//
// QueryDosDeviceW does not allow a trailing backslash,
// so temporarily remove it.
VolumeName[Index] = L'\0';
WCHAR NtName[MAX_PATH] = L"";
DWORD CharCount = QueryDosDeviceW(&VolumeName[4], NtName, ARRAYSIZE(NtName));
VolumeName[Index] = L'\\';
if (CharCount == 0)
{
dwRet = GetLastError();
break;
}
std::vector<std::wstring> vpaths;
GetVolumePaths(VolumeName, vpaths);
XLOGI("EnumtVolumeW NtName[%s] vpaths size:%d", W2ACSTR(NtName), vpaths.size());
for (auto &it: vpaths)
{
XLOGI("EnumtVolumeW NtName[%s] path[%s]", W2ACSTR(NtName), W2ACSTR(it));
}
map_nt_to_dos_paths[NtName] = vpaths.empty() ? L"" : vpaths[0];
// Move on to the next volume.
if (!FindNextVolumeW(FindHandle, VolumeName, ARRAYSIZE(VolumeName)))
{
dwRet = GetLastError();
if (dwRet != ERROR_NO_MORE_FILES)break;
// Finished iterating
// through all the volumes.
dwRet = ERROR_SUCCESS;
break;
}
}
FindVolumeClose(FindHandle);
FindHandle = INVALID_HANDLE_VALUE;
return dwRet;
}
std::wstring NtPathToDosPath(const std::wstring& ntpath)
{
static const std::wstring NT_PREFIX = L"\\Device\\";
if (_wcsnicmp(ntpath.c_str(), NT_PREFIX.c_str(), NT_PREFIX.size()) != 0) return L"";
std::wstring res;
size_t wkey_size = 0;
std::lock_guard<std::recursive_mutex> lk(m_data_mtx);
for (auto &it:m_mapNtNameToDrivers)
{
if (_wcsnicmp(it.first.c_str(), ntpath.c_str(), it.first.size()) == 0)
{
//尽可能匹配多的字符 eg:\Device\VDXCLN12 \Device\VDXCLN1
if (it.first.size() > wkey_size)
{
wkey_size = it.first.size();
res = it.second + ntpath.substr(it.first.size());
}
}
}
return res;
}
测试: