Exemplo n.º 1
0
// Get the alternate setting number of the interface. 
int UsbDev::GetNoOfAlternateSetting(UCHAR InterfaceNo)
{
	PUSB_INTERFACE_DESCRIPTOR pAlternateSetting = NULL;
	int i;

	for(i=0;;i++) 
	{// for loop i
		if (!m_pConfigDesc)
			break;

		pAlternateSetting = (PUSB_INTERFACE_DESCRIPTOR)USBD_ParseConfigurationDescriptorEx(
								m_pConfigDesc[m_UsbConfigurationNo],// Pointer to configuration descriptor
								m_pConfigDesc[m_UsbConfigurationNo],// Start position
								InterfaceNo,					// Interface number
								i,								// Alternate setting
								-1,								// Class
								-1,								// Subclass
								-1);							// Protocol

		if(!pAlternateSetting) 
			break;
	}//for loop i

	return (i);
}
Exemplo n.º 2
0
static usb_interface_descriptor_t *
USBD_ParseConfigurationDescriptor(usb_config_descriptor_t *conf,
	uint8_t intfnum, uint8_t altset)
{

	return USBD_ParseConfigurationDescriptorEx(conf, conf, intfnum, altset,
	    -1, -1, -1);
}
Exemplo n.º 3
0
PUSB_INTERFACE_DESCRIPTOR WINAPI USBD_ParseConfigurationDescriptor(
        PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, UCHAR InterfaceNumber,
        UCHAR AlternateSetting )
{
    TRACE( "(%p, %u, %u)\n", ConfigurationDescriptor, InterfaceNumber, AlternateSetting );
    return USBD_ParseConfigurationDescriptorEx( ConfigurationDescriptor, ConfigurationDescriptor,
                                                InterfaceNumber, AlternateSetting, -1, -1, -1 );
}
Exemplo n.º 4
0
static union usbd_urb *
USBD_CreateConfigurationRequest(usb_config_descriptor_t *conf, uint16_t *len)
{
	struct usbd_interface_list_entry list[2];
	union usbd_urb *urb;

	bzero(list, sizeof(struct usbd_interface_list_entry) * 2);
	list[0].uil_intfdesc = USBD_ParseConfigurationDescriptorEx(conf, conf,
	    -1, -1, -1, -1, -1);
	urb = USBD_CreateConfigurationRequestEx(conf, list);
	if (urb == NULL)
		return (NULL);

	*len = urb->uu_selconf.usc_hdr.uuh_len;
	return (urb);
}
Exemplo n.º 5
0
NTSTATUS
AllocateInterfaceDescriptorsArray(
    IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
    OUT PUSB_INTERFACE_DESCRIPTOR **OutArray)
{
    PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
    ULONG Count = 0;
    PUSB_INTERFACE_DESCRIPTOR *Array;

    //
    // allocate array
    //
    Array = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * ConfigurationDescriptor->bNumInterfaces);
    if (!Array)
        return STATUS_INSUFFICIENT_RESOURCES;

    //
    // enumerate all interfaces
    //
    Count = 0;
    do
    {
        //
        // find next descriptor
        //
        InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, Count, 0, -1, -1, -1);
        if (!InterfaceDescriptor)
            break;

        //
        // store descriptor
        //
        Array[Count] = InterfaceDescriptor;
        Count++;

    }while(TRUE);

    //
    // store result
    //
    *OutArray = Array;

    //
    // done
    //
    return STATUS_SUCCESS;
}
Exemplo n.º 6
0
PURB WINAPI USBD_CreateConfigurationRequestEx(
        PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
        PUSBD_INTERFACE_LIST_ENTRY InterfaceList )
{
    URB *urb;
    ULONG size = 0;
    USBD_INTERFACE_LIST_ENTRY *interfaceEntry;
    ULONG interfaceCount = 0;

    TRACE( "(%p, %p)\n", ConfigurationDescriptor, InterfaceList );

    size = sizeof(struct _URB_SELECT_CONFIGURATION);
    for (interfaceEntry = InterfaceList; interfaceEntry->InterfaceDescriptor; interfaceEntry++)
    {
        ++interfaceCount;
        size += (interfaceEntry->InterfaceDescriptor->bNumEndpoints - 1) *
            sizeof(USBD_PIPE_INFORMATION);
    }
    size += (interfaceCount - 1) * sizeof(USBD_INTERFACE_INFORMATION);

    urb = ExAllocatePool( NonPagedPool, size );
    if (urb)
    {
        USBD_INTERFACE_INFORMATION *interfaceInfo;

        RtlZeroMemory( urb, size );
        urb->u.UrbSelectConfiguration.Hdr.Length = size;
        urb->u.UrbSelectConfiguration.Hdr.Function = URB_FUNCTION_SELECT_CONFIGURATION;
        urb->u.UrbSelectConfiguration.ConfigurationDescriptor = ConfigurationDescriptor;
        interfaceInfo = &urb->u.UrbSelectConfiguration.Interface;
        for (interfaceEntry = InterfaceList; interfaceEntry->InterfaceDescriptor; interfaceEntry++)
        {
            int i;
            USB_INTERFACE_DESCRIPTOR *currentInterface;
            USB_ENDPOINT_DESCRIPTOR *endpointDescriptor;
            interfaceInfo->InterfaceNumber = interfaceEntry->InterfaceDescriptor->bInterfaceNumber;
            interfaceInfo->AlternateSetting = interfaceEntry->InterfaceDescriptor->bAlternateSetting;
            interfaceInfo->Class = interfaceEntry->InterfaceDescriptor->bInterfaceClass;
            interfaceInfo->SubClass = interfaceEntry->InterfaceDescriptor->bInterfaceSubClass;
            interfaceInfo->Protocol = interfaceEntry->InterfaceDescriptor->bInterfaceProtocol;
            interfaceInfo->NumberOfPipes = interfaceEntry->InterfaceDescriptor->bNumEndpoints;
            currentInterface = USBD_ParseConfigurationDescriptorEx(
                ConfigurationDescriptor, ConfigurationDescriptor,
                interfaceEntry->InterfaceDescriptor->bInterfaceNumber, -1, -1, -1, -1 );
            endpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(
                ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
                currentInterface, USB_ENDPOINT_DESCRIPTOR_TYPE );
            for (i = 0; i < interfaceInfo->NumberOfPipes && endpointDescriptor; i++)
            {
                interfaceInfo->Pipes[i].MaximumPacketSize = endpointDescriptor->wMaxPacketSize;
                interfaceInfo->Pipes[i].EndpointAddress = endpointDescriptor->bEndpointAddress;
                interfaceInfo->Pipes[i].Interval = endpointDescriptor->bInterval;
                switch (endpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK)
                {
                case USB_ENDPOINT_TYPE_CONTROL:
                    interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeControl;
                    break;
                case USB_ENDPOINT_TYPE_BULK:
                    interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeBulk;
                    break;
                case USB_ENDPOINT_TYPE_INTERRUPT:
                    interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeInterrupt;
                    break;
                case USB_ENDPOINT_TYPE_ISOCHRONOUS:
                    interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeIsochronous;
                    break;
                }
                endpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(
                    ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
                    endpointDescriptor + 1, USB_ENDPOINT_DESCRIPTOR_TYPE );
            }
            interfaceInfo->Length = sizeof(USBD_INTERFACE_INFORMATION) +
                (i - 1) * sizeof(USBD_PIPE_INFORMATION);
            interfaceEntry->Interface = interfaceInfo;
            interfaceInfo = (USBD_INTERFACE_INFORMATION*)(((char*)interfaceInfo)+interfaceInfo->Length);
        }
    }
    return urb;
}
Exemplo n.º 7
0
NTSTATUS
USBHUB_ParentFDOStartDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
{
    PHUB_DEVICE_EXTENSION HubDeviceExtension;
    PURB Urb, ConfigurationUrb;
    PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
    PUSBD_INTERFACE_LIST_ENTRY InterfaceList;
    ULONG Index;
    NTSTATUS Status;

    // get hub device extension
    HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;

    // Send the StartDevice to lower device object
    Status = ForwardIrpAndWait(HubDeviceExtension->LowerDeviceObject, Irp);

    if (!NT_SUCCESS(Status))
    {
        // failed to start pdo
        DPRINT1("Failed to start the RootHub PDO\n");
        return Status;
    }

    // FIXME get capabilities

    Urb = ExAllocatePool(NonPagedPool, sizeof(URB));
    if (!Urb)
    {
        // no memory
        DPRINT1("No memory\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }


    // lets get device descriptor
    UsbBuildGetDescriptorRequest(Urb,
                                    sizeof(Urb->UrbControlDescriptorRequest),
                                    USB_DEVICE_DESCRIPTOR_TYPE,
                                    0,
                                    0,
                                    &HubDeviceExtension->HubDeviceDescriptor,
                                    NULL,
                                    sizeof(USB_DEVICE_DESCRIPTOR),
                                    NULL);


    // get hub device descriptor
    Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
                                    IOCTL_INTERNAL_USB_SUBMIT_URB,
                                    Urb,
                                    NULL);

    if (!NT_SUCCESS(Status))
    {
        // failed to get device descriptor of hub
        DPRINT1("Failed to get hub device descriptor with Status %x!\n", Status);
        ExFreePool(Urb);
        return Status;
    }

    // now get configuration descriptor
    UsbBuildGetDescriptorRequest(Urb,
                                    sizeof(Urb->UrbControlDescriptorRequest),
                                    USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                    0,
                                    0,
                                    &HubDeviceExtension->HubConfigDescriptor,
                                    NULL,
                                    sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR),
                                    NULL);

    // request configuration descriptor
    Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
                                    IOCTL_INTERNAL_USB_SUBMIT_URB,
                                    Urb,
                                    NULL);

    if (!NT_SUCCESS(Status))
    {
        // failed to get configuration descriptor
        DPRINT1("Failed to get hub configuration descriptor with status %x\n", Status);
        ExFreePool(Urb);
        return Status;
    }

    // sanity checks
    ASSERT(HubDeviceExtension->HubConfigDescriptor.wTotalLength == sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR));
    ASSERT(HubDeviceExtension->HubConfigDescriptor.bDescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE);
    ASSERT(HubDeviceExtension->HubConfigDescriptor.bLength == sizeof(USB_CONFIGURATION_DESCRIPTOR));
    ASSERT(HubDeviceExtension->HubConfigDescriptor.bNumInterfaces == 1);
    ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bLength == sizeof(USB_INTERFACE_DESCRIPTOR));
    ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE);
    ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bNumEndpoints == 1);
    ASSERT(HubDeviceExtension->HubEndPointDescriptor.bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE);
    ASSERT(HubDeviceExtension->HubEndPointDescriptor.bLength == sizeof(USB_ENDPOINT_DESCRIPTOR));
    ASSERT(HubDeviceExtension->HubEndPointDescriptor.bmAttributes == USB_ENDPOINT_TYPE_INTERRUPT);
    ASSERT(HubDeviceExtension->HubEndPointDescriptor.bEndpointAddress == 0x81); // interrupt in

    // Build hub descriptor request
    UsbBuildVendorRequest(Urb,
                            URB_FUNCTION_CLASS_DEVICE,
                            sizeof(Urb->UrbControlVendorClassRequest),
                            USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
                            0,
                            USB_REQUEST_GET_DESCRIPTOR,
                            USB_DEVICE_CLASS_RESERVED,
                            0,
                            &HubDeviceExtension->HubDescriptor,
                            NULL,
                            sizeof(USB_HUB_DESCRIPTOR),
                            NULL);

    // send request
    Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
                                    IOCTL_INTERNAL_USB_SUBMIT_URB,
                                    Urb,
                                    NULL);

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to get Hub Descriptor Status %x!\n", Status);
        ExFreePool(Urb);
        return STATUS_UNSUCCESSFUL;
    }

    // sanity checks
    ASSERT(HubDeviceExtension->HubDescriptor.bDescriptorLength == sizeof(USB_HUB_DESCRIPTOR));
    ASSERT(HubDeviceExtension->HubDescriptor.bNumberOfPorts);
    ASSERT(HubDeviceExtension->HubDescriptor.bDescriptorType == 0x29);

    // store number of ports
    DPRINT1("NumberOfPorts %lu\n", HubDeviceExtension->HubDescriptor.bNumberOfPorts);
    HubDeviceExtension->UsbExtHubInfo.NumberOfPorts = HubDeviceExtension->HubDescriptor.bNumberOfPorts;

    // allocate interface list
    InterfaceList = ExAllocatePool(NonPagedPool, sizeof(USBD_INTERFACE_LIST_ENTRY) * (HubDeviceExtension->HubConfigDescriptor.bNumInterfaces + 1));
    if (!InterfaceList)
    {
        // no memory
        DPRINT1("No memory\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    // zero list
    RtlZeroMemory(InterfaceList, sizeof(USBD_INTERFACE_LIST_ENTRY) * (HubDeviceExtension->HubConfigDescriptor.bNumInterfaces + 1));

    // grab all interface descriptors
    for(Index = 0; Index < HubDeviceExtension->HubConfigDescriptor.bNumInterfaces; Index++)
    {
        // Get the first Configuration Descriptor
        InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension->HubConfigDescriptor,
                                                                  &HubDeviceExtension->HubConfigDescriptor,
                                                                  Index, 0, -1, -1, -1);

        // store in list
        InterfaceList[Index].InterfaceDescriptor = InterfaceDescriptor;
    }

    // now create configuration request
    ConfigurationUrb = USBD_CreateConfigurationRequestEx(&HubDeviceExtension->HubConfigDescriptor,
                                                    (PUSBD_INTERFACE_LIST_ENTRY)&InterfaceList);
    if (ConfigurationUrb == NULL)
    {
        // failed to build urb
        DPRINT1("Failed to build configuration urb\n");
        ExFreePool(Urb);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    // send request
    Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
                                    IOCTL_INTERNAL_USB_SUBMIT_URB,
                                    ConfigurationUrb,
                                    NULL);

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to get Hub Descriptor Status %x!\n", Status);
        ExFreePool(Urb);
        ExFreePool(ConfigurationUrb);
        return STATUS_UNSUCCESSFUL;
    }

    // store configuration & pipe handle
    HubDeviceExtension->ConfigurationHandle = ConfigurationUrb->UrbSelectConfiguration.ConfigurationHandle;
    HubDeviceExtension->PipeHandle = ConfigurationUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
    DPRINT("Hub Configuration Handle %x\n", HubDeviceExtension->ConfigurationHandle);

    // free urb
    ExFreePool(ConfigurationUrb);
    ExFreePool(Urb);

    // FIXME build SCE interrupt request

    // FIXME create pdos

    return Status;
}
Exemplo n.º 8
0
// Set the configuration of the usb device.
NTSTATUS UsbDev::SetConfiguration()
{
	NTSTATUS ntStatus = STATUS_SUCCESS;
    PUSBD_INTERFACE_LIST_ENTRY	pTempInterfaceList = NULL, pTempInterfaceList_First = NULL;
	PUSB_CONFIGURATION_DESCRIPTOR pTemp_pConfigDesc = m_pConfigDesc[m_UsbConfigurationNo];
	int i,j,NoOfInterface;
	PUSB_INTERFACE_DESCRIPTOR pTempInterfaceDesc = NULL;
	PURB pUrb = NULL;
	//2010/8/17 03:49下午
	KIRQL oldIrql;
	PUSBD_INTERFACE_INFORMATION interface_temp;
	
	//2010/8/16 06:17下午
	NoOfInterface = pTemp_pConfigDesc->bNumInterfaces;
	DBGU_TRACE(">>>UsbDev::SetConfiguration ! NoOfInterface = %d\n",NoOfInterface);
	pTempInterfaceList_First = pTempInterfaceList = (PUSBD_INTERFACE_LIST_ENTRY) ExAllocatePoolWithTag( NonPagedPool,	sizeof(USBD_INTERFACE_LIST_ENTRY) * (NoOfInterface + 1), USBDEV_POOLTAG);
	
	//2010/8/23 11:51上午
	m_NumberOfInterfaces = NoOfInterface;
	
	if(pTempInterfaceList)
	{// pTempInterfaceList != NULL
		RtlZeroMemory(pTempInterfaceList, sizeof(USBD_INTERFACE_LIST_ENTRY) * (NoOfInterface + 1));

		for(i=0;i<NoOfInterface;i++) 
		{// for loop i
			pTempInterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseConfigurationDescriptorEx( 
														m_pConfigDesc[0],		// Pointer to configuration descriptor
														m_pConfigDesc[0],		// Start position
														i,					// Interface number
														-1,//0,					// Alternate setting
														-1,
														-1,
														-1);

			if(!pTempInterfaceDesc)
				break;

			pTempInterfaceList->InterfaceDescriptor = pTempInterfaceDesc;
			pTempInterfaceList++;
		}// for loop i

	    pTempInterfaceList->InterfaceDescriptor = NULL;	// Mark the end of the list
		//pTempInterfaceList = pTempInterfaceList_First; // Pointer to the first entry of the interface list.
		pUrb = USBD_CreateConfigurationRequestEx(pTemp_pConfigDesc, pTempInterfaceList_First);

		if(pUrb) 
		{// pUrb != NULL
			for(i=0;i<NoOfInterface;i++) 
			{// for loop i
				// Set to interface i, alternater 0
				pTempInterfaceList_First[i].Interface->InterfaceNumber	= i;
				pTempInterfaceList_First[i].Interface->AlternateSetting	= 0;	
				DBGU_TRACE("No of endpoints : %d\n", pTempInterfaceList_First[i].InterfaceDescriptor->bNumEndpoints);
				
				for(j=0;j<pTempInterfaceList_First[i].InterfaceDescriptor->bNumEndpoints;j++) 
					pTempInterfaceList_First[i].Interface->Pipes[j].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
			}// for loop i
			
			//2010/8/24 05:51下午
			interface_temp = &pUrb->UrbSelectConfiguration.Interface;
			
			ntStatus = SendAwaitUrb(pUrb);
			
			if(!NT_SUCCESS(ntStatus)) 
			{// ntStatus != STATUS_SUCCESS
				ntStatus = STATUS_IO_DEVICE_ERROR;
				DBGU_TRACE("Fail to configure usb device !\n");
			}// ntStatus != STATUS_SUCCESS
			else
			{// ntStatus == STATUS_SUCCESS
				m_hConfigureation = pUrb->UrbSelectConfiguration.ConfigurationHandle;
				//Release memory
				//if(m_pInterfaceListEntry)
				{ // m_pInterfaceListEntry != NULL
					for(i=0;i<m_NumberOfInterfaces;i++)
						if(m_pInterface[i])
						{
							ExFreePoolWithTag(m_pInterface[i],USBDEV_POOLTAG);
							m_pInterface[i] = NULL;
							DBGU_TRACE("ExFreePoolWithTag m_pInterface[%d]\n",i);
						}
				//	ExFreePoolWithTag(m_pInterfaceListEntry,USBDEV_POOLTAG);
				//	m_pInterfaceListEntry = NULL;
				} // m_pInterfaceListEntry != NULL
				//2010/8/23 11:51上午
				//m_NumberOfInterfaces = NoOfInterface;
				//Copy interface list
				//m_pInterfaceListEntry = (PUSBD_INTERFACE_LIST_ENTRY) ExAllocatePoolWithTag(NonPagedPool,(m_NumberOfInterfaces * sizeof(USBD_INTERFACE_LIST_ENTRY)), USBDEV_POOLTAG);

				//if(m_pInterfaceListEntry)
				{// m_pInterfaceListEntry != NULL
					
					for(i=0;i<m_NumberOfInterfaces;i++) 
					{//for loop i
						//m_pInterfaceListEntry[i].InterfaceDescriptor = pTempInterfaceList_First[i].InterfaceDescriptor;
#ifdef __VIDEO_CLASS__
						// For Video Class Device
						if (pTempInterfaceList_First[i].Interface->InterfaceNumber==1) // UVC has 2 interfaces
						{
							//2011/5/12 02:22下午
							if(BeST5R286)
								pTempInterfaceList_First[i].Interface->NumberOfPipes = 2;
							else
								pTempInterfaceList_First[i].Interface->NumberOfPipes = 1;
							
							pTempInterfaceList_First[i].Interface->Length = sizeof(USBD_INTERFACE_INFORMATION);
						}

						// james try M2TS.
						if (pTempInterfaceList_First[i].Interface->InterfaceNumber==2)
						{
							pTempInterfaceList_First[i].Interface->NumberOfPipes = 1;
							pTempInterfaceList_First[i].Interface->Length = sizeof(USBD_INTERFACE_INFORMATION);
						}
#endif
						//2010/8/24 05:53下午
//						m_pInterface[i] = (PUSBD_INTERFACE_INFORMATION) ExAllocatePoolWithTag(NonPagedPool, pTempInterfaceList_First[i].Interface->Length, USBDEV_POOLTAG);
						if(BeST5R286)
							m_pInterface[i] = (PUSBD_INTERFACE_INFORMATION) ExAllocatePoolWithTag(NonPagedPool, GET_USBD_INTERFACE_SIZE(2), USBDEV_POOLTAG);
						else
							m_pInterface[i] = (PUSBD_INTERFACE_INFORMATION) ExAllocatePoolWithTag(NonPagedPool, interface_temp->Length, USBDEV_POOLTAG);
						
						//2010/8/17 05:42下午
						//KeAcquireSpinLock(&SetConfigSpinLock, &oldIrql);

						//2010/8/13 05:20下午
						if (m_pInterface[i] && pTempInterfaceList_First[i].Interface && pTempInterfaceList_First[i].Interface->Length >0)
						//if (m_pInterfaceListEntry[i].Interface)
						{
							//2010/8/25 10:52上午
							//DBGU_TRACE("RtlCopyMemory Interface[%d] len = %d\n",i,pTempInterfaceList_First[i].Interface->Length);
							//RtlCopyMemory(m_pInterface[i], pTempInterfaceList_First[i].Interface, pTempInterfaceList_First[i].Interface->Length);
							DBGU_TRACE("MJ RtlCopyMemory Interface[%d] len = %d\n",i,interface_temp->Length);
							RtlCopyMemory(m_pInterface[i], interface_temp, interface_temp->Length);
							m_pInterface[i]->InterfaceNumber	= i;
							m_pInterface[i]->AlternateSetting	= 0;	
							
							if(i==0)
								m_pInterface[i]->Pipes[0].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
							else
							{
								if(BeST5R286)
									m_pInterface[i]->NumberOfPipes = 2;
								else	
									m_pInterface[i]->NumberOfPipes = 1;
							}

						}
						else
						{
							DBGU_TRACE("RtlCopyMemory Interface[%d] STATUS_INSUFFICIENT_RESOURCES\n",i);
							ntStatus = STATUS_INSUFFICIENT_RESOURCES;
						}	
						//2010/8/17 03:42下午
						//KeReleaseSpinLock(&SetConfigSpinLock, oldIrql);
					}//for loop i
					

				}// m_pInterfaceListEntry != NULL
				/*else
				{// m_pInterfaceListEntry == NULL
					ntStatus = STATUS_INSUFFICIENT_RESOURCES;
				}*/// m_pInterfaceListEntry == NULL
			}// ntStatus == STATUS_SUCCESS
		}// pUrb != NULL
		else
		{// pUrb == NULL
			ntStatus = STATUS_INSUFFICIENT_RESOURCES;
		}// pUrb == NULL
	}// pTempInterfaceList != NULL
	else
	{// pTempInterfaceList == NULL
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;
	}// pTempInterfaceList == NULL

	if(pUrb) 
		ExFreePool(pUrb);

	if(pTempInterfaceList_First)
	{
		ExFreePoolWithTag(pTempInterfaceList_First,USBDEV_POOLTAG);
		//2010/8/16 07:00下午
		pTempInterfaceList_First = NULL;
	}

	return ntStatus;
}
Exemplo n.º 9
0
NTSTATUS
USBCCGP_LegacyEnum(
    IN PDEVICE_OBJECT DeviceObject)
{
    ULONG Index;
    PFDO_DEVICE_EXTENSION FDODeviceExtension;
    NTSTATUS Status = STATUS_SUCCESS;
    PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;

    //
    // get device extension
    //
    FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
    ASSERT(FDODeviceExtension->Common.IsFDO);

    //
    // sanity check
    //
    ASSERT(FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces);

    //
    // allocate function array
    //
    FDODeviceExtension->FunctionDescriptor = AllocateItem(NonPagedPool, sizeof(USBC_FUNCTION_DESCRIPTOR) * FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces);
    if (!FDODeviceExtension->FunctionDescriptor)
    {
        //
        // no memory
        //
        DPRINT1("USBCCGP_EnumWithAssociationDescriptor failed to allocate function descriptor %lu\n", FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // init function descriptors
    //
    for (Index = 0; Index < FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces; Index++)
    {
        // get interface descriptor
        InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(FDODeviceExtension->ConfigurationDescriptor, FDODeviceExtension->ConfigurationDescriptor, Index, 0, -1, -1, -1);
        if (InterfaceDescriptor == NULL)
        {
            //
            // failed to find interface descriptor
            //
            DPRINT1("[USBCCGP] Failed to find interface descriptor index %lu\n", Index);
            ASSERT(FALSE);
            return STATUS_UNSUCCESSFUL;
        }

        //
        // init function descriptor
        //
        FDODeviceExtension->FunctionDescriptor[Index].FunctionNumber = Index;
        FDODeviceExtension->FunctionDescriptor[Index].NumberOfInterfaces = 1;
        FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * 1);
        if (!FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList)
        {
            //
            // no memory
            //
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        //
        // store interface descriptor
        //
        FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList[0] = InterfaceDescriptor;

        //
        // now init the device ids
        //
        Status = USBCCG_InitIdsWithInterfaceDescriptor(FDODeviceExtension, InterfaceDescriptor, Index, &FDODeviceExtension->FunctionDescriptor[Index]);
        if (!NT_SUCCESS(Status))
        {
            //
            // failed to init ids
            //
            DPRINT1("[USBCCGP] Failed to init ids with %lx\n", Status);
            return Status;
        }

        //
        // store function count
        //
        FDODeviceExtension->FunctionDescriptorCount++;
    }

    //
    // done
    //
    return Status;
}
NTSTATUS StartDevice( PDEVICE_OBJECT fdo, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated )
{
    USB_CONFIGURATION_DESCRIPTOR  tcd;
    PUSB_CONFIGURATION_DESCRIPTOR pcd;
    PUSB_STRING_DESCRIPTOR        desc;            
    HANDLE                        RecoveryHandle;
    PURB                          selurb;
    URB                           urb;     
    NTSTATUS                      status;

    status = STATUS_SUCCESS; 
    
    PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

    selurb = NULL;
    pcd    = NULL;

    // Read our device descriptor. The only real purpose to this would be to find out how many
    // configurations there are so we can read their descriptors. In this simplest of examples,
    // there's only one configuration.
    
    KdPrint((DRIVERNAME " - Start device\n"));

    UsbBuildGetDescriptorRequest(
                                  &urb, 
                                  sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), 
                                  USB_DEVICE_DESCRIPTOR_TYPE,
                                  0, 
                                  LangId, 
                                  &pdx->dd, 
                                  NULL, 
                                  sizeof(pdx->dd), 
                                  NULL
                                );
 
    status = SendAwaitUrb( fdo, &urb );
    
    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - Error %X trying to retrieve device descriptor\n", status));
        goto cleanup;
    }

    // allocate the buffer for the descriptor; take extra space to null terminate the bString member
    desc = (PUSB_STRING_DESCRIPTOR)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, SPOT_TAG );

    if(!desc)
    {
        KdPrint((DRIVERNAME " - Unable to allocate %X bytes for string descriptor\n", sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }
    
    pdx->devHash = desc;

    UsbBuildGetDescriptorRequest(&urb, 
                                 sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), 
                                 USB_STRING_DESCRIPTOR_TYPE,
                                 DeviceId, 
                                 LangId, 
                                 desc, 
                                 NULL, 
                                 sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes,
                                 NULL);
    
    status = SendAwaitUrb(fdo, &urb);
    
    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - Error %X trying to retrieve string descriptor for DeviceId\n", status));
        goto cleanup;
    }
        
    // null terminate the buffer; we allocated one more wchar_t for the purpose 
    desc->bString[ (desc->bLength / 2) - 1 ] = L'\0';

    UpdateDeviceInformation( fdo );

    // Read the descriptor of the first configuration. This requires two steps. The first step
    // reads the fixed-size configuration descriptor alone. The second step reads the
    // configuration descriptor plus all imbedded interface and endpoint descriptors.

    UsbBuildGetDescriptorRequest(&urb, 
                                 sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), 
                                 USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                 0, 
                                 LangId, 
                                 &tcd, 
                                 NULL, 
                                 sizeof(tcd), 
                                 NULL);

    status = SendAwaitUrb(fdo, &urb);
    
    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - Error %X trying to read configuration descriptor 1\n", status));
        goto cleanup;
    }

    ULONG size = tcd.wTotalLength;
    
    pcd = (PUSB_CONFIGURATION_DESCRIPTOR) ExAllocatePoolWithTag(NonPagedPool, size, SPOT_TAG);
    
    if(!pcd)
    {
        KdPrint((DRIVERNAME " - Unable to allocate %X bytes for configuration descriptor\n", size));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }

    UsbBuildGetDescriptorRequest(&urb, 
                                 sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), 
                                 USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                 0, 
                                 LangId, 
                                 pcd, 
                                 NULL, 
                                 size, 
                                 NULL);

    status = SendAwaitUrb(fdo, &urb);
    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - Error %X trying to read configuration descriptor 1\n", status));
        goto cleanup;
    }
                           
    // Locate the descriptor for the one and only interface we expect to find

    PUSB_INTERFACE_DESCRIPTOR pid = USBD_ParseConfigurationDescriptorEx(pcd, 
                                                                        pcd,
                                                                        -1, 
                                                                        -1, 
                                                                        -1, 
                                                                        -1, 
                                                                        -1);

    ASSERT(pid);
                           
    // Create a URB to use in selecting a configuration.

    USBD_INTERFACE_LIST_ENTRY interfaces[2] = {
        {pid, NULL},
        {NULL, NULL},        // fence to terminate the array
    };

    selurb = USBD_CreateConfigurationRequestEx(pcd, interfaces);
    if(!selurb)
    {
        KdPrint((DRIVERNAME " - Unable to create configuration request\n"));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }

    // Verify that the interface describes exactly the endpoints we expect
    if(pid->bNumEndpoints != 2)
    {
        KdPrint((DRIVERNAME " - %d is the wrong number of endpoints\n", pid->bNumEndpoints));
        status = STATUS_DEVICE_CONFIGURATION_ERROR;
        goto cleanup;
    }

    PUSB_ENDPOINT_DESCRIPTOR ped = (PUSB_ENDPOINT_DESCRIPTOR) pid;
    ped = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(pcd, tcd.wTotalLength, ped, USB_ENDPOINT_DESCRIPTOR_TYPE);
    if(!ped || 0 == (ped->bEndpointAddress & 0x80) || ped->bmAttributes != USB_ENDPOINT_TYPE_BULK || ped->wMaxPacketSize > 64)
    {
        KdPrint((DRIVERNAME " - Endpoint has wrong attributes\n"));
        status = STATUS_DEVICE_CONFIGURATION_ERROR;
        goto cleanup;
    }
    ++ped;
    if(!ped || 0 != (ped->bEndpointAddress & 0x80) || ped->bmAttributes != USB_ENDPOINT_TYPE_BULK || ped->wMaxPacketSize > 64)
    {
        KdPrint((DRIVERNAME " - Endpoint has wrong attributes\n"));
        status = STATUS_DEVICE_CONFIGURATION_ERROR;
        goto cleanup;
    }
    ++ped;

    PUSBD_INTERFACE_INFORMATION pii = interfaces[0].Interface;
    ASSERT(pii->NumberOfPipes == pid->bNumEndpoints);

    // Initialize the maximum transfer size for each of the endpoints. The
    // default would be PAGE_SIZE. The firmware itself only has a 4096-byte
    // ring buffer, though. We need to restrict the test applet to that many
    // bytes. In order to exercise the multi-segment aspect of the transfer code,
    // therefore, reduce the maximum transfer size to 1024 bytes.

    pii->Pipes[0].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
    pii->Pipes[1].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
    pdx->maxtransfer = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;

    // Submit the set-configuration request

    status = SendAwaitUrb(fdo, selurb);
    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - Error %X trying to select configuration\n", status));
        goto cleanup;
    }

    // Save the configuration and pipe handles
    pdx->hconfig = selurb->UrbSelectConfiguration.ConfigurationHandle;
    pdx->hinpipe = pii->Pipes[0].PipeHandle;
    pdx->houtpipe = pii->Pipes[1].PipeHandle;

    // Transfer ownership of the configuration descriptor to the device extension

    pdx->pcd = pcd;
    pcd = NULL;

    // Enable the interface
    IoSetDeviceInterfaceState(&pdx->operationsInterfaceName, TRUE);        

    // Enable the interface
    IoSetDeviceInterfaceState(&pdx->inquiriesInterfaceName, TRUE);                    

    // create recovery thread                     
    status = PsCreateSystemThread(&RecoveryHandle, 0, NULL, NULL, NULL, RecoveryThread, (PVOID)pdx);

    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - PsCreateSystemThread failed with error %08x\n", status));
        goto cleanup;
    }
    
    status = ObReferenceObjectByHandle( RecoveryHandle,
                                        SYNCHRONIZE,
                                        NULL,
                                        KernelMode,
                                        (PVOID*)&pdx->RecoveryThread,
                                        NULL );

    ASSERT(NT_SUCCESS(status));

    ZwClose(RecoveryHandle);
    
    // Start polling
    status = StartPolling(pdx);
    
    if(!NT_SUCCESS(status))
    {   
        KdPrint((DRIVERNAME " - StartPolling failed 0x%08x\n", status));

        if(pdx->RecoveryThread)
        {
            // shutdown recovery thread
            pdx->RecoveryExit = TRUE; 
            KeSetEvent(&pdx->RecoveryEvent, 0, FALSE);    
            // wait for polling thread to exit 
            KeWaitForSingleObject(pdx->RecoveryThread, Executive, KernelMode, FALSE, NULL);     
            ObDereferenceObject(pdx->RecoveryThread);
            pdx->RecoveryThread = NULL;
        }
        
        goto cleanup;
    }
    
cleanup:
    if(selurb) ExFreePool(selurb);
    if(pcd   ) ExFreePool(pcd   );

    // get rid of return codes like STATUS_PENDING
    if(NT_SUCCESS(status)) 
    {
        return STATUS_SUCCESS;
    }
    
    return status;
}
Exemplo n.º 11
0
NTSTATUS NTAPI
UsbhubPnpFdo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    PIO_STACK_LOCATION IrpSp;
    NTSTATUS Status = STATUS_SUCCESS;
    ULONG MinorFunction;
    ULONG_PTR Information = 0;
    PHUB_DEVICE_EXTENSION DeviceExtension;

    IrpSp = IoGetCurrentIrpStackLocation(Irp);
    MinorFunction = IrpSp->MinorFunction;

    DeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;

    switch (MinorFunction)
    {
        case IRP_MN_START_DEVICE: /* 0x0 */
        {
            PURB Urb;
            ULONG Result = 0;
            PUSB_INTERFACE_DESCRIPTOR Pid;
            /* Theres only one descriptor on hub */
            USBD_INTERFACE_LIST_ENTRY InterfaceList[2] = {{NULL, NULL}, {NULL, NULL}};
            PURB ConfigUrb = NULL;

            /* We differ from windows on hubpdo because we dont have usbport.sys which manages all usb device objects */
            DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");

            /* Allocating size including the sizeof USBD_INTERFACE_LIST_ENTRY */
            Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB) + sizeof(USBD_INTERFACE_LIST_ENTRY), USB_HUB_TAG);
            RtlZeroMemory(Urb, sizeof(URB) + sizeof(USBD_INTERFACE_LIST_ENTRY));

            /* Get the hubs PDO */
            QueryRootHub(DeviceExtension->LowerDevice, IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO, &DeviceExtension->RootHubPdo, &DeviceExtension->RootHubFdo);
            ASSERT(DeviceExtension->RootHubPdo);
            ASSERT(DeviceExtension->RootHubFdo);
            DPRINT1("RootPdo %x, RootFdo %x\n", DeviceExtension->RootHubPdo, DeviceExtension->RootHubFdo);

            /* Send the START_DEVICE irp down to the PDO of RootHub */
            Status = ForwardIrpAndWait(DeviceExtension->RootHubPdo, Irp);

            if (!NT_SUCCESS(Status))
            {
                DPRINT1("Failed to start the RootHub PDO\n");
                ASSERT(FALSE);
            }

            /* Get the current number of hubs */
            QueryRootHub(DeviceExtension->RootHubPdo,IOCTL_INTERNAL_USB_GET_HUB_COUNT, &DeviceExtension->HubCount, NULL);

            /* Get the Direct Call Interfaces */
            Status = QueryInterface(DeviceExtension->RootHubPdo, 
                                    USB_BUS_INTERFACE_HUB_GUID,
                                    sizeof(USB_BUS_INTERFACE_HUB_V5),
                                    5,
                                    (PVOID)&DeviceExtension->HubInterface);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("UsbhubM Failed to get HUB_GUID interface with status 0x%08lx\n", Status);
                return STATUS_UNSUCCESSFUL;
            }

            Status = QueryInterface(DeviceExtension->RootHubPdo,
                                    USB_BUS_INTERFACE_USBDI_GUID,
                                    sizeof(USB_BUS_INTERFACE_USBDI_V2),
                                    2,
                                    (PVOID)&DeviceExtension->UsbDInterface);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("UsbhubM Failed to get USBDI_GUID interface with status 0x%08lx\n", Status);
                return STATUS_UNSUCCESSFUL;
            }

            /* Get roothub device handle */
            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE, &DeviceExtension->RootHubUsbDevice, NULL);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("Usbhub: GetRootHubDeviceHandle failed with status 0x%08lx\n", Status);
                return Status;
            }

            Status = DeviceExtension->HubInterface.QueryDeviceInformation(DeviceExtension->RootHubPdo,
                                                                 DeviceExtension->RootHubUsbDevice,
                                                                 &DeviceExtension->DeviceInformation,
                                                                 sizeof(USB_DEVICE_INFORMATION_0),
                                                                 &Result);


            DPRINT("Status %x, Result %x\n", Status, Result);
            DPRINT("InformationLevel %x\n", DeviceExtension->DeviceInformation.InformationLevel);
            DPRINT("ActualLength %x\n", DeviceExtension->DeviceInformation.ActualLength);
            DPRINT("PortNumber %x\n", DeviceExtension->DeviceInformation.PortNumber);
            DPRINT("DeviceDescriptor %x\n", DeviceExtension->DeviceInformation.DeviceDescriptor);
            DPRINT("HubAddress %x\n", DeviceExtension->DeviceInformation.HubAddress);
            DPRINT("NumberofPipes %x\n", DeviceExtension->DeviceInformation.NumberOfOpenPipes);

            /* Get roothubs device descriptor */
            UsbBuildGetDescriptorRequest(Urb,
                                         sizeof(Urb->UrbControlDescriptorRequest),
                                         USB_DEVICE_DESCRIPTOR_TYPE,
                                         0,
                                         0,
                                         &DeviceExtension->HubDeviceDescriptor,
                                         NULL,
                                         sizeof(USB_DEVICE_DESCRIPTOR),
                                         NULL);

            Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->RootHubUsbDevice;

            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("Usbhub: Failed to get HubDeviceDescriptor!\n");
            }

            DumpDeviceDescriptor(&DeviceExtension->HubDeviceDescriptor);

            /* Get roothubs configuration descriptor */
            UsbBuildGetDescriptorRequest(Urb,
                                         sizeof(Urb->UrbControlDescriptorRequest),
                                         USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                         0,
                                         0,
                                         &DeviceExtension->HubConfigDescriptor,
                                         NULL,
                                         sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR),
                                         NULL);
            Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->RootHubUsbDevice;

            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);

            if (!NT_SUCCESS(Status))
            {
                DPRINT1("Usbhub: Failed to get RootHub Configuration with status %x\n", Status);
                ASSERT(FALSE);
            }
            ASSERT(DeviceExtension->HubConfigDescriptor.wTotalLength);

            DumpFullConfigurationDescriptor(&DeviceExtension->HubConfigDescriptor);
            //DPRINT1("DeviceExtension->HubConfigDescriptor.wTotalLength %x\n", DeviceExtension->HubConfigDescriptor.wTotalLength);

            Status = DeviceExtension->HubInterface.GetExtendedHubInformation(DeviceExtension->RootHubPdo,
                                                                    DeviceExtension->RootHubPdo,
                                                                    &DeviceExtension->UsbExtHubInfo,
                                                                    sizeof(USB_EXTHUB_INFORMATION_0),
                                                                    &Result);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("Usbhub: Failed to extended hub information. Unable to determine the number of ports!\n");
                ASSERT(FALSE);
            }

            DPRINT1("DeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n", DeviceExtension->UsbExtHubInfo.NumberOfPorts);

            UsbBuildVendorRequest(Urb,
                                  URB_FUNCTION_CLASS_DEVICE,
                                  sizeof(Urb->UrbControlVendorClassRequest),
                                  USBD_TRANSFER_DIRECTION_IN,
                                  0,
                                  USB_DEVICE_CLASS_RESERVED,
                                  0,
                                  0,
                                  &DeviceExtension->HubDescriptor,
                                  NULL,
                                  sizeof(USB_HUB_DESCRIPTOR),
                                  NULL);

            Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->RootHubUsbDevice;

            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);

            DPRINT1("bDescriptorType %x\n", DeviceExtension->HubDescriptor.bDescriptorType);

            /* Select the configuration */

            /* Get the first one */
            Pid = USBD_ParseConfigurationDescriptorEx(&DeviceExtension->HubConfigDescriptor,
                                                      &DeviceExtension->HubConfigDescriptor,
                                                      -1, -1, -1, -1, -1);
            ASSERT(Pid != NULL);
            InterfaceList[0].InterfaceDescriptor = Pid;
            ConfigUrb = USBD_CreateConfigurationRequestEx(&DeviceExtension->HubConfigDescriptor, (PUSBD_INTERFACE_LIST_ENTRY)&InterfaceList);
            ASSERT(ConfigUrb != NULL);
            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, ConfigUrb, NULL);

            DeviceExtension->ConfigurationHandle = ConfigUrb->UrbSelectConfiguration.ConfigurationHandle;
            DeviceExtension->PipeHandle = ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
            DPRINT1("Configuration Handle %x\n", DeviceExtension->ConfigurationHandle);

            ExFreePool(ConfigUrb);

            Status = DeviceExtension->HubInterface.Initialize20Hub(DeviceExtension->RootHubPdo, DeviceExtension->RootHubUsbDevice, 1);
            DPRINT1("Status %x\n", Status);

            {
                int PortLoop;
                USHORT PortStatusAndChange[2];

                for (PortLoop=0; PortLoop< DeviceExtension->UsbExtHubInfo.NumberOfPorts; PortLoop++)
                {
                    DPRINT1("Port %x\n", PortLoop);
                    UsbBuildVendorRequest(Urb,
                                          URB_FUNCTION_CLASS_OTHER,
                                          sizeof(Urb->UrbControlVendorClassRequest),
                                          USBD_TRANSFER_DIRECTION_IN,
                                          0,
                                          USB_REQUEST_SET_FEATURE,
                                          PORT_POWER,
                                          1,
                                          0,
                                          0,
                                          0,
                                          0);

                    Urb->UrbOSFeatureDescriptorRequest.MS_FeatureDescriptorIndex = PortLoop + 1;
                    Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);

                    DPRINT1("Status %x\n", Status);

                    UsbBuildVendorRequest(Urb,
                                          URB_FUNCTION_CLASS_OTHER,
                                          sizeof(Urb->UrbControlVendorClassRequest),
                                          USBD_TRANSFER_DIRECTION_OUT,
                                          0,
                                          USB_REQUEST_GET_STATUS,
                                          0,
                                          PortLoop + 1,
                                          &PortStatusAndChange,
                                          0,
                                        sizeof(PortStatusAndChange),
                                        0);
                    Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);

                    DPRINT1("Status %x\n", Status);
                    DPRINT1("PortStatus = %x\n", PortStatusAndChange[0]);
                    DPRINT1("PortChange = %x\n", PortStatusAndChange[1]);
                }
            }

            ExFreePool(Urb);
            break;
        }

        case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */
        {
            switch (IrpSp->Parameters.QueryDeviceRelations.Type)
            {
                case BusRelations:
                {
                    PDEVICE_RELATIONS DeviceRelations = NULL;
                    DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");

                    Status = UsbhubFdoQueryBusRelations(DeviceObject, &DeviceRelations);

                    Information = (ULONG_PTR)DeviceRelations;
                    break;
                }
                case RemovalRelations:
                {
                    DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
                    return ForwardIrpAndForget(DeviceObject, Irp);
                }
                default:
                    DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
                        IrpSp->Parameters.QueryDeviceRelations.Type);
                    return ForwardIrpAndForget(DeviceObject, Irp);
            }
            break;
        }
        case IRP_MN_QUERY_BUS_INFORMATION:
        {
            DPRINT1("IRP_MN_QUERY_BUS_INFORMATION\n");
            break;
        }
        case IRP_MN_QUERY_ID:
        {
            DPRINT1("IRP_MN_QUERY_ID\n");
            break;
        }
        case IRP_MN_QUERY_CAPABILITIES:
        {
            DPRINT1("IRP_MN_QUERY_CAPABILITIES\n");
            break;
        }
        default:
        {
            DPRINT1("Usbhub: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
            return ForwardIrpAndForget(DeviceObject, Irp);
        }
    }
    Irp->IoStatus.Information = Information;
    Irp->IoStatus.Status = Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return Status;
}
Exemplo n.º 12
0
NTSTATUS
NTAPI
USBCCGP_ScanConfigurationDescriptor(
    IN OUT PFDO_DEVICE_EXTENSION FDODeviceExtension,
    IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
{
    PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
    ULONG InterfaceIndex = 0;
    ULONG DescriptorCount;

    //
    // sanity checks
    //
    ASSERT(ConfigurationDescriptor);
    ASSERT(ConfigurationDescriptor->bNumInterfaces);

    //
    // count all interface descriptors
    //
    DescriptorCount = ConfigurationDescriptor->bNumInterfaces;

    //
    // allocate array holding the interface descriptors
    //
    FDODeviceExtension->InterfaceList = AllocateItem(NonPagedPool, sizeof(USBD_INTERFACE_LIST_ENTRY) * (DescriptorCount + 1));
    if (!FDODeviceExtension->InterfaceList)
    {
        //
        // no memory
        //
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    do
    {
        //
        // parse configuration descriptor
        //
        InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, InterfaceIndex, -1, -1, -1, -1);
        if (InterfaceDescriptor)
        {
            //
            // store in interface list
            //
            FDODeviceExtension->InterfaceList[FDODeviceExtension->InterfaceListCount].InterfaceDescriptor = InterfaceDescriptor;
            FDODeviceExtension->InterfaceListCount++;
        }
        else
        {
            DumpConfigurationDescriptor(ConfigurationDescriptor);
            DumpFullConfigurationDescriptor(FDODeviceExtension, ConfigurationDescriptor);

            //
            // see issue
            // CORE-6574 Test 3 (USB Web Cam)
            //
            if (FDODeviceExtension->DeviceDescriptor && FDODeviceExtension->DeviceDescriptor->idVendor == 0x0458 && FDODeviceExtension->DeviceDescriptor->idProduct == 0x705f)
                ASSERT(FALSE);
        }

        //
        // move to next interface
        //
        InterfaceIndex++;

    }while(InterfaceIndex < DescriptorCount);

    //
    // sanity check
    //
    ASSERT(FDODeviceExtension->InterfaceListCount);

    //
    // done
    //
    return STATUS_SUCCESS;
}
Exemplo n.º 13
0
NTSTATUS
IsoUsb_SelectInterface(
    IN PDEVICE_OBJECT DeviceObject,
    IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
    )
/*++

Routine Description:

    Initializes an 82930 with (possibly) multiple interfaces;
	This minidriver only supports one interface (with multiple endpoints).

Arguments:

    DeviceObject - pointer to the device object for this instance of the 82930
                    device.

    ConfigurationDescriptor - pointer to the USB configuration
                    descriptor containing the interface and endpoint
                    descriptors.

Return Value:

    NT status code

--*/
{
    PDEVICE_EXTENSION deviceExtension;
    NTSTATUS ntStatus;
    PURB urb = NULL;
    ULONG i;
    PUSB_INTERFACE_DESCRIPTOR interfaceDescriptor = NULL;
	PUSBD_INTERFACE_INFORMATION Interface = NULL;
    USHORT siz;
    PUCHAR pInf;

    ISOUSB_KdPrint( DBGLVL_MEDIUM,("enter IsoUsb_SelectInterface\n"));

    deviceExtension = DeviceObject->DeviceExtension;


    ISOUSB_KdPrint( DBGLVL_HIGH,("IsoUsb_SelectInterface() called with NULL Interface\n"));
    //
    // IsoUsb driver only supports one interface, we must parse
    // the configuration descriptor for the interface 
    // and remember the pipes.
    //

    urb = USBD_CreateConfigurationRequest(ConfigurationDescriptor, &siz);

    if (urb) {

		//
		// USBD_ParseConfigurationDescriptorEx searches a given configuration
		// descriptor and returns a pointer to an interface that matches the 
		//  given search criteria. We only support one interface on this device
		//
        interfaceDescriptor =
            USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor,
								  ConfigurationDescriptor, //search from start of config  descriptro
								  -1,	// interface number not a criteria; we only support one interface
								  -1,   // not interested in alternate setting here either
								  -1,   // interface class not a criteria
								  -1,   // interface subclass not a criteria
								  -1    // interface protocol not a criteria
								  );

		if ( !interfaceDescriptor ) {

			ISOUSB_KdPrint( DBGLVL_HIGH,("IsoUsb_SelectInterface() ParseConfigurationDescriptorEx() failed\n  returning STATUS_INSUFFICIENT_RESOURCES\n"));
			ExFreePool(urb);
			return STATUS_INSUFFICIENT_RESOURCES;
		}

        Interface = &urb->UrbSelectConfiguration.Interface;


        // allocate space for an array of pipe information structs;
        //  in this basic sample, just used to track if opened/closed
        deviceExtension->PipeInfo = ExAllocatePool(
            NonPagedPool, 
            Interface->NumberOfPipes * sizeof ( ISOUSB_PIPEINFO ) );
    
        if ( !deviceExtension->PipeInfo ) {
		    return STATUS_INSUFFICIENT_RESOURCES;
        }

        RtlZeroMemory(deviceExtension->PipeInfo,
            Interface->NumberOfPipes * sizeof ( ISOUSB_PIPEINFO ) );

        pInf = (PUCHAR ) deviceExtension->PipeInfo;

        for (i=0; i< Interface->NumberOfPipes; i++) {
            //
            // Perform any pipe initialization here;
			// We set the max transfer size and any Pipe flags we use; USBD sets the rest
			// of the Interface struct members
            //
            Interface->Pipes[i].MaximumTransferSize = deviceExtension->MaximumTransferSize;
            ( (PISOUSB_PIPEINFO) pInf)->fPipeOpened = FALSE;
            pInf += sizeof ( ISOUSB_PIPEINFO );
        }

        UsbBuildSelectConfigurationRequest(urb,
                                          (USHORT) siz,
                                          ConfigurationDescriptor);


        ntStatus = IsoUsb_CallUSBD(DeviceObject, urb);

        deviceExtension->UsbConfigurationHandle =
            urb->UrbSelectConfiguration.ConfigurationHandle;

    } else {
        ISOUSB_KdPrint( DBGLVL_HIGH,("IsoUsb_SelectInterface() USBD_CreateConfigurationRequest() failed\n  returning STATUS_INSUFFICIENT_RESOURCES\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }


    if (NT_SUCCESS(ntStatus)) {

        //
        // Save the configuration handle for this device
        //

        deviceExtension->UsbConfigurationHandle =
            urb->UrbSelectConfiguration.ConfigurationHandle;

        deviceExtension->UsbInterface = ExAllocatePool(NonPagedPool,
                                                    Interface->Length);

        if (deviceExtension->UsbInterface) {
            ULONG j;

            //
            // save a copy of the interface information returned
            //
            RtlCopyMemory(deviceExtension->UsbInterface, Interface, Interface->Length);

            //
            // Dump the interface to the debugger
            //
            ISOUSB_KdPrint( DBGLVL_MEDIUM,("---------\n"));
            ISOUSB_KdPrint( DBGLVL_MEDIUM,("NumberOfPipes 0x%x\n", deviceExtension->UsbInterface->NumberOfPipes));
            ISOUSB_KdPrint( DBGLVL_MEDIUM,("Length 0x%x\n", deviceExtension->UsbInterface->Length));
            ISOUSB_KdPrint( DBGLVL_MEDIUM,("Alt Setting 0x%x\n", deviceExtension->UsbInterface->AlternateSetting));
            ISOUSB_KdPrint( DBGLVL_MEDIUM,("Interface Number 0x%x\n", deviceExtension->UsbInterface->InterfaceNumber));
            ISOUSB_KdPrint( DBGLVL_MEDIUM,("Class, subclass, protocol 0x%x 0x%x 0x%x\n",
                deviceExtension->UsbInterface->Class,
                deviceExtension->UsbInterface->SubClass,
                deviceExtension->UsbInterface->Protocol));

            // Dump the pipe info

            for (j=0; j<Interface->NumberOfPipes; j++) {
                PUSBD_PIPE_INFORMATION pipeInformation;

                pipeInformation = &deviceExtension->UsbInterface->Pipes[j];

                ISOUSB_KdPrint( DBGLVL_MEDIUM,("---------\n"));
                ISOUSB_KdPrint( DBGLVL_MEDIUM,("PipeType 0x%x\n", pipeInformation->PipeType));
                ISOUSB_KdPrint( DBGLVL_MEDIUM,("EndpointAddress 0x%x\n", pipeInformation->EndpointAddress));
                ISOUSB_KdPrint( DBGLVL_MEDIUM,("MaxPacketSize 0x%x\n", pipeInformation->MaximumPacketSize));
                ISOUSB_KdPrint( DBGLVL_MEDIUM,("Interval 0x%x\n", pipeInformation->Interval));
                ISOUSB_KdPrint( DBGLVL_MEDIUM,("Handle 0x%x\n", pipeInformation->PipeHandle));
                ISOUSB_KdPrint( DBGLVL_MEDIUM,("MaximumTransferSize 0x%x\n", pipeInformation->MaximumTransferSize));
            }

            ISOUSB_KdPrint( DBGLVL_MEDIUM,("---------\n"));
        }
    }

    if (urb) {
		// don't call the ISOUSB_ExFreePool since the buffer was 
		//  alloced by USBD_CreateConfigurationRequest, not ISOUSB_ExAllocatePool()
        ExFreePool(urb);
    }
    ISOUSB_KdPrint( DBGLVL_HIGH,("exit IsoUsb_SelectInterface (%x)\n", ntStatus));

    return ntStatus; 
}