Skip to content

Commit a43868f

Browse files
committed
listmount/listvolume
1 parent c9c9800 commit a43868f

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
@@ -682,6 +682,87 @@ pub(crate) mod module {
682682
Ok(vm.ctx.new_list(drives))
683683
}
684684

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

0 commit comments

Comments
 (0)