NTSTATUS AndroidUsbDeviceObject::SelectInterfaces() {
  ASSERT_IRQL_PASSIVE();

  ASSERT(IsDeviceConfigured());
  if (!IsDeviceConfigured())
    return STATUS_INTERNAL_ERROR;

  WDF_USB_DEVICE_SELECT_CONFIG_PARAMS config_params;
  PWDF_USB_INTERFACE_SETTING_PAIR pairs = NULL;
  // TODO: We need to find a way (possibly by looking at each
  // interface descriptor) to get index of the ADB interface in multiinterface
  // configuration.
  UCHAR adb_interface_index = 0;

  if (IsSingleInterfaceDevice()) {
    // Our device has only one interface, so we don't have to bother with
    // multiple interfaces at all.
    GoogleDbgPrint("\n********** Device reports single interface");
    // Select single interface configuration
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&config_params);
  } else {
    // Configure multiple interfaces
    ULONG num_interf = GetInterfaceCount();
    GoogleDbgPrint("\n********** Device reports %u interfaces",
             num_interf);

    // Allocate pairs for each interface
    pairs = new(PagedPool, GANDR_POOL_TAG_INTERF_PAIRS)
              WDF_USB_INTERFACE_SETTING_PAIR[num_interf];
    ASSERT(NULL != pairs);
    if (NULL == pairs)
      return STATUS_INSUFFICIENT_RESOURCES;

    adb_interface_index = 1;
    // Initialize each interface pair
    for (UCHAR pair = 0; pair < num_interf; pair++) {
      pairs[pair].SettingIndex = 0;
      pairs[pair].UsbInterface =
        WdfUsbTargetDeviceGetInterface(wdf_target_device(), pair);
      ASSERT(NULL != pairs[pair].UsbInterface);
      if (NULL == pairs[pair].UsbInterface) {
        delete[] pairs;
        return STATUS_INTERNAL_ERROR;
      }
    }

    // Select multiinterface configuration
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_MULTIPLE_INTERFACES(&config_params,
                                                                 (UCHAR)num_interf,
                                                                 pairs);
  }

  NTSTATUS status =
    WdfUsbTargetDeviceSelectConfig(wdf_target_device(),
                                   WDF_NO_OBJECT_ATTRIBUTES,
                                   &config_params);
  if (NULL != pairs)
    delete[] pairs;

  // ASSERT(NT_SUCCESS(status));
  if (!NT_SUCCESS(status))
    return status;

#if DBG
  PrintSelectedConfig(&config_params);
#endif  // DBG

  wdf_usb_interface_ =
    WdfUsbTargetDeviceGetInterface(wdf_target_device(), adb_interface_index);
  ASSERT(NULL != wdf_usb_interface_);
  if (NULL == wdf_usb_interface_)
    return STATUS_INTERNAL_ERROR;

  configured_pipes_num_ = WdfUsbInterfaceGetNumEndpoints(wdf_usb_interface(), 0);
  ASSERT(0 != configured_pipes_num_);

  // Cache selected interface descriptor
  BYTE setting_index =
    WdfUsbInterfaceGetConfiguredSettingIndex(wdf_usb_interface());

  WdfUsbInterfaceGetDescriptor(wdf_usb_interface(),
                               setting_index,
                               &interface_descriptor_);

#if DBG
  PrintInterfaceDescriptor(interface_descriptor());
#endif  // DBG

  // Iterate over pipes, decoding and saving info about bulk r/w pipes for
  // easier and faster addressing later on when they get opened
  for (UCHAR pipe = 0; pipe < configured_pipes_num(); pipe++) {
    WDF_USB_PIPE_INFORMATION pipe_info;
    WDF_USB_PIPE_INFORMATION_INIT(&pipe_info);
    WDFUSBPIPE wdf_pipe_obj =
      WdfUsbInterfaceGetConfiguredPipe(wdf_usb_interface(), pipe, &pipe_info);
    ASSERT(NULL != wdf_pipe_obj);
    if (NULL != wdf_pipe_obj) {
      if ((WdfUsbPipeTypeBulk  == pipe_info.PipeType) &&
          WDF_USB_PIPE_DIRECTION_IN(pipe_info.EndpointAddress)) {
        // This is a bulk read pipe
        ASSERT(!IsBulkReadPipeKnown());
        bulk_read_pipe_index_ = pipe;
      } else {
        ASSERT(!IsBulkWritePipeKnown());
        bulk_write_pipe_index_ = pipe;
      }
    }
#if DBG
    PrintPipeInformation(&pipe_info, pipe);
#endif  // DBG
  }

  // At the end we must have calculated indexes for both,
  // bulk read and write pipes
  ASSERT(!NT_SUCCESS(status) || (IsBulkReadPipeKnown() &&
                                 IsBulkWritePipeKnown()));

  return status;
}
示例#2
0
NTSTATUS ConfigureUsbPipes(PDEVICE_CONTEXT DeviceContext)
{
  NTSTATUS status = STATUS_SUCCESS;
  BYTE index = 0;
  WDF_USB_PIPE_INFORMATION pipeConfig;
  WDFUSBPIPE pipe = NULL;
  BYTE  numEndpoints;

  // For debug
  numEndpoints = WdfUsbInterfaceGetNumEndpoints(
                                              DeviceContext->UsbInterface,
                                              0
                                              );

  KdPrint((__DRIVER_NAME " Found %i EndPoints\n", numEndpoints)); 
  // For debug

  DeviceContext->UsbInterruptPipe = NULL;
  DeviceContext->UsbBulkInPipe = NULL;
  DeviceContext->UsbBulkOutPipe = NULL;
  WDF_USB_PIPE_INFORMATION_INIT(&pipeConfig);	// Init pipe config
  
  //
  // Scan all pipe from USB Interface
  //
  do
  {
    pipe = WdfUsbInterfaceGetConfiguredPipe(DeviceContext->UsbInterface,
                                          index,
                                          &pipeConfig);
											
    if (NULL == pipe)
      break;

    // For debug
    KdPrint((__DRIVER_NAME " Pipe[%i].PacketSize = %i\n", index, pipeConfig.MaximumPacketSize));    
    // For debug

    /*None of our data transfers will have a guarantee that the requested
      data size is a multiple of the packet size.*/
    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);

    if(WdfUsbPipeTypeInterrupt == pipeConfig.PipeType)	// Interrupt pipe
    { 
	  KdPrint((__DRIVER_NAME " Found Interrupt Pipe at index %i\n", index));
      DeviceContext->UsbInterruptPipe = pipe;
    }
    else if(WdfUsbPipeTypeBulk == pipeConfig.PipeType)	// Bulk pipe
    {
      if(TRUE == WdfUsbTargetPipeIsInEndpoint(pipe))	// In EndPoint of Bulk
      {
	    KdPrint((__DRIVER_NAME " Found In Endpoint Pipe at index %i\n", index));
        DeviceContext->UsbBulkInPipe = pipe;
      }
      else if(TRUE == WdfUsbTargetPipeIsOutEndpoint(pipe))
      {
        KdPrint((__DRIVER_NAME " Found Out Endpoint Pipe at index %i\n", index));
        DeviceContext->UsbBulkOutPipe = pipe;			// Out EndPoint of Bulk
      }
    }
	
	index++;	// Encreate index of Pipe
	
  } while (NULL != pipe);

  // Check for all 3 pipe: interrupt, Bulk In, Bulk Out for our device
  if((NULL == DeviceContext->UsbInterruptPipe) ||
	  (NULL == DeviceContext->UsbBulkInPipe) ||
	  (NULL == DeviceContext->UsbBulkOutPipe))
  {
    KdPrint((__DRIVER_NAME
      "Not all expected USB pipes were found.\n"));
    return STATUS_INVALID_PARAMETER;
  }
  
  return status;
}