private UsbDescriptorStructure GetNextDescriptor(UsbDescriptorTypes descriptorType)
        {
            byte[] temp = new byte[2];
            UsbDescriptorStructure result = null;

            while (ms.Position < ms.Length - 2)
            {
                if (2 != ms.Read(temp, 0, 2))
                {
                    return(null);
                }

                UsbDescriptorStructure des = new UsbDescriptorStructure();
                PduMarshaler.Unmarshal(temp, des);

                if (des.bDescriptorType == descriptorType)
                {
                    ms.Seek(-2, SeekOrigin.Current);

                    switch (des.bDescriptorType)
                    {
                    case UsbDescriptorTypes.USB_INTERFACE_DESCRIPTOR_TYPE:
                        result = new USB_INTERFACE_DESCRIPTOR();
                        if (ParseDescriptor(USB_INTERFACE_DESCRIPTOR.DefaultSize, result))
                        {
                            return(result);
                        }
                        break;

                    default:
                        throw new NotImplementedException();
                        //break;
                    }
                }
                else
                {
                    ms.Seek(des.bLength - 1, SeekOrigin.Current);
                }
            }
            return(result);
        }
        /// <summary>
        /// Parses all information of the configuration result.
        /// </summary>
        /// <param name="pdu">The EusbUrbCompletionPdu to be parsed.</param>
        /// <returns>true indicates successful.</returns>
        public bool ParseAll(EusbUrbCompletionPdu pdu)
        {
            if (pdu.OutputBuffer == null)
            {
                return(false);
            }
            ms = new MemoryStream(pdu.OutputBuffer);

            USB_CONFIGURATION_DESCRIPTOR cd = UsbStructParser.Parse <USB_CONFIGURATION_DESCRIPTOR>(pdu);

            ms.Seek(USB_CONFIGURATION_DESCRIPTOR.DefaultSize, SeekOrigin.Begin);

            if (ms.Length != cd.wTotalLength)
            {
                return(false);
            }

            configDescriptor = pdu.OutputBuffer;

            USB_INTERFACE_DESCRIPTOR interfaceDes = (USB_INTERFACE_DESCRIPTOR)GetNextDescriptor(UsbDescriptorTypes.USB_INTERFACE_DESCRIPTOR_TYPE);

            while (null != interfaceDes)
            {
                TS_USBD_INTERFACE_INFORMATION interfaceInfo = new TS_USBD_INTERFACE_INFORMATION();
                interfaceInfo.NumberOfPipesExpected = interfaceDes.bNumEndpoints;
                interfaceInfo.InterfaceNumber       = interfaceDes.bInterfaceNumber;
                interfaceInfo.AlternateSetting      = interfaceDes.bAlternateSetting;
                // Padding can be set to any value and MUST be ignored upon receipt.
                interfaceInfo.Padding = PaddingGenerator.GeneratePadding();
                GeneratePipeInformation(interfaceDes, interfaceInfo);
                interfaces.Add(interfaceInfo);

                interfaceDes = (USB_INTERFACE_DESCRIPTOR)GetNextDescriptor(UsbDescriptorTypes.USB_INTERFACE_DESCRIPTOR_TYPE);
            }

            return(true);
        }
        private void GeneratePipeInformation(USB_INTERFACE_DESCRIPTOR interfaceDes, TS_USBD_INTERFACE_INFORMATION interfaceInfo)
        {
            uint pipeCount = interfaceDes.bNumEndpoints;

            interfaceInfo.NumberOfPipes = pipeCount;
            interfaceInfo.Infomations   = new TS_USBD_PIPE_INFORMATION[pipeCount];

            ushort lenExpectPipeInfo = 2 + 2 + 1 + 1 + 2 + 4;

            interfaceInfo.Length = (ushort)(lenExpectPipeInfo + pipeCount * (2 + 2 + 4 + 4));

            for (int i = 0; i < pipeCount; i++)
            {
                interfaceInfo.Infomations[i] = new TS_USBD_PIPE_INFORMATION();
                // TODO:
                // In Windows XP, Windows Server 2003 and later operating system, Alt settings for an interface or restrict the maximum packet size by setting
                // MaximumPacketSize to some value less than or equal to the value of of wMaxPacketSize defined in device firmware for the current Alt settings.
                interfaceInfo.Infomations[i].MaximumPacketSize = 0;
                interfaceInfo.Infomations[i].Padding           = PaddingGenerator.GeneratePadding();
                // In Windows XP, Windows Server 2003 and later operating system, the MaximumTransferSize member of the USBD_PIPE_INFORMATION structure is obsolete.
                interfaceInfo.Infomations[i].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
                interfaceInfo.Infomations[i].PipeFlags           = 0;
            }
        }