seeseadream
驱动牛犊
驱动牛犊
  • 注册日期2003-10-06
  • 最后登录2005-01-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1128回复:1

请教一个USB-MIDI驱动的问题,谢谢!

楼主#
更多 发布于:2003-12-02 01:03
我现在在为一个USB-MIDI设备开发驱动程序, 我是用一般的USB驱动开发方法来开发的, 但是出现了问题。 我已经成功的AddDevice, 但是在DispatchPnp中, StartDevice 时出现了问题, 以致于设备只能被识别,而不能被使用。 我使用的方法是:设备->设置->接口->端点  的顺序。
请问有没有做过MIDI设备的高手,指点一二,谢谢!
愿与你分享成功的喜悦、失败的悲哀!
seeseadream
驱动牛犊
驱动牛犊
  • 注册日期2003-10-06
  • 最后登录2005-01-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-12-02 01:26
程序如下:
NTSTATUS
Midiusb_HandleStartDevice(
   IN PDEVICE_OBJECT fdo,
   IN PIRP Irp
   )
{
   NTSTATUS ntStatus;
   ntStatus = ForwardAndWait(fdo, Irp);
if (!NT_SUCCESS(ntStatus))
return CompleteRequest(Irp, ntStatus, Irp->IoStatus.Information);

   ntStatus = Midiusb_StartDevice(fdo);
return CompleteRequest(Irp, ntStatus, 0);
}
NTSTATUS
Midiusb_StartDevice(
    IN  PDEVICE_OBJECT fdo
    )

{
    PDEVICE_EXTENSION pdx;
    NTSTATUS ntStatus;
    PUSB_DEVICE_DESCRIPTOR deviceDescriptor = NULL;
    PURB urb;
    ULONG siz;

    Midiusb_KdPrint ((\"enter Midiusb_StartDevice\\n\"));

    pdx = fdo->DeviceExtension;
    pdx->NeedCleanup = TRUE;
urb = ExAllocatePool( NonPagedPool,
                          sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));

    if (urb) {

        siz = sizeof(USB_DEVICE_DESCRIPTOR);

        // Get some non paged memory for the device descriptor contents
        deviceDescriptor = ExAllocatePool(NonPagedPool,
                                          siz);

        if (deviceDescriptor) {

            // Use a macro in the standard USB header files to build the URB
            UsbBuildGetDescriptorRequest(urb,
                                         (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
                                         USB_DEVICE_DESCRIPTOR_TYPE,
                                         0,
                                         0,
                                         deviceDescriptor,
                                         NULL,
                                         siz,
                                         NULL);

            // Get the device descriptor
            ntStatus = Midiusb_CallUSBD(fdo, urb);

            // Dump out the descriptor info to the debugger
            if (NT_SUCCESS(ntStatus)) {
                Midiusb_KdPrint ((\"Device Descriptor = %x, len %x\\n\",
                                deviceDescriptor,
                                urb->UrbControlDescriptorRequest.TransferBufferLength));

                Midiusb_KdPrint ((\"Midiusb Device Descriptor:\\n\"));
                Midiusb_KdPrint ((\"-------------------------\\n\"));
                Midiusb_KdPrint ((\"bLength %d\\n\", deviceDescriptor->bLength));
                Midiusb_KdPrint ((\"bDescriptorType 0x%x\\n\", deviceDescriptor->bDescriptorType));
                Midiusb_KdPrint ((\"bcdUSB 0x%x\\n\", deviceDescriptor->bcdUSB));
                Midiusb_KdPrint ((\"bDeviceClass 0x%x\\n\", deviceDescriptor->bDeviceClass));
                Midiusb_KdPrint ((\"bDeviceSubClass 0x%x\\n\", deviceDescriptor->bDeviceSubClass));
                Midiusb_KdPrint ((\"bDeviceProtocol 0x%x\\n\", deviceDescriptor->bDeviceProtocol));
                Midiusb_KdPrint ((\"bMaxPacketSize0 0x%x\\n\", deviceDescriptor->bMaxPacketSize0));
                Midiusb_KdPrint ((\"idVendor 0x%x\\n\", deviceDescriptor->idVendor));
                Midiusb_KdPrint ((\"idProduct 0x%x\\n\", deviceDescriptor->idProduct));
                Midiusb_KdPrint ((\"bcdDevice 0x%x\\n\", deviceDescriptor->bcdDevice));
                Midiusb_KdPrint ((\"iManufacturer 0x%x\\n\", deviceDescriptor->iManufacturer));
                Midiusb_KdPrint ((\"iProduct 0x%x\\n\", deviceDescriptor->iProduct));
                Midiusb_KdPrint ((\"iSerialNumber 0x%x\\n\", deviceDescriptor->iSerialNumber));
                Midiusb_KdPrint ((\"bNumConfigurations 0x%x\\n\", deviceDescriptor->bNumConfigurations));
            }
        } else {
            ntStatus = STATUS_NO_MEMORY;
        }

        if (NT_SUCCESS(ntStatus)) {pdx->DeviceDescriptor = deviceDescriptor;
            pdx->Stopped = FALSE;
        } else if (deviceDescriptor) {ExFreePool(deviceDescriptor);
            pdx->DeviceDescriptor = NULL;
        }

        ExFreePool(urb);

    } else {
        // Failed getting memory for the Urb
        ntStatus = STATUS_NO_MEMORY;
    }

    // If the Get_Descriptor call was successful, then configure the device.
    if (NT_SUCCESS(ntStatus)) {
        ntStatus = Midiusb_ConfigureDevice(fdo);
    }


    Midiusb_KdPrint ((\"exit Midiusb_StartDevice (%x)\\n\", ntStatus));

    return ntStatus;
}
NTSTATUS
Midiusb_ConfigureDevice(
    IN  PDEVICE_OBJECT fdo
    )
{
   PDEVICE_EXTENSION pdx;
   NTSTATUS ntStatus;
   PURB urb = NULL;
   ULONG siz;
   PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor = NULL;

   Midiusb_KdPrint ((\"enter Midiusb_ConfigureDevice\\n\"));

   pdx = fdo->DeviceExtension;
urb = ExAllocatePool(NonPagedPool,
                      sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));

   if (urb != NULL)
   {siz = sizeof(USB_CONFIGURATION_DESCRIPTOR) + 16;

        // Get the nonpaged pool memory for the data buffer
        configurationDescriptor = ExAllocatePool(NonPagedPool, siz);

        if (configurationDescriptor != NULL) {

            UsbBuildGetDescriptorRequest(urb,
                                         (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
                                         USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                         0,
                                         0,
                                         configurationDescriptor,
                                         NULL,
                                         sizeof (USB_CONFIGURATION_DESCRIPTOR),/* Get only the configuration descriptor */
                                         NULL);

            ntStatus = Midiusb_CallUSBD(fdo, urb);

            if (NT_SUCCESS(ntStatus)) {
                Midiusb_KdPrint ((\"Configuration Descriptor is at %x, bytes txferred: %d\\n\\
                                  Configuration Descriptor Actual Length: %d\\n\",
                                  configurationDescriptor,
                                  urb->UrbControlDescriptorRequest.TransferBufferLength,
                                  configurationDescriptor->wTotalLength));
            }//pay attention to this structure and the format

        } else {
            ntStatus = STATUS_NO_MEMORY;
            goto Exit_MidiusbConfigureDevice;
        }//if-else

        // Determine how much data is in the entire configuration descriptor
        // and add extra room to protect against accidental overrun
        siz = configurationDescriptor->wTotalLength + 16;

        //  Free up the data buffer memory just used
        ExFreePool(configurationDescriptor);
        configurationDescriptor = NULL;

        // Get nonpaged pool memory for the data buffer
        configurationDescriptor = ExAllocatePool(NonPagedPool, siz);

        // Now get the entire Configuration Descriptor
        if (configurationDescriptor != NULL) {
            UsbBuildGetDescriptorRequest(urb,
                                         (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
                                         USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                         0,
                                         0,
                                         configurationDescriptor,
                                         NULL,
                                         siz,  // Get all the descriptor data
                                         NULL);

            ntStatus = Midiusb_CallUSBD(fdo, urb);

            if (NT_SUCCESS(ntStatus)) {
                Midiusb_KdPrint ((\"Entire Configuration Descriptor is at %x, bytes txferred: %d\\n\",
                                  configurationDescriptor,
                                  urb->UrbControlDescriptorRequest.TransferBufferLength));
            } else {
                //Error in getting configuration descriptor
                goto Exit_MidiusbConfigureDevice;
            }//else

        } else {
            // Failed getting data buffer (configurationDescriptor) memory
            ntStatus = STATUS_NO_MEMORY;
            goto Exit_MidiusbConfigureDevice;
        }//if-else

    } else {
        // failed getting urb memory
        ntStatus = STATUS_NO_MEMORY;
        goto Exit_MidiusbConfigureDevice;
    }//if-else
if (configurationDescriptor) {
        // Get our pipes
        ntStatus = Midiusb_SelectInterfaces(fdo,
                                           configurationDescriptor,
                                           NULL // Device not yet configured
                                           );
    } //if

Exit_MidiusbConfigureDevice:

    // Clean up and exit this routine
    if (urb != NULL) {
        ExFreePool(urb);                    // Free urb memory
    }//if

    if (configurationDescriptor != NULL) {
        ExFreePool(configurationDescriptor);// Free data buffer
    }//if

    Midiusb_KdPrint ((\"exit Midiusb_ConfigureDevice (%x)\\n\", ntStatus));
    return ntStatus;
}//Midiusb_ConfigureDevice

NTSTATUS
Midiusb_SelectInterfaces(
    IN PDEVICE_OBJECT fdo,
    IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
    IN PUSBD_INTERFACE_INFORMATION Interface
    )
{
   PDEVICE_EXTENSION pdx;
   NTSTATUS ntStatus;
   PURB urb;
   ULONG j;
   UCHAR alternateSetting, MyInterfaceNumber;
   PUSBD_INTERFACE_INFORMATION interfaceObject;
   USBD_INTERFACE_LIST_ENTRY interfaceList[2];

   Midiusb_KdPrint ((\"enter Midiusb_SelectInterfaces\\n\"));

   pdx = fdo->DeviceExtension;
  // MyInterfaceNumber = SAMPLE_INTERFACE_NBR;

// Search the configuration descriptor for the first interface/alternate setting

   interfaceList[0].InterfaceDescriptor =
   USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor,
                                       ConfigurationDescriptor,
                                       -1,         // Interface - don\'t care
                                       -1,         // Alternate Setting - don\'t care
                                       -1,         // Class - don\'t care
                                       -1,         // SubClass - don\'t care
                                       -1);        // Protocol - don\'t care

   ASSERT(interfaceList[0].InterfaceDescriptor != NULL);

   interfaceList[1].InterfaceDescriptor = NULL;
   interfaceList[1].Interface = NULL;

   urb = USBD_CreateConfigurationRequestEx(ConfigurationDescriptor,&interfaceList[0]);

   if (!urb)
   {
      Midiusb_KdPrint ((\" USBD_CreateConfigurationRequestEx failed\\n\"));            
   }

   DumpBuffer(urb, urb->UrbHeader.Length);

   interfaceObject = (PUSBD_INTERFACE_INFORMATION) (&(urb->UrbSelectConfiguration.Interface));
for (j=0; j<interfaceList[0].InterfaceDescriptor->bNumEndpoints; j++)
   {
  MyInterfaceNumber = SAMPLE_INTERFACE_NBR;
      interfaceObject->Pipes[j].MaximumTransferSize = (16* 1024) - 1;

   }
   ntStatus = Midiusb_CallUSBD(fdo, urb);

   DumpBuffer(urb, urb->UrbHeader.Length);

   if (NT_SUCCESS(ntStatus) && USBD_SUCCESS(urb->UrbHeader.Status))
   {

      // Save the configuration handle for this device
      pdx->ConfigurationHandle =
         urb->UrbSelectConfiguration.ConfigurationHandle;

      pdx->Interface = ExAllocatePool(NonPagedPool,
                                                interfaceObject->Length);

      // save a copy of the interfaceObject information returned
      RtlCopyMemory(pdx->Interface, interfaceObject, interfaceObject->Length);

      // Dump the interfaceObject to the debugger
      Midiusb_KdPrint ((\"---------\\n\"));
      Midiusb_KdPrint ((\"NumberOfPipes 0x%x\\n\", pdx->Interface->NumberOfPipes));
      Midiusb_KdPrint ((\"Length 0x%x\\n\", pdx->Interface->Length));
      Midiusb_KdPrint ((\"Alt Setting 0x%x\\n\", pdx->Interface->AlternateSetting));
      Midiusb_KdPrint ((\"Interface Number 0x%x\\n\", pdx->Interface->InterfaceNumber));

      // Dump the pipe info
      for (j=0; j<interfaceObject->NumberOfPipes; j++)
      {
         PUSBD_PIPE_INFORMATION pipeInformation;

         pipeInformation = &pdx->Interface->Pipes[j];

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

      Midiusb_KdPrint ((\"---------\\n\"));
   }


   Midiusb_KdPrint ((\"exit Midiusb_SelectInterfaces (%x)\\n\", ntStatus));

   return ntStatus;

}/* Midiusb_SelectInterfaces */



愿与你分享成功的喜悦、失败的悲哀!
游客

返回顶部