windows: fix submit-time error

This commit is contained in:
Kevin Mehall 2025-05-24 18:00:33 -06:00
parent 5ac12ef088
commit 00667caa01
2 changed files with 29 additions and 13 deletions

View file

@ -21,7 +21,10 @@ use windows_sys::Win32::{
WinUsb_SetPipePolicy, WinUsb_WritePipe, USB_DEVICE_DESCRIPTOR, WINUSB_INTERFACE_HANDLE,
WINUSB_SETUP_PACKET,
},
Foundation::{GetLastError, ERROR_IO_PENDING, ERROR_NOT_FOUND, FALSE, HANDLE, TRUE},
Foundation::{
GetLastError, ERROR_BAD_COMMAND, ERROR_DEVICE_NOT_CONNECTED, ERROR_FILE_NOT_FOUND,
ERROR_IO_PENDING, ERROR_NOT_FOUND, ERROR_NO_SUCH_DEVICE, FALSE, HANDLE, TRUE,
},
System::IO::{CancelIoEx, OVERLAPPED},
};
@ -540,6 +543,7 @@ impl WindowsInterface {
let len = t.request_len;
let buf = t.buf;
t.overlapped.InternalHigh = 0;
t.error_from_submit = Ok(());
let t = t.pre_submit();
let ptr = t.as_ptr();
@ -580,6 +584,7 @@ impl WindowsInterface {
let len = t.request_len;
let buf = t.buf;
t.overlapped.InternalHigh = 0;
t.error_from_submit = Ok(());
let t = t.pre_submit();
let ptr = t.as_ptr();
@ -613,7 +618,13 @@ impl WindowsInterface {
// Safety: Transfer was not submitted, so we still own it
// and must complete it in place of the event thread.
unsafe {
(*t.as_ptr()).overlapped.Internal = err as _;
(*t.as_ptr()).error_from_submit = match err {
ERROR_BAD_COMMAND
| ERROR_FILE_NOT_FOUND
| ERROR_DEVICE_NOT_CONNECTED
| ERROR_NO_SUCH_DEVICE => Err(TransferError::Disconnected),
other => Err(TransferError::Unknown(other)),
};
notify_completion::<TransferData>(t.as_ptr());
}
}

View file

@ -24,6 +24,7 @@ pub struct TransferData {
pub(crate) capacity: u32,
pub(crate) request_len: u32,
pub(crate) endpoint: u8,
pub(crate) error_from_submit: Result<(), TransferError>,
}
unsafe impl Send for TransferData {}
@ -39,6 +40,7 @@ impl TransferData {
capacity: 0,
request_len: 0,
endpoint,
error_from_submit: Ok(()),
}
}
@ -62,19 +64,22 @@ impl TransferData {
pub fn take_completion(&mut self, intf: &Interface) -> Completion {
let mut actual_len: u32 = 0;
unsafe { GetOverlappedResult(intf.handle, &self.overlapped, &mut actual_len, 0) };
let status = self.error_from_submit.and_then(|()| {
unsafe { GetOverlappedResult(intf.handle, &self.overlapped, &mut actual_len, 0) };
let status = match unsafe { GetLastError() } {
ERROR_SUCCESS => Ok(()),
ERROR_GEN_FAILURE => Err(TransferError::Stall),
ERROR_REQUEST_ABORTED | ERROR_TIMEOUT | ERROR_SEM_TIMEOUT | ERROR_OPERATION_ABORTED => {
Err(TransferError::Cancelled)
match unsafe { GetLastError() } {
ERROR_SUCCESS => Ok(()),
ERROR_GEN_FAILURE => Err(TransferError::Stall),
ERROR_REQUEST_ABORTED
| ERROR_TIMEOUT
| ERROR_SEM_TIMEOUT
| ERROR_OPERATION_ABORTED => Err(TransferError::Cancelled),
ERROR_FILE_NOT_FOUND | ERROR_DEVICE_NOT_CONNECTED | ERROR_NO_SUCH_DEVICE => {
Err(TransferError::Disconnected)
}
e => Err(TransferError::Unknown(e)),
}
ERROR_FILE_NOT_FOUND | ERROR_DEVICE_NOT_CONNECTED | ERROR_NO_SUCH_DEVICE => {
Err(TransferError::Disconnected)
}
e => Err(TransferError::Unknown(e)),
};
});
let mut empty = ManuallyDrop::new(Vec::new());
let ptr = mem::replace(&mut self.buf, empty.as_mut_ptr());