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

📄 usbfx2lk_usb.cpp

📁 VisualC++写的一个USB的驱动程序。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
///////////////////////////////////////////////////////////////////////////////
//
//    (C) Copyright 2005 OSR Open Systems Resources, Inc.
//    All Rights Reserved
//
//    This sofware is supplied for instructional purposes only.
//
//    OSR Open Systems Resources, Inc. (OSR) expressly disclaims any warranty
//    for this software.  THIS SOFTWARE IS PROVIDED  "AS IS" WITHOUT WARRANTY
//    OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION,
//    THE IMPLIED WARRANTIES OF MECHANTABILITY OR FITNESS FOR A PARTICULAR
//    PURPOSE.  THE ENTIRE RISK ARISING FROM THE USE OF THIS SOFTWARE REMAINS
//    WITH YOU.  OSR's entire liability and your exclusive remedy shall not
//    exceed the price paid for this material.  In no event shall OSR or its
//    suppliers be liable for any damages whatsoever (including, without
//    limitation, damages for loss of business profit, business interruption,
//    loss of business information, or any other pecuniary loss) arising out
//    of the use or inability to use this software, even if OSR has been
//    advised of the possibility of such damages.  Because some states/
//    jurisdictions do not allow the exclusion or limitation of liability for
//    consequential or incidental damages, the above limitation may not apply
//    to you.
//
//    OSR Open Systems Resources, Inc.
//    105 Route 101A Suite 19
//    Amherst, NH 03031  (603) 595-6500 FAX: (603) 595-6503
//    email bugs to: bugs@osr.com
//
//
//    MODULE:
//
//      USBFx2LK_PnP.cpp
//
//    ABSTRACT:
//
//      This file contains the routines that handle Plug and Play processing for the 
//      OSR USB FX2 Learning Kit Device
//
//    AUTHOR(S):
//
//      OSR Open Systems Resources, Inc.
// 
///////////////////////////////////////////////////////////////////////////////
#include "usbfx2lk.h"

#ifdef WPP_TRACING
//
// Include the necessary tmh file - this is 
//  just a matter of course if you're using WPP tracing.
//
extern "C" {
#include "usbfx2lk_usb.tmh"
}
#endif

//
// Forward Definitions
//
NTSTATUS SubmitUrb(PUSBFX2LK_EXT DevExt,PURB Urb);
NTSTATUS ConfigureUsbDevice(PUSBFX2LK_EXT DevExt);
NTSTATUS SelectUsbInterfaces(PUSBFX2LK_EXT DevExt,
                             PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor);
VOID DetermineDeviceSpeed(PUSBFX2LK_EXT DevExt);
#ifndef IoForwardIrpSynchronously
NTSTATUS DetermineDeviceSpeedCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
#endif //IoForwardIrpSynchronously
NTSTATUS AsynchronousUrbRequestCompletion(IN PDEVICE_OBJECT DeviceObject,
                                          IN PIRP Irp, IN PVOID Context);


///////////////////////////////////////////////////////////////////////////////
//
// ReadandSelectUsbDescriptors
//
//  This routine is called by OsrStartDevice to Read and Select the USB
//  descriptors that will be used to talk to the usb device.
//
//
//  INPUTS:
//
//      DevExt  -  Address of the Devices Device Extension.
//
//  OUTPUTS:
//
//      None
//
//  RETURNS:
//
//      None
//
//  IRQL:
//
//      IRQL == PASSIVE_LEVEL
//
//  CONTEXT:
//
//      Arbitrary Context
//
//  NOTES:
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS ReadandSelectUsbDescriptors(PUSBFX2LK_EXT DevExt)
{
    PURB                   urb = NULL;
    NTSTATUS               status;
    PUSB_DEVICE_DESCRIPTOR deviceDescriptor = NULL;
    
    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("ReadandSelectUsbDescriptors: Enter\n"));

    //
    // Allocate a URB.
    //
    urb = (PURB) ExAllocatePoolWithTag(NonPagedPool, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),'bruO');

    if(urb) {

        //
        // Allocate a USB_DEVICE_DESCRIPTOR to receive the device descriptor from our device.
        //
        deviceDescriptor = (PUSB_DEVICE_DESCRIPTOR) ExAllocatePoolWithTag(NonPagedPool, 
                                                        sizeof(USB_DEVICE_DESCRIPTOR), 'dduO');

        if(deviceDescriptor) {

            //
            // Format the Urb for the request to get the USB_DEVICE_DESCRIPTOR
            //
            UsbBuildGetDescriptorRequest(
                    urb, 
                    (USHORT) sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
                    USB_DEVICE_DESCRIPTOR_TYPE, 
                    0, 
                    0, 
                    deviceDescriptor, 
                    NULL, 
                    sizeof(USB_DEVICE_DESCRIPTOR), 
                    NULL);

            //
            // Submit the URB to the Device
            //
            status = SubmitUrb(DevExt,urb);

            //
            // If the request is successful, then configure the device
            //
            if(NT_SUCCESS(status)) {

                ASSERT(deviceDescriptor->bNumConfigurations);

                //
                // Save away the device descriptor
                //
                DevExt->UsbDeviceDescriptor = deviceDescriptor;

                status = ConfigureUsbDevice(DevExt);    

            } else {

                //
                // No descriptor info? Clean up.
                //
                ExFreePool(deviceDescriptor);

            }
              
            //
            // Free the URB 
            //
            ExFreePool(urb);

        } else {

            OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
                ("ReadandSelectUsbDescriptors: Failed to allocate memory for deviceDescriptor\n"));
            ExFreePool(urb);
            status = STATUS_INSUFFICIENT_RESOURCES;
        }
    } else {

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

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

    return status;
}

///////////////////////////////////////////////////////////////////////////////
//
// ConfigureUsbDevice
//
//  This routine is called by ReadandSelectUsbDescriptors to read the USB 
//  configuration descriptor that will be used to talk to the usb device.
//
//
//  INPUTS:
//
//      DevExt  -  Address of the Devices Device Extension.
//
//  OUTPUTS:
//
//      None
//
//  RETURNS:
//
//      None
//
//  IRQL:
//
//      IRQL == PASSIVE_LEVEL
//
//  CONTEXT:
//
//      Arbitrary Context
//
//  NOTES:
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS ConfigureUsbDevice(PUSBFX2LK_EXT DevExt)
{
    PURB                          urb = NULL;
    ULONG                         size = sizeof(USB_CONFIGURATION_DESCRIPTOR);
    NTSTATUS                      status;
    PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor = NULL;

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

    //
    // Allocate memory for a URB.
    //
    urb = (PURB) ExAllocatePoolWithTag(NonPagedPool,sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),'bruO');

    if(urb) {

        //
        // Allocate memory for the default sized configuration descriptor.
        //
        configurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR) ExAllocatePoolWithTag(NonPagedPool, size,'dcuO');

        if(configurationDescriptor) {

            //
            // Format the URB for the request.
            //
            UsbBuildGetDescriptorRequest(
                    urb, 
                    (USHORT) sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
                    USB_CONFIGURATION_DESCRIPTOR_TYPE, 
                    0, 
                    0, 
                    configurationDescriptor,
                    NULL, 
                    sizeof(USB_CONFIGURATION_DESCRIPTOR), 
                    NULL);

            //
            // Submit the request to the USB Device.
            //
            status = SubmitUrb(DevExt,urb);

            //
            // If the request is not successful, go and cleanup from the error.
            //
            if(!NT_SUCCESS(status)) {

                OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
                    ("ConfigureUsbDevice: UsbBuildGetDescriptorRequest failed\n"));
                goto ConfigureDevice_Exit;
            }
        } else {

            OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,("ConfigureUsbDevice: Failed to allocate mem for config Descriptor\n"));
            status = STATUS_INSUFFICIENT_RESOURCES;
            goto ConfigureDevice_Exit;
        }

        //
        // Okay, the request was successful.   Look at the returned length in the configuration
        // descriptor and use it to allocate a configuration descriptor that is big enough
        // to receive the full configuration from the device.
        //
        size = configurationDescriptor->wTotalLength;

        //
        // Free the existing configuration descriptor.
        //
        ExFreePool(configurationDescriptor);

        //
        // Allocate the correct sized descriptor.
        //
        configurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR) ExAllocatePoolWithTag(NonPagedPool, size,'dcuO');

        if(configurationDescriptor) {

            //
            // Format the urb to get the full configuration descriptor.
            //
            UsbBuildGetDescriptorRequest(
                    urb, 
                    (USHORT)sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
                    USB_CONFIGURATION_DESCRIPTOR_TYPE,
                    0, 
                    0, 
                    configurationDescriptor, 
                    NULL, 
                    size, 
                    NULL);

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

            //
            // If the request is not successful, clean up after the error.
            //
            if(!NT_SUCCESS(status)) {

                OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
                    ("ConfigureUsbDevice: Failed to read configuration descriptor\n"));
                goto ConfigureDevice_Exit;
            }
        } else {

            OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
                ("ConfigureUsbDevice: Failed to alloc mem for config Descriptor\n"));
            status = STATUS_INSUFFICIENT_RESOURCES;
            goto ConfigureDevice_Exit;
        }
    } else {

        OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
            ("ConfigureUsbDevice: Failed to allocate memory for urb\n"));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto ConfigureDevice_Exit;
    }

    //
    // Check to make sure that a configuration descriptor was allocated.
    //
    if(configurationDescriptor) {

        //
        // Save a copy of configurationDescriptor in deviceExtension
        // remember to free it later.
        //
        DevExt->UsbConfigurationDescriptor = configurationDescriptor;

        //
        // Determine if the USB configuration is cabable of supporting 
        // remote wake.
        //
        if(configurationDescriptor->bmAttributes & USB_CONFIG_REMOTE_WAKEUP) {
            //
            // This configuration supports remote wakeup
            //
            OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_PNP_INFO,
                ("ConfigureUsbDevice: Remote Wakeup Enabled.\n"));
            DevExt->WaitWakeEnable = TRUE;

        } else {

            OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_PNP_INFO,
                ("ConfigureUsbDevice: Remote Wakeup Disabled.\n"));
            DevExt->WaitWakeEnable = FALSE;
        }

        //
        // Select the interface(s) that we are going to use to communicate with the device.
        //
        status = SelectUsbInterfaces(DevExt, configurationDescriptor);

        //
        // And also determine the speed at which the device is running
        //
        DetermineDeviceSpeed(DevExt);

    } else {

        OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_PNP_INFO,
            ("ConfigureUsbDevice: Failed to allocate configuration descriptor.\n"));
        DevExt->UsbConfigurationDescriptor = NULL;
    }

    //
    // Cleanup memory and exit.
    //
ConfigureDevice_Exit:

    if(urb) {

        ExFreePool(urb);
    }

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

    return status;
}

///////////////////////////////////////////////////////////////////////////////
//
// SelectUsbInterfaces
//
//  This routine is called by ConfigureUsbDevice to read the USB 
//  select the interfaces that will be used to talk to the usb device.
//
//
//  INPUTS:
//
//      DevExt  -  Address of the Devices Device Extension.
//      ConfigurationDescriptor - Address of the Configuration Descriptor
//                                  selected.
//
//  OUTPUTS:
//
//      None
//
//  RETURNS:
//
//      None
//

⌨️ 快捷键说明

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