windows: InvalidArgument for unsupported control recipient interface

This commit is contained in:
Kevin Mehall 2025-05-24 18:02:18 -06:00
parent 00667caa01
commit e02378e556
2 changed files with 19 additions and 8 deletions

View file

@ -412,10 +412,6 @@ impl WindowsInterface {
data: ControlIn,
timeout: Duration,
) -> impl MaybeFuture<Output = Result<Vec<u8>, TransferError>> {
if data.recipient == Recipient::Interface && data.index as u8 != self.interface_number {
warn!("WinUSB sends interface number instead of passed `index` when performing a control transfer with `Recipient::Interface`");
}
let mut t = TransferData::new(0x80);
t.set_buffer(Buffer::new(data.length as usize));
@ -441,10 +437,6 @@ impl WindowsInterface {
data: ControlOut,
timeout: Duration,
) -> impl MaybeFuture<Output = Result<(), TransferError>> {
if data.recipient == Recipient::Interface && data.index as u8 != self.interface_number {
warn!("WinUSB sends interface number instead of passed `index` when performing a control transfer with `Recipient::Interface`");
}
let mut t = TransferData::new(0x00);
t.set_buffer(Buffer::from(data.data.to_vec()));
@ -589,6 +581,20 @@ impl WindowsInterface {
let t = t.pre_submit();
let ptr = t.as_ptr();
if pkt.RequestType & 0x1f == Recipient::Interface as u8
&& pkt.Index as u8 != self.interface_number
{
warn!("WinUSB requires control transfer with `Recipient::Interface` to pass the interface number in `index`");
// Safety: Transfer is not submitted, so we can complete it in place of the event thread.
unsafe {
(*t.as_ptr()).error_from_submit = Err(TransferError::InvalidArgument);
notify_completion::<TransferData>(t.as_ptr());
}
return t;
}
debug!("Submit control {dir:?} transfer {ptr:?} for {len} bytes");
let r = unsafe {

View file

@ -39,6 +39,9 @@ pub enum TransferError {
/// Hardware issue or protocol violation.
Fault,
/// The request has an invalid argument or is not supported by this OS.
InvalidArgument,
/// Unknown or OS-specific error.
///
/// It won't be considered a breaking change to map unhandled errors from
@ -55,6 +58,7 @@ impl Display for TransferError {
TransferError::Stall => write!(f, "endpoint stalled"),
TransferError::Disconnected => write!(f, "device disconnected"),
TransferError::Fault => write!(f, "hardware fault or protocol violation"),
TransferError::InvalidArgument => write!(f, "invalid or unsupported argument"),
TransferError::Unknown(e) => {
if cfg!(target_os = "macos") {
write!(f, "unknown error (0x{e:08x})")
@ -75,6 +79,7 @@ impl From<TransferError> for io::Error {
TransferError::Stall => io::Error::new(io::ErrorKind::ConnectionReset, value),
TransferError::Disconnected => io::Error::new(io::ErrorKind::ConnectionAborted, value),
TransferError::Fault => io::Error::other(value),
TransferError::InvalidArgument => io::Error::new(io::ErrorKind::InvalidInput, value),
TransferError::Unknown(_) => io::Error::other(value),
}
}