usbd.sys: Implement URB building functions.

This commit is contained in:
Damjan Jovanovic 2010-03-22 14:41:14 +02:00 committed by Alexandre Julliard
parent d57f05f062
commit 3f02dee355
4 changed files with 136 additions and 5 deletions

View file

@ -33,6 +33,128 @@
WINE_DEFAULT_DEBUG_CHANNEL(usbd);
PURB WINAPI USBD_CreateConfigurationRequest(
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PUSHORT Siz )
{
URB *urb = NULL;
USBD_INTERFACE_LIST_ENTRY *interfaceList;
ULONG interfaceListSize;
USB_INTERFACE_DESCRIPTOR *interfaceDesc;
int i;
TRACE( "(%p, %p)\n", ConfigurationDescriptor, Siz );
/* http://www.microsoft.com/whdc/archive/usbfaq.mspx
* claims USBD_CreateConfigurationRequest doesn't support > 1 interface,
* but is this on Windows 98 only or all versions?
*/
*Siz = 0;
interfaceListSize = (ConfigurationDescriptor->bNumInterfaces + 1) * sizeof(USBD_INTERFACE_LIST_ENTRY);
interfaceList = ExAllocatePool( NonPagedPool, interfaceListSize );
if (interfaceList)
{
RtlZeroMemory( interfaceList, interfaceListSize );
interfaceDesc = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(
ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
ConfigurationDescriptor, USB_INTERFACE_DESCRIPTOR_TYPE );
for (i = 0; i < ConfigurationDescriptor->bNumInterfaces && interfaceDesc != NULL; i++)
{
interfaceList[i].InterfaceDescriptor = interfaceDesc;
interfaceDesc = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(
ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
interfaceDesc + 1, USB_INTERFACE_DESCRIPTOR_TYPE );
}
urb = USBD_CreateConfigurationRequestEx( ConfigurationDescriptor, interfaceList );
if (urb)
*Siz = urb->u.UrbHeader.Length;
ExFreePool( interfaceList );
}
return urb;
}
PURB WINAPI USBD_CreateConfigurationRequestEx(
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
PUSBD_INTERFACE_LIST_ENTRY InterfaceList )
{
URB *urb;
ULONG size = 0;
USBD_INTERFACE_LIST_ENTRY *interfaceEntry;
ULONG interfaceCount = 0;
TRACE( "(%p, %p)\n", ConfigurationDescriptor, InterfaceList );
size = sizeof(struct _URB_SELECT_CONFIGURATION);
for (interfaceEntry = InterfaceList; interfaceEntry->InterfaceDescriptor; interfaceEntry++)
{
++interfaceCount;
size += (interfaceEntry->InterfaceDescriptor->bNumEndpoints - 1) *
sizeof(USBD_PIPE_INFORMATION);
}
size += (interfaceCount - 1) * sizeof(USBD_INTERFACE_INFORMATION);
urb = ExAllocatePool( NonPagedPool, size );
if (urb)
{
USBD_INTERFACE_INFORMATION *interfaceInfo;
RtlZeroMemory( urb, size );
urb->u.UrbSelectConfiguration.Hdr.Length = size;
urb->u.UrbSelectConfiguration.Hdr.Function = URB_FUNCTION_SELECT_CONFIGURATION;
urb->u.UrbSelectConfiguration.ConfigurationDescriptor = ConfigurationDescriptor;
interfaceInfo = &urb->u.UrbSelectConfiguration.Interface;
for (interfaceEntry = InterfaceList; interfaceEntry->InterfaceDescriptor; interfaceEntry++)
{
int i;
USB_INTERFACE_DESCRIPTOR *currentInterface;
USB_ENDPOINT_DESCRIPTOR *endpointDescriptor;
interfaceInfo->InterfaceNumber = interfaceEntry->InterfaceDescriptor->bInterfaceNumber;
interfaceInfo->AlternateSetting = interfaceEntry->InterfaceDescriptor->bAlternateSetting;
interfaceInfo->Class = interfaceEntry->InterfaceDescriptor->bInterfaceClass;
interfaceInfo->SubClass = interfaceEntry->InterfaceDescriptor->bInterfaceSubClass;
interfaceInfo->Protocol = interfaceEntry->InterfaceDescriptor->bInterfaceProtocol;
interfaceInfo->NumberOfPipes = interfaceEntry->InterfaceDescriptor->bNumEndpoints;
currentInterface = USBD_ParseConfigurationDescriptorEx(
ConfigurationDescriptor, ConfigurationDescriptor,
interfaceEntry->InterfaceDescriptor->bInterfaceNumber, -1, -1, -1, -1 );
endpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(
ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
currentInterface, USB_ENDPOINT_DESCRIPTOR_TYPE );
for (i = 0; i < interfaceInfo->NumberOfPipes && endpointDescriptor; i++)
{
interfaceInfo->Pipes[i].MaximumPacketSize = endpointDescriptor->wMaxPacketSize;
interfaceInfo->Pipes[i].EndpointAddress = endpointDescriptor->bEndpointAddress;
interfaceInfo->Pipes[i].Interval = endpointDescriptor->bInterval;
if (endpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_CONTROL)
interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeControl;
else if (endpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_BULK)
interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeBulk;
else if (endpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_INTERRUPT)
interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeInterrupt;
else if (endpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_ISOCHRONOUS)
interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeIsochronous;
endpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(
ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
endpointDescriptor + 1, USB_ENDPOINT_DESCRIPTOR_TYPE );
}
interfaceInfo->Length = sizeof(USBD_INTERFACE_INFORMATION) +
(i - 1) * sizeof(USBD_PIPE_INFORMATION);
interfaceEntry->Interface = interfaceInfo;
interfaceInfo = (USBD_INTERFACE_INFORMATION*)(((char*)interfaceInfo)+interfaceInfo->Length);
}
}
return urb;
}
VOID WINAPI USBD_GetUSBDIVersion(
PUSBD_VERSION_INFORMATION VersionInformation )
{
TRACE( "(%p)\n", VersionInformation );
/* Emulate Windows 2000 (= 0x300) for now */
VersionInformation->USBDI_Version = 0x300;
VersionInformation->Supported_USB_Version = 0x200;
}
PUSB_INTERFACE_DESCRIPTOR WINAPI USBD_ParseConfigurationDescriptorEx(
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
PVOID StartPosition, LONG InterfaceNumber,

View file

@ -1,11 +1,11 @@
@ stub USBD_CreateConfigurationRequestEx
@ stdcall USBD_CreateConfigurationRequestEx(ptr ptr)
@ stdcall USBD_ParseConfigurationDescriptorEx(ptr ptr long long long long long)
@ stdcall USBD_ParseDescriptors(ptr long ptr long)
@ stub USBD_AllocateDeviceName
@ stub USBD_CalculateUsbBandwidth
@ stub USBD_CompleteRequest
@ stub USBD_CreateConfigurationRequest
@ stub _USBD_CreateConfigurationRequestEx@8
@ stdcall USBD_CreateConfigurationRequest(ptr ptr)
@ stdcall _USBD_CreateConfigurationRequestEx@8(ptr ptr) USBD_CreateConfigurationRequestEx
@ stub USBD_CreateDevice
@ stub USBD_Debug_GetHeap
@ stub USBD_Debug_LogEntry
@ -17,7 +17,7 @@
@ stdcall USBD_GetInterfaceLength(ptr ptr)
@ stub USBD_GetPdoRegistryParameter
@ stub USBD_GetSuspendPowerState
@ stub USBD_GetUSBDIVersion
@ stdcall USBD_GetUSBDIVersion(ptr)
@ stub USBD_InitializeDevice
@ stub USBD_MakePdoName
@ stub USBD_ParseConfigurationDescriptor

View file

@ -48,6 +48,12 @@ typedef struct _USB_DEVICE_DESCRIPTOR {
} USB_DEVICE_DESCRIPTOR;
typedef struct _USB_DEVICE_DESCRIPTOR *PUSB_DEVICE_DESCRIPTOR;
#define USB_ENDPOINT_TYPE_MASK 0x03
#define USB_ENDPOINT_TYPE_CONTROL 0x00
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
#define USB_ENDPOINT_TYPE_BULK 0x02
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
typedef struct _USB_ENDPOINT_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;

View file

@ -25,8 +25,11 @@ typedef struct _USBD_INTERFACE_LIST_ENTRY {
} USBD_INTERFACE_LIST_ENTRY;
typedef struct _USBD_INTERFACE_LIST_ENTRY *PUSBD_INTERFACE_LIST_ENTRY;
PUSB_INTERFACE_DESCRIPTOR WINAPI USBD_ParseConfigurationDescriptorEx(PUSB_CONFIGURATION_DESCRIPTOR,PVOID,LONG,LONG,LONG,LONG,LONG);
PURB WINAPI USBD_CreateConfigurationRequest(PUSB_CONFIGURATION_DESCRIPTOR,PUSHORT);
PURB WINAPI USBD_CreateConfigurationRequestEx(PUSB_CONFIGURATION_DESCRIPTOR,PUSBD_INTERFACE_LIST_ENTRY);
ULONG WINAPI USBD_GetInterfaceLength(PUSB_INTERFACE_DESCRIPTOR,PUCHAR);
VOID WINAPI USBD_GetUSBDIVersion(PUSBD_VERSION_INFORMATION);
PUSB_COMMON_DESCRIPTOR WINAPI USBD_ParseDescriptors(PVOID,ULONG,PVOID,LONG);
PUSB_INTERFACE_DESCRIPTOR WINAPI USBD_ParseConfigurationDescriptorEx(PUSB_CONFIGURATION_DESCRIPTOR,PVOID,LONG,LONG,LONG,LONG,LONG);
#endif