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

📄 usbfx2lk_usb.cpp

📁 VisualC++写的一个USB的驱动程序。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//  IRQL:
//
//      IRQL == PASSIVE_LEVEL
//
//  CONTEXT:
//
//      Arbitrary Context
//
//  NOTES:
//
//      The OSR FX2 Learning Kit device running the OSR standard firmware only
//      offers one USB Interface.
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS SelectUsbInterfaces(PUSBFX2LK_EXT DevExt,
                             PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
{
    LONG                        numberOfInterfaces = ConfigurationDescriptor->bNumInterfaces;
    LONG                        interfaceNumber = 0;
    LONG                        interfaceindex = 0;
    ULONG                       i;
    PURB                        urb = NULL;
    NTSTATUS                    status;
    PUSB_INTERFACE_DESCRIPTOR   interfaceDescriptor = NULL;
    PUSBD_INTERFACE_LIST_ENTRY  interfaceList = NULL; 
    PUSBD_INTERFACE_LIST_ENTRY  tmp = NULL;
    PUSBD_INTERFACE_INFORMATION Interface = NULL;

    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("SelectUsbInterfaces: Enter\n"));

    //
    //  Allocate memory for the devices supported interfaces.
    //
    interfaceList = (PUSBD_INTERFACE_LIST_ENTRY) ExAllocatePoolWithTag(NonPagedPool, 
                        sizeof(USBD_INTERFACE_LIST_ENTRY) * (numberOfInterfaces + 1),'eliU');

    //
    // Confirm memory was allocated.
    //
    if(!interfaceList) {

        OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
            ("SelectUsbInterfaces: Failed to allocate mem for interfaceList\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    tmp = interfaceList;


    //
    // Parse the received USB interfaces selecting one that matches our input criteria.
    // Fortunately, we are not fussy and will take any interface found, which for our 
    // device is the only one we return.
    // 
    while(interfaceNumber < numberOfInterfaces) {

        //
        // A driver would call USBD_ParseConfigurationDescriptorEx in order
        // to select a interface that meets the input criteria of driver.
        // This would work well, if the a device had different interfaces.  
        // Unfortunately, our device only has one interface, so this will 
        // select it.
        //
        interfaceDescriptor = USBD_ParseConfigurationDescriptorEx(
                                            ConfigurationDescriptor, 
                                            ConfigurationDescriptor,
                                            interfaceindex,
                                            0, -1, -1, -1);

        if(interfaceDescriptor) {

            //
            // An interface met our criteria, save the information
            // in our interface list.
            //
            interfaceList->InterfaceDescriptor = interfaceDescriptor;
            interfaceList->Interface = NULL;
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("--------- Interface %d\n",interfaceNumber));
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("\tbLength = %d\n",interfaceList->InterfaceDescriptor->bLength));
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("\tbDescriptorType = %d\n",interfaceList->InterfaceDescriptor->bDescriptorType));
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("\tbInterfaceNumber = %d\n",interfaceList->InterfaceDescriptor->bInterfaceNumber));
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("\tbAlternateSetting = %d\n",interfaceList->InterfaceDescriptor->bAlternateSetting));
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("\tbNumEndpoints = %d\n",interfaceList->InterfaceDescriptor->bNumEndpoints));
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("\tbInterfaceClass = %d\n",interfaceList->InterfaceDescriptor->bInterfaceClass));
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("\tbInterfaceSubClass = %d\n",interfaceList->InterfaceDescriptor->bInterfaceSubClass));
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("\tbInterfaceProtocol = %d\n",interfaceList->InterfaceDescriptor->bInterfaceProtocol));
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("\tiInterface = %d\n\n",interfaceList->InterfaceDescriptor->iInterface));
            interfaceList++;
            interfaceNumber++;

        }

        interfaceindex++;
    }

    //
    // Format a URB that will be used to select the input configuration
    // that will be used to interface to the device.
    //
    interfaceList->InterfaceDescriptor = NULL;
    interfaceList->Interface = NULL;

    urb = USBD_CreateConfigurationRequestEx(ConfigurationDescriptor, tmp);

    //
    // Make sure that a URB was allocated.
    //
    if(urb) {

        //
        // Set our pipe information into the interface pipes list.
        // This tells our device our we will use the pipe.
        //
        Interface = &urb->UrbSelectConfiguration.Interface;

        for(i=0; i<Interface->NumberOfPipes; i++) {

            //
            // Set the transfer size and any pipe flags we use
            // USBD sets the rest of the Interface struct members
            //

            Interface->Pipes[i].MaximumTransferSize = 
                                USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
        }

        //
        // Submit the urb to the device.
        //
        status = SubmitUrb(DevExt, urb);

        if(NT_SUCCESS(status)) {

            //
            // save a copy of interface information in the device extension.
            //
            DevExt->UsbInterface = (PUSBD_INTERFACE_INFORMATION) ExAllocatePoolWithTag(NonPagedPool,
                                                                        Interface->Length,'eliU');

            if(DevExt->UsbInterface) {
                
                RtlCopyMemory(DevExt->UsbInterface,
                              Interface,
                              Interface->Length);
            } else {

                status = STATUS_INSUFFICIENT_RESOURCES;
                OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,("SelectUsbInterfaces: memory alloc for UsbInterface failed\n"));
                goto SelectUsbInterfacesExit;
            }

            //
            // Dump the interface to the debugger
            //

            Interface = &urb->UrbSelectConfiguration.Interface;

            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("---------\n"));
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("NumberOfPipes 0x%x\n", 
                                 Interface->NumberOfPipes));
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("Length 0x%x\n", 
                                 Interface->Length));
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("Alt Setting 0x%x\n", 
                                 Interface->AlternateSetting));
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("Interface Number 0x%x\n", 
                                 Interface->InterfaceNumber));
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("Class, subclass, protocol 0x%x 0x%x 0x%x\n",
                                 Interface->Class,
                                 Interface->SubClass,
                                 Interface->Protocol));

            //
            // Initialize the PipeContext
            // Dump the pipe info
            //
            if(Interface->NumberOfPipes) {
                DevExt->PipeContext = (PUSBFX2LK_PIPE_CONTEXT) ExAllocatePoolWithTag(NonPagedPool,
                                                Interface->NumberOfPipes *
                                                sizeof(USBFX2LK_PIPE_CONTEXT),'xtcP');

                if(DevExt->PipeContext) {
                
                    for(i=0; i<Interface->NumberOfPipes; i++) {

                        RtlCopyMemory(&DevExt->PipeContext[i].PipeInformation,
                                      &Interface->Pipes[i],sizeof(USBD_PIPE_INFORMATION));

                        //
                        // Setup our convenience pointer
                        //
                        if (Interface->Pipes[i].PipeType == UsbdPipeTypeBulk) {

                            if (USBD_PIPE_DIRECTION_IN(&Interface->Pipes[i])) {

                                //
                                // This is the bulk IN pipe. Make sure we only
                                //  have one
                                //
                                ASSERT(DevExt->BulkInPipe == NULL);

                                DevExt->BulkInPipe = &DevExt->PipeContext[i];

                            } else {

                                //
                                // This is the bulk OUT pipe. Make sure we only
                                //  have one
                                //
                                ASSERT(DevExt->BulkOutPipe == NULL);

                                DevExt->BulkOutPipe = &DevExt->PipeContext[i];

                            }

                        } else {

                            //
                            // Our device has two bulk pipes and one iso pipe,
                            //  we shouldn't get any other pipe besides iso here
                            // 
                            ASSERT(Interface->Pipes[i].PipeType == UsbdPipeTypeInterrupt);

                            //
                            // And we only have one
                            //
                            ASSERT(DevExt->InterruptPipe == NULL);

                            DevExt->InterruptPipe = &DevExt->PipeContext[i];

                        }

                    }

                    DevExt->NumberOfPipes = Interface->NumberOfPipes;

                } else {
                    
                    status = STATUS_INSUFFICIENT_RESOURCES;
                    OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
                        ("SelectUsbInterfaces: memory alloc for UsbInterface failed\n"));
                    goto SelectUsbInterfacesExit;
                }
            }

            for(i=0; i<Interface->NumberOfPipes; i++) {

                OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("---------\n"));
                OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("PipeType 0x%x\n", 
                                     Interface->Pipes[i].PipeType));
                OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("EndpointAddress 0x%x\n", 
                                     Interface->Pipes[i].EndpointAddress));
                OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("MaxPacketSize 0x%x\n", 
                                    Interface->Pipes[i].MaximumPacketSize));
                OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("Interval 0x%x\n", 
                                     Interface->Pipes[i].Interval));
                OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("Handle %p\n", 
                                     Interface->Pipes[i].PipeHandle));
                OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("MaximumTransferSize 0x%x\n", 
                                    Interface->Pipes[i].MaximumTransferSize));
            }

            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("---------\n"));
        } else {
            OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,("Failed to select an interface\n"));
        }
    } else {
        OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
            ("SelectUsbInterfaces: USBD_CreateConfigurationRequestEx failed\n"));
        status = STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // Clean up after ourselves and exit.
    //
SelectUsbInterfacesExit:

    if(tmp) {
        ExFreePool(tmp);
    }

    if(urb) {
        ExFreePool(urb);
    }

    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("SelectUsbInterfaces: Exit\n"));

    return status;
}

///////////////////////////////////////////////////////////////////////////////
//
// DeconfigureUsbDevice
//
//  This routine is called to release the Usb Device and deconfigure the
//  descriptors.
//
//
//  INPUTS:
//
//      DevExt  -  Address of the Devices Device Extension.
//
//  OUTPUTS:
//
//      None
//
//  RETURNS:
//
//      None
//
//  IRQL:
//
//      IRQL == PASSIVE_LEVEL
//
//  CONTEXT:
//
//      Arbitrary Context
//
//  NOTES:
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS DeconfigureUsbDevice(PUSBFX2LK_EXT DevExt)
{
    PURB     urb;
    ULONG    size = sizeof(struct _URB_SELECT_CONFIGURATION);;
    NTSTATUS status;
    
    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("DeconfigureUsbDevice: Enter\n"));

    urb = (PURB) ExAllocatePoolWithTag(NonPagedPool, size,'csuO');

    if(urb) {

        UsbBuildSelectConfigurationRequest(urb, (USHORT)size, NULL);

        status = SubmitUrb(DevExt,urb);

        if(!NT_SUCCESS(status)) {

            OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
                ("DeconfigureUsbDevice: Failed to deconfigure device %08.8x %s\n",
                status,OsrNtStatusToString(status)));
        }

        ExFreePool(urb);

    } else {

        OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,("DeconfigureUsbDevice: Failed to allocate urb\n"));
        status = STATUS_INSUFFICIENT_RESOURCES;
    }

    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("DeconfigureUsbDevice: Exit\n"));

    return status;
}

///////////////////////////////////////////////////////////////////////////////
//
// DetermineDeviceSpeed
//
//  This routine is called by ConfigureUsbDevice to determine if the device
//  is running at low or high speed.
//
//
//  INPUTS:
//
//      DevExt  -  Address of the Devices Device Extension.
//
//  OUTPUTS:
//
//      When finished, the RunningAtHighSpeed member of the 
//       device extension is set to either TRUE or FALSE
//
//  RETURNS:
//
//      None
//
//  IRQL:
//
//      IRQL == PASSIVE_LEVEL
//
//  CONTEXT:
//
//      Arbitrary Context
//
//  NOTES:
//   We need to determine if the device is running at high speed by querying 
//    for the USB_BUS_INTERFACE_USBDI_V1 interface.  One slight problem here, 
//    USB 2.0 support wasn't added to Windows 2000 until SP4 and so the latest 
//    DDK is a bit behind. If you were to believe the DDK documentation and 
//    headers, you would think that this interface is not supported at ALL in 
//    Windows 2000.  However, this exchange in 
//    microsoft.public.development.device.drivers in July 2004 says otherwise:
//  
////////////////////////////////////////////////////////////////////////////
//  
//    Subject: Availability of USB_BUS_INTERFACE_USBDI_V1 in Windows 2000 Sp4 ?
//    
//    Hello,
//    
//    Since Windows 2000 Service PAck4 has support for USB 2.0 Enhanced USB
//    Host Controller , I was wondering if it has support for
//    USB_BUS_INTERFACE_USBDI_V1 structure , since i want to use its member
//    ( PUSB_BUSIFFN_IS_DEVICE_HIGH_SPEED IsDeviceHighSpeed ) .
//    MSDN says that this is supported only on WinXP onwards but i am
//    thinking why should this not be available when Enhanced USB Host
//    Controller driver is available on W2k sp4
//    
//    could anybody please clarify this?
//    
//    thanks in advance
//    Taha
//    
////////////////////////////////////////////////////////////////////////////
//    	
//    Eliyas Yakub [MSFT] 	  Jul 12, 10:41 am     show options
//    From: "Eliyas Yakub [MSFT]" <eliy...@online.microsoft.com>
//    Date: Mon, 12 Jul 2004 10:41:52 -0700
//    
//    Looking at the code USBPORT code, I can definitely say it's available. I
//    will bring this to our doc team's attention. Thanks.
//    
//    -Eliyas
//  
////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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