@@ -49,13 +49,16 @@ async Task HandleSubmitAsync(UsbIpHeaderBasic basic, UsbIpHeaderCmdSubmit submit
4949 {
5050 ep = basic . ep ,
5151 dir = ( basic . direction == UsbIpDir . USBIP_DIR_IN ) ? UsbSupDirection . USBSUP_DIRECTION_IN : UsbSupDirection . USBSUP_DIRECTION_OUT ,
52- flags = ( basic . direction == UsbIpDir . USBIP_DIR_IN ) ? UsbSupXferFlags . USBSUP_FLAG_SHORT_OK : UsbSupXferFlags . USBSUP_FLAG_NONE ,
52+ flags = ( basic . direction == UsbIpDir . USBIP_DIR_IN )
53+ ? ( ( ( submit . transfer_flags & 1 ) != 0 ) ? UsbSupXferFlags . USBSUP_FLAG_NONE : UsbSupXferFlags . USBSUP_FLAG_SHORT_OK )
54+ : UsbSupXferFlags . USBSUP_FLAG_NONE ,
5355 error = UsbSupError . USBSUP_XFER_OK ,
5456 len = submit . transfer_buffer_length ,
5557 numIsoPkts = ( uint ) submit . number_of_packets ,
5658 aIsoPkts = new UsbSupIsoPkt [ 8 ] ,
5759 } ;
5860
61+ var requestLength = submit . transfer_buffer_length ;
5962 var payloadOffset = 0 ;
6063 switch ( transferType )
6164 {
@@ -95,17 +98,52 @@ async Task HandleSubmitAsync(UsbIpHeaderBasic basic, UsbIpHeaderCmdSubmit submit
9598 throw new NotImplementedException ( "ISO transfers" ) ;
9699 }
97100
98- if ( ( basic . ep == 0 ) && ( submit . setup . bmRequestType == 0 ) && ( submit . setup . bRequest == UsbRequest . SET_CONFIGURATION ) )
101+ if ( ( basic . ep == 0 )
102+ && ( submit . setup . bmRequestType == UsbRequestTypeRecipient . DEVICE )
103+ && ( submit . setup . bRequest == UsbRequest . SET_CONFIGURATION ) )
99104 {
100105 // VBoxUsb needs this to get the endpoint handles
101- var configurationValue = ( byte ) submit . setup . wValue ;
102- Logger . LogTrace ( $ "Trapped SET_CONFIGURATION { configurationValue } ") ;
103- await Device . IoControlAsync ( IoControl . SUPUSB_IOCTL_USB_SET_CONFIG , new byte [ ] { configurationValue } , null ) ;
104- ConfigurationDescriptors . SetConfiguration ( configurationValue ) ;
106+ var setConfig = new UsbSupSetConfig ( )
107+ {
108+ bConfigurationValue = ( byte ) submit . setup . wValue ,
109+ } ;
110+ Logger . LogDebug ( $ "Trapped SET_CONFIGURATION: { setConfig . bConfigurationValue } ") ;
111+ await Device . IoControlAsync ( IoControl . SUPUSB_IOCTL_USB_SET_CONFIG , StructToBytes ( setConfig ) , null ) ;
112+ ConfigurationDescriptors . SetConfiguration ( setConfig . bConfigurationValue ) ;
113+ }
114+ else if ( ( basic . ep == 0 )
115+ && ( submit . setup . bmRequestType == UsbRequestTypeRecipient . DEVICE )
116+ && ( submit . setup . bRequest == UsbRequest . SET_INTERFACE ) )
117+ {
118+ // VBoxUsb needs this to get the endpoint handles
119+ var selectInterface = new UsbSupSelectInterface ( )
120+ {
121+ bInterfaceNumber = ( byte ) submit . setup . wIndex ,
122+ bAlternateSetting = ( byte ) submit . setup . wValue ,
123+ } ;
124+ Logger . LogDebug ( $ "Trapped SET_INTERFACE: { selectInterface . bInterfaceNumber } -> { selectInterface . bAlternateSetting } ") ;
125+ await Device . IoControlAsync ( IoControl . SUPUSB_IOCTL_USB_SELECT_INTERFACE , StructToBytes ( selectInterface ) , null ) ;
126+ ConfigurationDescriptors . SetInterface ( selectInterface . bInterfaceNumber , selectInterface . bAlternateSetting ) ;
127+ }
128+ else if ( ( basic . ep == 0 )
129+ && ( submit . setup . bmRequestType == UsbRequestTypeRecipient . ENDPOINT )
130+ && ( submit . setup . bRequest == UsbRequest . CLEAR_FEATURE )
131+ && ( submit . setup . wValue == 0 ) )
132+ {
133+ // VBoxUsb needs this to notify the host controller
134+ var clearEndpoint = new UsbSupClearEndpoint ( )
135+ {
136+ bEndpoint = ( byte ) submit . setup . wIndex ,
137+ } ;
138+ Logger . LogDebug ( $ "Trapped CLEAR_FEATURE: { clearEndpoint . bEndpoint } ") ;
139+ await Device . IoControlAsync ( IoControl . SUPUSB_IOCTL_USB_CLEAR_ENDPOINT , StructToBytes ( clearEndpoint ) , null ) ;
105140 }
106141 else
107142 {
108- Logger . LogTrace ( $ "{ submit . setup . bmRequestType } { submit . setup . bRequest } { submit . setup . wValue } { submit . setup . wIndex } { submit . setup . wLength } ") ;
143+ if ( transferType == UsbEndpointType . USB_ENDPOINT_TYPE_CONTROL )
144+ {
145+ Logger . LogTrace ( $ "{ submit . setup . bmRequestType } { submit . setup . bRequest } { submit . setup . wValue } { submit . setup . wIndex } { submit . setup . wLength } ") ;
146+ }
109147 var gc = GCHandle . Alloc ( buf , GCHandleType . Pinned ) ;
110148 try
111149 {
@@ -123,7 +161,7 @@ async Task HandleSubmitAsync(UsbIpHeaderBasic basic, UsbIpHeaderCmdSubmit submit
123161 basic . command = UsbIpCmd . USBIP_RET_SUBMIT ;
124162 var retSubmit = new UsbIpHeaderRetSubmit ( )
125163 {
126- status = ( int ) urb . error ,
164+ status = - ( int ) ConvertError ( urb . error ) ,
127165 actual_length = ( int ) urb . len ,
128166 start_frame = submit . start_frame ,
129167 number_of_packets = ( int ) urb . numIsoPkts ,
@@ -135,7 +173,12 @@ async Task HandleSubmitAsync(UsbIpHeaderBasic basic, UsbIpHeaderCmdSubmit submit
135173 retSubmit . actual_length = ( retSubmit . actual_length > payloadOffset ) ? ( retSubmit . actual_length - payloadOffset ) : 0 ;
136174 }
137175
138- Logger . LogTrace ( $ "actual: { retSubmit . actual_length } ") ;
176+ if ( urb . error != UsbSupError . USBSUP_XFER_OK )
177+ {
178+ Logger . LogDebug ( $ "{ urb . error } -> { ConvertError ( urb . error ) } -> { retSubmit . status } ") ;
179+ }
180+ Logger . LogTrace ( $ "actual: { retSubmit . actual_length } , requested: { requestLength } ") ;
181+
139182 var retBuf = new byte [ 48 /* sizeof(usbip_header) */ ] ;
140183 BinaryPrimitives . WriteUInt32BigEndian ( retBuf . AsSpan ( 0 ) , ( uint ) basic . command ) ;
141184 BinaryPrimitives . WriteUInt32BigEndian ( retBuf . AsSpan ( 4 ) , basic . seqnum ) ;
0 commit comments