usbd.sys: implement URB building functions
Damjan Jovanovic
damjan.jov at gmail.com
Mon Mar 22 07:41:14 CDT 2010
Changelog:
* usbd.sys: implement URB building functions
Damjan Jovanovic
-------------- next part --------------
diff --git a/dlls/usbd.sys/usbd.c b/dlls/usbd.sys/usbd.c
index daeb5c0..4727512 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 47e0bdb..1cb507e 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 at 8
+@ stdcall USBD_CreateConfigurationRequest(ptr ptr)
+@ stdcall _USBD_CreateConfigurationRequestEx at 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 534dca1..b013f21 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 ce3cc86..0003816 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
More information about the wine-patches
mailing list