NTSTATUS AndroidUsbDeviceObject::OnEvtDeviceReleaseHardware(
    WDFCMRESLIST resources_translated) {
  ASSERT_IRQL_PASSIVE();

  // It's possible that Preparehardware failed half way thru. So make
  // sure the target device exists.
  if (!IsTaretDeviceCreated())
    return STATUS_SUCCESS;

  // Cancel all the currently queued I/O. This is better than sending an
  // explicit USB abort request down because release hardware gets
  // called even when the device surprise-removed.
  WdfIoTargetStop(WdfUsbTargetDeviceGetIoTarget(wdf_target_device()),
                  WdfIoTargetCancelSentIo);

  // Unselect all selected configurations
  WDF_USB_DEVICE_SELECT_CONFIG_PARAMS config_params;
  WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_DECONFIG(&config_params);

  NTSTATUS status = WdfUsbTargetDeviceSelectConfig(wdf_target_device(),
                                                   WDF_NO_OBJECT_ATTRIBUTES,
                                                   &config_params);
  ASSERT(NT_SUCCESS(status) || (STATUS_DEVICE_NOT_CONNECTED == status));
  return status;
}
Exemple #2
0
static NTSTATUS UsbChief_SelectInterfaces(IN WDFDEVICE Device)
{
	WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
	NTSTATUS Status;
	PDEVICE_CONTEXT pDeviceContext;

	PAGED_CODE();

	pDeviceContext = GetDeviceContext(Device);

	WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE( &configParams);

	Status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->WdfUsbTargetDevice,
						WDF_NO_OBJECT_ATTRIBUTES,
						&configParams);

	if (NT_SUCCESS(Status) &&
	    WdfUsbTargetDeviceGetNumInterfaces(pDeviceContext->WdfUsbTargetDevice) > 0) {

		pDeviceContext->UsbInterface =
			configParams.Types.SingleInterface.ConfiguredUsbInterface;

		pDeviceContext->NumberConfiguredPipes =
			configParams.Types.SingleInterface.NumberConfiguredPipes;
	}
	return Status;

}
Exemple #3
0
NTSTATUS
EvtDevicePrepareHardware(
    IN WDFDEVICE    Device,
    IN WDFCMRESLIST ResourceList,
    IN WDFCMRESLIST ResourceListTranslated
    )
{
    NTSTATUS                            status;
    PDEVICE_CONTEXT                     pDeviceContext;
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;

    UNREFERENCED_PARAMETER(ResourceList);
    UNREFERENCED_PARAMETER(ResourceListTranslated);

    pDeviceContext = GetDeviceContext(Device);

    //
    // Create the USB device if it is not already created.
    //
    if (pDeviceContext->UsbDevice == NULL) {
        WDF_USB_DEVICE_CREATE_CONFIG config;

        WDF_USB_DEVICE_CREATE_CONFIG_INIT(&config,
                                   USBD_CLIENT_CONTRACT_VERSION_602);

        status = WdfUsbTargetDeviceCreateWithParameters(Device,
                                               &config,
                                               WDF_NO_OBJECT_ATTRIBUTES,
                                               &pDeviceContext->UsbDevice);

        if (!NT_SUCCESS(status)) {
            KdPrint(("WdfUsbTargetDeviceCreateWithParameters failed 0x%x\n", status));        
            return status;
        }
    }
    
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams);

    status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice,
                                        WDF_NO_OBJECT_ATTRIBUTES,
                                        &configParams);
    if(!NT_SUCCESS(status)) {
        KdPrint(("WdfUsbTargetDeviceSelectConfig failed 0x%x\n", status));
        return status;
    }

    pDeviceContext->UsbInterface =  
                configParams.Types.SingleInterface.ConfiguredUsbInterface;

    return status;
}
// 此函数类似于WDM中的PNP_MN_STOP_DEVICE函数,在设备移除时被调用。
// 当个函数被调用时候,设备仍处于工作状态。
NTSTATUS DrvClass::PnpReleaseHardware(IN WDFCMRESLIST ResourceListTranslated)
{
	KDBG(DPFLTR_INFO_LEVEL, "[PnpReleaseHardware]");

	// 如果PnpPrepareHardware调用失败,UsbDevice为空;
	// 这时候直接返回即可。
	if (m_hUsbDevice == NULL)
		return STATUS_SUCCESS;

	// 取消USB设备的所有IO操作。它将连带取消所有Pipe的IO操作。
	WdfIoTargetStop(WdfUsbTargetDeviceGetIoTarget(m_hUsbDevice), WdfIoTargetCancelSentIo);

	// Deconfiguration或者“反配置”
	WDF_USB_DEVICE_SELECT_CONFIG_PARAMS  configParams;
	WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_DECONFIG(&configParams);
	return WdfUsbTargetDeviceSelectConfig(m_hUsbDevice, WDF_NO_OBJECT_ATTRIBUTES, &configParams);
}
Exemple #5
0
NTSTATUS ConfigureUsbInterface(WDFDEVICE Device, PDEVICE_CONTEXT DeviceContext)
{
  NTSTATUS status = STATUS_SUCCESS;
  WDF_USB_DEVICE_SELECT_CONFIG_PARAMS usbConfig;

  // Create USB Target Device Object for Device Context
  status = WdfUsbTargetDeviceCreate(Device,
                                    WDF_NO_OBJECT_ATTRIBUTES,
                                    &DeviceContext->UsbDevice);

  if(!NT_SUCCESS(status))
  {
    KdPrint((__DRIVER_NAME
      "WdfUsbTargetDeviceCreate failed with status 0x%08x\n", status));
    return status;
  }

  /*Initialize the parameters struct so that the device can initialize
    and use a single specified interface.
    this only works if the device has just 1 interface.*/
  /*Chon duy nhat 1 interface cua USB Device */
  WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&usbConfig);

  /*Chon duy nhat 1 interface cua USB Device */
  status = WdfUsbTargetDeviceSelectConfig(DeviceContext->UsbDevice,
                                          WDF_NO_OBJECT_ATTRIBUTES,
                                          &usbConfig);
  if(!NT_SUCCESS(status))
  {
    KdPrint((__DRIVER_NAME
      "WdfUsbTargetDeviceSelectConfig failed with status 0x%08x\n", status));
    return status;
  }

  /*Put the USB interface in our device context so that we can use it in
    future calls to our driver.*/
  DeviceContext->UsbInterface =
    usbConfig.Types.SingleInterface.ConfiguredUsbInterface;

  return status;
}
Exemple #6
0
/*++
Routine Description:

This helper routine selects the configuration, interface and
creates a context for every pipe (end point) in that interface.

Arguments:

Device - Handle to a framework device

Return Value:

NT status value
--*/
NTSTATUS SelectInterfaces(IN WDFDEVICE Device)
{
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
    NTSTATUS                            status;
    PDEVICE_CONTEXT                     pDeviceContext;
	UCHAR								numInterfaces;

    PAGED_CODE();

    pDeviceContext = GetDeviceContext(Device);

	numInterfaces = WdfUsbTargetDeviceGetNumInterfaces(pDeviceContext->WdfUsbTargetDevice);

	if (numInterfaces == 1)
	{
		// The device has only 1 interface.
		PSDrv_DbgPrint(3, ("Device has a single interface!\n"));

		WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams);

		status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->WdfUsbTargetDevice, WDF_NO_OBJECT_ATTRIBUTES, &configParams);
		if (NT_SUCCESS(status) && numInterfaces > 0)
		{
			pDeviceContext->UsbInterface = configParams.Types.SingleInterface.ConfiguredUsbInterface;
			pDeviceContext->NumberConfiguredPipes = configParams.Types.SingleInterface.NumberConfiguredPipes;
		}
	}
	else
	{
		// The device has more then one interface...
		PSDrv_DbgPrint(3, ("Device has multiple interfaces (%d) - this is not supported yet!\n", numInterfaces));
		status = STATUS_NOT_SUPPORTED;
	}

	pDeviceContext->nCurrIf = 0;
	pDeviceContext->nCurrAltIf = 0;

    return status;
}
Exemple #7
0
NTSTATUS
HidFx2EvtDevicePrepareHardware(
    IN WDFDEVICE    Device,
    IN WDFCMRESLIST ResourceList,
    IN WDFCMRESLIST ResourceListTranslated
    )
/*++

Routine Description:

    In this callback, the driver does whatever is necessary to make the
    hardware ready to use.  In the case of a USB device, this involves
    reading and selecting descriptors.

Arguments:

    Device - handle to a device

    ResourceList - A handle to a framework resource-list object that
    identifies the raw hardware resourcest

    ResourceListTranslated - A handle to a framework resource-list object
    that identifies the translated hardware resources

Return Value:

    NT status value

--*/
{
    NTSTATUS                            status = STATUS_SUCCESS;
    PDEVICE_EXTENSION                   devContext = NULL;
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
    WDF_OBJECT_ATTRIBUTES               attributes;
    PUSB_DEVICE_DESCRIPTOR              usbDeviceDescriptor = NULL;

    UNREFERENCED_PARAMETER(ResourceList);
    UNREFERENCED_PARAMETER(ResourceListTranslated);

    PAGED_CODE ();

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT,
        "HidFx2EvtDevicePrepareHardware Enter\n");

    devContext = GetDeviceContext(Device);

    //
    // Create a WDFUSBDEVICE object. WdfUsbTargetDeviceCreate obtains the
    // USB device descriptor and the first USB configuration descriptor from
    // the device and stores them. It also creates a framework USB interface
    // object for each interface in the device's first configuration.
    //
    // The parent of each USB device object is the driver's framework driver
    // object. The driver cannot change this parent, and the ParentObject
    // member or the WDF_OBJECT_ATTRIBUTES structure must be NULL.
    //
    // We only create device the first time PrepareHardware is called. If 
    // the device is restarted by pnp manager for resource rebalance, we 
    // will use the same device handle but then select the interfaces again
    // because the USB stack could reconfigure the device on restart.
    //
    if (devContext->UsbDevice == NULL) {
        status = WdfUsbTargetDeviceCreate(Device,
                                          WDF_NO_OBJECT_ATTRIBUTES,
                                          &devContext->UsbDevice);
  
        if (!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                "WdfUsbTargetDeviceCreate failed 0x%x\n", status);
            return status;
        }
    }

    //
    // Select a device configuration by using a
    // WDF_USB_DEVICE_SELECT_CONFIG_PARAMS structure to specify USB
    // descriptors, a URB, or handles to framework USB interface objects.
    //
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE( &configParams);

    status = WdfUsbTargetDeviceSelectConfig(devContext->UsbDevice,
                                        WDF_NO_OBJECT_ATTRIBUTES,
                                        &configParams);
    if(!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
            "WdfUsbTargetDeviceSelectConfig failed %!STATUS!\n",
            status);
        return status;
    }

    devContext->UsbInterface =
                configParams.Types.SingleInterface.ConfiguredUsbInterface;

    //
    // Get the device descriptor and store it in device context
    //
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = Device;
    status = WdfMemoryCreate(
                             &attributes,
                             NonPagedPool,
                             0,
                             sizeof(USB_DEVICE_DESCRIPTOR),
                             &devContext->DeviceDescriptor,
                             &usbDeviceDescriptor
                             );

    if(!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
            "WdfMemoryCreate for Device Descriptor failed %!STATUS!\n",
            status);
        return status;
    }

    WdfUsbTargetDeviceGetDeviceDescriptor(
          devContext->UsbDevice,
          usbDeviceDescriptor
          );

    //
    // Get the Interrupt pipe. There are other endpoints but we are only
    // interested in interrupt endpoint since our HID data comes from that
    // endpoint. Another way to get the interrupt endpoint is by enumerating
    // through all the pipes in a loop and looking for pipe of Interrupt type.
    //
    devContext->InterruptPipe = WdfUsbInterfaceGetConfiguredPipe(
                                                  devContext->UsbInterface,
                                                  INTERRUPT_ENDPOINT_INDEX,
                                                  NULL);// pipeInfo

    if (NULL == devContext->InterruptPipe) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                    "Failed to get interrupt pipe info\n");
        status = STATUS_INVALID_DEVICE_STATE;
        return status;
    }

    //
    // Tell the framework that it's okay to read less than
    // MaximumPacketSize
    //
    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(devContext->InterruptPipe);

    //
    //configure continuous reader
    //
    status = HidFx2ConfigContReaderForInterruptEndPoint(devContext);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT,
        "HidFx2EvtDevicePrepareHardware Exit, Status:0x%x\n", status);

    return status;
}
Exemple #8
0
///////////////////////////////////////////////////////////////////////////////
//
//  BasicUsbEvtDevicePrepareHardware
//
//    This routine is called by the framework when a device of
//    the type we support is coming online. Our job will be to
//    create our WDFUSBDEVICE and configure it.
//
//  INPUTS:
//
//      Device       - One of our WDFDEVICE objects
//
//      ResourceList - We're a USB device, so not used
//
//      ResourceListTranslated - We're a USB device, so not
//                               used
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      STATUS_SUCCESS, otherwise an error indicating why the driver could not
//                      load.
//
//  IRQL:
//
//      This routine is called at IRQL == PASSIVE_LEVEL.
//
//  NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS
BasicUsbEvtDevicePrepareHardware(
    IN WDFDEVICE Device,
    IN WDFCMRESLIST ResourceList,
    IN WDFCMRESLIST ResourceListTranslated
    ) {

    NTSTATUS                            status;
    PBASICUSB_DEVICE_CONTEXT            devContext;   
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS selectConfigParams;
    WDFUSBINTERFACE                     configuredInterface;
    WDF_USB_PIPE_INFORMATION            pipeInfo;
    UCHAR                               numPipes;
    UCHAR                               pipeIndex;
    WDFUSBPIPE                          configuredPipe;
    WDF_USB_CONTINUOUS_READER_CONFIG    contReaderConfig;

    UNREFERENCED_PARAMETER(ResourceList);
    UNREFERENCED_PARAMETER(ResourceListTranslated);

#if DBG
    DbgPrint("BasicUsbEvtDevicePrepareHardware\n");
#endif

    devContext = BasicUsbGetContextFromDevice(Device);

    //
    // First thing to do is create our WDFUSBDEVICE. This is the
    // special USB I/O target that we'll be using to configure our
    // device and to send control requests.
    //
    // Under very rare cirumstances (i.e. resource rebalance of the
    // host controller) it's possible to come through here multiple
    // times. We could handle this by having an
    // EvtDeviceReleaseHardware and cleaning up the USB device
    // target, but we'll just leave it around and avoid creating it
    // multiple times with this check. No race condition as our
    // Prepare and Release can't run in parallel for the same device
    // 
    if (devContext->BasicUsbUsbDevice == NULL) {

        status = WdfUsbTargetDeviceCreate(Device, 
                                          WDF_NO_OBJECT_ATTRIBUTES,
                                          &devContext->BasicUsbUsbDevice);
        if (!NT_SUCCESS(status)) {
    #if DBG
            DbgPrint("WdfUsbTargetDeviceCreate failed 0x%0x\n", status);
    #endif
            return status;
        }

    }

    //
    // Now that our WDFUSBDEVICE is created, it's time to select
    // our configuration and enable our interface.
    //

    //
    // The OSRFX2 device only has a single interface, so we'll
    // initialize our select configuration parameters structure
    // using the specially provided macro
    //
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(
                                                &selectConfigParams);

    //
    // And actually select our configuration.
    //
    status = WdfUsbTargetDeviceSelectConfig(devContext->BasicUsbUsbDevice,
                                            WDF_NO_OBJECT_ATTRIBUTES,
                                            &selectConfigParams);
    if (!NT_SUCCESS(status)) {
#if DBG
        DbgPrint("WdfUsbTargetDeviceSelectConfig failed 0x%0x\n", status);
#endif
        return status;

    }

    //
    // Our single interface has been configured. Let's grab the
    // WDFUSBINTERFACE object so that we can get our pipes.
    //
    configuredInterface 
            = selectConfigParams.Types.SingleInterface.ConfiguredUsbInterface;

    //
    // How many pipes were configure?
    //
    numPipes = selectConfigParams.Types.SingleInterface.NumberConfiguredPipes;

    //
    // For all the pipes that were configured....
    //
    for(pipeIndex = 0; pipeIndex < numPipes; pipeIndex++) {

        //
        // We'll need to find out the type the pipe, which we'll do
        // by supplying a pipe information structure when calling
        // WdfUsbInterfaceGetConfiguredPipe
        //
        WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);

        //
        // Get the configured pipe.
        //
        configuredPipe = WdfUsbInterfaceGetConfiguredPipe(configuredInterface,
                                                          pipeIndex,
                                                          &pipeInfo);

        //
        // For this device, we're looking for three pipes:
        //
        // 1) A Bulk IN pipe
        // 2) A Bulk OUT pipe
        // 3) An Interrupt IN pipe
        //

        //
        // First, let's see what type of pipe it is...
        //
        switch (pipeInfo.PipeType) {
            case WdfUsbPipeTypeBulk: {

                //
                // Bulk pipe. Determine if it's an IN pipe or not.
                //
                if (WdfUsbTargetPipeIsInEndpoint(configuredPipe)) {

                    //
                    // Bulk IN pipe. Should only ever get one of these...
                    //
                    ASSERT(devContext->BulkInPipe == NULL);

                    devContext->BulkInPipe = configuredPipe;

                } else {

                    //
                    // HAS to be an OUT...
                    //
                    ASSERT(WdfUsbTargetPipeIsOutEndpoint(configuredPipe));

                    //
                    // Bulk OUT pipe. Should only ever get one of these...
                    //
                    ASSERT(devContext->BulkOutPipe == NULL);

                    devContext->BulkOutPipe = configuredPipe;
                }
                break;
            }
            case WdfUsbPipeTypeInterrupt: {
                //
                // We're only expecting an IN interrupt pipe
                //
                ASSERT(WdfUsbTargetPipeIsInEndpoint(configuredPipe));

                //
                // And we're only expected one of them
                //
                ASSERT(devContext->InterruptInPipe == NULL);

                devContext->InterruptInPipe = configuredPipe;
                break;
            }
            default: {
                //
                // Don't know what it is, don't care what it is...
                //
#if DBG
                DbgPrint("Unexpected pipe type? 0x%x\n", pipeInfo.PipeType);
#endif                
                break;
            }

        }

    }

    //
    // We hopefully have found everything we need...
    //
    if (devContext->BulkInPipe == NULL  ||
        devContext->BulkOutPipe == NULL ||
        devContext->InterruptInPipe == NULL) {
#if DBG
        DbgPrint("Didn't find expected pipes. BIN=0x%p, BOUT=0x%p, IIN=0x%p\n",
                    devContext->BulkInPipe,
                    devContext->BulkOutPipe,
                    devContext->InterruptInPipe);

#endif
        return STATUS_DEVICE_CONFIGURATION_ERROR;
    }

    //
    // By default, KMDF will not allow any non-MaxPacketSize
    // aligned I/O to be done against IN pipes. This is to avoid
    // hitting "babble" conditions, which occur when the device
    // sends more data than what you've asked it for.
    //
    // Our device doesn't babble, so we don't need this check on
    // our IN pipes.
    //
    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(devContext->BulkInPipe);
    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(devContext->InterruptInPipe);


    //
    // For fun, we're going to hang a continuous reader out on the
    // interrupt endpoint. By doing so, we'll get called at
    // BasicUsbInterruptPipeReadComplete every time someone toggles
    // the switches on the switch pack.
    //


    //
    // Initialize the continuous reader config structure, specifying
    // our callback, our context, and the size of the transfers.
    //
    WDF_USB_CONTINUOUS_READER_CONFIG_INIT(&contReaderConfig,
                                          BasicUsbInterruptPipeReadComplete,
                                          devContext,
                                          sizeof(UCHAR));

    //
    // And create the continuous reader.
    //
    // Note that the continuous reader is not started by default, so
    // we'll need to manually start it when we are called at
    // EvtD0Entry.
    //
    status = WdfUsbTargetPipeConfigContinuousReader(devContext->InterruptInPipe,
                                                    &contReaderConfig);

    if (!NT_SUCCESS(status)) {
#if DBG
        DbgPrint("WdfUsbTargetPipeConfigContinuousReader failed 0x%0x\n", 
                 status);
#endif
        return status;
    }
        
    return STATUS_SUCCESS;

}
Exemple #9
0
NTSTATUS
OsrFxEvtDevicePrepareHardware(
    IN WDFDEVICE    Device,
    IN WDFCMRESLIST ResourceList,
    IN WDFCMRESLIST ResourceListTranslated
    )
/*++

Routine Description:

    In this callback, the driver does whatever is necessary to make the
    hardware ready to use.  In the case of a USB device, this involves
    reading descriptors and selecting interfaces.

Arguments:

    Device - handle to a device

Return Value:

    NT status value

--*/
{
    NTSTATUS                            status, tempStatus;
    PDEVICE_CONTEXT                     pDeviceContext;
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;

    UNREFERENCED_PARAMETER(ResourceList);
    UNREFERENCED_PARAMETER(ResourceListTranslated);

    PAGED_CODE();

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> EvtDevicePrepareHardware\n");

    pDeviceContext = GetDeviceContext(Device);

    //
    // Create a USB device handle so that we can communicate with the
    // underlying USB stack. The WDFUSBDEVICE handle is used to query,
    // configure, and manage all aspects of the USB device.
    // These aspects include device properties, bus properties,
    // and I/O creation and synchronization. We only create device the first
    // the PrepareHardware is called. If the device is restarted by pnp manager
    // for resource rebalance, we will use the same device handle but then select
    // the interfaces again because the USB stack could reconfigure the device on
    // restart.
    //
    if (pDeviceContext->UsbDevice == NULL) {
        status = WdfUsbTargetDeviceCreate(Device,
                                    WDF_NO_OBJECT_ATTRIBUTES,
                                    &pDeviceContext->UsbDevice);
        if (!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                 "WdfUsbTargetDeviceCreate failed with Status code %!STATUS!\n", status);
            return status;
        }
    }


    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE( &configParams);

    status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice,
                                        WDF_NO_OBJECT_ATTRIBUTES,
                                        &configParams);
    if(!NT_SUCCESS(status)) {
        WDF_USB_DEVICE_INFORMATION  deviceInfo;

        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                        "WdfUsbTargetDeviceSelectConfig failed %!STATUS! \n",
                        status);
        //
        // detect if we are connected to a 1.1 USB port 
        //
        WDF_USB_DEVICE_INFORMATION_INIT(&deviceInfo);
        tempStatus = WdfUsbTargetDeviceRetrieveInformation(pDeviceContext->UsbDevice, &deviceInfo);

        if (NT_SUCCESS(tempStatus)) {
            //
            // Since the Osr USB fx2 device is capable of working at high speed, the only reason 
            // the device would not be working at high speed is if the port doesn't 
            // support it. If the port doesn't support high speed it is a 1.1 port
            //
            if ((deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED) == 0) {
                TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                                " On a 1.1 USB port on Windows Vista" 
                                " this is expected as the OSR USB Fx2 board's Interrupt EndPoint descriptor" 
                                " doesn't conform to the USB specification. Windows Vista detects this and"
                                " returns an error. \n"
                                );
            }
        }

        return status;
    }

    pDeviceContext->UsbInterface =
                configParams.Types.SingleInterface.ConfiguredUsbInterface;

    status = OsrFxConfigContReaderForInterruptEndPoint(pDeviceContext);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- EvtDevicePrepareHardware\n");

    return status;
}
// 设备配置
// 按照WDF框架,设备配置选项默认为1;如存在多个配置选项,需要切换选择的话,会比较麻烦。
// 一种办法是:使用初始化宏:WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_INTERFACES_DESCRIPTORS 
// 使用这个宏,需要首先获取配置描述符,和相关接口描述符。
// 另一种办法是:使用WDM方法,先构建一个配置选择的URB,然后要么自己调用IRP发送到总线驱动,
// 要么使用WDF方法调用WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_URB初始化宏。
// 
NTSTATUS DrvClass::ConfigureUsbDevice()
{
	WDF_USB_DEVICE_SELECT_CONFIG_PARAMS usbConfig;
	WDF_USB_INTERFACE_SELECT_SETTING_PARAMS  interfaceSelectSetting;

	KDBG(DPFLTR_INFO_LEVEL, "[ConfigureUsbDevice]");

	// 创建Usb设备对象。
	// USB设备对象是我们进行USB操作的起点。大部分的USB接口函数,都是针对它进行的。
	// USB设备对象被创建后,由驱动自己维护;框架本身不处理它,也不保持它。
	NTSTATUS status = WdfUsbTargetDeviceCreate(m_hDevice, WDF_NO_OBJECT_ATTRIBUTES, &m_hUsbDevice);
	if(!NT_SUCCESS(status))
	{
		KDBG(DPFLTR_INFO_LEVEL, "WdfUsbTargetDeviceCreate failed with status 0x%08x\n", status);
		return status;
	}

	// 接口配置
	// WDF提供了多种接口配置的初始化宏,分别针对单一接口、多接口的USB设备,
	// 初始化宏还提供了在多个配置间进行切换的途径,正如上面所讲过的。
	// 在选择默认配置的情况下,设备配置将无比简单,简单到令长期受折磨的内核程序员大跌眼镜;
	// 因为WDM上百行的代码逻辑,这里只要两三行就够了。
	UCHAR numInterfaces = WdfUsbTargetDeviceGetNumInterfaces(m_hUsbDevice);
	if(1 == numInterfaces)
	{
		KDBG(DPFLTR_INFO_LEVEL, "There is one interface.", status);
		WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&usbConfig);
	}
	else// 多接口
	{
		KDBG(DPFLTR_INFO_LEVEL, "There are %d interfaces.", numInterfaces);

		PWDF_USB_INTERFACE_SETTING_PAIR settingPairs = (WDF_USB_INTERFACE_SETTING_PAIR*)
			ExAllocatePoolWithTag(PagedPool,
				sizeof(WDF_USB_INTERFACE_SETTING_PAIR) * numInterfaces, POOLTAG);

		if (settingPairs == NULL)
			return STATUS_INSUFFICIENT_RESOURCES;

		int nNum = InitSettingPairs(m_hUsbDevice, settingPairs, numInterfaces);
		WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_MULTIPLE_INTERFACES(&usbConfig, nNum, settingPairs);
	}

	status = WdfUsbTargetDeviceSelectConfig(m_hUsbDevice, WDF_NO_OBJECT_ATTRIBUTES, &usbConfig);
	if(!NT_SUCCESS(status))
	{
		KDBG(DPFLTR_INFO_LEVEL, "WdfUsbTargetDeviceSelectConfig failed with status 0x%08x\n", status);
		return status;
	}

	// 保存接口
	if(1 == numInterfaces)
	{
		m_hUsbInterface = usbConfig.Types.SingleInterface.ConfiguredUsbInterface;

		// 使用SINGLE_INTERFACE接口配置宏,接口的AltSetting值默认为0。
		// 下面两行代码演示了如何手动修改某接口的AltSetting值(此处为1).
		WDF_USB_INTERFACE_SELECT_SETTING_PARAMS_INIT_SETTING(&interfaceSelectSetting, 1);
		status = WdfUsbInterfaceSelectSetting(m_hUsbInterface, WDF_NO_OBJECT_ATTRIBUTES, &interfaceSelectSetting);
	}
	else
	{
		int i;
		m_hUsbInterface = usbConfig.Types.MultiInterface.Pairs[0].UsbInterface;
		for(i = 0; i < numInterfaces; i++)
			m_hMulInterfaces[i] = usbConfig.Types.MultiInterface.Pairs[i].UsbInterface;
	}

	return status;
}
Exemple #11
0
// In this callback, the driver does whatever is necessary to make the hardware ready to use.
// In the case of a USB device, this involves reading and selecting descriptors.
NTSTATUS
HidFx2EvtDevicePrepareHardware(
    _In_ WDFDEVICE    hDevice,
    _In_ WDFCMRESLIST hResourceList,
    _In_ WDFCMRESLIST hResourceListTranslated
   )
{
    NTSTATUS                            status = STATUS_SUCCESS;
    PDEVICE_EXTENSION                   pDevContext = NULL;
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
    WDF_OBJECT_ATTRIBUTES               attributes;
    PUSB_DEVICE_DESCRIPTOR              pUsbDeviceDescriptor = NULL;

    UNREFERENCED_PARAMETER(hResourceList);
    UNREFERENCED_PARAMETER(hResourceListTranslated);

    PAGED_CODE ();

    TraceVerbose(DBG_INIT, "(%!FUNC!) Enter\n");

    pDevContext = GetDeviceContext(hDevice);

    // Create a WDFUSBDEVICE object. WdfUsbTargetDeviceCreate obtains the USB device descriptor and the first USB configuration
    //descriptor from the device and stores them. It also creates a framework USB interface object for each interface in the device's first configuration.
    //
    // The parent of each USB device object is the driver's framework driver object. The driver cannot change this parent, and the ParentObject
    // member or the WDF_OBJECT_ATTRIBUTES structure must be NULL.
    //
    // We only create device the first time PrepareHardware is called. If the device is restarted by pnp manager for resource rebalance, we 
    // will use the same device handle but then select the interfaces again because the USB stack could reconfigure the device on restart.
    if (pDevContext->hUsbDevice == NULL)
    {
        status = WdfUsbTargetDeviceCreate(hDevice, WDF_NO_OBJECT_ATTRIBUTES, &pDevContext->hUsbDevice);
        if (!NT_SUCCESS(status))
        {
            TraceErr(DBG_PNP, "(%!FUNC!) WdfUsbTargetDeviceCreate failed %!STATUS!\n", status);
            return status;
        }
    }

    // Select a device configuration by using a WDF_USB_DEVICE_SELECT_CONFIG_PARAMS
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams);
    status = WdfUsbTargetDeviceSelectConfig(pDevContext->hUsbDevice, WDF_NO_OBJECT_ATTRIBUTES, &configParams);
    if (!NT_SUCCESS(status))
    {
        TraceErr(DBG_PNP, "(%!FUNC!) WdfUsbTargetDeviceSelectConfig failed %!STATUS!\n", status);
        return status;
    }

    pDevContext->hUsbInterface = configParams.Types.SingleInterface.ConfiguredUsbInterface;

    // Get the device descriptor and store it in device context
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = hDevice;
    status = WdfMemoryCreate(&attributes,
                             NonPagedPool,
                             0,
                             sizeof(USB_DEVICE_DESCRIPTOR),
                             &pDevContext->hDeviceDescriptor,
                             &pUsbDeviceDescriptor);
    if (!NT_SUCCESS(status))
    {
        TraceErr(DBG_PNP, "(%!FUNC!) WdfMemoryCreate for Device Descriptor failed %!STATUS!\n", status);
        return status;
    }

    WdfUsbTargetDeviceGetDeviceDescriptor(pDevContext->hUsbDevice, pUsbDeviceDescriptor);

    // Get the Interrupt pipe. There are other endpoints but we are only interested in interrupt endpoint since our HID data comes from this
    pDevContext->hInterruptPipe = WdfUsbInterfaceGetConfiguredPipe(pDevContext->hUsbInterface, INTERRUPT_ENDPOINT_INDEX, NULL);
    if (NULL == pDevContext->hInterruptPipe)
    {
        TraceErr(DBG_PNP, "(%!FUNC!) Failed to get interrupt pipe info\n");
        status = STATUS_INVALID_DEVICE_STATE;
        return status;
    }

    // Tell the framework that it's okay to read less than MaximumPacketSize
    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pDevContext->hInterruptPipe);

    //configure continuous reader
    status = HidFx2ConfigContReaderForInterruptEndPoint(pDevContext);

    TraceVerbose(DBG_INIT, "(%!FUNC!) Exit, Status: %!STATUS!\n", status);

    return status;
}
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;
}
Exemple #13
0
NTSTATUS
TemperUsbDriverEvtDevicePrepareHardware(
    _In_ WDFDEVICE Device,
    _In_ WDFCMRESLIST ResourceList,
    _In_ WDFCMRESLIST ResourceListTranslated
    )
/*++

Routine Description:

    In this callback, the driver does whatever is necessary to make the
    hardware ready to use.  In the case of a USB device, this involves
    reading and selecting descriptors.

Arguments:

    Device - handle to a device

Return Value:

    NT status value

--*/
{
    NTSTATUS status;
    PDEVICE_CONTEXT pDeviceContext;
    WDF_USB_DEVICE_CREATE_CONFIG createParams;
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;

    UNREFERENCED_PARAMETER(ResourceList);
    UNREFERENCED_PARAMETER(ResourceListTranslated);

    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");

    status = STATUS_SUCCESS;
    pDeviceContext = DeviceGetContext(Device);

    //
    // Create a USB device handle so that we can communicate with the
    // underlying USB stack. The WDFUSBDEVICE handle is used to query,
    // configure, and manage all aspects of the USB device.
    // These aspects include device properties, bus properties,
    // and I/O creation and synchronization. We only create the device the first time
    // PrepareHardware is called. If the device is restarted by pnp manager
    // for resource rebalance, we will use the same device handle but then select
    // the interfaces again because the USB stack could reconfigure the device on
    // restart.
    //
    if (pDeviceContext->UsbDevice == NULL) {

        status = WdfUsbTargetDeviceCreateWithParameters(Device,
                                                    &createParams,
                                                    WDF_NO_OBJECT_ATTRIBUTES,
                                                    &pDeviceContext->UsbDevice
                                                    );

        if (!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
                        "WdfUsbTargetDeviceCreateWithParameters failed 0x%x", status);
            return status;
        }
    }

    //
    // Select the first configuration of the device, using the first alternate
    // setting of each interface
    //
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_MULTIPLE_INTERFACES(&configParams,
                                                                 0,
                                                                 NULL
                                                                 );
    status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice,
                                            WDF_NO_OBJECT_ATTRIBUTES,
                                            &configParams
                                            );

    if (!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
                    "WdfUsbTargetDeviceSelectConfig failed 0x%x", status);
        return status;
    }

    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit");

    return status;
}
Exemple #14
0
NTSTATUS
SelectInterfaces(
    __in WDFDEVICE Device
    )
/*++

Routine Description:

    This helper routine selects the configuration, interface and
    creates a context for every pipe (end point) in that interface.

Arguments:

    Device - Handle to a framework device

Return Value:

    NT status value

--*/
{
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
    NTSTATUS                            status;
    PDEVICE_CONTEXT                     pDeviceContext;
    WDFUSBPIPE                          pipe;
    WDF_USB_PIPE_INFORMATION            pipeInfo;
    UCHAR                               index;
    UCHAR                               numberConfiguredPipes;

    PAGED_CODE();

    pDeviceContext = GetDeviceContext(Device);

    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE( &configParams);

    status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice,
                                        WDF_NO_OBJECT_ATTRIBUTES,
                                        &configParams);
    if(!NT_SUCCESS(status)) {

        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                        "WdfUsbTargetDeviceSelectConfig failed %!STATUS! \n",
                        status);

        //
        // Since the Osr USB fx2 device is capable of working at high speed, the only reason 
        // the device would not be working at high speed is if the port doesn't 
        // support it. If the port doesn't support high speed it is a 1.1 port
        //
        if ((pDeviceContext->UsbDeviceTraits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED) == 0) {
            GUID activity = DeviceToActivityId(Device);

            TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                            " On a 1.1 USB port on Windows Vista" 
                            " this is expected as the OSR USB Fx2 board's Interrupt EndPoint descriptor" 
                            " doesn't conform to the USB specification. Windows Vista detects this and"
                            " returns an error. \n"
                            );
            EventWriteSelectConfigFailure(
                &activity,
                pDeviceContext->DeviceName,
                pDeviceContext->Location,
                status
                );
        }
        
        return status;
    }


    pDeviceContext->UsbInterface =
                configParams.Types.SingleInterface.ConfiguredUsbInterface;

    numberConfiguredPipes = configParams.Types.SingleInterface.NumberConfiguredPipes;

    //
    // Get pipe handles
    //
    for(index=0; index < numberConfiguredPipes; index++) {

        WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);

        pipe = WdfUsbInterfaceGetConfiguredPipe(
            pDeviceContext->UsbInterface,
            index, //PipeIndex,
            &pipeInfo
            );
        //
        // Tell the framework that it's okay to read less than
        // MaximumPacketSize
        //
        WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);

        if(WdfUsbPipeTypeInterrupt == pipeInfo.PipeType) {
            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                    "Interrupt Pipe is 0x%p\n", pipe);
            pDeviceContext->InterruptPipe = pipe;
        }

        if(WdfUsbPipeTypeBulk == pipeInfo.PipeType &&
                WdfUsbTargetPipeIsInEndpoint(pipe)) {
            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                    "BulkInput Pipe is 0x%p\n", pipe);
            pDeviceContext->BulkReadPipe = pipe;
        }

        if(WdfUsbPipeTypeBulk == pipeInfo.PipeType &&
                WdfUsbTargetPipeIsOutEndpoint(pipe)) {
            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                    "BulkOutput Pipe is 0x%p\n", pipe);
            pDeviceContext->BulkWritePipe = pipe;
        }

    }

    //
    // If we didn't find all the 3 pipes, fail the start.
    //
    if(!(pDeviceContext->BulkWritePipe
            && pDeviceContext->BulkReadPipe && pDeviceContext->InterruptPipe)) {
        status = STATUS_INVALID_DEVICE_STATE;
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                            "Device is not configured properly %!STATUS!\n",
                            status);

        return status;
    }

    return status;
}
Exemple #15
0
NTSTATUS
CySelectInterfaces(
    __in WDFDEVICE Device
    )
{	    
    NTSTATUS                            NTStatus;
    PDEVICE_CONTEXT                     pDeviceContext;
	BYTE altSettings;
    	
    PAGED_CODE();

	CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"Start CySelectInterfaces\n");      

    pDeviceContext = CyGetDeviceContext(Device);

	pDeviceContext->ucNumberOfInterface = WdfUsbTargetDeviceGetNumInterfaces(pDeviceContext->CyUsbDevice);
	/*if(pDeviceContext->ucNumberOfInterface == 1)*/
	{		
		CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP," Single interface\n");      
		pDeviceContext->bIsMultiplInterface = FALSE;        
		WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&pDeviceContext->UsbInterfaceConfig);
	}
	//else
	//{
	//	CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"Multiple interface :0x%x\n",pDeviceContext->ucNumberOfInterface);      
	//	pDeviceContext->bIsMultiplInterface      = TRUE;
	//	pDeviceContext->MultipleInterfacePair = ExAllocatePoolWithTag(PagedPool,
	//																	sizeof(WDF_USB_INTERFACE_SETTING_PAIR) * pDeviceContext->ucNumberOfInterface,
	//																	CYMEM_TAG
	//																	 );
	//	if (pDeviceContext->MultipleInterfacePair == NULL)	
	//	{
	//		CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"Insufficient resources\n");      
	//		return STATUS_INSUFFICIENT_RESOURCES;   
	//	}

	//	//
	//	// Call driver-defined routine to populate the
	//	// WDF_USB_INTERFACE_SETTING_PAIR structures 
	//	// that ExAllocatePoolWithTag allocated.
	//	//
	//	InitInterfacePair(
	//					 pDeviceContext->CyUsbDevice,
	//					 pDeviceContext->MultipleInterfacePair,
	//					 pDeviceContext->ucNumberOfInterface
	//					 );

	//	WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_MULTIPLE_INTERFACES(
	//				    &pDeviceContext->UsbInterfaceConfig,
	//					pDeviceContext->ucNumberOfInterface,
	//					pDeviceContext->MultipleInterfacePair
	//					);
	//}

    NTStatus = WdfUsbTargetDeviceSelectConfig(pDeviceContext->CyUsbDevice,
                                        WDF_NO_OBJECT_ATTRIBUTES,
                                        &pDeviceContext->UsbInterfaceConfig);
    if(!NT_SUCCESS(NTStatus)) 
	{
        CyTraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                        "WdfUsbTargetDeviceSelectConfig failed %!STATUS! \n",
                        NTStatus);               
        return NTStatus;
    }
	pDeviceContext->ucNumAltSettigns = WdfUsbInterfaceGetNumSettings(pDeviceContext->UsbInterfaceConfig.Types.SingleInterface.ConfiguredUsbInterface);
	pDeviceContext->ucActiveAltSettings = 0;  /* First active alternat settings will be ZERO */
	pDeviceContext->ucActiveConfigNum = 0; // This is the defaul configuration number
	
	if(!(pDeviceContext->bIsMultiplInterface))
	{//single interface
		CyGetActiveAltInterfaceConfig(pDeviceContext);
	}
	else
	{// Multiple interface
		cyGetMultipleInterfaceConfig(pDeviceContext);
	}

	pDeviceContext->ucNumberOfInterfaceCompositUSB30Only = 0; // intialize
    // Check if device is USB3.0 then parse the device configuration and store SS EP information
	if(pDeviceContext->UsbDeviceDescriptor.bcdUSB == USB30MAJORVER)
	{
		/*
		RTL_OSVERSIONINFOW lpVersionInformation= {0};
		//WORKAROUND : WIN 8 based xHCI does not provide USBDI version of xHCI driver stack, so adding this works around to differenciate OS
		// Get the OS version if it is WIN 8 then we do not need to parse the descriptor table to get the MaxBurst other paramter as it is being added to MaxPacketSize in Windows 9
		if(RtlGetVersion(&lpVersionInformation)==STATUS_SUCCESS)
		{
			CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"Operting System Version information\n");      
			CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"dwMajorVersion:%x dwMinorVersion:%x dwBuildNumber:%x\n",lpVersionInformation.dwMajorVersion
																								  ,lpVersionInformation.dwMinorVersion
																								  ,lpVersionInformation.dwBuildNumber);      
		}
		if(!((lpVersionInformation.dwMajorVersion==6) && (lpVersionInformation.dwMinorVersion ==2)))*/
			CyGetAndParseUSB30DeviceConfiguration(pDeviceContext);
	}

    CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"End CySelectInterfaces\n");      

   return NTStatus;
}