cap-std
cap-std copied to clipboard
get entries of a windows unc path failed when call `cap_std::fs::Dir::from_std_file(dir).entries()`
test code
let path = std::path::Path::new("C:\\Users\\path\\to\\folder"); //works fine
let path = std::path::Path::new("\\\\?\\UNC\\Mac\\path\\to\\folder"); //throw an error
let dir = std::fs::OpenOptions::new()
.read(true)
.custom_flags(33554432u32)
.open(path).unwrap();
let entries = cap_std::fs::Dir::from_std_file(dir).entries();
dbg!(entries);
reason
After debugged, I found cap_primitives/src/windows/fs get_path cause this problem.
let wide_final = if wide.starts_with(&['\\' as u16, '\\' as _, '?' as _, '\\' as _]) {
&wide[4..] //throw error
//&wide //change to this and it works
} else {
&wide
};
when path start with \\\\?\\, \\\\?\\ will be remove, and \\\\?\\UNC\\Mac\\path\\to\\folder changed to UNC\\Mac\\path\\to\\folder, so a path not found error be throwed.
dependency chain
the dependency chain is:
cap_std::fs::dir::Dir::entriescap_primitives::fs::read_dir::read_base_dircap_primitives::windows::fs::read_dir_inner::ReadDirInner::read_base_dircap_primitives::windows::fs::read_dir_inner::ReadDirInner::new_uncheckedcap_primitives::windows::fs::get_path::concatenatecap_primitives::windows::fs::get_path::get_path
cargo.toml
cap-std = "1.0.14"
My guess is that that code for removing \\\\?\\ is ensuring that we can concatenate a relative path containing forward-slash separators onto the resulting path, which I think wouldn't work if the \\\\?\\ prefix were left in place. It may be that fixing this properly will require eliminating all code in cap-std that concatenates relative paths, and using NtCreateFile directly instead. We now do that for open, but we still use path concatenation in many of the other functions.