From 3f02dee355cac18a5b7d9589108007aa92298abd Mon Sep 17 00:00:00 2001 From: Damjan Jovanovic Date: Mon, 22 Mar 2010 14:41:14 +0200 Subject: [PATCH] usbd.sys: Implement URB building functions. --- dlls/usbd.sys/usbd.c | 122 ++++++++++++++++++++++++++++++++++++ dlls/usbd.sys/usbd.sys.spec | 8 +-- include/ddk/usb100.h | 6 ++ include/ddk/usbdlib.h | 5 +- 4 files changed, 136 insertions(+), 5 deletions(-) diff --git a/dlls/usbd.sys/usbd.c b/dlls/usbd.sys/usbd.c index daeb5c0131d..4727512be97 100644 --- a/dlls/usbd.sys/usbd.c +++ b/dlls/usbd.sys/usbd.c @@ -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, diff --git a/dlls/usbd.sys/usbd.sys.spec b/dlls/usbd.sys/usbd.sys.spec index 47e0bdb0bc5..1cb507e9a07 100644 --- a/dlls/usbd.sys/usbd.sys.spec +++ b/dlls/usbd.sys/usbd.sys.spec @@ -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 diff --git a/include/ddk/usb100.h b/include/ddk/usb100.h index 534dca1da40..b013f21c4b4 100644 --- a/include/ddk/usb100.h +++ b/include/ddk/usb100.h @@ -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; diff --git a/include/ddk/usbdlib.h b/include/ddk/usbdlib.h index ce3cc862d10..0003816edae 100644 --- a/include/ddk/usbdlib.h +++ b/include/ddk/usbdlib.h @@ -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