(
zelf: &Py<Self>,
handle: isize,
buf: PyBuffer,
vm: &VirtualMachine,
)
| 618 | // ReadFileInto |
| 619 | #[pymethod] |
| 620 | fn ReadFileInto( |
| 621 | zelf: &Py<Self>, |
| 622 | handle: isize, |
| 623 | buf: PyBuffer, |
| 624 | vm: &VirtualMachine, |
| 625 | ) -> PyResult { |
| 626 | use windows_sys::Win32::Foundation::{ |
| 627 | ERROR_BROKEN_PIPE, ERROR_IO_PENDING, ERROR_MORE_DATA, ERROR_SUCCESS, |
| 628 | }; |
| 629 | use windows_sys::Win32::Storage::FileSystem::ReadFile; |
| 630 | |
| 631 | let mut inner = zelf.inner.lock(); |
| 632 | if !matches!(inner.data, OverlappedData::None) { |
| 633 | return Err(vm.new_value_error("operation already attempted")); |
| 634 | } |
| 635 | |
| 636 | inner.handle = handle as HANDLE; |
| 637 | let buf_len = buf.desc.len; |
| 638 | if buf_len > u32::MAX as usize { |
| 639 | return Err(vm.new_value_error("buffer too large")); |
| 640 | } |
| 641 | |
| 642 | // For async read, buffer must be contiguous - we can't use a temporary copy |
| 643 | // because Windows writes data directly to the buffer after this call returns |
| 644 | let Some(contiguous) = buf.as_contiguous_mut() else { |
| 645 | return Err(vm.new_buffer_error("buffer is not contiguous")); |
| 646 | }; |
| 647 | |
| 648 | inner.data = OverlappedData::ReadInto(buf.clone()); |
| 649 | |
| 650 | let mut nread: u32 = 0; |
| 651 | let ret = unsafe { |
| 652 | ReadFile( |
| 653 | handle as HANDLE, |
| 654 | contiguous.as_ptr() as *mut _, |
| 655 | buf_len as u32, |
| 656 | &mut nread, |
| 657 | &mut inner.overlapped, |
| 658 | ) |
| 659 | }; |
| 660 | |
| 661 | let err = if ret != 0 { |
| 662 | ERROR_SUCCESS |
| 663 | } else { |
| 664 | unsafe { GetLastError() } |
| 665 | }; |
| 666 | inner.error = err; |
| 667 | |
| 668 | match err { |
| 669 | ERROR_BROKEN_PIPE => { |
| 670 | mark_as_completed(&mut inner.overlapped); |
| 671 | Err(set_from_windows_err(err, vm)) |
| 672 | } |
| 673 | ERROR_SUCCESS | ERROR_MORE_DATA | ERROR_IO_PENDING => Ok(vm.ctx.none()), |
| 674 | _ => { |
| 675 | inner.data = OverlappedData::NotStarted; |
| 676 | Err(set_from_windows_err(err, vm)) |
| 677 | } |
no test coverage detected