(path: OsPath, vm: &VirtualMachine)
| 846 | /// Check if a path is on a Windows Dev Drive. |
| 847 | #[pyfunction] |
| 848 | fn _path_isdevdrive(path: OsPath, vm: &VirtualMachine) -> PyResult<bool> { |
| 849 | use windows_sys::Win32::Foundation::CloseHandle; |
| 850 | use windows_sys::Win32::Storage::FileSystem::{ |
| 851 | CreateFileW, FILE_FLAG_BACKUP_SEMANTICS, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, |
| 852 | FILE_SHARE_WRITE, GetDriveTypeW, GetVolumePathNameW, OPEN_EXISTING, |
| 853 | }; |
| 854 | use windows_sys::Win32::System::IO::DeviceIoControl; |
| 855 | use windows_sys::Win32::System::Ioctl::FSCTL_QUERY_PERSISTENT_VOLUME_STATE; |
| 856 | use windows_sys::Win32::System::WindowsProgramming::DRIVE_FIXED; |
| 857 | |
| 858 | // PERSISTENT_VOLUME_STATE_DEV_VOLUME flag - not yet in windows-sys |
| 859 | const PERSISTENT_VOLUME_STATE_DEV_VOLUME: u32 = 0x00002000; |
| 860 | |
| 861 | // FILE_FS_PERSISTENT_VOLUME_INFORMATION structure |
| 862 | #[repr(C)] |
| 863 | struct FileFsPersistentVolumeInformation { |
| 864 | volume_flags: u32, |
| 865 | flag_mask: u32, |
| 866 | version: u32, |
| 867 | reserved: u32, |
| 868 | } |
| 869 | |
| 870 | let wide_path = path.to_wide_cstring(vm)?; |
| 871 | let mut volume = [0u16; Foundation::MAX_PATH as usize]; |
| 872 | |
| 873 | // Get volume path |
| 874 | let ret = unsafe { |
| 875 | GetVolumePathNameW(wide_path.as_ptr(), volume.as_mut_ptr(), volume.len() as _) |
| 876 | }; |
| 877 | if ret == 0 { |
| 878 | return Err(vm.new_last_os_error()); |
| 879 | } |
| 880 | |
| 881 | // Check if it's a fixed drive |
| 882 | if unsafe { GetDriveTypeW(volume.as_ptr()) } != DRIVE_FIXED { |
| 883 | return Ok(false); |
| 884 | } |
| 885 | |
| 886 | // Open the volume |
| 887 | let handle = unsafe { |
| 888 | CreateFileW( |
| 889 | volume.as_ptr(), |
| 890 | FILE_READ_ATTRIBUTES, |
| 891 | FILE_SHARE_READ | FILE_SHARE_WRITE, |
| 892 | core::ptr::null(), |
| 893 | OPEN_EXISTING, |
| 894 | FILE_FLAG_BACKUP_SEMANTICS, |
| 895 | core::ptr::null_mut(), |
| 896 | ) |
| 897 | }; |
| 898 | if handle == INVALID_HANDLE_VALUE { |
| 899 | return Err(vm.new_last_os_error()); |
| 900 | } |
| 901 | |
| 902 | // Query persistent volume state |
| 903 | let mut volume_state = FileFsPersistentVolumeInformation { |
| 904 | volume_flags: 0, |
| 905 | flag_mask: PERSISTENT_VOLUME_STATE_DEV_VOLUME, |
no test coverage detected