阅读:1129回复:1
请教一个USB-MIDI驱动的问题,谢谢!
我现在在为一个USB-MIDI设备开发驱动程序, 我是用一般的USB驱动开发方法来开发的, 但是出现了问题。 我已经成功的AddDevice, 但是在DispatchPnp中, StartDevice 时出现了问题, 以致于设备只能被识别,而不能被使用。 我使用的方法是:设备->设置->接口->端点 的顺序。
请问有没有做过MIDI设备的高手,指点一二,谢谢! |
|
|
沙发#
发布于: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 */ |
|
|