diff --git a/vm/src/stdlib/nt.rs b/vm/src/stdlib/nt.rs index cdab9e2f71..3b4d97c0e1 100644 --- a/vm/src/stdlib/nt.rs +++ b/vm/src/stdlib/nt.rs @@ -445,6 +445,39 @@ pub(crate) mod module { Ok(vm.ctx.new_list(drives)) } + #[pyfunction] + fn listvolumes(vm: &VirtualMachine) -> PyResult<PyListRef> { + let mut volumes = vec![]; + let mut buffer = [0u16; 257]; + let find = unsafe { FileSystem::FindFirstVolumeW(buffer.as_mut_ptr(), buffer.len() as _) }; + if find == windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE { + return Err(errno_err(vm)); + } + let mut err = 0; + while err == 0 { + let s = unsafe { widestring::WideCString::from_ptr_str(buffer.as_mut_ptr()) }; + let s = s.to_string_lossy(); + if s.is_empty() { + break; + } + volumes.push(s.to_string()); + let ret = unsafe { + FileSystem::FindNextVolumeW(find, buffer.as_mut_ptr(), buffer.len() as _) + }; + if ret == 0 { + err = std::io::Error::last_os_error().raw_os_error().unwrap_or(0); + } + } + if find != windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE { + unsafe { FileSystem::FindVolumeClose(find) }; + } + if err != 0 && err != windows_sys::Win32::Foundation::ERROR_NO_MORE_FILES as i32 { + return Err(std::io::Error::from_raw_os_error(err).to_pyexception(vm)); + } + let volumes: Vec<_> = volumes.into_iter().map(|v| vm.new_pyobj(v)).collect(); + Ok(vm.ctx.new_list(volumes)) + } + #[pyfunction] fn set_handle_inheritable( handle: intptr_t, @@ -476,3 +509,4 @@ pub(crate) mod module { Vec::new() } } +}