/// <summary> /// Decode this PDU from the PduMarshaler. /// </summary> /// <param name="marshaler">This is used to decode the fields of this PDU.</param> public override bool Decode(PduMarshaler marshaler) { try { if (!base.Decode(marshaler)) { return(false); } configurationHandle = marshaler.ReadUInt32(); numInterfaces = marshaler.ReadUInt32(); if (numInterfaces == 0) { interfaces = null; } else { interfaces = new TS_USBD_INTERFACE_INFORMATION_RESULT[numInterfaces]; for (int i = 0; i < numInterfaces; i++) { interfaces[i] = new TS_USBD_INTERFACE_INFORMATION_RESULT(); if (!interfaces[i].Decode(marshaler)) { return(false); } } } } catch (Exception) { return(false); } return(true); }
/// <summary> /// Builds an interface-selection request. /// </summary> /// <param name="configuration">The result of configuration-selection.</param> /// <param name="index">The index of the interface to be selected.</param> /// <returns>The interface-selection request.</returns> public TS_URB_SELECT_INTERFACE BuildSelectionInterfaceRequest(TS_URB_SELECT_CONFIGURATION_RESULT configuration, int index) { if (null == configuration) { throw new ArgumentNullException("configuration"); } if (index >= configuration.Interface.Length || null == configuration.Interface[index]) { throw new ArgumentException("index specified interface doesn't exist."); } TS_URB_SELECT_INTERFACE urb = new TS_URB_SELECT_INTERFACE(this.requestId, this.noAck); urb.ConfigurationHandle = configuration.ConfigurationHandle; urb.Header.Size = 8 + 4; // Header + ConfigurationHandle urb.TsUsbdIInfo = new TS_USBD_INTERFACE_INFORMATION(); TS_USBD_INTERFACE_INFORMATION_RESULT inf = configuration.Interface[index]; if (inf.NumberOfPipes != inf.Pipes.Length) { throw new ArgumentException(String.Format( "The selecting interface count doesn't match. NumberOfPipes: {0}, Pipes count: {1}.", inf.NumberOfPipes, inf.Pipes.Length )); } urb.TsUsbdIInfo.Length = 2 + 2 + 1 + 1 + 2 + 4; urb.TsUsbdIInfo.NumberOfPipesExpected = (ushort)inf.NumberOfPipes; urb.TsUsbdIInfo.InterfaceNumber = inf.InterfaceNumber; urb.TsUsbdIInfo.AlternateSetting = inf.AlternateSetting; urb.TsUsbdIInfo.Padding = PaddingGenerator.GeneratePadding(); urb.TsUsbdIInfo.NumberOfPipes = inf.NumberOfPipes; urb.TsUsbdIInfo.Infomations = new TS_USBD_PIPE_INFORMATION[inf.NumberOfPipes]; for (int i = 0; i < inf.NumberOfPipes; i++) { urb.TsUsbdIInfo.Length += 2 + 2 + 4 + 4; // count Pipe sizes urb.TsUsbdIInfo.Infomations[i] = new TS_USBD_PIPE_INFORMATION(); urb.TsUsbdIInfo.Infomations[i].MaximumPacketSize = inf.Pipes[i].MaximumPacketSize; urb.TsUsbdIInfo.Infomations[i].Padding = PaddingGenerator.GeneratePadding(); urb.TsUsbdIInfo.Infomations[i].MaximumTransferSize = inf.Pipes[i].MaximumTransferSize; urb.TsUsbdIInfo.Infomations[i].PipeFlags = inf.Pipes[i].PipeFlags; } urb.Header.Size += urb.TsUsbdIInfo.Length; // interface information size. return(urb); }
/// <summary> /// Decode this PDU from the PduMarshaler. /// </summary> /// <param name="marshaler">This is used to decode the fields of this PDU.</param> public override bool Decode(PduMarshaler marshaler) { try { if (!base.Decode(marshaler)) { return false; } configurationHandle = marshaler.ReadUInt32(); numInterfaces = marshaler.ReadUInt32(); if (numInterfaces == 0) { interfaces = null; } else { interfaces = new TS_USBD_INTERFACE_INFORMATION_RESULT[numInterfaces]; for (int i = 0; i < numInterfaces; i++) { interfaces[i] = new TS_USBD_INTERFACE_INFORMATION_RESULT(); if (!interfaces[i].Decode(marshaler)) { return false; } } } } catch (Exception) { return false; } return true; }
public void S3_EUSB_OperateIo_SelectInterface() { LogComment("S3_EUSB_OperateIo_SelectInterface"); LogComment("1. Creates the control virtual channel, exchanges capabilities then notifies that the channel is created."); context.ControlChannel = CreateVirtualChannel(); LogComment("2. Receives an add virtual channel request."); rdpeusbAdapter.ExpectAddVirtualChannel(context.ControlChannel); LogComment("3. Creates a new virtual channel for the device."); DynamicVirtualChannel channel = CreateVirtualChannel(); LogComment("4. Receives an add device request."); EusbDeviceContext device = rdpeusbAdapter.ExpectAddDevice(channel); LogComment("5. Registers a callback to provide the Request Completion Interface to the client."); uint interfaceId = IdGenerator.NewId(); rdpeusbAdapter.RegisterCallback(device, 1, interfaceId); LogComment("6. Select the configuration with index 0."); SelectConfiguration(device, 0); Site.Assume.IsTrue(context.SelectedConfig.NumInterfaces > 0, "The configuration must contain at least 1 interface to be selected."); LogComment("7. Select the interface with index 0 by sending TS_URB_SELECT_INTERFACE request."); uint requestId = 0; // TDI, so set to 0 TS_URB_SELECT_INTERFACE sel = new UrbBuilder( URB_FUNCTIONID.URB_FUNCTION_SELECT_INTERFACE, requestId, 0).BuildSelectionInterfaceRequest(context.SelectedConfig, 0); rdpeusbAdapter.TransferInRequest(device, sel, 0); LogComment("8. Receives a completion message with the result for interface selection."); EusbPdu pdu = rdpeusbAdapter.ExpectCompletion(device.VirtualChannel); Site.Assert.IsInstanceOfType( pdu, typeof(EusbUrbCompletionNoDataPdu), "The result must be type of EusbUrbCompletionNoDataPdu."); EusbUrbCompletionNoDataPdu pduRes = (EusbUrbCompletionNoDataPdu)pdu; Site.Assert.IsSuccess((int)pduRes.HResult, "The EusbUrbCompletionNoDataPdu must indicate successful."); ReqCapturer.VerifyUrbCompletionNoData(pduRes, sel, true, interfaceId); TS_USBD_INTERFACE_INFORMATION_RESULT urb = new TS_USBD_INTERFACE_INFORMATION_RESULT(); Site.Assert.IsTrue( PduMarshaler.Unmarshal(pduRes.TsUrbResult, urb), "The completion PDU must contain the result."); LogComment("The interface-selection result is {0}.", urb); LogComment("9. Sends retract device request and the channel for the device is expected to be closed."); rdpeusbAdapter.RetractDevice(device, USB_RETRACT_REASON.UsbRetractReason_BlockedByPolicy); }