[Lldb-commits] [lldb] 4b703fb - [lldb][windows] enumerate volumes via FindFirstVolumeW (#200231)
via lldb-commits
lldb-commits at lists.llvm.org
Fri May 29 06:09:17 PDT 2026
Author: Charles Zablit
Date: 2026-05-29T14:09:10+01:00
New Revision: 4b703fb5fbb9e517eb205f310a129472f3cac655
URL: https://github.com/llvm/llvm-project/commit/4b703fb5fbb9e517eb205f310a129472f3cac655
DIFF: https://github.com/llvm/llvm-project/commit/4b703fb5fbb9e517eb205f310a129472f3cac655.diff
LOG: [lldb][windows] enumerate volumes via FindFirstVolumeW (#200231)
Added:
Modified:
lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
Removed:
################################################################################
diff --git a/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp b/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
index 140a70d5017c4..22a836f9cbed5 100644
--- a/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
@@ -486,32 +486,74 @@ DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info,
static std::optional<std::string>
ConvertNtDevicePathToDosPath(llvm::ArrayRef<wchar_t> nt_path) {
- std::array<wchar_t, 512> drive_strings;
- drive_strings[0] = L'\0';
- if (!::GetLogicalDriveStringsW(drive_strings.size(), drive_strings.data()))
+ Log *log = GetLog(WindowsLog::Event);
+
+ llvm::SmallVector<wchar_t, MAX_PATH> vol_name(MAX_PATH);
+ HANDLE vol_iter = ::FindFirstVolumeW(vol_name.data(), vol_name.size());
+ if (vol_iter == INVALID_HANDLE_VALUE) {
+ LLDB_LOG(log,
+ "ConvertNtDevicePathToDosPath: FindFirstVolumeW failed, "
+ "error={0}",
+ ::GetLastError());
return std::nullopt;
+ }
+ auto close_iter = llvm::make_scope_exit([&] { ::FindVolumeClose(vol_iter); });
+
+ do {
+ // FindFirstVolumeW yields "\\?\Volume{GUID}\".
+ // QueryDosDeviceW expects "Volume{GUID}".
+ size_t vol_len = ::wcsnlen(vol_name.data(), vol_name.size());
+ if (vol_len < 5 || vol_name[vol_len - 1] != L'\\')
+ continue;
+
+ vol_name[vol_len - 1] = L'\0'; // strip trailing '\' for QueryDosDeviceW
+ llvm::SmallVector<wchar_t, MAX_PATH> dev_name(MAX_PATH);
+ bool ok = ::QueryDosDeviceW(vol_name.data() + 4, // skip "\\?\"
+ dev_name.data(), dev_name.size());
+ vol_name[vol_len - 1] = L'\\'; // restore
+ if (!ok)
+ continue;
- std::array<wchar_t, 3> drive = {L"_:"};
- for (const wchar_t *it = drive_strings.data(); *it != L'\0';
- it += wcslen(it) + 1) {
- drive[0] = it[0];
- std::array<wchar_t, MAX_PATH> device_name;
- if (!::QueryDosDeviceW(drive.data(), device_name.data(),
- device_name.size()))
+ // Check that nt_path begins with this device name followed by '\'.
+ size_t dev_len = ::wcsnlen(dev_name.data(), dev_name.size());
+ if (dev_len == 0 || dev_len >= nt_path.size())
+ continue;
+ if (_wcsnicmp(nt_path.data(), dev_name.data(), dev_len) != 0)
continue;
- size_t device_name_len = wcslen(device_name.data());
- if (device_name_len >= nt_path.size())
+ if (nt_path[dev_len] != L'\\')
continue;
- bool match =
- _wcsnicmp(nt_path.data(), device_name.data(), device_name_len) == 0;
- if (match && nt_path[device_name_len] == L'\\') {
- std::wstring rebuilt_path(drive.data());
- rebuilt_path.append(&nt_path[device_name_len]);
- std::string path_utf8;
- llvm::convertWideToUTF8(rebuilt_path, path_utf8);
- return path_utf8;
+
+ // Prefer a drive-letter/mount-point over the raw volume GUID path.
+ llvm::ArrayRef<wchar_t> mount(vol_name.data(), vol_len);
+ llvm::SmallVector<wchar_t> mount_names;
+ DWORD names_size = 0;
+ ::GetVolumePathNamesForVolumeNameW(vol_name.data(), nullptr, 0,
+ &names_size);
+ if (names_size > 1) {
+ mount_names.resize(names_size);
+ DWORD written = 0;
+ if (::GetVolumePathNamesForVolumeNameW(
+ vol_name.data(), mount_names.data(), names_size, &written) &&
+ mount_names[0] != L'\0') {
+ mount = llvm::ArrayRef<wchar_t>(
+ mount_names.data(),
+ ::wcsnlen(mount_names.data(), mount_names.size()));
+ }
}
- }
+
+ // Build the final path: mount point + rest of nt_path.
+ llvm::SmallVector<wchar_t> dos_wide(mount.begin(), mount.end());
+ if (!dos_wide.empty() && dos_wide.back() == L'\\')
+ dos_wide.pop_back();
+ dos_wide.append(nt_path.begin() + dev_len, nt_path.end());
+
+ std::string result;
+ llvm::convertWideToUTF8(std::wstring(dos_wide.begin(), dos_wide.end()),
+ result);
+ return result;
+ } while (::FindNextVolumeW(vol_iter, vol_name.data(), vol_name.size()));
+
+ LLDB_LOG(log, "ConvertNtDevicePathToDosPath: no matching volume found");
return std::nullopt;
}
More information about the lldb-commits
mailing list