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

📄 isopnp.c

📁 传说中的 usb 端口 驱动 源码 啊啊啊啊啊啊啊
💻 C
📖 第 1 页 / 共 5 页
字号:

    configurationDescriptor = deviceExtension->ConfigurationDescriptor;

    numInterfaces = configurationDescriptor->bNumInterfaces;

    // Build an USBD_INTERFACE_LIST_ENTRY array to use as an
    // input/output parameter to USBD_CreateConfigurationRequestEx().
    //
    interfaceList = IsoUsb_BuildInterfaceList(configurationDescriptor);

    if (interfaceList == NULL)
    {
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;

        goto IsoUsb_SelectConfigurationExit;
    }

    // Create a SELECT_CONFIGURATION URB, turning the Interface
    // Descriptors in the interfaceList into
    // USBD_INTERFACE_INFORMATION structures in the URB.
    //
    urb = USBD_CreateConfigurationRequestEx(configurationDescriptor,
                                            interfaceList);

    // Now done with the interfaceList as soon as the URB is built (or
    // not built).
    //
    ExFreePool(interfaceList);
    interfaceList = NULL;

    if (urb == NULL)
    {
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;

        goto IsoUsb_SelectConfigurationExit;
    }

    // Now issue the USB request to set the Configuration
    //
    ntStatus = IsoUsb_SyncSendUsbRequest(DeviceObject,
                                         urb);

    if (!NT_SUCCESS(ntStatus))
    {
        // Now done with the URB
        //
        ExFreePool(urb);
        urb = NULL;

        goto IsoUsb_SelectConfigurationExit;
    }

    // Save the configuration handle for this device in the Device
    // Extension.
    //
    deviceExtension->ConfigurationHandle = urb->UrbSelectConfiguration.ConfigurationHandle;

    ASSERT(deviceExtension->InterfaceInfoList == NULL);

    // Allocate an array to hold pointers to one
    // USBD_INTERFACE_INFORMATION structure per configured Interface.
    // Save this array in the Device Extension.
    //
    interfaceInfoList = (PUSBD_INTERFACE_INFORMATION *)
                        ExAllocatePool(NonPagedPool,
                                       numInterfaces *
                                       sizeof(PUSBD_INTERFACE_INFORMATION));

    if (interfaceInfoList == NULL)
    {
        // Now done with the URB
        //
        ExFreePool(urb);
        urb = NULL;

        goto IsoUsb_SelectConfigurationExit;
    }

    deviceExtension->InterfaceInfoList = interfaceInfoList;

    // The end of the SELECT_CONFIGURATION URB contains a contiguous
    // array of variably sized USBD_INTERFACE_INFORMATION structures,
    // one per configured Interface.
    //
    // Get a pointer to the USBD_INTERFACE_INFORMATION structure for
    // the first configured Interface.
    //
    interfaceInfo = &urb->UrbSelectConfiguration.Interface;

    // Iterate over each configured Interface.  Allocate memory for a
    // copy of the USBD_INTERFACE_INFORMATION structure for the
    // Interface and save a copy of the structure from the URB.
    //
    for (i = 0; i < numInterfaces; i++)
    {
        interfaceInfoList[i] =  ExAllocatePool(NonPagedPool,
                                               interfaceInfo->Length);

        if (interfaceInfoList[i] == NULL)
        {
            // Allocation failure, free the previously allocated
            // USBD_INTERFACE_INFORMATION structure copies.
            //
            for (i = 0; i < numInterfaces; i++)
            {
                if (interfaceInfoList[i] != NULL)
                {
                    ExFreePool(interfaceInfoList[i]);
                }
            }

            // Free the list of pointers to allocated
            // USBD_INTERFACE_INFORMATION structure copies.
            //
            ExFreePool(deviceExtension->InterfaceInfoList);
            deviceExtension->InterfaceInfoList = NULL;

            // Now done with the URB
            //
            ExFreePool(urb);
            urb = NULL;

            ntStatus = STATUS_INSUFFICIENT_RESOURCES;

            goto IsoUsb_SelectConfigurationExit;
        }

        // Save a copy of the USBD_INTERFACE_INFORMATION structure from
        // the URB in the Device Extension InterfaceInfoList.
        //
        RtlCopyMemory(interfaceInfoList[i],
                      interfaceInfo,
                      interfaceInfo->Length);

        // Save pointers back into the USBD_PIPE_INFORMATION structures
        // contained within the above saved USBD_INTERFACE_INFORMATION
        // structure.
        //
        // This is makes it easier to iterate over all currently
        // configured pipes without having to interate over all
        // currently configured interfaces as we are in the middle of
        // doing right now.
        //
        for (j = 0; j < interfaceInfo->NumberOfPipes; j++)
        {
            if (deviceExtension->NumberOfPipes < ISOUSB_MAX_PIPES)
            {
                deviceExtension->PipeInformation[deviceExtension->NumberOfPipes] =
                    &interfaceInfoList[i]->Pipes[j];

                deviceExtension->NumberOfPipes++;
            }
        }

#if DBG
        DumpInterfaceInformation(interfaceInfo);
#endif

        // Advance to the next variably sized USBD_INTERFACE_INFORMATION
        // structure in the SELECT_CONFIGURATION URB.
        //
        interfaceInfo = (PUSBD_INTERFACE_INFORMATION)
                        ((PUCHAR)interfaceInfo + interfaceInfo->Length);
    }

    // Now done with the URB
    //
    ExFreePool(urb);

IsoUsb_SelectConfigurationExit:

    IsoUsb_DbgPrint(2, ("exit:  IsoUsb_SelectConfiguration %08X\n", ntStatus));

    return ntStatus;
}


NTSTATUS
IsoUsb_SelectAlternateInterface (
    IN PDEVICE_OBJECT   DeviceObject,
    IN UCHAR            InterfaceNumber,
    IN UCHAR            AlternateSetting
    )
/*++

Routine Description:

    This routine attempts to select the specified alternate interface
    setting for the specified interface.

    The InterfaceNumber and AlternateSetting parameters will be
    validated by this routine and are not assumed to be valid.

    This routines assumes that the device is currently configured, i.e.
    IsoUsb_SelectConfiguration() has been successfully called and
    IsoUsb_UnConfigure() has not been called.

    This routine assumes that no pipes will be accessed while this
    routine is executing as the deviceExtension->InterfaceInfoList and
    deviceExtension->PipeInformation data is updated by this routine.
    This exclusion synchronization must be handled external to this
    routine.

--*/
{
    PDEVICE_EXTENSION               deviceExtension;
    PUSB_CONFIGURATION_DESCRIPTOR   configurationDescriptor;
    ULONG                           numInterfaces;
    PUSB_INTERFACE_DESCRIPTOR       interfaceDescriptor;
    UCHAR                           numEndpoints;
    USHORT                          urbSize;
    PURB                            urb;
    PUSBD_INTERFACE_INFORMATION     interfaceInfoUrb;
    PUSBD_INTERFACE_INFORMATION     interfaceInfoCopy;
    ULONG                           i;
    ULONG                           j;
    NTSTATUS                        ntStatus;

    IsoUsb_DbgPrint(2, ("enter: IsoUsb_SelectAlternateInterface\n"));

    deviceExtension = DeviceObject->DeviceExtension;

    configurationDescriptor = deviceExtension->ConfigurationDescriptor;

    numInterfaces = configurationDescriptor->bNumInterfaces;

    // Find the Interface Descriptor which matches the InterfaceNumber
    // and AlternateSetting parameters.
    //
    interfaceDescriptor = USBD_ParseConfigurationDescriptorEx(
                              configurationDescriptor,
                              configurationDescriptor,
                              InterfaceNumber,
                              AlternateSetting,
                              -1, // InterfaceClass, don't care
                              -1, // InterfaceSubClass, don't care
                              -1  // InterfaceProtocol, don't care
                              );

    if (interfaceDescriptor == NULL)
    {
        // Interface Descriptor not found, bad InterfaceNumber or
        // AlternateSetting.
        //
        ntStatus = STATUS_INVALID_PARAMETER;

        goto IsoUsb_SelectAlternateInterfaceExit;
    }

    // Allocate a URB_FUNCTION_SELECT_INTERFACE request structure
    //
    numEndpoints = interfaceDescriptor->bNumEndpoints;

    urbSize = GET_SELECT_INTERFACE_REQUEST_SIZE(numEndpoints);

    urb = ExAllocatePool(NonPagedPool,
                         urbSize);

    if (urb == NULL)
    {
        // Could not allocate the URB.
        //
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;

        goto IsoUsb_SelectAlternateInterfaceExit;
    }

    // Initialize the URB
    //
    RtlZeroMemory(urb, urbSize);

    urb->UrbHeader.Length   = urbSize;

    urb->UrbHeader.Function = URB_FUNCTION_SELECT_INTERFACE;

    urb->UrbSelectInterface.ConfigurationHandle =
        deviceExtension->ConfigurationHandle;

    interfaceInfoUrb = &urb->UrbSelectInterface.Interface;

    interfaceInfoUrb->Length = GET_USBD_INTERFACE_SIZE(numEndpoints);

    interfaceInfoUrb->InterfaceNumber = InterfaceNumber;

    interfaceInfoUrb->AlternateSetting = AlternateSetting;

    for (i = 0; i < numEndpoints; i++)
    {
        interfaceInfoUrb->Pipes[i].MaximumTransferSize =
            USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
    }

    // Allocate a USBD_INTERFACE_INFORMATION structure to hold the
    // result of the URB_FUNCTION_SELECT_INTERFACE request.
    //
    interfaceInfoCopy = ExAllocatePool(NonPagedPool,
                                       GET_USBD_INTERFACE_SIZE(numEndpoints));

    // Could not allocate the USBD_INTERFACE_INFORMATION copy.
    //
    if (interfaceInfoCopy == NULL)
    {
        ExFreePool(urb);

        ntStatus = STATUS_INSUFFICIENT_RESOURCES;

        goto IsoUsb_SelectAlternateInterfaceExit;
    }

    // Now issue the USB request to select the alternate interface
    //
    ntStatus = IsoUsb_SyncSendUsbRequest(DeviceObject,
                                         urb);

    if (NT_SUCCESS(ntStatus))
    {
        // Save a copy of the interface information returned by the
        // SELECT_INTERFACE request.  This gives us a list of
        // PIPE_INFORMATION structures for each pipe opened in this
        // selected alternate interface setting.
        //
        ASSERT(interfaceInfoUrb->Length == GET_USBD_INTERFACE_SIZE(numEndpoints));

        RtlCopyMemory(interfaceInfoCopy,
                      interfaceInfoUrb,
                      GET_USBD_INTERFACE_SIZE(numEndpoints));

#if DBG
        DumpInterfaceInformation(interfaceInfoCopy);
#endif
    }
    else
    {
        // How to recover from a select alternate interface failure?
        //
        // The other currently configured interfaces (if any) should
        // not be disturbed by this select alternate interface failure.
        //
        // Just note that this interface now has no currently
        // configured pipes (i.e. interfaceInfoCopy->NumberOfPipes == 0)
        //
        RtlZeroMemory(interfaceInfoCopy,
                      GET_USBD_INTERFACE_SIZE(numEndpoints));

        interfaceInfoCopy->Length = GET_USBD_INTERFACE_SIZE(numEndpoints);

        interfaceInfoCopy->InterfaceNumber = InterfaceNumber;

        interfaceInfoCopy->AlternateSetting = AlternateSetting;
    }

    // Zero out and then reset the currently configured
    // USBD_PIPE_INFORMATION
    //
    deviceExtension->NumberOfPipes = 0;

    RtlZeroMemory(deviceExtension->PipeInformation,
                  sizeof(deviceExtension->PipeInformation));

    for (i = 0; i < numInterfaces; i++)
    {
        // Save pointers back into the USBD_PIPE_INFORMATION structures
        // contained within the above saved USBD_INTERFACE_INFORMATION
        // structure.
        //
        // This is makes it easier to iterate over all currently
        // configured pipes without having to interate over all
        // currently configured interfaces as we are in the middle of
        // doing right now.
        //

        if ((deviceExtension->InterfaceInfoList[i]->InterfaceNumber ==
             InterfaceNumber) &&
            (interfaceInfoCopy != NULL))
        {
            // Free the USBD_INTERFACE_INFORMATION for the previously
            // selected alternate interface setting and swap in the new
            // USBD_INTERFACE_INFORMATION copy.
            //
            ExFreePool(deviceExtension->InterfaceInfoList[i]);

            deviceExtension->InterfaceInfoList[i] = interfaceInfoCopy;

            interfaceInfoCopy = NULL;
        }

        for (j = 0; j < deviceExtension->InterfaceInfoList[i]->NumberOfPipes; j++)
        {
            if (deviceExtension->NumberOfPipes < ISOUSB_MAX_PIPES)
            {
                deviceExtension->PipeInformation[deviceExtension->NumberOfPipes] =
                    &deviceExtension->InterfaceInfoList[i]->Pipes[j];

                deviceExtension->NumberOfPipes++;
            }
        }
    }

    // Done with the URB
    //
    ExFreePool(urb);

IsoUsb_SelectAlternateInterfaceExit:

    IsoUsb_DbgPrint(2, ("exit:  IsoUsb_SelectAlternateInterface %08X\n", ntStatus));

    return ntStatus;
}


NTSTATUS
IsoUsb_UnConfigure (
    IN PDEVICE_OBJECT   DeviceObject
    )
/*++

Routine Description:

    This routine is invoked when the device is removed or stopped.
    This routine de-configures the usb device.

Arguments:

    DeviceObject - pointer to device object

Return Value:

    NT status value

--*/
{
    PDEVICE_EXTENSION   deviceExtension;
    NTSTATUS            ntStatus;
    PURB                urb;
    ULONG               ulSize;
    ULONG               numInterfaces;
    ULONG               i;

    IsoUsb_DbgPrint(2, ("enter: IsoUsb_UnConfigure\n"));

    deviceExtension = DeviceObject->DeviceExtension;

    // Allocate a URB for the SELECT_CONFIGURATION request.  As we are
    // unconfiguring the device, the request needs no pipe and interface
    // information structures.
    //
    ulSize = sizeof(struct _URB_SELECT_CONFIGURATION) -
             sizeof(USBD_INTERFACE_INFORMATION);

    urb = ExAllocatePool(
              NonPagedPool,
              ulSize
              );

    if (urb)
    {
        // Initialize the URB.  A NULL Configuration Descriptor indicates
        // that the device should be unconfigured.
        //
        UsbBuildSelectConfigurationRequest(
      

⌨️ 快捷键说明

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