@@ -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