* PURPOSE: Helper Library for USB
* PROGRAMMERS:
* Filip Navara <xnavara@volny.cz>
+ * Michael Martin <michael.martin@reactos.org>
*
*/
* USBD_GetPdoRegistryParameters (implemented)
*/
+#define _USBD_
+#define NDEBUG
#include <ntddk.h>
#include <usbdi.h>
+#include <usbdlib.h>
+#include <debug.h>
#ifndef PLUGPLAY_REGKEY_DRIVER
#define PLUGPLAY_REGKEY_DRIVER 2
#endif
-typedef struct _USBD_INTERFACE_LIST_ENTRY {
- PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
- PUSBD_INTERFACE_INFORMATION Interface;
-} USBD_INTERFACE_LIST_ENTRY, *PUSBD_INTERFACE_LIST_ENTRY;
NTSTATUS NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject,
/*
* @implemented
*/
-DWORD NTAPI
-DllInitialize(DWORD Unknown)
+ULONG NTAPI
+DllInitialize(ULONG Unknown)
{
return 0;
}
/*
* @implemented
*/
-DWORD NTAPI
+ULONG NTAPI
DllUnload(VOID)
{
return 0;
* @implemented
*/
PVOID NTAPI
-USBD_Debug_GetHeap(DWORD Unknown1, POOL_TYPE PoolType, ULONG NumberOfBytes,
- ULONG Tag)
+USBD_Debug_GetHeap(ULONG Unknown1, POOL_TYPE PoolType, ULONG NumberOfBytes,
+ ULONG Tag)
{
return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
}
* @implemented
*/
VOID NTAPI
-USBD_Debug_RetHeap(PVOID Heap, DWORD Unknown2, DWORD Unknown3)
+USBD_Debug_RetHeap(PVOID Heap, ULONG Unknown2, ULONG Unknown3)
{
ExFreePool(Heap);
}
* @implemented
*/
PVOID NTAPI
-USBD_AllocateDeviceName(DWORD Unknown)
+USBD_AllocateDeviceName(ULONG Unknown)
{
+ UNIMPLEMENTED
return NULL;
}
/*
* @implemented
*/
-DWORD NTAPI
+ULONG NTAPI
USBD_CalculateUsbBandwidth(
ULONG MaxPacketSize,
UCHAR EndpointType,
BOOLEAN LowSpeed
)
{
- DWORD OverheadTable[] = {
+ ULONG OverheadTable[] = {
0x00, /* UsbdPipeTypeControl */
0x09, /* UsbdPipeTypeIsochronous */
0x00, /* UsbdPipeTypeBulk */
0x0d /* UsbdPipeTypeInterrupt */
};
- DWORD Result;
+ ULONG Result;
if (OverheadTable[EndpointType] != 0)
{
/*
* @implemented
*/
-DWORD NTAPI
-USBD_Dispatch(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4)
+ULONG NTAPI
+USBD_Dispatch(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3, ULONG Unknown4)
{
+ UNIMPLEMENTED
return 1;
}
VOID NTAPI
USBD_FreeDeviceMutex(PVOID Unknown)
{
+ UNIMPLEMENTED
}
/*
VOID NTAPI
USBD_FreeDeviceName(PVOID Unknown)
{
+ UNIMPLEMENTED
}
/*
VOID NTAPI
USBD_WaitDeviceMutex(PVOID Unknown)
{
+ UNIMPLEMENTED
}
/*
* @implemented
*/
-DWORD NTAPI
-USBD_GetSuspendPowerState(DWORD Unknown1)
+ULONG NTAPI
+USBD_GetSuspendPowerState(ULONG Unknown1)
{
+ UNIMPLEMENTED
return 0;
}
* @implemented
*/
NTSTATUS NTAPI
-USBD_InitializeDevice(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3,
- DWORD Unknown4, DWORD Unknown5, DWORD Unknown6)
+USBD_InitializeDevice(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3,
+ ULONG Unknown4, ULONG Unknown5, ULONG Unknown6)
{
+ UNIMPLEMENTED
return STATUS_NOT_SUPPORTED;
}
* @implemented
*/
NTSTATUS NTAPI
-USBD_RegisterHostController(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3,
- DWORD Unknown4, DWORD Unknown5, DWORD Unknown6, DWORD Unknown7,
- DWORD Unknown8, DWORD Unknown9, DWORD Unknown10)
+USBD_RegisterHostController(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3,
+ ULONG Unknown4, ULONG Unknown5, ULONG Unknown6, ULONG Unknown7,
+ ULONG Unknown8, ULONG Unknown9, ULONG Unknown10)
{
+ UNIMPLEMENTED
return STATUS_NOT_SUPPORTED;
}
* @implemented
*/
NTSTATUS NTAPI
-USBD_GetDeviceInformation(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3)
+USBD_GetDeviceInformation(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3)
{
+ UNIMPLEMENTED
return STATUS_NOT_SUPPORTED;
}
* @implemented
*/
NTSTATUS NTAPI
-USBD_CreateDevice(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3,
- DWORD Unknown4, DWORD Unknown5)
+USBD_CreateDevice(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3,
+ ULONG Unknown4, ULONG Unknown5)
{
+ UNIMPLEMENTED
return STATUS_NOT_SUPPORTED;
}
* @implemented
*/
NTSTATUS NTAPI
-USBD_RemoveDevice(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3)
+USBD_RemoveDevice(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3)
{
+ UNIMPLEMENTED
return STATUS_NOT_SUPPORTED;
}
* @implemented
*/
VOID NTAPI
-USBD_CompleteRequest(DWORD Unknown1, DWORD Unknown2)
+USBD_CompleteRequest(ULONG Unknown1, ULONG Unknown2)
{
+ UNIMPLEMENTED
}
/*
PDEVICE_OBJECT FilterDeviceObject
)
{
+ UNIMPLEMENTED
}
/*
* @implemented
*/
VOID NTAPI
-USBD_SetSuspendPowerState(DWORD Unknown1, DWORD Unknown2)
+USBD_SetSuspendPowerState(ULONG Unknown1, ULONG Unknown2)
{
+ UNIMPLEMENTED
}
/*
* @implemented
*/
NTSTATUS NTAPI
-USBD_MakePdoName(DWORD Unknown1, DWORD Unknown2)
+USBD_MakePdoName(ULONG Unknown1, ULONG Unknown2)
{
+ UNIMPLEMENTED
return STATUS_NOT_SUPPORTED;
}
PULONG CurrentFrame
)
{
+ UNIMPLEMENTED
return STATUS_NOT_SUPPORTED;
}
if (Version != NULL)
{
Version->USBDI_Version = USBDI_VERSION;
- Version->Supported_USB_Version = 0x100;
+ Version->Supported_USB_Version = 0x200;
}
}
* @implemented
*/
NTSTATUS NTAPI
-USBD_RestoreDevice(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3)
+USBD_RestoreDevice(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3)
{
+ UNIMPLEMENTED
return STATUS_NOT_SUPPORTED;
}
* @implemented
*/
VOID NTAPI
-USBD_RegisterHcDeviceCapabilities(DWORD Unknown1, DWORD Unknown2,
- DWORD Unknown3)
+USBD_RegisterHcDeviceCapabilities(ULONG Unknown1, ULONG Unknown2,
+ ULONG Unknown3)
{
+ UNIMPLEMENTED
}
/*
* @implemented
- * FIXME: Test
*/
-PURB
-NTAPI
+PURB NTAPI
USBD_CreateConfigurationRequestEx(
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
PUSBD_INTERFACE_LIST_ENTRY InterfaceList
)
{
PURB Urb;
- DWORD UrbSize;
- DWORD InterfaceCount;
-
- for (InterfaceCount = 0;
- InterfaceList[InterfaceCount].InterfaceDescriptor != NULL;
- ++InterfaceCount)
- ;
- /* Include the NULL entry */
- ++InterfaceCount;
-
- UrbSize = sizeof(Urb->UrbSelectConfiguration) +
- (InterfaceCount * sizeof(PUSBD_INTERFACE_LIST_ENTRY));
+ ULONG UrbSize = 0;
+ ULONG InterfaceCount = 0, PipeCount = 0;
+ ULONG InterfaceNumber, EndPointNumber;
+ PUSBD_INTERFACE_INFORMATION InterfaceInfo;
+
+ while(InterfaceList[InterfaceCount].InterfaceDescriptor)
+ {
+ // pipe count
+ PipeCount += InterfaceList[InterfaceCount].InterfaceDescriptor->bNumEndpoints;
+
+ // interface count
+ InterfaceCount++;
+ }
+
+ // size of urb
+ UrbSize = GET_SELECT_CONFIGURATION_REQUEST_SIZE(InterfaceCount, PipeCount);
+
+ // allocate urb
Urb = ExAllocatePool(NonPagedPool, UrbSize);
- Urb->UrbSelectConfiguration.Hdr.Function =
- URB_FUNCTION_SELECT_CONFIGURATION;
- Urb->UrbSelectConfiguration.Hdr.Length =
- sizeof(Urb->UrbSelectConfiguration);
- Urb->UrbSelectConfiguration.ConfigurationDescriptor =
- ConfigurationDescriptor;
- memcpy((PVOID)&Urb->UrbSelectConfiguration.Interface, (PVOID)InterfaceList,
- InterfaceCount * sizeof(PUSBD_INTERFACE_LIST_ENTRY));
+ if (!Urb)
+ {
+ // no memory
+ return NULL;
+ }
+
+ // zero urb
+ RtlZeroMemory(Urb, UrbSize);
+
+ // init urb header
+ Urb->UrbSelectConfiguration.Hdr.Function = URB_FUNCTION_SELECT_CONFIGURATION;
+ Urb->UrbSelectConfiguration.Hdr.Length = UrbSize;
+ Urb->UrbSelectConfiguration.ConfigurationDescriptor = ConfigurationDescriptor;
+
+ // init interface information
+ InterfaceInfo = &Urb->UrbSelectConfiguration.Interface;
+ for (InterfaceNumber = 0; InterfaceNumber < InterfaceCount; InterfaceNumber++)
+ {
+ // init interface info
+ InterfaceList[InterfaceNumber].Interface = InterfaceInfo;
+ InterfaceInfo->InterfaceNumber = InterfaceList[InterfaceNumber].InterfaceDescriptor->bInterfaceNumber;
+ InterfaceInfo->AlternateSetting = InterfaceList[InterfaceNumber].InterfaceDescriptor->bAlternateSetting;
+ InterfaceInfo->NumberOfPipes = InterfaceList[InterfaceNumber].InterfaceDescriptor->bNumEndpoints;
+
+ // store length
+ InterfaceInfo->Length = GET_USBD_INTERFACE_SIZE(InterfaceList[InterfaceNumber].InterfaceDescriptor->bNumEndpoints);
+
+ // sanity check
+ //C_ASSERT(FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes) == 16);
+
+ for (EndPointNumber = 0; EndPointNumber < InterfaceInfo->NumberOfPipes; EndPointNumber++)
+ {
+ // init max transfer size
+ InterfaceInfo->Pipes[EndPointNumber].MaximumTransferSize = PAGE_SIZE;
+ }
+
+ // next interface info
+ InterfaceInfo = (PUSBD_INTERFACE_INFORMATION) ((ULONG_PTR)InterfaceInfo + InterfaceInfo->Length);
+ }
return Urb;
}
/*
- * @unimplemented
+ * @implemented
*/
PURB NTAPI
USBD_CreateConfigurationRequest(
PUSHORT Size
)
{
+ /* WindowsXP returns NULL */
return NULL;
}
/*
- * @unimplemented
+ * @implemented
*/
ULONG NTAPI
USBD_GetInterfaceLength(
{
ULONG_PTR Current;
PUSB_INTERFACE_DESCRIPTOR CurrentDescriptor = InterfaceDescriptor;
- DWORD Length = CurrentDescriptor->bLength;
+ ULONG Length = 0;
+ BOOLEAN InterfaceFound = FALSE;
- // USB_ENDPOINT_DESCRIPTOR_TYPE
- if (CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
+ for (Current = (ULONG_PTR)CurrentDescriptor;
+ Current < (ULONG_PTR)BufferEnd;
+ Current += CurrentDescriptor->bLength)
{
- for (Current = (ULONG_PTR)CurrentDescriptor;
- Current < (ULONG_PTR)BufferEnd;
- Current += CurrentDescriptor->bLength)
- CurrentDescriptor = (PUSB_INTERFACE_DESCRIPTOR)Current;
- Length += CurrentDescriptor->bLength;
+ CurrentDescriptor = (PUSB_INTERFACE_DESCRIPTOR)Current;
+ if ((CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) && (InterfaceFound))
+ break;
+ else if (CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
+ InterfaceFound = TRUE;
+
+ Length += CurrentDescriptor->bLength;
}
+
return Length;
}
LONG DescriptorType
)
{
- PUSB_COMMON_DESCRIPTOR PComDes = StartPosition;
+ PUSB_COMMON_DESCRIPTOR CommonDescriptor;
- while(PComDes)
+ /* use start position */
+ CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)StartPosition;
+
+
+ /* find next available descriptor */
+ while(CommonDescriptor)
{
- if (PComDes >= (PUSB_COMMON_DESCRIPTOR)
- ((PLONG)DescriptorBuffer + TotalLength) ) break;
- if (PComDes->bDescriptorType == DescriptorType) return PComDes;
- if (PComDes->bLength == 0) break;
- PComDes = PComDes + PComDes->bLength;
+ if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)DescriptorBuffer + TotalLength))
+ {
+ /* end reached */
+ DPRINT("End reached %p\n", CommonDescriptor);
+ return NULL;
+ }
+
+ DPRINT("CommonDescriptor Type %x Length %x\n", CommonDescriptor->bDescriptorType, CommonDescriptor->bLength);
+
+ /* is the requested one */
+ if (CommonDescriptor->bDescriptorType == DescriptorType)
+ {
+ /* it is */
+ return CommonDescriptor;
+ }
+
+ if (CommonDescriptor->bLength == 0)
+ {
+ /* invalid usb descriptor */
+ return NULL;
+ }
+
+ /* move to next descriptor */
+ CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
}
+
+ /* no descriptor found */
return NULL;
}
LONG InterfaceProtocol
)
{
- int x = 0;
- PUSB_INTERFACE_DESCRIPTOR UsbInterfaceDesc = StartPosition;
+ BOOLEAN Found;
+ PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+
+ /* set to start position */
+ InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)StartPosition;
- while(UsbInterfaceDesc)
+ DPRINT("USBD_ParseConfigurationDescriptorEx\n");
+ DPRINT("ConfigurationDescriptor %p Length %lu\n", ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength);
+ DPRINT("CurrentOffset %p Offset %lu\n", StartPosition, ((ULONG_PTR)StartPosition - (ULONG_PTR)ConfigurationDescriptor));
+
+ while(InterfaceDescriptor)
{
- UsbInterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR)
- USBD_ParseDescriptors(ConfigurationDescriptor,
- ConfigurationDescriptor->wTotalLength,
- UsbInterfaceDesc,
- USB_INTERFACE_DESCRIPTOR_TYPE);
+ /* get interface descriptor */
+ InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, InterfaceDescriptor, USB_INTERFACE_DESCRIPTOR_TYPE);
+ if (!InterfaceDescriptor)
+ {
+ /* no more descriptors available */
+ break;
+ }
+
+ DPRINT("InterfaceDescriptor %p InterfaceNumber %x AlternateSetting %x Length %lu\n", InterfaceDescriptor, InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting, InterfaceDescriptor->bLength);
- if (!UsbInterfaceDesc) break;
+ /* set found */
+ Found = TRUE;
+ /* is there an interface number provided */
if(InterfaceNumber != -1)
{
- if(InterfaceNumber != UsbInterfaceDesc->bInterfaceNumber) x = 1;
+ if(InterfaceNumber != InterfaceDescriptor->bInterfaceNumber)
+ {
+ /* interface number does not match */
+ Found = FALSE;
+ }
}
+
+ /* is there an alternate setting provided */
if(AlternateSetting != -1)
{
- if(AlternateSetting != UsbInterfaceDesc->bAlternateSetting) x = 1;
+ if(AlternateSetting != InterfaceDescriptor->bAlternateSetting)
+ {
+ /* alternate setting does not match */
+ Found = FALSE;
+ }
}
+
+ /* match on interface class */
if(InterfaceClass != -1)
{
- if(InterfaceClass != UsbInterfaceDesc->bInterfaceClass) x = 1;
+ if(InterfaceClass != InterfaceDescriptor->bInterfaceClass)
+ {
+ /* no match with interface class criteria */
+ Found = FALSE;
+ }
}
+
+ /* match on interface sub class */
if(InterfaceSubClass != -1)
{
- if(InterfaceSubClass != UsbInterfaceDesc->bInterfaceSubClass) x = 1;
+ if(InterfaceSubClass != InterfaceDescriptor->bInterfaceSubClass)
+ {
+ /* no interface sub class match */
+ Found = FALSE;
+ }
}
+
+ /* interface protocol criteria */
if(InterfaceProtocol != -1)
{
- if(InterfaceProtocol != UsbInterfaceDesc->bInterfaceProtocol) x = 1;
+ if(InterfaceProtocol != InterfaceDescriptor->bInterfaceProtocol)
+ {
+ /* no interface protocol match */
+ Found = FALSE;
+ }
+ }
+
+ if (Found)
+ {
+ /* the choosen one */
+ return InterfaceDescriptor;
}
- if (!x) return UsbInterfaceDesc;
+ /* sanity check */
+ ASSERT(InterfaceDescriptor->bLength);
- if (UsbInterfaceDesc->bLength == 0) break;
- UsbInterfaceDesc = UsbInterfaceDesc + UsbInterfaceDesc->bLength;
+ /* move to next descriptor */
+ InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
}
+
+ DPRINT("No Descriptor With InterfaceNumber %ld AlternateSetting %ld InterfaceClass %ld InterfaceSubClass %ld InterfaceProtocol %ld found\n", InterfaceNumber,
+ AlternateSetting, InterfaceClass, InterfaceSubClass, InterfaceProtocol);
+
return NULL;
}
/*
* @implemented
*/
-DWORD NTAPI
+ULONG NTAPI
USBD_GetPdoRegistryParameter(
PDEVICE_OBJECT PhysicalDeviceObject,
PVOID Parameter,
NTSTATUS Status;
HANDLE DevInstRegKey;
+ /* Open the device key */
Status = IoOpenDeviceRegistryKey(PhysicalDeviceObject,
- PLUGPLAY_REGKEY_DRIVER, STANDARD_RIGHTS_ALL, &DevInstRegKey);
+ PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_ALL, &DevInstRegKey);
if (NT_SUCCESS(Status))
{
- PKEY_VALUE_FULL_INFORMATION FullInfo;
+ PKEY_VALUE_PARTIAL_INFORMATION PartialInfo;
UNICODE_STRING ValueName;
ULONG Length;
- RtlInitUnicodeString(&ValueName, KeyName);
- Length = ParameterLength + KeyNameLength + sizeof(KEY_VALUE_FULL_INFORMATION);
- FullInfo = ExAllocatePool(PagedPool, Length);
- if (FullInfo)
+ /* Initialize the unicode string based on caller data */
+ ValueName.Buffer = KeyName;
+ ValueName.Length = ValueName.MaximumLength = KeyNameLength;
+
+ Length = ParameterLength + sizeof(KEY_VALUE_PARTIAL_INFORMATION);
+ PartialInfo = ExAllocatePool(PagedPool, Length);
+ if (PartialInfo)
{
Status = ZwQueryValueKey(DevInstRegKey, &ValueName,
- KeyValueFullInformation, FullInfo, Length, &Length);
+ KeyValuePartialInformation, PartialInfo, Length, &Length);
+ if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ /* The caller doesn't want all the data */
+ ExFreePool(PartialInfo);
+ PartialInfo = ExAllocatePool(PagedPool, Length);
+ if (PartialInfo)
+ {
+ Status = ZwQueryValueKey(DevInstRegKey, &ValueName,
+ KeyValuePartialInformation, PartialInfo, Length, &Length);
+ }
+ else
+ {
+ Status = STATUS_NO_MEMORY;
+ }
+ }
+
if (NT_SUCCESS(Status))
{
+ /* Compute the length to copy back */
+ if (ParameterLength < PartialInfo->DataLength)
+ Length = ParameterLength;
+ else
+ Length = PartialInfo->DataLength;
+
RtlCopyMemory(Parameter,
- ((PUCHAR)FullInfo) + FullInfo->DataOffset,
- ParameterLength /*FullInfo->DataLength*/);
+ PartialInfo->Data,
+ Length);
+ }
+
+ if (PartialInfo)
+ {
+ ExFreePool(PartialInfo);
}
- ExFreePool(FullInfo);
} else
Status = STATUS_NO_MEMORY;
ZwClose(DevInstRegKey);