Skip to content

Commit c3ab168

Browse files
committed
listmount/listvolume
1 parent cbf5f02 commit c3ab168

File tree

1 file changed

+81
-0
lines changed
  • crates/vm/src/stdlib

1 file changed

+81
-0
lines changed

crates/vm/src/stdlib/nt.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,87 @@ pub(crate) mod module {
700700
Ok(vm.ctx.new_list(drives))
701701
}
702702

703+
#[pyfunction]
704+
fn listvolumes(vm: &VirtualMachine) -> PyResult<PyListRef> {
705+
use windows_sys::Win32::Foundation::ERROR_NO_MORE_FILES;
706+
707+
let mut result = Vec::new();
708+
let mut buffer = [0u16; Foundation::MAX_PATH as usize + 1];
709+
710+
let find = unsafe { FileSystem::FindFirstVolumeW(buffer.as_mut_ptr(), buffer.len() as _) };
711+
if find == INVALID_HANDLE_VALUE {
712+
return Err(errno_err(vm));
713+
}
714+
715+
loop {
716+
// Find the null terminator
717+
let len = buffer.iter().position(|&c| c == 0).unwrap_or(buffer.len());
718+
let volume = String::from_utf16_lossy(&buffer[..len]);
719+
result.push(vm.new_pyobj(volume));
720+
721+
let ret = unsafe {
722+
FileSystem::FindNextVolumeW(find, buffer.as_mut_ptr(), buffer.len() as _)
723+
};
724+
if ret == 0 {
725+
let err = io::Error::last_os_error();
726+
unsafe { FileSystem::FindVolumeClose(find) };
727+
if err.raw_os_error() == Some(ERROR_NO_MORE_FILES as i32) {
728+
break;
729+
}
730+
return Err(err.to_pyexception(vm));
731+
}
732+
}
733+
734+
Ok(vm.ctx.new_list(result))
735+
}
736+
737+
#[pyfunction]
738+
fn listmounts(volume: OsPath, vm: &VirtualMachine) -> PyResult<PyListRef> {
739+
use windows_sys::Win32::Foundation::ERROR_MORE_DATA;
740+
741+
let wide = volume.to_wide_cstring(vm)?;
742+
let mut buflen: u32 = Foundation::MAX_PATH + 1;
743+
let mut buffer: Vec<u16> = vec![0; buflen as usize];
744+
745+
loop {
746+
let success = unsafe {
747+
FileSystem::GetVolumePathNamesForVolumeNameW(
748+
wide.as_ptr(),
749+
buffer.as_mut_ptr(),
750+
buflen,
751+
&mut buflen,
752+
)
753+
};
754+
if success != 0 {
755+
break;
756+
}
757+
let err = io::Error::last_os_error();
758+
if err.raw_os_error() == Some(ERROR_MORE_DATA as i32) {
759+
buffer.resize(buflen as usize, 0);
760+
continue;
761+
}
762+
return Err(err.to_pyexception(vm));
763+
}
764+
765+
// Parse null-separated strings
766+
let mut result = Vec::new();
767+
let mut start = 0;
768+
for (i, &c) in buffer.iter().enumerate() {
769+
if c == 0 {
770+
if i > start {
771+
let mount = String::from_utf16_lossy(&buffer[start..i]);
772+
result.push(vm.new_pyobj(mount));
773+
}
774+
start = i + 1;
775+
if start < buffer.len() && buffer[start] == 0 {
776+
break; // Double null = end
777+
}
778+
}
779+
}
780+
781+
Ok(vm.ctx.new_list(result))
782+
}
783+
703784
#[pyfunction]
704785
fn set_handle_inheritable(
705786
handle: intptr_t,

0 commit comments

Comments
 (0)