⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cusbintf.cpp

📁 完整的基于Conxant平台的USB电视棒的WIN驱动程序。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    for(UCHAR i = 0; i < config_count; i++)
    {
        //Set the default configuration size. If it is too small, we will have to call this twice.
        DWORD dwConfigSize = sizeof(USB_CONFIGURATION_DESCRIPTOR) + 256;	
        USB_CONFIGURATION_DESCRIPTOR* pConfig;

        BOOLEAN query_config = TRUE;  //This flag is TRUE when we should send a query.

        while(query_config) 
        {
            if(dwConfigSize % 8)
            {                
                dwConfigSize = ((dwConfigSize /8) + 1 ) * 8;
                DbgLogInfo(("CUsbInterface::UsbConfigGetDescriptor : adjusting size to %d\n",dwConfigSize)); 
            }

            pConfig = (USB_CONFIGURATION_DESCRIPTOR *) new BYTE[dwConfigSize];

            if(!pConfig)
            {
                status = STATUS_INSUFFICIENT_RESOURCES;
                break;
            }

            RtlZeroMemory(pConfig, dwConfigSize);
            
            //Set up the URB to get the configuration from the device
            UsbBuildGetDescriptorRequest(
                p_urb,
                sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
                USB_CONFIGURATION_DESCRIPTOR_TYPE,
                i, //Configuration number
                0,
                pConfig,
                0,
                dwConfigSize,
                0);
            
            //Send the URB to the USB bus driver.
            status = UsbCall_GSPN(p_urb);

            //Default to not having to do the query again.
            query_config = FALSE;
            if(NT_SUCCESS(status)) 
            {
                //Our buffer was too small.  Reallocate it with the size provided, and
                // send the request again.
                if ((p_urb->UrbControlDescriptorRequest.TransferBufferLength > 0) && 
                    (pConfig->wTotalLength > dwConfigSize))
                {
                    //Save the size
                    dwConfigSize = pConfig->wTotalLength;
                    delete [] pConfig;
                    pConfig = NULL;
                    
                    //Query for the configuration again.
                    query_config = TRUE;
                }
            } 
            else 
            {
                delete [] pConfig;
                pConfig = NULL;
            }

        }

        if (pConfig) 
        {
            //We were successful.  Save the configuration descriptor
            _p_configs[i] = pConfig;
            status = STATUS_SUCCESS;
            DumpUsbConfigDescriptor(pConfig);
        }
    }

    delete p_urb;

    return (status);
}

/////////////////////////////////////////////////////////////////////////////////////////
//CUsbInterface::assignInterface
//
// This is a helper function that save's interface information
//
VOID CUsbInterface::assignInterface(USBD_INTERFACE_INFORMATION* p_interface, DWORD index)
{
    DWORD interface_size = p_interface->Length;
    
    _p_interfaces[index] = (USBD_INTERFACE_INFORMATION *) new BYTE[interface_size];
    
    if(_p_interfaces[index])
    {
        RtlCopyMemory(_p_interfaces[index], p_interface, interface_size);
        DumpUsbInterfaceInfo(_p_interfaces[index]);
    }
}


/////////////////////////////////////////////////////////////////////////////////////////
//CUsbInterface::UsbConfigSelect
//
// Select a USB configuration
//
NTSTATUS CUsbInterface::UsbConfigSelect(ULONG configuration_number)
{
    NTSTATUS    status = STATUS_UNSUCCESSFUL;
    USBD_INTERFACE_INFORMATION* p_interface;
    POLARIS_REV_ID rev_id = (POLARIS_REV_ID)getRevID();

    //Make sure the configuration number is valid
    if (configuration_number >= ((ULONG)_device_descriptor.bNumConfigurations & 0xFF))
    {
        DbgLogError(("UsbConfigSelect: invalid configuration number: %x\n", configuration_number));
        configuration_number = 0;
    }

    //Make sure we have the configuration descriptor.
    if(!_p_configs || !_p_configs[configuration_number])
    {
        return STATUS_UNSUCCESSFUL;
    }

    USB_CONFIGURATION_DESCRIPTOR* p_config = _p_configs[configuration_number];

    //Allocate the interface  list
    PUSBD_INTERFACE_LIST_ENTRY interface_list = new USBD_INTERFACE_LIST_ENTRY[p_config->bNumInterfaces + 1];
    if (!interface_list)
    {
        DbgLogError(("CUsbInterface::UsbConfigSelect() can not allocate interfaceList\n"));
        delete [] _p_interfaces;
        _p_interfaces = NULL;
        return (status);
    }

    RtlZeroMemory(interface_list, sizeof(USBD_INTERFACE_LIST_ENTRY) * (p_config->bNumInterfaces + 1));

    //Get a pointer to each interface descriptor from the configuration descriptor.
    UCHAR i;
    if(rev_id == POLARIS_REVID_T0)
    {
        DbgLog(("the revision is T0\n"));
        for (i = 0; i < p_config->bNumInterfaces; i++)
        {
            //the interface number is change according different scenario, so Interface =-1, Alternate = -1 (not Specifies)
            interface_list[i].InterfaceDescriptor =
                USBD_ParseConfigurationDescriptorEx(
                p_config,
                p_config,
                -1,    // Interface
                -1,    // Alternate Setting
                -1,    // Class - don't care
                -1,    // SubClass - don't care
                -1);   // Protocol - don't care
            
        }
    }
    else if(rev_id >=POLARIS_REVID_A0)        
    {
        DbgLog(("the revision is A0\n"));
        for (i = 0; i < p_config->bNumInterfaces; i++)
        {
            
            interface_list[i].InterfaceDescriptor =
                USBD_ParseConfigurationDescriptorEx(
                p_config,
                p_config,
                (i+1),   // Interface
                0,       // Alternate Setting
                -1,      // Class - don't care
                -1,      // SubClass - don't care
                -1);     // Protocol - don't care
        }
    }
    else
    {
        DbgLogError(("Invalid revision ID\n"));
        delete [] interface_list;
        return STATUS_UNSUCCESSFUL;
    }
    //Set the last interface entry iin the list to NULL
    interface_list[i].InterfaceDescriptor = NULL;
    interface_list[i].Interface = NULL;

    //Create a URB to select the requested configuration
    PURB p_urb = USBD_CreateConfigurationRequestEx(p_config, &interface_list[0]);
    if(!p_urb)
    {
        delete [] interface_list;
        return STATUS_INSUFFICIENT_RESOURCES;
    }
  
    //Send the URB to select the configuration
    status = UsbCall_GSPN(p_urb);
        
    if (NT_SUCCESS(status) && USBD_SUCCESS(p_urb->UrbHeader.Status))
    {
        // free previous allocated interfaces
        freeInterfaces();
        
        //Allocate new interfaces
        _p_interfaces = new PUSBD_INTERFACE_INFORMATION[p_config->bNumInterfaces];
        if (!_p_interfaces)
        {
            ExFreePool(p_urb);
            delete [] interface_list;
            DbgLogError(("CUsbInterface::UsbConfigSelect() can not allocate _p_interfaces\n"));
            return STATUS_INSUFFICIENT_RESOURCES;
        }
        
        RtlZeroMemory(_p_interfaces, sizeof(PUSBD_INTERFACE_INFORMATION) * p_config->bNumInterfaces);
        
        //Save the current configuration index and handle
        _config_index = configuration_number;
        _config_handle = p_urb->UrbSelectConfiguration.ConfigurationHandle;
        
        //For each interface, copy the interface information into our member variable.
        ULONG interface_offset = 0;
        for (i = 0; i < p_config->bNumInterfaces; i++)
        {
            p_interface = (PUSBD_INTERFACE_INFORMATION)
                ((PBYTE)&p_urb->UrbSelectConfiguration.Interface + interface_offset);
            interface_offset += p_interface->Length;
            
            assignInterface(p_interface, i);
        }
    }
    
    ExFreePool(p_urb);
    
    delete [] interface_list;
    DbgLog(("Select Configuration successful\n"));
    
    return (status);
}



/////////////////////////////////////////////////////////////////////////////////////////
//UsbInterfaceSelect
//
// Select a USB interface and alternate setting
//
NTSTATUS CUsbInterface::UsbInterfaceSelect(UCHAR interface_number, UCHAR alternate_setting)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;

    KeWaitForSingleObject(&_mutex, Executive, KernelMode, FALSE, NULL);
    UCHAR interface_number_rev=0;  

    DWORD revID = getRevID();
        
    if(revID==POLARIS_REVID_T0)
    {
        interface_number_rev = interface_number;
    }
    else if(revID >=POLARIS_REVID_A0)        
    {
        interface_number_rev = interface_number+1;
    }
    else
    {
        DbgLogError(("Invaild revision ID\n"));
        KeReleaseMutex(&_mutex, FALSE);
        return status;
    }
    
        
    if (isInterfaceValid(interface_number)) 
    {
        //Check that alternate setting 1 exists for this interface.
        PUSB_INTERFACE_DESCRIPTOR p_interface = 
            USBD_ParseConfigurationDescriptorEx(
            _p_configs[_config_index],
            _p_configs[_config_index],
            interface_number_rev,    // Interface
            1,                       // Alternate Setting 1
            -1,                      // Class - don't care
            -1,                      // SubClass - don't care
            -1);                     // Protocol - don't care

        if (!p_interface)
        {
            KeReleaseMutex(&_mutex, FALSE);

            //There is only one setting.  Return success if we are selecting alternate
            // setting 0 since we are already on it.  If we are trying to select
            // some other alternate setting, fail.
            return ((0 == alternate_setting) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
       }

        //Get the interface descriptor for the selected interface and alternate setting.
        p_interface = 
            USBD_ParseConfigurationDescriptorEx(_p_configs[_config_index],
            _p_configs[_config_index],
            interface_number_rev,    // Interface
            alternate_setting,       // Alternate Setting
            -1,                      // Class - don't care
            -1,                      // SubClass - don't care
            -1);                     // Protocol - don't care

        if (!p_interface)
        {
            //Invalid interface and/or alternate setting
            DbgLogError(("CUsbInterface::UsbInterfaceSelect() pInterfaceDescriptor is NULL\n"));
            KeReleaseMutex(&_mutex, FALSE);
            return STATUS_UNSUCCESSFUL;
        }

        UCHAR pipe_count = p_interface->bNumEndpoints;
        ULONG urb_size = GET_SELECT_INTERFACE_REQUEST_SIZE(pipe_count);

        PURB p_urb = (PURB) new BYTE[urb_size];

        if(!p_urb)
        {
            KeReleaseMutex(&_mutex, FALSE);
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        RtlZeroMemory(p_urb, urb_size);
        UsbBuildSelectInterfaceRequest(
            p_urb,
            (USHORT)urb_size,
            _config_handle,
            interface_number_rev,
            alternate_setting);

        PUSBD_INTERFACE_INFORMATION p_interface_info = 
            (PUSBD_INTERFACE_INFORMATION)&p_urb->UrbSelectInterface.Interface;
        p_interface_info->Length = GET_USBD_INTERFACE_SIZE(pipe_count);

        //For isochronous pipes, set the maximum transfer size to 0x20000
        for(UCHAR i = 0; i < pipe_count; i++)
        {
            if(p_interface_info->Pipes[i].PipeType == UsbdPipeTypeIsochronous)
            {
                p_interface_info->Pipes[i].MaximumTransferSize = 0x20000;
            }
        }

        //Send the URB to the USB bus driver
        status = UsbCall_GSPN(p_urb);
        
        //If it was successful, save the interface information
        if (NT_SUCCESS(status) && USBD_SUCCESS(p_urb->UrbHeader.Status))
        {
            // free previous allocated interfaces
            if (_p_interfaces[interface_number])
            {
                delete [] (BYTE *)_p_interfaces[interface_number];
                _p_interfaces[interface_number] = NULL;
            }

            //Get the interface information
            p_interface_info = 
                (PUSBD_INTERFACE_INFORMATION)&p_urb->UrbSelectInterface.Interface;
            
            assignInterface(p_interface_info, interface_number);
        }
        else
        {
            DbgLogError((
                "CUsbInterface::UsbInterfaceSelect() FAILED NT Status(0x%x) USB Status(0x%x)\n",
                status,
                p_urb->UrbHeader.Status));
            status = STATUS_UNSUCCESSFUL;
        }

        delete [] p_urb;
    }


    KeReleaseMutex(&_mutex, FALSE);

    return (status);
}



#ifndef USBD_STATUS_XACT_ERROR
#define USBD_STATUS_XACT_ERROR               ((USBD_STATUS)0xC0000011L)
#endif //USBD_STATUS_XACT_ERROR

#ifndef USBD_STATUS_BABBLE_DETECTED
#define USBD_STATUS_BABBLE_DETECTED          ((USBD_STATUS)0xC0000012L)
#endif //USBD_STATUS_BABBLE_DETECTED


#ifndef USBD_STATUS_ISO_NOT_ACCESSED_BY_HW
#define USBD_STATUS_ISO_NOT_ACCESSED_BY_HW   ((USBD_STATUS)0xC0020000L)   
#endif //USBD_STATUS_ISO_NOT_ACCESSED_BY_HW

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -